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
72 /* V4L2 controls supported by the driver */
73 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
);
74 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
);
75 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
);
76 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
);
77 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
);
78 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
);
79 static int sd_setblue_balance(struct gspca_dev
*gspca_dev
, __s32 val
);
80 static int sd_getblue_balance(struct gspca_dev
*gspca_dev
, __s32
*val
);
81 static int sd_setred_balance(struct gspca_dev
*gspca_dev
, __s32 val
);
82 static int sd_getred_balance(struct gspca_dev
*gspca_dev
, __s32
*val
);
83 static int sd_setgamma(struct gspca_dev
*gspca_dev
, __s32 val
);
84 static int sd_getgamma(struct gspca_dev
*gspca_dev
, __s32
*val
);
85 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
);
86 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
);
87 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
);
88 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
);
89 static int sd_setinfrared(struct gspca_dev
*gspca_dev
, __s32 val
);
90 static int sd_getinfrared(struct gspca_dev
*gspca_dev
, __s32
*val
);
92 static struct ctrl sd_ctrls
[] = {
95 .id
= V4L2_CID_BRIGHTNESS
,
96 .type
= V4L2_CTRL_TYPE_INTEGER
,
99 #define BRIGHTNESS_MAX 0xffff
100 .maximum
= BRIGHTNESS_MAX
,
102 #define BRIGHTNESS_DEF 0x8000
103 .default_value
= BRIGHTNESS_DEF
,
105 .set
= sd_setbrightness
,
106 .get
= sd_getbrightness
,
110 .id
= V4L2_CID_CONTRAST
,
111 .type
= V4L2_CTRL_TYPE_INTEGER
,
114 #define CONTRAST_MAX 127
115 .maximum
= CONTRAST_MAX
,
117 #define CONTRAST_DEF 63
118 .default_value
= CONTRAST_DEF
,
120 .set
= sd_setcontrast
,
121 .get
= sd_getcontrast
,
125 .id
= V4L2_CID_SATURATION
,
126 .type
= V4L2_CTRL_TYPE_INTEGER
,
132 .default_value
= COLOR_DEF
,
139 .id
= V4L2_CID_BLUE_BALANCE
,
140 .type
= V4L2_CTRL_TYPE_INTEGER
,
141 .name
= "Blue Balance",
145 #define BLUE_BALANCE_DEF 32
146 .default_value
= BLUE_BALANCE_DEF
,
148 .set
= sd_setblue_balance
,
149 .get
= sd_getblue_balance
,
153 .id
= V4L2_CID_RED_BALANCE
,
154 .type
= V4L2_CTRL_TYPE_INTEGER
,
155 .name
= "Red Balance",
159 #define RED_BALANCE_DEF 32
160 .default_value
= RED_BALANCE_DEF
,
162 .set
= sd_setred_balance
,
163 .get
= sd_getred_balance
,
167 .id
= V4L2_CID_GAMMA
,
168 .type
= V4L2_CTRL_TYPE_INTEGER
,
174 .default_value
= GAMMA_DEF
,
179 #define AUTOGAIN_IDX 5
182 .id
= V4L2_CID_AUTOGAIN
,
183 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
188 #define AUTOGAIN_DEF 1
189 .default_value
= AUTOGAIN_DEF
,
191 .set
= sd_setautogain
,
192 .get
= sd_getautogain
,
198 .id
= V4L2_CID_VFLIP
,
199 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
205 .default_value
= VFLIP_DEF
,
211 #define INFRARED_IDX 7
214 .id
= V4L2_CID_INFRARED
,
215 .type
= V4L2_CTRL_TYPE_BOOLEAN
,
220 #define INFRARED_DEF 0
221 .default_value
= INFRARED_DEF
,
223 .set
= sd_setinfrared
,
224 .get
= sd_getinfrared
,
228 /* table of the disabled controls */
229 static __u32 ctrl_dis
[] = {
230 (1 << INFRARED_IDX
) | (1 << VFLIP_IDX
),
231 /* SENSOR_HV7131R 0 */
232 (1 << INFRARED_IDX
) | (1 << VFLIP_IDX
),
233 /* SENSOR_MI0360 1 */
234 (1 << INFRARED_IDX
) | (1 << VFLIP_IDX
),
235 /* SENSOR_MO4000 2 */
237 /* SENSOR_MT9V111 3 */
238 (1 << INFRARED_IDX
) | (1 << VFLIP_IDX
),
239 /* SENSOR_OM6802 4 */
240 (1 << AUTOGAIN_IDX
) | (1 << INFRARED_IDX
),
241 /* SENSOR_OV7630 5 */
242 (1 << AUTOGAIN_IDX
) | (1 << INFRARED_IDX
) | (1 << VFLIP_IDX
),
243 /* SENSOR_OV7648 6 */
244 (1 << AUTOGAIN_IDX
) | (1 << INFRARED_IDX
) | (1 << VFLIP_IDX
),
245 /* SENSOR_OV7660 7 */
248 static const struct v4l2_pix_format vga_mode
[] = {
249 {160, 120, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
251 .sizeimage
= 160 * 120 * 4 / 8 + 590,
252 .colorspace
= V4L2_COLORSPACE_JPEG
,
254 {320, 240, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
256 .sizeimage
= 320 * 240 * 3 / 8 + 590,
257 .colorspace
= V4L2_COLORSPACE_JPEG
,
259 {640, 480, V4L2_PIX_FMT_JPEG
, V4L2_FIELD_NONE
,
261 .sizeimage
= 640 * 480 * 3 / 8 + 590,
262 .colorspace
= V4L2_COLORSPACE_JPEG
,
266 /*Data from sn9c102p+hv7131r */
267 static const u8 sn_hv7131
[0x1c] = {
268 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
269 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
270 /* reg8 reg9 rega regb regc regd rege regf */
271 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
272 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
273 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
274 /* reg18 reg19 reg1a reg1b */
275 0x0a, 0x00, 0x00, 0x00
278 static const u8 sn_mi0360
[0x1c] = {
279 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
280 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
281 /* reg8 reg9 rega regb regc regd rege regf */
282 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
283 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
284 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
285 /* reg18 reg19 reg1a reg1b */
286 0x06, 0x00, 0x00, 0x00
289 static const u8 sn_mo4000
[0x1c] = {
290 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
291 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
292 /* reg8 reg9 rega regb regc regd rege regf */
293 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
294 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
295 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
296 /* reg18 reg19 reg1a reg1b */
297 0x08, 0x00, 0x00, 0x00
300 static const u8 sn_mt9v111
[0x1c] = {
301 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
302 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
303 /* reg8 reg9 rega regb regc regd rege regf */
304 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
305 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
306 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
307 /* reg18 reg19 reg1a reg1b */
308 0x06, 0x00, 0x00, 0x00
311 static const u8 sn_om6802
[0x1c] = {
312 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
313 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
314 /* reg8 reg9 rega regb regc regd rege regf */
315 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
316 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
317 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
318 /* reg18 reg19 reg1a reg1b */
319 0x05, 0x00, 0x00, 0x00
322 static const u8 sn_ov7630
[0x1c] = {
323 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
324 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
325 /* reg8 reg9 rega regb regc regd rege regf */
326 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
327 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
328 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
329 /* reg18 reg19 reg1a reg1b */
330 0x0b, 0x00, 0x00, 0x00
333 static const u8 sn_ov7648
[0x1c] = {
334 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
335 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
336 /* reg8 reg9 rega regb regc regd rege regf */
337 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
338 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
339 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
340 /* reg18 reg19 reg1a reg1b */
341 0x0b, 0x00, 0x00, 0x00
344 static const u8 sn_ov7660
[0x1c] = {
345 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
346 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
347 /* reg8 reg9 rega regb regc regd rege regf */
348 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
349 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
350 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
351 /* reg18 reg19 reg1a reg1b */
352 0x07, 0x00, 0x00, 0x00
355 /* sequence specific to the sensors - !! index = SENSOR_xxx */
356 static const u8
*sn_tb
[] = {
367 static const u8 gamma_def
[17] = {
368 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
369 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
373 /* color matrix and offsets */
374 static const u8 reg84
[] = {
375 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
376 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
377 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
378 0x00, 0x00, 0x00 /* YUV offsets */
380 static const u8 hv7131r_sensor_init
[][8] = {
381 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
382 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
383 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
384 /* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
385 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
386 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
387 /* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
389 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
390 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
391 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
392 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
393 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
394 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
395 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
396 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
398 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
399 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
401 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
402 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
404 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
405 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
406 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
407 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
408 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
411 static const u8 mi0360_sensor_init
[][8] = {
412 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
413 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
414 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
415 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
416 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
417 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
418 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
419 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
420 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
422 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
424 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
426 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
428 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
429 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
430 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
431 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
432 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
434 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
435 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
436 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
437 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
438 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
439 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
440 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
441 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
444 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
446 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
447 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
448 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
449 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
450 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
452 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
453 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
454 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
455 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
457 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
458 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
459 /* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
460 /* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
461 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
462 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
465 static const u8 mo4000_sensor_init
[][8] = {
466 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
467 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
469 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
470 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
471 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
472 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
473 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
474 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
475 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
476 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
477 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
478 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
479 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
480 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
481 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
483 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
484 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
485 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
488 static const u8 mt9v111_sensor_init
[][8] = {
489 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
491 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
492 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
493 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
494 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
495 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
496 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
497 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
498 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
499 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
500 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
501 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
502 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
503 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
504 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
505 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
506 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
508 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
509 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
510 {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */
511 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
512 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
514 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
515 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
516 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
517 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
520 static const u8 om6802_sensor_init
[][8] = {
521 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
522 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
523 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
524 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
525 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
526 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
527 /* white balance & auto-exposure */
528 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
530 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
531 * max AGC value in AE */
532 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
534 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
535 * preset brightness */
536 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
538 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
540 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
541 /* luminance mode (0x4f = AE) */
542 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
544 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
546 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
548 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
549 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
550 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
551 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
554 static const u8 ov7630_sensor_init
[][8] = {
555 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
556 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
557 /* win: delay 20ms */
558 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
559 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
560 /* win: delay 20ms */
561 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
562 /* win: i2c_r from 00 to 80 */
563 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
564 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
565 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
566 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
567 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
568 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
569 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
570 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
571 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
572 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
573 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
574 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
575 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
576 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
577 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
578 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
579 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
580 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
581 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
582 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
583 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
584 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
585 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
586 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
587 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
588 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
590 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
591 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
592 /*fixme: + 0x12, 0x04*/
593 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
595 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
596 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
597 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
599 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
601 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
603 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
604 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
608 static const u8 ov7648_sensor_init
[][8] = {
609 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
610 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
611 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
612 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
613 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
614 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
615 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
616 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
617 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
618 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
619 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
620 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
621 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
622 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
623 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
624 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
625 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
626 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
627 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
628 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
629 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
631 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
632 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
633 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
634 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
636 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
637 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
638 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
639 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
640 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
641 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
642 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
644 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
645 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
646 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
647 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
648 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
649 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
654 static const u8 ov7660_sensor_init
[][8] = {
655 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
657 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
658 /* Outformat = rawRGB */
659 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
660 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
661 /* GAIN BLUE RED VREF */
662 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
663 /* COM 1 BAVE GEAVE AECHH */
664 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
665 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
666 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
667 /* AECH CLKRC COM7 COM8 */
668 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
669 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
670 /* HSTART HSTOP VSTRT VSTOP */
671 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
672 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
673 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
674 /* BOS GBOS GROS ROS (BGGR offset) */
675 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
676 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
677 /* AEW AEB VPT BBIAS */
678 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
679 /* GbBIAS RSVD EXHCH EXHCL */
680 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
681 /* RBIAS ADVFL ASDVFH YAVE */
682 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
683 /* HSYST HSYEN HREF */
684 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
685 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
686 /* ADC ACOM OFON TSLB */
687 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
688 /* COM11 COM12 COM13 COM14 */
689 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
690 /* EDGE COM15 COM16 COM17 */
691 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
692 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
693 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
694 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
695 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
696 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
697 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
698 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
699 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
700 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
701 /* LCC1 LCC2 LCC3 LCC4 */
702 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
703 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
704 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
705 /* band gap reference [0:3] DBLV */
706 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
707 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
708 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
709 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
710 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
711 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
712 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
713 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
714 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
715 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
716 /****** (some exchanges in the win trace) ******/
717 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
718 /* bits[3..0]reserved */
719 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
720 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
721 /* VREF vertical frame ctrl */
722 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
723 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
724 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
725 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
726 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
727 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
728 /****** (some exchanges in the win trace) ******/
729 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
730 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
731 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
732 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
733 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
734 /****** (some exchanges in the win trace) ******/
735 /******!! startsensor KO if changed !!****/
736 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
737 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
738 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
739 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
743 static const u8 qtable4
[] = {
744 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
745 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
746 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
747 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
748 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
749 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
750 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
751 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
752 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
753 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
754 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
755 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
756 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
757 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
758 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
759 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
762 /* read <len> bytes to gspca_dev->usb_buf */
763 static void reg_r(struct gspca_dev
*gspca_dev
,
767 if (len
> USB_BUF_SZ
) {
768 err("reg_r: buffer overflow");
772 usb_control_msg(gspca_dev
->dev
,
773 usb_rcvctrlpipe(gspca_dev
->dev
, 0),
775 USB_DIR_IN
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
777 gspca_dev
->usb_buf
, len
,
779 PDEBUG(D_USBI
, "reg_r [%02x] -> %02x", value
, gspca_dev
->usb_buf
[0]);
782 static void reg_w1(struct gspca_dev
*gspca_dev
,
786 PDEBUG(D_USBO
, "reg_w1 [%04x] = %02x", value
, data
);
787 gspca_dev
->usb_buf
[0] = data
;
788 usb_control_msg(gspca_dev
->dev
,
789 usb_sndctrlpipe(gspca_dev
->dev
, 0),
791 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
794 gspca_dev
->usb_buf
, 1,
797 static void reg_w(struct gspca_dev
*gspca_dev
,
802 PDEBUG(D_USBO
, "reg_w [%04x] = %02x %02x ..",
803 value
, buffer
[0], buffer
[1]);
805 if (len
> USB_BUF_SZ
) {
806 err("reg_w: buffer overflow");
810 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
811 usb_control_msg(gspca_dev
->dev
,
812 usb_sndctrlpipe(gspca_dev
->dev
, 0),
814 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
816 gspca_dev
->usb_buf
, len
,
820 /* I2C write 1 byte */
821 static void i2c_w1(struct gspca_dev
*gspca_dev
, u8 reg
, u8 val
)
823 struct sd
*sd
= (struct sd
*) gspca_dev
;
825 PDEBUG(D_USBO
, "i2c_w2 [%02x] = %02x", reg
, val
);
826 gspca_dev
->usb_buf
[0] = 0x81 | (2 << 4); /* = a1 */
827 gspca_dev
->usb_buf
[1] = sd
->i2c_base
;
828 gspca_dev
->usb_buf
[2] = reg
;
829 gspca_dev
->usb_buf
[3] = val
;
830 gspca_dev
->usb_buf
[4] = 0;
831 gspca_dev
->usb_buf
[5] = 0;
832 gspca_dev
->usb_buf
[6] = 0;
833 gspca_dev
->usb_buf
[7] = 0x10;
834 usb_control_msg(gspca_dev
->dev
,
835 usb_sndctrlpipe(gspca_dev
->dev
, 0),
837 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
838 0x08, /* value = i2c */
840 gspca_dev
->usb_buf
, 8,
844 /* I2C write 8 bytes */
845 static void i2c_w8(struct gspca_dev
*gspca_dev
,
848 memcpy(gspca_dev
->usb_buf
, buffer
, 8);
849 usb_control_msg(gspca_dev
->dev
,
850 usb_sndctrlpipe(gspca_dev
->dev
, 0),
852 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
853 0x08, 0, /* value, index */
854 gspca_dev
->usb_buf
, 8,
859 /* read 5 bytes in gspca_dev->usb_buf */
860 static void i2c_r5(struct gspca_dev
*gspca_dev
, u8 reg
)
862 struct sd
*sd
= (struct sd
*) gspca_dev
;
865 mode
[0] = 0x81 | 0x10;
866 mode
[1] = sd
->i2c_base
;
873 i2c_w8(gspca_dev
, mode
);
875 mode
[0] = 0x81 | (5 << 4) | 0x02;
877 i2c_w8(gspca_dev
, mode
);
879 reg_r(gspca_dev
, 0x0a, 5);
882 static int hv7131r_probe(struct gspca_dev
*gspca_dev
)
884 i2c_w1(gspca_dev
, 0x02, 0); /* sensor wakeup */
886 reg_w1(gspca_dev
, 0x02, 0x66); /* Gpio on */
888 i2c_r5(gspca_dev
, 0); /* read sensor id */
889 if (gspca_dev
->usb_buf
[0] == 0x02
890 && gspca_dev
->usb_buf
[1] == 0x09
891 && gspca_dev
->usb_buf
[2] == 0x01
892 && gspca_dev
->usb_buf
[3] == 0x00
893 && gspca_dev
->usb_buf
[4] == 0x00) {
894 PDEBUG(D_PROBE
, "Find Sensor sn9c102P HV7131R");
897 PDEBUG(D_PROBE
, "Find Sensor 0x%02x 0x%02x 0x%02x",
898 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1],
899 gspca_dev
->usb_buf
[2]);
900 PDEBUG(D_PROBE
, "Sensor sn9c102P Not found");
904 static int mi0360_probe(struct gspca_dev
*gspca_dev
)
908 static const u8 probe_tb
[][4][8] = {
910 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
911 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
912 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
913 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
916 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
917 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
918 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
923 for (i
= 0; i
< ARRAY_SIZE(probe_tb
); i
++) {
924 reg_w1(gspca_dev
, 0x17, 0x62);
925 reg_w1(gspca_dev
, 0x01, 0x08);
926 for (j
= 0; j
< 3; j
++)
927 i2c_w8(gspca_dev
, probe_tb
[i
][j
]);
929 reg_r(gspca_dev
, 0x0a, 5);
930 val
= (gspca_dev
->usb_buf
[3] << 8) | gspca_dev
->usb_buf
[4];
931 if (probe_tb
[i
][3][0] != 0)
932 i2c_w8(gspca_dev
, probe_tb
[i
][3]);
933 reg_w1(gspca_dev
, 0x01, 0x29);
934 reg_w1(gspca_dev
, 0x17, 0x42);
940 PDEBUG(D_PROBE
, "Sensor mt9v111");
941 return SENSOR_MT9V111
;
943 PDEBUG(D_PROBE
, "Sensor mi0360");
944 return SENSOR_MI0360
;
946 PDEBUG(D_PROBE
, "Unknown sensor %04x - forced to mi0360", val
);
947 return SENSOR_MI0360
;
950 static int configure_gpio(struct gspca_dev
*gspca_dev
,
953 struct sd
*sd
= (struct sd
*) gspca_dev
;
955 static const u8 reg9a_def
[] =
956 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
957 static const u8 reg9a_sn9c325
[] =
958 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
959 static const u8 regd4
[] = {0x60, 0x00, 0x00};
961 reg_w1(gspca_dev
, 0xf1, 0x00);
962 reg_w1(gspca_dev
, 0x01, sn9c1xx
[1]);
965 reg_w(gspca_dev
, 0x01, &sn9c1xx
[1], 2);
966 reg_w(gspca_dev
, 0x08, &sn9c1xx
[8], 2);
967 reg_w(gspca_dev
, 0x17, &sn9c1xx
[0x17], 5); /* jfm len was 3 */
968 switch (sd
->bridge
) {
970 reg9a
= reg9a_sn9c325
;
976 reg_w(gspca_dev
, 0x9a, reg9a
, 6);
978 reg_w(gspca_dev
, 0xd4, regd4
, sizeof regd4
); /*fixme:jfm was 60 only*/
980 reg_w(gspca_dev
, 0x03, &sn9c1xx
[3], 0x0f);
982 switch (sd
->sensor
) {
984 reg_w1(gspca_dev
, 0x01, 0x61);
985 reg_w1(gspca_dev
, 0x17, 0x61);
986 reg_w1(gspca_dev
, 0x01, 0x60);
987 reg_w1(gspca_dev
, 0x01, 0x40);
990 reg_w1(gspca_dev
, 0x02, 0x71);
991 reg_w1(gspca_dev
, 0x01, 0x42);
992 reg_w1(gspca_dev
, 0x17, 0x64);
993 reg_w1(gspca_dev
, 0x01, 0x42);
995 /*jfm: from win trace */
997 reg_w1(gspca_dev
, 0x01, 0x61);
998 reg_w1(gspca_dev
, 0x17, 0xe2);
999 reg_w1(gspca_dev
, 0x01, 0x60);
1000 reg_w1(gspca_dev
, 0x01, 0x40);
1003 reg_w1(gspca_dev
, 0x01, 0x63);
1004 reg_w1(gspca_dev
, 0x17, 0x20);
1005 reg_w1(gspca_dev
, 0x01, 0x42);
1007 /*jfm: from win trace */
1009 if (sd
->bridge
== BRIDGE_SN9C120
) {
1010 reg_w1(gspca_dev
, 0x01, 0x61);
1011 reg_w1(gspca_dev
, 0x17, 0x20);
1012 reg_w1(gspca_dev
, 0x01, 0x60);
1013 reg_w1(gspca_dev
, 0x01, 0x40);
1018 reg_w1(gspca_dev
, 0x01, 0x43);
1019 reg_w1(gspca_dev
, 0x17, 0x61);
1020 reg_w1(gspca_dev
, 0x01, 0x42);
1021 if (sd
->sensor
== SENSOR_HV7131R
) {
1022 if (hv7131r_probe(gspca_dev
) < 0)
1030 static void hv7131R_InitSensor(struct gspca_dev
*gspca_dev
)
1033 static const u8 SetSensorClk
[] = /* 0x08 Mclk */
1034 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1036 while (hv7131r_sensor_init
[i
][0]) {
1037 i2c_w8(gspca_dev
, hv7131r_sensor_init
[i
]);
1040 i2c_w8(gspca_dev
, SetSensorClk
);
1043 static void mi0360_InitSensor(struct gspca_dev
*gspca_dev
)
1047 while (mi0360_sensor_init
[i
][0]) {
1048 i2c_w8(gspca_dev
, mi0360_sensor_init
[i
]);
1053 static void mo4000_InitSensor(struct gspca_dev
*gspca_dev
)
1057 while (mo4000_sensor_init
[i
][0]) {
1058 i2c_w8(gspca_dev
, mo4000_sensor_init
[i
]);
1063 static void mt9v111_InitSensor(struct gspca_dev
*gspca_dev
)
1067 i2c_w8(gspca_dev
, mt9v111_sensor_init
[i
]);
1070 while (mt9v111_sensor_init
[i
][0]) {
1071 i2c_w8(gspca_dev
, mt9v111_sensor_init
[i
]);
1076 static void om6802_InitSensor(struct gspca_dev
*gspca_dev
)
1080 while (om6802_sensor_init
[i
][0]) {
1081 i2c_w8(gspca_dev
, om6802_sensor_init
[i
]);
1086 static void ov7630_InitSensor(struct gspca_dev
*gspca_dev
)
1090 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 76 01 */
1092 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 c8 (RGB+SRST) */
1095 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 48 */
1097 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 c8 */
1100 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 48 */
1102 /*jfm:win i2c_r from 00 to 80*/
1104 while (ov7630_sensor_init
[i
][0]) {
1105 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]);
1110 static void ov7648_InitSensor(struct gspca_dev
*gspca_dev
)
1114 i2c_w8(gspca_dev
, ov7648_sensor_init
[i
]);
1116 /* win: dble reset */
1117 i2c_w8(gspca_dev
, ov7648_sensor_init
[i
]); /* reset */
1120 /* win: i2c reg read 00..7f */
1121 while (ov7648_sensor_init
[i
][0]) {
1122 i2c_w8(gspca_dev
, ov7648_sensor_init
[i
]);
1127 static void ov7660_InitSensor(struct gspca_dev
*gspca_dev
)
1131 i2c_w8(gspca_dev
, ov7660_sensor_init
[i
]); /* reset SCCB */
1134 while (ov7660_sensor_init
[i
][0]) {
1135 i2c_w8(gspca_dev
, ov7660_sensor_init
[i
]);
1140 /* this function is called at probe time */
1141 static int sd_config(struct gspca_dev
*gspca_dev
,
1142 const struct usb_device_id
*id
)
1144 struct sd
*sd
= (struct sd
*) gspca_dev
;
1147 cam
= &gspca_dev
->cam
;
1148 cam
->cam_mode
= vga_mode
;
1149 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
1151 sd
->bridge
= id
->driver_info
>> 16;
1152 sd
->sensor
= id
->driver_info
>> 8;
1153 sd
->i2c_base
= id
->driver_info
;
1155 sd
->brightness
= BRIGHTNESS_DEF
;
1156 sd
->contrast
= CONTRAST_DEF
;
1157 sd
->colors
= COLOR_DEF
;
1158 sd
->blue
= BLUE_BALANCE_DEF
;
1159 sd
->red
= RED_BALANCE_DEF
;
1160 sd
->gamma
= GAMMA_DEF
;
1161 sd
->autogain
= AUTOGAIN_DEF
;
1163 sd
->vflip
= VFLIP_DEF
;
1164 sd
->infrared
= INFRARED_DEF
;
1166 gspca_dev
->ctrl_dis
= ctrl_dis
[sd
->sensor
];
1170 /* this function is called at probe and resume time */
1171 static int sd_init(struct gspca_dev
*gspca_dev
)
1173 struct sd
*sd
= (struct sd
*) gspca_dev
;
1174 u8 regGpio
[] = { 0x29, 0x74 };
1177 /* setup a selector by bridge */
1178 reg_w1(gspca_dev
, 0xf1, 0x01);
1179 reg_r(gspca_dev
, 0x00, 1);
1180 reg_w1(gspca_dev
, 0xf1, gspca_dev
->usb_buf
[0]);
1181 reg_r(gspca_dev
, 0x00, 1); /* get sonix chip id */
1182 regF1
= gspca_dev
->usb_buf
[0];
1183 PDEBUG(D_PROBE
, "Sonix chip id: %02x", regF1
);
1184 switch (sd
->bridge
) {
1185 case BRIDGE_SN9C102P
:
1188 reg_w1(gspca_dev
, 0x02, regGpio
[1]);
1190 case BRIDGE_SN9C105
:
1193 if (sd
->sensor
== SENSOR_MI0360
) {
1194 sd
->sensor
= mi0360_probe(gspca_dev
);
1195 if (sd
->sensor
== SENSOR_MT9V111
)
1196 sd
->i2c_base
= 0x5c;
1198 reg_w(gspca_dev
, 0x01, regGpio
, 2);
1200 case BRIDGE_SN9C120
:
1203 if (sd
->sensor
== SENSOR_MI0360
) {
1204 sd
->sensor
= mi0360_probe(gspca_dev
);
1205 if (sd
->sensor
== SENSOR_MT9V111
)
1206 sd
->i2c_base
= 0x5c;
1209 reg_w(gspca_dev
, 0x01, regGpio
, 2);
1212 /* case BRIDGE_SN9C110: */
1213 /* case BRIDGE_SN9C325: */
1216 reg_w1(gspca_dev
, 0x02, 0x62);
1220 reg_w1(gspca_dev
, 0xf1, 0x01);
1225 static u32
setexposure(struct gspca_dev
*gspca_dev
,
1228 struct sd
*sd
= (struct sd
*) gspca_dev
;
1230 switch (sd
->sensor
) {
1231 case SENSOR_HV7131R
: {
1233 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1235 Expodoit
[3] = expo
>> 16;
1236 Expodoit
[4] = expo
>> 8;
1238 i2c_w8(gspca_dev
, Expodoit
);
1241 case SENSOR_MI0360
: {
1242 u8 expoMi
[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1243 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1244 static const u8 doit
[] = /* update sensor */
1245 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1246 static const u8 sensorgo
[] = /* sensor on */
1247 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1251 else if (expo
< 0x0001)
1253 expoMi
[3] = expo
>> 8;
1255 i2c_w8(gspca_dev
, expoMi
);
1256 i2c_w8(gspca_dev
, doit
);
1257 i2c_w8(gspca_dev
, sensorgo
);
1260 case SENSOR_MO4000
: {
1262 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1264 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1265 static const u8 gainMo
[] =
1266 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1270 else if (expo
< 0x0001)
1272 expoMof
[3] = (expo
& 0x03fc) >> 2;
1273 i2c_w8(gspca_dev
, expoMof
);
1274 expoMo10
[3] = ((expo
& 0x1c00) >> 10)
1275 | ((expo
& 0x0003) << 4);
1276 i2c_w8(gspca_dev
, expoMo10
);
1277 i2c_w8(gspca_dev
, gainMo
);
1278 PDEBUG(D_FRAM
, "set exposure %d",
1279 ((expoMo10
[3] & 0x07) << 10)
1281 | ((expoMo10
[3] & 0x30) >> 4));
1284 case SENSOR_MT9V111
: {
1286 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1290 else if (expo
< 0x0040)
1292 expo_c1
[3] = expo
>> 8;
1294 i2c_w8(gspca_dev
, expo_c1
);
1297 case SENSOR_OM6802
: {
1299 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1305 gainOm
[3] = expo
>> 2;
1306 i2c_w8(gspca_dev
, gainOm
);
1307 reg_w1(gspca_dev
, 0x96, (expo
>> 5) & 0x1f);
1308 PDEBUG(D_FRAM
, "set exposure %d", gainOm
[3]);
1315 static void setbrightness(struct gspca_dev
*gspca_dev
)
1317 struct sd
*sd
= (struct sd
*) gspca_dev
;
1321 k2
= ((int) sd
->brightness
- 0x8000) >> 10;
1322 switch (sd
->sensor
) {
1323 case SENSOR_HV7131R
:
1324 expo
= sd
->brightness
<< 4;
1325 if (expo
> 0x002dc6c0)
1327 else if (expo
< 0x02a0)
1329 sd
->exposure
= setexposure(gspca_dev
, expo
);
1333 expo
= sd
->brightness
>> 4;
1334 sd
->exposure
= setexposure(gspca_dev
, expo
);
1336 case SENSOR_MT9V111
:
1337 expo
= sd
->brightness
>> 8;
1338 sd
->exposure
= setexposure(gspca_dev
, expo
);
1341 expo
= sd
->brightness
>> 6;
1342 sd
->exposure
= setexposure(gspca_dev
, expo
);
1343 k2
= sd
->brightness
>> 11;
1347 if (sd
->sensor
!= SENSOR_MT9V111
)
1348 reg_w1(gspca_dev
, 0x96, k2
); /* color matrix Y offset */
1351 static void setcontrast(struct gspca_dev
*gspca_dev
)
1353 struct sd
*sd
= (struct sd
*) gspca_dev
;
1357 k2
= sd
->contrast
* 0x30 / (CONTRAST_MAX
+ 1) + 0x10; /* 10..40 */
1358 contrast
[0] = (k2
+ 1) / 2; /* red */
1360 contrast
[2] = k2
; /* green */
1362 contrast
[4] = (k2
+ 1) / 5; /* blue */
1364 reg_w(gspca_dev
, 0x84, contrast
, sizeof contrast
);
1367 static void setcolors(struct gspca_dev
*gspca_dev
)
1369 struct sd
*sd
= (struct sd
*) gspca_dev
;
1371 u8 reg8a
[12]; /* U & V gains */
1372 static s16 uv
[6] = { /* same as reg84 in signed decimal */
1373 -24, -38, 64, /* UR UG UB */
1374 62, -51, -9 /* VR VG VB */
1376 for (i
= 0; i
< 6; i
++) {
1377 v
= uv
[i
] * sd
->colors
/ COLOR_DEF
;
1379 reg8a
[i
* 2 + 1] = (v
>> 8) & 0x0f;
1381 reg_w(gspca_dev
, 0x8a, reg8a
, sizeof reg8a
);
1384 static void setredblue(struct gspca_dev
*gspca_dev
)
1386 struct sd
*sd
= (struct sd
*) gspca_dev
;
1388 reg_w1(gspca_dev
, 0x05, sd
->red
);
1389 /* reg_w1(gspca_dev, 0x07, 32); */
1390 reg_w1(gspca_dev
, 0x06, sd
->blue
);
1393 static void setgamma(struct gspca_dev
*gspca_dev
)
1395 struct sd
*sd
= (struct sd
*) gspca_dev
;
1398 static const u8 delta
[17] = {
1399 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1400 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1403 for (i
= 0; i
< sizeof gamma
; i
++)
1404 gamma
[i
] = gamma_def
[i
]
1405 + delta
[i
] * (sd
->gamma
- GAMMA_DEF
) / 32;
1406 reg_w(gspca_dev
, 0x20, gamma
, sizeof gamma
);
1409 static void setautogain(struct gspca_dev
*gspca_dev
)
1411 struct sd
*sd
= (struct sd
*) gspca_dev
;
1413 if (gspca_dev
->ctrl_dis
& (1 << AUTOGAIN_IDX
))
1416 sd
->ag_cnt
= AG_CNT_START
;
1421 static void setvflip(struct sd
*sd
)
1423 i2c_w1(&sd
->gspca_dev
, 0x75, /* COMN */
1424 sd
->vflip
? 0x82 : 0x02);
1427 static void setinfrared(struct sd
*sd
)
1429 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1431 i2c_w1(&sd
->gspca_dev
, 0x02, /* gpio */
1432 sd
->infrared
? 0x66 : 0x64);
1435 /* -- start the camera -- */
1436 static int sd_start(struct gspca_dev
*gspca_dev
)
1438 struct sd
*sd
= (struct sd
*) gspca_dev
;
1440 u8 reg1
, reg17
, reg18
;
1443 static const u8 C0
[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1444 static const u8 CA
[] = { 0x28, 0xd8, 0x14, 0xec };
1445 static const u8 CE
[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1446 static const u8 CE_ov76xx
[] =
1447 { 0x32, 0xdd, 0x32, 0xdd };
1449 sn9c1xx
= sn_tb
[(int) sd
->sensor
];
1450 configure_gpio(gspca_dev
, sn9c1xx
);
1452 reg_w1(gspca_dev
, 0x15, sn9c1xx
[0x15]);
1453 reg_w1(gspca_dev
, 0x16, sn9c1xx
[0x16]);
1454 reg_w1(gspca_dev
, 0x12, sn9c1xx
[0x12]);
1455 reg_w1(gspca_dev
, 0x13, sn9c1xx
[0x13]);
1456 reg_w1(gspca_dev
, 0x18, sn9c1xx
[0x18]);
1457 reg_w1(gspca_dev
, 0xd2, 0x6a); /* DC29 */
1458 reg_w1(gspca_dev
, 0xd3, 0x50);
1459 reg_w1(gspca_dev
, 0xc6, 0x00);
1460 reg_w1(gspca_dev
, 0xc7, 0x00);
1461 reg_w1(gspca_dev
, 0xc8, 0x50);
1462 reg_w1(gspca_dev
, 0xc9, 0x3c);
1463 reg_w1(gspca_dev
, 0x18, sn9c1xx
[0x18]);
1464 switch (sd
->sensor
) {
1465 case SENSOR_MT9V111
:
1474 /*jfm: from win trace */
1476 if (sd
->bridge
== BRIDGE_SN9C120
) {
1485 reg_w1(gspca_dev
, 0x17, reg17
);
1486 /* set reg1 was here */
1487 reg_w1(gspca_dev
, 0x05, sn9c1xx
[5]); /* red */
1488 reg_w1(gspca_dev
, 0x07, sn9c1xx
[7]); /* green */
1489 reg_w1(gspca_dev
, 0x06, sn9c1xx
[6]); /* blue */
1490 reg_w1(gspca_dev
, 0x14, sn9c1xx
[0x14]);
1491 setgamma(gspca_dev
);
1492 for (i
= 0; i
< 8; i
++)
1493 reg_w(gspca_dev
, 0x84, reg84
, sizeof reg84
);
1494 switch (sd
->sensor
) {
1495 case SENSOR_MT9V111
:
1496 reg_w1(gspca_dev
, 0x9a, 0x07);
1497 reg_w1(gspca_dev
, 0x99, 0x59);
1500 reg_w1(gspca_dev
, 0x9a, 0x0a);
1501 reg_w1(gspca_dev
, 0x99, 0x60);
1504 if (sd
->bridge
== BRIDGE_SN9C120
) {
1505 reg_w1(gspca_dev
, 0x9a, 0x05);
1510 reg_w1(gspca_dev
, 0x9a, 0x08);
1511 reg_w1(gspca_dev
, 0x99, 0x59);
1515 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
1517 reg1
= 0x46; /* 320x240: clk 48Mhz, video trf enable */
1519 reg1
= 0x06; /* 640x480: clk 24Mhz, video trf enable */
1520 reg17
= 0x61; /* 0x:20: enable sensor clock */
1521 switch (sd
->sensor
) {
1522 case SENSOR_HV7131R
:
1523 hv7131R_InitSensor(gspca_dev
);
1526 mi0360_InitSensor(gspca_dev
);
1529 mo4000_InitSensor(gspca_dev
);
1531 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1532 reg1
= 0x06; /* clk 24Mz */
1534 reg17
= 0x22; /* 640 MCKSIZE */
1535 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1538 case SENSOR_MT9V111
:
1539 mt9v111_InitSensor(gspca_dev
);
1541 reg1
= 0x04; /* 320 clk 48Mhz */
1543 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1547 om6802_InitSensor(gspca_dev
);
1548 reg17
= 0x64; /* 640 MCKSIZE */
1551 ov7630_InitSensor(gspca_dev
);
1557 ov7648_InitSensor(gspca_dev
);
1559 /* reg1 = 0x42; * 42 - 46? */
1562 /* case SENSOR_OV7660: */
1563 ov7660_InitSensor(gspca_dev
);
1564 if (sd
->bridge
== BRIDGE_SN9C120
) {
1565 if (mode
) { /* 320x240 - 160x120 */
1567 reg1
= 0x44; /* 48 Mhz, video trf eneble */
1571 reg1
= 0x06; /* 24 Mhz, video trf eneble
1572 * inverse power down */
1576 reg_w(gspca_dev
, 0xc0, C0
, 6);
1577 reg_w(gspca_dev
, 0xca, CA
, 4);
1578 switch (sd
->sensor
) {
1582 reg_w(gspca_dev
, 0xce, CE_ov76xx
, 4);
1585 reg_w(gspca_dev
, 0xce, CE
, 4);
1586 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1590 /* here change size mode 0 -> VGA; 1 -> CIF */
1591 reg18
= sn9c1xx
[0x18] | (mode
<< 4);
1592 reg_w1(gspca_dev
, 0x18, reg18
| 0x40);
1594 reg_w(gspca_dev
, 0x0100, qtable4
, 0x40);
1595 reg_w(gspca_dev
, 0x0140, qtable4
+ 0x40, 0x40);
1597 reg_w1(gspca_dev
, 0x18, reg18
);
1599 reg_w1(gspca_dev
, 0x17, reg17
);
1600 reg_w1(gspca_dev
, 0x01, reg1
);
1601 switch (sd
->sensor
) {
1606 setbrightness(gspca_dev
);
1607 setcontrast(gspca_dev
);
1608 setautogain(gspca_dev
);
1612 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1614 struct sd
*sd
= (struct sd
*) gspca_dev
;
1615 static const u8 stophv7131
[] =
1616 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1617 static const u8 stopmi0360
[] =
1618 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1619 static const u8 stopov7648
[] =
1620 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1625 switch (sd
->sensor
) {
1626 case SENSOR_HV7131R
:
1627 i2c_w8(gspca_dev
, stophv7131
);
1631 i2c_w8(gspca_dev
, stopmi0360
);
1635 i2c_w8(gspca_dev
, stopov7648
);
1637 case SENSOR_MT9V111
:
1642 /* case SENSOR_MO4000: */
1643 /* case SENSOR_OV7660: */
1646 sn9c1xx
= sn_tb
[(int) sd
->sensor
];
1647 reg_w1(gspca_dev
, 0x01, sn9c1xx
[1]);
1648 reg_w1(gspca_dev
, 0x17, sn9c1xx
[0x17]);
1649 reg_w1(gspca_dev
, 0x01, sn9c1xx
[1]);
1650 reg_w1(gspca_dev
, 0x01, data
);
1651 reg_w1(gspca_dev
, 0xf1, 0x00);
1654 static void do_autogain(struct gspca_dev
*gspca_dev
)
1656 struct sd
*sd
= (struct sd
*) gspca_dev
;
1662 /* Thanks S., without your advice, autobright should not work :) */
1665 if (--sd
->ag_cnt
>= 0)
1667 sd
->ag_cnt
= AG_CNT_START
;
1669 delta
= atomic_read(&sd
->avg_lum
);
1670 PDEBUG(D_FRAM
, "mean lum %d", delta
);
1671 if (delta
< luma_mean
- luma_delta
||
1672 delta
> luma_mean
+ luma_delta
) {
1673 switch (sd
->sensor
) {
1674 case SENSOR_HV7131R
:
1675 expotimes
= sd
->exposure
>> 8;
1676 expotimes
+= (luma_mean
- delta
) >> 4;
1679 sd
->exposure
= setexposure(gspca_dev
,
1680 (unsigned int) (expotimes
<< 8));
1683 /* case SENSOR_MO4000: */
1684 /* case SENSOR_MI0360: */
1685 /* case SENSOR_MT9V111: */
1686 /* case SENSOR_OM6802: */
1687 expotimes
= sd
->exposure
;
1688 expotimes
+= (luma_mean
- delta
) >> 6;
1691 sd
->exposure
= setexposure(gspca_dev
,
1692 (unsigned int) expotimes
);
1693 setredblue(gspca_dev
);
1699 /* scan the URB packets */
1700 /* This function is run at interrupt level. */
1701 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1702 struct gspca_frame
*frame
, /* target */
1703 u8
*data
, /* isoc packet */
1704 int len
) /* iso packet length */
1706 struct sd
*sd
= (struct sd
*) gspca_dev
;
1710 if (sof
>= 0 && data
[sof
] == 0xff && data
[sof
+ 1] == 0xd9) {
1713 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1714 frame
, data
, sof
+ 2);
1721 avg_lum
= ((data
[sof
+ 29] << 8) | data
[sof
+ 30]) >> 6;
1723 avg_lum
+= ((data
[sof
+ 33] << 8) | data
[sof
+ 34]) >> 6;
1725 avg_lum
+= ((data
[sof
+ 25] << 8) | data
[sof
+ 26]) >> 6;
1727 avg_lum
+= ((data
[sof
+ 37] << 8) | data
[sof
+ 38]) >> 6;
1729 avg_lum
+= ((data
[sof
+ 31] << 8) | data
[sof
+ 32]) >> 4;
1731 atomic_set(&sd
->avg_lum
, avg_lum
);
1734 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
1736 /* put the JPEG 422 header */
1737 jpeg_put_header(gspca_dev
, frame
, 0x21);
1739 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
1742 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1744 struct sd
*sd
= (struct sd
*) gspca_dev
;
1746 sd
->brightness
= val
;
1747 if (gspca_dev
->streaming
)
1748 setbrightness(gspca_dev
);
1752 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1754 struct sd
*sd
= (struct sd
*) gspca_dev
;
1756 *val
= sd
->brightness
;
1760 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1762 struct sd
*sd
= (struct sd
*) gspca_dev
;
1765 if (gspca_dev
->streaming
)
1766 setcontrast(gspca_dev
);
1770 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1772 struct sd
*sd
= (struct sd
*) gspca_dev
;
1774 *val
= sd
->contrast
;
1778 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1780 struct sd
*sd
= (struct sd
*) gspca_dev
;
1783 if (gspca_dev
->streaming
)
1784 setcolors(gspca_dev
);
1788 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1790 struct sd
*sd
= (struct sd
*) gspca_dev
;
1796 static int sd_setblue_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
1798 struct sd
*sd
= (struct sd
*) gspca_dev
;
1801 if (gspca_dev
->streaming
)
1802 setredblue(gspca_dev
);
1806 static int sd_getblue_balance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1808 struct sd
*sd
= (struct sd
*) gspca_dev
;
1814 static int sd_setred_balance(struct gspca_dev
*gspca_dev
, __s32 val
)
1816 struct sd
*sd
= (struct sd
*) gspca_dev
;
1819 if (gspca_dev
->streaming
)
1820 setredblue(gspca_dev
);
1824 static int sd_getred_balance(struct gspca_dev
*gspca_dev
, __s32
*val
)
1826 struct sd
*sd
= (struct sd
*) gspca_dev
;
1832 static int sd_setgamma(struct gspca_dev
*gspca_dev
, __s32 val
)
1834 struct sd
*sd
= (struct sd
*) gspca_dev
;
1837 if (gspca_dev
->streaming
)
1838 setgamma(gspca_dev
);
1842 static int sd_getgamma(struct gspca_dev
*gspca_dev
, __s32
*val
)
1844 struct sd
*sd
= (struct sd
*) gspca_dev
;
1850 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
1852 struct sd
*sd
= (struct sd
*) gspca_dev
;
1855 if (gspca_dev
->streaming
)
1856 setautogain(gspca_dev
);
1860 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1862 struct sd
*sd
= (struct sd
*) gspca_dev
;
1864 *val
= sd
->autogain
;
1868 static int sd_setvflip(struct gspca_dev
*gspca_dev
, __s32 val
)
1870 struct sd
*sd
= (struct sd
*) gspca_dev
;
1873 if (gspca_dev
->streaming
)
1878 static int sd_getvflip(struct gspca_dev
*gspca_dev
, __s32
*val
)
1880 struct sd
*sd
= (struct sd
*) gspca_dev
;
1886 static int sd_setinfrared(struct gspca_dev
*gspca_dev
, __s32 val
)
1888 struct sd
*sd
= (struct sd
*) gspca_dev
;
1891 if (gspca_dev
->streaming
)
1896 static int sd_getinfrared(struct gspca_dev
*gspca_dev
, __s32
*val
)
1898 struct sd
*sd
= (struct sd
*) gspca_dev
;
1900 *val
= sd
->infrared
;
1904 /* sub-driver description */
1905 static const struct sd_desc sd_desc
= {
1906 .name
= MODULE_NAME
,
1908 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1909 .config
= sd_config
,
1913 .pkt_scan
= sd_pkt_scan
,
1914 .dq_callback
= do_autogain
,
1917 /* -- module initialisation -- */
1918 #define BSI(bridge, sensor, i2c_addr) \
1919 .driver_info = (BRIDGE_ ## bridge << 16) \
1920 | (SENSOR_ ## sensor << 8) \
1922 static const __devinitdata
struct usb_device_id device_table
[] = {
1923 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1924 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120
, MI0360
, 0x5d)},
1925 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120
, OV7660
, 0x21)},
1927 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105
, OV7660
, 0x21)},
1928 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105
, OV7660
, 0x21)},
1929 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1930 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105
, MI0360
, 0x5d)},
1932 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105
, MI0360
, 0x5d)},
1933 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105
, MI0360
, 0x5d)},
1934 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105
, OV7660
, 0x21)},
1935 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P
, HV7131R
, 0x11)},
1937 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1938 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1939 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1940 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P
, HV7131R
, 0x11)},
1941 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1942 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105
, MT9V111
, 0x5c)},
1943 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1944 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1945 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105
, MO4000
, 0x21)},
1946 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1947 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1948 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105
, OV7660
, 0x21)},
1949 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105
, HV7131R
, 0x11)},
1950 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1951 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105
, OV7630
, 0x21)},
1953 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1954 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1955 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1956 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110
, OM6802
, 0x21)}, /*sn9c325?*/
1958 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120
, OV7648
, 0x21)}, /*sn9c110?*/
1959 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110
, MO4000
, 0x21)},
1960 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110
, OV7630
, 0x21)},
1961 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1962 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1963 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120
, MI0360
, 0x5d)},
1965 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120
, MO4000
, 0x21)},
1966 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120
, OV7648
, 0x21)},
1967 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1968 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120
, OV7660
, 0x21)},
1969 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120
, HV7131R
, 0x11)},
1970 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1972 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120
, MI0360
, 0x5d)},
1975 MODULE_DEVICE_TABLE(usb
, device_table
);
1977 /* -- device connect -- */
1978 static int sd_probe(struct usb_interface
*intf
,
1979 const struct usb_device_id
*id
)
1981 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1985 static struct usb_driver sd_driver
= {
1986 .name
= MODULE_NAME
,
1987 .id_table
= device_table
,
1989 .disconnect
= gspca_disconnect
,
1991 .suspend
= gspca_suspend
,
1992 .resume
= gspca_resume
,
1996 /* -- module insert / remove -- */
1997 static int __init
sd_mod_init(void)
2000 ret
= usb_register(&sd_driver
);
2006 static void __exit
sd_mod_exit(void)
2008 usb_deregister(&sd_driver
);
2009 info("deregistered");
2012 module_init(sd_mod_init
);
2013 module_exit(sd_mod_exit
);