blob: 1d6f2ee1eec8d186e2ae4d4242eaf4e0219d0d1f [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,
147#define VFLIP_DEF 0
148 .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 Moinea5ae2062008-07-04 11:16:16 -0300270static const __u8 reg84[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300271 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
272 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300273 0xf7, 0x0f, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300274};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300275static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300276 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
277 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
278 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
279 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
280 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
281 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
282 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
283
284 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
285 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
286 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
287 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
288 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
289 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
290 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
291 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
292
293 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
294 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
295 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
296 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
297 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
298
299 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
300 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
301 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
302 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300304 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300305};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300306static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300307 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
308 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
309 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
310 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
311 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
312 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
313 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
314 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
315 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
316 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
317 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
318 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
319 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
320 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
321 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
322 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
323 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
324 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
325 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
326 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
327 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
328 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
329 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
330 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
331 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
332 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
333 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
334 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
335 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
336 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
337 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
338 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
339 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
340
341 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
342 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
343 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
344 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
345 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
346
347 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
348 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
349 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
350 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
351
352 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
353 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
354/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
355/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
356 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
357 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300358 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300359};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300360static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300361 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
362 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
363 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
364 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
365 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
366 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
367 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
368 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
369 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
370 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
371 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
372 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
373 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
374 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
375 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
377 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
378 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
379 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
380 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300381 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300382};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300383static __u8 om6802_sensor_init[][8] = {
384 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
385 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
386 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
387 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
388/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
389 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
390 /* white balance & auto-exposure */
391/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
392 * set color mode */
393/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
394 * max AGC value in AE */
395/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
396 * preset AGC */
397/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
398 * preset brightness */
399/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
400 * preset contrast */
401/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
402 * preset gamma */
403 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
404 /* luminance mode (0x4f = AE) */
405 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
406 /* preset shutter */
407/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
408 * auto frame rate */
409/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
410
411/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
412/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
413/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
414/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
415 {}
416};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300417static const __u8 ov7630_sensor_init[][8] = {
418 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
419 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
420/* win: delay 20ms */
421 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
422 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
423/* win: delay 20ms */
424 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300425/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300426 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
427 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
428 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
429 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
430 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
431 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
432 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
433 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
434 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
435 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
436 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
437 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
441 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
443 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
444 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
445 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
447 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
448 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
449 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
450 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
451 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
452/* */
453 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
454 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
455/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300456/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
457 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300458 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
459 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
460 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300461/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300462 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
463 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
464 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300465/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300466 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300467/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300468 {}
469};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300470static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300471 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300472/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300473 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300474 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300475 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300476 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300477 /* GAIN BLUE RED VREF */
478 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
479 /* COM 1 BAVE GEAVE AECHH */
480 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
481 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300482 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300483 /* AECH CLKRC COM7 COM8 */
484 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
485 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
486 /* HSTART HSTOP VSTRT VSTOP */
487 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
488 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
489 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
490 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300491/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
492 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300493 /* AEW AEB VPT BBIAS */
494 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
495 /* GbBIAS RSVD EXHCH EXHCL */
496 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
497 /* RBIAS ADVFL ASDVFH YAVE */
498 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
499 /* HSYST HSYEN HREF */
500 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
501 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
502 /* ADC ACOM OFON TSLB */
503 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
504 /* COM11 COM12 COM13 COM14 */
505 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
506 /* EDGE COM15 COM16 COM17 */
507 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
508 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
509 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
510 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
511 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
512 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
513 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
514 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
515 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
516 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
517 /* LCC1 LCC2 LCC3 LCC4 */
518 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300519 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300520 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300521 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300522 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
523 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
524 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
525 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
526 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
527 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
528 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
529 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
530 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300531 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300532/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300533 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300534 /* bits[3..0]reserved */
535 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
536 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
537 /* VREF vertical frame ctrl */
538 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300539 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
540 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
541 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
542 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
543/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300544/****** (some exchanges in the win trace) ******/
545 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300546 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
547 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
548 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
549/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300550/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300551/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300552 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
553 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
554 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
555 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300556 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300557};
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300558/* reg 0x04 reg 0x07 reg 0x10 */
559/* expo = (COM1 & 0x02) | ((AECHH & 0x2f) << 10) | (AECh << 2) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300560
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300561static const __u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300562 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
563 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
564 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
565 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
566 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
567 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
568 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
569 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
570 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
571 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
572 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
573 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
574 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
575 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
576 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
577 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
578 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
579 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
580 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
581 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
582 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
583 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
584 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
585 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
586 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
587 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
588 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
589 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
590 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
591 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
592 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
593 * This is currently setting a
594 * blue tint, and some things more , i leave it here for future test if
595 * somene is having problems with color on this sensor
596 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
597 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
598 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
599 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
600 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
601 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
602 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
603 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
604 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
605 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
606 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
607 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
608 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
609 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
610 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
611 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
612 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
613/* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300614 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300615};
616
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300617static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300618 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
619 0x06, 0x08, 0x0A, 0x11,
620 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
621 0x19, 0x19, 0x17, 0x15,
622 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
623 0x21, 0x2E, 0x21, 0x23,
624 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
625 0x25, 0x29, 0x2C, 0x29,
626 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
627 0x17, 0x1B, 0x29, 0x29,
628 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
629 0x29, 0x29, 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};
635
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300636/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300637static void reg_r(struct gspca_dev *gspca_dev,
638 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300639{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300640#ifdef GSPCA_DEBUG
641 if (len > USB_BUF_SZ) {
642 err("reg_r: buffer overflow");
643 return;
644 }
645#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300646 usb_control_msg(gspca_dev->dev,
647 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300648 0,
649 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
650 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300651 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300652 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300653 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654}
655
Jean-Francois Moine60017612008-07-18 08:46:19 -0300656static void reg_w1(struct gspca_dev *gspca_dev,
657 __u16 value,
658 __u8 data)
659{
660 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
661 gspca_dev->usb_buf[0] = data;
662 usb_control_msg(gspca_dev->dev,
663 usb_sndctrlpipe(gspca_dev->dev, 0),
664 0x08,
665 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
666 value,
667 0,
668 gspca_dev->usb_buf, 1,
669 500);
670}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300671static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300672 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300673 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300674 int len)
675{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300676 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
677 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300678#ifdef GSPCA_DEBUG
679 if (len > USB_BUF_SZ) {
680 err("reg_w: buffer overflow");
681 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300682 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300683#endif
684 memcpy(gspca_dev->usb_buf, buffer, len);
685 usb_control_msg(gspca_dev->dev,
686 usb_sndctrlpipe(gspca_dev->dev, 0),
687 0x08,
688 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
689 value, 0,
690 gspca_dev->usb_buf, len,
691 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300692}
693
Jean-Francois Moine60017612008-07-18 08:46:19 -0300694/* I2C write 1 byte */
695static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300696{
697 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300698
Jean-Francois Moine60017612008-07-18 08:46:19 -0300699 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
700 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
701 gspca_dev->usb_buf[1] = sd->i2c_base;
702 gspca_dev->usb_buf[2] = reg;
703 gspca_dev->usb_buf[3] = val;
704 gspca_dev->usb_buf[4] = 0;
705 gspca_dev->usb_buf[5] = 0;
706 gspca_dev->usb_buf[6] = 0;
707 gspca_dev->usb_buf[7] = 0x10;
708 usb_control_msg(gspca_dev->dev,
709 usb_sndctrlpipe(gspca_dev->dev, 0),
710 0x08,
711 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
712 0x08, /* value = i2c */
713 0,
714 gspca_dev->usb_buf, 8,
715 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300716}
717
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300718/* I2C write 8 bytes */
719static void i2c_w8(struct gspca_dev *gspca_dev,
720 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300721{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300722 memcpy(gspca_dev->usb_buf, buffer, 8);
723 usb_control_msg(gspca_dev->dev,
724 usb_sndctrlpipe(gspca_dev->dev, 0),
725 0x08,
726 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
727 0x08, 0, /* value, index */
728 gspca_dev->usb_buf, 8,
729 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300730 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300731}
732
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300733/* read 5 bytes in gspca_dev->usb_buf */
734static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300735{
736 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300737 __u8 mode[8];
738
Hans de Goede3647fea2008-07-15 05:36:30 -0300739 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300740 mode[1] = sd->i2c_base;
741 mode[2] = reg;
742 mode[3] = 0;
743 mode[4] = 0;
744 mode[5] = 0;
745 mode[6] = 0;
746 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300747 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300748 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300749 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300750 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300751 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300752 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300753 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300754}
755
756static int probesensor(struct gspca_dev *gspca_dev)
757{
758 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300759
Jean-Francois Moine60017612008-07-18 08:46:19 -0300760 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300761 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300762 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300763 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300764 i2c_r5(gspca_dev, 0); /* read sensor id */
765 if (gspca_dev->usb_buf[0] == 0x02
766 && gspca_dev->usb_buf[1] == 0x09
767 && gspca_dev->usb_buf[2] == 0x01
768 && gspca_dev->usb_buf[3] == 0x00
769 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300770 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
771 sd->sensor = SENSOR_HV7131R;
772 return SENSOR_HV7131R;
773 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300774 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300775 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
776 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
778 return -ENODEV;
779}
780
781static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300782 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300783{
784 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300785 const __u8 *reg9a;
786 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300787 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300788 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300789 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300790 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300791
Jean-Francois Moine60017612008-07-18 08:46:19 -0300792 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300793 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300794
795 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300796 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
797 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300798 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300799 switch (sd->bridge) {
800 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801 reg9a = reg9a_sn9c325;
802 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300803 default:
804 reg9a = reg9a_def;
805 break;
806 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300807 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300808
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300809 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300810
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300811 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300812
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300813 switch (sd->sensor) {
814 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300815 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300816 reg_w1(gspca_dev, 0x01, 0x42);
817 reg_w1(gspca_dev, 0x17, 0x64);
818 reg_w1(gspca_dev, 0x01, 0x42);
819 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300820/*jfm: from win trace */
821 case SENSOR_OV7630:
822 reg_w1(gspca_dev, 0x01, 0x61);
823 reg_w1(gspca_dev, 0x17, 0xe2);
824 reg_w1(gspca_dev, 0x01, 0x60);
825 reg_w1(gspca_dev, 0x01, 0x40);
826 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300827 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300828 reg_w1(gspca_dev, 0x01, 0x43);
829 reg_w1(gspca_dev, 0x17, 0xae);
830 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300831 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300832/*jfm: from win trace */
833 case SENSOR_OV7660:
834 reg_w1(gspca_dev, 0x01, 0x61);
835 reg_w1(gspca_dev, 0x17, 0x20);
836 reg_w1(gspca_dev, 0x01, 0x60);
837 reg_w1(gspca_dev, 0x01, 0x40);
838 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300839 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300840 reg_w1(gspca_dev, 0x01, 0x43);
841 reg_w1(gspca_dev, 0x17, 0x61);
842 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300843 if (sd->sensor == SENSOR_HV7131R) {
844 if (probesensor(gspca_dev) < 0)
845 return -ENODEV;
846 }
847 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300848 }
849 return 0;
850}
851
852static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
853{
854 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300855 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300856 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
857
858 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300859 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300860 i++;
861 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300862 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863}
864
865static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
866{
867 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300868
869 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300870 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300871 i++;
872 }
873}
874
875static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
876{
877 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878
879 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300880 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300881 i++;
882 }
883}
884
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300885static void om6802_InitSensor(struct gspca_dev *gspca_dev)
886{
887 int i = 0;
888
889 while (om6802_sensor_init[i][0]) {
890 i2c_w8(gspca_dev, om6802_sensor_init[i]);
891 i++;
892 }
893}
894
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300895static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
896{
897 int i = 0;
898
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300899 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
900 i++;
901 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300902 i++;
903 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300904 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
905 i++;
906 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
907 i++;
908 msleep(20);
909 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
910 i++;
911/*jfm:win i2c_r from 00 to 80*/
912
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300913 while (ov7630_sensor_init[i][0]) {
914 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
915 i++;
916 }
917}
918
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300919static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
920{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921 int i = 0;
922
923 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300924 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300925 i++;
926 }
927}
928
929static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
930{
931 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932
Jean-Francois Moine60017612008-07-18 08:46:19 -0300933 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
934 i++;
935 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300937 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300938 i++;
939 }
940}
941
942/* this function is called at probe time */
943static int sd_config(struct gspca_dev *gspca_dev,
944 const struct usb_device_id *id)
945{
946 struct sd *sd = (struct sd *) gspca_dev;
947 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300948
949 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300950 cam->epaddr = 0x01;
951 cam->cam_mode = vga_mode;
952 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300953
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300954 sd->bridge = id->driver_info >> 16;
955 sd->sensor = id->driver_info >> 8;
956 sd->i2c_base = id->driver_info;
957
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300958 sd->qindex = 4; /* set the quantization table */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300959 sd->brightness = BRIGHTNESS_DEF;
960 sd->contrast = CONTRAST_DEF;
961 sd->colors = COLOR_DEF;
962 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -0300963 sd->ag_cnt = -1;
964
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300965 switch (sd->sensor) {
966 case SENSOR_OV7630:
967 case SENSOR_OV7648:
968 case SENSOR_OV7660:
969 gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX);
970 break;
971 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300972 if (sd->sensor != SENSOR_OV7630)
973 gspca_dev->ctrl_dis |= (1 << VFLIP_IDX);
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -0300974
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300975 return 0;
976}
977
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300978/* this function is called at probe and resume time */
979static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300980{
981 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300982/* const __u8 *sn9c1xx; */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300983 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -0300984 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300985
Hans de Goede3647fea2008-07-15 05:36:30 -0300986 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300987 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300988 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300989 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
990 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300991 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300992 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -0300993 switch (sd->bridge) {
994 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300995 if (regF1 != 0x11)
996 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -0300997 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300998 break;
Hans de Goede3647fea2008-07-15 05:36:30 -0300999 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001000 if (regF1 != 0x11)
1001 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001002 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001003 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001004 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001005 if (regF1 != 0x12)
1006 return -ENODEV;
1007 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001008 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001009 break;
1010 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001011/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001012/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001013 if (regF1 != 0x12)
1014 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001015 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001016 break;
1017 }
1018
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001019 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001020
1021 return 0;
1022}
1023
1024static unsigned int setexposure(struct gspca_dev *gspca_dev,
1025 unsigned int expo)
1026{
1027 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001028 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001029 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001030 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001031 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001032 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001033 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1034
1035 switch (sd->sensor) {
1036 case SENSOR_HV7131R: {
1037 __u8 Expodoit[] =
1038 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1039
1040 Expodoit[3] = expo >> 16;
1041 Expodoit[4] = expo >> 8;
1042 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001043 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001044 break;
1045 }
1046 case SENSOR_MI0360: {
1047 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1048 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1049
1050 if (expo > 0x0635)
1051 expo = 0x0635;
1052 else if (expo < 0x0001)
1053 expo = 0x0001;
1054 expoMi[3] = expo >> 8;
1055 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001056 i2c_w8(gspca_dev, expoMi);
1057 i2c_w8(gspca_dev, doit);
1058 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001059 break;
1060 }
1061 case SENSOR_MO4000: {
1062 __u8 expoMof[] =
1063 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1064 __u8 expoMo10[] =
1065 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1066
1067 if (expo > 0x1fff)
1068 expo = 0x1fff;
1069 else if (expo < 0x0001)
1070 expo = 0x0001;
1071 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001072 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001073 expoMo10[3] = ((expo & 0x1c00) >> 10)
1074 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001075 i2c_w8(gspca_dev, expoMo10);
1076 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001077 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001078 ((expoMo10[3] & 0x07) << 10)
1079 | (expoMof[3] << 2)
1080 | ((expoMo10[3] & 0x30) >> 4));
1081 break;
1082 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001083 case SENSOR_OM6802: {
1084 __u8 gainOm[] =
1085 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1086
1087 if (expo > 0x03ff)
1088 expo = 0x03ff;
1089 if (expo < 0x0001)
1090 expo = 0x0001;
1091 gainOm[3] = expo >> 2;
1092 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001093 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001094 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1095 break;
1096 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001097 }
1098 return expo;
1099}
1100
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001101/* this function is used for sensors o76xx only */
1102static void setbrightcont(struct gspca_dev *gspca_dev)
1103{
1104 struct sd *sd = (struct sd *) gspca_dev;
1105 unsigned val;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001106 __u8 reg84_full[0x15];
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001107
1108 memset(reg84_full, 0, sizeof reg84_full);
1109 val = sd->contrast * 0x20 / CONTRAST_MAX + 0x10; /* 10..30 */
1110 reg84_full[2] = val;
1111 reg84_full[0] = (val + 1) / 2;
1112 reg84_full[4] = (val + 1) / 5;
1113 if (val > BRIGHTNESS_DEF)
1114 val = (sd->brightness - BRIGHTNESS_DEF) * 0x20
1115 / BRIGHTNESS_MAX;
1116 else
1117 val = 0;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001118 reg84_full[0x12] = val; /* 00..1f */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001119 reg_w(gspca_dev, 0x84, reg84_full, sizeof reg84_full);
1120}
1121
1122/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001123static void setbrightness(struct gspca_dev *gspca_dev)
1124{
1125 struct sd *sd = (struct sd *) gspca_dev;
1126 unsigned int expo;
1127 __u8 k2;
1128
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001129 k2 = sd->brightness >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001130 switch (sd->sensor) {
1131 case SENSOR_HV7131R:
1132 expo = sd->brightness << 4;
1133 if (expo > 0x002dc6c0)
1134 expo = 0x002dc6c0;
1135 else if (expo < 0x02a0)
1136 expo = 0x02a0;
1137 sd->exposure = setexposure(gspca_dev, expo);
1138 break;
1139 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001140 case SENSOR_MO4000:
1141 expo = sd->brightness >> 4;
1142 sd->exposure = setexposure(gspca_dev, expo);
1143 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001144 case SENSOR_OM6802:
1145 expo = sd->brightness >> 6;
1146 sd->exposure = setexposure(gspca_dev, expo);
1147 k2 = sd->brightness >> 11;
1148 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001149 }
1150
Jean-Francois Moine60017612008-07-18 08:46:19 -03001151 reg_w1(gspca_dev, 0x96, k2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001152}
1153
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001154/* sensor != ov76xx */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001155static void setcontrast(struct gspca_dev *gspca_dev)
1156{
1157 struct sd *sd = (struct sd *) gspca_dev;
1158 __u8 k2;
1159 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1160
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001161 k2 = sd->contrast;
1162 contrast[2] = k2;
1163 contrast[0] = (k2 + 1) >> 1;
1164 contrast[4] = (k2 + 1) / 5;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001165 reg_w(gspca_dev, 0x84, contrast, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001166}
1167
1168static void setcolors(struct gspca_dev *gspca_dev)
1169{
1170 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001171 __u8 blue, red;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001172
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001173 if (sd->colors >= 32) {
1174 red = 32 + (sd->colors - 32) / 2;
1175 blue = 64 - sd->colors;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001176 } else {
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001177 red = sd->colors;
1178 blue = 32 + (32 - sd->colors) / 2;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001179 }
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001180 reg_w1(gspca_dev, 0x05, red);
1181/* reg_w1(gspca_dev, 0x07, 32); */
1182 reg_w1(gspca_dev, 0x06, blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001183}
1184
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001185static void setautogain(struct gspca_dev *gspca_dev)
1186{
1187 struct sd *sd = (struct sd *) gspca_dev;
1188
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001189 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1190 return;
1191 if (sd->autogain)
1192 sd->ag_cnt = AG_CNT_START;
1193 else
1194 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001195}
1196
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001197static void setvflip(struct sd *sd)
1198{
1199 if (sd->sensor != SENSOR_OV7630)
1200 return;
1201 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1202 sd->vflip ? 0x82 : 0x02);
1203}
1204
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001205/* -- start the camera -- */
1206static void sd_start(struct gspca_dev *gspca_dev)
1207{
1208 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001209 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001210 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001211 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001212 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001213 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1214 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001215 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001216 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001217 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001218
1219 sn9c1xx = sn_tb[(int) sd->sensor];
1220 configure_gpio(gspca_dev, sn9c1xx);
1221
Jean-Francois Moine60017612008-07-18 08:46:19 -03001222 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1223 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1224 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1225 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1226 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1227 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1228 reg_w1(gspca_dev, 0xd3, 0x50);
1229 reg_w1(gspca_dev, 0xc6, 0x00);
1230 reg_w1(gspca_dev, 0xc7, 0x00);
1231 reg_w1(gspca_dev, 0xc8, 0x50);
1232 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001233 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001234 switch (sd->sensor) {
1235 case SENSOR_OV7630:
1236 reg17 = 0xe2;
1237 break;
1238 case SENSOR_OV7648:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001239 reg17 = 0xae;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001240 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001241/*jfm: from win trace */
1242 case SENSOR_OV7660:
1243 reg17 = 0xa0;
1244 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001245 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001246 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001247 break;
1248 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001249 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001250 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1251 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1252 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1253 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001254 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1255 for (i = 0; i < 8; i++)
1256 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001257 switch (sd->sensor) {
1258 case SENSOR_OV7660:
1259 reg_w1(gspca_dev, 0x9a, 0x05);
1260 break;
1261 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001262 reg_w1(gspca_dev, 0x9a, 0x08);
1263 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001264 break;
1265 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001266
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001267 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001268 if (mode)
1269 reg1 = 0x46; /* 320 clk 48Mhz */
1270 else
1271 reg1 = 0x06; /* 640 clk 24Mz */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001272 reg17 = 0x61;
1273 switch (sd->sensor) {
1274 case SENSOR_HV7131R:
1275 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001276 break;
1277 case SENSOR_MI0360:
1278 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001279 break;
1280 case SENSOR_MO4000:
1281 mo4000_InitSensor(gspca_dev);
1282 if (mode) {
1283/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1284 reg1 = 0x06; /* clk 24Mz */
1285 } else {
1286 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001287/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001288 }
1289 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001290 case SENSOR_OM6802:
1291 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001292 reg17 = 0x64; /* 640 MCKSIZE */
1293 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001294 case SENSOR_OV7630:
1295 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001296 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001297 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001298 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001299 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001300 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001301 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001302 reg17 = 0xa2;
1303 reg1 = 0x44;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001304/* if (mode)
1305 ; * 320x2...
1306 else
1307 ; * 640x... */
1308 break;
1309 default:
1310/* case SENSOR_OV7660: */
1311 ov7660_InitSensor(gspca_dev);
1312 if (mode) {
1313/* reg17 = 0x21; * 320 */
1314/* reg1 = 0x44; */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001315/* reg1 = 0x46; (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001316 } else {
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001317 reg17 = 0xa2; /* 640 */
1318 reg1 = 0x44;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001319 }
1320 break;
1321 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001322 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001323 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001324 switch (sd->sensor) {
1325 case SENSOR_OV7630:
1326 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001327 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001328 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001329 break;
1330 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001331 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001332 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1333 break;
1334 }
1335
1336 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001337 reg18 = sn9c1xx[0x18] | (mode << 4);
1338 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001339
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001340 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1341 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001342
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001343 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001344
Jean-Francois Moine60017612008-07-18 08:46:19 -03001345 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001346 switch (sd->sensor) {
1347 case SENSOR_HV7131R:
1348 case SENSOR_MI0360:
1349 case SENSOR_MO4000:
1350 case SENSOR_OM6802:
1351 setbrightness(gspca_dev);
1352 setcontrast(gspca_dev);
1353 break;
1354 default: /* OV76xx */
1355 setbrightcont(gspca_dev);
1356 break;
1357 }
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001358 setautogain(gspca_dev);
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001359 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001360}
1361
1362static void sd_stopN(struct gspca_dev *gspca_dev)
1363{
1364 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001365 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001366 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001367 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001369 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001370 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001371
1372 data = 0x0b;
1373 switch (sd->sensor) {
1374 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001375 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001376 data = 0x2b;
1377 break;
1378 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001379 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001380 data = 0x29;
1381 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001382 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001383 case SENSOR_OV7648:
1384 data = 0x29;
1385 break;
1386 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001387/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001388/* case SENSOR_OV7660: */
1389 break;
1390 }
1391 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001392 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1393 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1394 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1395 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001396 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001397}
1398
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001399static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001400{
1401 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001402 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001403 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001404 __u8 luma_mean = 130;
1405 __u8 luma_delta = 20;
1406
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001407 /* Thanks S., without your advice, autobright should not work :) */
1408 if (sd->ag_cnt < 0)
1409 return;
1410 if (--sd->ag_cnt >= 0)
1411 return;
1412 sd->ag_cnt = AG_CNT_START;
1413
1414 delta = atomic_read(&sd->avg_lum);
1415 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001416 if (delta < luma_mean - luma_delta ||
1417 delta > luma_mean + luma_delta) {
1418 switch (sd->sensor) {
1419 case SENSOR_HV7131R:
1420 expotimes = sd->exposure >> 8;
1421 expotimes += (luma_mean - delta) >> 4;
1422 if (expotimes < 0)
1423 expotimes = 0;
1424 sd->exposure = setexposure(gspca_dev,
1425 (unsigned int) (expotimes << 8));
1426 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001427 default:
1428/* case SENSOR_MO4000: */
1429/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001430/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001431 expotimes = sd->exposure;
1432 expotimes += (luma_mean - delta) >> 6;
1433 if (expotimes < 0)
1434 expotimes = 0;
1435 sd->exposure = setexposure(gspca_dev,
1436 (unsigned int) expotimes);
1437 setcolors(gspca_dev);
1438 break;
1439 }
1440 }
1441}
1442
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001443/* scan the URB packets */
1444/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001445static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1446 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001447 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001448 int len) /* iso packet length */
1449{
1450 struct sd *sd = (struct sd *) gspca_dev;
1451 int sof, avg_lum;
1452
1453 sof = len - 64;
1454 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1455
1456 /* end of frame */
1457 gspca_frame_add(gspca_dev, LAST_PACKET,
1458 frame, data, sof + 2);
1459 if (sd->ag_cnt < 0)
1460 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001461/* w1 w2 w3 */
1462/* w4 w5 w6 */
1463/* w7 w8 */
1464/* w4 */
1465 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1466/* w6 */
1467 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1468/* w2 */
1469 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1470/* w8 */
1471 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1472/* w5 */
1473 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1474 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001475 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001476 return;
1477 }
1478 if (gspca_dev->last_packet_type == LAST_PACKET) {
1479
1480 /* put the JPEG 422 header */
1481 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1482 }
1483 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1484}
1485
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001486static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1487{
1488 struct sd *sd = (struct sd *) gspca_dev;
1489
1490 sd->brightness = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001491 if (gspca_dev->streaming) {
1492 switch (sd->sensor) {
1493 case SENSOR_HV7131R:
1494 case SENSOR_MI0360:
1495 case SENSOR_MO4000:
1496 case SENSOR_OM6802:
1497 setbrightness(gspca_dev);
1498 break;
1499 default: /* OV76xx */
1500 setbrightcont(gspca_dev);
1501 break;
1502 }
1503 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001504 return 0;
1505}
1506
1507static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1508{
1509 struct sd *sd = (struct sd *) gspca_dev;
1510
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001511 *val = sd->brightness;
1512 return 0;
1513}
1514
1515static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1516{
1517 struct sd *sd = (struct sd *) gspca_dev;
1518
1519 sd->contrast = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001520 if (gspca_dev->streaming) {
1521 switch (sd->sensor) {
1522 case SENSOR_HV7131R:
1523 case SENSOR_MI0360:
1524 case SENSOR_MO4000:
1525 case SENSOR_OM6802:
1526 setcontrast(gspca_dev);
1527 break;
1528 default: /* OV76xx */
1529 setbrightcont(gspca_dev);
1530 break;
1531 }
1532 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001533 return 0;
1534}
1535
1536static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1537{
1538 struct sd *sd = (struct sd *) gspca_dev;
1539
1540 *val = sd->contrast;
1541 return 0;
1542}
1543
1544static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1545{
1546 struct sd *sd = (struct sd *) gspca_dev;
1547
1548 sd->colors = val;
1549 if (gspca_dev->streaming)
1550 setcolors(gspca_dev);
1551 return 0;
1552}
1553
1554static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1555{
1556 struct sd *sd = (struct sd *) gspca_dev;
1557
1558 *val = sd->colors;
1559 return 0;
1560}
1561
1562static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1563{
1564 struct sd *sd = (struct sd *) gspca_dev;
1565
1566 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001567 if (gspca_dev->streaming)
1568 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001569 return 0;
1570}
1571
1572static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1573{
1574 struct sd *sd = (struct sd *) gspca_dev;
1575
1576 *val = sd->autogain;
1577 return 0;
1578}
1579
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001580static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1581{
1582 struct sd *sd = (struct sd *) gspca_dev;
1583
1584 sd->vflip = val;
1585 setvflip(sd);
1586 return 0;
1587}
1588
1589static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1590{
1591 struct sd *sd = (struct sd *) gspca_dev;
1592
1593 *val = sd->vflip;
1594 return 0;
1595}
1596
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001597/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001598static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001599 .name = MODULE_NAME,
1600 .ctrls = sd_ctrls,
1601 .nctrls = ARRAY_SIZE(sd_ctrls),
1602 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001603 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001604 .start = sd_start,
1605 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001606 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001607 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001608};
1609
1610/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001611#define BSI(bridge, sensor, i2c_addr) \
1612 .driver_info = (BRIDGE_ ## bridge << 16) \
1613 | (SENSOR_ ## sensor << 8) \
1614 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001615static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001616#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001617 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001618 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001619 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1620 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1621 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1622 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001623#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001624 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1625 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1626/* bw600.inf:
1627 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1628/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1629/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1630 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1631/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1632 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1633/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1634/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1635 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1636/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1637/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1638 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1639 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
1640/* {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x??)}, */
1641/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1642/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1643/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001644 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1645/*bw600.inf:*/
1646 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001647 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001648 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001649/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001650#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001651 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001652#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001653 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001654#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001655/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1656 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1657 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1658/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001659#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001660 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001661 {}
1662};
1663MODULE_DEVICE_TABLE(usb, device_table);
1664
1665/* -- device connect -- */
1666static int sd_probe(struct usb_interface *intf,
1667 const struct usb_device_id *id)
1668{
1669 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1670 THIS_MODULE);
1671}
1672
1673static struct usb_driver sd_driver = {
1674 .name = MODULE_NAME,
1675 .id_table = device_table,
1676 .probe = sd_probe,
1677 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001678#ifdef CONFIG_PM
1679 .suspend = gspca_suspend,
1680 .resume = gspca_resume,
1681#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001682};
1683
1684/* -- module insert / remove -- */
1685static int __init sd_mod_init(void)
1686{
1687 if (usb_register(&sd_driver) < 0)
1688 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001689 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001690 return 0;
1691}
1692static void __exit sd_mod_exit(void)
1693{
1694 usb_deregister(&sd_driver);
1695 info("deregistered");
1696}
1697
1698module_init(sd_mod_init);
1699module_exit(sd_mod_exit);