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, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
256 /* reg8 reg9 rega regb regc regd rege regf */
257 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
258 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
259 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
260 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
261 0x07, 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}, */
493 static const __u8 ov7660_sensor_init[][8] = {
494 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
496 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
497 /* Outformat = rawRGB */
498 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
499 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
500 /* GAIN BLUE RED VREF */
501 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
502 /* COM 1 BAVE GEAVE AECHH */
503 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
504 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
505 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
506 /* AECH CLKRC COM7 COM8 */
507 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
508 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
509 /* HSTART HSTOP VSTRT VSTOP */
510 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
511 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
512 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
513 /* BOS GBOS GROS ROS (BGGR offset) */
514 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
515 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
516 /* AEW AEB VPT BBIAS */
517 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
518 /* GbBIAS RSVD EXHCH EXHCL */
519 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
520 /* RBIAS ADVFL ASDVFH YAVE */
521 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
522 /* HSYST HSYEN HREF */
523 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
524 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
525 /* ADC ACOM OFON TSLB */
526 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
527 /* COM11 COM12 COM13 COM14 */
528 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
529 /* EDGE COM15 COM16 COM17 */
530 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
531 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
532 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
533 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
534 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
535 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
536 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
537 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
538 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
539 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
540 /* LCC1 LCC2 LCC3 LCC4 */
541 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
542 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
543 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
544 /* band gap reference [0:3] DBLV */
545 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
546 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
547 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
548 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
549 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
550 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
551 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
552 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
553 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
554 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
555 /****** (some exchanges in the win trace) ******/
556 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
557 /* bits[3..0]reserved */
558 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
559 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
560 /* VREF vertical frame ctrl */
561 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
562 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
563 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
564 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
565 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
566 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
567 /****** (some exchanges in the win trace) ******/
568 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
569 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
570 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
571 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
572 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
573 /****** (some exchanges in the win trace) ******/
574 /******!! startsensor KO if changed !!****/
575 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
576 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
578 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
581 /* reg 0x04 reg 0x07 reg 0x10 */
582 /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
584 static const __u8 ov7648_sensor_init[][8] = {
585 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
586 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
587 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
588 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
589 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
590 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
591 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
592 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
593 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
594 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
595 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
596 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
597 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
598 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
599 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
600 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
601 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
602 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
603 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
604 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
605 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
606 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
607 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
608 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
609 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
610 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
611 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
612 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
613 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
614 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
615 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
616 * This is currently setting a
617 * blue tint, and some things more , i leave it here for future test if
618 * somene is having problems with color on this sensor
619 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
620 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
621 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
622 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
623 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
624 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
625 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
626 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
627 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
628 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
629 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
630 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
631 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
632 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
633 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
634 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
635 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
636 /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
640 static const __u8 qtable4[] = {
641 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
642 0x06, 0x08, 0x0A, 0x11,
643 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
644 0x19, 0x19, 0x17, 0x15,
645 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
646 0x21, 0x2E, 0x21, 0x23,
647 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
648 0x25, 0x29, 0x2C, 0x29,
649 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
650 0x17, 0x1B, 0x29, 0x29,
651 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
652 0x29, 0x29, 0x29, 0x29,
653 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
654 0x29, 0x29, 0x29, 0x29,
655 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
656 0x29, 0x29, 0x29, 0x29
659 /* read <len> bytes to gspca_dev->usb_buf */
660 static void reg_r(struct gspca_dev *gspca_dev,
661 __u16 value, int len)
664 if (len > USB_BUF_SZ) {
665 err("reg_r: buffer overflow");
669 usb_control_msg(gspca_dev->dev,
670 usb_rcvctrlpipe(gspca_dev->dev, 0),
672 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
674 gspca_dev->usb_buf, len,
676 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
679 static void reg_w1(struct gspca_dev *gspca_dev,
683 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
684 gspca_dev->usb_buf[0] = data;
685 usb_control_msg(gspca_dev->dev,
686 usb_sndctrlpipe(gspca_dev->dev, 0),
688 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
691 gspca_dev->usb_buf, 1,
694 static void reg_w(struct gspca_dev *gspca_dev,
699 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
700 value, buffer[0], buffer[1]);
702 if (len > USB_BUF_SZ) {
703 err("reg_w: buffer overflow");
707 memcpy(gspca_dev->usb_buf, buffer, len);
708 usb_control_msg(gspca_dev->dev,
709 usb_sndctrlpipe(gspca_dev->dev, 0),
711 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
713 gspca_dev->usb_buf, len,
717 /* I2C write 1 byte */
718 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
720 struct sd *sd = (struct sd *) gspca_dev;
722 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
723 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
724 gspca_dev->usb_buf[1] = sd->i2c_base;
725 gspca_dev->usb_buf[2] = reg;
726 gspca_dev->usb_buf[3] = val;
727 gspca_dev->usb_buf[4] = 0;
728 gspca_dev->usb_buf[5] = 0;
729 gspca_dev->usb_buf[6] = 0;
730 gspca_dev->usb_buf[7] = 0x10;
731 usb_control_msg(gspca_dev->dev,
732 usb_sndctrlpipe(gspca_dev->dev, 0),
734 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
735 0x08, /* value = i2c */
737 gspca_dev->usb_buf, 8,
741 /* I2C write 8 bytes */
742 static void i2c_w8(struct gspca_dev *gspca_dev,
745 memcpy(gspca_dev->usb_buf, buffer, 8);
746 usb_control_msg(gspca_dev->dev,
747 usb_sndctrlpipe(gspca_dev->dev, 0),
749 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
750 0x08, 0, /* value, index */
751 gspca_dev->usb_buf, 8,
756 /* read 5 bytes in gspca_dev->usb_buf */
757 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
759 struct sd *sd = (struct sd *) gspca_dev;
762 mode[0] = 0x81 | 0x10;
763 mode[1] = sd->i2c_base;
770 i2c_w8(gspca_dev, mode);
772 mode[0] = 0x81 | (5 << 4) | 0x02;
774 i2c_w8(gspca_dev, mode);
776 reg_r(gspca_dev, 0x0a, 5);
779 static int probesensor(struct gspca_dev *gspca_dev)
781 struct sd *sd = (struct sd *) gspca_dev;
783 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
785 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
787 i2c_r5(gspca_dev, 0); /* read sensor id */
788 if (gspca_dev->usb_buf[0] == 0x02
789 && gspca_dev->usb_buf[1] == 0x09
790 && gspca_dev->usb_buf[2] == 0x01
791 && gspca_dev->usb_buf[3] == 0x00
792 && gspca_dev->usb_buf[4] == 0x00) {
793 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
794 sd->sensor = SENSOR_HV7131R;
795 return SENSOR_HV7131R;
797 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
798 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
799 gspca_dev->usb_buf[2]);
800 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
804 static int configure_gpio(struct gspca_dev *gspca_dev,
807 struct sd *sd = (struct sd *) gspca_dev;
809 static const __u8 reg9a_def[] =
810 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
811 static const __u8 reg9a_sn9c325[] =
812 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
813 static const __u8 regd4[] = {0x60, 0x00, 0x00};
815 reg_w1(gspca_dev, 0xf1, 0x00);
816 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
819 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
820 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
821 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
822 switch (sd->bridge) {
824 reg9a = reg9a_sn9c325;
830 reg_w(gspca_dev, 0x9a, reg9a, 6);
832 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
834 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
836 switch (sd->sensor) {
838 reg_w1(gspca_dev, 0x02, 0x71);
839 reg_w1(gspca_dev, 0x01, 0x42);
840 reg_w1(gspca_dev, 0x17, 0x64);
841 reg_w1(gspca_dev, 0x01, 0x42);
843 /*jfm: from win trace */
845 reg_w1(gspca_dev, 0x01, 0x61);
846 reg_w1(gspca_dev, 0x17, 0xe2);
847 reg_w1(gspca_dev, 0x01, 0x60);
848 reg_w1(gspca_dev, 0x01, 0x40);
851 reg_w1(gspca_dev, 0x01, 0x43);
852 reg_w1(gspca_dev, 0x17, 0xae);
853 reg_w1(gspca_dev, 0x01, 0x42);
855 /*jfm: from win trace */
857 reg_w1(gspca_dev, 0x01, 0x61);
858 reg_w1(gspca_dev, 0x17, 0x20);
859 reg_w1(gspca_dev, 0x01, 0x60);
860 reg_w1(gspca_dev, 0x01, 0x40);
863 reg_w1(gspca_dev, 0x01, 0x43);
864 reg_w1(gspca_dev, 0x17, 0x61);
865 reg_w1(gspca_dev, 0x01, 0x42);
866 if (sd->sensor == SENSOR_HV7131R) {
867 if (probesensor(gspca_dev) < 0)
875 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
878 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
879 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
881 while (hv7131r_sensor_init[i][0]) {
882 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
885 i2c_w8(gspca_dev, SetSensorClk);
888 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
892 while (mi0360_sensor_init[i][0]) {
893 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
898 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
902 while (mo4000_sensor_init[i][0]) {
903 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
908 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
912 while (om6802_sensor_init[i][0]) {
913 i2c_w8(gspca_dev, om6802_sensor_init[i]);
918 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
922 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
924 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
927 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
929 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
932 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
934 /*jfm:win i2c_r from 00 to 80*/
936 while (ov7630_sensor_init[i][0]) {
937 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
942 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
946 while (ov7648_sensor_init[i][0]) {
947 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
952 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
956 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
959 while (ov7660_sensor_init[i][0]) {
960 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
965 /* this function is called at probe time */
966 static int sd_config(struct gspca_dev *gspca_dev,
967 const struct usb_device_id *id)
969 struct sd *sd = (struct sd *) gspca_dev;
972 cam = &gspca_dev->cam;
974 cam->cam_mode = vga_mode;
975 cam->nmodes = ARRAY_SIZE(vga_mode);
977 sd->bridge = id->driver_info >> 16;
978 sd->sensor = id->driver_info >> 8;
979 sd->i2c_base = id->driver_info;
981 sd->qindex = 4; /* set the quantization table */
982 sd->brightness = BRIGHTNESS_DEF;
983 sd->contrast = CONTRAST_DEF;
984 sd->colors = COLOR_DEF;
985 sd->autogain = AUTOGAIN_DEF;
987 sd->vflip = VFLIP_DEF;
988 sd->infrared = INFRARED_DEF;
990 switch (sd->sensor) {
994 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
997 if (sd->sensor != SENSOR_OV7630)
998 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
999 if (sd->sensor != SENSOR_MI0360)
1000 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
1004 /* this function is called at probe and resume time */
1005 static int sd_init(struct gspca_dev *gspca_dev)
1007 struct sd *sd = (struct sd *) gspca_dev;
1008 /* const __u8 *sn9c1xx; */
1009 __u8 regGpio[] = { 0x29, 0x74 };
1012 /* setup a selector by bridge */
1013 reg_w1(gspca_dev, 0xf1, 0x01);
1014 reg_r(gspca_dev, 0x00, 1);
1015 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1016 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1017 regF1 = gspca_dev->usb_buf[0];
1018 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1019 switch (sd->bridge) {
1020 case BRIDGE_SN9C102P:
1023 reg_w1(gspca_dev, 0x02, regGpio[1]);
1025 case BRIDGE_SN9C105:
1028 reg_w(gspca_dev, 0x01, regGpio, 2);
1030 case BRIDGE_SN9C120:
1034 reg_w(gspca_dev, 0x01, regGpio, 2);
1037 /* case BRIDGE_SN9C110: */
1038 /* case BRIDGE_SN9C325: */
1041 reg_w1(gspca_dev, 0x02, 0x62);
1045 reg_w1(gspca_dev, 0xf1, 0x01);
1050 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1053 struct sd *sd = (struct sd *) gspca_dev;
1054 static const __u8 doit[] = /* update sensor */
1055 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1056 static const __u8 sensorgo[] = /* sensor on */
1057 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1058 static const __u8 gainMo[] =
1059 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1061 switch (sd->sensor) {
1062 case SENSOR_HV7131R: {
1064 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1066 Expodoit[3] = expo >> 16;
1067 Expodoit[4] = expo >> 8;
1069 i2c_w8(gspca_dev, Expodoit);
1072 case SENSOR_MI0360: {
1073 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1074 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1078 else if (expo < 0x0001)
1080 expoMi[3] = expo >> 8;
1082 i2c_w8(gspca_dev, expoMi);
1083 i2c_w8(gspca_dev, doit);
1084 i2c_w8(gspca_dev, sensorgo);
1087 case SENSOR_MO4000: {
1089 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1091 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1095 else if (expo < 0x0001)
1097 expoMof[3] = (expo & 0x03fc) >> 2;
1098 i2c_w8(gspca_dev, expoMof);
1099 expoMo10[3] = ((expo & 0x1c00) >> 10)
1100 | ((expo & 0x0003) << 4);
1101 i2c_w8(gspca_dev, expoMo10);
1102 i2c_w8(gspca_dev, gainMo);
1103 PDEBUG(D_CONF, "set exposure %d",
1104 ((expoMo10[3] & 0x07) << 10)
1106 | ((expoMo10[3] & 0x30) >> 4));
1109 case SENSOR_OM6802: {
1111 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1117 gainOm[3] = expo >> 2;
1118 i2c_w8(gspca_dev, gainOm);
1119 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1120 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1127 /* this function is used for sensors o76xx only */
1128 static void setbrightcont(struct gspca_dev *gspca_dev)
1130 struct sd *sd = (struct sd *) gspca_dev;
1132 __u8 reg84_full[0x15];
1134 memcpy(reg84_full, reg84, sizeof reg84_full);
1135 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1136 reg84_full[0] = (val + 1) / 2; /* red */
1137 reg84_full[2] = val; /* green */
1138 reg84_full[4] = (val + 1) / 5; /* blue */
1139 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1141 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
1142 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1145 /* sensor != ov76xx */
1146 static void setbrightness(struct gspca_dev *gspca_dev)
1148 struct sd *sd = (struct sd *) gspca_dev;
1152 k2 = sd->brightness >> 10;
1153 switch (sd->sensor) {
1154 case SENSOR_HV7131R:
1155 expo = sd->brightness << 4;
1156 if (expo > 0x002dc6c0)
1158 else if (expo < 0x02a0)
1160 sd->exposure = setexposure(gspca_dev, expo);
1164 expo = sd->brightness >> 4;
1165 sd->exposure = setexposure(gspca_dev, expo);
1168 expo = sd->brightness >> 6;
1169 sd->exposure = setexposure(gspca_dev, expo);
1170 k2 = sd->brightness >> 11;
1174 reg_w1(gspca_dev, 0x96, k2);
1177 /* sensor != ov76xx */
1178 static void setcontrast(struct gspca_dev *gspca_dev)
1180 struct sd *sd = (struct sd *) gspca_dev;
1182 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1186 contrast[0] = (k2 + 1) >> 1;
1187 contrast[4] = (k2 + 1) / 5;
1188 reg_w(gspca_dev, 0x84, contrast, 6);
1191 static void setcolors(struct gspca_dev *gspca_dev)
1193 struct sd *sd = (struct sd *) gspca_dev;
1196 if (sd->colors >= 32) {
1197 red = 32 + (sd->colors - 32) / 2;
1198 blue = 64 - sd->colors;
1201 blue = 32 + (32 - sd->colors) / 2;
1203 reg_w1(gspca_dev, 0x05, red);
1204 /* reg_w1(gspca_dev, 0x07, 32); */
1205 reg_w1(gspca_dev, 0x06, blue);
1208 static void setautogain(struct gspca_dev *gspca_dev)
1210 struct sd *sd = (struct sd *) gspca_dev;
1212 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1215 sd->ag_cnt = AG_CNT_START;
1220 static void setvflip(struct sd *sd)
1222 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1223 sd->vflip ? 0x82 : 0x02);
1226 static void setinfrared(struct sd *sd)
1228 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1230 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1231 sd->infrared ? 0x66 : 0x64);
1234 /* -- start the camera -- */
1235 static int sd_start(struct gspca_dev *gspca_dev)
1237 struct sd *sd = (struct sd *) gspca_dev;
1239 __u8 reg1, reg17, reg18;
1240 const __u8 *sn9c1xx;
1242 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1243 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1244 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1245 static const __u8 CE_ov76xx[] =
1246 { 0x32, 0xdd, 0x32, 0xdd };
1248 sn9c1xx = sn_tb[(int) sd->sensor];
1249 configure_gpio(gspca_dev, sn9c1xx);
1251 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1252 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1253 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1254 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1255 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1256 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1257 reg_w1(gspca_dev, 0xd3, 0x50);
1258 reg_w1(gspca_dev, 0xc6, 0x00);
1259 reg_w1(gspca_dev, 0xc7, 0x00);
1260 reg_w1(gspca_dev, 0xc8, 0x50);
1261 reg_w1(gspca_dev, 0xc9, 0x3c);
1262 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1263 switch (sd->sensor) {
1270 /*jfm: from win trace */
1278 reg_w1(gspca_dev, 0x17, reg17);
1279 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1280 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1281 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1282 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1283 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1284 for (i = 0; i < 8; i++)
1285 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1286 switch (sd->sensor) {
1288 reg_w1(gspca_dev, 0x9a, 0x05);
1291 reg_w1(gspca_dev, 0x9a, 0x08);
1292 reg_w1(gspca_dev, 0x99, 0x59);
1296 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1298 reg1 = 0x46; /* 320 clk 48Mhz */
1300 reg1 = 0x06; /* 640 clk 24Mz */
1302 switch (sd->sensor) {
1303 case SENSOR_HV7131R:
1304 hv7131R_InitSensor(gspca_dev);
1307 mi0360_InitSensor(gspca_dev);
1310 mo4000_InitSensor(gspca_dev);
1312 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1313 reg1 = 0x06; /* clk 24Mz */
1315 reg17 = 0x22; /* 640 MCKSIZE */
1316 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1320 om6802_InitSensor(gspca_dev);
1321 reg17 = 0x64; /* 640 MCKSIZE */
1324 ov7630_InitSensor(gspca_dev);
1330 ov7648_InitSensor(gspca_dev);
1339 /* case SENSOR_OV7660: */
1340 ov7660_InitSensor(gspca_dev);
1342 /* reg17 = 0x21; * 320 */
1344 /* reg1 = 0x46; (done) */
1346 reg17 = 0xa2; /* 640 */
1351 reg_w(gspca_dev, 0xc0, C0, 6);
1352 reg_w(gspca_dev, 0xca, CA, 4);
1353 switch (sd->sensor) {
1357 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1360 reg_w(gspca_dev, 0xce, CE, 4);
1361 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1365 /* here change size mode 0 -> VGA; 1 -> CIF */
1366 reg18 = sn9c1xx[0x18] | (mode << 4);
1367 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1369 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1370 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1372 reg_w1(gspca_dev, 0x18, reg18);
1374 reg_w1(gspca_dev, 0x17, reg17);
1375 switch (sd->sensor) {
1379 case SENSOR_HV7131R:
1382 setbrightness(gspca_dev);
1383 setcontrast(gspca_dev);
1388 default: /* OV76xx */
1389 setbrightcont(gspca_dev);
1392 setautogain(gspca_dev);
1393 reg_w1(gspca_dev, 0x01, reg1);
1397 static void sd_stopN(struct gspca_dev *gspca_dev)
1399 struct sd *sd = (struct sd *) gspca_dev;
1400 static const __u8 stophv7131[] =
1401 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1402 static const __u8 stopmi0360[] =
1403 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1405 const __u8 *sn9c1xx;
1408 switch (sd->sensor) {
1409 case SENSOR_HV7131R:
1410 i2c_w8(gspca_dev, stophv7131);
1414 i2c_w8(gspca_dev, stopmi0360);
1422 /* case SENSOR_MO4000: */
1423 /* case SENSOR_OV7660: */
1426 sn9c1xx = sn_tb[(int) sd->sensor];
1427 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1428 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1429 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1430 reg_w1(gspca_dev, 0x01, data);
1431 reg_w1(gspca_dev, 0xf1, 0x00);
1434 static void do_autogain(struct gspca_dev *gspca_dev)
1436 struct sd *sd = (struct sd *) gspca_dev;
1439 __u8 luma_mean = 130;
1440 __u8 luma_delta = 20;
1442 /* Thanks S., without your advice, autobright should not work :) */
1445 if (--sd->ag_cnt >= 0)
1447 sd->ag_cnt = AG_CNT_START;
1449 delta = atomic_read(&sd->avg_lum);
1450 PDEBUG(D_FRAM, "mean lum %d", delta);
1451 if (delta < luma_mean - luma_delta ||
1452 delta > luma_mean + luma_delta) {
1453 switch (sd->sensor) {
1454 case SENSOR_HV7131R:
1455 expotimes = sd->exposure >> 8;
1456 expotimes += (luma_mean - delta) >> 4;
1459 sd->exposure = setexposure(gspca_dev,
1460 (unsigned int) (expotimes << 8));
1463 /* case SENSOR_MO4000: */
1464 /* case SENSOR_MI0360: */
1465 /* case SENSOR_OM6802: */
1466 expotimes = sd->exposure;
1467 expotimes += (luma_mean - delta) >> 6;
1470 sd->exposure = setexposure(gspca_dev,
1471 (unsigned int) expotimes);
1472 setcolors(gspca_dev);
1478 /* scan the URB packets */
1479 /* This function is run at interrupt level. */
1480 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1481 struct gspca_frame *frame, /* target */
1482 __u8 *data, /* isoc packet */
1483 int len) /* iso packet length */
1485 struct sd *sd = (struct sd *) gspca_dev;
1489 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1492 gspca_frame_add(gspca_dev, LAST_PACKET,
1493 frame, data, sof + 2);
1500 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1502 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1504 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1506 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1508 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1510 atomic_set(&sd->avg_lum, avg_lum);
1513 if (gspca_dev->last_packet_type == LAST_PACKET) {
1515 /* put the JPEG 422 header */
1516 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1518 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1521 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1523 struct sd *sd = (struct sd *) gspca_dev;
1525 sd->brightness = val;
1526 if (gspca_dev->streaming) {
1527 switch (sd->sensor) {
1528 case SENSOR_HV7131R:
1532 setbrightness(gspca_dev);
1534 default: /* OV76xx */
1535 setbrightcont(gspca_dev);
1542 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1544 struct sd *sd = (struct sd *) gspca_dev;
1546 *val = sd->brightness;
1550 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1552 struct sd *sd = (struct sd *) gspca_dev;
1555 if (gspca_dev->streaming) {
1556 switch (sd->sensor) {
1557 case SENSOR_HV7131R:
1561 setcontrast(gspca_dev);
1563 default: /* OV76xx */
1564 setbrightcont(gspca_dev);
1571 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1573 struct sd *sd = (struct sd *) gspca_dev;
1575 *val = sd->contrast;
1579 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1581 struct sd *sd = (struct sd *) gspca_dev;
1584 if (gspca_dev->streaming)
1585 setcolors(gspca_dev);
1589 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1591 struct sd *sd = (struct sd *) gspca_dev;
1597 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1599 struct sd *sd = (struct sd *) gspca_dev;
1602 if (gspca_dev->streaming)
1603 setautogain(gspca_dev);
1607 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1609 struct sd *sd = (struct sd *) gspca_dev;
1611 *val = sd->autogain;
1615 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1617 struct sd *sd = (struct sd *) gspca_dev;
1620 if (gspca_dev->streaming)
1625 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1627 struct sd *sd = (struct sd *) gspca_dev;
1633 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1635 struct sd *sd = (struct sd *) gspca_dev;
1638 if (gspca_dev->streaming)
1643 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1645 struct sd *sd = (struct sd *) gspca_dev;
1647 *val = sd->infrared;
1651 /* sub-driver description */
1652 static const struct sd_desc sd_desc = {
1653 .name = MODULE_NAME,
1655 .nctrls = ARRAY_SIZE(sd_ctrls),
1656 .config = sd_config,
1660 .pkt_scan = sd_pkt_scan,
1661 .dq_callback = do_autogain,
1664 /* -- module initialisation -- */
1665 #define BSI(bridge, sensor, i2c_addr) \
1666 .driver_info = (BRIDGE_ ## bridge << 16) \
1667 | (SENSOR_ ## sensor << 8) \
1669 static const __devinitdata struct usb_device_id device_table[] = {
1670 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1671 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1672 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1673 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1674 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1675 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1677 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1678 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1679 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1681 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1682 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1683 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1684 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1685 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1686 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1687 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1688 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1689 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1690 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1691 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1692 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1693 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1694 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1695 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1697 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1698 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1699 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1700 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1702 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1703 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1704 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1705 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1706 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1707 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1709 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1710 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1711 /* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1712 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1713 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1714 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1716 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1719 MODULE_DEVICE_TABLE(usb, device_table);
1721 /* -- device connect -- */
1722 static int sd_probe(struct usb_interface *intf,
1723 const struct usb_device_id *id)
1725 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1729 static struct usb_driver sd_driver = {
1730 .name = MODULE_NAME,
1731 .id_table = device_table,
1733 .disconnect = gspca_disconnect,
1735 .suspend = gspca_suspend,
1736 .resume = gspca_resume,
1740 /* -- module insert / remove -- */
1741 static int __init sd_mod_init(void)
1743 if (usb_register(&sd_driver) < 0)
1748 static void __exit sd_mod_exit(void)
1750 usb_deregister(&sd_driver);
1751 info("deregistered");
1754 module_init(sd_mod_init);
1755 module_exit(sd_mod_exit);