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 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
33 struct gspca_dev gspca_dev; /* !! must be the first item */
36 unsigned int exposure;
38 unsigned short brightness;
39 unsigned char contrast;
41 unsigned char autogain;
42 __u8 vflip; /* ov7630 only */
45 #define AG_CNT_START 13
49 #define BRIDGE_SN9C102P 0
50 #define BRIDGE_SN9C105 1
51 #define BRIDGE_SN9C110 2
52 #define BRIDGE_SN9C120 3
53 #define BRIDGE_SN9C325 4
54 char sensor; /* Type of image sensor chip */
55 #define SENSOR_HV7131R 0
56 #define SENSOR_MI0360 1
57 #define SENSOR_MO4000 2
58 #define SENSOR_OM6802 3
59 #define SENSOR_OV7630 4
60 #define SENSOR_OV7648 5
61 #define SENSOR_OV7660 6
62 unsigned char i2c_base;
65 /* V4L2 controls supported by the driver */
66 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
72 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
73 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
75 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
77 static struct ctrl sd_ctrls[] = {
80 .id = V4L2_CID_BRIGHTNESS,
81 .type = V4L2_CTRL_TYPE_INTEGER,
84 #define BRIGHTNESS_MAX 0xffff
85 .maximum = BRIGHTNESS_MAX,
87 #define BRIGHTNESS_DEF 0x7fff
88 .default_value = BRIGHTNESS_DEF,
90 .set = sd_setbrightness,
91 .get = sd_getbrightness,
95 .id = V4L2_CID_CONTRAST,
96 .type = V4L2_CTRL_TYPE_INTEGER,
99 #define CONTRAST_MAX 127
100 .maximum = CONTRAST_MAX,
102 #define CONTRAST_DEF 63
103 .default_value = CONTRAST_DEF,
105 .set = sd_setcontrast,
106 .get = sd_getcontrast,
110 .id = V4L2_CID_SATURATION,
111 .type = V4L2_CTRL_TYPE_INTEGER,
117 .default_value = COLOR_DEF,
122 #define AUTOGAIN_IDX 3
125 .id = V4L2_CID_AUTOGAIN,
126 .type = V4L2_CTRL_TYPE_BOOLEAN,
131 #define AUTOGAIN_DEF 1
132 .default_value = AUTOGAIN_DEF,
134 .set = sd_setautogain,
135 .get = sd_getautogain,
141 .id = V4L2_CID_VFLIP,
142 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .default_value = VFLIP_DEF,
155 static struct v4l2_pix_format vga_mode[] = {
156 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
158 .sizeimage = 160 * 120 * 4 / 8 + 590,
159 .colorspace = V4L2_COLORSPACE_JPEG,
161 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
163 .sizeimage = 320 * 240 * 3 / 8 + 590,
164 .colorspace = V4L2_COLORSPACE_JPEG,
166 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
168 .sizeimage = 640 * 480 * 3 / 8 + 590,
169 .colorspace = V4L2_COLORSPACE_JPEG,
173 /*Data from sn9c102p+hv71331r */
174 static const __u8 sn_hv7131[] = {
175 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
176 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
177 /* reg8 reg9 rega regb regc regd rege regf */
178 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
179 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
180 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
181 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
182 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
185 static const __u8 sn_mi0360[] = {
186 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
187 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
188 /* reg8 reg9 rega regb regc regd rege regf */
189 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
190 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
191 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
192 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
193 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
196 static const __u8 sn_mo4000[] = {
197 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
198 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
199 /* reg8 reg9 rega regb regc regd rege regf */
200 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
202 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
203 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
204 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
207 static const __u8 sn_om6802[] = {
208 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
209 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
210 /* reg8 reg9 rega regb regc regd rege regf */
211 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
213 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
214 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
215 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
217 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
221 static const __u8 sn_ov7630[] = {
222 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
223 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
224 /* reg8 reg9 rega regb regc regd rege regf */
225 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
226 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
227 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
228 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
229 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
232 static const __u8 sn_ov7648[] = {
233 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
234 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
235 /* reg8 reg9 rega regb regc regd rege regf */
236 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
237 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
238 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
239 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
240 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
243 static const __u8 sn_ov7660[] = {
244 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
245 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
246 /* reg8 reg9 rega regb regc regd rege regf */
247 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
248 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
249 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
250 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
251 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 /* sequence specific to the sensors - !! index = SENSOR_xxx */
255 static const __u8 *sn_tb[] = {
265 static const __u8 gamma_def[] = {
266 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
267 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
270 /* color matrix and offsets */
271 static const __u8 reg84[] = {
272 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
273 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
274 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
275 0x00, 0x00, 0x00 /* YUV offsets */
277 static const __u8 hv7131r_sensor_init[][8] = {
278 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
279 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
280 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
281 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
282 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
283 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
284 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
286 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
287 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
288 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
289 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
290 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
291 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
292 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
293 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
295 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
296 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
297 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
298 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
299 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
301 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
302 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
304 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
305 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
308 static const __u8 mi0360_sensor_init[][8] = {
309 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
310 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
311 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
312 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
313 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
314 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
315 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
316 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
317 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
318 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
319 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
321 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
322 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
323 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
325 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
326 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
327 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
328 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
329 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
330 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
331 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
332 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
334 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
335 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
336 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
337 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
338 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
339 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
340 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
341 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
343 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
344 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
345 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
346 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
347 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
349 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
350 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
351 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
352 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
354 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
355 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
356 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
357 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
358 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
359 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
362 static const __u8 mo4000_sensor_init[][8] = {
363 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
364 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
365 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
366 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
367 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
368 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
369 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
370 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
371 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
373 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
374 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
375 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
376 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
377 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
379 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
380 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
381 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
382 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
385 static __u8 om6802_sensor_init[][8] = {
386 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
387 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
388 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
389 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
390 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
391 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
392 /* white balance & auto-exposure */
393 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
395 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
396 * max AGC value in AE */
397 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
399 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
400 * preset brightness */
401 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
403 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
405 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
406 /* luminance mode (0x4f = AE) */
407 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
409 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
411 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
413 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
414 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
415 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
416 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
419 static const __u8 ov7630_sensor_init[][8] = {
420 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
421 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
422 /* win: delay 20ms */
423 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
425 /* win: delay 20ms */
426 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
427 /* win: i2c_r from 00 to 80 */
428 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
429 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
430 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
431 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
432 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
433 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
434 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
435 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
436 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
437 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
438 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
439 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
443 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
444 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
445 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
447 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
449 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
450 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
451 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
452 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
453 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
455 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
456 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
457 /*fixme: + 0x12, 0x04*/
458 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
460 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
461 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
462 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
464 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
465 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
466 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
468 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
469 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
472 static const __u8 ov7660_sensor_init[][8] = {
473 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
475 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
476 /* Outformat = rawRGB */
477 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
478 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
479 /* GAIN BLUE RED VREF */
480 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
481 /* COM 1 BAVE GEAVE AECHH */
482 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
483 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
484 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
485 /* AECH CLKRC COM7 COM8 */
486 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
487 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
488 /* HSTART HSTOP VSTRT VSTOP */
489 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
490 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
491 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
492 /* BOS GBOS GROS ROS (BGGR offset) */
493 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
494 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
495 /* AEW AEB VPT BBIAS */
496 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
497 /* GbBIAS RSVD EXHCH EXHCL */
498 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
499 /* RBIAS ADVFL ASDVFH YAVE */
500 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
501 /* HSYST HSYEN HREF */
502 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
503 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
504 /* ADC ACOM OFON TSLB */
505 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
506 /* COM11 COM12 COM13 COM14 */
507 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
508 /* EDGE COM15 COM16 COM17 */
509 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
510 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
511 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
512 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
513 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
514 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
515 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
516 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
517 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
518 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
519 /* LCC1 LCC2 LCC3 LCC4 */
520 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
521 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
522 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
523 /* band gap reference [0:3] DBLV */
524 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
525 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
526 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
527 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
528 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
529 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
530 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
531 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
532 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
533 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
534 /****** (some exchanges in the win trace) ******/
535 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
536 /* bits[3..0]reserved */
537 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
538 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
539 /* VREF vertical frame ctrl */
540 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
541 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
542 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
543 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
544 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
545 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
546 /****** (some exchanges in the win trace) ******/
547 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
548 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
549 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
550 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
551 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
552 /****** (some exchanges in the win trace) ******/
553 /******!! startsensor KO if changed !!****/
554 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
555 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
556 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
557 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
560 /* reg 0x04 reg 0x07 reg 0x10 */
561 /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
563 static const __u8 ov7648_sensor_init[][8] = {
564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
566 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
567 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
568 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
569 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
571 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
572 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
573 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
574 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
575 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
576 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
578 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
579 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
580 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
581 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
582 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
583 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
584 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
585 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
586 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
587 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
588 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
589 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
590 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
591 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
593 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
594 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
595 * This is currently setting a
596 * blue tint, and some things more , i leave it here for future test if
597 * somene is having problems with color on this sensor
598 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
601 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
602 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
603 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
604 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
609 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
610 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
611 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
612 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
613 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
614 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
615 /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
619 static const __u8 qtable4[] = {
620 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
621 0x06, 0x08, 0x0A, 0x11,
622 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
623 0x19, 0x19, 0x17, 0x15,
624 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
625 0x21, 0x2E, 0x21, 0x23,
626 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
627 0x25, 0x29, 0x2C, 0x29,
628 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
629 0x17, 0x1B, 0x29, 0x29,
630 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
631 0x29, 0x29, 0x29, 0x29,
632 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
633 0x29, 0x29, 0x29, 0x29,
634 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
635 0x29, 0x29, 0x29, 0x29
638 /* read <len> bytes to gspca_dev->usb_buf */
639 static void reg_r(struct gspca_dev *gspca_dev,
640 __u16 value, int len)
643 if (len > USB_BUF_SZ) {
644 err("reg_r: buffer overflow");
648 usb_control_msg(gspca_dev->dev,
649 usb_rcvctrlpipe(gspca_dev->dev, 0),
651 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
653 gspca_dev->usb_buf, len,
655 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
658 static void reg_w1(struct gspca_dev *gspca_dev,
662 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
663 gspca_dev->usb_buf[0] = data;
664 usb_control_msg(gspca_dev->dev,
665 usb_sndctrlpipe(gspca_dev->dev, 0),
667 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
670 gspca_dev->usb_buf, 1,
673 static void reg_w(struct gspca_dev *gspca_dev,
678 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
679 value, buffer[0], buffer[1]);
681 if (len > USB_BUF_SZ) {
682 err("reg_w: buffer overflow");
686 memcpy(gspca_dev->usb_buf, buffer, len);
687 usb_control_msg(gspca_dev->dev,
688 usb_sndctrlpipe(gspca_dev->dev, 0),
690 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
692 gspca_dev->usb_buf, len,
696 /* I2C write 1 byte */
697 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
699 struct sd *sd = (struct sd *) gspca_dev;
701 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
702 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
703 gspca_dev->usb_buf[1] = sd->i2c_base;
704 gspca_dev->usb_buf[2] = reg;
705 gspca_dev->usb_buf[3] = val;
706 gspca_dev->usb_buf[4] = 0;
707 gspca_dev->usb_buf[5] = 0;
708 gspca_dev->usb_buf[6] = 0;
709 gspca_dev->usb_buf[7] = 0x10;
710 usb_control_msg(gspca_dev->dev,
711 usb_sndctrlpipe(gspca_dev->dev, 0),
713 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
714 0x08, /* value = i2c */
716 gspca_dev->usb_buf, 8,
720 /* I2C write 8 bytes */
721 static void i2c_w8(struct gspca_dev *gspca_dev,
724 memcpy(gspca_dev->usb_buf, buffer, 8);
725 usb_control_msg(gspca_dev->dev,
726 usb_sndctrlpipe(gspca_dev->dev, 0),
728 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
729 0x08, 0, /* value, index */
730 gspca_dev->usb_buf, 8,
735 /* read 5 bytes in gspca_dev->usb_buf */
736 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
738 struct sd *sd = (struct sd *) gspca_dev;
741 mode[0] = 0x81 | 0x10;
742 mode[1] = sd->i2c_base;
749 i2c_w8(gspca_dev, mode);
751 mode[0] = 0x81 | (5 << 4) | 0x02;
753 i2c_w8(gspca_dev, mode);
755 reg_r(gspca_dev, 0x0a, 5);
758 static int probesensor(struct gspca_dev *gspca_dev)
760 struct sd *sd = (struct sd *) gspca_dev;
762 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
764 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
766 i2c_r5(gspca_dev, 0); /* read sensor id */
767 if (gspca_dev->usb_buf[0] == 0x02
768 && gspca_dev->usb_buf[1] == 0x09
769 && gspca_dev->usb_buf[2] == 0x01
770 && gspca_dev->usb_buf[3] == 0x00
771 && gspca_dev->usb_buf[4] == 0x00) {
772 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
773 sd->sensor = SENSOR_HV7131R;
774 return SENSOR_HV7131R;
776 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
777 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
778 gspca_dev->usb_buf[2]);
779 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
783 static int configure_gpio(struct gspca_dev *gspca_dev,
786 struct sd *sd = (struct sd *) gspca_dev;
788 static const __u8 reg9a_def[] =
789 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
790 static const __u8 reg9a_sn9c325[] =
791 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
792 static const __u8 regd4[] = {0x60, 0x00, 0x00};
794 reg_w1(gspca_dev, 0xf1, 0x00);
795 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
798 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
799 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
800 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
801 switch (sd->bridge) {
803 reg9a = reg9a_sn9c325;
809 reg_w(gspca_dev, 0x9a, reg9a, 6);
811 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
813 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
815 switch (sd->sensor) {
817 reg_w1(gspca_dev, 0x02, 0x71);
818 reg_w1(gspca_dev, 0x01, 0x42);
819 reg_w1(gspca_dev, 0x17, 0x64);
820 reg_w1(gspca_dev, 0x01, 0x42);
822 /*jfm: from win trace */
824 reg_w1(gspca_dev, 0x01, 0x61);
825 reg_w1(gspca_dev, 0x17, 0xe2);
826 reg_w1(gspca_dev, 0x01, 0x60);
827 reg_w1(gspca_dev, 0x01, 0x40);
830 reg_w1(gspca_dev, 0x01, 0x43);
831 reg_w1(gspca_dev, 0x17, 0xae);
832 reg_w1(gspca_dev, 0x01, 0x42);
834 /*jfm: from win trace */
836 reg_w1(gspca_dev, 0x01, 0x61);
837 reg_w1(gspca_dev, 0x17, 0x20);
838 reg_w1(gspca_dev, 0x01, 0x60);
839 reg_w1(gspca_dev, 0x01, 0x40);
842 reg_w1(gspca_dev, 0x01, 0x43);
843 reg_w1(gspca_dev, 0x17, 0x61);
844 reg_w1(gspca_dev, 0x01, 0x42);
845 if (sd->sensor == SENSOR_HV7131R) {
846 if (probesensor(gspca_dev) < 0)
854 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
857 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
858 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
860 while (hv7131r_sensor_init[i][0]) {
861 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
864 i2c_w8(gspca_dev, SetSensorClk);
867 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
871 while (mi0360_sensor_init[i][0]) {
872 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
877 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
881 while (mo4000_sensor_init[i][0]) {
882 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
887 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
891 while (om6802_sensor_init[i][0]) {
892 i2c_w8(gspca_dev, om6802_sensor_init[i]);
897 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
901 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
903 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
906 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
908 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
911 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
913 /*jfm:win i2c_r from 00 to 80*/
915 while (ov7630_sensor_init[i][0]) {
916 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
921 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
925 while (ov7648_sensor_init[i][0]) {
926 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
931 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
935 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
938 while (ov7660_sensor_init[i][0]) {
939 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
944 /* this function is called at probe time */
945 static int sd_config(struct gspca_dev *gspca_dev,
946 const struct usb_device_id *id)
948 struct sd *sd = (struct sd *) gspca_dev;
951 cam = &gspca_dev->cam;
953 cam->cam_mode = vga_mode;
954 cam->nmodes = ARRAY_SIZE(vga_mode);
956 sd->bridge = id->driver_info >> 16;
957 sd->sensor = id->driver_info >> 8;
958 sd->i2c_base = id->driver_info;
960 sd->qindex = 4; /* set the quantization table */
961 sd->brightness = BRIGHTNESS_DEF;
962 sd->contrast = CONTRAST_DEF;
963 sd->colors = COLOR_DEF;
964 sd->autogain = AUTOGAIN_DEF;
967 switch (sd->sensor) {
971 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
974 if (sd->sensor != SENSOR_OV7630)
975 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
980 /* this function is called at probe and resume time */
981 static int sd_init(struct gspca_dev *gspca_dev)
983 struct sd *sd = (struct sd *) gspca_dev;
984 /* const __u8 *sn9c1xx; */
985 __u8 regGpio[] = { 0x29, 0x74 };
988 /* setup a selector by bridge */
989 reg_w1(gspca_dev, 0xf1, 0x01);
990 reg_r(gspca_dev, 0x00, 1);
991 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
992 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
993 regF1 = gspca_dev->usb_buf[0];
994 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
995 switch (sd->bridge) {
996 case BRIDGE_SN9C102P:
999 reg_w1(gspca_dev, 0x02, regGpio[1]);
1001 case BRIDGE_SN9C105:
1004 reg_w(gspca_dev, 0x01, regGpio, 2);
1006 case BRIDGE_SN9C120:
1010 reg_w(gspca_dev, 0x01, regGpio, 2);
1013 /* case BRIDGE_SN9C110: */
1014 /* case BRIDGE_SN9C325: */
1017 reg_w1(gspca_dev, 0x02, 0x62);
1021 reg_w1(gspca_dev, 0xf1, 0x01);
1026 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1029 struct sd *sd = (struct sd *) gspca_dev;
1030 static const __u8 doit[] = /* update sensor */
1031 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1032 static const __u8 sensorgo[] = /* sensor on */
1033 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1034 static const __u8 gainMo[] =
1035 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1037 switch (sd->sensor) {
1038 case SENSOR_HV7131R: {
1040 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1042 Expodoit[3] = expo >> 16;
1043 Expodoit[4] = expo >> 8;
1045 i2c_w8(gspca_dev, Expodoit);
1048 case SENSOR_MI0360: {
1049 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1050 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1054 else if (expo < 0x0001)
1056 expoMi[3] = expo >> 8;
1058 i2c_w8(gspca_dev, expoMi);
1059 i2c_w8(gspca_dev, doit);
1060 i2c_w8(gspca_dev, sensorgo);
1063 case SENSOR_MO4000: {
1065 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1067 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1071 else if (expo < 0x0001)
1073 expoMof[3] = (expo & 0x03fc) >> 2;
1074 i2c_w8(gspca_dev, expoMof);
1075 expoMo10[3] = ((expo & 0x1c00) >> 10)
1076 | ((expo & 0x0003) << 4);
1077 i2c_w8(gspca_dev, expoMo10);
1078 i2c_w8(gspca_dev, gainMo);
1079 PDEBUG(D_CONF, "set exposure %d",
1080 ((expoMo10[3] & 0x07) << 10)
1082 | ((expoMo10[3] & 0x30) >> 4));
1085 case SENSOR_OM6802: {
1087 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1093 gainOm[3] = expo >> 2;
1094 i2c_w8(gspca_dev, gainOm);
1095 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1096 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1103 /* this function is used for sensors o76xx only */
1104 static void setbrightcont(struct gspca_dev *gspca_dev)
1106 struct sd *sd = (struct sd *) gspca_dev;
1108 __u8 reg84_full[0x15];
1110 memcpy(reg84_full, reg84, sizeof reg84_full);
1111 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1112 reg84_full[0] = (val + 1) / 2; /* red */
1113 reg84_full[2] = val; /* green */
1114 reg84_full[4] = (val + 1) / 5; /* blue */
1115 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
1117 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
1118 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1121 /* sensor != ov76xx */
1122 static void setbrightness(struct gspca_dev *gspca_dev)
1124 struct sd *sd = (struct sd *) gspca_dev;
1128 k2 = sd->brightness >> 10;
1129 switch (sd->sensor) {
1130 case SENSOR_HV7131R:
1131 expo = sd->brightness << 4;
1132 if (expo > 0x002dc6c0)
1134 else if (expo < 0x02a0)
1136 sd->exposure = setexposure(gspca_dev, expo);
1140 expo = sd->brightness >> 4;
1141 sd->exposure = setexposure(gspca_dev, expo);
1144 expo = sd->brightness >> 6;
1145 sd->exposure = setexposure(gspca_dev, expo);
1146 k2 = sd->brightness >> 11;
1150 reg_w1(gspca_dev, 0x96, k2);
1153 /* sensor != ov76xx */
1154 static void setcontrast(struct gspca_dev *gspca_dev)
1156 struct sd *sd = (struct sd *) gspca_dev;
1158 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1162 contrast[0] = (k2 + 1) >> 1;
1163 contrast[4] = (k2 + 1) / 5;
1164 reg_w(gspca_dev, 0x84, contrast, 6);
1167 static void setcolors(struct gspca_dev *gspca_dev)
1169 struct sd *sd = (struct sd *) gspca_dev;
1172 if (sd->colors >= 32) {
1173 red = 32 + (sd->colors - 32) / 2;
1174 blue = 64 - sd->colors;
1177 blue = 32 + (32 - sd->colors) / 2;
1179 reg_w1(gspca_dev, 0x05, red);
1180 /* reg_w1(gspca_dev, 0x07, 32); */
1181 reg_w1(gspca_dev, 0x06, blue);
1184 static void setautogain(struct gspca_dev *gspca_dev)
1186 struct sd *sd = (struct sd *) gspca_dev;
1188 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1191 sd->ag_cnt = AG_CNT_START;
1196 static void setvflip(struct sd *sd)
1198 if (sd->sensor != SENSOR_OV7630)
1200 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1201 sd->vflip ? 0x82 : 0x02);
1204 /* -- start the camera -- */
1205 static int sd_start(struct gspca_dev *gspca_dev)
1207 struct sd *sd = (struct sd *) gspca_dev;
1209 __u8 reg1, reg17, reg18;
1210 const __u8 *sn9c1xx;
1212 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1213 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1214 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1215 static const __u8 CE_ov76xx[] =
1216 { 0x32, 0xdd, 0x32, 0xdd };
1218 sn9c1xx = sn_tb[(int) sd->sensor];
1219 configure_gpio(gspca_dev, sn9c1xx);
1221 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1222 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1223 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1224 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1225 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1226 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1227 reg_w1(gspca_dev, 0xd3, 0x50);
1228 reg_w1(gspca_dev, 0xc6, 0x00);
1229 reg_w1(gspca_dev, 0xc7, 0x00);
1230 reg_w1(gspca_dev, 0xc8, 0x50);
1231 reg_w1(gspca_dev, 0xc9, 0x3c);
1232 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1233 switch (sd->sensor) {
1240 /*jfm: from win trace */
1248 reg_w1(gspca_dev, 0x17, reg17);
1249 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1250 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1251 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1252 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1253 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1254 for (i = 0; i < 8; i++)
1255 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1256 switch (sd->sensor) {
1258 reg_w1(gspca_dev, 0x9a, 0x05);
1261 reg_w1(gspca_dev, 0x9a, 0x08);
1262 reg_w1(gspca_dev, 0x99, 0x59);
1266 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1268 reg1 = 0x46; /* 320 clk 48Mhz */
1270 reg1 = 0x06; /* 640 clk 24Mz */
1272 switch (sd->sensor) {
1273 case SENSOR_HV7131R:
1274 hv7131R_InitSensor(gspca_dev);
1277 mi0360_InitSensor(gspca_dev);
1280 mo4000_InitSensor(gspca_dev);
1282 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1283 reg1 = 0x06; /* clk 24Mz */
1285 reg17 = 0x22; /* 640 MCKSIZE */
1286 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1290 om6802_InitSensor(gspca_dev);
1291 reg17 = 0x64; /* 640 MCKSIZE */
1294 ov7630_InitSensor(gspca_dev);
1300 ov7648_InitSensor(gspca_dev);
1309 /* case SENSOR_OV7660: */
1310 ov7660_InitSensor(gspca_dev);
1312 /* reg17 = 0x21; * 320 */
1314 /* reg1 = 0x46; (done) */
1316 reg17 = 0xa2; /* 640 */
1321 reg_w(gspca_dev, 0xc0, C0, 6);
1322 reg_w(gspca_dev, 0xca, CA, 4);
1323 switch (sd->sensor) {
1327 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1330 reg_w(gspca_dev, 0xce, CE, 4);
1331 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1335 /* here change size mode 0 -> VGA; 1 -> CIF */
1336 reg18 = sn9c1xx[0x18] | (mode << 4);
1337 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1339 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1340 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1342 reg_w1(gspca_dev, 0x18, reg18);
1344 reg_w1(gspca_dev, 0x17, reg17);
1345 switch (sd->sensor) {
1346 case SENSOR_HV7131R:
1350 setbrightness(gspca_dev);
1351 setcontrast(gspca_dev);
1356 default: /* OV76xx */
1357 setbrightcont(gspca_dev);
1360 setautogain(gspca_dev);
1361 reg_w1(gspca_dev, 0x01, reg1);
1365 static void sd_stopN(struct gspca_dev *gspca_dev)
1367 struct sd *sd = (struct sd *) gspca_dev;
1368 static const __u8 stophv7131[] =
1369 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1370 static const __u8 stopmi0360[] =
1371 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1373 const __u8 *sn9c1xx;
1376 switch (sd->sensor) {
1377 case SENSOR_HV7131R:
1378 i2c_w8(gspca_dev, stophv7131);
1382 i2c_w8(gspca_dev, stopmi0360);
1390 /* case SENSOR_MO4000: */
1391 /* case SENSOR_OV7660: */
1394 sn9c1xx = sn_tb[(int) sd->sensor];
1395 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1396 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1397 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1398 reg_w1(gspca_dev, 0x01, data);
1399 reg_w1(gspca_dev, 0xf1, 0x00);
1402 static void do_autogain(struct gspca_dev *gspca_dev)
1404 struct sd *sd = (struct sd *) gspca_dev;
1407 __u8 luma_mean = 130;
1408 __u8 luma_delta = 20;
1410 /* Thanks S., without your advice, autobright should not work :) */
1413 if (--sd->ag_cnt >= 0)
1415 sd->ag_cnt = AG_CNT_START;
1417 delta = atomic_read(&sd->avg_lum);
1418 PDEBUG(D_FRAM, "mean lum %d", delta);
1419 if (delta < luma_mean - luma_delta ||
1420 delta > luma_mean + luma_delta) {
1421 switch (sd->sensor) {
1422 case SENSOR_HV7131R:
1423 expotimes = sd->exposure >> 8;
1424 expotimes += (luma_mean - delta) >> 4;
1427 sd->exposure = setexposure(gspca_dev,
1428 (unsigned int) (expotimes << 8));
1431 /* case SENSOR_MO4000: */
1432 /* case SENSOR_MI0360: */
1433 /* case SENSOR_OM6802: */
1434 expotimes = sd->exposure;
1435 expotimes += (luma_mean - delta) >> 6;
1438 sd->exposure = setexposure(gspca_dev,
1439 (unsigned int) expotimes);
1440 setcolors(gspca_dev);
1446 /* scan the URB packets */
1447 /* This function is run at interrupt level. */
1448 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1449 struct gspca_frame *frame, /* target */
1450 __u8 *data, /* isoc packet */
1451 int len) /* iso packet length */
1453 struct sd *sd = (struct sd *) gspca_dev;
1457 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1460 gspca_frame_add(gspca_dev, LAST_PACKET,
1461 frame, data, sof + 2);
1468 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1470 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1472 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1474 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1476 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1478 atomic_set(&sd->avg_lum, avg_lum);
1481 if (gspca_dev->last_packet_type == LAST_PACKET) {
1483 /* put the JPEG 422 header */
1484 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1486 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1489 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1491 struct sd *sd = (struct sd *) gspca_dev;
1493 sd->brightness = val;
1494 if (gspca_dev->streaming) {
1495 switch (sd->sensor) {
1496 case SENSOR_HV7131R:
1500 setbrightness(gspca_dev);
1502 default: /* OV76xx */
1503 setbrightcont(gspca_dev);
1510 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1512 struct sd *sd = (struct sd *) gspca_dev;
1514 *val = sd->brightness;
1518 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1520 struct sd *sd = (struct sd *) gspca_dev;
1523 if (gspca_dev->streaming) {
1524 switch (sd->sensor) {
1525 case SENSOR_HV7131R:
1529 setcontrast(gspca_dev);
1531 default: /* OV76xx */
1532 setbrightcont(gspca_dev);
1539 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1541 struct sd *sd = (struct sd *) gspca_dev;
1543 *val = sd->contrast;
1547 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1549 struct sd *sd = (struct sd *) gspca_dev;
1552 if (gspca_dev->streaming)
1553 setcolors(gspca_dev);
1557 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1559 struct sd *sd = (struct sd *) gspca_dev;
1565 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1567 struct sd *sd = (struct sd *) gspca_dev;
1570 if (gspca_dev->streaming)
1571 setautogain(gspca_dev);
1575 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1577 struct sd *sd = (struct sd *) gspca_dev;
1579 *val = sd->autogain;
1583 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1585 struct sd *sd = (struct sd *) gspca_dev;
1588 if (gspca_dev->streaming)
1593 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1595 struct sd *sd = (struct sd *) gspca_dev;
1601 /* sub-driver description */
1602 static const struct sd_desc sd_desc = {
1603 .name = MODULE_NAME,
1605 .nctrls = ARRAY_SIZE(sd_ctrls),
1606 .config = sd_config,
1610 .pkt_scan = sd_pkt_scan,
1611 .dq_callback = do_autogain,
1614 /* -- module initialisation -- */
1615 #define BSI(bridge, sensor, i2c_addr) \
1616 .driver_info = (BRIDGE_ ## bridge << 16) \
1617 | (SENSOR_ ## sensor << 8) \
1619 static const __devinitdata struct usb_device_id device_table[] = {
1620 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1621 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1623 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1624 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1625 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1626 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1628 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1629 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1631 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1632 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1633 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1634 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1635 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1636 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1637 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1638 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1639 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1640 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1641 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1642 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1643 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1644 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1645 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1647 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1648 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1649 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1650 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1652 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1653 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1654 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1655 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1656 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1657 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1659 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1660 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1661 /* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1662 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1663 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1664 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1666 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1669 MODULE_DEVICE_TABLE(usb, device_table);
1671 /* -- device connect -- */
1672 static int sd_probe(struct usb_interface *intf,
1673 const struct usb_device_id *id)
1675 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1679 static struct usb_driver sd_driver = {
1680 .name = MODULE_NAME,
1681 .id_table = device_table,
1683 .disconnect = gspca_disconnect,
1685 .suspend = gspca_suspend,
1686 .resume = gspca_resume,
1690 /* -- module insert / remove -- */
1691 static int __init sd_mod_init(void)
1693 if (usb_register(&sd_driver) < 0)
1698 static void __exit sd_mod_exit(void)
1700 usb_deregister(&sd_driver);
1701 info("deregistered");
1704 module_init(sd_mod_init);
1705 module_exit(sd_mod_exit);