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