V4L/DVB (11035): mt9t031 bugfix
[deliverable/linux.git] / drivers / media / video / gspca / sonixj.c
CommitLineData
6a7eba24
JFM
1/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#define MODULE_NAME "sonixj"
23
24#include "gspca.h"
36e819db 25#define QUANT_VAL 4 /* quantization table */
6a7eba24
JFM
26#include "jpeg.h"
27
0cae8964
JFM
28#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29
6a7eba24
JFM
30MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
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 */
3ef2c5be 49 u8 infrared; /* mt9v111 only */
6a7eba24 50
98819187 51 s8 ag_cnt;
6a7eba24
JFM
52#define AG_CNT_START 13
53
98819187 54 u8 bridge;
3647fea8
HG
55#define BRIDGE_SN9C102P 0
56#define BRIDGE_SN9C105 1
57#define BRIDGE_SN9C110 2
58#define BRIDGE_SN9C120 3
59#define BRIDGE_SN9C325 4
98819187 60 u8 sensor; /* Type of image sensor chip */
6a7eba24
JFM
61#define SENSOR_HV7131R 0
62#define SENSOR_MI0360 1
63#define SENSOR_MO4000 2
3ef2c5be
JFM
64#define SENSOR_MT9V111 3
65#define SENSOR_OM6802 4
66#define SENSOR_OV7630 5
67#define SENSOR_OV7648 6
68#define SENSOR_OV7660 7
5e31dc8d 69#define SENSOR_SP80708 8
98819187 70 u8 i2c_base;
6a7eba24
JFM
71};
72
73/* V4L2 controls supported by the driver */
74static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
403123d2
JFM
80static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
592f4eb9
JFM
84static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
6a7eba24
JFM
86static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
6c86274f
JFM
88static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
0cae8964
JFM
90static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
6a7eba24
JFM
92
93static struct ctrl sd_ctrls[] = {
6a7eba24
JFM
94 {
95 {
96 .id = V4L2_CID_BRIGHTNESS,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Brightness",
99 .minimum = 0,
05b809c7
JFM
100#define BRIGHTNESS_MAX 0xffff
101 .maximum = BRIGHTNESS_MAX,
6a7eba24 102 .step = 1,
b1b056a5 103#define BRIGHTNESS_DEF 0x8000
a5ae2062 104 .default_value = BRIGHTNESS_DEF,
6a7eba24
JFM
105 },
106 .set = sd_setbrightness,
107 .get = sd_getbrightness,
108 },
6a7eba24
JFM
109 {
110 {
111 .id = V4L2_CID_CONTRAST,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Contrast",
114 .minimum = 0,
05b809c7
JFM
115#define CONTRAST_MAX 127
116 .maximum = CONTRAST_MAX,
6a7eba24 117 .step = 1,
a5ae2062
JFM
118#define CONTRAST_DEF 63
119 .default_value = CONTRAST_DEF,
6a7eba24
JFM
120 },
121 .set = sd_setcontrast,
122 .get = sd_getcontrast,
123 },
6a7eba24
JFM
124 {
125 {
126 .id = V4L2_CID_SATURATION,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Color",
129 .minimum = 0,
403123d2 130 .maximum = 40,
6a7eba24 131 .step = 1,
9c5f70f2 132#define COLOR_DEF 32
a5ae2062 133 .default_value = COLOR_DEF,
6a7eba24
JFM
134 },
135 .set = sd_setcolors,
136 .get = sd_getcolors,
137 },
403123d2
JFM
138 {
139 {
140 .id = V4L2_CID_BLUE_BALANCE,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Blue Balance",
143 .minimum = 24,
144 .maximum = 40,
145 .step = 1,
146#define BLUE_BALANCE_DEF 32
147 .default_value = BLUE_BALANCE_DEF,
148 },
149 .set = sd_setblue_balance,
150 .get = sd_getblue_balance,
151 },
152 {
153 {
154 .id = V4L2_CID_RED_BALANCE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Red Balance",
157 .minimum = 24,
158 .maximum = 40,
159 .step = 1,
160#define RED_BALANCE_DEF 32
161 .default_value = RED_BALANCE_DEF,
162 },
163 .set = sd_setred_balance,
164 .get = sd_getred_balance,
165 },
592f4eb9
JFM
166 {
167 {
168 .id = V4L2_CID_GAMMA,
169 .type = V4L2_CTRL_TYPE_INTEGER,
170 .name = "Gamma",
171 .minimum = 0,
172 .maximum = 40,
173 .step = 1,
174#define GAMMA_DEF 20
175 .default_value = GAMMA_DEF,
176 },
177 .set = sd_setgamma,
178 .get = sd_getgamma,
179 },
403123d2 180#define AUTOGAIN_IDX 5
6a7eba24
JFM
181 {
182 {
183 .id = V4L2_CID_AUTOGAIN,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
185 .name = "Auto Gain",
186 .minimum = 0,
187 .maximum = 1,
188 .step = 1,
a5ae2062
JFM
189#define AUTOGAIN_DEF 1
190 .default_value = AUTOGAIN_DEF,
6a7eba24
JFM
191 },
192 .set = sd_setautogain,
193 .get = sd_getautogain,
194 },
2797ba2a 195/* ov7630/ov7648 only */
403123d2 196#define VFLIP_IDX 6
6c86274f
JFM
197 {
198 {
199 .id = V4L2_CID_VFLIP,
200 .type = V4L2_CTRL_TYPE_BOOLEAN,
201 .name = "Vflip",
202 .minimum = 0,
203 .maximum = 1,
204 .step = 1,
2797ba2a 205#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
6c86274f
JFM
206 .default_value = VFLIP_DEF,
207 },
208 .set = sd_setvflip,
209 .get = sd_getvflip,
210 },
3ef2c5be 211/* mt9v111 only */
403123d2 212#define INFRARED_IDX 7
0cae8964
JFM
213 {
214 {
215 .id = V4L2_CID_INFRARED,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "Infrared",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221#define INFRARED_DEF 0
222 .default_value = INFRARED_DEF,
223 },
224 .set = sd_setinfrared,
225 .get = sd_getinfrared,
226 },
6a7eba24
JFM
227};
228
577cbf49
JFM
229/* table of the disabled controls */
230static __u32 ctrl_dis[] = {
231 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
232 /* SENSOR_HV7131R 0 */
3ef2c5be 233 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
577cbf49
JFM
234 /* SENSOR_MI0360 1 */
235 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
236 /* SENSOR_MO4000 2 */
c33c02ed 237 (1 << VFLIP_IDX),
3ef2c5be 238 /* SENSOR_MT9V111 3 */
577cbf49 239 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
3ef2c5be 240 /* SENSOR_OM6802 4 */
577cbf49 241 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
3ef2c5be 242 /* SENSOR_OV7630 5 */
2797ba2a 243 (1 << INFRARED_IDX),
3ef2c5be 244 /* SENSOR_OV7648 6 */
577cbf49 245 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
3ef2c5be 246 /* SENSOR_OV7660 7 */
5e31dc8d
JFM
247 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
248 /* SENSOR_SP80708 8 */
577cbf49
JFM
249};
250
cc611b8a 251static const struct v4l2_pix_format vga_mode[] = {
c2446b3e
JFM
252 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
253 .bytesperline = 160,
5d05294a 254 .sizeimage = 160 * 120 * 4 / 8 + 590,
c2446b3e
JFM
255 .colorspace = V4L2_COLORSPACE_JPEG,
256 .priv = 2},
257 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
258 .bytesperline = 320,
259 .sizeimage = 320 * 240 * 3 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
261 .priv = 1},
262 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
263 .bytesperline = 640,
264 .sizeimage = 640 * 480 * 3 / 8 + 590,
265 .colorspace = V4L2_COLORSPACE_JPEG,
266 .priv = 0},
6a7eba24
JFM
267};
268
8c2ba441
JFM
269/*Data from sn9c102p+hv7131r */
270static const u8 sn_hv7131[0x1c] = {
8f47a3ce
JFM
271/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
272 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
273/* reg8 reg9 rega regb regc regd rege regf */
274 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
275/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
276 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
8c2ba441
JFM
277/* reg18 reg19 reg1a reg1b */
278 0x0a, 0x00, 0x00, 0x00
6a7eba24
JFM
279};
280
8c2ba441 281static const u8 sn_mi0360[0x1c] = {
8f47a3ce
JFM
282/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
283 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
284/* reg8 reg9 rega regb regc regd rege regf */
285 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
286/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
287 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
8c2ba441
JFM
288/* reg18 reg19 reg1a reg1b */
289 0x06, 0x00, 0x00, 0x00
6a7eba24
JFM
290};
291
8c2ba441 292static const u8 sn_mo4000[0x1c] = {
8f47a3ce 293/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
8c2ba441 294 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
8f47a3ce
JFM
295/* reg8 reg9 rega regb regc regd rege regf */
296 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
298 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
8c2ba441
JFM
299/* reg18 reg19 reg1a reg1b */
300 0x08, 0x00, 0x00, 0x00
6a7eba24
JFM
301};
302
3ef2c5be
JFM
303static const u8 sn_mt9v111[0x1c] = {
304/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
306/* reg8 reg9 rega regb regc regd rege regf */
307 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
308/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
310/* reg18 reg19 reg1a reg1b */
311 0x06, 0x00, 0x00, 0x00
312};
313
8c2ba441 314static const u8 sn_om6802[0x1c] = {
d2d16e90
JFM
315/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
317/* reg8 reg9 rega regb regc regd rege regf */
318 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
8c2ba441
JFM
321/* reg18 reg19 reg1a reg1b */
322 0x05, 0x00, 0x00, 0x00
d2d16e90
JFM
323};
324
8c2ba441 325static const u8 sn_ov7630[0x1c] = {
6ab0b174
JFM
326/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
327 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
328/* reg8 reg9 rega regb regc regd rege regf */
329 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
330/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
331 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
8c2ba441
JFM
332/* reg18 reg19 reg1a reg1b */
333 0x0b, 0x00, 0x00, 0x00
6ab0b174
JFM
334};
335
8c2ba441 336static const u8 sn_ov7648[0x1c] = {
8f47a3ce 337/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
6270330a 338 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
8f47a3ce 339/* reg8 reg9 rega regb regc regd rege regf */
6270330a 340 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
8f47a3ce 341/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
6270330a 342 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
8c2ba441
JFM
343/* reg18 reg19 reg1a reg1b */
344 0x0b, 0x00, 0x00, 0x00
6a7eba24
JFM
345};
346
8c2ba441 347static const u8 sn_ov7660[0x1c] = {
8f47a3ce
JFM
348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
350/* reg8 reg9 rega regb regc regd rege regf */
351 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
352/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
353 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
8c2ba441
JFM
354/* reg18 reg19 reg1a reg1b */
355 0x07, 0x00, 0x00, 0x00
6a7eba24
JFM
356};
357
5e31dc8d
JFM
358static const u8 sn_sp80708[0x1c] = {
359/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
361/* reg8 reg9 rega regb regc regd rege regf */
362 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
363/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
365/* reg18 reg19 reg1a reg1b */
366 0x07, 0x00, 0x00, 0x00
367};
368
6a7eba24 369/* sequence specific to the sensors - !! index = SENSOR_xxx */
8c2ba441 370static const u8 *sn_tb[] = {
6a7eba24
JFM
371 sn_hv7131,
372 sn_mi0360,
373 sn_mo4000,
3ef2c5be 374 sn_mt9v111,
d2d16e90 375 sn_om6802,
6ab0b174 376 sn_ov7630,
6a7eba24 377 sn_ov7648,
5e31dc8d
JFM
378 sn_ov7660,
379 sn_sp80708
6a7eba24
JFM
380};
381
b083b92f 382/* default gamma table */
98819187 383static const u8 gamma_def[17] = {
6a7eba24
JFM
384 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
385 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
386};
b083b92f
JFM
387/* gamma for sensors HV7131R and MT9V111 */
388static const u8 gamma_spec_1[17] = {
389 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
390 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
391};
392/* gamma for sensor SP80708 */
393static const u8 gamma_spec_2[17] = {
394 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
395 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
396};
592f4eb9 397
803f9ccf 398/* color matrix and offsets */
98819187 399static const u8 reg84[] = {
803f9ccf
JFM
400 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
401 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
402 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
403 0x00, 0x00, 0x00 /* YUV offsets */
6a7eba24 404};
98819187 405static const u8 hv7131r_sensor_init[][8] = {
8c2ba441
JFM
406 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
407 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
408 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
409/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
410 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
411 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
412/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
413
414 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
416 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
417 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
418 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
419 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
420 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
421 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
422
423 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
428
429 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
a5ae2062 434 {}
6a7eba24 435};
98819187 436static const u8 mi0360_sensor_init[][8] = {
8c2ba441 437 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
98819187 438 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
3ef2c5be 439 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
8c2ba441
JFM
440 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
441 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
442 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
443 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
444 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
449 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
454 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
456 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
98819187 459 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
8c2ba441
JFM
460 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
462 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
463 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
464 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
465 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
466 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
469 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
470
471 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
472 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
473 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
474 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
475 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
476
477 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
478 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
479 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
480 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
481
482 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
483 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
484/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
485/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
486 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
487 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
a5ae2062 488 {}
6a7eba24 489};
98819187 490static const u8 mo4000_sensor_init[][8] = {
6a7eba24
JFM
491 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
502 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
503 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
504 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
505 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
506 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
508 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
509 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
510 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
a5ae2062 511 {}
6a7eba24 512};
3ef2c5be
JFM
513static const u8 mt9v111_sensor_init[][8] = {
514 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
515 /* delay 20 ms */
516 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
518 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
519 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
2687a2fb
JFM
520 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
521 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
522 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
523 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
3ef2c5be 524 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
2687a2fb
JFM
525 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
526 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
527 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
528 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
529 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
3ef2c5be 530 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
2687a2fb 531 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
3ef2c5be
JFM
532 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
533 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
534 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
535 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
536 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
537 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
538 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
539 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
540 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
541 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
542 /*******/
543 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
544 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
2687a2fb 545 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
3ef2c5be
JFM
546 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
547 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
548 /*******/
549 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
550 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
551 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
552 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
553 {}
554};
98819187 555static const u8 om6802_sensor_init[][8] = {
d2d16e90
JFM
556 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
557 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
558 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
559 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
560/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
561 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
562 /* white balance & auto-exposure */
563/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
564 * set color mode */
565/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
566 * max AGC value in AE */
567/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
568 * preset AGC */
569/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
570 * preset brightness */
571/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
572 * preset contrast */
573/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
574 * preset gamma */
575 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
576 /* luminance mode (0x4f = AE) */
577 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
578 /* preset shutter */
579/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
580 * auto frame rate */
581/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
582
583/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
584/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
585/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
586/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
587 {}
588};
98819187 589static const u8 ov7630_sensor_init[][8] = {
6ab0b174
JFM
590 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
591 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
592/* win: delay 20ms */
593 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
594 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
595/* win: delay 20ms */
596 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
05b809c7 597/* win: i2c_r from 00 to 80 */
6ab0b174
JFM
598 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
599 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
600 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
601 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
602 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
603 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
605 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
606 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
607 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
608 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
609 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
610 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
611 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
612 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
613 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
614 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
615 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
616 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
617 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
618 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
619 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
620 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
621 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
622 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
623 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
624/* */
625 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
627/*fixme: + 0x12, 0x04*/
6c86274f
JFM
628/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
629 * set by setvflip */
6ab0b174
JFM
630 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
631 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
632 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
05b809c7 633/* */
6ab0b174
JFM
634 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
636 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
05b809c7 637/* */
6ab0b174 638 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
91de65ac 639/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
6ab0b174
JFM
640 {}
641};
6270330a 642
98819187 643static const u8 ov7648_sensor_init[][8] = {
6270330a
JFM
644 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
645 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
646 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
647 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
648 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
649 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
650 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
651 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
652 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
653 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
654 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
655 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
656 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
657 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
658 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
659 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
660 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
661 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
662 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
663 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
664 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
665
666 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
667/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
668/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
669 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
670/*...*/
671/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
2797ba2a
JFM
672/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
673 * set by setvflip */
6270330a
JFM
674 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
675 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
676/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
677/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
678/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
679/*...*/
680 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
681/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
682/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
683/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
684/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
685/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
686
687 {}
688};
689
98819187 690static const u8 ov7660_sensor_init[][8] = {
6a7eba24 691 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
60017617 692/* (delay 20ms) */
6a7eba24 693 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
738608ae 694 /* Outformat = rawRGB */
6a7eba24 695 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
738608ae 696 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
6a7eba24
JFM
697 /* GAIN BLUE RED VREF */
698 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
699 /* COM 1 BAVE GEAVE AECHH */
700 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
701 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
738608ae 702 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
6a7eba24
JFM
703 /* AECH CLKRC COM7 COM8 */
704 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
705 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
706 /* HSTART HSTOP VSTRT VSTOP */
707 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
708 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
709 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
710 /* BOS GBOS GROS ROS (BGGR offset) */
738608ae
JFM
711/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
712 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
6a7eba24
JFM
713 /* AEW AEB VPT BBIAS */
714 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
715 /* GbBIAS RSVD EXHCH EXHCL */
716 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
717 /* RBIAS ADVFL ASDVFH YAVE */
718 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
719 /* HSYST HSYEN HREF */
720 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
721 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
722 /* ADC ACOM OFON TSLB */
723 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
724 /* COM11 COM12 COM13 COM14 */
725 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
726 /* EDGE COM15 COM16 COM17 */
727 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
728 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
729 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
730 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
731 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
732 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
733 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
734 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
735 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
736 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
737 /* LCC1 LCC2 LCC3 LCC4 */
738 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
738608ae 739 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
6a7eba24 740 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
738608ae 741 /* band gap reference [0:3] DBLV */
6a7eba24
JFM
742 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
743 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
744 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
745 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
746 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
747 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
748 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
749 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
750 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
738608ae 751 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
6a7eba24 752/****** (some exchanges in the win trace) ******/
738608ae 753 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
6a7eba24
JFM
754 /* bits[3..0]reserved */
755 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
756 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
757 /* VREF vertical frame ctrl */
758 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
738608ae
JFM
759 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
760 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
761 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
762 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
763/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
6a7eba24
JFM
764/****** (some exchanges in the win trace) ******/
765 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
738608ae
JFM
766 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
767 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
768 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
769/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
6a7eba24 770/****** (some exchanges in the win trace) ******/
738608ae 771/******!! startsensor KO if changed !!****/
6a7eba24
JFM
772 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
a5ae2062 776 {}
6a7eba24 777};
6a7eba24 778
5e31dc8d
JFM
779static const u8 sp80708_sensor_init[][8] = {
780 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
847 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
848 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
849 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
850 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
851 /********/
852 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
853 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
854 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
856 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
857 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
858 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
859 {}
860};
861
98819187
JFM
862static const u8 qtable4[] = {
863 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
864 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
865 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
866 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
867 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
868 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
869 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
870 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
871 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
872 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
873 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
874 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
875 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
876 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
877 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
878 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
6a7eba24
JFM
879};
880
8295d99e 881/* read <len> bytes to gspca_dev->usb_buf */
739570bb 882static void reg_r(struct gspca_dev *gspca_dev,
98819187 883 u16 value, int len)
6a7eba24 884{
8295d99e
JFM
885#ifdef GSPCA_DEBUG
886 if (len > USB_BUF_SZ) {
887 err("reg_r: buffer overflow");
888 return;
889 }
890#endif
739570bb
JFM
891 usb_control_msg(gspca_dev->dev,
892 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
893 0,
894 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
895 value, 0,
739570bb 896 gspca_dev->usb_buf, len,
6a7eba24 897 500);
60017617 898 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
6a7eba24
JFM
899}
900
60017617 901static void reg_w1(struct gspca_dev *gspca_dev,
98819187
JFM
902 u16 value,
903 u8 data)
60017617 904{
3ef2c5be 905 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
60017617
JFM
906 gspca_dev->usb_buf[0] = data;
907 usb_control_msg(gspca_dev->dev,
908 usb_sndctrlpipe(gspca_dev->dev, 0),
909 0x08,
910 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
911 value,
912 0,
913 gspca_dev->usb_buf, 1,
914 500);
915}
739570bb 916static void reg_w(struct gspca_dev *gspca_dev,
98819187
JFM
917 u16 value,
918 const u8 *buffer,
6a7eba24
JFM
919 int len)
920{
3ef2c5be 921 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
60017617 922 value, buffer[0], buffer[1]);
8295d99e
JFM
923#ifdef GSPCA_DEBUG
924 if (len > USB_BUF_SZ) {
925 err("reg_w: buffer overflow");
926 return;
bf7f0b98 927 }
8295d99e
JFM
928#endif
929 memcpy(gspca_dev->usb_buf, buffer, len);
930 usb_control_msg(gspca_dev->dev,
931 usb_sndctrlpipe(gspca_dev->dev, 0),
932 0x08,
933 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
934 value, 0,
935 gspca_dev->usb_buf, len,
936 500);
6a7eba24
JFM
937}
938
60017617 939/* I2C write 1 byte */
98819187 940static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
6a7eba24
JFM
941{
942 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 943
60017617
JFM
944 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
945 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
946 gspca_dev->usb_buf[1] = sd->i2c_base;
947 gspca_dev->usb_buf[2] = reg;
948 gspca_dev->usb_buf[3] = val;
949 gspca_dev->usb_buf[4] = 0;
950 gspca_dev->usb_buf[5] = 0;
951 gspca_dev->usb_buf[6] = 0;
952 gspca_dev->usb_buf[7] = 0x10;
953 usb_control_msg(gspca_dev->dev,
954 usb_sndctrlpipe(gspca_dev->dev, 0),
955 0x08,
956 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
957 0x08, /* value = i2c */
958 0,
959 gspca_dev->usb_buf, 8,
960 500);
6a7eba24
JFM
961}
962
739570bb
JFM
963/* I2C write 8 bytes */
964static void i2c_w8(struct gspca_dev *gspca_dev,
98819187 965 const u8 *buffer)
6a7eba24 966{
60017617
JFM
967 memcpy(gspca_dev->usb_buf, buffer, 8);
968 usb_control_msg(gspca_dev->dev,
969 usb_sndctrlpipe(gspca_dev->dev, 0),
970 0x08,
971 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
972 0x08, 0, /* value, index */
973 gspca_dev->usb_buf, 8,
974 500);
8d768e14 975 msleep(2);
6a7eba24
JFM
976}
977
739570bb 978/* read 5 bytes in gspca_dev->usb_buf */
98819187 979static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
6a7eba24
JFM
980{
981 struct sd *sd = (struct sd *) gspca_dev;
98819187 982 u8 mode[8];
6a7eba24 983
3647fea8 984 mode[0] = 0x81 | 0x10;
6a7eba24
JFM
985 mode[1] = sd->i2c_base;
986 mode[2] = reg;
987 mode[3] = 0;
988 mode[4] = 0;
989 mode[5] = 0;
990 mode[6] = 0;
991 mode[7] = 0x10;
739570bb 992 i2c_w8(gspca_dev, mode);
60017617 993 msleep(2);
3647fea8 994 mode[0] = 0x81 | (5 << 4) | 0x02;
6a7eba24 995 mode[2] = 0;
739570bb 996 i2c_w8(gspca_dev, mode);
60017617 997 msleep(2);
739570bb 998 reg_r(gspca_dev, 0x0a, 5);
6a7eba24
JFM
999}
1000
3ef2c5be 1001static int hv7131r_probe(struct gspca_dev *gspca_dev)
6a7eba24 1002{
60017617 1003 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
6a7eba24 1004 msleep(10);
60017617 1005 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
6a7eba24 1006 msleep(10);
739570bb
JFM
1007 i2c_r5(gspca_dev, 0); /* read sensor id */
1008 if (gspca_dev->usb_buf[0] == 0x02
1009 && gspca_dev->usb_buf[1] == 0x09
1010 && gspca_dev->usb_buf[2] == 0x01
1011 && gspca_dev->usb_buf[3] == 0x00
1012 && gspca_dev->usb_buf[4] == 0x00) {
6a7eba24 1013 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
577cbf49 1014 return 0;
6a7eba24 1015 }
60017617 1016 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
739570bb
JFM
1017 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1018 gspca_dev->usb_buf[2]);
6a7eba24
JFM
1019 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1020 return -ENODEV;
1021}
1022
65c5259c 1023static void mi0360_probe(struct gspca_dev *gspca_dev)
3ef2c5be 1024{
65c5259c 1025 struct sd *sd = (struct sd *) gspca_dev;
3ef2c5be 1026 int i, j;
92e8c91b 1027 u16 val = 0;
3ef2c5be 1028 static const u8 probe_tb[][4][8] = {
65c5259c 1029 { /* mi0360 */
3ef2c5be
JFM
1030 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1031 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1032 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1033 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1034 },
65c5259c 1035 { /* mt9v111 */
3ef2c5be
JFM
1036 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1037 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1038 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1039 {}
1040 },
1041 };
1042
1043 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1044 reg_w1(gspca_dev, 0x17, 0x62);
1045 reg_w1(gspca_dev, 0x01, 0x08);
1046 for (j = 0; j < 3; j++)
1047 i2c_w8(gspca_dev, probe_tb[i][j]);
1048 msleep(2);
1049 reg_r(gspca_dev, 0x0a, 5);
1050 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1051 if (probe_tb[i][3][0] != 0)
1052 i2c_w8(gspca_dev, probe_tb[i][3]);
1053 reg_w1(gspca_dev, 0x01, 0x29);
1054 reg_w1(gspca_dev, 0x17, 0x42);
1055 if (val != 0xffff)
1056 break;
1057 }
1058 switch (val) {
1059 case 0x823a:
1060 PDEBUG(D_PROBE, "Sensor mt9v111");
65c5259c
JFM
1061 sd->sensor = SENSOR_MT9V111;
1062 sd->i2c_base = 0x5c;
1063 break;
3ef2c5be
JFM
1064 case 0x8243:
1065 PDEBUG(D_PROBE, "Sensor mi0360");
65c5259c
JFM
1066 break;
1067 default:
1068 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1069 break;
3ef2c5be 1070 }
3ef2c5be
JFM
1071}
1072
6a7eba24 1073static int configure_gpio(struct gspca_dev *gspca_dev,
98819187 1074 const u8 *sn9c1xx)
6a7eba24
JFM
1075{
1076 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
1077 const u8 *reg9a;
1078 static const u8 reg9a_def[] =
6a7eba24 1079 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
98819187 1080 static const u8 reg9a_sn9c325[] =
6a7eba24 1081 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
98819187 1082 static const u8 regd4[] = {0x60, 0x00, 0x00};
6a7eba24 1083
60017617 1084 reg_w1(gspca_dev, 0xf1, 0x00);
05b809c7 1085 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
6a7eba24
JFM
1086
1087 /* configure gpio */
739570bb
JFM
1088 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1089 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
60017617 1090 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
3647fea8
HG
1091 switch (sd->bridge) {
1092 case BRIDGE_SN9C325:
6a7eba24
JFM
1093 reg9a = reg9a_sn9c325;
1094 break;
6a7eba24
JFM
1095 default:
1096 reg9a = reg9a_def;
1097 break;
1098 }
739570bb 1099 reg_w(gspca_dev, 0x9a, reg9a, 6);
6a7eba24 1100
8f47a3ce 1101 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
6a7eba24 1102
739570bb 1103 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
6a7eba24 1104
d2d16e90 1105 switch (sd->sensor) {
3ef2c5be
JFM
1106 case SENSOR_MT9V111:
1107 reg_w1(gspca_dev, 0x01, 0x61);
1108 reg_w1(gspca_dev, 0x17, 0x61);
1109 reg_w1(gspca_dev, 0x01, 0x60);
1110 reg_w1(gspca_dev, 0x01, 0x40);
1111 break;
d2d16e90 1112 case SENSOR_OM6802:
4f30f6cf 1113 reg_w1(gspca_dev, 0x02, 0x71);
d2d16e90
JFM
1114 reg_w1(gspca_dev, 0x01, 0x42);
1115 reg_w1(gspca_dev, 0x17, 0x64);
1116 reg_w1(gspca_dev, 0x01, 0x42);
1117 break;
05b809c7
JFM
1118/*jfm: from win trace */
1119 case SENSOR_OV7630:
1120 reg_w1(gspca_dev, 0x01, 0x61);
1121 reg_w1(gspca_dev, 0x17, 0xe2);
1122 reg_w1(gspca_dev, 0x01, 0x60);
1123 reg_w1(gspca_dev, 0x01, 0x40);
1124 break;
d2d16e90 1125 case SENSOR_OV7648:
6270330a
JFM
1126 reg_w1(gspca_dev, 0x01, 0x63);
1127 reg_w1(gspca_dev, 0x17, 0x20);
60017617 1128 reg_w1(gspca_dev, 0x01, 0x42);
6a7eba24 1129 break;
91de65ac
JFM
1130/*jfm: from win trace */
1131 case SENSOR_OV7660:
1432f306
JFM
1132 if (sd->bridge == BRIDGE_SN9C120) {
1133 reg_w1(gspca_dev, 0x01, 0x61);
1134 reg_w1(gspca_dev, 0x17, 0x20);
1135 reg_w1(gspca_dev, 0x01, 0x60);
1136 reg_w1(gspca_dev, 0x01, 0x40);
1137 break;
1138 }
1139 /* fall thru */
5e31dc8d
JFM
1140 case SENSOR_SP80708:
1141 reg_w1(gspca_dev, 0x01, 0x63);
1142 reg_w1(gspca_dev, 0x17, 0x20);
1143 reg_w1(gspca_dev, 0x01, 0x62);
1144 reg_w1(gspca_dev, 0x01, 0x42);
1145 mdelay(100);
1146 reg_w1(gspca_dev, 0x02, 0x62);
1147 break;
6a7eba24 1148 default:
60017617
JFM
1149 reg_w1(gspca_dev, 0x01, 0x43);
1150 reg_w1(gspca_dev, 0x17, 0x61);
1151 reg_w1(gspca_dev, 0x01, 0x42);
d2d16e90 1152 if (sd->sensor == SENSOR_HV7131R) {
3ef2c5be 1153 if (hv7131r_probe(gspca_dev) < 0)
d2d16e90
JFM
1154 return -ENODEV;
1155 }
1156 break;
6a7eba24
JFM
1157 }
1158 return 0;
1159}
1160
1161static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1162{
1163 int i = 0;
98819187 1164 static const u8 SetSensorClk[] = /* 0x08 Mclk */
6a7eba24
JFM
1165 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1166
1167 while (hv7131r_sensor_init[i][0]) {
739570bb 1168 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
6a7eba24
JFM
1169 i++;
1170 }
739570bb 1171 i2c_w8(gspca_dev, SetSensorClk);
6a7eba24
JFM
1172}
1173
1174static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1175{
1176 int i = 0;
6a7eba24
JFM
1177
1178 while (mi0360_sensor_init[i][0]) {
739570bb 1179 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
6a7eba24
JFM
1180 i++;
1181 }
1182}
1183
1184static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1185{
1186 int i = 0;
6a7eba24
JFM
1187
1188 while (mo4000_sensor_init[i][0]) {
739570bb 1189 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
6a7eba24
JFM
1190 i++;
1191 }
1192}
1193
3ef2c5be
JFM
1194static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1195{
1196 int i = 0;
1197
1198 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1199 i++;
1200 msleep(20);
1201 while (mt9v111_sensor_init[i][0]) {
1202 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1203 i++;
1204 }
1205}
1206
d2d16e90
JFM
1207static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1208{
1209 int i = 0;
1210
1211 while (om6802_sensor_init[i][0]) {
1212 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1213 i++;
1214 }
1215}
1216
6ab0b174
JFM
1217static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1218{
1219 int i = 0;
1220
05b809c7
JFM
1221 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1222 i++;
1223 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
6ab0b174
JFM
1224 i++;
1225 msleep(20);
05b809c7
JFM
1226 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1227 i++;
1228 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1229 i++;
1230 msleep(20);
1231 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1232 i++;
1233/*jfm:win i2c_r from 00 to 80*/
1234
6ab0b174
JFM
1235 while (ov7630_sensor_init[i][0]) {
1236 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1237 i++;
1238 }
1239}
1240
6a7eba24
JFM
1241static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1242{
6a7eba24
JFM
1243 int i = 0;
1244
6270330a
JFM
1245 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1246 i++;
1247/* win: dble reset */
1248 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1249 i++;
1250 msleep(20);
1251/* win: i2c reg read 00..7f */
6a7eba24 1252 while (ov7648_sensor_init[i][0]) {
739570bb 1253 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
6a7eba24
JFM
1254 i++;
1255 }
1256}
1257
1258static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1259{
1260 int i = 0;
6a7eba24 1261
60017617
JFM
1262 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1263 i++;
1264 msleep(20);
6a7eba24 1265 while (ov7660_sensor_init[i][0]) {
739570bb 1266 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
6a7eba24
JFM
1267 i++;
1268 }
1269}
1270
5e31dc8d
JFM
1271static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1272{
1273 int i = 0;
1274
1275 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1276 i++;
1277 msleep(20);
1278 while (sp80708_sensor_init[i][0]) {
1279 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1280 i++;
1281 }
1282}
1283
6a7eba24
JFM
1284/* this function is called at probe time */
1285static int sd_config(struct gspca_dev *gspca_dev,
1286 const struct usb_device_id *id)
1287{
1288 struct sd *sd = (struct sd *) gspca_dev;
1289 struct cam *cam;
6a7eba24
JFM
1290
1291 cam = &gspca_dev->cam;
6a7eba24
JFM
1292 cam->cam_mode = vga_mode;
1293 cam->nmodes = ARRAY_SIZE(vga_mode);
a5ae2062 1294
9d64fdb1
JFM
1295 sd->bridge = id->driver_info >> 16;
1296 sd->sensor = id->driver_info >> 8;
1297 sd->i2c_base = id->driver_info;
1298
a5ae2062
JFM
1299 sd->brightness = BRIGHTNESS_DEF;
1300 sd->contrast = CONTRAST_DEF;
1301 sd->colors = COLOR_DEF;
403123d2
JFM
1302 sd->blue = BLUE_BALANCE_DEF;
1303 sd->red = RED_BALANCE_DEF;
592f4eb9 1304 sd->gamma = GAMMA_DEF;
a5ae2062 1305 sd->autogain = AUTOGAIN_DEF;
cebf3b67 1306 sd->ag_cnt = -1;
2797ba2a
JFM
1307 if (sd->sensor != SENSOR_OV7630)
1308 sd->vflip = 0;
1309 else
1310 sd->vflip = 1;
0cae8964 1311 sd->infrared = INFRARED_DEF;
cebf3b67 1312
577cbf49 1313 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
6a7eba24
JFM
1314 return 0;
1315}
1316
012d6b02
JFM
1317/* this function is called at probe and resume time */
1318static int sd_init(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1319{
1320 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
1321 u8 regGpio[] = { 0x29, 0x74 };
1322 u8 regF1;
6a7eba24 1323
3647fea8 1324 /* setup a selector by bridge */
60017617 1325 reg_w1(gspca_dev, 0xf1, 0x01);
739570bb 1326 reg_r(gspca_dev, 0x00, 1);
8f47a3ce
JFM
1327 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1328 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
739570bb 1329 regF1 = gspca_dev->usb_buf[0];
8f47a3ce 1330 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
3647fea8
HG
1331 switch (sd->bridge) {
1332 case BRIDGE_SN9C102P:
6a7eba24
JFM
1333 if (regF1 != 0x11)
1334 return -ENODEV;
60017617 1335 reg_w1(gspca_dev, 0x02, regGpio[1]);
6a7eba24 1336 break;
3647fea8 1337 case BRIDGE_SN9C105:
6a7eba24
JFM
1338 if (regF1 != 0x11)
1339 return -ENODEV;
65c5259c
JFM
1340 if (sd->sensor == SENSOR_MI0360)
1341 mi0360_probe(gspca_dev);
674cbc69 1342 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24 1343 break;
3647fea8 1344 case BRIDGE_SN9C120:
6a7eba24
JFM
1345 if (regF1 != 0x12)
1346 return -ENODEV;
65c5259c
JFM
1347 if (sd->sensor == SENSOR_MI0360)
1348 mi0360_probe(gspca_dev);
6a7eba24 1349 regGpio[1] = 0x70;
674cbc69 1350 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24
JFM
1351 break;
1352 default:
60017617 1353/* case BRIDGE_SN9C110: */
3647fea8 1354/* case BRIDGE_SN9C325: */
6a7eba24
JFM
1355 if (regF1 != 0x12)
1356 return -ENODEV;
60017617 1357 reg_w1(gspca_dev, 0x02, 0x62);
6a7eba24
JFM
1358 break;
1359 }
1360
759aa3c2 1361 reg_w1(gspca_dev, 0xf1, 0x01);
6a7eba24
JFM
1362
1363 return 0;
1364}
1365
98819187
JFM
1366static u32 setexposure(struct gspca_dev *gspca_dev,
1367 u32 expo)
6a7eba24
JFM
1368{
1369 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24
JFM
1370
1371 switch (sd->sensor) {
1372 case SENSOR_HV7131R: {
98819187 1373 u8 Expodoit[] =
6a7eba24
JFM
1374 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1375
1376 Expodoit[3] = expo >> 16;
1377 Expodoit[4] = expo >> 8;
1378 Expodoit[5] = expo;
739570bb 1379 i2c_w8(gspca_dev, Expodoit);
6a7eba24
JFM
1380 break;
1381 }
1382 case SENSOR_MI0360: {
3ef2c5be 1383 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
6a7eba24 1384 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
98819187
JFM
1385 static const u8 doit[] = /* update sensor */
1386 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1387 static const u8 sensorgo[] = /* sensor on */
1388 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
6a7eba24
JFM
1389
1390 if (expo > 0x0635)
1391 expo = 0x0635;
1392 else if (expo < 0x0001)
1393 expo = 0x0001;
1394 expoMi[3] = expo >> 8;
1395 expoMi[4] = expo;
739570bb
JFM
1396 i2c_w8(gspca_dev, expoMi);
1397 i2c_w8(gspca_dev, doit);
1398 i2c_w8(gspca_dev, sensorgo);
6a7eba24
JFM
1399 break;
1400 }
1401 case SENSOR_MO4000: {
98819187 1402 u8 expoMof[] =
6a7eba24 1403 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
98819187 1404 u8 expoMo10[] =
6a7eba24 1405 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
98819187
JFM
1406 static const u8 gainMo[] =
1407 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
6a7eba24
JFM
1408
1409 if (expo > 0x1fff)
1410 expo = 0x1fff;
1411 else if (expo < 0x0001)
1412 expo = 0x0001;
1413 expoMof[3] = (expo & 0x03fc) >> 2;
739570bb 1414 i2c_w8(gspca_dev, expoMof);
6a7eba24
JFM
1415 expoMo10[3] = ((expo & 0x1c00) >> 10)
1416 | ((expo & 0x0003) << 4);
739570bb
JFM
1417 i2c_w8(gspca_dev, expoMo10);
1418 i2c_w8(gspca_dev, gainMo);
3ef2c5be 1419 PDEBUG(D_FRAM, "set exposure %d",
6a7eba24
JFM
1420 ((expoMo10[3] & 0x07) << 10)
1421 | (expoMof[3] << 2)
1422 | ((expoMo10[3] & 0x30) >> 4));
1423 break;
1424 }
3ef2c5be
JFM
1425 case SENSOR_MT9V111: {
1426 u8 expo_c1[] =
1427 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1428
1429 if (expo > 0x0280)
1430 expo = 0x0280;
1431 else if (expo < 0x0040)
1432 expo = 0x0040;
1433 expo_c1[3] = expo >> 8;
1434 expo_c1[4] = expo;
1435 i2c_w8(gspca_dev, expo_c1);
1436 break;
1437 }
d2d16e90 1438 case SENSOR_OM6802: {
98819187 1439 u8 gainOm[] =
d2d16e90
JFM
1440 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1441
1442 if (expo > 0x03ff)
1443 expo = 0x03ff;
1444 if (expo < 0x0001)
1445 expo = 0x0001;
1446 gainOm[3] = expo >> 2;
1447 i2c_w8(gspca_dev, gainOm);
d55b83d3 1448 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
3ef2c5be 1449 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
d2d16e90
JFM
1450 break;
1451 }
6a7eba24
JFM
1452 }
1453 return expo;
1454}
1455
1456static void setbrightness(struct gspca_dev *gspca_dev)
1457{
1458 struct sd *sd = (struct sd *) gspca_dev;
1459 unsigned int expo;
98819187 1460 u8 k2;
6a7eba24 1461
b1b056a5 1462 k2 = ((int) sd->brightness - 0x8000) >> 10;
6a7eba24
JFM
1463 switch (sd->sensor) {
1464 case SENSOR_HV7131R:
1465 expo = sd->brightness << 4;
1466 if (expo > 0x002dc6c0)
1467 expo = 0x002dc6c0;
1468 else if (expo < 0x02a0)
1469 expo = 0x02a0;
1470 sd->exposure = setexposure(gspca_dev, expo);
1471 break;
1472 case SENSOR_MI0360:
6a7eba24
JFM
1473 case SENSOR_MO4000:
1474 expo = sd->brightness >> 4;
1475 sd->exposure = setexposure(gspca_dev, expo);
1476 break;
3ef2c5be
JFM
1477 case SENSOR_MT9V111:
1478 expo = sd->brightness >> 8;
1479 sd->exposure = setexposure(gspca_dev, expo);
1480 break;
d2d16e90
JFM
1481 case SENSOR_OM6802:
1482 expo = sd->brightness >> 6;
1483 sd->exposure = setexposure(gspca_dev, expo);
b1b056a5 1484 k2 = sd->brightness >> 11;
d2d16e90 1485 break;
6a7eba24
JFM
1486 }
1487
3ef2c5be
JFM
1488 if (sd->sensor != SENSOR_MT9V111)
1489 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
6a7eba24
JFM
1490}
1491
1492static void setcontrast(struct gspca_dev *gspca_dev)
1493{
1494 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
1495 u8 k2;
1496 u8 contrast[6];
6a7eba24 1497
91bd3412
JFM
1498 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1499 contrast[0] = (k2 + 1) / 2; /* red */
577cbf49 1500 contrast[1] = 0;
91bd3412 1501 contrast[2] = k2; /* green */
577cbf49 1502 contrast[3] = 0;
91bd3412 1503 contrast[4] = (k2 + 1) / 5; /* blue */
577cbf49
JFM
1504 contrast[5] = 0;
1505 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
6a7eba24
JFM
1506}
1507
1508static void setcolors(struct gspca_dev *gspca_dev)
1509{
1510 struct sd *sd = (struct sd *) gspca_dev;
403123d2 1511 int i, v;
98819187
JFM
1512 u8 reg8a[12]; /* U & V gains */
1513 static s16 uv[6] = { /* same as reg84 in signed decimal */
403123d2
JFM
1514 -24, -38, 64, /* UR UG UB */
1515 62, -51, -9 /* VR VG VB */
1516 };
1517 for (i = 0; i < 6; i++) {
1518 v = uv[i] * sd->colors / COLOR_DEF;
bd088835
JFM
1519 reg8a[i * 2] = v;
1520 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
d55b83d3 1521 }
bd088835 1522 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
403123d2
JFM
1523}
1524
1525static void setredblue(struct gspca_dev *gspca_dev)
1526{
1527 struct sd *sd = (struct sd *) gspca_dev;
1528
1529 reg_w1(gspca_dev, 0x05, sd->red);
9c5f70f2 1530/* reg_w1(gspca_dev, 0x07, 32); */
403123d2 1531 reg_w1(gspca_dev, 0x06, sd->blue);
6a7eba24
JFM
1532}
1533
592f4eb9
JFM
1534static void setgamma(struct gspca_dev *gspca_dev)
1535{
1536 struct sd *sd = (struct sd *) gspca_dev;
1537 int i;
1538 u8 gamma[17];
b083b92f 1539 const u8 *gamma_base;
592f4eb9
JFM
1540 static const u8 delta[17] = {
1541 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1542 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1543 };
1544
b083b92f
JFM
1545 switch (sd->sensor) {
1546 case SENSOR_HV7131R:
1547 case SENSOR_MT9V111:
1548 gamma_base = gamma_spec_1;
1549 break;
1550 case SENSOR_SP80708:
1551 gamma_base = gamma_spec_2;
1552 break;
1553 default:
1554 gamma_base = gamma_def;
1555 break;
1556 }
5e31dc8d 1557
592f4eb9 1558 for (i = 0; i < sizeof gamma; i++)
b083b92f 1559 gamma[i] = gamma_base[i]
592f4eb9
JFM
1560 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1561 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1562}
1563
cebf3b67
JFM
1564static void setautogain(struct gspca_dev *gspca_dev)
1565{
1566 struct sd *sd = (struct sd *) gspca_dev;
1567
f50ba1be
JFM
1568 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1569 return;
2797ba2a
JFM
1570 switch (sd->sensor) {
1571 case SENSOR_OV7630:
1572 case SENSOR_OV7648: {
1573 u8 comb;
1574
1575 if (sd->sensor == SENSOR_OV7630)
1576 comb = 0xc0;
1577 else
1578 comb = 0xa0;
1579 if (sd->autogain)
1580 comb |= 0x02;
1581 i2c_w1(&sd->gspca_dev, 0x13, comb);
1582 return;
1583 }
1584 }
f50ba1be
JFM
1585 if (sd->autogain)
1586 sd->ag_cnt = AG_CNT_START;
1587 else
1588 sd->ag_cnt = -1;
cebf3b67
JFM
1589}
1590
2797ba2a 1591/* ov7630/ov7648 only */
6c86274f
JFM
1592static void setvflip(struct sd *sd)
1593{
2797ba2a
JFM
1594 u8 comn;
1595
1596 if (sd->sensor == SENSOR_OV7630)
1597 comn = 0x02;
1598 else
1599 comn = 0x06;
1600 if (sd->vflip)
1601 comn |= 0x80;
1602 i2c_w1(&sd->gspca_dev, 0x75, comn);
6c86274f
JFM
1603}
1604
0cae8964
JFM
1605static void setinfrared(struct sd *sd)
1606{
1607/*fixme: different sequence for StarCam Clip and StarCam 370i */
1608/* Clip */
1609 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1610 sd->infrared ? 0x66 : 0x64);
1611}
1612
6a7eba24 1613/* -- start the camera -- */
72ab97ce 1614static int sd_start(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1615{
1616 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 1617 int i;
98819187
JFM
1618 u8 reg1, reg17, reg18;
1619 const u8 *sn9c1xx;
6a7eba24 1620 int mode;
98819187
JFM
1621 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1622 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1623 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1624 static const u8 CE_ov76xx[] =
674cbc69 1625 { 0x32, 0xdd, 0x32, 0xdd };
6a7eba24
JFM
1626
1627 sn9c1xx = sn_tb[(int) sd->sensor];
1628 configure_gpio(gspca_dev, sn9c1xx);
1629
60017617
JFM
1630 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1631 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1632 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1633 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1634 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1635 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1636 reg_w1(gspca_dev, 0xd3, 0x50);
1637 reg_w1(gspca_dev, 0xc6, 0x00);
1638 reg_w1(gspca_dev, 0xc7, 0x00);
1639 reg_w1(gspca_dev, 0xc8, 0x50);
1640 reg_w1(gspca_dev, 0xc9, 0x3c);
60017617 1641 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
6ab0b174 1642 switch (sd->sensor) {
3ef2c5be
JFM
1643 case SENSOR_MT9V111:
1644 reg17 = 0xe0;
1645 break;
6ab0b174
JFM
1646 case SENSOR_OV7630:
1647 reg17 = 0xe2;
1648 break;
1649 case SENSOR_OV7648:
6270330a 1650 reg17 = 0x20;
568788a7 1651 break;
6ab0b174
JFM
1652/*jfm: from win trace */
1653 case SENSOR_OV7660:
1432f306
JFM
1654 if (sd->bridge == BRIDGE_SN9C120) {
1655 reg17 = 0xa0;
1656 break;
1657 }
1658 /* fall thru */
568788a7 1659 default:
8f47a3ce 1660 reg17 = 0x60;
568788a7
JFM
1661 break;
1662 }
8f47a3ce 1663 reg_w1(gspca_dev, 0x17, reg17);
1432f306 1664/* set reg1 was here */
403123d2
JFM
1665 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1666 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1667 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
60017617 1668 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
b083b92f 1669
5e31dc8d
JFM
1670 setgamma(gspca_dev);
1671
05b809c7
JFM
1672 for (i = 0; i < 8; i++)
1673 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
674cbc69 1674 switch (sd->sensor) {
3ef2c5be
JFM
1675 case SENSOR_MT9V111:
1676 reg_w1(gspca_dev, 0x9a, 0x07);
1677 reg_w1(gspca_dev, 0x99, 0x59);
1678 break;
6270330a
JFM
1679 case SENSOR_OV7648:
1680 reg_w1(gspca_dev, 0x9a, 0x0a);
1681 reg_w1(gspca_dev, 0x99, 0x60);
1682 break;
5e31dc8d
JFM
1683 case SENSOR_SP80708:
1684 reg_w1(gspca_dev, 0x9a, 0x05);
1685 reg_w1(gspca_dev, 0x99, 0x59);
1686 break;
674cbc69 1687 case SENSOR_OV7660:
1432f306
JFM
1688 if (sd->bridge == BRIDGE_SN9C120) {
1689 reg_w1(gspca_dev, 0x9a, 0x05);
1690 break;
1691 }
1692 /* fall thru */
674cbc69 1693 default:
60017617
JFM
1694 reg_w1(gspca_dev, 0x9a, 0x08);
1695 reg_w1(gspca_dev, 0x99, 0x59);
674cbc69
JFM
1696 break;
1697 }
6a7eba24 1698
c2446b3e 1699 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
60017617 1700 if (mode)
1432f306 1701 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
60017617 1702 else
1432f306
JFM
1703 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1704 reg17 = 0x61; /* 0x:20: enable sensor clock */
6a7eba24
JFM
1705 switch (sd->sensor) {
1706 case SENSOR_HV7131R:
1707 hv7131R_InitSensor(gspca_dev);
6a7eba24
JFM
1708 break;
1709 case SENSOR_MI0360:
1710 mi0360_InitSensor(gspca_dev);
6a7eba24
JFM
1711 break;
1712 case SENSOR_MO4000:
1713 mo4000_InitSensor(gspca_dev);
1714 if (mode) {
1715/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1716 reg1 = 0x06; /* clk 24Mz */
1717 } else {
1718 reg17 = 0x22; /* 640 MCKSIZE */
60017617 1719/* reg1 = 0x06; * 640 clk 24Mz (done) */
6a7eba24
JFM
1720 }
1721 break;
3ef2c5be
JFM
1722 case SENSOR_MT9V111:
1723 mt9v111_InitSensor(gspca_dev);
1724 if (mode) {
1725 reg1 = 0x04; /* 320 clk 48Mhz */
1726 } else {
1727/* reg1 = 0x06; * 640 clk 24Mz (done) */
2687a2fb 1728 reg17 = 0xc2;
3ef2c5be 1729 }
0fbe0574 1730 break;
d2d16e90
JFM
1731 case SENSOR_OM6802:
1732 om6802_InitSensor(gspca_dev);
d2d16e90
JFM
1733 reg17 = 0x64; /* 640 MCKSIZE */
1734 break;
6ab0b174
JFM
1735 case SENSOR_OV7630:
1736 ov7630_InitSensor(gspca_dev);
6c86274f 1737 setvflip(sd);
6ab0b174 1738 reg17 = 0xe2;
5b064da8 1739 reg1 = 0x44;
6ab0b174 1740 break;
6a7eba24 1741 case SENSOR_OV7648:
60017617 1742 ov7648_InitSensor(gspca_dev);
6270330a
JFM
1743 reg17 = 0x21;
1744/* reg1 = 0x42; * 42 - 46? */
6a7eba24 1745 break;
5e31dc8d 1746 case SENSOR_OV7660:
6a7eba24 1747 ov7660_InitSensor(gspca_dev);
daa5cb42
JFM
1748 if (sd->bridge == BRIDGE_SN9C120) {
1749 if (mode) { /* 320x240 - 160x120 */
1432f306
JFM
1750 reg17 = 0xa2;
1751 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1432f306 1752 }
daa5cb42
JFM
1753 } else {
1754 reg17 = 0x22;
1755 reg1 = 0x06; /* 24 Mhz, video trf eneble
1756 * inverse power down */
6a7eba24
JFM
1757 }
1758 break;
5e31dc8d
JFM
1759 default:
1760/* case SENSOR_SP80708: */
1761 sp80708_InitSensor(gspca_dev);
1762 if (mode) {
1763/*?? reg1 = 0x04; * 320 clk 48Mhz */
5e31dc8d
JFM
1764 } else {
1765 reg1 = 0x46; /* 640 clk 48Mz */
1766 reg17 = 0xa2;
1767 }
1768 break;
6a7eba24 1769 }
739570bb 1770 reg_w(gspca_dev, 0xc0, C0, 6);
8f47a3ce 1771 reg_w(gspca_dev, 0xca, CA, 4);
6ab0b174
JFM
1772 switch (sd->sensor) {
1773 case SENSOR_OV7630:
1774 case SENSOR_OV7648:
674cbc69 1775 case SENSOR_OV7660:
6ab0b174 1776 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
6a7eba24
JFM
1777 break;
1778 default:
739570bb 1779 reg_w(gspca_dev, 0xce, CE, 4);
6a7eba24
JFM
1780 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1781 break;
1782 }
1783
1784 /* here change size mode 0 -> VGA; 1 -> CIF */
8f47a3ce
JFM
1785 reg18 = sn9c1xx[0x18] | (mode << 4);
1786 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
6a7eba24 1787
3ef2c5be
JFM
1788 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1789 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
6a7eba24 1790
8f47a3ce 1791 reg_w1(gspca_dev, 0x18, reg18);
6a7eba24 1792
60017617 1793 reg_w1(gspca_dev, 0x17, reg17);
1432f306 1794 reg_w1(gspca_dev, 0x01, reg1);
05b809c7 1795 switch (sd->sensor) {
79a9098a
JFM
1796 case SENSOR_OV7630:
1797 setvflip(sd);
05b809c7
JFM
1798 break;
1799 }
91bd3412
JFM
1800 setbrightness(gspca_dev);
1801 setcontrast(gspca_dev);
cebf3b67 1802 setautogain(gspca_dev);
72ab97ce 1803 return 0;
6a7eba24
JFM
1804}
1805
1806static void sd_stopN(struct gspca_dev *gspca_dev)
1807{
1808 struct sd *sd = (struct sd *) gspca_dev;
98819187 1809 static const u8 stophv7131[] =
6a7eba24 1810 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
98819187 1811 static const u8 stopmi0360[] =
6a7eba24 1812 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
98819187 1813 static const u8 stopov7648[] =
6270330a 1814 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
98819187
JFM
1815 u8 data;
1816 const u8 *sn9c1xx;
6a7eba24
JFM
1817
1818 data = 0x0b;
1819 switch (sd->sensor) {
1820 case SENSOR_HV7131R:
739570bb 1821 i2c_w8(gspca_dev, stophv7131);
6a7eba24
JFM
1822 data = 0x2b;
1823 break;
1824 case SENSOR_MI0360:
739570bb 1825 i2c_w8(gspca_dev, stopmi0360);
6a7eba24
JFM
1826 data = 0x29;
1827 break;
6a7eba24 1828 case SENSOR_OV7648:
6270330a
JFM
1829 i2c_w8(gspca_dev, stopov7648);
1830 /* fall thru */
3ef2c5be 1831 case SENSOR_MT9V111:
6270330a 1832 case SENSOR_OV7630:
6a7eba24
JFM
1833 data = 0x29;
1834 break;
1835 default:
8f47a3ce 1836/* case SENSOR_MO4000: */
6a7eba24
JFM
1837/* case SENSOR_OV7660: */
1838 break;
1839 }
1840 sn9c1xx = sn_tb[(int) sd->sensor];
60017617
JFM
1841 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1842 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1843 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1844 reg_w1(gspca_dev, 0x01, data);
759aa3c2 1845 reg_w1(gspca_dev, 0xf1, 0x00);
6a7eba24
JFM
1846}
1847
cebf3b67 1848static void do_autogain(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1849{
1850 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 1851 int delta;
cebf3b67 1852 int expotimes;
98819187
JFM
1853 u8 luma_mean = 130;
1854 u8 luma_delta = 20;
6a7eba24 1855
cebf3b67
JFM
1856 /* Thanks S., without your advice, autobright should not work :) */
1857 if (sd->ag_cnt < 0)
1858 return;
1859 if (--sd->ag_cnt >= 0)
1860 return;
1861 sd->ag_cnt = AG_CNT_START;
1862
1863 delta = atomic_read(&sd->avg_lum);
1864 PDEBUG(D_FRAM, "mean lum %d", delta);
6a7eba24
JFM
1865 if (delta < luma_mean - luma_delta ||
1866 delta > luma_mean + luma_delta) {
1867 switch (sd->sensor) {
1868 case SENSOR_HV7131R:
1869 expotimes = sd->exposure >> 8;
1870 expotimes += (luma_mean - delta) >> 4;
1871 if (expotimes < 0)
1872 expotimes = 0;
1873 sd->exposure = setexposure(gspca_dev,
1874 (unsigned int) (expotimes << 8));
1875 break;
cebf3b67
JFM
1876 default:
1877/* case SENSOR_MO4000: */
1878/* case SENSOR_MI0360: */
3ef2c5be 1879/* case SENSOR_MT9V111: */
d2d16e90 1880/* case SENSOR_OM6802: */
6a7eba24
JFM
1881 expotimes = sd->exposure;
1882 expotimes += (luma_mean - delta) >> 6;
1883 if (expotimes < 0)
1884 expotimes = 0;
1885 sd->exposure = setexposure(gspca_dev,
1886 (unsigned int) expotimes);
403123d2 1887 setredblue(gspca_dev);
6a7eba24
JFM
1888 break;
1889 }
1890 }
1891}
1892
cebf3b67
JFM
1893/* scan the URB packets */
1894/* This function is run at interrupt level. */
6a7eba24
JFM
1895static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1896 struct gspca_frame *frame, /* target */
98819187 1897 u8 *data, /* isoc packet */
6a7eba24
JFM
1898 int len) /* iso packet length */
1899{
1900 struct sd *sd = (struct sd *) gspca_dev;
1901 int sof, avg_lum;
1902
1903 sof = len - 64;
1904 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1905
1906 /* end of frame */
1907 gspca_frame_add(gspca_dev, LAST_PACKET,
1908 frame, data, sof + 2);
1909 if (sd->ag_cnt < 0)
1910 return;
6a7eba24
JFM
1911/* w1 w2 w3 */
1912/* w4 w5 w6 */
1913/* w7 w8 */
1914/* w4 */
1915 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1916/* w6 */
1917 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1918/* w2 */
1919 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1920/* w8 */
1921 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1922/* w5 */
1923 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1924 avg_lum >>= 4;
cebf3b67 1925 atomic_set(&sd->avg_lum, avg_lum);
6a7eba24
JFM
1926 return;
1927 }
1928 if (gspca_dev->last_packet_type == LAST_PACKET) {
1929
1930 /* put the JPEG 422 header */
36e819db 1931 jpeg_put_header(gspca_dev, frame, 0x21);
6a7eba24
JFM
1932 }
1933 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1934}
1935
6a7eba24
JFM
1936static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1937{
1938 struct sd *sd = (struct sd *) gspca_dev;
1939
1940 sd->brightness = val;
91bd3412
JFM
1941 if (gspca_dev->streaming)
1942 setbrightness(gspca_dev);
6a7eba24
JFM
1943 return 0;
1944}
1945
1946static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1947{
1948 struct sd *sd = (struct sd *) gspca_dev;
1949
6a7eba24
JFM
1950 *val = sd->brightness;
1951 return 0;
1952}
1953
1954static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1955{
1956 struct sd *sd = (struct sd *) gspca_dev;
1957
1958 sd->contrast = val;
91bd3412
JFM
1959 if (gspca_dev->streaming)
1960 setcontrast(gspca_dev);
6a7eba24
JFM
1961 return 0;
1962}
1963
1964static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1965{
1966 struct sd *sd = (struct sd *) gspca_dev;
1967
1968 *val = sd->contrast;
1969 return 0;
1970}
1971
1972static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1973{
1974 struct sd *sd = (struct sd *) gspca_dev;
1975
1976 sd->colors = val;
1977 if (gspca_dev->streaming)
1978 setcolors(gspca_dev);
1979 return 0;
1980}
1981
1982static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1983{
1984 struct sd *sd = (struct sd *) gspca_dev;
1985
1986 *val = sd->colors;
1987 return 0;
1988}
1989
403123d2
JFM
1990static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1991{
1992 struct sd *sd = (struct sd *) gspca_dev;
1993
1994 sd->blue = val;
1995 if (gspca_dev->streaming)
1996 setredblue(gspca_dev);
1997 return 0;
1998}
1999
2000static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2001{
2002 struct sd *sd = (struct sd *) gspca_dev;
2003
2004 *val = sd->blue;
2005 return 0;
2006}
2007
2008static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2009{
2010 struct sd *sd = (struct sd *) gspca_dev;
2011
2012 sd->red = val;
2013 if (gspca_dev->streaming)
2014 setredblue(gspca_dev);
2015 return 0;
2016}
2017
2018static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2019{
2020 struct sd *sd = (struct sd *) gspca_dev;
2021
2022 *val = sd->red;
2023 return 0;
2024}
2025
592f4eb9
JFM
2026static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2027{
2028 struct sd *sd = (struct sd *) gspca_dev;
2029
2030 sd->gamma = val;
2031 if (gspca_dev->streaming)
2032 setgamma(gspca_dev);
2033 return 0;
2034}
2035
2036static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2037{
2038 struct sd *sd = (struct sd *) gspca_dev;
2039
2040 *val = sd->gamma;
2041 return 0;
2042}
2043
6a7eba24
JFM
2044static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2045{
2046 struct sd *sd = (struct sd *) gspca_dev;
2047
2048 sd->autogain = val;
cebf3b67
JFM
2049 if (gspca_dev->streaming)
2050 setautogain(gspca_dev);
6a7eba24
JFM
2051 return 0;
2052}
2053
2054static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2055{
2056 struct sd *sd = (struct sd *) gspca_dev;
2057
2058 *val = sd->autogain;
2059 return 0;
2060}
2061
6c86274f
JFM
2062static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2063{
2064 struct sd *sd = (struct sd *) gspca_dev;
2065
2066 sd->vflip = val;
79a9098a
JFM
2067 if (gspca_dev->streaming)
2068 setvflip(sd);
6c86274f
JFM
2069 return 0;
2070}
2071
2072static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2073{
2074 struct sd *sd = (struct sd *) gspca_dev;
2075
2076 *val = sd->vflip;
2077 return 0;
2078}
2079
0cae8964
JFM
2080static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2081{
2082 struct sd *sd = (struct sd *) gspca_dev;
2083
2084 sd->infrared = val;
2085 if (gspca_dev->streaming)
2086 setinfrared(sd);
2087 return 0;
2088}
2089
2090static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2091{
2092 struct sd *sd = (struct sd *) gspca_dev;
2093
2094 *val = sd->infrared;
2095 return 0;
2096}
2097
6a7eba24 2098/* sub-driver description */
a5ae2062 2099static const struct sd_desc sd_desc = {
6a7eba24
JFM
2100 .name = MODULE_NAME,
2101 .ctrls = sd_ctrls,
2102 .nctrls = ARRAY_SIZE(sd_ctrls),
2103 .config = sd_config,
012d6b02 2104 .init = sd_init,
6a7eba24
JFM
2105 .start = sd_start,
2106 .stopN = sd_stopN,
6a7eba24 2107 .pkt_scan = sd_pkt_scan,
cebf3b67 2108 .dq_callback = do_autogain,
6a7eba24
JFM
2109};
2110
2111/* -- module initialisation -- */
9d64fdb1
JFM
2112#define BSI(bridge, sensor, i2c_addr) \
2113 .driver_info = (BRIDGE_ ## bridge << 16) \
2114 | (SENSOR_ ## sensor << 8) \
2115 | (i2c_addr)
a5ae2062 2116static const __devinitdata struct usb_device_id device_table[] = {
222a07ff 2117#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2118 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
7b537391 2119 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
a08d81af 2120#endif
9d64fdb1
JFM
2121 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2122 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
a08d81af 2123#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2124 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
c41492c8 2125#endif
7e21fda1 2126 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
9d64fdb1 2127 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
3319dc98 2128 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
9d64fdb1
JFM
2129 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2130/* bw600.inf:
2131 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2132/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2133/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2134 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2135/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
661ab25d 2136 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
9d64fdb1
JFM
2137/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2138/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2139 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2140/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2141/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2142 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2143 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
3c41cb77
JFM
2144#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2145 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2146#endif
9d64fdb1
JFM
2147/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2148/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2149/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
d2d16e90
JFM
2150 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2151/*bw600.inf:*/
6270330a 2152 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
9d64fdb1 2153 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
6ab0b174 2154 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
9d64fdb1 2155/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
222a07ff 2156#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2157 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
222a07ff 2158#endif
9d64fdb1 2159 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
821ced29 2160 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
222a07ff 2161#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2162 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
8d97770a 2163#endif
9d64fdb1
JFM
2164 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2165/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
5e31dc8d 2166 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
6a7eba24
JFM
2167 {}
2168};
2169MODULE_DEVICE_TABLE(usb, device_table);
2170
2171/* -- device connect -- */
2172static int sd_probe(struct usb_interface *intf,
2173 const struct usb_device_id *id)
2174{
2175 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2176 THIS_MODULE);
2177}
2178
2179static struct usb_driver sd_driver = {
2180 .name = MODULE_NAME,
2181 .id_table = device_table,
2182 .probe = sd_probe,
2183 .disconnect = gspca_disconnect,
6a709749
JFM
2184#ifdef CONFIG_PM
2185 .suspend = gspca_suspend,
2186 .resume = gspca_resume,
2187#endif
6a7eba24
JFM
2188};
2189
2190/* -- module insert / remove -- */
2191static int __init sd_mod_init(void)
2192{
f69e9529
AK
2193 int ret;
2194 ret = usb_register(&sd_driver);
2195 if (ret < 0)
e6b14849 2196 return ret;
10b0e96e 2197 info("registered");
6a7eba24
JFM
2198 return 0;
2199}
2200static void __exit sd_mod_exit(void)
2201{
2202 usb_deregister(&sd_driver);
2203 info("deregistered");
2204}
2205
2206module_init(sd_mod_init);
2207module_exit(sd_mod_exit);
This page took 0.225443 seconds and 5 git commands to generate.