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 static const __u8 reg84[] = {
271 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
272 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
273 0xf7, 0x0f, 0x00, 0x00, 0x00
275 static const __u8 hv7131r_sensor_init[][8] = {
276 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
277 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
278 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
279 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
280 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
281 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
282 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
284 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
285 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
286 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
287 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
288 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
289 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
290 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
291 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
293 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
294 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
295 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
296 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
297 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
299 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
300 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
301 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
302 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
306 static const __u8 mi0360_sensor_init[][8] = {
307 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
308 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
309 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
310 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
311 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
312 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
313 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
314 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
315 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
316 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
317 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
318 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
319 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
321 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
322 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
323 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
325 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
326 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
327 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
328 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
329 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
330 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
331 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
332 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
334 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
335 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
336 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
337 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
338 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
339 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
341 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
342 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
343 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
344 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
345 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
347 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
348 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
349 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
350 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
352 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
353 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
354 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
355 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
356 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
357 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
360 static const __u8 mo4000_sensor_init[][8] = {
361 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
362 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
363 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
364 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
365 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
366 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
367 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
368 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
369 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
370 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
371 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
372 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
373 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
374 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
375 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
377 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
378 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
379 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
380 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
383 static __u8 om6802_sensor_init[][8] = {
384 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
385 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
386 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
387 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
388 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
389 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
390 /* white balance & auto-exposure */
391 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
393 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
394 * max AGC value in AE */
395 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
397 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
398 * preset brightness */
399 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
401 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
403 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
404 /* luminance mode (0x4f = AE) */
405 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
407 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
409 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
411 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
412 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
413 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
414 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
417 static const __u8 ov7630_sensor_init[][8] = {
418 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
420 /* win: delay 20ms */
421 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
422 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
423 /* win: delay 20ms */
424 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
425 /* win: i2c_r from 00 to 80 */
426 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
427 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
428 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
429 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
430 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
431 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
432 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
433 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
434 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
435 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
436 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
437 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
441 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
443 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
444 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
445 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
447 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
448 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
449 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
450 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
451 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
453 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
454 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
455 /*fixme: + 0x12, 0x04*/
456 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
458 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
459 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
460 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
462 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
463 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
464 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
466 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
467 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
470 static const __u8 ov7660_sensor_init[][8] = {
471 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
473 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
474 /* Outformat = rawRGB */
475 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
476 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
477 /* GAIN BLUE RED VREF */
478 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
479 /* COM 1 BAVE GEAVE AECHH */
480 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
481 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
482 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
483 /* AECH CLKRC COM7 COM8 */
484 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
485 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
486 /* HSTART HSTOP VSTRT VSTOP */
487 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
488 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
489 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
490 /* BOS GBOS GROS ROS (BGGR offset) */
491 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
492 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
493 /* AEW AEB VPT BBIAS */
494 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
495 /* GbBIAS RSVD EXHCH EXHCL */
496 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
497 /* RBIAS ADVFL ASDVFH YAVE */
498 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
499 /* HSYST HSYEN HREF */
500 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
501 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
502 /* ADC ACOM OFON TSLB */
503 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
504 /* COM11 COM12 COM13 COM14 */
505 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
506 /* EDGE COM15 COM16 COM17 */
507 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
508 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
509 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
510 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
511 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
512 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
513 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
514 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
515 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
516 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
517 /* LCC1 LCC2 LCC3 LCC4 */
518 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
519 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
520 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
521 /* band gap reference [0:3] DBLV */
522 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
523 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
524 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
525 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
526 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
527 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
528 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
529 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
530 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
531 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
532 /****** (some exchanges in the win trace) ******/
533 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
534 /* bits[3..0]reserved */
535 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
536 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
537 /* VREF vertical frame ctrl */
538 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
539 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
540 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
541 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
542 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
543 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
544 /****** (some exchanges in the win trace) ******/
545 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
546 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
547 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
548 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
549 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
550 /****** (some exchanges in the win trace) ******/
551 /******!! startsensor KO if changed !!****/
552 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
553 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
554 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
555 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
558 /* reg 0x04 reg 0x07 reg 0x10 */
559 /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
561 static const __u8 ov7648_sensor_init[][8] = {
562 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
563 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
566 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
567 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
568 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
569 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
571 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
572 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
573 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
574 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
575 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
576 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
578 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
579 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
580 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
581 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
582 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
583 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
584 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
585 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
586 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
587 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
588 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
589 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
590 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
591 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
593 * This is currently setting a
594 * blue tint, and some things more , i leave it here for future test if
595 * somene is having problems with color on this sensor
596 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
597 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
598 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
599 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
600 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
601 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
602 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
603 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
604 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
609 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
610 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
611 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
612 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
613 /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
617 static const __u8 qtable4[] = {
618 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
619 0x06, 0x08, 0x0A, 0x11,
620 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
621 0x19, 0x19, 0x17, 0x15,
622 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
623 0x21, 0x2E, 0x21, 0x23,
624 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
625 0x25, 0x29, 0x2C, 0x29,
626 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
627 0x17, 0x1B, 0x29, 0x29,
628 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
629 0x29, 0x29, 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
636 /* read <len> bytes to gspca_dev->usb_buf */
637 static void reg_r(struct gspca_dev *gspca_dev,
638 __u16 value, int len)
641 if (len > USB_BUF_SZ) {
642 err("reg_r: buffer overflow");
646 usb_control_msg(gspca_dev->dev,
647 usb_rcvctrlpipe(gspca_dev->dev, 0),
649 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
651 gspca_dev->usb_buf, len,
653 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
656 static void reg_w1(struct gspca_dev *gspca_dev,
660 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
661 gspca_dev->usb_buf[0] = data;
662 usb_control_msg(gspca_dev->dev,
663 usb_sndctrlpipe(gspca_dev->dev, 0),
665 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
668 gspca_dev->usb_buf, 1,
671 static void reg_w(struct gspca_dev *gspca_dev,
676 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
677 value, buffer[0], buffer[1]);
679 if (len > USB_BUF_SZ) {
680 err("reg_w: buffer overflow");
684 memcpy(gspca_dev->usb_buf, buffer, len);
685 usb_control_msg(gspca_dev->dev,
686 usb_sndctrlpipe(gspca_dev->dev, 0),
688 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
690 gspca_dev->usb_buf, len,
694 /* I2C write 1 byte */
695 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
697 struct sd *sd = (struct sd *) gspca_dev;
699 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
700 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
701 gspca_dev->usb_buf[1] = sd->i2c_base;
702 gspca_dev->usb_buf[2] = reg;
703 gspca_dev->usb_buf[3] = val;
704 gspca_dev->usb_buf[4] = 0;
705 gspca_dev->usb_buf[5] = 0;
706 gspca_dev->usb_buf[6] = 0;
707 gspca_dev->usb_buf[7] = 0x10;
708 usb_control_msg(gspca_dev->dev,
709 usb_sndctrlpipe(gspca_dev->dev, 0),
711 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
712 0x08, /* value = i2c */
714 gspca_dev->usb_buf, 8,
718 /* I2C write 8 bytes */
719 static void i2c_w8(struct gspca_dev *gspca_dev,
722 memcpy(gspca_dev->usb_buf, buffer, 8);
723 usb_control_msg(gspca_dev->dev,
724 usb_sndctrlpipe(gspca_dev->dev, 0),
726 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
727 0x08, 0, /* value, index */
728 gspca_dev->usb_buf, 8,
733 /* read 5 bytes in gspca_dev->usb_buf */
734 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
736 struct sd *sd = (struct sd *) gspca_dev;
739 mode[0] = 0x81 | 0x10;
740 mode[1] = sd->i2c_base;
747 i2c_w8(gspca_dev, mode);
749 mode[0] = 0x81 | (5 << 4) | 0x02;
751 i2c_w8(gspca_dev, mode);
753 reg_r(gspca_dev, 0x0a, 5);
756 static int probesensor(struct gspca_dev *gspca_dev)
758 struct sd *sd = (struct sd *) gspca_dev;
760 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
762 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
764 i2c_r5(gspca_dev, 0); /* read sensor id */
765 if (gspca_dev->usb_buf[0] == 0x02
766 && gspca_dev->usb_buf[1] == 0x09
767 && gspca_dev->usb_buf[2] == 0x01
768 && gspca_dev->usb_buf[3] == 0x00
769 && gspca_dev->usb_buf[4] == 0x00) {
770 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
771 sd->sensor = SENSOR_HV7131R;
772 return SENSOR_HV7131R;
774 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
775 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
776 gspca_dev->usb_buf[2]);
777 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
781 static int configure_gpio(struct gspca_dev *gspca_dev,
784 struct sd *sd = (struct sd *) gspca_dev;
786 static const __u8 reg9a_def[] =
787 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
788 static const __u8 reg9a_sn9c325[] =
789 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
790 static const __u8 regd4[] = {0x60, 0x00, 0x00};
792 reg_w1(gspca_dev, 0xf1, 0x00);
793 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
796 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
797 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
798 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
799 switch (sd->bridge) {
801 reg9a = reg9a_sn9c325;
807 reg_w(gspca_dev, 0x9a, reg9a, 6);
809 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
811 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
813 switch (sd->sensor) {
815 reg_w1(gspca_dev, 0x02, 0x71);
816 reg_w1(gspca_dev, 0x01, 0x42);
817 reg_w1(gspca_dev, 0x17, 0x64);
818 reg_w1(gspca_dev, 0x01, 0x42);
820 /*jfm: from win trace */
822 reg_w1(gspca_dev, 0x01, 0x61);
823 reg_w1(gspca_dev, 0x17, 0xe2);
824 reg_w1(gspca_dev, 0x01, 0x60);
825 reg_w1(gspca_dev, 0x01, 0x40);
828 reg_w1(gspca_dev, 0x01, 0x43);
829 reg_w1(gspca_dev, 0x17, 0xae);
830 reg_w1(gspca_dev, 0x01, 0x42);
832 /*jfm: from win trace */
834 reg_w1(gspca_dev, 0x01, 0x61);
835 reg_w1(gspca_dev, 0x17, 0x20);
836 reg_w1(gspca_dev, 0x01, 0x60);
837 reg_w1(gspca_dev, 0x01, 0x40);
840 reg_w1(gspca_dev, 0x01, 0x43);
841 reg_w1(gspca_dev, 0x17, 0x61);
842 reg_w1(gspca_dev, 0x01, 0x42);
843 if (sd->sensor == SENSOR_HV7131R) {
844 if (probesensor(gspca_dev) < 0)
852 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
855 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
856 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
858 while (hv7131r_sensor_init[i][0]) {
859 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
862 i2c_w8(gspca_dev, SetSensorClk);
865 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
869 while (mi0360_sensor_init[i][0]) {
870 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
875 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
879 while (mo4000_sensor_init[i][0]) {
880 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
885 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
889 while (om6802_sensor_init[i][0]) {
890 i2c_w8(gspca_dev, om6802_sensor_init[i]);
895 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
899 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
901 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
904 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
906 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
909 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
911 /*jfm:win i2c_r from 00 to 80*/
913 while (ov7630_sensor_init[i][0]) {
914 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
919 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
923 while (ov7648_sensor_init[i][0]) {
924 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
929 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
933 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
936 while (ov7660_sensor_init[i][0]) {
937 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
942 /* this function is called at probe time */
943 static int sd_config(struct gspca_dev *gspca_dev,
944 const struct usb_device_id *id)
946 struct sd *sd = (struct sd *) gspca_dev;
949 cam = &gspca_dev->cam;
951 cam->cam_mode = vga_mode;
952 cam->nmodes = ARRAY_SIZE(vga_mode);
954 sd->bridge = id->driver_info >> 16;
955 sd->sensor = id->driver_info >> 8;
956 sd->i2c_base = id->driver_info;
958 sd->qindex = 4; /* set the quantization table */
959 sd->brightness = BRIGHTNESS_DEF;
960 sd->contrast = CONTRAST_DEF;
961 sd->colors = COLOR_DEF;
962 sd->autogain = AUTOGAIN_DEF;
965 switch (sd->sensor) {
969 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
972 if (sd->sensor != SENSOR_OV7630)
973 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
978 /* this function is called at probe and resume time */
979 static int sd_init(struct gspca_dev *gspca_dev)
981 struct sd *sd = (struct sd *) gspca_dev;
982 /* const __u8 *sn9c1xx; */
983 __u8 regGpio[] = { 0x29, 0x74 };
986 /* setup a selector by bridge */
987 reg_w1(gspca_dev, 0xf1, 0x01);
988 reg_r(gspca_dev, 0x00, 1);
989 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
990 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
991 regF1 = gspca_dev->usb_buf[0];
992 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
993 switch (sd->bridge) {
994 case BRIDGE_SN9C102P:
997 reg_w1(gspca_dev, 0x02, regGpio[1]);
1002 reg_w(gspca_dev, 0x01, regGpio, 2);
1004 case BRIDGE_SN9C120:
1008 reg_w(gspca_dev, 0x01, regGpio, 2);
1011 /* case BRIDGE_SN9C110: */
1012 /* case BRIDGE_SN9C325: */
1015 reg_w1(gspca_dev, 0x02, 0x62);
1019 reg_w1(gspca_dev, 0xf1, 0x01);
1024 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1027 struct sd *sd = (struct sd *) gspca_dev;
1028 static const __u8 doit[] = /* update sensor */
1029 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1030 static const __u8 sensorgo[] = /* sensor on */
1031 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1032 static const __u8 gainMo[] =
1033 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1035 switch (sd->sensor) {
1036 case SENSOR_HV7131R: {
1038 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1040 Expodoit[3] = expo >> 16;
1041 Expodoit[4] = expo >> 8;
1043 i2c_w8(gspca_dev, Expodoit);
1046 case SENSOR_MI0360: {
1047 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1048 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1052 else if (expo < 0x0001)
1054 expoMi[3] = expo >> 8;
1056 i2c_w8(gspca_dev, expoMi);
1057 i2c_w8(gspca_dev, doit);
1058 i2c_w8(gspca_dev, sensorgo);
1061 case SENSOR_MO4000: {
1063 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1065 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1069 else if (expo < 0x0001)
1071 expoMof[3] = (expo & 0x03fc) >> 2;
1072 i2c_w8(gspca_dev, expoMof);
1073 expoMo10[3] = ((expo & 0x1c00) >> 10)
1074 | ((expo & 0x0003) << 4);
1075 i2c_w8(gspca_dev, expoMo10);
1076 i2c_w8(gspca_dev, gainMo);
1077 PDEBUG(D_CONF, "set exposure %d",
1078 ((expoMo10[3] & 0x07) << 10)
1080 | ((expoMo10[3] & 0x30) >> 4));
1083 case SENSOR_OM6802: {
1085 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1091 gainOm[3] = expo >> 2;
1092 i2c_w8(gspca_dev, gainOm);
1093 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1094 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1101 /* this function is used for sensors o76xx only */
1102 static void setbrightcont(struct gspca_dev *gspca_dev)
1104 struct sd *sd = (struct sd *) gspca_dev;
1106 __u8 reg84_full[0x15];
1108 memset(reg84_full, 0, sizeof reg84_full);
1109 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1110 reg84_full[2] = val;
1111 reg84_full[0] = (val + 1) / 2;
1112 reg84_full[4] = (val + 1) / 5;
1113 if (val > BRIGHTNESS_DEF)
1114 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1118 reg84_full[0x12] = val; /* 00..1f */
1119 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1122 /* sensor != ov76xx */
1123 static void setbrightness(struct gspca_dev *gspca_dev)
1125 struct sd *sd = (struct sd *) gspca_dev;
1129 k2 = sd->brightness >> 10;
1130 switch (sd->sensor) {
1131 case SENSOR_HV7131R:
1132 expo = sd->brightness << 4;
1133 if (expo > 0x002dc6c0)
1135 else if (expo < 0x02a0)
1137 sd->exposure = setexposure(gspca_dev, expo);
1141 expo = sd->brightness >> 4;
1142 sd->exposure = setexposure(gspca_dev, expo);
1145 expo = sd->brightness >> 6;
1146 sd->exposure = setexposure(gspca_dev, expo);
1147 k2 = sd->brightness >> 11;
1151 reg_w1(gspca_dev, 0x96, k2);
1154 /* sensor != ov76xx */
1155 static void setcontrast(struct gspca_dev *gspca_dev)
1157 struct sd *sd = (struct sd *) gspca_dev;
1159 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1163 contrast[0] = (k2 + 1) >> 1;
1164 contrast[4] = (k2 + 1) / 5;
1165 reg_w(gspca_dev, 0x84, contrast, 6);
1168 static void setcolors(struct gspca_dev *gspca_dev)
1170 struct sd *sd = (struct sd *) gspca_dev;
1173 if (sd->colors >= 32) {
1174 red = 32 + (sd->colors - 32) / 2;
1175 blue = 64 - sd->colors;
1178 blue = 32 + (32 - sd->colors) / 2;
1180 reg_w1(gspca_dev, 0x05, red);
1181 /* reg_w1(gspca_dev, 0x07, 32); */
1182 reg_w1(gspca_dev, 0x06, blue);
1185 static void setautogain(struct gspca_dev *gspca_dev)
1187 struct sd *sd = (struct sd *) gspca_dev;
1189 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1192 sd->ag_cnt = AG_CNT_START;
1197 static void setvflip(struct sd *sd)
1199 if (sd->sensor != SENSOR_OV7630)
1201 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1202 sd->vflip ? 0x82 : 0x02);
1205 /* -- start the camera -- */
1206 static void sd_start(struct gspca_dev *gspca_dev)
1208 struct sd *sd = (struct sd *) gspca_dev;
1210 __u8 reg1, reg17, reg18;
1211 const __u8 *sn9c1xx;
1213 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1214 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1215 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1216 static const __u8 CE_ov76xx[] =
1217 { 0x32, 0xdd, 0x32, 0xdd };
1219 sn9c1xx = sn_tb[(int) sd->sensor];
1220 configure_gpio(gspca_dev, sn9c1xx);
1222 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1223 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1224 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1225 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1226 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1227 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1228 reg_w1(gspca_dev, 0xd3, 0x50);
1229 reg_w1(gspca_dev, 0xc6, 0x00);
1230 reg_w1(gspca_dev, 0xc7, 0x00);
1231 reg_w1(gspca_dev, 0xc8, 0x50);
1232 reg_w1(gspca_dev, 0xc9, 0x3c);
1233 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1234 switch (sd->sensor) {
1241 /*jfm: from win trace */
1249 reg_w1(gspca_dev, 0x17, reg17);
1250 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1251 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1252 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1253 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1254 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1255 for (i = 0; i < 8; i++)
1256 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1257 switch (sd->sensor) {
1259 reg_w1(gspca_dev, 0x9a, 0x05);
1262 reg_w1(gspca_dev, 0x9a, 0x08);
1263 reg_w1(gspca_dev, 0x99, 0x59);
1267 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1269 reg1 = 0x46; /* 320 clk 48Mhz */
1271 reg1 = 0x06; /* 640 clk 24Mz */
1273 switch (sd->sensor) {
1274 case SENSOR_HV7131R:
1275 hv7131R_InitSensor(gspca_dev);
1278 mi0360_InitSensor(gspca_dev);
1281 mo4000_InitSensor(gspca_dev);
1283 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1284 reg1 = 0x06; /* clk 24Mz */
1286 reg17 = 0x22; /* 640 MCKSIZE */
1287 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1291 om6802_InitSensor(gspca_dev);
1292 reg17 = 0x64; /* 640 MCKSIZE */
1295 ov7630_InitSensor(gspca_dev);
1301 ov7648_InitSensor(gspca_dev);
1310 /* case SENSOR_OV7660: */
1311 ov7660_InitSensor(gspca_dev);
1313 /* reg17 = 0x21; * 320 */
1315 /* reg1 = 0x46; (done) */
1317 reg17 = 0xa2; /* 640 */
1322 reg_w(gspca_dev, 0xc0, C0, 6);
1323 reg_w(gspca_dev, 0xca, CA, 4);
1324 switch (sd->sensor) {
1328 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1331 reg_w(gspca_dev, 0xce, CE, 4);
1332 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1336 /* here change size mode 0 -> VGA; 1 -> CIF */
1337 reg18 = sn9c1xx[0x18] | (mode << 4);
1338 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1340 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1341 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1343 reg_w1(gspca_dev, 0x18, reg18);
1345 reg_w1(gspca_dev, 0x17, reg17);
1346 switch (sd->sensor) {
1347 case SENSOR_HV7131R:
1351 setbrightness(gspca_dev);
1352 setcontrast(gspca_dev);
1354 default: /* OV76xx */
1355 setbrightcont(gspca_dev);
1358 setautogain(gspca_dev);
1359 reg_w1(gspca_dev, 0x01, reg1);
1362 static void sd_stopN(struct gspca_dev *gspca_dev)
1364 struct sd *sd = (struct sd *) gspca_dev;
1365 static const __u8 stophv7131[] =
1366 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1367 static const __u8 stopmi0360[] =
1368 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1370 const __u8 *sn9c1xx;
1373 switch (sd->sensor) {
1374 case SENSOR_HV7131R:
1375 i2c_w8(gspca_dev, stophv7131);
1379 i2c_w8(gspca_dev, stopmi0360);
1387 /* case SENSOR_MO4000: */
1388 /* case SENSOR_OV7660: */
1391 sn9c1xx = sn_tb[(int) sd->sensor];
1392 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1393 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1394 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1395 reg_w1(gspca_dev, 0x01, data);
1396 reg_w1(gspca_dev, 0xf1, 0x00);
1399 static void do_autogain(struct gspca_dev *gspca_dev)
1401 struct sd *sd = (struct sd *) gspca_dev;
1404 __u8 luma_mean = 130;
1405 __u8 luma_delta = 20;
1407 /* Thanks S., without your advice, autobright should not work :) */
1410 if (--sd->ag_cnt >= 0)
1412 sd->ag_cnt = AG_CNT_START;
1414 delta = atomic_read(&sd->avg_lum);
1415 PDEBUG(D_FRAM, "mean lum %d", delta);
1416 if (delta < luma_mean - luma_delta ||
1417 delta > luma_mean + luma_delta) {
1418 switch (sd->sensor) {
1419 case SENSOR_HV7131R:
1420 expotimes = sd->exposure >> 8;
1421 expotimes += (luma_mean - delta) >> 4;
1424 sd->exposure = setexposure(gspca_dev,
1425 (unsigned int) (expotimes << 8));
1428 /* case SENSOR_MO4000: */
1429 /* case SENSOR_MI0360: */
1430 /* case SENSOR_OM6802: */
1431 expotimes = sd->exposure;
1432 expotimes += (luma_mean - delta) >> 6;
1435 sd->exposure = setexposure(gspca_dev,
1436 (unsigned int) expotimes);
1437 setcolors(gspca_dev);
1443 /* scan the URB packets */
1444 /* This function is run at interrupt level. */
1445 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1446 struct gspca_frame *frame, /* target */
1447 __u8 *data, /* isoc packet */
1448 int len) /* iso packet length */
1450 struct sd *sd = (struct sd *) gspca_dev;
1454 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1457 gspca_frame_add(gspca_dev, LAST_PACKET,
1458 frame, data, sof + 2);
1465 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1467 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1469 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1471 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1473 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1475 atomic_set(&sd->avg_lum, avg_lum);
1478 if (gspca_dev->last_packet_type == LAST_PACKET) {
1480 /* put the JPEG 422 header */
1481 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1483 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1486 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1488 struct sd *sd = (struct sd *) gspca_dev;
1490 sd->brightness = val;
1491 if (gspca_dev->streaming) {
1492 switch (sd->sensor) {
1493 case SENSOR_HV7131R:
1497 setbrightness(gspca_dev);
1499 default: /* OV76xx */
1500 setbrightcont(gspca_dev);
1507 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1509 struct sd *sd = (struct sd *) gspca_dev;
1511 *val = sd->brightness;
1515 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1517 struct sd *sd = (struct sd *) gspca_dev;
1520 if (gspca_dev->streaming) {
1521 switch (sd->sensor) {
1522 case SENSOR_HV7131R:
1526 setcontrast(gspca_dev);
1528 default: /* OV76xx */
1529 setbrightcont(gspca_dev);
1536 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1538 struct sd *sd = (struct sd *) gspca_dev;
1540 *val = sd->contrast;
1544 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1546 struct sd *sd = (struct sd *) gspca_dev;
1549 if (gspca_dev->streaming)
1550 setcolors(gspca_dev);
1554 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1556 struct sd *sd = (struct sd *) gspca_dev;
1562 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1564 struct sd *sd = (struct sd *) gspca_dev;
1567 if (gspca_dev->streaming)
1568 setautogain(gspca_dev);
1572 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1574 struct sd *sd = (struct sd *) gspca_dev;
1576 *val = sd->autogain;
1580 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1582 struct sd *sd = (struct sd *) gspca_dev;
1589 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1591 struct sd *sd = (struct sd *) gspca_dev;
1597 /* sub-driver description */
1598 static const struct sd_desc sd_desc = {
1599 .name = MODULE_NAME,
1601 .nctrls = ARRAY_SIZE(sd_ctrls),
1602 .config = sd_config,
1606 .pkt_scan = sd_pkt_scan,
1607 .dq_callback = do_autogain,
1610 /* -- module initialisation -- */
1611 #define BSI(bridge, sensor, i2c_addr) \
1612 .driver_info = (BRIDGE_ ## bridge << 16) \
1613 | (SENSOR_ ## sensor << 8) \
1615 static const __devinitdata struct usb_device_id device_table[] = {
1616 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1617 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1618 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1619 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1620 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1621 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1624 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1625 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1627 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1628 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1629 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1630 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1631 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1632 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1633 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1634 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1635 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1636 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1637 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1638 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1639 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1640 /* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1641 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1642 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1643 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1644 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1646 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1647 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1648 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1649 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1650 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1651 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1653 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1654 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1655 /* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1656 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1657 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1658 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1660 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1663 MODULE_DEVICE_TABLE(usb, device_table);
1665 /* -- device connect -- */
1666 static int sd_probe(struct usb_interface *intf,
1667 const struct usb_device_id *id)
1669 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1673 static struct usb_driver sd_driver = {
1674 .name = MODULE_NAME,
1675 .id_table = device_table,
1677 .disconnect = gspca_disconnect,
1679 .suspend = gspca_suspend,
1680 .resume = gspca_resume,
1684 /* -- module insert / remove -- */
1685 static int __init sd_mod_init(void)
1687 if (usb_register(&sd_driver) < 0)
1692 static void __exit sd_mod_exit(void)
1694 usb_deregister(&sd_driver);
1695 info("deregistered");
1698 module_init(sd_mod_init);
1699 module_exit(sd_mod_exit);