blob: 97056703e17788306836c6c2aeb63ab8161329b4 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
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.
11 *
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.
16 *
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
20 */
21
22#define MODULE_NAME "sonixj"
23
24#include "gspca.h"
25#include "jpeg.h"
26
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030027#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030029MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
31MODULE_LICENSE("GPL");
32
33/* specific webcam descriptor */
34struct sd {
35 struct gspca_dev gspca_dev; /* !! must be the first item */
36
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030037 atomic_t avg_lum;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030038 unsigned int exposure;
39
40 unsigned short brightness;
41 unsigned char contrast;
42 unsigned char colors;
43 unsigned char autogain;
Jean-Francois Moine403123d2008-11-26 04:46:15 -030044 __u8 blue;
45 __u8 red;
Jean-Francois Moine6c862742008-09-08 04:57:26 -030046 __u8 vflip; /* ov7630 only */
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030047 __u8 infrared; /* mi0360 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030048
49 signed char ag_cnt;
50#define AG_CNT_START 13
51
52 char qindex;
Hans de Goede3647fea2008-07-15 05:36:30 -030053 unsigned char 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
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030059 char sensor; /* Type of image sensor chip */
60#define SENSOR_HV7131R 0
61#define SENSOR_MI0360 1
62#define SENSOR_MO4000 2
Jean-Francois Moined2d16e92008-09-03 16:47:23 -030063#define SENSOR_OM6802 3
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -030064#define SENSOR_OV7630 4
65#define SENSOR_OV7648 5
66#define SENSOR_OV7660 6
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030067 unsigned char i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030068};
69
70/* V4L2 controls supported by the driver */
71static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030077static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030081static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030083static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030085static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030087
88static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030089 {
90 {
91 .id = V4L2_CID_BRIGHTNESS,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Brightness",
94 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -030095#define BRIGHTNESS_MAX 0xffff
96 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030097 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -030098#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -030099 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300100 },
101 .set = sd_setbrightness,
102 .get = sd_getbrightness,
103 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300104 {
105 {
106 .id = V4L2_CID_CONTRAST,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Contrast",
109 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300110#define CONTRAST_MAX 127
111 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300112 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300113#define CONTRAST_DEF 63
114 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300115 },
116 .set = sd_setcontrast,
117 .get = sd_getcontrast,
118 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300119 {
120 {
121 .id = V4L2_CID_SATURATION,
122 .type = V4L2_CTRL_TYPE_INTEGER,
123 .name = "Color",
124 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300125 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300126 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300127#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300128 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300129 },
130 .set = sd_setcolors,
131 .get = sd_getcolors,
132 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300133 {
134 {
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,
143 },
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
146 },
147 {
148 {
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,
157 },
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
160 },
161#define AUTOGAIN_IDX 5
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300162 {
163 {
164 .id = V4L2_CID_AUTOGAIN,
165 .type = V4L2_CTRL_TYPE_BOOLEAN,
166 .name = "Auto Gain",
167 .minimum = 0,
168 .maximum = 1,
169 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300170#define AUTOGAIN_DEF 1
171 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300172 },
173 .set = sd_setautogain,
174 .get = sd_getautogain,
175 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300176/* ov7630 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300177#define VFLIP_IDX 6
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300178 {
179 {
180 .id = V4L2_CID_VFLIP,
181 .type = V4L2_CTRL_TYPE_BOOLEAN,
182 .name = "Vflip",
183 .minimum = 0,
184 .maximum = 1,
185 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300186#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300187 .default_value = VFLIP_DEF,
188 },
189 .set = sd_setvflip,
190 .get = sd_getvflip,
191 },
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300192/* mi0360 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300193#define INFRARED_IDX 7
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300194 {
195 {
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,
204 },
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
207 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300208};
209
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300210static struct v4l2_pix_format vga_mode[] = {
211 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
212 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300213 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300214 .colorspace = V4L2_COLORSPACE_JPEG,
215 .priv = 2},
216 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
217 .bytesperline = 320,
218 .sizeimage = 320 * 240 * 3 / 8 + 590,
219 .colorspace = V4L2_COLORSPACE_JPEG,
220 .priv = 1},
221 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
222 .bytesperline = 640,
223 .sizeimage = 640 * 480 * 3 / 8 + 590,
224 .colorspace = V4L2_COLORSPACE_JPEG,
225 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300226};
227
228/*Data from sn9c102p+hv71331r */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300229static const __u8 sn_hv7131[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300230/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
231 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
232/* reg8 reg9 rega regb regc regd rege regf */
233 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
234/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
235 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
236/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
237 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300238};
239
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300240static const __u8 sn_mi0360[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300241/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
242 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
243/* reg8 reg9 rega regb regc regd rege regf */
244 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
245/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
246 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
247/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
248 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300249};
250
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300251static const __u8 sn_mo4000[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300252/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
253 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
254/* reg8 reg9 rega regb regc regd rege regf */
255 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
256/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
257 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
258/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
259 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300260};
261
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300262static const __u8 sn_om6802[] = {
263/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
264 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
265/* reg8 reg9 rega regb regc regd rege regf */
266 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
267/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
268 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
269/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
270 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
272 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
273 0xf7
274};
275
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300276static const __u8 sn_ov7630[] = {
277/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
278 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
279/* reg8 reg9 rega regb regc regd rege regf */
280 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
281/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
282 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
283/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
284 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
285};
286
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300287static const __u8 sn_ov7648[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300288/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300289 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300290/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300291 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300292/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300293 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300294/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300295 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300296};
297
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300298static const __u8 sn_ov7660[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300299/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
300 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
301/* reg8 reg9 rega regb regc regd rege regf */
302 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
303/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
304 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
305/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
306 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300307};
308
309/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300310static const __u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300311 sn_hv7131,
312 sn_mi0360,
313 sn_mo4000,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300314 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300315 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300316 sn_ov7648,
317 sn_ov7660
318};
319
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300320static const __u8 gamma_def[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300321 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
322 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
323};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300324
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300325/* color matrix and offsets */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300326static const __u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300327 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
328 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
329 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
330 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300331};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300332static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300333 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
334 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
335 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
336 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
337 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
338 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
339 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
340
341 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
342 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
343 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
344 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
345 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
346 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
347 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
348 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
349
350 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
351 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
352 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
353 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
354 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
355
356 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
357 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
358 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
359 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
360 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300361 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300362};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300363static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300364 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
365 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
366 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
367 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
368 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
369 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
370 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
371 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
373 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
374 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
375 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
377 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
379 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
380 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
381 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
382 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
383 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
384 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
385 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
386 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
387 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
388 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
389 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
390 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
391 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
392 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
393 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
395 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
396 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
397
398 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
399 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
400 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
401 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
402 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
403
404 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
405 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
406 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
407 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
408
409 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
410 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
411/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
412/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
413 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
414 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300415 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300416};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300417static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300418 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
422 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
428 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
429 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
434 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
436 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
437 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300438 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300439};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300440static __u8 om6802_sensor_init[][8] = {
441 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
442 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
443 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
444 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
445/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
446 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
447 /* white balance & auto-exposure */
448/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
449 * set color mode */
450/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
451 * max AGC value in AE */
452/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
453 * preset AGC */
454/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
455 * preset brightness */
456/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
457 * preset contrast */
458/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
459 * preset gamma */
460 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
461 /* luminance mode (0x4f = AE) */
462 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
463 /* preset shutter */
464/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
465 * auto frame rate */
466/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
467
468/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
469/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
470/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
471/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
472 {}
473};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300474static const __u8 ov7630_sensor_init[][8] = {
475 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
476 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
477/* win: delay 20ms */
478 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
479 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
480/* win: delay 20ms */
481 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300482/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300483 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
484 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
485 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
486 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
487 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
488 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
489 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
490 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
491 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
492 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
493 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
494 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
497 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
498 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
499 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
500 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
501 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
502 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
504 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
505 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
506 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
507 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
508 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
509/* */
510 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
511 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
512/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300513/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
514 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300515 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
516 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300518/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300519 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
520 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
521 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300522/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300523 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300524/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300525 {}
526};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300527
528static const __u8 ov7648_sensor_init[][8] = {
529 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
530 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
531 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
532 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
533 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
534 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
535 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
536 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
537 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
538 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
539 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
540 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
541 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
542 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
543 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
544 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
545 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
546 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
547 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
548 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
549 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
550
551 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
552/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
553/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
554 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
555/*...*/
556/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
557/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
558 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
559 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
560/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
561/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
562/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
563/*...*/
564 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
565/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
566/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
567/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
568/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
569/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
570
571 {}
572};
573
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300574static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300575 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300576/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300577 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300578 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300579 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300580 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300581 /* GAIN BLUE RED VREF */
582 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
583 /* COM 1 BAVE GEAVE AECHH */
584 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
585 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300586 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300587 /* AECH CLKRC COM7 COM8 */
588 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
589 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
590 /* HSTART HSTOP VSTRT VSTOP */
591 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
592 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
593 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
594 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300595/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
596 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300597 /* AEW AEB VPT BBIAS */
598 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
599 /* GbBIAS RSVD EXHCH EXHCL */
600 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
601 /* RBIAS ADVFL ASDVFH YAVE */
602 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
603 /* HSYST HSYEN HREF */
604 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
605 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
606 /* ADC ACOM OFON TSLB */
607 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
608 /* COM11 COM12 COM13 COM14 */
609 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
610 /* EDGE COM15 COM16 COM17 */
611 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
612 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
613 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
614 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
615 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
616 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
617 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
618 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
619 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
620 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
621 /* LCC1 LCC2 LCC3 LCC4 */
622 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300623 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300624 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300625 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300626 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
627 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
628 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
629 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
630 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
631 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
632 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
633 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
634 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300635 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300636/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300637 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300638 /* bits[3..0]reserved */
639 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
640 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
641 /* VREF vertical frame ctrl */
642 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300643 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
644 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
645 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
646 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
647/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300648/****** (some exchanges in the win trace) ******/
649 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300650 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
651 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
652 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
653/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300655/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300656 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
657 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
658 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
659 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300660 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300661};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300662
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300663static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300664 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
665 0x06, 0x08, 0x0A, 0x11,
666 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
667 0x19, 0x19, 0x17, 0x15,
668 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
669 0x21, 0x2E, 0x21, 0x23,
670 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
671 0x25, 0x29, 0x2C, 0x29,
672 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
673 0x17, 0x1B, 0x29, 0x29,
674 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
675 0x29, 0x29, 0x29, 0x29,
676 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
677 0x29, 0x29, 0x29, 0x29,
678 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
679 0x29, 0x29, 0x29, 0x29
680};
681
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300682/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300683static void reg_r(struct gspca_dev *gspca_dev,
684 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300685{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300686#ifdef GSPCA_DEBUG
687 if (len > USB_BUF_SZ) {
688 err("reg_r: buffer overflow");
689 return;
690 }
691#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300692 usb_control_msg(gspca_dev->dev,
693 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300694 0,
695 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
696 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300697 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300698 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300699 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300700}
701
Jean-Francois Moine60017612008-07-18 08:46:19 -0300702static void reg_w1(struct gspca_dev *gspca_dev,
703 __u16 value,
704 __u8 data)
705{
706 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
707 gspca_dev->usb_buf[0] = data;
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 value,
713 0,
714 gspca_dev->usb_buf, 1,
715 500);
716}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300717static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300718 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300719 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300720 int len)
721{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300722 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
723 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300724#ifdef GSPCA_DEBUG
725 if (len > USB_BUF_SZ) {
726 err("reg_w: buffer overflow");
727 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300728 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300729#endif
730 memcpy(gspca_dev->usb_buf, buffer, len);
731 usb_control_msg(gspca_dev->dev,
732 usb_sndctrlpipe(gspca_dev->dev, 0),
733 0x08,
734 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
735 value, 0,
736 gspca_dev->usb_buf, len,
737 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300738}
739
Jean-Francois Moine60017612008-07-18 08:46:19 -0300740/* I2C write 1 byte */
741static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742{
743 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300744
Jean-Francois Moine60017612008-07-18 08:46:19 -0300745 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
746 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
747 gspca_dev->usb_buf[1] = sd->i2c_base;
748 gspca_dev->usb_buf[2] = reg;
749 gspca_dev->usb_buf[3] = val;
750 gspca_dev->usb_buf[4] = 0;
751 gspca_dev->usb_buf[5] = 0;
752 gspca_dev->usb_buf[6] = 0;
753 gspca_dev->usb_buf[7] = 0x10;
754 usb_control_msg(gspca_dev->dev,
755 usb_sndctrlpipe(gspca_dev->dev, 0),
756 0x08,
757 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
758 0x08, /* value = i2c */
759 0,
760 gspca_dev->usb_buf, 8,
761 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300762}
763
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300764/* I2C write 8 bytes */
765static void i2c_w8(struct gspca_dev *gspca_dev,
766 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300767{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300768 memcpy(gspca_dev->usb_buf, buffer, 8);
769 usb_control_msg(gspca_dev->dev,
770 usb_sndctrlpipe(gspca_dev->dev, 0),
771 0x08,
772 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
773 0x08, 0, /* value, index */
774 gspca_dev->usb_buf, 8,
775 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300776 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777}
778
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300779/* read 5 bytes in gspca_dev->usb_buf */
780static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300781{
782 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300783 __u8 mode[8];
784
Hans de Goede3647fea2008-07-15 05:36:30 -0300785 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300786 mode[1] = sd->i2c_base;
787 mode[2] = reg;
788 mode[3] = 0;
789 mode[4] = 0;
790 mode[5] = 0;
791 mode[6] = 0;
792 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300793 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300794 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300795 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300796 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300797 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300798 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300799 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300800}
801
802static int probesensor(struct gspca_dev *gspca_dev)
803{
804 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805
Jean-Francois Moine60017612008-07-18 08:46:19 -0300806 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300807 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300808 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300809 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300810 i2c_r5(gspca_dev, 0); /* read sensor id */
811 if (gspca_dev->usb_buf[0] == 0x02
812 && gspca_dev->usb_buf[1] == 0x09
813 && gspca_dev->usb_buf[2] == 0x01
814 && gspca_dev->usb_buf[3] == 0x00
815 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300816 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
817 sd->sensor = SENSOR_HV7131R;
818 return SENSOR_HV7131R;
819 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300820 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300821 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
822 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300823 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
824 return -ENODEV;
825}
826
827static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300828 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300829{
830 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300831 const __u8 *reg9a;
832 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300833 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300834 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300835 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300836 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300837
Jean-Francois Moine60017612008-07-18 08:46:19 -0300838 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300839 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300840
841 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300842 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
843 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300844 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300845 switch (sd->bridge) {
846 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300847 reg9a = reg9a_sn9c325;
848 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300849 default:
850 reg9a = reg9a_def;
851 break;
852 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300853 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300854
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300855 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300856
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300857 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300858
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300859 switch (sd->sensor) {
860 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300861 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300862 reg_w1(gspca_dev, 0x01, 0x42);
863 reg_w1(gspca_dev, 0x17, 0x64);
864 reg_w1(gspca_dev, 0x01, 0x42);
865 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300866/*jfm: from win trace */
867 case SENSOR_OV7630:
868 reg_w1(gspca_dev, 0x01, 0x61);
869 reg_w1(gspca_dev, 0x17, 0xe2);
870 reg_w1(gspca_dev, 0x01, 0x60);
871 reg_w1(gspca_dev, 0x01, 0x40);
872 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300873 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -0300874 reg_w1(gspca_dev, 0x01, 0x63);
875 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300876 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300877 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300878/*jfm: from win trace */
879 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -0300880 if (sd->bridge == BRIDGE_SN9C120) {
881 reg_w1(gspca_dev, 0x01, 0x61);
882 reg_w1(gspca_dev, 0x17, 0x20);
883 reg_w1(gspca_dev, 0x01, 0x60);
884 reg_w1(gspca_dev, 0x01, 0x40);
885 break;
886 }
887 /* fall thru */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300889 reg_w1(gspca_dev, 0x01, 0x43);
890 reg_w1(gspca_dev, 0x17, 0x61);
891 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300892 if (sd->sensor == SENSOR_HV7131R) {
893 if (probesensor(gspca_dev) < 0)
894 return -ENODEV;
895 }
896 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300897 }
898 return 0;
899}
900
901static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
902{
903 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300904 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300905 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
906
907 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300908 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300909 i++;
910 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300911 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300912}
913
914static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
915{
916 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300917
918 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300919 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300920 i++;
921 }
922}
923
924static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
925{
926 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300927
928 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300929 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930 i++;
931 }
932}
933
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300934static void om6802_InitSensor(struct gspca_dev *gspca_dev)
935{
936 int i = 0;
937
938 while (om6802_sensor_init[i][0]) {
939 i2c_w8(gspca_dev, om6802_sensor_init[i]);
940 i++;
941 }
942}
943
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300944static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
945{
946 int i = 0;
947
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300948 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
949 i++;
950 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300951 i++;
952 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300953 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
954 i++;
955 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
956 i++;
957 msleep(20);
958 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
959 i++;
960/*jfm:win i2c_r from 00 to 80*/
961
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300962 while (ov7630_sensor_init[i][0]) {
963 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
964 i++;
965 }
966}
967
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300968static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
969{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300970 int i = 0;
971
Jean-Francois Moine62703302008-11-11 08:42:56 -0300972 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
973 i++;
974/* win: dble reset */
975 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
976 i++;
977 msleep(20);
978/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300979 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300980 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300981 i++;
982 }
983}
984
985static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
986{
987 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300988
Jean-Francois Moine60017612008-07-18 08:46:19 -0300989 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
990 i++;
991 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300992 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300993 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300994 i++;
995 }
996}
997
998/* this function is called at probe time */
999static int sd_config(struct gspca_dev *gspca_dev,
1000 const struct usb_device_id *id)
1001{
1002 struct sd *sd = (struct sd *) gspca_dev;
1003 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001004
1005 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001006 cam->epaddr = 0x01;
1007 cam->cam_mode = vga_mode;
1008 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001009
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001010 sd->bridge = id->driver_info >> 16;
1011 sd->sensor = id->driver_info >> 8;
1012 sd->i2c_base = id->driver_info;
1013
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001014 sd->qindex = 4; /* set the quantization table */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001015 sd->brightness = BRIGHTNESS_DEF;
1016 sd->contrast = CONTRAST_DEF;
1017 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001018 sd->blue = BLUE_BALANCE_DEF;
1019 sd->red = RED_BALANCE_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001020 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001021 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001022 sd->vflip = VFLIP_DEF;
1023 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001024
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001025 switch (sd->sensor) {
1026 case SENSOR_OV7630:
1027 case SENSOR_OV7648:
1028 case SENSOR_OV7660:
1029 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
1030 break;
1031 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001032 if (sd->sensor != SENSOR_OV7630)
1033 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001034 if (sd->sensor != SENSOR_MI0360)
1035 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001036 return 0;
1037}
1038
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001039/* this function is called at probe and resume time */
1040static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001041{
1042 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001043/* const __u8 *sn9c1xx; */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001044 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -03001045 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001046
Hans de Goede3647fea2008-07-15 05:36:30 -03001047 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001048 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001049 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001050 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1051 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001052 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001053 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001054 switch (sd->bridge) {
1055 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001056 if (regF1 != 0x11)
1057 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001058 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001059 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001060 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001061 if (regF1 != 0x11)
1062 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001063 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001064 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001065 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001066 if (regF1 != 0x12)
1067 return -ENODEV;
1068 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001069 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001070 break;
1071 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001072/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001073/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001074 if (regF1 != 0x12)
1075 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001076 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001077 break;
1078 }
1079
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001080 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001081
1082 return 0;
1083}
1084
1085static unsigned int setexposure(struct gspca_dev *gspca_dev,
1086 unsigned int expo)
1087{
1088 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001089 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001090 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001091 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001092 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001093 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001094 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1095
1096 switch (sd->sensor) {
1097 case SENSOR_HV7131R: {
1098 __u8 Expodoit[] =
1099 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1100
1101 Expodoit[3] = expo >> 16;
1102 Expodoit[4] = expo >> 8;
1103 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001104 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001105 break;
1106 }
1107 case SENSOR_MI0360: {
1108 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1109 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1110
1111 if (expo > 0x0635)
1112 expo = 0x0635;
1113 else if (expo < 0x0001)
1114 expo = 0x0001;
1115 expoMi[3] = expo >> 8;
1116 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001117 i2c_w8(gspca_dev, expoMi);
1118 i2c_w8(gspca_dev, doit);
1119 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001120 break;
1121 }
1122 case SENSOR_MO4000: {
1123 __u8 expoMof[] =
1124 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1125 __u8 expoMo10[] =
1126 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1127
1128 if (expo > 0x1fff)
1129 expo = 0x1fff;
1130 else if (expo < 0x0001)
1131 expo = 0x0001;
1132 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001133 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001134 expoMo10[3] = ((expo & 0x1c00) >> 10)
1135 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001136 i2c_w8(gspca_dev, expoMo10);
1137 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001138 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001139 ((expoMo10[3] & 0x07) << 10)
1140 | (expoMof[3] << 2)
1141 | ((expoMo10[3] & 0x30) >> 4));
1142 break;
1143 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001144 case SENSOR_OM6802: {
1145 __u8 gainOm[] =
1146 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1147
1148 if (expo > 0x03ff)
1149 expo = 0x03ff;
1150 if (expo < 0x0001)
1151 expo = 0x0001;
1152 gainOm[3] = expo >> 2;
1153 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001154 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001155 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1156 break;
1157 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001158 }
1159 return expo;
1160}
1161
1162static void setbrightness(struct gspca_dev *gspca_dev)
1163{
1164 struct sd *sd = (struct sd *) gspca_dev;
1165 unsigned int expo;
1166 __u8 k2;
1167
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001168 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001169 switch (sd->sensor) {
1170 case SENSOR_HV7131R:
1171 expo = sd->brightness << 4;
1172 if (expo > 0x002dc6c0)
1173 expo = 0x002dc6c0;
1174 else if (expo < 0x02a0)
1175 expo = 0x02a0;
1176 sd->exposure = setexposure(gspca_dev, expo);
1177 break;
1178 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001179 case SENSOR_MO4000:
1180 expo = sd->brightness >> 4;
1181 sd->exposure = setexposure(gspca_dev, expo);
1182 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001183 case SENSOR_OM6802:
1184 expo = sd->brightness >> 6;
1185 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001186 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001187 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001188 }
1189
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001190 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001191}
1192
1193static void setcontrast(struct gspca_dev *gspca_dev)
1194{
1195 struct sd *sd = (struct sd *) gspca_dev;
1196 __u8 k2;
1197 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1198
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001199 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1200 contrast[0] = (k2 + 1) / 2; /* red */
1201 contrast[2] = k2; /* green */
1202 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001203 reg_w(gspca_dev, 0x84, contrast, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001204}
1205
1206static void setcolors(struct gspca_dev *gspca_dev)
1207{
1208 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001209 int i, v;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001210 __u8 reg8a[12]; /* U & V gains */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001211 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1212 -24, -38, 64, /* UR UG UB */
1213 62, -51, -9 /* VR VG VB */
1214 };
1215 for (i = 0; i < 6; i++) {
1216 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001217 reg8a[i * 2] = v;
1218 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001219 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001220 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001221}
1222
1223static void setredblue(struct gspca_dev *gspca_dev)
1224{
1225 struct sd *sd = (struct sd *) gspca_dev;
1226
1227 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001228/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001229 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001230}
1231
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001232static void setautogain(struct gspca_dev *gspca_dev)
1233{
1234 struct sd *sd = (struct sd *) gspca_dev;
1235
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001236 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1237 return;
1238 if (sd->autogain)
1239 sd->ag_cnt = AG_CNT_START;
1240 else
1241 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001242}
1243
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001244static void setvflip(struct sd *sd)
1245{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001246 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1247 sd->vflip ? 0x82 : 0x02);
1248}
1249
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001250static void setinfrared(struct sd *sd)
1251{
1252/*fixme: different sequence for StarCam Clip and StarCam 370i */
1253/* Clip */
1254 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1255 sd->infrared ? 0x66 : 0x64);
1256}
1257
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001258/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001259static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001260{
1261 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001262 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001263 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001264 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001265 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001266 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1267 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001268 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001269 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001270 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001271
1272 sn9c1xx = sn_tb[(int) sd->sensor];
1273 configure_gpio(gspca_dev, sn9c1xx);
1274
Jean-Francois Moine60017612008-07-18 08:46:19 -03001275 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1276 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1277 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1278 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1279 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1280 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1281 reg_w1(gspca_dev, 0xd3, 0x50);
1282 reg_w1(gspca_dev, 0xc6, 0x00);
1283 reg_w1(gspca_dev, 0xc7, 0x00);
1284 reg_w1(gspca_dev, 0xc8, 0x50);
1285 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001286 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001287 switch (sd->sensor) {
1288 case SENSOR_OV7630:
1289 reg17 = 0xe2;
1290 break;
1291 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001292 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001293 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001294/*jfm: from win trace */
1295 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001296 if (sd->bridge == BRIDGE_SN9C120) {
1297 reg17 = 0xa0;
1298 break;
1299 }
1300 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001301 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001302 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001303 break;
1304 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001305 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001306/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001307 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1308 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1309 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001310 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001311 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1312 for (i = 0; i < 8; i++)
1313 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001314 switch (sd->sensor) {
Jean-Francois Moine62703302008-11-11 08:42:56 -03001315 case SENSOR_OV7648:
1316 reg_w1(gspca_dev, 0x9a, 0x0a);
1317 reg_w1(gspca_dev, 0x99, 0x60);
1318 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001319 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001320 if (sd->bridge == BRIDGE_SN9C120) {
1321 reg_w1(gspca_dev, 0x9a, 0x05);
1322 break;
1323 }
1324 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001325 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001326 reg_w1(gspca_dev, 0x9a, 0x08);
1327 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001328 break;
1329 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001330
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001331 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001332 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001333 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001334 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001335 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1336 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001337 switch (sd->sensor) {
1338 case SENSOR_HV7131R:
1339 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001340 break;
1341 case SENSOR_MI0360:
1342 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001343 break;
1344 case SENSOR_MO4000:
1345 mo4000_InitSensor(gspca_dev);
1346 if (mode) {
1347/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1348 reg1 = 0x06; /* clk 24Mz */
1349 } else {
1350 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001351/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001352 }
1353 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001354 case SENSOR_OM6802:
1355 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001356 reg17 = 0x64; /* 640 MCKSIZE */
1357 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001358 case SENSOR_OV7630:
1359 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001360 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001361 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001362 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001363 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001364 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001365 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001366 reg17 = 0x21;
1367/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368/* if (mode)
1369 ; * 320x2...
1370 else
1371 ; * 640x... */
1372 break;
1373 default:
1374/* case SENSOR_OV7660: */
1375 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001376 if (sd->bridge == BRIDGE_SN9C120) {
1377 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001378 reg17 = 0xa2;
1379 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001380 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001381 } else {
1382 reg17 = 0x22;
1383 reg1 = 0x06; /* 24 Mhz, video trf eneble
1384 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001385 }
1386 break;
1387 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001388 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001389 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001390 switch (sd->sensor) {
1391 case SENSOR_OV7630:
1392 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001393 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001394 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001395 break;
1396 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001397 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001398 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1399 break;
1400 }
1401
1402 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001403 reg18 = sn9c1xx[0x18] | (mode << 4);
1404 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001405
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001406 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1407 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001408
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001409 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001410
Jean-Francois Moine60017612008-07-18 08:46:19 -03001411 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001412 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001413 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001414 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001415 setinfrared(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001416 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001417 case SENSOR_OV7630:
1418 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001419 break;
1420 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001421 setbrightness(gspca_dev);
1422 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001423 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001424 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001425}
1426
1427static void sd_stopN(struct gspca_dev *gspca_dev)
1428{
1429 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001430 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001431 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001432 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001433 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine62703302008-11-11 08:42:56 -03001434 static const __u8 stopov7648[] =
1435 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001436 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001437 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001438
1439 data = 0x0b;
1440 switch (sd->sensor) {
1441 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001442 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001443 data = 0x2b;
1444 break;
1445 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001446 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001447 data = 0x29;
1448 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001449 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001450 i2c_w8(gspca_dev, stopov7648);
1451 /* fall thru */
1452 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001453 data = 0x29;
1454 break;
1455 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001456/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001457/* case SENSOR_OV7660: */
1458 break;
1459 }
1460 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001461 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1462 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1463 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1464 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001465 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001466}
1467
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001468static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001469{
1470 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001471 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001472 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001473 __u8 luma_mean = 130;
1474 __u8 luma_delta = 20;
1475
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001476 /* Thanks S., without your advice, autobright should not work :) */
1477 if (sd->ag_cnt < 0)
1478 return;
1479 if (--sd->ag_cnt >= 0)
1480 return;
1481 sd->ag_cnt = AG_CNT_START;
1482
1483 delta = atomic_read(&sd->avg_lum);
1484 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001485 if (delta < luma_mean - luma_delta ||
1486 delta > luma_mean + luma_delta) {
1487 switch (sd->sensor) {
1488 case SENSOR_HV7131R:
1489 expotimes = sd->exposure >> 8;
1490 expotimes += (luma_mean - delta) >> 4;
1491 if (expotimes < 0)
1492 expotimes = 0;
1493 sd->exposure = setexposure(gspca_dev,
1494 (unsigned int) (expotimes << 8));
1495 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001496 default:
1497/* case SENSOR_MO4000: */
1498/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001499/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001500 expotimes = sd->exposure;
1501 expotimes += (luma_mean - delta) >> 6;
1502 if (expotimes < 0)
1503 expotimes = 0;
1504 sd->exposure = setexposure(gspca_dev,
1505 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001506 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001507 break;
1508 }
1509 }
1510}
1511
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001512/* scan the URB packets */
1513/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001514static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1515 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001516 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001517 int len) /* iso packet length */
1518{
1519 struct sd *sd = (struct sd *) gspca_dev;
1520 int sof, avg_lum;
1521
1522 sof = len - 64;
1523 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1524
1525 /* end of frame */
1526 gspca_frame_add(gspca_dev, LAST_PACKET,
1527 frame, data, sof + 2);
1528 if (sd->ag_cnt < 0)
1529 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001530/* w1 w2 w3 */
1531/* w4 w5 w6 */
1532/* w7 w8 */
1533/* w4 */
1534 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1535/* w6 */
1536 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1537/* w2 */
1538 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1539/* w8 */
1540 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1541/* w5 */
1542 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1543 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001544 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001545 return;
1546 }
1547 if (gspca_dev->last_packet_type == LAST_PACKET) {
1548
1549 /* put the JPEG 422 header */
1550 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1551 }
1552 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1553}
1554
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001555static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558
1559 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001560 if (gspca_dev->streaming)
1561 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001562 return 0;
1563}
1564
1565static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1566{
1567 struct sd *sd = (struct sd *) gspca_dev;
1568
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001569 *val = sd->brightness;
1570 return 0;
1571}
1572
1573static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1574{
1575 struct sd *sd = (struct sd *) gspca_dev;
1576
1577 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001578 if (gspca_dev->streaming)
1579 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001580 return 0;
1581}
1582
1583static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1584{
1585 struct sd *sd = (struct sd *) gspca_dev;
1586
1587 *val = sd->contrast;
1588 return 0;
1589}
1590
1591static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1592{
1593 struct sd *sd = (struct sd *) gspca_dev;
1594
1595 sd->colors = val;
1596 if (gspca_dev->streaming)
1597 setcolors(gspca_dev);
1598 return 0;
1599}
1600
1601static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1602{
1603 struct sd *sd = (struct sd *) gspca_dev;
1604
1605 *val = sd->colors;
1606 return 0;
1607}
1608
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001609static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1610{
1611 struct sd *sd = (struct sd *) gspca_dev;
1612
1613 sd->blue = val;
1614 if (gspca_dev->streaming)
1615 setredblue(gspca_dev);
1616 return 0;
1617}
1618
1619static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1620{
1621 struct sd *sd = (struct sd *) gspca_dev;
1622
1623 *val = sd->blue;
1624 return 0;
1625}
1626
1627static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1628{
1629 struct sd *sd = (struct sd *) gspca_dev;
1630
1631 sd->red = val;
1632 if (gspca_dev->streaming)
1633 setredblue(gspca_dev);
1634 return 0;
1635}
1636
1637static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1638{
1639 struct sd *sd = (struct sd *) gspca_dev;
1640
1641 *val = sd->red;
1642 return 0;
1643}
1644
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001645static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1646{
1647 struct sd *sd = (struct sd *) gspca_dev;
1648
1649 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001650 if (gspca_dev->streaming)
1651 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001652 return 0;
1653}
1654
1655static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1656{
1657 struct sd *sd = (struct sd *) gspca_dev;
1658
1659 *val = sd->autogain;
1660 return 0;
1661}
1662
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001663static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1664{
1665 struct sd *sd = (struct sd *) gspca_dev;
1666
1667 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001668 if (gspca_dev->streaming)
1669 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001670 return 0;
1671}
1672
1673static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1674{
1675 struct sd *sd = (struct sd *) gspca_dev;
1676
1677 *val = sd->vflip;
1678 return 0;
1679}
1680
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001681static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1682{
1683 struct sd *sd = (struct sd *) gspca_dev;
1684
1685 sd->infrared = val;
1686 if (gspca_dev->streaming)
1687 setinfrared(sd);
1688 return 0;
1689}
1690
1691static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1692{
1693 struct sd *sd = (struct sd *) gspca_dev;
1694
1695 *val = sd->infrared;
1696 return 0;
1697}
1698
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001699/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001700static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001701 .name = MODULE_NAME,
1702 .ctrls = sd_ctrls,
1703 .nctrls = ARRAY_SIZE(sd_ctrls),
1704 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001705 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001706 .start = sd_start,
1707 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001708 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001709 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001710};
1711
1712/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001713#define BSI(bridge, sensor, i2c_addr) \
1714 .driver_info = (BRIDGE_ ## bridge << 16) \
1715 | (SENSOR_ ## sensor << 8) \
1716 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001717static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001718#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001719 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001720 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001721#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001722 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1723 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001724#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001725 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001726#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001727 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001728 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03001729 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001730 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1731/* bw600.inf:
1732 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1733/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1734/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1735 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1736/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1737 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1738/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1739/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1740 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1741/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1742/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1743 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1744 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001745#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1746 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1747#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001748/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1749/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1750/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001751 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1752/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03001753 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001754 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001755 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001756/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001757#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001758 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001759#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001760 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03001761 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001762#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001763 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1764 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1765/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001766#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001767 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001768 {}
1769};
1770MODULE_DEVICE_TABLE(usb, device_table);
1771
1772/* -- device connect -- */
1773static int sd_probe(struct usb_interface *intf,
1774 const struct usb_device_id *id)
1775{
1776 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1777 THIS_MODULE);
1778}
1779
1780static struct usb_driver sd_driver = {
1781 .name = MODULE_NAME,
1782 .id_table = device_table,
1783 .probe = sd_probe,
1784 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001785#ifdef CONFIG_PM
1786 .suspend = gspca_suspend,
1787 .resume = gspca_resume,
1788#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001789};
1790
1791/* -- module insert / remove -- */
1792static int __init sd_mod_init(void)
1793{
1794 if (usb_register(&sd_driver) < 0)
1795 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001796 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001797 return 0;
1798}
1799static void __exit sd_mod_exit(void)
1800{
1801 usb_deregister(&sd_driver);
1802 info("deregistered");
1803}
1804
1805module_init(sd_mod_init);
1806module_exit(sd_mod_exit);