blob: 53cb82d9e7c6a28909636595968ae335c9809698 [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 Moine6a7eba22008-06-30 15:50:11 -030027MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29MODULE_LICENSE("GPL");
30
31/* specific webcam descriptor */
32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */
34
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030035 atomic_t avg_lum;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030036 unsigned int exposure;
37
38 unsigned short brightness;
39 unsigned char contrast;
40 unsigned char colors;
41 unsigned char autogain;
Jean-Francois Moine6c862742008-09-08 04:57:26 -030042 __u8 vflip; /* ov7630 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030043
44 signed char ag_cnt;
45#define AG_CNT_START 13
46
47 char qindex;
Hans de Goede3647fea2008-07-15 05:36:30 -030048 unsigned char bridge;
49#define BRIDGE_SN9C102P 0
50#define BRIDGE_SN9C105 1
51#define BRIDGE_SN9C110 2
52#define BRIDGE_SN9C120 3
53#define BRIDGE_SN9C325 4
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030054 char sensor; /* Type of image sensor chip */
55#define SENSOR_HV7131R 0
56#define SENSOR_MI0360 1
57#define SENSOR_MO4000 2
Jean-Francois Moined2d16e92008-09-03 16:47:23 -030058#define SENSOR_OM6802 3
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -030059#define SENSOR_OV7630 4
60#define SENSOR_OV7648 5
61#define SENSOR_OV7660 6
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030062 unsigned char i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030063};
64
65/* V4L2 controls supported by the driver */
66static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
67static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
68static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
69static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
70static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
71static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
72static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030074static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030076
77static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030078 {
79 {
80 .id = V4L2_CID_BRIGHTNESS,
81 .type = V4L2_CTRL_TYPE_INTEGER,
82 .name = "Brightness",
83 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -030084#define BRIGHTNESS_MAX 0xffff
85 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030086 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -030087#define BRIGHTNESS_DEF 0x7fff
88 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030089 },
90 .set = sd_setbrightness,
91 .get = sd_getbrightness,
92 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030093 {
94 {
95 .id = V4L2_CID_CONTRAST,
96 .type = V4L2_CTRL_TYPE_INTEGER,
97 .name = "Contrast",
98 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -030099#define CONTRAST_MAX 127
100 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300101 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300102#define CONTRAST_DEF 63
103 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300104 },
105 .set = sd_setcontrast,
106 .get = sd_getcontrast,
107 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300108 {
109 {
110 .id = V4L2_CID_SATURATION,
111 .type = V4L2_CTRL_TYPE_INTEGER,
112 .name = "Color",
113 .minimum = 0,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300114 .maximum = 64,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300115 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300116#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300117 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118 },
119 .set = sd_setcolors,
120 .get = sd_getcolors,
121 },
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300122#define AUTOGAIN_IDX 3
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300123 {
124 {
125 .id = V4L2_CID_AUTOGAIN,
126 .type = V4L2_CTRL_TYPE_BOOLEAN,
127 .name = "Auto Gain",
128 .minimum = 0,
129 .maximum = 1,
130 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300131#define AUTOGAIN_DEF 1
132 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300133 },
134 .set = sd_setautogain,
135 .get = sd_getautogain,
136 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300137/* ov7630 only */
138#define VFLIP_IDX 4
139 {
140 {
141 .id = V4L2_CID_VFLIP,
142 .type = V4L2_CTRL_TYPE_BOOLEAN,
143 .name = "Vflip",
144 .minimum = 0,
145 .maximum = 1,
146 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300147#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300148 .default_value = VFLIP_DEF,
149 },
150 .set = sd_setvflip,
151 .get = sd_getvflip,
152 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300153};
154
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300155static struct v4l2_pix_format vga_mode[] = {
156 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
157 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300158 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300159 .colorspace = V4L2_COLORSPACE_JPEG,
160 .priv = 2},
161 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
162 .bytesperline = 320,
163 .sizeimage = 320 * 240 * 3 / 8 + 590,
164 .colorspace = V4L2_COLORSPACE_JPEG,
165 .priv = 1},
166 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
167 .bytesperline = 640,
168 .sizeimage = 640 * 480 * 3 / 8 + 590,
169 .colorspace = V4L2_COLORSPACE_JPEG,
170 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300171};
172
173/*Data from sn9c102p+hv71331r */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300174static const __u8 sn_hv7131[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300175/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
176 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
177/* reg8 reg9 rega regb regc regd rege regf */
178 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
179/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
180 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
181/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
182 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300183};
184
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300185static const __u8 sn_mi0360[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300186/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
187 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
188/* reg8 reg9 rega regb regc regd rege regf */
189 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
190/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
191 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
192/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
193 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300194};
195
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300196static const __u8 sn_mo4000[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300197/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
198 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
199/* reg8 reg9 rega regb regc regd rege regf */
200 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
201/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
202 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
203/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
204 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300205};
206
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300207static const __u8 sn_om6802[] = {
208/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
209 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
210/* reg8 reg9 rega regb regc regd rege regf */
211 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
212/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
213 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
214/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
215 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
216 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
217 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
218 0xf7
219};
220
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300221static const __u8 sn_ov7630[] = {
222/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
223 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
224/* reg8 reg9 rega regb regc regd rege regf */
225 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
226/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
227 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
228/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
229 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
230};
231
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300232static const __u8 sn_ov7648[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300233/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
234 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
235/* reg8 reg9 rega regb regc regd rege regf */
236 0xa1, 0x6e, 0x18, 0x65, 0x00, 0x00, 0x00, 0x10,
237/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
238 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x82,
239/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
240 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300241};
242
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300243static const __u8 sn_ov7660[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300244/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
245 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
246/* reg8 reg9 rega regb regc regd rege regf */
247 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
248/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
249 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
250/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
251 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300252};
253
254/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300255static const __u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300256 sn_hv7131,
257 sn_mi0360,
258 sn_mo4000,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300259 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300260 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300261 sn_ov7648,
262 sn_ov7660
263};
264
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300265static const __u8 gamma_def[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300266 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
267 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
268};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300269
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300270/* color matrix and offsets */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300271static const __u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300272 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
273 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
274 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
275 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300276};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300277static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300278 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
279 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
280 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
281 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
282 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
283 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
284 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
285
286 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
287 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
288 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
289 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
290 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
291 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
292 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
293 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
294
295 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
296 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
297 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
298 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
299 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
300
301 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
302 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
304 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
305 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300306 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300307};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300308static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300309 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
310 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
311 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
312 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
313 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
314 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
315 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
316 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
317 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
318 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
319 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
321 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
322 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
323 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
325 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
326 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
327 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
328 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
329 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
330 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
331 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
332 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
334 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
335 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
336 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
337 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
338 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
339 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
340 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
341 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
342
343 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
344 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
345 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
346 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
347 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
348
349 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
350 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
351 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
352 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
353
354 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
355 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
356/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
357/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
358 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
359 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300360 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300361};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300362static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300363 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
364 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
365 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
366 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
367 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
368 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
369 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
370 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
371 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
373 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
374 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
375 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
376 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
377 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
379 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
380 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
381 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
382 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300383 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300385static __u8 om6802_sensor_init[][8] = {
386 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
387 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
388 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
389 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
390/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
391 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
392 /* white balance & auto-exposure */
393/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
394 * set color mode */
395/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
396 * max AGC value in AE */
397/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
398 * preset AGC */
399/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
400 * preset brightness */
401/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
402 * preset contrast */
403/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
404 * preset gamma */
405 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
406 /* luminance mode (0x4f = AE) */
407 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
408 /* preset shutter */
409/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
410 * auto frame rate */
411/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
412
413/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
414/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
415/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
416/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
417 {}
418};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300419static const __u8 ov7630_sensor_init[][8] = {
420 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
421 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
422/* win: delay 20ms */
423 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
425/* win: delay 20ms */
426 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300427/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300428 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
429 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
430 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
431 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
432 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
433 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
434 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
435 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
436 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
437 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
438 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
439 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
443 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
444 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
445 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
447 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
449 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
450 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
451 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
452 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
453 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
454/* */
455 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
456 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
457/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300458/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
459 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300460 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
461 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
462 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300463/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300464 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
465 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
466 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300467/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300468 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300469/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300470 {}
471};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300472static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300473 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300474/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300475 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300476 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300477 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300478 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300479 /* GAIN BLUE RED VREF */
480 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
481 /* COM 1 BAVE GEAVE AECHH */
482 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
483 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300484 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300485 /* AECH CLKRC COM7 COM8 */
486 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
487 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
488 /* HSTART HSTOP VSTRT VSTOP */
489 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
490 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
491 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
492 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300493/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
494 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300495 /* AEW AEB VPT BBIAS */
496 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
497 /* GbBIAS RSVD EXHCH EXHCL */
498 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
499 /* RBIAS ADVFL ASDVFH YAVE */
500 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
501 /* HSYST HSYEN HREF */
502 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
503 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
504 /* ADC ACOM OFON TSLB */
505 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
506 /* COM11 COM12 COM13 COM14 */
507 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
508 /* EDGE COM15 COM16 COM17 */
509 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
510 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
511 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
512 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
513 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
514 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
515 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
516 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
517 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
518 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
519 /* LCC1 LCC2 LCC3 LCC4 */
520 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300521 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300522 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300523 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300524 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
525 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
526 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
527 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
528 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
529 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
530 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
531 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
532 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300533 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300534/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300535 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300536 /* bits[3..0]reserved */
537 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
538 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
539 /* VREF vertical frame ctrl */
540 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300541 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
542 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
543 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
544 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
545/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300546/****** (some exchanges in the win trace) ******/
547 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300548 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
549 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
550 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
551/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300552/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300553/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300554 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
555 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
556 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
557 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300558 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300559};
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300560/* reg 0x04 reg 0x07 reg 0x10 */
561/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300562
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300563static const __u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
566 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
567 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
568 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
569 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
571 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
572 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
573 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
574 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
575 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
576 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
578 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
579 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
580 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
581 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
582 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
583 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
584 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
585 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
586 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
587 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
588 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
589 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
590 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
591 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
593 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
594 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
595 * This is currently setting a
596 * blue tint, and some things more , i leave it here for future test if
597 * somene is having problems with color on this sensor
598 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
601 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
602 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
603 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
604 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
609 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
610 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
611 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
612 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
613 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
614 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
615/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300616 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300617};
618
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300619static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300620 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
621 0x06, 0x08, 0x0A, 0x11,
622 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
623 0x19, 0x19, 0x17, 0x15,
624 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
625 0x21, 0x2E, 0x21, 0x23,
626 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
627 0x25, 0x29, 0x2C, 0x29,
628 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
629 0x17, 0x1B, 0x29, 0x29,
630 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
631 0x29, 0x29, 0x29, 0x29,
632 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
633 0x29, 0x29, 0x29, 0x29,
634 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
635 0x29, 0x29, 0x29, 0x29
636};
637
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300638/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300639static void reg_r(struct gspca_dev *gspca_dev,
640 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300641{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300642#ifdef GSPCA_DEBUG
643 if (len > USB_BUF_SZ) {
644 err("reg_r: buffer overflow");
645 return;
646 }
647#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300648 usb_control_msg(gspca_dev->dev,
649 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300650 0,
651 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
652 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300653 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300655 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300656}
657
Jean-Francois Moine60017612008-07-18 08:46:19 -0300658static void reg_w1(struct gspca_dev *gspca_dev,
659 __u16 value,
660 __u8 data)
661{
662 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
663 gspca_dev->usb_buf[0] = data;
664 usb_control_msg(gspca_dev->dev,
665 usb_sndctrlpipe(gspca_dev->dev, 0),
666 0x08,
667 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
668 value,
669 0,
670 gspca_dev->usb_buf, 1,
671 500);
672}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300673static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300674 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300675 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300676 int len)
677{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300678 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
679 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300680#ifdef GSPCA_DEBUG
681 if (len > USB_BUF_SZ) {
682 err("reg_w: buffer overflow");
683 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300684 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300685#endif
686 memcpy(gspca_dev->usb_buf, buffer, len);
687 usb_control_msg(gspca_dev->dev,
688 usb_sndctrlpipe(gspca_dev->dev, 0),
689 0x08,
690 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
691 value, 0,
692 gspca_dev->usb_buf, len,
693 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300694}
695
Jean-Francois Moine60017612008-07-18 08:46:19 -0300696/* I2C write 1 byte */
697static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300698{
699 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300700
Jean-Francois Moine60017612008-07-18 08:46:19 -0300701 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
702 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
703 gspca_dev->usb_buf[1] = sd->i2c_base;
704 gspca_dev->usb_buf[2] = reg;
705 gspca_dev->usb_buf[3] = val;
706 gspca_dev->usb_buf[4] = 0;
707 gspca_dev->usb_buf[5] = 0;
708 gspca_dev->usb_buf[6] = 0;
709 gspca_dev->usb_buf[7] = 0x10;
710 usb_control_msg(gspca_dev->dev,
711 usb_sndctrlpipe(gspca_dev->dev, 0),
712 0x08,
713 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
714 0x08, /* value = i2c */
715 0,
716 gspca_dev->usb_buf, 8,
717 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300718}
719
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300720/* I2C write 8 bytes */
721static void i2c_w8(struct gspca_dev *gspca_dev,
722 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300723{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300724 memcpy(gspca_dev->usb_buf, buffer, 8);
725 usb_control_msg(gspca_dev->dev,
726 usb_sndctrlpipe(gspca_dev->dev, 0),
727 0x08,
728 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
729 0x08, 0, /* value, index */
730 gspca_dev->usb_buf, 8,
731 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300732 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733}
734
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300735/* read 5 bytes in gspca_dev->usb_buf */
736static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300737{
738 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300739 __u8 mode[8];
740
Hans de Goede3647fea2008-07-15 05:36:30 -0300741 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742 mode[1] = sd->i2c_base;
743 mode[2] = reg;
744 mode[3] = 0;
745 mode[4] = 0;
746 mode[5] = 0;
747 mode[6] = 0;
748 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300749 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300750 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300751 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300752 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300753 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300754 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300755 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300756}
757
758static int probesensor(struct gspca_dev *gspca_dev)
759{
760 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300761
Jean-Francois Moine60017612008-07-18 08:46:19 -0300762 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300763 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300764 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300765 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300766 i2c_r5(gspca_dev, 0); /* read sensor id */
767 if (gspca_dev->usb_buf[0] == 0x02
768 && gspca_dev->usb_buf[1] == 0x09
769 && gspca_dev->usb_buf[2] == 0x01
770 && gspca_dev->usb_buf[3] == 0x00
771 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300772 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
773 sd->sensor = SENSOR_HV7131R;
774 return SENSOR_HV7131R;
775 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300776 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300777 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
778 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300779 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
780 return -ENODEV;
781}
782
783static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300784 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300785{
786 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300787 const __u8 *reg9a;
788 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300789 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300790 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300791 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300792 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300793
Jean-Francois Moine60017612008-07-18 08:46:19 -0300794 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300795 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300796
797 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300798 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
799 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300800 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300801 switch (sd->bridge) {
802 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300803 reg9a = reg9a_sn9c325;
804 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805 default:
806 reg9a = reg9a_def;
807 break;
808 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300809 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300810
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300811 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300812
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300813 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300815 switch (sd->sensor) {
816 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300817 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300818 reg_w1(gspca_dev, 0x01, 0x42);
819 reg_w1(gspca_dev, 0x17, 0x64);
820 reg_w1(gspca_dev, 0x01, 0x42);
821 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300822/*jfm: from win trace */
823 case SENSOR_OV7630:
824 reg_w1(gspca_dev, 0x01, 0x61);
825 reg_w1(gspca_dev, 0x17, 0xe2);
826 reg_w1(gspca_dev, 0x01, 0x60);
827 reg_w1(gspca_dev, 0x01, 0x40);
828 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300829 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300830 reg_w1(gspca_dev, 0x01, 0x43);
831 reg_w1(gspca_dev, 0x17, 0xae);
832 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300833 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300834/*jfm: from win trace */
835 case SENSOR_OV7660:
836 reg_w1(gspca_dev, 0x01, 0x61);
837 reg_w1(gspca_dev, 0x17, 0x20);
838 reg_w1(gspca_dev, 0x01, 0x60);
839 reg_w1(gspca_dev, 0x01, 0x40);
840 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300842 reg_w1(gspca_dev, 0x01, 0x43);
843 reg_w1(gspca_dev, 0x17, 0x61);
844 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300845 if (sd->sensor == SENSOR_HV7131R) {
846 if (probesensor(gspca_dev) < 0)
847 return -ENODEV;
848 }
849 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300850 }
851 return 0;
852}
853
854static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
855{
856 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300857 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300858 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
859
860 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300861 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862 i++;
863 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300864 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865}
866
867static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
868{
869 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300870
871 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300872 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300873 i++;
874 }
875}
876
877static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
878{
879 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300880
881 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300882 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883 i++;
884 }
885}
886
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300887static void om6802_InitSensor(struct gspca_dev *gspca_dev)
888{
889 int i = 0;
890
891 while (om6802_sensor_init[i][0]) {
892 i2c_w8(gspca_dev, om6802_sensor_init[i]);
893 i++;
894 }
895}
896
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300897static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
898{
899 int i = 0;
900
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300901 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
902 i++;
903 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300904 i++;
905 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300906 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
907 i++;
908 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
909 i++;
910 msleep(20);
911 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
912 i++;
913/*jfm:win i2c_r from 00 to 80*/
914
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300915 while (ov7630_sensor_init[i][0]) {
916 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
917 i++;
918 }
919}
920
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
922{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300923 int i = 0;
924
925 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300926 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300927 i++;
928 }
929}
930
931static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
932{
933 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300934
Jean-Francois Moine60017612008-07-18 08:46:19 -0300935 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
936 i++;
937 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300938 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300939 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300940 i++;
941 }
942}
943
944/* this function is called at probe time */
945static int sd_config(struct gspca_dev *gspca_dev,
946 const struct usb_device_id *id)
947{
948 struct sd *sd = (struct sd *) gspca_dev;
949 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300950
951 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300952 cam->epaddr = 0x01;
953 cam->cam_mode = vga_mode;
954 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300955
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300956 sd->bridge = id->driver_info >> 16;
957 sd->sensor = id->driver_info >> 8;
958 sd->i2c_base = id->driver_info;
959
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300960 sd->qindex = 4; /* set the quantization table */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300961 sd->brightness = BRIGHTNESS_DEF;
962 sd->contrast = CONTRAST_DEF;
963 sd->colors = COLOR_DEF;
964 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -0300965 sd->ag_cnt = -1;
966
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300967 switch (sd->sensor) {
968 case SENSOR_OV7630:
969 case SENSOR_OV7648:
970 case SENSOR_OV7660:
971 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
972 break;
973 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300974 if (sd->sensor != SENSOR_OV7630)
975 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300976
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300977 return 0;
978}
979
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300980/* this function is called at probe and resume time */
981static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300982{
983 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300984/* const __u8 *sn9c1xx; */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300985 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -0300986 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300987
Hans de Goede3647fea2008-07-15 05:36:30 -0300988 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300989 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300990 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300991 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
992 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300993 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300994 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -0300995 switch (sd->bridge) {
996 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300997 if (regF1 != 0x11)
998 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -0300999 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001000 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001001 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001002 if (regF1 != 0x11)
1003 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001004 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001005 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001006 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001007 if (regF1 != 0x12)
1008 return -ENODEV;
1009 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001010 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001011 break;
1012 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001013/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001014/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001015 if (regF1 != 0x12)
1016 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001017 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001018 break;
1019 }
1020
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001021 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001022
1023 return 0;
1024}
1025
1026static unsigned int setexposure(struct gspca_dev *gspca_dev,
1027 unsigned int expo)
1028{
1029 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001030 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001031 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001032 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001033 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001034 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001035 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1036
1037 switch (sd->sensor) {
1038 case SENSOR_HV7131R: {
1039 __u8 Expodoit[] =
1040 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1041
1042 Expodoit[3] = expo >> 16;
1043 Expodoit[4] = expo >> 8;
1044 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001045 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001046 break;
1047 }
1048 case SENSOR_MI0360: {
1049 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1050 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1051
1052 if (expo > 0x0635)
1053 expo = 0x0635;
1054 else if (expo < 0x0001)
1055 expo = 0x0001;
1056 expoMi[3] = expo >> 8;
1057 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001058 i2c_w8(gspca_dev, expoMi);
1059 i2c_w8(gspca_dev, doit);
1060 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001061 break;
1062 }
1063 case SENSOR_MO4000: {
1064 __u8 expoMof[] =
1065 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1066 __u8 expoMo10[] =
1067 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1068
1069 if (expo > 0x1fff)
1070 expo = 0x1fff;
1071 else if (expo < 0x0001)
1072 expo = 0x0001;
1073 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001074 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001075 expoMo10[3] = ((expo & 0x1c00) >> 10)
1076 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001077 i2c_w8(gspca_dev, expoMo10);
1078 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001079 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001080 ((expoMo10[3] & 0x07) << 10)
1081 | (expoMof[3] << 2)
1082 | ((expoMo10[3] & 0x30) >> 4));
1083 break;
1084 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001085 case SENSOR_OM6802: {
1086 __u8 gainOm[] =
1087 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1088
1089 if (expo > 0x03ff)
1090 expo = 0x03ff;
1091 if (expo < 0x0001)
1092 expo = 0x0001;
1093 gainOm[3] = expo >> 2;
1094 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001095 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001096 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1097 break;
1098 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001099 }
1100 return expo;
1101}
1102
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001103/* this function is used for sensors o76xx only */
1104static void setbrightcont(struct gspca_dev *gspca_dev)
1105{
1106 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001107 int val;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001108 __u8 reg84_full[0x15];
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001109
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001110 memcpy(reg84_full, reg84, sizeof reg84_full);
1111 val = sd->contrast * 0x30 / CONTRAST_MAX + 0x10; /* 10..40 */
1112 reg84_full[0] = (val + 1) / 2; /* red */
1113 reg84_full[2] = val; /* green */
1114 reg84_full[4] = (val + 1) / 5; /* blue */
1115 val = (sd->brightness - BRIGHTNESS_DEF) * 0x10
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001116 / BRIGHTNESS_MAX;
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -03001117 reg84_full[0x12] = val & 0x1f; /* 5:0 signed value */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001118 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1119}
1120
1121/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001122static void setbrightness(struct gspca_dev *gspca_dev)
1123{
1124 struct sd *sd = (struct sd *) gspca_dev;
1125 unsigned int expo;
1126 __u8 k2;
1127
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001128 k2 = sd->brightness >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001129 switch (sd->sensor) {
1130 case SENSOR_HV7131R:
1131 expo = sd->brightness << 4;
1132 if (expo > 0x002dc6c0)
1133 expo = 0x002dc6c0;
1134 else if (expo < 0x02a0)
1135 expo = 0x02a0;
1136 sd->exposure = setexposure(gspca_dev, expo);
1137 break;
1138 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001139 case SENSOR_MO4000:
1140 expo = sd->brightness >> 4;
1141 sd->exposure = setexposure(gspca_dev, expo);
1142 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001143 case SENSOR_OM6802:
1144 expo = sd->brightness >> 6;
1145 sd->exposure = setexposure(gspca_dev, expo);
1146 k2 = sd->brightness >> 11;
1147 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001148 }
1149
Jean-Francois Moine60017612008-07-18 08:46:19 -03001150 reg_w1(gspca_dev, 0x96, k2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001151}
1152
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001153/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001154static void setcontrast(struct gspca_dev *gspca_dev)
1155{
1156 struct sd *sd = (struct sd *) gspca_dev;
1157 __u8 k2;
1158 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1159
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001160 k2 = sd->contrast;
1161 contrast[2] = k2;
1162 contrast[0] = (k2 + 1) >> 1;
1163 contrast[4] = (k2 + 1) / 5;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001164 reg_w(gspca_dev, 0x84, contrast, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001165}
1166
1167static void setcolors(struct gspca_dev *gspca_dev)
1168{
1169 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001170 __u8 blue, red;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001171
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001172 if (sd->colors >= 32) {
1173 red = 32 + (sd->colors - 32) / 2;
1174 blue = 64 - sd->colors;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001175 } else {
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001176 red = sd->colors;
1177 blue = 32 + (32 - sd->colors) / 2;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001178 }
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001179 reg_w1(gspca_dev, 0x05, red);
1180/* reg_w1(gspca_dev, 0x07, 32); */
1181 reg_w1(gspca_dev, 0x06, blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001182}
1183
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001184static void setautogain(struct gspca_dev *gspca_dev)
1185{
1186 struct sd *sd = (struct sd *) gspca_dev;
1187
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001188 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1189 return;
1190 if (sd->autogain)
1191 sd->ag_cnt = AG_CNT_START;
1192 else
1193 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001194}
1195
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001196static void setvflip(struct sd *sd)
1197{
1198 if (sd->sensor != SENSOR_OV7630)
1199 return;
1200 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1201 sd->vflip ? 0x82 : 0x02);
1202}
1203
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001204/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001205static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001206{
1207 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001208 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001209 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001210 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001211 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001212 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1213 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001214 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001215 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001216 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001217
1218 sn9c1xx = sn_tb[(int) sd->sensor];
1219 configure_gpio(gspca_dev, sn9c1xx);
1220
Jean-Francois Moine60017612008-07-18 08:46:19 -03001221 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1222 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1223 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1224 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1225 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1226 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1227 reg_w1(gspca_dev, 0xd3, 0x50);
1228 reg_w1(gspca_dev, 0xc6, 0x00);
1229 reg_w1(gspca_dev, 0xc7, 0x00);
1230 reg_w1(gspca_dev, 0xc8, 0x50);
1231 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001232 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001233 switch (sd->sensor) {
1234 case SENSOR_OV7630:
1235 reg17 = 0xe2;
1236 break;
1237 case SENSOR_OV7648:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001238 reg17 = 0xae;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001239 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001240/*jfm: from win trace */
1241 case SENSOR_OV7660:
1242 reg17 = 0xa0;
1243 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001244 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001245 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001246 break;
1247 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001248 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001249 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1250 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1251 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1252 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001253 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1254 for (i = 0; i < 8; i++)
1255 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001256 switch (sd->sensor) {
1257 case SENSOR_OV7660:
1258 reg_w1(gspca_dev, 0x9a, 0x05);
1259 break;
1260 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001261 reg_w1(gspca_dev, 0x9a, 0x08);
1262 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001263 break;
1264 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001265
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001266 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001267 if (mode)
1268 reg1 = 0x46; /* 320 clk 48Mhz */
1269 else
1270 reg1 = 0x06; /* 640 clk 24Mz */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001271 reg17 = 0x61;
1272 switch (sd->sensor) {
1273 case SENSOR_HV7131R:
1274 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001275 break;
1276 case SENSOR_MI0360:
1277 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001278 break;
1279 case SENSOR_MO4000:
1280 mo4000_InitSensor(gspca_dev);
1281 if (mode) {
1282/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1283 reg1 = 0x06; /* clk 24Mz */
1284 } else {
1285 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001286/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001287 }
1288 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001289 case SENSOR_OM6802:
1290 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001291 reg17 = 0x64; /* 640 MCKSIZE */
1292 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001293 case SENSOR_OV7630:
1294 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001295 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001296 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001297 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001298 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001299 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001300 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001301 reg17 = 0xa2;
1302 reg1 = 0x44;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001303/* if (mode)
1304 ; * 320x2...
1305 else
1306 ; * 640x... */
1307 break;
1308 default:
1309/* case SENSOR_OV7660: */
1310 ov7660_InitSensor(gspca_dev);
1311 if (mode) {
1312/* reg17 = 0x21; * 320 */
1313/* reg1 = 0x44; */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001314/* reg1 = 0x46; (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001315 } else {
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001316 reg17 = 0xa2; /* 640 */
1317 reg1 = 0x44;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001318 }
1319 break;
1320 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001321 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001322 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001323 switch (sd->sensor) {
1324 case SENSOR_OV7630:
1325 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001326 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001327 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001328 break;
1329 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001330 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001331 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1332 break;
1333 }
1334
1335 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001336 reg18 = sn9c1xx[0x18] | (mode << 4);
1337 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001338
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001339 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1340 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001341
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001342 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001343
Jean-Francois Moine60017612008-07-18 08:46:19 -03001344 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001345 switch (sd->sensor) {
1346 case SENSOR_HV7131R:
1347 case SENSOR_MI0360:
1348 case SENSOR_MO4000:
1349 case SENSOR_OM6802:
1350 setbrightness(gspca_dev);
1351 setcontrast(gspca_dev);
1352 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001353 case SENSOR_OV7630:
1354 setvflip(sd);
1355 /* fall thru */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001356 default: /* OV76xx */
1357 setbrightcont(gspca_dev);
1358 break;
1359 }
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001360 setautogain(gspca_dev);
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001361 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001362 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001363}
1364
1365static void sd_stopN(struct gspca_dev *gspca_dev)
1366{
1367 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001368 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001369 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001370 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001371 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001372 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001373 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001374
1375 data = 0x0b;
1376 switch (sd->sensor) {
1377 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001378 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001379 data = 0x2b;
1380 break;
1381 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001382 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001383 data = 0x29;
1384 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001385 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001386 case SENSOR_OV7648:
1387 data = 0x29;
1388 break;
1389 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001390/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001391/* case SENSOR_OV7660: */
1392 break;
1393 }
1394 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001395 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1396 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1397 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1398 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001399 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001400}
1401
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001402static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001403{
1404 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001405 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001406 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001407 __u8 luma_mean = 130;
1408 __u8 luma_delta = 20;
1409
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001410 /* Thanks S., without your advice, autobright should not work :) */
1411 if (sd->ag_cnt < 0)
1412 return;
1413 if (--sd->ag_cnt >= 0)
1414 return;
1415 sd->ag_cnt = AG_CNT_START;
1416
1417 delta = atomic_read(&sd->avg_lum);
1418 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001419 if (delta < luma_mean - luma_delta ||
1420 delta > luma_mean + luma_delta) {
1421 switch (sd->sensor) {
1422 case SENSOR_HV7131R:
1423 expotimes = sd->exposure >> 8;
1424 expotimes += (luma_mean - delta) >> 4;
1425 if (expotimes < 0)
1426 expotimes = 0;
1427 sd->exposure = setexposure(gspca_dev,
1428 (unsigned int) (expotimes << 8));
1429 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001430 default:
1431/* case SENSOR_MO4000: */
1432/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001433/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001434 expotimes = sd->exposure;
1435 expotimes += (luma_mean - delta) >> 6;
1436 if (expotimes < 0)
1437 expotimes = 0;
1438 sd->exposure = setexposure(gspca_dev,
1439 (unsigned int) expotimes);
1440 setcolors(gspca_dev);
1441 break;
1442 }
1443 }
1444}
1445
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001446/* scan the URB packets */
1447/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001448static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1449 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001450 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 int len) /* iso packet length */
1452{
1453 struct sd *sd = (struct sd *) gspca_dev;
1454 int sof, avg_lum;
1455
1456 sof = len - 64;
1457 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1458
1459 /* end of frame */
1460 gspca_frame_add(gspca_dev, LAST_PACKET,
1461 frame, data, sof + 2);
1462 if (sd->ag_cnt < 0)
1463 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001464/* w1 w2 w3 */
1465/* w4 w5 w6 */
1466/* w7 w8 */
1467/* w4 */
1468 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1469/* w6 */
1470 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1471/* w2 */
1472 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1473/* w8 */
1474 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1475/* w5 */
1476 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1477 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001478 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001479 return;
1480 }
1481 if (gspca_dev->last_packet_type == LAST_PACKET) {
1482
1483 /* put the JPEG 422 header */
1484 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1485 }
1486 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1487}
1488
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001489static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1490{
1491 struct sd *sd = (struct sd *) gspca_dev;
1492
1493 sd->brightness = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001494 if (gspca_dev->streaming) {
1495 switch (sd->sensor) {
1496 case SENSOR_HV7131R:
1497 case SENSOR_MI0360:
1498 case SENSOR_MO4000:
1499 case SENSOR_OM6802:
1500 setbrightness(gspca_dev);
1501 break;
1502 default: /* OV76xx */
1503 setbrightcont(gspca_dev);
1504 break;
1505 }
1506 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001507 return 0;
1508}
1509
1510static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1511{
1512 struct sd *sd = (struct sd *) gspca_dev;
1513
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001514 *val = sd->brightness;
1515 return 0;
1516}
1517
1518static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1519{
1520 struct sd *sd = (struct sd *) gspca_dev;
1521
1522 sd->contrast = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001523 if (gspca_dev->streaming) {
1524 switch (sd->sensor) {
1525 case SENSOR_HV7131R:
1526 case SENSOR_MI0360:
1527 case SENSOR_MO4000:
1528 case SENSOR_OM6802:
1529 setcontrast(gspca_dev);
1530 break;
1531 default: /* OV76xx */
1532 setbrightcont(gspca_dev);
1533 break;
1534 }
1535 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001536 return 0;
1537}
1538
1539static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1540{
1541 struct sd *sd = (struct sd *) gspca_dev;
1542
1543 *val = sd->contrast;
1544 return 0;
1545}
1546
1547static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1548{
1549 struct sd *sd = (struct sd *) gspca_dev;
1550
1551 sd->colors = val;
1552 if (gspca_dev->streaming)
1553 setcolors(gspca_dev);
1554 return 0;
1555}
1556
1557static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1558{
1559 struct sd *sd = (struct sd *) gspca_dev;
1560
1561 *val = sd->colors;
1562 return 0;
1563}
1564
1565static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1566{
1567 struct sd *sd = (struct sd *) gspca_dev;
1568
1569 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001570 if (gspca_dev->streaming)
1571 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001572 return 0;
1573}
1574
1575static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1576{
1577 struct sd *sd = (struct sd *) gspca_dev;
1578
1579 *val = sd->autogain;
1580 return 0;
1581}
1582
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001583static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1584{
1585 struct sd *sd = (struct sd *) gspca_dev;
1586
1587 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001588 if (gspca_dev->streaming)
1589 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001590 return 0;
1591}
1592
1593static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1594{
1595 struct sd *sd = (struct sd *) gspca_dev;
1596
1597 *val = sd->vflip;
1598 return 0;
1599}
1600
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001601/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001602static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001603 .name = MODULE_NAME,
1604 .ctrls = sd_ctrls,
1605 .nctrls = ARRAY_SIZE(sd_ctrls),
1606 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001607 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001608 .start = sd_start,
1609 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001610 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001611 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001612};
1613
1614/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001615#define BSI(bridge, sensor, i2c_addr) \
1616 .driver_info = (BRIDGE_ ## bridge << 16) \
1617 | (SENSOR_ ## sensor << 8) \
1618 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001619static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001620#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001621 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001622 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001623 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1624 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1625 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1626 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001627#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001628 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1629 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1630/* bw600.inf:
1631 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1632/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1633/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1634 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1635/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1636 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1637/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1638/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1639 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1640/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1641/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1642 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1643 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001644#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1645 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1646#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001647/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1648/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1649/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001650 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1651/*bw600.inf:*/
1652 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001653 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001654 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001655/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001656#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001657 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001658#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001659 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001660#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001661/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1662 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1663 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1664/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001665#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001666 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001667 {}
1668};
1669MODULE_DEVICE_TABLE(usb, device_table);
1670
1671/* -- device connect -- */
1672static int sd_probe(struct usb_interface *intf,
1673 const struct usb_device_id *id)
1674{
1675 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1676 THIS_MODULE);
1677}
1678
1679static struct usb_driver sd_driver = {
1680 .name = MODULE_NAME,
1681 .id_table = device_table,
1682 .probe = sd_probe,
1683 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001684#ifdef CONFIG_PM
1685 .suspend = gspca_suspend,
1686 .resume = gspca_resume,
1687#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001688};
1689
1690/* -- module insert / remove -- */
1691static int __init sd_mod_init(void)
1692{
1693 if (usb_register(&sd_driver) < 0)
1694 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001695 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001696 return 0;
1697}
1698static void __exit sd_mod_exit(void)
1699{
1700 usb_deregister(&sd_driver);
1701 info("deregistered");
1702}
1703
1704module_init(sd_mod_init);
1705module_exit(sd_mod_exit);