blob: 9c6a874be990484bfe3f0d076714b49aff89b0bf [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 -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001206static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001207{
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 Moine72ab97c2008-09-20 06:39:08 -03001360 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001361}
1362
1363static void sd_stopN(struct gspca_dev *gspca_dev)
1364{
1365 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001366 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001367 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001368 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001369 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001370 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001371 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001372
1373 data = 0x0b;
1374 switch (sd->sensor) {
1375 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001376 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001377 data = 0x2b;
1378 break;
1379 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001380 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001381 data = 0x29;
1382 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001383 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001384 case SENSOR_OV7648:
1385 data = 0x29;
1386 break;
1387 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001388/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001389/* case SENSOR_OV7660: */
1390 break;
1391 }
1392 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001393 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1394 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1395 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1396 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001397 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001398}
1399
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001400static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001401{
1402 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001403 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001404 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001405 __u8 luma_mean = 130;
1406 __u8 luma_delta = 20;
1407
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001408 /* Thanks S., without your advice, autobright should not work :) */
1409 if (sd->ag_cnt < 0)
1410 return;
1411 if (--sd->ag_cnt >= 0)
1412 return;
1413 sd->ag_cnt = AG_CNT_START;
1414
1415 delta = atomic_read(&sd->avg_lum);
1416 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001417 if (delta < luma_mean - luma_delta ||
1418 delta > luma_mean + luma_delta) {
1419 switch (sd->sensor) {
1420 case SENSOR_HV7131R:
1421 expotimes = sd->exposure >> 8;
1422 expotimes += (luma_mean - delta) >> 4;
1423 if (expotimes < 0)
1424 expotimes = 0;
1425 sd->exposure = setexposure(gspca_dev,
1426 (unsigned int) (expotimes << 8));
1427 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001428 default:
1429/* case SENSOR_MO4000: */
1430/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001431/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001432 expotimes = sd->exposure;
1433 expotimes += (luma_mean - delta) >> 6;
1434 if (expotimes < 0)
1435 expotimes = 0;
1436 sd->exposure = setexposure(gspca_dev,
1437 (unsigned int) expotimes);
1438 setcolors(gspca_dev);
1439 break;
1440 }
1441 }
1442}
1443
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001444/* scan the URB packets */
1445/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001446static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1447 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001448 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001449 int len) /* iso packet length */
1450{
1451 struct sd *sd = (struct sd *) gspca_dev;
1452 int sof, avg_lum;
1453
1454 sof = len - 64;
1455 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1456
1457 /* end of frame */
1458 gspca_frame_add(gspca_dev, LAST_PACKET,
1459 frame, data, sof + 2);
1460 if (sd->ag_cnt < 0)
1461 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001462/* w1 w2 w3 */
1463/* w4 w5 w6 */
1464/* w7 w8 */
1465/* w4 */
1466 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1467/* w6 */
1468 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1469/* w2 */
1470 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1471/* w8 */
1472 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1473/* w5 */
1474 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1475 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001476 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001477 return;
1478 }
1479 if (gspca_dev->last_packet_type == LAST_PACKET) {
1480
1481 /* put the JPEG 422 header */
1482 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1483 }
1484 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1485}
1486
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001487static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1488{
1489 struct sd *sd = (struct sd *) gspca_dev;
1490
1491 sd->brightness = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001492 if (gspca_dev->streaming) {
1493 switch (sd->sensor) {
1494 case SENSOR_HV7131R:
1495 case SENSOR_MI0360:
1496 case SENSOR_MO4000:
1497 case SENSOR_OM6802:
1498 setbrightness(gspca_dev);
1499 break;
1500 default: /* OV76xx */
1501 setbrightcont(gspca_dev);
1502 break;
1503 }
1504 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001505 return 0;
1506}
1507
1508static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1509{
1510 struct sd *sd = (struct sd *) gspca_dev;
1511
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001512 *val = sd->brightness;
1513 return 0;
1514}
1515
1516static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1517{
1518 struct sd *sd = (struct sd *) gspca_dev;
1519
1520 sd->contrast = val;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001521 if (gspca_dev->streaming) {
1522 switch (sd->sensor) {
1523 case SENSOR_HV7131R:
1524 case SENSOR_MI0360:
1525 case SENSOR_MO4000:
1526 case SENSOR_OM6802:
1527 setcontrast(gspca_dev);
1528 break;
1529 default: /* OV76xx */
1530 setbrightcont(gspca_dev);
1531 break;
1532 }
1533 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001534 return 0;
1535}
1536
1537static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1538{
1539 struct sd *sd = (struct sd *) gspca_dev;
1540
1541 *val = sd->contrast;
1542 return 0;
1543}
1544
1545static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1546{
1547 struct sd *sd = (struct sd *) gspca_dev;
1548
1549 sd->colors = val;
1550 if (gspca_dev->streaming)
1551 setcolors(gspca_dev);
1552 return 0;
1553}
1554
1555static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1556{
1557 struct sd *sd = (struct sd *) gspca_dev;
1558
1559 *val = sd->colors;
1560 return 0;
1561}
1562
1563static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1564{
1565 struct sd *sd = (struct sd *) gspca_dev;
1566
1567 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001568 if (gspca_dev->streaming)
1569 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001570 return 0;
1571}
1572
1573static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1574{
1575 struct sd *sd = (struct sd *) gspca_dev;
1576
1577 *val = sd->autogain;
1578 return 0;
1579}
1580
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001581static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1582{
1583 struct sd *sd = (struct sd *) gspca_dev;
1584
1585 sd->vflip = val;
1586 setvflip(sd);
1587 return 0;
1588}
1589
1590static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1591{
1592 struct sd *sd = (struct sd *) gspca_dev;
1593
1594 *val = sd->vflip;
1595 return 0;
1596}
1597
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001598/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001599static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001600 .name = MODULE_NAME,
1601 .ctrls = sd_ctrls,
1602 .nctrls = ARRAY_SIZE(sd_ctrls),
1603 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001604 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001605 .start = sd_start,
1606 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001607 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001608 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001609};
1610
1611/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001612#define BSI(bridge, sensor, i2c_addr) \
1613 .driver_info = (BRIDGE_ ## bridge << 16) \
1614 | (SENSOR_ ## sensor << 8) \
1615 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001616static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001617#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001618 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001619 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001620 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1621 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
1622 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
1623 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001624#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001625 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
1626 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1627/* bw600.inf:
1628 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1629/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1630/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1631 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1632/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1633 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1634/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1635/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1636 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1637/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1638/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1639 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1640 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001641#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1642 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1643#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001644/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1645/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1646/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001647 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1648/*bw600.inf:*/
1649 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C110, OV7648, 0x21)}, /*sn9c325?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001650 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001651 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001652/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001653#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001654 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001655#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001656 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001657#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001658/* {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x??)}, */
1659 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1660 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1661/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001662#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001663 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001664 {}
1665};
1666MODULE_DEVICE_TABLE(usb, device_table);
1667
1668/* -- device connect -- */
1669static int sd_probe(struct usb_interface *intf,
1670 const struct usb_device_id *id)
1671{
1672 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1673 THIS_MODULE);
1674}
1675
1676static struct usb_driver sd_driver = {
1677 .name = MODULE_NAME,
1678 .id_table = device_table,
1679 .probe = sd_probe,
1680 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001681#ifdef CONFIG_PM
1682 .suspend = gspca_suspend,
1683 .resume = gspca_resume,
1684#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001685};
1686
1687/* -- module insert / remove -- */
1688static int __init sd_mod_init(void)
1689{
1690 if (usb_register(&sd_driver) < 0)
1691 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001692 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001693 return 0;
1694}
1695static void __exit sd_mod_exit(void)
1696{
1697 usb_deregister(&sd_driver);
1698 info("deregistered");
1699}
1700
1701module_init(sd_mod_init);
1702module_exit(sd_mod_exit);