]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/video/gspca/sonixj.c
V4L/DVB (9709): gspca: Fix typos and name errors in Kconfig.
[net-next-2.6.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:
1432f306
JFM
846 if (sd->bridge == BRIDGE_SN9C120) {
847 reg_w1(gspca_dev, 0x01, 0x61);
848 reg_w1(gspca_dev, 0x17, 0x20);
849 reg_w1(gspca_dev, 0x01, 0x60);
850 reg_w1(gspca_dev, 0x01, 0x40);
851 break;
852 }
853 /* fall thru */
6a7eba24 854 default:
60017617
JFM
855 reg_w1(gspca_dev, 0x01, 0x43);
856 reg_w1(gspca_dev, 0x17, 0x61);
857 reg_w1(gspca_dev, 0x01, 0x42);
d2d16e90
JFM
858 if (sd->sensor == SENSOR_HV7131R) {
859 if (probesensor(gspca_dev) < 0)
860 return -ENODEV;
861 }
862 break;
6a7eba24
JFM
863 }
864 return 0;
865}
866
867static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
868{
869 int i = 0;
a5ae2062 870 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
6a7eba24
JFM
871 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
872
873 while (hv7131r_sensor_init[i][0]) {
739570bb 874 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
6a7eba24
JFM
875 i++;
876 }
739570bb 877 i2c_w8(gspca_dev, SetSensorClk);
6a7eba24
JFM
878}
879
880static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
881{
882 int i = 0;
6a7eba24
JFM
883
884 while (mi0360_sensor_init[i][0]) {
739570bb 885 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
6a7eba24
JFM
886 i++;
887 }
888}
889
890static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
891{
892 int i = 0;
6a7eba24
JFM
893
894 while (mo4000_sensor_init[i][0]) {
739570bb 895 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
6a7eba24
JFM
896 i++;
897 }
898}
899
d2d16e90
JFM
900static void om6802_InitSensor(struct gspca_dev *gspca_dev)
901{
902 int i = 0;
903
904 while (om6802_sensor_init[i][0]) {
905 i2c_w8(gspca_dev, om6802_sensor_init[i]);
906 i++;
907 }
908}
909
6ab0b174
JFM
910static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
911{
912 int i = 0;
913
05b809c7
JFM
914 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
915 i++;
916 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
6ab0b174
JFM
917 i++;
918 msleep(20);
05b809c7
JFM
919 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
920 i++;
921 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
922 i++;
923 msleep(20);
924 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
925 i++;
926/*jfm:win i2c_r from 00 to 80*/
927
6ab0b174
JFM
928 while (ov7630_sensor_init[i][0]) {
929 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
930 i++;
931 }
932}
933
6a7eba24
JFM
934static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
935{
6a7eba24
JFM
936 int i = 0;
937
6270330a
JFM
938 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
939 i++;
940/* win: dble reset */
941 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
942 i++;
943 msleep(20);
944/* win: i2c reg read 00..7f */
6a7eba24 945 while (ov7648_sensor_init[i][0]) {
739570bb 946 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
6a7eba24
JFM
947 i++;
948 }
949}
950
951static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
952{
953 int i = 0;
6a7eba24 954
60017617
JFM
955 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
956 i++;
957 msleep(20);
6a7eba24 958 while (ov7660_sensor_init[i][0]) {
739570bb 959 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
6a7eba24
JFM
960 i++;
961 }
962}
963
964/* this function is called at probe time */
965static int sd_config(struct gspca_dev *gspca_dev,
966 const struct usb_device_id *id)
967{
968 struct sd *sd = (struct sd *) gspca_dev;
969 struct cam *cam;
6a7eba24
JFM
970
971 cam = &gspca_dev->cam;
6a7eba24
JFM
972 cam->epaddr = 0x01;
973 cam->cam_mode = vga_mode;
974 cam->nmodes = ARRAY_SIZE(vga_mode);
a5ae2062 975
9d64fdb1
JFM
976 sd->bridge = id->driver_info >> 16;
977 sd->sensor = id->driver_info >> 8;
978 sd->i2c_base = id->driver_info;
979
6a7eba24 980 sd->qindex = 4; /* set the quantization table */
a5ae2062
JFM
981 sd->brightness = BRIGHTNESS_DEF;
982 sd->contrast = CONTRAST_DEF;
983 sd->colors = COLOR_DEF;
984 sd->autogain = AUTOGAIN_DEF;
cebf3b67 985 sd->ag_cnt = -1;
0cae8964
JFM
986 sd->vflip = VFLIP_DEF;
987 sd->infrared = INFRARED_DEF;
cebf3b67 988
f50ba1be
JFM
989 switch (sd->sensor) {
990 case SENSOR_OV7630:
991 case SENSOR_OV7648:
992 case SENSOR_OV7660:
993 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
994 break;
995 }
6c86274f
JFM
996 if (sd->sensor != SENSOR_OV7630)
997 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
0cae8964
JFM
998 if (sd->sensor != SENSOR_MI0360)
999 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
6a7eba24
JFM
1000 return 0;
1001}
1002
012d6b02
JFM
1003/* this function is called at probe and resume time */
1004static int sd_init(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1005{
1006 struct sd *sd = (struct sd *) gspca_dev;
a5ae2062 1007/* const __u8 *sn9c1xx; */
6a7eba24 1008 __u8 regGpio[] = { 0x29, 0x74 };
60017617 1009 __u8 regF1;
6a7eba24 1010
3647fea8 1011 /* setup a selector by bridge */
60017617 1012 reg_w1(gspca_dev, 0xf1, 0x01);
739570bb 1013 reg_r(gspca_dev, 0x00, 1);
8f47a3ce
JFM
1014 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1015 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
739570bb 1016 regF1 = gspca_dev->usb_buf[0];
8f47a3ce 1017 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
3647fea8
HG
1018 switch (sd->bridge) {
1019 case BRIDGE_SN9C102P:
6a7eba24
JFM
1020 if (regF1 != 0x11)
1021 return -ENODEV;
60017617 1022 reg_w1(gspca_dev, 0x02, regGpio[1]);
6a7eba24 1023 break;
3647fea8 1024 case BRIDGE_SN9C105:
6a7eba24
JFM
1025 if (regF1 != 0x11)
1026 return -ENODEV;
674cbc69 1027 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24 1028 break;
3647fea8 1029 case BRIDGE_SN9C120:
6a7eba24
JFM
1030 if (regF1 != 0x12)
1031 return -ENODEV;
1032 regGpio[1] = 0x70;
674cbc69 1033 reg_w(gspca_dev, 0x01, regGpio, 2);
6a7eba24
JFM
1034 break;
1035 default:
60017617 1036/* case BRIDGE_SN9C110: */
3647fea8 1037/* case BRIDGE_SN9C325: */
6a7eba24
JFM
1038 if (regF1 != 0x12)
1039 return -ENODEV;
60017617 1040 reg_w1(gspca_dev, 0x02, 0x62);
6a7eba24
JFM
1041 break;
1042 }
1043
759aa3c2 1044 reg_w1(gspca_dev, 0xf1, 0x01);
6a7eba24
JFM
1045
1046 return 0;
1047}
1048
1049static unsigned int setexposure(struct gspca_dev *gspca_dev,
1050 unsigned int expo)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
a5ae2062 1053 static const __u8 doit[] = /* update sensor */
6a7eba24 1054 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
a5ae2062 1055 static const __u8 sensorgo[] = /* sensor on */
6a7eba24 1056 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
a5ae2062 1057 static const __u8 gainMo[] =
6a7eba24
JFM
1058 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1059
1060 switch (sd->sensor) {
1061 case SENSOR_HV7131R: {
1062 __u8 Expodoit[] =
1063 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1064
1065 Expodoit[3] = expo >> 16;
1066 Expodoit[4] = expo >> 8;
1067 Expodoit[5] = expo;
739570bb 1068 i2c_w8(gspca_dev, Expodoit);
6a7eba24
JFM
1069 break;
1070 }
1071 case SENSOR_MI0360: {
1072 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1073 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1074
1075 if (expo > 0x0635)
1076 expo = 0x0635;
1077 else if (expo < 0x0001)
1078 expo = 0x0001;
1079 expoMi[3] = expo >> 8;
1080 expoMi[4] = expo;
739570bb
JFM
1081 i2c_w8(gspca_dev, expoMi);
1082 i2c_w8(gspca_dev, doit);
1083 i2c_w8(gspca_dev, sensorgo);
6a7eba24
JFM
1084 break;
1085 }
1086 case SENSOR_MO4000: {
1087 __u8 expoMof[] =
1088 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1089 __u8 expoMo10[] =
1090 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1091
1092 if (expo > 0x1fff)
1093 expo = 0x1fff;
1094 else if (expo < 0x0001)
1095 expo = 0x0001;
1096 expoMof[3] = (expo & 0x03fc) >> 2;
739570bb 1097 i2c_w8(gspca_dev, expoMof);
6a7eba24
JFM
1098 expoMo10[3] = ((expo & 0x1c00) >> 10)
1099 | ((expo & 0x0003) << 4);
739570bb
JFM
1100 i2c_w8(gspca_dev, expoMo10);
1101 i2c_w8(gspca_dev, gainMo);
956e42d2 1102 PDEBUG(D_CONF, "set exposure %d",
6a7eba24
JFM
1103 ((expoMo10[3] & 0x07) << 10)
1104 | (expoMof[3] << 2)
1105 | ((expoMo10[3] & 0x30) >> 4));
1106 break;
1107 }
d2d16e90
JFM
1108 case SENSOR_OM6802: {
1109 __u8 gainOm[] =
1110 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1111
1112 if (expo > 0x03ff)
1113 expo = 0x03ff;
1114 if (expo < 0x0001)
1115 expo = 0x0001;
1116 gainOm[3] = expo >> 2;
1117 i2c_w8(gspca_dev, gainOm);
d55b83d3 1118 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
d2d16e90
JFM
1119 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1120 break;
1121 }
6a7eba24
JFM
1122 }
1123 return expo;
1124}
1125
05b809c7
JFM
1126/* this function is used for sensors o76xx only */
1127static void setbrightcont(struct gspca_dev *gspca_dev)
1128{
1129 struct sd *sd = (struct sd *) gspca_dev;
803f9ccf 1130 int val;
91de65ac 1131 __u8 reg84_full[0x15];
05b809c7 1132
803f9ccf
JFM
1133 memcpy(reg84_full, reg84, sizeof reg84_full);
1134 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1135 reg84_full[0] = (val + 1) / 2; /* red */
1136 reg84_full[2] = val; /* green */
1137 reg84_full[4] = (val + 1) / 5; /* blue */
1138 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
05b809c7 1139 / BRIGHTNESS_MAX;
803f9ccf 1140 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
05b809c7
JFM
1141 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1142}
1143
1144/* sensor != ov76xx */
6a7eba24
JFM
1145static void setbrightness(struct gspca_dev *gspca_dev)
1146{
1147 struct sd *sd = (struct sd *) gspca_dev;
1148 unsigned int expo;
1149 __u8 k2;
1150
d2d16e90 1151 k2 = sd->brightness >> 10;
6a7eba24
JFM
1152 switch (sd->sensor) {
1153 case SENSOR_HV7131R:
1154 expo = sd->brightness << 4;
1155 if (expo > 0x002dc6c0)
1156 expo = 0x002dc6c0;
1157 else if (expo < 0x02a0)
1158 expo = 0x02a0;
1159 sd->exposure = setexposure(gspca_dev, expo);
1160 break;
1161 case SENSOR_MI0360:
6a7eba24
JFM
1162 case SENSOR_MO4000:
1163 expo = sd->brightness >> 4;
1164 sd->exposure = setexposure(gspca_dev, expo);
1165 break;
d2d16e90
JFM
1166 case SENSOR_OM6802:
1167 expo = sd->brightness >> 6;
1168 sd->exposure = setexposure(gspca_dev, expo);
1169 k2 = sd->brightness >> 11;
1170 break;
6a7eba24
JFM
1171 }
1172
60017617 1173 reg_w1(gspca_dev, 0x96, k2);
6a7eba24
JFM
1174}
1175
05b809c7 1176/* sensor != ov76xx */
6a7eba24
JFM
1177static void setcontrast(struct gspca_dev *gspca_dev)
1178{
1179 struct sd *sd = (struct sd *) gspca_dev;
1180 __u8 k2;
1181 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1182
6a7eba24
JFM
1183 k2 = sd->contrast;
1184 contrast[2] = k2;
1185 contrast[0] = (k2 + 1) >> 1;
1186 contrast[4] = (k2 + 1) / 5;
739570bb 1187 reg_w(gspca_dev, 0x84, contrast, 6);
6a7eba24
JFM
1188}
1189
1190static void setcolors(struct gspca_dev *gspca_dev)
1191{
1192 struct sd *sd = (struct sd *) gspca_dev;
9c5f70f2 1193 __u8 blue, red;
6a7eba24 1194
9c5f70f2
JFM
1195 if (sd->colors >= 32) {
1196 red = 32 + (sd->colors - 32) / 2;
1197 blue = 64 - sd->colors;
d55b83d3 1198 } else {
9c5f70f2
JFM
1199 red = sd->colors;
1200 blue = 32 + (32 - sd->colors) / 2;
d55b83d3 1201 }
9c5f70f2
JFM
1202 reg_w1(gspca_dev, 0x05, red);
1203/* reg_w1(gspca_dev, 0x07, 32); */
1204 reg_w1(gspca_dev, 0x06, blue);
6a7eba24
JFM
1205}
1206
cebf3b67
JFM
1207static void setautogain(struct gspca_dev *gspca_dev)
1208{
1209 struct sd *sd = (struct sd *) gspca_dev;
1210
f50ba1be
JFM
1211 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1212 return;
1213 if (sd->autogain)
1214 sd->ag_cnt = AG_CNT_START;
1215 else
1216 sd->ag_cnt = -1;
cebf3b67
JFM
1217}
1218
6c86274f
JFM
1219static void setvflip(struct sd *sd)
1220{
6c86274f
JFM
1221 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1222 sd->vflip ? 0x82 : 0x02);
1223}
1224
0cae8964
JFM
1225static void setinfrared(struct sd *sd)
1226{
1227/*fixme: different sequence for StarCam Clip and StarCam 370i */
1228/* Clip */
1229 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1230 sd->infrared ? 0x66 : 0x64);
1231}
1232
6a7eba24 1233/* -- start the camera -- */
72ab97ce 1234static int sd_start(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1235{
1236 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 1237 int i;
8f47a3ce 1238 __u8 reg1, reg17, reg18;
a5ae2062 1239 const __u8 *sn9c1xx;
6a7eba24 1240 int mode;
a5ae2062
JFM
1241 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1242 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
a5ae2062 1243 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
6ab0b174 1244 static const __u8 CE_ov76xx[] =
674cbc69 1245 { 0x32, 0xdd, 0x32, 0xdd };
6a7eba24
JFM
1246
1247 sn9c1xx = sn_tb[(int) sd->sensor];
1248 configure_gpio(gspca_dev, sn9c1xx);
1249
60017617
JFM
1250 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1251 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1252 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1253 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1254 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1255 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1256 reg_w1(gspca_dev, 0xd3, 0x50);
1257 reg_w1(gspca_dev, 0xc6, 0x00);
1258 reg_w1(gspca_dev, 0xc7, 0x00);
1259 reg_w1(gspca_dev, 0xc8, 0x50);
1260 reg_w1(gspca_dev, 0xc9, 0x3c);
60017617 1261 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
6ab0b174
JFM
1262 switch (sd->sensor) {
1263 case SENSOR_OV7630:
1264 reg17 = 0xe2;
1265 break;
1266 case SENSOR_OV7648:
6270330a 1267 reg17 = 0x20;
568788a7 1268 break;
6ab0b174
JFM
1269/*jfm: from win trace */
1270 case SENSOR_OV7660:
1432f306
JFM
1271 if (sd->bridge == BRIDGE_SN9C120) {
1272 reg17 = 0xa0;
1273 break;
1274 }
1275 /* fall thru */
568788a7 1276 default:
8f47a3ce 1277 reg17 = 0x60;
568788a7
JFM
1278 break;
1279 }
8f47a3ce 1280 reg_w1(gspca_dev, 0x17, reg17);
1432f306 1281/* set reg1 was here */
60017617
JFM
1282 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1283 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1284 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1285 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
05b809c7
JFM
1286 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1287 for (i = 0; i < 8; i++)
1288 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
674cbc69 1289 switch (sd->sensor) {
6270330a
JFM
1290 case SENSOR_OV7648:
1291 reg_w1(gspca_dev, 0x9a, 0x0a);
1292 reg_w1(gspca_dev, 0x99, 0x60);
1293 break;
674cbc69 1294 case SENSOR_OV7660:
1432f306
JFM
1295 if (sd->bridge == BRIDGE_SN9C120) {
1296 reg_w1(gspca_dev, 0x9a, 0x05);
1297 break;
1298 }
1299 /* fall thru */
674cbc69 1300 default:
60017617
JFM
1301 reg_w1(gspca_dev, 0x9a, 0x08);
1302 reg_w1(gspca_dev, 0x99, 0x59);
674cbc69
JFM
1303 break;
1304 }
6a7eba24 1305
c2446b3e 1306 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
60017617 1307 if (mode)
1432f306 1308 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
60017617 1309 else
1432f306
JFM
1310 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1311 reg17 = 0x61; /* 0x:20: enable sensor clock */
6a7eba24
JFM
1312 switch (sd->sensor) {
1313 case SENSOR_HV7131R:
1314 hv7131R_InitSensor(gspca_dev);
6a7eba24
JFM
1315 break;
1316 case SENSOR_MI0360:
1317 mi0360_InitSensor(gspca_dev);
6a7eba24
JFM
1318 break;
1319 case SENSOR_MO4000:
1320 mo4000_InitSensor(gspca_dev);
1321 if (mode) {
1322/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1323 reg1 = 0x06; /* clk 24Mz */
1324 } else {
1325 reg17 = 0x22; /* 640 MCKSIZE */
60017617 1326/* reg1 = 0x06; * 640 clk 24Mz (done) */
6a7eba24
JFM
1327 }
1328 break;
d2d16e90
JFM
1329 case SENSOR_OM6802:
1330 om6802_InitSensor(gspca_dev);
d2d16e90
JFM
1331 reg17 = 0x64; /* 640 MCKSIZE */
1332 break;
6ab0b174
JFM
1333 case SENSOR_OV7630:
1334 ov7630_InitSensor(gspca_dev);
6c86274f 1335 setvflip(sd);
6ab0b174 1336 reg17 = 0xe2;
5b064da8 1337 reg1 = 0x44;
6ab0b174 1338 break;
6a7eba24 1339 case SENSOR_OV7648:
60017617 1340 ov7648_InitSensor(gspca_dev);
6270330a
JFM
1341 reg17 = 0x21;
1342/* reg1 = 0x42; * 42 - 46? */
6a7eba24
JFM
1343/* if (mode)
1344 ; * 320x2...
1345 else
1346 ; * 640x... */
1347 break;
1348 default:
1349/* case SENSOR_OV7660: */
1350 ov7660_InitSensor(gspca_dev);
1351 if (mode) {
1352/* reg17 = 0x21; * 320 */
1353/* reg1 = 0x44; */
60017617 1354/* reg1 = 0x46; (done) */
1432f306
JFM
1355 } else { /* 640 */
1356 if (sd->bridge == BRIDGE_SN9C120) {
1357 reg17 = 0xa2;
1358 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1359 } else {
1360 reg17 = 0x22;
1361 reg1 = 0x06; /* 24 Mhz, video trf eneble
1362 * inverse power down */
1363 }
6a7eba24
JFM
1364 }
1365 break;
1366 }
739570bb 1367 reg_w(gspca_dev, 0xc0, C0, 6);
8f47a3ce 1368 reg_w(gspca_dev, 0xca, CA, 4);
6ab0b174
JFM
1369 switch (sd->sensor) {
1370 case SENSOR_OV7630:
1371 case SENSOR_OV7648:
674cbc69 1372 case SENSOR_OV7660:
6ab0b174 1373 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
6a7eba24
JFM
1374 break;
1375 default:
739570bb 1376 reg_w(gspca_dev, 0xce, CE, 4);
6a7eba24
JFM
1377 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1378 break;
1379 }
1380
1381 /* here change size mode 0 -> VGA; 1 -> CIF */
8f47a3ce
JFM
1382 reg18 = sn9c1xx[0x18] | (mode << 4);
1383 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
6a7eba24 1384
739570bb
JFM
1385 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1386 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
6a7eba24 1387
8f47a3ce 1388 reg_w1(gspca_dev, 0x18, reg18);
6a7eba24 1389
60017617 1390 reg_w1(gspca_dev, 0x17, reg17);
1432f306 1391 reg_w1(gspca_dev, 0x01, reg1);
05b809c7 1392 switch (sd->sensor) {
05b809c7 1393 case SENSOR_MI0360:
0cae8964
JFM
1394 setinfrared(sd);
1395 /* fall thru */
1396 case SENSOR_HV7131R:
05b809c7
JFM
1397 case SENSOR_MO4000:
1398 case SENSOR_OM6802:
1399 setbrightness(gspca_dev);
1400 setcontrast(gspca_dev);
1401 break;
79a9098a
JFM
1402 case SENSOR_OV7630:
1403 setvflip(sd);
1404 /* fall thru */
05b809c7
JFM
1405 default: /* OV76xx */
1406 setbrightcont(gspca_dev);
1407 break;
1408 }
cebf3b67 1409 setautogain(gspca_dev);
72ab97ce 1410 return 0;
6a7eba24
JFM
1411}
1412
1413static void sd_stopN(struct gspca_dev *gspca_dev)
1414{
1415 struct sd *sd = (struct sd *) gspca_dev;
a5ae2062 1416 static const __u8 stophv7131[] =
6a7eba24 1417 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
a5ae2062 1418 static const __u8 stopmi0360[] =
6a7eba24 1419 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
6270330a
JFM
1420 static const __u8 stopov7648[] =
1421 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
6a7eba24 1422 __u8 data;
a5ae2062 1423 const __u8 *sn9c1xx;
6a7eba24
JFM
1424
1425 data = 0x0b;
1426 switch (sd->sensor) {
1427 case SENSOR_HV7131R:
739570bb 1428 i2c_w8(gspca_dev, stophv7131);
6a7eba24
JFM
1429 data = 0x2b;
1430 break;
1431 case SENSOR_MI0360:
739570bb 1432 i2c_w8(gspca_dev, stopmi0360);
6a7eba24
JFM
1433 data = 0x29;
1434 break;
6a7eba24 1435 case SENSOR_OV7648:
6270330a
JFM
1436 i2c_w8(gspca_dev, stopov7648);
1437 /* fall thru */
1438 case SENSOR_OV7630:
6a7eba24
JFM
1439 data = 0x29;
1440 break;
1441 default:
8f47a3ce 1442/* case SENSOR_MO4000: */
6a7eba24
JFM
1443/* case SENSOR_OV7660: */
1444 break;
1445 }
1446 sn9c1xx = sn_tb[(int) sd->sensor];
60017617
JFM
1447 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1448 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1449 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1450 reg_w1(gspca_dev, 0x01, data);
759aa3c2 1451 reg_w1(gspca_dev, 0xf1, 0x00);
6a7eba24
JFM
1452}
1453
cebf3b67 1454static void do_autogain(struct gspca_dev *gspca_dev)
6a7eba24
JFM
1455{
1456 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 1457 int delta;
cebf3b67 1458 int expotimes;
6a7eba24
JFM
1459 __u8 luma_mean = 130;
1460 __u8 luma_delta = 20;
1461
cebf3b67
JFM
1462 /* Thanks S., without your advice, autobright should not work :) */
1463 if (sd->ag_cnt < 0)
1464 return;
1465 if (--sd->ag_cnt >= 0)
1466 return;
1467 sd->ag_cnt = AG_CNT_START;
1468
1469 delta = atomic_read(&sd->avg_lum);
1470 PDEBUG(D_FRAM, "mean lum %d", delta);
6a7eba24
JFM
1471 if (delta < luma_mean - luma_delta ||
1472 delta > luma_mean + luma_delta) {
1473 switch (sd->sensor) {
1474 case SENSOR_HV7131R:
1475 expotimes = sd->exposure >> 8;
1476 expotimes += (luma_mean - delta) >> 4;
1477 if (expotimes < 0)
1478 expotimes = 0;
1479 sd->exposure = setexposure(gspca_dev,
1480 (unsigned int) (expotimes << 8));
1481 break;
cebf3b67
JFM
1482 default:
1483/* case SENSOR_MO4000: */
1484/* case SENSOR_MI0360: */
d2d16e90 1485/* case SENSOR_OM6802: */
6a7eba24
JFM
1486 expotimes = sd->exposure;
1487 expotimes += (luma_mean - delta) >> 6;
1488 if (expotimes < 0)
1489 expotimes = 0;
1490 sd->exposure = setexposure(gspca_dev,
1491 (unsigned int) expotimes);
1492 setcolors(gspca_dev);
1493 break;
1494 }
1495 }
1496}
1497
cebf3b67
JFM
1498/* scan the URB packets */
1499/* This function is run at interrupt level. */
6a7eba24
JFM
1500static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1501 struct gspca_frame *frame, /* target */
a5ae2062 1502 __u8 *data, /* isoc packet */
6a7eba24
JFM
1503 int len) /* iso packet length */
1504{
1505 struct sd *sd = (struct sd *) gspca_dev;
1506 int sof, avg_lum;
1507
1508 sof = len - 64;
1509 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1510
1511 /* end of frame */
1512 gspca_frame_add(gspca_dev, LAST_PACKET,
1513 frame, data, sof + 2);
1514 if (sd->ag_cnt < 0)
1515 return;
6a7eba24
JFM
1516/* w1 w2 w3 */
1517/* w4 w5 w6 */
1518/* w7 w8 */
1519/* w4 */
1520 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1521/* w6 */
1522 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1523/* w2 */
1524 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1525/* w8 */
1526 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1527/* w5 */
1528 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1529 avg_lum >>= 4;
cebf3b67 1530 atomic_set(&sd->avg_lum, avg_lum);
6a7eba24
JFM
1531 return;
1532 }
1533 if (gspca_dev->last_packet_type == LAST_PACKET) {
1534
1535 /* put the JPEG 422 header */
1536 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1537 }
1538 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1539}
1540
6a7eba24
JFM
1541static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1542{
1543 struct sd *sd = (struct sd *) gspca_dev;
1544
1545 sd->brightness = val;
05b809c7
JFM
1546 if (gspca_dev->streaming) {
1547 switch (sd->sensor) {
1548 case SENSOR_HV7131R:
1549 case SENSOR_MI0360:
1550 case SENSOR_MO4000:
1551 case SENSOR_OM6802:
1552 setbrightness(gspca_dev);
1553 break;
1554 default: /* OV76xx */
1555 setbrightcont(gspca_dev);
1556 break;
1557 }
1558 }
6a7eba24
JFM
1559 return 0;
1560}
1561
1562static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1563{
1564 struct sd *sd = (struct sd *) gspca_dev;
1565
6a7eba24
JFM
1566 *val = sd->brightness;
1567 return 0;
1568}
1569
1570static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1571{
1572 struct sd *sd = (struct sd *) gspca_dev;
1573
1574 sd->contrast = val;
05b809c7
JFM
1575 if (gspca_dev->streaming) {
1576 switch (sd->sensor) {
1577 case SENSOR_HV7131R:
1578 case SENSOR_MI0360:
1579 case SENSOR_MO4000:
1580 case SENSOR_OM6802:
1581 setcontrast(gspca_dev);
1582 break;
1583 default: /* OV76xx */
1584 setbrightcont(gspca_dev);
1585 break;
1586 }
1587 }
6a7eba24
JFM
1588 return 0;
1589}
1590
1591static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1592{
1593 struct sd *sd = (struct sd *) gspca_dev;
1594
1595 *val = sd->contrast;
1596 return 0;
1597}
1598
1599static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1600{
1601 struct sd *sd = (struct sd *) gspca_dev;
1602
1603 sd->colors = val;
1604 if (gspca_dev->streaming)
1605 setcolors(gspca_dev);
1606 return 0;
1607}
1608
1609static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1610{
1611 struct sd *sd = (struct sd *) gspca_dev;
1612
1613 *val = sd->colors;
1614 return 0;
1615}
1616
1617static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1618{
1619 struct sd *sd = (struct sd *) gspca_dev;
1620
1621 sd->autogain = val;
cebf3b67
JFM
1622 if (gspca_dev->streaming)
1623 setautogain(gspca_dev);
6a7eba24
JFM
1624 return 0;
1625}
1626
1627static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1628{
1629 struct sd *sd = (struct sd *) gspca_dev;
1630
1631 *val = sd->autogain;
1632 return 0;
1633}
1634
6c86274f
JFM
1635static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1636{
1637 struct sd *sd = (struct sd *) gspca_dev;
1638
1639 sd->vflip = val;
79a9098a
JFM
1640 if (gspca_dev->streaming)
1641 setvflip(sd);
6c86274f
JFM
1642 return 0;
1643}
1644
1645static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1646{
1647 struct sd *sd = (struct sd *) gspca_dev;
1648
1649 *val = sd->vflip;
1650 return 0;
1651}
1652
0cae8964
JFM
1653static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1654{
1655 struct sd *sd = (struct sd *) gspca_dev;
1656
1657 sd->infrared = val;
1658 if (gspca_dev->streaming)
1659 setinfrared(sd);
1660 return 0;
1661}
1662
1663static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1664{
1665 struct sd *sd = (struct sd *) gspca_dev;
1666
1667 *val = sd->infrared;
1668 return 0;
1669}
1670
6a7eba24 1671/* sub-driver description */
a5ae2062 1672static const struct sd_desc sd_desc = {
6a7eba24
JFM
1673 .name = MODULE_NAME,
1674 .ctrls = sd_ctrls,
1675 .nctrls = ARRAY_SIZE(sd_ctrls),
1676 .config = sd_config,
012d6b02 1677 .init = sd_init,
6a7eba24
JFM
1678 .start = sd_start,
1679 .stopN = sd_stopN,
6a7eba24 1680 .pkt_scan = sd_pkt_scan,
cebf3b67 1681 .dq_callback = do_autogain,
6a7eba24
JFM
1682};
1683
1684/* -- module initialisation -- */
9d64fdb1
JFM
1685#define BSI(bridge, sensor, i2c_addr) \
1686 .driver_info = (BRIDGE_ ## bridge << 16) \
1687 | (SENSOR_ ## sensor << 8) \
1688 | (i2c_addr)
a5ae2062 1689static const __devinitdata struct usb_device_id device_table[] = {
222a07ff 1690#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 1691 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
7b537391 1692 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
9d64fdb1
JFM
1693 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1694 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1695 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
c41492c8 1696#endif
7e21fda1 1697 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
9d64fdb1
JFM
1698 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1699 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1700/* bw600.inf:
1701 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1702/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1703/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1704 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1705/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1706 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1707/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1708/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1709 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1710/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1711/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1712 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1713 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
3c41cb77
JFM
1714#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1715 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1716#endif
9d64fdb1
JFM
1717/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1718/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1719/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
d2d16e90
JFM
1720 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1721/*bw600.inf:*/
6270330a 1722 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
9d64fdb1 1723 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
6ab0b174 1724 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
9d64fdb1 1725/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
222a07ff 1726#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1 1727 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
222a07ff 1728#endif
9d64fdb1 1729 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
821ced29 1730 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
222a07ff 1731#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
9d64fdb1
JFM
1732 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1733 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1734/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
c41492c8 1735#endif
e546f4bb 1736 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
6a7eba24
JFM
1737 {}
1738};
1739MODULE_DEVICE_TABLE(usb, device_table);
1740
1741/* -- device connect -- */
1742static int sd_probe(struct usb_interface *intf,
1743 const struct usb_device_id *id)
1744{
1745 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1746 THIS_MODULE);
1747}
1748
1749static struct usb_driver sd_driver = {
1750 .name = MODULE_NAME,
1751 .id_table = device_table,
1752 .probe = sd_probe,
1753 .disconnect = gspca_disconnect,
6a709749
JFM
1754#ifdef CONFIG_PM
1755 .suspend = gspca_suspend,
1756 .resume = gspca_resume,
1757#endif
6a7eba24
JFM
1758};
1759
1760/* -- module insert / remove -- */
1761static int __init sd_mod_init(void)
1762{
1763 if (usb_register(&sd_driver) < 0)
1764 return -1;
10b0e96e 1765 info("registered");
6a7eba24
JFM
1766 return 0;
1767}
1768static void __exit sd_mod_exit(void)
1769{
1770 usb_deregister(&sd_driver);
1771 info("deregistered");
1772}
1773
1774module_init(sd_mod_init);
1775module_exit(sd_mod_exit);