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 to gspca_dev->usb_buf */
617 static void reg_r(struct gspca_dev
*gspca_dev
,
618 __u16 value
, int len
)
621 if (len
> USB_BUF_SZ
) {
622 err("reg_r: buffer overflow");
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]);
659 if (len
> USB_BUF_SZ
) {
660 err("reg_w: buffer overflow");
664 memcpy(gspca_dev
->usb_buf
, buffer
, len
);
665 usb_control_msg(gspca_dev
->dev
,
666 usb_sndctrlpipe(gspca_dev
->dev
, 0),
668 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
670 gspca_dev
->usb_buf
, len
,
674 /* I2C write 1 byte */
675 static void i2c_w1(struct gspca_dev
*gspca_dev
, __u8 reg
, __u8 val
)
677 struct sd
*sd
= (struct sd
*) gspca_dev
;
679 PDEBUG(D_USBO
, "i2c_w2 [%02x] = %02x", reg
, val
);
680 gspca_dev
->usb_buf
[0] = 0x81 | (2 << 4); /* = a1 */
681 gspca_dev
->usb_buf
[1] = sd
->i2c_base
;
682 gspca_dev
->usb_buf
[2] = reg
;
683 gspca_dev
->usb_buf
[3] = val
;
684 gspca_dev
->usb_buf
[4] = 0;
685 gspca_dev
->usb_buf
[5] = 0;
686 gspca_dev
->usb_buf
[6] = 0;
687 gspca_dev
->usb_buf
[7] = 0x10;
688 usb_control_msg(gspca_dev
->dev
,
689 usb_sndctrlpipe(gspca_dev
->dev
, 0),
691 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
692 0x08, /* value = i2c */
694 gspca_dev
->usb_buf
, 8,
698 /* I2C write 8 bytes */
699 static void i2c_w8(struct gspca_dev
*gspca_dev
,
702 memcpy(gspca_dev
->usb_buf
, buffer
, 8);
703 usb_control_msg(gspca_dev
->dev
,
704 usb_sndctrlpipe(gspca_dev
->dev
, 0),
706 USB_DIR_OUT
| USB_TYPE_VENDOR
| USB_RECIP_INTERFACE
,
707 0x08, 0, /* value, index */
708 gspca_dev
->usb_buf
, 8,
713 /* read 5 bytes in gspca_dev->usb_buf */
714 static void i2c_r5(struct gspca_dev
*gspca_dev
, __u8 reg
)
716 struct sd
*sd
= (struct sd
*) gspca_dev
;
719 mode
[0] = 0x81 | 0x10;
720 mode
[1] = sd
->i2c_base
;
727 i2c_w8(gspca_dev
, mode
);
729 mode
[0] = 0x81 | (5 << 4) | 0x02;
731 i2c_w8(gspca_dev
, mode
);
733 reg_r(gspca_dev
, 0x0a, 5);
736 static int probesensor(struct gspca_dev
*gspca_dev
)
738 struct sd
*sd
= (struct sd
*) gspca_dev
;
740 i2c_w1(gspca_dev
, 0x02, 0); /* sensor wakeup */
742 reg_w1(gspca_dev
, 0x02, 0x66); /* Gpio on */
744 i2c_r5(gspca_dev
, 0); /* read sensor id */
745 if (gspca_dev
->usb_buf
[0] == 0x02
746 && gspca_dev
->usb_buf
[1] == 0x09
747 && gspca_dev
->usb_buf
[2] == 0x01
748 && gspca_dev
->usb_buf
[3] == 0x00
749 && gspca_dev
->usb_buf
[4] == 0x00) {
750 PDEBUG(D_PROBE
, "Find Sensor sn9c102P HV7131R");
751 sd
->sensor
= SENSOR_HV7131R
;
752 return SENSOR_HV7131R
;
754 PDEBUG(D_PROBE
, "Find Sensor 0x%02x 0x%02x 0x%02x",
755 gspca_dev
->usb_buf
[0], gspca_dev
->usb_buf
[1],
756 gspca_dev
->usb_buf
[2]);
757 PDEBUG(D_PROBE
, "Sensor sn9c102P Not found");
761 static int configure_gpio(struct gspca_dev
*gspca_dev
,
764 struct sd
*sd
= (struct sd
*) gspca_dev
;
766 static const __u8 reg9a_def
[] =
767 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
768 static const __u8 reg9a_sn9c325
[] =
769 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
770 static const __u8 regd4
[] = {0x60, 0x00, 0x00};
772 reg_w1(gspca_dev
, 0xf1, 0x00);
773 reg_w1(gspca_dev
, 0x01, sn9c1xx
[1]);
776 reg_w(gspca_dev
, 0x01, &sn9c1xx
[1], 2);
777 reg_w(gspca_dev
, 0x08, &sn9c1xx
[8], 2);
778 reg_w(gspca_dev
, 0x17, &sn9c1xx
[0x17], 5); /* jfm len was 3 */
779 switch (sd
->bridge
) {
781 reg9a
= reg9a_sn9c325
;
787 reg_w(gspca_dev
, 0x9a, reg9a
, 6);
789 reg_w(gspca_dev
, 0xd4, regd4
, sizeof regd4
); /*fixme:jfm was 60 only*/
791 reg_w(gspca_dev
, 0x03, &sn9c1xx
[3], 0x0f);
793 switch (sd
->sensor
) {
795 reg_w1(gspca_dev
, 0x02, 0x71);
796 reg_w1(gspca_dev
, 0x01, 0x42);
797 reg_w1(gspca_dev
, 0x17, 0x64);
798 reg_w1(gspca_dev
, 0x01, 0x42);
800 /*jfm: from win trace */
802 reg_w1(gspca_dev
, 0x01, 0x61);
803 reg_w1(gspca_dev
, 0x17, 0xe2);
804 reg_w1(gspca_dev
, 0x01, 0x60);
805 reg_w1(gspca_dev
, 0x01, 0x40);
808 reg_w1(gspca_dev
, 0x01, 0x43);
809 reg_w1(gspca_dev
, 0x17, 0xae);
810 reg_w1(gspca_dev
, 0x01, 0x42);
812 /*jfm: from win trace */
814 reg_w1(gspca_dev
, 0x01, 0x61);
815 reg_w1(gspca_dev
, 0x17, 0x20);
816 reg_w1(gspca_dev
, 0x01, 0x60);
817 reg_w1(gspca_dev
, 0x01, 0x40);
820 reg_w1(gspca_dev
, 0x01, 0x43);
821 reg_w1(gspca_dev
, 0x17, 0x61);
822 reg_w1(gspca_dev
, 0x01, 0x42);
823 if (sd
->sensor
== SENSOR_HV7131R
) {
824 if (probesensor(gspca_dev
) < 0)
832 static void hv7131R_InitSensor(struct gspca_dev
*gspca_dev
)
835 static const __u8 SetSensorClk
[] = /* 0x08 Mclk */
836 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
838 while (hv7131r_sensor_init
[i
][0]) {
839 i2c_w8(gspca_dev
, hv7131r_sensor_init
[i
]);
842 i2c_w8(gspca_dev
, SetSensorClk
);
845 static void mi0360_InitSensor(struct gspca_dev
*gspca_dev
)
849 while (mi0360_sensor_init
[i
][0]) {
850 i2c_w8(gspca_dev
, mi0360_sensor_init
[i
]);
855 static void mo4000_InitSensor(struct gspca_dev
*gspca_dev
)
859 while (mo4000_sensor_init
[i
][0]) {
860 i2c_w8(gspca_dev
, mo4000_sensor_init
[i
]);
865 static void om6802_InitSensor(struct gspca_dev
*gspca_dev
)
869 while (om6802_sensor_init
[i
][0]) {
870 i2c_w8(gspca_dev
, om6802_sensor_init
[i
]);
875 static void ov7630_InitSensor(struct gspca_dev
*gspca_dev
)
879 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 76 01 */
881 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 c8 (RGB+SRST) */
884 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 48 */
886 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 c8 */
889 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]); /* 12 48 */
891 /*jfm:win i2c_r from 00 to 80*/
893 while (ov7630_sensor_init
[i
][0]) {
894 i2c_w8(gspca_dev
, ov7630_sensor_init
[i
]);
899 static void ov7648_InitSensor(struct gspca_dev
*gspca_dev
)
903 while (ov7648_sensor_init
[i
][0]) {
904 i2c_w8(gspca_dev
, ov7648_sensor_init
[i
]);
909 static void ov7660_InitSensor(struct gspca_dev
*gspca_dev
)
913 i2c_w8(gspca_dev
, ov7660_sensor_init
[i
]); /* reset SCCB */
916 while (ov7660_sensor_init
[i
][0]) {
917 i2c_w8(gspca_dev
, ov7660_sensor_init
[i
]);
922 /* this function is called at probe time */
923 static int sd_config(struct gspca_dev
*gspca_dev
,
924 const struct usb_device_id
*id
)
926 struct sd
*sd
= (struct sd
*) gspca_dev
;
929 cam
= &gspca_dev
->cam
;
931 cam
->cam_mode
= vga_mode
;
932 cam
->nmodes
= ARRAY_SIZE(vga_mode
);
934 sd
->bridge
= id
->driver_info
>> 16;
935 sd
->sensor
= id
->driver_info
>> 8;
936 sd
->i2c_base
= id
->driver_info
;
938 sd
->qindex
= 4; /* set the quantization table */
939 sd
->brightness
= BRIGHTNESS_DEF
;
940 sd
->contrast
= CONTRAST_DEF
;
941 sd
->colors
= COLOR_DEF
;
942 sd
->autogain
= AUTOGAIN_DEF
;
945 switch (sd
->sensor
) {
949 gspca_dev
->ctrl_dis
= (1 << AUTOGAIN_IDX
);
956 /* this function is called at probe and resume time */
957 static int sd_init(struct gspca_dev
*gspca_dev
)
959 struct sd
*sd
= (struct sd
*) gspca_dev
;
960 /* const __u8 *sn9c1xx; */
961 __u8 regGpio
[] = { 0x29, 0x74 };
964 /* setup a selector by bridge */
965 reg_w1(gspca_dev
, 0xf1, 0x01);
966 reg_r(gspca_dev
, 0x00, 1);
967 reg_w1(gspca_dev
, 0xf1, gspca_dev
->usb_buf
[0]);
968 reg_r(gspca_dev
, 0x00, 1); /* get sonix chip id */
969 regF1
= gspca_dev
->usb_buf
[0];
970 PDEBUG(D_PROBE
, "Sonix chip id: %02x", regF1
);
971 switch (sd
->bridge
) {
972 case BRIDGE_SN9C102P
:
975 reg_w1(gspca_dev
, 0x02, regGpio
[1]);
980 reg_w(gspca_dev
, 0x01, regGpio
, 2);
986 reg_w(gspca_dev
, 0x01, regGpio
, 2);
989 /* case BRIDGE_SN9C110: */
990 /* case BRIDGE_SN9C325: */
993 reg_w1(gspca_dev
, 0x02, 0x62);
997 reg_w1(gspca_dev
, 0xf1, 0x01);
1002 static unsigned int setexposure(struct gspca_dev
*gspca_dev
,
1005 struct sd
*sd
= (struct sd
*) gspca_dev
;
1006 static const __u8 doit
[] = /* update sensor */
1007 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1008 static const __u8 sensorgo
[] = /* sensor on */
1009 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1010 static const __u8 gainMo
[] =
1011 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1013 switch (sd
->sensor
) {
1014 case SENSOR_HV7131R
: {
1016 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1018 Expodoit
[3] = expo
>> 16;
1019 Expodoit
[4] = expo
>> 8;
1021 i2c_w8(gspca_dev
, Expodoit
);
1024 case SENSOR_MI0360
: {
1025 __u8 expoMi
[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1026 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1030 else if (expo
< 0x0001)
1032 expoMi
[3] = expo
>> 8;
1034 i2c_w8(gspca_dev
, expoMi
);
1035 i2c_w8(gspca_dev
, doit
);
1036 i2c_w8(gspca_dev
, sensorgo
);
1039 case SENSOR_MO4000
: {
1041 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1043 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1047 else if (expo
< 0x0001)
1049 expoMof
[3] = (expo
& 0x03fc) >> 2;
1050 i2c_w8(gspca_dev
, expoMof
);
1051 expoMo10
[3] = ((expo
& 0x1c00) >> 10)
1052 | ((expo
& 0x0003) << 4);
1053 i2c_w8(gspca_dev
, expoMo10
);
1054 i2c_w8(gspca_dev
, gainMo
);
1055 PDEBUG(D_CONF
, "set exposure %d",
1056 ((expoMo10
[3] & 0x07) << 10)
1058 | ((expoMo10
[3] & 0x30) >> 4));
1061 case SENSOR_OM6802
: {
1063 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1069 gainOm
[3] = expo
>> 2;
1070 i2c_w8(gspca_dev
, gainOm
);
1071 reg_w1(gspca_dev
, 0x96, (expo
>> 5) & 0x1f);
1072 PDEBUG(D_CONF
, "set exposure %d", gainOm
[3]);
1079 /* this function is used for sensors o76xx only */
1080 static void setbrightcont(struct gspca_dev
*gspca_dev
)
1082 struct sd
*sd
= (struct sd
*) gspca_dev
;
1084 __u8 reg84_full
[0x15];
1086 memset(reg84_full
, 0, sizeof reg84_full
);
1087 val
= sd
->contrast
* 0x20 / CONTRAST_MAX
+ 0x10; /* 10..30 */
1088 reg84_full
[2] = val
;
1089 reg84_full
[0] = (val
+ 1) / 2;
1090 reg84_full
[4] = (val
+ 1) / 5;
1091 if (val
> BRIGHTNESS_DEF
)
1092 val
= (sd
->brightness
- BRIGHTNESS_DEF
) * 0x20
1096 reg84_full
[0x12] = val
; /* 00..1f */
1097 reg_w(gspca_dev
, 0x84, reg84_full
, sizeof reg84_full
);
1100 /* sensor != ov76xx */
1101 static void setbrightness(struct gspca_dev
*gspca_dev
)
1103 struct sd
*sd
= (struct sd
*) gspca_dev
;
1107 k2
= sd
->brightness
>> 10;
1108 switch (sd
->sensor
) {
1109 case SENSOR_HV7131R
:
1110 expo
= sd
->brightness
<< 4;
1111 if (expo
> 0x002dc6c0)
1113 else if (expo
< 0x02a0)
1115 sd
->exposure
= setexposure(gspca_dev
, expo
);
1119 expo
= sd
->brightness
>> 4;
1120 sd
->exposure
= setexposure(gspca_dev
, expo
);
1123 expo
= sd
->brightness
>> 6;
1124 sd
->exposure
= setexposure(gspca_dev
, expo
);
1125 k2
= sd
->brightness
>> 11;
1129 reg_w1(gspca_dev
, 0x96, k2
);
1132 /* sensor != ov76xx */
1133 static void setcontrast(struct gspca_dev
*gspca_dev
)
1135 struct sd
*sd
= (struct sd
*) gspca_dev
;
1137 __u8 contrast
[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1141 contrast
[0] = (k2
+ 1) >> 1;
1142 contrast
[4] = (k2
+ 1) / 5;
1143 reg_w(gspca_dev
, 0x84, contrast
, 6);
1146 static void setcolors(struct gspca_dev
*gspca_dev
)
1148 struct sd
*sd
= (struct sd
*) gspca_dev
;
1151 if (sd
->colors
>= 32) {
1152 red
= 32 + (sd
->colors
- 32) / 2;
1153 blue
= 64 - sd
->colors
;
1156 blue
= 32 + (32 - sd
->colors
) / 2;
1158 reg_w1(gspca_dev
, 0x05, red
);
1159 /* reg_w1(gspca_dev, 0x07, 32); */
1160 reg_w1(gspca_dev
, 0x06, blue
);
1163 static void setautogain(struct gspca_dev
*gspca_dev
)
1165 struct sd
*sd
= (struct sd
*) gspca_dev
;
1167 if (gspca_dev
->ctrl_dis
& (1 << AUTOGAIN_IDX
))
1170 sd
->ag_cnt
= AG_CNT_START
;
1175 /* -- start the camera -- */
1176 static void sd_start(struct gspca_dev
*gspca_dev
)
1178 struct sd
*sd
= (struct sd
*) gspca_dev
;
1180 __u8 reg1
, reg17
, reg18
;
1181 const __u8
*sn9c1xx
;
1183 static const __u8 C0
[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1184 static const __u8 CA
[] = { 0x28, 0xd8, 0x14, 0xec };
1185 static const __u8 CE
[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1186 static const __u8 CE_ov76xx
[] =
1187 { 0x32, 0xdd, 0x32, 0xdd };
1189 sn9c1xx
= sn_tb
[(int) sd
->sensor
];
1190 configure_gpio(gspca_dev
, sn9c1xx
);
1192 reg_w1(gspca_dev
, 0x15, sn9c1xx
[0x15]);
1193 reg_w1(gspca_dev
, 0x16, sn9c1xx
[0x16]);
1194 reg_w1(gspca_dev
, 0x12, sn9c1xx
[0x12]);
1195 reg_w1(gspca_dev
, 0x13, sn9c1xx
[0x13]);
1196 reg_w1(gspca_dev
, 0x18, sn9c1xx
[0x18]);
1197 reg_w1(gspca_dev
, 0xd2, 0x6a); /* DC29 */
1198 reg_w1(gspca_dev
, 0xd3, 0x50);
1199 reg_w1(gspca_dev
, 0xc6, 0x00);
1200 reg_w1(gspca_dev
, 0xc7, 0x00);
1201 reg_w1(gspca_dev
, 0xc8, 0x50);
1202 reg_w1(gspca_dev
, 0xc9, 0x3c);
1203 reg_w1(gspca_dev
, 0x18, sn9c1xx
[0x18]);
1204 switch (sd
->sensor
) {
1211 /*jfm: from win trace */
1219 reg_w1(gspca_dev
, 0x17, reg17
);
1220 reg_w1(gspca_dev
, 0x05, sn9c1xx
[5]);
1221 reg_w1(gspca_dev
, 0x07, sn9c1xx
[7]);
1222 reg_w1(gspca_dev
, 0x06, sn9c1xx
[6]);
1223 reg_w1(gspca_dev
, 0x14, sn9c1xx
[0x14]);
1224 reg_w(gspca_dev
, 0x20, gamma_def
, sizeof gamma_def
);
1225 for (i
= 0; i
< 8; i
++)
1226 reg_w(gspca_dev
, 0x84, reg84
, sizeof reg84
);
1227 switch (sd
->sensor
) {
1229 reg_w1(gspca_dev
, 0x9a, 0x05);
1232 reg_w1(gspca_dev
, 0x9a, 0x08);
1233 reg_w1(gspca_dev
, 0x99, 0x59);
1237 mode
= gspca_dev
->cam
.cam_mode
[(int) gspca_dev
->curr_mode
].priv
;
1239 reg1
= 0x46; /* 320 clk 48Mhz */
1241 reg1
= 0x06; /* 640 clk 24Mz */
1243 switch (sd
->sensor
) {
1244 case SENSOR_HV7131R
:
1245 hv7131R_InitSensor(gspca_dev
);
1248 mi0360_InitSensor(gspca_dev
);
1251 mo4000_InitSensor(gspca_dev
);
1253 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1254 reg1
= 0x06; /* clk 24Mz */
1256 reg17
= 0x22; /* 640 MCKSIZE */
1257 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1261 om6802_InitSensor(gspca_dev
);
1262 reg17
= 0x64; /* 640 MCKSIZE */
1265 ov7630_InitSensor(gspca_dev
);
1270 ov7648_InitSensor(gspca_dev
);
1279 /* case SENSOR_OV7660: */
1280 ov7660_InitSensor(gspca_dev
);
1282 /* reg17 = 0x21; * 320 */
1284 /* reg1 = 0x46; (done) */
1286 reg17
= 0xa2; /* 640 */
1291 reg_w(gspca_dev
, 0xc0, C0
, 6);
1292 reg_w(gspca_dev
, 0xca, CA
, 4);
1293 switch (sd
->sensor
) {
1297 reg_w(gspca_dev
, 0xce, CE_ov76xx
, 4);
1300 reg_w(gspca_dev
, 0xce, CE
, 4);
1301 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1305 /* here change size mode 0 -> VGA; 1 -> CIF */
1306 reg18
= sn9c1xx
[0x18] | (mode
<< 4);
1307 reg_w1(gspca_dev
, 0x18, reg18
| 0x40);
1309 reg_w(gspca_dev
, 0x100, qtable4
, 0x40);
1310 reg_w(gspca_dev
, 0x140, qtable4
+ 0x40, 0x40);
1312 reg_w1(gspca_dev
, 0x18, reg18
);
1314 reg_w1(gspca_dev
, 0x17, reg17
);
1315 switch (sd
->sensor
) {
1316 case SENSOR_HV7131R
:
1320 setbrightness(gspca_dev
);
1321 setcontrast(gspca_dev
);
1323 default: /* OV76xx */
1324 setbrightcont(gspca_dev
);
1327 setautogain(gspca_dev
);
1328 reg_w1(gspca_dev
, 0x01, reg1
);
1331 static void sd_stopN(struct gspca_dev
*gspca_dev
)
1333 struct sd
*sd
= (struct sd
*) gspca_dev
;
1334 static const __u8 stophv7131
[] =
1335 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1336 static const __u8 stopmi0360
[] =
1337 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1339 const __u8
*sn9c1xx
;
1342 switch (sd
->sensor
) {
1343 case SENSOR_HV7131R
:
1344 i2c_w8(gspca_dev
, stophv7131
);
1348 i2c_w8(gspca_dev
, stopmi0360
);
1356 /* case SENSOR_MO4000: */
1357 /* case SENSOR_OV7660: */
1360 sn9c1xx
= sn_tb
[(int) sd
->sensor
];
1361 reg_w1(gspca_dev
, 0x01, sn9c1xx
[1]);
1362 reg_w1(gspca_dev
, 0x17, sn9c1xx
[0x17]);
1363 reg_w1(gspca_dev
, 0x01, sn9c1xx
[1]);
1364 reg_w1(gspca_dev
, 0x01, data
);
1365 reg_w1(gspca_dev
, 0xf1, 0x00);
1368 static void do_autogain(struct gspca_dev
*gspca_dev
)
1370 struct sd
*sd
= (struct sd
*) gspca_dev
;
1373 __u8 luma_mean
= 130;
1374 __u8 luma_delta
= 20;
1376 /* Thanks S., without your advice, autobright should not work :) */
1379 if (--sd
->ag_cnt
>= 0)
1381 sd
->ag_cnt
= AG_CNT_START
;
1383 delta
= atomic_read(&sd
->avg_lum
);
1384 PDEBUG(D_FRAM
, "mean lum %d", delta
);
1385 if (delta
< luma_mean
- luma_delta
||
1386 delta
> luma_mean
+ luma_delta
) {
1387 switch (sd
->sensor
) {
1388 case SENSOR_HV7131R
:
1389 expotimes
= sd
->exposure
>> 8;
1390 expotimes
+= (luma_mean
- delta
) >> 4;
1393 sd
->exposure
= setexposure(gspca_dev
,
1394 (unsigned int) (expotimes
<< 8));
1397 /* case SENSOR_MO4000: */
1398 /* case SENSOR_MI0360: */
1399 /* case SENSOR_OM6802: */
1400 expotimes
= sd
->exposure
;
1401 expotimes
+= (luma_mean
- delta
) >> 6;
1404 sd
->exposure
= setexposure(gspca_dev
,
1405 (unsigned int) expotimes
);
1406 setcolors(gspca_dev
);
1412 /* scan the URB packets */
1413 /* This function is run at interrupt level. */
1414 static void sd_pkt_scan(struct gspca_dev
*gspca_dev
,
1415 struct gspca_frame
*frame
, /* target */
1416 __u8
*data
, /* isoc packet */
1417 int len
) /* iso packet length */
1419 struct sd
*sd
= (struct sd
*) gspca_dev
;
1423 if (sof
>= 0 && data
[sof
] == 0xff && data
[sof
+ 1] == 0xd9) {
1426 gspca_frame_add(gspca_dev
, LAST_PACKET
,
1427 frame
, data
, sof
+ 2);
1434 avg_lum
= ((data
[sof
+ 29] << 8) | data
[sof
+ 30]) >> 6;
1436 avg_lum
+= ((data
[sof
+ 33] << 8) | data
[sof
+ 34]) >> 6;
1438 avg_lum
+= ((data
[sof
+ 25] << 8) | data
[sof
+ 26]) >> 6;
1440 avg_lum
+= ((data
[sof
+ 37] << 8) | data
[sof
+ 38]) >> 6;
1442 avg_lum
+= ((data
[sof
+ 31] << 8) | data
[sof
+ 32]) >> 4;
1444 atomic_set(&sd
->avg_lum
, avg_lum
);
1447 if (gspca_dev
->last_packet_type
== LAST_PACKET
) {
1449 /* put the JPEG 422 header */
1450 jpeg_put_header(gspca_dev
, frame
, sd
->qindex
, 0x21);
1452 gspca_frame_add(gspca_dev
, INTER_PACKET
, frame
, data
, len
);
1455 static int sd_setbrightness(struct gspca_dev
*gspca_dev
, __s32 val
)
1457 struct sd
*sd
= (struct sd
*) gspca_dev
;
1459 sd
->brightness
= val
;
1460 if (gspca_dev
->streaming
) {
1461 switch (sd
->sensor
) {
1462 case SENSOR_HV7131R
:
1466 setbrightness(gspca_dev
);
1468 default: /* OV76xx */
1469 setbrightcont(gspca_dev
);
1476 static int sd_getbrightness(struct gspca_dev
*gspca_dev
, __s32
*val
)
1478 struct sd
*sd
= (struct sd
*) gspca_dev
;
1480 *val
= sd
->brightness
;
1484 static int sd_setcontrast(struct gspca_dev
*gspca_dev
, __s32 val
)
1486 struct sd
*sd
= (struct sd
*) gspca_dev
;
1489 if (gspca_dev
->streaming
) {
1490 switch (sd
->sensor
) {
1491 case SENSOR_HV7131R
:
1495 setcontrast(gspca_dev
);
1497 default: /* OV76xx */
1498 setbrightcont(gspca_dev
);
1505 static int sd_getcontrast(struct gspca_dev
*gspca_dev
, __s32
*val
)
1507 struct sd
*sd
= (struct sd
*) gspca_dev
;
1509 *val
= sd
->contrast
;
1513 static int sd_setcolors(struct gspca_dev
*gspca_dev
, __s32 val
)
1515 struct sd
*sd
= (struct sd
*) gspca_dev
;
1518 if (gspca_dev
->streaming
)
1519 setcolors(gspca_dev
);
1523 static int sd_getcolors(struct gspca_dev
*gspca_dev
, __s32
*val
)
1525 struct sd
*sd
= (struct sd
*) gspca_dev
;
1531 static int sd_setautogain(struct gspca_dev
*gspca_dev
, __s32 val
)
1533 struct sd
*sd
= (struct sd
*) gspca_dev
;
1536 if (gspca_dev
->streaming
)
1537 setautogain(gspca_dev
);
1541 static int sd_getautogain(struct gspca_dev
*gspca_dev
, __s32
*val
)
1543 struct sd
*sd
= (struct sd
*) gspca_dev
;
1545 *val
= sd
->autogain
;
1549 /* sub-driver description */
1550 static const struct sd_desc sd_desc
= {
1551 .name
= MODULE_NAME
,
1553 .nctrls
= ARRAY_SIZE(sd_ctrls
),
1554 .config
= sd_config
,
1558 .pkt_scan
= sd_pkt_scan
,
1559 .dq_callback
= do_autogain
,
1562 /* -- module initialisation -- */
1563 #define BSI(bridge, sensor, i2c_addr) \
1564 .driver_info = (BRIDGE_ ## bridge << 16) \
1565 | (SENSOR_ ## sensor << 8) \
1567 static const __devinitdata
struct usb_device_id device_table
[] = {
1568 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1569 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120
, MI0360
, 0x5d)},
1570 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105
, OV7660
, 0x21)},
1571 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105
, OV7660
, 0x21)},
1572 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105
, MI0360
, 0x5d)},
1573 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105
, MI0360
, 0x5d)},
1575 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105
, MI0360
, 0x5d)},
1576 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P
, HV7131R
, 0x11)},
1578 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1579 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1580 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1581 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P
, HV7131R
, 0x11)},
1582 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1583 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105
, MI0360
, 0x5d)},
1584 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1585 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1586 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105
, MO4000
, 0x21)},
1587 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1588 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1589 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105
, OV7660
, 0x21)},
1590 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105
, HV7131R
, 0x11)},
1591 /* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1592 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1593 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1594 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1595 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110
, OM6802
, 0x21)}, /*sn9c325?*/
1597 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110
, OV7648
, 0x21)}, /*sn9c325?*/
1598 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110
, MO4000
, 0x21)},
1599 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110
, OV7630
, 0x21)},
1600 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1601 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1602 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120
, MI0360
, 0x5d)},
1604 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120
, MO4000
, 0x21)},
1605 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1606 /* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1607 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120
, OV7660
, 0x21)},
1608 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120
, HV7131R
, 0x11)},
1609 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1611 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120
, MI0360
, 0x5d)},
1614 MODULE_DEVICE_TABLE(usb
, device_table
);
1616 /* -- device connect -- */
1617 static int sd_probe(struct usb_interface
*intf
,
1618 const struct usb_device_id
*id
)
1620 return gspca_dev_probe(intf
, id
, &sd_desc
, sizeof(struct sd
),
1624 static struct usb_driver sd_driver
= {
1625 .name
= MODULE_NAME
,
1626 .id_table
= device_table
,
1628 .disconnect
= gspca_disconnect
,
1630 .suspend
= gspca_suspend
,
1631 .resume
= gspca_resume
,
1635 /* -- module insert / remove -- */
1636 static int __init
sd_mod_init(void)
1638 if (usb_register(&sd_driver
) < 0)
1643 static void __exit
sd_mod_exit(void)
1645 usb_deregister(&sd_driver
);
1646 info("deregistered");
1649 module_init(sd_mod_init
);
1650 module_exit(sd_mod_exit
);