V4L/DVB: gspca - sonixj: Add sensor mi0360b
[deliverable/linux.git] / drivers / media / video / gspca / sonixj.c
CommitLineData
6a7eba24 1/*
5b34e3e4 2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
d5aa3856 3 *
27c6f9e5 4 * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
5b34e3e4 5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
6a7eba24
JFM
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
9712a8be 24#include <linux/input.h>
6a7eba24
JFM
25#include "gspca.h"
26#include "jpeg.h"
27
0cae8964
JFM
28#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29
27c6f9e5 30MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
6a7eba24
JFM
31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
37
cebf3b67 38 atomic_t avg_lum;
98819187
JFM
39 u32 exposure;
40
41 u16 brightness;
42 u8 contrast;
43 u8 colors;
44 u8 autogain;
45 u8 blue;
46 u8 red;
592f4eb9 47 u8 gamma;
2797ba2a 48 u8 vflip; /* ov7630/ov7648 only */
878b35ae 49 u8 sharpness;
3ef2c5be 50 u8 infrared; /* mt9v111 only */
37c6dbe2 51 u8 freq; /* ov76xx only */
71cb2764 52 u8 quality; /* image quality */
77ac0baf
JFM
53#define QUALITY_MIN 60
54#define QUALITY_MAX 95
55#define QUALITY_DEF 80
71cb2764
JFM
56 u8 jpegqual; /* webcam quality */
57
58 u8 reg18;
6a7eba24 59
98819187 60 s8 ag_cnt;
6a7eba24
JFM
61#define AG_CNT_START 13
62
98819187 63 u8 bridge;
3647fea8
HG
64#define BRIDGE_SN9C102P 0
65#define BRIDGE_SN9C105 1
66#define BRIDGE_SN9C110 2
67#define BRIDGE_SN9C120 3
98819187 68 u8 sensor; /* Type of image sensor chip */
11ce884a
JFM
69 u8 i2c_addr;
70
71 u8 jpeg_hdr[JPEG_HDR_SZ];
72};
73enum sensors {
9c33afc6 74 SENSOR_ADCM1700,
ad98c0f6 75 SENSOR_GC0307,
9c33afc6
JFM
76 SENSOR_HV7131R,
77 SENSOR_MI0360,
a067db84 78 SENSOR_MI0360B,
9c33afc6
JFM
79 SENSOR_MO4000,
80 SENSOR_MT9V111,
81 SENSOR_OM6802,
82 SENSOR_OV7630,
83 SENSOR_OV7648,
84 SENSOR_OV7660,
85 SENSOR_PO1030,
ad98c0f6 86 SENSOR_PO2030N,
03ed2a11 87 SENSOR_SOI768,
9c33afc6 88 SENSOR_SP80708,
6a7eba24
JFM
89};
90
91/* V4L2 controls supported by the driver */
92static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
94static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
96static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
97static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
403123d2
JFM
98static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
99static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
100static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
101static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
592f4eb9
JFM
102static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
103static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
6a7eba24
JFM
104static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
105static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
6c86274f
JFM
106static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
107static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
878b35ae
JFM
108static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
109static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
0cae8964
JFM
110static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
111static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
37c6dbe2
HG
112static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
113static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
6a7eba24 114
7e64dc4c 115static const struct ctrl sd_ctrls[] = {
9764398b 116#define BRIGHTNESS_IDX 0
6a7eba24
JFM
117 {
118 {
119 .id = V4L2_CID_BRIGHTNESS,
120 .type = V4L2_CTRL_TYPE_INTEGER,
121 .name = "Brightness",
122 .minimum = 0,
05b809c7
JFM
123#define BRIGHTNESS_MAX 0xffff
124 .maximum = BRIGHTNESS_MAX,
6a7eba24 125 .step = 1,
b1b056a5 126#define BRIGHTNESS_DEF 0x8000
a5ae2062 127 .default_value = BRIGHTNESS_DEF,
6a7eba24
JFM
128 },
129 .set = sd_setbrightness,
130 .get = sd_getbrightness,
131 },
9764398b 132#define CONTRAST_IDX 1
6a7eba24
JFM
133 {
134 {
135 .id = V4L2_CID_CONTRAST,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Contrast",
138 .minimum = 0,
05b809c7
JFM
139#define CONTRAST_MAX 127
140 .maximum = CONTRAST_MAX,
6a7eba24 141 .step = 1,
a5ae2062
JFM
142#define CONTRAST_DEF 63
143 .default_value = CONTRAST_DEF,
6a7eba24
JFM
144 },
145 .set = sd_setcontrast,
146 .get = sd_getcontrast,
147 },
9764398b 148#define COLOR_IDX 2
6a7eba24
JFM
149 {
150 {
151 .id = V4L2_CID_SATURATION,
152 .type = V4L2_CTRL_TYPE_INTEGER,
3fb4a57b 153 .name = "Saturation",
6a7eba24 154 .minimum = 0,
403123d2 155 .maximum = 40,
6a7eba24 156 .step = 1,
3fb4a57b 157#define COLOR_DEF 25
a5ae2062 158 .default_value = COLOR_DEF,
6a7eba24
JFM
159 },
160 .set = sd_setcolors,
161 .get = sd_getcolors,
162 },
9764398b 163#define BLUE_BALANCE_IDX 3
403123d2
JFM
164 {
165 {
166 .id = V4L2_CID_BLUE_BALANCE,
167 .type = V4L2_CTRL_TYPE_INTEGER,
168 .name = "Blue Balance",
169 .minimum = 24,
170 .maximum = 40,
171 .step = 1,
172#define BLUE_BALANCE_DEF 32
173 .default_value = BLUE_BALANCE_DEF,
174 },
175 .set = sd_setblue_balance,
176 .get = sd_getblue_balance,
177 },
9764398b 178#define RED_BALANCE_IDX 4
403123d2
JFM
179 {
180 {
181 .id = V4L2_CID_RED_BALANCE,
182 .type = V4L2_CTRL_TYPE_INTEGER,
183 .name = "Red Balance",
184 .minimum = 24,
185 .maximum = 40,
186 .step = 1,
187#define RED_BALANCE_DEF 32
188 .default_value = RED_BALANCE_DEF,
189 },
190 .set = sd_setred_balance,
191 .get = sd_getred_balance,
192 },
9764398b 193#define GAMMA_IDX 5
592f4eb9
JFM
194 {
195 {
196 .id = V4L2_CID_GAMMA,
197 .type = V4L2_CTRL_TYPE_INTEGER,
198 .name = "Gamma",
199 .minimum = 0,
200 .maximum = 40,
201 .step = 1,
202#define GAMMA_DEF 20
203 .default_value = GAMMA_DEF,
204 },
205 .set = sd_setgamma,
206 .get = sd_getgamma,
207 },
9764398b 208#define AUTOGAIN_IDX 6
6a7eba24
JFM
209 {
210 {
211 .id = V4L2_CID_AUTOGAIN,
212 .type = V4L2_CTRL_TYPE_BOOLEAN,
213 .name = "Auto Gain",
214 .minimum = 0,
215 .maximum = 1,
216 .step = 1,
a5ae2062
JFM
217#define AUTOGAIN_DEF 1
218 .default_value = AUTOGAIN_DEF,
6a7eba24
JFM
219 },
220 .set = sd_setautogain,
221 .get = sd_getautogain,
222 },
2797ba2a 223/* ov7630/ov7648 only */
9764398b 224#define VFLIP_IDX 7
6c86274f
JFM
225 {
226 {
227 .id = V4L2_CID_VFLIP,
228 .type = V4L2_CTRL_TYPE_BOOLEAN,
229 .name = "Vflip",
230 .minimum = 0,
231 .maximum = 1,
232 .step = 1,
f800952c 233#define VFLIP_DEF 0
6c86274f
JFM
234 .default_value = VFLIP_DEF,
235 },
236 .set = sd_setvflip,
237 .get = sd_getvflip,
238 },
878b35ae
JFM
239#define SHARPNESS_IDX 8
240 {
241 {
242 .id = V4L2_CID_SHARPNESS,
243 .type = V4L2_CTRL_TYPE_INTEGER,
244 .name = "Sharpness",
245 .minimum = 0,
246 .maximum = 255,
247 .step = 1,
248#define SHARPNESS_DEF 90
249 .default_value = SHARPNESS_DEF,
250 },
251 .set = sd_setsharpness,
252 .get = sd_getsharpness,
253 },
3ef2c5be 254/* mt9v111 only */
878b35ae 255#define INFRARED_IDX 9
0cae8964
JFM
256 {
257 {
258 .id = V4L2_CID_INFRARED,
259 .type = V4L2_CTRL_TYPE_BOOLEAN,
260 .name = "Infrared",
261 .minimum = 0,
262 .maximum = 1,
263 .step = 1,
264#define INFRARED_DEF 0
265 .default_value = INFRARED_DEF,
266 },
267 .set = sd_setinfrared,
268 .get = sd_getinfrared,
269 },
37c6dbe2 270/* ov7630/ov7648/ov7660 only */
878b35ae 271#define FREQ_IDX 10
37c6dbe2
HG
272 {
273 {
274 .id = V4L2_CID_POWER_LINE_FREQUENCY,
275 .type = V4L2_CTRL_TYPE_MENU,
276 .name = "Light frequency filter",
277 .minimum = 0,
278 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
279 .step = 1,
b8c8a5bf 280#define FREQ_DEF 1
37c6dbe2
HG
281 .default_value = FREQ_DEF,
282 },
283 .set = sd_setfreq,
284 .get = sd_getfreq,
285 },
6a7eba24
JFM
286};
287
577cbf49 288/* table of the disabled controls */
9c33afc6
JFM
289static const __u32 ctrl_dis[] = {
290[SENSOR_ADCM1700] = (1 << AUTOGAIN_IDX) |
291 (1 << INFRARED_IDX) |
292 (1 << VFLIP_IDX) |
293 (1 << FREQ_IDX),
294
c26b12d0 295[SENSOR_GC0307] = (1 << INFRARED_IDX) |
ad98c0f6
JFM
296 (1 << VFLIP_IDX) |
297 (1 << FREQ_IDX),
298
9c33afc6
JFM
299[SENSOR_HV7131R] = (1 << INFRARED_IDX) |
300 (1 << FREQ_IDX),
301
302[SENSOR_MI0360] = (1 << INFRARED_IDX) |
303 (1 << VFLIP_IDX) |
304 (1 << FREQ_IDX),
305
a067db84
JFM
306[SENSOR_MI0360B] = (1 << INFRARED_IDX) |
307 (1 << VFLIP_IDX) |
308 (1 << FREQ_IDX),
309
9c33afc6
JFM
310[SENSOR_MO4000] = (1 << INFRARED_IDX) |
311 (1 << VFLIP_IDX) |
312 (1 << FREQ_IDX),
313
314[SENSOR_MT9V111] = (1 << VFLIP_IDX) |
315 (1 << FREQ_IDX),
316
317[SENSOR_OM6802] = (1 << INFRARED_IDX) |
318 (1 << VFLIP_IDX) |
319 (1 << FREQ_IDX),
320
321[SENSOR_OV7630] = (1 << INFRARED_IDX),
322
323[SENSOR_OV7648] = (1 << INFRARED_IDX),
324
325[SENSOR_OV7660] = (1 << AUTOGAIN_IDX) |
326 (1 << INFRARED_IDX) |
327 (1 << VFLIP_IDX),
328
329[SENSOR_PO1030] = (1 << AUTOGAIN_IDX) |
330 (1 << INFRARED_IDX) |
331 (1 << VFLIP_IDX) |
332 (1 << FREQ_IDX),
333
ad98c0f6
JFM
334[SENSOR_PO2030N] = (1 << AUTOGAIN_IDX) |
335 (1 << INFRARED_IDX) |
336 (1 << VFLIP_IDX) |
337 (1 << FREQ_IDX),
03ed2a11
JFM
338[SENSOR_SOI768] = (1 << AUTOGAIN_IDX) |
339 (1 << INFRARED_IDX) |
340 (1 << VFLIP_IDX) |
341 (1 << FREQ_IDX),
ad98c0f6 342
9c33afc6
JFM
343[SENSOR_SP80708] = (1 << AUTOGAIN_IDX) |
344 (1 << INFRARED_IDX) |
345 (1 << VFLIP_IDX) |
346 (1 << FREQ_IDX),
577cbf49
JFM
347};
348
64677573
JFM
349static const struct v4l2_pix_format cif_mode[] = {
350 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
351 .bytesperline = 352,
352 .sizeimage = 352 * 288 * 4 / 8 + 590,
353 .colorspace = V4L2_COLORSPACE_JPEG,
354 .priv = 0},
355};
cc611b8a 356static const struct v4l2_pix_format vga_mode[] = {
c2446b3e
JFM
357 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
358 .bytesperline = 160,
5d05294a 359 .sizeimage = 160 * 120 * 4 / 8 + 590,
c2446b3e
JFM
360 .colorspace = V4L2_COLORSPACE_JPEG,
361 .priv = 2},
362 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
363 .bytesperline = 320,
364 .sizeimage = 320 * 240 * 3 / 8 + 590,
365 .colorspace = V4L2_COLORSPACE_JPEG,
366 .priv = 1},
367 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
368 .bytesperline = 640,
a5d1cc39
HG
369 /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
370 .sizeimage = 640 * 480 * 3 / 4 + 590,
c2446b3e
JFM
371 .colorspace = V4L2_COLORSPACE_JPEG,
372 .priv = 0},
6a7eba24
JFM
373};
374
64677573
JFM
375static const u8 sn_adcm1700[0x1c] = {
376/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
878b35ae 377 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
64677573
JFM
378/* reg8 reg9 rega regb regc regd rege regf */
379 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
380/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
381 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
382/* reg18 reg19 reg1a reg1b */
383 0x06, 0x00, 0x00, 0x00
384};
385
ad98c0f6
JFM
386static const u8 sn_gc0307[0x1c] = {
387/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
388 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
389/* reg8 reg9 rega regb regc regd rege regf */
390 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
391/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
392 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
393/* reg18 reg19 reg1a reg1b */
394 0x06, 0x00, 0x00, 0x00
395};
396
8c2ba441 397static const u8 sn_hv7131[0x1c] = {
8f47a3ce 398/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
19697b54 399 0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
8f47a3ce 400/* reg8 reg9 rega regb regc regd rege regf */
98941e4d 401 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8f47a3ce
JFM
402/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
403 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
8c2ba441
JFM
404/* reg18 reg19 reg1a reg1b */
405 0x0a, 0x00, 0x00, 0x00
6a7eba24
JFM
406};
407
8c2ba441 408static const u8 sn_mi0360[0x1c] = {
8f47a3ce 409/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
19697b54 410 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
8f47a3ce 411/* reg8 reg9 rega regb regc regd rege regf */
98941e4d 412 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8f47a3ce
JFM
413/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
414 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
8c2ba441
JFM
415/* reg18 reg19 reg1a reg1b */
416 0x06, 0x00, 0x00, 0x00
6a7eba24
JFM
417};
418
a067db84
JFM
419static const u8 sn_mi0360b[0x1c] = {
420/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
421 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
422/* reg8 reg9 rega regb regc regd rege regf */
423 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
424/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
425 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40,
426/* reg18 reg19 reg1a reg1b */
427 0x06, 0x00, 0x00, 0x00
428};
429
8c2ba441 430static const u8 sn_mo4000[0x1c] = {
8f47a3ce 431/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
8c2ba441 432 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
8f47a3ce
JFM
433/* reg8 reg9 rega regb regc regd rege regf */
434 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
435/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
436 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
8c2ba441
JFM
437/* reg18 reg19 reg1a reg1b */
438 0x08, 0x00, 0x00, 0x00
6a7eba24
JFM
439};
440
3ef2c5be
JFM
441static const u8 sn_mt9v111[0x1c] = {
442/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
443 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
444/* reg8 reg9 rega regb regc regd rege regf */
98941e4d 445 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
3ef2c5be
JFM
446/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
447 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
448/* reg18 reg19 reg1a reg1b */
449 0x06, 0x00, 0x00, 0x00
450};
451
8c2ba441 452static const u8 sn_om6802[0x1c] = {
d2d16e90 453/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
46b4f2ab 454 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
d2d16e90
JFM
455/* reg8 reg9 rega regb regc regd rege regf */
456 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
457/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
458 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
8c2ba441
JFM
459/* reg18 reg19 reg1a reg1b */
460 0x05, 0x00, 0x00, 0x00
d2d16e90
JFM
461};
462
8c2ba441 463static const u8 sn_ov7630[0x1c] = {
6ab0b174 464/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
0a85c74b 465 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
6ab0b174 466/* reg8 reg9 rega regb regc regd rege regf */
98941e4d 467 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
6ab0b174
JFM
468/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
469 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
8c2ba441
JFM
470/* reg18 reg19 reg1a reg1b */
471 0x0b, 0x00, 0x00, 0x00
6ab0b174
JFM
472};
473
8c2ba441 474static const u8 sn_ov7648[0x1c] = {
8f47a3ce 475/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
6270330a 476 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
8f47a3ce 477/* reg8 reg9 rega regb regc regd rege regf */
98941e4d 478 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8f47a3ce 479/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
6270330a 480 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
8c2ba441
JFM
481/* reg18 reg19 reg1a reg1b */
482 0x0b, 0x00, 0x00, 0x00
6a7eba24
JFM
483};
484
8c2ba441 485static const u8 sn_ov7660[0x1c] = {
8f47a3ce 486/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
c8b9b2ca 487 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
8f47a3ce 488/* reg8 reg9 rega regb regc regd rege regf */
c8b9b2ca 489 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
8f47a3ce
JFM
490/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
491 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
8c2ba441
JFM
492/* reg18 reg19 reg1a reg1b */
493 0x07, 0x00, 0x00, 0x00
6a7eba24
JFM
494};
495
b8c8a5bf
JFM
496static const u8 sn_po1030[0x1c] = {
497/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
498 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
499/* reg8 reg9 rega regb regc regd rege regf */
500 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
501/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
502 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
503/* reg18 reg19 reg1a reg1b */
504 0x07, 0x00, 0x00, 0x00
505};
506
ad98c0f6
JFM
507static const u8 sn_po2030n[0x1c] = {
508/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
509 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
510/* reg8 reg9 rega regb regc regd rege regf */
511 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
512/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
513 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
514/* reg18 reg19 reg1a reg1b */
515 0x07, 0x00, 0x00, 0x00
516};
517
03ed2a11
JFM
518static const u8 sn_soi768[0x1c] = {
519/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
520 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
521/* reg8 reg9 rega regb regc regd rege regf */
522 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
523/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
524 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
525/* reg18 reg19 reg1a reg1b */
526 0x07, 0x00, 0x00, 0x00
527};
528
5e31dc8d
JFM
529static const u8 sn_sp80708[0x1c] = {
530/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
531 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
532/* reg8 reg9 rega regb regc regd rege regf */
98941e4d 533 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
5e31dc8d
JFM
534/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
535 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
536/* reg18 reg19 reg1a reg1b */
537 0x07, 0x00, 0x00, 0x00
538};
539
6a7eba24 540/* sequence specific to the sensors - !! index = SENSOR_xxx */
8c2ba441 541static const u8 *sn_tb[] = {
9c33afc6 542[SENSOR_ADCM1700] = sn_adcm1700,
ad98c0f6 543[SENSOR_GC0307] = sn_gc0307,
9c33afc6
JFM
544[SENSOR_HV7131R] = sn_hv7131,
545[SENSOR_MI0360] = sn_mi0360,
a067db84 546[SENSOR_MI0360B] = sn_mi0360b,
9c33afc6
JFM
547[SENSOR_MO4000] = sn_mo4000,
548[SENSOR_MT9V111] = sn_mt9v111,
549[SENSOR_OM6802] = sn_om6802,
550[SENSOR_OV7630] = sn_ov7630,
551[SENSOR_OV7648] = sn_ov7648,
552[SENSOR_OV7660] = sn_ov7660,
553[SENSOR_PO1030] = sn_po1030,
ad98c0f6 554[SENSOR_PO2030N] = sn_po2030n,
03ed2a11
JFM
555[SENSOR_SOI768] = sn_soi768,
556[SENSOR_SP80708] = sn_sp80708,
6a7eba24
JFM
557};
558
b083b92f 559/* default gamma table */
98819187 560static const u8 gamma_def[17] = {
6a7eba24
JFM
561 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
562 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
563};
64677573
JFM
564/* gamma for sensor ADCM1700 */
565static const u8 gamma_spec_0[17] = {
566 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
567 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
568};
b083b92f
JFM
569/* gamma for sensors HV7131R and MT9V111 */
570static const u8 gamma_spec_1[17] = {
571 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
572 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
573};
ad98c0f6 574/* gamma for sensor GC0307 */
b083b92f 575static const u8 gamma_spec_2[17] = {
ad98c0f6
JFM
576 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
577 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
578};
579/* gamma for sensor SP80708 */
580static const u8 gamma_spec_3[17] = {
b083b92f
JFM
581 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
582 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
583};
592f4eb9 584
803f9ccf 585/* color matrix and offsets */
98819187 586static const u8 reg84[] = {
803f9ccf
JFM
587 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
588 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
589 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
590 0x00, 0x00, 0x00 /* YUV offsets */
6a7eba24 591};
64677573
JFM
592static const u8 adcm1700_sensor_init[][8] = {
593 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
878b35ae 594 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
64677573
JFM
595 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
596 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
597 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
598 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
599 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
600 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
601 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
602 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
603 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
604 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
605 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
606 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
607 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
608 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
609 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
610 {}
611};
612static const u8 adcm1700_sensor_param1[][8] = {
878b35ae 613 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
64677573
JFM
614 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
615
616 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
617 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
618 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
619 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
878b35ae 620 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
64677573 621
878b35ae
JFM
622 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
623 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
624 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
625 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
64677573
JFM
626 {}
627};
ad98c0f6
JFM
628static const u8 gc0307_sensor_init[][8] = {
629 {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
630 {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
631 {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
632 {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
633 {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
634 {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
636 {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
637 {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
638 {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
639 {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
640 {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
641 {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
642 {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
643 {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
644 {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
645 {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
646 {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
647 {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
648 {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
649 {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
650 {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
651 {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
652 {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
653 {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
654 {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
655 {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
656 {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
657 {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
658 {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
659 {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
660 {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
661 {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
662 {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
663 {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
664 {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
665 {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
666 {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
667 {}
668};
669static const u8 gc0307_sensor_param1[][8] = {
670 {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
671 {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
672 {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
673 {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
674/*param3*/
675 {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
676 {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
ad98c0f6
JFM
677 {}
678};
679
98819187 680static const u8 hv7131r_sensor_init[][8] = {
8c2ba441
JFM
681 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
682 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
683 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
684/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
685 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
686 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
687/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
688
689 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
690 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
691 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
692 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
693 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
694 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
695 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
696 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
697
698 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
699 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
7fb101ae 700 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
8c2ba441
JFM
701 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
702 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
703
704 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
705 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
706 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
707 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
708 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
23a98274
JFM
709 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
710 /* set sensor clock */
a5ae2062 711 {}
6a7eba24 712};
98819187 713static const u8 mi0360_sensor_init[][8] = {
8c2ba441 714 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
98819187 715 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
3ef2c5be 716 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
8c2ba441
JFM
717 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
718 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
719 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
720 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
721 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
722 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
723 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
724 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
725 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
726 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
727 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
728 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
729 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
730 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
731 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
732 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
733 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
734 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
735 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
98819187 736 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
8c2ba441
JFM
737 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
738 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
739 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
740 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
741 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
742 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
743 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
744 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
745 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
746 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
747
748 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
749 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
750 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
751 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
752 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
753
754 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
755 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
756 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
757 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
758
759 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
760 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
761/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
762/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
763 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
764 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
a5ae2062 765 {}
6a7eba24 766};
a067db84
JFM
767static const u8 mi0360b_sensor_init[][8] = {
768 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
769 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
770 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
771 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
772 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
773 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
774 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
775 {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
776 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
777 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
778 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
779 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
780 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
781 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
782 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
783 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
784 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
785 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
786 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
787 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
788 {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
789 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
790 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
791 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
792 {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
793 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
794 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
795 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
796 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
797 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
798 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
799 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
800 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
801 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
802 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
803
804 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
805 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
806 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
807 {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
808 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
809 {}
810};
811static const u8 mi0360b_sensor_param1[][8] = {
812 {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
813 {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
814 {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
815 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
816
817 {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
818 {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
819 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
820 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
821 {}
822};
98819187 823static const u8 mo4000_sensor_init[][8] = {
6a7eba24
JFM
824 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
a5ae2062 844 {}
6a7eba24 845};
3ef2c5be
JFM
846static const u8 mt9v111_sensor_init[][8] = {
847 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
23a98274 848 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
3ef2c5be
JFM
849 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
850 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
851 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
852 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
2687a2fb
JFM
853 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
854 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
855 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
856 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
3ef2c5be 857 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
2687a2fb
JFM
858 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
859 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
860 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
861 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
862 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
3ef2c5be 863 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
2687a2fb 864 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
3ef2c5be
JFM
865 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
866 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
867 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
868 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
869 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
870 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
871 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
872 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
873 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
874 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
3fccb774
JFM
875 {}
876};
877static const u8 mt9v111_sensor_param1[][8] = {
3ef2c5be
JFM
878 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
879 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
2687a2fb 880 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
3ef2c5be
JFM
881 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
882 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
883 /*******/
884 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
885 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
886 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
887 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
888 {}
889};
3fccb774
JFM
890static const u8 om6802_init0[2][8] = {
891/*fixme: variable*/
892 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
893 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
894};
98819187 895static const u8 om6802_sensor_init[][8] = {
3fccb774
JFM
896 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
897 /* factory mode */
d2d16e90 898 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
d5aa3856 899 /* output raw RGB */
3fccb774 900 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
d2d16e90
JFM
901/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
902 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
d5aa3856 903 /* auto-exposure speed (0) / white balance mode (auto RGB) */
d2d16e90
JFM
904/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
905 * set color mode */
906/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
907 * max AGC value in AE */
908/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
909 * preset AGC */
910/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
911 * preset brightness */
912/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
913 * preset contrast */
914/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
915 * preset gamma */
916 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
d5aa3856 917 /* luminance mode (0x4f -> AutoExpo on) */
d2d16e90
JFM
918 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
919 /* preset shutter */
920/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
921 * auto frame rate */
922/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
3fccb774
JFM
923 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
924 {}
925};
926static const u8 om6802_sensor_param1[][8] = {
927 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
928 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
929 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
930 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
d2d16e90
JFM
931 {}
932};
98819187 933static const u8 ov7630_sensor_init[][8] = {
6ab0b174
JFM
934 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
935 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
23a98274 936 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
6ab0b174
JFM
937 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
938 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
23a98274 939 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
6ab0b174 940 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
05b809c7 941/* win: i2c_r from 00 to 80 */
6ab0b174
JFM
942 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
943 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
cc7b5b57
HG
944/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
945 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
946 {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
6ab0b174
JFM
947 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
948 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
949 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
950 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
951 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
952 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
953 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
954 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
955 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
956 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
957 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
958 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
959 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
960 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
961 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
962 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
963 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
964 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
965 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
966 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
967 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
968 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
969 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
bdd2b93c
JFM
970 {}
971};
972static const u8 ov7630_sensor_param1[][8] = {
6ab0b174
JFM
973 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
974 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
975/*fixme: + 0x12, 0x04*/
6c86274f
JFM
976/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
977 * set by setvflip */
6ab0b174
JFM
978 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
979 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
980 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
05b809c7 981/* */
37c6dbe2
HG
982/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
983/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
05b809c7 984/* */
6ab0b174 985 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
91de65ac 986/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
6ab0b174
JFM
987 {}
988};
6270330a 989
98819187 990static const u8 ov7648_sensor_init[][8] = {
6270330a
JFM
991 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
992 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
23a98274 993 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
6270330a
JFM
994 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
995 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
996 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
997 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
998 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
999 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
1000 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
1001 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
1002 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
1003 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
1004 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
1005 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
1006 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
1007 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
1008 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
1009 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
1010 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
1011 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
1012 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
1013
1014 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
1015/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
1016/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
37c6dbe2 1017/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
3fccb774
JFM
1018 {}
1019};
1020static const u8 ov7648_sensor_param1[][8] = {
6270330a 1021/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
2797ba2a
JFM
1022/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
1023 * set by setvflip */
6270330a
JFM
1024 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
1025 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
1026/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1027/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
1028/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
1029/*...*/
1030 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
1031/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1032/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1033/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
1034/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1035/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
1036
1037 {}
1038};
1039
98819187 1040static const u8 ov7660_sensor_init[][8] = {
6a7eba24 1041 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
23a98274 1042 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
6a7eba24 1043 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
738608ae 1044 /* Outformat = rawRGB */
6a7eba24 1045 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
d8f400ef 1046 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
6a7eba24
JFM
1047 /* GAIN BLUE RED VREF */
1048 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
1049 /* COM 1 BAVE GEAVE AECHH */
1050 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
1051 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
47f7f6fb 1052 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
6a7eba24
JFM
1053 /* AECH CLKRC COM7 COM8 */
1054 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
1055 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
1056 /* HSTART HSTOP VSTRT VSTOP */
1057 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
1058 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
1059 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
1060 /* BOS GBOS GROS ROS (BGGR offset) */
738608ae
JFM
1061/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
1062 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
6a7eba24
JFM
1063 /* AEW AEB VPT BBIAS */
1064 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
1065 /* GbBIAS RSVD EXHCH EXHCL */
1066 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
1067 /* RBIAS ADVFL ASDVFH YAVE */
1068 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
1069 /* HSYST HSYEN HREF */
1070 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1071 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1072 /* ADC ACOM OFON TSLB */
1073 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1074 /* COM11 COM12 COM13 COM14 */
1075 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1076 /* EDGE COM15 COM16 COM17 */
1077 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1078 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1079 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1080 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1081 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1082 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1083 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1084 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1085 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1086 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1087 /* LCC1 LCC2 LCC3 LCC4 */
1088 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
738608ae 1089 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
6a7eba24 1090 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
738608ae 1091 /* band gap reference [0:3] DBLV */
6a7eba24
JFM
1092 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1093 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1094 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1095 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1096 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1097 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1098 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1099 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1100 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
738608ae 1101 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
3fccb774 1102/* not in all ms-win traces*/
47f7f6fb 1103 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
3fccb774
JFM
1104 {}
1105};
1106static const u8 ov7660_sensor_param1[][8] = {
738608ae 1107 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
6a7eba24
JFM
1108 /* bits[3..0]reserved */
1109 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1110 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1111 /* VREF vertical frame ctrl */
1112 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
738608ae
JFM
1113 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1114 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1115 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1116 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1117/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
6a7eba24 1118/****** (some exchanges in the win trace) ******/
3fccb774 1119/*fixme:param2*/
6a7eba24 1120 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
738608ae
JFM
1121 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1122 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1123 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1124/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
6a7eba24 1125/****** (some exchanges in the win trace) ******/
738608ae 1126/******!! startsensor KO if changed !!****/
3fccb774 1127/*fixme: param3*/
6a7eba24
JFM
1128 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1129 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1130 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1131 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
a5ae2062 1132 {}
6a7eba24 1133};
6a7eba24 1134
b8c8a5bf
JFM
1135static const u8 po1030_sensor_init[][8] = {
1136/* the sensor registers are described in m5602/m5602_po1030.h */
1137 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
1138 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
1139 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1140 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1141 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1142 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1143 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1144 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1145 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1146 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1147 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1148 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1149 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1150 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1151 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1152 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1153 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1154 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1155 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1156 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1157 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1158 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1159 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1160 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1161 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1162 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1163 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1164 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1165
1166 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1167 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1168 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1169 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1170 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1171 {}
1172};
1173static const u8 po1030_sensor_param1[][8] = {
1174/* from ms-win traces - these values change with auto gain/expo/wb.. */
1175 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1176 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1177/* mean values */
1178 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1179 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1180 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1181
1182 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1183 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1184 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1185/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1186 {}
1187};
1188
ad98c0f6
JFM
1189static const u8 po2030n_sensor_init[][8] = {
1190 {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1191 {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
1192 {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1193 {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1194 {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
1195 {0xdd, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
1196 {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1197 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1198 {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1199 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1200 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1201 {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1202 {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1203 {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1204 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1205 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1206 {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1207 {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1208 {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1209 {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1210 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1211 {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1212 {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1213 {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1214 {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1215 {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1216 {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1217 {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1218 {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1219 {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1220 {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1221 {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1222 {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1223 {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1224 {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1225 {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1226 {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1227 {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1228 {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1229 {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1230 {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1231 {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1232 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1233 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1234 {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1235 {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1236 {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1237 {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1238 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1239 {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1240 {}
1241};
1242static const u8 po2030n_sensor_param1[][8] = {
1243 {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
1244 {0xdd, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
1245 {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1246 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1247 {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1248/*param2*/
1249 {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1250 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1251 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1252 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1253 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1254 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1255 {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1256/*after start*/
1257 {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
1258 {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1259 {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
1260 {0xdd, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
1261 {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1262 {}
1263};
1264
03ed2a11
JFM
1265static const u8 soi768_sensor_init[][8] = {
1266 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
1267 {0xdd, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
1268 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1269 {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1270 {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1271 {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1272 {}
1273};
1274static const u8 soi768_sensor_param1[][8] = {
1275 {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1276 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1277 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1278 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1279 {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1280/* */
1281/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1282/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1283 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1284/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1285 {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1286/* the next sequence should be used for auto gain */
1287 {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1288 /* global gain ? : 07 - change with 0x15 at the end */
1289 {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1290 {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1291 {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1292 /* exposure ? : 0200 - change with 0x1e at the end */
1293 {}
1294};
1295
5e31dc8d
JFM
1296static const u8 sp80708_sensor_init[][8] = {
1297 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1298 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1299 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1300 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1301 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1302 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1303 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1304 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1305 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1306 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1307 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1308 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1309 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1310 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1311 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1312 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1313 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1314 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1315 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1316 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1317 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1318 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1319 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1320 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1321 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1322 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1323 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1324 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1325 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1326 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1327 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1328 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1329 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1330 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1331 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1332 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1333 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1334 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1335 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1336 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1337 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1338 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1339 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1340 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1341 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1342 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1343 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1344 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1345 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1346 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1347 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1348 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1349 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1350 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1351 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1352 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1353 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1354 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1355 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1356 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1357 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1358 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1359 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1360 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1361 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1362 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1363 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1364 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1365 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1366 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1367 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
3fccb774
JFM
1368 {}
1369};
1370static const u8 sp80708_sensor_param1[][8] = {
5e31dc8d
JFM
1371 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1372 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1373 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1374 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1375 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1376 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1377 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1378 {}
1379};
1380
9c33afc6
JFM
1381static const u8 (*sensor_init[])[8] = {
1382[SENSOR_ADCM1700] = adcm1700_sensor_init,
ad98c0f6 1383[SENSOR_GC0307] = gc0307_sensor_init,
9c33afc6
JFM
1384[SENSOR_HV7131R] = hv7131r_sensor_init,
1385[SENSOR_MI0360] = mi0360_sensor_init,
a067db84 1386[SENSOR_MI0360B] = mi0360b_sensor_init,
9c33afc6
JFM
1387[SENSOR_MO4000] = mo4000_sensor_init,
1388[SENSOR_MT9V111] = mt9v111_sensor_init,
1389[SENSOR_OM6802] = om6802_sensor_init,
1390[SENSOR_OV7630] = ov7630_sensor_init,
1391[SENSOR_OV7648] = ov7648_sensor_init,
1392[SENSOR_OV7660] = ov7660_sensor_init,
1393[SENSOR_PO1030] = po1030_sensor_init,
ad98c0f6 1394[SENSOR_PO2030N] = po2030n_sensor_init,
03ed2a11 1395[SENSOR_SOI768] = soi768_sensor_init,
9c33afc6 1396[SENSOR_SP80708] = sp80708_sensor_init,
23a98274
JFM
1397};
1398
8295d99e 1399/* read <len> bytes to gspca_dev->usb_buf */
739570bb 1400static void reg_r(struct gspca_dev *gspca_dev,
98819187 1401 u16 value, int len)
6a7eba24 1402{
4bf8b679
JFM
1403 int ret;
1404
1405 if (gspca_dev->usb_err < 0)
1406 return;
8295d99e
JFM
1407#ifdef GSPCA_DEBUG
1408 if (len > USB_BUF_SZ) {
1409 err("reg_r: buffer overflow");
1410 return;
1411 }
1412#endif
4bf8b679 1413 ret = usb_control_msg(gspca_dev->dev,
739570bb 1414 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
1415 0,
1416 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1417 value, 0,
739570bb 1418 gspca_dev->usb_buf, len,
6a7eba24 1419 500);
60017617 1420 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
4bf8b679
JFM
1421 if (ret < 0) {
1422 err("reg_r err %d", ret);
1423 gspca_dev->usb_err = ret;
1424 }
6a7eba24
JFM
1425}
1426
60017617 1427static void reg_w1(struct gspca_dev *gspca_dev,
98819187
JFM
1428 u16 value,
1429 u8 data)
60017617 1430{
4bf8b679
JFM
1431 int ret;
1432
1433 if (gspca_dev->usb_err < 0)
1434 return;
3ef2c5be 1435 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
60017617 1436 gspca_dev->usb_buf[0] = data;
4bf8b679 1437 ret = usb_control_msg(gspca_dev->dev,
60017617
JFM
1438 usb_sndctrlpipe(gspca_dev->dev, 0),
1439 0x08,
1440 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1441 value,
1442 0,
1443 gspca_dev->usb_buf, 1,
1444 500);
4bf8b679
JFM
1445 if (ret < 0) {
1446 err("reg_w1 err %d", ret);
1447 gspca_dev->usb_err = ret;
1448 }
60017617 1449}
739570bb 1450static void reg_w(struct gspca_dev *gspca_dev,
98819187
JFM
1451 u16 value,
1452 const u8 *buffer,
6a7eba24
JFM
1453 int len)
1454{
4bf8b679
JFM
1455 int ret;
1456
1457 if (gspca_dev->usb_err < 0)
1458 return;
3ef2c5be 1459 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
60017617 1460 value, buffer[0], buffer[1]);
8295d99e
JFM
1461#ifdef GSPCA_DEBUG
1462 if (len > USB_BUF_SZ) {
1463 err("reg_w: buffer overflow");
1464 return;
bf7f0b98 1465 }
8295d99e
JFM
1466#endif
1467 memcpy(gspca_dev->usb_buf, buffer, len);
4bf8b679 1468 ret = usb_control_msg(gspca_dev->dev,
8295d99e
JFM
1469 usb_sndctrlpipe(gspca_dev->dev, 0),
1470 0x08,
1471 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1472 value, 0,
1473 gspca_dev->usb_buf, len,
1474 500);
4bf8b679
JFM
1475 if (ret < 0) {
1476 err("reg_w err %d", ret);
1477 gspca_dev->usb_err = ret;
1478 }
6a7eba24
JFM
1479}
1480
60017617 1481/* I2C write 1 byte */
98819187 1482static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
6a7eba24
JFM
1483{
1484 struct sd *sd = (struct sd *) gspca_dev;
4bf8b679 1485 int ret;
6a7eba24 1486
4bf8b679
JFM
1487 if (gspca_dev->usb_err < 0)
1488 return;
cfd23c8e 1489 PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
a782636c 1490 switch (sd->sensor) {
64677573 1491 case SENSOR_ADCM1700:
ad98c0f6
JFM
1492 case SENSOR_OM6802:
1493 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
a782636c
JFM
1494 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1495 break;
1496 default: /* i2c command = a1 (400 kHz) */
1497 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1498 break;
1499 }
d5aa3856 1500 gspca_dev->usb_buf[1] = sd->i2c_addr;
60017617
JFM
1501 gspca_dev->usb_buf[2] = reg;
1502 gspca_dev->usb_buf[3] = val;
1503 gspca_dev->usb_buf[4] = 0;
1504 gspca_dev->usb_buf[5] = 0;
1505 gspca_dev->usb_buf[6] = 0;
1506 gspca_dev->usb_buf[7] = 0x10;
4bf8b679 1507 ret = usb_control_msg(gspca_dev->dev,
60017617
JFM
1508 usb_sndctrlpipe(gspca_dev->dev, 0),
1509 0x08,
1510 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1511 0x08, /* value = i2c */
1512 0,
1513 gspca_dev->usb_buf, 8,
1514 500);
4bf8b679
JFM
1515 if (ret < 0) {
1516 err("i2c_w1 err %d", ret);
1517 gspca_dev->usb_err = ret;
1518 }
6a7eba24
JFM
1519}
1520
739570bb
JFM
1521/* I2C write 8 bytes */
1522static void i2c_w8(struct gspca_dev *gspca_dev,
98819187 1523 const u8 *buffer)
6a7eba24 1524{
4bf8b679
JFM
1525 int ret;
1526
1527 if (gspca_dev->usb_err < 0)
1528 return;
cfd23c8e
JFM
1529 PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1530 buffer[2], buffer[3]);
60017617 1531 memcpy(gspca_dev->usb_buf, buffer, 8);
4bf8b679 1532 ret = usb_control_msg(gspca_dev->dev,
60017617
JFM
1533 usb_sndctrlpipe(gspca_dev->dev, 0),
1534 0x08,
1535 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1536 0x08, 0, /* value, index */
1537 gspca_dev->usb_buf, 8,
1538 500);
8d768e14 1539 msleep(2);
4bf8b679
JFM
1540 if (ret < 0) {
1541 err("i2c_w8 err %d", ret);
1542 gspca_dev->usb_err = ret;
1543 }
6a7eba24
JFM
1544}
1545
b8c8a5bf
JFM
1546/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1547static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
6a7eba24
JFM
1548{
1549 struct sd *sd = (struct sd *) gspca_dev;
98819187 1550 u8 mode[8];
6a7eba24 1551
a782636c 1552 switch (sd->sensor) {
64677573 1553 case SENSOR_ADCM1700:
ad98c0f6
JFM
1554 case SENSOR_OM6802:
1555 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
a782636c
JFM
1556 mode[0] = 0x80 | 0x10;
1557 break;
1558 default: /* i2c command = 91 (400 kHz) */
1559 mode[0] = 0x81 | 0x10;
1560 break;
1561 }
d5aa3856 1562 mode[1] = sd->i2c_addr;
6a7eba24
JFM
1563 mode[2] = reg;
1564 mode[3] = 0;
1565 mode[4] = 0;
1566 mode[5] = 0;
1567 mode[6] = 0;
1568 mode[7] = 0x10;
739570bb 1569 i2c_w8(gspca_dev, mode);
60017617 1570 msleep(2);
b8c8a5bf 1571 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
6a7eba24 1572 mode[2] = 0;
739570bb 1573 i2c_w8(gspca_dev, mode);
60017617 1574 msleep(2);
739570bb 1575 reg_r(gspca_dev, 0x0a, 5);
6a7eba24
JFM
1576}
1577
23a98274
JFM
1578static void i2c_w_seq(struct gspca_dev *gspca_dev,
1579 const u8 (*data)[8])
1580{
1581 while ((*data)[0] != 0) {
1582 if ((*data)[0] != 0xdd)
1583 i2c_w8(gspca_dev, *data);
1584 else
1585 msleep((*data)[1]);
1586 data++;
1587 }
1588}
1589
7fb101ae 1590static void hv7131r_probe(struct gspca_dev *gspca_dev)
6a7eba24 1591{
60017617 1592 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
6a7eba24 1593 msleep(10);
60017617 1594 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
6a7eba24 1595 msleep(10);
b8c8a5bf 1596 i2c_r(gspca_dev, 0, 5); /* read sensor id */
739570bb
JFM
1597 if (gspca_dev->usb_buf[0] == 0x02
1598 && gspca_dev->usb_buf[1] == 0x09
1599 && gspca_dev->usb_buf[2] == 0x01
1600 && gspca_dev->usb_buf[3] == 0x00
1601 && gspca_dev->usb_buf[4] == 0x00) {
7fb101ae
JFM
1602 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1603 return;
6a7eba24 1604 }
7fb101ae 1605 PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
739570bb
JFM
1606 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1607 gspca_dev->usb_buf[2]);
6a7eba24
JFM
1608}
1609
65c5259c 1610static void mi0360_probe(struct gspca_dev *gspca_dev)
3ef2c5be 1611{
65c5259c 1612 struct sd *sd = (struct sd *) gspca_dev;
3ef2c5be 1613 int i, j;
92e8c91b 1614 u16 val = 0;
3ef2c5be 1615 static const u8 probe_tb[][4][8] = {
65c5259c 1616 { /* mi0360 */
3ef2c5be
JFM
1617 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1618 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1619 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1620 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1621 },
65c5259c 1622 { /* mt9v111 */
3ef2c5be
JFM
1623 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1624 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1625 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1626 {}
1627 },
1628 };
1629
1630 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1631 reg_w1(gspca_dev, 0x17, 0x62);
1632 reg_w1(gspca_dev, 0x01, 0x08);
1633 for (j = 0; j < 3; j++)
1634 i2c_w8(gspca_dev, probe_tb[i][j]);
1635 msleep(2);
1636 reg_r(gspca_dev, 0x0a, 5);
1637 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1638 if (probe_tb[i][3][0] != 0)
1639 i2c_w8(gspca_dev, probe_tb[i][3]);
1640 reg_w1(gspca_dev, 0x01, 0x29);
1641 reg_w1(gspca_dev, 0x17, 0x42);
1642 if (val != 0xffff)
1643 break;
1644 }
4bf8b679
JFM
1645 if (gspca_dev->usb_err < 0)
1646 return;
3ef2c5be 1647 switch (val) {
a067db84
JFM
1648 case 0x8221:
1649 PDEBUG(D_PROBE, "Sensor mi0360b");
1650 sd->sensor = SENSOR_MI0360B;
1651 break;
3ef2c5be
JFM
1652 case 0x823a:
1653 PDEBUG(D_PROBE, "Sensor mt9v111");
65c5259c 1654 sd->sensor = SENSOR_MT9V111;
65c5259c 1655 break;
3ef2c5be
JFM
1656 case 0x8243:
1657 PDEBUG(D_PROBE, "Sensor mi0360");
65c5259c
JFM
1658 break;
1659 default:
1660 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1661 break;
3ef2c5be 1662 }
3ef2c5be
JFM
1663}
1664
03ed2a11
JFM
1665static void ov7630_probe(struct gspca_dev *gspca_dev)
1666{
1667 struct sd *sd = (struct sd *) gspca_dev;
1668 u16 val;
1669
1670 /* check ov76xx */
1671 reg_w1(gspca_dev, 0x17, 0x62);
1672 reg_w1(gspca_dev, 0x01, 0x08);
1673 sd->i2c_addr = 0x21;
1674 i2c_r(gspca_dev, 0x0a, 2);
1675 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1676 reg_w1(gspca_dev, 0x01, 0x29);
1677 reg_w1(gspca_dev, 0x17, 0x42);
4bf8b679
JFM
1678 if (gspca_dev->usb_err < 0)
1679 return;
03ed2a11
JFM
1680 if (val == 0x7628) { /* soi768 */
1681 sd->sensor = SENSOR_SOI768;
1682/*fixme: only valid for 0c45:613e?*/
1683 gspca_dev->cam.input_flags =
1684 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1685 PDEBUG(D_PROBE, "Sensor soi768");
1686 return;
1687 }
1688 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1689}
1690
b8c8a5bf
JFM
1691static void ov7648_probe(struct gspca_dev *gspca_dev)
1692{
1693 struct sd *sd = (struct sd *) gspca_dev;
e3302cad 1694 u16 val;
b8c8a5bf
JFM
1695
1696 /* check ov76xx */
1697 reg_w1(gspca_dev, 0x17, 0x62);
1698 reg_w1(gspca_dev, 0x01, 0x08);
1699 sd->i2c_addr = 0x21;
1700 i2c_r(gspca_dev, 0x0a, 2);
e3302cad 1701 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
b8c8a5bf
JFM
1702 reg_w1(gspca_dev, 0x01, 0x29);
1703 reg_w1(gspca_dev, 0x17, 0x42);
e3302cad
JFM
1704 if ((val & 0xff00) == 0x7600) { /* ov76xx */
1705 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1706 return;
1707 }
b8c8a5bf
JFM
1708
1709 /* check po1030 */
1710 reg_w1(gspca_dev, 0x17, 0x62);
1711 reg_w1(gspca_dev, 0x01, 0x08);
1712 sd->i2c_addr = 0x6e;
1713 i2c_r(gspca_dev, 0x00, 2);
e3302cad
JFM
1714 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1715 reg_w1(gspca_dev, 0x01, 0x29);
1716 reg_w1(gspca_dev, 0x17, 0x42);
4bf8b679
JFM
1717 if (gspca_dev->usb_err < 0)
1718 return;
e3302cad 1719 if (val == 0x1030) { /* po1030 */
b8c8a5bf
JFM
1720 PDEBUG(D_PROBE, "Sensor po1030");
1721 sd->sensor = SENSOR_PO1030;
1722 return;
1723 }
1724
0b656321 1725 err("Unknown sensor %04x", val);
b8c8a5bf
JFM
1726}
1727
ad98c0f6
JFM
1728/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1729static void po2030n_probe(struct gspca_dev *gspca_dev)
1730{
1731 struct sd *sd = (struct sd *) gspca_dev;
e3302cad 1732 u16 val;
ad98c0f6
JFM
1733
1734 /* check gc0307 */
1735 reg_w1(gspca_dev, 0x17, 0x62);
1736 reg_w1(gspca_dev, 0x01, 0x08);
1737 reg_w1(gspca_dev, 0x02, 0x22);
1738 sd->i2c_addr = 0x21;
1739 i2c_r(gspca_dev, 0x00, 1);
e3302cad 1740 val = gspca_dev->usb_buf[4];
ad98c0f6
JFM
1741 reg_w1(gspca_dev, 0x01, 0x29); /* reset */
1742 reg_w1(gspca_dev, 0x17, 0x42);
e3302cad 1743 if (val == 0x99) { /* gc0307 (?) */
ad98c0f6
JFM
1744 PDEBUG(D_PROBE, "Sensor gc0307");
1745 sd->sensor = SENSOR_GC0307;
1746 return;
1747 }
1748
1749 /* check po2030n */
1750 reg_w1(gspca_dev, 0x17, 0x62);
1751 reg_w1(gspca_dev, 0x01, 0x0a);
1752 sd->i2c_addr = 0x6e;
1753 i2c_r(gspca_dev, 0x00, 2);
e3302cad 1754 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
ad98c0f6
JFM
1755 reg_w1(gspca_dev, 0x01, 0x29);
1756 reg_w1(gspca_dev, 0x17, 0x42);
4bf8b679
JFM
1757 if (gspca_dev->usb_err < 0)
1758 return;
e3302cad 1759 if (val == 0x2030) {
ad98c0f6
JFM
1760 PDEBUG(D_PROBE, "Sensor po2030n");
1761/* sd->sensor = SENSOR_PO2030N; */
e3302cad 1762 } else {
0b656321 1763 err("Unknown sensor ID %04x", val);
e3302cad 1764 }
ad98c0f6
JFM
1765}
1766
3fccb774 1767static void bridge_init(struct gspca_dev *gspca_dev,
98819187 1768 const u8 *sn9c1xx)
6a7eba24
JFM
1769{
1770 struct sd *sd = (struct sd *) gspca_dev;
19697b54 1771 u8 reg0102[2];
98819187
JFM
1772 const u8 *reg9a;
1773 static const u8 reg9a_def[] =
c8b9b2ca
JFM
1774 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1775 static const u8 reg9a_spec[] =
1776 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
98819187 1777 static const u8 regd4[] = {0x60, 0x00, 0x00};
6a7eba24 1778
9712a8be
HG
1779 /* sensor clock already enabled in sd_init */
1780 /* reg_w1(gspca_dev, 0xf1, 0x00); */
05b809c7 1781 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
6a7eba24
JFM
1782
1783 /* configure gpio */
19697b54
JFM
1784 reg0102[0] = sn9c1xx[1];
1785 reg0102[1] = sn9c1xx[2];
1786 if (gspca_dev->audio)
1787 reg0102[1] |= 0x04; /* keep the audio connection */
1788 reg_w(gspca_dev, 0x01, reg0102, 2);
739570bb 1789 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
d5aa3856 1790 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
c8b9b2ca 1791 switch (sd->sensor) {
ad98c0f6 1792 case SENSOR_GC0307:
c8b9b2ca 1793 case SENSOR_OV7660:
b8c8a5bf 1794 case SENSOR_PO1030:
ad98c0f6 1795 case SENSOR_PO2030N:
03ed2a11 1796 case SENSOR_SOI768:
c8b9b2ca
JFM
1797 case SENSOR_SP80708:
1798 reg9a = reg9a_spec;
6a7eba24 1799 break;
6a7eba24
JFM
1800 default:
1801 reg9a = reg9a_def;
1802 break;
1803 }
739570bb 1804 reg_w(gspca_dev, 0x9a, reg9a, 6);
6a7eba24 1805
d5aa3856 1806 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
6a7eba24 1807
739570bb 1808 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
6a7eba24 1809
d2d16e90 1810 switch (sd->sensor) {
64677573 1811 case SENSOR_ADCM1700:
878b35ae 1812 reg_w1(gspca_dev, 0x01, 0x43);
64677573
JFM
1813 reg_w1(gspca_dev, 0x17, 0x62);
1814 reg_w1(gspca_dev, 0x01, 0x42);
1815 reg_w1(gspca_dev, 0x01, 0x42);
1816 break;
ad98c0f6
JFM
1817 case SENSOR_GC0307:
1818 msleep(50);
1819 reg_w1(gspca_dev, 0x01, 0x61);
1820 reg_w1(gspca_dev, 0x17, 0x22);
1821 reg_w1(gspca_dev, 0x01, 0x60);
1822 reg_w1(gspca_dev, 0x01, 0x40);
1823 msleep(50);
1824 break;
a067db84
JFM
1825 case SENSOR_MI0360B:
1826 reg_w1(gspca_dev, 0x01, 0x61);
1827 reg_w1(gspca_dev, 0x17, 0x60);
1828 reg_w1(gspca_dev, 0x01, 0x60);
1829 reg_w1(gspca_dev, 0x01, 0x40);
1830 break;
3ef2c5be
JFM
1831 case SENSOR_MT9V111:
1832 reg_w1(gspca_dev, 0x01, 0x61);
1833 reg_w1(gspca_dev, 0x17, 0x61);
1834 reg_w1(gspca_dev, 0x01, 0x60);
1835 reg_w1(gspca_dev, 0x01, 0x40);
1836 break;
d2d16e90 1837 case SENSOR_OM6802:
3fccb774
JFM
1838 msleep(10);
1839 reg_w1(gspca_dev, 0x02, 0x73);
1840 reg_w1(gspca_dev, 0x17, 0x60);
1841 reg_w1(gspca_dev, 0x01, 0x22);
1842 msleep(100);
1843 reg_w1(gspca_dev, 0x01, 0x62);
d2d16e90 1844 reg_w1(gspca_dev, 0x17, 0x64);
3fccb774
JFM
1845 reg_w1(gspca_dev, 0x17, 0x64);
1846 reg_w1(gspca_dev, 0x01, 0x42);
1847 msleep(10);
d2d16e90 1848 reg_w1(gspca_dev, 0x01, 0x42);
3fccb774
JFM
1849 i2c_w8(gspca_dev, om6802_init0[0]);
1850 i2c_w8(gspca_dev, om6802_init0[1]);
1851 msleep(15);
1852 reg_w1(gspca_dev, 0x02, 0x71);
1853 msleep(150);
d2d16e90 1854 break;
05b809c7
JFM
1855 case SENSOR_OV7630:
1856 reg_w1(gspca_dev, 0x01, 0x61);
1857 reg_w1(gspca_dev, 0x17, 0xe2);
1858 reg_w1(gspca_dev, 0x01, 0x60);
1859 reg_w1(gspca_dev, 0x01, 0x40);
1860 break;
d2d16e90 1861 case SENSOR_OV7648:
6270330a
JFM
1862 reg_w1(gspca_dev, 0x01, 0x63);
1863 reg_w1(gspca_dev, 0x17, 0x20);
c8b9b2ca 1864 reg_w1(gspca_dev, 0x01, 0x62);
60017617 1865 reg_w1(gspca_dev, 0x01, 0x42);
6a7eba24 1866 break;
b8c8a5bf 1867 case SENSOR_PO1030:
03ed2a11 1868 case SENSOR_SOI768:
b8c8a5bf
JFM
1869 reg_w1(gspca_dev, 0x01, 0x61);
1870 reg_w1(gspca_dev, 0x17, 0x20);
1871 reg_w1(gspca_dev, 0x01, 0x60);
1872 reg_w1(gspca_dev, 0x01, 0x40);
1873 break;
ad98c0f6 1874 case SENSOR_PO2030N:
19697b54 1875 case SENSOR_OV7660:
ad98c0f6
JFM
1876 reg_w1(gspca_dev, 0x01, 0x63);
1877 reg_w1(gspca_dev, 0x17, 0x20);
1878 reg_w1(gspca_dev, 0x01, 0x62);
1879 reg_w1(gspca_dev, 0x01, 0x42);
1880 break;
5e31dc8d
JFM
1881 case SENSOR_SP80708:
1882 reg_w1(gspca_dev, 0x01, 0x63);
1883 reg_w1(gspca_dev, 0x17, 0x20);
1884 reg_w1(gspca_dev, 0x01, 0x62);
1885 reg_w1(gspca_dev, 0x01, 0x42);
1f78a976 1886 msleep(100);
5e31dc8d
JFM
1887 reg_w1(gspca_dev, 0x02, 0x62);
1888 break;
d5aa3856 1889 default:
c8b9b2ca
JFM
1890/* case SENSOR_HV7131R: */
1891/* case SENSOR_MI0360: */
1892/* case SENSOR_MO4000: */
60017617
JFM
1893 reg_w1(gspca_dev, 0x01, 0x43);
1894 reg_w1(gspca_dev, 0x17, 0x61);
1895 reg_w1(gspca_dev, 0x01, 0x42);
d5aa3856
JFM
1896 if (sd->sensor == SENSOR_HV7131R
1897 && sd->bridge == BRIDGE_SN9C102P)
7fb101ae 1898 hv7131r_probe(gspca_dev);
d2d16e90 1899 break;
6a7eba24 1900 }
6a7eba24
JFM
1901}
1902
6a7eba24
JFM
1903/* this function is called at probe time */
1904static int sd_config(struct gspca_dev *gspca_dev,
1905 const struct usb_device_id *id)
1906{
1907 struct sd *sd = (struct sd *) gspca_dev;
1908 struct cam *cam;
6a7eba24 1909
eac8f5fa
JFM
1910 sd->bridge = id->driver_info >> 16;
1911 sd->sensor = id->driver_info;
1912
6a7eba24 1913 cam = &gspca_dev->cam;
64677573
JFM
1914 if (sd->sensor == SENSOR_ADCM1700) {
1915 cam->cam_mode = cif_mode;
1916 cam->nmodes = ARRAY_SIZE(cif_mode);
1917 } else {
1918 cam->cam_mode = vga_mode;
1919 cam->nmodes = ARRAY_SIZE(vga_mode);
1920 }
49cb6b04 1921 cam->npkt = 24; /* 24 packets per ISOC message */
a5ae2062 1922
a5ae2062
JFM
1923 sd->brightness = BRIGHTNESS_DEF;
1924 sd->contrast = CONTRAST_DEF;
1925 sd->colors = COLOR_DEF;
403123d2
JFM
1926 sd->blue = BLUE_BALANCE_DEF;
1927 sd->red = RED_BALANCE_DEF;
592f4eb9 1928 sd->gamma = GAMMA_DEF;
a5ae2062 1929 sd->autogain = AUTOGAIN_DEF;
cebf3b67 1930 sd->ag_cnt = -1;
f800952c 1931 sd->vflip = VFLIP_DEF;
878b35ae
JFM
1932 switch (sd->sensor) {
1933 case SENSOR_OM6802:
1934 sd->sharpness = 0x10;
1935 break;
1936 default:
1937 sd->sharpness = SHARPNESS_DEF;
1938 break;
1939 }
0cae8964 1940 sd->infrared = INFRARED_DEF;
37c6dbe2 1941 sd->freq = FREQ_DEF;
77ac0baf 1942 sd->quality = QUALITY_DEF;
71cb2764 1943 sd->jpegqual = 80;
cebf3b67 1944
6a7eba24
JFM
1945 return 0;
1946}
1947
012d6b02
JFM
1948/* this function is called at probe and resume time */
1949static int sd_init(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1950{
1951 struct sd *sd = (struct sd *) gspca_dev;
d5aa3856 1952 const u8 *sn9c1xx;
19697b54 1953 u8 regGpio[] = { 0x29, 0x74 }; /* with audio */
98819187 1954 u8 regF1;
6a7eba24 1955
3647fea8 1956 /* setup a selector by bridge */
60017617 1957 reg_w1(gspca_dev, 0xf1, 0x01);
739570bb 1958 reg_r(gspca_dev, 0x00, 1);
8f47a3ce
JFM
1959 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1960 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
739570bb 1961 regF1 = gspca_dev->usb_buf[0];
4bf8b679
JFM
1962 if (gspca_dev->usb_err < 0)
1963 return gspca_dev->usb_err;
8f47a3ce 1964 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
3647fea8
HG
1965 switch (sd->bridge) {
1966 case BRIDGE_SN9C102P:
6a7eba24
JFM
1967 if (regF1 != 0x11)
1968 return -ENODEV;
60017617 1969 reg_w1(gspca_dev, 0x02, regGpio[1]);
6a7eba24 1970 break;
3647fea8 1971 case BRIDGE_SN9C105:
6a7eba24
JFM
1972 if (regF1 != 0x11)
1973 return -ENODEV;
65c5259c
JFM
1974 if (sd->sensor == SENSOR_MI0360)
1975 mi0360_probe(gspca_dev);
674cbc69 1976 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24 1977 break;
3647fea8 1978 case BRIDGE_SN9C120:
6a7eba24
JFM
1979 if (regF1 != 0x12)
1980 return -ENODEV;
b8c8a5bf
JFM
1981 switch (sd->sensor) {
1982 case SENSOR_MI0360:
65c5259c 1983 mi0360_probe(gspca_dev);
b8c8a5bf 1984 break;
03ed2a11
JFM
1985 case SENSOR_OV7630:
1986 ov7630_probe(gspca_dev);
1987 break;
b8c8a5bf
JFM
1988 case SENSOR_OV7648:
1989 ov7648_probe(gspca_dev);
1990 break;
ad98c0f6
JFM
1991 case SENSOR_PO2030N:
1992 po2030n_probe(gspca_dev);
1993 break;
b8c8a5bf 1994 }
19697b54 1995 regGpio[1] = 0x70; /* no audio */
674cbc69 1996 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24
JFM
1997 break;
1998 default:
60017617 1999/* case BRIDGE_SN9C110: */
3647fea8 2000/* case BRIDGE_SN9C325: */
6a7eba24
JFM
2001 if (regF1 != 0x12)
2002 return -ENODEV;
60017617 2003 reg_w1(gspca_dev, 0x02, 0x62);
6a7eba24
JFM
2004 break;
2005 }
2006
9712a8be
HG
2007 /* Note we do not disable the sensor clock here (power saving mode),
2008 as that also disables the button on the cam. */
2009 reg_w1(gspca_dev, 0xf1, 0x00);
6a7eba24 2010
d5aa3856
JFM
2011 /* set the i2c address */
2012 sn9c1xx = sn_tb[sd->sensor];
2013 sd->i2c_addr = sn9c1xx[9];
2014
b8c8a5bf
JFM
2015 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
2016
4bf8b679 2017 return gspca_dev->usb_err;
6a7eba24
JFM
2018}
2019
98819187
JFM
2020static u32 setexposure(struct gspca_dev *gspca_dev,
2021 u32 expo)
6a7eba24
JFM
2022{
2023 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24
JFM
2024
2025 switch (sd->sensor) {
c26b12d0
JFM
2026 case SENSOR_GC0307: {
2027 int a, b;
2028
2029 /* expo = 0..255 -> a = 19..43 */
2030 a = 19 + expo * 25 / 256;
2031 i2c_w1(gspca_dev, 0x68, a);
2032 a -= 12;
2033 b = a * a * 4; /* heuristic */
2034 i2c_w1(gspca_dev, 0x03, b >> 8);
2035 i2c_w1(gspca_dev, 0x04, b);
2036 break;
2037 }
6a7eba24 2038 case SENSOR_HV7131R: {
98819187 2039 u8 Expodoit[] =
d5aa3856 2040 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
6a7eba24
JFM
2041
2042 Expodoit[3] = expo >> 16;
2043 Expodoit[4] = expo >> 8;
2044 Expodoit[5] = expo;
739570bb 2045 i2c_w8(gspca_dev, Expodoit);
6a7eba24
JFM
2046 break;
2047 }
a067db84
JFM
2048 case SENSOR_MI0360:
2049 case SENSOR_MI0360B: {
3ef2c5be 2050 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
d5aa3856 2051 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
98819187
JFM
2052 static const u8 doit[] = /* update sensor */
2053 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
2054 static const u8 sensorgo[] = /* sensor on */
2055 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
6a7eba24
JFM
2056
2057 if (expo > 0x0635)
2058 expo = 0x0635;
2059 else if (expo < 0x0001)
2060 expo = 0x0001;
2061 expoMi[3] = expo >> 8;
2062 expoMi[4] = expo;
739570bb
JFM
2063 i2c_w8(gspca_dev, expoMi);
2064 i2c_w8(gspca_dev, doit);
2065 i2c_w8(gspca_dev, sensorgo);
6a7eba24
JFM
2066 break;
2067 }
2068 case SENSOR_MO4000: {
98819187 2069 u8 expoMof[] =
d5aa3856 2070 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
98819187 2071 u8 expoMo10[] =
d5aa3856 2072 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
98819187
JFM
2073 static const u8 gainMo[] =
2074 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
6a7eba24
JFM
2075
2076 if (expo > 0x1fff)
2077 expo = 0x1fff;
2078 else if (expo < 0x0001)
2079 expo = 0x0001;
2080 expoMof[3] = (expo & 0x03fc) >> 2;
739570bb 2081 i2c_w8(gspca_dev, expoMof);
6a7eba24
JFM
2082 expoMo10[3] = ((expo & 0x1c00) >> 10)
2083 | ((expo & 0x0003) << 4);
739570bb
JFM
2084 i2c_w8(gspca_dev, expoMo10);
2085 i2c_w8(gspca_dev, gainMo);
3ef2c5be 2086 PDEBUG(D_FRAM, "set exposure %d",
6a7eba24
JFM
2087 ((expoMo10[3] & 0x07) << 10)
2088 | (expoMof[3] << 2)
2089 | ((expoMo10[3] & 0x30) >> 4));
2090 break;
2091 }
3ef2c5be
JFM
2092 case SENSOR_MT9V111: {
2093 u8 expo_c1[] =
2094 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
2095
2096 if (expo > 0x0280)
2097 expo = 0x0280;
2098 else if (expo < 0x0040)
2099 expo = 0x0040;
2100 expo_c1[3] = expo >> 8;
2101 expo_c1[4] = expo;
2102 i2c_w8(gspca_dev, expo_c1);
2103 break;
2104 }
d2d16e90 2105 case SENSOR_OM6802: {
98819187 2106 u8 gainOm[] =
d2d16e90 2107 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
d5aa3856 2108 /* preset AGC - works when AutoExpo = off */
d2d16e90
JFM
2109
2110 if (expo > 0x03ff)
2111 expo = 0x03ff;
2112 if (expo < 0x0001)
2113 expo = 0x0001;
2114 gainOm[3] = expo >> 2;
2115 i2c_w8(gspca_dev, gainOm);
d5aa3856 2116 reg_w1(gspca_dev, 0x96, expo >> 5);
3ef2c5be 2117 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
d2d16e90
JFM
2118 break;
2119 }
6a7eba24
JFM
2120 }
2121 return expo;
2122}
2123
2124static void setbrightness(struct gspca_dev *gspca_dev)
2125{
2126 struct sd *sd = (struct sd *) gspca_dev;
2127 unsigned int expo;
98819187 2128 u8 k2;
6a7eba24 2129
b1b056a5 2130 k2 = ((int) sd->brightness - 0x8000) >> 10;
6a7eba24 2131 switch (sd->sensor) {
64677573 2132 case SENSOR_ADCM1700:
878b35ae
JFM
2133 if (k2 > 0x1f)
2134 k2 = 0; /* only positive Y offset */
2135 break;
6a7eba24
JFM
2136 case SENSOR_HV7131R:
2137 expo = sd->brightness << 4;
2138 if (expo > 0x002dc6c0)
2139 expo = 0x002dc6c0;
2140 else if (expo < 0x02a0)
2141 expo = 0x02a0;
2142 sd->exposure = setexposure(gspca_dev, expo);
2143 break;
2144 case SENSOR_MI0360:
6a7eba24
JFM
2145 case SENSOR_MO4000:
2146 expo = sd->brightness >> 4;
2147 sd->exposure = setexposure(gspca_dev, expo);
2148 break;
a067db84
JFM
2149 case SENSOR_MI0360B:
2150 expo = sd->brightness >> 6;
2151 sd->exposure = setexposure(gspca_dev, expo);
2152 break;
c26b12d0 2153 case SENSOR_GC0307:
3ef2c5be
JFM
2154 case SENSOR_MT9V111:
2155 expo = sd->brightness >> 8;
2156 sd->exposure = setexposure(gspca_dev, expo);
d5aa3856 2157 return; /* don't set the Y offset */
d2d16e90
JFM
2158 case SENSOR_OM6802:
2159 expo = sd->brightness >> 6;
2160 sd->exposure = setexposure(gspca_dev, expo);
b1b056a5 2161 k2 = sd->brightness >> 11;
d2d16e90 2162 break;
6a7eba24
JFM
2163 }
2164
d5aa3856 2165 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
6a7eba24
JFM
2166}
2167
2168static void setcontrast(struct gspca_dev *gspca_dev)
2169{
2170 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
2171 u8 k2;
2172 u8 contrast[6];
6a7eba24 2173
91bd3412
JFM
2174 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
2175 contrast[0] = (k2 + 1) / 2; /* red */
577cbf49 2176 contrast[1] = 0;
91bd3412 2177 contrast[2] = k2; /* green */
577cbf49 2178 contrast[3] = 0;
91bd3412 2179 contrast[4] = (k2 + 1) / 5; /* blue */
577cbf49
JFM
2180 contrast[5] = 0;
2181 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
6a7eba24
JFM
2182}
2183
2184static void setcolors(struct gspca_dev *gspca_dev)
2185{
2186 struct sd *sd = (struct sd *) gspca_dev;
403123d2 2187 int i, v;
a067db84 2188 const s16 *uv;
98819187 2189 u8 reg8a[12]; /* U & V gains */
a067db84 2190 static const s16 uv_com[6] = { /* same as reg84 in signed decimal */
403123d2
JFM
2191 -24, -38, 64, /* UR UG UB */
2192 62, -51, -9 /* VR VG VB */
2193 };
a067db84
JFM
2194 static const s16 uv_mi0360b[6] = {
2195 -20, -38, 64, /* UR UG UB */
2196 60, -51, -9 /* VR VG VB */
2197 };
d5aa3856 2198
a067db84
JFM
2199 if (sd->sensor == SENSOR_MI0360B)
2200 uv = uv_mi0360b;
2201 else
2202 uv = uv_com;
403123d2
JFM
2203 for (i = 0; i < 6; i++) {
2204 v = uv[i] * sd->colors / COLOR_DEF;
bd088835
JFM
2205 reg8a[i * 2] = v;
2206 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
d55b83d3 2207 }
bd088835 2208 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
403123d2
JFM
2209}
2210
2211static void setredblue(struct gspca_dev *gspca_dev)
2212{
2213 struct sd *sd = (struct sd *) gspca_dev;
2214
2215 reg_w1(gspca_dev, 0x05, sd->red);
9c5f70f2 2216/* reg_w1(gspca_dev, 0x07, 32); */
403123d2 2217 reg_w1(gspca_dev, 0x06, sd->blue);
6a7eba24
JFM
2218}
2219
592f4eb9
JFM
2220static void setgamma(struct gspca_dev *gspca_dev)
2221{
2222 struct sd *sd = (struct sd *) gspca_dev;
2223 int i;
2224 u8 gamma[17];
b083b92f 2225 const u8 *gamma_base;
592f4eb9
JFM
2226 static const u8 delta[17] = {
2227 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2228 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2229 };
2230
b083b92f 2231 switch (sd->sensor) {
64677573
JFM
2232 case SENSOR_ADCM1700:
2233 gamma_base = gamma_spec_0;
2234 break;
b083b92f 2235 case SENSOR_HV7131R:
a067db84 2236 case SENSOR_MI0360B:
b083b92f
JFM
2237 case SENSOR_MT9V111:
2238 gamma_base = gamma_spec_1;
2239 break;
ad98c0f6 2240 case SENSOR_GC0307:
b083b92f
JFM
2241 gamma_base = gamma_spec_2;
2242 break;
ad98c0f6
JFM
2243 case SENSOR_SP80708:
2244 gamma_base = gamma_spec_3;
2245 break;
b083b92f
JFM
2246 default:
2247 gamma_base = gamma_def;
2248 break;
2249 }
5e31dc8d 2250
592f4eb9 2251 for (i = 0; i < sizeof gamma; i++)
b083b92f 2252 gamma[i] = gamma_base[i]
592f4eb9
JFM
2253 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
2254 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2255}
2256
cebf3b67
JFM
2257static void setautogain(struct gspca_dev *gspca_dev)
2258{
2259 struct sd *sd = (struct sd *) gspca_dev;
2260
f50ba1be
JFM
2261 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
2262 return;
2797ba2a
JFM
2263 switch (sd->sensor) {
2264 case SENSOR_OV7630:
2265 case SENSOR_OV7648: {
2266 u8 comb;
2267
2268 if (sd->sensor == SENSOR_OV7630)
2269 comb = 0xc0;
2270 else
2271 comb = 0xa0;
2272 if (sd->autogain)
1fec747c 2273 comb |= 0x03;
2797ba2a
JFM
2274 i2c_w1(&sd->gspca_dev, 0x13, comb);
2275 return;
2276 }
2277 }
f50ba1be
JFM
2278 if (sd->autogain)
2279 sd->ag_cnt = AG_CNT_START;
2280 else
2281 sd->ag_cnt = -1;
cebf3b67
JFM
2282}
2283
f6b22e5e 2284/* hv7131r/ov7630/ov7648 only */
6c86274f
JFM
2285static void setvflip(struct sd *sd)
2286{
2797ba2a
JFM
2287 u8 comn;
2288
0939e266
JFM
2289 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
2290 return;
f6b22e5e
JFM
2291 switch (sd->sensor) {
2292 case SENSOR_HV7131R:
2293 comn = 0x18; /* clkdiv = 1, ablcen = 1 */
2294 if (sd->vflip)
2295 comn |= 0x01;
2296 i2c_w1(&sd->gspca_dev, 0x01, comn); /* sctra */
2297 break;
2298 case SENSOR_OV7630:
2797ba2a 2299 comn = 0x02;
f800952c
HG
2300 if (!sd->vflip)
2301 comn |= 0x80;
f6b22e5e
JFM
2302 i2c_w1(&sd->gspca_dev, 0x75, comn);
2303 break;
2304 default:
2305/* case SENSOR_OV7648: */
2797ba2a 2306 comn = 0x06;
f800952c
HG
2307 if (sd->vflip)
2308 comn |= 0x80;
f6b22e5e
JFM
2309 i2c_w1(&sd->gspca_dev, 0x75, comn);
2310 break;
f800952c 2311 }
6c86274f
JFM
2312}
2313
878b35ae
JFM
2314static void setsharpness(struct sd *sd)
2315{
2316 reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
2317}
2318
0cae8964
JFM
2319static void setinfrared(struct sd *sd)
2320{
47f7f6fb
JFM
2321 if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
2322 return;
0cae8964
JFM
2323/*fixme: different sequence for StarCam Clip and StarCam 370i */
2324/* Clip */
2325 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
2326 sd->infrared ? 0x66 : 0x64);
2327}
2328
37c6dbe2
HG
2329static void setfreq(struct gspca_dev *gspca_dev)
2330{
2331 struct sd *sd = (struct sd *) gspca_dev;
2332
27954930
JFM
2333 if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
2334 return;
37c6dbe2 2335 if (sd->sensor == SENSOR_OV7660) {
d8f400ef
JFM
2336 u8 com8;
2337
47f7f6fb 2338 com8 = 0xdf; /* auto gain/wb/expo */
37c6dbe2
HG
2339 switch (sd->freq) {
2340 case 0: /* Banding filter disabled */
47f7f6fb 2341 i2c_w1(gspca_dev, 0x13, com8 | 0x20);
37c6dbe2
HG
2342 break;
2343 case 1: /* 50 hz */
d8f400ef 2344 i2c_w1(gspca_dev, 0x13, com8);
37c6dbe2
HG
2345 i2c_w1(gspca_dev, 0x3b, 0x0a);
2346 break;
2347 case 2: /* 60 hz */
d8f400ef 2348 i2c_w1(gspca_dev, 0x13, com8);
37c6dbe2
HG
2349 i2c_w1(gspca_dev, 0x3b, 0x02);
2350 break;
2351 }
2352 } else {
2353 u8 reg2a = 0, reg2b = 0, reg2d = 0;
2354
2355 /* Get reg2a / reg2d base values */
2356 switch (sd->sensor) {
2357 case SENSOR_OV7630:
2358 reg2a = 0x08;
2359 reg2d = 0x01;
2360 break;
2361 case SENSOR_OV7648:
2362 reg2a = 0x11;
2363 reg2d = 0x81;
2364 break;
2365 }
2366
2367 switch (sd->freq) {
2368 case 0: /* Banding filter disabled */
2369 break;
2370 case 1: /* 50 hz (filter on and framerate adj) */
2371 reg2a |= 0x80;
2372 reg2b = 0xac;
2373 reg2d |= 0x04;
2374 break;
2375 case 2: /* 60 hz (filter on, no framerate adj) */
2376 reg2a |= 0x80;
2377 reg2d |= 0x04;
2378 break;
2379 }
2380 i2c_w1(gspca_dev, 0x2a, reg2a);
2381 i2c_w1(gspca_dev, 0x2b, reg2b);
2382 i2c_w1(gspca_dev, 0x2d, reg2d);
2383 }
2384}
2385
71cb2764
JFM
2386static void setjpegqual(struct gspca_dev *gspca_dev)
2387{
2388 struct sd *sd = (struct sd *) gspca_dev;
2389 int i, sc;
2390
2391 if (sd->jpegqual < 50)
2392 sc = 5000 / sd->jpegqual;
2393 else
2394 sc = 200 - sd->jpegqual * 2;
2395#if USB_BUF_SZ < 64
2396#error "No room enough in usb_buf for quantization table"
2397#endif
2398 for (i = 0; i < 64; i++)
2399 gspca_dev->usb_buf[i] =
2400 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
2401 usb_control_msg(gspca_dev->dev,
2402 usb_sndctrlpipe(gspca_dev->dev, 0),
2403 0x08,
2404 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2405 0x0100, 0,
2406 gspca_dev->usb_buf, 64,
2407 500);
2408 for (i = 0; i < 64; i++)
2409 gspca_dev->usb_buf[i] =
2410 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
2411 usb_control_msg(gspca_dev->dev,
2412 usb_sndctrlpipe(gspca_dev->dev, 0),
2413 0x08,
2414 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2415 0x0140, 0,
2416 gspca_dev->usb_buf, 64,
2417 500);
2418
2419 sd->reg18 ^= 0x40;
2420 reg_w1(gspca_dev, 0x18, sd->reg18);
2421}
2422
6a7eba24 2423/* -- start the camera -- */
72ab97ce 2424static int sd_start(struct gspca_dev *gspca_dev)
6a7eba24
JFM
2425{
2426 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 2427 int i;
19697b54 2428 u8 reg1, reg17;
98819187 2429 const u8 *sn9c1xx;
3fccb774 2430 const u8 (*init)[8];
6a7eba24 2431 int mode;
98819187
JFM
2432 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2433 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
64677573
JFM
2434 static const u8 CA_adcm1700[] =
2435 { 0x14, 0xec, 0x0a, 0xf6 };
ad98c0f6
JFM
2436 static const u8 CA_po2030n[] =
2437 { 0x1e, 0xe2, 0x14, 0xec };
98819187 2438 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
ad98c0f6
JFM
2439 static const u8 CE_gc0307[] =
2440 { 0x32, 0xce, 0x2d, 0xd3 };
98819187 2441 static const u8 CE_ov76xx[] =
674cbc69 2442 { 0x32, 0xdd, 0x32, 0xdd };
ad98c0f6
JFM
2443 static const u8 CE_po2030n[] =
2444 { 0x14, 0xe7, 0x1e, 0xdd };
6a7eba24 2445
71cb2764 2446 /* create the JPEG header */
71cb2764
JFM
2447 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2448 0x21); /* JPEG 422 */
2449 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2450
3fccb774
JFM
2451 /* initialize the bridge */
2452 sn9c1xx = sn_tb[sd->sensor];
2453 bridge_init(gspca_dev, sn9c1xx);
d5aa3856 2454
3fccb774
JFM
2455 /* initialize the sensor */
2456 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2457
60017617
JFM
2458 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2459 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2460 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2461 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2462 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
64677573 2463 if (sd->sensor == SENSOR_ADCM1700) {
878b35ae
JFM
2464 reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
2465 reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
64677573 2466 } else {
878b35ae
JFM
2467 reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
2468 reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
64677573 2469 }
60017617
JFM
2470 reg_w1(gspca_dev, 0xc6, 0x00);
2471 reg_w1(gspca_dev, 0xc7, 0x00);
64677573 2472 if (sd->sensor == SENSOR_ADCM1700) {
878b35ae
JFM
2473 reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
2474 reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
64677573 2475 } else {
878b35ae
JFM
2476 reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
2477 reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
64677573 2478 }
60017617 2479 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
6ab0b174 2480 switch (sd->sensor) {
ad98c0f6
JFM
2481 case SENSOR_GC0307:
2482 reg17 = 0xa2;
2483 break;
3ef2c5be 2484 case SENSOR_MT9V111:
a067db84 2485 case SENSOR_MI0360B:
3ef2c5be
JFM
2486 reg17 = 0xe0;
2487 break;
64677573 2488 case SENSOR_ADCM1700:
6ab0b174
JFM
2489 case SENSOR_OV7630:
2490 reg17 = 0xe2;
2491 break;
2492 case SENSOR_OV7648:
6270330a 2493 reg17 = 0x20;
568788a7 2494 break;
6ab0b174 2495 case SENSOR_OV7660:
03ed2a11 2496 case SENSOR_SOI768:
c8b9b2ca
JFM
2497 reg17 = 0xa0;
2498 break;
b8c8a5bf 2499 case SENSOR_PO1030:
ad98c0f6 2500 case SENSOR_PO2030N:
b8c8a5bf
JFM
2501 reg17 = 0xa0;
2502 break;
568788a7 2503 default:
8f47a3ce 2504 reg17 = 0x60;
568788a7
JFM
2505 break;
2506 }
8f47a3ce 2507 reg_w1(gspca_dev, 0x17, reg17);
878b35ae
JFM
2508
2509 reg_w1(gspca_dev, 0x05, 0x00); /* red */
2510 reg_w1(gspca_dev, 0x07, 0x00); /* green */
2511 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
60017617 2512 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
b083b92f 2513
5e31dc8d
JFM
2514 setgamma(gspca_dev);
2515
878b35ae 2516/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
05b809c7
JFM
2517 for (i = 0; i < 8; i++)
2518 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
674cbc69 2519 switch (sd->sensor) {
64677573 2520 case SENSOR_ADCM1700:
878b35ae
JFM
2521 case SENSOR_OV7660:
2522 case SENSOR_SP80708:
64677573 2523 reg_w1(gspca_dev, 0x9a, 0x05);
64677573 2524 break;
ad98c0f6 2525 case SENSOR_GC0307:
3ef2c5be 2526 case SENSOR_MT9V111:
a067db84 2527 case SENSOR_MI0360B:
3ef2c5be 2528 reg_w1(gspca_dev, 0x9a, 0x07);
3fccb774 2529 break;
0a85c74b 2530 case SENSOR_OV7630:
6270330a
JFM
2531 case SENSOR_OV7648:
2532 reg_w1(gspca_dev, 0x9a, 0x0a);
5e31dc8d 2533 break;
ad98c0f6 2534 case SENSOR_PO2030N:
03ed2a11 2535 case SENSOR_SOI768:
ad98c0f6
JFM
2536 reg_w1(gspca_dev, 0x9a, 0x06);
2537 break;
674cbc69 2538 default:
60017617 2539 reg_w1(gspca_dev, 0x9a, 0x08);
674cbc69
JFM
2540 break;
2541 }
878b35ae 2542 setsharpness(sd);
6a7eba24 2543
3fccb774 2544 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
878b35ae
JFM
2545 reg_w1(gspca_dev, 0x05, 0x20); /* red */
2546 reg_w1(gspca_dev, 0x07, 0x20); /* green */
2547 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
23a98274 2548
3fccb774 2549 init = NULL;
d5aa3856 2550 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
60017617 2551 if (mode)
1432f306 2552 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
60017617 2553 else
1432f306
JFM
2554 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
2555 reg17 = 0x61; /* 0x:20: enable sensor clock */
6a7eba24 2556 switch (sd->sensor) {
64677573
JFM
2557 case SENSOR_ADCM1700:
2558 init = adcm1700_sensor_param1;
2559 reg1 = 0x46;
2560 reg17 = 0xe2;
2561 break;
ad98c0f6
JFM
2562 case SENSOR_GC0307:
2563 init = gc0307_sensor_param1;
2564 reg17 = 0xa2;
2565 reg1 = 0x44;
2566 break;
a067db84
JFM
2567 case SENSOR_MI0360B:
2568 init = mi0360b_sensor_param1;
2569 reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */
2570 reg17 = 0xe2;
2571 break;
6a7eba24 2572 case SENSOR_MO4000:
6a7eba24
JFM
2573 if (mode) {
2574/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
2575 reg1 = 0x06; /* clk 24Mz */
2576 } else {
2577 reg17 = 0x22; /* 640 MCKSIZE */
60017617 2578/* reg1 = 0x06; * 640 clk 24Mz (done) */
6a7eba24
JFM
2579 }
2580 break;
3ef2c5be 2581 case SENSOR_MT9V111:
3fccb774 2582 init = mt9v111_sensor_param1;
3ef2c5be
JFM
2583 if (mode) {
2584 reg1 = 0x04; /* 320 clk 48Mhz */
2585 } else {
2586/* reg1 = 0x06; * 640 clk 24Mz (done) */
2687a2fb 2587 reg17 = 0xc2;
3ef2c5be 2588 }
0fbe0574 2589 break;
d2d16e90 2590 case SENSOR_OM6802:
3fccb774 2591 init = om6802_sensor_param1;
d2d16e90
JFM
2592 reg17 = 0x64; /* 640 MCKSIZE */
2593 break;
6ab0b174 2594 case SENSOR_OV7630:
bdd2b93c 2595 init = ov7630_sensor_param1;
6ab0b174 2596 reg17 = 0xe2;
5b064da8 2597 reg1 = 0x44;
6ab0b174 2598 break;
6a7eba24 2599 case SENSOR_OV7648:
3fccb774 2600 init = ov7648_sensor_param1;
6270330a
JFM
2601 reg17 = 0x21;
2602/* reg1 = 0x42; * 42 - 46? */
6a7eba24 2603 break;
5e31dc8d 2604 case SENSOR_OV7660:
3fccb774 2605 init = ov7660_sensor_param1;
daa5cb42
JFM
2606 if (sd->bridge == BRIDGE_SN9C120) {
2607 if (mode) { /* 320x240 - 160x120 */
1432f306
JFM
2608 reg17 = 0xa2;
2609 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1432f306 2610 }
daa5cb42
JFM
2611 } else {
2612 reg17 = 0x22;
2613 reg1 = 0x06; /* 24 Mhz, video trf eneble
2614 * inverse power down */
6a7eba24
JFM
2615 }
2616 break;
b8c8a5bf
JFM
2617 case SENSOR_PO1030:
2618 init = po1030_sensor_param1;
2619 reg17 = 0xa2;
2620 reg1 = 0x44;
2621 break;
ad98c0f6
JFM
2622 case SENSOR_PO2030N:
2623 init = po2030n_sensor_param1;
2624 reg1 = 0x46;
2625 reg17 = 0xa2;
2626 break;
03ed2a11
JFM
2627 case SENSOR_SOI768:
2628 init = soi768_sensor_param1;
2629 reg1 = 0x44;
2630 reg17 = 0xa2;
2631 break;
5e31dc8d
JFM
2632 default:
2633/* case SENSOR_SP80708: */
3fccb774 2634 init = sp80708_sensor_param1;
5e31dc8d
JFM
2635 if (mode) {
2636/*?? reg1 = 0x04; * 320 clk 48Mhz */
5e31dc8d
JFM
2637 } else {
2638 reg1 = 0x46; /* 640 clk 48Mz */
2639 reg17 = 0xa2;
2640 }
2641 break;
6a7eba24 2642 }
3fccb774
JFM
2643
2644 /* more sensor initialization - param1 */
2645 if (init != NULL) {
2646 i2c_w_seq(gspca_dev, init);
2647/* init = NULL; */
2648 }
2649
739570bb 2650 reg_w(gspca_dev, 0xc0, C0, 6);
ad98c0f6
JFM
2651 switch (sd->sensor) {
2652 case SENSOR_ADCM1700:
2653 case SENSOR_GC0307:
03ed2a11 2654 case SENSOR_SOI768:
64677573 2655 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
ad98c0f6
JFM
2656 break;
2657 case SENSOR_PO2030N:
2658 reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2659 break;
2660 default:
64677573 2661 reg_w(gspca_dev, 0xca, CA, 4);
ad98c0f6
JFM
2662 break;
2663 }
6ab0b174 2664 switch (sd->sensor) {
64677573 2665 case SENSOR_ADCM1700:
6ab0b174
JFM
2666 case SENSOR_OV7630:
2667 case SENSOR_OV7648:
674cbc69 2668 case SENSOR_OV7660:
03ed2a11 2669 case SENSOR_SOI768:
6ab0b174 2670 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
6a7eba24 2671 break;
ad98c0f6
JFM
2672 case SENSOR_GC0307:
2673 reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2674 break;
2675 case SENSOR_PO2030N:
2676 reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2677 break;
6a7eba24 2678 default:
739570bb 2679 reg_w(gspca_dev, 0xce, CE, 4);
6a7eba24
JFM
2680 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2681 break;
2682 }
2683
3fccb774 2684
6a7eba24 2685 /* here change size mode 0 -> VGA; 1 -> CIF */
71cb2764
JFM
2686 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2687 reg_w1(gspca_dev, 0x18, sd->reg18);
2688 setjpegqual(gspca_dev);
6a7eba24 2689
60017617 2690 reg_w1(gspca_dev, 0x17, reg17);
1432f306 2691 reg_w1(gspca_dev, 0x01, reg1);
3fccb774 2692
1e5eb113 2693 setvflip(sd);
91bd3412
JFM
2694 setbrightness(gspca_dev);
2695 setcontrast(gspca_dev);
fff2f708 2696 setcolors(gspca_dev);
cebf3b67 2697 setautogain(gspca_dev);
37c6dbe2 2698 setfreq(gspca_dev);
4bf8b679 2699 return gspca_dev->usb_err;
6a7eba24
JFM
2700}
2701
2702static void sd_stopN(struct gspca_dev *gspca_dev)
2703{
2704 struct sd *sd = (struct sd *) gspca_dev;
98819187 2705 static const u8 stophv7131[] =
6a7eba24 2706 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
98819187 2707 static const u8 stopmi0360[] =
6a7eba24 2708 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
98819187 2709 static const u8 stopov7648[] =
6270330a 2710 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
03ed2a11
JFM
2711 static const u8 stopsoi768[] =
2712 { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
98819187
JFM
2713 u8 data;
2714 const u8 *sn9c1xx;
6a7eba24
JFM
2715
2716 data = 0x0b;
2717 switch (sd->sensor) {
ad98c0f6
JFM
2718 case SENSOR_GC0307:
2719 data = 0x29;
2720 break;
6a7eba24 2721 case SENSOR_HV7131R:
739570bb 2722 i2c_w8(gspca_dev, stophv7131);
6a7eba24
JFM
2723 data = 0x2b;
2724 break;
2725 case SENSOR_MI0360:
a067db84 2726 case SENSOR_MI0360B:
739570bb 2727 i2c_w8(gspca_dev, stopmi0360);
6a7eba24
JFM
2728 data = 0x29;
2729 break;
6a7eba24 2730 case SENSOR_OV7648:
6270330a
JFM
2731 i2c_w8(gspca_dev, stopov7648);
2732 /* fall thru */
3ef2c5be 2733 case SENSOR_MT9V111:
6270330a 2734 case SENSOR_OV7630:
b8c8a5bf 2735 case SENSOR_PO1030:
6a7eba24
JFM
2736 data = 0x29;
2737 break;
03ed2a11
JFM
2738 case SENSOR_SOI768:
2739 i2c_w8(gspca_dev, stopsoi768);
2740 data = 0x29;
2741 break;
6a7eba24 2742 }
d5aa3856 2743 sn9c1xx = sn_tb[sd->sensor];
60017617
JFM
2744 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2745 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2746 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2747 reg_w1(gspca_dev, 0x01, data);
9712a8be
HG
2748 /* Don't disable sensor clock as that disables the button on the cam */
2749 /* reg_w1(gspca_dev, 0xf1, 0x01); */
6a7eba24
JFM
2750}
2751
cebf3b67 2752static void do_autogain(struct gspca_dev *gspca_dev)
6a7eba24
JFM
2753{
2754 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 2755 int delta;
cebf3b67 2756 int expotimes;
98819187
JFM
2757 u8 luma_mean = 130;
2758 u8 luma_delta = 20;
6a7eba24 2759
cebf3b67
JFM
2760 /* Thanks S., without your advice, autobright should not work :) */
2761 if (sd->ag_cnt < 0)
2762 return;
2763 if (--sd->ag_cnt >= 0)
2764 return;
2765 sd->ag_cnt = AG_CNT_START;
2766
2767 delta = atomic_read(&sd->avg_lum);
2768 PDEBUG(D_FRAM, "mean lum %d", delta);
6a7eba24
JFM
2769 if (delta < luma_mean - luma_delta ||
2770 delta > luma_mean + luma_delta) {
2771 switch (sd->sensor) {
c26b12d0
JFM
2772 case SENSOR_GC0307:
2773 expotimes = sd->exposure;
2774 expotimes += (luma_mean - delta) >> 6;
2775 if (expotimes < 0)
2776 expotimes = 0;
2777 sd->exposure = setexposure(gspca_dev,
2778 (unsigned int) expotimes);
2779 break;
6a7eba24
JFM
2780 case SENSOR_HV7131R:
2781 expotimes = sd->exposure >> 8;
2782 expotimes += (luma_mean - delta) >> 4;
2783 if (expotimes < 0)
2784 expotimes = 0;
2785 sd->exposure = setexposure(gspca_dev,
2786 (unsigned int) (expotimes << 8));
2787 break;
46b4f2ab
AM
2788 case SENSOR_OM6802:
2789 expotimes = sd->exposure;
2790 expotimes += (luma_mean - delta) >> 2;
2791 if (expotimes < 0)
2792 expotimes = 0;
2793 sd->exposure = setexposure(gspca_dev,
2794 (unsigned int) expotimes);
2795 setredblue(gspca_dev);
2796 break;
cebf3b67
JFM
2797 default:
2798/* case SENSOR_MO4000: */
2799/* case SENSOR_MI0360: */
a067db84 2800/* case SENSOR_MI0360B: */
3ef2c5be 2801/* case SENSOR_MT9V111: */
6a7eba24
JFM
2802 expotimes = sd->exposure;
2803 expotimes += (luma_mean - delta) >> 6;
2804 if (expotimes < 0)
2805 expotimes = 0;
2806 sd->exposure = setexposure(gspca_dev,
2807 (unsigned int) expotimes);
403123d2 2808 setredblue(gspca_dev);
6a7eba24
JFM
2809 break;
2810 }
2811 }
2812}
2813
cebf3b67
JFM
2814/* scan the URB packets */
2815/* This function is run at interrupt level. */
6a7eba24 2816static void sd_pkt_scan(struct gspca_dev *gspca_dev,
98819187 2817 u8 *data, /* isoc packet */
6a7eba24
JFM
2818 int len) /* iso packet length */
2819{
2820 struct sd *sd = (struct sd *) gspca_dev;
2821 int sof, avg_lum;
2822
2823 sof = len - 64;
2824 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
2825
2826 /* end of frame */
2827 gspca_frame_add(gspca_dev, LAST_PACKET,
76dd272b 2828 data, sof + 2);
6a7eba24
JFM
2829 if (sd->ag_cnt < 0)
2830 return;
6a7eba24
JFM
2831/* w1 w2 w3 */
2832/* w4 w5 w6 */
2833/* w7 w8 */
2834/* w4 */
2835 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2836/* w6 */
2837 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2838/* w2 */
2839 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2840/* w8 */
2841 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2842/* w5 */
2843 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2844 avg_lum >>= 4;
cebf3b67 2845 atomic_set(&sd->avg_lum, avg_lum);
6a7eba24
JFM
2846 return;
2847 }
2848 if (gspca_dev->last_packet_type == LAST_PACKET) {
2849
2850 /* put the JPEG 422 header */
76dd272b 2851 gspca_frame_add(gspca_dev, FIRST_PACKET,
71cb2764 2852 sd->jpeg_hdr, JPEG_HDR_SZ);
6a7eba24 2853 }
76dd272b 2854 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
6a7eba24
JFM
2855}
2856
6a7eba24
JFM
2857static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2858{
2859 struct sd *sd = (struct sd *) gspca_dev;
2860
2861 sd->brightness = val;
91bd3412
JFM
2862 if (gspca_dev->streaming)
2863 setbrightness(gspca_dev);
4bf8b679 2864 return gspca_dev->usb_err;
6a7eba24
JFM
2865}
2866
2867static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2868{
2869 struct sd *sd = (struct sd *) gspca_dev;
2870
6a7eba24
JFM
2871 *val = sd->brightness;
2872 return 0;
2873}
2874
2875static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2876{
2877 struct sd *sd = (struct sd *) gspca_dev;
2878
2879 sd->contrast = val;
91bd3412
JFM
2880 if (gspca_dev->streaming)
2881 setcontrast(gspca_dev);
4bf8b679 2882 return gspca_dev->usb_err;
6a7eba24
JFM
2883}
2884
2885static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2886{
2887 struct sd *sd = (struct sd *) gspca_dev;
2888
2889 *val = sd->contrast;
2890 return 0;
2891}
2892
2893static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2894{
2895 struct sd *sd = (struct sd *) gspca_dev;
2896
2897 sd->colors = val;
2898 if (gspca_dev->streaming)
2899 setcolors(gspca_dev);
4bf8b679 2900 return gspca_dev->usb_err;
6a7eba24
JFM
2901}
2902
2903static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2904{
2905 struct sd *sd = (struct sd *) gspca_dev;
2906
2907 *val = sd->colors;
2908 return 0;
2909}
2910
403123d2
JFM
2911static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2912{
2913 struct sd *sd = (struct sd *) gspca_dev;
2914
2915 sd->blue = val;
2916 if (gspca_dev->streaming)
2917 setredblue(gspca_dev);
4bf8b679 2918 return gspca_dev->usb_err;
403123d2
JFM
2919}
2920
2921static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2922{
2923 struct sd *sd = (struct sd *) gspca_dev;
2924
2925 *val = sd->blue;
2926 return 0;
2927}
2928
2929static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2930{
2931 struct sd *sd = (struct sd *) gspca_dev;
2932
2933 sd->red = val;
2934 if (gspca_dev->streaming)
2935 setredblue(gspca_dev);
4bf8b679 2936 return gspca_dev->usb_err;
403123d2
JFM
2937}
2938
2939static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2940{
2941 struct sd *sd = (struct sd *) gspca_dev;
2942
2943 *val = sd->red;
2944 return 0;
2945}
2946
592f4eb9
JFM
2947static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2948{
2949 struct sd *sd = (struct sd *) gspca_dev;
2950
2951 sd->gamma = val;
2952 if (gspca_dev->streaming)
2953 setgamma(gspca_dev);
4bf8b679 2954 return gspca_dev->usb_err;
592f4eb9
JFM
2955}
2956
2957static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2958{
2959 struct sd *sd = (struct sd *) gspca_dev;
2960
2961 *val = sd->gamma;
2962 return 0;
2963}
2964
6a7eba24
JFM
2965static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2966{
2967 struct sd *sd = (struct sd *) gspca_dev;
2968
2969 sd->autogain = val;
cebf3b67
JFM
2970 if (gspca_dev->streaming)
2971 setautogain(gspca_dev);
4bf8b679 2972 return gspca_dev->usb_err;
6a7eba24
JFM
2973}
2974
2975static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2976{
2977 struct sd *sd = (struct sd *) gspca_dev;
2978
2979 *val = sd->autogain;
2980 return 0;
2981}
2982
878b35ae
JFM
2983static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2984{
2985 struct sd *sd = (struct sd *) gspca_dev;
2986
2987 sd->sharpness = val;
2988 if (gspca_dev->streaming)
2989 setsharpness(sd);
4bf8b679 2990 return gspca_dev->usb_err;
878b35ae
JFM
2991}
2992
2993static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2994{
2995 struct sd *sd = (struct sd *) gspca_dev;
2996
2997 *val = sd->sharpness;
2998 return 0;
2999}
3000
6c86274f
JFM
3001static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
3002{
3003 struct sd *sd = (struct sd *) gspca_dev;
3004
3005 sd->vflip = val;
79a9098a
JFM
3006 if (gspca_dev->streaming)
3007 setvflip(sd);
4bf8b679 3008 return gspca_dev->usb_err;
6c86274f
JFM
3009}
3010
3011static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
3012{
3013 struct sd *sd = (struct sd *) gspca_dev;
3014
3015 *val = sd->vflip;
3016 return 0;
3017}
3018
0cae8964
JFM
3019static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
3020{
3021 struct sd *sd = (struct sd *) gspca_dev;
3022
3023 sd->infrared = val;
3024 if (gspca_dev->streaming)
3025 setinfrared(sd);
4bf8b679 3026 return gspca_dev->usb_err;
0cae8964
JFM
3027}
3028
3029static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
3030{
3031 struct sd *sd = (struct sd *) gspca_dev;
3032
3033 *val = sd->infrared;
3034 return 0;
3035}
3036
37c6dbe2
HG
3037static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
3038{
3039 struct sd *sd = (struct sd *) gspca_dev;
3040
3041 sd->freq = val;
3042 if (gspca_dev->streaming)
3043 setfreq(gspca_dev);
4bf8b679 3044 return gspca_dev->usb_err;
37c6dbe2
HG
3045}
3046
3047static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
3048{
3049 struct sd *sd = (struct sd *) gspca_dev;
3050
3051 *val = sd->freq;
3052 return 0;
3053}
3054
77ac0baf
JFM
3055static int sd_set_jcomp(struct gspca_dev *gspca_dev,
3056 struct v4l2_jpegcompression *jcomp)
3057{
3058 struct sd *sd = (struct sd *) gspca_dev;
3059
3060 if (jcomp->quality < QUALITY_MIN)
3061 sd->quality = QUALITY_MIN;
3062 else if (jcomp->quality > QUALITY_MAX)
3063 sd->quality = QUALITY_MAX;
3064 else
3065 sd->quality = jcomp->quality;
3066 if (gspca_dev->streaming)
3067 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
3068 return 0;
3069}
3070
3071static int sd_get_jcomp(struct gspca_dev *gspca_dev,
3072 struct v4l2_jpegcompression *jcomp)
3073{
3074 struct sd *sd = (struct sd *) gspca_dev;
3075
3076 memset(jcomp, 0, sizeof *jcomp);
3077 jcomp->quality = sd->quality;
3078 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
3079 | V4L2_JPEG_MARKER_DQT;
3080 return 0;
3081}
3082
37c6dbe2
HG
3083static int sd_querymenu(struct gspca_dev *gspca_dev,
3084 struct v4l2_querymenu *menu)
3085{
3086 switch (menu->id) {
3087 case V4L2_CID_POWER_LINE_FREQUENCY:
3088 switch (menu->index) {
3089 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
3090 strcpy((char *) menu->name, "NoFliker");
3091 return 0;
3092 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
3093 strcpy((char *) menu->name, "50 Hz");
3094 return 0;
3095 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
3096 strcpy((char *) menu->name, "60 Hz");
3097 return 0;
3098 }
3099 break;
3100 }
3101 return -EINVAL;
3102}
3103
2856643e 3104#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
9712a8be
HG
3105static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
3106 u8 *data, /* interrupt packet data */
3107 int len) /* interrupt packet length */
3108{
3109 int ret = -EINVAL;
3110
3111 if (len == 1 && data[0] == 1) {
3112 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
3113 input_sync(gspca_dev->input_dev);
3114 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
3115 input_sync(gspca_dev->input_dev);
3116 ret = 0;
3117 }
3118
3119 return ret;
3120}
3121#endif
3122
6a7eba24 3123/* sub-driver description */
a5ae2062 3124static const struct sd_desc sd_desc = {
6a7eba24
JFM
3125 .name = MODULE_NAME,
3126 .ctrls = sd_ctrls,
3127 .nctrls = ARRAY_SIZE(sd_ctrls),
3128 .config = sd_config,
012d6b02 3129 .init = sd_init,
6a7eba24
JFM
3130 .start = sd_start,
3131 .stopN = sd_stopN,
6a7eba24 3132 .pkt_scan = sd_pkt_scan,
cebf3b67 3133 .dq_callback = do_autogain,
77ac0baf
JFM
3134 .get_jcomp = sd_get_jcomp,
3135 .set_jcomp = sd_set_jcomp,
37c6dbe2 3136 .querymenu = sd_querymenu,
2856643e 3137#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
9712a8be
HG
3138 .int_pkt_scan = sd_int_pkt_scan,
3139#endif
6a7eba24
JFM
3140};
3141
3142/* -- module initialisation -- */
d5aa3856 3143#define BS(bridge, sensor) \
9d64fdb1 3144 .driver_info = (BRIDGE_ ## bridge << 16) \
d5aa3856 3145 | SENSOR_ ## sensor
a5ae2062 3146static const __devinitdata struct usb_device_id device_table[] = {
222a07ff 3147#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
d5aa3856
JFM
3148 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
3149 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
a08d81af 3150#endif
d5aa3856
JFM
3151 {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
3152 {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
3153 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
3154 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
3155 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
3156 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
3157 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
3158/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
3159 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
3160/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
3161/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
3162 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
3163/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
3164 {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
a067db84 3165 /* or MT9V111 */
d5aa3856
JFM
3166/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
3167/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
3168/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
c4f95d84 3169 {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
d5aa3856
JFM
3170 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
3171/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3172/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
6804675e 3173/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
d5aa3856 3174 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
3c41cb77 3175#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
d5aa3856
JFM
3176 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3177 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
3c41cb77 3178#endif
d5aa3856 3179 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
860e7f47 3180 {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
d5aa3856
JFM
3181/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3182 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
3183 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
3184 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
3185 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
3186/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3187/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3188/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3189 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
d2d16e90 3190/*bw600.inf:*/
b8c8a5bf 3191 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
2a3b501f 3192 {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
d5aa3856
JFM
3193 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3194 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3195/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
222a07ff 3196#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
d5aa3856 3197 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
a067db84 3198 /* or MT9V111 / MI0360B */
222a07ff 3199#endif
d5aa3856
JFM
3200/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3201 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3202 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
222a07ff 3203#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
d5aa3856 3204 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
8d97770a 3205#endif
d5aa3856
JFM
3206 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3207 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
ad98c0f6 3208 {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
6804675e 3209 /* or GC0305 / GC0307 */
d5aa3856
JFM
3210 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
3211 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
64677573 3212 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
6a7eba24
JFM
3213 {}
3214};
3215MODULE_DEVICE_TABLE(usb, device_table);
3216
3217/* -- device connect -- */
3218static int sd_probe(struct usb_interface *intf,
3219 const struct usb_device_id *id)
3220{
3221 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3222 THIS_MODULE);
3223}
3224
3225static struct usb_driver sd_driver = {
3226 .name = MODULE_NAME,
3227 .id_table = device_table,
3228 .probe = sd_probe,
3229 .disconnect = gspca_disconnect,
6a709749
JFM
3230#ifdef CONFIG_PM
3231 .suspend = gspca_suspend,
3232 .resume = gspca_resume,
3233#endif
6a7eba24
JFM
3234};
3235
3236/* -- module insert / remove -- */
3237static int __init sd_mod_init(void)
3238{
54826437 3239 return usb_register(&sd_driver);
6a7eba24
JFM
3240}
3241static void __exit sd_mod_exit(void)
3242{
3243 usb_deregister(&sd_driver);
6a7eba24
JFM
3244}
3245
3246module_init(sd_mod_init);
3247module_exit(sd_mod_exit);
This page took 0.643071 seconds and 5 git commands to generate.