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,
83 #define BRIGHTNESS_DEF 0x7fff
84 .default_value = BRIGHTNESS_DEF,
86 .set = sd_setbrightness,
87 .get = sd_getbrightness,
91 .id = V4L2_CID_CONTRAST,
92 .type = V4L2_CTRL_TYPE_INTEGER,
97 #define CONTRAST_DEF 63
98 .default_value = CONTRAST_DEF,
100 .set = sd_setcontrast,
101 .get = sd_getcontrast,
105 .id = V4L2_CID_SATURATION,
106 .type = V4L2_CTRL_TYPE_INTEGER,
111 #define COLOR_DEF 127
112 .default_value = COLOR_DEF,
119 .id = V4L2_CID_AUTOGAIN,
120 .type = V4L2_CTRL_TYPE_BOOLEAN,
125 #define AUTOGAIN_DEF 1
126 .default_value = AUTOGAIN_DEF,
128 .set = sd_setautogain,
129 .get = sd_getautogain,
133 static struct v4l2_pix_format vga_mode[] = {
134 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
136 .sizeimage = 160 * 120 * 3 / 8 + 590,
137 .colorspace = V4L2_COLORSPACE_JPEG,
139 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
141 .sizeimage = 320 * 240 * 3 / 8 + 590,
142 .colorspace = V4L2_COLORSPACE_JPEG,
144 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
146 .sizeimage = 640 * 480 * 3 / 8 + 590,
147 .colorspace = V4L2_COLORSPACE_JPEG,
151 /*Data from sn9c102p+hv71331r */
152 static const __u8 sn_hv7131[] = {
153 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
154 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
155 /* reg8 reg9 rega regb regc regd rege regf */
156 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
157 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
158 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
159 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
160 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
163 static const __u8 sn_mi0360[] = {
164 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
165 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
166 /* reg8 reg9 rega regb regc regd rege regf */
167 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
168 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
169 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
170 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
171 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
174 static const __u8 sn_mo4000[] = {
175 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
176 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
177 /* reg8 reg9 rega regb regc regd rege regf */
178 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
180 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
181 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
182 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
185 static const __u8 sn_om6802[] = {
186 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
187 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
188 /* reg8 reg9 rega regb regc regd rege regf */
189 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
190 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
191 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
192 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
193 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
194 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
195 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
199 static const __u8 sn_ov7630[] = {
200 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
201 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
202 /* reg8 reg9 rega regb regc regd rege regf */
203 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
204 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
205 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
206 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
207 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
210 static const __u8 sn_ov7648[] = {
211 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
212 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
213 /* reg8 reg9 rega regb regc regd rege regf */
214 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
215 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
216 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
217 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
218 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
221 static const __u8 sn_ov7660[] = {
222 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
223 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
224 /* reg8 reg9 rega regb regc regd rege regf */
225 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
226 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
227 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
228 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
229 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 /* sequence specific to the sensors - !! index = SENSOR_xxx */
233 static const __u8 *sn_tb[] = {
243 static const __u8 regsn20[] = {
244 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
245 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
247 static const __u8 regsn20_sn9c325[] = {
248 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
249 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
252 static const __u8 reg84[] = {
253 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
254 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
255 /* 0x00, 0x00, 0x00, 0x00, 0x00 */
256 0xf7, 0x0f, 0x0a, 0x00, 0x00
258 static const __u8 reg84_sn9c325[] = {
259 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
260 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
261 0xf8, 0x0f, 0x00, 0x00, 0x00
264 static const __u8 hv7131r_sensor_init[][8] = {
265 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
266 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
267 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
268 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
269 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
270 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
271 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
273 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
274 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
275 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
276 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
277 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
278 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
279 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
280 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
282 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
283 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
284 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
285 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
286 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
288 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
289 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
290 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
291 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
292 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
295 static const __u8 mi0360_sensor_init[][8] = {
296 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
297 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
298 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
299 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
300 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
301 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
302 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
303 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
304 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
305 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
306 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
307 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
308 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
309 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
310 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
311 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
312 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
313 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
314 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
315 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
316 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
317 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
318 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
319 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
321 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
322 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
323 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
324 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
325 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
326 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
327 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
328 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
330 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
331 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
332 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
334 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
336 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
337 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
338 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
339 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
341 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
342 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
343 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
344 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
345 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
346 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
349 static const __u8 mo4000_sensor_init[][8] = {
350 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
351 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
352 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
353 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
354 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
355 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
356 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
357 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
358 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
359 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
360 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
361 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
362 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
363 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
364 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
365 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
366 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
367 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
368 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
369 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
372 static __u8 om6802_sensor_init[][8] = {
373 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
374 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
375 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
376 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
377 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
378 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
379 /* white balance & auto-exposure */
380 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
382 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
383 * max AGC value in AE */
384 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
386 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
387 * preset brightness */
388 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
390 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
392 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
393 /* luminance mode (0x4f = AE) */
394 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
396 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
398 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
400 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
401 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
402 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
403 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
406 static const __u8 ov7630_sensor_init[][8] = {
407 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
408 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
409 /* win: delay 20ms */
410 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
411 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
412 /* win: delay 20ms */
413 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
414 /* win: loop on 2 wwrite, 1 read */
415 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
416 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
417 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
418 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
419 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
420 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
421 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
422 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
423 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
424 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
425 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
426 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
428 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
429 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
430 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
431 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
432 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
433 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
434 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
435 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
436 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
437 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
438 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
439 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
440 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
444 /*fixme: + 0x12, 0x04*/
445 {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
449 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
451 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
452 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
453 {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10},
456 static const __u8 ov7660_sensor_init[][8] = {
457 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
459 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
460 /* Outformat = rawRGB */
461 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
462 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
463 /* GAIN BLUE RED VREF */
464 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
465 /* COM 1 BAVE GEAVE AECHH */
466 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
467 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
468 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
469 /* AECH CLKRC COM7 COM8 */
470 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
471 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
472 /* HSTART HSTOP VSTRT VSTOP */
473 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
474 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
475 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
476 /* BOS GBOS GROS ROS (BGGR offset) */
477 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
478 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
479 /* AEW AEB VPT BBIAS */
480 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
481 /* GbBIAS RSVD EXHCH EXHCL */
482 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
483 /* RBIAS ADVFL ASDVFH YAVE */
484 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
485 /* HSYST HSYEN HREF */
486 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
487 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
488 /* ADC ACOM OFON TSLB */
489 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
490 /* COM11 COM12 COM13 COM14 */
491 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
492 /* EDGE COM15 COM16 COM17 */
493 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
494 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
495 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
496 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
497 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
498 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
499 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
500 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
501 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
502 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
503 /* LCC1 LCC2 LCC3 LCC4 */
504 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
505 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
506 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
507 /* band gap reference [0:3] DBLV */
508 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
509 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
510 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
511 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
512 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
513 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
514 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
515 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
516 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
517 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
518 /****** (some exchanges in the win trace) ******/
519 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
520 /* bits[3..0]reserved */
521 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
522 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
523 /* VREF vertical frame ctrl */
524 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
525 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
526 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
527 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
528 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
529 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
530 /****** (some exchanges in the win trace) ******/
531 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
532 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
533 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
534 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
535 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
536 /****** (some exchanges in the win trace) ******/
537 /******!! startsensor KO if changed !!****/
538 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
539 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
540 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
541 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
544 /* reg 0x04 reg 0x07 reg 0x10 */
545 /* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
547 static const __u8 ov7648_sensor_init[][8] = {
548 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
549 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
550 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
551 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
552 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
553 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
554 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
555 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
556 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
557 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
558 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
559 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
560 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
561 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
562 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
563 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
564 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
565 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
566 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
567 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
568 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
569 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
570 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
571 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
572 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
573 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
574 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
575 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
576 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
577 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
578 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
579 * This is currently setting a
580 * blue tint, and some things more , i leave it here for future test if
581 * somene is having problems with color on this sensor
582 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
583 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
584 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
585 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
586 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
587 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
588 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
589 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
590 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
591 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
592 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
593 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
594 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
595 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
596 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
597 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
598 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
599 /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
603 static const __u8 qtable4[] = {
604 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
605 0x06, 0x08, 0x0A, 0x11,
606 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
607 0x19, 0x19, 0x17, 0x15,
608 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
609 0x21, 0x2E, 0x21, 0x23,
610 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
611 0x25, 0x29, 0x2C, 0x29,
612 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
613 0x17, 0x1B, 0x29, 0x29,
614 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
615 0x29, 0x29, 0x29, 0x29,
616 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
617 0x29, 0x29, 0x29, 0x29,
618 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
619 0x29, 0x29, 0x29, 0x29
622 /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
623 static void reg_r(struct gspca_dev *gspca_dev,
624 __u16 value, int len)
626 usb_control_msg(gspca_dev->dev,
627 usb_rcvctrlpipe(gspca_dev->dev, 0),
629 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
631 gspca_dev->usb_buf, len,
633 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
636 static void reg_w1(struct gspca_dev *gspca_dev,
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),
645 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
648 gspca_dev->usb_buf, 1,
651 static void reg_w(struct gspca_dev *gspca_dev,
656 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
657 value, buffer[0], buffer[1]);
658 if (len <= sizeof gspca_dev->usb_buf) {
659 memcpy(gspca_dev->usb_buf, buffer, len);
660 usb_control_msg(gspca_dev->dev,
661 usb_sndctrlpipe(gspca_dev->dev, 0),
663 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
665 gspca_dev->usb_buf, len,
670 tmpbuf = kmalloc(len, GFP_KERNEL);
671 memcpy(tmpbuf, buffer, len);
672 usb_control_msg(gspca_dev->dev,
673 usb_sndctrlpipe(gspca_dev->dev, 0),
675 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
683 /* I2C write 1 byte */
684 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
686 struct sd *sd = (struct sd *) gspca_dev;
688 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
689 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
690 gspca_dev->usb_buf[1] = sd->i2c_base;
691 gspca_dev->usb_buf[2] = reg;
692 gspca_dev->usb_buf[3] = val;
693 gspca_dev->usb_buf[4] = 0;
694 gspca_dev->usb_buf[5] = 0;
695 gspca_dev->usb_buf[6] = 0;
696 gspca_dev->usb_buf[7] = 0x10;
697 usb_control_msg(gspca_dev->dev,
698 usb_sndctrlpipe(gspca_dev->dev, 0),
700 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
701 0x08, /* value = i2c */
703 gspca_dev->usb_buf, 8,
707 /* I2C write 8 bytes */
708 static void i2c_w8(struct gspca_dev *gspca_dev,
711 memcpy(gspca_dev->usb_buf, buffer, 8);
712 usb_control_msg(gspca_dev->dev,
713 usb_sndctrlpipe(gspca_dev->dev, 0),
715 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
716 0x08, 0, /* value, index */
717 gspca_dev->usb_buf, 8,
721 /* read 5 bytes in gspca_dev->usb_buf */
722 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
724 struct sd *sd = (struct sd *) gspca_dev;
727 mode[0] = 0x81 | 0x10;
728 mode[1] = sd->i2c_base;
735 i2c_w8(gspca_dev, mode);
737 mode[0] = 0x81 | (5 << 4) | 0x02;
739 i2c_w8(gspca_dev, mode);
741 reg_r(gspca_dev, 0x0a, 5);
744 static int probesensor(struct gspca_dev *gspca_dev)
746 struct sd *sd = (struct sd *) gspca_dev;
748 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
750 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
752 i2c_r5(gspca_dev, 0); /* read sensor id */
753 if (gspca_dev->usb_buf[0] == 0x02
754 && gspca_dev->usb_buf[1] == 0x09
755 && gspca_dev->usb_buf[2] == 0x01
756 && gspca_dev->usb_buf[3] == 0x00
757 && gspca_dev->usb_buf[4] == 0x00) {
758 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
759 sd->sensor = SENSOR_HV7131R;
760 return SENSOR_HV7131R;
762 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
763 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
764 gspca_dev->usb_buf[2]);
765 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
769 static int configure_gpio(struct gspca_dev *gspca_dev,
772 struct sd *sd = (struct sd *) gspca_dev;
774 static const __u8 reg9a_def[] =
775 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
776 static const __u8 reg9a_sn9c325[] =
777 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
778 static const __u8 regd4[] = {0x60, 0x00, 0x00};
780 reg_w1(gspca_dev, 0xf1, 0x00);
781 reg_w1(gspca_dev, 0x01, 0x00); /*jfm was sn9c1xx[1] in v1*/
784 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
785 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
786 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
787 switch (sd->bridge) {
789 reg9a = reg9a_sn9c325;
795 reg_w(gspca_dev, 0x9a, reg9a, 6);
797 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
799 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
801 switch (sd->sensor) {
803 reg_w1(gspca_dev, 0x02, 0x71);
804 reg_w1(gspca_dev, 0x01, 0x42);
805 reg_w1(gspca_dev, 0x17, 0x64);
806 reg_w1(gspca_dev, 0x01, 0x42);
809 reg_w1(gspca_dev, 0x01, 0x43);
810 reg_w1(gspca_dev, 0x17, 0xae);
811 reg_w1(gspca_dev, 0x01, 0x42);
814 reg_w1(gspca_dev, 0x01, 0x43);
815 reg_w1(gspca_dev, 0x17, 0x61);
816 reg_w1(gspca_dev, 0x01, 0x42);
817 if (sd->sensor == SENSOR_HV7131R) {
818 if (probesensor(gspca_dev) < 0)
826 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
829 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
830 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
832 while (hv7131r_sensor_init[i][0]) {
833 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
836 i2c_w8(gspca_dev, SetSensorClk);
839 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
843 while (mi0360_sensor_init[i][0]) {
844 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
849 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
853 while (mo4000_sensor_init[i][0]) {
854 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
859 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
863 while (om6802_sensor_init[i][0]) {
864 i2c_w8(gspca_dev, om6802_sensor_init[i]);
869 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
873 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
876 while (ov7630_sensor_init[i][0]) {
877 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
882 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
886 while (ov7648_sensor_init[i][0]) {
887 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
892 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
896 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
899 while (ov7660_sensor_init[i][0]) {
900 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
905 /* this function is called at probe time */
906 static int sd_config(struct gspca_dev *gspca_dev,
907 const struct usb_device_id *id)
909 struct sd *sd = (struct sd *) gspca_dev;
912 cam = &gspca_dev->cam;
914 cam->cam_mode = vga_mode;
915 cam->nmodes = ARRAY_SIZE(vga_mode);
917 sd->bridge = id->driver_info >> 16;
918 sd->sensor = id->driver_info >> 8;
919 sd->i2c_base = id->driver_info;
921 sd->qindex = 4; /* set the quantization table */
922 sd->brightness = BRIGHTNESS_DEF;
923 sd->contrast = CONTRAST_DEF;
924 sd->colors = COLOR_DEF;
925 sd->autogain = AUTOGAIN_DEF;
931 /* this function is called at open time */
932 static int sd_open(struct gspca_dev *gspca_dev)
934 struct sd *sd = (struct sd *) gspca_dev;
935 /* const __u8 *sn9c1xx; */
936 __u8 regGpio[] = { 0x29, 0x74 };
939 /* setup a selector by bridge */
940 reg_w1(gspca_dev, 0xf1, 0x01);
941 reg_r(gspca_dev, 0x00, 1);
942 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
943 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
944 regF1 = gspca_dev->usb_buf[0];
945 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
946 switch (sd->bridge) {
947 case BRIDGE_SN9C102P:
950 reg_w1(gspca_dev, 0x02, regGpio[1]);
955 reg_w(gspca_dev, 0x02, regGpio, 2);
961 reg_w(gspca_dev, 0x02, regGpio, 2);
964 /* case BRIDGE_SN9C110: */
965 /* case BRIDGE_SN9C325: */
968 reg_w1(gspca_dev, 0x02, 0x62);
972 reg_w1(gspca_dev, 0xf1, 0x01);
977 static unsigned int setexposure(struct gspca_dev *gspca_dev,
980 struct sd *sd = (struct sd *) gspca_dev;
981 static const __u8 doit[] = /* update sensor */
982 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
983 static const __u8 sensorgo[] = /* sensor on */
984 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
985 static const __u8 gainMo[] =
986 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
988 switch (sd->sensor) {
989 case SENSOR_HV7131R: {
991 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
993 Expodoit[3] = expo >> 16;
994 Expodoit[4] = expo >> 8;
996 i2c_w8(gspca_dev, Expodoit);
999 case SENSOR_MI0360: {
1000 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1001 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1005 else if (expo < 0x0001)
1007 expoMi[3] = expo >> 8;
1009 i2c_w8(gspca_dev, expoMi);
1010 i2c_w8(gspca_dev, doit);
1011 i2c_w8(gspca_dev, sensorgo);
1014 case SENSOR_MO4000: {
1016 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1018 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1022 else if (expo < 0x0001)
1024 expoMof[3] = (expo & 0x03fc) >> 2;
1025 i2c_w8(gspca_dev, expoMof);
1026 expoMo10[3] = ((expo & 0x1c00) >> 10)
1027 | ((expo & 0x0003) << 4);
1028 i2c_w8(gspca_dev, expoMo10);
1029 i2c_w8(gspca_dev, gainMo);
1030 PDEBUG(D_CONF, "set exposure %d",
1031 ((expoMo10[3] & 0x07) << 10)
1033 | ((expoMo10[3] & 0x30) >> 4));
1036 case SENSOR_OM6802: {
1038 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1044 gainOm[3] = expo >> 2;
1045 i2c_w8(gspca_dev, gainOm);
1046 reg_w1(gspca_dev, 0x96, expo >> 5);
1047 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1054 static void setbrightness(struct gspca_dev *gspca_dev)
1056 struct sd *sd = (struct sd *) gspca_dev;
1060 k2 = sd->brightness >> 10;
1061 switch (sd->sensor) {
1062 case SENSOR_HV7131R:
1063 expo = sd->brightness << 4;
1064 if (expo > 0x002dc6c0)
1066 else if (expo < 0x02a0)
1068 sd->exposure = setexposure(gspca_dev, expo);
1072 expo = sd->brightness >> 4;
1073 sd->exposure = setexposure(gspca_dev, expo);
1076 expo = sd->brightness >> 6;
1077 sd->exposure = setexposure(gspca_dev, expo);
1078 k2 = sd->brightness >> 11;
1082 reg_w1(gspca_dev, 0x96, k2);
1085 static void setcontrast(struct gspca_dev *gspca_dev)
1087 struct sd *sd = (struct sd *) gspca_dev;
1089 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1093 contrast[0] = (k2 + 1) >> 1;
1094 contrast[4] = (k2 + 1) / 5;
1095 reg_w(gspca_dev, 0x84, contrast, 6);
1098 static void setcolors(struct gspca_dev *gspca_dev)
1100 struct sd *sd = (struct sd *) gspca_dev;
1104 colour = sd->colors - 128;
1106 data = (colour + 32) & 0x7f; /* blue */
1108 data = (-colour + 32) & 0x7f; /* red */
1109 reg_w1(gspca_dev, 0x05, data);
1112 static void setautogain(struct gspca_dev *gspca_dev)
1114 struct sd *sd = (struct sd *) gspca_dev;
1116 switch (sd->sensor) {
1117 case SENSOR_HV7131R:
1121 sd->ag_cnt = AG_CNT_START;
1128 /* -- start the camera -- */
1129 static void sd_start(struct gspca_dev *gspca_dev)
1131 struct sd *sd = (struct sd *) gspca_dev;
1133 __u8 reg1, reg17, reg18;
1134 const __u8 *sn9c1xx;
1136 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1137 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1138 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1139 static const __u8 CE_ov76xx[] =
1140 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7630/48 */
1142 sn9c1xx = sn_tb[(int) sd->sensor];
1143 configure_gpio(gspca_dev, sn9c1xx);
1145 /* reg_w1(gspca_dev, 0x01, 0x44); jfm from win trace*/
1146 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1147 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1148 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1149 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1150 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1151 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1152 reg_w1(gspca_dev, 0xd3, 0x50);
1153 reg_w1(gspca_dev, 0xc6, 0x00);
1154 reg_w1(gspca_dev, 0xc7, 0x00);
1155 reg_w1(gspca_dev, 0xc8, 0x50);
1156 reg_w1(gspca_dev, 0xc9, 0x3c);
1157 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1158 switch (sd->sensor) {
1165 /*jfm: from win trace */
1173 reg_w1(gspca_dev, 0x17, reg17);
1174 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1175 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1176 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1177 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1178 switch (sd->bridge) {
1179 case BRIDGE_SN9C325:
1180 reg_w(gspca_dev, 0x20, regsn20_sn9c325,
1181 sizeof regsn20_sn9c325);
1182 for (i = 0; i < 8; i++)
1183 reg_w(gspca_dev, 0x84, reg84_sn9c325,
1184 sizeof reg84_sn9c325);
1185 reg_w1(gspca_dev, 0x9a, 0x0a);
1186 reg_w1(gspca_dev, 0x99, 0x60);
1189 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1190 for (i = 0; i < 8; i++)
1191 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1192 reg_w1(gspca_dev, 0x9a, 0x08);
1193 reg_w1(gspca_dev, 0x99, 0x59);
1197 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1199 reg1 = 0x46; /* 320 clk 48Mhz */
1201 reg1 = 0x06; /* 640 clk 24Mz */
1203 switch (sd->sensor) {
1204 case SENSOR_HV7131R:
1205 hv7131R_InitSensor(gspca_dev);
1208 mi0360_InitSensor(gspca_dev);
1211 mo4000_InitSensor(gspca_dev);
1213 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1214 reg1 = 0x06; /* clk 24Mz */
1216 reg17 = 0x22; /* 640 MCKSIZE */
1217 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1221 om6802_InitSensor(gspca_dev);
1222 reg17 = 0x64; /* 640 MCKSIZE */
1225 ov7630_InitSensor(gspca_dev);
1230 ov7648_InitSensor(gspca_dev);
1239 /* case SENSOR_OV7660: */
1240 ov7660_InitSensor(gspca_dev);
1242 /* reg17 = 0x21; * 320 */
1244 /* reg1 = 0x46; (done) */
1246 reg17 = 0x22; /* 640 MCKSIZE */
1251 reg_w(gspca_dev, 0xc0, C0, 6);
1252 reg_w(gspca_dev, 0xca, CA, 4);
1253 switch (sd->sensor) {
1256 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1259 reg_w(gspca_dev, 0xce, CE, 4);
1260 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1264 /* here change size mode 0 -> VGA; 1 -> CIF */
1265 reg18 = sn9c1xx[0x18] | (mode << 4);
1266 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1268 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1269 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1271 reg_w1(gspca_dev, 0x18, reg18);
1273 reg_w1(gspca_dev, 0x17, reg17);
1274 reg_w1(gspca_dev, 0x01, reg1);
1275 setbrightness(gspca_dev);
1276 setcontrast(gspca_dev);
1277 setautogain(gspca_dev);
1280 static void sd_stopN(struct gspca_dev *gspca_dev)
1282 struct sd *sd = (struct sd *) gspca_dev;
1283 static const __u8 stophv7131[] =
1284 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1285 static const __u8 stopmi0360[] =
1286 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1288 const __u8 *sn9c1xx;
1291 switch (sd->sensor) {
1292 case SENSOR_HV7131R:
1293 i2c_w8(gspca_dev, stophv7131);
1297 i2c_w8(gspca_dev, stopmi0360);
1305 /* case SENSOR_MO4000: */
1306 /* case SENSOR_OV7660: */
1309 sn9c1xx = sn_tb[(int) sd->sensor];
1310 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1311 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1312 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1313 reg_w1(gspca_dev, 0x01, data);
1314 reg_w1(gspca_dev, 0xf1, 0x01);
1317 static void sd_stop0(struct gspca_dev *gspca_dev)
1321 static void sd_close(struct gspca_dev *gspca_dev)
1325 static void do_autogain(struct gspca_dev *gspca_dev)
1327 struct sd *sd = (struct sd *) gspca_dev;
1330 __u8 luma_mean = 130;
1331 __u8 luma_delta = 20;
1333 /* Thanks S., without your advice, autobright should not work :) */
1336 if (--sd->ag_cnt >= 0)
1338 sd->ag_cnt = AG_CNT_START;
1340 delta = atomic_read(&sd->avg_lum);
1341 PDEBUG(D_FRAM, "mean lum %d", delta);
1342 if (delta < luma_mean - luma_delta ||
1343 delta > luma_mean + luma_delta) {
1344 switch (sd->sensor) {
1345 case SENSOR_HV7131R:
1346 expotimes = sd->exposure >> 8;
1347 expotimes += (luma_mean - delta) >> 4;
1350 sd->exposure = setexposure(gspca_dev,
1351 (unsigned int) (expotimes << 8));
1354 /* case SENSOR_MO4000: */
1355 /* case SENSOR_MI0360: */
1356 /* case SENSOR_OM6802: */
1357 expotimes = sd->exposure;
1358 expotimes += (luma_mean - delta) >> 6;
1361 sd->exposure = setexposure(gspca_dev,
1362 (unsigned int) expotimes);
1363 setcolors(gspca_dev);
1369 /* scan the URB packets */
1370 /* This function is run at interrupt level. */
1371 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1372 struct gspca_frame *frame, /* target */
1373 __u8 *data, /* isoc packet */
1374 int len) /* iso packet length */
1376 struct sd *sd = (struct sd *) gspca_dev;
1380 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1383 gspca_frame_add(gspca_dev, LAST_PACKET,
1384 frame, data, sof + 2);
1391 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1393 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1395 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1397 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1399 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1401 atomic_set(&sd->avg_lum, avg_lum);
1404 if (gspca_dev->last_packet_type == LAST_PACKET) {
1406 /* put the JPEG 422 header */
1407 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1409 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1412 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1414 struct sd *sd = (struct sd *) gspca_dev;
1415 __u8 hexpo, mexpo, lexpo;
1417 switch (sd->sensor) {
1418 case SENSOR_HV7131R:
1419 /* read sensor exposure */
1420 i2c_r5(gspca_dev, 0x25);
1421 return (gspca_dev->usb_buf[0] << 16)
1422 | (gspca_dev->usb_buf[1] << 8)
1423 | gspca_dev->usb_buf[2];
1425 /* read sensor exposure */
1426 i2c_r5(gspca_dev, 0x09);
1427 return (gspca_dev->usb_buf[0] << 8)
1428 | gspca_dev->usb_buf[1];
1430 /* case SENSOR_MO4000: */
1431 i2c_r5(gspca_dev, 0x0e);
1432 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1433 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1434 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1435 PDEBUG(D_CONF, "exposure %d",
1436 (hexpo << 10) | (mexpo << 2) | lexpo);
1437 return (hexpo << 10) | (mexpo << 2) | lexpo;
1440 /* case SENSOR_OV7648: * jfm: is it ok for 7648? */
1441 /* case SENSOR_OV7660: */
1442 /* read sensor exposure */
1443 i2c_r5(gspca_dev, 0x04);
1444 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1445 lexpo = gspca_dev->usb_buf[0] & 0x02;
1446 i2c_r5(gspca_dev, 0x08);
1447 mexpo = gspca_dev->usb_buf[2];
1448 return (hexpo << 10) | (mexpo << 2) | lexpo;
1454 static void getbrightness(struct gspca_dev *gspca_dev)
1456 struct sd *sd = (struct sd *) gspca_dev;
1458 /* hardcoded registers seem not readable */
1459 switch (sd->sensor) {
1460 case SENSOR_HV7131R:
1461 sd->brightness = getexposure(gspca_dev) >> 4;
1466 sd->brightness = getexposure(gspca_dev) << 4;
1471 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1473 struct sd *sd = (struct sd *) gspca_dev;
1475 sd->brightness = val;
1476 if (gspca_dev->streaming)
1477 setbrightness(gspca_dev);
1481 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1483 struct sd *sd = (struct sd *) gspca_dev;
1485 getbrightness(gspca_dev);
1486 *val = sd->brightness;
1490 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1492 struct sd *sd = (struct sd *) gspca_dev;
1495 if (gspca_dev->streaming)
1496 setcontrast(gspca_dev);
1500 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1502 struct sd *sd = (struct sd *) gspca_dev;
1504 *val = sd->contrast;
1508 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1510 struct sd *sd = (struct sd *) gspca_dev;
1513 if (gspca_dev->streaming)
1514 setcolors(gspca_dev);
1518 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1520 struct sd *sd = (struct sd *) gspca_dev;
1526 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1528 struct sd *sd = (struct sd *) gspca_dev;
1531 if (gspca_dev->streaming)
1532 setautogain(gspca_dev);
1536 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1538 struct sd *sd = (struct sd *) gspca_dev;
1540 *val = sd->autogain;
1544 /* sub-driver description */
1545 static const struct sd_desc sd_desc = {
1546 .name = MODULE_NAME,
1548 .nctrls = ARRAY_SIZE(sd_ctrls),
1549 .config = sd_config,
1555 .pkt_scan = sd_pkt_scan,
1556 .dq_callback = do_autogain,
1559 /* -- module initialisation -- */
1560 #define BSI(bridge, sensor, i2c_addr) \
1561 .driver_info = (BRIDGE_ ## bridge << 16) \
1562 | (SENSOR_ ## sensor << 8) \
1564 static const __devinitdata struct usb_device_id device_table[] = {
1565 #ifndef CONFIG_USB_SN9C102
1566 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1567 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1568 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1569 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1570 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1572 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1573 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1575 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1576 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1577 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1578 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1579 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1580 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1581 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1582 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1583 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1584 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1585 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1586 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1587 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1588 /* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1589 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1590 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1591 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1592 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1594 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
1595 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1596 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1597 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1598 #ifndef CONFIG_USB_SN9C102
1599 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1600 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1601 /* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1602 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1603 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1604 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1606 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1609 MODULE_DEVICE_TABLE(usb, device_table);
1611 /* -- device connect -- */
1612 static int sd_probe(struct usb_interface *intf,
1613 const struct usb_device_id *id)
1615 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1619 static struct usb_driver sd_driver = {
1620 .name = MODULE_NAME,
1621 .id_table = device_table,
1623 .disconnect = gspca_disconnect,
1626 /* -- module insert / remove -- */
1627 static int __init sd_mod_init(void)
1629 if (usb_register(&sd_driver) < 0)
1634 static void __exit sd_mod_exit(void)
1636 usb_deregister(&sd_driver);
1637 info("deregistered");
1640 module_init(sd_mod_init);
1641 module_exit(sd_mod_exit);