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