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"
27 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
31 MODULE_LICENSE("GPL");
33 /* specific webcam descriptor */
35 struct gspca_dev gspca_dev; /* !! must be the first item */
38 unsigned int exposure;
46 __u8 vflip; /* ov7630 only */
47 __u8 infrared; /* mi0360 only */
50 #define AG_CNT_START 13
54 #define BRIDGE_SN9C102P 0
55 #define BRIDGE_SN9C105 1
56 #define BRIDGE_SN9C110 2
57 #define BRIDGE_SN9C120 3
58 #define BRIDGE_SN9C325 4
59 __u8 sensor; /* Type of image sensor chip */
60 #define SENSOR_HV7131R 0
61 #define SENSOR_MI0360 1
62 #define SENSOR_MO4000 2
63 #define SENSOR_OM6802 3
64 #define SENSOR_OV7630 4
65 #define SENSOR_OV7648 5
66 #define SENSOR_OV7660 6
70 /* V4L2 controls supported by the driver */
71 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
81 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
85 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
88 static struct ctrl sd_ctrls[] = {
91 .id = V4L2_CID_BRIGHTNESS,
92 .type = V4L2_CTRL_TYPE_INTEGER,
95 #define BRIGHTNESS_MAX 0xffff
96 .maximum = BRIGHTNESS_MAX,
98 #define BRIGHTNESS_DEF 0x8000
99 .default_value = BRIGHTNESS_DEF,
101 .set = sd_setbrightness,
102 .get = sd_getbrightness,
106 .id = V4L2_CID_CONTRAST,
107 .type = V4L2_CTRL_TYPE_INTEGER,
110 #define CONTRAST_MAX 127
111 .maximum = CONTRAST_MAX,
113 #define CONTRAST_DEF 63
114 .default_value = CONTRAST_DEF,
116 .set = sd_setcontrast,
117 .get = sd_getcontrast,
121 .id = V4L2_CID_SATURATION,
122 .type = V4L2_CTRL_TYPE_INTEGER,
128 .default_value = COLOR_DEF,
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
141 #define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
155 #define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
161 #define AUTOGAIN_IDX 5
164 .id = V4L2_CID_AUTOGAIN,
165 .type = V4L2_CTRL_TYPE_BOOLEAN,
170 #define AUTOGAIN_DEF 1
171 .default_value = AUTOGAIN_DEF,
173 .set = sd_setautogain,
174 .get = sd_getautogain,
180 .id = V4L2_CID_VFLIP,
181 .type = V4L2_CTRL_TYPE_BOOLEAN,
187 .default_value = VFLIP_DEF,
193 #define INFRARED_IDX 7
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
202 #define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
210 /* table of the disabled controls */
211 static __u32 ctrl_dis[] = {
212 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
213 /* SENSOR_HV7131R 0 */
215 /* SENSOR_MI0360 1 */
216 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
217 /* SENSOR_MO4000 2 */
218 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
219 /* SENSOR_OM6802 3 */
220 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
221 /* SENSOR_OV7630 4 */
222 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
223 /* SENSOR_OV7648 5 */
224 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
225 /* SENSOR_OV7660 6 */
228 static const struct v4l2_pix_format vga_mode[] = {
229 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
231 .sizeimage = 160 * 120 * 4 / 8 + 590,
232 .colorspace = V4L2_COLORSPACE_JPEG,
234 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
236 .sizeimage = 320 * 240 * 3 / 8 + 590,
237 .colorspace = V4L2_COLORSPACE_JPEG,
239 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
241 .sizeimage = 640 * 480 * 3 / 8 + 590,
242 .colorspace = V4L2_COLORSPACE_JPEG,
246 /*Data from sn9c102p+hv71331r */
247 static const __u8 sn_hv7131[] = {
248 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
249 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
250 /* reg8 reg9 rega regb regc regd rege regf */
251 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
252 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
253 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
254 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
255 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
258 static const __u8 sn_mi0360[] = {
259 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
260 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
261 /* reg8 reg9 rega regb regc regd rege regf */
262 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
263 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
264 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
265 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
266 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
269 static const __u8 sn_mo4000[] = {
270 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
271 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
272 /* reg8 reg9 rega regb regc regd rege regf */
273 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
275 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
276 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
277 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
280 static const __u8 sn_om6802[] = {
281 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
282 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
283 /* reg8 reg9 rega regb regc regd rege regf */
284 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
286 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
287 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
288 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
290 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
294 static const __u8 sn_ov7630[] = {
295 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
296 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
297 /* reg8 reg9 rega regb regc regd rege regf */
298 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
299 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
300 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
301 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
302 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
305 static const __u8 sn_ov7648[] = {
306 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
307 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
308 /* reg8 reg9 rega regb regc regd rege regf */
309 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
310 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
311 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
312 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
313 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
316 static const __u8 sn_ov7660[] = {
317 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
318 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
319 /* reg8 reg9 rega regb regc regd rege regf */
320 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
321 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
322 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
323 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
324 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 /* sequence specific to the sensors - !! index = SENSOR_xxx */
328 static const __u8 *sn_tb[] = {
338 static const __u8 gamma_def[] = {
339 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
340 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
343 /* color matrix and offsets */
344 static const __u8 reg84[] = {
345 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
346 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
347 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
348 0x00, 0x00, 0x00 /* YUV offsets */
350 static const __u8 hv7131r_sensor_init[][8] = {
351 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
352 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
353 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
354 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
355 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
356 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
357 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
359 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
360 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
361 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
362 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
363 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
364 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
365 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
366 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
368 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
369 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
370 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
371 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
374 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
375 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
377 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
381 static const __u8 mi0360_sensor_init[][8] = {
382 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
383 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
384 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
385 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
386 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
387 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
388 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
389 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
390 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
391 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
392 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
395 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
396 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
397 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
398 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
399 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
401 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
402 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
403 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
404 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
405 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
406 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
407 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
408 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
409 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
410 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
411 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
412 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
413 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
414 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
416 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
417 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
418 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
419 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
420 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
422 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
423 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
424 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
425 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
427 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
428 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
429 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
430 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
431 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
432 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
435 static const __u8 mo4000_sensor_init[][8] = {
436 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
437 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
448 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
449 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
450 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
453 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
454 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
458 static __u8 om6802_sensor_init[][8] = {
459 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
460 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
461 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
462 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
463 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
464 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
465 /* white balance & auto-exposure */
466 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
468 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
469 * max AGC value in AE */
470 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
472 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
473 * preset brightness */
474 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
476 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
478 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
479 /* luminance mode (0x4f = AE) */
480 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
482 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
484 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
486 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
487 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
488 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
489 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
492 static const __u8 ov7630_sensor_init[][8] = {
493 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
495 /* win: delay 20ms */
496 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
498 /* win: delay 20ms */
499 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
500 /* win: i2c_r from 00 to 80 */
501 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
502 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
504 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
505 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
506 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
507 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
508 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
509 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
510 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
511 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
512 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
513 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
514 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
515 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
516 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
518 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
519 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
520 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
521 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
522 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
523 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
524 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
525 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
526 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
528 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
529 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
530 /*fixme: + 0x12, 0x04*/
531 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
533 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
534 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
537 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
538 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
539 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
541 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
542 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
546 static const __u8 ov7648_sensor_init[][8] = {
547 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
548 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
549 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
551 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
552 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
553 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
554 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
555 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
556 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
557 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
558 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
559 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
560 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
561 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
562 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
563 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
564 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
565 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
566 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
567 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
569 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
570 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
571 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
572 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
574 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
575 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
576 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
578 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
579 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
580 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
582 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
583 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
585 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
586 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
587 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
592 static const __u8 ov7660_sensor_init[][8] = {
593 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
595 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
596 /* Outformat = rawRGB */
597 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
598 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
599 /* GAIN BLUE RED VREF */
600 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
601 /* COM 1 BAVE GEAVE AECHH */
602 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
603 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
604 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
605 /* AECH CLKRC COM7 COM8 */
606 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
607 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
608 /* HSTART HSTOP VSTRT VSTOP */
609 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
610 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
611 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
612 /* BOS GBOS GROS ROS (BGGR offset) */
613 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
614 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
615 /* AEW AEB VPT BBIAS */
616 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
617 /* GbBIAS RSVD EXHCH EXHCL */
618 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
619 /* RBIAS ADVFL ASDVFH YAVE */
620 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
621 /* HSYST HSYEN HREF */
622 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
623 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
624 /* ADC ACOM OFON TSLB */
625 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
626 /* COM11 COM12 COM13 COM14 */
627 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
628 /* EDGE COM15 COM16 COM17 */
629 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
630 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
631 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
632 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
633 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
634 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
635 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
636 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
637 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
638 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
639 /* LCC1 LCC2 LCC3 LCC4 */
640 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
641 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
642 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
643 /* band gap reference [0:3] DBLV */
644 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
645 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
646 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
647 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
648 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
649 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
650 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
651 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
652 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
653 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
654 /****** (some exchanges in the win trace) ******/
655 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
656 /* bits[3..0]reserved */
657 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
658 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
659 /* VREF vertical frame ctrl */
660 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
661 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
662 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
663 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
664 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
665 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
666 /****** (some exchanges in the win trace) ******/
667 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
668 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
669 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
670 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
671 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
672 /****** (some exchanges in the win trace) ******/
673 /******!! startsensor KO if changed !!****/
674 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
675 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
676 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
677 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
681 static const __u8 qtable4[] = {
682 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
683 0x06, 0x08, 0x0A, 0x11,
684 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
685 0x19, 0x19, 0x17, 0x15,
686 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
687 0x21, 0x2E, 0x21, 0x23,
688 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
689 0x25, 0x29, 0x2C, 0x29,
690 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
691 0x17, 0x1B, 0x29, 0x29,
692 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
693 0x29, 0x29, 0x29, 0x29,
694 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
695 0x29, 0x29, 0x29, 0x29,
696 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
697 0x29, 0x29, 0x29, 0x29
700 /* read <len> bytes to gspca_dev->usb_buf */
701 static void reg_r(struct gspca_dev *gspca_dev,
702 __u16 value, int len)
705 if (len > USB_BUF_SZ) {
706 err("reg_r: buffer overflow");
710 usb_control_msg(gspca_dev->dev,
711 usb_rcvctrlpipe(gspca_dev->dev, 0),
713 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
715 gspca_dev->usb_buf, len,
717 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
720 static void reg_w1(struct gspca_dev *gspca_dev,
724 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
725 gspca_dev->usb_buf[0] = data;
726 usb_control_msg(gspca_dev->dev,
727 usb_sndctrlpipe(gspca_dev->dev, 0),
729 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
732 gspca_dev->usb_buf, 1,
735 static void reg_w(struct gspca_dev *gspca_dev,
740 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
741 value, buffer[0], buffer[1]);
743 if (len > USB_BUF_SZ) {
744 err("reg_w: buffer overflow");
748 memcpy(gspca_dev->usb_buf, buffer, len);
749 usb_control_msg(gspca_dev->dev,
750 usb_sndctrlpipe(gspca_dev->dev, 0),
752 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
754 gspca_dev->usb_buf, len,
758 /* I2C write 1 byte */
759 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
761 struct sd *sd = (struct sd *) gspca_dev;
763 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
764 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
765 gspca_dev->usb_buf[1] = sd->i2c_base;
766 gspca_dev->usb_buf[2] = reg;
767 gspca_dev->usb_buf[3] = val;
768 gspca_dev->usb_buf[4] = 0;
769 gspca_dev->usb_buf[5] = 0;
770 gspca_dev->usb_buf[6] = 0;
771 gspca_dev->usb_buf[7] = 0x10;
772 usb_control_msg(gspca_dev->dev,
773 usb_sndctrlpipe(gspca_dev->dev, 0),
775 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
776 0x08, /* value = i2c */
778 gspca_dev->usb_buf, 8,
782 /* I2C write 8 bytes */
783 static void i2c_w8(struct gspca_dev *gspca_dev,
786 memcpy(gspca_dev->usb_buf, buffer, 8);
787 usb_control_msg(gspca_dev->dev,
788 usb_sndctrlpipe(gspca_dev->dev, 0),
790 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
791 0x08, 0, /* value, index */
792 gspca_dev->usb_buf, 8,
797 /* read 5 bytes in gspca_dev->usb_buf */
798 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
800 struct sd *sd = (struct sd *) gspca_dev;
803 mode[0] = 0x81 | 0x10;
804 mode[1] = sd->i2c_base;
811 i2c_w8(gspca_dev, mode);
813 mode[0] = 0x81 | (5 << 4) | 0x02;
815 i2c_w8(gspca_dev, mode);
817 reg_r(gspca_dev, 0x0a, 5);
820 static int probesensor(struct gspca_dev *gspca_dev)
822 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
824 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
826 i2c_r5(gspca_dev, 0); /* read sensor id */
827 if (gspca_dev->usb_buf[0] == 0x02
828 && gspca_dev->usb_buf[1] == 0x09
829 && gspca_dev->usb_buf[2] == 0x01
830 && gspca_dev->usb_buf[3] == 0x00
831 && gspca_dev->usb_buf[4] == 0x00) {
832 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
835 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
836 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
837 gspca_dev->usb_buf[2]);
838 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
842 static int configure_gpio(struct gspca_dev *gspca_dev,
845 struct sd *sd = (struct sd *) gspca_dev;
847 static const __u8 reg9a_def[] =
848 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
849 static const __u8 reg9a_sn9c325[] =
850 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
851 static const __u8 regd4[] = {0x60, 0x00, 0x00};
853 reg_w1(gspca_dev, 0xf1, 0x00);
854 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
857 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
858 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
859 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
860 switch (sd->bridge) {
862 reg9a = reg9a_sn9c325;
868 reg_w(gspca_dev, 0x9a, reg9a, 6);
870 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
872 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
874 switch (sd->sensor) {
876 reg_w1(gspca_dev, 0x02, 0x71);
877 reg_w1(gspca_dev, 0x01, 0x42);
878 reg_w1(gspca_dev, 0x17, 0x64);
879 reg_w1(gspca_dev, 0x01, 0x42);
881 /*jfm: from win trace */
883 reg_w1(gspca_dev, 0x01, 0x61);
884 reg_w1(gspca_dev, 0x17, 0xe2);
885 reg_w1(gspca_dev, 0x01, 0x60);
886 reg_w1(gspca_dev, 0x01, 0x40);
889 reg_w1(gspca_dev, 0x01, 0x63);
890 reg_w1(gspca_dev, 0x17, 0x20);
891 reg_w1(gspca_dev, 0x01, 0x42);
893 /*jfm: from win trace */
895 if (sd->bridge == BRIDGE_SN9C120) {
896 reg_w1(gspca_dev, 0x01, 0x61);
897 reg_w1(gspca_dev, 0x17, 0x20);
898 reg_w1(gspca_dev, 0x01, 0x60);
899 reg_w1(gspca_dev, 0x01, 0x40);
904 reg_w1(gspca_dev, 0x01, 0x43);
905 reg_w1(gspca_dev, 0x17, 0x61);
906 reg_w1(gspca_dev, 0x01, 0x42);
907 if (sd->sensor == SENSOR_HV7131R) {
908 if (probesensor(gspca_dev) < 0)
916 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
919 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
920 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
922 while (hv7131r_sensor_init[i][0]) {
923 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
926 i2c_w8(gspca_dev, SetSensorClk);
929 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
933 while (mi0360_sensor_init[i][0]) {
934 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
939 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
943 while (mo4000_sensor_init[i][0]) {
944 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
949 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
953 while (om6802_sensor_init[i][0]) {
954 i2c_w8(gspca_dev, om6802_sensor_init[i]);
959 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
963 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
965 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
968 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
970 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
973 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
975 /*jfm:win i2c_r from 00 to 80*/
977 while (ov7630_sensor_init[i][0]) {
978 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
983 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
987 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
989 /* win: dble reset */
990 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
993 /* win: i2c reg read 00..7f */
994 while (ov7648_sensor_init[i][0]) {
995 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1000 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1004 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1007 while (ov7660_sensor_init[i][0]) {
1008 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1013 /* this function is called at probe time */
1014 static int sd_config(struct gspca_dev *gspca_dev,
1015 const struct usb_device_id *id)
1017 struct sd *sd = (struct sd *) gspca_dev;
1020 cam = &gspca_dev->cam;
1021 cam->cam_mode = vga_mode;
1022 cam->nmodes = ARRAY_SIZE(vga_mode);
1024 sd->bridge = id->driver_info >> 16;
1025 sd->sensor = id->driver_info >> 8;
1026 sd->i2c_base = id->driver_info;
1028 sd->qindex = 4; /* set the quantization table */
1029 sd->brightness = BRIGHTNESS_DEF;
1030 sd->contrast = CONTRAST_DEF;
1031 sd->colors = COLOR_DEF;
1032 sd->blue = BLUE_BALANCE_DEF;
1033 sd->red = RED_BALANCE_DEF;
1034 sd->autogain = AUTOGAIN_DEF;
1036 sd->vflip = VFLIP_DEF;
1037 sd->infrared = INFRARED_DEF;
1039 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1043 /* this function is called at probe and resume time */
1044 static int sd_init(struct gspca_dev *gspca_dev)
1046 struct sd *sd = (struct sd *) gspca_dev;
1047 __u8 regGpio[] = { 0x29, 0x74 };
1050 /* setup a selector by bridge */
1051 reg_w1(gspca_dev, 0xf1, 0x01);
1052 reg_r(gspca_dev, 0x00, 1);
1053 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1054 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1055 regF1 = gspca_dev->usb_buf[0];
1056 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1057 switch (sd->bridge) {
1058 case BRIDGE_SN9C102P:
1061 reg_w1(gspca_dev, 0x02, regGpio[1]);
1063 case BRIDGE_SN9C105:
1066 reg_w(gspca_dev, 0x01, regGpio, 2);
1068 case BRIDGE_SN9C120:
1072 reg_w(gspca_dev, 0x01, regGpio, 2);
1075 /* case BRIDGE_SN9C110: */
1076 /* case BRIDGE_SN9C325: */
1079 reg_w1(gspca_dev, 0x02, 0x62);
1083 reg_w1(gspca_dev, 0xf1, 0x01);
1088 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1091 struct sd *sd = (struct sd *) gspca_dev;
1092 static const __u8 doit[] = /* update sensor */
1093 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1094 static const __u8 sensorgo[] = /* sensor on */
1095 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1096 static const __u8 gainMo[] =
1097 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1099 switch (sd->sensor) {
1100 case SENSOR_HV7131R: {
1102 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1104 Expodoit[3] = expo >> 16;
1105 Expodoit[4] = expo >> 8;
1107 i2c_w8(gspca_dev, Expodoit);
1110 case SENSOR_MI0360: {
1111 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1112 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1116 else if (expo < 0x0001)
1118 expoMi[3] = expo >> 8;
1120 i2c_w8(gspca_dev, expoMi);
1121 i2c_w8(gspca_dev, doit);
1122 i2c_w8(gspca_dev, sensorgo);
1125 case SENSOR_MO4000: {
1127 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1129 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1133 else if (expo < 0x0001)
1135 expoMof[3] = (expo & 0x03fc) >> 2;
1136 i2c_w8(gspca_dev, expoMof);
1137 expoMo10[3] = ((expo & 0x1c00) >> 10)
1138 | ((expo & 0x0003) << 4);
1139 i2c_w8(gspca_dev, expoMo10);
1140 i2c_w8(gspca_dev, gainMo);
1141 PDEBUG(D_CONF, "set exposure %d",
1142 ((expoMo10[3] & 0x07) << 10)
1144 | ((expoMo10[3] & 0x30) >> 4));
1147 case SENSOR_OM6802: {
1149 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1155 gainOm[3] = expo >> 2;
1156 i2c_w8(gspca_dev, gainOm);
1157 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1158 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1165 static void setbrightness(struct gspca_dev *gspca_dev)
1167 struct sd *sd = (struct sd *) gspca_dev;
1171 k2 = ((int) sd->brightness - 0x8000) >> 10;
1172 switch (sd->sensor) {
1173 case SENSOR_HV7131R:
1174 expo = sd->brightness << 4;
1175 if (expo > 0x002dc6c0)
1177 else if (expo < 0x02a0)
1179 sd->exposure = setexposure(gspca_dev, expo);
1183 expo = sd->brightness >> 4;
1184 sd->exposure = setexposure(gspca_dev, expo);
1187 expo = sd->brightness >> 6;
1188 sd->exposure = setexposure(gspca_dev, expo);
1189 k2 = sd->brightness >> 11;
1193 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1196 static void setcontrast(struct gspca_dev *gspca_dev)
1198 struct sd *sd = (struct sd *) gspca_dev;
1202 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1203 contrast[0] = (k2 + 1) / 2; /* red */
1205 contrast[2] = k2; /* green */
1207 contrast[4] = (k2 + 1) / 5; /* blue */
1209 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1212 static void setcolors(struct gspca_dev *gspca_dev)
1214 struct sd *sd = (struct sd *) gspca_dev;
1216 __u8 reg8a[12]; /* U & V gains */
1217 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1218 -24, -38, 64, /* UR UG UB */
1219 62, -51, -9 /* VR VG VB */
1221 for (i = 0; i < 6; i++) {
1222 v = uv[i] * sd->colors / COLOR_DEF;
1224 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1226 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1229 static void setredblue(struct gspca_dev *gspca_dev)
1231 struct sd *sd = (struct sd *) gspca_dev;
1233 reg_w1(gspca_dev, 0x05, sd->red);
1234 /* reg_w1(gspca_dev, 0x07, 32); */
1235 reg_w1(gspca_dev, 0x06, sd->blue);
1238 static void setautogain(struct gspca_dev *gspca_dev)
1240 struct sd *sd = (struct sd *) gspca_dev;
1242 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1245 sd->ag_cnt = AG_CNT_START;
1250 static void setvflip(struct sd *sd)
1252 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1253 sd->vflip ? 0x82 : 0x02);
1256 static void setinfrared(struct sd *sd)
1258 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1260 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1261 sd->infrared ? 0x66 : 0x64);
1264 /* -- start the camera -- */
1265 static int sd_start(struct gspca_dev *gspca_dev)
1267 struct sd *sd = (struct sd *) gspca_dev;
1269 __u8 reg1, reg17, reg18;
1270 const __u8 *sn9c1xx;
1272 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1273 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1274 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1275 static const __u8 CE_ov76xx[] =
1276 { 0x32, 0xdd, 0x32, 0xdd };
1278 sn9c1xx = sn_tb[(int) sd->sensor];
1279 configure_gpio(gspca_dev, sn9c1xx);
1281 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1282 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1283 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1284 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1285 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1286 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1287 reg_w1(gspca_dev, 0xd3, 0x50);
1288 reg_w1(gspca_dev, 0xc6, 0x00);
1289 reg_w1(gspca_dev, 0xc7, 0x00);
1290 reg_w1(gspca_dev, 0xc8, 0x50);
1291 reg_w1(gspca_dev, 0xc9, 0x3c);
1292 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1293 switch (sd->sensor) {
1300 /*jfm: from win trace */
1302 if (sd->bridge == BRIDGE_SN9C120) {
1311 reg_w1(gspca_dev, 0x17, reg17);
1312 /* set reg1 was here */
1313 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1314 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1315 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1316 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1317 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1318 for (i = 0; i < 8; i++)
1319 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1320 switch (sd->sensor) {
1322 reg_w1(gspca_dev, 0x9a, 0x0a);
1323 reg_w1(gspca_dev, 0x99, 0x60);
1326 if (sd->bridge == BRIDGE_SN9C120) {
1327 reg_w1(gspca_dev, 0x9a, 0x05);
1332 reg_w1(gspca_dev, 0x9a, 0x08);
1333 reg_w1(gspca_dev, 0x99, 0x59);
1337 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1339 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1341 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1342 reg17 = 0x61; /* 0x:20: enable sensor clock */
1343 switch (sd->sensor) {
1344 case SENSOR_HV7131R:
1345 hv7131R_InitSensor(gspca_dev);
1348 mi0360_InitSensor(gspca_dev);
1351 mo4000_InitSensor(gspca_dev);
1353 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1354 reg1 = 0x06; /* clk 24Mz */
1356 reg17 = 0x22; /* 640 MCKSIZE */
1357 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1361 om6802_InitSensor(gspca_dev);
1362 reg17 = 0x64; /* 640 MCKSIZE */
1365 ov7630_InitSensor(gspca_dev);
1371 ov7648_InitSensor(gspca_dev);
1373 /* reg1 = 0x42; * 42 - 46? */
1376 /* case SENSOR_OV7660: */
1377 ov7660_InitSensor(gspca_dev);
1378 if (sd->bridge == BRIDGE_SN9C120) {
1379 if (mode) { /* 320x240 - 160x120 */
1381 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1385 reg1 = 0x06; /* 24 Mhz, video trf eneble
1386 * inverse power down */
1390 reg_w(gspca_dev, 0xc0, C0, 6);
1391 reg_w(gspca_dev, 0xca, CA, 4);
1392 switch (sd->sensor) {
1396 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1399 reg_w(gspca_dev, 0xce, CE, 4);
1400 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1404 /* here change size mode 0 -> VGA; 1 -> CIF */
1405 reg18 = sn9c1xx[0x18] | (mode << 4);
1406 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1408 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1409 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1411 reg_w1(gspca_dev, 0x18, reg18);
1413 reg_w1(gspca_dev, 0x17, reg17);
1414 reg_w1(gspca_dev, 0x01, reg1);
1415 switch (sd->sensor) {
1423 setbrightness(gspca_dev);
1424 setcontrast(gspca_dev);
1425 setautogain(gspca_dev);
1429 static void sd_stopN(struct gspca_dev *gspca_dev)
1431 struct sd *sd = (struct sd *) gspca_dev;
1432 static const __u8 stophv7131[] =
1433 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1434 static const __u8 stopmi0360[] =
1435 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1436 static const __u8 stopov7648[] =
1437 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1439 const __u8 *sn9c1xx;
1442 switch (sd->sensor) {
1443 case SENSOR_HV7131R:
1444 i2c_w8(gspca_dev, stophv7131);
1448 i2c_w8(gspca_dev, stopmi0360);
1452 i2c_w8(gspca_dev, stopov7648);
1458 /* case SENSOR_MO4000: */
1459 /* case SENSOR_OV7660: */
1462 sn9c1xx = sn_tb[(int) sd->sensor];
1463 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1464 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1465 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1466 reg_w1(gspca_dev, 0x01, data);
1467 reg_w1(gspca_dev, 0xf1, 0x00);
1470 static void do_autogain(struct gspca_dev *gspca_dev)
1472 struct sd *sd = (struct sd *) gspca_dev;
1475 __u8 luma_mean = 130;
1476 __u8 luma_delta = 20;
1478 /* Thanks S., without your advice, autobright should not work :) */
1481 if (--sd->ag_cnt >= 0)
1483 sd->ag_cnt = AG_CNT_START;
1485 delta = atomic_read(&sd->avg_lum);
1486 PDEBUG(D_FRAM, "mean lum %d", delta);
1487 if (delta < luma_mean - luma_delta ||
1488 delta > luma_mean + luma_delta) {
1489 switch (sd->sensor) {
1490 case SENSOR_HV7131R:
1491 expotimes = sd->exposure >> 8;
1492 expotimes += (luma_mean - delta) >> 4;
1495 sd->exposure = setexposure(gspca_dev,
1496 (unsigned int) (expotimes << 8));
1499 /* case SENSOR_MO4000: */
1500 /* case SENSOR_MI0360: */
1501 /* case SENSOR_OM6802: */
1502 expotimes = sd->exposure;
1503 expotimes += (luma_mean - delta) >> 6;
1506 sd->exposure = setexposure(gspca_dev,
1507 (unsigned int) expotimes);
1508 setredblue(gspca_dev);
1514 /* scan the URB packets */
1515 /* This function is run at interrupt level. */
1516 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1517 struct gspca_frame *frame, /* target */
1518 __u8 *data, /* isoc packet */
1519 int len) /* iso packet length */
1521 struct sd *sd = (struct sd *) gspca_dev;
1525 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1528 gspca_frame_add(gspca_dev, LAST_PACKET,
1529 frame, data, sof + 2);
1536 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1538 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1540 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1542 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1544 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1546 atomic_set(&sd->avg_lum, avg_lum);
1549 if (gspca_dev->last_packet_type == LAST_PACKET) {
1551 /* put the JPEG 422 header */
1552 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1554 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1557 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1559 struct sd *sd = (struct sd *) gspca_dev;
1561 sd->brightness = val;
1562 if (gspca_dev->streaming)
1563 setbrightness(gspca_dev);
1567 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1569 struct sd *sd = (struct sd *) gspca_dev;
1571 *val = sd->brightness;
1575 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1577 struct sd *sd = (struct sd *) gspca_dev;
1580 if (gspca_dev->streaming)
1581 setcontrast(gspca_dev);
1585 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1587 struct sd *sd = (struct sd *) gspca_dev;
1589 *val = sd->contrast;
1593 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1595 struct sd *sd = (struct sd *) gspca_dev;
1598 if (gspca_dev->streaming)
1599 setcolors(gspca_dev);
1603 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1605 struct sd *sd = (struct sd *) gspca_dev;
1611 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1613 struct sd *sd = (struct sd *) gspca_dev;
1616 if (gspca_dev->streaming)
1617 setredblue(gspca_dev);
1621 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1623 struct sd *sd = (struct sd *) gspca_dev;
1629 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1631 struct sd *sd = (struct sd *) gspca_dev;
1634 if (gspca_dev->streaming)
1635 setredblue(gspca_dev);
1639 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1641 struct sd *sd = (struct sd *) gspca_dev;
1647 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1649 struct sd *sd = (struct sd *) gspca_dev;
1652 if (gspca_dev->streaming)
1653 setautogain(gspca_dev);
1657 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1659 struct sd *sd = (struct sd *) gspca_dev;
1661 *val = sd->autogain;
1665 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1667 struct sd *sd = (struct sd *) gspca_dev;
1670 if (gspca_dev->streaming)
1675 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1677 struct sd *sd = (struct sd *) gspca_dev;
1683 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1685 struct sd *sd = (struct sd *) gspca_dev;
1688 if (gspca_dev->streaming)
1693 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1695 struct sd *sd = (struct sd *) gspca_dev;
1697 *val = sd->infrared;
1701 /* sub-driver description */
1702 static const struct sd_desc sd_desc = {
1703 .name = MODULE_NAME,
1705 .nctrls = ARRAY_SIZE(sd_ctrls),
1706 .config = sd_config,
1710 .pkt_scan = sd_pkt_scan,
1711 .dq_callback = do_autogain,
1714 /* -- module initialisation -- */
1715 #define BSI(bridge, sensor, i2c_addr) \
1716 .driver_info = (BRIDGE_ ## bridge << 16) \
1717 | (SENSOR_ ## sensor << 8) \
1719 static const __devinitdata struct usb_device_id device_table[] = {
1720 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1721 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1722 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1724 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1725 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1726 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1727 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1729 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1730 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1731 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1732 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1734 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1735 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1736 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1737 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1738 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1739 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1740 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1741 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1742 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1743 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1744 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1745 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1746 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1747 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1748 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1750 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1751 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1752 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1753 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1755 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1756 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1757 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1758 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1759 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1760 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1762 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1763 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1764 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1765 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1766 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1767 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1769 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1772 MODULE_DEVICE_TABLE(usb, device_table);
1774 /* -- device connect -- */
1775 static int sd_probe(struct usb_interface *intf,
1776 const struct usb_device_id *id)
1778 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1782 static struct usb_driver sd_driver = {
1783 .name = MODULE_NAME,
1784 .id_table = device_table,
1786 .disconnect = gspca_disconnect,
1788 .suspend = gspca_suspend,
1789 .resume = gspca_resume,
1793 /* -- module insert / remove -- */
1794 static int __init sd_mod_init(void)
1797 ret = usb_register(&sd_driver);
1803 static void __exit sd_mod_exit(void)
1805 usb_deregister(&sd_driver);
1806 info("deregistered");
1809 module_init(sd_mod_init);
1810 module_exit(sd_mod_exit);