]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/media/video/gspca/sonixj.c
V4L/DVB (10617): gspca - vc032x: Remove the vc0321 reset.
[mirror_ubuntu-jammy-kernel.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;
98819187 48 u8 vflip; /* ov7630 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 },
6c86274f 195/* ov7630 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,
40e6ec12 205#define VFLIP_DEF 1
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 */
2687a2fb 237 0,
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 */
577cbf49 243 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_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 */
672/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
673 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
674 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
675/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
676/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
677/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
678/*...*/
679 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
680/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
681/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
682/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
683/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
684/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
685
686 {}
687};
688
98819187 689static const u8 ov7660_sensor_init[][8] = {
6a7eba24 690 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
60017617 691/* (delay 20ms) */
6a7eba24 692 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
738608ae 693 /* Outformat = rawRGB */
6a7eba24 694 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
738608ae 695 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
6a7eba24
JFM
696 /* GAIN BLUE RED VREF */
697 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
698 /* COM 1 BAVE GEAVE AECHH */
699 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
700 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
738608ae 701 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
6a7eba24
JFM
702 /* AECH CLKRC COM7 COM8 */
703 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
704 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
705 /* HSTART HSTOP VSTRT VSTOP */
706 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
707 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
708 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
709 /* BOS GBOS GROS ROS (BGGR offset) */
738608ae
JFM
710/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
711 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
6a7eba24
JFM
712 /* AEW AEB VPT BBIAS */
713 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
714 /* GbBIAS RSVD EXHCH EXHCL */
715 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
716 /* RBIAS ADVFL ASDVFH YAVE */
717 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
718 /* HSYST HSYEN HREF */
719 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
720 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
721 /* ADC ACOM OFON TSLB */
722 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
723 /* COM11 COM12 COM13 COM14 */
724 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
725 /* EDGE COM15 COM16 COM17 */
726 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
727 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
728 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
729 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
730 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
731 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
732 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
733 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
734 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
735 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
736 /* LCC1 LCC2 LCC3 LCC4 */
737 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
738608ae 738 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
6a7eba24 739 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
738608ae 740 /* band gap reference [0:3] DBLV */
6a7eba24
JFM
741 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
742 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
743 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
744 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
745 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
746 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
747 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
748 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
749 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
738608ae 750 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
6a7eba24 751/****** (some exchanges in the win trace) ******/
738608ae 752 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
6a7eba24
JFM
753 /* bits[3..0]reserved */
754 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
755 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
756 /* VREF vertical frame ctrl */
757 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
738608ae
JFM
758 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
759 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
760 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
761 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
762/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
6a7eba24
JFM
763/****** (some exchanges in the win trace) ******/
764 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
738608ae
JFM
765 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
766 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
767 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
768/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
6a7eba24 769/****** (some exchanges in the win trace) ******/
738608ae 770/******!! startsensor KO if changed !!****/
6a7eba24
JFM
771 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
a5ae2062 775 {}
6a7eba24 776};
6a7eba24 777
5e31dc8d
JFM
778static const u8 sp80708_sensor_init[][8] = {
779 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
847 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
848 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
849 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
850 /********/
851 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
852 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
853 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
854 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
856 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
857 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
858 {}
859};
860
98819187
JFM
861static const u8 qtable4[] = {
862 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
863 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
864 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
865 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
866 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
867 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
868 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
869 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
870 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
871 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
872 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 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
6a7eba24
JFM
878};
879
8295d99e 880/* read <len> bytes to gspca_dev->usb_buf */
739570bb 881static void reg_r(struct gspca_dev *gspca_dev,
98819187 882 u16 value, int len)
6a7eba24 883{
8295d99e
JFM
884#ifdef GSPCA_DEBUG
885 if (len > USB_BUF_SZ) {
886 err("reg_r: buffer overflow");
887 return;
888 }
889#endif
739570bb
JFM
890 usb_control_msg(gspca_dev->dev,
891 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
892 0,
893 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
894 value, 0,
739570bb 895 gspca_dev->usb_buf, len,
6a7eba24 896 500);
60017617 897 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
6a7eba24
JFM
898}
899
60017617 900static void reg_w1(struct gspca_dev *gspca_dev,
98819187
JFM
901 u16 value,
902 u8 data)
60017617 903{
3ef2c5be 904 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
60017617
JFM
905 gspca_dev->usb_buf[0] = data;
906 usb_control_msg(gspca_dev->dev,
907 usb_sndctrlpipe(gspca_dev->dev, 0),
908 0x08,
909 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
910 value,
911 0,
912 gspca_dev->usb_buf, 1,
913 500);
914}
739570bb 915static void reg_w(struct gspca_dev *gspca_dev,
98819187
JFM
916 u16 value,
917 const u8 *buffer,
6a7eba24
JFM
918 int len)
919{
3ef2c5be 920 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
60017617 921 value, buffer[0], buffer[1]);
8295d99e
JFM
922#ifdef GSPCA_DEBUG
923 if (len > USB_BUF_SZ) {
924 err("reg_w: buffer overflow");
925 return;
bf7f0b98 926 }
8295d99e
JFM
927#endif
928 memcpy(gspca_dev->usb_buf, buffer, len);
929 usb_control_msg(gspca_dev->dev,
930 usb_sndctrlpipe(gspca_dev->dev, 0),
931 0x08,
932 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
933 value, 0,
934 gspca_dev->usb_buf, len,
935 500);
6a7eba24
JFM
936}
937
60017617 938/* I2C write 1 byte */
98819187 939static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
6a7eba24
JFM
940{
941 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 942
60017617
JFM
943 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
944 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
945 gspca_dev->usb_buf[1] = sd->i2c_base;
946 gspca_dev->usb_buf[2] = reg;
947 gspca_dev->usb_buf[3] = val;
948 gspca_dev->usb_buf[4] = 0;
949 gspca_dev->usb_buf[5] = 0;
950 gspca_dev->usb_buf[6] = 0;
951 gspca_dev->usb_buf[7] = 0x10;
952 usb_control_msg(gspca_dev->dev,
953 usb_sndctrlpipe(gspca_dev->dev, 0),
954 0x08,
955 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
956 0x08, /* value = i2c */
957 0,
958 gspca_dev->usb_buf, 8,
959 500);
6a7eba24
JFM
960}
961
739570bb
JFM
962/* I2C write 8 bytes */
963static void i2c_w8(struct gspca_dev *gspca_dev,
98819187 964 const u8 *buffer)
6a7eba24 965{
60017617
JFM
966 memcpy(gspca_dev->usb_buf, buffer, 8);
967 usb_control_msg(gspca_dev->dev,
968 usb_sndctrlpipe(gspca_dev->dev, 0),
969 0x08,
970 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
971 0x08, 0, /* value, index */
972 gspca_dev->usb_buf, 8,
973 500);
8d768e14 974 msleep(2);
6a7eba24
JFM
975}
976
739570bb 977/* read 5 bytes in gspca_dev->usb_buf */
98819187 978static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
6a7eba24
JFM
979{
980 struct sd *sd = (struct sd *) gspca_dev;
98819187 981 u8 mode[8];
6a7eba24 982
3647fea8 983 mode[0] = 0x81 | 0x10;
6a7eba24
JFM
984 mode[1] = sd->i2c_base;
985 mode[2] = reg;
986 mode[3] = 0;
987 mode[4] = 0;
988 mode[5] = 0;
989 mode[6] = 0;
990 mode[7] = 0x10;
739570bb 991 i2c_w8(gspca_dev, mode);
60017617 992 msleep(2);
3647fea8 993 mode[0] = 0x81 | (5 << 4) | 0x02;
6a7eba24 994 mode[2] = 0;
739570bb 995 i2c_w8(gspca_dev, mode);
60017617 996 msleep(2);
739570bb 997 reg_r(gspca_dev, 0x0a, 5);
6a7eba24
JFM
998}
999
3ef2c5be 1000static int hv7131r_probe(struct gspca_dev *gspca_dev)
6a7eba24 1001{
60017617 1002 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
6a7eba24 1003 msleep(10);
60017617 1004 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
6a7eba24 1005 msleep(10);
739570bb
JFM
1006 i2c_r5(gspca_dev, 0); /* read sensor id */
1007 if (gspca_dev->usb_buf[0] == 0x02
1008 && gspca_dev->usb_buf[1] == 0x09
1009 && gspca_dev->usb_buf[2] == 0x01
1010 && gspca_dev->usb_buf[3] == 0x00
1011 && gspca_dev->usb_buf[4] == 0x00) {
6a7eba24 1012 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
577cbf49 1013 return 0;
6a7eba24 1014 }
60017617 1015 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
739570bb
JFM
1016 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1017 gspca_dev->usb_buf[2]);
6a7eba24
JFM
1018 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1019 return -ENODEV;
1020}
1021
65c5259c 1022static void mi0360_probe(struct gspca_dev *gspca_dev)
3ef2c5be 1023{
65c5259c 1024 struct sd *sd = (struct sd *) gspca_dev;
3ef2c5be
JFM
1025 int i, j;
1026 u16 val;
1027 static const u8 probe_tb[][4][8] = {
65c5259c 1028 { /* mi0360 */
3ef2c5be
JFM
1029 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1030 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1031 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1032 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1033 },
65c5259c 1034 { /* mt9v111 */
3ef2c5be
JFM
1035 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1036 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1037 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1038 {}
1039 },
1040 };
1041
1042 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1043 reg_w1(gspca_dev, 0x17, 0x62);
1044 reg_w1(gspca_dev, 0x01, 0x08);
1045 for (j = 0; j < 3; j++)
1046 i2c_w8(gspca_dev, probe_tb[i][j]);
1047 msleep(2);
1048 reg_r(gspca_dev, 0x0a, 5);
1049 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1050 if (probe_tb[i][3][0] != 0)
1051 i2c_w8(gspca_dev, probe_tb[i][3]);
1052 reg_w1(gspca_dev, 0x01, 0x29);
1053 reg_w1(gspca_dev, 0x17, 0x42);
1054 if (val != 0xffff)
1055 break;
1056 }
1057 switch (val) {
1058 case 0x823a:
1059 PDEBUG(D_PROBE, "Sensor mt9v111");
65c5259c
JFM
1060 sd->sensor = SENSOR_MT9V111;
1061 sd->i2c_base = 0x5c;
1062 break;
3ef2c5be
JFM
1063 case 0x8243:
1064 PDEBUG(D_PROBE, "Sensor mi0360");
65c5259c
JFM
1065 break;
1066 default:
1067 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1068 break;
3ef2c5be 1069 }
3ef2c5be
JFM
1070}
1071
6a7eba24 1072static int configure_gpio(struct gspca_dev *gspca_dev,
98819187 1073 const u8 *sn9c1xx)
6a7eba24
JFM
1074{
1075 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
1076 const u8 *reg9a;
1077 static const u8 reg9a_def[] =
6a7eba24 1078 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
98819187 1079 static const u8 reg9a_sn9c325[] =
6a7eba24 1080 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
98819187 1081 static const u8 regd4[] = {0x60, 0x00, 0x00};
6a7eba24 1082
60017617 1083 reg_w1(gspca_dev, 0xf1, 0x00);
05b809c7 1084 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
6a7eba24
JFM
1085
1086 /* configure gpio */
739570bb
JFM
1087 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1088 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
60017617 1089 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
3647fea8
HG
1090 switch (sd->bridge) {
1091 case BRIDGE_SN9C325:
6a7eba24
JFM
1092 reg9a = reg9a_sn9c325;
1093 break;
6a7eba24
JFM
1094 default:
1095 reg9a = reg9a_def;
1096 break;
1097 }
739570bb 1098 reg_w(gspca_dev, 0x9a, reg9a, 6);
6a7eba24 1099
8f47a3ce 1100 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
6a7eba24 1101
739570bb 1102 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
6a7eba24 1103
d2d16e90 1104 switch (sd->sensor) {
3ef2c5be
JFM
1105 case SENSOR_MT9V111:
1106 reg_w1(gspca_dev, 0x01, 0x61);
1107 reg_w1(gspca_dev, 0x17, 0x61);
1108 reg_w1(gspca_dev, 0x01, 0x60);
1109 reg_w1(gspca_dev, 0x01, 0x40);
1110 break;
d2d16e90 1111 case SENSOR_OM6802:
4f30f6cf 1112 reg_w1(gspca_dev, 0x02, 0x71);
d2d16e90
JFM
1113 reg_w1(gspca_dev, 0x01, 0x42);
1114 reg_w1(gspca_dev, 0x17, 0x64);
1115 reg_w1(gspca_dev, 0x01, 0x42);
1116 break;
05b809c7
JFM
1117/*jfm: from win trace */
1118 case SENSOR_OV7630:
1119 reg_w1(gspca_dev, 0x01, 0x61);
1120 reg_w1(gspca_dev, 0x17, 0xe2);
1121 reg_w1(gspca_dev, 0x01, 0x60);
1122 reg_w1(gspca_dev, 0x01, 0x40);
1123 break;
d2d16e90 1124 case SENSOR_OV7648:
6270330a
JFM
1125 reg_w1(gspca_dev, 0x01, 0x63);
1126 reg_w1(gspca_dev, 0x17, 0x20);
60017617 1127 reg_w1(gspca_dev, 0x01, 0x42);
6a7eba24 1128 break;
91de65ac
JFM
1129/*jfm: from win trace */
1130 case SENSOR_OV7660:
1432f306
JFM
1131 if (sd->bridge == BRIDGE_SN9C120) {
1132 reg_w1(gspca_dev, 0x01, 0x61);
1133 reg_w1(gspca_dev, 0x17, 0x20);
1134 reg_w1(gspca_dev, 0x01, 0x60);
1135 reg_w1(gspca_dev, 0x01, 0x40);
1136 break;
1137 }
1138 /* fall thru */
5e31dc8d
JFM
1139 case SENSOR_SP80708:
1140 reg_w1(gspca_dev, 0x01, 0x63);
1141 reg_w1(gspca_dev, 0x17, 0x20);
1142 reg_w1(gspca_dev, 0x01, 0x62);
1143 reg_w1(gspca_dev, 0x01, 0x42);
1144 mdelay(100);
1145 reg_w1(gspca_dev, 0x02, 0x62);
1146 break;
6a7eba24 1147 default:
60017617
JFM
1148 reg_w1(gspca_dev, 0x01, 0x43);
1149 reg_w1(gspca_dev, 0x17, 0x61);
1150 reg_w1(gspca_dev, 0x01, 0x42);
d2d16e90 1151 if (sd->sensor == SENSOR_HV7131R) {
3ef2c5be 1152 if (hv7131r_probe(gspca_dev) < 0)
d2d16e90
JFM
1153 return -ENODEV;
1154 }
1155 break;
6a7eba24
JFM
1156 }
1157 return 0;
1158}
1159
1160static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1161{
1162 int i = 0;
98819187 1163 static const u8 SetSensorClk[] = /* 0x08 Mclk */
6a7eba24
JFM
1164 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1165
1166 while (hv7131r_sensor_init[i][0]) {
739570bb 1167 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
6a7eba24
JFM
1168 i++;
1169 }
739570bb 1170 i2c_w8(gspca_dev, SetSensorClk);
6a7eba24
JFM
1171}
1172
1173static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1174{
1175 int i = 0;
6a7eba24
JFM
1176
1177 while (mi0360_sensor_init[i][0]) {
739570bb 1178 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
6a7eba24
JFM
1179 i++;
1180 }
1181}
1182
1183static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1184{
1185 int i = 0;
6a7eba24
JFM
1186
1187 while (mo4000_sensor_init[i][0]) {
739570bb 1188 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
6a7eba24
JFM
1189 i++;
1190 }
1191}
1192
3ef2c5be
JFM
1193static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1194{
1195 int i = 0;
1196
1197 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1198 i++;
1199 msleep(20);
1200 while (mt9v111_sensor_init[i][0]) {
1201 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1202 i++;
1203 }
1204}
1205
d2d16e90
JFM
1206static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1207{
1208 int i = 0;
1209
1210 while (om6802_sensor_init[i][0]) {
1211 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1212 i++;
1213 }
1214}
1215
6ab0b174
JFM
1216static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1217{
1218 int i = 0;
1219
05b809c7
JFM
1220 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1221 i++;
1222 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
6ab0b174
JFM
1223 i++;
1224 msleep(20);
05b809c7
JFM
1225 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1226 i++;
1227 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1228 i++;
1229 msleep(20);
1230 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1231 i++;
1232/*jfm:win i2c_r from 00 to 80*/
1233
6ab0b174
JFM
1234 while (ov7630_sensor_init[i][0]) {
1235 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1236 i++;
1237 }
1238}
1239
6a7eba24
JFM
1240static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1241{
6a7eba24
JFM
1242 int i = 0;
1243
6270330a
JFM
1244 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1245 i++;
1246/* win: dble reset */
1247 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1248 i++;
1249 msleep(20);
1250/* win: i2c reg read 00..7f */
6a7eba24 1251 while (ov7648_sensor_init[i][0]) {
739570bb 1252 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
6a7eba24
JFM
1253 i++;
1254 }
1255}
1256
1257static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1258{
1259 int i = 0;
6a7eba24 1260
60017617
JFM
1261 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1262 i++;
1263 msleep(20);
6a7eba24 1264 while (ov7660_sensor_init[i][0]) {
739570bb 1265 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
6a7eba24
JFM
1266 i++;
1267 }
1268}
1269
5e31dc8d
JFM
1270static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1271{
1272 int i = 0;
1273
1274 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1275 i++;
1276 msleep(20);
1277 while (sp80708_sensor_init[i][0]) {
1278 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1279 i++;
1280 }
1281}
1282
6a7eba24
JFM
1283/* this function is called at probe time */
1284static int sd_config(struct gspca_dev *gspca_dev,
1285 const struct usb_device_id *id)
1286{
1287 struct sd *sd = (struct sd *) gspca_dev;
1288 struct cam *cam;
6a7eba24
JFM
1289
1290 cam = &gspca_dev->cam;
6a7eba24
JFM
1291 cam->cam_mode = vga_mode;
1292 cam->nmodes = ARRAY_SIZE(vga_mode);
a5ae2062 1293
9d64fdb1
JFM
1294 sd->bridge = id->driver_info >> 16;
1295 sd->sensor = id->driver_info >> 8;
1296 sd->i2c_base = id->driver_info;
1297
a5ae2062
JFM
1298 sd->brightness = BRIGHTNESS_DEF;
1299 sd->contrast = CONTRAST_DEF;
1300 sd->colors = COLOR_DEF;
403123d2
JFM
1301 sd->blue = BLUE_BALANCE_DEF;
1302 sd->red = RED_BALANCE_DEF;
592f4eb9 1303 sd->gamma = GAMMA_DEF;
a5ae2062 1304 sd->autogain = AUTOGAIN_DEF;
cebf3b67 1305 sd->ag_cnt = -1;
0cae8964
JFM
1306 sd->vflip = VFLIP_DEF;
1307 sd->infrared = INFRARED_DEF;
cebf3b67 1308
577cbf49 1309 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
6a7eba24
JFM
1310 return 0;
1311}
1312
012d6b02
JFM
1313/* this function is called at probe and resume time */
1314static int sd_init(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1315{
1316 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
1317 u8 regGpio[] = { 0x29, 0x74 };
1318 u8 regF1;
6a7eba24 1319
3647fea8 1320 /* setup a selector by bridge */
60017617 1321 reg_w1(gspca_dev, 0xf1, 0x01);
739570bb 1322 reg_r(gspca_dev, 0x00, 1);
8f47a3ce
JFM
1323 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1324 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
739570bb 1325 regF1 = gspca_dev->usb_buf[0];
8f47a3ce 1326 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
3647fea8
HG
1327 switch (sd->bridge) {
1328 case BRIDGE_SN9C102P:
6a7eba24
JFM
1329 if (regF1 != 0x11)
1330 return -ENODEV;
60017617 1331 reg_w1(gspca_dev, 0x02, regGpio[1]);
6a7eba24 1332 break;
3647fea8 1333 case BRIDGE_SN9C105:
6a7eba24
JFM
1334 if (regF1 != 0x11)
1335 return -ENODEV;
65c5259c
JFM
1336 if (sd->sensor == SENSOR_MI0360)
1337 mi0360_probe(gspca_dev);
674cbc69 1338 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24 1339 break;
3647fea8 1340 case BRIDGE_SN9C120:
6a7eba24
JFM
1341 if (regF1 != 0x12)
1342 return -ENODEV;
65c5259c
JFM
1343 if (sd->sensor == SENSOR_MI0360)
1344 mi0360_probe(gspca_dev);
6a7eba24 1345 regGpio[1] = 0x70;
674cbc69 1346 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24
JFM
1347 break;
1348 default:
60017617 1349/* case BRIDGE_SN9C110: */
3647fea8 1350/* case BRIDGE_SN9C325: */
6a7eba24
JFM
1351 if (regF1 != 0x12)
1352 return -ENODEV;
60017617 1353 reg_w1(gspca_dev, 0x02, 0x62);
6a7eba24
JFM
1354 break;
1355 }
1356
759aa3c2 1357 reg_w1(gspca_dev, 0xf1, 0x01);
6a7eba24
JFM
1358
1359 return 0;
1360}
1361
98819187
JFM
1362static u32 setexposure(struct gspca_dev *gspca_dev,
1363 u32 expo)
6a7eba24
JFM
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24
JFM
1366
1367 switch (sd->sensor) {
1368 case SENSOR_HV7131R: {
98819187 1369 u8 Expodoit[] =
6a7eba24
JFM
1370 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1371
1372 Expodoit[3] = expo >> 16;
1373 Expodoit[4] = expo >> 8;
1374 Expodoit[5] = expo;
739570bb 1375 i2c_w8(gspca_dev, Expodoit);
6a7eba24
JFM
1376 break;
1377 }
1378 case SENSOR_MI0360: {
3ef2c5be 1379 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
6a7eba24 1380 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
98819187
JFM
1381 static const u8 doit[] = /* update sensor */
1382 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1383 static const u8 sensorgo[] = /* sensor on */
1384 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
6a7eba24
JFM
1385
1386 if (expo > 0x0635)
1387 expo = 0x0635;
1388 else if (expo < 0x0001)
1389 expo = 0x0001;
1390 expoMi[3] = expo >> 8;
1391 expoMi[4] = expo;
739570bb
JFM
1392 i2c_w8(gspca_dev, expoMi);
1393 i2c_w8(gspca_dev, doit);
1394 i2c_w8(gspca_dev, sensorgo);
6a7eba24
JFM
1395 break;
1396 }
1397 case SENSOR_MO4000: {
98819187 1398 u8 expoMof[] =
6a7eba24 1399 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
98819187 1400 u8 expoMo10[] =
6a7eba24 1401 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
98819187
JFM
1402 static const u8 gainMo[] =
1403 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
6a7eba24
JFM
1404
1405 if (expo > 0x1fff)
1406 expo = 0x1fff;
1407 else if (expo < 0x0001)
1408 expo = 0x0001;
1409 expoMof[3] = (expo & 0x03fc) >> 2;
739570bb 1410 i2c_w8(gspca_dev, expoMof);
6a7eba24
JFM
1411 expoMo10[3] = ((expo & 0x1c00) >> 10)
1412 | ((expo & 0x0003) << 4);
739570bb
JFM
1413 i2c_w8(gspca_dev, expoMo10);
1414 i2c_w8(gspca_dev, gainMo);
3ef2c5be 1415 PDEBUG(D_FRAM, "set exposure %d",
6a7eba24
JFM
1416 ((expoMo10[3] & 0x07) << 10)
1417 | (expoMof[3] << 2)
1418 | ((expoMo10[3] & 0x30) >> 4));
1419 break;
1420 }
3ef2c5be
JFM
1421 case SENSOR_MT9V111: {
1422 u8 expo_c1[] =
1423 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1424
1425 if (expo > 0x0280)
1426 expo = 0x0280;
1427 else if (expo < 0x0040)
1428 expo = 0x0040;
1429 expo_c1[3] = expo >> 8;
1430 expo_c1[4] = expo;
1431 i2c_w8(gspca_dev, expo_c1);
1432 break;
1433 }
d2d16e90 1434 case SENSOR_OM6802: {
98819187 1435 u8 gainOm[] =
d2d16e90
JFM
1436 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1437
1438 if (expo > 0x03ff)
1439 expo = 0x03ff;
1440 if (expo < 0x0001)
1441 expo = 0x0001;
1442 gainOm[3] = expo >> 2;
1443 i2c_w8(gspca_dev, gainOm);
d55b83d3 1444 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
3ef2c5be 1445 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
d2d16e90
JFM
1446 break;
1447 }
6a7eba24
JFM
1448 }
1449 return expo;
1450}
1451
1452static void setbrightness(struct gspca_dev *gspca_dev)
1453{
1454 struct sd *sd = (struct sd *) gspca_dev;
1455 unsigned int expo;
98819187 1456 u8 k2;
6a7eba24 1457
b1b056a5 1458 k2 = ((int) sd->brightness - 0x8000) >> 10;
6a7eba24
JFM
1459 switch (sd->sensor) {
1460 case SENSOR_HV7131R:
1461 expo = sd->brightness << 4;
1462 if (expo > 0x002dc6c0)
1463 expo = 0x002dc6c0;
1464 else if (expo < 0x02a0)
1465 expo = 0x02a0;
1466 sd->exposure = setexposure(gspca_dev, expo);
1467 break;
1468 case SENSOR_MI0360:
6a7eba24
JFM
1469 case SENSOR_MO4000:
1470 expo = sd->brightness >> 4;
1471 sd->exposure = setexposure(gspca_dev, expo);
1472 break;
3ef2c5be
JFM
1473 case SENSOR_MT9V111:
1474 expo = sd->brightness >> 8;
1475 sd->exposure = setexposure(gspca_dev, expo);
1476 break;
d2d16e90
JFM
1477 case SENSOR_OM6802:
1478 expo = sd->brightness >> 6;
1479 sd->exposure = setexposure(gspca_dev, expo);
b1b056a5 1480 k2 = sd->brightness >> 11;
d2d16e90 1481 break;
6a7eba24
JFM
1482 }
1483
3ef2c5be
JFM
1484 if (sd->sensor != SENSOR_MT9V111)
1485 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
6a7eba24
JFM
1486}
1487
1488static void setcontrast(struct gspca_dev *gspca_dev)
1489{
1490 struct sd *sd = (struct sd *) gspca_dev;
98819187
JFM
1491 u8 k2;
1492 u8 contrast[6];
6a7eba24 1493
91bd3412
JFM
1494 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1495 contrast[0] = (k2 + 1) / 2; /* red */
577cbf49 1496 contrast[1] = 0;
91bd3412 1497 contrast[2] = k2; /* green */
577cbf49 1498 contrast[3] = 0;
91bd3412 1499 contrast[4] = (k2 + 1) / 5; /* blue */
577cbf49
JFM
1500 contrast[5] = 0;
1501 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
6a7eba24
JFM
1502}
1503
1504static void setcolors(struct gspca_dev *gspca_dev)
1505{
1506 struct sd *sd = (struct sd *) gspca_dev;
403123d2 1507 int i, v;
98819187
JFM
1508 u8 reg8a[12]; /* U & V gains */
1509 static s16 uv[6] = { /* same as reg84 in signed decimal */
403123d2
JFM
1510 -24, -38, 64, /* UR UG UB */
1511 62, -51, -9 /* VR VG VB */
1512 };
1513 for (i = 0; i < 6; i++) {
1514 v = uv[i] * sd->colors / COLOR_DEF;
bd088835
JFM
1515 reg8a[i * 2] = v;
1516 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
d55b83d3 1517 }
bd088835 1518 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
403123d2
JFM
1519}
1520
1521static void setredblue(struct gspca_dev *gspca_dev)
1522{
1523 struct sd *sd = (struct sd *) gspca_dev;
1524
1525 reg_w1(gspca_dev, 0x05, sd->red);
9c5f70f2 1526/* reg_w1(gspca_dev, 0x07, 32); */
403123d2 1527 reg_w1(gspca_dev, 0x06, sd->blue);
6a7eba24
JFM
1528}
1529
592f4eb9
JFM
1530static void setgamma(struct gspca_dev *gspca_dev)
1531{
1532 struct sd *sd = (struct sd *) gspca_dev;
1533 int i;
1534 u8 gamma[17];
b083b92f 1535 const u8 *gamma_base;
592f4eb9
JFM
1536 static const u8 delta[17] = {
1537 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1538 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1539 };
1540
b083b92f
JFM
1541 switch (sd->sensor) {
1542 case SENSOR_HV7131R:
1543 case SENSOR_MT9V111:
1544 gamma_base = gamma_spec_1;
1545 break;
1546 case SENSOR_SP80708:
1547 gamma_base = gamma_spec_2;
1548 break;
1549 default:
1550 gamma_base = gamma_def;
1551 break;
1552 }
5e31dc8d 1553
592f4eb9 1554 for (i = 0; i < sizeof gamma; i++)
b083b92f 1555 gamma[i] = gamma_base[i]
592f4eb9
JFM
1556 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1557 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1558}
1559
cebf3b67
JFM
1560static void setautogain(struct gspca_dev *gspca_dev)
1561{
1562 struct sd *sd = (struct sd *) gspca_dev;
1563
f50ba1be
JFM
1564 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1565 return;
1566 if (sd->autogain)
1567 sd->ag_cnt = AG_CNT_START;
1568 else
1569 sd->ag_cnt = -1;
cebf3b67
JFM
1570}
1571
6c86274f
JFM
1572static void setvflip(struct sd *sd)
1573{
6c86274f
JFM
1574 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1575 sd->vflip ? 0x82 : 0x02);
1576}
1577
0cae8964
JFM
1578static void setinfrared(struct sd *sd)
1579{
1580/*fixme: different sequence for StarCam Clip and StarCam 370i */
1581/* Clip */
1582 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1583 sd->infrared ? 0x66 : 0x64);
1584}
1585
6a7eba24 1586/* -- start the camera -- */
72ab97ce 1587static int sd_start(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1588{
1589 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 1590 int i;
98819187
JFM
1591 u8 reg1, reg17, reg18;
1592 const u8 *sn9c1xx;
6a7eba24 1593 int mode;
98819187
JFM
1594 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1595 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1596 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1597 static const u8 CE_ov76xx[] =
674cbc69 1598 { 0x32, 0xdd, 0x32, 0xdd };
6a7eba24
JFM
1599
1600 sn9c1xx = sn_tb[(int) sd->sensor];
1601 configure_gpio(gspca_dev, sn9c1xx);
1602
60017617
JFM
1603 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1604 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1605 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1606 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1607 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1608 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1609 reg_w1(gspca_dev, 0xd3, 0x50);
1610 reg_w1(gspca_dev, 0xc6, 0x00);
1611 reg_w1(gspca_dev, 0xc7, 0x00);
1612 reg_w1(gspca_dev, 0xc8, 0x50);
1613 reg_w1(gspca_dev, 0xc9, 0x3c);
60017617 1614 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
6ab0b174 1615 switch (sd->sensor) {
3ef2c5be
JFM
1616 case SENSOR_MT9V111:
1617 reg17 = 0xe0;
1618 break;
6ab0b174
JFM
1619 case SENSOR_OV7630:
1620 reg17 = 0xe2;
1621 break;
1622 case SENSOR_OV7648:
6270330a 1623 reg17 = 0x20;
568788a7 1624 break;
6ab0b174
JFM
1625/*jfm: from win trace */
1626 case SENSOR_OV7660:
1432f306
JFM
1627 if (sd->bridge == BRIDGE_SN9C120) {
1628 reg17 = 0xa0;
1629 break;
1630 }
1631 /* fall thru */
568788a7 1632 default:
8f47a3ce 1633 reg17 = 0x60;
568788a7
JFM
1634 break;
1635 }
8f47a3ce 1636 reg_w1(gspca_dev, 0x17, reg17);
1432f306 1637/* set reg1 was here */
403123d2
JFM
1638 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1639 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1640 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
60017617 1641 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
b083b92f 1642
5e31dc8d
JFM
1643 setgamma(gspca_dev);
1644
05b809c7
JFM
1645 for (i = 0; i < 8; i++)
1646 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
674cbc69 1647 switch (sd->sensor) {
3ef2c5be
JFM
1648 case SENSOR_MT9V111:
1649 reg_w1(gspca_dev, 0x9a, 0x07);
1650 reg_w1(gspca_dev, 0x99, 0x59);
1651 break;
6270330a
JFM
1652 case SENSOR_OV7648:
1653 reg_w1(gspca_dev, 0x9a, 0x0a);
1654 reg_w1(gspca_dev, 0x99, 0x60);
1655 break;
5e31dc8d
JFM
1656 case SENSOR_SP80708:
1657 reg_w1(gspca_dev, 0x9a, 0x05);
1658 reg_w1(gspca_dev, 0x99, 0x59);
1659 break;
674cbc69 1660 case SENSOR_OV7660:
1432f306
JFM
1661 if (sd->bridge == BRIDGE_SN9C120) {
1662 reg_w1(gspca_dev, 0x9a, 0x05);
1663 break;
1664 }
1665 /* fall thru */
674cbc69 1666 default:
60017617
JFM
1667 reg_w1(gspca_dev, 0x9a, 0x08);
1668 reg_w1(gspca_dev, 0x99, 0x59);
674cbc69
JFM
1669 break;
1670 }
6a7eba24 1671
c2446b3e 1672 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
60017617 1673 if (mode)
1432f306 1674 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
60017617 1675 else
1432f306
JFM
1676 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1677 reg17 = 0x61; /* 0x:20: enable sensor clock */
6a7eba24
JFM
1678 switch (sd->sensor) {
1679 case SENSOR_HV7131R:
1680 hv7131R_InitSensor(gspca_dev);
6a7eba24
JFM
1681 break;
1682 case SENSOR_MI0360:
1683 mi0360_InitSensor(gspca_dev);
6a7eba24
JFM
1684 break;
1685 case SENSOR_MO4000:
1686 mo4000_InitSensor(gspca_dev);
1687 if (mode) {
1688/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1689 reg1 = 0x06; /* clk 24Mz */
1690 } else {
1691 reg17 = 0x22; /* 640 MCKSIZE */
60017617 1692/* reg1 = 0x06; * 640 clk 24Mz (done) */
6a7eba24
JFM
1693 }
1694 break;
3ef2c5be
JFM
1695 case SENSOR_MT9V111:
1696 mt9v111_InitSensor(gspca_dev);
1697 if (mode) {
1698 reg1 = 0x04; /* 320 clk 48Mhz */
1699 } else {
1700/* reg1 = 0x06; * 640 clk 24Mz (done) */
2687a2fb 1701 reg17 = 0xc2;
3ef2c5be 1702 }
0fbe0574 1703 break;
d2d16e90
JFM
1704 case SENSOR_OM6802:
1705 om6802_InitSensor(gspca_dev);
d2d16e90
JFM
1706 reg17 = 0x64; /* 640 MCKSIZE */
1707 break;
6ab0b174
JFM
1708 case SENSOR_OV7630:
1709 ov7630_InitSensor(gspca_dev);
6c86274f 1710 setvflip(sd);
6ab0b174 1711 reg17 = 0xe2;
5b064da8 1712 reg1 = 0x44;
6ab0b174 1713 break;
6a7eba24 1714 case SENSOR_OV7648:
60017617 1715 ov7648_InitSensor(gspca_dev);
6270330a
JFM
1716 reg17 = 0x21;
1717/* reg1 = 0x42; * 42 - 46? */
6a7eba24 1718 break;
5e31dc8d 1719 case SENSOR_OV7660:
6a7eba24 1720 ov7660_InitSensor(gspca_dev);
daa5cb42
JFM
1721 if (sd->bridge == BRIDGE_SN9C120) {
1722 if (mode) { /* 320x240 - 160x120 */
1432f306
JFM
1723 reg17 = 0xa2;
1724 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1432f306 1725 }
daa5cb42
JFM
1726 } else {
1727 reg17 = 0x22;
1728 reg1 = 0x06; /* 24 Mhz, video trf eneble
1729 * inverse power down */
6a7eba24
JFM
1730 }
1731 break;
5e31dc8d
JFM
1732 default:
1733/* case SENSOR_SP80708: */
1734 sp80708_InitSensor(gspca_dev);
1735 if (mode) {
1736/*?? reg1 = 0x04; * 320 clk 48Mhz */
5e31dc8d
JFM
1737 } else {
1738 reg1 = 0x46; /* 640 clk 48Mz */
1739 reg17 = 0xa2;
1740 }
1741 break;
6a7eba24 1742 }
739570bb 1743 reg_w(gspca_dev, 0xc0, C0, 6);
8f47a3ce 1744 reg_w(gspca_dev, 0xca, CA, 4);
6ab0b174
JFM
1745 switch (sd->sensor) {
1746 case SENSOR_OV7630:
1747 case SENSOR_OV7648:
674cbc69 1748 case SENSOR_OV7660:
6ab0b174 1749 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
6a7eba24
JFM
1750 break;
1751 default:
739570bb 1752 reg_w(gspca_dev, 0xce, CE, 4);
6a7eba24
JFM
1753 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1754 break;
1755 }
1756
1757 /* here change size mode 0 -> VGA; 1 -> CIF */
8f47a3ce
JFM
1758 reg18 = sn9c1xx[0x18] | (mode << 4);
1759 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
6a7eba24 1760
3ef2c5be
JFM
1761 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1762 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
6a7eba24 1763
8f47a3ce 1764 reg_w1(gspca_dev, 0x18, reg18);
6a7eba24 1765
60017617 1766 reg_w1(gspca_dev, 0x17, reg17);
1432f306 1767 reg_w1(gspca_dev, 0x01, reg1);
05b809c7 1768 switch (sd->sensor) {
79a9098a
JFM
1769 case SENSOR_OV7630:
1770 setvflip(sd);
05b809c7
JFM
1771 break;
1772 }
91bd3412
JFM
1773 setbrightness(gspca_dev);
1774 setcontrast(gspca_dev);
cebf3b67 1775 setautogain(gspca_dev);
72ab97ce 1776 return 0;
6a7eba24
JFM
1777}
1778
1779static void sd_stopN(struct gspca_dev *gspca_dev)
1780{
1781 struct sd *sd = (struct sd *) gspca_dev;
98819187 1782 static const u8 stophv7131[] =
6a7eba24 1783 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
98819187 1784 static const u8 stopmi0360[] =
6a7eba24 1785 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
98819187 1786 static const u8 stopov7648[] =
6270330a 1787 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
98819187
JFM
1788 u8 data;
1789 const u8 *sn9c1xx;
6a7eba24
JFM
1790
1791 data = 0x0b;
1792 switch (sd->sensor) {
1793 case SENSOR_HV7131R:
739570bb 1794 i2c_w8(gspca_dev, stophv7131);
6a7eba24
JFM
1795 data = 0x2b;
1796 break;
1797 case SENSOR_MI0360:
739570bb 1798 i2c_w8(gspca_dev, stopmi0360);
6a7eba24
JFM
1799 data = 0x29;
1800 break;
6a7eba24 1801 case SENSOR_OV7648:
6270330a
JFM
1802 i2c_w8(gspca_dev, stopov7648);
1803 /* fall thru */
3ef2c5be 1804 case SENSOR_MT9V111:
6270330a 1805 case SENSOR_OV7630:
6a7eba24
JFM
1806 data = 0x29;
1807 break;
1808 default:
8f47a3ce 1809/* case SENSOR_MO4000: */
6a7eba24
JFM
1810/* case SENSOR_OV7660: */
1811 break;
1812 }
1813 sn9c1xx = sn_tb[(int) sd->sensor];
60017617
JFM
1814 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1815 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1816 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1817 reg_w1(gspca_dev, 0x01, data);
759aa3c2 1818 reg_w1(gspca_dev, 0xf1, 0x00);
6a7eba24
JFM
1819}
1820
cebf3b67 1821static void do_autogain(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1822{
1823 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 1824 int delta;
cebf3b67 1825 int expotimes;
98819187
JFM
1826 u8 luma_mean = 130;
1827 u8 luma_delta = 20;
6a7eba24 1828
cebf3b67
JFM
1829 /* Thanks S., without your advice, autobright should not work :) */
1830 if (sd->ag_cnt < 0)
1831 return;
1832 if (--sd->ag_cnt >= 0)
1833 return;
1834 sd->ag_cnt = AG_CNT_START;
1835
1836 delta = atomic_read(&sd->avg_lum);
1837 PDEBUG(D_FRAM, "mean lum %d", delta);
6a7eba24
JFM
1838 if (delta < luma_mean - luma_delta ||
1839 delta > luma_mean + luma_delta) {
1840 switch (sd->sensor) {
1841 case SENSOR_HV7131R:
1842 expotimes = sd->exposure >> 8;
1843 expotimes += (luma_mean - delta) >> 4;
1844 if (expotimes < 0)
1845 expotimes = 0;
1846 sd->exposure = setexposure(gspca_dev,
1847 (unsigned int) (expotimes << 8));
1848 break;
cebf3b67
JFM
1849 default:
1850/* case SENSOR_MO4000: */
1851/* case SENSOR_MI0360: */
3ef2c5be 1852/* case SENSOR_MT9V111: */
d2d16e90 1853/* case SENSOR_OM6802: */
6a7eba24
JFM
1854 expotimes = sd->exposure;
1855 expotimes += (luma_mean - delta) >> 6;
1856 if (expotimes < 0)
1857 expotimes = 0;
1858 sd->exposure = setexposure(gspca_dev,
1859 (unsigned int) expotimes);
403123d2 1860 setredblue(gspca_dev);
6a7eba24
JFM
1861 break;
1862 }
1863 }
1864}
1865
cebf3b67
JFM
1866/* scan the URB packets */
1867/* This function is run at interrupt level. */
6a7eba24
JFM
1868static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1869 struct gspca_frame *frame, /* target */
98819187 1870 u8 *data, /* isoc packet */
6a7eba24
JFM
1871 int len) /* iso packet length */
1872{
1873 struct sd *sd = (struct sd *) gspca_dev;
1874 int sof, avg_lum;
1875
1876 sof = len - 64;
1877 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1878
1879 /* end of frame */
1880 gspca_frame_add(gspca_dev, LAST_PACKET,
1881 frame, data, sof + 2);
1882 if (sd->ag_cnt < 0)
1883 return;
6a7eba24
JFM
1884/* w1 w2 w3 */
1885/* w4 w5 w6 */
1886/* w7 w8 */
1887/* w4 */
1888 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1889/* w6 */
1890 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1891/* w2 */
1892 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1893/* w8 */
1894 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1895/* w5 */
1896 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1897 avg_lum >>= 4;
cebf3b67 1898 atomic_set(&sd->avg_lum, avg_lum);
6a7eba24
JFM
1899 return;
1900 }
1901 if (gspca_dev->last_packet_type == LAST_PACKET) {
1902
1903 /* put the JPEG 422 header */
36e819db 1904 jpeg_put_header(gspca_dev, frame, 0x21);
6a7eba24
JFM
1905 }
1906 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1907}
1908
6a7eba24
JFM
1909static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1910{
1911 struct sd *sd = (struct sd *) gspca_dev;
1912
1913 sd->brightness = val;
91bd3412
JFM
1914 if (gspca_dev->streaming)
1915 setbrightness(gspca_dev);
6a7eba24
JFM
1916 return 0;
1917}
1918
1919static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1920{
1921 struct sd *sd = (struct sd *) gspca_dev;
1922
6a7eba24
JFM
1923 *val = sd->brightness;
1924 return 0;
1925}
1926
1927static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1928{
1929 struct sd *sd = (struct sd *) gspca_dev;
1930
1931 sd->contrast = val;
91bd3412
JFM
1932 if (gspca_dev->streaming)
1933 setcontrast(gspca_dev);
6a7eba24
JFM
1934 return 0;
1935}
1936
1937static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1938{
1939 struct sd *sd = (struct sd *) gspca_dev;
1940
1941 *val = sd->contrast;
1942 return 0;
1943}
1944
1945static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1946{
1947 struct sd *sd = (struct sd *) gspca_dev;
1948
1949 sd->colors = val;
1950 if (gspca_dev->streaming)
1951 setcolors(gspca_dev);
1952 return 0;
1953}
1954
1955static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1956{
1957 struct sd *sd = (struct sd *) gspca_dev;
1958
1959 *val = sd->colors;
1960 return 0;
1961}
1962
403123d2
JFM
1963static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1964{
1965 struct sd *sd = (struct sd *) gspca_dev;
1966
1967 sd->blue = val;
1968 if (gspca_dev->streaming)
1969 setredblue(gspca_dev);
1970 return 0;
1971}
1972
1973static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1974{
1975 struct sd *sd = (struct sd *) gspca_dev;
1976
1977 *val = sd->blue;
1978 return 0;
1979}
1980
1981static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1982{
1983 struct sd *sd = (struct sd *) gspca_dev;
1984
1985 sd->red = val;
1986 if (gspca_dev->streaming)
1987 setredblue(gspca_dev);
1988 return 0;
1989}
1990
1991static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1992{
1993 struct sd *sd = (struct sd *) gspca_dev;
1994
1995 *val = sd->red;
1996 return 0;
1997}
1998
592f4eb9
JFM
1999static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2000{
2001 struct sd *sd = (struct sd *) gspca_dev;
2002
2003 sd->gamma = val;
2004 if (gspca_dev->streaming)
2005 setgamma(gspca_dev);
2006 return 0;
2007}
2008
2009static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2010{
2011 struct sd *sd = (struct sd *) gspca_dev;
2012
2013 *val = sd->gamma;
2014 return 0;
2015}
2016
6a7eba24
JFM
2017static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2018{
2019 struct sd *sd = (struct sd *) gspca_dev;
2020
2021 sd->autogain = val;
cebf3b67
JFM
2022 if (gspca_dev->streaming)
2023 setautogain(gspca_dev);
6a7eba24
JFM
2024 return 0;
2025}
2026
2027static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2028{
2029 struct sd *sd = (struct sd *) gspca_dev;
2030
2031 *val = sd->autogain;
2032 return 0;
2033}
2034
6c86274f
JFM
2035static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2036{
2037 struct sd *sd = (struct sd *) gspca_dev;
2038
2039 sd->vflip = val;
79a9098a
JFM
2040 if (gspca_dev->streaming)
2041 setvflip(sd);
6c86274f
JFM
2042 return 0;
2043}
2044
2045static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2046{
2047 struct sd *sd = (struct sd *) gspca_dev;
2048
2049 *val = sd->vflip;
2050 return 0;
2051}
2052
0cae8964
JFM
2053static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2054{
2055 struct sd *sd = (struct sd *) gspca_dev;
2056
2057 sd->infrared = val;
2058 if (gspca_dev->streaming)
2059 setinfrared(sd);
2060 return 0;
2061}
2062
2063static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2064{
2065 struct sd *sd = (struct sd *) gspca_dev;
2066
2067 *val = sd->infrared;
2068 return 0;
2069}
2070
6a7eba24 2071/* sub-driver description */
a5ae2062 2072static const struct sd_desc sd_desc = {
6a7eba24
JFM
2073 .name = MODULE_NAME,
2074 .ctrls = sd_ctrls,
2075 .nctrls = ARRAY_SIZE(sd_ctrls),
2076 .config = sd_config,
012d6b02 2077 .init = sd_init,
6a7eba24
JFM
2078 .start = sd_start,
2079 .stopN = sd_stopN,
6a7eba24 2080 .pkt_scan = sd_pkt_scan,
cebf3b67 2081 .dq_callback = do_autogain,
6a7eba24
JFM
2082};
2083
2084/* -- module initialisation -- */
9d64fdb1
JFM
2085#define BSI(bridge, sensor, i2c_addr) \
2086 .driver_info = (BRIDGE_ ## bridge << 16) \
2087 | (SENSOR_ ## sensor << 8) \
2088 | (i2c_addr)
a5ae2062 2089static const __devinitdata struct usb_device_id device_table[] = {
222a07ff 2090#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2091 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
7b537391 2092 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
a08d81af 2093#endif
9d64fdb1
JFM
2094 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2095 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
a08d81af 2096#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2097 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
c41492c8 2098#endif
7e21fda1 2099 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
9d64fdb1 2100 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
3319dc98 2101 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
9d64fdb1
JFM
2102 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2103/* bw600.inf:
2104 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2105/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2106/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2107 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2108/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
661ab25d 2109 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
9d64fdb1
JFM
2110/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2111/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2112 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2113/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2114/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2115 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2116 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
3c41cb77
JFM
2117#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2118 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2119#endif
9d64fdb1
JFM
2120/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2121/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2122/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
d2d16e90
JFM
2123 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2124/*bw600.inf:*/
6270330a 2125 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
9d64fdb1 2126 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
6ab0b174 2127 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
9d64fdb1 2128/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
222a07ff 2129#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 2130 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
222a07ff 2131#endif
9d64fdb1 2132 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
821ced29 2133 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
222a07ff 2134#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1
JFM
2135 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2136 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2137/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
c41492c8 2138#endif
5e31dc8d 2139 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
6a7eba24
JFM
2140 {}
2141};
2142MODULE_DEVICE_TABLE(usb, device_table);
2143
2144/* -- device connect -- */
2145static int sd_probe(struct usb_interface *intf,
2146 const struct usb_device_id *id)
2147{
2148 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2149 THIS_MODULE);
2150}
2151
2152static struct usb_driver sd_driver = {
2153 .name = MODULE_NAME,
2154 .id_table = device_table,
2155 .probe = sd_probe,
2156 .disconnect = gspca_disconnect,
6a709749
JFM
2157#ifdef CONFIG_PM
2158 .suspend = gspca_suspend,
2159 .resume = gspca_resume,
2160#endif
6a7eba24
JFM
2161};
2162
2163/* -- module insert / remove -- */
2164static int __init sd_mod_init(void)
2165{
f69e9529
AK
2166 int ret;
2167 ret = usb_register(&sd_driver);
2168 if (ret < 0)
e6b14849 2169 return ret;
10b0e96e 2170 info("registered");
6a7eba24
JFM
2171 return 0;
2172}
2173static void __exit sd_mod_exit(void)
2174{
2175 usb_deregister(&sd_driver);
2176 info("deregistered");
2177}
2178
2179module_init(sd_mod_init);
2180module_exit(sd_mod_exit);