2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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
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.
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
22 #define MODULE_NAME "sonixj"
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
33 struct gspca_dev gspca_dev; /* !! must be the first item */
36 unsigned int exposure;
38 unsigned short brightness;
39 unsigned char contrast;
41 unsigned char autogain;
44 #define AG_CNT_START 13
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
53 char sensor; /* Type of image sensor chip */
54 #define SENSOR_HV7131R 0
55 #define SENSOR_MI0360 1
56 #define SENSOR_MO4000 2
57 #define SENSOR_OM6802 3
58 #define SENSOR_OV7630 4
59 #define SENSOR_OV7648 5
60 #define SENSOR_OV7660 6
61 unsigned char i2c_base;
64 /* V4L2 controls supported by the driver */
65 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
71 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
74 static struct ctrl sd_ctrls[] = {
77 .id = V4L2_CID_BRIGHTNESS,
78 .type = V4L2_CTRL_TYPE_INTEGER,
81 #define BRIGHTNESS_MAX 0xffff
82 .maximum = BRIGHTNESS_MAX,
84 #define BRIGHTNESS_DEF 0x7fff
85 .default_value = BRIGHTNESS_DEF,
87 .set = sd_setbrightness,
88 .get = sd_getbrightness,
92 .id = V4L2_CID_CONTRAST,
93 .type = V4L2_CTRL_TYPE_INTEGER,
96 #define CONTRAST_MAX 127
97 .maximum = CONTRAST_MAX,
99 #define CONTRAST_DEF 63
100 .default_value = CONTRAST_DEF,
102 .set = sd_setcontrast,
103 .get = sd_getcontrast,
107 .id = V4L2_CID_SATURATION,
108 .type = V4L2_CTRL_TYPE_INTEGER,
114 .default_value = COLOR_DEF,
119 #define AUTOGAIN_IDX 3
122 .id = V4L2_CID_AUTOGAIN,
123 .type = V4L2_CTRL_TYPE_BOOLEAN,
128 #define AUTOGAIN_DEF 1
129 .default_value = AUTOGAIN_DEF,
131 .set = sd_setautogain,
132 .get = sd_getautogain,
136 static struct v4l2_pix_format vga_mode[] = {
137 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
139 .sizeimage = 160 * 120 * 4 / 8 + 590,
140 .colorspace = V4L2_COLORSPACE_JPEG,
142 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
144 .sizeimage = 320 * 240 * 3 / 8 + 590,
145 .colorspace = V4L2_COLORSPACE_JPEG,
147 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
149 .sizeimage = 640 * 480 * 3 / 8 + 590,
150 .colorspace = V4L2_COLORSPACE_JPEG,
154 /*Data from sn9c102p+hv71331r */
155 static const __u8 sn_hv7131[] = {
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
166 static const __u8 sn_mi0360[] = {
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
177 static const __u8 sn_mo4000[] = {
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
188 static 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,
202 static 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
213 static const __u8 sn_ov7648[] = {
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
224 static const __u8 sn_ov7660[] = {
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,
235 /* sequence specific to the sensors - !! index = SENSOR_xxx */
236 static const __u8 *sn_tb[] = {
246 static const __u8 gamma_def[] = {
247 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
248 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
251 static const __u8 reg84[] = {
252 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
253 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
254 0xf7, 0x0f, 0x00, 0x00, 0x00
256 static const __u8 hv7131r_sensor_init[][8] = {
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},
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 */
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},
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},
287 static const __u8 mi0360_sensor_init[][8] = {
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},
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},
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 */
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 */
341 static const __u8 mo4000_sensor_init[][8] = {
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},
364 static __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},
374 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
375 * max AGC value in AE */
376 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
378 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
379 * preset brightness */
380 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
382 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
384 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
385 /* luminance mode (0x4f = AE) */
386 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
388 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
390 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
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}, */
398 static 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},
406 /* win: i2c_r from 00 to 80 */
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},
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},
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},
446 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
447 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
450 static const __u8 ov7660_sensor_init[][8] = {
451 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
453 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
454 /* Outformat = rawRGB */
455 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
456 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
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 */
462 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
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) */
471 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
472 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
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 */
499 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
500 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
501 /* band gap reference [0:3] DBLV */
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 */
511 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
512 /****** (some exchanges in the win trace) ******/
513 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
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},
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 */
524 /****** (some exchanges in the win trace) ******/
525 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
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 */
530 /****** (some exchanges in the win trace) ******/
531 /******!! startsensor KO if changed !!****/
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},
538 /* reg 0x04 reg 0x07 reg 0x10 */
539 /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
541 static const __u8 ov7648_sensor_init[][8] = {
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 */
597 static const __u8 qtable4[] = {
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
616 /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
617 static void reg_r(struct gspca_dev *gspca_dev,
618 __u16 value, int len)
620 usb_control_msg(gspca_dev->dev,
621 usb_rcvctrlpipe(gspca_dev->dev, 0),
623 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
625 gspca_dev->usb_buf, len,
627 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
630 static void reg_w1(struct gspca_dev *gspca_dev,
634 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
635 gspca_dev->usb_buf[0] = data;
636 usb_control_msg(gspca_dev->dev,
637 usb_sndctrlpipe(gspca_dev->dev, 0),
639 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
642 gspca_dev->usb_buf, 1,
645 static void reg_w(struct gspca_dev *gspca_dev,
650 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
651 value, buffer[0], buffer[1]);
652 if (len <= sizeof gspca_dev->usb_buf) {
653 memcpy(gspca_dev->usb_buf, buffer, len);
654 usb_control_msg(gspca_dev->dev,
655 usb_sndctrlpipe(gspca_dev->dev, 0),
657 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
659 gspca_dev->usb_buf, len,
664 tmpbuf = kmalloc(len, GFP_KERNEL);
665 memcpy(tmpbuf, buffer, len);
666 usb_control_msg(gspca_dev->dev,
667 usb_sndctrlpipe(gspca_dev->dev, 0),
669 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
677 /* I2C write 1 byte */
678 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
680 struct sd *sd = (struct sd *) gspca_dev;
682 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
683 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
684 gspca_dev->usb_buf[1] = sd->i2c_base;
685 gspca_dev->usb_buf[2] = reg;
686 gspca_dev->usb_buf[3] = val;
687 gspca_dev->usb_buf[4] = 0;
688 gspca_dev->usb_buf[5] = 0;
689 gspca_dev->usb_buf[6] = 0;
690 gspca_dev->usb_buf[7] = 0x10;
691 usb_control_msg(gspca_dev->dev,
692 usb_sndctrlpipe(gspca_dev->dev, 0),
694 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
695 0x08, /* value = i2c */
697 gspca_dev->usb_buf, 8,
701 /* I2C write 8 bytes */
702 static void i2c_w8(struct gspca_dev *gspca_dev,
705 memcpy(gspca_dev->usb_buf, buffer, 8);
706 usb_control_msg(gspca_dev->dev,
707 usb_sndctrlpipe(gspca_dev->dev, 0),
709 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
710 0x08, 0, /* value, index */
711 gspca_dev->usb_buf, 8,
715 /* read 5 bytes in gspca_dev->usb_buf */
716 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
718 struct sd *sd = (struct sd *) gspca_dev;
721 mode[0] = 0x81 | 0x10;
722 mode[1] = sd->i2c_base;
729 i2c_w8(gspca_dev, mode);
731 mode[0] = 0x81 | (5 << 4) | 0x02;
733 i2c_w8(gspca_dev, mode);
735 reg_r(gspca_dev, 0x0a, 5);
738 static int probesensor(struct gspca_dev *gspca_dev)
740 struct sd *sd = (struct sd *) gspca_dev;
742 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
744 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
746 i2c_r5(gspca_dev, 0); /* read sensor id */
747 if (gspca_dev->usb_buf[0] == 0x02
748 && gspca_dev->usb_buf[1] == 0x09
749 && gspca_dev->usb_buf[2] == 0x01
750 && gspca_dev->usb_buf[3] == 0x00
751 && gspca_dev->usb_buf[4] == 0x00) {
752 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
753 sd->sensor = SENSOR_HV7131R;
754 return SENSOR_HV7131R;
756 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
757 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
758 gspca_dev->usb_buf[2]);
759 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
763 static int configure_gpio(struct gspca_dev *gspca_dev,
766 struct sd *sd = (struct sd *) gspca_dev;
768 static const __u8 reg9a_def[] =
769 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
770 static const __u8 reg9a_sn9c325[] =
771 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
772 static const __u8 regd4[] = {0x60, 0x00, 0x00};
774 reg_w1(gspca_dev, 0xf1, 0x00);
775 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
778 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
779 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
780 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
781 switch (sd->bridge) {
783 reg9a = reg9a_sn9c325;
789 reg_w(gspca_dev, 0x9a, reg9a, 6);
791 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
793 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
795 switch (sd->sensor) {
797 reg_w1(gspca_dev, 0x02, 0x71);
798 reg_w1(gspca_dev, 0x01, 0x42);
799 reg_w1(gspca_dev, 0x17, 0x64);
800 reg_w1(gspca_dev, 0x01, 0x42);
802 /*jfm: from win trace */
804 reg_w1(gspca_dev, 0x01, 0x61);
805 reg_w1(gspca_dev, 0x17, 0xe2);
806 reg_w1(gspca_dev, 0x01, 0x60);
807 reg_w1(gspca_dev, 0x01, 0x40);
810 reg_w1(gspca_dev, 0x01, 0x43);
811 reg_w1(gspca_dev, 0x17, 0xae);
812 reg_w1(gspca_dev, 0x01, 0x42);
814 /*jfm: from win trace */
816 reg_w1(gspca_dev, 0x01, 0x61);
817 reg_w1(gspca_dev, 0x17, 0x20);
818 reg_w1(gspca_dev, 0x01, 0x60);
819 reg_w1(gspca_dev, 0x01, 0x40);
822 reg_w1(gspca_dev, 0x01, 0x43);
823 reg_w1(gspca_dev, 0x17, 0x61);
824 reg_w1(gspca_dev, 0x01, 0x42);
825 if (sd->sensor == SENSOR_HV7131R) {
826 if (probesensor(gspca_dev) < 0)
834 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
837 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
838 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
840 while (hv7131r_sensor_init[i][0]) {
841 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
844 i2c_w8(gspca_dev, SetSensorClk);
847 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
851 while (mi0360_sensor_init[i][0]) {
852 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
857 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
861 while (mo4000_sensor_init[i][0]) {
862 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
867 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
871 while (om6802_sensor_init[i][0]) {
872 i2c_w8(gspca_dev, om6802_sensor_init[i]);
877 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
881 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
883 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
886 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
888 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
891 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
893 /*jfm:win i2c_r from 00 to 80*/
895 while (ov7630_sensor_init[i][0]) {
896 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
901 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
905 while (ov7648_sensor_init[i][0]) {
906 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
911 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
915 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
918 while (ov7660_sensor_init[i][0]) {
919 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
924 /* this function is called at probe time */
925 static int sd_config(struct gspca_dev *gspca_dev,
926 const struct usb_device_id *id)
928 struct sd *sd = (struct sd *) gspca_dev;
931 cam = &gspca_dev->cam;
933 cam->cam_mode = vga_mode;
934 cam->nmodes = ARRAY_SIZE(vga_mode);
936 sd->bridge = id->driver_info >> 16;
937 sd->sensor = id->driver_info >> 8;
938 sd->i2c_base = id->driver_info;
940 sd->qindex = 4; /* set the quantization table */
941 sd->brightness = BRIGHTNESS_DEF;
942 sd->contrast = CONTRAST_DEF;
943 sd->colors = COLOR_DEF;
944 sd->autogain = AUTOGAIN_DEF;
947 switch (sd->sensor) {
951 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
958 /* this function is called at probe and resume time */
959 static int sd_init(struct gspca_dev *gspca_dev)
961 struct sd *sd = (struct sd *) gspca_dev;
962 /* const __u8 *sn9c1xx; */
963 __u8 regGpio[] = { 0x29, 0x74 };
966 /* setup a selector by bridge */
967 reg_w1(gspca_dev, 0xf1, 0x01);
968 reg_r(gspca_dev, 0x00, 1);
969 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
970 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
971 regF1 = gspca_dev->usb_buf[0];
972 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
973 switch (sd->bridge) {
974 case BRIDGE_SN9C102P:
977 reg_w1(gspca_dev, 0x02, regGpio[1]);
982 reg_w(gspca_dev, 0x02, regGpio, 2);
988 reg_w(gspca_dev, 0x02, regGpio, 2);
991 /* case BRIDGE_SN9C110: */
992 /* case BRIDGE_SN9C325: */
995 reg_w1(gspca_dev, 0x02, 0x62);
999 reg_w1(gspca_dev, 0xf1, 0x01);
1004 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1007 struct sd *sd = (struct sd *) gspca_dev;
1008 static const __u8 doit[] = /* update sensor */
1009 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1010 static const __u8 sensorgo[] = /* sensor on */
1011 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1012 static const __u8 gainMo[] =
1013 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1015 switch (sd->sensor) {
1016 case SENSOR_HV7131R: {
1018 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1020 Expodoit[3] = expo >> 16;
1021 Expodoit[4] = expo >> 8;
1023 i2c_w8(gspca_dev, Expodoit);
1026 case SENSOR_MI0360: {
1027 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1028 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1032 else if (expo < 0x0001)
1034 expoMi[3] = expo >> 8;
1036 i2c_w8(gspca_dev, expoMi);
1037 i2c_w8(gspca_dev, doit);
1038 i2c_w8(gspca_dev, sensorgo);
1041 case SENSOR_MO4000: {
1043 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1045 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1049 else if (expo < 0x0001)
1051 expoMof[3] = (expo & 0x03fc) >> 2;
1052 i2c_w8(gspca_dev, expoMof);
1053 expoMo10[3] = ((expo & 0x1c00) >> 10)
1054 | ((expo & 0x0003) << 4);
1055 i2c_w8(gspca_dev, expoMo10);
1056 i2c_w8(gspca_dev, gainMo);
1057 PDEBUG(D_CONF, "set exposure %d",
1058 ((expoMo10[3] & 0x07) << 10)
1060 | ((expoMo10[3] & 0x30) >> 4));
1063 case SENSOR_OM6802: {
1065 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1071 gainOm[3] = expo >> 2;
1072 i2c_w8(gspca_dev, gainOm);
1073 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1074 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1081 /* this function is used for sensors o76xx only */
1082 static void setbrightcont(struct gspca_dev *gspca_dev)
1084 struct sd *sd = (struct sd *) gspca_dev;
1086 __u8 reg84_full[0x15];
1088 memset(reg84_full, 0, sizeof reg84_full);
1089 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1090 reg84_full[2] = val;
1091 reg84_full[0] = (val + 1) / 2;
1092 reg84_full[4] = (val + 1) / 5;
1093 if (val > BRIGHTNESS_DEF)
1094 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1098 reg84_full[0x12] = val; /* 00..1f */
1099 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1102 /* sensor != ov76xx */
1103 static void setbrightness(struct gspca_dev *gspca_dev)
1105 struct sd *sd = (struct sd *) gspca_dev;
1109 k2 = sd->brightness >> 10;
1110 switch (sd->sensor) {
1111 case SENSOR_HV7131R:
1112 expo = sd->brightness << 4;
1113 if (expo > 0x002dc6c0)
1115 else if (expo < 0x02a0)
1117 sd->exposure = setexposure(gspca_dev, expo);
1121 expo = sd->brightness >> 4;
1122 sd->exposure = setexposure(gspca_dev, expo);
1125 expo = sd->brightness >> 6;
1126 sd->exposure = setexposure(gspca_dev, expo);
1127 k2 = sd->brightness >> 11;
1131 reg_w1(gspca_dev, 0x96, k2);
1134 /* sensor != ov76xx */
1135 static void setcontrast(struct gspca_dev *gspca_dev)
1137 struct sd *sd = (struct sd *) gspca_dev;
1139 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1143 contrast[0] = (k2 + 1) >> 1;
1144 contrast[4] = (k2 + 1) / 5;
1145 reg_w(gspca_dev, 0x84, contrast, 6);
1148 static void setcolors(struct gspca_dev *gspca_dev)
1150 struct sd *sd = (struct sd *) gspca_dev;
1153 if (sd->colors >= 32) {
1154 red = 32 + (sd->colors - 32) / 2;
1155 blue = 64 - sd->colors;
1158 blue = 32 + (32 - sd->colors) / 2;
1160 reg_w1(gspca_dev, 0x05, red);
1161 /* reg_w1(gspca_dev, 0x07, 32); */
1162 reg_w1(gspca_dev, 0x06, blue);
1165 static void setautogain(struct gspca_dev *gspca_dev)
1167 struct sd *sd = (struct sd *) gspca_dev;
1169 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1172 sd->ag_cnt = AG_CNT_START;
1177 /* -- start the camera -- */
1178 static void sd_start(struct gspca_dev *gspca_dev)
1180 struct sd *sd = (struct sd *) gspca_dev;
1182 __u8 reg1, reg17, reg18;
1183 const __u8 *sn9c1xx;
1185 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1186 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1187 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1188 static const __u8 CE_ov76xx[] =
1189 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7630/48 */
1191 sn9c1xx = sn_tb[(int) sd->sensor];
1192 configure_gpio(gspca_dev, sn9c1xx);
1194 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1195 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1196 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1197 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1198 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1199 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1200 reg_w1(gspca_dev, 0xd3, 0x50);
1201 reg_w1(gspca_dev, 0xc6, 0x00);
1202 reg_w1(gspca_dev, 0xc7, 0x00);
1203 reg_w1(gspca_dev, 0xc8, 0x50);
1204 reg_w1(gspca_dev, 0xc9, 0x3c);
1205 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1206 switch (sd->sensor) {
1213 /*jfm: from win trace */
1221 reg_w1(gspca_dev, 0x17, reg17);
1222 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1223 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1224 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1225 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1226 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1227 for (i = 0; i < 8; i++)
1228 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1229 reg_w1(gspca_dev, 0x9a, 0x08);
1230 reg_w1(gspca_dev, 0x99, 0x59);
1232 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1234 reg1 = 0x46; /* 320 clk 48Mhz */
1236 reg1 = 0x06; /* 640 clk 24Mz */
1238 switch (sd->sensor) {
1239 case SENSOR_HV7131R:
1240 hv7131R_InitSensor(gspca_dev);
1243 mi0360_InitSensor(gspca_dev);
1246 mo4000_InitSensor(gspca_dev);
1248 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1249 reg1 = 0x06; /* clk 24Mz */
1251 reg17 = 0x22; /* 640 MCKSIZE */
1252 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1256 om6802_InitSensor(gspca_dev);
1257 reg17 = 0x64; /* 640 MCKSIZE */
1260 ov7630_InitSensor(gspca_dev);
1265 ov7648_InitSensor(gspca_dev);
1274 /* case SENSOR_OV7660: */
1275 ov7660_InitSensor(gspca_dev);
1277 /* reg17 = 0x21; * 320 */
1279 /* reg1 = 0x46; (done) */
1281 reg17 = 0x22; /* 640 MCKSIZE */
1286 reg_w(gspca_dev, 0xc0, C0, 6);
1287 reg_w(gspca_dev, 0xca, CA, 4);
1288 switch (sd->sensor) {
1291 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1294 reg_w(gspca_dev, 0xce, CE, 4);
1295 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1299 /* here change size mode 0 -> VGA; 1 -> CIF */
1300 reg18 = sn9c1xx[0x18] | (mode << 4);
1301 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1303 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1304 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1306 reg_w1(gspca_dev, 0x18, reg18);
1308 reg_w1(gspca_dev, 0x17, reg17);
1309 switch (sd->sensor) {
1310 case SENSOR_HV7131R:
1314 setbrightness(gspca_dev);
1315 setcontrast(gspca_dev);
1317 default: /* OV76xx */
1318 setbrightcont(gspca_dev);
1321 setautogain(gspca_dev);
1322 reg_w1(gspca_dev, 0x01, reg1);
1325 static void sd_stopN(struct gspca_dev *gspca_dev)
1327 struct sd *sd = (struct sd *) gspca_dev;
1328 static const __u8 stophv7131[] =
1329 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1330 static const __u8 stopmi0360[] =
1331 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1333 const __u8 *sn9c1xx;
1336 switch (sd->sensor) {
1337 case SENSOR_HV7131R:
1338 i2c_w8(gspca_dev, stophv7131);
1342 i2c_w8(gspca_dev, stopmi0360);
1350 /* case SENSOR_MO4000: */
1351 /* case SENSOR_OV7660: */
1354 sn9c1xx = sn_tb[(int) sd->sensor];
1355 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1356 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1357 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1358 reg_w1(gspca_dev, 0x01, data);
1359 reg_w1(gspca_dev, 0xf1, 0x00);
1362 static void do_autogain(struct gspca_dev *gspca_dev)
1364 struct sd *sd = (struct sd *) gspca_dev;
1367 __u8 luma_mean = 130;
1368 __u8 luma_delta = 20;
1370 /* Thanks S., without your advice, autobright should not work :) */
1373 if (--sd->ag_cnt >= 0)
1375 sd->ag_cnt = AG_CNT_START;
1377 delta = atomic_read(&sd->avg_lum);
1378 PDEBUG(D_FRAM, "mean lum %d", delta);
1379 if (delta < luma_mean - luma_delta ||
1380 delta > luma_mean + luma_delta) {
1381 switch (sd->sensor) {
1382 case SENSOR_HV7131R:
1383 expotimes = sd->exposure >> 8;
1384 expotimes += (luma_mean - delta) >> 4;
1387 sd->exposure = setexposure(gspca_dev,
1388 (unsigned int) (expotimes << 8));
1391 /* case SENSOR_MO4000: */
1392 /* case SENSOR_MI0360: */
1393 /* case SENSOR_OM6802: */
1394 expotimes = sd->exposure;
1395 expotimes += (luma_mean - delta) >> 6;
1398 sd->exposure = setexposure(gspca_dev,
1399 (unsigned int) expotimes);
1400 setcolors(gspca_dev);
1406 /* scan the URB packets */
1407 /* This function is run at interrupt level. */
1408 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1409 struct gspca_frame *frame, /* target */
1410 __u8 *data, /* isoc packet */
1411 int len) /* iso packet length */
1413 struct sd *sd = (struct sd *) gspca_dev;
1417 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1420 gspca_frame_add(gspca_dev, LAST_PACKET,
1421 frame, data, sof + 2);
1428 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1430 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1432 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1434 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1436 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1438 atomic_set(&sd->avg_lum, avg_lum);
1441 if (gspca_dev->last_packet_type == LAST_PACKET) {
1443 /* put the JPEG 422 header */
1444 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1446 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1449 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1451 struct sd *sd = (struct sd *) gspca_dev;
1453 sd->brightness = val;
1454 if (gspca_dev->streaming) {
1455 switch (sd->sensor) {
1456 case SENSOR_HV7131R:
1460 setbrightness(gspca_dev);
1462 default: /* OV76xx */
1463 setbrightcont(gspca_dev);
1470 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1472 struct sd *sd = (struct sd *) gspca_dev;
1474 *val = sd->brightness;
1478 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1480 struct sd *sd = (struct sd *) gspca_dev;
1483 if (gspca_dev->streaming) {
1484 switch (sd->sensor) {
1485 case SENSOR_HV7131R:
1489 setcontrast(gspca_dev);
1491 default: /* OV76xx */
1492 setbrightcont(gspca_dev);
1499 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1501 struct sd *sd = (struct sd *) gspca_dev;
1503 *val = sd->contrast;
1507 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1509 struct sd *sd = (struct sd *) gspca_dev;
1512 if (gspca_dev->streaming)
1513 setcolors(gspca_dev);
1517 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1519 struct sd *sd = (struct sd *) gspca_dev;
1525 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1527 struct sd *sd = (struct sd *) gspca_dev;
1530 if (gspca_dev->streaming)
1531 setautogain(gspca_dev);
1535 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1537 struct sd *sd = (struct sd *) gspca_dev;
1539 *val = sd->autogain;
1543 /* sub-driver description */
1544 static const struct sd_desc sd_desc = {
1545 .name = MODULE_NAME,
1547 .nctrls = ARRAY_SIZE(sd_ctrls),
1548 .config = sd_config,
1552 .pkt_scan = sd_pkt_scan,
1553 .dq_callback = do_autogain,
1556 /* -- module initialisation -- */
1557 #define BSI(bridge, sensor, i2c_addr) \
1558 .driver_info = (BRIDGE_ ## bridge << 16) \
1559 | (SENSOR_ ## sensor << 8) \
1561 static const __devinitdata struct usb_device_id device_table[] = {
1562 #ifndef CONFIG_USB_SN9C102
1563 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1564 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1565 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1566 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1567 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1569 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1570 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1572 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1573 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1574 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1575 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1576 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1577 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1578 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1579 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1580 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1581 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1582 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1583 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1584 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1585 /* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1586 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1587 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1588 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1589 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1591 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1592 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1593 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1594 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1595 #ifndef CONFIG_USB_SN9C102
1596 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1597 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
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??)}, */
1603 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1606 MODULE_DEVICE_TABLE(usb, device_table);
1608 /* -- device connect -- */
1609 static int sd_probe(struct usb_interface *intf,
1610 const struct usb_device_id *id)
1612 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1616 static struct usb_driver sd_driver = {
1617 .name = MODULE_NAME,
1618 .id_table = device_table,
1620 .disconnect = gspca_disconnect,
1622 .suspend = gspca_suspend,
1623 .resume = gspca_resume,
1627 /* -- module insert / remove -- */
1628 static int __init sd_mod_init(void)
1630 if (usb_register(&sd_driver) < 0)
1635 static void __exit sd_mod_exit(void)
1637 usb_deregister(&sd_driver);
1638 info("deregistered");
1641 module_init(sd_mod_init);
1642 module_exit(sd_mod_exit);