V4L/DVB (10425): gspca - sonixj: Bad initialization of sensor mt9v111.
[linux-2.6/mini2440.git] / drivers / media / video / gspca / sonixj.c
blobe4454b573598f854da4cc9b0db2c9ab24e1bb0d8
1 /*
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
10 * any later version.
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"
24 #include "gspca.h"
25 #define QUANT_VAL 4 /* quantization table */
26 #include "jpeg.h"
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 */
35 struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
38 atomic_t avg_lum;
39 u32 exposure;
41 u16 brightness;
42 u8 contrast;
43 u8 colors;
44 u8 autogain;
45 u8 blue;
46 u8 red;
47 u8 gamma;
48 u8 vflip; /* ov7630 only */
49 u8 infrared; /* mt9v111 only */
51 s8 ag_cnt;
52 #define AG_CNT_START 13
54 u8 bridge;
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 u8 i2c_base;
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,
97 .name = "Brightness",
98 .minimum = 0,
99 #define BRIGHTNESS_MAX 0xffff
100 .maximum = BRIGHTNESS_MAX,
101 .step = 1,
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,
112 .name = "Contrast",
113 .minimum = 0,
114 #define CONTRAST_MAX 127
115 .maximum = CONTRAST_MAX,
116 .step = 1,
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,
127 .name = "Color",
128 .minimum = 0,
129 .maximum = 40,
130 .step = 1,
131 #define COLOR_DEF 32
132 .default_value = COLOR_DEF,
134 .set = sd_setcolors,
135 .get = sd_getcolors,
139 .id = V4L2_CID_BLUE_BALANCE,
140 .type = V4L2_CTRL_TYPE_INTEGER,
141 .name = "Blue Balance",
142 .minimum = 24,
143 .maximum = 40,
144 .step = 1,
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",
156 .minimum = 24,
157 .maximum = 40,
158 .step = 1,
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,
169 .name = "Gamma",
170 .minimum = 0,
171 .maximum = 40,
172 .step = 1,
173 #define GAMMA_DEF 20
174 .default_value = GAMMA_DEF,
176 .set = sd_setgamma,
177 .get = sd_getgamma,
179 #define AUTOGAIN_IDX 5
182 .id = V4L2_CID_AUTOGAIN,
183 .type = V4L2_CTRL_TYPE_BOOLEAN,
184 .name = "Auto Gain",
185 .minimum = 0,
186 .maximum = 1,
187 .step = 1,
188 #define AUTOGAIN_DEF 1
189 .default_value = AUTOGAIN_DEF,
191 .set = sd_setautogain,
192 .get = sd_getautogain,
194 /* ov7630 only */
195 #define VFLIP_IDX 6
198 .id = V4L2_CID_VFLIP,
199 .type = V4L2_CTRL_TYPE_BOOLEAN,
200 .name = "Vflip",
201 .minimum = 0,
202 .maximum = 1,
203 .step = 1,
204 #define VFLIP_DEF 1
205 .default_value = VFLIP_DEF,
207 .set = sd_setvflip,
208 .get = sd_getvflip,
210 /* mt9v111 only */
211 #define INFRARED_IDX 7
214 .id = V4L2_CID_INFRARED,
215 .type = V4L2_CTRL_TYPE_BOOLEAN,
216 .name = "Infrared",
217 .minimum = 0,
218 .maximum = 1,
219 .step = 1,
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 */
236 (1 << AUTOGAIN_IDX),
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,
250 .bytesperline = 160,
251 .sizeimage = 160 * 120 * 4 / 8 + 590,
252 .colorspace = V4L2_COLORSPACE_JPEG,
253 .priv = 2},
254 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
255 .bytesperline = 320,
256 .sizeimage = 320 * 240 * 3 / 8 + 590,
257 .colorspace = V4L2_COLORSPACE_JPEG,
258 .priv = 1},
259 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
260 .bytesperline = 640,
261 .sizeimage = 640 * 480 * 3 / 8 + 590,
262 .colorspace = V4L2_COLORSPACE_JPEG,
263 .priv = 0},
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[] = {
357 sn_hv7131,
358 sn_mi0360,
359 sn_mo4000,
360 sn_mt9v111,
361 sn_om6802,
362 sn_ov7630,
363 sn_ov7648,
364 sn_ov7660
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? */
490 /* delay 20 ms */
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},
507 /*******/
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 */
513 /*******/
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},
529 * set color mode */
530 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
531 * max AGC value in AE */
532 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
533 * preset AGC */
534 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
535 * preset brightness */
536 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
537 * preset contrast */
538 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
539 * preset gamma */
540 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
541 /* luminance mode (0x4f = AE) */
542 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
543 /* preset shutter */
544 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
545 * auto frame rate */
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},
589 /* */
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
594 * set by setvflip */
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},
598 /* */
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},
602 /* */
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},
635 /*...*/
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 */
643 /*...*/
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 */
656 /* (delay 20ms) */
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,
764 u16 value, int len)
766 #ifdef GSPCA_DEBUG
767 if (len > USB_BUF_SZ) {
768 err("reg_r: buffer overflow");
769 return;
771 #endif
772 usb_control_msg(gspca_dev->dev,
773 usb_rcvctrlpipe(gspca_dev->dev, 0),
775 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
776 value, 0,
777 gspca_dev->usb_buf, len,
778 500);
779 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
782 static void reg_w1(struct gspca_dev *gspca_dev,
783 u16 value,
784 u8 data)
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),
790 0x08,
791 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
792 value,
794 gspca_dev->usb_buf, 1,
795 500);
797 static void reg_w(struct gspca_dev *gspca_dev,
798 u16 value,
799 const u8 *buffer,
800 int len)
802 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
803 value, buffer[0], buffer[1]);
804 #ifdef GSPCA_DEBUG
805 if (len > USB_BUF_SZ) {
806 err("reg_w: buffer overflow");
807 return;
809 #endif
810 memcpy(gspca_dev->usb_buf, buffer, len);
811 usb_control_msg(gspca_dev->dev,
812 usb_sndctrlpipe(gspca_dev->dev, 0),
813 0x08,
814 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
815 value, 0,
816 gspca_dev->usb_buf, len,
817 500);
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),
836 0x08,
837 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
838 0x08, /* value = i2c */
840 gspca_dev->usb_buf, 8,
841 500);
844 /* I2C write 8 bytes */
845 static void i2c_w8(struct gspca_dev *gspca_dev,
846 const u8 *buffer)
848 memcpy(gspca_dev->usb_buf, buffer, 8);
849 usb_control_msg(gspca_dev->dev,
850 usb_sndctrlpipe(gspca_dev->dev, 0),
851 0x08,
852 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
853 0x08, 0, /* value, index */
854 gspca_dev->usb_buf, 8,
855 500);
856 msleep(2);
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;
863 u8 mode[8];
865 mode[0] = 0x81 | 0x10;
866 mode[1] = sd->i2c_base;
867 mode[2] = reg;
868 mode[3] = 0;
869 mode[4] = 0;
870 mode[5] = 0;
871 mode[6] = 0;
872 mode[7] = 0x10;
873 i2c_w8(gspca_dev, mode);
874 msleep(2);
875 mode[0] = 0x81 | (5 << 4) | 0x02;
876 mode[2] = 0;
877 i2c_w8(gspca_dev, mode);
878 msleep(2);
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 */
885 msleep(10);
886 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
887 msleep(10);
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");
895 return 0;
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");
901 return -ENODEV;
904 static int mi0360_probe(struct gspca_dev *gspca_dev)
906 int i, j;
907 u16 val;
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]);
928 msleep(2);
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);
935 if (val != 0xffff)
936 break;
938 switch (val) {
939 case 0x823a:
940 PDEBUG(D_PROBE, "Sensor mt9v111");
941 return SENSOR_MT9V111;
942 case 0x8243:
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,
951 const u8 *sn9c1xx)
953 struct sd *sd = (struct sd *) gspca_dev;
954 const u8 *reg9a;
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]);
964 /* configure gpio */
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) {
969 case BRIDGE_SN9C325:
970 reg9a = reg9a_sn9c325;
971 break;
972 default:
973 reg9a = reg9a_def;
974 break;
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) {
983 case SENSOR_MT9V111:
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);
988 break;
989 case SENSOR_OM6802:
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);
994 break;
995 /*jfm: from win trace */
996 case SENSOR_OV7630:
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);
1001 break;
1002 case SENSOR_OV7648:
1003 reg_w1(gspca_dev, 0x01, 0x63);
1004 reg_w1(gspca_dev, 0x17, 0x20);
1005 reg_w1(gspca_dev, 0x01, 0x42);
1006 break;
1007 /*jfm: from win trace */
1008 case SENSOR_OV7660:
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);
1014 break;
1016 /* fall thru */
1017 default:
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)
1023 return -ENODEV;
1025 break;
1027 return 0;
1030 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1032 int i = 0;
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]);
1038 i++;
1040 i2c_w8(gspca_dev, SetSensorClk);
1043 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1045 int i = 0;
1047 while (mi0360_sensor_init[i][0]) {
1048 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
1049 i++;
1053 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1055 int i = 0;
1057 while (mo4000_sensor_init[i][0]) {
1058 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
1059 i++;
1063 static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1065 int i = 0;
1067 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1068 i++;
1069 msleep(20);
1070 while (mt9v111_sensor_init[i][0]) {
1071 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1072 i++;
1076 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1078 int i = 0;
1080 while (om6802_sensor_init[i][0]) {
1081 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1082 i++;
1086 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1088 int i = 0;
1090 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1091 i++;
1092 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
1093 i++;
1094 msleep(20);
1095 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1096 i++;
1097 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1098 i++;
1099 msleep(20);
1100 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1101 i++;
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]);
1106 i++;
1110 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1112 int i = 0;
1114 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1115 i++;
1116 /* win: dble reset */
1117 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1118 i++;
1119 msleep(20);
1120 /* win: i2c reg read 00..7f */
1121 while (ov7648_sensor_init[i][0]) {
1122 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1123 i++;
1127 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1129 int i = 0;
1131 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1132 i++;
1133 msleep(20);
1134 while (ov7660_sensor_init[i][0]) {
1135 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1136 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;
1145 struct cam *cam;
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;
1162 sd->ag_cnt = -1;
1163 sd->vflip = VFLIP_DEF;
1164 sd->infrared = INFRARED_DEF;
1166 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1167 return 0;
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 };
1175 u8 regF1;
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:
1186 if (regF1 != 0x11)
1187 return -ENODEV;
1188 reg_w1(gspca_dev, 0x02, regGpio[1]);
1189 break;
1190 case BRIDGE_SN9C105:
1191 if (regF1 != 0x11)
1192 return -ENODEV;
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);
1199 break;
1200 case BRIDGE_SN9C120:
1201 if (regF1 != 0x12)
1202 return -ENODEV;
1203 if (sd->sensor == SENSOR_MI0360) {
1204 sd->sensor = mi0360_probe(gspca_dev);
1205 if (sd->sensor == SENSOR_MT9V111)
1206 sd->i2c_base = 0x5c;
1208 regGpio[1] = 0x70;
1209 reg_w(gspca_dev, 0x01, regGpio, 2);
1210 break;
1211 default:
1212 /* case BRIDGE_SN9C110: */
1213 /* case BRIDGE_SN9C325: */
1214 if (regF1 != 0x12)
1215 return -ENODEV;
1216 reg_w1(gspca_dev, 0x02, 0x62);
1217 break;
1220 reg_w1(gspca_dev, 0xf1, 0x01);
1222 return 0;
1225 static u32 setexposure(struct gspca_dev *gspca_dev,
1226 u32 expo)
1228 struct sd *sd = (struct sd *) gspca_dev;
1230 switch (sd->sensor) {
1231 case SENSOR_HV7131R: {
1232 u8 Expodoit[] =
1233 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1235 Expodoit[3] = expo >> 16;
1236 Expodoit[4] = expo >> 8;
1237 Expodoit[5] = expo;
1238 i2c_w8(gspca_dev, Expodoit);
1239 break;
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 };
1249 if (expo > 0x0635)
1250 expo = 0x0635;
1251 else if (expo < 0x0001)
1252 expo = 0x0001;
1253 expoMi[3] = expo >> 8;
1254 expoMi[4] = expo;
1255 i2c_w8(gspca_dev, expoMi);
1256 i2c_w8(gspca_dev, doit);
1257 i2c_w8(gspca_dev, sensorgo);
1258 break;
1260 case SENSOR_MO4000: {
1261 u8 expoMof[] =
1262 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1263 u8 expoMo10[] =
1264 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1265 static const u8 gainMo[] =
1266 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1268 if (expo > 0x1fff)
1269 expo = 0x1fff;
1270 else if (expo < 0x0001)
1271 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)
1280 | (expoMof[3] << 2)
1281 | ((expoMo10[3] & 0x30) >> 4));
1282 break;
1284 case SENSOR_MT9V111: {
1285 u8 expo_c1[] =
1286 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1288 if (expo > 0x0280)
1289 expo = 0x0280;
1290 else if (expo < 0x0040)
1291 expo = 0x0040;
1292 expo_c1[3] = expo >> 8;
1293 expo_c1[4] = expo;
1294 i2c_w8(gspca_dev, expo_c1);
1295 break;
1297 case SENSOR_OM6802: {
1298 u8 gainOm[] =
1299 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1301 if (expo > 0x03ff)
1302 expo = 0x03ff;
1303 if (expo < 0x0001)
1304 expo = 0x0001;
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]);
1309 break;
1312 return expo;
1315 static void setbrightness(struct gspca_dev *gspca_dev)
1317 struct sd *sd = (struct sd *) gspca_dev;
1318 unsigned int expo;
1319 u8 k2;
1321 k2 = ((int) sd->brightness - 0x8000) >> 10;
1322 switch (sd->sensor) {
1323 case SENSOR_HV7131R:
1324 expo = sd->brightness << 4;
1325 if (expo > 0x002dc6c0)
1326 expo = 0x002dc6c0;
1327 else if (expo < 0x02a0)
1328 expo = 0x02a0;
1329 sd->exposure = setexposure(gspca_dev, expo);
1330 break;
1331 case SENSOR_MI0360:
1332 case SENSOR_MO4000:
1333 expo = sd->brightness >> 4;
1334 sd->exposure = setexposure(gspca_dev, expo);
1335 break;
1336 case SENSOR_MT9V111:
1337 expo = sd->brightness >> 8;
1338 sd->exposure = setexposure(gspca_dev, expo);
1339 break;
1340 case SENSOR_OM6802:
1341 expo = sd->brightness >> 6;
1342 sd->exposure = setexposure(gspca_dev, expo);
1343 k2 = sd->brightness >> 11;
1344 break;
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;
1354 u8 k2;
1355 u8 contrast[6];
1357 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1358 contrast[0] = (k2 + 1) / 2; /* red */
1359 contrast[1] = 0;
1360 contrast[2] = k2; /* green */
1361 contrast[3] = 0;
1362 contrast[4] = (k2 + 1) / 5; /* blue */
1363 contrast[5] = 0;
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;
1370 int i, v;
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;
1378 reg8a[i * 2] = v;
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;
1396 int i;
1397 u8 gamma[17];
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))
1414 return;
1415 if (sd->autogain)
1416 sd->ag_cnt = AG_CNT_START;
1417 else
1418 sd->ag_cnt = -1;
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 */
1430 /* Clip */
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;
1439 int i;
1440 u8 reg1, reg17, reg18;
1441 const u8 *sn9c1xx;
1442 int mode;
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:
1466 reg17 = 0xe0;
1467 break;
1468 case SENSOR_OV7630:
1469 reg17 = 0xe2;
1470 break;
1471 case SENSOR_OV7648:
1472 reg17 = 0x20;
1473 break;
1474 /*jfm: from win trace */
1475 case SENSOR_OV7660:
1476 if (sd->bridge == BRIDGE_SN9C120) {
1477 reg17 = 0xa0;
1478 break;
1480 /* fall thru */
1481 default:
1482 reg17 = 0x60;
1483 break;
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);
1498 break;
1499 case SENSOR_OV7648:
1500 reg_w1(gspca_dev, 0x9a, 0x0a);
1501 reg_w1(gspca_dev, 0x99, 0x60);
1502 break;
1503 case SENSOR_OV7660:
1504 if (sd->bridge == BRIDGE_SN9C120) {
1505 reg_w1(gspca_dev, 0x9a, 0x05);
1506 break;
1508 /* fall thru */
1509 default:
1510 reg_w1(gspca_dev, 0x9a, 0x08);
1511 reg_w1(gspca_dev, 0x99, 0x59);
1512 break;
1515 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1516 if (mode)
1517 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1518 else
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);
1524 break;
1525 case SENSOR_MI0360:
1526 mi0360_InitSensor(gspca_dev);
1527 break;
1528 case SENSOR_MO4000:
1529 mo4000_InitSensor(gspca_dev);
1530 if (mode) {
1531 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1532 reg1 = 0x06; /* clk 24Mz */
1533 } else {
1534 reg17 = 0x22; /* 640 MCKSIZE */
1535 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1537 break;
1538 case SENSOR_MT9V111:
1539 mt9v111_InitSensor(gspca_dev);
1540 if (mode) {
1541 reg1 = 0x04; /* 320 clk 48Mhz */
1542 } else {
1543 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1544 reg17 = 0xe2;
1546 break;
1547 case SENSOR_OM6802:
1548 om6802_InitSensor(gspca_dev);
1549 reg17 = 0x64; /* 640 MCKSIZE */
1550 break;
1551 case SENSOR_OV7630:
1552 ov7630_InitSensor(gspca_dev);
1553 setvflip(sd);
1554 reg17 = 0xe2;
1555 reg1 = 0x44;
1556 break;
1557 case SENSOR_OV7648:
1558 ov7648_InitSensor(gspca_dev);
1559 reg17 = 0x21;
1560 /* reg1 = 0x42; * 42 - 46? */
1561 break;
1562 default:
1563 /* case SENSOR_OV7660: */
1564 ov7660_InitSensor(gspca_dev);
1565 if (sd->bridge == BRIDGE_SN9C120) {
1566 if (mode) { /* 320x240 - 160x120 */
1567 reg17 = 0xa2;
1568 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1570 } else {
1571 reg17 = 0x22;
1572 reg1 = 0x06; /* 24 Mhz, video trf eneble
1573 * inverse power down */
1575 break;
1577 reg_w(gspca_dev, 0xc0, C0, 6);
1578 reg_w(gspca_dev, 0xca, CA, 4);
1579 switch (sd->sensor) {
1580 case SENSOR_OV7630:
1581 case SENSOR_OV7648:
1582 case SENSOR_OV7660:
1583 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1584 break;
1585 default:
1586 reg_w(gspca_dev, 0xce, CE, 4);
1587 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1588 break;
1591 /* here change size mode 0 -> VGA; 1 -> CIF */
1592 reg18 = sn9c1xx[0x18] | (mode << 4);
1593 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1595 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1596 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
1598 reg_w1(gspca_dev, 0x18, reg18);
1600 reg_w1(gspca_dev, 0x17, reg17);
1601 reg_w1(gspca_dev, 0x01, reg1);
1602 switch (sd->sensor) {
1603 case SENSOR_OV7630:
1604 setvflip(sd);
1605 break;
1607 setbrightness(gspca_dev);
1608 setcontrast(gspca_dev);
1609 setautogain(gspca_dev);
1610 return 0;
1613 static void sd_stopN(struct gspca_dev *gspca_dev)
1615 struct sd *sd = (struct sd *) gspca_dev;
1616 static const u8 stophv7131[] =
1617 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1618 static const u8 stopmi0360[] =
1619 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1620 static const u8 stopov7648[] =
1621 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1622 u8 data;
1623 const u8 *sn9c1xx;
1625 data = 0x0b;
1626 switch (sd->sensor) {
1627 case SENSOR_HV7131R:
1628 i2c_w8(gspca_dev, stophv7131);
1629 data = 0x2b;
1630 break;
1631 case SENSOR_MI0360:
1632 i2c_w8(gspca_dev, stopmi0360);
1633 data = 0x29;
1634 break;
1635 case SENSOR_OV7648:
1636 i2c_w8(gspca_dev, stopov7648);
1637 /* fall thru */
1638 case SENSOR_MT9V111:
1639 case SENSOR_OV7630:
1640 data = 0x29;
1641 break;
1642 default:
1643 /* case SENSOR_MO4000: */
1644 /* case SENSOR_OV7660: */
1645 break;
1647 sn9c1xx = sn_tb[(int) sd->sensor];
1648 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1649 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1650 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1651 reg_w1(gspca_dev, 0x01, data);
1652 reg_w1(gspca_dev, 0xf1, 0x00);
1655 static void do_autogain(struct gspca_dev *gspca_dev)
1657 struct sd *sd = (struct sd *) gspca_dev;
1658 int delta;
1659 int expotimes;
1660 u8 luma_mean = 130;
1661 u8 luma_delta = 20;
1663 /* Thanks S., without your advice, autobright should not work :) */
1664 if (sd->ag_cnt < 0)
1665 return;
1666 if (--sd->ag_cnt >= 0)
1667 return;
1668 sd->ag_cnt = AG_CNT_START;
1670 delta = atomic_read(&sd->avg_lum);
1671 PDEBUG(D_FRAM, "mean lum %d", delta);
1672 if (delta < luma_mean - luma_delta ||
1673 delta > luma_mean + luma_delta) {
1674 switch (sd->sensor) {
1675 case SENSOR_HV7131R:
1676 expotimes = sd->exposure >> 8;
1677 expotimes += (luma_mean - delta) >> 4;
1678 if (expotimes < 0)
1679 expotimes = 0;
1680 sd->exposure = setexposure(gspca_dev,
1681 (unsigned int) (expotimes << 8));
1682 break;
1683 default:
1684 /* case SENSOR_MO4000: */
1685 /* case SENSOR_MI0360: */
1686 /* case SENSOR_MT9V111: */
1687 /* case SENSOR_OM6802: */
1688 expotimes = sd->exposure;
1689 expotimes += (luma_mean - delta) >> 6;
1690 if (expotimes < 0)
1691 expotimes = 0;
1692 sd->exposure = setexposure(gspca_dev,
1693 (unsigned int) expotimes);
1694 setredblue(gspca_dev);
1695 break;
1700 /* scan the URB packets */
1701 /* This function is run at interrupt level. */
1702 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1703 struct gspca_frame *frame, /* target */
1704 u8 *data, /* isoc packet */
1705 int len) /* iso packet length */
1707 struct sd *sd = (struct sd *) gspca_dev;
1708 int sof, avg_lum;
1710 sof = len - 64;
1711 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1713 /* end of frame */
1714 gspca_frame_add(gspca_dev, LAST_PACKET,
1715 frame, data, sof + 2);
1716 if (sd->ag_cnt < 0)
1717 return;
1718 /* w1 w2 w3 */
1719 /* w4 w5 w6 */
1720 /* w7 w8 */
1721 /* w4 */
1722 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1723 /* w6 */
1724 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1725 /* w2 */
1726 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1727 /* w8 */
1728 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1729 /* w5 */
1730 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1731 avg_lum >>= 4;
1732 atomic_set(&sd->avg_lum, avg_lum);
1733 return;
1735 if (gspca_dev->last_packet_type == LAST_PACKET) {
1737 /* put the JPEG 422 header */
1738 jpeg_put_header(gspca_dev, frame, 0x21);
1740 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1743 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1745 struct sd *sd = (struct sd *) gspca_dev;
1747 sd->brightness = val;
1748 if (gspca_dev->streaming)
1749 setbrightness(gspca_dev);
1750 return 0;
1753 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1755 struct sd *sd = (struct sd *) gspca_dev;
1757 *val = sd->brightness;
1758 return 0;
1761 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1763 struct sd *sd = (struct sd *) gspca_dev;
1765 sd->contrast = val;
1766 if (gspca_dev->streaming)
1767 setcontrast(gspca_dev);
1768 return 0;
1771 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1773 struct sd *sd = (struct sd *) gspca_dev;
1775 *val = sd->contrast;
1776 return 0;
1779 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1781 struct sd *sd = (struct sd *) gspca_dev;
1783 sd->colors = val;
1784 if (gspca_dev->streaming)
1785 setcolors(gspca_dev);
1786 return 0;
1789 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1791 struct sd *sd = (struct sd *) gspca_dev;
1793 *val = sd->colors;
1794 return 0;
1797 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1799 struct sd *sd = (struct sd *) gspca_dev;
1801 sd->blue = val;
1802 if (gspca_dev->streaming)
1803 setredblue(gspca_dev);
1804 return 0;
1807 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1809 struct sd *sd = (struct sd *) gspca_dev;
1811 *val = sd->blue;
1812 return 0;
1815 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1817 struct sd *sd = (struct sd *) gspca_dev;
1819 sd->red = val;
1820 if (gspca_dev->streaming)
1821 setredblue(gspca_dev);
1822 return 0;
1825 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1827 struct sd *sd = (struct sd *) gspca_dev;
1829 *val = sd->red;
1830 return 0;
1833 static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1835 struct sd *sd = (struct sd *) gspca_dev;
1837 sd->gamma = val;
1838 if (gspca_dev->streaming)
1839 setgamma(gspca_dev);
1840 return 0;
1843 static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1845 struct sd *sd = (struct sd *) gspca_dev;
1847 *val = sd->gamma;
1848 return 0;
1851 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1853 struct sd *sd = (struct sd *) gspca_dev;
1855 sd->autogain = val;
1856 if (gspca_dev->streaming)
1857 setautogain(gspca_dev);
1858 return 0;
1861 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1863 struct sd *sd = (struct sd *) gspca_dev;
1865 *val = sd->autogain;
1866 return 0;
1869 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1871 struct sd *sd = (struct sd *) gspca_dev;
1873 sd->vflip = val;
1874 if (gspca_dev->streaming)
1875 setvflip(sd);
1876 return 0;
1879 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1881 struct sd *sd = (struct sd *) gspca_dev;
1883 *val = sd->vflip;
1884 return 0;
1887 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1889 struct sd *sd = (struct sd *) gspca_dev;
1891 sd->infrared = val;
1892 if (gspca_dev->streaming)
1893 setinfrared(sd);
1894 return 0;
1897 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1899 struct sd *sd = (struct sd *) gspca_dev;
1901 *val = sd->infrared;
1902 return 0;
1905 /* sub-driver description */
1906 static const struct sd_desc sd_desc = {
1907 .name = MODULE_NAME,
1908 .ctrls = sd_ctrls,
1909 .nctrls = ARRAY_SIZE(sd_ctrls),
1910 .config = sd_config,
1911 .init = sd_init,
1912 .start = sd_start,
1913 .stopN = sd_stopN,
1914 .pkt_scan = sd_pkt_scan,
1915 .dq_callback = do_autogain,
1918 /* -- module initialisation -- */
1919 #define BSI(bridge, sensor, i2c_addr) \
1920 .driver_info = (BRIDGE_ ## bridge << 16) \
1921 | (SENSOR_ ## sensor << 8) \
1922 | (i2c_addr)
1923 static const __devinitdata struct usb_device_id device_table[] = {
1924 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1925 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1926 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1927 #endif
1928 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1929 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1930 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1931 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1932 #endif
1933 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1934 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1935 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1936 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1937 /* bw600.inf:
1938 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1939 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1940 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1941 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1942 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1943 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1944 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1945 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1946 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1947 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1948 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1949 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1950 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1951 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1952 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1953 #endif
1954 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1955 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1956 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1957 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1958 /*bw600.inf:*/
1959 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1960 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1961 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1962 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1963 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1964 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1965 #endif
1966 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1967 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1968 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1969 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1970 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1971 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1972 #endif
1973 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1976 MODULE_DEVICE_TABLE(usb, device_table);
1978 /* -- device connect -- */
1979 static int sd_probe(struct usb_interface *intf,
1980 const struct usb_device_id *id)
1982 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1983 THIS_MODULE);
1986 static struct usb_driver sd_driver = {
1987 .name = MODULE_NAME,
1988 .id_table = device_table,
1989 .probe = sd_probe,
1990 .disconnect = gspca_disconnect,
1991 #ifdef CONFIG_PM
1992 .suspend = gspca_suspend,
1993 .resume = gspca_resume,
1994 #endif
1997 /* -- module insert / remove -- */
1998 static int __init sd_mod_init(void)
2000 int ret;
2001 ret = usb_register(&sd_driver);
2002 if (ret < 0)
2003 return ret;
2004 info("registered");
2005 return 0;
2007 static void __exit sd_mod_exit(void)
2009 usb_deregister(&sd_driver);
2010 info("deregistered");
2013 module_init(sd_mod_init);
2014 module_exit(sd_mod_exit);