blob: 4101a240e4810613c47179277ad7f2370e874d50 [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 Moine98819182009-01-19 07:37:33 -030039 u32 exposure;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030040
Jean-Francois Moine98819182009-01-19 07:37:33 -030041 u16 brightness;
42 u8 contrast;
43 u8 colors;
44 u8 autogain;
45 u8 blue;
46 u8 red;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030047 u8 gamma;
Jean-Francois Moine98819182009-01-19 07:37:33 -030048 u8 vflip; /* ov7630 only */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -030049 u8 infrared; /* mt9v111 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030050
Jean-Francois Moine98819182009-01-19 07:37:33 -030051 s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030052#define AG_CNT_START 13
53
Jean-Francois Moine98819182009-01-19 07:37:33 -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 Moine98819182009-01-19 07:37:33 -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 Moine3ef2c5b2009-01-29 04:59:45 -030064#define SENSOR_MT9V111 3
65#define SENSOR_OM6802 4
66#define SENSOR_OV7630 5
67#define SENSOR_OV7648 6
68#define SENSOR_OV7660 7
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -030069#define SENSOR_SP80708 8
Jean-Francois Moine98819182009-01-19 07:37:33 -030070 u8 i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030071};
72
73/* V4L2 controls supported by the driver */
74static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030080static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030084static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030086static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030088static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030090static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030092
93static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030094 {
95 {
96 .id = V4L2_CID_BRIGHTNESS,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Brightness",
99 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300100#define BRIGHTNESS_MAX 0xffff
101 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300102 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -0300103#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300104 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300105 },
106 .set = sd_setbrightness,
107 .get = sd_getbrightness,
108 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300109 {
110 {
111 .id = V4L2_CID_CONTRAST,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Contrast",
114 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300115#define CONTRAST_MAX 127
116 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300117 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300118#define CONTRAST_DEF 63
119 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120 },
121 .set = sd_setcontrast,
122 .get = sd_getcontrast,
123 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300124 {
125 {
126 .id = V4L2_CID_SATURATION,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Color",
129 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300130 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300131 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300132#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300133 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300134 },
135 .set = sd_setcolors,
136 .get = sd_getcolors,
137 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300138 {
139 {
140 .id = V4L2_CID_BLUE_BALANCE,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Blue Balance",
143 .minimum = 24,
144 .maximum = 40,
145 .step = 1,
146#define BLUE_BALANCE_DEF 32
147 .default_value = BLUE_BALANCE_DEF,
148 },
149 .set = sd_setblue_balance,
150 .get = sd_getblue_balance,
151 },
152 {
153 {
154 .id = V4L2_CID_RED_BALANCE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Red Balance",
157 .minimum = 24,
158 .maximum = 40,
159 .step = 1,
160#define RED_BALANCE_DEF 32
161 .default_value = RED_BALANCE_DEF,
162 },
163 .set = sd_setred_balance,
164 .get = sd_getred_balance,
165 },
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300166 {
167 {
168 .id = V4L2_CID_GAMMA,
169 .type = V4L2_CTRL_TYPE_INTEGER,
170 .name = "Gamma",
171 .minimum = 0,
172 .maximum = 40,
173 .step = 1,
174#define GAMMA_DEF 20
175 .default_value = GAMMA_DEF,
176 },
177 .set = sd_setgamma,
178 .get = sd_getgamma,
179 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300180#define AUTOGAIN_IDX 5
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300181 {
182 {
183 .id = V4L2_CID_AUTOGAIN,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
185 .name = "Auto Gain",
186 .minimum = 0,
187 .maximum = 1,
188 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300189#define AUTOGAIN_DEF 1
190 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300191 },
192 .set = sd_setautogain,
193 .get = sd_getautogain,
194 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300195/* ov7630 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300196#define VFLIP_IDX 6
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300197 {
198 {
199 .id = V4L2_CID_VFLIP,
200 .type = V4L2_CTRL_TYPE_BOOLEAN,
201 .name = "Vflip",
202 .minimum = 0,
203 .maximum = 1,
204 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300205#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300206 .default_value = VFLIP_DEF,
207 },
208 .set = sd_setvflip,
209 .get = sd_getvflip,
210 },
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300211/* mt9v111 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300212#define INFRARED_IDX 7
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300213 {
214 {
215 .id = V4L2_CID_INFRARED,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "Infrared",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221#define INFRARED_DEF 0
222 .default_value = INFRARED_DEF,
223 },
224 .set = sd_setinfrared,
225 .get = sd_getinfrared,
226 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300227};
228
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300229/* table of the disabled controls */
230static __u32 ctrl_dis[] = {
231 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
232 /* SENSOR_HV7131R 0 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300233 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300234 /* SENSOR_MI0360 1 */
235 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
236 /* SENSOR_MO4000 2 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300237 (1 << AUTOGAIN_IDX),
238 /* SENSOR_MT9V111 3 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300239 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300240 /* SENSOR_OM6802 4 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300241 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300242 /* SENSOR_OV7630 5 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300243 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300244 /* SENSOR_OV7648 6 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300245 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300246 /* SENSOR_OV7660 7 */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300247 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
248 /* SENSOR_SP80708 8 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300249};
250
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300251static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300252 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
253 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300254 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300255 .colorspace = V4L2_COLORSPACE_JPEG,
256 .priv = 2},
257 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
258 .bytesperline = 320,
259 .sizeimage = 320 * 240 * 3 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
261 .priv = 1},
262 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
263 .bytesperline = 640,
264 .sizeimage = 640 * 480 * 3 / 8 + 590,
265 .colorspace = V4L2_COLORSPACE_JPEG,
266 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267};
268
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300269/*Data from sn9c102p+hv7131r */
270static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300271/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
272 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
273/* reg8 reg9 rega regb regc regd rege regf */
274 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
275/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
276 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300277/* reg18 reg19 reg1a reg1b */
278 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300279};
280
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300281static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300282/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
283 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
284/* reg8 reg9 rega regb regc regd rege regf */
285 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
286/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
287 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300288/* reg18 reg19 reg1a reg1b */
289 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300290};
291
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300292static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300293/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300294 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300295/* reg8 reg9 rega regb regc regd rege regf */
296 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
298 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300299/* reg18 reg19 reg1a reg1b */
300 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300301};
302
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300303static const u8 sn_mt9v111[0x1c] = {
304/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
306/* reg8 reg9 rega regb regc regd rege regf */
307 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
308/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
310/* reg18 reg19 reg1a reg1b */
311 0x06, 0x00, 0x00, 0x00
312};
313
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300314static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300315/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
317/* reg8 reg9 rega regb regc regd rege regf */
318 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300321/* reg18 reg19 reg1a reg1b */
322 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300323};
324
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300325static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300326/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
327 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
328/* reg8 reg9 rega regb regc regd rege regf */
329 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
330/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
331 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300332/* reg18 reg19 reg1a reg1b */
333 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300334};
335
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300336static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300337/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300338 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300339/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300340 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300341/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300342 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300343/* reg18 reg19 reg1a reg1b */
344 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300345};
346
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300347static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
350/* reg8 reg9 rega regb regc regd rege regf */
351 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
352/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
353 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300354/* reg18 reg19 reg1a reg1b */
355 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356};
357
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300358static const u8 sn_sp80708[0x1c] = {
359/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
361/* reg8 reg9 rega regb regc regd rege regf */
362 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
363/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
365/* reg18 reg19 reg1a reg1b */
366 0x07, 0x00, 0x00, 0x00
367};
368
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300369/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300370static const u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300371 sn_hv7131,
372 sn_mi0360,
373 sn_mo4000,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300374 sn_mt9v111,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300375 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300376 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300377 sn_ov7648,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300378 sn_ov7660,
379 sn_sp80708
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300380};
381
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300382/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300383static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
385 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
386};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300387/* gamma for sensors HV7131R and MT9V111 */
388static const u8 gamma_spec_1[17] = {
389 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
390 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
391};
392/* gamma for sensor SP80708 */
393static const u8 gamma_spec_2[17] = {
394 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
395 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
396};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300397
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300398/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300399static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300400 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
401 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
402 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
403 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300404};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300405static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300406 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
407 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
408 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
409/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
410 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
411 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
412/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300413
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300414 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
416 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
417 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
418 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
419 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
420 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
421 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300422
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300423 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300428
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300429 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300434 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300435};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300436static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300437 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300438 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300439 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300440 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
441 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
442 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
443 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
444 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
449 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
454 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
456 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300459 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300460 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
462 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
463 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
464 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
465 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
466 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
469 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300470
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300471 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
472 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
473 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
474 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
475 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300476
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300477 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
478 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
479 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
480 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300481
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300482 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
483 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
484/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
485/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
486 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
487 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300488 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300489};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300490static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300491 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
502 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
503 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
504 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
505 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
506 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
508 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
509 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
510 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300511 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300512};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300513static const u8 mt9v111_sensor_init[][8] = {
514 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
515 /* delay 20 ms */
516 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
518 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
519 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
520 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
521 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
522 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
523 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
524 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
525 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
526 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
527 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
528 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
529 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
530 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
531 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
532 /*******/
533 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
534 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */
536 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
537 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
538 /*******/
539 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
540 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
541 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
542 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
543 {}
544};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300545static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300546 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
547 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
548 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
549 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
550/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
551 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
552 /* white balance & auto-exposure */
553/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
554 * set color mode */
555/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
556 * max AGC value in AE */
557/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
558 * preset AGC */
559/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
560 * preset brightness */
561/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
562 * preset contrast */
563/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
564 * preset gamma */
565 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
566 /* luminance mode (0x4f = AE) */
567 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
568 /* preset shutter */
569/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
570 * auto frame rate */
571/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
572
573/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
574/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
575/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
576/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
577 {}
578};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300579static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300580 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
581 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
582/* win: delay 20ms */
583 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
584 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
585/* win: delay 20ms */
586 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300587/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300588 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
589 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
590 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
591 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
592 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
593 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
594 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
595 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
596 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
597 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
598 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
599 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
600 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
601 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
602 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
603 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
605 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
606 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
607 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
608 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
609 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
610 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
611 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
612 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
613 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
614/* */
615 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
616 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
617/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300618/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
619 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300620 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
621 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
622 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300623/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300624 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300627/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300628 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300629/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300630 {}
631};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300632
Jean-Francois Moine98819182009-01-19 07:37:33 -0300633static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300634 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
636 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
637 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
638 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
639 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
640 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
641 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
642 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
643 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
644 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
645 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
646 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
647 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
648 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
649 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
650 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
651 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
652 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
653 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
654 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
655
656 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
657/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
658/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
659 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
660/*...*/
661/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
662/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
663 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
664 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
665/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
666/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
667/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
668/*...*/
669 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
670/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
671/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
672/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
673/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
674/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
675
676 {}
677};
678
Jean-Francois Moine98819182009-01-19 07:37:33 -0300679static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300680 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300681/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300683 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300684 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300685 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686 /* GAIN BLUE RED VREF */
687 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
688 /* COM 1 BAVE GEAVE AECHH */
689 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
690 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300691 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300692 /* AECH CLKRC COM7 COM8 */
693 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
694 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
695 /* HSTART HSTOP VSTRT VSTOP */
696 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
697 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
698 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
699 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300700/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
701 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300702 /* AEW AEB VPT BBIAS */
703 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
704 /* GbBIAS RSVD EXHCH EXHCL */
705 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
706 /* RBIAS ADVFL ASDVFH YAVE */
707 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
708 /* HSYST HSYEN HREF */
709 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
710 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
711 /* ADC ACOM OFON TSLB */
712 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
713 /* COM11 COM12 COM13 COM14 */
714 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
715 /* EDGE COM15 COM16 COM17 */
716 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
717 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
718 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
719 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
720 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
721 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
722 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
723 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
724 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
725 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
726 /* LCC1 LCC2 LCC3 LCC4 */
727 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300728 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300729 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300730 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300731 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
732 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
733 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
734 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
735 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
736 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
737 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
738 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
739 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300740 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300741/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300742 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300743 /* bits[3..0]reserved */
744 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
745 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
746 /* VREF vertical frame ctrl */
747 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300748 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
749 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
750 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
751 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
752/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753/****** (some exchanges in the win trace) ******/
754 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300755 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
756 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
757 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
758/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300759/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300760/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300761 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
762 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
763 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
764 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300765 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300766};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300767
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300768static const u8 sp80708_sensor_init[][8] = {
769 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
770 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
771 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
776 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
777 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
778 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
779 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
840 /********/
841 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
847 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
848 {}
849};
850
Jean-Francois Moine98819182009-01-19 07:37:33 -0300851static const u8 qtable4[] = {
852 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
853 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
854 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
855 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
856 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
857 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
858 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
859 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
860 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
861 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
862 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
863 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
864 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
865 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
866 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
867 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300868};
869
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300870/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300871static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300872 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300873{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300874#ifdef GSPCA_DEBUG
875 if (len > USB_BUF_SZ) {
876 err("reg_r: buffer overflow");
877 return;
878 }
879#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300880 usb_control_msg(gspca_dev->dev,
881 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300882 0,
883 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
884 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300885 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300887 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888}
889
Jean-Francois Moine60017612008-07-18 08:46:19 -0300890static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300891 u16 value,
892 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -0300893{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300894 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300895 gspca_dev->usb_buf[0] = data;
896 usb_control_msg(gspca_dev->dev,
897 usb_sndctrlpipe(gspca_dev->dev, 0),
898 0x08,
899 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
900 value,
901 0,
902 gspca_dev->usb_buf, 1,
903 500);
904}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300905static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300906 u16 value,
907 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300908 int len)
909{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300910 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -0300911 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300912#ifdef GSPCA_DEBUG
913 if (len > USB_BUF_SZ) {
914 err("reg_w: buffer overflow");
915 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300916 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300917#endif
918 memcpy(gspca_dev->usb_buf, buffer, len);
919 usb_control_msg(gspca_dev->dev,
920 usb_sndctrlpipe(gspca_dev->dev, 0),
921 0x08,
922 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
923 value, 0,
924 gspca_dev->usb_buf, len,
925 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300926}
927
Jean-Francois Moine60017612008-07-18 08:46:19 -0300928/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300929static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930{
931 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932
Jean-Francois Moine60017612008-07-18 08:46:19 -0300933 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
934 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
935 gspca_dev->usb_buf[1] = sd->i2c_base;
936 gspca_dev->usb_buf[2] = reg;
937 gspca_dev->usb_buf[3] = val;
938 gspca_dev->usb_buf[4] = 0;
939 gspca_dev->usb_buf[5] = 0;
940 gspca_dev->usb_buf[6] = 0;
941 gspca_dev->usb_buf[7] = 0x10;
942 usb_control_msg(gspca_dev->dev,
943 usb_sndctrlpipe(gspca_dev->dev, 0),
944 0x08,
945 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
946 0x08, /* value = i2c */
947 0,
948 gspca_dev->usb_buf, 8,
949 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300950}
951
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300952/* I2C write 8 bytes */
953static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300954 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300955{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300956 memcpy(gspca_dev->usb_buf, buffer, 8);
957 usb_control_msg(gspca_dev->dev,
958 usb_sndctrlpipe(gspca_dev->dev, 0),
959 0x08,
960 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
961 0x08, 0, /* value, index */
962 gspca_dev->usb_buf, 8,
963 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300964 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300965}
966
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300967/* read 5 bytes in gspca_dev->usb_buf */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300968static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300969{
970 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -0300971 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300972
Hans de Goede3647fea2008-07-15 05:36:30 -0300973 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300974 mode[1] = sd->i2c_base;
975 mode[2] = reg;
976 mode[3] = 0;
977 mode[4] = 0;
978 mode[5] = 0;
979 mode[6] = 0;
980 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300981 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300982 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300983 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300984 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300985 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300986 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300987 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300988}
989
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300990static int hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300991{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300992 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300993 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300994 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300995 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300996 i2c_r5(gspca_dev, 0); /* read sensor id */
997 if (gspca_dev->usb_buf[0] == 0x02
998 && gspca_dev->usb_buf[1] == 0x09
999 && gspca_dev->usb_buf[2] == 0x01
1000 && gspca_dev->usb_buf[3] == 0x00
1001 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001002 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001003 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001004 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001005 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001006 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1007 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001008 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1009 return -ENODEV;
1010}
1011
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001012static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001013{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001014 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001015 int i, j;
1016 u16 val;
1017 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001018 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001019 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1020 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1021 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1022 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1023 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001024 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001025 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1026 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1027 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1028 {}
1029 },
1030 };
1031
1032 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1033 reg_w1(gspca_dev, 0x17, 0x62);
1034 reg_w1(gspca_dev, 0x01, 0x08);
1035 for (j = 0; j < 3; j++)
1036 i2c_w8(gspca_dev, probe_tb[i][j]);
1037 msleep(2);
1038 reg_r(gspca_dev, 0x0a, 5);
1039 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1040 if (probe_tb[i][3][0] != 0)
1041 i2c_w8(gspca_dev, probe_tb[i][3]);
1042 reg_w1(gspca_dev, 0x01, 0x29);
1043 reg_w1(gspca_dev, 0x17, 0x42);
1044 if (val != 0xffff)
1045 break;
1046 }
1047 switch (val) {
1048 case 0x823a:
1049 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001050 sd->sensor = SENSOR_MT9V111;
1051 sd->i2c_base = 0x5c;
1052 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001053 case 0x8243:
1054 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001055 break;
1056 default:
1057 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1058 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001059 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001060}
1061
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001062static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001063 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001064{
1065 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001066 const u8 *reg9a;
1067 static const u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001068 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001069 static const u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001070 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001071 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001072
Jean-Francois Moine60017612008-07-18 08:46:19 -03001073 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001074 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001075
1076 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001077 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1078 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001079 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -03001080 switch (sd->bridge) {
1081 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001082 reg9a = reg9a_sn9c325;
1083 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001084 default:
1085 reg9a = reg9a_def;
1086 break;
1087 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001088 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001089
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001090 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001091
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001092 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001093
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001094 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001095 case SENSOR_MT9V111:
1096 reg_w1(gspca_dev, 0x01, 0x61);
1097 reg_w1(gspca_dev, 0x17, 0x61);
1098 reg_w1(gspca_dev, 0x01, 0x60);
1099 reg_w1(gspca_dev, 0x01, 0x40);
1100 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001101 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -03001102 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001103 reg_w1(gspca_dev, 0x01, 0x42);
1104 reg_w1(gspca_dev, 0x17, 0x64);
1105 reg_w1(gspca_dev, 0x01, 0x42);
1106 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001107/*jfm: from win trace */
1108 case SENSOR_OV7630:
1109 reg_w1(gspca_dev, 0x01, 0x61);
1110 reg_w1(gspca_dev, 0x17, 0xe2);
1111 reg_w1(gspca_dev, 0x01, 0x60);
1112 reg_w1(gspca_dev, 0x01, 0x40);
1113 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001114 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001115 reg_w1(gspca_dev, 0x01, 0x63);
1116 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001117 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001118 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001119/*jfm: from win trace */
1120 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001121 if (sd->bridge == BRIDGE_SN9C120) {
1122 reg_w1(gspca_dev, 0x01, 0x61);
1123 reg_w1(gspca_dev, 0x17, 0x20);
1124 reg_w1(gspca_dev, 0x01, 0x60);
1125 reg_w1(gspca_dev, 0x01, 0x40);
1126 break;
1127 }
1128 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001129 case SENSOR_SP80708:
1130 reg_w1(gspca_dev, 0x01, 0x63);
1131 reg_w1(gspca_dev, 0x17, 0x20);
1132 reg_w1(gspca_dev, 0x01, 0x62);
1133 reg_w1(gspca_dev, 0x01, 0x42);
1134 mdelay(100);
1135 reg_w1(gspca_dev, 0x02, 0x62);
1136 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001137 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001138 reg_w1(gspca_dev, 0x01, 0x43);
1139 reg_w1(gspca_dev, 0x17, 0x61);
1140 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001141 if (sd->sensor == SENSOR_HV7131R) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001142 if (hv7131r_probe(gspca_dev) < 0)
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001143 return -ENODEV;
1144 }
1145 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001146 }
1147 return 0;
1148}
1149
1150static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1151{
1152 int i = 0;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001153 static const u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001154 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1155
1156 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001157 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001158 i++;
1159 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001160 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001161}
1162
1163static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1164{
1165 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001166
1167 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001168 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001169 i++;
1170 }
1171}
1172
1173static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1174{
1175 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001176
1177 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001178 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001179 i++;
1180 }
1181}
1182
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001183static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1184{
1185 int i = 0;
1186
1187 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1188 i++;
1189 msleep(20);
1190 while (mt9v111_sensor_init[i][0]) {
1191 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1192 i++;
1193 }
1194}
1195
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001196static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1197{
1198 int i = 0;
1199
1200 while (om6802_sensor_init[i][0]) {
1201 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1202 i++;
1203 }
1204}
1205
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001206static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1207{
1208 int i = 0;
1209
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001210 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1211 i++;
1212 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001213 i++;
1214 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001215 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1216 i++;
1217 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1218 i++;
1219 msleep(20);
1220 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1221 i++;
1222/*jfm:win i2c_r from 00 to 80*/
1223
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001224 while (ov7630_sensor_init[i][0]) {
1225 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1226 i++;
1227 }
1228}
1229
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001230static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1231{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001232 int i = 0;
1233
Jean-Francois Moine62703302008-11-11 08:42:56 -03001234 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1235 i++;
1236/* win: dble reset */
1237 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1238 i++;
1239 msleep(20);
1240/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001241 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001242 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001243 i++;
1244 }
1245}
1246
1247static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1248{
1249 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001250
Jean-Francois Moine60017612008-07-18 08:46:19 -03001251 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1252 i++;
1253 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001254 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001255 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001256 i++;
1257 }
1258}
1259
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001260static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1261{
1262 int i = 0;
1263
1264 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1265 i++;
1266 msleep(20);
1267 while (sp80708_sensor_init[i][0]) {
1268 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1269 i++;
1270 }
1271}
1272
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001273/* this function is called at probe time */
1274static int sd_config(struct gspca_dev *gspca_dev,
1275 const struct usb_device_id *id)
1276{
1277 struct sd *sd = (struct sd *) gspca_dev;
1278 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001279
1280 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001281 cam->cam_mode = vga_mode;
1282 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001283
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001284 sd->bridge = id->driver_info >> 16;
1285 sd->sensor = id->driver_info >> 8;
1286 sd->i2c_base = id->driver_info;
1287
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001288 sd->brightness = BRIGHTNESS_DEF;
1289 sd->contrast = CONTRAST_DEF;
1290 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001291 sd->blue = BLUE_BALANCE_DEF;
1292 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001293 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001294 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001295 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001296 sd->vflip = VFLIP_DEF;
1297 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001298
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001299 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001300 return 0;
1301}
1302
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001303/* this function is called at probe and resume time */
1304static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001305{
1306 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001307 u8 regGpio[] = { 0x29, 0x74 };
1308 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001309
Hans de Goede3647fea2008-07-15 05:36:30 -03001310 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001311 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001312 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001313 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1314 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001315 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001316 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001317 switch (sd->bridge) {
1318 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001319 if (regF1 != 0x11)
1320 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001321 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001322 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001323 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001324 if (regF1 != 0x11)
1325 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001326 if (sd->sensor == SENSOR_MI0360)
1327 mi0360_probe(gspca_dev);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001328 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001329 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001330 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001331 if (regF1 != 0x12)
1332 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001333 if (sd->sensor == SENSOR_MI0360)
1334 mi0360_probe(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001335 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001336 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001337 break;
1338 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001339/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001340/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001341 if (regF1 != 0x12)
1342 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001343 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001344 break;
1345 }
1346
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001347 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001348
1349 return 0;
1350}
1351
Jean-Francois Moine98819182009-01-19 07:37:33 -03001352static u32 setexposure(struct gspca_dev *gspca_dev,
1353 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001354{
1355 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001356
1357 switch (sd->sensor) {
1358 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001359 u8 Expodoit[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001360 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1361
1362 Expodoit[3] = expo >> 16;
1363 Expodoit[4] = expo >> 8;
1364 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001365 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001366 break;
1367 }
1368 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001369 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001370 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001371 static const u8 doit[] = /* update sensor */
1372 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1373 static const u8 sensorgo[] = /* sensor on */
1374 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001375
1376 if (expo > 0x0635)
1377 expo = 0x0635;
1378 else if (expo < 0x0001)
1379 expo = 0x0001;
1380 expoMi[3] = expo >> 8;
1381 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001382 i2c_w8(gspca_dev, expoMi);
1383 i2c_w8(gspca_dev, doit);
1384 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001385 break;
1386 }
1387 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001388 u8 expoMof[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001389 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001390 u8 expoMo10[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001391 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001392 static const u8 gainMo[] =
1393 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001394
1395 if (expo > 0x1fff)
1396 expo = 0x1fff;
1397 else if (expo < 0x0001)
1398 expo = 0x0001;
1399 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001400 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001401 expoMo10[3] = ((expo & 0x1c00) >> 10)
1402 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001403 i2c_w8(gspca_dev, expoMo10);
1404 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001405 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001406 ((expoMo10[3] & 0x07) << 10)
1407 | (expoMof[3] << 2)
1408 | ((expoMo10[3] & 0x30) >> 4));
1409 break;
1410 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001411 case SENSOR_MT9V111: {
1412 u8 expo_c1[] =
1413 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1414
1415 if (expo > 0x0280)
1416 expo = 0x0280;
1417 else if (expo < 0x0040)
1418 expo = 0x0040;
1419 expo_c1[3] = expo >> 8;
1420 expo_c1[4] = expo;
1421 i2c_w8(gspca_dev, expo_c1);
1422 break;
1423 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001424 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001425 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001426 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1427
1428 if (expo > 0x03ff)
1429 expo = 0x03ff;
1430 if (expo < 0x0001)
1431 expo = 0x0001;
1432 gainOm[3] = expo >> 2;
1433 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001434 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001435 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001436 break;
1437 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001438 }
1439 return expo;
1440}
1441
1442static void setbrightness(struct gspca_dev *gspca_dev)
1443{
1444 struct sd *sd = (struct sd *) gspca_dev;
1445 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001446 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001447
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001448 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001449 switch (sd->sensor) {
1450 case SENSOR_HV7131R:
1451 expo = sd->brightness << 4;
1452 if (expo > 0x002dc6c0)
1453 expo = 0x002dc6c0;
1454 else if (expo < 0x02a0)
1455 expo = 0x02a0;
1456 sd->exposure = setexposure(gspca_dev, expo);
1457 break;
1458 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001459 case SENSOR_MO4000:
1460 expo = sd->brightness >> 4;
1461 sd->exposure = setexposure(gspca_dev, expo);
1462 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001463 case SENSOR_MT9V111:
1464 expo = sd->brightness >> 8;
1465 sd->exposure = setexposure(gspca_dev, expo);
1466 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001467 case SENSOR_OM6802:
1468 expo = sd->brightness >> 6;
1469 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001470 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001471 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001472 }
1473
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001474 if (sd->sensor != SENSOR_MT9V111)
1475 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001476}
1477
1478static void setcontrast(struct gspca_dev *gspca_dev)
1479{
1480 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001481 u8 k2;
1482 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001483
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001484 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1485 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001486 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001487 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001488 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001489 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001490 contrast[5] = 0;
1491 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001492}
1493
1494static void setcolors(struct gspca_dev *gspca_dev)
1495{
1496 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001497 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001498 u8 reg8a[12]; /* U & V gains */
1499 static s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001500 -24, -38, 64, /* UR UG UB */
1501 62, -51, -9 /* VR VG VB */
1502 };
1503 for (i = 0; i < 6; i++) {
1504 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001505 reg8a[i * 2] = v;
1506 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001507 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001508 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001509}
1510
1511static void setredblue(struct gspca_dev *gspca_dev)
1512{
1513 struct sd *sd = (struct sd *) gspca_dev;
1514
1515 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001516/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001517 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001518}
1519
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001520static void setgamma(struct gspca_dev *gspca_dev)
1521{
1522 struct sd *sd = (struct sd *) gspca_dev;
1523 int i;
1524 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001525 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001526 static const u8 delta[17] = {
1527 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1528 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1529 };
1530
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001531 switch (sd->sensor) {
1532 case SENSOR_HV7131R:
1533 case SENSOR_MT9V111:
1534 gamma_base = gamma_spec_1;
1535 break;
1536 case SENSOR_SP80708:
1537 gamma_base = gamma_spec_2;
1538 break;
1539 default:
1540 gamma_base = gamma_def;
1541 break;
1542 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001543
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001544 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001545 gamma[i] = gamma_base[i]
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001546 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1547 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1548}
1549
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001550static void setautogain(struct gspca_dev *gspca_dev)
1551{
1552 struct sd *sd = (struct sd *) gspca_dev;
1553
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001554 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1555 return;
1556 if (sd->autogain)
1557 sd->ag_cnt = AG_CNT_START;
1558 else
1559 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001560}
1561
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001562static void setvflip(struct sd *sd)
1563{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001564 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1565 sd->vflip ? 0x82 : 0x02);
1566}
1567
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001568static void setinfrared(struct sd *sd)
1569{
1570/*fixme: different sequence for StarCam Clip and StarCam 370i */
1571/* Clip */
1572 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1573 sd->infrared ? 0x66 : 0x64);
1574}
1575
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001576/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001577static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001578{
1579 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001580 int i;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001581 u8 reg1, reg17, reg18;
1582 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001583 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001584 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1585 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1586 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1587 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001588 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001589
1590 sn9c1xx = sn_tb[(int) sd->sensor];
1591 configure_gpio(gspca_dev, sn9c1xx);
1592
Jean-Francois Moine60017612008-07-18 08:46:19 -03001593 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1594 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1595 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1596 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1597 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1598 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1599 reg_w1(gspca_dev, 0xd3, 0x50);
1600 reg_w1(gspca_dev, 0xc6, 0x00);
1601 reg_w1(gspca_dev, 0xc7, 0x00);
1602 reg_w1(gspca_dev, 0xc8, 0x50);
1603 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001604 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001605 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001606 case SENSOR_MT9V111:
1607 reg17 = 0xe0;
1608 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001609 case SENSOR_OV7630:
1610 reg17 = 0xe2;
1611 break;
1612 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001613 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001614 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001615/*jfm: from win trace */
1616 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001617 if (sd->bridge == BRIDGE_SN9C120) {
1618 reg17 = 0xa0;
1619 break;
1620 }
1621 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001622 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001623 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001624 break;
1625 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001626 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001627/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001628 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1629 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1630 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001631 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001632
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001633 setgamma(gspca_dev);
1634
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001635 for (i = 0; i < 8; i++)
1636 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001637 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001638 case SENSOR_MT9V111:
1639 reg_w1(gspca_dev, 0x9a, 0x07);
1640 reg_w1(gspca_dev, 0x99, 0x59);
1641 break;
Jean-Francois Moine62703302008-11-11 08:42:56 -03001642 case SENSOR_OV7648:
1643 reg_w1(gspca_dev, 0x9a, 0x0a);
1644 reg_w1(gspca_dev, 0x99, 0x60);
1645 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001646 case SENSOR_SP80708:
1647 reg_w1(gspca_dev, 0x9a, 0x05);
1648 reg_w1(gspca_dev, 0x99, 0x59);
1649 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001650 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001651 if (sd->bridge == BRIDGE_SN9C120) {
1652 reg_w1(gspca_dev, 0x9a, 0x05);
1653 break;
1654 }
1655 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001656 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001657 reg_w1(gspca_dev, 0x9a, 0x08);
1658 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001659 break;
1660 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001661
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001662 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001663 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001664 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001665 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001666 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1667 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001668 switch (sd->sensor) {
1669 case SENSOR_HV7131R:
1670 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001671 break;
1672 case SENSOR_MI0360:
1673 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001674 break;
1675 case SENSOR_MO4000:
1676 mo4000_InitSensor(gspca_dev);
1677 if (mode) {
1678/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1679 reg1 = 0x06; /* clk 24Mz */
1680 } else {
1681 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001682/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001683 }
1684 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001685 case SENSOR_MT9V111:
1686 mt9v111_InitSensor(gspca_dev);
1687 if (mode) {
1688 reg1 = 0x04; /* 320 clk 48Mhz */
1689 } else {
1690/* reg1 = 0x06; * 640 clk 24Mz (done) */
1691 reg17 = 0xe2;
1692 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03001693 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001694 case SENSOR_OM6802:
1695 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001696 reg17 = 0x64; /* 640 MCKSIZE */
1697 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001698 case SENSOR_OV7630:
1699 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001700 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001701 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001702 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001703 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001704 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001705 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001706 reg17 = 0x21;
1707/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001708 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001709 case SENSOR_OV7660:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001710 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001711 if (sd->bridge == BRIDGE_SN9C120) {
1712 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001713 reg17 = 0xa2;
1714 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001715 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001716 } else {
1717 reg17 = 0x22;
1718 reg1 = 0x06; /* 24 Mhz, video trf eneble
1719 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001720 }
1721 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001722 default:
1723/* case SENSOR_SP80708: */
1724 sp80708_InitSensor(gspca_dev);
1725 if (mode) {
1726/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001727 } else {
1728 reg1 = 0x46; /* 640 clk 48Mz */
1729 reg17 = 0xa2;
1730 }
1731 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001732 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001733 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001734 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001735 switch (sd->sensor) {
1736 case SENSOR_OV7630:
1737 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001738 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001739 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001740 break;
1741 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001742 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001743 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1744 break;
1745 }
1746
1747 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001748 reg18 = sn9c1xx[0x18] | (mode << 4);
1749 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001750
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001751 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1752 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001753
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001754 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001755
Jean-Francois Moine60017612008-07-18 08:46:19 -03001756 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001757 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001758 switch (sd->sensor) {
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001759 case SENSOR_OV7630:
1760 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001761 break;
1762 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001763 setbrightness(gspca_dev);
1764 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001765 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001766 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001767}
1768
1769static void sd_stopN(struct gspca_dev *gspca_dev)
1770{
1771 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001772 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001773 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001774 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001775 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001776 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03001777 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001778 u8 data;
1779 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001780
1781 data = 0x0b;
1782 switch (sd->sensor) {
1783 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001784 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001785 data = 0x2b;
1786 break;
1787 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001788 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001789 data = 0x29;
1790 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001791 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001792 i2c_w8(gspca_dev, stopov7648);
1793 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001794 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001795 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001796 data = 0x29;
1797 break;
1798 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001799/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001800/* case SENSOR_OV7660: */
1801 break;
1802 }
1803 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001804 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1805 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1806 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1807 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001808 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001809}
1810
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001811static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001812{
1813 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001814 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001815 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001816 u8 luma_mean = 130;
1817 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001818
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001819 /* Thanks S., without your advice, autobright should not work :) */
1820 if (sd->ag_cnt < 0)
1821 return;
1822 if (--sd->ag_cnt >= 0)
1823 return;
1824 sd->ag_cnt = AG_CNT_START;
1825
1826 delta = atomic_read(&sd->avg_lum);
1827 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001828 if (delta < luma_mean - luma_delta ||
1829 delta > luma_mean + luma_delta) {
1830 switch (sd->sensor) {
1831 case SENSOR_HV7131R:
1832 expotimes = sd->exposure >> 8;
1833 expotimes += (luma_mean - delta) >> 4;
1834 if (expotimes < 0)
1835 expotimes = 0;
1836 sd->exposure = setexposure(gspca_dev,
1837 (unsigned int) (expotimes << 8));
1838 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001839 default:
1840/* case SENSOR_MO4000: */
1841/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001842/* case SENSOR_MT9V111: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001843/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001844 expotimes = sd->exposure;
1845 expotimes += (luma_mean - delta) >> 6;
1846 if (expotimes < 0)
1847 expotimes = 0;
1848 sd->exposure = setexposure(gspca_dev,
1849 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001850 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001851 break;
1852 }
1853 }
1854}
1855
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001856/* scan the URB packets */
1857/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001858static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1859 struct gspca_frame *frame, /* target */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001860 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001861 int len) /* iso packet length */
1862{
1863 struct sd *sd = (struct sd *) gspca_dev;
1864 int sof, avg_lum;
1865
1866 sof = len - 64;
1867 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1868
1869 /* end of frame */
1870 gspca_frame_add(gspca_dev, LAST_PACKET,
1871 frame, data, sof + 2);
1872 if (sd->ag_cnt < 0)
1873 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001874/* w1 w2 w3 */
1875/* w4 w5 w6 */
1876/* w7 w8 */
1877/* w4 */
1878 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1879/* w6 */
1880 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1881/* w2 */
1882 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1883/* w8 */
1884 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1885/* w5 */
1886 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1887 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001888 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001889 return;
1890 }
1891 if (gspca_dev->last_packet_type == LAST_PACKET) {
1892
1893 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001894 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001895 }
1896 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1897}
1898
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001899static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1900{
1901 struct sd *sd = (struct sd *) gspca_dev;
1902
1903 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001904 if (gspca_dev->streaming)
1905 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001906 return 0;
1907}
1908
1909static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1910{
1911 struct sd *sd = (struct sd *) gspca_dev;
1912
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001913 *val = sd->brightness;
1914 return 0;
1915}
1916
1917static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1918{
1919 struct sd *sd = (struct sd *) gspca_dev;
1920
1921 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001922 if (gspca_dev->streaming)
1923 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001924 return 0;
1925}
1926
1927static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1928{
1929 struct sd *sd = (struct sd *) gspca_dev;
1930
1931 *val = sd->contrast;
1932 return 0;
1933}
1934
1935static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1936{
1937 struct sd *sd = (struct sd *) gspca_dev;
1938
1939 sd->colors = val;
1940 if (gspca_dev->streaming)
1941 setcolors(gspca_dev);
1942 return 0;
1943}
1944
1945static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1946{
1947 struct sd *sd = (struct sd *) gspca_dev;
1948
1949 *val = sd->colors;
1950 return 0;
1951}
1952
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001953static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1954{
1955 struct sd *sd = (struct sd *) gspca_dev;
1956
1957 sd->blue = val;
1958 if (gspca_dev->streaming)
1959 setredblue(gspca_dev);
1960 return 0;
1961}
1962
1963static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1964{
1965 struct sd *sd = (struct sd *) gspca_dev;
1966
1967 *val = sd->blue;
1968 return 0;
1969}
1970
1971static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1972{
1973 struct sd *sd = (struct sd *) gspca_dev;
1974
1975 sd->red = val;
1976 if (gspca_dev->streaming)
1977 setredblue(gspca_dev);
1978 return 0;
1979}
1980
1981static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1982{
1983 struct sd *sd = (struct sd *) gspca_dev;
1984
1985 *val = sd->red;
1986 return 0;
1987}
1988
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001989static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1990{
1991 struct sd *sd = (struct sd *) gspca_dev;
1992
1993 sd->gamma = val;
1994 if (gspca_dev->streaming)
1995 setgamma(gspca_dev);
1996 return 0;
1997}
1998
1999static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2000{
2001 struct sd *sd = (struct sd *) gspca_dev;
2002
2003 *val = sd->gamma;
2004 return 0;
2005}
2006
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002007static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2008{
2009 struct sd *sd = (struct sd *) gspca_dev;
2010
2011 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002012 if (gspca_dev->streaming)
2013 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002014 return 0;
2015}
2016
2017static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2018{
2019 struct sd *sd = (struct sd *) gspca_dev;
2020
2021 *val = sd->autogain;
2022 return 0;
2023}
2024
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002025static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2026{
2027 struct sd *sd = (struct sd *) gspca_dev;
2028
2029 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002030 if (gspca_dev->streaming)
2031 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002032 return 0;
2033}
2034
2035static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2036{
2037 struct sd *sd = (struct sd *) gspca_dev;
2038
2039 *val = sd->vflip;
2040 return 0;
2041}
2042
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002043static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2044{
2045 struct sd *sd = (struct sd *) gspca_dev;
2046
2047 sd->infrared = val;
2048 if (gspca_dev->streaming)
2049 setinfrared(sd);
2050 return 0;
2051}
2052
2053static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2054{
2055 struct sd *sd = (struct sd *) gspca_dev;
2056
2057 *val = sd->infrared;
2058 return 0;
2059}
2060
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002061/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002062static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002063 .name = MODULE_NAME,
2064 .ctrls = sd_ctrls,
2065 .nctrls = ARRAY_SIZE(sd_ctrls),
2066 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002067 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002068 .start = sd_start,
2069 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002070 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002071 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002072};
2073
2074/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002075#define BSI(bridge, sensor, i2c_addr) \
2076 .driver_info = (BRIDGE_ ## bridge << 16) \
2077 | (SENSOR_ ## sensor << 8) \
2078 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002079static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002080#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002081 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03002082 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002083#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002084 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2085 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002086#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002087 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002088#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03002089 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002090 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03002091 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002092 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2093/* bw600.inf:
2094 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2095/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2096/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2097 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2098/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
Jean-Francois Moine661ab252009-01-29 16:03:19 -03002099 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002100/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2101/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2102 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2103/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2104/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2105 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2106 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002107#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2108 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2109#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002110/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2111/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2112/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002113 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2114/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03002115 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002116 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002117 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002118/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002119#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002120 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002121#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002122 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03002123 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002124#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002125 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2126 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2127/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002128#endif
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002129 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002130 {}
2131};
2132MODULE_DEVICE_TABLE(usb, device_table);
2133
2134/* -- device connect -- */
2135static int sd_probe(struct usb_interface *intf,
2136 const struct usb_device_id *id)
2137{
2138 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2139 THIS_MODULE);
2140}
2141
2142static struct usb_driver sd_driver = {
2143 .name = MODULE_NAME,
2144 .id_table = device_table,
2145 .probe = sd_probe,
2146 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002147#ifdef CONFIG_PM
2148 .suspend = gspca_suspend,
2149 .resume = gspca_resume,
2150#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002151};
2152
2153/* -- module insert / remove -- */
2154static int __init sd_mod_init(void)
2155{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002156 int ret;
2157 ret = usb_register(&sd_driver);
2158 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002159 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002160 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002161 return 0;
2162}
2163static void __exit sd_mod_exit(void)
2164{
2165 usb_deregister(&sd_driver);
2166 info("deregistered");
2167}
2168
2169module_init(sd_mod_init);
2170module_exit(sd_mod_exit);