2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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
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.
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
22 #define MODULE_NAME "sonixj"
25 #define QUANT_VAL 4 /* quantization table */
28 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32 MODULE_LICENSE("GPL");
34 /* specific webcam descriptor */
36 struct gspca_dev gspca_dev; /* !! must be the first item */
48 u8 vflip; /* ov7630 only */
49 u8 infrared; /* mt9v111 only */
52 #define AG_CNT_START 13
55 #define BRIDGE_SN9C102P 0
56 #define BRIDGE_SN9C105 1
57 #define BRIDGE_SN9C110 2
58 #define BRIDGE_SN9C120 3
59 #define BRIDGE_SN9C325 4
60 u8 sensor; /* Type of image sensor chip */
61 #define SENSOR_HV7131R 0
62 #define SENSOR_MI0360 1
63 #define SENSOR_MO4000 2
64 #define SENSOR_MT9V111 3
65 #define SENSOR_OM6802 4
66 #define SENSOR_OV7630 5
67 #define SENSOR_OV7648 6
68 #define SENSOR_OV7660 7
69 #define SENSOR_SP80708 8
73 /* V4L2 controls supported by the driver */
74 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
75 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
76 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
80 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
81 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
82 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
93 static struct ctrl sd_ctrls[] = {
96 .id = V4L2_CID_BRIGHTNESS,
97 .type = V4L2_CTRL_TYPE_INTEGER,
100 #define BRIGHTNESS_MAX 0xffff
101 .maximum = BRIGHTNESS_MAX,
103 #define BRIGHTNESS_DEF 0x8000
104 .default_value = BRIGHTNESS_DEF,
106 .set = sd_setbrightness,
107 .get = sd_getbrightness,
111 .id = V4L2_CID_CONTRAST,
112 .type = V4L2_CTRL_TYPE_INTEGER,
115 #define CONTRAST_MAX 127
116 .maximum = CONTRAST_MAX,
118 #define CONTRAST_DEF 63
119 .default_value = CONTRAST_DEF,
121 .set = sd_setcontrast,
122 .get = sd_getcontrast,
126 .id = V4L2_CID_SATURATION,
127 .type = V4L2_CTRL_TYPE_INTEGER,
133 .default_value = COLOR_DEF,
140 .id = V4L2_CID_BLUE_BALANCE,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Blue Balance",
146 #define BLUE_BALANCE_DEF 32
147 .default_value = BLUE_BALANCE_DEF,
149 .set = sd_setblue_balance,
150 .get = sd_getblue_balance,
154 .id = V4L2_CID_RED_BALANCE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Red Balance",
160 #define RED_BALANCE_DEF 32
161 .default_value = RED_BALANCE_DEF,
163 .set = sd_setred_balance,
164 .get = sd_getred_balance,
168 .id = V4L2_CID_GAMMA,
169 .type = V4L2_CTRL_TYPE_INTEGER,
175 .default_value = GAMMA_DEF,
180 #define AUTOGAIN_IDX 5
183 .id = V4L2_CID_AUTOGAIN,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
189 #define AUTOGAIN_DEF 1
190 .default_value = AUTOGAIN_DEF,
192 .set = sd_setautogain,
193 .get = sd_getautogain,
199 .id = V4L2_CID_VFLIP,
200 .type = V4L2_CTRL_TYPE_BOOLEAN,
206 .default_value = VFLIP_DEF,
212 #define INFRARED_IDX 7
215 .id = V4L2_CID_INFRARED,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
221 #define INFRARED_DEF 0
222 .default_value = INFRARED_DEF,
224 .set = sd_setinfrared,
225 .get = sd_getinfrared,
229 /* table of the disabled controls */
230 static __u32 ctrl_dis[] = {
231 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
232 /* SENSOR_HV7131R 0 */
233 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
234 /* SENSOR_MI0360 1 */
235 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
236 /* SENSOR_MO4000 2 */
238 /* SENSOR_MT9V111 3 */
239 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
240 /* SENSOR_OM6802 4 */
241 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
242 /* SENSOR_OV7630 5 */
243 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
244 /* SENSOR_OV7648 6 */
245 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
246 /* SENSOR_OV7660 7 */
247 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
248 /* SENSOR_SP80708 8 */
251 static const struct v4l2_pix_format vga_mode[] = {
252 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
254 .sizeimage = 160 * 120 * 4 / 8 + 590,
255 .colorspace = V4L2_COLORSPACE_JPEG,
257 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
259 .sizeimage = 320 * 240 * 3 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
262 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
264 .sizeimage = 640 * 480 * 3 / 8 + 590,
265 .colorspace = V4L2_COLORSPACE_JPEG,
269 /*Data from sn9c102p+hv7131r */
270 static const u8 sn_hv7131[0x1c] = {
271 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
272 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
273 /* reg8 reg9 rega regb regc regd rege regf */
274 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
275 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
276 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
277 /* reg18 reg19 reg1a reg1b */
278 0x0a, 0x00, 0x00, 0x00
281 static const u8 sn_mi0360[0x1c] = {
282 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
283 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
284 /* reg8 reg9 rega regb regc regd rege regf */
285 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
286 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
287 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
288 /* reg18 reg19 reg1a reg1b */
289 0x06, 0x00, 0x00, 0x00
292 static const u8 sn_mo4000[0x1c] = {
293 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
294 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
295 /* reg8 reg9 rega regb regc regd rege regf */
296 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
298 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
299 /* reg18 reg19 reg1a reg1b */
300 0x08, 0x00, 0x00, 0x00
303 static const u8 sn_mt9v111[0x1c] = {
304 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
306 /* reg8 reg9 rega regb regc regd rege regf */
307 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
308 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
310 /* reg18 reg19 reg1a reg1b */
311 0x06, 0x00, 0x00, 0x00
314 static const u8 sn_om6802[0x1c] = {
315 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
317 /* reg8 reg9 rega regb regc regd rege regf */
318 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
321 /* reg18 reg19 reg1a reg1b */
322 0x05, 0x00, 0x00, 0x00
325 static const u8 sn_ov7630[0x1c] = {
326 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
327 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
328 /* reg8 reg9 rega regb regc regd rege regf */
329 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
330 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
331 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
332 /* reg18 reg19 reg1a reg1b */
333 0x0b, 0x00, 0x00, 0x00
336 static const u8 sn_ov7648[0x1c] = {
337 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
338 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
339 /* reg8 reg9 rega regb regc regd rege regf */
340 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
341 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
342 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
343 /* reg18 reg19 reg1a reg1b */
344 0x0b, 0x00, 0x00, 0x00
347 static const u8 sn_ov7660[0x1c] = {
348 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
350 /* reg8 reg9 rega regb regc regd rege regf */
351 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
352 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
353 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
354 /* reg18 reg19 reg1a reg1b */
355 0x07, 0x00, 0x00, 0x00
358 static const u8 sn_sp80708[0x1c] = {
359 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
361 /* reg8 reg9 rega regb regc regd rege regf */
362 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
363 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
365 /* reg18 reg19 reg1a reg1b */
366 0x07, 0x00, 0x00, 0x00
369 /* sequence specific to the sensors - !! index = SENSOR_xxx */
370 static const u8 *sn_tb[] = {
382 /* default gamma table */
383 static const u8 gamma_def[17] = {
384 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
385 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
387 /* gamma for sensors HV7131R and MT9V111 */
388 static const u8 gamma_spec_1[17] = {
389 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
390 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
392 /* gamma for sensor SP80708 */
393 static const u8 gamma_spec_2[17] = {
394 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
395 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
398 /* color matrix and offsets */
399 static const u8 reg84[] = {
400 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
401 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
402 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
403 0x00, 0x00, 0x00 /* YUV offsets */
405 static const u8 hv7131r_sensor_init[][8] = {
406 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
407 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
408 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
409 /* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
410 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
411 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
412 /* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
414 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
416 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
417 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
418 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
419 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
420 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
421 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
423 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
429 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
436 static const u8 mi0360_sensor_init[][8] = {
437 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
438 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
439 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
441 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
442 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
443 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
444 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
449 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
454 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
456 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
459 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
460 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
462 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
463 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
464 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
465 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
466 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
469 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
471 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
472 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
473 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
474 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
475 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
477 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
478 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
479 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
480 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
482 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
483 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
484 /* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
485 /* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
486 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
487 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
490 static const u8 mo4000_sensor_init[][8] = {
491 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
502 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
503 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
504 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
505 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
506 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
508 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
509 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
510 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
513 static const u8 mt9v111_sensor_init[][8] = {
514 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
516 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
518 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
519 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
520 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
521 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
522 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
523 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
524 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
525 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
526 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
527 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
528 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
529 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
530 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
531 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
533 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
534 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */
536 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
537 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
539 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
540 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
541 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
542 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
545 static const u8 om6802_sensor_init[][8] = {
546 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
547 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
548 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
549 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
550 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
551 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
552 /* white balance & auto-exposure */
553 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
555 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
556 * max AGC value in AE */
557 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
559 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
560 * preset brightness */
561 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
563 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
565 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
566 /* luminance mode (0x4f = AE) */
567 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
569 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
571 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
573 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
574 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
575 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
576 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
579 static const u8 ov7630_sensor_init[][8] = {
580 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
581 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
582 /* win: delay 20ms */
583 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
584 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
585 /* win: delay 20ms */
586 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
587 /* win: i2c_r from 00 to 80 */
588 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
589 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
590 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
591 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
592 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
593 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
594 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
595 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
596 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
597 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
598 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
599 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
600 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
601 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
602 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
603 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
605 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
606 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
607 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
608 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
609 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
610 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
611 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
612 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
613 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
615 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
616 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
617 /*fixme: + 0x12, 0x04*/
618 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
620 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
621 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
622 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
624 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
628 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
629 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
633 static const u8 ov7648_sensor_init[][8] = {
634 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
636 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
637 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
638 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
639 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
640 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
641 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
642 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
643 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
644 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
645 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
646 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
647 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
648 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
649 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
650 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
651 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
652 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
653 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
654 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
656 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
657 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
658 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
659 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
661 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
662 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
663 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
664 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
665 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
666 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
667 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
669 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
670 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
671 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
672 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
673 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
674 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
679 static const u8 ov7660_sensor_init[][8] = {
680 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
682 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
683 /* Outformat = rawRGB */
684 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
685 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
686 /* GAIN BLUE RED VREF */
687 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
688 /* COM 1 BAVE GEAVE AECHH */
689 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
690 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
691 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
692 /* AECH CLKRC COM7 COM8 */
693 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
694 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
695 /* HSTART HSTOP VSTRT VSTOP */
696 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
697 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
698 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
699 /* BOS GBOS GROS ROS (BGGR offset) */
700 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
701 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
702 /* AEW AEB VPT BBIAS */
703 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
704 /* GbBIAS RSVD EXHCH EXHCL */
705 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
706 /* RBIAS ADVFL ASDVFH YAVE */
707 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
708 /* HSYST HSYEN HREF */
709 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
710 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
711 /* ADC ACOM OFON TSLB */
712 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
713 /* COM11 COM12 COM13 COM14 */
714 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
715 /* EDGE COM15 COM16 COM17 */
716 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
717 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
718 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
719 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
720 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
721 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
722 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
723 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
724 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
725 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
726 /* LCC1 LCC2 LCC3 LCC4 */
727 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
728 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
729 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
730 /* band gap reference [0:3] DBLV */
731 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
732 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
733 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
734 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
735 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
736 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
737 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
738 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
739 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
740 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
741 /****** (some exchanges in the win trace) ******/
742 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
743 /* bits[3..0]reserved */
744 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
745 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
746 /* VREF vertical frame ctrl */
747 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
748 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
749 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
750 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
751 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
752 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
753 /****** (some exchanges in the win trace) ******/
754 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
755 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
756 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
757 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
758 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
759 /****** (some exchanges in the win trace) ******/
760 /******!! startsensor KO if changed !!****/
761 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
762 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
763 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
764 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
768 static const u8 sp80708_sensor_init[][8] = {
769 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
770 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
771 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
776 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
777 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
778 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
779 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
847 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
851 static const u8 qtable4[] = {
852 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
853 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
854 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
855 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
856 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
857 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
858 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
859 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
860 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
861 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
862 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
863 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
864 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
865 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
866 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
867 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
870 /* read <len> bytes to gspca_dev->usb_buf */
871 static void reg_r(struct gspca_dev *gspca_dev,
875 if (len > USB_BUF_SZ) {
876 err("reg_r: buffer overflow");
880 usb_control_msg(gspca_dev->dev,
881 usb_rcvctrlpipe(gspca_dev->dev, 0),
883 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
885 gspca_dev->usb_buf, len,
887 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
890 static void reg_w1(struct gspca_dev *gspca_dev,
894 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
895 gspca_dev->usb_buf[0] = data;
896 usb_control_msg(gspca_dev->dev,
897 usb_sndctrlpipe(gspca_dev->dev, 0),
899 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
902 gspca_dev->usb_buf, 1,
905 static void reg_w(struct gspca_dev *gspca_dev,
910 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
911 value, buffer[0], buffer[1]);
913 if (len > USB_BUF_SZ) {
914 err("reg_w: buffer overflow");
918 memcpy(gspca_dev->usb_buf, buffer, len);
919 usb_control_msg(gspca_dev->dev,
920 usb_sndctrlpipe(gspca_dev->dev, 0),
922 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
924 gspca_dev->usb_buf, len,
928 /* I2C write 1 byte */
929 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
931 struct sd *sd = (struct sd *) gspca_dev;
933 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
934 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
935 gspca_dev->usb_buf[1] = sd->i2c_base;
936 gspca_dev->usb_buf[2] = reg;
937 gspca_dev->usb_buf[3] = val;
938 gspca_dev->usb_buf[4] = 0;
939 gspca_dev->usb_buf[5] = 0;
940 gspca_dev->usb_buf[6] = 0;
941 gspca_dev->usb_buf[7] = 0x10;
942 usb_control_msg(gspca_dev->dev,
943 usb_sndctrlpipe(gspca_dev->dev, 0),
945 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
946 0x08, /* value = i2c */
948 gspca_dev->usb_buf, 8,
952 /* I2C write 8 bytes */
953 static void i2c_w8(struct gspca_dev *gspca_dev,
956 memcpy(gspca_dev->usb_buf, buffer, 8);
957 usb_control_msg(gspca_dev->dev,
958 usb_sndctrlpipe(gspca_dev->dev, 0),
960 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
961 0x08, 0, /* value, index */
962 gspca_dev->usb_buf, 8,
967 /* read 5 bytes in gspca_dev->usb_buf */
968 static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
970 struct sd *sd = (struct sd *) gspca_dev;
973 mode[0] = 0x81 | 0x10;
974 mode[1] = sd->i2c_base;
981 i2c_w8(gspca_dev, mode);
983 mode[0] = 0x81 | (5 << 4) | 0x02;
985 i2c_w8(gspca_dev, mode);
987 reg_r(gspca_dev, 0x0a, 5);
990 static int hv7131r_probe(struct gspca_dev *gspca_dev)
992 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
994 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
996 i2c_r5(gspca_dev, 0); /* read sensor id */
997 if (gspca_dev->usb_buf[0] == 0x02
998 && gspca_dev->usb_buf[1] == 0x09
999 && gspca_dev->usb_buf[2] == 0x01
1000 && gspca_dev->usb_buf[3] == 0x00
1001 && gspca_dev->usb_buf[4] == 0x00) {
1002 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
1005 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
1006 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1007 gspca_dev->usb_buf[2]);
1008 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1012 static int mi0360_probe(struct gspca_dev *gspca_dev)
1016 static const u8 probe_tb[][4][8] = {
1018 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1019 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1020 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1021 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1024 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1025 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1026 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1031 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1032 reg_w1(gspca_dev, 0x17, 0x62);
1033 reg_w1(gspca_dev, 0x01, 0x08);
1034 for (j = 0; j < 3; j++)
1035 i2c_w8(gspca_dev, probe_tb[i][j]);
1037 reg_r(gspca_dev, 0x0a, 5);
1038 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1039 if (probe_tb[i][3][0] != 0)
1040 i2c_w8(gspca_dev, probe_tb[i][3]);
1041 reg_w1(gspca_dev, 0x01, 0x29);
1042 reg_w1(gspca_dev, 0x17, 0x42);
1048 PDEBUG(D_PROBE, "Sensor mt9v111");
1049 return SENSOR_MT9V111;
1051 PDEBUG(D_PROBE, "Sensor mi0360");
1052 return SENSOR_MI0360;
1054 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1055 return SENSOR_MI0360;
1058 static int configure_gpio(struct gspca_dev *gspca_dev,
1061 struct sd *sd = (struct sd *) gspca_dev;
1063 static const u8 reg9a_def[] =
1064 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
1065 static const u8 reg9a_sn9c325[] =
1066 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
1067 static const u8 regd4[] = {0x60, 0x00, 0x00};
1069 reg_w1(gspca_dev, 0xf1, 0x00);
1070 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1072 /* configure gpio */
1073 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1074 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1075 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
1076 switch (sd->bridge) {
1077 case BRIDGE_SN9C325:
1078 reg9a = reg9a_sn9c325;
1084 reg_w(gspca_dev, 0x9a, reg9a, 6);
1086 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
1088 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1090 switch (sd->sensor) {
1091 case SENSOR_MT9V111:
1092 reg_w1(gspca_dev, 0x01, 0x61);
1093 reg_w1(gspca_dev, 0x17, 0x61);
1094 reg_w1(gspca_dev, 0x01, 0x60);
1095 reg_w1(gspca_dev, 0x01, 0x40);
1098 reg_w1(gspca_dev, 0x02, 0x71);
1099 reg_w1(gspca_dev, 0x01, 0x42);
1100 reg_w1(gspca_dev, 0x17, 0x64);
1101 reg_w1(gspca_dev, 0x01, 0x42);
1103 /*jfm: from win trace */
1105 reg_w1(gspca_dev, 0x01, 0x61);
1106 reg_w1(gspca_dev, 0x17, 0xe2);
1107 reg_w1(gspca_dev, 0x01, 0x60);
1108 reg_w1(gspca_dev, 0x01, 0x40);
1111 reg_w1(gspca_dev, 0x01, 0x63);
1112 reg_w1(gspca_dev, 0x17, 0x20);
1113 reg_w1(gspca_dev, 0x01, 0x42);
1115 /*jfm: from win trace */
1117 if (sd->bridge == BRIDGE_SN9C120) {
1118 reg_w1(gspca_dev, 0x01, 0x61);
1119 reg_w1(gspca_dev, 0x17, 0x20);
1120 reg_w1(gspca_dev, 0x01, 0x60);
1121 reg_w1(gspca_dev, 0x01, 0x40);
1125 case SENSOR_SP80708:
1126 reg_w1(gspca_dev, 0x01, 0x63);
1127 reg_w1(gspca_dev, 0x17, 0x20);
1128 reg_w1(gspca_dev, 0x01, 0x62);
1129 reg_w1(gspca_dev, 0x01, 0x42);
1131 reg_w1(gspca_dev, 0x02, 0x62);
1134 reg_w1(gspca_dev, 0x01, 0x43);
1135 reg_w1(gspca_dev, 0x17, 0x61);
1136 reg_w1(gspca_dev, 0x01, 0x42);
1137 if (sd->sensor == SENSOR_HV7131R) {
1138 if (hv7131r_probe(gspca_dev) < 0)
1146 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1149 static const u8 SetSensorClk[] = /* 0x08 Mclk */
1150 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1152 while (hv7131r_sensor_init[i][0]) {
1153 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1156 i2c_w8(gspca_dev, SetSensorClk);
1159 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1163 while (mi0360_sensor_init[i][0]) {
1164 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1169 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1173 while (mo4000_sensor_init[i][0]) {
1174 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1179 static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1183 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1186 while (mt9v111_sensor_init[i][0]) {
1187 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1192 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1196 while (om6802_sensor_init[i][0]) {
1197 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1202 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1206 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1208 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
1211 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1213 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1216 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1218 /*jfm:win i2c_r from 00 to 80*/
1220 while (ov7630_sensor_init[i][0]) {
1221 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1226 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1230 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1232 /* win: dble reset */
1233 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1236 /* win: i2c reg read 00..7f */
1237 while (ov7648_sensor_init[i][0]) {
1238 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1243 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1247 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1250 while (ov7660_sensor_init[i][0]) {
1251 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1256 static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1260 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1263 while (sp80708_sensor_init[i][0]) {
1264 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1269 /* this function is called at probe time */
1270 static int sd_config(struct gspca_dev *gspca_dev,
1271 const struct usb_device_id *id)
1273 struct sd *sd = (struct sd *) gspca_dev;
1276 cam = &gspca_dev->cam;
1277 cam->cam_mode = vga_mode;
1278 cam->nmodes = ARRAY_SIZE(vga_mode);
1280 sd->bridge = id->driver_info >> 16;
1281 sd->sensor = id->driver_info >> 8;
1282 sd->i2c_base = id->driver_info;
1284 sd->brightness = BRIGHTNESS_DEF;
1285 sd->contrast = CONTRAST_DEF;
1286 sd->colors = COLOR_DEF;
1287 sd->blue = BLUE_BALANCE_DEF;
1288 sd->red = RED_BALANCE_DEF;
1289 sd->gamma = GAMMA_DEF;
1290 sd->autogain = AUTOGAIN_DEF;
1292 sd->vflip = VFLIP_DEF;
1293 sd->infrared = INFRARED_DEF;
1295 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1299 /* this function is called at probe and resume time */
1300 static int sd_init(struct gspca_dev *gspca_dev)
1302 struct sd *sd = (struct sd *) gspca_dev;
1303 u8 regGpio[] = { 0x29, 0x74 };
1306 /* setup a selector by bridge */
1307 reg_w1(gspca_dev, 0xf1, 0x01);
1308 reg_r(gspca_dev, 0x00, 1);
1309 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1310 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1311 regF1 = gspca_dev->usb_buf[0];
1312 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1313 switch (sd->bridge) {
1314 case BRIDGE_SN9C102P:
1317 reg_w1(gspca_dev, 0x02, regGpio[1]);
1319 case BRIDGE_SN9C105:
1322 if (sd->sensor == SENSOR_MI0360) {
1323 sd->sensor = mi0360_probe(gspca_dev);
1324 if (sd->sensor == SENSOR_MT9V111)
1325 sd->i2c_base = 0x5c;
1327 reg_w(gspca_dev, 0x01, regGpio, 2);
1329 case BRIDGE_SN9C120:
1332 if (sd->sensor == SENSOR_MI0360) {
1333 sd->sensor = mi0360_probe(gspca_dev);
1334 if (sd->sensor == SENSOR_MT9V111)
1335 sd->i2c_base = 0x5c;
1338 reg_w(gspca_dev, 0x01, regGpio, 2);
1341 /* case BRIDGE_SN9C110: */
1342 /* case BRIDGE_SN9C325: */
1345 reg_w1(gspca_dev, 0x02, 0x62);
1349 reg_w1(gspca_dev, 0xf1, 0x01);
1354 static u32 setexposure(struct gspca_dev *gspca_dev,
1357 struct sd *sd = (struct sd *) gspca_dev;
1359 switch (sd->sensor) {
1360 case SENSOR_HV7131R: {
1362 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1364 Expodoit[3] = expo >> 16;
1365 Expodoit[4] = expo >> 8;
1367 i2c_w8(gspca_dev, Expodoit);
1370 case SENSOR_MI0360: {
1371 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1372 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1373 static const u8 doit[] = /* update sensor */
1374 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1375 static const u8 sensorgo[] = /* sensor on */
1376 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1380 else if (expo < 0x0001)
1382 expoMi[3] = expo >> 8;
1384 i2c_w8(gspca_dev, expoMi);
1385 i2c_w8(gspca_dev, doit);
1386 i2c_w8(gspca_dev, sensorgo);
1389 case SENSOR_MO4000: {
1391 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1393 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1394 static const u8 gainMo[] =
1395 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1399 else if (expo < 0x0001)
1401 expoMof[3] = (expo & 0x03fc) >> 2;
1402 i2c_w8(gspca_dev, expoMof);
1403 expoMo10[3] = ((expo & 0x1c00) >> 10)
1404 | ((expo & 0x0003) << 4);
1405 i2c_w8(gspca_dev, expoMo10);
1406 i2c_w8(gspca_dev, gainMo);
1407 PDEBUG(D_FRAM, "set exposure %d",
1408 ((expoMo10[3] & 0x07) << 10)
1410 | ((expoMo10[3] & 0x30) >> 4));
1413 case SENSOR_MT9V111: {
1415 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1419 else if (expo < 0x0040)
1421 expo_c1[3] = expo >> 8;
1423 i2c_w8(gspca_dev, expo_c1);
1426 case SENSOR_OM6802: {
1428 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1434 gainOm[3] = expo >> 2;
1435 i2c_w8(gspca_dev, gainOm);
1436 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1437 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1444 static void setbrightness(struct gspca_dev *gspca_dev)
1446 struct sd *sd = (struct sd *) gspca_dev;
1450 k2 = ((int) sd->brightness - 0x8000) >> 10;
1451 switch (sd->sensor) {
1452 case SENSOR_HV7131R:
1453 expo = sd->brightness << 4;
1454 if (expo > 0x002dc6c0)
1456 else if (expo < 0x02a0)
1458 sd->exposure = setexposure(gspca_dev, expo);
1462 expo = sd->brightness >> 4;
1463 sd->exposure = setexposure(gspca_dev, expo);
1465 case SENSOR_MT9V111:
1466 expo = sd->brightness >> 8;
1467 sd->exposure = setexposure(gspca_dev, expo);
1470 expo = sd->brightness >> 6;
1471 sd->exposure = setexposure(gspca_dev, expo);
1472 k2 = sd->brightness >> 11;
1476 if (sd->sensor != SENSOR_MT9V111)
1477 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1480 static void setcontrast(struct gspca_dev *gspca_dev)
1482 struct sd *sd = (struct sd *) gspca_dev;
1486 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1487 contrast[0] = (k2 + 1) / 2; /* red */
1489 contrast[2] = k2; /* green */
1491 contrast[4] = (k2 + 1) / 5; /* blue */
1493 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1496 static void setcolors(struct gspca_dev *gspca_dev)
1498 struct sd *sd = (struct sd *) gspca_dev;
1500 u8 reg8a[12]; /* U & V gains */
1501 static s16 uv[6] = { /* same as reg84 in signed decimal */
1502 -24, -38, 64, /* UR UG UB */
1503 62, -51, -9 /* VR VG VB */
1505 for (i = 0; i < 6; i++) {
1506 v = uv[i] * sd->colors / COLOR_DEF;
1508 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1510 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1513 static void setredblue(struct gspca_dev *gspca_dev)
1515 struct sd *sd = (struct sd *) gspca_dev;
1517 reg_w1(gspca_dev, 0x05, sd->red);
1518 /* reg_w1(gspca_dev, 0x07, 32); */
1519 reg_w1(gspca_dev, 0x06, sd->blue);
1522 static void setgamma(struct gspca_dev *gspca_dev)
1524 struct sd *sd = (struct sd *) gspca_dev;
1527 const u8 *gamma_base;
1528 static const u8 delta[17] = {
1529 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1530 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1533 switch (sd->sensor) {
1534 case SENSOR_HV7131R:
1535 case SENSOR_MT9V111:
1536 gamma_base = gamma_spec_1;
1538 case SENSOR_SP80708:
1539 gamma_base = gamma_spec_2;
1542 gamma_base = gamma_def;
1546 for (i = 0; i < sizeof gamma; i++)
1547 gamma[i] = gamma_base[i]
1548 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1549 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1552 static void setautogain(struct gspca_dev *gspca_dev)
1554 struct sd *sd = (struct sd *) gspca_dev;
1556 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1559 sd->ag_cnt = AG_CNT_START;
1564 static void setvflip(struct sd *sd)
1566 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1567 sd->vflip ? 0x82 : 0x02);
1570 static void setinfrared(struct sd *sd)
1572 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1574 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1575 sd->infrared ? 0x66 : 0x64);
1578 /* -- start the camera -- */
1579 static int sd_start(struct gspca_dev *gspca_dev)
1581 struct sd *sd = (struct sd *) gspca_dev;
1583 u8 reg1, reg17, reg18;
1586 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1587 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1588 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1589 static const u8 CE_ov76xx[] =
1590 { 0x32, 0xdd, 0x32, 0xdd };
1592 sn9c1xx = sn_tb[(int) sd->sensor];
1593 configure_gpio(gspca_dev, sn9c1xx);
1595 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1596 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1597 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1598 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1599 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1600 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1601 reg_w1(gspca_dev, 0xd3, 0x50);
1602 reg_w1(gspca_dev, 0xc6, 0x00);
1603 reg_w1(gspca_dev, 0xc7, 0x00);
1604 reg_w1(gspca_dev, 0xc8, 0x50);
1605 reg_w1(gspca_dev, 0xc9, 0x3c);
1606 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1607 switch (sd->sensor) {
1608 case SENSOR_MT9V111:
1617 /*jfm: from win trace */
1619 if (sd->bridge == BRIDGE_SN9C120) {
1628 reg_w1(gspca_dev, 0x17, reg17);
1629 /* set reg1 was here */
1630 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1631 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1632 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1633 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1635 setgamma(gspca_dev);
1637 for (i = 0; i < 8; i++)
1638 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1639 switch (sd->sensor) {
1640 case SENSOR_MT9V111:
1641 reg_w1(gspca_dev, 0x9a, 0x07);
1642 reg_w1(gspca_dev, 0x99, 0x59);
1645 reg_w1(gspca_dev, 0x9a, 0x0a);
1646 reg_w1(gspca_dev, 0x99, 0x60);
1648 case SENSOR_SP80708:
1649 reg_w1(gspca_dev, 0x9a, 0x05);
1650 reg_w1(gspca_dev, 0x99, 0x59);
1653 if (sd->bridge == BRIDGE_SN9C120) {
1654 reg_w1(gspca_dev, 0x9a, 0x05);
1659 reg_w1(gspca_dev, 0x9a, 0x08);
1660 reg_w1(gspca_dev, 0x99, 0x59);
1664 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1666 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1668 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1669 reg17 = 0x61; /* 0x:20: enable sensor clock */
1670 switch (sd->sensor) {
1671 case SENSOR_HV7131R:
1672 hv7131R_InitSensor(gspca_dev);
1675 mi0360_InitSensor(gspca_dev);
1678 mo4000_InitSensor(gspca_dev);
1680 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1681 reg1 = 0x06; /* clk 24Mz */
1683 reg17 = 0x22; /* 640 MCKSIZE */
1684 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1687 case SENSOR_MT9V111:
1688 mt9v111_InitSensor(gspca_dev);
1690 reg1 = 0x04; /* 320 clk 48Mhz */
1692 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1697 om6802_InitSensor(gspca_dev);
1698 reg17 = 0x64; /* 640 MCKSIZE */
1701 ov7630_InitSensor(gspca_dev);
1707 ov7648_InitSensor(gspca_dev);
1709 /* reg1 = 0x42; * 42 - 46? */
1712 ov7660_InitSensor(gspca_dev);
1713 if (sd->bridge == BRIDGE_SN9C120) {
1714 if (mode) { /* 320x240 - 160x120 */
1716 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1720 reg1 = 0x06; /* 24 Mhz, video trf eneble
1721 * inverse power down */
1725 /* case SENSOR_SP80708: */
1726 sp80708_InitSensor(gspca_dev);
1728 /*?? reg1 = 0x04; * 320 clk 48Mhz */
1730 reg1 = 0x46; /* 640 clk 48Mz */
1735 reg_w(gspca_dev, 0xc0, C0, 6);
1736 reg_w(gspca_dev, 0xca, CA, 4);
1737 switch (sd->sensor) {
1741 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1744 reg_w(gspca_dev, 0xce, CE, 4);
1745 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1749 /* here change size mode 0 -> VGA; 1 -> CIF */
1750 reg18 = sn9c1xx[0x18] | (mode << 4);
1751 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1753 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1754 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
1756 reg_w1(gspca_dev, 0x18, reg18);
1758 reg_w1(gspca_dev, 0x17, reg17);
1759 reg_w1(gspca_dev, 0x01, reg1);
1760 switch (sd->sensor) {
1765 setbrightness(gspca_dev);
1766 setcontrast(gspca_dev);
1767 setautogain(gspca_dev);
1771 static void sd_stopN(struct gspca_dev *gspca_dev)
1773 struct sd *sd = (struct sd *) gspca_dev;
1774 static const u8 stophv7131[] =
1775 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1776 static const u8 stopmi0360[] =
1777 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1778 static const u8 stopov7648[] =
1779 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1784 switch (sd->sensor) {
1785 case SENSOR_HV7131R:
1786 i2c_w8(gspca_dev, stophv7131);
1790 i2c_w8(gspca_dev, stopmi0360);
1794 i2c_w8(gspca_dev, stopov7648);
1796 case SENSOR_MT9V111:
1801 /* case SENSOR_MO4000: */
1802 /* case SENSOR_OV7660: */
1805 sn9c1xx = sn_tb[(int) sd->sensor];
1806 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1807 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1808 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1809 reg_w1(gspca_dev, 0x01, data);
1810 reg_w1(gspca_dev, 0xf1, 0x00);
1813 static void do_autogain(struct gspca_dev *gspca_dev)
1815 struct sd *sd = (struct sd *) gspca_dev;
1821 /* Thanks S., without your advice, autobright should not work :) */
1824 if (--sd->ag_cnt >= 0)
1826 sd->ag_cnt = AG_CNT_START;
1828 delta = atomic_read(&sd->avg_lum);
1829 PDEBUG(D_FRAM, "mean lum %d", delta);
1830 if (delta < luma_mean - luma_delta ||
1831 delta > luma_mean + luma_delta) {
1832 switch (sd->sensor) {
1833 case SENSOR_HV7131R:
1834 expotimes = sd->exposure >> 8;
1835 expotimes += (luma_mean - delta) >> 4;
1838 sd->exposure = setexposure(gspca_dev,
1839 (unsigned int) (expotimes << 8));
1842 /* case SENSOR_MO4000: */
1843 /* case SENSOR_MI0360: */
1844 /* case SENSOR_MT9V111: */
1845 /* case SENSOR_OM6802: */
1846 expotimes = sd->exposure;
1847 expotimes += (luma_mean - delta) >> 6;
1850 sd->exposure = setexposure(gspca_dev,
1851 (unsigned int) expotimes);
1852 setredblue(gspca_dev);
1858 /* scan the URB packets */
1859 /* This function is run at interrupt level. */
1860 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1861 struct gspca_frame *frame, /* target */
1862 u8 *data, /* isoc packet */
1863 int len) /* iso packet length */
1865 struct sd *sd = (struct sd *) gspca_dev;
1869 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1872 gspca_frame_add(gspca_dev, LAST_PACKET,
1873 frame, data, sof + 2);
1880 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1882 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1884 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1886 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1888 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1890 atomic_set(&sd->avg_lum, avg_lum);
1893 if (gspca_dev->last_packet_type == LAST_PACKET) {
1895 /* put the JPEG 422 header */
1896 jpeg_put_header(gspca_dev, frame, 0x21);
1898 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1901 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1903 struct sd *sd = (struct sd *) gspca_dev;
1905 sd->brightness = val;
1906 if (gspca_dev->streaming)
1907 setbrightness(gspca_dev);
1911 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1913 struct sd *sd = (struct sd *) gspca_dev;
1915 *val = sd->brightness;
1919 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1921 struct sd *sd = (struct sd *) gspca_dev;
1924 if (gspca_dev->streaming)
1925 setcontrast(gspca_dev);
1929 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1931 struct sd *sd = (struct sd *) gspca_dev;
1933 *val = sd->contrast;
1937 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1939 struct sd *sd = (struct sd *) gspca_dev;
1942 if (gspca_dev->streaming)
1943 setcolors(gspca_dev);
1947 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1949 struct sd *sd = (struct sd *) gspca_dev;
1955 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1957 struct sd *sd = (struct sd *) gspca_dev;
1960 if (gspca_dev->streaming)
1961 setredblue(gspca_dev);
1965 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1967 struct sd *sd = (struct sd *) gspca_dev;
1973 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1975 struct sd *sd = (struct sd *) gspca_dev;
1978 if (gspca_dev->streaming)
1979 setredblue(gspca_dev);
1983 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1985 struct sd *sd = (struct sd *) gspca_dev;
1991 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1993 struct sd *sd = (struct sd *) gspca_dev;
1996 if (gspca_dev->streaming)
1997 setgamma(gspca_dev);
2001 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2003 struct sd *sd = (struct sd *) gspca_dev;
2009 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2011 struct sd *sd = (struct sd *) gspca_dev;
2014 if (gspca_dev->streaming)
2015 setautogain(gspca_dev);
2019 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2021 struct sd *sd = (struct sd *) gspca_dev;
2023 *val = sd->autogain;
2027 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2029 struct sd *sd = (struct sd *) gspca_dev;
2032 if (gspca_dev->streaming)
2037 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2039 struct sd *sd = (struct sd *) gspca_dev;
2045 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2047 struct sd *sd = (struct sd *) gspca_dev;
2050 if (gspca_dev->streaming)
2055 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2057 struct sd *sd = (struct sd *) gspca_dev;
2059 *val = sd->infrared;
2063 /* sub-driver description */
2064 static const struct sd_desc sd_desc = {
2065 .name = MODULE_NAME,
2067 .nctrls = ARRAY_SIZE(sd_ctrls),
2068 .config = sd_config,
2072 .pkt_scan = sd_pkt_scan,
2073 .dq_callback = do_autogain,
2076 /* -- module initialisation -- */
2077 #define BSI(bridge, sensor, i2c_addr) \
2078 .driver_info = (BRIDGE_ ## bridge << 16) \
2079 | (SENSOR_ ## sensor << 8) \
2081 static const __devinitdata struct usb_device_id device_table[] = {
2082 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2083 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
2084 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
2086 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2087 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
2088 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2089 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
2091 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2092 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2093 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2094 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2096 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2097 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2098 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2099 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2100 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
2101 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
2102 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2103 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2104 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2105 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2106 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2107 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2108 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2109 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2110 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2112 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2113 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2114 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2115 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2117 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
2118 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
2119 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
2120 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
2121 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2122 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
2124 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
2125 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
2126 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2127 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2128 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2129 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
2131 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
2134 MODULE_DEVICE_TABLE(usb, device_table);
2136 /* -- device connect -- */
2137 static int sd_probe(struct usb_interface *intf,
2138 const struct usb_device_id *id)
2140 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2144 static struct usb_driver sd_driver = {
2145 .name = MODULE_NAME,
2146 .id_table = device_table,
2148 .disconnect = gspca_disconnect,
2150 .suspend = gspca_suspend,
2151 .resume = gspca_resume,
2155 /* -- module insert / remove -- */
2156 static int __init sd_mod_init(void)
2159 ret = usb_register(&sd_driver);
2165 static void __exit sd_mod_exit(void)
2167 usb_deregister(&sd_driver);
2168 info("deregistered");
2171 module_init(sd_mod_init);
2172 module_exit(sd_mod_exit);