blob: a7954a72e4b902d03543a5f2ee3084dfc863debc [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 Moine6c862742008-09-08 04:57:26 -030044 __u8 vflip; /* ov7630 only */
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030045 __u8 infrared; /* mi0360 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030046
47 signed char ag_cnt;
48#define AG_CNT_START 13
49
50 char qindex;
Hans de Goede3647fea2008-07-15 05:36:30 -030051 unsigned char bridge;
52#define BRIDGE_SN9C102P 0
53#define BRIDGE_SN9C105 1
54#define BRIDGE_SN9C110 2
55#define BRIDGE_SN9C120 3
56#define BRIDGE_SN9C325 4
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030057 char sensor; /* Type of image sensor chip */
58#define SENSOR_HV7131R 0
59#define SENSOR_MI0360 1
60#define SENSOR_MO4000 2
Jean-Francois Moined2d16e92008-09-03 16:47:23 -030061#define SENSOR_OM6802 3
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -030062#define SENSOR_OV7630 4
63#define SENSOR_OV7648 5
64#define SENSOR_OV7660 6
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030065 unsigned char i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030066};
67
68/* V4L2 controls supported by the driver */
69static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
70static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
71static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
73static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
75static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030077static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030079static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030081
82static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030083 {
84 {
85 .id = V4L2_CID_BRIGHTNESS,
86 .type = V4L2_CTRL_TYPE_INTEGER,
87 .name = "Brightness",
88 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -030089#define BRIGHTNESS_MAX 0xffff
90 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030091 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -030092#define BRIGHTNESS_DEF 0x7fff
93 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030094 },
95 .set = sd_setbrightness,
96 .get = sd_getbrightness,
97 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030098 {
99 {
100 .id = V4L2_CID_CONTRAST,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Contrast",
103 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300104#define CONTRAST_MAX 127
105 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300106 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300107#define CONTRAST_DEF 63
108 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300109 },
110 .set = sd_setcontrast,
111 .get = sd_getcontrast,
112 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300113 {
114 {
115 .id = V4L2_CID_SATURATION,
116 .type = V4L2_CTRL_TYPE_INTEGER,
117 .name = "Color",
118 .minimum = 0,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300119 .maximum = 64,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300121#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300122 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300123 },
124 .set = sd_setcolors,
125 .get = sd_getcolors,
126 },
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300127#define AUTOGAIN_IDX 3
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300128 {
129 {
130 .id = V4L2_CID_AUTOGAIN,
131 .type = V4L2_CTRL_TYPE_BOOLEAN,
132 .name = "Auto Gain",
133 .minimum = 0,
134 .maximum = 1,
135 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300136#define AUTOGAIN_DEF 1
137 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300138 },
139 .set = sd_setautogain,
140 .get = sd_getautogain,
141 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300142/* ov7630 only */
143#define VFLIP_IDX 4
144 {
145 {
146 .id = V4L2_CID_VFLIP,
147 .type = V4L2_CTRL_TYPE_BOOLEAN,
148 .name = "Vflip",
149 .minimum = 0,
150 .maximum = 1,
151 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300152#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300153 .default_value = VFLIP_DEF,
154 },
155 .set = sd_setvflip,
156 .get = sd_getvflip,
157 },
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300158/* mi0360 only */
159#define INFRARED_IDX 5
160 {
161 {
162 .id = V4L2_CID_INFRARED,
163 .type = V4L2_CTRL_TYPE_BOOLEAN,
164 .name = "Infrared",
165 .minimum = 0,
166 .maximum = 1,
167 .step = 1,
168#define INFRARED_DEF 0
169 .default_value = INFRARED_DEF,
170 },
171 .set = sd_setinfrared,
172 .get = sd_getinfrared,
173 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300174};
175
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300176static struct v4l2_pix_format vga_mode[] = {
177 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
178 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300179 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300180 .colorspace = V4L2_COLORSPACE_JPEG,
181 .priv = 2},
182 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
183 .bytesperline = 320,
184 .sizeimage = 320 * 240 * 3 / 8 + 590,
185 .colorspace = V4L2_COLORSPACE_JPEG,
186 .priv = 1},
187 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
188 .bytesperline = 640,
189 .sizeimage = 640 * 480 * 3 / 8 + 590,
190 .colorspace = V4L2_COLORSPACE_JPEG,
191 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300192};
193
194/*Data from sn9c102p+hv71331r */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300195static const __u8 sn_hv7131[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300196/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
197 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
198/* reg8 reg9 rega regb regc regd rege regf */
199 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
200/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
201 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
202/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
203 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300204};
205
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300206static const __u8 sn_mi0360[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300207/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
208 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
209/* reg8 reg9 rega regb regc regd rege regf */
210 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
211/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
212 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
213/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
214 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300215};
216
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300217static const __u8 sn_mo4000[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300218/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
219 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
220/* reg8 reg9 rega regb regc regd rege regf */
221 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
223 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
224/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
225 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300226};
227
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300228static const __u8 sn_om6802[] = {
229/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
230 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
231/* reg8 reg9 rega regb regc regd rege regf */
232 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
234 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
235/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
236 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
238 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
239 0xf7
240};
241
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300242static const __u8 sn_ov7630[] = {
243/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
244 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
245/* reg8 reg9 rega regb regc regd rege regf */
246 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
247/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
248 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
249/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
250 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
251};
252
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300253static const __u8 sn_ov7648[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300254/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
255 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
256/* reg8 reg9 rega regb regc regd rege regf */
257 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
258/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
259 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
260/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
261 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300262};
263
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300264static const __u8 sn_ov7660[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300265/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
266 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
267/* reg8 reg9 rega regb regc regd rege regf */
268 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
269/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
270 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
271/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
272 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300273};
274
275/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300276static const __u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300277 sn_hv7131,
278 sn_mi0360,
279 sn_mo4000,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300280 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300281 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300282 sn_ov7648,
283 sn_ov7660
284};
285
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300286static const __u8 gamma_def[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300287 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
288 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
289};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300290
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300291/* color matrix and offsets */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300292static const __u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300293 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
294 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
295 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
296 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300297};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300298static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300299 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
300 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
301 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
302 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
304 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
305 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
306
307 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
308 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
309 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
310 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
311 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
312 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
313 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
314 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
315
316 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
317 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
318 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
319 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
321
322 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
323 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
325 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
326 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300327 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300328};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300329static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300330 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
331 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
332 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
334 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
335 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
336 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
337 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
338 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
339 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
340 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
341 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
342 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
343 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
344 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
345 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
346 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
347 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
348 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
349 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
350 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
351 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
352 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
353 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
354 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
355 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
356 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
357 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
358 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
359 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
360 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
361 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
362 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
363
364 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
365 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
366 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
367 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
368 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
369
370 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
371 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
372 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
373 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
374
375 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
376 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
377/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
378/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
379 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
380 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300381 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300382};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300383static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
385 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
386 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
387 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
388 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
389 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
390 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
391 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
392 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
395 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
396 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
397 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
398 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
399 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
401 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
402 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
403 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300404 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300405};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300406static __u8 om6802_sensor_init[][8] = {
407 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
408 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
409 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
410 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
411/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
412 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
413 /* white balance & auto-exposure */
414/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
415 * set color mode */
416/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
417 * max AGC value in AE */
418/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
419 * preset AGC */
420/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
421 * preset brightness */
422/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
423 * preset contrast */
424/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
425 * preset gamma */
426 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
427 /* luminance mode (0x4f = AE) */
428 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
429 /* preset shutter */
430/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
431 * auto frame rate */
432/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
433
434/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
435/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
436/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
437/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
438 {}
439};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300440static const __u8 ov7630_sensor_init[][8] = {
441 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
443/* win: delay 20ms */
444 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
446/* win: delay 20ms */
447 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300448/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300449 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
450 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
451 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
452 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
453 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
454 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
456 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
457 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
458 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
459 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
460 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
461 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
462 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
463 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
464 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
465 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
466 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
468 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
469 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
470 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
471 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
472 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
473 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
474 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
475/* */
476 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
477 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
478/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300479/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
480 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300481 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
483 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300484/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300485 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
486 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
487 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300488/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300489 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300490/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300491 {}
492};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300493static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300494 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300495/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300496 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300497 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300498 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300499 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300500 /* GAIN BLUE RED VREF */
501 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
502 /* COM 1 BAVE GEAVE AECHH */
503 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
504 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300505 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300506 /* AECH CLKRC COM7 COM8 */
507 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
508 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
509 /* HSTART HSTOP VSTRT VSTOP */
510 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
511 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
512 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
513 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300514/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
515 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300516 /* AEW AEB VPT BBIAS */
517 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
518 /* GbBIAS RSVD EXHCH EXHCL */
519 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
520 /* RBIAS ADVFL ASDVFH YAVE */
521 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
522 /* HSYST HSYEN HREF */
523 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
524 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
525 /* ADC ACOM OFON TSLB */
526 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
527 /* COM11 COM12 COM13 COM14 */
528 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
529 /* EDGE COM15 COM16 COM17 */
530 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
531 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
532 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
533 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
534 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
535 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
536 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
537 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
538 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
539 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
540 /* LCC1 LCC2 LCC3 LCC4 */
541 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300542 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300543 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300544 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300545 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
546 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
547 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
548 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
549 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
550 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
551 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
552 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
553 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300554 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300555/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300556 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300557 /* bits[3..0]reserved */
558 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
559 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
560 /* VREF vertical frame ctrl */
561 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300562 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
563 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
564 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
565 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
566/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300567/****** (some exchanges in the win trace) ******/
568 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300569 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
570 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
571 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
572/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300573/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300574/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300575 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
576 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
578 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300579 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300580};
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300581/* reg 0x04 reg 0x07 reg 0x10 */
582/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300583
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300584static const __u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300585 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
586 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
587 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
588 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
589 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
590 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
591 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
592 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
593 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
594 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
595 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
596 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
597 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
598 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
599 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
600 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
601 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
602 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
603 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
604 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
605 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
606 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
607 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
608 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
609 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
610 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
611 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
612 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
613 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
614 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
615 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
616 * This is currently setting a
617 * blue tint, and some things more , i leave it here for future test if
618 * somene is having problems with color on this sensor
619 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
620 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
621 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
622 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
623 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
624 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
625 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
626 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
627 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
628 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
629 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
630 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
631 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
632 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
633 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
634 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
635 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
636/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300637 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300638};
639
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300640static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300641 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
642 0x06, 0x08, 0x0A, 0x11,
643 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
644 0x19, 0x19, 0x17, 0x15,
645 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
646 0x21, 0x2E, 0x21, 0x23,
647 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
648 0x25, 0x29, 0x2C, 0x29,
649 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
650 0x17, 0x1B, 0x29, 0x29,
651 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
652 0x29, 0x29, 0x29, 0x29,
653 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
654 0x29, 0x29, 0x29, 0x29,
655 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
656 0x29, 0x29, 0x29, 0x29
657};
658
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300659/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300660static void reg_r(struct gspca_dev *gspca_dev,
661 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300662{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300663#ifdef GSPCA_DEBUG
664 if (len > USB_BUF_SZ) {
665 err("reg_r: buffer overflow");
666 return;
667 }
668#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300669 usb_control_msg(gspca_dev->dev,
670 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300671 0,
672 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
673 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300674 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300675 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300676 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300677}
678
Jean-Francois Moine60017612008-07-18 08:46:19 -0300679static void reg_w1(struct gspca_dev *gspca_dev,
680 __u16 value,
681 __u8 data)
682{
683 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
684 gspca_dev->usb_buf[0] = data;
685 usb_control_msg(gspca_dev->dev,
686 usb_sndctrlpipe(gspca_dev->dev, 0),
687 0x08,
688 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
689 value,
690 0,
691 gspca_dev->usb_buf, 1,
692 500);
693}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300694static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300695 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300696 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300697 int len)
698{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300699 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
700 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300701#ifdef GSPCA_DEBUG
702 if (len > USB_BUF_SZ) {
703 err("reg_w: buffer overflow");
704 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300705 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300706#endif
707 memcpy(gspca_dev->usb_buf, buffer, len);
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, 0,
713 gspca_dev->usb_buf, len,
714 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300715}
716
Jean-Francois Moine60017612008-07-18 08:46:19 -0300717/* I2C write 1 byte */
718static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300719{
720 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300721
Jean-Francois Moine60017612008-07-18 08:46:19 -0300722 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
723 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
724 gspca_dev->usb_buf[1] = sd->i2c_base;
725 gspca_dev->usb_buf[2] = reg;
726 gspca_dev->usb_buf[3] = val;
727 gspca_dev->usb_buf[4] = 0;
728 gspca_dev->usb_buf[5] = 0;
729 gspca_dev->usb_buf[6] = 0;
730 gspca_dev->usb_buf[7] = 0x10;
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 0x08, /* value = i2c */
736 0,
737 gspca_dev->usb_buf, 8,
738 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300739}
740
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300741/* I2C write 8 bytes */
742static void i2c_w8(struct gspca_dev *gspca_dev,
743 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300744{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300745 memcpy(gspca_dev->usb_buf, buffer, 8);
746 usb_control_msg(gspca_dev->dev,
747 usb_sndctrlpipe(gspca_dev->dev, 0),
748 0x08,
749 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
750 0x08, 0, /* value, index */
751 gspca_dev->usb_buf, 8,
752 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300753 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300754}
755
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300756/* read 5 bytes in gspca_dev->usb_buf */
757static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300758{
759 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300760 __u8 mode[8];
761
Hans de Goede3647fea2008-07-15 05:36:30 -0300762 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300763 mode[1] = sd->i2c_base;
764 mode[2] = reg;
765 mode[3] = 0;
766 mode[4] = 0;
767 mode[5] = 0;
768 mode[6] = 0;
769 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300770 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300771 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300772 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300773 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300774 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300775 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300776 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777}
778
779static int probesensor(struct gspca_dev *gspca_dev)
780{
781 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300782
Jean-Francois Moine60017612008-07-18 08:46:19 -0300783 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300784 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300785 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300786 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300787 i2c_r5(gspca_dev, 0); /* read sensor id */
788 if (gspca_dev->usb_buf[0] == 0x02
789 && gspca_dev->usb_buf[1] == 0x09
790 && gspca_dev->usb_buf[2] == 0x01
791 && gspca_dev->usb_buf[3] == 0x00
792 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300793 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
794 sd->sensor = SENSOR_HV7131R;
795 return SENSOR_HV7131R;
796 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300797 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300798 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
799 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300800 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
801 return -ENODEV;
802}
803
804static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300805 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300806{
807 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300808 const __u8 *reg9a;
809 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300810 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300811 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300812 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300813 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814
Jean-Francois Moine60017612008-07-18 08:46:19 -0300815 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300816 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300817
818 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300819 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
820 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300821 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300822 switch (sd->bridge) {
823 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300824 reg9a = reg9a_sn9c325;
825 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826 default:
827 reg9a = reg9a_def;
828 break;
829 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300830 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300831
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300832 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300833
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300834 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300835
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300836 switch (sd->sensor) {
837 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300838 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300839 reg_w1(gspca_dev, 0x01, 0x42);
840 reg_w1(gspca_dev, 0x17, 0x64);
841 reg_w1(gspca_dev, 0x01, 0x42);
842 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300843/*jfm: from win trace */
844 case SENSOR_OV7630:
845 reg_w1(gspca_dev, 0x01, 0x61);
846 reg_w1(gspca_dev, 0x17, 0xe2);
847 reg_w1(gspca_dev, 0x01, 0x60);
848 reg_w1(gspca_dev, 0x01, 0x40);
849 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300850 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300851 reg_w1(gspca_dev, 0x01, 0x43);
852 reg_w1(gspca_dev, 0x17, 0xae);
853 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300854 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300855/*jfm: from win trace */
856 case SENSOR_OV7660:
857 reg_w1(gspca_dev, 0x01, 0x61);
858 reg_w1(gspca_dev, 0x17, 0x20);
859 reg_w1(gspca_dev, 0x01, 0x60);
860 reg_w1(gspca_dev, 0x01, 0x40);
861 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300863 reg_w1(gspca_dev, 0x01, 0x43);
864 reg_w1(gspca_dev, 0x17, 0x61);
865 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300866 if (sd->sensor == SENSOR_HV7131R) {
867 if (probesensor(gspca_dev) < 0)
868 return -ENODEV;
869 }
870 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300871 }
872 return 0;
873}
874
875static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
876{
877 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300878 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300879 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
880
881 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300882 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883 i++;
884 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300885 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886}
887
888static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
889{
890 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300891
892 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300893 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300894 i++;
895 }
896}
897
898static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
899{
900 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300901
902 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300903 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300904 i++;
905 }
906}
907
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300908static void om6802_InitSensor(struct gspca_dev *gspca_dev)
909{
910 int i = 0;
911
912 while (om6802_sensor_init[i][0]) {
913 i2c_w8(gspca_dev, om6802_sensor_init[i]);
914 i++;
915 }
916}
917
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300918static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
919{
920 int i = 0;
921
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300922 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
923 i++;
924 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300925 i++;
926 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300927 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
928 i++;
929 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
930 i++;
931 msleep(20);
932 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
933 i++;
934/*jfm:win i2c_r from 00 to 80*/
935
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300936 while (ov7630_sensor_init[i][0]) {
937 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
938 i++;
939 }
940}
941
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300942static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
943{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300944 int i = 0;
945
946 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300947 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300948 i++;
949 }
950}
951
952static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
953{
954 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300955
Jean-Francois Moine60017612008-07-18 08:46:19 -0300956 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
957 i++;
958 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300959 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300960 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300961 i++;
962 }
963}
964
965/* this function is called at probe time */
966static int sd_config(struct gspca_dev *gspca_dev,
967 const struct usb_device_id *id)
968{
969 struct sd *sd = (struct sd *) gspca_dev;
970 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300971
972 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300973 cam->epaddr = 0x01;
974 cam->cam_mode = vga_mode;
975 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300976
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300977 sd->bridge = id->driver_info >> 16;
978 sd->sensor = id->driver_info >> 8;
979 sd->i2c_base = id->driver_info;
980
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300981 sd->qindex = 4; /* set the quantization table */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300982 sd->brightness = BRIGHTNESS_DEF;
983 sd->contrast = CONTRAST_DEF;
984 sd->colors = COLOR_DEF;
985 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -0300986 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300987 sd->vflip = VFLIP_DEF;
988 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -0300989
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300990 switch (sd->sensor) {
991 case SENSOR_OV7630:
992 case SENSOR_OV7648:
993 case SENSOR_OV7660:
994 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
995 break;
996 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300997 if (sd->sensor != SENSOR_OV7630)
998 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300999 if (sd->sensor != SENSOR_MI0360)
1000 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001001 return 0;
1002}
1003
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001004/* this function is called at probe and resume time */
1005static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001006{
1007 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001008/* const __u8 *sn9c1xx; */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001009 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -03001010 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001011
Hans de Goede3647fea2008-07-15 05:36:30 -03001012 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001013 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001014 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001015 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1016 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001017 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001018 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001019 switch (sd->bridge) {
1020 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001021 if (regF1 != 0x11)
1022 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001023 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001024 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001025 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001026 if (regF1 != 0x11)
1027 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001028 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001029 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001030 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001031 if (regF1 != 0x12)
1032 return -ENODEV;
1033 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001034 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001035 break;
1036 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001037/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001038/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001039 if (regF1 != 0x12)
1040 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001041 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001042 break;
1043 }
1044
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001045 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001046
1047 return 0;
1048}
1049
1050static unsigned int setexposure(struct gspca_dev *gspca_dev,
1051 unsigned int expo)
1052{
1053 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001054 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001055 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001056 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001057 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001058 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001059 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1060
1061 switch (sd->sensor) {
1062 case SENSOR_HV7131R: {
1063 __u8 Expodoit[] =
1064 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1065
1066 Expodoit[3] = expo >> 16;
1067 Expodoit[4] = expo >> 8;
1068 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001069 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001070 break;
1071 }
1072 case SENSOR_MI0360: {
1073 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1074 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1075
1076 if (expo > 0x0635)
1077 expo = 0x0635;
1078 else if (expo < 0x0001)
1079 expo = 0x0001;
1080 expoMi[3] = expo >> 8;
1081 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001082 i2c_w8(gspca_dev, expoMi);
1083 i2c_w8(gspca_dev, doit);
1084 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001085 break;
1086 }
1087 case SENSOR_MO4000: {
1088 __u8 expoMof[] =
1089 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1090 __u8 expoMo10[] =
1091 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1092
1093 if (expo > 0x1fff)
1094 expo = 0x1fff;
1095 else if (expo < 0x0001)
1096 expo = 0x0001;
1097 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001098 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001099 expoMo10[3] = ((expo & 0x1c00) >> 10)
1100 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001101 i2c_w8(gspca_dev, expoMo10);
1102 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001103 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001104 ((expoMo10[3] & 0x07) << 10)
1105 | (expoMof[3] << 2)
1106 | ((expoMo10[3] & 0x30) >> 4));
1107 break;
1108 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001109 case SENSOR_OM6802: {
1110 __u8 gainOm[] =
1111 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1112
1113 if (expo > 0x03ff)
1114 expo = 0x03ff;
1115 if (expo < 0x0001)
1116 expo = 0x0001;
1117 gainOm[3] = expo >> 2;
1118 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001119 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001120 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1121 break;
1122 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001123 }
1124 return expo;
1125}
1126
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001127/* this function is used for sensors o76xx only */
1128static void setbrightcont(struct gspca_dev *gspca_dev)
1129{
1130 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001131 int val;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001132 __u8 reg84_full[0x15];
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001133
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001134 memcpy(reg84_full, reg84, sizeof reg84_full);
1135 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1136 reg84_full[0] = (val + 1) / 2; /* red */
1137 reg84_full[2] = val; /* green */
1138 reg84_full[4] = (val + 1) / 5; /* blue */
1139 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001140 / BRIGHTNESS_MAX;
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001141 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001142 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1143}
1144
1145/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001146static void setbrightness(struct gspca_dev *gspca_dev)
1147{
1148 struct sd *sd = (struct sd *) gspca_dev;
1149 unsigned int expo;
1150 __u8 k2;
1151
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001152 k2 = sd->brightness >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001153 switch (sd->sensor) {
1154 case SENSOR_HV7131R:
1155 expo = sd->brightness << 4;
1156 if (expo > 0x002dc6c0)
1157 expo = 0x002dc6c0;
1158 else if (expo < 0x02a0)
1159 expo = 0x02a0;
1160 sd->exposure = setexposure(gspca_dev, expo);
1161 break;
1162 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001163 case SENSOR_MO4000:
1164 expo = sd->brightness >> 4;
1165 sd->exposure = setexposure(gspca_dev, expo);
1166 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001167 case SENSOR_OM6802:
1168 expo = sd->brightness >> 6;
1169 sd->exposure = setexposure(gspca_dev, expo);
1170 k2 = sd->brightness >> 11;
1171 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001172 }
1173
Jean-Francois Moine60017612008-07-18 08:46:19 -03001174 reg_w1(gspca_dev, 0x96, k2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001175}
1176
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001177/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001178static void setcontrast(struct gspca_dev *gspca_dev)
1179{
1180 struct sd *sd = (struct sd *) gspca_dev;
1181 __u8 k2;
1182 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1183
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001184 k2 = sd->contrast;
1185 contrast[2] = k2;
1186 contrast[0] = (k2 + 1) >> 1;
1187 contrast[4] = (k2 + 1) / 5;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001188 reg_w(gspca_dev, 0x84, contrast, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001189}
1190
1191static void setcolors(struct gspca_dev *gspca_dev)
1192{
1193 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001194 __u8 blue, red;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001195
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001196 if (sd->colors >= 32) {
1197 red = 32 + (sd->colors - 32) / 2;
1198 blue = 64 - sd->colors;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001199 } else {
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001200 red = sd->colors;
1201 blue = 32 + (32 - sd->colors) / 2;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001202 }
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001203 reg_w1(gspca_dev, 0x05, red);
1204/* reg_w1(gspca_dev, 0x07, 32); */
1205 reg_w1(gspca_dev, 0x06, blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001206}
1207
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001208static void setautogain(struct gspca_dev *gspca_dev)
1209{
1210 struct sd *sd = (struct sd *) gspca_dev;
1211
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001212 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1213 return;
1214 if (sd->autogain)
1215 sd->ag_cnt = AG_CNT_START;
1216 else
1217 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001218}
1219
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001220static void setvflip(struct sd *sd)
1221{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001222 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1223 sd->vflip ? 0x82 : 0x02);
1224}
1225
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001226static void setinfrared(struct sd *sd)
1227{
1228/*fixme: different sequence for StarCam Clip and StarCam 370i */
1229/* Clip */
1230 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1231 sd->infrared ? 0x66 : 0x64);
1232}
1233
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001234/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001235static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001236{
1237 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001238 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001239 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001240 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001241 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001242 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1243 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001244 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001245 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001246 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001247
1248 sn9c1xx = sn_tb[(int) sd->sensor];
1249 configure_gpio(gspca_dev, sn9c1xx);
1250
Jean-Francois Moine60017612008-07-18 08:46:19 -03001251 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1252 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1253 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1254 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1255 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1256 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1257 reg_w1(gspca_dev, 0xd3, 0x50);
1258 reg_w1(gspca_dev, 0xc6, 0x00);
1259 reg_w1(gspca_dev, 0xc7, 0x00);
1260 reg_w1(gspca_dev, 0xc8, 0x50);
1261 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001262 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001263 switch (sd->sensor) {
1264 case SENSOR_OV7630:
1265 reg17 = 0xe2;
1266 break;
1267 case SENSOR_OV7648:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001268 reg17 = 0xae;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001269 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001270/*jfm: from win trace */
1271 case SENSOR_OV7660:
1272 reg17 = 0xa0;
1273 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001274 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001275 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001276 break;
1277 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001278 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001279 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1280 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1281 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1282 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001283 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1284 for (i = 0; i < 8; i++)
1285 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001286 switch (sd->sensor) {
1287 case SENSOR_OV7660:
1288 reg_w1(gspca_dev, 0x9a, 0x05);
1289 break;
1290 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001291 reg_w1(gspca_dev, 0x9a, 0x08);
1292 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001293 break;
1294 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001295
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001296 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001297 if (mode)
1298 reg1 = 0x46; /* 320 clk 48Mhz */
1299 else
1300 reg1 = 0x06; /* 640 clk 24Mz */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001301 reg17 = 0x61;
1302 switch (sd->sensor) {
1303 case SENSOR_HV7131R:
1304 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001305 break;
1306 case SENSOR_MI0360:
1307 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001308 break;
1309 case SENSOR_MO4000:
1310 mo4000_InitSensor(gspca_dev);
1311 if (mode) {
1312/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1313 reg1 = 0x06; /* clk 24Mz */
1314 } else {
1315 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001316/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001317 }
1318 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001319 case SENSOR_OM6802:
1320 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001321 reg17 = 0x64; /* 640 MCKSIZE */
1322 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001323 case SENSOR_OV7630:
1324 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001325 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001326 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001327 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001328 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001329 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001330 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001331 reg17 = 0xa2;
1332 reg1 = 0x44;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001333/* if (mode)
1334 ; * 320x2...
1335 else
1336 ; * 640x... */
1337 break;
1338 default:
1339/* case SENSOR_OV7660: */
1340 ov7660_InitSensor(gspca_dev);
1341 if (mode) {
1342/* reg17 = 0x21; * 320 */
1343/* reg1 = 0x44; */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001344/* reg1 = 0x46; (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001345 } else {
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001346 reg17 = 0xa2; /* 640 */
1347 reg1 = 0x44;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001348 }
1349 break;
1350 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001351 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001352 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001353 switch (sd->sensor) {
1354 case SENSOR_OV7630:
1355 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001356 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001357 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001358 break;
1359 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001360 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001361 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1362 break;
1363 }
1364
1365 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001366 reg18 = sn9c1xx[0x18] | (mode << 4);
1367 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001369 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1370 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001371
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001372 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001373
Jean-Francois Moine60017612008-07-18 08:46:19 -03001374 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001375 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001376 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001377 setinfrared(sd);
1378 /* fall thru */
1379 case SENSOR_HV7131R:
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001380 case SENSOR_MO4000:
1381 case SENSOR_OM6802:
1382 setbrightness(gspca_dev);
1383 setcontrast(gspca_dev);
1384 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001385 case SENSOR_OV7630:
1386 setvflip(sd);
1387 /* fall thru */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001388 default: /* OV76xx */
1389 setbrightcont(gspca_dev);
1390 break;
1391 }
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001392 setautogain(gspca_dev);
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001393 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001394 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001395}
1396
1397static void sd_stopN(struct gspca_dev *gspca_dev)
1398{
1399 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001400 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001401 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001402 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001403 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001404 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001405 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001406
1407 data = 0x0b;
1408 switch (sd->sensor) {
1409 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001410 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001411 data = 0x2b;
1412 break;
1413 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001414 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001415 data = 0x29;
1416 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001417 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001418 case SENSOR_OV7648:
1419 data = 0x29;
1420 break;
1421 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001422/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001423/* case SENSOR_OV7660: */
1424 break;
1425 }
1426 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001427 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1428 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1429 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1430 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001431 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001432}
1433
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001434static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001435{
1436 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001437 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001438 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001439 __u8 luma_mean = 130;
1440 __u8 luma_delta = 20;
1441
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001442 /* Thanks S., without your advice, autobright should not work :) */
1443 if (sd->ag_cnt < 0)
1444 return;
1445 if (--sd->ag_cnt >= 0)
1446 return;
1447 sd->ag_cnt = AG_CNT_START;
1448
1449 delta = atomic_read(&sd->avg_lum);
1450 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 if (delta < luma_mean - luma_delta ||
1452 delta > luma_mean + luma_delta) {
1453 switch (sd->sensor) {
1454 case SENSOR_HV7131R:
1455 expotimes = sd->exposure >> 8;
1456 expotimes += (luma_mean - delta) >> 4;
1457 if (expotimes < 0)
1458 expotimes = 0;
1459 sd->exposure = setexposure(gspca_dev,
1460 (unsigned int) (expotimes << 8));
1461 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001462 default:
1463/* case SENSOR_MO4000: */
1464/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001465/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001466 expotimes = sd->exposure;
1467 expotimes += (luma_mean - delta) >> 6;
1468 if (expotimes < 0)
1469 expotimes = 0;
1470 sd->exposure = setexposure(gspca_dev,
1471 (unsigned int) expotimes);
1472 setcolors(gspca_dev);
1473 break;
1474 }
1475 }
1476}
1477
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001478/* scan the URB packets */
1479/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001480static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1481 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001482 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001483 int len) /* iso packet length */
1484{
1485 struct sd *sd = (struct sd *) gspca_dev;
1486 int sof, avg_lum;
1487
1488 sof = len - 64;
1489 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1490
1491 /* end of frame */
1492 gspca_frame_add(gspca_dev, LAST_PACKET,
1493 frame, data, sof + 2);
1494 if (sd->ag_cnt < 0)
1495 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001496/* w1 w2 w3 */
1497/* w4 w5 w6 */
1498/* w7 w8 */
1499/* w4 */
1500 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1501/* w6 */
1502 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1503/* w2 */
1504 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1505/* w8 */
1506 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1507/* w5 */
1508 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1509 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001510 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001511 return;
1512 }
1513 if (gspca_dev->last_packet_type == LAST_PACKET) {
1514
1515 /* put the JPEG 422 header */
1516 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1517 }
1518 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1519}
1520
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001521static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1522{
1523 struct sd *sd = (struct sd *) gspca_dev;
1524
1525 sd->brightness = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001526 if (gspca_dev->streaming) {
1527 switch (sd->sensor) {
1528 case SENSOR_HV7131R:
1529 case SENSOR_MI0360:
1530 case SENSOR_MO4000:
1531 case SENSOR_OM6802:
1532 setbrightness(gspca_dev);
1533 break;
1534 default: /* OV76xx */
1535 setbrightcont(gspca_dev);
1536 break;
1537 }
1538 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001539 return 0;
1540}
1541
1542static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1543{
1544 struct sd *sd = (struct sd *) gspca_dev;
1545
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001546 *val = sd->brightness;
1547 return 0;
1548}
1549
1550static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1551{
1552 struct sd *sd = (struct sd *) gspca_dev;
1553
1554 sd->contrast = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001555 if (gspca_dev->streaming) {
1556 switch (sd->sensor) {
1557 case SENSOR_HV7131R:
1558 case SENSOR_MI0360:
1559 case SENSOR_MO4000:
1560 case SENSOR_OM6802:
1561 setcontrast(gspca_dev);
1562 break;
1563 default: /* OV76xx */
1564 setbrightcont(gspca_dev);
1565 break;
1566 }
1567 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001568 return 0;
1569}
1570
1571static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574
1575 *val = sd->contrast;
1576 return 0;
1577}
1578
1579static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1580{
1581 struct sd *sd = (struct sd *) gspca_dev;
1582
1583 sd->colors = val;
1584 if (gspca_dev->streaming)
1585 setcolors(gspca_dev);
1586 return 0;
1587}
1588
1589static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1590{
1591 struct sd *sd = (struct sd *) gspca_dev;
1592
1593 *val = sd->colors;
1594 return 0;
1595}
1596
1597static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1598{
1599 struct sd *sd = (struct sd *) gspca_dev;
1600
1601 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001602 if (gspca_dev->streaming)
1603 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001604 return 0;
1605}
1606
1607static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1608{
1609 struct sd *sd = (struct sd *) gspca_dev;
1610
1611 *val = sd->autogain;
1612 return 0;
1613}
1614
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001615static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1616{
1617 struct sd *sd = (struct sd *) gspca_dev;
1618
1619 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001620 if (gspca_dev->streaming)
1621 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001622 return 0;
1623}
1624
1625static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1626{
1627 struct sd *sd = (struct sd *) gspca_dev;
1628
1629 *val = sd->vflip;
1630 return 0;
1631}
1632
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001633static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1634{
1635 struct sd *sd = (struct sd *) gspca_dev;
1636
1637 sd->infrared = val;
1638 if (gspca_dev->streaming)
1639 setinfrared(sd);
1640 return 0;
1641}
1642
1643static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1644{
1645 struct sd *sd = (struct sd *) gspca_dev;
1646
1647 *val = sd->infrared;
1648 return 0;
1649}
1650
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001651/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001652static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001653 .name = MODULE_NAME,
1654 .ctrls = sd_ctrls,
1655 .nctrls = ARRAY_SIZE(sd_ctrls),
1656 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001657 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001658 .start = sd_start,
1659 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001660 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001661 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001662};
1663
1664/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001665#define BSI(bridge, sensor, i2c_addr) \
1666 .driver_info = (BRIDGE_ ## bridge << 16) \
1667 | (SENSOR_ ## sensor << 8) \
1668 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001669static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001670#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001671 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001672 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001673 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1674 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1675 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001676#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001677 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001678 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1679 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1680/* bw600.inf:
1681 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1682/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1683/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1684 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1685/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1686 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1687/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1688/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1689 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1690/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1691/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1692 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1693 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001694#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1695 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1696#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001697/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1698/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1699/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001700 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1701/*bw600.inf:*/
1702 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001703 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001704 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001705/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001706#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001707 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001708#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001709 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001710#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001711/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1712 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1713 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1714/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001715#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001716 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001717 {}
1718};
1719MODULE_DEVICE_TABLE(usb, device_table);
1720
1721/* -- device connect -- */
1722static int sd_probe(struct usb_interface *intf,
1723 const struct usb_device_id *id)
1724{
1725 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1726 THIS_MODULE);
1727}
1728
1729static struct usb_driver sd_driver = {
1730 .name = MODULE_NAME,
1731 .id_table = device_table,
1732 .probe = sd_probe,
1733 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001734#ifdef CONFIG_PM
1735 .suspend = gspca_suspend,
1736 .resume = gspca_resume,
1737#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001738};
1739
1740/* -- module insert / remove -- */
1741static int __init sd_mod_init(void)
1742{
1743 if (usb_register(&sd_driver) < 0)
1744 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001745 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001746 return 0;
1747}
1748static void __exit sd_mod_exit(void)
1749{
1750 usb_deregister(&sd_driver);
1751 info("deregistered");
1752}
1753
1754module_init(sd_mod_init);
1755module_exit(sd_mod_exit);