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/ov7648 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,
195 /* ov7630/ov7648 only */
199 .id = V4L2_CID_VFLIP,
200 .type = V4L2_CTRL_TYPE_BOOLEAN,
205 #define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
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 */
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, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
521 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
522 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
523 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
524 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
525 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
526 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
527 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
528 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
529 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
530 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
531 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
532 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
533 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
534 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
535 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
536 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
537 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
538 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
539 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
540 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
541 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
543 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
544 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
545 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
546 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
547 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
549 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
550 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
551 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
552 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
555 static const u8 om6802_sensor_init[][8] = {
556 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
557 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
558 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
559 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
560 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
561 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
562 /* white balance & auto-exposure */
563 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
565 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
566 * max AGC value in AE */
567 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
569 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
570 * preset brightness */
571 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
573 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
575 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
576 /* luminance mode (0x4f = AE) */
577 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
579 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
581 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
583 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
584 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
585 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
586 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
589 static const u8 ov7630_sensor_init[][8] = {
590 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
591 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
592 /* win: delay 20ms */
593 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
594 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
595 /* win: delay 20ms */
596 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
597 /* win: i2c_r from 00 to 80 */
598 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
599 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
600 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
601 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
602 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
603 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
605 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
606 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
607 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
608 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
609 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
610 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
611 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
612 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
613 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
614 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
615 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
616 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
617 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
618 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
619 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
620 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
621 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
622 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
623 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
627 /*fixme: + 0x12, 0x04*/
628 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
630 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
631 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
632 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
634 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
636 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
638 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
639 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
643 static const u8 ov7648_sensor_init[][8] = {
644 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
645 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
646 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
647 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
648 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
649 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
650 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
651 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
652 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
653 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
654 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
655 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
656 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
657 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
658 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
659 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
660 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
661 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
662 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
663 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
664 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
666 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
667 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
668 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
669 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
671 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
672 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
674 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
675 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
676 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
677 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
678 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
680 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
681 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
682 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
683 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
684 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
685 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
690 static const u8 ov7660_sensor_init[][8] = {
691 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
693 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
694 /* Outformat = rawRGB */
695 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
696 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
697 /* GAIN BLUE RED VREF */
698 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
699 /* COM 1 BAVE GEAVE AECHH */
700 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
701 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
702 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
703 /* AECH CLKRC COM7 COM8 */
704 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
705 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
706 /* HSTART HSTOP VSTRT VSTOP */
707 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
708 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
709 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
710 /* BOS GBOS GROS ROS (BGGR offset) */
711 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
712 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
713 /* AEW AEB VPT BBIAS */
714 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
715 /* GbBIAS RSVD EXHCH EXHCL */
716 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
717 /* RBIAS ADVFL ASDVFH YAVE */
718 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
719 /* HSYST HSYEN HREF */
720 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
721 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
722 /* ADC ACOM OFON TSLB */
723 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
724 /* COM11 COM12 COM13 COM14 */
725 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
726 /* EDGE COM15 COM16 COM17 */
727 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
728 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
729 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
730 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
731 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
732 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
733 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
734 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
735 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
736 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
737 /* LCC1 LCC2 LCC3 LCC4 */
738 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
739 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
740 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
741 /* band gap reference [0:3] DBLV */
742 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
743 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
744 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
745 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
746 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
747 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
748 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
749 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
750 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
751 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
752 /****** (some exchanges in the win trace) ******/
753 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
754 /* bits[3..0]reserved */
755 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
756 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
757 /* VREF vertical frame ctrl */
758 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
759 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
760 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
761 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
762 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
763 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
764 /****** (some exchanges in the win trace) ******/
765 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
766 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
767 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
768 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
769 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
770 /****** (some exchanges in the win trace) ******/
771 /******!! startsensor KO if changed !!****/
772 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
779 static const u8 sp80708_sensor_init[][8] = {
780 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
847 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
848 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
849 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
850 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
852 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
853 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
854 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
856 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
857 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
858 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
862 static const u8 qtable4[] = {
863 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
864 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
865 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
866 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
867 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
868 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
869 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
870 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
871 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
872 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
873 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
874 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
875 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
876 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
877 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
878 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
881 /* read <len> bytes to gspca_dev->usb_buf */
882 static void reg_r(struct gspca_dev *gspca_dev,
886 if (len > USB_BUF_SZ) {
887 err("reg_r: buffer overflow");
891 usb_control_msg(gspca_dev->dev,
892 usb_rcvctrlpipe(gspca_dev->dev, 0),
894 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
896 gspca_dev->usb_buf, len,
898 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
901 static void reg_w1(struct gspca_dev *gspca_dev,
905 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
906 gspca_dev->usb_buf[0] = data;
907 usb_control_msg(gspca_dev->dev,
908 usb_sndctrlpipe(gspca_dev->dev, 0),
910 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
913 gspca_dev->usb_buf, 1,
916 static void reg_w(struct gspca_dev *gspca_dev,
921 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
922 value, buffer[0], buffer[1]);
924 if (len > USB_BUF_SZ) {
925 err("reg_w: buffer overflow");
929 memcpy(gspca_dev->usb_buf, buffer, len);
930 usb_control_msg(gspca_dev->dev,
931 usb_sndctrlpipe(gspca_dev->dev, 0),
933 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
935 gspca_dev->usb_buf, len,
939 /* I2C write 1 byte */
940 static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
942 struct sd *sd = (struct sd *) gspca_dev;
944 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
945 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
946 gspca_dev->usb_buf[1] = sd->i2c_base;
947 gspca_dev->usb_buf[2] = reg;
948 gspca_dev->usb_buf[3] = val;
949 gspca_dev->usb_buf[4] = 0;
950 gspca_dev->usb_buf[5] = 0;
951 gspca_dev->usb_buf[6] = 0;
952 gspca_dev->usb_buf[7] = 0x10;
953 usb_control_msg(gspca_dev->dev,
954 usb_sndctrlpipe(gspca_dev->dev, 0),
956 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
957 0x08, /* value = i2c */
959 gspca_dev->usb_buf, 8,
963 /* I2C write 8 bytes */
964 static void i2c_w8(struct gspca_dev *gspca_dev,
967 memcpy(gspca_dev->usb_buf, buffer, 8);
968 usb_control_msg(gspca_dev->dev,
969 usb_sndctrlpipe(gspca_dev->dev, 0),
971 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
972 0x08, 0, /* value, index */
973 gspca_dev->usb_buf, 8,
978 /* read 5 bytes in gspca_dev->usb_buf */
979 static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
981 struct sd *sd = (struct sd *) gspca_dev;
984 mode[0] = 0x81 | 0x10;
985 mode[1] = sd->i2c_base;
992 i2c_w8(gspca_dev, mode);
994 mode[0] = 0x81 | (5 << 4) | 0x02;
996 i2c_w8(gspca_dev, mode);
998 reg_r(gspca_dev, 0x0a, 5);
1001 static int hv7131r_probe(struct gspca_dev *gspca_dev)
1003 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
1005 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
1007 i2c_r5(gspca_dev, 0); /* read sensor id */
1008 if (gspca_dev->usb_buf[0] == 0x02
1009 && gspca_dev->usb_buf[1] == 0x09
1010 && gspca_dev->usb_buf[2] == 0x01
1011 && gspca_dev->usb_buf[3] == 0x00
1012 && gspca_dev->usb_buf[4] == 0x00) {
1013 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
1016 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
1017 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1018 gspca_dev->usb_buf[2]);
1019 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1023 static void mi0360_probe(struct gspca_dev *gspca_dev)
1025 struct sd *sd = (struct sd *) gspca_dev;
1028 static const u8 probe_tb[][4][8] = {
1030 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1031 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1032 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1033 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1036 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1037 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1038 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1043 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1044 reg_w1(gspca_dev, 0x17, 0x62);
1045 reg_w1(gspca_dev, 0x01, 0x08);
1046 for (j = 0; j < 3; j++)
1047 i2c_w8(gspca_dev, probe_tb[i][j]);
1049 reg_r(gspca_dev, 0x0a, 5);
1050 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1051 if (probe_tb[i][3][0] != 0)
1052 i2c_w8(gspca_dev, probe_tb[i][3]);
1053 reg_w1(gspca_dev, 0x01, 0x29);
1054 reg_w1(gspca_dev, 0x17, 0x42);
1060 PDEBUG(D_PROBE, "Sensor mt9v111");
1061 sd->sensor = SENSOR_MT9V111;
1062 sd->i2c_base = 0x5c;
1065 PDEBUG(D_PROBE, "Sensor mi0360");
1068 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1073 static int configure_gpio(struct gspca_dev *gspca_dev,
1076 struct sd *sd = (struct sd *) gspca_dev;
1078 static const u8 reg9a_def[] =
1079 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
1080 static const u8 reg9a_sn9c325[] =
1081 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
1082 static const u8 regd4[] = {0x60, 0x00, 0x00};
1084 reg_w1(gspca_dev, 0xf1, 0x00);
1085 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1087 /* configure gpio */
1088 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1089 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
1090 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
1091 switch (sd->bridge) {
1092 case BRIDGE_SN9C325:
1093 reg9a = reg9a_sn9c325;
1099 reg_w(gspca_dev, 0x9a, reg9a, 6);
1101 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
1103 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
1105 switch (sd->sensor) {
1106 case SENSOR_MT9V111:
1107 reg_w1(gspca_dev, 0x01, 0x61);
1108 reg_w1(gspca_dev, 0x17, 0x61);
1109 reg_w1(gspca_dev, 0x01, 0x60);
1110 reg_w1(gspca_dev, 0x01, 0x40);
1113 reg_w1(gspca_dev, 0x02, 0x71);
1114 reg_w1(gspca_dev, 0x01, 0x42);
1115 reg_w1(gspca_dev, 0x17, 0x64);
1116 reg_w1(gspca_dev, 0x01, 0x42);
1118 /*jfm: from win trace */
1120 reg_w1(gspca_dev, 0x01, 0x61);
1121 reg_w1(gspca_dev, 0x17, 0xe2);
1122 reg_w1(gspca_dev, 0x01, 0x60);
1123 reg_w1(gspca_dev, 0x01, 0x40);
1126 reg_w1(gspca_dev, 0x01, 0x63);
1127 reg_w1(gspca_dev, 0x17, 0x20);
1128 reg_w1(gspca_dev, 0x01, 0x42);
1130 /*jfm: from win trace */
1132 if (sd->bridge == BRIDGE_SN9C120) {
1133 reg_w1(gspca_dev, 0x01, 0x61);
1134 reg_w1(gspca_dev, 0x17, 0x20);
1135 reg_w1(gspca_dev, 0x01, 0x60);
1136 reg_w1(gspca_dev, 0x01, 0x40);
1140 case SENSOR_SP80708:
1141 reg_w1(gspca_dev, 0x01, 0x63);
1142 reg_w1(gspca_dev, 0x17, 0x20);
1143 reg_w1(gspca_dev, 0x01, 0x62);
1144 reg_w1(gspca_dev, 0x01, 0x42);
1146 reg_w1(gspca_dev, 0x02, 0x62);
1149 reg_w1(gspca_dev, 0x01, 0x43);
1150 reg_w1(gspca_dev, 0x17, 0x61);
1151 reg_w1(gspca_dev, 0x01, 0x42);
1152 if (sd->sensor == SENSOR_HV7131R) {
1153 if (hv7131r_probe(gspca_dev) < 0)
1161 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1164 static const u8 SetSensorClk[] = /* 0x08 Mclk */
1165 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1167 while (hv7131r_sensor_init[i][0]) {
1168 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
1171 i2c_w8(gspca_dev, SetSensorClk);
1174 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1178 while (mi0360_sensor_init[i][0]) {
1179 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1184 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1188 while (mo4000_sensor_init[i][0]) {
1189 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1194 static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1198 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1201 while (mt9v111_sensor_init[i][0]) {
1202 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1207 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1211 while (om6802_sensor_init[i][0]) {
1212 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1217 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1221 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1223 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
1226 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1228 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1231 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1233 /*jfm:win i2c_r from 00 to 80*/
1235 while (ov7630_sensor_init[i][0]) {
1236 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1241 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1245 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1247 /* win: dble reset */
1248 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1251 /* win: i2c reg read 00..7f */
1252 while (ov7648_sensor_init[i][0]) {
1253 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1258 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1262 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1265 while (ov7660_sensor_init[i][0]) {
1266 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1271 static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1275 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1278 while (sp80708_sensor_init[i][0]) {
1279 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1284 /* this function is called at probe time */
1285 static int sd_config(struct gspca_dev *gspca_dev,
1286 const struct usb_device_id *id)
1288 struct sd *sd = (struct sd *) gspca_dev;
1291 cam = &gspca_dev->cam;
1292 cam->cam_mode = vga_mode;
1293 cam->nmodes = ARRAY_SIZE(vga_mode);
1295 sd->bridge = id->driver_info >> 16;
1296 sd->sensor = id->driver_info >> 8;
1297 sd->i2c_base = id->driver_info;
1299 sd->brightness = BRIGHTNESS_DEF;
1300 sd->contrast = CONTRAST_DEF;
1301 sd->colors = COLOR_DEF;
1302 sd->blue = BLUE_BALANCE_DEF;
1303 sd->red = RED_BALANCE_DEF;
1304 sd->gamma = GAMMA_DEF;
1305 sd->autogain = AUTOGAIN_DEF;
1307 if (sd->sensor != SENSOR_OV7630)
1311 sd->infrared = INFRARED_DEF;
1313 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1317 /* this function is called at probe and resume time */
1318 static int sd_init(struct gspca_dev *gspca_dev)
1320 struct sd *sd = (struct sd *) gspca_dev;
1321 u8 regGpio[] = { 0x29, 0x74 };
1324 /* setup a selector by bridge */
1325 reg_w1(gspca_dev, 0xf1, 0x01);
1326 reg_r(gspca_dev, 0x00, 1);
1327 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1328 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1329 regF1 = gspca_dev->usb_buf[0];
1330 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1331 switch (sd->bridge) {
1332 case BRIDGE_SN9C102P:
1335 reg_w1(gspca_dev, 0x02, regGpio[1]);
1337 case BRIDGE_SN9C105:
1340 if (sd->sensor == SENSOR_MI0360)
1341 mi0360_probe(gspca_dev);
1342 reg_w(gspca_dev, 0x01, regGpio, 2);
1344 case BRIDGE_SN9C120:
1347 if (sd->sensor == SENSOR_MI0360)
1348 mi0360_probe(gspca_dev);
1350 reg_w(gspca_dev, 0x01, regGpio, 2);
1353 /* case BRIDGE_SN9C110: */
1354 /* case BRIDGE_SN9C325: */
1357 reg_w1(gspca_dev, 0x02, 0x62);
1361 reg_w1(gspca_dev, 0xf1, 0x01);
1366 static u32 setexposure(struct gspca_dev *gspca_dev,
1369 struct sd *sd = (struct sd *) gspca_dev;
1371 switch (sd->sensor) {
1372 case SENSOR_HV7131R: {
1374 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1376 Expodoit[3] = expo >> 16;
1377 Expodoit[4] = expo >> 8;
1379 i2c_w8(gspca_dev, Expodoit);
1382 case SENSOR_MI0360: {
1383 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1384 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1385 static const u8 doit[] = /* update sensor */
1386 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1387 static const u8 sensorgo[] = /* sensor on */
1388 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1392 else if (expo < 0x0001)
1394 expoMi[3] = expo >> 8;
1396 i2c_w8(gspca_dev, expoMi);
1397 i2c_w8(gspca_dev, doit);
1398 i2c_w8(gspca_dev, sensorgo);
1401 case SENSOR_MO4000: {
1403 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1405 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1406 static const u8 gainMo[] =
1407 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1411 else if (expo < 0x0001)
1413 expoMof[3] = (expo & 0x03fc) >> 2;
1414 i2c_w8(gspca_dev, expoMof);
1415 expoMo10[3] = ((expo & 0x1c00) >> 10)
1416 | ((expo & 0x0003) << 4);
1417 i2c_w8(gspca_dev, expoMo10);
1418 i2c_w8(gspca_dev, gainMo);
1419 PDEBUG(D_FRAM, "set exposure %d",
1420 ((expoMo10[3] & 0x07) << 10)
1422 | ((expoMo10[3] & 0x30) >> 4));
1425 case SENSOR_MT9V111: {
1427 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1431 else if (expo < 0x0040)
1433 expo_c1[3] = expo >> 8;
1435 i2c_w8(gspca_dev, expo_c1);
1438 case SENSOR_OM6802: {
1440 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1446 gainOm[3] = expo >> 2;
1447 i2c_w8(gspca_dev, gainOm);
1448 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1449 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
1456 static void setbrightness(struct gspca_dev *gspca_dev)
1458 struct sd *sd = (struct sd *) gspca_dev;
1462 k2 = ((int) sd->brightness - 0x8000) >> 10;
1463 switch (sd->sensor) {
1464 case SENSOR_HV7131R:
1465 expo = sd->brightness << 4;
1466 if (expo > 0x002dc6c0)
1468 else if (expo < 0x02a0)
1470 sd->exposure = setexposure(gspca_dev, expo);
1474 expo = sd->brightness >> 4;
1475 sd->exposure = setexposure(gspca_dev, expo);
1477 case SENSOR_MT9V111:
1478 expo = sd->brightness >> 8;
1479 sd->exposure = setexposure(gspca_dev, expo);
1482 expo = sd->brightness >> 6;
1483 sd->exposure = setexposure(gspca_dev, expo);
1484 k2 = sd->brightness >> 11;
1488 if (sd->sensor != SENSOR_MT9V111)
1489 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1492 static void setcontrast(struct gspca_dev *gspca_dev)
1494 struct sd *sd = (struct sd *) gspca_dev;
1498 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1499 contrast[0] = (k2 + 1) / 2; /* red */
1501 contrast[2] = k2; /* green */
1503 contrast[4] = (k2 + 1) / 5; /* blue */
1505 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1508 static void setcolors(struct gspca_dev *gspca_dev)
1510 struct sd *sd = (struct sd *) gspca_dev;
1512 u8 reg8a[12]; /* U & V gains */
1513 static s16 uv[6] = { /* same as reg84 in signed decimal */
1514 -24, -38, 64, /* UR UG UB */
1515 62, -51, -9 /* VR VG VB */
1517 for (i = 0; i < 6; i++) {
1518 v = uv[i] * sd->colors / COLOR_DEF;
1520 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1522 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1525 static void setredblue(struct gspca_dev *gspca_dev)
1527 struct sd *sd = (struct sd *) gspca_dev;
1529 reg_w1(gspca_dev, 0x05, sd->red);
1530 /* reg_w1(gspca_dev, 0x07, 32); */
1531 reg_w1(gspca_dev, 0x06, sd->blue);
1534 static void setgamma(struct gspca_dev *gspca_dev)
1536 struct sd *sd = (struct sd *) gspca_dev;
1539 const u8 *gamma_base;
1540 static const u8 delta[17] = {
1541 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1542 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1545 switch (sd->sensor) {
1546 case SENSOR_HV7131R:
1547 case SENSOR_MT9V111:
1548 gamma_base = gamma_spec_1;
1550 case SENSOR_SP80708:
1551 gamma_base = gamma_spec_2;
1554 gamma_base = gamma_def;
1558 for (i = 0; i < sizeof gamma; i++)
1559 gamma[i] = gamma_base[i]
1560 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1561 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1564 static void setautogain(struct gspca_dev *gspca_dev)
1566 struct sd *sd = (struct sd *) gspca_dev;
1568 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1570 switch (sd->sensor) {
1572 case SENSOR_OV7648: {
1575 if (sd->sensor == SENSOR_OV7630)
1581 i2c_w1(&sd->gspca_dev, 0x13, comb);
1586 sd->ag_cnt = AG_CNT_START;
1591 /* ov7630/ov7648 only */
1592 static void setvflip(struct sd *sd)
1596 if (sd->sensor == SENSOR_OV7630)
1602 i2c_w1(&sd->gspca_dev, 0x75, comn);
1605 static void setinfrared(struct sd *sd)
1607 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1609 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1610 sd->infrared ? 0x66 : 0x64);
1613 /* -- start the camera -- */
1614 static int sd_start(struct gspca_dev *gspca_dev)
1616 struct sd *sd = (struct sd *) gspca_dev;
1618 u8 reg1, reg17, reg18;
1621 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1622 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1623 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1624 static const u8 CE_ov76xx[] =
1625 { 0x32, 0xdd, 0x32, 0xdd };
1627 sn9c1xx = sn_tb[(int) sd->sensor];
1628 configure_gpio(gspca_dev, sn9c1xx);
1630 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1631 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1632 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1633 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1634 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1635 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1636 reg_w1(gspca_dev, 0xd3, 0x50);
1637 reg_w1(gspca_dev, 0xc6, 0x00);
1638 reg_w1(gspca_dev, 0xc7, 0x00);
1639 reg_w1(gspca_dev, 0xc8, 0x50);
1640 reg_w1(gspca_dev, 0xc9, 0x3c);
1641 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1642 switch (sd->sensor) {
1643 case SENSOR_MT9V111:
1652 /*jfm: from win trace */
1654 if (sd->bridge == BRIDGE_SN9C120) {
1663 reg_w1(gspca_dev, 0x17, reg17);
1664 /* set reg1 was here */
1665 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1666 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1667 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1668 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1670 setgamma(gspca_dev);
1672 for (i = 0; i < 8; i++)
1673 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1674 switch (sd->sensor) {
1675 case SENSOR_MT9V111:
1676 reg_w1(gspca_dev, 0x9a, 0x07);
1677 reg_w1(gspca_dev, 0x99, 0x59);
1680 reg_w1(gspca_dev, 0x9a, 0x0a);
1681 reg_w1(gspca_dev, 0x99, 0x60);
1683 case SENSOR_SP80708:
1684 reg_w1(gspca_dev, 0x9a, 0x05);
1685 reg_w1(gspca_dev, 0x99, 0x59);
1688 if (sd->bridge == BRIDGE_SN9C120) {
1689 reg_w1(gspca_dev, 0x9a, 0x05);
1694 reg_w1(gspca_dev, 0x9a, 0x08);
1695 reg_w1(gspca_dev, 0x99, 0x59);
1699 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1701 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1703 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1704 reg17 = 0x61; /* 0x:20: enable sensor clock */
1705 switch (sd->sensor) {
1706 case SENSOR_HV7131R:
1707 hv7131R_InitSensor(gspca_dev);
1710 mi0360_InitSensor(gspca_dev);
1713 mo4000_InitSensor(gspca_dev);
1715 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1716 reg1 = 0x06; /* clk 24Mz */
1718 reg17 = 0x22; /* 640 MCKSIZE */
1719 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1722 case SENSOR_MT9V111:
1723 mt9v111_InitSensor(gspca_dev);
1725 reg1 = 0x04; /* 320 clk 48Mhz */
1727 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1732 om6802_InitSensor(gspca_dev);
1733 reg17 = 0x64; /* 640 MCKSIZE */
1736 ov7630_InitSensor(gspca_dev);
1742 ov7648_InitSensor(gspca_dev);
1744 /* reg1 = 0x42; * 42 - 46? */
1747 ov7660_InitSensor(gspca_dev);
1748 if (sd->bridge == BRIDGE_SN9C120) {
1749 if (mode) { /* 320x240 - 160x120 */
1751 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1755 reg1 = 0x06; /* 24 Mhz, video trf eneble
1756 * inverse power down */
1760 /* case SENSOR_SP80708: */
1761 sp80708_InitSensor(gspca_dev);
1763 /*?? reg1 = 0x04; * 320 clk 48Mhz */
1765 reg1 = 0x46; /* 640 clk 48Mz */
1770 reg_w(gspca_dev, 0xc0, C0, 6);
1771 reg_w(gspca_dev, 0xca, CA, 4);
1772 switch (sd->sensor) {
1776 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1779 reg_w(gspca_dev, 0xce, CE, 4);
1780 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1784 /* here change size mode 0 -> VGA; 1 -> CIF */
1785 reg18 = sn9c1xx[0x18] | (mode << 4);
1786 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1788 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1789 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
1791 reg_w1(gspca_dev, 0x18, reg18);
1793 reg_w1(gspca_dev, 0x17, reg17);
1794 reg_w1(gspca_dev, 0x01, reg1);
1795 switch (sd->sensor) {
1800 setbrightness(gspca_dev);
1801 setcontrast(gspca_dev);
1802 setautogain(gspca_dev);
1806 static void sd_stopN(struct gspca_dev *gspca_dev)
1808 struct sd *sd = (struct sd *) gspca_dev;
1809 static const u8 stophv7131[] =
1810 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1811 static const u8 stopmi0360[] =
1812 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1813 static const u8 stopov7648[] =
1814 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1819 switch (sd->sensor) {
1820 case SENSOR_HV7131R:
1821 i2c_w8(gspca_dev, stophv7131);
1825 i2c_w8(gspca_dev, stopmi0360);
1829 i2c_w8(gspca_dev, stopov7648);
1831 case SENSOR_MT9V111:
1836 /* case SENSOR_MO4000: */
1837 /* case SENSOR_OV7660: */
1840 sn9c1xx = sn_tb[(int) sd->sensor];
1841 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1842 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1843 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1844 reg_w1(gspca_dev, 0x01, data);
1845 reg_w1(gspca_dev, 0xf1, 0x00);
1848 static void do_autogain(struct gspca_dev *gspca_dev)
1850 struct sd *sd = (struct sd *) gspca_dev;
1856 /* Thanks S., without your advice, autobright should not work :) */
1859 if (--sd->ag_cnt >= 0)
1861 sd->ag_cnt = AG_CNT_START;
1863 delta = atomic_read(&sd->avg_lum);
1864 PDEBUG(D_FRAM, "mean lum %d", delta);
1865 if (delta < luma_mean - luma_delta ||
1866 delta > luma_mean + luma_delta) {
1867 switch (sd->sensor) {
1868 case SENSOR_HV7131R:
1869 expotimes = sd->exposure >> 8;
1870 expotimes += (luma_mean - delta) >> 4;
1873 sd->exposure = setexposure(gspca_dev,
1874 (unsigned int) (expotimes << 8));
1877 /* case SENSOR_MO4000: */
1878 /* case SENSOR_MI0360: */
1879 /* case SENSOR_MT9V111: */
1880 /* case SENSOR_OM6802: */
1881 expotimes = sd->exposure;
1882 expotimes += (luma_mean - delta) >> 6;
1885 sd->exposure = setexposure(gspca_dev,
1886 (unsigned int) expotimes);
1887 setredblue(gspca_dev);
1893 /* scan the URB packets */
1894 /* This function is run at interrupt level. */
1895 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1896 struct gspca_frame *frame, /* target */
1897 u8 *data, /* isoc packet */
1898 int len) /* iso packet length */
1900 struct sd *sd = (struct sd *) gspca_dev;
1904 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1907 gspca_frame_add(gspca_dev, LAST_PACKET,
1908 frame, data, sof + 2);
1915 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1917 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1919 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1921 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1923 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1925 atomic_set(&sd->avg_lum, avg_lum);
1928 if (gspca_dev->last_packet_type == LAST_PACKET) {
1930 /* put the JPEG 422 header */
1931 jpeg_put_header(gspca_dev, frame, 0x21);
1933 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1936 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1938 struct sd *sd = (struct sd *) gspca_dev;
1940 sd->brightness = val;
1941 if (gspca_dev->streaming)
1942 setbrightness(gspca_dev);
1946 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1948 struct sd *sd = (struct sd *) gspca_dev;
1950 *val = sd->brightness;
1954 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1956 struct sd *sd = (struct sd *) gspca_dev;
1959 if (gspca_dev->streaming)
1960 setcontrast(gspca_dev);
1964 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1966 struct sd *sd = (struct sd *) gspca_dev;
1968 *val = sd->contrast;
1972 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1974 struct sd *sd = (struct sd *) gspca_dev;
1977 if (gspca_dev->streaming)
1978 setcolors(gspca_dev);
1982 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1984 struct sd *sd = (struct sd *) gspca_dev;
1990 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1992 struct sd *sd = (struct sd *) gspca_dev;
1995 if (gspca_dev->streaming)
1996 setredblue(gspca_dev);
2000 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2002 struct sd *sd = (struct sd *) gspca_dev;
2008 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2010 struct sd *sd = (struct sd *) gspca_dev;
2013 if (gspca_dev->streaming)
2014 setredblue(gspca_dev);
2018 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2020 struct sd *sd = (struct sd *) gspca_dev;
2026 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2028 struct sd *sd = (struct sd *) gspca_dev;
2031 if (gspca_dev->streaming)
2032 setgamma(gspca_dev);
2036 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2038 struct sd *sd = (struct sd *) gspca_dev;
2044 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2046 struct sd *sd = (struct sd *) gspca_dev;
2049 if (gspca_dev->streaming)
2050 setautogain(gspca_dev);
2054 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2056 struct sd *sd = (struct sd *) gspca_dev;
2058 *val = sd->autogain;
2062 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2064 struct sd *sd = (struct sd *) gspca_dev;
2067 if (gspca_dev->streaming)
2072 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2074 struct sd *sd = (struct sd *) gspca_dev;
2080 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2082 struct sd *sd = (struct sd *) gspca_dev;
2085 if (gspca_dev->streaming)
2090 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2092 struct sd *sd = (struct sd *) gspca_dev;
2094 *val = sd->infrared;
2098 /* sub-driver description */
2099 static const struct sd_desc sd_desc = {
2100 .name = MODULE_NAME,
2102 .nctrls = ARRAY_SIZE(sd_ctrls),
2103 .config = sd_config,
2107 .pkt_scan = sd_pkt_scan,
2108 .dq_callback = do_autogain,
2111 /* -- module initialisation -- */
2112 #define BSI(bridge, sensor, i2c_addr) \
2113 .driver_info = (BRIDGE_ ## bridge << 16) \
2114 | (SENSOR_ ## sensor << 8) \
2116 static const __devinitdata struct usb_device_id device_table[] = {
2117 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2118 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
2119 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
2121 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2122 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
2123 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2124 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
2126 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
2127 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
2128 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
2129 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2131 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2132 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2133 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2134 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2135 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
2136 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
2137 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2138 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2139 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2140 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2141 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2142 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2143 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
2144 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2145 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2147 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2148 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2149 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
2150 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2152 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
2153 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
2154 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
2155 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
2156 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2157 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
2159 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
2160 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
2161 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2162 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2164 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2165 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
2166 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
2169 MODULE_DEVICE_TABLE(usb, device_table);
2171 /* -- device connect -- */
2172 static int sd_probe(struct usb_interface *intf,
2173 const struct usb_device_id *id)
2175 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2179 static struct usb_driver sd_driver = {
2180 .name = MODULE_NAME,
2181 .id_table = device_table,
2183 .disconnect = gspca_disconnect,
2185 .suspend = gspca_suspend,
2186 .resume = gspca_resume,
2190 /* -- module insert / remove -- */
2191 static int __init sd_mod_init(void)
2194 ret = usb_register(&sd_driver);
2200 static void __exit sd_mod_exit(void)
2202 usb_deregister(&sd_driver);
2203 info("deregistered");
2206 module_init(sd_mod_init);
2207 module_exit(sd_mod_exit);