blob: d1c85ce39e566ed89db4a108962c6153a131a569 [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
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300246/*Data from sn9c102p+hv7131r */
247static const u8 sn_hv7131[0x1c] = {
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,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300254/* reg18 reg19 reg1a reg1b */
255 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300256};
257
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300258static const u8 sn_mi0360[0x1c] = {
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,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300265/* reg18 reg19 reg1a reg1b */
266 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267};
268
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300269static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300270/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300271 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300272/* 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,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300276/* reg18 reg19 reg1a reg1b */
277 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300278};
279
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300280static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300281/* 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,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300287/* reg18 reg19 reg1a reg1b */
288 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300289};
290
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300291static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300292/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
293 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
294/* reg8 reg9 rega regb regc regd rege regf */
295 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
296/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
297 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300298/* reg18 reg19 reg1a reg1b */
299 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300300};
301
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300302static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300303/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300304 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300305/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300306 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300307/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300308 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300309/* reg18 reg19 reg1a reg1b */
310 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300311};
312
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300313static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300314/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
315 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
316/* reg8 reg9 rega regb regc regd rege regf */
317 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
318/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
319 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300320/* reg18 reg19 reg1a reg1b */
321 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300322};
323
324/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300325static const u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300326 sn_hv7131,
327 sn_mi0360,
328 sn_mo4000,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300329 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300330 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300331 sn_ov7648,
332 sn_ov7660
333};
334
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300335static const __u8 gamma_def[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300336 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
337 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
338};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300339
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300340/* color matrix and offsets */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300341static const __u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300342 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
343 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
344 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
345 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300346};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300347static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300348 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
349 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
350 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
351/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
352 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
353 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
354/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300355
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300356 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
357 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
358 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
359 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
360 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
361 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
362 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
363 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300364
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300365 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
366 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
367 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
368 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
369 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300370
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300371 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
372 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
373 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
374 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
375 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300376 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300377};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300378static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300379 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
380 {0xb1, 0x5d, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
381 {0xb1, 0x5d, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
382 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
383 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
384 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
385 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
386 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
387 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
388 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
389 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
390 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
391 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
392 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
394 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
395 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
396 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
397 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
398 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
399 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
401 {0xd1, 0x5d, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
402 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
403 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
404 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
405 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
406 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
407 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
408 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
409 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
410 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
411 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300412
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300413 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
414 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
415 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
416 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
417 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300418
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300419 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
420 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
421 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
422 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300423
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300424 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
425 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
426/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
427/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
428 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
429 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300430 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300431};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300432static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300433 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
434 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
435 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
436 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
437 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
438 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
439 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
444 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
449 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
450 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
451 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300453 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300454};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300455static __u8 om6802_sensor_init[][8] = {
456 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
457 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
458 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
459 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
460/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
461 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
462 /* white balance & auto-exposure */
463/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
464 * set color mode */
465/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
466 * max AGC value in AE */
467/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
468 * preset AGC */
469/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
470 * preset brightness */
471/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
472 * preset contrast */
473/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
474 * preset gamma */
475 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
476 /* luminance mode (0x4f = AE) */
477 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
478 /* preset shutter */
479/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
480 * auto frame rate */
481/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
482
483/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
484/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
485/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
486/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
487 {}
488};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300489static const __u8 ov7630_sensor_init[][8] = {
490 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
491 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
492/* win: delay 20ms */
493 {0xa1, 0x21, 0x12, 0x48, 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},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300497/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300498 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
499 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
500 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
501 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
502 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
503 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
504 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
505 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
506 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
507 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
508 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
509 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
510 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
511 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
512 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
513 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
514 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
515 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
516 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
517 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
518 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
519 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
520 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
521 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
522 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
523 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
524/* */
525 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
526 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
527/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300528/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
529 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300530 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
531 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
532 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300533/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300534 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
536 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300537/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300538 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300539/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300540 {}
541};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300542
543static const __u8 ov7648_sensor_init[][8] = {
544 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
545 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
546 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
547 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
548 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
549 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
550 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
551 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
552 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
553 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
554 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
555 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
556 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
557 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
558 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
559 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
560 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
561 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
562 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
563 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
564 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
565
566 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
567/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
568/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
569 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
570/*...*/
571/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
572/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
573 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
574 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
575/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
576/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
577/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
578/*...*/
579 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
580/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
581/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
582/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
583/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
584/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
585
586 {}
587};
588
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300589static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300590 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300591/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300592 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300593 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300594 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300595 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300596 /* GAIN BLUE RED VREF */
597 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
598 /* COM 1 BAVE GEAVE AECHH */
599 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
600 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300601 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300602 /* AECH CLKRC COM7 COM8 */
603 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
604 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
605 /* HSTART HSTOP VSTRT VSTOP */
606 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
607 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
608 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
609 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300610/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
611 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300612 /* AEW AEB VPT BBIAS */
613 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
614 /* GbBIAS RSVD EXHCH EXHCL */
615 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
616 /* RBIAS ADVFL ASDVFH YAVE */
617 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
618 /* HSYST HSYEN HREF */
619 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
620 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
621 /* ADC ACOM OFON TSLB */
622 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
623 /* COM11 COM12 COM13 COM14 */
624 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
625 /* EDGE COM15 COM16 COM17 */
626 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
627 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
628 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
629 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
630 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
631 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
632 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
633 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
634 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
635 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
636 /* LCC1 LCC2 LCC3 LCC4 */
637 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300638 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300639 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300640 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300641 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
642 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
643 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
644 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
645 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
646 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
647 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
648 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
649 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300650 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300651/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300652 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300653 /* bits[3..0]reserved */
654 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
655 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
656 /* VREF vertical frame ctrl */
657 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300658 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
659 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
660 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
661 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
662/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300663/****** (some exchanges in the win trace) ******/
664 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300665 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
666 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
667 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
668/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300669/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300670/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300671 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
672 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
673 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
674 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300675 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300676};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300677
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300678static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300679 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300680 0x06, 0x08, 0x0a, 0x11,
681 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f, 0x0c, 0x11, 0x19, 0x15,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 0x19, 0x19, 0x17, 0x15,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300683 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d, 0x23, 0x1d, 0x17, 0x17,
684 0x21, 0x2e, 0x21, 0x23,
685 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30, 0x32, 0x2e, 0x29, 0x32,
686 0x25, 0x29, 0x2c, 0x29,
687 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a, 0x0a, 0x13, 0x29, 0x1b,
688 0x17, 0x1b, 0x29, 0x29,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300689 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
690 0x29, 0x29, 0x29, 0x29,
691 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
692 0x29, 0x29, 0x29, 0x29,
693 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
694 0x29, 0x29, 0x29, 0x29
695};
696
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300697/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300698static void reg_r(struct gspca_dev *gspca_dev,
699 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300700{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300701#ifdef GSPCA_DEBUG
702 if (len > USB_BUF_SZ) {
703 err("reg_r: buffer overflow");
704 return;
705 }
706#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300707 usb_control_msg(gspca_dev->dev,
708 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300709 0,
710 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
711 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300712 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300713 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300714 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300715}
716
Jean-Francois Moine60017612008-07-18 08:46:19 -0300717static void reg_w1(struct gspca_dev *gspca_dev,
718 __u16 value,
719 __u8 data)
720{
721 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
722 gspca_dev->usb_buf[0] = data;
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 value,
728 0,
729 gspca_dev->usb_buf, 1,
730 500);
731}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300732static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300734 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300735 int len)
736{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300737 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
738 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300739#ifdef GSPCA_DEBUG
740 if (len > USB_BUF_SZ) {
741 err("reg_w: buffer overflow");
742 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300743 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300744#endif
745 memcpy(gspca_dev->usb_buf, buffer, len);
746 usb_control_msg(gspca_dev->dev,
747 usb_sndctrlpipe(gspca_dev->dev, 0),
748 0x08,
749 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
750 value, 0,
751 gspca_dev->usb_buf, len,
752 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753}
754
Jean-Francois Moine60017612008-07-18 08:46:19 -0300755/* I2C write 1 byte */
756static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300757{
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 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
761 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
762 gspca_dev->usb_buf[1] = sd->i2c_base;
763 gspca_dev->usb_buf[2] = reg;
764 gspca_dev->usb_buf[3] = val;
765 gspca_dev->usb_buf[4] = 0;
766 gspca_dev->usb_buf[5] = 0;
767 gspca_dev->usb_buf[6] = 0;
768 gspca_dev->usb_buf[7] = 0x10;
769 usb_control_msg(gspca_dev->dev,
770 usb_sndctrlpipe(gspca_dev->dev, 0),
771 0x08,
772 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
773 0x08, /* value = i2c */
774 0,
775 gspca_dev->usb_buf, 8,
776 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777}
778
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300779/* I2C write 8 bytes */
780static void i2c_w8(struct gspca_dev *gspca_dev,
781 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300782{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300783 memcpy(gspca_dev->usb_buf, buffer, 8);
784 usb_control_msg(gspca_dev->dev,
785 usb_sndctrlpipe(gspca_dev->dev, 0),
786 0x08,
787 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
788 0x08, 0, /* value, index */
789 gspca_dev->usb_buf, 8,
790 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300791 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300792}
793
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300794/* read 5 bytes in gspca_dev->usb_buf */
795static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300796{
797 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300798 __u8 mode[8];
799
Hans de Goede3647fea2008-07-15 05:36:30 -0300800 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801 mode[1] = sd->i2c_base;
802 mode[2] = reg;
803 mode[3] = 0;
804 mode[4] = 0;
805 mode[5] = 0;
806 mode[6] = 0;
807 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300808 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300809 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300810 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300811 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300812 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300813 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300814 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300815}
816
817static int probesensor(struct gspca_dev *gspca_dev)
818{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300819 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300820 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300821 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300823 i2c_r5(gspca_dev, 0); /* read sensor id */
824 if (gspca_dev->usb_buf[0] == 0x02
825 && gspca_dev->usb_buf[1] == 0x09
826 && gspca_dev->usb_buf[2] == 0x01
827 && gspca_dev->usb_buf[3] == 0x00
828 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300829 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300830 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300831 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300832 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300833 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
834 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300835 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
836 return -ENODEV;
837}
838
839static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300840 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841{
842 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300843 const __u8 *reg9a;
844 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300845 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300846 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300847 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300848 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300849
Jean-Francois Moine60017612008-07-18 08:46:19 -0300850 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300851 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300852
853 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300854 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
855 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300856 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300857 switch (sd->bridge) {
858 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859 reg9a = reg9a_sn9c325;
860 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300861 default:
862 reg9a = reg9a_def;
863 break;
864 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300865 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300866
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300867 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300868
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300869 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300870
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300871 switch (sd->sensor) {
872 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300873 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300874 reg_w1(gspca_dev, 0x01, 0x42);
875 reg_w1(gspca_dev, 0x17, 0x64);
876 reg_w1(gspca_dev, 0x01, 0x42);
877 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300878/*jfm: from win trace */
879 case SENSOR_OV7630:
880 reg_w1(gspca_dev, 0x01, 0x61);
881 reg_w1(gspca_dev, 0x17, 0xe2);
882 reg_w1(gspca_dev, 0x01, 0x60);
883 reg_w1(gspca_dev, 0x01, 0x40);
884 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300885 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -0300886 reg_w1(gspca_dev, 0x01, 0x63);
887 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300888 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300889 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300890/*jfm: from win trace */
891 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -0300892 if (sd->bridge == BRIDGE_SN9C120) {
893 reg_w1(gspca_dev, 0x01, 0x61);
894 reg_w1(gspca_dev, 0x17, 0x20);
895 reg_w1(gspca_dev, 0x01, 0x60);
896 reg_w1(gspca_dev, 0x01, 0x40);
897 break;
898 }
899 /* fall thru */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300900 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300901 reg_w1(gspca_dev, 0x01, 0x43);
902 reg_w1(gspca_dev, 0x17, 0x61);
903 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300904 if (sd->sensor == SENSOR_HV7131R) {
905 if (probesensor(gspca_dev) < 0)
906 return -ENODEV;
907 }
908 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300909 }
910 return 0;
911}
912
913static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
914{
915 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300916 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300917 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
918
919 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300920 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921 i++;
922 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300923 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300924}
925
926static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
927{
928 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300929
930 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300931 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932 i++;
933 }
934}
935
936static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
937{
938 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300939
940 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300941 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300942 i++;
943 }
944}
945
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300946static void om6802_InitSensor(struct gspca_dev *gspca_dev)
947{
948 int i = 0;
949
950 while (om6802_sensor_init[i][0]) {
951 i2c_w8(gspca_dev, om6802_sensor_init[i]);
952 i++;
953 }
954}
955
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300956static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
957{
958 int i = 0;
959
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300960 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
961 i++;
962 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300963 i++;
964 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300965 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
966 i++;
967 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
968 i++;
969 msleep(20);
970 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
971 i++;
972/*jfm:win i2c_r from 00 to 80*/
973
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300974 while (ov7630_sensor_init[i][0]) {
975 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
976 i++;
977 }
978}
979
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300980static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
981{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300982 int i = 0;
983
Jean-Francois Moine62703302008-11-11 08:42:56 -0300984 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
985 i++;
986/* win: dble reset */
987 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
988 i++;
989 msleep(20);
990/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300991 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300992 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300993 i++;
994 }
995}
996
997static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
998{
999 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001000
Jean-Francois Moine60017612008-07-18 08:46:19 -03001001 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1002 i++;
1003 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001004 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001005 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001006 i++;
1007 }
1008}
1009
1010/* this function is called at probe time */
1011static int sd_config(struct gspca_dev *gspca_dev,
1012 const struct usb_device_id *id)
1013{
1014 struct sd *sd = (struct sd *) gspca_dev;
1015 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001016
1017 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001018 cam->cam_mode = vga_mode;
1019 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001020
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001021 sd->bridge = id->driver_info >> 16;
1022 sd->sensor = id->driver_info >> 8;
1023 sd->i2c_base = id->driver_info;
1024
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001025 sd->brightness = BRIGHTNESS_DEF;
1026 sd->contrast = CONTRAST_DEF;
1027 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001028 sd->blue = BLUE_BALANCE_DEF;
1029 sd->red = RED_BALANCE_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001030 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001031 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001032 sd->vflip = VFLIP_DEF;
1033 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001034
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001035 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001036 return 0;
1037}
1038
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001039/* this function is called at probe and resume time */
1040static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001041{
1042 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001043 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -03001044 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001045
Hans de Goede3647fea2008-07-15 05:36:30 -03001046 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001047 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001048 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001049 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1050 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001051 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001052 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001053 switch (sd->bridge) {
1054 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001055 if (regF1 != 0x11)
1056 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001057 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001058 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001059 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001060 if (regF1 != 0x11)
1061 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001062 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001063 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001064 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001065 if (regF1 != 0x12)
1066 return -ENODEV;
1067 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001068 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001069 break;
1070 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001071/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001072/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001073 if (regF1 != 0x12)
1074 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001075 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001076 break;
1077 }
1078
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001079 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001080
1081 return 0;
1082}
1083
1084static unsigned int setexposure(struct gspca_dev *gspca_dev,
1085 unsigned int expo)
1086{
1087 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001088 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001089 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001090 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001091 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001092 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001093 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1094
1095 switch (sd->sensor) {
1096 case SENSOR_HV7131R: {
1097 __u8 Expodoit[] =
1098 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1099
1100 Expodoit[3] = expo >> 16;
1101 Expodoit[4] = expo >> 8;
1102 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001103 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001104 break;
1105 }
1106 case SENSOR_MI0360: {
1107 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1108 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1109
1110 if (expo > 0x0635)
1111 expo = 0x0635;
1112 else if (expo < 0x0001)
1113 expo = 0x0001;
1114 expoMi[3] = expo >> 8;
1115 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001116 i2c_w8(gspca_dev, expoMi);
1117 i2c_w8(gspca_dev, doit);
1118 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001119 break;
1120 }
1121 case SENSOR_MO4000: {
1122 __u8 expoMof[] =
1123 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1124 __u8 expoMo10[] =
1125 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1126
1127 if (expo > 0x1fff)
1128 expo = 0x1fff;
1129 else if (expo < 0x0001)
1130 expo = 0x0001;
1131 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001132 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001133 expoMo10[3] = ((expo & 0x1c00) >> 10)
1134 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001135 i2c_w8(gspca_dev, expoMo10);
1136 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001137 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001138 ((expoMo10[3] & 0x07) << 10)
1139 | (expoMof[3] << 2)
1140 | ((expoMo10[3] & 0x30) >> 4));
1141 break;
1142 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001143 case SENSOR_OM6802: {
1144 __u8 gainOm[] =
1145 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1146
1147 if (expo > 0x03ff)
1148 expo = 0x03ff;
1149 if (expo < 0x0001)
1150 expo = 0x0001;
1151 gainOm[3] = expo >> 2;
1152 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001153 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001154 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1155 break;
1156 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001157 }
1158 return expo;
1159}
1160
1161static void setbrightness(struct gspca_dev *gspca_dev)
1162{
1163 struct sd *sd = (struct sd *) gspca_dev;
1164 unsigned int expo;
1165 __u8 k2;
1166
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001167 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001168 switch (sd->sensor) {
1169 case SENSOR_HV7131R:
1170 expo = sd->brightness << 4;
1171 if (expo > 0x002dc6c0)
1172 expo = 0x002dc6c0;
1173 else if (expo < 0x02a0)
1174 expo = 0x02a0;
1175 sd->exposure = setexposure(gspca_dev, expo);
1176 break;
1177 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001178 case SENSOR_MO4000:
1179 expo = sd->brightness >> 4;
1180 sd->exposure = setexposure(gspca_dev, expo);
1181 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001182 case SENSOR_OM6802:
1183 expo = sd->brightness >> 6;
1184 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001185 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001186 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001187 }
1188
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001189 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001190}
1191
1192static void setcontrast(struct gspca_dev *gspca_dev)
1193{
1194 struct sd *sd = (struct sd *) gspca_dev;
1195 __u8 k2;
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001196 __u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001197
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001198 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1199 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001200 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001201 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001202 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001203 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001204 contrast[5] = 0;
1205 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001206}
1207
1208static void setcolors(struct gspca_dev *gspca_dev)
1209{
1210 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001211 int i, v;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001212 __u8 reg8a[12]; /* U & V gains */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001213 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1214 -24, -38, 64, /* UR UG UB */
1215 62, -51, -9 /* VR VG VB */
1216 };
1217 for (i = 0; i < 6; i++) {
1218 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001219 reg8a[i * 2] = v;
1220 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001221 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001222 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001223}
1224
1225static void setredblue(struct gspca_dev *gspca_dev)
1226{
1227 struct sd *sd = (struct sd *) gspca_dev;
1228
1229 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001230/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001231 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001232}
1233
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001234static void setautogain(struct gspca_dev *gspca_dev)
1235{
1236 struct sd *sd = (struct sd *) gspca_dev;
1237
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001238 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1239 return;
1240 if (sd->autogain)
1241 sd->ag_cnt = AG_CNT_START;
1242 else
1243 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001244}
1245
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001246static void setvflip(struct sd *sd)
1247{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001248 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1249 sd->vflip ? 0x82 : 0x02);
1250}
1251
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001252static void setinfrared(struct sd *sd)
1253{
1254/*fixme: different sequence for StarCam Clip and StarCam 370i */
1255/* Clip */
1256 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1257 sd->infrared ? 0x66 : 0x64);
1258}
1259
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001260/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001261static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001262{
1263 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001264 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001265 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001266 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001267 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001268 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1269 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001270 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001271 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001272 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001273
1274 sn9c1xx = sn_tb[(int) sd->sensor];
1275 configure_gpio(gspca_dev, sn9c1xx);
1276
Jean-Francois Moine60017612008-07-18 08:46:19 -03001277 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1278 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1279 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1280 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1281 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1282 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1283 reg_w1(gspca_dev, 0xd3, 0x50);
1284 reg_w1(gspca_dev, 0xc6, 0x00);
1285 reg_w1(gspca_dev, 0xc7, 0x00);
1286 reg_w1(gspca_dev, 0xc8, 0x50);
1287 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001288 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001289 switch (sd->sensor) {
1290 case SENSOR_OV7630:
1291 reg17 = 0xe2;
1292 break;
1293 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001294 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001295 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001296/*jfm: from win trace */
1297 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001298 if (sd->bridge == BRIDGE_SN9C120) {
1299 reg17 = 0xa0;
1300 break;
1301 }
1302 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001303 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001304 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001305 break;
1306 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001307 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001308/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001309 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1310 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1311 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001312 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001313 reg_w(gspca_dev, 0x20, gamma_def, sizeof gamma_def);
1314 for (i = 0; i < 8; i++)
1315 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001316 switch (sd->sensor) {
Jean-Francois Moine62703302008-11-11 08:42:56 -03001317 case SENSOR_OV7648:
1318 reg_w1(gspca_dev, 0x9a, 0x0a);
1319 reg_w1(gspca_dev, 0x99, 0x60);
1320 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001321 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001322 if (sd->bridge == BRIDGE_SN9C120) {
1323 reg_w1(gspca_dev, 0x9a, 0x05);
1324 break;
1325 }
1326 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001327 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001328 reg_w1(gspca_dev, 0x9a, 0x08);
1329 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001330 break;
1331 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001332
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001333 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001334 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001335 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001336 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001337 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1338 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001339 switch (sd->sensor) {
1340 case SENSOR_HV7131R:
1341 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001342 break;
1343 case SENSOR_MI0360:
1344 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001345 break;
1346 case SENSOR_MO4000:
1347 mo4000_InitSensor(gspca_dev);
1348 if (mode) {
1349/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1350 reg1 = 0x06; /* clk 24Mz */
1351 } else {
1352 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001353/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001354 }
1355 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001356 case SENSOR_OM6802:
1357 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001358 reg17 = 0x64; /* 640 MCKSIZE */
1359 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001360 case SENSOR_OV7630:
1361 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001362 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001363 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001364 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001365 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001366 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001367 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001368 reg17 = 0x21;
1369/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001370 break;
1371 default:
1372/* case SENSOR_OV7660: */
1373 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001374 if (sd->bridge == BRIDGE_SN9C120) {
1375 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001376 reg17 = 0xa2;
1377 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001378 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001379 } else {
1380 reg17 = 0x22;
1381 reg1 = 0x06; /* 24 Mhz, video trf eneble
1382 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001383 }
1384 break;
1385 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001386 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001387 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001388 switch (sd->sensor) {
1389 case SENSOR_OV7630:
1390 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001391 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001392 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001393 break;
1394 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001395 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001396 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1397 break;
1398 }
1399
1400 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001401 reg18 = sn9c1xx[0x18] | (mode << 4);
1402 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001403
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001404 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1405 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001406
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001407 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001408
Jean-Francois Moine60017612008-07-18 08:46:19 -03001409 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001410 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001411 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001412 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001413 setinfrared(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001414 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001415 case SENSOR_OV7630:
1416 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001417 break;
1418 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001419 setbrightness(gspca_dev);
1420 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001421 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001422 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001423}
1424
1425static void sd_stopN(struct gspca_dev *gspca_dev)
1426{
1427 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001428 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001429 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001430 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001431 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine62703302008-11-11 08:42:56 -03001432 static const __u8 stopov7648[] =
1433 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001434 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001435 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001436
1437 data = 0x0b;
1438 switch (sd->sensor) {
1439 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001440 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001441 data = 0x2b;
1442 break;
1443 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001444 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001445 data = 0x29;
1446 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001447 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001448 i2c_w8(gspca_dev, stopov7648);
1449 /* fall thru */
1450 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 data = 0x29;
1452 break;
1453 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001454/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001455/* case SENSOR_OV7660: */
1456 break;
1457 }
1458 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001459 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1460 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1461 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1462 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001463 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001464}
1465
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001466static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001467{
1468 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001469 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001470 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001471 __u8 luma_mean = 130;
1472 __u8 luma_delta = 20;
1473
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001474 /* Thanks S., without your advice, autobright should not work :) */
1475 if (sd->ag_cnt < 0)
1476 return;
1477 if (--sd->ag_cnt >= 0)
1478 return;
1479 sd->ag_cnt = AG_CNT_START;
1480
1481 delta = atomic_read(&sd->avg_lum);
1482 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001483 if (delta < luma_mean - luma_delta ||
1484 delta > luma_mean + luma_delta) {
1485 switch (sd->sensor) {
1486 case SENSOR_HV7131R:
1487 expotimes = sd->exposure >> 8;
1488 expotimes += (luma_mean - delta) >> 4;
1489 if (expotimes < 0)
1490 expotimes = 0;
1491 sd->exposure = setexposure(gspca_dev,
1492 (unsigned int) (expotimes << 8));
1493 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001494 default:
1495/* case SENSOR_MO4000: */
1496/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001497/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001498 expotimes = sd->exposure;
1499 expotimes += (luma_mean - delta) >> 6;
1500 if (expotimes < 0)
1501 expotimes = 0;
1502 sd->exposure = setexposure(gspca_dev,
1503 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001504 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001505 break;
1506 }
1507 }
1508}
1509
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001510/* scan the URB packets */
1511/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001512static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1513 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001514 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001515 int len) /* iso packet length */
1516{
1517 struct sd *sd = (struct sd *) gspca_dev;
1518 int sof, avg_lum;
1519
1520 sof = len - 64;
1521 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1522
1523 /* end of frame */
1524 gspca_frame_add(gspca_dev, LAST_PACKET,
1525 frame, data, sof + 2);
1526 if (sd->ag_cnt < 0)
1527 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001528/* w1 w2 w3 */
1529/* w4 w5 w6 */
1530/* w7 w8 */
1531/* w4 */
1532 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1533/* w6 */
1534 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1535/* w2 */
1536 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1537/* w8 */
1538 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1539/* w5 */
1540 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1541 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001542 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001543 return;
1544 }
1545 if (gspca_dev->last_packet_type == LAST_PACKET) {
1546
1547 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001548 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001549 }
1550 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1551}
1552
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001553static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1554{
1555 struct sd *sd = (struct sd *) gspca_dev;
1556
1557 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001558 if (gspca_dev->streaming)
1559 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001560 return 0;
1561}
1562
1563static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1564{
1565 struct sd *sd = (struct sd *) gspca_dev;
1566
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001567 *val = sd->brightness;
1568 return 0;
1569}
1570
1571static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1572{
1573 struct sd *sd = (struct sd *) gspca_dev;
1574
1575 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001576 if (gspca_dev->streaming)
1577 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001578 return 0;
1579}
1580
1581static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1582{
1583 struct sd *sd = (struct sd *) gspca_dev;
1584
1585 *val = sd->contrast;
1586 return 0;
1587}
1588
1589static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1590{
1591 struct sd *sd = (struct sd *) gspca_dev;
1592
1593 sd->colors = val;
1594 if (gspca_dev->streaming)
1595 setcolors(gspca_dev);
1596 return 0;
1597}
1598
1599static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1600{
1601 struct sd *sd = (struct sd *) gspca_dev;
1602
1603 *val = sd->colors;
1604 return 0;
1605}
1606
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001607static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1608{
1609 struct sd *sd = (struct sd *) gspca_dev;
1610
1611 sd->blue = val;
1612 if (gspca_dev->streaming)
1613 setredblue(gspca_dev);
1614 return 0;
1615}
1616
1617static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1618{
1619 struct sd *sd = (struct sd *) gspca_dev;
1620
1621 *val = sd->blue;
1622 return 0;
1623}
1624
1625static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1626{
1627 struct sd *sd = (struct sd *) gspca_dev;
1628
1629 sd->red = val;
1630 if (gspca_dev->streaming)
1631 setredblue(gspca_dev);
1632 return 0;
1633}
1634
1635static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1636{
1637 struct sd *sd = (struct sd *) gspca_dev;
1638
1639 *val = sd->red;
1640 return 0;
1641}
1642
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001643static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1644{
1645 struct sd *sd = (struct sd *) gspca_dev;
1646
1647 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001648 if (gspca_dev->streaming)
1649 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001650 return 0;
1651}
1652
1653static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1654{
1655 struct sd *sd = (struct sd *) gspca_dev;
1656
1657 *val = sd->autogain;
1658 return 0;
1659}
1660
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001661static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1662{
1663 struct sd *sd = (struct sd *) gspca_dev;
1664
1665 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001666 if (gspca_dev->streaming)
1667 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001668 return 0;
1669}
1670
1671static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1672{
1673 struct sd *sd = (struct sd *) gspca_dev;
1674
1675 *val = sd->vflip;
1676 return 0;
1677}
1678
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001679static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1680{
1681 struct sd *sd = (struct sd *) gspca_dev;
1682
1683 sd->infrared = val;
1684 if (gspca_dev->streaming)
1685 setinfrared(sd);
1686 return 0;
1687}
1688
1689static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1690{
1691 struct sd *sd = (struct sd *) gspca_dev;
1692
1693 *val = sd->infrared;
1694 return 0;
1695}
1696
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001697/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001698static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001699 .name = MODULE_NAME,
1700 .ctrls = sd_ctrls,
1701 .nctrls = ARRAY_SIZE(sd_ctrls),
1702 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001703 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001704 .start = sd_start,
1705 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001706 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001707 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001708};
1709
1710/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001711#define BSI(bridge, sensor, i2c_addr) \
1712 .driver_info = (BRIDGE_ ## bridge << 16) \
1713 | (SENSOR_ ## sensor << 8) \
1714 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001715static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001716#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001717 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001718 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001719#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001720 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1721 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001722#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001723 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001724#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001725 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001726 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03001727 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001728 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1729/* bw600.inf:
1730 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1731/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1732/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1733 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1734/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1735 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1736/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1737/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1738 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1739/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1740/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1741 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1742 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001743#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1744 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1745#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001746/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1747/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1748/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001749 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1750/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03001751 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001752 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001753 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001754/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001755#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001756 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001757#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001758 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03001759 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001760#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001761 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1762 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1763/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001764#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001765 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001766 {}
1767};
1768MODULE_DEVICE_TABLE(usb, device_table);
1769
1770/* -- device connect -- */
1771static int sd_probe(struct usb_interface *intf,
1772 const struct usb_device_id *id)
1773{
1774 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1775 THIS_MODULE);
1776}
1777
1778static struct usb_driver sd_driver = {
1779 .name = MODULE_NAME,
1780 .id_table = device_table,
1781 .probe = sd_probe,
1782 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001783#ifdef CONFIG_PM
1784 .suspend = gspca_suspend,
1785 .resume = gspca_resume,
1786#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001787};
1788
1789/* -- module insert / remove -- */
1790static int __init sd_mod_init(void)
1791{
Alexey Klimovf69e9522009-01-01 13:02:07 -03001792 int ret;
1793 ret = usb_register(&sd_driver);
1794 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03001795 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001796 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001797 return 0;
1798}
1799static void __exit sd_mod_exit(void)
1800{
1801 usb_deregister(&sd_driver);
1802 info("deregistered");
1803}
1804
1805module_init(sd_mod_init);
1806module_exit(sd_mod_exit);