blob: db8db0c6bbb9b29b045d506f0b8ef7a0dd902b96 [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 Moine592f4eb2009-01-15 08:01:32 -030047 u8 gamma;
Jean-Francois Moine6c862742008-09-08 04:57:26 -030048 __u8 vflip; /* ov7630 only */
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030049 __u8 infrared; /* mi0360 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030050
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030051 __s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030052#define AG_CNT_START 13
53
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030054 __u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030055#define BRIDGE_SN9C102P 0
56#define BRIDGE_SN9C105 1
57#define BRIDGE_SN9C110 2
58#define BRIDGE_SN9C120 3
59#define BRIDGE_SN9C325 4
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030060 __u8 sensor; /* Type of image sensor chip */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030061#define SENSOR_HV7131R 0
62#define SENSOR_MI0360 1
63#define SENSOR_MO4000 2
Jean-Francois Moined2d16e92008-09-03 16:47:23 -030064#define SENSOR_OM6802 3
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -030065#define SENSOR_OV7630 4
66#define SENSOR_OV7648 5
67#define SENSOR_OV7660 6
Jean-Francois Moine577cbf42008-12-05 06:18:37 -030068 __u8 i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030069};
70
71/* V4L2 controls supported by the driver */
72static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
73static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
74static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030078static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
80static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030082static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030084static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030086static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030088static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030090
91static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030092 {
93 {
94 .id = V4L2_CID_BRIGHTNESS,
95 .type = V4L2_CTRL_TYPE_INTEGER,
96 .name = "Brightness",
97 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -030098#define BRIGHTNESS_MAX 0xffff
99 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300100 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -0300101#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300102 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300103 },
104 .set = sd_setbrightness,
105 .get = sd_getbrightness,
106 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300107 {
108 {
109 .id = V4L2_CID_CONTRAST,
110 .type = V4L2_CTRL_TYPE_INTEGER,
111 .name = "Contrast",
112 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300113#define CONTRAST_MAX 127
114 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300115 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300116#define CONTRAST_DEF 63
117 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118 },
119 .set = sd_setcontrast,
120 .get = sd_getcontrast,
121 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300122 {
123 {
124 .id = V4L2_CID_SATURATION,
125 .type = V4L2_CTRL_TYPE_INTEGER,
126 .name = "Color",
127 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300128 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300129 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300130#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300131 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300132 },
133 .set = sd_setcolors,
134 .get = sd_getcolors,
135 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300136 {
137 {
138 .id = V4L2_CID_BLUE_BALANCE,
139 .type = V4L2_CTRL_TYPE_INTEGER,
140 .name = "Blue Balance",
141 .minimum = 24,
142 .maximum = 40,
143 .step = 1,
144#define BLUE_BALANCE_DEF 32
145 .default_value = BLUE_BALANCE_DEF,
146 },
147 .set = sd_setblue_balance,
148 .get = sd_getblue_balance,
149 },
150 {
151 {
152 .id = V4L2_CID_RED_BALANCE,
153 .type = V4L2_CTRL_TYPE_INTEGER,
154 .name = "Red Balance",
155 .minimum = 24,
156 .maximum = 40,
157 .step = 1,
158#define RED_BALANCE_DEF 32
159 .default_value = RED_BALANCE_DEF,
160 },
161 .set = sd_setred_balance,
162 .get = sd_getred_balance,
163 },
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300164 {
165 {
166 .id = V4L2_CID_GAMMA,
167 .type = V4L2_CTRL_TYPE_INTEGER,
168 .name = "Gamma",
169 .minimum = 0,
170 .maximum = 40,
171 .step = 1,
172#define GAMMA_DEF 20
173 .default_value = GAMMA_DEF,
174 },
175 .set = sd_setgamma,
176 .get = sd_getgamma,
177 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300178#define AUTOGAIN_IDX 5
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300179 {
180 {
181 .id = V4L2_CID_AUTOGAIN,
182 .type = V4L2_CTRL_TYPE_BOOLEAN,
183 .name = "Auto Gain",
184 .minimum = 0,
185 .maximum = 1,
186 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300187#define AUTOGAIN_DEF 1
188 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300189 },
190 .set = sd_setautogain,
191 .get = sd_getautogain,
192 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300193/* ov7630 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300194#define VFLIP_IDX 6
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300195 {
196 {
197 .id = V4L2_CID_VFLIP,
198 .type = V4L2_CTRL_TYPE_BOOLEAN,
199 .name = "Vflip",
200 .minimum = 0,
201 .maximum = 1,
202 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300203#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300204 .default_value = VFLIP_DEF,
205 },
206 .set = sd_setvflip,
207 .get = sd_getvflip,
208 },
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300209/* mi0360 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300210#define INFRARED_IDX 7
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300211 {
212 {
213 .id = V4L2_CID_INFRARED,
214 .type = V4L2_CTRL_TYPE_BOOLEAN,
215 .name = "Infrared",
216 .minimum = 0,
217 .maximum = 1,
218 .step = 1,
219#define INFRARED_DEF 0
220 .default_value = INFRARED_DEF,
221 },
222 .set = sd_setinfrared,
223 .get = sd_getinfrared,
224 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300225};
226
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300227/* table of the disabled controls */
228static __u32 ctrl_dis[] = {
229 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
230 /* SENSOR_HV7131R 0 */
231 (1 << VFLIP_IDX),
232 /* SENSOR_MI0360 1 */
233 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
234 /* SENSOR_MO4000 2 */
235 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
236 /* SENSOR_OM6802 3 */
237 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
238 /* SENSOR_OV7630 4 */
239 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
240 /* SENSOR_OV7648 5 */
241 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
242 /* SENSOR_OV7660 6 */
243};
244
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300245static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300246 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
247 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300248 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300249 .colorspace = V4L2_COLORSPACE_JPEG,
250 .priv = 2},
251 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
252 .bytesperline = 320,
253 .sizeimage = 320 * 240 * 3 / 8 + 590,
254 .colorspace = V4L2_COLORSPACE_JPEG,
255 .priv = 1},
256 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
257 .bytesperline = 640,
258 .sizeimage = 640 * 480 * 3 / 8 + 590,
259 .colorspace = V4L2_COLORSPACE_JPEG,
260 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300261};
262
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300263/*Data from sn9c102p+hv7131r */
264static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300265/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
266 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
267/* reg8 reg9 rega regb regc regd rege regf */
268 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
269/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
270 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300271/* reg18 reg19 reg1a reg1b */
272 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300273};
274
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300275static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300276/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
277 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
278/* reg8 reg9 rega regb regc regd rege regf */
279 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
280/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
281 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300282/* reg18 reg19 reg1a reg1b */
283 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300284};
285
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300286static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300287/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300288 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300289/* reg8 reg9 rega regb regc regd rege regf */
290 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
291/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
292 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300293/* reg18 reg19 reg1a reg1b */
294 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300295};
296
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300297static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300298/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
299 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
300/* reg8 reg9 rega regb regc regd rege regf */
301 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
302/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
303 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300304/* reg18 reg19 reg1a reg1b */
305 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300306};
307
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300308static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300309/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
310 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
311/* reg8 reg9 rega regb regc regd rege regf */
312 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
313/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
314 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300315/* reg18 reg19 reg1a reg1b */
316 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300317};
318
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300319static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300320/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300321 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300322/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300323 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300324/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300325 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300326/* reg18 reg19 reg1a reg1b */
327 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300328};
329
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300330static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300331/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
332 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
333/* reg8 reg9 rega regb regc regd rege regf */
334 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
335/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
336 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300337/* reg18 reg19 reg1a reg1b */
338 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300339};
340
341/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300342static const u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300343 sn_hv7131,
344 sn_mi0360,
345 sn_mo4000,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300346 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300347 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300348 sn_ov7648,
349 sn_ov7660
350};
351
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300352static const __u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300353 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
354 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
355};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300357
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300358/* color matrix and offsets */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300359static const __u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300360 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
361 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
362 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
363 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300364};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300365static const __u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300366 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
367 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
368 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
369/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
370 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
371 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
372/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300373
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300374 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
375 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
376 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
377 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
378 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
379 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
380 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
381 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300382
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300383 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
384 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
385 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
386 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
387 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300388
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300389 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
390 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
391 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
392 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
393 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300394 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300395};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300396static const __u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300397 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
398 {0xb1, 0x5d, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
399 {0xb1, 0x5d, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
400 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
401 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
402 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
403 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
404 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
405 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
406 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
407 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
408 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
409 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
410 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
411 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
412 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
413 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
414 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
415 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
416 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
417 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
418 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
419 {0xd1, 0x5d, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
420 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
422 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
423 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
424 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
425 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
426 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
428 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
429 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300430
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300431 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
432 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
433 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
434 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
435 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300436
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300437 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
438 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
439 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
440 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300441
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300442 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
443 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
444/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
445/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
446 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
447 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300448 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300449};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300450static const __u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300451 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
452 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
453 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
454 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
456 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
457 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
458 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
459 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
460 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
462 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
463 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
464 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
465 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
466 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
467 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
468 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
469 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
470 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300471 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300472};
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300473static __u8 om6802_sensor_init[][8] = {
474 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
475 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
476 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
477 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
478/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
479 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
480 /* white balance & auto-exposure */
481/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
482 * set color mode */
483/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
484 * max AGC value in AE */
485/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
486 * preset AGC */
487/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
488 * preset brightness */
489/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
490 * preset contrast */
491/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
492 * preset gamma */
493 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
494 /* luminance mode (0x4f = AE) */
495 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
496 /* preset shutter */
497/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
498 * auto frame rate */
499/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
500
501/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
502/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
503/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
504/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
505 {}
506};
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300507static const __u8 ov7630_sensor_init[][8] = {
508 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
509 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
510/* win: delay 20ms */
511 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
512 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
513/* win: delay 20ms */
514 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300515/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300516 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
517 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
518 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
519 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
520 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
521 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
522 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
523 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
524 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
525 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
526 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
527 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
528 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
529 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
530 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
531 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
532 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
533 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
534 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
535 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
536 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
537 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
538 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
539 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
540 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
541 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
542/* */
543 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
544 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
545/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300546/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
547 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300548 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
549 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
550 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300551/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300552 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
553 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
554 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300555/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300556 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300557/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300558 {}
559};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300560
561static const __u8 ov7648_sensor_init[][8] = {
562 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
563 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
564 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
565 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
566 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
567 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
568 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
569 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
570 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
571 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
572 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
573 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
574 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
575 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
576 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
577 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
578 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
579 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
580 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
581 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
582 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
583
584 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
585/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
586/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
587 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
588/*...*/
589/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
590/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
591 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
592 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
593/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
594/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
595/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
596/*...*/
597 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
598/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
599/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
600/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
601/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
602/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
603
604 {}
605};
606
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300607static const __u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300608 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300609/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300610 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300611 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300612 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300613 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300614 /* GAIN BLUE RED VREF */
615 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
616 /* COM 1 BAVE GEAVE AECHH */
617 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
618 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300619 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300620 /* AECH CLKRC COM7 COM8 */
621 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
622 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
623 /* HSTART HSTOP VSTRT VSTOP */
624 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
625 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
626 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
627 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300628/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
629 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300630 /* AEW AEB VPT BBIAS */
631 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
632 /* GbBIAS RSVD EXHCH EXHCL */
633 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
634 /* RBIAS ADVFL ASDVFH YAVE */
635 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
636 /* HSYST HSYEN HREF */
637 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
638 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
639 /* ADC ACOM OFON TSLB */
640 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
641 /* COM11 COM12 COM13 COM14 */
642 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
643 /* EDGE COM15 COM16 COM17 */
644 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
645 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
646 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
647 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
648 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
649 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
650 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
651 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
652 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
653 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
654 /* LCC1 LCC2 LCC3 LCC4 */
655 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300656 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300657 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300658 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300659 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
660 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
661 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
662 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
663 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
664 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
665 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
666 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
667 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300668 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300669/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300670 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300671 /* bits[3..0]reserved */
672 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
673 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
674 /* VREF vertical frame ctrl */
675 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300676 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
677 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
678 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
679 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
680/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300681/****** (some exchanges in the win trace) ******/
682 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300683 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
684 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
685 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
686/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300687/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300688/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300689 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
690 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
691 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
692 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300693 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300694};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300695
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300696static const __u8 qtable4[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300697 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300698 0x06, 0x08, 0x0a, 0x11,
699 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f, 0x0c, 0x11, 0x19, 0x15,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300700 0x19, 0x19, 0x17, 0x15,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300701 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d, 0x23, 0x1d, 0x17, 0x17,
702 0x21, 0x2e, 0x21, 0x23,
703 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30, 0x32, 0x2e, 0x29, 0x32,
704 0x25, 0x29, 0x2c, 0x29,
705 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a, 0x0a, 0x13, 0x29, 0x1b,
706 0x17, 0x1b, 0x29, 0x29,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300707 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
708 0x29, 0x29, 0x29, 0x29,
709 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
710 0x29, 0x29, 0x29, 0x29,
711 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
712 0x29, 0x29, 0x29, 0x29
713};
714
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300715/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300716static void reg_r(struct gspca_dev *gspca_dev,
717 __u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300718{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300719#ifdef GSPCA_DEBUG
720 if (len > USB_BUF_SZ) {
721 err("reg_r: buffer overflow");
722 return;
723 }
724#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300725 usb_control_msg(gspca_dev->dev,
726 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300727 0,
728 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
729 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300730 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300731 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300732 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733}
734
Jean-Francois Moine60017612008-07-18 08:46:19 -0300735static void reg_w1(struct gspca_dev *gspca_dev,
736 __u16 value,
737 __u8 data)
738{
739 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
740 gspca_dev->usb_buf[0] = data;
741 usb_control_msg(gspca_dev->dev,
742 usb_sndctrlpipe(gspca_dev->dev, 0),
743 0x08,
744 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
745 value,
746 0,
747 gspca_dev->usb_buf, 1,
748 500);
749}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300750static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751 __u16 value,
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300752 const __u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753 int len)
754{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300755 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
756 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300757#ifdef GSPCA_DEBUG
758 if (len > USB_BUF_SZ) {
759 err("reg_w: buffer overflow");
760 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300761 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300762#endif
763 memcpy(gspca_dev->usb_buf, buffer, len);
764 usb_control_msg(gspca_dev->dev,
765 usb_sndctrlpipe(gspca_dev->dev, 0),
766 0x08,
767 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
768 value, 0,
769 gspca_dev->usb_buf, len,
770 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300771}
772
Jean-Francois Moine60017612008-07-18 08:46:19 -0300773/* I2C write 1 byte */
774static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300775{
776 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777
Jean-Francois Moine60017612008-07-18 08:46:19 -0300778 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
779 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
780 gspca_dev->usb_buf[1] = sd->i2c_base;
781 gspca_dev->usb_buf[2] = reg;
782 gspca_dev->usb_buf[3] = val;
783 gspca_dev->usb_buf[4] = 0;
784 gspca_dev->usb_buf[5] = 0;
785 gspca_dev->usb_buf[6] = 0;
786 gspca_dev->usb_buf[7] = 0x10;
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, /* value = i2c */
792 0,
793 gspca_dev->usb_buf, 8,
794 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300795}
796
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300797/* I2C write 8 bytes */
798static void i2c_w8(struct gspca_dev *gspca_dev,
799 const __u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300800{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300801 memcpy(gspca_dev->usb_buf, buffer, 8);
802 usb_control_msg(gspca_dev->dev,
803 usb_sndctrlpipe(gspca_dev->dev, 0),
804 0x08,
805 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
806 0x08, 0, /* value, index */
807 gspca_dev->usb_buf, 8,
808 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300809 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300810}
811
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300812/* read 5 bytes in gspca_dev->usb_buf */
813static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814{
815 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300816 __u8 mode[8];
817
Hans de Goede3647fea2008-07-15 05:36:30 -0300818 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300819 mode[1] = sd->i2c_base;
820 mode[2] = reg;
821 mode[3] = 0;
822 mode[4] = 0;
823 mode[5] = 0;
824 mode[6] = 0;
825 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300826 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300827 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300828 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300829 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300830 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300831 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300832 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300833}
834
835static int probesensor(struct gspca_dev *gspca_dev)
836{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300837 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300838 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300839 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300840 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300841 i2c_r5(gspca_dev, 0); /* read sensor id */
842 if (gspca_dev->usb_buf[0] == 0x02
843 && gspca_dev->usb_buf[1] == 0x09
844 && gspca_dev->usb_buf[2] == 0x01
845 && gspca_dev->usb_buf[3] == 0x00
846 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300847 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300848 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300849 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300850 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300851 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
852 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300853 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
854 return -ENODEV;
855}
856
857static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300858 const __u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859{
860 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300861 const __u8 *reg9a;
862 static const __u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300864 static const __u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300866 static const __u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300867
Jean-Francois Moine60017612008-07-18 08:46:19 -0300868 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300869 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300870
871 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300872 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
873 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300874 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -0300875 switch (sd->bridge) {
876 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300877 reg9a = reg9a_sn9c325;
878 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300879 default:
880 reg9a = reg9a_def;
881 break;
882 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300883 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300884
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300885 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300887 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300889 switch (sd->sensor) {
890 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -0300891 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300892 reg_w1(gspca_dev, 0x01, 0x42);
893 reg_w1(gspca_dev, 0x17, 0x64);
894 reg_w1(gspca_dev, 0x01, 0x42);
895 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300896/*jfm: from win trace */
897 case SENSOR_OV7630:
898 reg_w1(gspca_dev, 0x01, 0x61);
899 reg_w1(gspca_dev, 0x17, 0xe2);
900 reg_w1(gspca_dev, 0x01, 0x60);
901 reg_w1(gspca_dev, 0x01, 0x40);
902 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300903 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -0300904 reg_w1(gspca_dev, 0x01, 0x63);
905 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300906 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300907 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300908/*jfm: from win trace */
909 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -0300910 if (sd->bridge == BRIDGE_SN9C120) {
911 reg_w1(gspca_dev, 0x01, 0x61);
912 reg_w1(gspca_dev, 0x17, 0x20);
913 reg_w1(gspca_dev, 0x01, 0x60);
914 reg_w1(gspca_dev, 0x01, 0x40);
915 break;
916 }
917 /* fall thru */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300918 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -0300919 reg_w1(gspca_dev, 0x01, 0x43);
920 reg_w1(gspca_dev, 0x17, 0x61);
921 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300922 if (sd->sensor == SENSOR_HV7131R) {
923 if (probesensor(gspca_dev) < 0)
924 return -ENODEV;
925 }
926 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300927 }
928 return 0;
929}
930
931static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
932{
933 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300934 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300935 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
936
937 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300938 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300939 i++;
940 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300941 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300942}
943
944static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
945{
946 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300947
948 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300949 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300950 i++;
951 }
952}
953
954static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
955{
956 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300957
958 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300959 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300960 i++;
961 }
962}
963
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300964static void om6802_InitSensor(struct gspca_dev *gspca_dev)
965{
966 int i = 0;
967
968 while (om6802_sensor_init[i][0]) {
969 i2c_w8(gspca_dev, om6802_sensor_init[i]);
970 i++;
971 }
972}
973
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300974static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
975{
976 int i = 0;
977
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300978 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
979 i++;
980 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300981 i++;
982 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300983 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
984 i++;
985 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
986 i++;
987 msleep(20);
988 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
989 i++;
990/*jfm:win i2c_r from 00 to 80*/
991
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300992 while (ov7630_sensor_init[i][0]) {
993 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
994 i++;
995 }
996}
997
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300998static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
999{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001000 int i = 0;
1001
Jean-Francois Moine62703302008-11-11 08:42:56 -03001002 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1003 i++;
1004/* win: dble reset */
1005 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1006 i++;
1007 msleep(20);
1008/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001009 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001010 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001011 i++;
1012 }
1013}
1014
1015static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1016{
1017 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001018
Jean-Francois Moine60017612008-07-18 08:46:19 -03001019 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1020 i++;
1021 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001022 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001023 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001024 i++;
1025 }
1026}
1027
1028/* this function is called at probe time */
1029static int sd_config(struct gspca_dev *gspca_dev,
1030 const struct usb_device_id *id)
1031{
1032 struct sd *sd = (struct sd *) gspca_dev;
1033 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001034
1035 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001036 cam->cam_mode = vga_mode;
1037 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001038
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001039 sd->bridge = id->driver_info >> 16;
1040 sd->sensor = id->driver_info >> 8;
1041 sd->i2c_base = id->driver_info;
1042
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001043 sd->brightness = BRIGHTNESS_DEF;
1044 sd->contrast = CONTRAST_DEF;
1045 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001046 sd->blue = BLUE_BALANCE_DEF;
1047 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001048 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001049 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001050 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001051 sd->vflip = VFLIP_DEF;
1052 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001053
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001054 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001055 return 0;
1056}
1057
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001058/* this function is called at probe and resume time */
1059static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001060{
1061 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001062 __u8 regGpio[] = { 0x29, 0x74 };
Jean-Francois Moine60017612008-07-18 08:46:19 -03001063 __u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001064
Hans de Goede3647fea2008-07-15 05:36:30 -03001065 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001066 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001067 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001068 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1069 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001070 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001071 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001072 switch (sd->bridge) {
1073 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001074 if (regF1 != 0x11)
1075 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001076 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001077 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001078 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001079 if (regF1 != 0x11)
1080 return -ENODEV;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001081 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001082 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001083 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001084 if (regF1 != 0x12)
1085 return -ENODEV;
1086 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001087 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001088 break;
1089 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001090/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001091/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001092 if (regF1 != 0x12)
1093 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001094 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001095 break;
1096 }
1097
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001098 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001099
1100 return 0;
1101}
1102
1103static unsigned int setexposure(struct gspca_dev *gspca_dev,
1104 unsigned int expo)
1105{
1106 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001107 static const __u8 doit[] = /* update sensor */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001108 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001109 static const __u8 sensorgo[] = /* sensor on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001110 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001111 static const __u8 gainMo[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001112 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1113
1114 switch (sd->sensor) {
1115 case SENSOR_HV7131R: {
1116 __u8 Expodoit[] =
1117 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1118
1119 Expodoit[3] = expo >> 16;
1120 Expodoit[4] = expo >> 8;
1121 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001122 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001123 break;
1124 }
1125 case SENSOR_MI0360: {
1126 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1127 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1128
1129 if (expo > 0x0635)
1130 expo = 0x0635;
1131 else if (expo < 0x0001)
1132 expo = 0x0001;
1133 expoMi[3] = expo >> 8;
1134 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001135 i2c_w8(gspca_dev, expoMi);
1136 i2c_w8(gspca_dev, doit);
1137 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001138 break;
1139 }
1140 case SENSOR_MO4000: {
1141 __u8 expoMof[] =
1142 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1143 __u8 expoMo10[] =
1144 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1145
1146 if (expo > 0x1fff)
1147 expo = 0x1fff;
1148 else if (expo < 0x0001)
1149 expo = 0x0001;
1150 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001151 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001152 expoMo10[3] = ((expo & 0x1c00) >> 10)
1153 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001154 i2c_w8(gspca_dev, expoMo10);
1155 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine956e42d2008-07-01 10:03:42 -03001156 PDEBUG(D_CONF, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001157 ((expoMo10[3] & 0x07) << 10)
1158 | (expoMof[3] << 2)
1159 | ((expoMo10[3] & 0x30) >> 4));
1160 break;
1161 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001162 case SENSOR_OM6802: {
1163 __u8 gainOm[] =
1164 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1165
1166 if (expo > 0x03ff)
1167 expo = 0x03ff;
1168 if (expo < 0x0001)
1169 expo = 0x0001;
1170 gainOm[3] = expo >> 2;
1171 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001172 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001173 PDEBUG(D_CONF, "set exposure %d", gainOm[3]);
1174 break;
1175 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001176 }
1177 return expo;
1178}
1179
1180static void setbrightness(struct gspca_dev *gspca_dev)
1181{
1182 struct sd *sd = (struct sd *) gspca_dev;
1183 unsigned int expo;
1184 __u8 k2;
1185
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001186 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001187 switch (sd->sensor) {
1188 case SENSOR_HV7131R:
1189 expo = sd->brightness << 4;
1190 if (expo > 0x002dc6c0)
1191 expo = 0x002dc6c0;
1192 else if (expo < 0x02a0)
1193 expo = 0x02a0;
1194 sd->exposure = setexposure(gspca_dev, expo);
1195 break;
1196 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001197 case SENSOR_MO4000:
1198 expo = sd->brightness >> 4;
1199 sd->exposure = setexposure(gspca_dev, expo);
1200 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001201 case SENSOR_OM6802:
1202 expo = sd->brightness >> 6;
1203 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001204 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001205 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001206 }
1207
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001208 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001209}
1210
1211static void setcontrast(struct gspca_dev *gspca_dev)
1212{
1213 struct sd *sd = (struct sd *) gspca_dev;
1214 __u8 k2;
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001215 __u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001216
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001217 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1218 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001219 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001220 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001221 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001222 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001223 contrast[5] = 0;
1224 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001225}
1226
1227static void setcolors(struct gspca_dev *gspca_dev)
1228{
1229 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001230 int i, v;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001231 __u8 reg8a[12]; /* U & V gains */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001232 static __s16 uv[6] = { /* same as reg84 in signed decimal */
1233 -24, -38, 64, /* UR UG UB */
1234 62, -51, -9 /* VR VG VB */
1235 };
1236 for (i = 0; i < 6; i++) {
1237 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001238 reg8a[i * 2] = v;
1239 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001240 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001241 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001242}
1243
1244static void setredblue(struct gspca_dev *gspca_dev)
1245{
1246 struct sd *sd = (struct sd *) gspca_dev;
1247
1248 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001249/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001250 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001251}
1252
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001253static void setgamma(struct gspca_dev *gspca_dev)
1254{
1255 struct sd *sd = (struct sd *) gspca_dev;
1256 int i;
1257 u8 gamma[17];
1258 static const u8 delta[17] = {
1259 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1260 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1261 };
1262
1263 for (i = 0; i < sizeof gamma; i++)
1264 gamma[i] = gamma_def[i]
1265 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1266 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1267}
1268
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001269static void setautogain(struct gspca_dev *gspca_dev)
1270{
1271 struct sd *sd = (struct sd *) gspca_dev;
1272
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001273 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1274 return;
1275 if (sd->autogain)
1276 sd->ag_cnt = AG_CNT_START;
1277 else
1278 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001279}
1280
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001281static void setvflip(struct sd *sd)
1282{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001283 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1284 sd->vflip ? 0x82 : 0x02);
1285}
1286
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001287static void setinfrared(struct sd *sd)
1288{
1289/*fixme: different sequence for StarCam Clip and StarCam 370i */
1290/* Clip */
1291 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1292 sd->infrared ? 0x66 : 0x64);
1293}
1294
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001295/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001296static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001297{
1298 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001299 int i;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001300 __u8 reg1, reg17, reg18;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001301 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001302 int mode;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001303 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1304 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001305 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001306 static const __u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001307 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001308
1309 sn9c1xx = sn_tb[(int) sd->sensor];
1310 configure_gpio(gspca_dev, sn9c1xx);
1311
Jean-Francois Moine60017612008-07-18 08:46:19 -03001312 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1313 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1314 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1315 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1316 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1317 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1318 reg_w1(gspca_dev, 0xd3, 0x50);
1319 reg_w1(gspca_dev, 0xc6, 0x00);
1320 reg_w1(gspca_dev, 0xc7, 0x00);
1321 reg_w1(gspca_dev, 0xc8, 0x50);
1322 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001323 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001324 switch (sd->sensor) {
1325 case SENSOR_OV7630:
1326 reg17 = 0xe2;
1327 break;
1328 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001329 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001330 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001331/*jfm: from win trace */
1332 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001333 if (sd->bridge == BRIDGE_SN9C120) {
1334 reg17 = 0xa0;
1335 break;
1336 }
1337 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001338 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001339 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001340 break;
1341 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001342 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001343/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001344 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1345 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1346 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001347 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001348 setgamma(gspca_dev);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001349 for (i = 0; i < 8; i++)
1350 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001351 switch (sd->sensor) {
Jean-Francois Moine62703302008-11-11 08:42:56 -03001352 case SENSOR_OV7648:
1353 reg_w1(gspca_dev, 0x9a, 0x0a);
1354 reg_w1(gspca_dev, 0x99, 0x60);
1355 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001356 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001357 if (sd->bridge == BRIDGE_SN9C120) {
1358 reg_w1(gspca_dev, 0x9a, 0x05);
1359 break;
1360 }
1361 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001362 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001363 reg_w1(gspca_dev, 0x9a, 0x08);
1364 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001365 break;
1366 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001367
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001368 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001369 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001370 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001371 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001372 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1373 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001374 switch (sd->sensor) {
1375 case SENSOR_HV7131R:
1376 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001377 break;
1378 case SENSOR_MI0360:
1379 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001380 break;
1381 case SENSOR_MO4000:
1382 mo4000_InitSensor(gspca_dev);
1383 if (mode) {
1384/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1385 reg1 = 0x06; /* clk 24Mz */
1386 } else {
1387 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001388/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001389 }
1390 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001391 case SENSOR_OM6802:
1392 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001393 reg17 = 0x64; /* 640 MCKSIZE */
1394 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001395 case SENSOR_OV7630:
1396 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001397 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001398 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001399 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001400 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001401 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001402 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001403 reg17 = 0x21;
1404/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001405 break;
1406 default:
1407/* case SENSOR_OV7660: */
1408 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001409 if (sd->bridge == BRIDGE_SN9C120) {
1410 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001411 reg17 = 0xa2;
1412 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001413 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001414 } else {
1415 reg17 = 0x22;
1416 reg1 = 0x06; /* 24 Mhz, video trf eneble
1417 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001418 }
1419 break;
1420 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001421 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001422 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001423 switch (sd->sensor) {
1424 case SENSOR_OV7630:
1425 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001426 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001427 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001428 break;
1429 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001430 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001431 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1432 break;
1433 }
1434
1435 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001436 reg18 = sn9c1xx[0x18] | (mode << 4);
1437 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001438
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001439 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1440 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001441
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001442 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001443
Jean-Francois Moine60017612008-07-18 08:46:19 -03001444 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001445 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001446 switch (sd->sensor) {
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001447 case SENSOR_MI0360:
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001448 setinfrared(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001449 break;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001450 case SENSOR_OV7630:
1451 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001452 break;
1453 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001454 setbrightness(gspca_dev);
1455 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001456 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001457 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001458}
1459
1460static void sd_stopN(struct gspca_dev *gspca_dev)
1461{
1462 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001463 static const __u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001464 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001465 static const __u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001466 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine62703302008-11-11 08:42:56 -03001467 static const __u8 stopov7648[] =
1468 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001469 __u8 data;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001470 const __u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001471
1472 data = 0x0b;
1473 switch (sd->sensor) {
1474 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001475 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001476 data = 0x2b;
1477 break;
1478 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001479 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001480 data = 0x29;
1481 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001482 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001483 i2c_w8(gspca_dev, stopov7648);
1484 /* fall thru */
1485 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001486 data = 0x29;
1487 break;
1488 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001489/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001490/* case SENSOR_OV7660: */
1491 break;
1492 }
1493 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001494 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1495 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1496 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1497 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001498 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001499}
1500
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001501static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001502{
1503 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001504 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001505 int expotimes;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001506 __u8 luma_mean = 130;
1507 __u8 luma_delta = 20;
1508
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001509 /* Thanks S., without your advice, autobright should not work :) */
1510 if (sd->ag_cnt < 0)
1511 return;
1512 if (--sd->ag_cnt >= 0)
1513 return;
1514 sd->ag_cnt = AG_CNT_START;
1515
1516 delta = atomic_read(&sd->avg_lum);
1517 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001518 if (delta < luma_mean - luma_delta ||
1519 delta > luma_mean + luma_delta) {
1520 switch (sd->sensor) {
1521 case SENSOR_HV7131R:
1522 expotimes = sd->exposure >> 8;
1523 expotimes += (luma_mean - delta) >> 4;
1524 if (expotimes < 0)
1525 expotimes = 0;
1526 sd->exposure = setexposure(gspca_dev,
1527 (unsigned int) (expotimes << 8));
1528 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001529 default:
1530/* case SENSOR_MO4000: */
1531/* case SENSOR_MI0360: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001532/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001533 expotimes = sd->exposure;
1534 expotimes += (luma_mean - delta) >> 6;
1535 if (expotimes < 0)
1536 expotimes = 0;
1537 sd->exposure = setexposure(gspca_dev,
1538 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001539 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001540 break;
1541 }
1542 }
1543}
1544
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001545/* scan the URB packets */
1546/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001547static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1548 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001549 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001550 int len) /* iso packet length */
1551{
1552 struct sd *sd = (struct sd *) gspca_dev;
1553 int sof, avg_lum;
1554
1555 sof = len - 64;
1556 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1557
1558 /* end of frame */
1559 gspca_frame_add(gspca_dev, LAST_PACKET,
1560 frame, data, sof + 2);
1561 if (sd->ag_cnt < 0)
1562 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001563/* w1 w2 w3 */
1564/* w4 w5 w6 */
1565/* w7 w8 */
1566/* w4 */
1567 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1568/* w6 */
1569 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1570/* w2 */
1571 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1572/* w8 */
1573 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1574/* w5 */
1575 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1576 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001577 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001578 return;
1579 }
1580 if (gspca_dev->last_packet_type == LAST_PACKET) {
1581
1582 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001583 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001584 }
1585 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1586}
1587
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001588static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1589{
1590 struct sd *sd = (struct sd *) gspca_dev;
1591
1592 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001593 if (gspca_dev->streaming)
1594 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001595 return 0;
1596}
1597
1598static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1599{
1600 struct sd *sd = (struct sd *) gspca_dev;
1601
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001602 *val = sd->brightness;
1603 return 0;
1604}
1605
1606static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1607{
1608 struct sd *sd = (struct sd *) gspca_dev;
1609
1610 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001611 if (gspca_dev->streaming)
1612 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001613 return 0;
1614}
1615
1616static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1617{
1618 struct sd *sd = (struct sd *) gspca_dev;
1619
1620 *val = sd->contrast;
1621 return 0;
1622}
1623
1624static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1625{
1626 struct sd *sd = (struct sd *) gspca_dev;
1627
1628 sd->colors = val;
1629 if (gspca_dev->streaming)
1630 setcolors(gspca_dev);
1631 return 0;
1632}
1633
1634static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1635{
1636 struct sd *sd = (struct sd *) gspca_dev;
1637
1638 *val = sd->colors;
1639 return 0;
1640}
1641
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001642static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1643{
1644 struct sd *sd = (struct sd *) gspca_dev;
1645
1646 sd->blue = val;
1647 if (gspca_dev->streaming)
1648 setredblue(gspca_dev);
1649 return 0;
1650}
1651
1652static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1653{
1654 struct sd *sd = (struct sd *) gspca_dev;
1655
1656 *val = sd->blue;
1657 return 0;
1658}
1659
1660static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1661{
1662 struct sd *sd = (struct sd *) gspca_dev;
1663
1664 sd->red = val;
1665 if (gspca_dev->streaming)
1666 setredblue(gspca_dev);
1667 return 0;
1668}
1669
1670static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1671{
1672 struct sd *sd = (struct sd *) gspca_dev;
1673
1674 *val = sd->red;
1675 return 0;
1676}
1677
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001678static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1679{
1680 struct sd *sd = (struct sd *) gspca_dev;
1681
1682 sd->gamma = val;
1683 if (gspca_dev->streaming)
1684 setgamma(gspca_dev);
1685 return 0;
1686}
1687
1688static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1689{
1690 struct sd *sd = (struct sd *) gspca_dev;
1691
1692 *val = sd->gamma;
1693 return 0;
1694}
1695
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001696static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1697{
1698 struct sd *sd = (struct sd *) gspca_dev;
1699
1700 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001701 if (gspca_dev->streaming)
1702 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001703 return 0;
1704}
1705
1706static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1707{
1708 struct sd *sd = (struct sd *) gspca_dev;
1709
1710 *val = sd->autogain;
1711 return 0;
1712}
1713
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001714static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
1715{
1716 struct sd *sd = (struct sd *) gspca_dev;
1717
1718 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001719 if (gspca_dev->streaming)
1720 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001721 return 0;
1722}
1723
1724static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
1725{
1726 struct sd *sd = (struct sd *) gspca_dev;
1727
1728 *val = sd->vflip;
1729 return 0;
1730}
1731
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001732static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
1733{
1734 struct sd *sd = (struct sd *) gspca_dev;
1735
1736 sd->infrared = val;
1737 if (gspca_dev->streaming)
1738 setinfrared(sd);
1739 return 0;
1740}
1741
1742static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
1743{
1744 struct sd *sd = (struct sd *) gspca_dev;
1745
1746 *val = sd->infrared;
1747 return 0;
1748}
1749
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001750/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001751static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001752 .name = MODULE_NAME,
1753 .ctrls = sd_ctrls,
1754 .nctrls = ARRAY_SIZE(sd_ctrls),
1755 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001756 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001757 .start = sd_start,
1758 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001759 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001760 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001761};
1762
1763/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001764#define BSI(bridge, sensor, i2c_addr) \
1765 .driver_info = (BRIDGE_ ## bridge << 16) \
1766 | (SENSOR_ ## sensor << 8) \
1767 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001768static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03001769#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001770 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03001771 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001772#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001773 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
1774 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03001775#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001776 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001777#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03001778 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001779 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03001780 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001781 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
1782/* bw600.inf:
1783 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
1784/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
1785/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
1786 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
1787/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
1788 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
1789/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
1790/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
1791 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
1792/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
1793/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
1794 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
1795 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03001796#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1797 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
1798#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001799/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
1800/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
1801/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001802 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
1803/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03001804 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001805 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001806 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001807/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03001808#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001809 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001810#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001811 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03001812 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03001813#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001814 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
1815 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
1816/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03001817#endif
Jean-Francois Moinee546f4b2008-07-26 03:43:59 -03001818 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001819 {}
1820};
1821MODULE_DEVICE_TABLE(usb, device_table);
1822
1823/* -- device connect -- */
1824static int sd_probe(struct usb_interface *intf,
1825 const struct usb_device_id *id)
1826{
1827 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1828 THIS_MODULE);
1829}
1830
1831static struct usb_driver sd_driver = {
1832 .name = MODULE_NAME,
1833 .id_table = device_table,
1834 .probe = sd_probe,
1835 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001836#ifdef CONFIG_PM
1837 .suspend = gspca_suspend,
1838 .resume = gspca_resume,
1839#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001840};
1841
1842/* -- module insert / remove -- */
1843static int __init sd_mod_init(void)
1844{
Alexey Klimovf69e9522009-01-01 13:02:07 -03001845 int ret;
1846 ret = usb_register(&sd_driver);
1847 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03001848 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001849 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001850 return 0;
1851}
1852static void __exit sd_mod_exit(void)
1853{
1854 usb_deregister(&sd_driver);
1855 info("deregistered");
1856}
1857
1858module_init(sd_mod_init);
1859module_exit(sd_mod_exit);