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;
40 unsigned short brightness;
41 unsigned char contrast;
43 unsigned char autogain;
44 __u8 vflip; /* ov7630 only */
45 __u8 infrared; /* mi0360 only */
48 #define AG_CNT_START 13
52 #define BRIDGE_SN9C102P 0
53 #define BRIDGE_SN9C105 1
54 #define BRIDGE_SN9C110 2
55 #define BRIDGE_SN9C120 3
56 #define BRIDGE_SN9C325 4
57 char sensor; /* Type of image sensor chip */
58 #define SENSOR_HV7131R 0
59 #define SENSOR_MI0360 1
60 #define SENSOR_MO4000 2
61 #define SENSOR_OM6802 3
62 #define SENSOR_OV7630 4
63 #define SENSOR_OV7648 5
64 #define SENSOR_OV7660 6
65 unsigned char i2c_base;
68 /* V4L2 controls supported by the driver */
69 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
82 static struct ctrl sd_ctrls[] = {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
89 #define BRIGHTNESS_MAX 0xffff
90 .maximum = BRIGHTNESS_MAX,
92 #define BRIGHTNESS_DEF 0x7fff
93 .default_value = BRIGHTNESS_DEF,
95 .set = sd_setbrightness,
96 .get = sd_getbrightness,
100 .id = V4L2_CID_CONTRAST,
101 .type = V4L2_CTRL_TYPE_INTEGER,
104 #define CONTRAST_MAX 127
105 .maximum = CONTRAST_MAX,
107 #define CONTRAST_DEF 63
108 .default_value = CONTRAST_DEF,
110 .set = sd_setcontrast,
111 .get = sd_getcontrast,
115 .id = V4L2_CID_SATURATION,
116 .type = V4L2_CTRL_TYPE_INTEGER,
122 .default_value = COLOR_DEF,
127 #define AUTOGAIN_IDX 3
130 .id = V4L2_CID_AUTOGAIN,
131 .type = V4L2_CTRL_TYPE_BOOLEAN,
136 #define AUTOGAIN_DEF 1
137 .default_value = AUTOGAIN_DEF,
139 .set = sd_setautogain,
140 .get = sd_getautogain,
146 .id = V4L2_CID_VFLIP,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
153 .default_value = VFLIP_DEF,
159 #define INFRARED_IDX 5
162 .id = V4L2_CID_INFRARED,
163 .type = V4L2_CTRL_TYPE_BOOLEAN,
168 #define INFRARED_DEF 0
169 .default_value = INFRARED_DEF,
171 .set = sd_setinfrared,
172 .get = sd_getinfrared,
176 static struct v4l2_pix_format vga_mode[] = {
177 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
179 .sizeimage = 160 * 120 * 4 / 8 + 590,
180 .colorspace = V4L2_COLORSPACE_JPEG,
182 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
184 .sizeimage = 320 * 240 * 3 / 8 + 590,
185 .colorspace = V4L2_COLORSPACE_JPEG,
187 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
189 .sizeimage = 640 * 480 * 3 / 8 + 590,
190 .colorspace = V4L2_COLORSPACE_JPEG,
194 /*Data from sn9c102p+hv71331r */
195 static const __u8 sn_hv7131[] = {
196 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
197 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
198 /* reg8 reg9 rega regb regc regd rege regf */
199 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
200 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
201 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
202 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
203 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
206 static const __u8 sn_mi0360[] = {
207 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
208 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
209 /* reg8 reg9 rega regb regc regd rege regf */
210 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
211 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
212 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
213 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
214 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
217 static const __u8 sn_mo4000[] = {
218 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
219 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
220 /* reg8 reg9 rega regb regc regd rege regf */
221 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
223 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
224 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
225 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
228 static const __u8 sn_om6802[] = {
229 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
230 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
231 /* reg8 reg9 rega regb regc regd rege regf */
232 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
234 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
235 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
236 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
238 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
242 static const __u8 sn_ov7630[] = {
243 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
244 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
245 /* reg8 reg9 rega regb regc regd rege regf */
246 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
247 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
248 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
249 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
250 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
253 static const __u8 sn_ov7648[] = {
254 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
255 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
256 /* reg8 reg9 rega regb regc regd rege regf */
257 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
258 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
259 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
260 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
261 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
264 static const __u8 sn_ov7660[] = {
265 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
266 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
267 /* reg8 reg9 rega regb regc regd rege regf */
268 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
269 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
270 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
271 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
272 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
275 /* sequence specific to the sensors - !! index = SENSOR_xxx */
276 static const __u8 *sn_tb[] = {
286 static const __u8 gamma_def[] = {
287 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
288 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
291 /* color matrix and offsets */
292 static const __u8 reg84[] = {
293 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
294 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
295 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
296 0x00, 0x00, 0x00 /* YUV offsets */
298 static const __u8 hv7131r_sensor_init[][8] = {
299 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
300 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
301 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
302 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
304 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
305 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
307 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
308 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
309 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
310 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
311 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
312 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
313 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
314 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
316 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
317 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
318 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
319 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
322 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
323 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
325 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
326 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
329 static const __u8 mi0360_sensor_init[][8] = {
330 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
331 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
332 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
334 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
335 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
336 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
337 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
338 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
339 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
340 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
341 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
342 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
343 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
344 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
345 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
346 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
347 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
348 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
349 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
350 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
351 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
352 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
353 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
354 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
355 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
356 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
357 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
358 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
359 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
360 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
361 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
362 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
364 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
365 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
366 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
367 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
368 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
370 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
371 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
372 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
373 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
375 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
376 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
377 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
378 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
379 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
380 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
383 static const __u8 mo4000_sensor_init[][8] = {
384 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
385 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
386 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
387 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
388 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
389 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
390 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
391 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
392 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
395 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
396 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
397 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
398 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
399 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
401 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
402 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
403 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
406 static __u8 om6802_sensor_init[][8] = {
407 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
408 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
409 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
410 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
411 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
412 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
413 /* white balance & auto-exposure */
414 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
416 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
417 * max AGC value in AE */
418 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
420 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
421 * preset brightness */
422 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
424 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
426 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
427 /* luminance mode (0x4f = AE) */
428 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
430 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
432 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
434 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
435 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
436 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
437 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
440 static const __u8 ov7630_sensor_init[][8] = {
441 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
443 /* win: delay 20ms */
444 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
446 /* win: delay 20ms */
447 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
448 /* win: i2c_r from 00 to 80 */
449 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
450 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
451 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
452 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
453 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
454 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
456 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
457 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
458 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
459 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
460 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
461 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
462 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
463 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
464 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
465 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
466 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
468 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
469 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
470 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
471 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
472 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
473 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
474 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
476 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
477 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
478 /*fixme: + 0x12, 0x04*/
479 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
481 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
483 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
485 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
486 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
487 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
489 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
490 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
494 static const __u8 ov7648_sensor_init[][8] = {
495 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
497 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
498 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
499 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
500 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
501 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
502 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
504 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
505 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
506 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
507 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
508 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
509 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
510 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
511 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
512 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
513 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
514 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
515 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
517 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
518 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
519 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
520 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
522 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
523 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
524 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
525 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
526 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
527 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
528 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
530 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
531 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
532 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
533 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
534 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
535 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
540 static const __u8 ov7660_sensor_init[][8] = {
541 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
543 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
544 /* Outformat = rawRGB */
545 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
546 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
547 /* GAIN BLUE RED VREF */
548 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
549 /* COM 1 BAVE GEAVE AECHH */
550 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
551 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
552 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
553 /* AECH CLKRC COM7 COM8 */
554 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
555 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
556 /* HSTART HSTOP VSTRT VSTOP */
557 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
558 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
559 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
560 /* BOS GBOS GROS ROS (BGGR offset) */
561 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
562 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
563 /* AEW AEB VPT BBIAS */
564 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
565 /* GbBIAS RSVD EXHCH EXHCL */
566 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
567 /* RBIAS ADVFL ASDVFH YAVE */
568 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
569 /* HSYST HSYEN HREF */
570 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
571 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
572 /* ADC ACOM OFON TSLB */
573 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
574 /* COM11 COM12 COM13 COM14 */
575 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
576 /* EDGE COM15 COM16 COM17 */
577 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
578 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
579 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
580 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
581 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
582 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
583 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
584 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
585 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
586 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
587 /* LCC1 LCC2 LCC3 LCC4 */
588 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
589 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
590 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
591 /* band gap reference [0:3] DBLV */
592 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
593 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
594 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
595 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
596 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
597 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
598 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
599 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
600 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
601 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
602 /****** (some exchanges in the win trace) ******/
603 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
604 /* bits[3..0]reserved */
605 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
606 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
607 /* VREF vertical frame ctrl */
608 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
609 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
610 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
611 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
612 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
613 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
614 /****** (some exchanges in the win trace) ******/
615 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
616 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
617 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
618 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
619 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
620 /****** (some exchanges in the win trace) ******/
621 /******!! startsensor KO if changed !!****/
622 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
623 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
624 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
629 static const __u8 qtable4[] = {
630 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
631 0x06, 0x08, 0x0A, 0x11,
632 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
633 0x19, 0x19, 0x17, 0x15,
634 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
635 0x21, 0x2E, 0x21, 0x23,
636 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
637 0x25, 0x29, 0x2C, 0x29,
638 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
639 0x17, 0x1B, 0x29, 0x29,
640 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
641 0x29, 0x29, 0x29, 0x29,
642 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
643 0x29, 0x29, 0x29, 0x29,
644 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
645 0x29, 0x29, 0x29, 0x29
648 /* read <len> bytes to gspca_dev->usb_buf */
649 static void reg_r(struct gspca_dev *gspca_dev,
650 __u16 value, int len)
653 if (len > USB_BUF_SZ) {
654 err("reg_r: buffer overflow");
658 usb_control_msg(gspca_dev->dev,
659 usb_rcvctrlpipe(gspca_dev->dev, 0),
661 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
663 gspca_dev->usb_buf, len,
665 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
668 static void reg_w1(struct gspca_dev *gspca_dev,
672 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
673 gspca_dev->usb_buf[0] = data;
674 usb_control_msg(gspca_dev->dev,
675 usb_sndctrlpipe(gspca_dev->dev, 0),
677 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
680 gspca_dev->usb_buf, 1,
683 static void reg_w(struct gspca_dev *gspca_dev,
688 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
689 value, buffer[0], buffer[1]);
691 if (len > USB_BUF_SZ) {
692 err("reg_w: buffer overflow");
696 memcpy(gspca_dev->usb_buf, buffer, len);
697 usb_control_msg(gspca_dev->dev,
698 usb_sndctrlpipe(gspca_dev->dev, 0),
700 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
702 gspca_dev->usb_buf, len,
706 /* I2C write 1 byte */
707 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
709 struct sd *sd = (struct sd *) gspca_dev;
711 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
712 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
713 gspca_dev->usb_buf[1] = sd->i2c_base;
714 gspca_dev->usb_buf[2] = reg;
715 gspca_dev->usb_buf[3] = val;
716 gspca_dev->usb_buf[4] = 0;
717 gspca_dev->usb_buf[5] = 0;
718 gspca_dev->usb_buf[6] = 0;
719 gspca_dev->usb_buf[7] = 0x10;
720 usb_control_msg(gspca_dev->dev,
721 usb_sndctrlpipe(gspca_dev->dev, 0),
723 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
724 0x08, /* value = i2c */
726 gspca_dev->usb_buf, 8,
730 /* I2C write 8 bytes */
731 static void i2c_w8(struct gspca_dev *gspca_dev,
734 memcpy(gspca_dev->usb_buf, buffer, 8);
735 usb_control_msg(gspca_dev->dev,
736 usb_sndctrlpipe(gspca_dev->dev, 0),
738 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
739 0x08, 0, /* value, index */
740 gspca_dev->usb_buf, 8,
745 /* read 5 bytes in gspca_dev->usb_buf */
746 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
748 struct sd *sd = (struct sd *) gspca_dev;
751 mode[0] = 0x81 | 0x10;
752 mode[1] = sd->i2c_base;
759 i2c_w8(gspca_dev, mode);
761 mode[0] = 0x81 | (5 << 4) | 0x02;
763 i2c_w8(gspca_dev, mode);
765 reg_r(gspca_dev, 0x0a, 5);
768 static int probesensor(struct gspca_dev *gspca_dev)
770 struct sd *sd = (struct sd *) gspca_dev;
772 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
774 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
776 i2c_r5(gspca_dev, 0); /* read sensor id */
777 if (gspca_dev->usb_buf[0] == 0x02
778 && gspca_dev->usb_buf[1] == 0x09
779 && gspca_dev->usb_buf[2] == 0x01
780 && gspca_dev->usb_buf[3] == 0x00
781 && gspca_dev->usb_buf[4] == 0x00) {
782 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
783 sd->sensor = SENSOR_HV7131R;
784 return SENSOR_HV7131R;
786 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
787 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
788 gspca_dev->usb_buf[2]);
789 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
793 static int configure_gpio(struct gspca_dev *gspca_dev,
796 struct sd *sd = (struct sd *) gspca_dev;
798 static const __u8 reg9a_def[] =
799 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
800 static const __u8 reg9a_sn9c325[] =
801 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
802 static const __u8 regd4[] = {0x60, 0x00, 0x00};
804 reg_w1(gspca_dev, 0xf1, 0x00);
805 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
808 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
809 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
810 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
811 switch (sd->bridge) {
813 reg9a = reg9a_sn9c325;
819 reg_w(gspca_dev, 0x9a, reg9a, 6);
821 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
823 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
825 switch (sd->sensor) {
827 reg_w1(gspca_dev, 0x02, 0x71);
828 reg_w1(gspca_dev, 0x01, 0x42);
829 reg_w1(gspca_dev, 0x17, 0x64);
830 reg_w1(gspca_dev, 0x01, 0x42);
832 /*jfm: from win trace */
834 reg_w1(gspca_dev, 0x01, 0x61);
835 reg_w1(gspca_dev, 0x17, 0xe2);
836 reg_w1(gspca_dev, 0x01, 0x60);
837 reg_w1(gspca_dev, 0x01, 0x40);
840 reg_w1(gspca_dev, 0x01, 0x63);
841 reg_w1(gspca_dev, 0x17, 0x20);
842 reg_w1(gspca_dev, 0x01, 0x42);
844 /*jfm: from win trace */
846 if (sd->bridge == BRIDGE_SN9C120) {
847 reg_w1(gspca_dev, 0x01, 0x61);
848 reg_w1(gspca_dev, 0x17, 0x20);
849 reg_w1(gspca_dev, 0x01, 0x60);
850 reg_w1(gspca_dev, 0x01, 0x40);
855 reg_w1(gspca_dev, 0x01, 0x43);
856 reg_w1(gspca_dev, 0x17, 0x61);
857 reg_w1(gspca_dev, 0x01, 0x42);
858 if (sd->sensor == SENSOR_HV7131R) {
859 if (probesensor(gspca_dev) < 0)
867 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
870 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
871 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
873 while (hv7131r_sensor_init[i][0]) {
874 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
877 i2c_w8(gspca_dev, SetSensorClk);
880 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
884 while (mi0360_sensor_init[i][0]) {
885 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
890 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
894 while (mo4000_sensor_init[i][0]) {
895 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
900 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
904 while (om6802_sensor_init[i][0]) {
905 i2c_w8(gspca_dev, om6802_sensor_init[i]);
910 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
914 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
916 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
919 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
921 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
924 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
926 /*jfm:win i2c_r from 00 to 80*/
928 while (ov7630_sensor_init[i][0]) {
929 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
934 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
938 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
940 /* win: dble reset */
941 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
944 /* win: i2c reg read 00..7f */
945 while (ov7648_sensor_init[i][0]) {
946 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
951 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
955 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
958 while (ov7660_sensor_init[i][0]) {
959 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
964 /* this function is called at probe time */
965 static int sd_config(struct gspca_dev *gspca_dev,
966 const struct usb_device_id *id)
968 struct sd *sd = (struct sd *) gspca_dev;
971 cam = &gspca_dev->cam;
973 cam->cam_mode = vga_mode;
974 cam->nmodes = ARRAY_SIZE(vga_mode);
976 sd->bridge = id->driver_info >> 16;
977 sd->sensor = id->driver_info >> 8;
978 sd->i2c_base = id->driver_info;
980 sd->qindex = 4; /* set the quantization table */
981 sd->brightness = BRIGHTNESS_DEF;
982 sd->contrast = CONTRAST_DEF;
983 sd->colors = COLOR_DEF;
984 sd->autogain = AUTOGAIN_DEF;
986 sd->vflip = VFLIP_DEF;
987 sd->infrared = INFRARED_DEF;
989 switch (sd->sensor) {
993 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
996 if (sd->sensor != SENSOR_OV7630)
997 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
998 if (sd->sensor != SENSOR_MI0360)
999 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
1003 /* this function is called at probe and resume time */
1004 static int sd_init(struct gspca_dev *gspca_dev)
1006 struct sd *sd = (struct sd *) gspca_dev;
1007 /* const __u8 *sn9c1xx; */
1008 __u8 regGpio[] = { 0x29, 0x74 };
1011 /* setup a selector by bridge */
1012 reg_w1(gspca_dev, 0xf1, 0x01);
1013 reg_r(gspca_dev, 0x00, 1);
1014 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1015 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1016 regF1 = gspca_dev->usb_buf[0];
1017 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1018 switch (sd->bridge) {
1019 case BRIDGE_SN9C102P:
1022 reg_w1(gspca_dev, 0x02, regGpio[1]);
1024 case BRIDGE_SN9C105:
1027 reg_w(gspca_dev, 0x01, regGpio, 2);
1029 case BRIDGE_SN9C120:
1033 reg_w(gspca_dev, 0x01, regGpio, 2);
1036 /* case BRIDGE_SN9C110: */
1037 /* case BRIDGE_SN9C325: */
1040 reg_w1(gspca_dev, 0x02, 0x62);
1044 reg_w1(gspca_dev, 0xf1, 0x01);
1049 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1052 struct sd *sd = (struct sd *) gspca_dev;
1053 static const __u8 doit[] = /* update sensor */
1054 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1055 static const __u8 sensorgo[] = /* sensor on */
1056 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1057 static const __u8 gainMo[] =
1058 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1060 switch (sd->sensor) {
1061 case SENSOR_HV7131R: {
1063 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1065 Expodoit[3] = expo >> 16;
1066 Expodoit[4] = expo >> 8;
1068 i2c_w8(gspca_dev, Expodoit);
1071 case SENSOR_MI0360: {
1072 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1073 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1077 else if (expo < 0x0001)
1079 expoMi[3] = expo >> 8;
1081 i2c_w8(gspca_dev, expoMi);
1082 i2c_w8(gspca_dev, doit);
1083 i2c_w8(gspca_dev, sensorgo);
1086 case SENSOR_MO4000: {
1088 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1090 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1094 else if (expo < 0x0001)
1096 expoMof[3] = (expo & 0x03fc) >> 2;
1097 i2c_w8(gspca_dev, expoMof);
1098 expoMo10[3] = ((expo & 0x1c00) >> 10)
1099 | ((expo & 0x0003) << 4);
1100 i2c_w8(gspca_dev, expoMo10);
1101 i2c_w8(gspca_dev, gainMo);
1102 PDEBUG(D_CONF, "set exposure %d",
1103 ((expoMo10[3] & 0x07) << 10)
1105 | ((expoMo10[3] & 0x30) >> 4));
1108 case SENSOR_OM6802: {
1110 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1116 gainOm[3] = expo >> 2;
1117 i2c_w8(gspca_dev, gainOm);
1118 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1119 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1126 static void setbrightness(struct gspca_dev *gspca_dev)
1128 struct sd *sd = (struct sd *) gspca_dev;
1132 k2 = sd->brightness >> 10;
1133 switch (sd->sensor) {
1134 case SENSOR_HV7131R:
1135 expo = sd->brightness << 4;
1136 if (expo > 0x002dc6c0)
1138 else if (expo < 0x02a0)
1140 sd->exposure = setexposure(gspca_dev, expo);
1144 expo = sd->brightness >> 4;
1145 sd->exposure = setexposure(gspca_dev, expo);
1148 expo = sd->brightness >> 6;
1149 sd->exposure = setexposure(gspca_dev, expo);
1154 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1157 static void setcontrast(struct gspca_dev *gspca_dev)
1159 struct sd *sd = (struct sd *) gspca_dev;
1161 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1163 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1164 contrast[0] = (k2 + 1) / 2; /* red */
1165 contrast[2] = k2; /* green */
1166 contrast[4] = (k2 + 1) / 5; /* blue */
1167 reg_w(gspca_dev, 0x84, contrast, 6);
1170 static void setcolors(struct gspca_dev *gspca_dev)
1172 struct sd *sd = (struct sd *) gspca_dev;
1175 if (sd->colors >= 32) {
1176 red = 32 + (sd->colors - 32) / 2;
1177 blue = 64 - sd->colors;
1180 blue = 32 + (32 - sd->colors) / 2;
1182 reg_w1(gspca_dev, 0x05, red);
1183 /* reg_w1(gspca_dev, 0x07, 32); */
1184 reg_w1(gspca_dev, 0x06, blue);
1187 static void setautogain(struct gspca_dev *gspca_dev)
1189 struct sd *sd = (struct sd *) gspca_dev;
1191 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1194 sd->ag_cnt = AG_CNT_START;
1199 static void setvflip(struct sd *sd)
1201 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1202 sd->vflip ? 0x82 : 0x02);
1205 static void setinfrared(struct sd *sd)
1207 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1209 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1210 sd->infrared ? 0x66 : 0x64);
1213 /* -- start the camera -- */
1214 static int sd_start(struct gspca_dev *gspca_dev)
1216 struct sd *sd = (struct sd *) gspca_dev;
1218 __u8 reg1, reg17, reg18;
1219 const __u8 *sn9c1xx;
1221 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1222 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1223 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1224 static const __u8 CE_ov76xx[] =
1225 { 0x32, 0xdd, 0x32, 0xdd };
1227 sn9c1xx = sn_tb[(int) sd->sensor];
1228 configure_gpio(gspca_dev, sn9c1xx);
1230 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1231 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1232 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1233 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1234 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1235 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1236 reg_w1(gspca_dev, 0xd3, 0x50);
1237 reg_w1(gspca_dev, 0xc6, 0x00);
1238 reg_w1(gspca_dev, 0xc7, 0x00);
1239 reg_w1(gspca_dev, 0xc8, 0x50);
1240 reg_w1(gspca_dev, 0xc9, 0x3c);
1241 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1242 switch (sd->sensor) {
1249 /*jfm: from win trace */
1251 if (sd->bridge == BRIDGE_SN9C120) {
1260 reg_w1(gspca_dev, 0x17, reg17);
1261 /* set reg1 was here */
1262 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1263 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1264 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1265 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1266 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1267 for (i = 0; i < 8; i++)
1268 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1269 switch (sd->sensor) {
1271 reg_w1(gspca_dev, 0x9a, 0x0a);
1272 reg_w1(gspca_dev, 0x99, 0x60);
1275 if (sd->bridge == BRIDGE_SN9C120) {
1276 reg_w1(gspca_dev, 0x9a, 0x05);
1281 reg_w1(gspca_dev, 0x9a, 0x08);
1282 reg_w1(gspca_dev, 0x99, 0x59);
1286 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1288 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1290 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1291 reg17 = 0x61; /* 0x:20: enable sensor clock */
1292 switch (sd->sensor) {
1293 case SENSOR_HV7131R:
1294 hv7131R_InitSensor(gspca_dev);
1297 mi0360_InitSensor(gspca_dev);
1300 mo4000_InitSensor(gspca_dev);
1302 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1303 reg1 = 0x06; /* clk 24Mz */
1305 reg17 = 0x22; /* 640 MCKSIZE */
1306 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1310 om6802_InitSensor(gspca_dev);
1311 reg17 = 0x64; /* 640 MCKSIZE */
1314 ov7630_InitSensor(gspca_dev);
1320 ov7648_InitSensor(gspca_dev);
1322 /* reg1 = 0x42; * 42 - 46? */
1329 /* case SENSOR_OV7660: */
1330 ov7660_InitSensor(gspca_dev);
1332 /* reg17 = 0x21; * 320 */
1334 /* reg1 = 0x46; (done) */
1336 if (sd->bridge == BRIDGE_SN9C120) {
1338 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1341 reg1 = 0x06; /* 24 Mhz, video trf eneble
1342 * inverse power down */
1347 reg_w(gspca_dev, 0xc0, C0, 6);
1348 reg_w(gspca_dev, 0xca, CA, 4);
1349 switch (sd->sensor) {
1353 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1356 reg_w(gspca_dev, 0xce, CE, 4);
1357 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1361 /* here change size mode 0 -> VGA; 1 -> CIF */
1362 reg18 = sn9c1xx[0x18] | (mode << 4);
1363 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1365 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1366 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1368 reg_w1(gspca_dev, 0x18, reg18);
1370 reg_w1(gspca_dev, 0x17, reg17);
1371 reg_w1(gspca_dev, 0x01, reg1);
1372 switch (sd->sensor) {
1380 setbrightness(gspca_dev);
1381 setcontrast(gspca_dev);
1382 setautogain(gspca_dev);
1386 static void sd_stopN(struct gspca_dev *gspca_dev)
1388 struct sd *sd = (struct sd *) gspca_dev;
1389 static const __u8 stophv7131[] =
1390 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1391 static const __u8 stopmi0360[] =
1392 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1393 static const __u8 stopov7648[] =
1394 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1396 const __u8 *sn9c1xx;
1399 switch (sd->sensor) {
1400 case SENSOR_HV7131R:
1401 i2c_w8(gspca_dev, stophv7131);
1405 i2c_w8(gspca_dev, stopmi0360);
1409 i2c_w8(gspca_dev, stopov7648);
1415 /* case SENSOR_MO4000: */
1416 /* case SENSOR_OV7660: */
1419 sn9c1xx = sn_tb[(int) sd->sensor];
1420 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1421 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1422 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1423 reg_w1(gspca_dev, 0x01, data);
1424 reg_w1(gspca_dev, 0xf1, 0x00);
1427 static void do_autogain(struct gspca_dev *gspca_dev)
1429 struct sd *sd = (struct sd *) gspca_dev;
1432 __u8 luma_mean = 130;
1433 __u8 luma_delta = 20;
1435 /* Thanks S., without your advice, autobright should not work :) */
1438 if (--sd->ag_cnt >= 0)
1440 sd->ag_cnt = AG_CNT_START;
1442 delta = atomic_read(&sd->avg_lum);
1443 PDEBUG(D_FRAM, "mean lum %d", delta);
1444 if (delta < luma_mean - luma_delta ||
1445 delta > luma_mean + luma_delta) {
1446 switch (sd->sensor) {
1447 case SENSOR_HV7131R:
1448 expotimes = sd->exposure >> 8;
1449 expotimes += (luma_mean - delta) >> 4;
1452 sd->exposure = setexposure(gspca_dev,
1453 (unsigned int) (expotimes << 8));
1456 /* case SENSOR_MO4000: */
1457 /* case SENSOR_MI0360: */
1458 /* case SENSOR_OM6802: */
1459 expotimes = sd->exposure;
1460 expotimes += (luma_mean - delta) >> 6;
1463 sd->exposure = setexposure(gspca_dev,
1464 (unsigned int) expotimes);
1465 setcolors(gspca_dev);
1471 /* scan the URB packets */
1472 /* This function is run at interrupt level. */
1473 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1474 struct gspca_frame *frame, /* target */
1475 __u8 *data, /* isoc packet */
1476 int len) /* iso packet length */
1478 struct sd *sd = (struct sd *) gspca_dev;
1482 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1485 gspca_frame_add(gspca_dev, LAST_PACKET,
1486 frame, data, sof + 2);
1493 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1495 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1497 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1499 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1501 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1503 atomic_set(&sd->avg_lum, avg_lum);
1506 if (gspca_dev->last_packet_type == LAST_PACKET) {
1508 /* put the JPEG 422 header */
1509 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1511 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1514 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1516 struct sd *sd = (struct sd *) gspca_dev;
1518 sd->brightness = val;
1519 if (gspca_dev->streaming)
1520 setbrightness(gspca_dev);
1524 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1526 struct sd *sd = (struct sd *) gspca_dev;
1528 *val = sd->brightness;
1532 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1534 struct sd *sd = (struct sd *) gspca_dev;
1537 if (gspca_dev->streaming)
1538 setcontrast(gspca_dev);
1542 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1544 struct sd *sd = (struct sd *) gspca_dev;
1546 *val = sd->contrast;
1550 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1552 struct sd *sd = (struct sd *) gspca_dev;
1555 if (gspca_dev->streaming)
1556 setcolors(gspca_dev);
1560 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1562 struct sd *sd = (struct sd *) gspca_dev;
1568 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1570 struct sd *sd = (struct sd *) gspca_dev;
1573 if (gspca_dev->streaming)
1574 setautogain(gspca_dev);
1578 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1580 struct sd *sd = (struct sd *) gspca_dev;
1582 *val = sd->autogain;
1586 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1588 struct sd *sd = (struct sd *) gspca_dev;
1591 if (gspca_dev->streaming)
1596 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1598 struct sd *sd = (struct sd *) gspca_dev;
1604 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1606 struct sd *sd = (struct sd *) gspca_dev;
1609 if (gspca_dev->streaming)
1614 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1616 struct sd *sd = (struct sd *) gspca_dev;
1618 *val = sd->infrared;
1622 /* sub-driver description */
1623 static const struct sd_desc sd_desc = {
1624 .name = MODULE_NAME,
1626 .nctrls = ARRAY_SIZE(sd_ctrls),
1627 .config = sd_config,
1631 .pkt_scan = sd_pkt_scan,
1632 .dq_callback = do_autogain,
1635 /* -- module initialisation -- */
1636 #define BSI(bridge, sensor, i2c_addr) \
1637 .driver_info = (BRIDGE_ ## bridge << 16) \
1638 | (SENSOR_ ## sensor << 8) \
1640 static const __devinitdata struct usb_device_id device_table[] = {
1641 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1642 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1643 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1645 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1646 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1647 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1648 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1650 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1651 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1652 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1654 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1655 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1656 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1657 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1658 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1659 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1660 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1661 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1662 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1663 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1664 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1665 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1666 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1667 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1668 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1670 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1671 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1672 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1673 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1675 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1676 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1677 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1678 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1679 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1680 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1682 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1683 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1684 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1685 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1686 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1687 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1689 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1692 MODULE_DEVICE_TABLE(usb, device_table);
1694 /* -- device connect -- */
1695 static int sd_probe(struct usb_interface *intf,
1696 const struct usb_device_id *id)
1698 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1702 static struct usb_driver sd_driver = {
1703 .name = MODULE_NAME,
1704 .id_table = device_table,
1706 .disconnect = gspca_disconnect,
1708 .suspend = gspca_suspend,
1709 .resume = gspca_resume,
1713 /* -- module insert / remove -- */
1714 static int __init sd_mod_init(void)
1716 if (usb_register(&sd_driver) < 0)
1721 static void __exit sd_mod_exit(void)
1723 usb_deregister(&sd_driver);
1724 info("deregistered");
1727 module_init(sd_mod_init);
1728 module_exit(sd_mod_exit);