blob: b99d1e5607b3ba0162b7b55cb3a4f1787d6f56ca [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 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300255 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300256/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300257 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300258/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300259 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300260/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300261 0x0b, 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 Moine62703302008-11-11 08:42:56 -0300493
494static const __u8 ov7648_sensor_init[][8] = {
495 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
497 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
498 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
499 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
500 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
501 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
502 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
504 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
505 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
506 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
507 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
508 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
509 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
510 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
511 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
512 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
513 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
514 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
515 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
516
517 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
518/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
519/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
520 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
521/*...*/
522/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
523/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
524 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
525 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
526/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
527/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
528/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
529/*...*/
530 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
531/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
532/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
533/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
534/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
535/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
536
537 {}
538};
539
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300540static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300541 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300542/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300543 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300544 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300545 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300546 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300547 /* GAIN BLUE RED VREF */
548 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
549 /* COM 1 BAVE GEAVE AECHH */
550 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
551 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300552 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300553 /* AECH CLKRC COM7 COM8 */
554 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
555 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
556 /* HSTART HSTOP VSTRT VSTOP */
557 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
558 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
559 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
560 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300561/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
562 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300563 /* AEW AEB VPT BBIAS */
564 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
565 /* GbBIAS RSVD EXHCH EXHCL */
566 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
567 /* RBIAS ADVFL ASDVFH YAVE */
568 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
569 /* HSYST HSYEN HREF */
570 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
571 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
572 /* ADC ACOM OFON TSLB */
573 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
574 /* COM11 COM12 COM13 COM14 */
575 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
576 /* EDGE COM15 COM16 COM17 */
577 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
578 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
579 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
580 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
581 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
582 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
583 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
584 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
585 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
586 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
587 /* LCC1 LCC2 LCC3 LCC4 */
588 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300589 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300590 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300591 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300592 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
593 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
594 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
595 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
596 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
597 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
598 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
599 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
600 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300601 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300602/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300603 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300604 /* bits[3..0]reserved */
605 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
606 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
607 /* VREF vertical frame ctrl */
608 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300609 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
610 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
611 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
612 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
613/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300614/****** (some exchanges in the win trace) ******/
615 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300616 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
617 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
618 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
619/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300620/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300621/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300622 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
623 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
624 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300626 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300627};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300628
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300629static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300630 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
631 0x06, 0x08, 0x0A, 0x11,
632 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
633 0x19, 0x19, 0x17, 0x15,
634 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
635 0x21, 0x2E, 0x21, 0x23,
636 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
637 0x25, 0x29, 0x2C, 0x29,
638 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
639 0x17, 0x1B, 0x29, 0x29,
640 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
641 0x29, 0x29, 0x29, 0x29,
642 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
643 0x29, 0x29, 0x29, 0x29,
644 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
645 0x29, 0x29, 0x29, 0x29
646};
647
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300648/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300649static void reg_r(struct gspca_dev *gspca_dev,
650 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300651{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300652#ifdef GSPCA_DEBUG
653 if (len > USB_BUF_SZ) {
654 err("reg_r: buffer overflow");
655 return;
656 }
657#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300658 usb_control_msg(gspca_dev->dev,
659 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300660 0,
661 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
662 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300663 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300664 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300665 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300666}
667
Jean-Francois Moine60017612008-07-18 08:46:19 -0300668static void reg_w1(struct gspca_dev *gspca_dev,
669 __u16 value,
670 __u8 data)
671{
672 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
673 gspca_dev->usb_buf[0] = data;
674 usb_control_msg(gspca_dev->dev,
675 usb_sndctrlpipe(gspca_dev->dev, 0),
676 0x08,
677 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
678 value,
679 0,
680 gspca_dev->usb_buf, 1,
681 500);
682}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300683static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300684 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300685 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686 int len)
687{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300688 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
689 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300690#ifdef GSPCA_DEBUG
691 if (len > USB_BUF_SZ) {
692 err("reg_w: buffer overflow");
693 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300694 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300695#endif
696 memcpy(gspca_dev->usb_buf, buffer, len);
697 usb_control_msg(gspca_dev->dev,
698 usb_sndctrlpipe(gspca_dev->dev, 0),
699 0x08,
700 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
701 value, 0,
702 gspca_dev->usb_buf, len,
703 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300704}
705
Jean-Francois Moine60017612008-07-18 08:46:19 -0300706/* I2C write 1 byte */
707static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300708{
709 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300710
Jean-Francois Moine60017612008-07-18 08:46:19 -0300711 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
712 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
713 gspca_dev->usb_buf[1] = sd->i2c_base;
714 gspca_dev->usb_buf[2] = reg;
715 gspca_dev->usb_buf[3] = val;
716 gspca_dev->usb_buf[4] = 0;
717 gspca_dev->usb_buf[5] = 0;
718 gspca_dev->usb_buf[6] = 0;
719 gspca_dev->usb_buf[7] = 0x10;
720 usb_control_msg(gspca_dev->dev,
721 usb_sndctrlpipe(gspca_dev->dev, 0),
722 0x08,
723 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
724 0x08, /* value = i2c */
725 0,
726 gspca_dev->usb_buf, 8,
727 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300728}
729
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300730/* I2C write 8 bytes */
731static void i2c_w8(struct gspca_dev *gspca_dev,
732 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300734 memcpy(gspca_dev->usb_buf, buffer, 8);
735 usb_control_msg(gspca_dev->dev,
736 usb_sndctrlpipe(gspca_dev->dev, 0),
737 0x08,
738 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
739 0x08, 0, /* value, index */
740 gspca_dev->usb_buf, 8,
741 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300742 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300743}
744
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300745/* read 5 bytes in gspca_dev->usb_buf */
746static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300747{
748 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300749 __u8 mode[8];
750
Hans de Goede3647fea2008-07-15 05:36:30 -0300751 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300752 mode[1] = sd->i2c_base;
753 mode[2] = reg;
754 mode[3] = 0;
755 mode[4] = 0;
756 mode[5] = 0;
757 mode[6] = 0;
758 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300759 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300760 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300761 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300762 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300763 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300764 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300765 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300766}
767
768static int probesensor(struct gspca_dev *gspca_dev)
769{
770 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300771
Jean-Francois Moine60017612008-07-18 08:46:19 -0300772 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300773 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300774 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300775 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300776 i2c_r5(gspca_dev, 0); /* read sensor id */
777 if (gspca_dev->usb_buf[0] == 0x02
778 && gspca_dev->usb_buf[1] == 0x09
779 && gspca_dev->usb_buf[2] == 0x01
780 && gspca_dev->usb_buf[3] == 0x00
781 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300782 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
783 sd->sensor = SENSOR_HV7131R;
784 return SENSOR_HV7131R;
785 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300786 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300787 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
788 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300789 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
790 return -ENODEV;
791}
792
793static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300794 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300795{
796 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300797 const __u8 *reg9a;
798 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300799 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300800 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300802 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300803
Jean-Francois Moine60017612008-07-18 08:46:19 -0300804 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300805 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300806
807 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300808 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
809 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300810 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300811 switch (sd->bridge) {
812 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300813 reg9a = reg9a_sn9c325;
814 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300815 default:
816 reg9a = reg9a_def;
817 break;
818 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300819 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300820
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300821 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300823 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300824
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300825 switch (sd->sensor) {
826 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300827 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300828 reg_w1(gspca_dev, 0x01, 0x42);
829 reg_w1(gspca_dev, 0x17, 0x64);
830 reg_w1(gspca_dev, 0x01, 0x42);
831 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300832/*jfm: from win trace */
833 case SENSOR_OV7630:
834 reg_w1(gspca_dev, 0x01, 0x61);
835 reg_w1(gspca_dev, 0x17, 0xe2);
836 reg_w1(gspca_dev, 0x01, 0x60);
837 reg_w1(gspca_dev, 0x01, 0x40);
838 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300839 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -0300840 reg_w1(gspca_dev, 0x01, 0x63);
841 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300842 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300843 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300844/*jfm: from win trace */
845 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -0300846 if (sd->bridge == BRIDGE_SN9C120) {
847 reg_w1(gspca_dev, 0x01, 0x61);
848 reg_w1(gspca_dev, 0x17, 0x20);
849 reg_w1(gspca_dev, 0x01, 0x60);
850 reg_w1(gspca_dev, 0x01, 0x40);
851 break;
852 }
853 /* fall thru */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300854 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300855 reg_w1(gspca_dev, 0x01, 0x43);
856 reg_w1(gspca_dev, 0x17, 0x61);
857 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300858 if (sd->sensor == SENSOR_HV7131R) {
859 if (probesensor(gspca_dev) < 0)
860 return -ENODEV;
861 }
862 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863 }
864 return 0;
865}
866
867static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
868{
869 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300870 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300871 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
872
873 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300874 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300875 i++;
876 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300877 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878}
879
880static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
881{
882 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883
884 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300885 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886 i++;
887 }
888}
889
890static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
891{
892 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300893
894 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300895 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300896 i++;
897 }
898}
899
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300900static void om6802_InitSensor(struct gspca_dev *gspca_dev)
901{
902 int i = 0;
903
904 while (om6802_sensor_init[i][0]) {
905 i2c_w8(gspca_dev, om6802_sensor_init[i]);
906 i++;
907 }
908}
909
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300910static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
911{
912 int i = 0;
913
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300914 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
915 i++;
916 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300917 i++;
918 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300919 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
920 i++;
921 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
922 i++;
923 msleep(20);
924 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
925 i++;
926/*jfm:win i2c_r from 00 to 80*/
927
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300928 while (ov7630_sensor_init[i][0]) {
929 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
930 i++;
931 }
932}
933
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300934static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
935{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936 int i = 0;
937
Jean-Francois Moine62703302008-11-11 08:42:56 -0300938 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
939 i++;
940/* win: dble reset */
941 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
942 i++;
943 msleep(20);
944/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300945 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300946 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300947 i++;
948 }
949}
950
951static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
952{
953 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300954
Jean-Francois Moine60017612008-07-18 08:46:19 -0300955 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
956 i++;
957 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300958 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300959 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300960 i++;
961 }
962}
963
964/* this function is called at probe time */
965static int sd_config(struct gspca_dev *gspca_dev,
966 const struct usb_device_id *id)
967{
968 struct sd *sd = (struct sd *) gspca_dev;
969 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300970
971 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300972 cam->epaddr = 0x01;
973 cam->cam_mode = vga_mode;
974 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300975
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300976 sd->bridge = id->driver_info >> 16;
977 sd->sensor = id->driver_info >> 8;
978 sd->i2c_base = id->driver_info;
979
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300980 sd->qindex = 4; /* set the quantization table */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300981 sd->brightness = BRIGHTNESS_DEF;
982 sd->contrast = CONTRAST_DEF;
983 sd->colors = COLOR_DEF;
984 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -0300985 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300986 sd->vflip = VFLIP_DEF;
987 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -0300988
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300989 switch (sd->sensor) {
990 case SENSOR_OV7630:
991 case SENSOR_OV7648:
992 case SENSOR_OV7660:
993 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
994 break;
995 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300996 if (sd->sensor != SENSOR_OV7630)
997 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300998 if (sd->sensor != SENSOR_MI0360)
999 gspca_dev->ctrl_dis |= (1 << INFRARED_IDX);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001000 return 0;
1001}
1002
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001003/* this function is called at probe and resume time */
1004static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001005{
1006 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001007/* const __u8 *sn9c1xx; */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001008 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -03001009 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001010
Hans de Goede3647fea2008-07-15 05:36:30 -03001011 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001012 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001013 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001014 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1015 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001016 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001017 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001018 switch (sd->bridge) {
1019 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001020 if (regF1 != 0x11)
1021 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001022 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001023 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001024 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001025 if (regF1 != 0x11)
1026 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001027 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001028 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001029 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001030 if (regF1 != 0x12)
1031 return -ENODEV;
1032 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001033 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001034 break;
1035 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001036/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001037/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001038 if (regF1 != 0x12)
1039 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001040 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001041 break;
1042 }
1043
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001044 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001045
1046 return 0;
1047}
1048
1049static unsigned int setexposure(struct gspca_dev *gspca_dev,
1050 unsigned int expo)
1051{
1052 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001053 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001054 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001055 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001056 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001057 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001058 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1059
1060 switch (sd->sensor) {
1061 case SENSOR_HV7131R: {
1062 __u8 Expodoit[] =
1063 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1064
1065 Expodoit[3] = expo >> 16;
1066 Expodoit[4] = expo >> 8;
1067 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001068 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001069 break;
1070 }
1071 case SENSOR_MI0360: {
1072 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1073 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1074
1075 if (expo > 0x0635)
1076 expo = 0x0635;
1077 else if (expo < 0x0001)
1078 expo = 0x0001;
1079 expoMi[3] = expo >> 8;
1080 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001081 i2c_w8(gspca_dev, expoMi);
1082 i2c_w8(gspca_dev, doit);
1083 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001084 break;
1085 }
1086 case SENSOR_MO4000: {
1087 __u8 expoMof[] =
1088 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1089 __u8 expoMo10[] =
1090 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1091
1092 if (expo > 0x1fff)
1093 expo = 0x1fff;
1094 else if (expo < 0x0001)
1095 expo = 0x0001;
1096 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001097 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001098 expoMo10[3] = ((expo & 0x1c00) >> 10)
1099 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001100 i2c_w8(gspca_dev, expoMo10);
1101 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001102 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001103 ((expoMo10[3] & 0x07) << 10)
1104 | (expoMof[3] << 2)
1105 | ((expoMo10[3] & 0x30) >> 4));
1106 break;
1107 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001108 case SENSOR_OM6802: {
1109 __u8 gainOm[] =
1110 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1111
1112 if (expo > 0x03ff)
1113 expo = 0x03ff;
1114 if (expo < 0x0001)
1115 expo = 0x0001;
1116 gainOm[3] = expo >> 2;
1117 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001118 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001119 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1120 break;
1121 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001122 }
1123 return expo;
1124}
1125
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001126/* this function is used for sensors o76xx only */
1127static void setbrightcont(struct gspca_dev *gspca_dev)
1128{
1129 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001130 int val;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001131 __u8 reg84_full[0x15];
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001132
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001133 memcpy(reg84_full, reg84, sizeof reg84_full);
1134 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1135 reg84_full[0] = (val + 1) / 2; /* red */
1136 reg84_full[2] = val; /* green */
1137 reg84_full[4] = (val + 1) / 5; /* blue */
1138 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001139 / BRIGHTNESS_MAX;
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001140 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001141 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1142}
1143
1144/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001145static void setbrightness(struct gspca_dev *gspca_dev)
1146{
1147 struct sd *sd = (struct sd *) gspca_dev;
1148 unsigned int expo;
1149 __u8 k2;
1150
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001151 k2 = sd->brightness >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001152 switch (sd->sensor) {
1153 case SENSOR_HV7131R:
1154 expo = sd->brightness << 4;
1155 if (expo > 0x002dc6c0)
1156 expo = 0x002dc6c0;
1157 else if (expo < 0x02a0)
1158 expo = 0x02a0;
1159 sd->exposure = setexposure(gspca_dev, expo);
1160 break;
1161 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001162 case SENSOR_MO4000:
1163 expo = sd->brightness >> 4;
1164 sd->exposure = setexposure(gspca_dev, expo);
1165 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001166 case SENSOR_OM6802:
1167 expo = sd->brightness >> 6;
1168 sd->exposure = setexposure(gspca_dev, expo);
1169 k2 = sd->brightness >> 11;
1170 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001171 }
1172
Jean-Francois Moine60017612008-07-18 08:46:19 -03001173 reg_w1(gspca_dev, 0x96, k2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001174}
1175
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001176/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001177static void setcontrast(struct gspca_dev *gspca_dev)
1178{
1179 struct sd *sd = (struct sd *) gspca_dev;
1180 __u8 k2;
1181 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1182
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001183 k2 = sd->contrast;
1184 contrast[2] = k2;
1185 contrast[0] = (k2 + 1) >> 1;
1186 contrast[4] = (k2 + 1) / 5;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001187 reg_w(gspca_dev, 0x84, contrast, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001188}
1189
1190static void setcolors(struct gspca_dev *gspca_dev)
1191{
1192 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001193 __u8 blue, red;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001194
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001195 if (sd->colors >= 32) {
1196 red = 32 + (sd->colors - 32) / 2;
1197 blue = 64 - sd->colors;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001198 } else {
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001199 red = sd->colors;
1200 blue = 32 + (32 - sd->colors) / 2;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001201 }
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001202 reg_w1(gspca_dev, 0x05, red);
1203/* reg_w1(gspca_dev, 0x07, 32); */
1204 reg_w1(gspca_dev, 0x06, blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001205}
1206
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001207static void setautogain(struct gspca_dev *gspca_dev)
1208{
1209 struct sd *sd = (struct sd *) gspca_dev;
1210
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001211 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1212 return;
1213 if (sd->autogain)
1214 sd->ag_cnt = AG_CNT_START;
1215 else
1216 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001217}
1218
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001219static void setvflip(struct sd *sd)
1220{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001221 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1222 sd->vflip ? 0x82 : 0x02);
1223}
1224
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001225static void setinfrared(struct sd *sd)
1226{
1227/*fixme: different sequence for StarCam Clip and StarCam 370i */
1228/* Clip */
1229 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1230 sd->infrared ? 0x66 : 0x64);
1231}
1232
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001233/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001234static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001235{
1236 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001237 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001238 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001239 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001240 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001241 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1242 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001243 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001244 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001245 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001246
1247 sn9c1xx = sn_tb[(int) sd->sensor];
1248 configure_gpio(gspca_dev, sn9c1xx);
1249
Jean-Francois Moine60017612008-07-18 08:46:19 -03001250 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1251 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1252 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1253 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1254 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1255 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1256 reg_w1(gspca_dev, 0xd3, 0x50);
1257 reg_w1(gspca_dev, 0xc6, 0x00);
1258 reg_w1(gspca_dev, 0xc7, 0x00);
1259 reg_w1(gspca_dev, 0xc8, 0x50);
1260 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001261 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001262 switch (sd->sensor) {
1263 case SENSOR_OV7630:
1264 reg17 = 0xe2;
1265 break;
1266 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001267 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001268 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001269/*jfm: from win trace */
1270 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001271 if (sd->bridge == BRIDGE_SN9C120) {
1272 reg17 = 0xa0;
1273 break;
1274 }
1275 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001276 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001277 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001278 break;
1279 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001280 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001281/* set reg1 was here */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001282 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1283 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1284 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1285 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001286 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1287 for (i = 0; i < 8; i++)
1288 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001289 switch (sd->sensor) {
Jean-Francois Moine62703302008-11-11 08:42:56 -03001290 case SENSOR_OV7648:
1291 reg_w1(gspca_dev, 0x9a, 0x0a);
1292 reg_w1(gspca_dev, 0x99, 0x60);
1293 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001294 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001295 if (sd->bridge == BRIDGE_SN9C120) {
1296 reg_w1(gspca_dev, 0x9a, 0x05);
1297 break;
1298 }
1299 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001300 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001301 reg_w1(gspca_dev, 0x9a, 0x08);
1302 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001303 break;
1304 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001305
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001306 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001307 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001308 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001309 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001310 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1311 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001312 switch (sd->sensor) {
1313 case SENSOR_HV7131R:
1314 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001315 break;
1316 case SENSOR_MI0360:
1317 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001318 break;
1319 case SENSOR_MO4000:
1320 mo4000_InitSensor(gspca_dev);
1321 if (mode) {
1322/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1323 reg1 = 0x06; /* clk 24Mz */
1324 } else {
1325 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001326/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001327 }
1328 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001329 case SENSOR_OM6802:
1330 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001331 reg17 = 0x64; /* 640 MCKSIZE */
1332 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001333 case SENSOR_OV7630:
1334 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001335 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001336 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001337 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001338 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001339 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001340 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001341 reg17 = 0x21;
1342/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001343/* if (mode)
1344 ; * 320x2...
1345 else
1346 ; * 640x... */
1347 break;
1348 default:
1349/* case SENSOR_OV7660: */
1350 ov7660_InitSensor(gspca_dev);
1351 if (mode) {
1352/* reg17 = 0x21; * 320 */
1353/* reg1 = 0x44; */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001354/* reg1 = 0x46; (done) */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001355 } else { /* 640 */
1356 if (sd->bridge == BRIDGE_SN9C120) {
1357 reg17 = 0xa2;
1358 reg1 = 0x44; /* 48 Mhz, video trf eneble */
1359 } else {
1360 reg17 = 0x22;
1361 reg1 = 0x06; /* 24 Mhz, video trf eneble
1362 * inverse power down */
1363 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001364 }
1365 break;
1366 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001367 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001368 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001369 switch (sd->sensor) {
1370 case SENSOR_OV7630:
1371 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001372 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001373 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001374 break;
1375 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001376 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001377 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1378 break;
1379 }
1380
1381 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001382 reg18 = sn9c1xx[0x18] | (mode << 4);
1383 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001384
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001385 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1386 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001387
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001388 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001389
Jean-Francois Moine60017612008-07-18 08:46:19 -03001390 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001391 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001392 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001393 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001394 setinfrared(sd);
1395 /* fall thru */
1396 case SENSOR_HV7131R:
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001397 case SENSOR_MO4000:
1398 case SENSOR_OM6802:
1399 setbrightness(gspca_dev);
1400 setcontrast(gspca_dev);
1401 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001402 case SENSOR_OV7630:
1403 setvflip(sd);
1404 /* fall thru */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001405 default: /* OV76xx */
1406 setbrightcont(gspca_dev);
1407 break;
1408 }
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001409 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001410 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001411}
1412
1413static void sd_stopN(struct gspca_dev *gspca_dev)
1414{
1415 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001416 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001417 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001418 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001419 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine62703302008-11-11 08:42:56 -03001420 static const __u8 stopov7648[] =
1421 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001422 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001423 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001424
1425 data = 0x0b;
1426 switch (sd->sensor) {
1427 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001428 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001429 data = 0x2b;
1430 break;
1431 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001432 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001433 data = 0x29;
1434 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001435 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001436 i2c_w8(gspca_dev, stopov7648);
1437 /* fall thru */
1438 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001439 data = 0x29;
1440 break;
1441 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001442/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001443/* case SENSOR_OV7660: */
1444 break;
1445 }
1446 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001447 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1448 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1449 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1450 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001451 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001452}
1453
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001454static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001455{
1456 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001457 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001458 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001459 __u8 luma_mean = 130;
1460 __u8 luma_delta = 20;
1461
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001462 /* Thanks S., without your advice, autobright should not work :) */
1463 if (sd->ag_cnt < 0)
1464 return;
1465 if (--sd->ag_cnt >= 0)
1466 return;
1467 sd->ag_cnt = AG_CNT_START;
1468
1469 delta = atomic_read(&sd->avg_lum);
1470 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001471 if (delta < luma_mean - luma_delta ||
1472 delta > luma_mean + luma_delta) {
1473 switch (sd->sensor) {
1474 case SENSOR_HV7131R:
1475 expotimes = sd->exposure >> 8;
1476 expotimes += (luma_mean - delta) >> 4;
1477 if (expotimes < 0)
1478 expotimes = 0;
1479 sd->exposure = setexposure(gspca_dev,
1480 (unsigned int) (expotimes << 8));
1481 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001482 default:
1483/* case SENSOR_MO4000: */
1484/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001485/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001486 expotimes = sd->exposure;
1487 expotimes += (luma_mean - delta) >> 6;
1488 if (expotimes < 0)
1489 expotimes = 0;
1490 sd->exposure = setexposure(gspca_dev,
1491 (unsigned int) expotimes);
1492 setcolors(gspca_dev);
1493 break;
1494 }
1495 }
1496}
1497
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001498/* scan the URB packets */
1499/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001500static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1501 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001502 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001503 int len) /* iso packet length */
1504{
1505 struct sd *sd = (struct sd *) gspca_dev;
1506 int sof, avg_lum;
1507
1508 sof = len - 64;
1509 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1510
1511 /* end of frame */
1512 gspca_frame_add(gspca_dev, LAST_PACKET,
1513 frame, data, sof + 2);
1514 if (sd->ag_cnt < 0)
1515 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001516/* w1 w2 w3 */
1517/* w4 w5 w6 */
1518/* w7 w8 */
1519/* w4 */
1520 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1521/* w6 */
1522 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1523/* w2 */
1524 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1525/* w8 */
1526 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1527/* w5 */
1528 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1529 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001530 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001531 return;
1532 }
1533 if (gspca_dev->last_packet_type == LAST_PACKET) {
1534
1535 /* put the JPEG 422 header */
1536 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1537 }
1538 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1539}
1540
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001541static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1542{
1543 struct sd *sd = (struct sd *) gspca_dev;
1544
1545 sd->brightness = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001546 if (gspca_dev->streaming) {
1547 switch (sd->sensor) {
1548 case SENSOR_HV7131R:
1549 case SENSOR_MI0360:
1550 case SENSOR_MO4000:
1551 case SENSOR_OM6802:
1552 setbrightness(gspca_dev);
1553 break;
1554 default: /* OV76xx */
1555 setbrightcont(gspca_dev);
1556 break;
1557 }
1558 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001559 return 0;
1560}
1561
1562static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1563{
1564 struct sd *sd = (struct sd *) gspca_dev;
1565
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001566 *val = sd->brightness;
1567 return 0;
1568}
1569
1570static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1571{
1572 struct sd *sd = (struct sd *) gspca_dev;
1573
1574 sd->contrast = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001575 if (gspca_dev->streaming) {
1576 switch (sd->sensor) {
1577 case SENSOR_HV7131R:
1578 case SENSOR_MI0360:
1579 case SENSOR_MO4000:
1580 case SENSOR_OM6802:
1581 setcontrast(gspca_dev);
1582 break;
1583 default: /* OV76xx */
1584 setbrightcont(gspca_dev);
1585 break;
1586 }
1587 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001588 return 0;
1589}
1590
1591static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1592{
1593 struct sd *sd = (struct sd *) gspca_dev;
1594
1595 *val = sd->contrast;
1596 return 0;
1597}
1598
1599static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1600{
1601 struct sd *sd = (struct sd *) gspca_dev;
1602
1603 sd->colors = val;
1604 if (gspca_dev->streaming)
1605 setcolors(gspca_dev);
1606 return 0;
1607}
1608
1609static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1610{
1611 struct sd *sd = (struct sd *) gspca_dev;
1612
1613 *val = sd->colors;
1614 return 0;
1615}
1616
1617static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1618{
1619 struct sd *sd = (struct sd *) gspca_dev;
1620
1621 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001622 if (gspca_dev->streaming)
1623 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001624 return 0;
1625}
1626
1627static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1628{
1629 struct sd *sd = (struct sd *) gspca_dev;
1630
1631 *val = sd->autogain;
1632 return 0;
1633}
1634
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001635static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1636{
1637 struct sd *sd = (struct sd *) gspca_dev;
1638
1639 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001640 if (gspca_dev->streaming)
1641 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001642 return 0;
1643}
1644
1645static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1646{
1647 struct sd *sd = (struct sd *) gspca_dev;
1648
1649 *val = sd->vflip;
1650 return 0;
1651}
1652
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001653static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1654{
1655 struct sd *sd = (struct sd *) gspca_dev;
1656
1657 sd->infrared = val;
1658 if (gspca_dev->streaming)
1659 setinfrared(sd);
1660 return 0;
1661}
1662
1663static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1664{
1665 struct sd *sd = (struct sd *) gspca_dev;
1666
1667 *val = sd->infrared;
1668 return 0;
1669}
1670
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001671/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001672static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001673 .name = MODULE_NAME,
1674 .ctrls = sd_ctrls,
1675 .nctrls = ARRAY_SIZE(sd_ctrls),
1676 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001677 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001678 .start = sd_start,
1679 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001680 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001681 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001682};
1683
1684/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001685#define BSI(bridge, sensor, i2c_addr) \
1686 .driver_info = (BRIDGE_ ## bridge << 16) \
1687 | (SENSOR_ ## sensor << 8) \
1688 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001689static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001690#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001691 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001692 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001693 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1694 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1695 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001696#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001697 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001698 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1699 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1700/* bw600.inf:
1701 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1702/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1703/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1704 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1705/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1706 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1707/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1708/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1709 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1710/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1711/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1712 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1713 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001714#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1715 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1716#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001717/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1718/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1719/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001720 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1721/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03001722 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001723 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001724 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001725/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001726#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001727 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001728#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001729 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03001730 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001731#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001732 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1733 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1734/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001735#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001736 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001737 {}
1738};
1739MODULE_DEVICE_TABLE(usb, device_table);
1740
1741/* -- device connect -- */
1742static int sd_probe(struct usb_interface *intf,
1743 const struct usb_device_id *id)
1744{
1745 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1746 THIS_MODULE);
1747}
1748
1749static struct usb_driver sd_driver = {
1750 .name = MODULE_NAME,
1751 .id_table = device_table,
1752 .probe = sd_probe,
1753 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001754#ifdef CONFIG_PM
1755 .suspend = gspca_suspend,
1756 .resume = gspca_resume,
1757#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001758};
1759
1760/* -- module insert / remove -- */
1761static int __init sd_mod_init(void)
1762{
1763 if (usb_register(&sd_driver) < 0)
1764 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001765 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001766 return 0;
1767}
1768static void __exit sd_mod_exit(void)
1769{
1770 usb_deregister(&sd_driver);
1771 info("deregistered");
1772}
1773
1774module_init(sd_mod_init);
1775module_exit(sd_mod_exit);