added 2.6.29.6 aldebaran kernel
[nao-ulib.git] / kernel / 2.6.29.6-aldebaran-rt / drivers / media / video / gspca / sonixj.c
blob3373b8d9d2a88fa92c8ec40feb5d4d207d9b17ab
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 #define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
31 MODULE_LICENSE("GPL");
33 /* specific webcam descriptor */
34 struct sd {
35 struct gspca_dev gspca_dev; /* !! must be the first item */
37 atomic_t avg_lum;
38 unsigned int exposure;
40 __u16 brightness;
41 __u8 contrast;
42 __u8 colors;
43 __u8 autogain;
44 __u8 blue;
45 __u8 red;
46 __u8 vflip; /* ov7630 only */
47 __u8 infrared; /* mi0360 only */
49 __s8 ag_cnt;
50 #define AG_CNT_START 13
52 __u8 qindex;
53 __u8 bridge;
54 #define BRIDGE_SN9C102P 0
55 #define BRIDGE_SN9C105 1
56 #define BRIDGE_SN9C110 2
57 #define BRIDGE_SN9C120 3
58 #define BRIDGE_SN9C325 4
59 __u8 sensor; /* Type of image sensor chip */
60 #define SENSOR_HV7131R 0
61 #define SENSOR_MI0360 1
62 #define SENSOR_MO4000 2
63 #define SENSOR_OM6802 3
64 #define SENSOR_OV7630 4
65 #define SENSOR_OV7648 5
66 #define SENSOR_OV7660 6
67 __u8 i2c_base;
70 /* V4L2 controls supported by the driver */
71 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
77 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
81 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
82 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
83 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
85 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
88 static struct ctrl sd_ctrls[] = {
91 .id = V4L2_CID_BRIGHTNESS,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Brightness",
94 .minimum = 0,
95 #define BRIGHTNESS_MAX 0xffff
96 .maximum = BRIGHTNESS_MAX,
97 .step = 1,
98 #define BRIGHTNESS_DEF 0x8000
99 .default_value = BRIGHTNESS_DEF,
101 .set = sd_setbrightness,
102 .get = sd_getbrightness,
106 .id = V4L2_CID_CONTRAST,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Contrast",
109 .minimum = 0,
110 #define CONTRAST_MAX 127
111 .maximum = CONTRAST_MAX,
112 .step = 1,
113 #define CONTRAST_DEF 63
114 .default_value = CONTRAST_DEF,
116 .set = sd_setcontrast,
117 .get = sd_getcontrast,
121 .id = V4L2_CID_SATURATION,
122 .type = V4L2_CTRL_TYPE_INTEGER,
123 .name = "Color",
124 .minimum = 0,
125 .maximum = 40,
126 .step = 1,
127 #define COLOR_DEF 32
128 .default_value = COLOR_DEF,
130 .set = sd_setcolors,
131 .get = sd_getcolors,
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
138 .minimum = 24,
139 .maximum = 40,
140 .step = 1,
141 #define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
152 .minimum = 24,
153 .maximum = 40,
154 .step = 1,
155 #define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
161 #define AUTOGAIN_IDX 5
164 .id = V4L2_CID_AUTOGAIN,
165 .type = V4L2_CTRL_TYPE_BOOLEAN,
166 .name = "Auto Gain",
167 .minimum = 0,
168 .maximum = 1,
169 .step = 1,
170 #define AUTOGAIN_DEF 1
171 .default_value = AUTOGAIN_DEF,
173 .set = sd_setautogain,
174 .get = sd_getautogain,
176 /* ov7630 only */
177 #define VFLIP_IDX 6
180 .id = V4L2_CID_VFLIP,
181 .type = V4L2_CTRL_TYPE_BOOLEAN,
182 .name = "Vflip",
183 .minimum = 0,
184 .maximum = 1,
185 .step = 1,
186 #define VFLIP_DEF 1
187 .default_value = VFLIP_DEF,
189 .set = sd_setvflip,
190 .get = sd_getvflip,
192 /* mi0360 only */
193 #define INFRARED_IDX 7
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Infrared",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202 #define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
210 /* table of the disabled controls */
211 static __u32 ctrl_dis[] = {
212 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
213 /* SENSOR_HV7131R 0 */
214 (1 << VFLIP_IDX),
215 /* SENSOR_MI0360 1 */
216 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
217 /* SENSOR_MO4000 2 */
218 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
219 /* SENSOR_OM6802 3 */
220 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
221 /* SENSOR_OV7630 4 */
222 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
223 /* SENSOR_OV7648 5 */
224 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
225 /* SENSOR_OV7660 6 */
228 static const struct v4l2_pix_format vga_mode[] = {
229 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
230 .bytesperline = 160,
231 .sizeimage = 160 * 120 * 4 / 8 + 590,
232 .colorspace = V4L2_COLORSPACE_JPEG,
233 .priv = 2},
234 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
235 .bytesperline = 320,
236 .sizeimage = 320 * 240 * 3 / 8 + 590,
237 .colorspace = V4L2_COLORSPACE_JPEG,
238 .priv = 1},
239 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
240 .bytesperline = 640,
241 .sizeimage = 640 * 480 * 3 / 8 + 590,
242 .colorspace = V4L2_COLORSPACE_JPEG,
243 .priv = 0},
246 /*Data from sn9c102p+hv71331r */
247 static const __u8 sn_hv7131[] = {
248 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
249 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
250 /* reg8 reg9 rega regb regc regd rege regf */
251 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
252 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
253 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
254 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
255 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
258 static const __u8 sn_mi0360[] = {
259 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
260 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
261 /* reg8 reg9 rega regb regc regd rege regf */
262 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
263 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
264 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
265 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
266 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
269 static const __u8 sn_mo4000[] = {
270 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
271 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
272 /* reg8 reg9 rega regb regc regd rege regf */
273 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
275 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
276 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
277 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
280 static const __u8 sn_om6802[] = {
281 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
282 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
283 /* reg8 reg9 rega regb regc regd rege regf */
284 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
286 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
287 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
288 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
290 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
291 0xf7
294 static const __u8 sn_ov7630[] = {
295 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
296 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
297 /* reg8 reg9 rega regb regc regd rege regf */
298 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
299 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
300 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
301 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
302 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
305 static const __u8 sn_ov7648[] = {
306 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
307 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
308 /* reg8 reg9 rega regb regc regd rege regf */
309 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
310 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
311 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
312 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
313 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
316 static const __u8 sn_ov7660[] = {
317 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
318 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
319 /* reg8 reg9 rega regb regc regd rege regf */
320 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
321 /* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
322 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
323 /* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
324 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
327 /* sequence specific to the sensors - !! index = SENSOR_xxx */
328 static const __u8 *sn_tb[] = {
329 sn_hv7131,
330 sn_mi0360,
331 sn_mo4000,
332 sn_om6802,
333 sn_ov7630,
334 sn_ov7648,
335 sn_ov7660
338 static const __u8 gamma_def[] = {
339 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
340 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
343 /* color matrix and offsets */
344 static const __u8 reg84[] = {
345 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
346 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
347 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
348 0x00, 0x00, 0x00 /* YUV offsets */
350 static const __u8 hv7131r_sensor_init[][8] = {
351 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
352 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
353 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
354 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
355 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
356 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
357 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
359 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
360 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
361 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
362 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
363 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
364 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
365 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
366 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
368 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
369 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
370 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
371 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
374 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
375 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
377 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
381 static const __u8 mi0360_sensor_init[][8] = {
382 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
383 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
384 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
385 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
386 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
387 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
388 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
389 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
390 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
391 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
392 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
395 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
396 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
397 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
398 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
399 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
401 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
402 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
403 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
404 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
405 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
406 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
407 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
408 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
409 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
410 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
411 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
412 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
413 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
414 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
416 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
417 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
418 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
419 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
420 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
422 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
423 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
424 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
425 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
427 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
428 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
429 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
430 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
431 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
432 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
435 static const __u8 mo4000_sensor_init[][8] = {
436 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
437 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
448 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
449 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
450 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
453 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
454 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
458 static __u8 om6802_sensor_init[][8] = {
459 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
460 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
461 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
462 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
463 /* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
464 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
465 /* white balance & auto-exposure */
466 /* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
467 * set color mode */
468 /* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
469 * max AGC value in AE */
470 /* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
471 * preset AGC */
472 /* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
473 * preset brightness */
474 /* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
475 * preset contrast */
476 /* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
477 * preset gamma */
478 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
479 /* luminance mode (0x4f = AE) */
480 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
481 /* preset shutter */
482 /* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
483 * auto frame rate */
484 /* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
486 /* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
487 /* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
488 /* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
489 /* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
492 static const __u8 ov7630_sensor_init[][8] = {
493 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
495 /* win: delay 20ms */
496 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
498 /* win: delay 20ms */
499 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
500 /* win: i2c_r from 00 to 80 */
501 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
502 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
504 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
505 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
506 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
507 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
508 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
509 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
510 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
511 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
512 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
513 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
514 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
515 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
516 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
518 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
519 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
520 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
521 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
522 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
523 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
524 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
525 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
526 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
527 /* */
528 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
529 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
530 /*fixme: + 0x12, 0x04*/
531 /* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
532 * set by setvflip */
533 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
534 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
536 /* */
537 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
538 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
539 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
540 /* */
541 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
542 /* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
546 static const __u8 ov7648_sensor_init[][8] = {
547 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
548 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
549 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
551 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
552 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
553 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
554 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
555 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
556 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
557 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
558 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
559 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
560 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
561 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
562 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
563 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
564 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
565 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
566 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
567 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
569 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
570 /* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
571 /* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
572 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
573 /*...*/
574 /* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
575 /* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
576 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
578 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
579 /* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
580 /* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
581 /*...*/
582 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
583 /* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584 /* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
585 /* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
586 /* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
587 /* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
592 static const __u8 ov7660_sensor_init[][8] = {
593 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
594 /* (delay 20ms) */
595 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
596 /* Outformat = rawRGB */
597 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
598 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
599 /* GAIN BLUE RED VREF */
600 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
601 /* COM 1 BAVE GEAVE AECHH */
602 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
603 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
604 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
605 /* AECH CLKRC COM7 COM8 */
606 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
607 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
608 /* HSTART HSTOP VSTRT VSTOP */
609 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
610 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
611 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
612 /* BOS GBOS GROS ROS (BGGR offset) */
613 /* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
614 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
615 /* AEW AEB VPT BBIAS */
616 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
617 /* GbBIAS RSVD EXHCH EXHCL */
618 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
619 /* RBIAS ADVFL ASDVFH YAVE */
620 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
621 /* HSYST HSYEN HREF */
622 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
623 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
624 /* ADC ACOM OFON TSLB */
625 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
626 /* COM11 COM12 COM13 COM14 */
627 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
628 /* EDGE COM15 COM16 COM17 */
629 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
630 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
631 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
632 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
633 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
634 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
635 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
636 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
637 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
638 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
639 /* LCC1 LCC2 LCC3 LCC4 */
640 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
641 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
642 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
643 /* band gap reference [0:3] DBLV */
644 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
645 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
646 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
647 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
648 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
649 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
650 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
651 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
652 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
653 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
654 /****** (some exchanges in the win trace) ******/
655 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
656 /* bits[3..0]reserved */
657 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
658 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
659 /* VREF vertical frame ctrl */
660 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
661 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
662 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
663 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
664 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
665 /* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
666 /****** (some exchanges in the win trace) ******/
667 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
668 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
669 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
670 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
671 /* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
672 /****** (some exchanges in the win trace) ******/
673 /******!! startsensor KO if changed !!****/
674 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
675 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
676 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
677 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
681 static const __u8 qtable4[] = {
682 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
683 0x06, 0x08, 0x0A, 0x11,
684 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
685 0x19, 0x19, 0x17, 0x15,
686 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
687 0x21, 0x2E, 0x21, 0x23,
688 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
689 0x25, 0x29, 0x2C, 0x29,
690 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
691 0x17, 0x1B, 0x29, 0x29,
692 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
693 0x29, 0x29, 0x29, 0x29,
694 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
695 0x29, 0x29, 0x29, 0x29,
696 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
697 0x29, 0x29, 0x29, 0x29
700 /* read <len> bytes to gspca_dev->usb_buf */
701 static void reg_r(struct gspca_dev *gspca_dev,
702 __u16 value, int len)
704 #ifdef GSPCA_DEBUG
705 if (len > USB_BUF_SZ) {
706 err("reg_r: buffer overflow");
707 return;
709 #endif
710 usb_control_msg(gspca_dev->dev,
711 usb_rcvctrlpipe(gspca_dev->dev, 0),
713 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
714 value, 0,
715 gspca_dev->usb_buf, len,
716 500);
717 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
720 static void reg_w1(struct gspca_dev *gspca_dev,
721 __u16 value,
722 __u8 data)
724 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
725 gspca_dev->usb_buf[0] = data;
726 usb_control_msg(gspca_dev->dev,
727 usb_sndctrlpipe(gspca_dev->dev, 0),
728 0x08,
729 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
730 value,
732 gspca_dev->usb_buf, 1,
733 500);
735 static void reg_w(struct gspca_dev *gspca_dev,
736 __u16 value,
737 const __u8 *buffer,
738 int len)
740 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
741 value, buffer[0], buffer[1]);
742 #ifdef GSPCA_DEBUG
743 if (len > USB_BUF_SZ) {
744 err("reg_w: buffer overflow");
745 return;
747 #endif
748 memcpy(gspca_dev->usb_buf, buffer, len);
749 usb_control_msg(gspca_dev->dev,
750 usb_sndctrlpipe(gspca_dev->dev, 0),
751 0x08,
752 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
753 value, 0,
754 gspca_dev->usb_buf, len,
755 500);
758 /* I2C write 1 byte */
759 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
761 struct sd *sd = (struct sd *) gspca_dev;
763 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
764 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
765 gspca_dev->usb_buf[1] = sd->i2c_base;
766 gspca_dev->usb_buf[2] = reg;
767 gspca_dev->usb_buf[3] = val;
768 gspca_dev->usb_buf[4] = 0;
769 gspca_dev->usb_buf[5] = 0;
770 gspca_dev->usb_buf[6] = 0;
771 gspca_dev->usb_buf[7] = 0x10;
772 usb_control_msg(gspca_dev->dev,
773 usb_sndctrlpipe(gspca_dev->dev, 0),
774 0x08,
775 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
776 0x08, /* value = i2c */
778 gspca_dev->usb_buf, 8,
779 500);
782 /* I2C write 8 bytes */
783 static void i2c_w8(struct gspca_dev *gspca_dev,
784 const __u8 *buffer)
786 memcpy(gspca_dev->usb_buf, buffer, 8);
787 usb_control_msg(gspca_dev->dev,
788 usb_sndctrlpipe(gspca_dev->dev, 0),
789 0x08,
790 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
791 0x08, 0, /* value, index */
792 gspca_dev->usb_buf, 8,
793 500);
794 msleep(2);
797 /* read 5 bytes in gspca_dev->usb_buf */
798 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
800 struct sd *sd = (struct sd *) gspca_dev;
801 __u8 mode[8];
803 mode[0] = 0x81 | 0x10;
804 mode[1] = sd->i2c_base;
805 mode[2] = reg;
806 mode[3] = 0;
807 mode[4] = 0;
808 mode[5] = 0;
809 mode[6] = 0;
810 mode[7] = 0x10;
811 i2c_w8(gspca_dev, mode);
812 msleep(2);
813 mode[0] = 0x81 | (5 << 4) | 0x02;
814 mode[2] = 0;
815 i2c_w8(gspca_dev, mode);
816 msleep(2);
817 reg_r(gspca_dev, 0x0a, 5);
820 static int probesensor(struct gspca_dev *gspca_dev)
822 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
823 msleep(10);
824 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
825 msleep(10);
826 i2c_r5(gspca_dev, 0); /* read sensor id */
827 if (gspca_dev->usb_buf[0] == 0x02
828 && gspca_dev->usb_buf[1] == 0x09
829 && gspca_dev->usb_buf[2] == 0x01
830 && gspca_dev->usb_buf[3] == 0x00
831 && gspca_dev->usb_buf[4] == 0x00) {
832 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
833 return 0;
835 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
836 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
837 gspca_dev->usb_buf[2]);
838 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
839 return -ENODEV;
842 static int configure_gpio(struct gspca_dev *gspca_dev,
843 const __u8 *sn9c1xx)
845 struct sd *sd = (struct sd *) gspca_dev;
846 const __u8 *reg9a;
847 static const __u8 reg9a_def[] =
848 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
849 static const __u8 reg9a_sn9c325[] =
850 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
851 static const __u8 regd4[] = {0x60, 0x00, 0x00};
853 reg_w1(gspca_dev, 0xf1, 0x00);
854 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
856 /* configure gpio */
857 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
858 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
859 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
860 switch (sd->bridge) {
861 case BRIDGE_SN9C325:
862 reg9a = reg9a_sn9c325;
863 break;
864 default:
865 reg9a = reg9a_def;
866 break;
868 reg_w(gspca_dev, 0x9a, reg9a, 6);
870 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
872 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
874 switch (sd->sensor) {
875 case SENSOR_OM6802:
876 reg_w1(gspca_dev, 0x02, 0x71);
877 reg_w1(gspca_dev, 0x01, 0x42);
878 reg_w1(gspca_dev, 0x17, 0x64);
879 reg_w1(gspca_dev, 0x01, 0x42);
880 break;
881 /*jfm: from win trace */
882 case SENSOR_OV7630:
883 reg_w1(gspca_dev, 0x01, 0x61);
884 reg_w1(gspca_dev, 0x17, 0xe2);
885 reg_w1(gspca_dev, 0x01, 0x60);
886 reg_w1(gspca_dev, 0x01, 0x40);
887 break;
888 case SENSOR_OV7648:
889 reg_w1(gspca_dev, 0x01, 0x63);
890 reg_w1(gspca_dev, 0x17, 0x20);
891 reg_w1(gspca_dev, 0x01, 0x42);
892 break;
893 /*jfm: from win trace */
894 case SENSOR_OV7660:
895 if (sd->bridge == BRIDGE_SN9C120) {
896 reg_w1(gspca_dev, 0x01, 0x61);
897 reg_w1(gspca_dev, 0x17, 0x20);
898 reg_w1(gspca_dev, 0x01, 0x60);
899 reg_w1(gspca_dev, 0x01, 0x40);
900 break;
902 /* fall thru */
903 default:
904 reg_w1(gspca_dev, 0x01, 0x43);
905 reg_w1(gspca_dev, 0x17, 0x61);
906 reg_w1(gspca_dev, 0x01, 0x42);
907 if (sd->sensor == SENSOR_HV7131R) {
908 if (probesensor(gspca_dev) < 0)
909 return -ENODEV;
911 break;
913 return 0;
916 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
918 int i = 0;
919 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
920 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
922 while (hv7131r_sensor_init[i][0]) {
923 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
924 i++;
926 i2c_w8(gspca_dev, SetSensorClk);
929 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
931 int i = 0;
933 while (mi0360_sensor_init[i][0]) {
934 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
935 i++;
939 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
941 int i = 0;
943 while (mo4000_sensor_init[i][0]) {
944 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
945 i++;
949 static void om6802_InitSensor(struct gspca_dev *gspca_dev)
951 int i = 0;
953 while (om6802_sensor_init[i][0]) {
954 i2c_w8(gspca_dev, om6802_sensor_init[i]);
955 i++;
959 static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
961 int i = 0;
963 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
964 i++;
965 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
966 i++;
967 msleep(20);
968 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
969 i++;
970 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
971 i++;
972 msleep(20);
973 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
974 i++;
975 /*jfm:win i2c_r from 00 to 80*/
977 while (ov7630_sensor_init[i][0]) {
978 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
979 i++;
983 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
985 int i = 0;
987 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
988 i++;
989 /* win: dble reset */
990 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
991 i++;
992 msleep(20);
993 /* win: i2c reg read 00..7f */
994 while (ov7648_sensor_init[i][0]) {
995 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
996 i++;
1000 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1002 int i = 0;
1004 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1005 i++;
1006 msleep(20);
1007 while (ov7660_sensor_init[i][0]) {
1008 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
1009 i++;
1013 /* this function is called at probe time */
1014 static int sd_config(struct gspca_dev *gspca_dev,
1015 const struct usb_device_id *id)
1017 struct sd *sd = (struct sd *) gspca_dev;
1018 struct cam *cam;
1020 cam = &gspca_dev->cam;
1021 cam->epaddr = 0x01;
1022 cam->cam_mode = vga_mode;
1023 cam->nmodes = ARRAY_SIZE(vga_mode);
1025 sd->bridge = id->driver_info >> 16;
1026 sd->sensor = id->driver_info >> 8;
1027 sd->i2c_base = id->driver_info;
1029 sd->qindex = 4; /* set the quantization table */
1030 sd->brightness = BRIGHTNESS_DEF;
1031 sd->contrast = CONTRAST_DEF;
1032 sd->colors = COLOR_DEF;
1033 sd->blue = BLUE_BALANCE_DEF;
1034 sd->red = RED_BALANCE_DEF;
1035 sd->autogain = AUTOGAIN_DEF;
1036 sd->ag_cnt = -1;
1037 sd->vflip = VFLIP_DEF;
1038 sd->infrared = INFRARED_DEF;
1040 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1041 return 0;
1044 /* this function is called at probe and resume time */
1045 static int sd_init(struct gspca_dev *gspca_dev)
1047 struct sd *sd = (struct sd *) gspca_dev;
1048 __u8 regGpio[] = { 0x29, 0x74 };
1049 __u8 regF1;
1051 /* setup a selector by bridge */
1052 reg_w1(gspca_dev, 0xf1, 0x01);
1053 reg_r(gspca_dev, 0x00, 1);
1054 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1055 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
1056 regF1 = gspca_dev->usb_buf[0];
1057 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
1058 switch (sd->bridge) {
1059 case BRIDGE_SN9C102P:
1060 if (regF1 != 0x11)
1061 return -ENODEV;
1062 reg_w1(gspca_dev, 0x02, regGpio[1]);
1063 break;
1064 case BRIDGE_SN9C105:
1065 if (regF1 != 0x11)
1066 return -ENODEV;
1067 reg_w(gspca_dev, 0x01, regGpio, 2);
1068 break;
1069 case BRIDGE_SN9C120:
1070 if (regF1 != 0x12)
1071 return -ENODEV;
1072 regGpio[1] = 0x70;
1073 reg_w(gspca_dev, 0x01, regGpio, 2);
1074 break;
1075 default:
1076 /* case BRIDGE_SN9C110: */
1077 /* case BRIDGE_SN9C325: */
1078 if (regF1 != 0x12)
1079 return -ENODEV;
1080 reg_w1(gspca_dev, 0x02, 0x62);
1081 break;
1084 reg_w1(gspca_dev, 0xf1, 0x01);
1086 return 0;
1089 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1090 unsigned int expo)
1092 struct sd *sd = (struct sd *) gspca_dev;
1093 static const __u8 doit[] = /* update sensor */
1094 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1095 static const __u8 sensorgo[] = /* sensor on */
1096 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1097 static const __u8 gainMo[] =
1098 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1100 switch (sd->sensor) {
1101 case SENSOR_HV7131R: {
1102 __u8 Expodoit[] =
1103 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1105 Expodoit[3] = expo >> 16;
1106 Expodoit[4] = expo >> 8;
1107 Expodoit[5] = expo;
1108 i2c_w8(gspca_dev, Expodoit);
1109 break;
1111 case SENSOR_MI0360: {
1112 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1113 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1115 if (expo > 0x0635)
1116 expo = 0x0635;
1117 else if (expo < 0x0001)
1118 expo = 0x0001;
1119 expoMi[3] = expo >> 8;
1120 expoMi[4] = expo;
1121 i2c_w8(gspca_dev, expoMi);
1122 i2c_w8(gspca_dev, doit);
1123 i2c_w8(gspca_dev, sensorgo);
1124 break;
1126 case SENSOR_MO4000: {
1127 __u8 expoMof[] =
1128 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1129 __u8 expoMo10[] =
1130 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1132 if (expo > 0x1fff)
1133 expo = 0x1fff;
1134 else if (expo < 0x0001)
1135 expo = 0x0001;
1136 expoMof[3] = (expo & 0x03fc) >> 2;
1137 i2c_w8(gspca_dev, expoMof);
1138 expoMo10[3] = ((expo & 0x1c00) >> 10)
1139 | ((expo & 0x0003) << 4);
1140 i2c_w8(gspca_dev, expoMo10);
1141 i2c_w8(gspca_dev, gainMo);
1142 PDEBUG(D_CONF, "set exposure %d",
1143 ((expoMo10[3] & 0x07) << 10)
1144 | (expoMof[3] << 2)
1145 | ((expoMo10[3] & 0x30) >> 4));
1146 break;
1148 case SENSOR_OM6802: {
1149 __u8 gainOm[] =
1150 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1152 if (expo > 0x03ff)
1153 expo = 0x03ff;
1154 if (expo < 0x0001)
1155 expo = 0x0001;
1156 gainOm[3] = expo >> 2;
1157 i2c_w8(gspca_dev, gainOm);
1158 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
1159 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1160 break;
1163 return expo;
1166 static void setbrightness(struct gspca_dev *gspca_dev)
1168 struct sd *sd = (struct sd *) gspca_dev;
1169 unsigned int expo;
1170 __u8 k2;
1172 k2 = ((int) sd->brightness - 0x8000) >> 10;
1173 switch (sd->sensor) {
1174 case SENSOR_HV7131R:
1175 expo = sd->brightness << 4;
1176 if (expo > 0x002dc6c0)
1177 expo = 0x002dc6c0;
1178 else if (expo < 0x02a0)
1179 expo = 0x02a0;
1180 sd->exposure = setexposure(gspca_dev, expo);
1181 break;
1182 case SENSOR_MI0360:
1183 case SENSOR_MO4000:
1184 expo = sd->brightness >> 4;
1185 sd->exposure = setexposure(gspca_dev, expo);
1186 break;
1187 case SENSOR_OM6802:
1188 expo = sd->brightness >> 6;
1189 sd->exposure = setexposure(gspca_dev, expo);
1190 k2 = sd->brightness >> 11;
1191 break;
1194 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
1197 static void setcontrast(struct gspca_dev *gspca_dev)
1199 struct sd *sd = (struct sd *) gspca_dev;
1200 __u8 k2;
1201 __u8 contrast[6];
1203 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1204 contrast[0] = (k2 + 1) / 2; /* red */
1205 contrast[1] = 0;
1206 contrast[2] = k2; /* green */
1207 contrast[3] = 0;
1208 contrast[4] = (k2 + 1) / 5; /* blue */
1209 contrast[5] = 0;
1210 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
1213 static void setcolors(struct gspca_dev *gspca_dev)
1215 struct sd *sd = (struct sd *) gspca_dev;
1216 int i, v;
1217 __u8 reg8a[12]; /* U & V gains */
1218 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1219 -24, -38, 64, /* UR UG UB */
1220 62, -51, -9 /* VR VG VB */
1222 for (i = 0; i < 6; i++) {
1223 v = uv[i] * sd->colors / COLOR_DEF;
1224 reg8a[i * 2] = v;
1225 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
1227 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
1230 static void setredblue(struct gspca_dev *gspca_dev)
1232 struct sd *sd = (struct sd *) gspca_dev;
1234 reg_w1(gspca_dev, 0x05, sd->red);
1235 /* reg_w1(gspca_dev, 0x07, 32); */
1236 reg_w1(gspca_dev, 0x06, sd->blue);
1239 static void setautogain(struct gspca_dev *gspca_dev)
1241 struct sd *sd = (struct sd *) gspca_dev;
1243 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1244 return;
1245 if (sd->autogain)
1246 sd->ag_cnt = AG_CNT_START;
1247 else
1248 sd->ag_cnt = -1;
1251 static void setvflip(struct sd *sd)
1253 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1254 sd->vflip ? 0x82 : 0x02);
1257 static void setinfrared(struct sd *sd)
1259 /*fixme: different sequence for StarCam Clip and StarCam 370i */
1260 /* Clip */
1261 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1262 sd->infrared ? 0x66 : 0x64);
1265 /* -- start the camera -- */
1266 static int sd_start(struct gspca_dev *gspca_dev)
1268 struct sd *sd = (struct sd *) gspca_dev;
1269 int i;
1270 __u8 reg1, reg17, reg18;
1271 const __u8 *sn9c1xx;
1272 int mode;
1273 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1274 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1275 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1276 static const __u8 CE_ov76xx[] =
1277 { 0x32, 0xdd, 0x32, 0xdd };
1279 sn9c1xx = sn_tb[(int) sd->sensor];
1280 configure_gpio(gspca_dev, sn9c1xx);
1282 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1283 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1284 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1285 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1286 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1287 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1288 reg_w1(gspca_dev, 0xd3, 0x50);
1289 reg_w1(gspca_dev, 0xc6, 0x00);
1290 reg_w1(gspca_dev, 0xc7, 0x00);
1291 reg_w1(gspca_dev, 0xc8, 0x50);
1292 reg_w1(gspca_dev, 0xc9, 0x3c);
1293 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1294 switch (sd->sensor) {
1295 case SENSOR_OV7630:
1296 reg17 = 0xe2;
1297 break;
1298 case SENSOR_OV7648:
1299 reg17 = 0x20;
1300 break;
1301 /*jfm: from win trace */
1302 case SENSOR_OV7660:
1303 if (sd->bridge == BRIDGE_SN9C120) {
1304 reg17 = 0xa0;
1305 break;
1307 /* fall thru */
1308 default:
1309 reg17 = 0x60;
1310 break;
1312 reg_w1(gspca_dev, 0x17, reg17);
1313 /* set reg1 was here */
1314 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1315 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1316 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
1317 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1318 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1319 for (i = 0; i < 8; i++)
1320 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1321 switch (sd->sensor) {
1322 case SENSOR_OV7648:
1323 reg_w1(gspca_dev, 0x9a, 0x0a);
1324 reg_w1(gspca_dev, 0x99, 0x60);
1325 break;
1326 case SENSOR_OV7660:
1327 if (sd->bridge == BRIDGE_SN9C120) {
1328 reg_w1(gspca_dev, 0x9a, 0x05);
1329 break;
1331 /* fall thru */
1332 default:
1333 reg_w1(gspca_dev, 0x9a, 0x08);
1334 reg_w1(gspca_dev, 0x99, 0x59);
1335 break;
1338 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1339 if (mode)
1340 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
1341 else
1342 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1343 reg17 = 0x61; /* 0x:20: enable sensor clock */
1344 switch (sd->sensor) {
1345 case SENSOR_HV7131R:
1346 hv7131R_InitSensor(gspca_dev);
1347 break;
1348 case SENSOR_MI0360:
1349 mi0360_InitSensor(gspca_dev);
1350 break;
1351 case SENSOR_MO4000:
1352 mo4000_InitSensor(gspca_dev);
1353 if (mode) {
1354 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1355 reg1 = 0x06; /* clk 24Mz */
1356 } else {
1357 reg17 = 0x22; /* 640 MCKSIZE */
1358 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1360 break;
1361 case SENSOR_OM6802:
1362 om6802_InitSensor(gspca_dev);
1363 reg17 = 0x64; /* 640 MCKSIZE */
1364 break;
1365 case SENSOR_OV7630:
1366 ov7630_InitSensor(gspca_dev);
1367 setvflip(sd);
1368 reg17 = 0xe2;
1369 reg1 = 0x44;
1370 break;
1371 case SENSOR_OV7648:
1372 ov7648_InitSensor(gspca_dev);
1373 reg17 = 0x21;
1374 /* reg1 = 0x42; * 42 - 46? */
1375 break;
1376 default:
1377 /* case SENSOR_OV7660: */
1378 ov7660_InitSensor(gspca_dev);
1379 if (sd->bridge == BRIDGE_SN9C120) {
1380 if (mode) { /* 320x240 - 160x120 */
1381 reg17 = 0xa2;
1382 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1384 } else {
1385 reg17 = 0x22;
1386 reg1 = 0x06; /* 24 Mhz, video trf eneble
1387 * inverse power down */
1389 break;
1391 reg_w(gspca_dev, 0xc0, C0, 6);
1392 reg_w(gspca_dev, 0xca, CA, 4);
1393 switch (sd->sensor) {
1394 case SENSOR_OV7630:
1395 case SENSOR_OV7648:
1396 case SENSOR_OV7660:
1397 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
1398 break;
1399 default:
1400 reg_w(gspca_dev, 0xce, CE, 4);
1401 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1402 break;
1405 /* here change size mode 0 -> VGA; 1 -> CIF */
1406 reg18 = sn9c1xx[0x18] | (mode << 4);
1407 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
1409 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1410 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1412 reg_w1(gspca_dev, 0x18, reg18);
1414 reg_w1(gspca_dev, 0x17, reg17);
1415 reg_w1(gspca_dev, 0x01, reg1);
1416 switch (sd->sensor) {
1417 case SENSOR_MI0360:
1418 setinfrared(sd);
1419 break;
1420 case SENSOR_OV7630:
1421 setvflip(sd);
1422 break;
1424 setbrightness(gspca_dev);
1425 setcontrast(gspca_dev);
1426 setautogain(gspca_dev);
1427 return 0;
1430 static void sd_stopN(struct gspca_dev *gspca_dev)
1432 struct sd *sd = (struct sd *) gspca_dev;
1433 static const __u8 stophv7131[] =
1434 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1435 static const __u8 stopmi0360[] =
1436 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1437 static const __u8 stopov7648[] =
1438 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
1439 __u8 data;
1440 const __u8 *sn9c1xx;
1442 data = 0x0b;
1443 switch (sd->sensor) {
1444 case SENSOR_HV7131R:
1445 i2c_w8(gspca_dev, stophv7131);
1446 data = 0x2b;
1447 break;
1448 case SENSOR_MI0360:
1449 i2c_w8(gspca_dev, stopmi0360);
1450 data = 0x29;
1451 break;
1452 case SENSOR_OV7648:
1453 i2c_w8(gspca_dev, stopov7648);
1454 /* fall thru */
1455 case SENSOR_OV7630:
1456 data = 0x29;
1457 break;
1458 default:
1459 /* case SENSOR_MO4000: */
1460 /* case SENSOR_OV7660: */
1461 break;
1463 sn9c1xx = sn_tb[(int) sd->sensor];
1464 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1465 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1466 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1467 reg_w1(gspca_dev, 0x01, data);
1468 reg_w1(gspca_dev, 0xf1, 0x00);
1471 static void do_autogain(struct gspca_dev *gspca_dev)
1473 struct sd *sd = (struct sd *) gspca_dev;
1474 int delta;
1475 int expotimes;
1476 __u8 luma_mean = 130;
1477 __u8 luma_delta = 20;
1479 /* Thanks S., without your advice, autobright should not work :) */
1480 if (sd->ag_cnt < 0)
1481 return;
1482 if (--sd->ag_cnt >= 0)
1483 return;
1484 sd->ag_cnt = AG_CNT_START;
1486 delta = atomic_read(&sd->avg_lum);
1487 PDEBUG(D_FRAM, "mean lum %d", delta);
1488 if (delta < luma_mean - luma_delta ||
1489 delta > luma_mean + luma_delta) {
1490 switch (sd->sensor) {
1491 case SENSOR_HV7131R:
1492 expotimes = sd->exposure >> 8;
1493 expotimes += (luma_mean - delta) >> 4;
1494 if (expotimes < 0)
1495 expotimes = 0;
1496 sd->exposure = setexposure(gspca_dev,
1497 (unsigned int) (expotimes << 8));
1498 break;
1499 default:
1500 /* case SENSOR_MO4000: */
1501 /* case SENSOR_MI0360: */
1502 /* case SENSOR_OM6802: */
1503 expotimes = sd->exposure;
1504 expotimes += (luma_mean - delta) >> 6;
1505 if (expotimes < 0)
1506 expotimes = 0;
1507 sd->exposure = setexposure(gspca_dev,
1508 (unsigned int) expotimes);
1509 setredblue(gspca_dev);
1510 break;
1515 /* scan the URB packets */
1516 /* This function is run at interrupt level. */
1517 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1518 struct gspca_frame *frame, /* target */
1519 __u8 *data, /* isoc packet */
1520 int len) /* iso packet length */
1522 struct sd *sd = (struct sd *) gspca_dev;
1523 int sof, avg_lum;
1525 sof = len - 64;
1526 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1528 /* end of frame */
1529 gspca_frame_add(gspca_dev, LAST_PACKET,
1530 frame, data, sof + 2);
1531 if (sd->ag_cnt < 0)
1532 return;
1533 /* w1 w2 w3 */
1534 /* w4 w5 w6 */
1535 /* w7 w8 */
1536 /* w4 */
1537 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1538 /* w6 */
1539 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1540 /* w2 */
1541 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1542 /* w8 */
1543 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1544 /* w5 */
1545 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1546 avg_lum >>= 4;
1547 atomic_set(&sd->avg_lum, avg_lum);
1548 return;
1550 if (gspca_dev->last_packet_type == LAST_PACKET) {
1552 /* put the JPEG 422 header */
1553 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1555 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1558 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1560 struct sd *sd = (struct sd *) gspca_dev;
1562 sd->brightness = val;
1563 if (gspca_dev->streaming)
1564 setbrightness(gspca_dev);
1565 return 0;
1568 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1570 struct sd *sd = (struct sd *) gspca_dev;
1572 *val = sd->brightness;
1573 return 0;
1576 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1578 struct sd *sd = (struct sd *) gspca_dev;
1580 sd->contrast = val;
1581 if (gspca_dev->streaming)
1582 setcontrast(gspca_dev);
1583 return 0;
1586 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1588 struct sd *sd = (struct sd *) gspca_dev;
1590 *val = sd->contrast;
1591 return 0;
1594 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1596 struct sd *sd = (struct sd *) gspca_dev;
1598 sd->colors = val;
1599 if (gspca_dev->streaming)
1600 setcolors(gspca_dev);
1601 return 0;
1604 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1606 struct sd *sd = (struct sd *) gspca_dev;
1608 *val = sd->colors;
1609 return 0;
1612 static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1614 struct sd *sd = (struct sd *) gspca_dev;
1616 sd->blue = val;
1617 if (gspca_dev->streaming)
1618 setredblue(gspca_dev);
1619 return 0;
1622 static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1624 struct sd *sd = (struct sd *) gspca_dev;
1626 *val = sd->blue;
1627 return 0;
1630 static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1632 struct sd *sd = (struct sd *) gspca_dev;
1634 sd->red = val;
1635 if (gspca_dev->streaming)
1636 setredblue(gspca_dev);
1637 return 0;
1640 static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1642 struct sd *sd = (struct sd *) gspca_dev;
1644 *val = sd->red;
1645 return 0;
1648 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1650 struct sd *sd = (struct sd *) gspca_dev;
1652 sd->autogain = val;
1653 if (gspca_dev->streaming)
1654 setautogain(gspca_dev);
1655 return 0;
1658 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1660 struct sd *sd = (struct sd *) gspca_dev;
1662 *val = sd->autogain;
1663 return 0;
1666 static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1668 struct sd *sd = (struct sd *) gspca_dev;
1670 sd->vflip = val;
1671 if (gspca_dev->streaming)
1672 setvflip(sd);
1673 return 0;
1676 static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1678 struct sd *sd = (struct sd *) gspca_dev;
1680 *val = sd->vflip;
1681 return 0;
1684 static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1686 struct sd *sd = (struct sd *) gspca_dev;
1688 sd->infrared = val;
1689 if (gspca_dev->streaming)
1690 setinfrared(sd);
1691 return 0;
1694 static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1696 struct sd *sd = (struct sd *) gspca_dev;
1698 *val = sd->infrared;
1699 return 0;
1702 /* sub-driver description */
1703 static const struct sd_desc sd_desc = {
1704 .name = MODULE_NAME,
1705 .ctrls = sd_ctrls,
1706 .nctrls = ARRAY_SIZE(sd_ctrls),
1707 .config = sd_config,
1708 .init = sd_init,
1709 .start = sd_start,
1710 .stopN = sd_stopN,
1711 .pkt_scan = sd_pkt_scan,
1712 .dq_callback = do_autogain,
1715 /* -- module initialisation -- */
1716 #define BSI(bridge, sensor, i2c_addr) \
1717 .driver_info = (BRIDGE_ ## bridge << 16) \
1718 | (SENSOR_ ## sensor << 8) \
1719 | (i2c_addr)
1720 static const __devinitdata struct usb_device_id device_table[] = {
1721 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1722 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
1723 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
1724 #endif
1725 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1726 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1727 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1728 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1729 #endif
1730 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
1731 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1732 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
1733 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1734 /* bw600.inf:
1735 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1736 /* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1737 /* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1738 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1739 /* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1740 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1741 /* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1742 /* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1743 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1744 /* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1745 /* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1746 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1747 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1748 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1749 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1750 #endif
1751 /* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1752 /* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1753 /* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
1754 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1755 /*bw600.inf:*/
1756 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
1757 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
1758 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
1759 /* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
1760 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1761 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
1762 #endif
1763 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
1764 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
1765 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1766 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1767 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1768 /* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
1769 #endif
1770 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
1773 MODULE_DEVICE_TABLE(usb, device_table);
1775 /* -- device connect -- */
1776 static int sd_probe(struct usb_interface *intf,
1777 const struct usb_device_id *id)
1779 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1780 THIS_MODULE);
1783 static struct usb_driver sd_driver = {
1784 .name = MODULE_NAME,
1785 .id_table = device_table,
1786 .probe = sd_probe,
1787 .disconnect = gspca_disconnect,
1788 #ifdef CONFIG_PM
1789 .suspend = gspca_suspend,
1790 .resume = gspca_resume,
1791 #endif
1794 /* -- module insert / remove -- */
1795 static int __init sd_mod_init(void)
1797 if (usb_register(&sd_driver) < 0)
1798 return -1;
1799 info("registered");
1800 return 0;
1802 static void __exit sd_mod_exit(void)
1804 usb_deregister(&sd_driver);
1805 info("deregistered");
1808 module_init(sd_mod_init);
1809 module_exit(sd_mod_exit);