Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
sonixj.c
Go to the documentation of this file.
1 /*
2  * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
3  *
4  * Copyright (C) 2009-2011 Jean-Fran├žois Moine <http://moinejf.free.fr>
5  * Copyright (C) 2005 Michel Xhaard [email protected]
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 
24 #define MODULE_NAME "sonixj"
25 
26 #include <linux/input.h>
27 #include "gspca.h"
28 #include "jpeg.h"
29 
30 MODULE_AUTHOR("Jean-Fran├žois Moine <http://moinejf.free.fr>");
31 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32 MODULE_LICENSE("GPL");
33 
34 /* controls */
35 enum e_ctrl {
40  RED,
50  NCTRLS /* number of controls */
51 };
52 
53 /* specific webcam descriptor */
54 struct sd {
55  struct gspca_dev gspca_dev; /* !! must be the first item */
56 
58 
61 
62  struct work_struct work;
64 
65  u32 pktsz; /* (used by pkt_scan) */
66  u16 npkt;
67  s8 nchg;
69 
70  u8 quality; /* image quality */
71 #define QUALITY_MIN 25
72 #define QUALITY_MAX 90
73 #define QUALITY_DEF 70
74 
78  u8 flags;
79 
80  s8 ag_cnt;
81 #define AG_CNT_START 13
82 
83  u8 bridge;
84 #define BRIDGE_SN9C102P 0
85 #define BRIDGE_SN9C105 1
86 #define BRIDGE_SN9C110 2
87 #define BRIDGE_SN9C120 3
88  u8 sensor; /* Type of image sensor chip */
89  u8 i2c_addr;
90 
92 };
93 enum sensors {
109 };
110 
111 static void qual_upd(struct work_struct *work);
112 
113 /* device flags */
114 #define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
115 #define F_ILLUM 0x02 /* presence of illuminator */
116 
117 /* sn9c1xx definitions */
118 /* register 0x01 */
119 #define S_PWR_DN 0x01 /* sensor power down */
120 #define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
121 #define V_TX_EN 0x04 /* video transfer enable */
122 #define LED 0x08 /* output to pin LED */
123 #define SCL_SEL_OD 0x20 /* open-drain mode */
124 #define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
125 /* register 0x17 */
126 #define MCK_SIZE_MASK 0x1f /* sensor master clock */
127 #define SEN_CLK_EN 0x20 /* enable sensor clock */
128 #define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
129 
130 /* V4L2 controls supported by the driver */
131 static void setbrightness(struct gspca_dev *gspca_dev);
132 static void setcontrast(struct gspca_dev *gspca_dev);
133 static void setcolors(struct gspca_dev *gspca_dev);
134 static void setredblue(struct gspca_dev *gspca_dev);
135 static void setgamma(struct gspca_dev *gspca_dev);
136 static void setexposure(struct gspca_dev *gspca_dev);
137 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
138 static void setgain(struct gspca_dev *gspca_dev);
139 static void sethvflip(struct gspca_dev *gspca_dev);
140 static void setsharpness(struct gspca_dev *gspca_dev);
141 static void setillum(struct gspca_dev *gspca_dev);
142 static void setfreq(struct gspca_dev *gspca_dev);
143 
144 static const struct ctrl sd_ctrls[NCTRLS] = {
145 [BRIGHTNESS] = {
146  {
147  .id = V4L2_CID_BRIGHTNESS,
148  .type = V4L2_CTRL_TYPE_INTEGER,
149  .name = "Brightness",
150  .minimum = 0,
151  .maximum = 0xff,
152  .step = 1,
153  .default_value = 0x80,
154  },
155  .set_control = setbrightness
156  },
157 [CONTRAST] = {
158  {
159  .id = V4L2_CID_CONTRAST,
160  .type = V4L2_CTRL_TYPE_INTEGER,
161  .name = "Contrast",
162  .minimum = 0,
163 #define CONTRAST_MAX 127
164  .maximum = CONTRAST_MAX,
165  .step = 1,
166  .default_value = 20,
167  },
168  .set_control = setcontrast
169  },
170 [COLORS] = {
171  {
172  .id = V4L2_CID_SATURATION,
173  .type = V4L2_CTRL_TYPE_INTEGER,
174  .name = "Saturation",
175  .minimum = 0,
176  .maximum = 40,
177  .step = 1,
178 #define COLORS_DEF 25
179  .default_value = COLORS_DEF,
180  },
181  .set_control = setcolors
182  },
183 [BLUE] = {
184  {
185  .id = V4L2_CID_BLUE_BALANCE,
186  .type = V4L2_CTRL_TYPE_INTEGER,
187  .name = "Blue Balance",
188  .minimum = 24,
189  .maximum = 40,
190  .step = 1,
191  .default_value = 32,
192  },
193  .set_control = setredblue
194  },
195 [RED] = {
196  {
197  .id = V4L2_CID_RED_BALANCE,
198  .type = V4L2_CTRL_TYPE_INTEGER,
199  .name = "Red Balance",
200  .minimum = 24,
201  .maximum = 40,
202  .step = 1,
203  .default_value = 32,
204  },
205  .set_control = setredblue
206  },
207 [GAMMA] = {
208  {
209  .id = V4L2_CID_GAMMA,
210  .type = V4L2_CTRL_TYPE_INTEGER,
211  .name = "Gamma",
212  .minimum = 0,
213  .maximum = 40,
214  .step = 1,
215 #define GAMMA_DEF 20
216  .default_value = GAMMA_DEF,
217  },
218  .set_control = setgamma
219  },
220 [EXPOSURE] = {
221  {
222  .id = V4L2_CID_EXPOSURE,
223  .type = V4L2_CTRL_TYPE_INTEGER,
224  .name = "Exposure",
225  .minimum = 500,
226  .maximum = 1500,
227  .step = 1,
228  .default_value = 1024
229  },
230  .set_control = setexposure
231  },
232 [AUTOGAIN] = {
233  {
234  .id = V4L2_CID_AUTOGAIN,
235  .type = V4L2_CTRL_TYPE_BOOLEAN,
236  .name = "Auto Gain",
237  .minimum = 0,
238  .maximum = 1,
239  .step = 1,
240  .default_value = 1
241  },
242  .set = sd_setautogain,
243  },
244 [GAIN] = {
245  {
246  .id = V4L2_CID_GAIN,
247  .type = V4L2_CTRL_TYPE_INTEGER,
248  .name = "Gain",
249  .minimum = 4,
250  .maximum = 49,
251  .step = 1,
252  .default_value = 15
253  },
254  .set_control = setgain
255  },
256 [HFLIP] = {
257  {
258  .id = V4L2_CID_HFLIP,
259  .type = V4L2_CTRL_TYPE_BOOLEAN,
260  .name = "Mirror",
261  .minimum = 0,
262  .maximum = 1,
263  .step = 1,
264  .default_value = 0,
265  },
266  .set_control = sethvflip
267  },
268 [VFLIP] = {
269  {
270  .id = V4L2_CID_VFLIP,
271  .type = V4L2_CTRL_TYPE_BOOLEAN,
272  .name = "Vflip",
273  .minimum = 0,
274  .maximum = 1,
275  .step = 1,
276  .default_value = 0,
277  },
278  .set_control = sethvflip
279  },
280 [SHARPNESS] = {
281  {
282  .id = V4L2_CID_SHARPNESS,
283  .type = V4L2_CTRL_TYPE_INTEGER,
284  .name = "Sharpness",
285  .minimum = 0,
286  .maximum = 255,
287  .step = 1,
288  .default_value = 90,
289  },
290  .set_control = setsharpness
291  },
292 [ILLUM] = {
293  {
295  .type = V4L2_CTRL_TYPE_BOOLEAN,
296  .name = "Illuminator / infrared",
297  .minimum = 0,
298  .maximum = 1,
299  .step = 1,
300  .default_value = 0,
301  },
302  .set_control = setillum
303  },
304 /* ov7630/ov7648/ov7660 only */
305 [FREQ] = {
306  {
308  .type = V4L2_CTRL_TYPE_MENU,
309  .name = "Light frequency filter",
310  .minimum = 0,
311  .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
312  .step = 1,
313  .default_value = 1,
314  },
315  .set_control = setfreq
316  },
317 };
318 
319 /* table of the disabled controls */
320 static const __u32 ctrl_dis[] = {
321 [SENSOR_ADCM1700] = (1 << EXPOSURE) |
322  (1 << AUTOGAIN) |
323  (1 << GAIN) |
324  (1 << HFLIP) |
325  (1 << VFLIP) |
326  (1 << FREQ),
327 
328 [SENSOR_GC0307] = (1 << EXPOSURE) |
329  (1 << GAIN) |
330  (1 << HFLIP) |
331  (1 << VFLIP) |
332  (1 << FREQ),
333 
334 [SENSOR_HV7131R] = (1 << EXPOSURE) |
335  (1 << GAIN) |
336  (1 << HFLIP) |
337  (1 << FREQ),
338 
339 [SENSOR_MI0360] = (1 << EXPOSURE) |
340  (1 << GAIN) |
341  (1 << HFLIP) |
342  (1 << VFLIP) |
343  (1 << FREQ),
344 
345 [SENSOR_MI0360B] = (1 << EXPOSURE) |
346  (1 << GAIN) |
347  (1 << HFLIP) |
348  (1 << VFLIP) |
349  (1 << FREQ),
350 
351 [SENSOR_MO4000] = (1 << EXPOSURE) |
352  (1 << GAIN) |
353  (1 << HFLIP) |
354  (1 << VFLIP) |
355  (1 << FREQ),
356 
357 [SENSOR_MT9V111] = (1 << EXPOSURE) |
358  (1 << GAIN) |
359  (1 << HFLIP) |
360  (1 << VFLIP) |
361  (1 << FREQ),
362 
363 [SENSOR_OM6802] = (1 << EXPOSURE) |
364  (1 << GAIN) |
365  (1 << HFLIP) |
366  (1 << VFLIP) |
367  (1 << FREQ),
368 
369 [SENSOR_OV7630] = (1 << EXPOSURE) |
370  (1 << GAIN) |
371  (1 << HFLIP),
372 
373 [SENSOR_OV7648] = (1 << EXPOSURE) |
374  (1 << GAIN) |
375  (1 << HFLIP),
376 
377 [SENSOR_OV7660] = (1 << EXPOSURE) |
378  (1 << AUTOGAIN) |
379  (1 << GAIN) |
380  (1 << HFLIP) |
381  (1 << VFLIP),
382 
383 [SENSOR_PO1030] = (1 << EXPOSURE) |
384  (1 << AUTOGAIN) |
385  (1 << GAIN) |
386  (1 << HFLIP) |
387  (1 << VFLIP) |
388  (1 << FREQ),
389 
390 [SENSOR_PO2030N] = (1 << FREQ),
391 
392 [SENSOR_SOI768] = (1 << EXPOSURE) |
393  (1 << AUTOGAIN) |
394  (1 << GAIN) |
395  (1 << HFLIP) |
396  (1 << VFLIP) |
397  (1 << FREQ),
398 
399 [SENSOR_SP80708] = (1 << EXPOSURE) |
400  (1 << AUTOGAIN) |
401  (1 << GAIN) |
402  (1 << HFLIP) |
403  (1 << VFLIP) |
404  (1 << FREQ),
405 };
406 
407 static const struct v4l2_pix_format cif_mode[] = {
409  .bytesperline = 352,
410  .sizeimage = 352 * 288 * 4 / 8 + 590,
411  .colorspace = V4L2_COLORSPACE_JPEG,
412  .priv = 0},
413 };
414 static const struct v4l2_pix_format vga_mode[] = {
416  .bytesperline = 160,
417  .sizeimage = 160 * 120 * 4 / 8 + 590,
418  .colorspace = V4L2_COLORSPACE_JPEG,
419  .priv = 2},
421  .bytesperline = 320,
422  .sizeimage = 320 * 240 * 3 / 8 + 590,
423  .colorspace = V4L2_COLORSPACE_JPEG,
424  .priv = 1},
426  .bytesperline = 640,
427  /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
428  .sizeimage = 640 * 480 * 3 / 4 + 590,
429  .colorspace = V4L2_COLORSPACE_JPEG,
430  .priv = 0},
431 };
432 
433 static const u8 sn_adcm1700[0x1c] = {
434 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
435  0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
436 /* reg8 reg9 rega regb regc regd rege regf */
437  0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
439  0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
440 /* reg18 reg19 reg1a reg1b */
441  0x06, 0x00, 0x00, 0x00
442 };
443 
444 static const u8 sn_gc0307[0x1c] = {
445 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
446  0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
447 /* reg8 reg9 rega regb regc regd rege regf */
448  0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
449 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
450  0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
451 /* reg18 reg19 reg1a reg1b */
452  0x06, 0x00, 0x00, 0x00
453 };
454 
455 static const u8 sn_hv7131[0x1c] = {
456 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
457  0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
458 /* reg8 reg9 rega regb regc regd rege regf */
459  0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
461  0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
462 /* reg18 reg19 reg1a reg1b */
463  0x0a, 0x00, 0x00, 0x00
464 };
465 
466 static const u8 sn_mi0360[0x1c] = {
467 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
468  0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
469 /* reg8 reg9 rega regb regc regd rege regf */
470  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
471 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
472  0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
473 /* reg18 reg19 reg1a reg1b */
474  0x06, 0x00, 0x00, 0x00
475 };
476 
477 static const u8 sn_mi0360b[0x1c] = {
478 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
479  0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
480 /* reg8 reg9 rega regb regc regd rege regf */
481  0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
482 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
483  0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40,
484 /* reg18 reg19 reg1a reg1b */
485  0x06, 0x00, 0x00, 0x00
486 };
487 
488 static const u8 sn_mo4000[0x1c] = {
489 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
490  0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
491 /* reg8 reg9 rega regb regc regd rege regf */
492  0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
493 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
494  0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
495 /* reg18 reg19 reg1a reg1b */
496  0x08, 0x00, 0x00, 0x00
497 };
498 
499 static const u8 sn_mt9v111[0x1c] = {
500 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
501  0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
502 /* reg8 reg9 rega regb regc regd rege regf */
503  0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
504 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
505  0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
506 /* reg18 reg19 reg1a reg1b */
507  0x06, 0x00, 0x00, 0x00
508 };
509 
510 static const u8 sn_om6802[0x1c] = {
511 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
512  0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
513 /* reg8 reg9 rega regb regc regd rege regf */
514  0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
516  0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
517 /* reg18 reg19 reg1a reg1b */
518  0x05, 0x00, 0x00, 0x00
519 };
520 
521 static const u8 sn_ov7630[0x1c] = {
522 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
523  0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
524 /* reg8 reg9 rega regb regc regd rege regf */
525  0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
527  0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
528 /* reg18 reg19 reg1a reg1b */
529  0x0b, 0x00, 0x00, 0x00
530 };
531 
532 static const u8 sn_ov7648[0x1c] = {
533 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
534  0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
535 /* reg8 reg9 rega regb regc regd rege regf */
536  0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
537 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
538  0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
539 /* reg18 reg19 reg1a reg1b */
540  0x0b, 0x00, 0x00, 0x00
541 };
542 
543 static const u8 sn_ov7660[0x1c] = {
544 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
545  0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
546 /* reg8 reg9 rega regb regc regd rege regf */
547  0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
548 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
549  0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
550 /* reg18 reg19 reg1a reg1b */
551  0x07, 0x00, 0x00, 0x00
552 };
553 
554 static const u8 sn_po1030[0x1c] = {
555 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
556  0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
557 /* reg8 reg9 rega regb regc regd rege regf */
558  0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
560  0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
561 /* reg18 reg19 reg1a reg1b */
562  0x07, 0x00, 0x00, 0x00
563 };
564 
565 static const u8 sn_po2030n[0x1c] = {
566 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
567  0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
568 /* reg8 reg9 rega regb regc regd rege regf */
569  0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
570 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
571  0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
572 /* reg18 reg19 reg1a reg1b */
573  0x07, 0x00, 0x00, 0x00
574 };
575 
576 static const u8 sn_soi768[0x1c] = {
577 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
578  0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
579 /* reg8 reg9 rega regb regc regd rege regf */
580  0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
581 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
582  0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
583 /* reg18 reg19 reg1a reg1b */
584  0x07, 0x00, 0x00, 0x00
585 };
586 
587 static const u8 sn_sp80708[0x1c] = {
588 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
589  0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
590 /* reg8 reg9 rega regb regc regd rege regf */
591  0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
592 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
593  0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
594 /* reg18 reg19 reg1a reg1b */
595  0x07, 0x00, 0x00, 0x00
596 };
597 
598 /* sequence specific to the sensors - !! index = SENSOR_xxx */
599 static const u8 *sn_tb[] = {
600 [SENSOR_ADCM1700] = sn_adcm1700,
601 [SENSOR_GC0307] = sn_gc0307,
602 [SENSOR_HV7131R] = sn_hv7131,
603 [SENSOR_MI0360] = sn_mi0360,
604 [SENSOR_MI0360B] = sn_mi0360b,
605 [SENSOR_MO4000] = sn_mo4000,
606 [SENSOR_MT9V111] = sn_mt9v111,
607 [SENSOR_OM6802] = sn_om6802,
608 [SENSOR_OV7630] = sn_ov7630,
609 [SENSOR_OV7648] = sn_ov7648,
610 [SENSOR_OV7660] = sn_ov7660,
611 [SENSOR_PO1030] = sn_po1030,
612 [SENSOR_PO2030N] = sn_po2030n,
613 [SENSOR_SOI768] = sn_soi768,
614 [SENSOR_SP80708] = sn_sp80708,
615 };
616 
617 /* default gamma table */
618 static const u8 gamma_def[17] = {
619  0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
620  0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
621 };
622 /* gamma for sensor ADCM1700 */
623 static const u8 gamma_spec_0[17] = {
624  0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
625  0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
626 };
627 /* gamma for sensors HV7131R and MT9V111 */
628 static const u8 gamma_spec_1[17] = {
629  0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
630  0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
631 };
632 /* gamma for sensor GC0307 */
633 static const u8 gamma_spec_2[17] = {
634  0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
635  0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
636 };
637 /* gamma for sensor SP80708 */
638 static const u8 gamma_spec_3[17] = {
639  0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
640  0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
641 };
642 
643 /* color matrix and offsets */
644 static const u8 reg84[] = {
645  0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
646  0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
647  0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
648  0x00, 0x00, 0x00 /* YUV offsets */
649 };
650 
651 #define DELAY 0xdd
652 
653 static const u8 adcm1700_sensor_init[][8] = {
654  {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
655  {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
656  {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
657  {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
658  {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
659  {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
660  {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
661  {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
662  {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
663  {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
664  {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
665  {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
666  {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
667  {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
668  {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
669  {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
670  {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
671  {}
672 };
673 static const u8 adcm1700_sensor_param1[][8] = {
674  {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
675  {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
676 
677  {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
678  {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
679  {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
680  {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
681  {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
682 
683  {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
684  {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
685  {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
686  {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
687  {}
688 };
689 static const u8 gc0307_sensor_init[][8] = {
690  {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
691  {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
692  {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
693  {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
694  {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
695  {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
696  {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
697  {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
698  {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
699  {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
700  {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
701  {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
702  {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
703  {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
704  {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
705  {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
706  {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
707  {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
708  {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
709  {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
710  {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
711  {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
712  {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
713  {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
714  {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
715  {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
716  {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
717  {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
718  {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
719  {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
720  {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
721  {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
722  {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
723  {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
724  {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
725  {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
726  {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
727  {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
728  {}
729 };
730 static const u8 gc0307_sensor_param1[][8] = {
731  {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
732  {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
733  {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
734  {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
735 /*param3*/
736  {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
737  {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
738  {}
739 };
740 
741 static const u8 hv7131r_sensor_init[][8] = {
742  {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
743  {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
744  {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
745 /* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
746  {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
747  {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
748 /* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
749 
750  {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
751  {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
752  {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
753  {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
754  {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
755  {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
756  {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
757  {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
758 
759  {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
760  {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
761  {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
762  {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
763  {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
764 
765  {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
766  {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
767  {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
768  {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
769  {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
770  {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
771  /* set sensor clock */
772  {}
773 };
774 static const u8 mi0360_sensor_init[][8] = {
775  {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
776  {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
777  {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
778  {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
779  {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
780  {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
781  {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
782  {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
783  {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
784  {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
785  {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
786  {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
787  {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
788  {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
789  {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
790  {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
791  {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
792  {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
793  {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
794  {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
795  {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
796  {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
797  {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
798  {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
799  {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
800  {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
801  {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
802  {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
803  {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
804  {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
805  {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
806  {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
807  {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
808 
809  {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
810  {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
811  {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
812  {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
813  {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
814 
815  {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
816  {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
817  {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
818  {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
819 
820  {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
821  {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
822 /* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
823 /* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
824  {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
825  {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
826  {}
827 };
828 static const u8 mi0360b_sensor_init[][8] = {
829  {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
830  {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
831  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
832  {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
833  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
834  {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
835  {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
836  {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
837  {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
838  {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
839  {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
840  {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
841  {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
842  {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
843  {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
844  {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
845  {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
846  {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
847  {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
848  {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
849  {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
850  {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
851  {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
852  {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
853  {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
854  {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
855  {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
856  {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
857  {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
858  {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
859  {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
860  {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
861  {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
862  {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
863  {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
864 
865  {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
866  {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
867  {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
868  {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
869  {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
870  {}
871 };
872 static const u8 mi0360b_sensor_param1[][8] = {
873  {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
874  {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
875  {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
876  {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
877 
878  {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
879  {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
880  {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
881  {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
882  {}
883 };
884 static const u8 mo4000_sensor_init[][8] = {
885  {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
886  {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
887  {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
888  {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
889  {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
890  {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
891  {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
892  {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
893  {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
894  {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
895  {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
896  {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
897  {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
898  {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
899  {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
900  {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
901  {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
902  {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
903  {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
904  {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
905  {}
906 };
907 static const u8 mt9v111_sensor_init[][8] = {
908  {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
909  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
910  {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
911  {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
912  {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
913  {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
914  {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
915  {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
916  {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
917  {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
918  {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
919  {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
920  {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
921  {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
922  {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
923  {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
924  {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
925  {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
926  {}
927 };
928 static const u8 mt9v111_sensor_param1[][8] = {
929  {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xad, 0x10}, /* G1 and B gains */
930  {0xd1, 0x5c, 0x2d, 0x00, 0xad, 0x00, 0x33, 0x10}, /* R and G2 gains */
931  {0xb1, 0x5c, 0x06, 0x00, 0x40, 0x00, 0x00, 0x10}, /* vert blanking */
932  {0xb1, 0x5c, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10}, /* horiz blanking */
933  {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
934  {}
935 };
936 static const u8 om6802_init0[2][8] = {
937 /*fixme: variable*/
938  {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
939  {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
940 };
941 static const u8 om6802_sensor_init[][8] = {
942  {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
943  /* factory mode */
944  {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
945  /* output raw RGB */
946  {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
947 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
948  {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
949  /* auto-exposure speed (0) / white balance mode (auto RGB) */
950 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
951  * set color mode */
952 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
953  * max AGC value in AE */
954 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
955  * preset AGC */
956 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
957  * preset brightness */
958 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
959  * preset contrast */
960 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
961  * preset gamma */
962  {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
963  /* luminance mode (0x4f -> AutoExpo on) */
964  {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
965  /* preset shutter */
966 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
967  * auto frame rate */
968 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
969  {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
970  {}
971 };
972 static const u8 om6802_sensor_param1[][8] = {
973  {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
974  {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
975  {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
976  {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
977  {}
978 };
979 static const u8 ov7630_sensor_init[][8] = {
980  {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
981  {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
982  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
983  {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
984  {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
985  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
986  {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
987 /* win: i2c_r from 00 to 80 */
988  {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
989  {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
990 /* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
991  0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
992  {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
993  {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
994  {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
995  {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
996  {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
997  {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
998  {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
999  {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
1000  {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
1001  {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
1002  {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
1003  {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1004  {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
1005  {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
1006  {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
1007  {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
1008  {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
1009  {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
1010  {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
1011  {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
1012  {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
1013  {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
1014  {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
1015  {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
1016  {}
1017 };
1018 static const u8 ov7630_sensor_param1[][8] = {
1019  {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
1020  {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
1021 /*fixme: + 0x12, 0x04*/
1022 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
1023  * set by setvflip */
1024  {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
1025  {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1026  {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
1027 /* */
1028 /* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
1029 /* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
1030 /* */
1031  {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
1032 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
1033  {}
1034 };
1035 
1036 static const u8 ov7648_sensor_init[][8] = {
1037  {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
1038  {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1039  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1040  {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1041  {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
1042  {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
1043  {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
1044  {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
1045  {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
1046  {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
1047  {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
1048  {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
1049  {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
1050  {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
1051  {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
1052  {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
1053  {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
1054  {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
1055  {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
1056  {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
1057  {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
1058  {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
1059 
1060  {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
1061 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
1062 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
1063 /* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
1064  {}
1065 };
1066 static const u8 ov7648_sensor_param1[][8] = {
1067 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
1068 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
1069  * set by setvflip */
1070  {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
1071  {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
1072 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1073 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
1074 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
1075 /*...*/
1076  {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
1077 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1078 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1079 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
1080 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1081 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
1082 
1083  {}
1084 };
1085 
1086 static const u8 ov7660_sensor_init[][8] = {
1087  {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
1088  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1089  {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
1090  /* Outformat = rawRGB */
1091  {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
1092  {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
1093  /* GAIN BLUE RED VREF */
1094  {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
1095  /* COM 1 BAVE GEAVE AECHH */
1096  {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
1097  {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
1098  {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
1099  /* AECH CLKRC COM7 COM8 */
1100  {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
1101  {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
1102  /* HSTART HSTOP VSTRT VSTOP */
1103  {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
1104  {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
1105  {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
1106  /* BOS GBOS GROS ROS (BGGR offset) */
1107 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
1108  {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
1109  /* AEW AEB VPT BBIAS */
1110  {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
1111  /* GbBIAS RSVD EXHCH EXHCL */
1112  {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
1113  /* RBIAS ADVFL ASDVFH YAVE */
1114  {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
1115  /* HSYST HSYEN HREF */
1116  {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1117  {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1118  /* ADC ACOM OFON TSLB */
1119  {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1120  /* COM11 COM12 COM13 COM14 */
1121  {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1122  /* EDGE COM15 COM16 COM17 */
1123  {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1124  {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1125  {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1126  {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1127  {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1128  {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1129  {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1130  {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1131  {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1132  {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1133  /* LCC1 LCC2 LCC3 LCC4 */
1134  {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
1135  {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
1136  {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
1137  /* band gap reference [0:3] DBLV */
1138  {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1139  {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1140  {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1141  {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1142  {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1143  {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1144  {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1145  {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1146  {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
1147  {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
1148 /* not in all ms-win traces*/
1149  {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
1150  {}
1151 };
1152 static const u8 ov7660_sensor_param1[][8] = {
1153  {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
1154  /* bits[3..0]reserved */
1155  {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1156  {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1157  /* VREF vertical frame ctrl */
1158  {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1159  {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1160  {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1161  {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1162  {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1163 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
1164 /****** (some exchanges in the win trace) ******/
1165 /*fixme:param2*/
1166  {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
1167  {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1168  {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1169  {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1170 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
1171 /****** (some exchanges in the win trace) ******/
1172 /******!! startsensor KO if changed !!****/
1173 /*fixme: param3*/
1174  {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1175  {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1176  {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1177  {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
1178  {}
1179 };
1180 
1181 static const u8 po1030_sensor_init[][8] = {
1182 /* the sensor registers are described in m5602/m5602_po1030.h */
1183  {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
1184  {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1185  {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1186  {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1187  {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1188  {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1189  {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1190  {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1191  {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1192  {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1193  {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1194  {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1195  {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1196  {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1197  {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1198  {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1199  {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1200  {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1201  {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1202  {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1203  {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1204  {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1205  {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1206  {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1207  {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1208  {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1209  {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1210  {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1211 
1212  {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1213  {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1214  {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1215  {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1216  {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1217  {}
1218 };
1219 static const u8 po1030_sensor_param1[][8] = {
1220 /* from ms-win traces - these values change with auto gain/expo/wb.. */
1221  {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1222  {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1223 /* mean values */
1224  {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1225  {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1226  {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1227 
1228  {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1229  {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1230  {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1231 /* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1232  {}
1233 };
1234 
1235 static const u8 po2030n_sensor_init[][8] = {
1236  {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1237  {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1238  {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1239  {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1240  {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1241  {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1242  {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1243  {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1244  {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1245  {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1246  {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1247  {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1248  {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1249  {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1250  {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1251  {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1252  {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1253  {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1254  {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1255  {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1256  {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1257  {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1258  {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1259  {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1260  {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1261  {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1262  {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1263  {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1264  {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1265  {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1266  {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1267  {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1268  {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1269  {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1270  {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1271  {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1272  {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1273  {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1274  {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1275  {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1276  {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1277  {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1278  {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1279  {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1280  {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1281  {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1282  {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1283  {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1284  {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1285  {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1286  {}
1287 };
1288 static const u8 po2030n_sensor_param1[][8] = {
1289  {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1290  {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1291  {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1292  {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1293  {0xd1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x40, 0x10}, /* RGBG gains */
1294 /*param2*/
1295  {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1296  {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1297  {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1298  {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1299  {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1300  {}
1301 };
1302 
1303 static const u8 soi768_sensor_init[][8] = {
1304  {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1305  {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1306  {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1307  {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1308  {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1309  {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1310  {}
1311 };
1312 static const u8 soi768_sensor_param1[][8] = {
1313  {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1314  {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1315  {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1316  {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1317  {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1318 /* */
1319 /* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1320 /* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1321  {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1322 /* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1323  {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1324 /* the next sequence should be used for auto gain */
1325  {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1326  /* global gain ? : 07 - change with 0x15 at the end */
1327  {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1328  {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1329  {0xb1, 0x21, 0x2d, 0x63, 0x03, 0x00, 0x00, 0x10},
1330  /* exposure ? : 0200 - change with 0x1e at the end */
1331  {}
1332 };
1333 
1334 static const u8 sp80708_sensor_init[][8] = {
1335  {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1336  {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1337  {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1338  {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1339  {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1340  {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1341  {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1342  {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1343  {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1344  {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1345  {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1346  {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1347  {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1348  {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1349  {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1350  {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1351  {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1352  {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1353  {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1354  {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1355  {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1356  {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1357  {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1358  {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1359  {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1360  {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1361  {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1362  {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1363  {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1364  {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1365  {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1366  {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1367  {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1368  {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1369  {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1370  {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1371  {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1372  {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1373  {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1374  {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1375  {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1376  {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1377  {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1378  {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1379  {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1380  {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1381  {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1382  {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1383  {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1384  {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1385  {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1386  {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1387  {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1388  {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1389  {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1390  {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1391  {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1392  {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1393  {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1394  {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1395  {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1396  {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1397  {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1398  {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1399  {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1400  {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1401  {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1402  {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1403  {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1404  {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1405  {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
1406  {}
1407 };
1408 static const u8 sp80708_sensor_param1[][8] = {
1409  {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1410  {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1411  {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1412  {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1413  {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1414  {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1415  {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1416  {}
1417 };
1418 
1419 static const u8 (*sensor_init[])[8] = {
1420 [SENSOR_ADCM1700] = adcm1700_sensor_init,
1421 [SENSOR_GC0307] = gc0307_sensor_init,
1422 [SENSOR_HV7131R] = hv7131r_sensor_init,
1423 [SENSOR_MI0360] = mi0360_sensor_init,
1424 [SENSOR_MI0360B] = mi0360b_sensor_init,
1425 [SENSOR_MO4000] = mo4000_sensor_init,
1426 [SENSOR_MT9V111] = mt9v111_sensor_init,
1427 [SENSOR_OM6802] = om6802_sensor_init,
1428 [SENSOR_OV7630] = ov7630_sensor_init,
1429 [SENSOR_OV7648] = ov7648_sensor_init,
1430 [SENSOR_OV7660] = ov7660_sensor_init,
1431 [SENSOR_PO1030] = po1030_sensor_init,
1432 [SENSOR_PO2030N] = po2030n_sensor_init,
1433 [SENSOR_SOI768] = soi768_sensor_init,
1434 [SENSOR_SP80708] = sp80708_sensor_init,
1435 };
1436 
1437 /* read <len> bytes to gspca_dev->usb_buf */
1438 static void reg_r(struct gspca_dev *gspca_dev,
1439  u16 value, int len)
1440 {
1441  int ret;
1442 
1443  if (gspca_dev->usb_err < 0)
1444  return;
1445 #ifdef GSPCA_DEBUG
1446  if (len > USB_BUF_SZ) {
1447  pr_err("reg_r: buffer overflow\n");
1448  return;
1449  }
1450 #endif
1451  ret = usb_control_msg(gspca_dev->dev,
1452  usb_rcvctrlpipe(gspca_dev->dev, 0),
1453  0,
1455  value, 0,
1456  gspca_dev->usb_buf, len,
1457  500);
1458  PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
1459  if (ret < 0) {
1460  pr_err("reg_r err %d\n", ret);
1461  gspca_dev->usb_err = ret;
1462  }
1463 }
1464 
1465 static void reg_w1(struct gspca_dev *gspca_dev,
1466  u16 value,
1467  u8 data)
1468 {
1469  int ret;
1470 
1471  if (gspca_dev->usb_err < 0)
1472  return;
1473  PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
1474  gspca_dev->usb_buf[0] = data;
1475  ret = usb_control_msg(gspca_dev->dev,
1476  usb_sndctrlpipe(gspca_dev->dev, 0),
1477  0x08,
1479  value,
1480  0,
1481  gspca_dev->usb_buf, 1,
1482  500);
1483  if (ret < 0) {
1484  pr_err("reg_w1 err %d\n", ret);
1485  gspca_dev->usb_err = ret;
1486  }
1487 }
1488 static void reg_w(struct gspca_dev *gspca_dev,
1489  u16 value,
1490  const u8 *buffer,
1491  int len)
1492 {
1493  int ret;
1494 
1495  if (gspca_dev->usb_err < 0)
1496  return;
1497  PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
1498  value, buffer[0], buffer[1]);
1499 #ifdef GSPCA_DEBUG
1500  if (len > USB_BUF_SZ) {
1501  pr_err("reg_w: buffer overflow\n");
1502  return;
1503  }
1504 #endif
1505  memcpy(gspca_dev->usb_buf, buffer, len);
1506  ret = usb_control_msg(gspca_dev->dev,
1507  usb_sndctrlpipe(gspca_dev->dev, 0),
1508  0x08,
1510  value, 0,
1511  gspca_dev->usb_buf, len,
1512  500);
1513  if (ret < 0) {
1514  pr_err("reg_w err %d\n", ret);
1515  gspca_dev->usb_err = ret;
1516  }
1517 }
1518 
1519 /* I2C write 1 byte */
1520 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
1521 {
1522  struct sd *sd = (struct sd *) gspca_dev;
1523  int ret;
1524 
1525  if (gspca_dev->usb_err < 0)
1526  return;
1527  PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
1528  switch (sd->sensor) {
1529  case SENSOR_ADCM1700:
1530  case SENSOR_OM6802:
1531  case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
1532  gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1533  break;
1534  default: /* i2c command = a1 (400 kHz) */
1535  gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1536  break;
1537  }
1538  gspca_dev->usb_buf[1] = sd->i2c_addr;
1539  gspca_dev->usb_buf[2] = reg;
1540  gspca_dev->usb_buf[3] = val;
1541  gspca_dev->usb_buf[4] = 0;
1542  gspca_dev->usb_buf[5] = 0;
1543  gspca_dev->usb_buf[6] = 0;
1544  gspca_dev->usb_buf[7] = 0x10;
1545  ret = usb_control_msg(gspca_dev->dev,
1546  usb_sndctrlpipe(gspca_dev->dev, 0),
1547  0x08,
1549  0x08, /* value = i2c */
1550  0,
1551  gspca_dev->usb_buf, 8,
1552  500);
1553  if (ret < 0) {
1554  pr_err("i2c_w1 err %d\n", ret);
1555  gspca_dev->usb_err = ret;
1556  }
1557 }
1558 
1559 /* I2C write 8 bytes */
1560 static void i2c_w8(struct gspca_dev *gspca_dev,
1561  const u8 *buffer)
1562 {
1563  int ret;
1564 
1565  if (gspca_dev->usb_err < 0)
1566  return;
1567  PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1568  buffer[2], buffer[3]);
1569  memcpy(gspca_dev->usb_buf, buffer, 8);
1570  ret = usb_control_msg(gspca_dev->dev,
1571  usb_sndctrlpipe(gspca_dev->dev, 0),
1572  0x08,
1574  0x08, 0, /* value, index */
1575  gspca_dev->usb_buf, 8,
1576  500);
1577  msleep(2);
1578  if (ret < 0) {
1579  pr_err("i2c_w8 err %d\n", ret);
1580  gspca_dev->usb_err = ret;
1581  }
1582 }
1583 
1584 /* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1585 static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
1586 {
1587  struct sd *sd = (struct sd *) gspca_dev;
1588  u8 mode[8];
1589 
1590  switch (sd->sensor) {
1591  case SENSOR_ADCM1700:
1592  case SENSOR_OM6802:
1593  case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
1594  mode[0] = 0x80 | 0x10;
1595  break;
1596  default: /* i2c command = 91 (400 kHz) */
1597  mode[0] = 0x81 | 0x10;
1598  break;
1599  }
1600  mode[1] = sd->i2c_addr;
1601  mode[2] = reg;
1602  mode[3] = 0;
1603  mode[4] = 0;
1604  mode[5] = 0;
1605  mode[6] = 0;
1606  mode[7] = 0x10;
1607  i2c_w8(gspca_dev, mode);
1608  msleep(2);
1609  mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
1610  mode[2] = 0;
1611  i2c_w8(gspca_dev, mode);
1612  msleep(2);
1613  reg_r(gspca_dev, 0x0a, 5);
1614 }
1615 
1616 static void i2c_w_seq(struct gspca_dev *gspca_dev,
1617  const u8 (*data)[8])
1618 {
1619  while ((*data)[0] != 0) {
1620  if ((*data)[0] != DELAY)
1621  i2c_w8(gspca_dev, *data);
1622  else
1623  msleep((*data)[1]);
1624  data++;
1625  }
1626 }
1627 
1628 /* check the ID of the hv7131 sensor */
1629 /* this sequence is needed because it activates the sensor */
1630 static void hv7131r_probe(struct gspca_dev *gspca_dev)
1631 {
1632  i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
1633  msleep(10);
1634  reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
1635  msleep(10);
1636  i2c_r(gspca_dev, 0, 5); /* read sensor id */
1637  if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
1638  && gspca_dev->usb_buf[1] == 0x09
1639  && gspca_dev->usb_buf[2] == 0x01) {
1640  PDEBUG(D_PROBE, "Sensor HV7131R found");
1641  return;
1642  }
1643  pr_warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x\n",
1644  gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1645  gspca_dev->usb_buf[2]);
1646 }
1647 
1648 static void mi0360_probe(struct gspca_dev *gspca_dev)
1649 {
1650  struct sd *sd = (struct sd *) gspca_dev;
1651  int i, j;
1652  u16 val = 0;
1653  static const u8 probe_tb[][4][8] = {
1654  { /* mi0360 */
1655  {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1656  {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1657  {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1658  {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1659  },
1660  { /* mt9v111 */
1661  {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1662  {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1663  {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1664  {}
1665  },
1666  };
1667 
1668  for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1669  reg_w1(gspca_dev, 0x17, 0x62);
1670  reg_w1(gspca_dev, 0x01, 0x08);
1671  for (j = 0; j < 3; j++)
1672  i2c_w8(gspca_dev, probe_tb[i][j]);
1673  msleep(2);
1674  reg_r(gspca_dev, 0x0a, 5);
1675  val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1676  if (probe_tb[i][3][0] != 0)
1677  i2c_w8(gspca_dev, probe_tb[i][3]);
1678  reg_w1(gspca_dev, 0x01, 0x29);
1679  reg_w1(gspca_dev, 0x17, 0x42);
1680  if (val != 0xffff)
1681  break;
1682  }
1683  if (gspca_dev->usb_err < 0)
1684  return;
1685  switch (val) {
1686  case 0x8221:
1687  PDEBUG(D_PROBE, "Sensor mi0360b");
1688  sd->sensor = SENSOR_MI0360B;
1689  break;
1690  case 0x823a:
1691  PDEBUG(D_PROBE, "Sensor mt9v111");
1692  sd->sensor = SENSOR_MT9V111;
1693  break;
1694  case 0x8243:
1695  PDEBUG(D_PROBE, "Sensor mi0360");
1696  break;
1697  default:
1698  PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1699  break;
1700  }
1701 }
1702 
1703 static void ov7630_probe(struct gspca_dev *gspca_dev)
1704 {
1705  struct sd *sd = (struct sd *) gspca_dev;
1706  u16 val;
1707 
1708  /* check ov76xx */
1709  reg_w1(gspca_dev, 0x17, 0x62);
1710  reg_w1(gspca_dev, 0x01, 0x08);
1711  sd->i2c_addr = 0x21;
1712  i2c_r(gspca_dev, 0x0a, 2);
1713  val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1714  reg_w1(gspca_dev, 0x01, 0x29);
1715  reg_w1(gspca_dev, 0x17, 0x42);
1716  if (gspca_dev->usb_err < 0)
1717  return;
1718  if (val == 0x7628) { /* soi768 */
1719  sd->sensor = SENSOR_SOI768;
1720 /*fixme: only valid for 0c45:613e?*/
1721  gspca_dev->cam.input_flags =
1723  PDEBUG(D_PROBE, "Sensor soi768");
1724  return;
1725  }
1726  PDEBUG(D_PROBE, "Sensor ov%04x", val);
1727 }
1728 
1729 static void ov7648_probe(struct gspca_dev *gspca_dev)
1730 {
1731  struct sd *sd = (struct sd *) gspca_dev;
1732  u16 val;
1733 
1734  /* check ov76xx */
1735  reg_w1(gspca_dev, 0x17, 0x62);
1736  reg_w1(gspca_dev, 0x01, 0x08);
1737  sd->i2c_addr = 0x21;
1738  i2c_r(gspca_dev, 0x0a, 2);
1739  val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1740  reg_w1(gspca_dev, 0x01, 0x29);
1741  reg_w1(gspca_dev, 0x17, 0x42);
1742  if ((val & 0xff00) == 0x7600) { /* ov76xx */
1743  PDEBUG(D_PROBE, "Sensor ov%04x", val);
1744  return;
1745  }
1746 
1747  /* check po1030 */
1748  reg_w1(gspca_dev, 0x17, 0x62);
1749  reg_w1(gspca_dev, 0x01, 0x08);
1750  sd->i2c_addr = 0x6e;
1751  i2c_r(gspca_dev, 0x00, 2);
1752  val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1753  reg_w1(gspca_dev, 0x01, 0x29);
1754  reg_w1(gspca_dev, 0x17, 0x42);
1755  if (gspca_dev->usb_err < 0)
1756  return;
1757  if (val == 0x1030) { /* po1030 */
1758  PDEBUG(D_PROBE, "Sensor po1030");
1759  sd->sensor = SENSOR_PO1030;
1760  return;
1761  }
1762  pr_err("Unknown sensor %04x\n", val);
1763 }
1764 
1765 /* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1766 static void po2030n_probe(struct gspca_dev *gspca_dev)
1767 {
1768  struct sd *sd = (struct sd *) gspca_dev;
1769  u16 val;
1770 
1771  /* check gc0307 */
1772  reg_w1(gspca_dev, 0x17, 0x62);
1773  reg_w1(gspca_dev, 0x01, 0x08);
1774  reg_w1(gspca_dev, 0x02, 0x22);
1775  sd->i2c_addr = 0x21;
1776  i2c_r(gspca_dev, 0x00, 1);
1777  val = gspca_dev->usb_buf[4];
1778  reg_w1(gspca_dev, 0x01, 0x29); /* reset */
1779  reg_w1(gspca_dev, 0x17, 0x42);
1780  if (val == 0x99) { /* gc0307 (?) */
1781  PDEBUG(D_PROBE, "Sensor gc0307");
1782  sd->sensor = SENSOR_GC0307;
1783  return;
1784  }
1785 
1786  /* check po2030n */
1787  reg_w1(gspca_dev, 0x17, 0x62);
1788  reg_w1(gspca_dev, 0x01, 0x0a);
1789  sd->i2c_addr = 0x6e;
1790  i2c_r(gspca_dev, 0x00, 2);
1791  val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1792  reg_w1(gspca_dev, 0x01, 0x29);
1793  reg_w1(gspca_dev, 0x17, 0x42);
1794  if (gspca_dev->usb_err < 0)
1795  return;
1796  if (val == 0x2030) {
1797  PDEBUG(D_PROBE, "Sensor po2030n");
1798 /* sd->sensor = SENSOR_PO2030N; */
1799  } else {
1800  pr_err("Unknown sensor ID %04x\n", val);
1801  }
1802 }
1803 
1804 /* this function is called at probe time */
1805 static int sd_config(struct gspca_dev *gspca_dev,
1806  const struct usb_device_id *id)
1807 {
1808  struct sd *sd = (struct sd *) gspca_dev;
1809  struct cam *cam;
1810 
1811  sd->bridge = id->driver_info >> 16;
1812  sd->sensor = id->driver_info >> 8;
1813  sd->flags = id->driver_info;
1814 
1815  cam = &gspca_dev->cam;
1816  if (sd->sensor == SENSOR_ADCM1700) {
1817  cam->cam_mode = cif_mode;
1818  cam->nmodes = ARRAY_SIZE(cif_mode);
1819  } else {
1820  cam->cam_mode = vga_mode;
1821  cam->nmodes = ARRAY_SIZE(vga_mode);
1822  }
1823  cam->npkt = 24; /* 24 packets per ISOC message */
1824  cam->ctrls = sd->ctrls;
1825 
1826  sd->ag_cnt = -1;
1827  sd->quality = QUALITY_DEF;
1828 
1829  INIT_WORK(&sd->work, qual_upd);
1830 
1831  return 0;
1832 }
1833 
1834 /* this function is called at probe and resume time */
1835 static int sd_init(struct gspca_dev *gspca_dev)
1836 {
1837  struct sd *sd = (struct sd *) gspca_dev;
1838  const u8 *sn9c1xx;
1839  u8 regGpio[] = { 0x29, 0x70 }; /* no audio */
1840  u8 regF1;
1841 
1842  /* setup a selector by bridge */
1843  reg_w1(gspca_dev, 0xf1, 0x01);
1844  reg_r(gspca_dev, 0x00, 1);
1845  reg_w1(gspca_dev, 0xf1, 0x00);
1846  reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1847  regF1 = gspca_dev->usb_buf[0];
1848  if (gspca_dev->usb_err < 0)
1849  return gspca_dev->usb_err;
1850  PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1851  if (gspca_dev->audio)
1852  regGpio[1] |= 0x04; /* with audio */
1853  switch (sd->bridge) {
1854  case BRIDGE_SN9C102P:
1855  case BRIDGE_SN9C105:
1856  if (regF1 != 0x11)
1857  return -ENODEV;
1858  break;
1859  default:
1860 /* case BRIDGE_SN9C110: */
1861 /* case BRIDGE_SN9C120: */
1862  if (regF1 != 0x12)
1863  return -ENODEV;
1864  }
1865 
1866  switch (sd->sensor) {
1867  case SENSOR_MI0360:
1868  mi0360_probe(gspca_dev);
1869  break;
1870  case SENSOR_OV7630:
1871  ov7630_probe(gspca_dev);
1872  break;
1873  case SENSOR_OV7648:
1874  ov7648_probe(gspca_dev);
1875  break;
1876  case SENSOR_PO2030N:
1877  po2030n_probe(gspca_dev);
1878  break;
1879  }
1880 
1881  switch (sd->bridge) {
1882  case BRIDGE_SN9C102P:
1883  reg_w1(gspca_dev, 0x02, regGpio[1]);
1884  break;
1885  default:
1886  reg_w(gspca_dev, 0x01, regGpio, 2);
1887  break;
1888  }
1889 
1890  if (sd->sensor == SENSOR_OM6802)
1891  sd->ctrls[SHARPNESS].def = 0x10;
1892 
1893  /* Note we do not disable the sensor clock here (power saving mode),
1894  as that also disables the button on the cam. */
1895  reg_w1(gspca_dev, 0xf1, 0x00);
1896 
1897  /* set the i2c address */
1898  sn9c1xx = sn_tb[sd->sensor];
1899  sd->i2c_addr = sn9c1xx[9];
1900 
1901  gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1902  if (!(sd->flags & F_ILLUM))
1903  gspca_dev->ctrl_dis |= (1 << ILLUM);
1904 
1905  return gspca_dev->usb_err;
1906 }
1907 
1908 static u32 expo_adjust(struct gspca_dev *gspca_dev,
1909  u32 expo)
1910 {
1911  struct sd *sd = (struct sd *) gspca_dev;
1912 
1913  switch (sd->sensor) {
1914  case SENSOR_GC0307: {
1915  int a, b;
1916 
1917  /* expo = 0..255 -> a = 19..43 */
1918  a = 19 + expo * 25 / 256;
1919  i2c_w1(gspca_dev, 0x68, a);
1920  a -= 12;
1921  b = a * a * 4; /* heuristic */
1922  i2c_w1(gspca_dev, 0x03, b >> 8);
1923  i2c_w1(gspca_dev, 0x04, b);
1924  break;
1925  }
1926  case SENSOR_HV7131R: {
1927  u8 Expodoit[] =
1928  { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
1929 
1930  Expodoit[3] = expo >> 16;
1931  Expodoit[4] = expo >> 8;
1932  Expodoit[5] = expo;
1933  i2c_w8(gspca_dev, Expodoit);
1934  break;
1935  }
1936  case SENSOR_MI0360:
1937  case SENSOR_MI0360B: {
1938  u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1939  { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
1940  static const u8 doit[] = /* update sensor */
1941  { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1942  static const u8 sensorgo[] = /* sensor on */
1943  { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1944 
1945  if (expo > 0x0635)
1946  expo = 0x0635;
1947  else if (expo < 0x0001)
1948  expo = 0x0001;
1949  expoMi[3] = expo >> 8;
1950  expoMi[4] = expo;
1951  i2c_w8(gspca_dev, expoMi);
1952  i2c_w8(gspca_dev, doit);
1953  i2c_w8(gspca_dev, sensorgo);
1954  break;
1955  }
1956  case SENSOR_MO4000: {
1957  u8 expoMof[] =
1958  { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
1959  u8 expoMo10[] =
1960  { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
1961  static const u8 gainMo[] =
1962  { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1963 
1964  if (expo > 0x1fff)
1965  expo = 0x1fff;
1966  else if (expo < 0x0001)
1967  expo = 0x0001;
1968  expoMof[3] = (expo & 0x03fc) >> 2;
1969  i2c_w8(gspca_dev, expoMof);
1970  expoMo10[3] = ((expo & 0x1c00) >> 10)
1971  | ((expo & 0x0003) << 4);
1972  i2c_w8(gspca_dev, expoMo10);
1973  i2c_w8(gspca_dev, gainMo);
1974  PDEBUG(D_FRAM, "set exposure %d",
1975  ((expoMo10[3] & 0x07) << 10)
1976  | (expoMof[3] << 2)
1977  | ((expoMo10[3] & 0x30) >> 4));
1978  break;
1979  }
1980  case SENSOR_MT9V111: {
1981  u8 expo_c1[] =
1982  { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1983 
1984  if (expo > 0x0390)
1985  expo = 0x0390;
1986  else if (expo < 0x0060)
1987  expo = 0x0060;
1988  expo_c1[3] = expo >> 8;
1989  expo_c1[4] = expo;
1990  i2c_w8(gspca_dev, expo_c1);
1991  break;
1992  }
1993  case SENSOR_OM6802: {
1994  u8 gainOm[] =
1995  { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1996  /* preset AGC - works when AutoExpo = off */
1997 
1998  if (expo > 0x03ff)
1999  expo = 0x03ff;
2000  if (expo < 0x0001)
2001  expo = 0x0001;
2002  gainOm[3] = expo >> 2;
2003  i2c_w8(gspca_dev, gainOm);
2004  reg_w1(gspca_dev, 0x96, expo >> 5);
2005  PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
2006  break;
2007  }
2008  }
2009  return expo;
2010 }
2011 
2012 static void setbrightness(struct gspca_dev *gspca_dev)
2013 {
2014  struct sd *sd = (struct sd *) gspca_dev;
2015  unsigned int expo;
2016  int brightness;
2017  u8 k2;
2018 
2019  brightness = sd->ctrls[BRIGHTNESS].val;
2020  k2 = (brightness - 0x80) >> 2;
2021  switch (sd->sensor) {
2022  case SENSOR_ADCM1700:
2023  if (k2 > 0x1f)
2024  k2 = 0; /* only positive Y offset */
2025  break;
2026  case SENSOR_HV7131R:
2027  expo = brightness << 12;
2028  if (expo > 0x002dc6c0)
2029  expo = 0x002dc6c0;
2030  else if (expo < 0x02a0)
2031  expo = 0x02a0;
2032  sd->exposure = expo_adjust(gspca_dev, expo);
2033  break;
2034  case SENSOR_MI0360:
2035  case SENSOR_MO4000:
2036  expo = brightness << 4;
2037  sd->exposure = expo_adjust(gspca_dev, expo);
2038  break;
2039  case SENSOR_MI0360B:
2040  expo = brightness << 2;
2041  sd->exposure = expo_adjust(gspca_dev, expo);
2042  break;
2043  case SENSOR_GC0307:
2044  expo = brightness;
2045  sd->exposure = expo_adjust(gspca_dev, expo);
2046  return; /* don't set the Y offset */
2047  case SENSOR_MT9V111:
2048  expo = brightness << 2;
2049  sd->exposure = expo_adjust(gspca_dev, expo);
2050  return; /* don't set the Y offset */
2051  case SENSOR_OM6802:
2052  expo = brightness << 2;
2053  sd->exposure = expo_adjust(gspca_dev, expo);
2054  return; /* Y offset already set */
2055  }
2056 
2057  reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
2058 }
2059 
2060 static void setcontrast(struct gspca_dev *gspca_dev)
2061 {
2062  struct sd *sd = (struct sd *) gspca_dev;
2063  u8 k2;
2064  u8 contrast[6];
2065 
2066  k2 = sd->ctrls[CONTRAST].val * 37 / (CONTRAST_MAX + 1)
2067  + 37; /* 37..73 */
2068  contrast[0] = (k2 + 1) / 2; /* red */
2069  contrast[1] = 0;
2070  contrast[2] = k2; /* green */
2071  contrast[3] = 0;
2072  contrast[4] = k2 / 5; /* blue */
2073  contrast[5] = 0;
2074  reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
2075 }
2076 
2077 static void setcolors(struct gspca_dev *gspca_dev)
2078 {
2079  struct sd *sd = (struct sd *) gspca_dev;
2080  int i, v, colors;
2081  const s16 *uv;
2082  u8 reg8a[12]; /* U & V gains */
2083  static const s16 uv_com[6] = { /* same as reg84 in signed decimal */
2084  -24, -38, 64, /* UR UG UB */
2085  62, -51, -9 /* VR VG VB */
2086  };
2087  static const s16 uv_mi0360b[6] = {
2088  -20, -38, 64, /* UR UG UB */
2089  60, -51, -9 /* VR VG VB */
2090  };
2091 
2092  colors = sd->ctrls[COLORS].val;
2093  if (sd->sensor == SENSOR_MI0360B)
2094  uv = uv_mi0360b;
2095  else
2096  uv = uv_com;
2097  for (i = 0; i < 6; i++) {
2098  v = uv[i] * colors / COLORS_DEF;
2099  reg8a[i * 2] = v;
2100  reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
2101  }
2102  reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
2103 }
2104 
2105 static void setredblue(struct gspca_dev *gspca_dev)
2106 {
2107  struct sd *sd = (struct sd *) gspca_dev;
2108 
2109  if (sd->sensor == SENSOR_PO2030N) {
2110  u8 rg1b[] = /* red green1 blue (no g2) */
2111  {0xc1, 0x6e, 0x16, 0x00, 0x40, 0x00, 0x00, 0x10};
2112 
2113  /* 0x40 = normal value = gain x 1 */
2114  rg1b[3] = sd->ctrls[RED].val * 2;
2115  rg1b[5] = sd->ctrls[BLUE].val * 2;
2116  i2c_w8(gspca_dev, rg1b);
2117  return;
2118  }
2119  reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
2120 /* reg_w1(gspca_dev, 0x07, 32); */
2121  reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
2122 }
2123 
2124 static void setgamma(struct gspca_dev *gspca_dev)
2125 {
2126  struct sd *sd = (struct sd *) gspca_dev;
2127  int i, val;
2128  u8 gamma[17];
2129  const u8 *gamma_base;
2130  static const u8 delta[17] = {
2131  0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2132  0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2133  };
2134 
2135  switch (sd->sensor) {
2136  case SENSOR_ADCM1700:
2137  gamma_base = gamma_spec_0;
2138  break;
2139  case SENSOR_HV7131R:
2140  case SENSOR_MI0360B:
2141  case SENSOR_MT9V111:
2142  gamma_base = gamma_spec_1;
2143  break;
2144  case SENSOR_GC0307:
2145  gamma_base = gamma_spec_2;
2146  break;
2147  case SENSOR_SP80708:
2148  gamma_base = gamma_spec_3;
2149  break;
2150  default:
2151  gamma_base = gamma_def;
2152  break;
2153  }
2154 
2155  val = sd->ctrls[GAMMA].val;
2156  for (i = 0; i < sizeof gamma; i++)
2157  gamma[i] = gamma_base[i]
2158  + delta[i] * (val - GAMMA_DEF) / 32;
2159  reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2160 }
2161 
2162 static void setexposure(struct gspca_dev *gspca_dev)
2163 {
2164  struct sd *sd = (struct sd *) gspca_dev;
2165 
2166  if (sd->sensor == SENSOR_PO2030N) {
2167  u8 rexpo[] = /* 1a: expo H, 1b: expo M */
2168  {0xa1, 0x6e, 0x1a, 0x00, 0x40, 0x00, 0x00, 0x10};
2169 
2170  rexpo[3] = sd->ctrls[EXPOSURE].val >> 8;
2171  i2c_w8(gspca_dev, rexpo);
2172  msleep(6);
2173  rexpo[2] = 0x1b;
2174  rexpo[3] = sd->ctrls[EXPOSURE].val;
2175  i2c_w8(gspca_dev, rexpo);
2176  }
2177 }
2178 
2179 static void setautogain(struct gspca_dev *gspca_dev)
2180 {
2181  struct sd *sd = (struct sd *) gspca_dev;
2182 
2183  if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
2184  return;
2185  switch (sd->sensor) {
2186  case SENSOR_OV7630:
2187  case SENSOR_OV7648: {
2188  u8 comb;
2189 
2190  if (sd->sensor == SENSOR_OV7630)
2191  comb = 0xc0;
2192  else
2193  comb = 0xa0;
2194  if (sd->ctrls[AUTOGAIN].val)
2195  comb |= 0x03;
2196  i2c_w1(&sd->gspca_dev, 0x13, comb);
2197  return;
2198  }
2199  }
2200  if (sd->ctrls[AUTOGAIN].val)
2201  sd->ag_cnt = AG_CNT_START;
2202  else
2203  sd->ag_cnt = -1;
2204 }
2205 
2206 static void setgain(struct gspca_dev *gspca_dev)
2207 {
2208  struct sd *sd = (struct sd *) gspca_dev;
2209 
2210  if (sd->sensor == SENSOR_PO2030N) {
2211  u8 rgain[] = /* 15: gain */
2212  {0xa1, 0x6e, 0x15, 0x00, 0x40, 0x00, 0x00, 0x15};
2213 
2214  rgain[3] = sd->ctrls[GAIN].val;
2215  i2c_w8(gspca_dev, rgain);
2216  }
2217 }
2218 
2219 static void sethvflip(struct gspca_dev *gspca_dev)
2220 {
2221  struct sd *sd = (struct sd *) gspca_dev;
2222  u8 comn;
2223 
2224  switch (sd->sensor) {
2225  case SENSOR_HV7131R:
2226  comn = 0x18; /* clkdiv = 1, ablcen = 1 */
2227  if (sd->ctrls[VFLIP].val)
2228  comn |= 0x01;
2229  i2c_w1(gspca_dev, 0x01, comn); /* sctra */
2230  break;
2231  case SENSOR_OV7630:
2232  comn = 0x02;
2233  if (!sd->ctrls[VFLIP].val)
2234  comn |= 0x80;
2235  i2c_w1(gspca_dev, 0x75, comn);
2236  break;
2237  case SENSOR_OV7648:
2238  comn = 0x06;
2239  if (sd->ctrls[VFLIP].val)
2240  comn |= 0x80;
2241  i2c_w1(gspca_dev, 0x75, comn);
2242  break;
2243  case SENSOR_PO2030N:
2244  /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
2245  * (reset value: 0x0A)
2246  * bit7: HM: Horizontal Mirror: 0: disable, 1: enable
2247  * bit6: VM: Vertical Mirror: 0: disable, 1: enable
2248  * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical
2249  * bit4: FT: Single Frame Transfer: 0: disable, 1: enable
2250  * bit3-0: X
2251  */
2252  comn = 0x0a;
2253  if (sd->ctrls[HFLIP].val)
2254  comn |= 0x80;
2255  if (sd->ctrls[VFLIP].val)
2256  comn |= 0x40;
2257  i2c_w1(&sd->gspca_dev, 0x1e, comn);
2258  break;
2259  }
2260 }
2261 
2262 static void setsharpness(struct gspca_dev *gspca_dev)
2263 {
2264  struct sd *sd = (struct sd *) gspca_dev;
2265 
2266  reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
2267 }
2268 
2269 static void setillum(struct gspca_dev *gspca_dev)
2270 {
2271  struct sd *sd = (struct sd *) gspca_dev;
2272 
2273  if (gspca_dev->ctrl_dis & (1 << ILLUM))
2274  return;
2275  switch (sd->sensor) {
2276  case SENSOR_ADCM1700:
2277  reg_w1(gspca_dev, 0x02, /* gpio */
2278  sd->ctrls[ILLUM].val ? 0x64 : 0x60);
2279  break;
2280  case SENSOR_MT9V111:
2281  reg_w1(gspca_dev, 0x02,
2282  sd->ctrls[ILLUM].val ? 0x77 : 0x74);
2283 /* should have been: */
2284 /* 0x55 : 0x54); * 370i */
2285 /* 0x66 : 0x64); * Clip */
2286  break;
2287  }
2288 }
2289 
2290 static void setfreq(struct gspca_dev *gspca_dev)
2291 {
2292  struct sd *sd = (struct sd *) gspca_dev;
2293 
2294  if (gspca_dev->ctrl_dis & (1 << FREQ))
2295  return;
2296  if (sd->sensor == SENSOR_OV7660) {
2297  u8 com8;
2298 
2299  com8 = 0xdf; /* auto gain/wb/expo */
2300  switch (sd->ctrls[FREQ].val) {
2301  case 0: /* Banding filter disabled */
2302  i2c_w1(gspca_dev, 0x13, com8 | 0x20);
2303  break;
2304  case 1: /* 50 hz */
2305  i2c_w1(gspca_dev, 0x13, com8);
2306  i2c_w1(gspca_dev, 0x3b, 0x0a);
2307  break;
2308  case 2: /* 60 hz */
2309  i2c_w1(gspca_dev, 0x13, com8);
2310  i2c_w1(gspca_dev, 0x3b, 0x02);
2311  break;
2312  }
2313  } else {
2314  u8 reg2a = 0, reg2b = 0, reg2d = 0;
2315 
2316  /* Get reg2a / reg2d base values */
2317  switch (sd->sensor) {
2318  case SENSOR_OV7630:
2319  reg2a = 0x08;
2320  reg2d = 0x01;
2321  break;
2322  case SENSOR_OV7648:
2323  reg2a = 0x11;
2324  reg2d = 0x81;
2325  break;
2326  }
2327 
2328  switch (sd->ctrls[FREQ].val) {
2329  case 0: /* Banding filter disabled */
2330  break;
2331  case 1: /* 50 hz (filter on and framerate adj) */
2332  reg2a |= 0x80;
2333  reg2b = 0xac;
2334  reg2d |= 0x04;
2335  break;
2336  case 2: /* 60 hz (filter on, no framerate adj) */
2337  reg2a |= 0x80;
2338  reg2d |= 0x04;
2339  break;
2340  }
2341  i2c_w1(gspca_dev, 0x2a, reg2a);
2342  i2c_w1(gspca_dev, 0x2b, reg2b);
2343  i2c_w1(gspca_dev, 0x2d, reg2d);
2344  }
2345 }
2346 
2347 static void setjpegqual(struct gspca_dev *gspca_dev)
2348 {
2349  struct sd *sd = (struct sd *) gspca_dev;
2350 
2351  jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2352 #if USB_BUF_SZ < 64
2353 #error "No room enough in usb_buf for quantization table"
2354 #endif
2355  memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
2356  usb_control_msg(gspca_dev->dev,
2357  usb_sndctrlpipe(gspca_dev->dev, 0),
2358  0x08,
2360  0x0100, 0,
2361  gspca_dev->usb_buf, 64,
2362  500);
2363  memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
2364  usb_control_msg(gspca_dev->dev,
2365  usb_sndctrlpipe(gspca_dev->dev, 0),
2366  0x08,
2368  0x0140, 0,
2369  gspca_dev->usb_buf, 64,
2370  500);
2371 
2372  sd->reg18 ^= 0x40;
2373  reg_w1(gspca_dev, 0x18, sd->reg18);
2374 }
2375 
2376 /* JPEG quality update */
2377 /* This function is executed from a work queue. */
2378 static void qual_upd(struct work_struct *work)
2379 {
2380  struct sd *sd = container_of(work, struct sd, work);
2381  struct gspca_dev *gspca_dev = &sd->gspca_dev;
2382 
2383  /* To protect gspca_dev->usb_buf and gspca_dev->usb_err */
2384  mutex_lock(&gspca_dev->usb_lock);
2385  PDEBUG(D_STREAM, "qual_upd %d%%", sd->quality);
2386  gspca_dev->usb_err = 0;
2387  setjpegqual(gspca_dev);
2388  mutex_unlock(&gspca_dev->usb_lock);
2389 }
2390 
2391 /* -- start the camera -- */
2392 static int sd_start(struct gspca_dev *gspca_dev)
2393 {
2394  struct sd *sd = (struct sd *) gspca_dev;
2395  int i;
2396  u8 reg01, reg17;
2397  u8 reg0102[2];
2398  const u8 *sn9c1xx;
2399  const u8 (*init)[8];
2400  const u8 *reg9a;
2401  int mode;
2402  static const u8 reg9a_def[] =
2403  {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
2404  static const u8 reg9a_spec[] =
2405  {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
2406  static const u8 regd4[] = {0x60, 0x00, 0x00};
2407  static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2408  static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
2409  static const u8 CA_adcm1700[] =
2410  { 0x14, 0xec, 0x0a, 0xf6 };
2411  static const u8 CA_po2030n[] =
2412  { 0x1e, 0xe2, 0x14, 0xec };
2413  static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
2414  static const u8 CE_gc0307[] =
2415  { 0x32, 0xce, 0x2d, 0xd3 };
2416  static const u8 CE_ov76xx[] =
2417  { 0x32, 0xdd, 0x32, 0xdd };
2418  static const u8 CE_po2030n[] =
2419  { 0x14, 0xe7, 0x1e, 0xdd };
2420 
2421  /* create the JPEG header */
2422  jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2423  0x21); /* JPEG 422 */
2424 
2425  /* initialize the bridge */
2426  sn9c1xx = sn_tb[sd->sensor];
2427 
2428  /* sensor clock already enabled in sd_init */
2429  /* reg_w1(gspca_dev, 0xf1, 0x00); */
2430  reg01 = sn9c1xx[1];
2431  if (sd->flags & F_PDN_INV)
2432  reg01 ^= S_PDN_INV; /* power down inverted */
2433  reg_w1(gspca_dev, 0x01, reg01);
2434 
2435  /* configure gpio */
2436  reg0102[0] = reg01;
2437  reg0102[1] = sn9c1xx[2];
2438  if (gspca_dev->audio)
2439  reg0102[1] |= 0x04; /* keep the audio connection */
2440  reg_w(gspca_dev, 0x01, reg0102, 2);
2441  reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
2442  reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
2443  switch (sd->sensor) {
2444  case SENSOR_GC0307:
2445  case SENSOR_OV7660:
2446  case SENSOR_PO1030:
2447  case SENSOR_PO2030N:
2448  case SENSOR_SOI768:
2449  case SENSOR_SP80708:
2450  reg9a = reg9a_spec;
2451  break;
2452  default:
2453  reg9a = reg9a_def;
2454  break;
2455  }
2456  reg_w(gspca_dev, 0x9a, reg9a, 6);
2457 
2458  reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
2459 
2460  reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
2461 
2462  reg17 = sn9c1xx[0x17];
2463  switch (sd->sensor) {
2464  case SENSOR_GC0307:
2465  msleep(50); /*fixme: is it useful? */
2466  break;
2467  case SENSOR_OM6802:
2468  msleep(10);
2469  reg_w1(gspca_dev, 0x02, 0x73);
2470  reg17 |= SEN_CLK_EN;
2471  reg_w1(gspca_dev, 0x17, reg17);
2472  reg_w1(gspca_dev, 0x01, 0x22);
2473  msleep(100);
2474  reg01 = SCL_SEL_OD | S_PDN_INV;
2475  reg17 &= ~MCK_SIZE_MASK;
2476  reg17 |= 0x04; /* clock / 4 */
2477  break;
2478  }
2479  reg01 |= SYS_SEL_48M;
2480  reg_w1(gspca_dev, 0x01, reg01);
2481  reg17 |= SEN_CLK_EN;
2482  reg_w1(gspca_dev, 0x17, reg17);
2483  reg01 &= ~S_PWR_DN; /* sensor power on */
2484  reg_w1(gspca_dev, 0x01, reg01);
2485  reg01 &= ~SCL_SEL_OD; /* remove open-drain mode */
2486  reg_w1(gspca_dev, 0x01, reg01);
2487 
2488  switch (sd->sensor) {
2489  case SENSOR_HV7131R:
2490  hv7131r_probe(gspca_dev); /*fixme: is it useful? */
2491  break;
2492  case SENSOR_OM6802:
2493  msleep(10);
2494  reg_w1(gspca_dev, 0x01, reg01);
2495  i2c_w8(gspca_dev, om6802_init0[0]);
2496  i2c_w8(gspca_dev, om6802_init0[1]);
2497  msleep(15);
2498  reg_w1(gspca_dev, 0x02, 0x71);
2499  msleep(150);
2500  break;
2501  case SENSOR_SP80708:
2502  msleep(100);
2503  reg_w1(gspca_dev, 0x02, 0x62);
2504  break;
2505  }
2506 
2507  /* initialize the sensor */
2508  i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2509 
2510  reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2511  reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2512  reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2513  reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2514  reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2515  if (sd->sensor == SENSOR_ADCM1700) {
2516  reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
2517  reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
2518  } else {
2519  reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
2520  reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
2521  }
2522  reg_w1(gspca_dev, 0xc6, 0x00);
2523  reg_w1(gspca_dev, 0xc7, 0x00);
2524  if (sd->sensor == SENSOR_ADCM1700) {
2525  reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
2526  reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
2527  } else {
2528  reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
2529  reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
2530  }
2531  reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
2532  switch (sd->sensor) {
2533  case SENSOR_OM6802:
2534 /* case SENSOR_OV7648: * fixme: sometimes */
2535  break;
2536  default:
2537  reg17 |= DEF_EN;
2538  break;
2539  }
2540  reg_w1(gspca_dev, 0x17, reg17);
2541 
2542  reg_w1(gspca_dev, 0x05, 0x00); /* red */
2543  reg_w1(gspca_dev, 0x07, 0x00); /* green */
2544  reg_w1(gspca_dev, 0x06, 0x00); /* blue */
2545  reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
2546 
2547  setgamma(gspca_dev);
2548 
2549 /*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
2550  for (i = 0; i < 8; i++)
2551  reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2552  switch (sd->sensor) {
2553  case SENSOR_ADCM1700:
2554  case SENSOR_OV7660:
2555  case SENSOR_SP80708:
2556  reg_w1(gspca_dev, 0x9a, 0x05);
2557  break;
2558  case SENSOR_GC0307:
2559  case SENSOR_MT9V111:
2560  case SENSOR_MI0360B:
2561  reg_w1(gspca_dev, 0x9a, 0x07);
2562  break;
2563  case SENSOR_OV7630:
2564  case SENSOR_OV7648:
2565  reg_w1(gspca_dev, 0x9a, 0x0a);
2566  break;
2567  case SENSOR_PO2030N:
2568  case SENSOR_SOI768:
2569  reg_w1(gspca_dev, 0x9a, 0x06);
2570  break;
2571  default:
2572  reg_w1(gspca_dev, 0x9a, 0x08);
2573  break;
2574  }
2575  setsharpness(gspca_dev);
2576 
2577  reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
2578  reg_w1(gspca_dev, 0x05, 0x20); /* red */
2579  reg_w1(gspca_dev, 0x07, 0x20); /* green */
2580  reg_w1(gspca_dev, 0x06, 0x20); /* blue */
2581 
2582  init = NULL;
2583  mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
2584  reg01 |= SYS_SEL_48M | V_TX_EN;
2585  reg17 &= ~MCK_SIZE_MASK;
2586  reg17 |= 0x02; /* clock / 2 */
2587  switch (sd->sensor) {
2588  case SENSOR_ADCM1700:
2589  init = adcm1700_sensor_param1;
2590  break;
2591  case SENSOR_GC0307:
2592  init = gc0307_sensor_param1;
2593  break;
2594  case SENSOR_HV7131R:
2595  case SENSOR_MI0360:
2596  if (!mode)
2597  reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
2598  reg17 &= ~MCK_SIZE_MASK;
2599  reg17 |= 0x01; /* clock / 1 */
2600  break;
2601  case SENSOR_MI0360B:
2602  init = mi0360b_sensor_param1;
2603  break;
2604  case SENSOR_MO4000:
2605  if (mode) { /* if 320x240 */
2606  reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
2607  reg17 &= ~MCK_SIZE_MASK;
2608  reg17 |= 0x01; /* clock / 1 */
2609  }
2610  break;
2611  case SENSOR_MT9V111:
2612  init = mt9v111_sensor_param1;
2613  break;
2614  case SENSOR_OM6802:
2615  init = om6802_sensor_param1;
2616  if (!mode) { /* if 640x480 */
2617  reg17 &= ~MCK_SIZE_MASK;
2618  reg17 |= 0x04; /* clock / 4 */
2619  } else {
2620  reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
2621  reg17 &= ~MCK_SIZE_MASK;
2622  reg17 |= 0x02; /* clock / 2 */
2623  }
2624  break;
2625  case SENSOR_OV7630:
2626  init = ov7630_sensor_param1;
2627  break;
2628  case SENSOR_OV7648:
2629  init = ov7648_sensor_param1;
2630  reg17 &= ~MCK_SIZE_MASK;
2631  reg17 |= 0x01; /* clock / 1 */
2632  break;
2633  case SENSOR_OV7660:
2634  init = ov7660_sensor_param1;
2635  break;
2636  case SENSOR_PO1030:
2637  init = po1030_sensor_param1;
2638  break;
2639  case SENSOR_PO2030N:
2640  init = po2030n_sensor_param1;
2641  break;
2642  case SENSOR_SOI768:
2643  init = soi768_sensor_param1;
2644  break;
2645  case SENSOR_SP80708:
2646  init = sp80708_sensor_param1;
2647  break;
2648  }
2649 
2650  /* more sensor initialization - param1 */
2651  if (init != NULL) {
2652  i2c_w_seq(gspca_dev, init);
2653 /* init = NULL; */
2654  }
2655 
2656  reg_w(gspca_dev, 0xc0, C0, 6);
2657  switch (sd->sensor) {
2658  case SENSOR_ADCM1700:
2659  case SENSOR_GC0307:
2660  case SENSOR_SOI768:
2661  reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2662  break;
2663  case SENSOR_PO2030N:
2664  reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2665  break;
2666  default:
2667  reg_w(gspca_dev, 0xca, CA, 4);
2668  break;
2669  }
2670  switch (sd->sensor) {
2671  case SENSOR_ADCM1700:
2672  case SENSOR_OV7630:
2673  case SENSOR_OV7648:
2674  case SENSOR_OV7660:
2675  case SENSOR_SOI768:
2676  reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
2677  break;
2678  case SENSOR_GC0307:
2679  reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2680  break;
2681  case SENSOR_PO2030N:
2682  reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2683  break;
2684  default:
2685  reg_w(gspca_dev, 0xce, CE, 4);
2686  /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2687  break;
2688  }
2689 
2690  /* here change size mode 0 -> VGA; 1 -> CIF */
2691  sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2692  reg_w1(gspca_dev, 0x18, sd->reg18);
2693  setjpegqual(gspca_dev);
2694 
2695  reg_w1(gspca_dev, 0x17, reg17);
2696  reg_w1(gspca_dev, 0x01, reg01);
2697  sd->reg01 = reg01;
2698  sd->reg17 = reg17;
2699 
2700  sethvflip(gspca_dev);
2701  setbrightness(gspca_dev);
2702  setcontrast(gspca_dev);
2703  setcolors(gspca_dev);
2704  setautogain(gspca_dev);
2705  if (!(gspca_dev->ctrl_inac & ((1 << EXPOSURE) | (1 << GAIN)))) {
2706  setexposure(gspca_dev);
2707  setgain(gspca_dev);
2708  }
2709  setfreq(gspca_dev);
2710 
2711  sd->pktsz = sd->npkt = 0;
2712  sd->nchg = sd->short_mark = 0;
2714 
2715  return gspca_dev->usb_err;
2716 }
2717 
2718 static void sd_stopN(struct gspca_dev *gspca_dev)
2719 {
2720  struct sd *sd = (struct sd *) gspca_dev;
2721  static const u8 stophv7131[] =
2722  { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
2723  static const u8 stopmi0360[] =
2724  { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
2725  static const u8 stopov7648[] =
2726  { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
2727  static const u8 stopsoi768[] =
2728  { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
2729  u8 reg01;
2730  u8 reg17;
2731 
2732  reg01 = sd->reg01;
2733  reg17 = sd->reg17 & ~SEN_CLK_EN;
2734  switch (sd->sensor) {
2735  case SENSOR_ADCM1700:
2736  case SENSOR_GC0307:
2737  case SENSOR_PO2030N:
2738  case SENSOR_SP80708:
2739  reg01 |= LED;
2740  reg_w1(gspca_dev, 0x01, reg01);
2741  reg01 &= ~(LED | V_TX_EN);
2742  reg_w1(gspca_dev, 0x01, reg01);
2743 /* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
2744  break;
2745  case SENSOR_HV7131R:
2746  reg01 &= ~V_TX_EN;
2747  reg_w1(gspca_dev, 0x01, reg01);
2748  i2c_w8(gspca_dev, stophv7131);
2749  break;
2750  case SENSOR_MI0360:
2751  case SENSOR_MI0360B:
2752  reg01 &= ~V_TX_EN;
2753  reg_w1(gspca_dev, 0x01, reg01);
2754 /* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
2755  i2c_w8(gspca_dev, stopmi0360);
2756  break;
2757  case SENSOR_MT9V111:
2758  case SENSOR_OM6802:
2759  case SENSOR_PO1030:
2760  reg01 &= ~V_TX_EN;
2761  reg_w1(gspca_dev, 0x01, reg01);
2762  break;
2763  case SENSOR_OV7630:
2764  case SENSOR_OV7648:
2765  reg01 &= ~V_TX_EN;
2766  reg_w1(gspca_dev, 0x01, reg01);
2767  i2c_w8(gspca_dev, stopov7648);
2768  break;
2769  case SENSOR_OV7660:
2770  reg01 &= ~V_TX_EN;
2771  reg_w1(gspca_dev, 0x01, reg01);
2772  break;
2773  case SENSOR_SOI768:
2774  i2c_w8(gspca_dev, stopsoi768);
2775  break;
2776  }
2777 
2778  reg01 |= SCL_SEL_OD;
2779  reg_w1(gspca_dev, 0x01, reg01);
2780  reg01 |= S_PWR_DN; /* sensor power down */
2781  reg_w1(gspca_dev, 0x01, reg01);
2782  reg_w1(gspca_dev, 0x17, reg17);
2783  reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
2784  reg_w1(gspca_dev, 0x01, reg01);
2785  reg01 |= LED;
2786  reg_w1(gspca_dev, 0x01, reg01);
2787  /* Don't disable sensor clock as that disables the button on the cam */
2788  /* reg_w1(gspca_dev, 0xf1, 0x01); */
2789 }
2790 
2791 /* called on streamoff with alt==0 and on disconnect */
2792 /* the usb_lock is held at entry - restore on exit */
2793 static void sd_stop0(struct gspca_dev *gspca_dev)
2794 {
2795  struct sd *sd = (struct sd *) gspca_dev;
2796 
2797  if (sd->work_thread != NULL) {
2798  mutex_unlock(&gspca_dev->usb_lock);
2800  mutex_lock(&gspca_dev->usb_lock);
2801  sd->work_thread = NULL;
2802  }
2803 }
2804 
2805 #define WANT_REGULAR_AUTOGAIN
2806 #include "autogain_functions.h"
2807 
2808 static void do_autogain(struct gspca_dev *gspca_dev)
2809 {
2810  struct sd *sd = (struct sd *) gspca_dev;
2811  int delta;
2812  int expotimes;
2813  u8 luma_mean = 130;
2814  u8 luma_delta = 20;
2815 
2816  /* Thanks S., without your advice, autobright should not work :) */
2817  if (sd->ag_cnt < 0)
2818  return;
2819  if (--sd->ag_cnt >= 0)
2820  return;
2821  sd->ag_cnt = AG_CNT_START;
2822 
2823  delta = atomic_read(&sd->avg_lum);
2824  PDEBUG(D_FRAM, "mean lum %d", delta);
2825 
2826  if (sd->sensor == SENSOR_PO2030N) {
2827  auto_gain_n_exposure(gspca_dev, delta, luma_mean, luma_delta,
2828  15, 1024);
2829  return;
2830  }
2831 
2832  if (delta < luma_mean - luma_delta ||
2833  delta > luma_mean + luma_delta) {
2834  switch (sd->sensor) {
2835  case SENSOR_GC0307:
2836  expotimes = sd->exposure;
2837  expotimes += (luma_mean - delta) >> 6;
2838  if (expotimes < 0)
2839  expotimes = 0;
2840  sd->exposure = expo_adjust(gspca_dev,
2841  (unsigned int) expotimes);
2842  break;
2843  case SENSOR_HV7131R:
2844  expotimes = sd->exposure >> 8;
2845  expotimes += (luma_mean - delta) >> 4;
2846  if (expotimes < 0)
2847  expotimes = 0;
2848  sd->exposure = expo_adjust(gspca_dev,
2849  (unsigned int) (expotimes << 8));
2850  break;
2851  case SENSOR_OM6802:
2852  case SENSOR_MT9V111:
2853  expotimes = sd->exposure;
2854  expotimes += (luma_mean - delta) >> 2;
2855  if (expotimes < 0)
2856  expotimes = 0;
2857  sd->exposure = expo_adjust(gspca_dev,
2858  (unsigned int) expotimes);
2859  setredblue(gspca_dev);
2860  break;
2861  default:
2862 /* case SENSOR_MO4000: */
2863 /* case SENSOR_MI0360: */
2864 /* case SENSOR_MI0360B: */
2865  expotimes = sd->exposure;
2866  expotimes += (luma_mean - delta) >> 6;
2867  if (expotimes < 0)
2868  expotimes = 0;
2869  sd->exposure = expo_adjust(gspca_dev,
2870  (unsigned int) expotimes);
2871  setredblue(gspca_dev);
2872  break;
2873  }
2874  }
2875 }
2876 
2877 /* set the average luminosity from an isoc marker */
2878 static void set_lum(struct sd *sd,
2879  u8 *data)
2880 {
2881  int avg_lum;
2882 
2883  /* w0 w1 w2
2884  * w3 w4 w5
2885  * w6 w7 w8
2886  */
2887  avg_lum = (data[27] << 8) + data[28] /* w3 */
2888 
2889  + (data[31] << 8) + data[32] /* w5 */
2890 
2891  + (data[23] << 8) + data[24] /* w1 */
2892 
2893  + (data[35] << 8) + data[36] /* w7 */
2894 
2895  + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */
2896  avg_lum >>= 10;
2897  atomic_set(&sd->avg_lum, avg_lum);
2898 }
2899 
2900 /* scan the URB packets */
2901 /* This function is run at interrupt level. */
2902 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
2903  u8 *data, /* isoc packet */
2904  int len) /* iso packet length */
2905 {
2906  struct sd *sd = (struct sd *) gspca_dev;
2907  int i, new_qual;
2908 
2909  /*
2910  * A frame ends on the marker
2911  * ff ff 00 c4 c4 96 ..
2912  * which is 62 bytes long and is followed by various information
2913  * including statuses and luminosity.
2914  *
2915  * A marker may be splitted on two packets.
2916  *
2917  * The 6th byte of a marker contains the bits:
2918  * 0x08: USB full
2919  * 0xc0: frame sequence
2920  * When the bit 'USB full' is set, the frame must be discarded;
2921  * this is also the case when the 2 bytes before the marker are
2922  * not the JPEG end of frame ('ff d9').
2923  */
2924 
2925  /* count the packets and their size */
2926  sd->npkt++;
2927  sd->pktsz += len;
2928 
2929 /*fixme: assumption about the following code:
2930  * - there can be only one marker in a packet
2931  */
2932 
2933  /* skip the remaining bytes of a short marker */
2934  i = sd->short_mark;
2935  if (i != 0) {
2936  sd->short_mark = 0;
2937  if (i < 0 /* if 'ff' at end of previous packet */
2938  && data[0] == 0xff
2939  && data[1] == 0x00)
2940  goto marker_found;
2941  if (data[0] == 0xff && data[1] == 0xff) {
2942  i = 0;
2943  goto marker_found;
2944  }
2945  len -= i;
2946  if (len <= 0)
2947  return;
2948  data += i;
2949  }
2950 
2951  /* search backwards if there is a marker in the packet */
2952  for (i = len - 1; --i >= 0; ) {
2953  if (data[i] != 0xff) {
2954  i--;
2955  continue;
2956  }
2957  if (data[i + 1] == 0xff) {
2958 
2959  /* (there may be 'ff ff' inside a marker) */
2960  if (i + 2 >= len || data[i + 2] == 0x00)
2961  goto marker_found;
2962  }
2963  }
2964 
2965  /* no marker found */
2966  /* add the JPEG header if first fragment */
2967  if (data[len - 1] == 0xff)
2968  sd->short_mark = -1;
2969  if (gspca_dev->last_packet_type == LAST_PACKET)
2970  gspca_frame_add(gspca_dev, FIRST_PACKET,
2971  sd->jpeg_hdr, JPEG_HDR_SZ);
2972  gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2973  return;
2974 
2975  /* marker found */
2976  /* if some error, discard the frame and decrease the quality */
2977 marker_found:
2978  new_qual = 0;
2979  if (i > 2) {
2980  if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2981  gspca_dev->last_packet_type = DISCARD_PACKET;
2982  new_qual = -3;
2983  }
2984  } else if (i + 6 < len) {
2985  if (data[i + 6] & 0x08) {
2986  gspca_dev->last_packet_type = DISCARD_PACKET;
2987  new_qual = -5;
2988  }
2989  }
2990 
2991  gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2992 
2993  /* compute the filling rate and a new JPEG quality */
2994  if (new_qual == 0) {
2995  int r;
2996 
2997  r = (sd->pktsz * 100) /
2998  (sd->npkt *
2999  gspca_dev->urb[0]->iso_frame_desc[0].length);
3000  if (r >= 85)
3001  new_qual = -3;
3002  else if (r < 75)
3003  new_qual = 2;
3004  }
3005  if (new_qual != 0) {
3006  sd->nchg += new_qual;
3007  if (sd->nchg < -6 || sd->nchg >= 12) {
3008  sd->nchg = 0;
3009  new_qual += sd->quality;
3010  if (new_qual < QUALITY_MIN)
3011  new_qual = QUALITY_MIN;
3012  else if (new_qual > QUALITY_MAX)
3013  new_qual = QUALITY_MAX;
3014  if (new_qual != sd->quality) {
3015  sd->quality = new_qual;
3016  queue_work(sd->work_thread, &sd->work);
3017  }
3018  }
3019  } else {
3020  sd->nchg = 0;
3021  }
3022  sd->pktsz = sd->npkt = 0;
3023 
3024  /* if the marker is smaller than 62 bytes,
3025  * memorize the number of bytes to skip in the next packet */
3026  if (i + 62 > len) { /* no more usable data */
3027  sd->short_mark = i + 62 - len;
3028  return;
3029  }
3030  if (sd->ag_cnt >= 0)
3031  set_lum(sd, data + i);
3032 
3033  /* if more data, start a new frame */
3034  i += 62;
3035  if (i < len) {
3036  data += i;
3037  len -= i;
3038  gspca_frame_add(gspca_dev, FIRST_PACKET,
3039  sd->jpeg_hdr, JPEG_HDR_SZ);
3040  gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
3041  }
3042 }
3043 
3044 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
3045 {
3046  struct sd *sd = (struct sd *) gspca_dev;
3047 
3048  sd->ctrls[AUTOGAIN].val = val;
3049  if (val)
3050  gspca_dev->ctrl_inac |= (1 << EXPOSURE) | (1 << GAIN);
3051  else
3052  gspca_dev->ctrl_inac &= ~(1 << EXPOSURE) & ~(1 << GAIN);
3053  if (gspca_dev->streaming)
3054  setautogain(gspca_dev);
3055  return gspca_dev->usb_err;
3056 }
3057 
3058 static int sd_querymenu(struct gspca_dev *gspca_dev,
3059  struct v4l2_querymenu *menu)
3060 {
3061  switch (menu->id) {
3063  switch (menu->index) {
3064  case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
3065  strcpy((char *) menu->name, "NoFliker");
3066  return 0;
3067  case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
3068  strcpy((char *) menu->name, "50 Hz");
3069  return 0;
3070  case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
3071  strcpy((char *) menu->name, "60 Hz");
3072  return 0;
3073  }
3074  break;
3075  }
3076  return -EINVAL;
3077 }
3078 
3079 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3080 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
3081  u8 *data, /* interrupt packet data */
3082  int len) /* interrupt packet length */
3083 {
3084  int ret = -EINVAL;
3085 
3086  if (len == 1 && data[0] == 1) {
3087  input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
3088  input_sync(gspca_dev->input_dev);
3089  input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
3090  input_sync(gspca_dev->input_dev);
3091  ret = 0;
3092  }
3093 
3094  return ret;
3095 }
3096 #endif
3097 
3098 /* sub-driver description */
3099 static const struct sd_desc sd_desc = {
3100  .name = MODULE_NAME,
3101  .ctrls = sd_ctrls,
3102  .nctrls = NCTRLS,
3103  .config = sd_config,
3104  .init = sd_init,
3105  .start = sd_start,
3106  .stopN = sd_stopN,
3107  .stop0 = sd_stop0,
3108  .pkt_scan = sd_pkt_scan,
3109  .dq_callback = do_autogain,
3110  .querymenu = sd_querymenu,
3111 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
3112  .int_pkt_scan = sd_int_pkt_scan,
3113 #endif
3114 };
3115 
3116 /* -- module initialisation -- */
3117 #define BS(bridge, sensor) \
3118  .driver_info = (BRIDGE_ ## bridge << 16) \
3119  | (SENSOR_ ## sensor << 8)
3120 #define BSF(bridge, sensor, flags) \
3121  .driver_info = (BRIDGE_ ## bridge << 16) \
3122  | (SENSOR_ ## sensor << 8) \
3123  | (flags)
3124 static const struct usb_device_id device_table[] = {
3125  {USB_DEVICE(0x0458, 0x7025), BSF(SN9C120, MI0360B, F_PDN_INV)},
3126  {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
3127  {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
3128  {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
3129  {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
3130  {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
3131  {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
3132  {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
3133  {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
3134 /* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
3135  {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
3136 /* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
3137 /* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
3138  {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
3139 /* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
3140  {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
3141  /* or MT9V111 */
3142 /* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3143 /* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3144 /* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
3145  {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
3146  {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3147 /* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3148 /* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
3149 /* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
3150  {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3151  {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3152  {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3153  {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
3154  {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
3155 /* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3156  {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
3157  {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
3158  {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
3159  {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
3160 /* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3161 /* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3162 /* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3163  {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
3164 /*bw600.inf:*/
3165  {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
3166  {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
3167  {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3168  {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3169 /* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
3170  {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
3171  /* or MT9V111 / MI0360B */
3172 /* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3173  {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3174  {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
3175  {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
3176  {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3177  {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
3178  {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
3179  /* or GC0305 / GC0307 */
3180  {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
3181  {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
3182  {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
3183 /* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/
3184  {}
3185 };
3186 MODULE_DEVICE_TABLE(usb, device_table);
3187 
3188 /* -- device connect -- */
3189 static int sd_probe(struct usb_interface *intf,
3190  const struct usb_device_id *id)
3191 {
3192  return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3193  THIS_MODULE);
3194 }
3195 
3196 static struct usb_driver sd_driver = {
3197  .name = MODULE_NAME,
3198  .id_table = device_table,
3199  .probe = sd_probe,
3200  .disconnect = gspca_disconnect,
3201 #ifdef CONFIG_PM
3202  .suspend = gspca_suspend,
3203  .resume = gspca_resume,
3204  .reset_resume = gspca_resume,
3205 #endif
3206 };
3207 
3208 module_usb_driver(sd_driver);