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 static const u8 gamma_def[17] = {
383 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
384 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
388 /* color matrix and offsets */
389 static const u8 reg84[] = {
390 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
391 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
392 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
393 0x00, 0x00, 0x00 /* YUV offsets */
395 static const u8 hv7131r_sensor_init[][8] = {
396 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
397 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
398 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
399 /* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
400 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
401 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
402 /* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
404 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
405 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
406 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
407 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
408 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
409 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
410 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
411 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
413 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
414 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
416 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
417 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
422 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
426 static const u8 mi0360_sensor_init[][8] = {
427 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
428 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
429 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
430 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
431 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
432 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
433 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
434 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
435 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
436 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
437 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
438 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
444 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
449 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
450 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
452 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
454 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
456 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
459 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
461 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
462 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
463 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
464 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
465 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
467 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
468 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
469 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
470 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
472 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
473 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
474 /* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
475 /* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
476 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
477 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
480 static const u8 mo4000_sensor_init[][8] = {
481 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
483 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
484 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
485 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
486 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
487 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
488 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
489 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
490 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
491 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
503 static const u8 mt9v111_sensor_init[][8] = {
504 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
506 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
508 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
509 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
510 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
511 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
512 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
513 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
514 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
515 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
516 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
517 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
518 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
519 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
520 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
521 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
523 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
524 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
525 {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */
526 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
527 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
529 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
530 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
531 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
532 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
535 static const u8 om6802_sensor_init[][8] = {
536 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
537 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
538 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
539 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
540 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
541 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
542 /* white balance & auto-exposure */
543 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
545 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
546 * max AGC value in AE */
547 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
549 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
550 * preset brightness */
551 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
553 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
555 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
556 /* luminance mode (0x4f = AE) */
557 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
559 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
561 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
563 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
564 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
565 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
566 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
569 static const u8 ov7630_sensor_init[][8] = {
570 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
571 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
572 /* win: delay 20ms */
573 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
574 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
575 /* win: delay 20ms */
576 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
577 /* win: i2c_r from 00 to 80 */
578 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
579 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
580 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
581 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
582 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
583 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
584 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
585 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
586 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
587 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
588 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
589 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
590 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
591 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
593 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
594 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
595 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
596 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
597 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
598 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
599 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
600 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
601 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
602 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
603 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
605 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
606 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
607 /*fixme: + 0x12, 0x04*/
608 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
610 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
611 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
612 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
614 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
615 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
616 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
618 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
619 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
623 static const u8 ov7648_sensor_init[][8] = {
624 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
626 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
627 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
628 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
629 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
630 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
631 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
632 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
633 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
634 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
635 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
636 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
637 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
638 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
639 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
640 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
641 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
642 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
643 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
644 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
646 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
647 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
648 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
649 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
651 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
652 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
653 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
654 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
655 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
656 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
657 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
659 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
660 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
661 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
662 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
663 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
664 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
669 static const u8 ov7660_sensor_init[][8] = {
670 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
672 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
673 /* Outformat = rawRGB */
674 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
675 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
676 /* GAIN BLUE RED VREF */
677 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
678 /* COM 1 BAVE GEAVE AECHH */
679 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
680 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
681 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
682 /* AECH CLKRC COM7 COM8 */
683 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
684 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
685 /* HSTART HSTOP VSTRT VSTOP */
686 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
687 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
688 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
689 /* BOS GBOS GROS ROS (BGGR offset) */
690 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
691 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
692 /* AEW AEB VPT BBIAS */
693 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
694 /* GbBIAS RSVD EXHCH EXHCL */
695 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
696 /* RBIAS ADVFL ASDVFH YAVE */
697 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
698 /* HSYST HSYEN HREF */
699 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
700 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
701 /* ADC ACOM OFON TSLB */
702 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
703 /* COM11 COM12 COM13 COM14 */
704 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
705 /* EDGE COM15 COM16 COM17 */
706 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
707 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
708 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
709 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
710 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
711 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
712 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
713 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
714 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
715 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
716 /* LCC1 LCC2 LCC3 LCC4 */
717 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
718 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
719 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
720 /* band gap reference [0:3] DBLV */
721 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
722 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
723 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
724 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
725 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
726 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
727 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
728 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
729 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
730 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
731 /****** (some exchanges in the win trace) ******/
732 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
733 /* bits[3..0]reserved */
734 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
735 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
736 /* VREF vertical frame ctrl */
737 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
738 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
739 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
740 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
741 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
742 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
743 /****** (some exchanges in the win trace) ******/
744 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
745 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
746 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
747 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
748 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
749 /****** (some exchanges in the win trace) ******/
750 /******!! startsensor KO if changed !!****/
751 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
752 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
753 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
754 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
758 static const u8 sp80708_sensor_init[][8] = {
759 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
760 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
761 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
762 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
763 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
764 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
765 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
766 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
767 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
768 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
769 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
770 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
771 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
776 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
777 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
778 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
779 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
837 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
841 static const u8 qtable4[] = {
842 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
843 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
844 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
845 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
846 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
847 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
848 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
849 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
850 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
851 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
852 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
853 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
854 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
855 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
856 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
857 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
860 /* read <len> bytes to gspca_dev->usb_buf */
861 static void reg_r(struct gspca_dev *gspca_dev,
865 if (len > USB_BUF_SZ) {
866 err("reg_r: buffer overflow");
870 usb_control_msg(gspca_dev->dev,
871 usb_rcvctrlpipe(gspca_dev->dev, 0),
873 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
875 gspca_dev->usb_buf, len,
877 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
880 static void reg_w1(struct gspca_dev *gspca_dev,
884 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
885 gspca_dev->usb_buf[0] = data;
886 usb_control_msg(gspca_dev->dev,
887 usb_sndctrlpipe(gspca_dev->dev, 0),
889 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
892 gspca_dev->usb_buf, 1,
895 static void reg_w(struct gspca_dev *gspca_dev,
900 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
901 value, buffer[0], buffer[1]);
903 if (len > USB_BUF_SZ) {
904 err("reg_w: buffer overflow");
908 memcpy(gspca_dev->usb_buf, buffer, len);
909 usb_control_msg(gspca_dev->dev,
910 usb_sndctrlpipe(gspca_dev->dev, 0),
912 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
914 gspca_dev->usb_buf, len,
918 /* I2C write 1 byte */
919 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
921 struct sd *sd = (struct sd *) gspca_dev;
923 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
924 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
925 gspca_dev->usb_buf[1] = sd->i2c_base;
926 gspca_dev->usb_buf[2] = reg;
927 gspca_dev->usb_buf[3] = val;
928 gspca_dev->usb_buf[4] = 0;
929 gspca_dev->usb_buf[5] = 0;
930 gspca_dev->usb_buf[6] = 0;
931 gspca_dev->usb_buf[7] = 0x10;
932 usb_control_msg(gspca_dev->dev,
933 usb_sndctrlpipe(gspca_dev->dev, 0),
935 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
936 0x08, /* value = i2c */
938 gspca_dev->usb_buf, 8,
942 /* I2C write 8 bytes */
943 static void i2c_w8(struct gspca_dev *gspca_dev,
946 memcpy(gspca_dev->usb_buf, buffer, 8);
947 usb_control_msg(gspca_dev->dev,
948 usb_sndctrlpipe(gspca_dev->dev, 0),
950 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
951 0x08, 0, /* value, index */
952 gspca_dev->usb_buf, 8,
957 /* read 5 bytes in gspca_dev->usb_buf */
958 static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
960 struct sd *sd = (struct sd *) gspca_dev;
963 mode[0] = 0x81 | 0x10;
964 mode[1] = sd->i2c_base;
971 i2c_w8(gspca_dev, mode);
973 mode[0] = 0x81 | (5 << 4) | 0x02;
975 i2c_w8(gspca_dev, mode);
977 reg_r(gspca_dev, 0x0a, 5);
980 static int hv7131r_probe(struct gspca_dev *gspca_dev)
982 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
984 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
986 i2c_r5(gspca_dev, 0); /* read sensor id */
987 if (gspca_dev->usb_buf[0] == 0x02
988 && gspca_dev->usb_buf[1] == 0x09
989 && gspca_dev->usb_buf[2] == 0x01
990 && gspca_dev->usb_buf[3] == 0x00
991 && gspca_dev->usb_buf[4] == 0x00) {
992 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
995 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
996 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
997 gspca_dev->usb_buf[2]);
998 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1002 static int mi0360_probe(struct gspca_dev *gspca_dev)
1006 static const u8 probe_tb[][4][8] = {
1008 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1009 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1010 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1011 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1014 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1015 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1016 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1021 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1022 reg_w1(gspca_dev, 0x17, 0x62);
1023 reg_w1(gspca_dev, 0x01, 0x08);
1024 for (j = 0; j < 3; j++)
1025 i2c_w8(gspca_dev, probe_tb[i][j]);
1027 reg_r(gspca_dev, 0x0a, 5);
1028 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1029 if (probe_tb[i][3][0] != 0)
1030 i2c_w8(gspca_dev, probe_tb[i][3]);
1031 reg_w1(gspca_dev, 0x01, 0x29);
1032 reg_w1(gspca_dev, 0x17, 0x42);
1038 PDEBUG(D_PROBE, "Sensor mt9v111");
1039 return SENSOR_MT9V111;
1041 PDEBUG(D_PROBE, "Sensor mi0360");
1042 return SENSOR_MI0360;
1044 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1045 return SENSOR_MI0360;
1048 static int configure_gpio(struct gspca_dev *gspca_dev,
1051 struct sd *sd = (struct sd *) gspca_dev;
1053 static const u8 reg9a_def[] =
1054 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
1055 static const u8 reg9a_sn9c325[] =
1056 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
1057 static const u8 regd4[] = {0x60, 0x00, 0x00};
1059 reg_w1(gspca_dev, 0xf1, 0x00);
1060 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1062 /* configure gpio */
1063 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1064 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1065 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
1066 switch (sd->bridge) {
1067 case BRIDGE_SN9C325:
1068 reg9a = reg9a_sn9c325;
1074 reg_w(gspca_dev, 0x9a, reg9a, 6);
1076 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
1078 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1080 switch (sd->sensor) {
1081 case SENSOR_MT9V111:
1082 reg_w1(gspca_dev, 0x01, 0x61);
1083 reg_w1(gspca_dev, 0x17, 0x61);
1084 reg_w1(gspca_dev, 0x01, 0x60);
1085 reg_w1(gspca_dev, 0x01, 0x40);
1088 reg_w1(gspca_dev, 0x02, 0x71);
1089 reg_w1(gspca_dev, 0x01, 0x42);
1090 reg_w1(gspca_dev, 0x17, 0x64);
1091 reg_w1(gspca_dev, 0x01, 0x42);
1093 /*jfm: from win trace */
1095 reg_w1(gspca_dev, 0x01, 0x61);
1096 reg_w1(gspca_dev, 0x17, 0xe2);
1097 reg_w1(gspca_dev, 0x01, 0x60);
1098 reg_w1(gspca_dev, 0x01, 0x40);
1101 reg_w1(gspca_dev, 0x01, 0x63);
1102 reg_w1(gspca_dev, 0x17, 0x20);
1103 reg_w1(gspca_dev, 0x01, 0x42);
1105 /*jfm: from win trace */
1107 if (sd->bridge == BRIDGE_SN9C120) {
1108 reg_w1(gspca_dev, 0x01, 0x61);
1109 reg_w1(gspca_dev, 0x17, 0x20);
1110 reg_w1(gspca_dev, 0x01, 0x60);
1111 reg_w1(gspca_dev, 0x01, 0x40);
1115 case SENSOR_SP80708:
1116 reg_w1(gspca_dev, 0x01, 0x63);
1117 reg_w1(gspca_dev, 0x17, 0x20);
1118 reg_w1(gspca_dev, 0x01, 0x62);
1119 reg_w1(gspca_dev, 0x01, 0x42);
1121 reg_w1(gspca_dev, 0x02, 0x62);
1124 reg_w1(gspca_dev, 0x01, 0x43);
1125 reg_w1(gspca_dev, 0x17, 0x61);
1126 reg_w1(gspca_dev, 0x01, 0x42);
1127 if (sd->sensor == SENSOR_HV7131R) {
1128 if (hv7131r_probe(gspca_dev) < 0)
1136 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1139 static const u8 SetSensorClk[] = /* 0x08 Mclk */
1140 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1142 while (hv7131r_sensor_init[i][0]) {
1143 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1146 i2c_w8(gspca_dev, SetSensorClk);
1149 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1153 while (mi0360_sensor_init[i][0]) {
1154 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1159 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1163 while (mo4000_sensor_init[i][0]) {
1164 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1169 static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1173 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1176 while (mt9v111_sensor_init[i][0]) {
1177 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1182 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1186 while (om6802_sensor_init[i][0]) {
1187 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1192 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1196 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1198 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
1201 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1203 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1206 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1208 /*jfm:win i2c_r from 00 to 80*/
1210 while (ov7630_sensor_init[i][0]) {
1211 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1216 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1220 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1222 /* win: dble reset */
1223 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1226 /* win: i2c reg read 00..7f */
1227 while (ov7648_sensor_init[i][0]) {
1228 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1233 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1237 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1240 while (ov7660_sensor_init[i][0]) {
1241 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1246 static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1250 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1253 while (sp80708_sensor_init[i][0]) {
1254 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1259 /* this function is called at probe time */
1260 static int sd_config(struct gspca_dev *gspca_dev,
1261 const struct usb_device_id *id)
1263 struct sd *sd = (struct sd *) gspca_dev;
1266 cam = &gspca_dev->cam;
1267 cam->cam_mode = vga_mode;
1268 cam->nmodes = ARRAY_SIZE(vga_mode);
1270 sd->bridge = id->driver_info >> 16;
1271 sd->sensor = id->driver_info >> 8;
1272 sd->i2c_base = id->driver_info;
1274 sd->brightness = BRIGHTNESS_DEF;
1275 sd->contrast = CONTRAST_DEF;
1276 sd->colors = COLOR_DEF;
1277 sd->blue = BLUE_BALANCE_DEF;
1278 sd->red = RED_BALANCE_DEF;
1279 sd->gamma = GAMMA_DEF;
1280 sd->autogain = AUTOGAIN_DEF;
1282 sd->vflip = VFLIP_DEF;
1283 sd->infrared = INFRARED_DEF;
1285 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1289 /* this function is called at probe and resume time */
1290 static int sd_init(struct gspca_dev *gspca_dev)
1292 struct sd *sd = (struct sd *) gspca_dev;
1293 u8 regGpio[] = { 0x29, 0x74 };
1296 /* setup a selector by bridge */
1297 reg_w1(gspca_dev, 0xf1, 0x01);
1298 reg_r(gspca_dev, 0x00, 1);
1299 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1300 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1301 regF1 = gspca_dev->usb_buf[0];
1302 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1303 switch (sd->bridge) {
1304 case BRIDGE_SN9C102P:
1307 reg_w1(gspca_dev, 0x02, regGpio[1]);
1309 case BRIDGE_SN9C105:
1312 if (sd->sensor == SENSOR_MI0360) {
1313 sd->sensor = mi0360_probe(gspca_dev);
1314 if (sd->sensor == SENSOR_MT9V111)
1315 sd->i2c_base = 0x5c;
1317 reg_w(gspca_dev, 0x01, regGpio, 2);
1319 case BRIDGE_SN9C120:
1322 if (sd->sensor == SENSOR_MI0360) {
1323 sd->sensor = mi0360_probe(gspca_dev);
1324 if (sd->sensor == SENSOR_MT9V111)
1325 sd->i2c_base = 0x5c;
1328 reg_w(gspca_dev, 0x01, regGpio, 2);
1331 /* case BRIDGE_SN9C110: */
1332 /* case BRIDGE_SN9C325: */
1335 reg_w1(gspca_dev, 0x02, 0x62);
1339 reg_w1(gspca_dev, 0xf1, 0x01);
1344 static u32 setexposure(struct gspca_dev *gspca_dev,
1347 struct sd *sd = (struct sd *) gspca_dev;
1349 switch (sd->sensor) {
1350 case SENSOR_HV7131R: {
1352 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1354 Expodoit[3] = expo >> 16;
1355 Expodoit[4] = expo >> 8;
1357 i2c_w8(gspca_dev, Expodoit);
1360 case SENSOR_MI0360: {
1361 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1362 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1363 static const u8 doit[] = /* update sensor */
1364 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1365 static const u8 sensorgo[] = /* sensor on */
1366 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1370 else if (expo < 0x0001)
1372 expoMi[3] = expo >> 8;
1374 i2c_w8(gspca_dev, expoMi);
1375 i2c_w8(gspca_dev, doit);
1376 i2c_w8(gspca_dev, sensorgo);
1379 case SENSOR_MO4000: {
1381 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1383 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1384 static const u8 gainMo[] =
1385 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1389 else if (expo < 0x0001)
1391 expoMof[3] = (expo & 0x03fc) >> 2;
1392 i2c_w8(gspca_dev, expoMof);
1393 expoMo10[3] = ((expo & 0x1c00) >> 10)
1394 | ((expo & 0x0003) << 4);
1395 i2c_w8(gspca_dev, expoMo10);
1396 i2c_w8(gspca_dev, gainMo);
1397 PDEBUG(D_FRAM, "set exposure %d",
1398 ((expoMo10[3] & 0x07) << 10)
1400 | ((expoMo10[3] & 0x30) >> 4));
1403 case SENSOR_MT9V111: {
1405 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1409 else if (expo < 0x0040)
1411 expo_c1[3] = expo >> 8;
1413 i2c_w8(gspca_dev, expo_c1);
1416 case SENSOR_OM6802: {
1418 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1424 gainOm[3] = expo >> 2;
1425 i2c_w8(gspca_dev, gainOm);
1426 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1427 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1434 static void setbrightness(struct gspca_dev *gspca_dev)
1436 struct sd *sd = (struct sd *) gspca_dev;
1440 k2 = ((int) sd->brightness - 0x8000) >> 10;
1441 switch (sd->sensor) {
1442 case SENSOR_HV7131R:
1443 expo = sd->brightness << 4;
1444 if (expo > 0x002dc6c0)
1446 else if (expo < 0x02a0)
1448 sd->exposure = setexposure(gspca_dev, expo);
1452 expo = sd->brightness >> 4;
1453 sd->exposure = setexposure(gspca_dev, expo);
1455 case SENSOR_MT9V111:
1456 expo = sd->brightness >> 8;
1457 sd->exposure = setexposure(gspca_dev, expo);
1460 expo = sd->brightness >> 6;
1461 sd->exposure = setexposure(gspca_dev, expo);
1462 k2 = sd->brightness >> 11;
1466 if (sd->sensor != SENSOR_MT9V111)
1467 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1470 static void setcontrast(struct gspca_dev *gspca_dev)
1472 struct sd *sd = (struct sd *) gspca_dev;
1476 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1477 contrast[0] = (k2 + 1) / 2; /* red */
1479 contrast[2] = k2; /* green */
1481 contrast[4] = (k2 + 1) / 5; /* blue */
1483 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1486 static void setcolors(struct gspca_dev *gspca_dev)
1488 struct sd *sd = (struct sd *) gspca_dev;
1490 u8 reg8a[12]; /* U & V gains */
1491 static s16 uv[6] = { /* same as reg84 in signed decimal */
1492 -24, -38, 64, /* UR UG UB */
1493 62, -51, -9 /* VR VG VB */
1495 for (i = 0; i < 6; i++) {
1496 v = uv[i] * sd->colors / COLOR_DEF;
1498 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1500 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1503 static void setredblue(struct gspca_dev *gspca_dev)
1505 struct sd *sd = (struct sd *) gspca_dev;
1507 reg_w1(gspca_dev, 0x05, sd->red);
1508 /* reg_w1(gspca_dev, 0x07, 32); */
1509 reg_w1(gspca_dev, 0x06, sd->blue);
1512 static void setgamma(struct gspca_dev *gspca_dev)
1514 struct sd *sd = (struct sd *) gspca_dev;
1517 static const u8 delta[17] = {
1518 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1519 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1523 for (i = 0; i < sizeof gamma; i++)
1524 gamma[i] = gamma_def[i]
1525 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1526 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1529 static void setautogain(struct gspca_dev *gspca_dev)
1531 struct sd *sd = (struct sd *) gspca_dev;
1533 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1536 sd->ag_cnt = AG_CNT_START;
1541 static void setvflip(struct sd *sd)
1543 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1544 sd->vflip ? 0x82 : 0x02);
1547 static void setinfrared(struct sd *sd)
1549 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1551 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1552 sd->infrared ? 0x66 : 0x64);
1555 /* -- start the camera -- */
1556 static int sd_start(struct gspca_dev *gspca_dev)
1558 struct sd *sd = (struct sd *) gspca_dev;
1560 u8 reg1, reg17, reg18;
1563 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1564 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1565 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1566 static const u8 CE_ov76xx[] =
1567 { 0x32, 0xdd, 0x32, 0xdd };
1569 sn9c1xx = sn_tb[(int) sd->sensor];
1570 configure_gpio(gspca_dev, sn9c1xx);
1572 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1573 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1574 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1575 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1576 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1577 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1578 reg_w1(gspca_dev, 0xd3, 0x50);
1579 reg_w1(gspca_dev, 0xc6, 0x00);
1580 reg_w1(gspca_dev, 0xc7, 0x00);
1581 reg_w1(gspca_dev, 0xc8, 0x50);
1582 reg_w1(gspca_dev, 0xc9, 0x3c);
1583 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1584 switch (sd->sensor) {
1585 case SENSOR_MT9V111:
1594 /*jfm: from win trace */
1596 if (sd->bridge == BRIDGE_SN9C120) {
1605 reg_w1(gspca_dev, 0x17, reg17);
1606 /* set reg1 was here */
1607 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1608 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1609 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1610 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1611 setgamma(gspca_dev);
1613 for (i = 0; i < 8; i++)
1614 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1615 switch (sd->sensor) {
1616 case SENSOR_MT9V111:
1617 reg_w1(gspca_dev, 0x9a, 0x07);
1618 reg_w1(gspca_dev, 0x99, 0x59);
1621 reg_w1(gspca_dev, 0x9a, 0x0a);
1622 reg_w1(gspca_dev, 0x99, 0x60);
1624 case SENSOR_SP80708:
1625 reg_w1(gspca_dev, 0x9a, 0x05);
1626 reg_w1(gspca_dev, 0x99, 0x59);
1629 if (sd->bridge == BRIDGE_SN9C120) {
1630 reg_w1(gspca_dev, 0x9a, 0x05);
1635 reg_w1(gspca_dev, 0x9a, 0x08);
1636 reg_w1(gspca_dev, 0x99, 0x59);
1640 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1642 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1644 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1645 reg17 = 0x61; /* 0x:20: enable sensor clock */
1646 switch (sd->sensor) {
1647 case SENSOR_HV7131R:
1648 hv7131R_InitSensor(gspca_dev);
1651 mi0360_InitSensor(gspca_dev);
1654 mo4000_InitSensor(gspca_dev);
1656 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1657 reg1 = 0x06; /* clk 24Mz */
1659 reg17 = 0x22; /* 640 MCKSIZE */
1660 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1663 case SENSOR_MT9V111:
1664 mt9v111_InitSensor(gspca_dev);
1666 reg1 = 0x04; /* 320 clk 48Mhz */
1668 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1673 om6802_InitSensor(gspca_dev);
1674 reg17 = 0x64; /* 640 MCKSIZE */
1677 ov7630_InitSensor(gspca_dev);
1683 ov7648_InitSensor(gspca_dev);
1685 /* reg1 = 0x42; * 42 - 46? */
1688 ov7660_InitSensor(gspca_dev);
1689 if (sd->bridge == BRIDGE_SN9C120) {
1690 if (mode) { /* 320x240 - 160x120 */
1692 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1696 reg1 = 0x06; /* 24 Mhz, video trf eneble
1697 * inverse power down */
1701 /* case SENSOR_SP80708: */
1702 sp80708_InitSensor(gspca_dev);
1704 /*?? reg1 = 0x04; * 320 clk 48Mhz */
1707 reg1 = 0x46; /* 640 clk 48Mz */
1712 reg_w(gspca_dev, 0xc0, C0, 6);
1713 reg_w(gspca_dev, 0xca, CA, 4);
1714 switch (sd->sensor) {
1718 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1721 reg_w(gspca_dev, 0xce, CE, 4);
1722 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1726 /* here change size mode 0 -> VGA; 1 -> CIF */
1727 reg18 = sn9c1xx[0x18] | (mode << 4);
1728 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1730 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1731 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
1733 reg_w1(gspca_dev, 0x18, reg18);
1735 reg_w1(gspca_dev, 0x17, reg17);
1736 reg_w1(gspca_dev, 0x01, reg1);
1737 switch (sd->sensor) {
1742 setbrightness(gspca_dev);
1743 setcontrast(gspca_dev);
1744 setautogain(gspca_dev);
1748 static void sd_stopN(struct gspca_dev *gspca_dev)
1750 struct sd *sd = (struct sd *) gspca_dev;
1751 static const u8 stophv7131[] =
1752 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1753 static const u8 stopmi0360[] =
1754 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1755 static const u8 stopov7648[] =
1756 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1761 switch (sd->sensor) {
1762 case SENSOR_HV7131R:
1763 i2c_w8(gspca_dev, stophv7131);
1767 i2c_w8(gspca_dev, stopmi0360);
1771 i2c_w8(gspca_dev, stopov7648);
1773 case SENSOR_MT9V111:
1778 /* case SENSOR_MO4000: */
1779 /* case SENSOR_OV7660: */
1782 sn9c1xx = sn_tb[(int) sd->sensor];
1783 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1784 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1785 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1786 reg_w1(gspca_dev, 0x01, data);
1787 reg_w1(gspca_dev, 0xf1, 0x00);
1790 static void do_autogain(struct gspca_dev *gspca_dev)
1792 struct sd *sd = (struct sd *) gspca_dev;
1798 /* Thanks S., without your advice, autobright should not work :) */
1801 if (--sd->ag_cnt >= 0)
1803 sd->ag_cnt = AG_CNT_START;
1805 delta = atomic_read(&sd->avg_lum);
1806 PDEBUG(D_FRAM, "mean lum %d", delta);
1807 if (delta < luma_mean - luma_delta ||
1808 delta > luma_mean + luma_delta) {
1809 switch (sd->sensor) {
1810 case SENSOR_HV7131R:
1811 expotimes = sd->exposure >> 8;
1812 expotimes += (luma_mean - delta) >> 4;
1815 sd->exposure = setexposure(gspca_dev,
1816 (unsigned int) (expotimes << 8));
1819 /* case SENSOR_MO4000: */
1820 /* case SENSOR_MI0360: */
1821 /* case SENSOR_MT9V111: */
1822 /* case SENSOR_OM6802: */
1823 expotimes = sd->exposure;
1824 expotimes += (luma_mean - delta) >> 6;
1827 sd->exposure = setexposure(gspca_dev,
1828 (unsigned int) expotimes);
1829 setredblue(gspca_dev);
1835 /* scan the URB packets */
1836 /* This function is run at interrupt level. */
1837 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1838 struct gspca_frame *frame, /* target */
1839 u8 *data, /* isoc packet */
1840 int len) /* iso packet length */
1842 struct sd *sd = (struct sd *) gspca_dev;
1846 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1849 gspca_frame_add(gspca_dev, LAST_PACKET,
1850 frame, data, sof + 2);
1857 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1859 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1861 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1863 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1865 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1867 atomic_set(&sd->avg_lum, avg_lum);
1870 if (gspca_dev->last_packet_type == LAST_PACKET) {
1872 /* put the JPEG 422 header */
1873 jpeg_put_header(gspca_dev, frame, 0x21);
1875 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1878 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1880 struct sd *sd = (struct sd *) gspca_dev;
1882 sd->brightness = val;
1883 if (gspca_dev->streaming)
1884 setbrightness(gspca_dev);
1888 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1890 struct sd *sd = (struct sd *) gspca_dev;
1892 *val = sd->brightness;
1896 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1898 struct sd *sd = (struct sd *) gspca_dev;
1901 if (gspca_dev->streaming)
1902 setcontrast(gspca_dev);
1906 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1908 struct sd *sd = (struct sd *) gspca_dev;
1910 *val = sd->contrast;
1914 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1916 struct sd *sd = (struct sd *) gspca_dev;
1919 if (gspca_dev->streaming)
1920 setcolors(gspca_dev);
1924 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1926 struct sd *sd = (struct sd *) gspca_dev;
1932 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1934 struct sd *sd = (struct sd *) gspca_dev;
1937 if (gspca_dev->streaming)
1938 setredblue(gspca_dev);
1942 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1944 struct sd *sd = (struct sd *) gspca_dev;
1950 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1952 struct sd *sd = (struct sd *) gspca_dev;
1955 if (gspca_dev->streaming)
1956 setredblue(gspca_dev);
1960 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1962 struct sd *sd = (struct sd *) gspca_dev;
1968 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1970 struct sd *sd = (struct sd *) gspca_dev;
1973 if (gspca_dev->streaming)
1974 setgamma(gspca_dev);
1978 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1980 struct sd *sd = (struct sd *) gspca_dev;
1986 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1988 struct sd *sd = (struct sd *) gspca_dev;
1991 if (gspca_dev->streaming)
1992 setautogain(gspca_dev);
1996 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1998 struct sd *sd = (struct sd *) gspca_dev;
2000 *val = sd->autogain;
2004 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2006 struct sd *sd = (struct sd *) gspca_dev;
2009 if (gspca_dev->streaming)
2014 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2016 struct sd *sd = (struct sd *) gspca_dev;
2022 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2024 struct sd *sd = (struct sd *) gspca_dev;
2027 if (gspca_dev->streaming)
2032 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2034 struct sd *sd = (struct sd *) gspca_dev;
2036 *val = sd->infrared;
2040 /* sub-driver description */
2041 static const struct sd_desc sd_desc = {
2042 .name = MODULE_NAME,
2044 .nctrls = ARRAY_SIZE(sd_ctrls),
2045 .config = sd_config,
2049 .pkt_scan = sd_pkt_scan,
2050 .dq_callback = do_autogain,
2053 /* -- module initialisation -- */
2054 #define BSI(bridge, sensor, i2c_addr) \
2055 .driver_info = (BRIDGE_ ## bridge << 16) \
2056 | (SENSOR_ ## sensor << 8) \
2058 static const __devinitdata struct usb_device_id device_table[] = {
2059 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2060 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
2061 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
2063 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2064 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
2065 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2066 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
2068 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2069 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2070 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2071 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2073 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2074 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2075 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2076 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2077 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
2078 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
2079 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2080 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2081 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2082 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2083 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2084 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2085 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2086 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2087 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2089 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2090 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2091 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2092 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2094 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
2095 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
2096 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
2097 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
2098 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2099 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
2101 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
2102 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
2103 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2104 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2105 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2106 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
2108 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
2111 MODULE_DEVICE_TABLE(usb, device_table);
2113 /* -- device connect -- */
2114 static int sd_probe(struct usb_interface *intf,
2115 const struct usb_device_id *id)
2117 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2121 static struct usb_driver sd_driver = {
2122 .name = MODULE_NAME,
2123 .id_table = device_table,
2125 .disconnect = gspca_disconnect,
2127 .suspend = gspca_suspend,
2128 .resume = gspca_resume,
2132 /* -- module insert / remove -- */
2133 static int __init sd_mod_init(void)
2136 ret = usb_register(&sd_driver);
2142 static void __exit sd_mod_exit(void)
2144 usb_deregister(&sd_driver);
2145 info("deregistered");
2148 module_init(sd_mod_init);
2149 module_exit(sd_mod_exit);