blob: 698f200df233646f76ab28aa8103544b770a2880 [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;
1210 __u8 rega0[12]; /* U & V gains */
1211 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;
1217 rega0[i * 2] = v;
1218 rega0[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001219 }
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001220 reg_w(gspca_dev, 0x84, rega0, sizeof rega0);
1221}
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);
1376 if (mode) {
1377/* reg17 = 0x21; * 320 */
1378/* reg1 = 0x44; */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001379/* reg1 = 0x46; (done) */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001380 } else { /* 640 */
1381 if (sd->bridge == BRIDGE_SN9C120) {
1382 reg17 = 0xa2;
1383 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1384 } else {
1385 reg17 = 0x22;
1386 reg1 = 0x06; /* 24 Mhz, video trf eneble
1387 * inverse power down */
1388 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001389 }
1390 break;
1391 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001392 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001393 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001394 switch (sd->sensor) {
1395 case SENSOR_OV7630:
1396 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001397 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001398 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001399 break;
1400 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001401 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001402 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1403 break;
1404 }
1405
1406 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001407 reg18 = sn9c1xx[0x18] | (mode << 4);
1408 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001409
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001410 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1411 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001412
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001413 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001414
Jean-Francois Moine60017612008-07-18 08:46:19 -03001415 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001416 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001417 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001418 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001419 setinfrared(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001420 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001421 case SENSOR_OV7630:
1422 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001423 break;
1424 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001425 setbrightness(gspca_dev);
1426 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001427 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001428 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001429}
1430
1431static void sd_stopN(struct gspca_dev *gspca_dev)
1432{
1433 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001434 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001435 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001436 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001437 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine62703302008-11-11 08:42:56 -03001438 static const __u8 stopov7648[] =
1439 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001440 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001441 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001442
1443 data = 0x0b;
1444 switch (sd->sensor) {
1445 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001446 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001447 data = 0x2b;
1448 break;
1449 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001450 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 data = 0x29;
1452 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001453 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001454 i2c_w8(gspca_dev, stopov7648);
1455 /* fall thru */
1456 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001457 data = 0x29;
1458 break;
1459 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001460/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001461/* case SENSOR_OV7660: */
1462 break;
1463 }
1464 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001465 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1466 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1467 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1468 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001469 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001470}
1471
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001472static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001473{
1474 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001475 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001476 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001477 __u8 luma_mean = 130;
1478 __u8 luma_delta = 20;
1479
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001480 /* Thanks S., without your advice, autobright should not work :) */
1481 if (sd->ag_cnt < 0)
1482 return;
1483 if (--sd->ag_cnt >= 0)
1484 return;
1485 sd->ag_cnt = AG_CNT_START;
1486
1487 delta = atomic_read(&sd->avg_lum);
1488 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001489 if (delta < luma_mean - luma_delta ||
1490 delta > luma_mean + luma_delta) {
1491 switch (sd->sensor) {
1492 case SENSOR_HV7131R:
1493 expotimes = sd->exposure >> 8;
1494 expotimes += (luma_mean - delta) >> 4;
1495 if (expotimes < 0)
1496 expotimes = 0;
1497 sd->exposure = setexposure(gspca_dev,
1498 (unsigned int) (expotimes << 8));
1499 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001500 default:
1501/* case SENSOR_MO4000: */
1502/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001503/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001504 expotimes = sd->exposure;
1505 expotimes += (luma_mean - delta) >> 6;
1506 if (expotimes < 0)
1507 expotimes = 0;
1508 sd->exposure = setexposure(gspca_dev,
1509 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001510 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001511 break;
1512 }
1513 }
1514}
1515
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001516/* scan the URB packets */
1517/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001518static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1519 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001520 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001521 int len) /* iso packet length */
1522{
1523 struct sd *sd = (struct sd *) gspca_dev;
1524 int sof, avg_lum;
1525
1526 sof = len - 64;
1527 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1528
1529 /* end of frame */
1530 gspca_frame_add(gspca_dev, LAST_PACKET,
1531 frame, data, sof + 2);
1532 if (sd->ag_cnt < 0)
1533 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001534/* w1 w2 w3 */
1535/* w4 w5 w6 */
1536/* w7 w8 */
1537/* w4 */
1538 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1539/* w6 */
1540 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1541/* w2 */
1542 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1543/* w8 */
1544 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1545/* w5 */
1546 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1547 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001548 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001549 return;
1550 }
1551 if (gspca_dev->last_packet_type == LAST_PACKET) {
1552
1553 /* put the JPEG 422 header */
1554 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1555 }
1556 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1557}
1558
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001559static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1560{
1561 struct sd *sd = (struct sd *) gspca_dev;
1562
1563 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001564 if (gspca_dev->streaming)
1565 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001566 return 0;
1567}
1568
1569static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1570{
1571 struct sd *sd = (struct sd *) gspca_dev;
1572
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001573 *val = sd->brightness;
1574 return 0;
1575}
1576
1577static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1578{
1579 struct sd *sd = (struct sd *) gspca_dev;
1580
1581 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001582 if (gspca_dev->streaming)
1583 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001584 return 0;
1585}
1586
1587static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1588{
1589 struct sd *sd = (struct sd *) gspca_dev;
1590
1591 *val = sd->contrast;
1592 return 0;
1593}
1594
1595static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1596{
1597 struct sd *sd = (struct sd *) gspca_dev;
1598
1599 sd->colors = val;
1600 if (gspca_dev->streaming)
1601 setcolors(gspca_dev);
1602 return 0;
1603}
1604
1605static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1606{
1607 struct sd *sd = (struct sd *) gspca_dev;
1608
1609 *val = sd->colors;
1610 return 0;
1611}
1612
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001613static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1614{
1615 struct sd *sd = (struct sd *) gspca_dev;
1616
1617 sd->blue = val;
1618 if (gspca_dev->streaming)
1619 setredblue(gspca_dev);
1620 return 0;
1621}
1622
1623static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1624{
1625 struct sd *sd = (struct sd *) gspca_dev;
1626
1627 *val = sd->blue;
1628 return 0;
1629}
1630
1631static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1632{
1633 struct sd *sd = (struct sd *) gspca_dev;
1634
1635 sd->red = val;
1636 if (gspca_dev->streaming)
1637 setredblue(gspca_dev);
1638 return 0;
1639}
1640
1641static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1642{
1643 struct sd *sd = (struct sd *) gspca_dev;
1644
1645 *val = sd->red;
1646 return 0;
1647}
1648
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001649static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1650{
1651 struct sd *sd = (struct sd *) gspca_dev;
1652
1653 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001654 if (gspca_dev->streaming)
1655 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001656 return 0;
1657}
1658
1659static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1660{
1661 struct sd *sd = (struct sd *) gspca_dev;
1662
1663 *val = sd->autogain;
1664 return 0;
1665}
1666
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001667static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1668{
1669 struct sd *sd = (struct sd *) gspca_dev;
1670
1671 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001672 if (gspca_dev->streaming)
1673 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001674 return 0;
1675}
1676
1677static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1678{
1679 struct sd *sd = (struct sd *) gspca_dev;
1680
1681 *val = sd->vflip;
1682 return 0;
1683}
1684
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001685static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1686{
1687 struct sd *sd = (struct sd *) gspca_dev;
1688
1689 sd->infrared = val;
1690 if (gspca_dev->streaming)
1691 setinfrared(sd);
1692 return 0;
1693}
1694
1695static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1696{
1697 struct sd *sd = (struct sd *) gspca_dev;
1698
1699 *val = sd->infrared;
1700 return 0;
1701}
1702
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001703/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001704static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001705 .name = MODULE_NAME,
1706 .ctrls = sd_ctrls,
1707 .nctrls = ARRAY_SIZE(sd_ctrls),
1708 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001709 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001710 .start = sd_start,
1711 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001712 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001713 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001714};
1715
1716/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001717#define BSI(bridge, sensor, i2c_addr) \
1718 .driver_info = (BRIDGE_ ## bridge << 16) \
1719 | (SENSOR_ ## sensor << 8) \
1720 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001721static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001722#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001723 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001724 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001725#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001726 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1727 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001728#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001729 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001730#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001731 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001732 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03001733 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001734 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1735/* bw600.inf:
1736 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1737/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1738/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1739 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1740/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1741 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1742/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1743/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1744 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1745/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1746/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1747 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1748 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001749#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1750 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1751#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001752/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1753/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1754/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001755 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1756/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03001757 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001758 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001759 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001760/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001761#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001762 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001763#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001764 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03001765 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001766#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001767 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1768 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1769/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001770#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001771 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001772 {}
1773};
1774MODULE_DEVICE_TABLE(usb, device_table);
1775
1776/* -- device connect -- */
1777static int sd_probe(struct usb_interface *intf,
1778 const struct usb_device_id *id)
1779{
1780 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1781 THIS_MODULE);
1782}
1783
1784static struct usb_driver sd_driver = {
1785 .name = MODULE_NAME,
1786 .id_table = device_table,
1787 .probe = sd_probe,
1788 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001789#ifdef CONFIG_PM
1790 .suspend = gspca_suspend,
1791 .resume = gspca_resume,
1792#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001793};
1794
1795/* -- module insert / remove -- */
1796static int __init sd_mod_init(void)
1797{
1798 if (usb_register(&sd_driver) < 0)
1799 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001800 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001801 return 0;
1802}
1803static void __exit sd_mod_exit(void)
1804{
1805 usb_deregister(&sd_driver);
1806 info("deregistered");
1807}
1808
1809module_init(sd_mod_init);
1810module_exit(sd_mod_exit);