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