V4L/DVB (9843): gspca: Change the colors and add the red and blue controls in sonixj.
[deliverable/linux.git] / drivers / media / video / gspca / sonixj.c
1 /*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
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
10 * any later version.
11 *
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.
16 *
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
20 */
21
22 #define MODULE_NAME "sonixj"
23
24 #include "gspca.h"
25 #include "jpeg.h"
26
27 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
29 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
31 MODULE_LICENSE("GPL");
32
33 /* specific webcam descriptor */
34 struct sd {
35 struct gspca_dev gspca_dev; /* !! must be the first item */
36
37 atomic_t avg_lum;
38 unsigned int exposure;
39
40 unsigned short brightness;
41 unsigned char contrast;
42 unsigned char colors;
43 unsigned char autogain;
44 __u8 blue;
45 __u8 red;
46 __u8 vflip; /* ov7630 only */
47 __u8 infrared; /* mi0360 only */
48
49 signed char ag_cnt;
50 #define AG_CNT_START 13
51
52 char qindex;
53 unsigned char bridge;
54 #define BRIDGE_SN9C102P 0
55 #define BRIDGE_SN9C105 1
56 #define BRIDGE_SN9C110 2
57 #define BRIDGE_SN9C120 3
58 #define BRIDGE_SN9C325 4
59 char sensor; /* Type of image sensor chip */
60 #define SENSOR_HV7131R 0
61 #define SENSOR_MI0360 1
62 #define SENSOR_MO4000 2
63 #define SENSOR_OM6802 3
64 #define SENSOR_OV7630 4
65 #define SENSOR_OV7648 5
66 #define SENSOR_OV7660 6
67 unsigned char i2c_base;
68 };
69
70 /* V4L2 controls supported by the driver */
71 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
81 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
85 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
87
88 static struct ctrl sd_ctrls[] = {
89 {
90 {
91 .id = V4L2_CID_BRIGHTNESS,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Brightness",
94 .minimum = 0,
95 #define BRIGHTNESS_MAX 0xffff
96 .maximum = BRIGHTNESS_MAX,
97 .step = 1,
98 #define BRIGHTNESS_DEF 0x8000
99 .default_value = BRIGHTNESS_DEF,
100 },
101 .set = sd_setbrightness,
102 .get = sd_getbrightness,
103 },
104 {
105 {
106 .id = V4L2_CID_CONTRAST,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Contrast",
109 .minimum = 0,
110 #define CONTRAST_MAX 127
111 .maximum = CONTRAST_MAX,
112 .step = 1,
113 #define CONTRAST_DEF 63
114 .default_value = CONTRAST_DEF,
115 },
116 .set = sd_setcontrast,
117 .get = sd_getcontrast,
118 },
119 {
120 {
121 .id = V4L2_CID_SATURATION,
122 .type = V4L2_CTRL_TYPE_INTEGER,
123 .name = "Color",
124 .minimum = 0,
125 .maximum = 40,
126 .step = 1,
127 #define COLOR_DEF 32
128 .default_value = COLOR_DEF,
129 },
130 .set = sd_setcolors,
131 .get = sd_getcolors,
132 },
133 {
134 {
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
138 .minimum = 24,
139 .maximum = 40,
140 .step = 1,
141 #define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
143 },
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
146 },
147 {
148 {
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
152 .minimum = 24,
153 .maximum = 40,
154 .step = 1,
155 #define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
157 },
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
160 },
161 #define AUTOGAIN_IDX 5
162 {
163 {
164 .id = V4L2_CID_AUTOGAIN,
165 .type = V4L2_CTRL_TYPE_BOOLEAN,
166 .name = "Auto Gain",
167 .minimum = 0,
168 .maximum = 1,
169 .step = 1,
170 #define AUTOGAIN_DEF 1
171 .default_value = AUTOGAIN_DEF,
172 },
173 .set = sd_setautogain,
174 .get = sd_getautogain,
175 },
176 /* ov7630 only */
177 #define VFLIP_IDX 6
178 {
179 {
180 .id = V4L2_CID_VFLIP,
181 .type = V4L2_CTRL_TYPE_BOOLEAN,
182 .name = "Vflip",
183 .minimum = 0,
184 .maximum = 1,
185 .step = 1,
186 #define VFLIP_DEF 1
187 .default_value = VFLIP_DEF,
188 },
189 .set = sd_setvflip,
190 .get = sd_getvflip,
191 },
192 /* mi0360 only */
193 #define INFRARED_IDX 7
194 {
195 {
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Infrared",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202 #define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
204 },
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
207 },
208 };
209
210 static struct v4l2_pix_format vga_mode[] = {
211 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
212 .bytesperline = 160,
213 .sizeimage = 160 * 120 * 4 / 8 + 590,
214 .colorspace = V4L2_COLORSPACE_JPEG,
215 .priv = 2},
216 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
217 .bytesperline = 320,
218 .sizeimage = 320 * 240 * 3 / 8 + 590,
219 .colorspace = V4L2_COLORSPACE_JPEG,
220 .priv = 1},
221 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
222 .bytesperline = 640,
223 .sizeimage = 640 * 480 * 3 / 8 + 590,
224 .colorspace = V4L2_COLORSPACE_JPEG,
225 .priv = 0},
226 };
227
228 /*Data from sn9c102p+hv71331r */
229 static const __u8 sn_hv7131[] = {
230 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
231 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
232 /* reg8 reg9 rega regb regc regd rege regf */
233 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
234 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
235 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
236 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
237 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
238 };
239
240 static const __u8 sn_mi0360[] = {
241 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
242 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
243 /* reg8 reg9 rega regb regc regd rege regf */
244 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
245 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
246 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
247 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
248 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
249 };
250
251 static const __u8 sn_mo4000[] = {
252 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
253 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
254 /* reg8 reg9 rega regb regc regd rege regf */
255 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
257 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
258 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
259 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
260 };
261
262 static const __u8 sn_om6802[] = {
263 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
264 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
265 /* reg8 reg9 rega regb regc regd rege regf */
266 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
268 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
269 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
270 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
272 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
273 0xf7
274 };
275
276 static const __u8 sn_ov7630[] = {
277 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
278 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
279 /* reg8 reg9 rega regb regc regd rege regf */
280 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
281 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
282 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
283 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
284 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
285 };
286
287 static const __u8 sn_ov7648[] = {
288 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
289 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
290 /* reg8 reg9 rega regb regc regd rege regf */
291 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
292 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
293 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
294 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
295 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
296 };
297
298 static const __u8 sn_ov7660[] = {
299 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
300 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
301 /* reg8 reg9 rega regb regc regd rege regf */
302 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
303 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
304 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
305 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
306 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
307 };
308
309 /* sequence specific to the sensors - !! index = SENSOR_xxx */
310 static const __u8 *sn_tb[] = {
311 sn_hv7131,
312 sn_mi0360,
313 sn_mo4000,
314 sn_om6802,
315 sn_ov7630,
316 sn_ov7648,
317 sn_ov7660
318 };
319
320 static const __u8 gamma_def[] = {
321 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
322 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
323 };
324
325 /* color matrix and offsets */
326 static const __u8 reg84[] = {
327 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
328 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
329 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
330 0x00, 0x00, 0x00 /* YUV offsets */
331 };
332 static const __u8 hv7131r_sensor_init[][8] = {
333 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
334 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
335 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
336 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
337 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
338 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
339 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
340
341 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
342 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
343 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
344 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
345 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
346 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
347 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
348 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
349
350 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
351 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
352 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
353 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
354 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
355
356 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
357 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
358 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
359 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
360 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
361 {}
362 };
363 static const __u8 mi0360_sensor_init[][8] = {
364 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
365 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
366 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
367 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
368 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
369 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
370 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
371 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
373 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
374 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
375 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
377 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
379 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
380 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
381 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
382 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
383 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
384 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
385 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
386 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
387 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
388 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
389 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
390 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
391 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
392 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
393 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
395 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
396 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
397
398 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
399 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
400 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
401 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
402 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
403
404 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
405 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
406 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
407 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
408
409 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
410 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
411 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
412 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
413 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
414 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
415 {}
416 };
417 static const __u8 mo4000_sensor_init[][8] = {
418 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
422 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
428 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
429 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
434 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
436 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
437 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
438 {}
439 };
440 static __u8 om6802_sensor_init[][8] = {
441 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
442 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
443 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
444 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
445 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
446 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
447 /* white balance & auto-exposure */
448 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
449 * set color mode */
450 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
451 * max AGC value in AE */
452 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
453 * preset AGC */
454 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
455 * preset brightness */
456 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
457 * preset contrast */
458 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
459 * preset gamma */
460 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
461 /* luminance mode (0x4f = AE) */
462 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
463 /* preset shutter */
464 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
465 * auto frame rate */
466 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
467
468 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
469 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
470 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
471 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
472 {}
473 };
474 static const __u8 ov7630_sensor_init[][8] = {
475 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
476 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
477 /* win: delay 20ms */
478 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
479 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
480 /* win: delay 20ms */
481 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
482 /* win: i2c_r from 00 to 80 */
483 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
484 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
485 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
486 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
487 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
488 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
489 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
490 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
491 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
492 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
493 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
494 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
497 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
498 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
499 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
500 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
501 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
502 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
504 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
505 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
506 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
507 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
508 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
509 /* */
510 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
511 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
512 /*fixme: + 0x12, 0x04*/
513 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
514 * set by setvflip */
515 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
516 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
518 /* */
519 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
520 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
521 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
522 /* */
523 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
524 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
525 {}
526 };
527
528 static const __u8 ov7648_sensor_init[][8] = {
529 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
530 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
531 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
532 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
533 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
534 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
535 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
536 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
537 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
538 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
539 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
540 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
541 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
542 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
543 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
544 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
545 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
546 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
547 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
548 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
549 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
550
551 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
552 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
553 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
554 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
555 /*...*/
556 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
557 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
558 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
559 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
560 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
561 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
562 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
563 /*...*/
564 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
565 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
566 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
567 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
568 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
569 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
570
571 {}
572 };
573
574 static const __u8 ov7660_sensor_init[][8] = {
575 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
576 /* (delay 20ms) */
577 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
578 /* Outformat = rawRGB */
579 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
580 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
581 /* GAIN BLUE RED VREF */
582 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
583 /* COM 1 BAVE GEAVE AECHH */
584 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
585 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
586 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
587 /* AECH CLKRC COM7 COM8 */
588 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
589 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
590 /* HSTART HSTOP VSTRT VSTOP */
591 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
592 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
593 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
594 /* BOS GBOS GROS ROS (BGGR offset) */
595 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
596 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
597 /* AEW AEB VPT BBIAS */
598 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
599 /* GbBIAS RSVD EXHCH EXHCL */
600 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
601 /* RBIAS ADVFL ASDVFH YAVE */
602 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
603 /* HSYST HSYEN HREF */
604 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
605 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
606 /* ADC ACOM OFON TSLB */
607 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
608 /* COM11 COM12 COM13 COM14 */
609 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
610 /* EDGE COM15 COM16 COM17 */
611 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
612 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
613 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
614 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
615 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
616 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
617 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
618 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
619 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
620 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
621 /* LCC1 LCC2 LCC3 LCC4 */
622 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
623 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
624 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
625 /* band gap reference [0:3] DBLV */
626 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
627 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
628 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
629 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
630 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
631 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
632 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
633 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
634 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
635 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
636 /****** (some exchanges in the win trace) ******/
637 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
638 /* bits[3..0]reserved */
639 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
640 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
641 /* VREF vertical frame ctrl */
642 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
643 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
644 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
645 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
646 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
647 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
648 /****** (some exchanges in the win trace) ******/
649 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
650 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
651 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
652 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
653 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
654 /****** (some exchanges in the win trace) ******/
655 /******!! startsensor KO if changed !!****/
656 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
657 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
658 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
659 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
660 {}
661 };
662
663 static const __u8 qtable4[] = {
664 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
665 0x06, 0x08, 0x0A, 0x11,
666 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
667 0x19, 0x19, 0x17, 0x15,
668 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
669 0x21, 0x2E, 0x21, 0x23,
670 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
671 0x25, 0x29, 0x2C, 0x29,
672 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
673 0x17, 0x1B, 0x29, 0x29,
674 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
675 0x29, 0x29, 0x29, 0x29,
676 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
677 0x29, 0x29, 0x29, 0x29,
678 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
679 0x29, 0x29, 0x29, 0x29
680 };
681
682 /* read <len> bytes to gspca_dev->usb_buf */
683 static void reg_r(struct gspca_dev *gspca_dev,
684 __u16 value, int len)
685 {
686 #ifdef GSPCA_DEBUG
687 if (len > USB_BUF_SZ) {
688 err("reg_r: buffer overflow");
689 return;
690 }
691 #endif
692 usb_control_msg(gspca_dev->dev,
693 usb_rcvctrlpipe(gspca_dev->dev, 0),
694 0,
695 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
696 value, 0,
697 gspca_dev->usb_buf, len,
698 500);
699 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
700 }
701
702 static void reg_w1(struct gspca_dev *gspca_dev,
703 __u16 value,
704 __u8 data)
705 {
706 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
707 gspca_dev->usb_buf[0] = data;
708 usb_control_msg(gspca_dev->dev,
709 usb_sndctrlpipe(gspca_dev->dev, 0),
710 0x08,
711 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
712 value,
713 0,
714 gspca_dev->usb_buf, 1,
715 500);
716 }
717 static void reg_w(struct gspca_dev *gspca_dev,
718 __u16 value,
719 const __u8 *buffer,
720 int len)
721 {
722 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
723 value, buffer[0], buffer[1]);
724 #ifdef GSPCA_DEBUG
725 if (len > USB_BUF_SZ) {
726 err("reg_w: buffer overflow");
727 return;
728 }
729 #endif
730 memcpy(gspca_dev->usb_buf, buffer, len);
731 usb_control_msg(gspca_dev->dev,
732 usb_sndctrlpipe(gspca_dev->dev, 0),
733 0x08,
734 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
735 value, 0,
736 gspca_dev->usb_buf, len,
737 500);
738 }
739
740 /* I2C write 1 byte */
741 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
742 {
743 struct sd *sd = (struct sd *) gspca_dev;
744
745 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
746 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
747 gspca_dev->usb_buf[1] = sd->i2c_base;
748 gspca_dev->usb_buf[2] = reg;
749 gspca_dev->usb_buf[3] = val;
750 gspca_dev->usb_buf[4] = 0;
751 gspca_dev->usb_buf[5] = 0;
752 gspca_dev->usb_buf[6] = 0;
753 gspca_dev->usb_buf[7] = 0x10;
754 usb_control_msg(gspca_dev->dev,
755 usb_sndctrlpipe(gspca_dev->dev, 0),
756 0x08,
757 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
758 0x08, /* value = i2c */
759 0,
760 gspca_dev->usb_buf, 8,
761 500);
762 }
763
764 /* I2C write 8 bytes */
765 static void i2c_w8(struct gspca_dev *gspca_dev,
766 const __u8 *buffer)
767 {
768 memcpy(gspca_dev->usb_buf, buffer, 8);
769 usb_control_msg(gspca_dev->dev,
770 usb_sndctrlpipe(gspca_dev->dev, 0),
771 0x08,
772 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
773 0x08, 0, /* value, index */
774 gspca_dev->usb_buf, 8,
775 500);
776 msleep(2);
777 }
778
779 /* read 5 bytes in gspca_dev->usb_buf */
780 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
781 {
782 struct sd *sd = (struct sd *) gspca_dev;
783 __u8 mode[8];
784
785 mode[0] = 0x81 | 0x10;
786 mode[1] = sd->i2c_base;
787 mode[2] = reg;
788 mode[3] = 0;
789 mode[4] = 0;
790 mode[5] = 0;
791 mode[6] = 0;
792 mode[7] = 0x10;
793 i2c_w8(gspca_dev, mode);
794 msleep(2);
795 mode[0] = 0x81 | (5 << 4) | 0x02;
796 mode[2] = 0;
797 i2c_w8(gspca_dev, mode);
798 msleep(2);
799 reg_r(gspca_dev, 0x0a, 5);
800 }
801
802 static int probesensor(struct gspca_dev *gspca_dev)
803 {
804 struct sd *sd = (struct sd *) gspca_dev;
805
806 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
807 msleep(10);
808 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
809 msleep(10);
810 i2c_r5(gspca_dev, 0); /* read sensor id */
811 if (gspca_dev->usb_buf[0] == 0x02
812 && gspca_dev->usb_buf[1] == 0x09
813 && gspca_dev->usb_buf[2] == 0x01
814 && gspca_dev->usb_buf[3] == 0x00
815 && gspca_dev->usb_buf[4] == 0x00) {
816 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
817 sd->sensor = SENSOR_HV7131R;
818 return SENSOR_HV7131R;
819 }
820 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
821 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
822 gspca_dev->usb_buf[2]);
823 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
824 return -ENODEV;
825 }
826
827 static int configure_gpio(struct gspca_dev *gspca_dev,
828 const __u8 *sn9c1xx)
829 {
830 struct sd *sd = (struct sd *) gspca_dev;
831 const __u8 *reg9a;
832 static const __u8 reg9a_def[] =
833 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
834 static const __u8 reg9a_sn9c325[] =
835 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
836 static const __u8 regd4[] = {0x60, 0x00, 0x00};
837
838 reg_w1(gspca_dev, 0xf1, 0x00);
839 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
840
841 /* configure gpio */
842 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
843 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
844 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
845 switch (sd->bridge) {
846 case BRIDGE_SN9C325:
847 reg9a = reg9a_sn9c325;
848 break;
849 default:
850 reg9a = reg9a_def;
851 break;
852 }
853 reg_w(gspca_dev, 0x9a, reg9a, 6);
854
855 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
856
857 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
858
859 switch (sd->sensor) {
860 case SENSOR_OM6802:
861 reg_w1(gspca_dev, 0x02, 0x71);
862 reg_w1(gspca_dev, 0x01, 0x42);
863 reg_w1(gspca_dev, 0x17, 0x64);
864 reg_w1(gspca_dev, 0x01, 0x42);
865 break;
866 /*jfm: from win trace */
867 case SENSOR_OV7630:
868 reg_w1(gspca_dev, 0x01, 0x61);
869 reg_w1(gspca_dev, 0x17, 0xe2);
870 reg_w1(gspca_dev, 0x01, 0x60);
871 reg_w1(gspca_dev, 0x01, 0x40);
872 break;
873 case SENSOR_OV7648:
874 reg_w1(gspca_dev, 0x01, 0x63);
875 reg_w1(gspca_dev, 0x17, 0x20);
876 reg_w1(gspca_dev, 0x01, 0x42);
877 break;
878 /*jfm: from win trace */
879 case SENSOR_OV7660:
880 if (sd->bridge == BRIDGE_SN9C120) {
881 reg_w1(gspca_dev, 0x01, 0x61);
882 reg_w1(gspca_dev, 0x17, 0x20);
883 reg_w1(gspca_dev, 0x01, 0x60);
884 reg_w1(gspca_dev, 0x01, 0x40);
885 break;
886 }
887 /* fall thru */
888 default:
889 reg_w1(gspca_dev, 0x01, 0x43);
890 reg_w1(gspca_dev, 0x17, 0x61);
891 reg_w1(gspca_dev, 0x01, 0x42);
892 if (sd->sensor == SENSOR_HV7131R) {
893 if (probesensor(gspca_dev) < 0)
894 return -ENODEV;
895 }
896 break;
897 }
898 return 0;
899 }
900
901 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
902 {
903 int i = 0;
904 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
905 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
906
907 while (hv7131r_sensor_init[i][0]) {
908 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
909 i++;
910 }
911 i2c_w8(gspca_dev, SetSensorClk);
912 }
913
914 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
915 {
916 int i = 0;
917
918 while (mi0360_sensor_init[i][0]) {
919 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
920 i++;
921 }
922 }
923
924 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
925 {
926 int i = 0;
927
928 while (mo4000_sensor_init[i][0]) {
929 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
930 i++;
931 }
932 }
933
934 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
935 {
936 int i = 0;
937
938 while (om6802_sensor_init[i][0]) {
939 i2c_w8(gspca_dev, om6802_sensor_init[i]);
940 i++;
941 }
942 }
943
944 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
945 {
946 int i = 0;
947
948 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
949 i++;
950 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
951 i++;
952 msleep(20);
953 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
954 i++;
955 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
956 i++;
957 msleep(20);
958 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
959 i++;
960 /*jfm:win i2c_r from 00 to 80*/
961
962 while (ov7630_sensor_init[i][0]) {
963 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
964 i++;
965 }
966 }
967
968 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
969 {
970 int i = 0;
971
972 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
973 i++;
974 /* win: dble reset */
975 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
976 i++;
977 msleep(20);
978 /* win: i2c reg read 00..7f */
979 while (ov7648_sensor_init[i][0]) {
980 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
981 i++;
982 }
983 }
984
985 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
986 {
987 int i = 0;
988
989 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
990 i++;
991 msleep(20);
992 while (ov7660_sensor_init[i][0]) {
993 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
994 i++;
995 }
996 }
997
998 /* this function is called at probe time */
999 static int sd_config(struct gspca_dev *gspca_dev,
1000 const struct usb_device_id *id)
1001 {
1002 struct sd *sd = (struct sd *) gspca_dev;
1003 struct cam *cam;
1004
1005 cam = &gspca_dev->cam;
1006 cam->epaddr = 0x01;
1007 cam->cam_mode = vga_mode;
1008 cam->nmodes = ARRAY_SIZE(vga_mode);
1009
1010 sd->bridge = id->driver_info >> 16;
1011 sd->sensor = id->driver_info >> 8;
1012 sd->i2c_base = id->driver_info;
1013
1014 sd->qindex = 4; /* set the quantization table */
1015 sd->brightness = BRIGHTNESS_DEF;
1016 sd->contrast = CONTRAST_DEF;
1017 sd->colors = COLOR_DEF;
1018 sd->blue = BLUE_BALANCE_DEF;
1019 sd->red = RED_BALANCE_DEF;
1020 sd->autogain = AUTOGAIN_DEF;
1021 sd->ag_cnt = -1;
1022 sd->vflip = VFLIP_DEF;
1023 sd->infrared = INFRARED_DEF;
1024
1025 switch (sd->sensor) {
1026 case SENSOR_OV7630:
1027 case SENSOR_OV7648:
1028 case SENSOR_OV7660:
1029 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
1030 break;
1031 }
1032 if (sd->sensor != SENSOR_OV7630)
1033 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
1034 if (sd->sensor != SENSOR_MI0360)
1035 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
1036 return 0;
1037 }
1038
1039 /* this function is called at probe and resume time */
1040 static int sd_init(struct gspca_dev *gspca_dev)
1041 {
1042 struct sd *sd = (struct sd *) gspca_dev;
1043 /* const __u8 *sn9c1xx; */
1044 __u8 regGpio[] = { 0x29, 0x74 };
1045 __u8 regF1;
1046
1047 /* setup a selector by bridge */
1048 reg_w1(gspca_dev, 0xf1, 0x01);
1049 reg_r(gspca_dev, 0x00, 1);
1050 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1051 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1052 regF1 = gspca_dev->usb_buf[0];
1053 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1054 switch (sd->bridge) {
1055 case BRIDGE_SN9C102P:
1056 if (regF1 != 0x11)
1057 return -ENODEV;
1058 reg_w1(gspca_dev, 0x02, regGpio[1]);
1059 break;
1060 case BRIDGE_SN9C105:
1061 if (regF1 != 0x11)
1062 return -ENODEV;
1063 reg_w(gspca_dev, 0x01, regGpio, 2);
1064 break;
1065 case BRIDGE_SN9C120:
1066 if (regF1 != 0x12)
1067 return -ENODEV;
1068 regGpio[1] = 0x70;
1069 reg_w(gspca_dev, 0x01, regGpio, 2);
1070 break;
1071 default:
1072 /* case BRIDGE_SN9C110: */
1073 /* case BRIDGE_SN9C325: */
1074 if (regF1 != 0x12)
1075 return -ENODEV;
1076 reg_w1(gspca_dev, 0x02, 0x62);
1077 break;
1078 }
1079
1080 reg_w1(gspca_dev, 0xf1, 0x01);
1081
1082 return 0;
1083 }
1084
1085 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1086 unsigned int expo)
1087 {
1088 struct sd *sd = (struct sd *) gspca_dev;
1089 static const __u8 doit[] = /* update sensor */
1090 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1091 static const __u8 sensorgo[] = /* sensor on */
1092 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1093 static const __u8 gainMo[] =
1094 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1095
1096 switch (sd->sensor) {
1097 case SENSOR_HV7131R: {
1098 __u8 Expodoit[] =
1099 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1100
1101 Expodoit[3] = expo >> 16;
1102 Expodoit[4] = expo >> 8;
1103 Expodoit[5] = expo;
1104 i2c_w8(gspca_dev, Expodoit);
1105 break;
1106 }
1107 case SENSOR_MI0360: {
1108 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1109 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1110
1111 if (expo > 0x0635)
1112 expo = 0x0635;
1113 else if (expo < 0x0001)
1114 expo = 0x0001;
1115 expoMi[3] = expo >> 8;
1116 expoMi[4] = expo;
1117 i2c_w8(gspca_dev, expoMi);
1118 i2c_w8(gspca_dev, doit);
1119 i2c_w8(gspca_dev, sensorgo);
1120 break;
1121 }
1122 case SENSOR_MO4000: {
1123 __u8 expoMof[] =
1124 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1125 __u8 expoMo10[] =
1126 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1127
1128 if (expo > 0x1fff)
1129 expo = 0x1fff;
1130 else if (expo < 0x0001)
1131 expo = 0x0001;
1132 expoMof[3] = (expo & 0x03fc) >> 2;
1133 i2c_w8(gspca_dev, expoMof);
1134 expoMo10[3] = ((expo & 0x1c00) >> 10)
1135 | ((expo & 0x0003) << 4);
1136 i2c_w8(gspca_dev, expoMo10);
1137 i2c_w8(gspca_dev, gainMo);
1138 PDEBUG(D_CONF, "set exposure %d",
1139 ((expoMo10[3] & 0x07) << 10)
1140 | (expoMof[3] << 2)
1141 | ((expoMo10[3] & 0x30) >> 4));
1142 break;
1143 }
1144 case SENSOR_OM6802: {
1145 __u8 gainOm[] =
1146 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1147
1148 if (expo > 0x03ff)
1149 expo = 0x03ff;
1150 if (expo < 0x0001)
1151 expo = 0x0001;
1152 gainOm[3] = expo >> 2;
1153 i2c_w8(gspca_dev, gainOm);
1154 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1155 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1156 break;
1157 }
1158 }
1159 return expo;
1160 }
1161
1162 static void setbrightness(struct gspca_dev *gspca_dev)
1163 {
1164 struct sd *sd = (struct sd *) gspca_dev;
1165 unsigned int expo;
1166 __u8 k2;
1167
1168 k2 = ((int) sd->brightness - 0x8000) >> 10;
1169 switch (sd->sensor) {
1170 case SENSOR_HV7131R:
1171 expo = sd->brightness << 4;
1172 if (expo > 0x002dc6c0)
1173 expo = 0x002dc6c0;
1174 else if (expo < 0x02a0)
1175 expo = 0x02a0;
1176 sd->exposure = setexposure(gspca_dev, expo);
1177 break;
1178 case SENSOR_MI0360:
1179 case SENSOR_MO4000:
1180 expo = sd->brightness >> 4;
1181 sd->exposure = setexposure(gspca_dev, expo);
1182 break;
1183 case SENSOR_OM6802:
1184 expo = sd->brightness >> 6;
1185 sd->exposure = setexposure(gspca_dev, expo);
1186 k2 = sd->brightness >> 11;
1187 break;
1188 }
1189
1190 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1191 }
1192
1193 static void setcontrast(struct gspca_dev *gspca_dev)
1194 {
1195 struct sd *sd = (struct sd *) gspca_dev;
1196 __u8 k2;
1197 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1198
1199 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1200 contrast[0] = (k2 + 1) / 2; /* red */
1201 contrast[2] = k2; /* green */
1202 contrast[4] = (k2 + 1) / 5; /* blue */
1203 reg_w(gspca_dev, 0x84, contrast, 6);
1204 }
1205
1206 static void setcolors(struct gspca_dev *gspca_dev)
1207 {
1208 struct sd *sd = (struct sd *) gspca_dev;
1209 int i, v;
1210 __u8 rega0[12]; /* U & V gains */
1211 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1212 -24, -38, 64, /* UR UG UB */
1213 62, -51, -9 /* VR VG VB */
1214 };
1215 for (i = 0; i < 6; i++) {
1216 v = uv[i] * sd->colors / COLOR_DEF;
1217 rega0[i * 2] = v;
1218 rega0[i * 2 + 1] = (v >> 8) & 0x0f;
1219 }
1220 reg_w(gspca_dev, 0x84, rega0, sizeof rega0);
1221 }
1222
1223 static void setredblue(struct gspca_dev *gspca_dev)
1224 {
1225 struct sd *sd = (struct sd *) gspca_dev;
1226
1227 reg_w1(gspca_dev, 0x05, sd->red);
1228 /* reg_w1(gspca_dev, 0x07, 32); */
1229 reg_w1(gspca_dev, 0x06, sd->blue);
1230 }
1231
1232 static void setautogain(struct gspca_dev *gspca_dev)
1233 {
1234 struct sd *sd = (struct sd *) gspca_dev;
1235
1236 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1237 return;
1238 if (sd->autogain)
1239 sd->ag_cnt = AG_CNT_START;
1240 else
1241 sd->ag_cnt = -1;
1242 }
1243
1244 static void setvflip(struct sd *sd)
1245 {
1246 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1247 sd->vflip ? 0x82 : 0x02);
1248 }
1249
1250 static void setinfrared(struct sd *sd)
1251 {
1252 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1253 /* Clip */
1254 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1255 sd->infrared ? 0x66 : 0x64);
1256 }
1257
1258 /* -- start the camera -- */
1259 static int sd_start(struct gspca_dev *gspca_dev)
1260 {
1261 struct sd *sd = (struct sd *) gspca_dev;
1262 int i;
1263 __u8 reg1, reg17, reg18;
1264 const __u8 *sn9c1xx;
1265 int mode;
1266 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1267 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1268 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1269 static const __u8 CE_ov76xx[] =
1270 { 0x32, 0xdd, 0x32, 0xdd };
1271
1272 sn9c1xx = sn_tb[(int) sd->sensor];
1273 configure_gpio(gspca_dev, sn9c1xx);
1274
1275 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1276 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1277 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1278 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1279 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1280 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1281 reg_w1(gspca_dev, 0xd3, 0x50);
1282 reg_w1(gspca_dev, 0xc6, 0x00);
1283 reg_w1(gspca_dev, 0xc7, 0x00);
1284 reg_w1(gspca_dev, 0xc8, 0x50);
1285 reg_w1(gspca_dev, 0xc9, 0x3c);
1286 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1287 switch (sd->sensor) {
1288 case SENSOR_OV7630:
1289 reg17 = 0xe2;
1290 break;
1291 case SENSOR_OV7648:
1292 reg17 = 0x20;
1293 break;
1294 /*jfm: from win trace */
1295 case SENSOR_OV7660:
1296 if (sd->bridge == BRIDGE_SN9C120) {
1297 reg17 = 0xa0;
1298 break;
1299 }
1300 /* fall thru */
1301 default:
1302 reg17 = 0x60;
1303 break;
1304 }
1305 reg_w1(gspca_dev, 0x17, reg17);
1306 /* set reg1 was here */
1307 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1308 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1309 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1310 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1311 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1312 for (i = 0; i < 8; i++)
1313 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1314 switch (sd->sensor) {
1315 case SENSOR_OV7648:
1316 reg_w1(gspca_dev, 0x9a, 0x0a);
1317 reg_w1(gspca_dev, 0x99, 0x60);
1318 break;
1319 case SENSOR_OV7660:
1320 if (sd->bridge == BRIDGE_SN9C120) {
1321 reg_w1(gspca_dev, 0x9a, 0x05);
1322 break;
1323 }
1324 /* fall thru */
1325 default:
1326 reg_w1(gspca_dev, 0x9a, 0x08);
1327 reg_w1(gspca_dev, 0x99, 0x59);
1328 break;
1329 }
1330
1331 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1332 if (mode)
1333 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1334 else
1335 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1336 reg17 = 0x61; /* 0x:20: enable sensor clock */
1337 switch (sd->sensor) {
1338 case SENSOR_HV7131R:
1339 hv7131R_InitSensor(gspca_dev);
1340 break;
1341 case SENSOR_MI0360:
1342 mi0360_InitSensor(gspca_dev);
1343 break;
1344 case SENSOR_MO4000:
1345 mo4000_InitSensor(gspca_dev);
1346 if (mode) {
1347 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1348 reg1 = 0x06; /* clk 24Mz */
1349 } else {
1350 reg17 = 0x22; /* 640 MCKSIZE */
1351 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1352 }
1353 break;
1354 case SENSOR_OM6802:
1355 om6802_InitSensor(gspca_dev);
1356 reg17 = 0x64; /* 640 MCKSIZE */
1357 break;
1358 case SENSOR_OV7630:
1359 ov7630_InitSensor(gspca_dev);
1360 setvflip(sd);
1361 reg17 = 0xe2;
1362 reg1 = 0x44;
1363 break;
1364 case SENSOR_OV7648:
1365 ov7648_InitSensor(gspca_dev);
1366 reg17 = 0x21;
1367 /* reg1 = 0x42; * 42 - 46? */
1368 /* if (mode)
1369 ; * 320x2...
1370 else
1371 ; * 640x... */
1372 break;
1373 default:
1374 /* case SENSOR_OV7660: */
1375 ov7660_InitSensor(gspca_dev);
1376 if (mode) {
1377 /* reg17 = 0x21; * 320 */
1378 /* reg1 = 0x44; */
1379 /* reg1 = 0x46; (done) */
1380 } else { /* 640 */
1381 if (sd->bridge == BRIDGE_SN9C120) {
1382 reg17 = 0xa2;
1383 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1384 } else {
1385 reg17 = 0x22;
1386 reg1 = 0x06; /* 24 Mhz, video trf eneble
1387 * inverse power down */
1388 }
1389 }
1390 break;
1391 }
1392 reg_w(gspca_dev, 0xc0, C0, 6);
1393 reg_w(gspca_dev, 0xca, CA, 4);
1394 switch (sd->sensor) {
1395 case SENSOR_OV7630:
1396 case SENSOR_OV7648:
1397 case SENSOR_OV7660:
1398 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1399 break;
1400 default:
1401 reg_w(gspca_dev, 0xce, CE, 4);
1402 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1403 break;
1404 }
1405
1406 /* here change size mode 0 -> VGA; 1 -> CIF */
1407 reg18 = sn9c1xx[0x18] | (mode << 4);
1408 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1409
1410 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1411 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1412
1413 reg_w1(gspca_dev, 0x18, reg18);
1414
1415 reg_w1(gspca_dev, 0x17, reg17);
1416 reg_w1(gspca_dev, 0x01, reg1);
1417 switch (sd->sensor) {
1418 case SENSOR_MI0360:
1419 setinfrared(sd);
1420 break;
1421 case SENSOR_OV7630:
1422 setvflip(sd);
1423 break;
1424 }
1425 setbrightness(gspca_dev);
1426 setcontrast(gspca_dev);
1427 setautogain(gspca_dev);
1428 return 0;
1429 }
1430
1431 static void sd_stopN(struct gspca_dev *gspca_dev)
1432 {
1433 struct sd *sd = (struct sd *) gspca_dev;
1434 static const __u8 stophv7131[] =
1435 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1436 static const __u8 stopmi0360[] =
1437 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1438 static const __u8 stopov7648[] =
1439 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1440 __u8 data;
1441 const __u8 *sn9c1xx;
1442
1443 data = 0x0b;
1444 switch (sd->sensor) {
1445 case SENSOR_HV7131R:
1446 i2c_w8(gspca_dev, stophv7131);
1447 data = 0x2b;
1448 break;
1449 case SENSOR_MI0360:
1450 i2c_w8(gspca_dev, stopmi0360);
1451 data = 0x29;
1452 break;
1453 case SENSOR_OV7648:
1454 i2c_w8(gspca_dev, stopov7648);
1455 /* fall thru */
1456 case SENSOR_OV7630:
1457 data = 0x29;
1458 break;
1459 default:
1460 /* case SENSOR_MO4000: */
1461 /* case SENSOR_OV7660: */
1462 break;
1463 }
1464 sn9c1xx = sn_tb[(int) sd->sensor];
1465 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1466 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1467 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1468 reg_w1(gspca_dev, 0x01, data);
1469 reg_w1(gspca_dev, 0xf1, 0x00);
1470 }
1471
1472 static void do_autogain(struct gspca_dev *gspca_dev)
1473 {
1474 struct sd *sd = (struct sd *) gspca_dev;
1475 int delta;
1476 int expotimes;
1477 __u8 luma_mean = 130;
1478 __u8 luma_delta = 20;
1479
1480 /* Thanks S., without your advice, autobright should not work :) */
1481 if (sd->ag_cnt < 0)
1482 return;
1483 if (--sd->ag_cnt >= 0)
1484 return;
1485 sd->ag_cnt = AG_CNT_START;
1486
1487 delta = atomic_read(&sd->avg_lum);
1488 PDEBUG(D_FRAM, "mean lum %d", delta);
1489 if (delta < luma_mean - luma_delta ||
1490 delta > luma_mean + luma_delta) {
1491 switch (sd->sensor) {
1492 case SENSOR_HV7131R:
1493 expotimes = sd->exposure >> 8;
1494 expotimes += (luma_mean - delta) >> 4;
1495 if (expotimes < 0)
1496 expotimes = 0;
1497 sd->exposure = setexposure(gspca_dev,
1498 (unsigned int) (expotimes << 8));
1499 break;
1500 default:
1501 /* case SENSOR_MO4000: */
1502 /* case SENSOR_MI0360: */
1503 /* case SENSOR_OM6802: */
1504 expotimes = sd->exposure;
1505 expotimes += (luma_mean - delta) >> 6;
1506 if (expotimes < 0)
1507 expotimes = 0;
1508 sd->exposure = setexposure(gspca_dev,
1509 (unsigned int) expotimes);
1510 setredblue(gspca_dev);
1511 break;
1512 }
1513 }
1514 }
1515
1516 /* scan the URB packets */
1517 /* This function is run at interrupt level. */
1518 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1519 struct gspca_frame *frame, /* target */
1520 __u8 *data, /* isoc packet */
1521 int len) /* iso packet length */
1522 {
1523 struct sd *sd = (struct sd *) gspca_dev;
1524 int sof, avg_lum;
1525
1526 sof = len - 64;
1527 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1528
1529 /* end of frame */
1530 gspca_frame_add(gspca_dev, LAST_PACKET,
1531 frame, data, sof + 2);
1532 if (sd->ag_cnt < 0)
1533 return;
1534 /* w1 w2 w3 */
1535 /* w4 w5 w6 */
1536 /* w7 w8 */
1537 /* w4 */
1538 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1539 /* w6 */
1540 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1541 /* w2 */
1542 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1543 /* w8 */
1544 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1545 /* w5 */
1546 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1547 avg_lum >>= 4;
1548 atomic_set(&sd->avg_lum, avg_lum);
1549 return;
1550 }
1551 if (gspca_dev->last_packet_type == LAST_PACKET) {
1552
1553 /* put the JPEG 422 header */
1554 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1555 }
1556 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1557 }
1558
1559 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1560 {
1561 struct sd *sd = (struct sd *) gspca_dev;
1562
1563 sd->brightness = val;
1564 if (gspca_dev->streaming)
1565 setbrightness(gspca_dev);
1566 return 0;
1567 }
1568
1569 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1570 {
1571 struct sd *sd = (struct sd *) gspca_dev;
1572
1573 *val = sd->brightness;
1574 return 0;
1575 }
1576
1577 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1578 {
1579 struct sd *sd = (struct sd *) gspca_dev;
1580
1581 sd->contrast = val;
1582 if (gspca_dev->streaming)
1583 setcontrast(gspca_dev);
1584 return 0;
1585 }
1586
1587 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1588 {
1589 struct sd *sd = (struct sd *) gspca_dev;
1590
1591 *val = sd->contrast;
1592 return 0;
1593 }
1594
1595 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1596 {
1597 struct sd *sd = (struct sd *) gspca_dev;
1598
1599 sd->colors = val;
1600 if (gspca_dev->streaming)
1601 setcolors(gspca_dev);
1602 return 0;
1603 }
1604
1605 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1606 {
1607 struct sd *sd = (struct sd *) gspca_dev;
1608
1609 *val = sd->colors;
1610 return 0;
1611 }
1612
1613 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1614 {
1615 struct sd *sd = (struct sd *) gspca_dev;
1616
1617 sd->blue = val;
1618 if (gspca_dev->streaming)
1619 setredblue(gspca_dev);
1620 return 0;
1621 }
1622
1623 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1624 {
1625 struct sd *sd = (struct sd *) gspca_dev;
1626
1627 *val = sd->blue;
1628 return 0;
1629 }
1630
1631 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1632 {
1633 struct sd *sd = (struct sd *) gspca_dev;
1634
1635 sd->red = val;
1636 if (gspca_dev->streaming)
1637 setredblue(gspca_dev);
1638 return 0;
1639 }
1640
1641 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1642 {
1643 struct sd *sd = (struct sd *) gspca_dev;
1644
1645 *val = sd->red;
1646 return 0;
1647 }
1648
1649 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1650 {
1651 struct sd *sd = (struct sd *) gspca_dev;
1652
1653 sd->autogain = val;
1654 if (gspca_dev->streaming)
1655 setautogain(gspca_dev);
1656 return 0;
1657 }
1658
1659 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1660 {
1661 struct sd *sd = (struct sd *) gspca_dev;
1662
1663 *val = sd->autogain;
1664 return 0;
1665 }
1666
1667 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1668 {
1669 struct sd *sd = (struct sd *) gspca_dev;
1670
1671 sd->vflip = val;
1672 if (gspca_dev->streaming)
1673 setvflip(sd);
1674 return 0;
1675 }
1676
1677 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1678 {
1679 struct sd *sd = (struct sd *) gspca_dev;
1680
1681 *val = sd->vflip;
1682 return 0;
1683 }
1684
1685 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1686 {
1687 struct sd *sd = (struct sd *) gspca_dev;
1688
1689 sd->infrared = val;
1690 if (gspca_dev->streaming)
1691 setinfrared(sd);
1692 return 0;
1693 }
1694
1695 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1696 {
1697 struct sd *sd = (struct sd *) gspca_dev;
1698
1699 *val = sd->infrared;
1700 return 0;
1701 }
1702
1703 /* sub-driver description */
1704 static const struct sd_desc sd_desc = {
1705 .name = MODULE_NAME,
1706 .ctrls = sd_ctrls,
1707 .nctrls = ARRAY_SIZE(sd_ctrls),
1708 .config = sd_config,
1709 .init = sd_init,
1710 .start = sd_start,
1711 .stopN = sd_stopN,
1712 .pkt_scan = sd_pkt_scan,
1713 .dq_callback = do_autogain,
1714 };
1715
1716 /* -- module initialisation -- */
1717 #define BSI(bridge, sensor, i2c_addr) \
1718 .driver_info = (BRIDGE_ ## bridge << 16) \
1719 | (SENSOR_ ## sensor << 8) \
1720 | (i2c_addr)
1721 static const __devinitdata struct usb_device_id device_table[] = {
1722 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1723 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1724 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1725 #endif
1726 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1727 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1728 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1729 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1730 #endif
1731 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1732 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1733 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1734 /* bw600.inf:
1735 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1736 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1737 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1738 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1739 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1740 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1741 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1742 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1743 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1744 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1745 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1746 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1747 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1748 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1749 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1750 #endif
1751 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1752 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1753 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1754 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1755 /*bw600.inf:*/
1756 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1757 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1758 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1759 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1760 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1761 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1762 #endif
1763 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1764 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1765 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1766 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1767 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1768 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1769 #endif
1770 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1771 {}
1772 };
1773 MODULE_DEVICE_TABLE(usb, device_table);
1774
1775 /* -- device connect -- */
1776 static int sd_probe(struct usb_interface *intf,
1777 const struct usb_device_id *id)
1778 {
1779 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1780 THIS_MODULE);
1781 }
1782
1783 static struct usb_driver sd_driver = {
1784 .name = MODULE_NAME,
1785 .id_table = device_table,
1786 .probe = sd_probe,
1787 .disconnect = gspca_disconnect,
1788 #ifdef CONFIG_PM
1789 .suspend = gspca_suspend,
1790 .resume = gspca_resume,
1791 #endif
1792 };
1793
1794 /* -- module insert / remove -- */
1795 static int __init sd_mod_init(void)
1796 {
1797 if (usb_register(&sd_driver) < 0)
1798 return -1;
1799 info("registered");
1800 return 0;
1801 }
1802 static void __exit sd_mod_exit(void)
1803 {
1804 usb_deregister(&sd_driver);
1805 info("deregistered");
1806 }
1807
1808 module_init(sd_mod_init);
1809 module_exit(sd_mod_exit);
This page took 0.075388 seconds and 5 git commands to generate.