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