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