blob: 51d68d35aa73788f882a63adf6b31bbebd25e659 [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"
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030025#define QUANT_VAL 4 /* quantization table */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030026#include "jpeg.h"
27
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030028#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030030MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
37
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030038 atomic_t avg_lum;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030039 unsigned int exposure;
40
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030041 __u16 brightness;
42 __u8 contrast;
43 __u8 colors;
44 __u8 autogain;
Jean-Francois Moine403123d2008-11-26 04:46:15 -030045 __u8 blue;
46 __u8 red;
Jean-Francois Moine6c862742008-09-08 04:57:26 -030047 __u8 vflip; /* ov7630 only */
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030048 __u8 infrared; /* mi0360 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030049
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030050 __s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030051#define AG_CNT_START 13
52
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030053 __u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030054#define BRIDGE_SN9C102P 0
55#define BRIDGE_SN9C105 1
56#define BRIDGE_SN9C110 2
57#define BRIDGE_SN9C120 3
58#define BRIDGE_SN9C325 4
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030059 __u8 sensor; /* Type of image sensor chip */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030060#define SENSOR_HV7131R 0
61#define SENSOR_MI0360 1
62#define SENSOR_MO4000 2
Jean-Francois Moined2d16e92008-09-03 16:47:23 -030063#define SENSOR_OM6802 3
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -030064#define SENSOR_OV7630 4
65#define SENSOR_OV7648 5
66#define SENSOR_OV7660 6
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030067 __u8 i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030068};
69
70/* V4L2 controls supported by the driver */
71static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
72static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
73static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
74static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
75static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
76static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030077static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
78static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
79static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
80static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030081static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
82static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030083static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
84static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030085static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030087
88static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030089 {
90 {
91 .id = V4L2_CID_BRIGHTNESS,
92 .type = V4L2_CTRL_TYPE_INTEGER,
93 .name = "Brightness",
94 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -030095#define BRIGHTNESS_MAX 0xffff
96 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030097 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -030098#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -030099 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300100 },
101 .set = sd_setbrightness,
102 .get = sd_getbrightness,
103 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300104 {
105 {
106 .id = V4L2_CID_CONTRAST,
107 .type = V4L2_CTRL_TYPE_INTEGER,
108 .name = "Contrast",
109 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300110#define CONTRAST_MAX 127
111 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300112 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300113#define CONTRAST_DEF 63
114 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300115 },
116 .set = sd_setcontrast,
117 .get = sd_getcontrast,
118 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300119 {
120 {
121 .id = V4L2_CID_SATURATION,
122 .type = V4L2_CTRL_TYPE_INTEGER,
123 .name = "Color",
124 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300125 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300126 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300127#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300128 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300129 },
130 .set = sd_setcolors,
131 .get = sd_getcolors,
132 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300133 {
134 {
135 .id = V4L2_CID_BLUE_BALANCE,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Blue Balance",
138 .minimum = 24,
139 .maximum = 40,
140 .step = 1,
141#define BLUE_BALANCE_DEF 32
142 .default_value = BLUE_BALANCE_DEF,
143 },
144 .set = sd_setblue_balance,
145 .get = sd_getblue_balance,
146 },
147 {
148 {
149 .id = V4L2_CID_RED_BALANCE,
150 .type = V4L2_CTRL_TYPE_INTEGER,
151 .name = "Red Balance",
152 .minimum = 24,
153 .maximum = 40,
154 .step = 1,
155#define RED_BALANCE_DEF 32
156 .default_value = RED_BALANCE_DEF,
157 },
158 .set = sd_setred_balance,
159 .get = sd_getred_balance,
160 },
161#define AUTOGAIN_IDX 5
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300162 {
163 {
164 .id = V4L2_CID_AUTOGAIN,
165 .type = V4L2_CTRL_TYPE_BOOLEAN,
166 .name = "Auto Gain",
167 .minimum = 0,
168 .maximum = 1,
169 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300170#define AUTOGAIN_DEF 1
171 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300172 },
173 .set = sd_setautogain,
174 .get = sd_getautogain,
175 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300176/* ov7630 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300177#define VFLIP_IDX 6
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300178 {
179 {
180 .id = V4L2_CID_VFLIP,
181 .type = V4L2_CTRL_TYPE_BOOLEAN,
182 .name = "Vflip",
183 .minimum = 0,
184 .maximum = 1,
185 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300186#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300187 .default_value = VFLIP_DEF,
188 },
189 .set = sd_setvflip,
190 .get = sd_getvflip,
191 },
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300192/* mi0360 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300193#define INFRARED_IDX 7
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300194 {
195 {
196 .id = V4L2_CID_INFRARED,
197 .type = V4L2_CTRL_TYPE_BOOLEAN,
198 .name = "Infrared",
199 .minimum = 0,
200 .maximum = 1,
201 .step = 1,
202#define INFRARED_DEF 0
203 .default_value = INFRARED_DEF,
204 },
205 .set = sd_setinfrared,
206 .get = sd_getinfrared,
207 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300208};
209
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300210/* table of the disabled controls */
211static __u32 ctrl_dis[] = {
212 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
213 /* SENSOR_HV7131R 0 */
214 (1 << VFLIP_IDX),
215 /* SENSOR_MI0360 1 */
216 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
217 /* SENSOR_MO4000 2 */
218 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
219 /* SENSOR_OM6802 3 */
220 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
221 /* SENSOR_OV7630 4 */
222 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
223 /* SENSOR_OV7648 5 */
224 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
225 /* SENSOR_OV7660 6 */
226};
227
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300228static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300229 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
230 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300231 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300232 .colorspace = V4L2_COLORSPACE_JPEG,
233 .priv = 2},
234 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
235 .bytesperline = 320,
236 .sizeimage = 320 * 240 * 3 / 8 + 590,
237 .colorspace = V4L2_COLORSPACE_JPEG,
238 .priv = 1},
239 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
240 .bytesperline = 640,
241 .sizeimage = 640 * 480 * 3 / 8 + 590,
242 .colorspace = V4L2_COLORSPACE_JPEG,
243 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300244};
245
246/*Data from sn9c102p+hv71331r */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300247static const __u8 sn_hv7131[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300248/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
249 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
250/* reg8 reg9 rega regb regc regd rege regf */
251 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
252/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
253 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
254/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
255 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300256};
257
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300258static const __u8 sn_mi0360[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300259/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
260 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
261/* reg8 reg9 rega regb regc regd rege regf */
262 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
263/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
264 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
265/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
266 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267};
268
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300269static const __u8 sn_mo4000[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300270/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
271 0x12, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
272/* reg8 reg9 rega regb regc regd rege regf */
273 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
275 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
276/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
277 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300278};
279
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300280static const __u8 sn_om6802[] = {
281/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
282 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
283/* reg8 reg9 rega regb regc regd rege regf */
284 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
285/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
286 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
287/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
288 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
289 0x08, 0x22, 0x44, 0x63, 0x7d, 0x92, 0xa3, 0xaf,
290 0xbc, 0xc4, 0xcd, 0xd5, 0xdc, 0xe1, 0xe8, 0xef,
291 0xf7
292};
293
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300294static const __u8 sn_ov7630[] = {
295/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
296 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
297/* reg8 reg9 rega regb regc regd rege regf */
298 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
299/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
300 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
301/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
302 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
303};
304
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300305static const __u8 sn_ov7648[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300306/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300307 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300308/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300309 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300310/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300311 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300312/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300313 0x0b, 0x00, 0x00, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300314};
315
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300316static const __u8 sn_ov7660[] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300317/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
318 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
319/* reg8 reg9 rega regb regc regd rege regf */
320 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
321/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
322 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
323/* reg18 reg19 reg1a reg1b reg1c reg1d reg1e reg1f */
324 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300325};
326
327/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300328static const __u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300329 sn_hv7131,
330 sn_mi0360,
331 sn_mo4000,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300332 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300333 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300334 sn_ov7648,
335 sn_ov7660
336};
337
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300338static const __u8 gamma_def[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300339 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
340 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
341};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300342
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300343/* color matrix and offsets */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300344static const __u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300345 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
346 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
347 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
348 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300349};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300350static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300351 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
352 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
353 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
354 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
355 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
356 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
357 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
358
359 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
360 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
361 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
362 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
363 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
364 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
365 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
366 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
367
368 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
369 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
370 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
371 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
372 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
373
374 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
375 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
376 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
377 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
378 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300379 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300380};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300381static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300382 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
383 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
384 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
385 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
386 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
387 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
388 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
389 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
390 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
391 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
392 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
395 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
396 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
397 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
398 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
399 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
401 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
402 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
403 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
404 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
405 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
406 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
407 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
408 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
409 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
410 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
411 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
412 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
413 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
414 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
415
416 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
417 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
418 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
419 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
420 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
421
422 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
423 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
424 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
425 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
426
427 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
428 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
429/* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
430/* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
431 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
432 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300433 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300434};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300435static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300436 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
437 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
448 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
449 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
450 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
453 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
454 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300456 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300457};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300458static __u8 om6802_sensor_init[][8] = {
459 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
460 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
461 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
462 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
463/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
464 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
465 /* white balance & auto-exposure */
466/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
467 * set color mode */
468/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
469 * max AGC value in AE */
470/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
471 * preset AGC */
472/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
473 * preset brightness */
474/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
475 * preset contrast */
476/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
477 * preset gamma */
478 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
479 /* luminance mode (0x4f = AE) */
480 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
481 /* preset shutter */
482/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
483 * auto frame rate */
484/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
485
486/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
487/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
488/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
489/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
490 {}
491};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300492static const __u8 ov7630_sensor_init[][8] = {
493 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
495/* win: delay 20ms */
496 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
498/* win: delay 20ms */
499 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300500/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300501 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
502 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
503 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
504 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
505 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
506 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
507 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
508 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
509 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
510 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
511 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
512 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
513 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
514 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
515 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
516 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
518 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
519 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
520 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
521 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
522 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
523 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
524 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
525 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
526 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
527/* */
528 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
529 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
530/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300531/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
532 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300533 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
534 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300536/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300537 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
538 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
539 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300540/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300541 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300542/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300543 {}
544};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300545
546static const __u8 ov7648_sensor_init[][8] = {
547 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
548 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
549 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
551 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
552 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
553 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
554 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
555 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
556 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
557 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
558 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
559 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
560 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
561 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
562 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
563 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
564 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
565 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
566 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
567 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
568
569 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
570/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
571/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
572 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
573/*...*/
574/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
575/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
576 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
577 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
578/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
579/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
580/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
581/*...*/
582 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
583/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
585/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
586/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
587/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
588
589 {}
590};
591
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300592static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300593 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300594/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300595 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300596 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300597 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300598 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300599 /* GAIN BLUE RED VREF */
600 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
601 /* COM 1 BAVE GEAVE AECHH */
602 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
603 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300604 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300605 /* AECH CLKRC COM7 COM8 */
606 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
607 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
608 /* HSTART HSTOP VSTRT VSTOP */
609 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
610 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
611 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
612 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300613/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
614 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300615 /* AEW AEB VPT BBIAS */
616 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
617 /* GbBIAS RSVD EXHCH EXHCL */
618 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
619 /* RBIAS ADVFL ASDVFH YAVE */
620 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
621 /* HSYST HSYEN HREF */
622 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
623 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
624 /* ADC ACOM OFON TSLB */
625 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
626 /* COM11 COM12 COM13 COM14 */
627 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
628 /* EDGE COM15 COM16 COM17 */
629 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
630 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
631 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
632 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
633 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
634 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
635 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
636 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
637 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
638 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
639 /* LCC1 LCC2 LCC3 LCC4 */
640 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300641 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300642 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300643 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300644 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
645 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
646 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
647 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
648 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
649 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
650 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
651 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
652 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300653 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300655 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300656 /* bits[3..0]reserved */
657 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
658 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
659 /* VREF vertical frame ctrl */
660 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300661 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
662 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
663 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
664 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
665/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300666/****** (some exchanges in the win trace) ******/
667 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300668 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
669 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
670 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
671/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300672/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300673/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300674 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
675 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
676 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
677 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300678 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300679};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300680
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300681static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
683 0x06, 0x08, 0x0A, 0x11,
684 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
685 0x19, 0x19, 0x17, 0x15,
686 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
687 0x21, 0x2E, 0x21, 0x23,
688 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
689 0x25, 0x29, 0x2C, 0x29,
690 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
691 0x17, 0x1B, 0x29, 0x29,
692 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
693 0x29, 0x29, 0x29, 0x29,
694 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
695 0x29, 0x29, 0x29, 0x29,
696 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
697 0x29, 0x29, 0x29, 0x29
698};
699
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300700/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300701static void reg_r(struct gspca_dev *gspca_dev,
702 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300703{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300704#ifdef GSPCA_DEBUG
705 if (len > USB_BUF_SZ) {
706 err("reg_r: buffer overflow");
707 return;
708 }
709#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300710 usb_control_msg(gspca_dev->dev,
711 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300712 0,
713 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
714 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300715 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300716 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300717 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300718}
719
Jean-Francois Moine60017612008-07-18 08:46:19 -0300720static void reg_w1(struct gspca_dev *gspca_dev,
721 __u16 value,
722 __u8 data)
723{
724 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
725 gspca_dev->usb_buf[0] = data;
726 usb_control_msg(gspca_dev->dev,
727 usb_sndctrlpipe(gspca_dev->dev, 0),
728 0x08,
729 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
730 value,
731 0,
732 gspca_dev->usb_buf, 1,
733 500);
734}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300735static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300736 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300737 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300738 int len)
739{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300740 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
741 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300742#ifdef GSPCA_DEBUG
743 if (len > USB_BUF_SZ) {
744 err("reg_w: buffer overflow");
745 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300746 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300747#endif
748 memcpy(gspca_dev->usb_buf, buffer, len);
749 usb_control_msg(gspca_dev->dev,
750 usb_sndctrlpipe(gspca_dev->dev, 0),
751 0x08,
752 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
753 value, 0,
754 gspca_dev->usb_buf, len,
755 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300756}
757
Jean-Francois Moine60017612008-07-18 08:46:19 -0300758/* I2C write 1 byte */
759static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300760{
761 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300762
Jean-Francois Moine60017612008-07-18 08:46:19 -0300763 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
764 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
765 gspca_dev->usb_buf[1] = sd->i2c_base;
766 gspca_dev->usb_buf[2] = reg;
767 gspca_dev->usb_buf[3] = val;
768 gspca_dev->usb_buf[4] = 0;
769 gspca_dev->usb_buf[5] = 0;
770 gspca_dev->usb_buf[6] = 0;
771 gspca_dev->usb_buf[7] = 0x10;
772 usb_control_msg(gspca_dev->dev,
773 usb_sndctrlpipe(gspca_dev->dev, 0),
774 0x08,
775 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
776 0x08, /* value = i2c */
777 0,
778 gspca_dev->usb_buf, 8,
779 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300780}
781
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300782/* I2C write 8 bytes */
783static void i2c_w8(struct gspca_dev *gspca_dev,
784 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300785{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300786 memcpy(gspca_dev->usb_buf, buffer, 8);
787 usb_control_msg(gspca_dev->dev,
788 usb_sndctrlpipe(gspca_dev->dev, 0),
789 0x08,
790 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
791 0x08, 0, /* value, index */
792 gspca_dev->usb_buf, 8,
793 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300794 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300795}
796
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300797/* read 5 bytes in gspca_dev->usb_buf */
798static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300799{
800 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801 __u8 mode[8];
802
Hans de Goede3647fea2008-07-15 05:36:30 -0300803 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300804 mode[1] = sd->i2c_base;
805 mode[2] = reg;
806 mode[3] = 0;
807 mode[4] = 0;
808 mode[5] = 0;
809 mode[6] = 0;
810 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300811 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300812 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300813 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300815 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300816 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300817 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300818}
819
820static int probesensor(struct gspca_dev *gspca_dev)
821{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300822 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300823 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300824 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300825 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300826 i2c_r5(gspca_dev, 0); /* read sensor id */
827 if (gspca_dev->usb_buf[0] == 0x02
828 && gspca_dev->usb_buf[1] == 0x09
829 && gspca_dev->usb_buf[2] == 0x01
830 && gspca_dev->usb_buf[3] == 0x00
831 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300832 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300833 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300834 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300835 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300836 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
837 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300838 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
839 return -ENODEV;
840}
841
842static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300843 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300844{
845 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300846 const __u8 *reg9a;
847 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300848 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300849 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300850 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300851 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300852
Jean-Francois Moine60017612008-07-18 08:46:19 -0300853 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300854 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300855
856 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300857 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
858 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300859 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300860 switch (sd->bridge) {
861 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862 reg9a = reg9a_sn9c325;
863 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300864 default:
865 reg9a = reg9a_def;
866 break;
867 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300868 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300869
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300870 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300871
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300872 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300873
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300874 switch (sd->sensor) {
875 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300876 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300877 reg_w1(gspca_dev, 0x01, 0x42);
878 reg_w1(gspca_dev, 0x17, 0x64);
879 reg_w1(gspca_dev, 0x01, 0x42);
880 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300881/*jfm: from win trace */
882 case SENSOR_OV7630:
883 reg_w1(gspca_dev, 0x01, 0x61);
884 reg_w1(gspca_dev, 0x17, 0xe2);
885 reg_w1(gspca_dev, 0x01, 0x60);
886 reg_w1(gspca_dev, 0x01, 0x40);
887 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300888 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -0300889 reg_w1(gspca_dev, 0x01, 0x63);
890 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300891 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300892 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300893/*jfm: from win trace */
894 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -0300895 if (sd->bridge == BRIDGE_SN9C120) {
896 reg_w1(gspca_dev, 0x01, 0x61);
897 reg_w1(gspca_dev, 0x17, 0x20);
898 reg_w1(gspca_dev, 0x01, 0x60);
899 reg_w1(gspca_dev, 0x01, 0x40);
900 break;
901 }
902 /* fall thru */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300903 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300904 reg_w1(gspca_dev, 0x01, 0x43);
905 reg_w1(gspca_dev, 0x17, 0x61);
906 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300907 if (sd->sensor == SENSOR_HV7131R) {
908 if (probesensor(gspca_dev) < 0)
909 return -ENODEV;
910 }
911 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300912 }
913 return 0;
914}
915
916static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
917{
918 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300919 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300920 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
921
922 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300923 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300924 i++;
925 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300926 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300927}
928
929static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
930{
931 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932
933 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300934 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300935 i++;
936 }
937}
938
939static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
940{
941 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300942
943 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300944 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300945 i++;
946 }
947}
948
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300949static void om6802_InitSensor(struct gspca_dev *gspca_dev)
950{
951 int i = 0;
952
953 while (om6802_sensor_init[i][0]) {
954 i2c_w8(gspca_dev, om6802_sensor_init[i]);
955 i++;
956 }
957}
958
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300959static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
960{
961 int i = 0;
962
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300963 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
964 i++;
965 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300966 i++;
967 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300968 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
969 i++;
970 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
971 i++;
972 msleep(20);
973 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
974 i++;
975/*jfm:win i2c_r from 00 to 80*/
976
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300977 while (ov7630_sensor_init[i][0]) {
978 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
979 i++;
980 }
981}
982
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300983static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
984{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300985 int i = 0;
986
Jean-Francois Moine62703302008-11-11 08:42:56 -0300987 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
988 i++;
989/* win: dble reset */
990 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
991 i++;
992 msleep(20);
993/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300994 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300995 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300996 i++;
997 }
998}
999
1000static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1001{
1002 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001003
Jean-Francois Moine60017612008-07-18 08:46:19 -03001004 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1005 i++;
1006 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001007 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001008 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001009 i++;
1010 }
1011}
1012
1013/* this function is called at probe time */
1014static int sd_config(struct gspca_dev *gspca_dev,
1015 const struct usb_device_id *id)
1016{
1017 struct sd *sd = (struct sd *) gspca_dev;
1018 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001019
1020 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001021 cam->cam_mode = vga_mode;
1022 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001023
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001024 sd->bridge = id->driver_info >> 16;
1025 sd->sensor = id->driver_info >> 8;
1026 sd->i2c_base = id->driver_info;
1027
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001028 sd->brightness = BRIGHTNESS_DEF;
1029 sd->contrast = CONTRAST_DEF;
1030 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001031 sd->blue = BLUE_BALANCE_DEF;
1032 sd->red = RED_BALANCE_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001033 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001034 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001035 sd->vflip = VFLIP_DEF;
1036 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001037
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001038 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001039 return 0;
1040}
1041
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001042/* this function is called at probe and resume time */
1043static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001044{
1045 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001046 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -03001047 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001048
Hans de Goede3647fea2008-07-15 05:36:30 -03001049 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001050 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001051 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001052 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1053 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001054 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001055 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001056 switch (sd->bridge) {
1057 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001058 if (regF1 != 0x11)
1059 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001060 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001061 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001062 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001063 if (regF1 != 0x11)
1064 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001065 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001066 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001067 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001068 if (regF1 != 0x12)
1069 return -ENODEV;
1070 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001071 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001072 break;
1073 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001074/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001075/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001076 if (regF1 != 0x12)
1077 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001078 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001079 break;
1080 }
1081
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001082 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001083
1084 return 0;
1085}
1086
1087static unsigned int setexposure(struct gspca_dev *gspca_dev,
1088 unsigned int expo)
1089{
1090 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001091 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001092 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001093 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001094 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001095 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001096 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1097
1098 switch (sd->sensor) {
1099 case SENSOR_HV7131R: {
1100 __u8 Expodoit[] =
1101 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1102
1103 Expodoit[3] = expo >> 16;
1104 Expodoit[4] = expo >> 8;
1105 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001106 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001107 break;
1108 }
1109 case SENSOR_MI0360: {
1110 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1111 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1112
1113 if (expo > 0x0635)
1114 expo = 0x0635;
1115 else if (expo < 0x0001)
1116 expo = 0x0001;
1117 expoMi[3] = expo >> 8;
1118 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001119 i2c_w8(gspca_dev, expoMi);
1120 i2c_w8(gspca_dev, doit);
1121 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001122 break;
1123 }
1124 case SENSOR_MO4000: {
1125 __u8 expoMof[] =
1126 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1127 __u8 expoMo10[] =
1128 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1129
1130 if (expo > 0x1fff)
1131 expo = 0x1fff;
1132 else if (expo < 0x0001)
1133 expo = 0x0001;
1134 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001135 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001136 expoMo10[3] = ((expo & 0x1c00) >> 10)
1137 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001138 i2c_w8(gspca_dev, expoMo10);
1139 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001140 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001141 ((expoMo10[3] & 0x07) << 10)
1142 | (expoMof[3] << 2)
1143 | ((expoMo10[3] & 0x30) >> 4));
1144 break;
1145 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001146 case SENSOR_OM6802: {
1147 __u8 gainOm[] =
1148 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1149
1150 if (expo > 0x03ff)
1151 expo = 0x03ff;
1152 if (expo < 0x0001)
1153 expo = 0x0001;
1154 gainOm[3] = expo >> 2;
1155 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001156 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001157 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1158 break;
1159 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001160 }
1161 return expo;
1162}
1163
1164static void setbrightness(struct gspca_dev *gspca_dev)
1165{
1166 struct sd *sd = (struct sd *) gspca_dev;
1167 unsigned int expo;
1168 __u8 k2;
1169
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001170 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001171 switch (sd->sensor) {
1172 case SENSOR_HV7131R:
1173 expo = sd->brightness << 4;
1174 if (expo > 0x002dc6c0)
1175 expo = 0x002dc6c0;
1176 else if (expo < 0x02a0)
1177 expo = 0x02a0;
1178 sd->exposure = setexposure(gspca_dev, expo);
1179 break;
1180 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001181 case SENSOR_MO4000:
1182 expo = sd->brightness >> 4;
1183 sd->exposure = setexposure(gspca_dev, expo);
1184 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001185 case SENSOR_OM6802:
1186 expo = sd->brightness >> 6;
1187 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001188 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001189 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001190 }
1191
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001192 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001193}
1194
1195static void setcontrast(struct gspca_dev *gspca_dev)
1196{
1197 struct sd *sd = (struct sd *) gspca_dev;
1198 __u8 k2;
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001199 __u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001200
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001201 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1202 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001203 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001204 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001205 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001206 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001207 contrast[5] = 0;
1208 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001209}
1210
1211static void setcolors(struct gspca_dev *gspca_dev)
1212{
1213 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001214 int i, v;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001215 __u8 reg8a[12]; /* U & V gains */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001216 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1217 -24, -38, 64, /* UR UG UB */
1218 62, -51, -9 /* VR VG VB */
1219 };
1220 for (i = 0; i < 6; i++) {
1221 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001222 reg8a[i * 2] = v;
1223 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001224 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001225 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001226}
1227
1228static void setredblue(struct gspca_dev *gspca_dev)
1229{
1230 struct sd *sd = (struct sd *) gspca_dev;
1231
1232 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001233/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001234 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001235}
1236
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001237static void setautogain(struct gspca_dev *gspca_dev)
1238{
1239 struct sd *sd = (struct sd *) gspca_dev;
1240
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001241 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1242 return;
1243 if (sd->autogain)
1244 sd->ag_cnt = AG_CNT_START;
1245 else
1246 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001247}
1248
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001249static void setvflip(struct sd *sd)
1250{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001251 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1252 sd->vflip ? 0x82 : 0x02);
1253}
1254
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001255static void setinfrared(struct sd *sd)
1256{
1257/*fixme: different sequence for StarCam Clip and StarCam 370i */
1258/* Clip */
1259 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1260 sd->infrared ? 0x66 : 0x64);
1261}
1262
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001263/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001264static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001265{
1266 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001267 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001268 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001269 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001270 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001271 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1272 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001273 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001274 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001275 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001276
1277 sn9c1xx = sn_tb[(int) sd->sensor];
1278 configure_gpio(gspca_dev, sn9c1xx);
1279
Jean-Francois Moine60017612008-07-18 08:46:19 -03001280 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1281 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1282 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1283 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1284 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1285 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1286 reg_w1(gspca_dev, 0xd3, 0x50);
1287 reg_w1(gspca_dev, 0xc6, 0x00);
1288 reg_w1(gspca_dev, 0xc7, 0x00);
1289 reg_w1(gspca_dev, 0xc8, 0x50);
1290 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001291 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001292 switch (sd->sensor) {
1293 case SENSOR_OV7630:
1294 reg17 = 0xe2;
1295 break;
1296 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001297 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001298 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001299/*jfm: from win trace */
1300 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001301 if (sd->bridge == BRIDGE_SN9C120) {
1302 reg17 = 0xa0;
1303 break;
1304 }
1305 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001306 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001307 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001308 break;
1309 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001310 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001311/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001312 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1313 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1314 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001315 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001316 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1317 for (i = 0; i < 8; i++)
1318 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001319 switch (sd->sensor) {
Jean-Francois Moine62703302008-11-11 08:42:56 -03001320 case SENSOR_OV7648:
1321 reg_w1(gspca_dev, 0x9a, 0x0a);
1322 reg_w1(gspca_dev, 0x99, 0x60);
1323 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001324 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001325 if (sd->bridge == BRIDGE_SN9C120) {
1326 reg_w1(gspca_dev, 0x9a, 0x05);
1327 break;
1328 }
1329 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001330 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001331 reg_w1(gspca_dev, 0x9a, 0x08);
1332 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001333 break;
1334 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001335
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001336 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001337 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001338 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001339 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001340 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1341 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001342 switch (sd->sensor) {
1343 case SENSOR_HV7131R:
1344 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001345 break;
1346 case SENSOR_MI0360:
1347 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001348 break;
1349 case SENSOR_MO4000:
1350 mo4000_InitSensor(gspca_dev);
1351 if (mode) {
1352/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1353 reg1 = 0x06; /* clk 24Mz */
1354 } else {
1355 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001356/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001357 }
1358 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001359 case SENSOR_OM6802:
1360 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001361 reg17 = 0x64; /* 640 MCKSIZE */
1362 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001363 case SENSOR_OV7630:
1364 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001365 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001366 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001367 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001368 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001369 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001370 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001371 reg17 = 0x21;
1372/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001373 break;
1374 default:
1375/* case SENSOR_OV7660: */
1376 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001377 if (sd->bridge == BRIDGE_SN9C120) {
1378 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001379 reg17 = 0xa2;
1380 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001381 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001382 } else {
1383 reg17 = 0x22;
1384 reg1 = 0x06; /* 24 Mhz, video trf eneble
1385 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001386 }
1387 break;
1388 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001389 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001390 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001391 switch (sd->sensor) {
1392 case SENSOR_OV7630:
1393 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001394 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001395 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001396 break;
1397 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001398 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001399 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1400 break;
1401 }
1402
1403 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001404 reg18 = sn9c1xx[0x18] | (mode << 4);
1405 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001406
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001407 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1408 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001409
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001410 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001411
Jean-Francois Moine60017612008-07-18 08:46:19 -03001412 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001413 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001414 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001415 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001416 setinfrared(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001417 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001418 case SENSOR_OV7630:
1419 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001420 break;
1421 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001422 setbrightness(gspca_dev);
1423 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001424 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001425 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001426}
1427
1428static void sd_stopN(struct gspca_dev *gspca_dev)
1429{
1430 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001431 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001432 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001433 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001434 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine62703302008-11-11 08:42:56 -03001435 static const __u8 stopov7648[] =
1436 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001437 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001438 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001439
1440 data = 0x0b;
1441 switch (sd->sensor) {
1442 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001443 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001444 data = 0x2b;
1445 break;
1446 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001447 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001448 data = 0x29;
1449 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001450 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001451 i2c_w8(gspca_dev, stopov7648);
1452 /* fall thru */
1453 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001454 data = 0x29;
1455 break;
1456 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001457/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001458/* case SENSOR_OV7660: */
1459 break;
1460 }
1461 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001462 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1463 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1464 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1465 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001466 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001467}
1468
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001469static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001470{
1471 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001472 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001473 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001474 __u8 luma_mean = 130;
1475 __u8 luma_delta = 20;
1476
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001477 /* Thanks S., without your advice, autobright should not work :) */
1478 if (sd->ag_cnt < 0)
1479 return;
1480 if (--sd->ag_cnt >= 0)
1481 return;
1482 sd->ag_cnt = AG_CNT_START;
1483
1484 delta = atomic_read(&sd->avg_lum);
1485 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001486 if (delta < luma_mean - luma_delta ||
1487 delta > luma_mean + luma_delta) {
1488 switch (sd->sensor) {
1489 case SENSOR_HV7131R:
1490 expotimes = sd->exposure >> 8;
1491 expotimes += (luma_mean - delta) >> 4;
1492 if (expotimes < 0)
1493 expotimes = 0;
1494 sd->exposure = setexposure(gspca_dev,
1495 (unsigned int) (expotimes << 8));
1496 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001497 default:
1498/* case SENSOR_MO4000: */
1499/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001500/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001501 expotimes = sd->exposure;
1502 expotimes += (luma_mean - delta) >> 6;
1503 if (expotimes < 0)
1504 expotimes = 0;
1505 sd->exposure = setexposure(gspca_dev,
1506 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001507 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001508 break;
1509 }
1510 }
1511}
1512
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001513/* scan the URB packets */
1514/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001515static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1516 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001517 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001518 int len) /* iso packet length */
1519{
1520 struct sd *sd = (struct sd *) gspca_dev;
1521 int sof, avg_lum;
1522
1523 sof = len - 64;
1524 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1525
1526 /* end of frame */
1527 gspca_frame_add(gspca_dev, LAST_PACKET,
1528 frame, data, sof + 2);
1529 if (sd->ag_cnt < 0)
1530 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001531/* w1 w2 w3 */
1532/* w4 w5 w6 */
1533/* w7 w8 */
1534/* w4 */
1535 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1536/* w6 */
1537 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1538/* w2 */
1539 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1540/* w8 */
1541 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1542/* w5 */
1543 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1544 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001545 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001546 return;
1547 }
1548 if (gspca_dev->last_packet_type == LAST_PACKET) {
1549
1550 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001551 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001552 }
1553 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1554}
1555
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001556static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1557{
1558 struct sd *sd = (struct sd *) gspca_dev;
1559
1560 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001561 if (gspca_dev->streaming)
1562 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001563 return 0;
1564}
1565
1566static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1567{
1568 struct sd *sd = (struct sd *) gspca_dev;
1569
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001570 *val = sd->brightness;
1571 return 0;
1572}
1573
1574static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1575{
1576 struct sd *sd = (struct sd *) gspca_dev;
1577
1578 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001579 if (gspca_dev->streaming)
1580 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001581 return 0;
1582}
1583
1584static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1585{
1586 struct sd *sd = (struct sd *) gspca_dev;
1587
1588 *val = sd->contrast;
1589 return 0;
1590}
1591
1592static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1593{
1594 struct sd *sd = (struct sd *) gspca_dev;
1595
1596 sd->colors = val;
1597 if (gspca_dev->streaming)
1598 setcolors(gspca_dev);
1599 return 0;
1600}
1601
1602static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1603{
1604 struct sd *sd = (struct sd *) gspca_dev;
1605
1606 *val = sd->colors;
1607 return 0;
1608}
1609
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001610static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1611{
1612 struct sd *sd = (struct sd *) gspca_dev;
1613
1614 sd->blue = val;
1615 if (gspca_dev->streaming)
1616 setredblue(gspca_dev);
1617 return 0;
1618}
1619
1620static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1621{
1622 struct sd *sd = (struct sd *) gspca_dev;
1623
1624 *val = sd->blue;
1625 return 0;
1626}
1627
1628static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1629{
1630 struct sd *sd = (struct sd *) gspca_dev;
1631
1632 sd->red = val;
1633 if (gspca_dev->streaming)
1634 setredblue(gspca_dev);
1635 return 0;
1636}
1637
1638static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1639{
1640 struct sd *sd = (struct sd *) gspca_dev;
1641
1642 *val = sd->red;
1643 return 0;
1644}
1645
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001646static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1647{
1648 struct sd *sd = (struct sd *) gspca_dev;
1649
1650 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001651 if (gspca_dev->streaming)
1652 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001653 return 0;
1654}
1655
1656static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1657{
1658 struct sd *sd = (struct sd *) gspca_dev;
1659
1660 *val = sd->autogain;
1661 return 0;
1662}
1663
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001664static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1665{
1666 struct sd *sd = (struct sd *) gspca_dev;
1667
1668 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001669 if (gspca_dev->streaming)
1670 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001671 return 0;
1672}
1673
1674static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1675{
1676 struct sd *sd = (struct sd *) gspca_dev;
1677
1678 *val = sd->vflip;
1679 return 0;
1680}
1681
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001682static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1683{
1684 struct sd *sd = (struct sd *) gspca_dev;
1685
1686 sd->infrared = val;
1687 if (gspca_dev->streaming)
1688 setinfrared(sd);
1689 return 0;
1690}
1691
1692static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1693{
1694 struct sd *sd = (struct sd *) gspca_dev;
1695
1696 *val = sd->infrared;
1697 return 0;
1698}
1699
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001700/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001701static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001702 .name = MODULE_NAME,
1703 .ctrls = sd_ctrls,
1704 .nctrls = ARRAY_SIZE(sd_ctrls),
1705 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001706 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001707 .start = sd_start,
1708 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001709 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001710 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001711};
1712
1713/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001714#define BSI(bridge, sensor, i2c_addr) \
1715 .driver_info = (BRIDGE_ ## bridge << 16) \
1716 | (SENSOR_ ## sensor << 8) \
1717 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001718static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001719#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001720 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001721 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001722#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001723 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1724 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001725#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001726 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001727#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001728 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001729 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03001730 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001731 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1732/* bw600.inf:
1733 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1734/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1735/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1736 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1737/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1738 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1739/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1740/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1741 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1742/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1743/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1744 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1745 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001746#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1747 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1748#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001749/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1750/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1751/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001752 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1753/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03001754 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001755 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001756 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001757/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001758#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001759 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001760#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001761 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03001762 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001763#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001764 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1765 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1766/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001767#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001768 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001769 {}
1770};
1771MODULE_DEVICE_TABLE(usb, device_table);
1772
1773/* -- device connect -- */
1774static int sd_probe(struct usb_interface *intf,
1775 const struct usb_device_id *id)
1776{
1777 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1778 THIS_MODULE);
1779}
1780
1781static struct usb_driver sd_driver = {
1782 .name = MODULE_NAME,
1783 .id_table = device_table,
1784 .probe = sd_probe,
1785 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001786#ifdef CONFIG_PM
1787 .suspend = gspca_suspend,
1788 .resume = gspca_resume,
1789#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001790};
1791
1792/* -- module insert / remove -- */
1793static int __init sd_mod_init(void)
1794{
Alexey Klimovf69e9522009-01-01 13:02:07 -03001795 int ret;
1796 ret = usb_register(&sd_driver);
1797 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03001798 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001799 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001800 return 0;
1801}
1802static void __exit sd_mod_exit(void)
1803{
1804 usb_deregister(&sd_driver);
1805 info("deregistered");
1806}
1807
1808module_init(sd_mod_init);
1809module_exit(sd_mod_exit);