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