blob: d9a7d1157f9277c490c6b8844c25fdcb00e7b11f [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 Moine98819182009-01-19 07:37:33 -0300382static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300383 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
384 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
385};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300386
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300387
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300388/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300389static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300390 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
391 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
392 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
393 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300394};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300395static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300396 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
397 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
398 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
399/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
400 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
401 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
402/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300403
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300404 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
405 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
406 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
407 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
408 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
409 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
410 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
411 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300412
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300413 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
414 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
416 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
417 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300418
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300419 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
420 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
421 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
422 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
423 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300424 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300425};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300426static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300427 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300428 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300429 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300430 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
431 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
432 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
433 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
434 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
435 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
436 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
437 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
438 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
439 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
442 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
443 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
444 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300449 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300450 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
452 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
454 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
456 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
459 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300460
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300461 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
462 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
463 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
464 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
465 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300466
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300467 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
468 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
469 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
470 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300471
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300472 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
473 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
474/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
475/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
476 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
477 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300478 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300479};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300480static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300481 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
482 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
483 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
484 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
485 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
486 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
487 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
488 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
489 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
490 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
491 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300501 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300502};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300503static const u8 mt9v111_sensor_init[][8] = {
504 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
505 /* delay 20 ms */
506 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
508 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
509 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
510 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
511 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
512 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
513 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
514 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
515 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
516 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
517 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
518 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
519 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
520 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
521 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
522 /*******/
523 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
524 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
525 {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */
526 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
527 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
528 /*******/
529 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
530 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
531 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
532 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
533 {}
534};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300535static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300536 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
537 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
538 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
539 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
540/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
541 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
542 /* white balance & auto-exposure */
543/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
544 * set color mode */
545/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
546 * max AGC value in AE */
547/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
548 * preset AGC */
549/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
550 * preset brightness */
551/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
552 * preset contrast */
553/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
554 * preset gamma */
555 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
556 /* luminance mode (0x4f = AE) */
557 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
558 /* preset shutter */
559/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
560 * auto frame rate */
561/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
562
563/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
564/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
565/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
566/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
567 {}
568};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300569static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300570 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
571 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
572/* win: delay 20ms */
573 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
574 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
575/* win: delay 20ms */
576 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300577/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300578 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
579 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
580 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
581 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
582 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
583 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
584 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
585 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
586 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
587 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
588 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
589 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
590 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
591 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
593 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
594 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
595 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
596 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
597 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
598 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
599 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
600 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
601 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
602 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
603 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
604/* */
605 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
606 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
607/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300608/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
609 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300610 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
611 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
612 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300613/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300614 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
615 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
616 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300617/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300618 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300619/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300620 {}
621};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300622
Jean-Francois Moine98819182009-01-19 07:37:33 -0300623static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300624 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
626 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
627 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
628 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
629 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
630 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
631 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
632 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
633 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
634 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
635 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
636 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
637 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
638 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
639 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
640 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
641 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
642 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
643 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
644 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
645
646 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
647/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
648/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
649 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
650/*...*/
651/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
652/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
653 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
654 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
655/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
656/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
657/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
658/*...*/
659 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
660/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
661/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
662/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
663/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
664/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
665
666 {}
667};
668
Jean-Francois Moine98819182009-01-19 07:37:33 -0300669static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300670 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300671/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300672 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300673 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300674 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300675 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300676 /* GAIN BLUE RED VREF */
677 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
678 /* COM 1 BAVE GEAVE AECHH */
679 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
680 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300681 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 /* AECH CLKRC COM7 COM8 */
683 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
684 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
685 /* HSTART HSTOP VSTRT VSTOP */
686 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
687 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
688 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
689 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300690/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
691 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300692 /* AEW AEB VPT BBIAS */
693 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
694 /* GbBIAS RSVD EXHCH EXHCL */
695 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
696 /* RBIAS ADVFL ASDVFH YAVE */
697 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
698 /* HSYST HSYEN HREF */
699 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
700 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
701 /* ADC ACOM OFON TSLB */
702 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
703 /* COM11 COM12 COM13 COM14 */
704 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
705 /* EDGE COM15 COM16 COM17 */
706 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
707 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
708 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
709 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
710 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
711 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
712 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
713 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
714 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
715 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
716 /* LCC1 LCC2 LCC3 LCC4 */
717 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300718 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300719 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300720 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300721 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
722 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
723 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
724 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
725 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
726 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
727 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
728 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
729 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300730 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300731/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300732 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733 /* bits[3..0]reserved */
734 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
735 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
736 /* VREF vertical frame ctrl */
737 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300738 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
739 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
740 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
741 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
742/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300743/****** (some exchanges in the win trace) ******/
744 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300745 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
746 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
747 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
748/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300749/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300750/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
752 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
753 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
754 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300755 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300756};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300757
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300758static const u8 sp80708_sensor_init[][8] = {
759 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
760 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
761 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
762 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
763 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
764 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
765 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
766 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
767 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
768 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
769 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
770 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
771 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
776 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
777 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
778 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
779 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
830 /********/
831 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
837 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
838 {}
839};
840
Jean-Francois Moine98819182009-01-19 07:37:33 -0300841static const u8 qtable4[] = {
842 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
843 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
844 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
845 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
846 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
847 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
848 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
849 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
850 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
851 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
852 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
853 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
854 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
855 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
856 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
857 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300858};
859
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300860/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300861static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300862 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300864#ifdef GSPCA_DEBUG
865 if (len > USB_BUF_SZ) {
866 err("reg_r: buffer overflow");
867 return;
868 }
869#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300870 usb_control_msg(gspca_dev->dev,
871 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300872 0,
873 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
874 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300875 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300876 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300877 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878}
879
Jean-Francois Moine60017612008-07-18 08:46:19 -0300880static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300881 u16 value,
882 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -0300883{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300884 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300885 gspca_dev->usb_buf[0] = data;
886 usb_control_msg(gspca_dev->dev,
887 usb_sndctrlpipe(gspca_dev->dev, 0),
888 0x08,
889 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
890 value,
891 0,
892 gspca_dev->usb_buf, 1,
893 500);
894}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300895static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300896 u16 value,
897 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300898 int len)
899{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300900 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -0300901 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300902#ifdef GSPCA_DEBUG
903 if (len > USB_BUF_SZ) {
904 err("reg_w: buffer overflow");
905 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300906 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300907#endif
908 memcpy(gspca_dev->usb_buf, buffer, len);
909 usb_control_msg(gspca_dev->dev,
910 usb_sndctrlpipe(gspca_dev->dev, 0),
911 0x08,
912 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
913 value, 0,
914 gspca_dev->usb_buf, len,
915 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300916}
917
Jean-Francois Moine60017612008-07-18 08:46:19 -0300918/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300919static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300920{
921 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300922
Jean-Francois Moine60017612008-07-18 08:46:19 -0300923 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
924 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
925 gspca_dev->usb_buf[1] = sd->i2c_base;
926 gspca_dev->usb_buf[2] = reg;
927 gspca_dev->usb_buf[3] = val;
928 gspca_dev->usb_buf[4] = 0;
929 gspca_dev->usb_buf[5] = 0;
930 gspca_dev->usb_buf[6] = 0;
931 gspca_dev->usb_buf[7] = 0x10;
932 usb_control_msg(gspca_dev->dev,
933 usb_sndctrlpipe(gspca_dev->dev, 0),
934 0x08,
935 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
936 0x08, /* value = i2c */
937 0,
938 gspca_dev->usb_buf, 8,
939 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300940}
941
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300942/* I2C write 8 bytes */
943static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300944 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300945{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300946 memcpy(gspca_dev->usb_buf, buffer, 8);
947 usb_control_msg(gspca_dev->dev,
948 usb_sndctrlpipe(gspca_dev->dev, 0),
949 0x08,
950 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
951 0x08, 0, /* value, index */
952 gspca_dev->usb_buf, 8,
953 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300954 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300955}
956
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300957/* read 5 bytes in gspca_dev->usb_buf */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300958static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300959{
960 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -0300961 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300962
Hans de Goede3647fea2008-07-15 05:36:30 -0300963 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300964 mode[1] = sd->i2c_base;
965 mode[2] = reg;
966 mode[3] = 0;
967 mode[4] = 0;
968 mode[5] = 0;
969 mode[6] = 0;
970 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300971 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300972 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300973 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300974 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300975 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300976 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300977 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300978}
979
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300980static int hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300981{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300982 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300983 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300984 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300985 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300986 i2c_r5(gspca_dev, 0); /* read sensor id */
987 if (gspca_dev->usb_buf[0] == 0x02
988 && gspca_dev->usb_buf[1] == 0x09
989 && gspca_dev->usb_buf[2] == 0x01
990 && gspca_dev->usb_buf[3] == 0x00
991 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300992 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300993 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300994 }
Jean-Francois Moine60017612008-07-18 08:46:19 -0300995 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300996 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
997 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300998 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
999 return -ENODEV;
1000}
1001
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001002static int mi0360_probe(struct gspca_dev *gspca_dev)
1003{
1004 int i, j;
1005 u16 val;
1006 static const u8 probe_tb[][4][8] = {
1007 {
1008 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1009 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1010 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1011 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1012 },
1013 {
1014 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1015 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1016 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1017 {}
1018 },
1019 };
1020
1021 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1022 reg_w1(gspca_dev, 0x17, 0x62);
1023 reg_w1(gspca_dev, 0x01, 0x08);
1024 for (j = 0; j < 3; j++)
1025 i2c_w8(gspca_dev, probe_tb[i][j]);
1026 msleep(2);
1027 reg_r(gspca_dev, 0x0a, 5);
1028 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1029 if (probe_tb[i][3][0] != 0)
1030 i2c_w8(gspca_dev, probe_tb[i][3]);
1031 reg_w1(gspca_dev, 0x01, 0x29);
1032 reg_w1(gspca_dev, 0x17, 0x42);
1033 if (val != 0xffff)
1034 break;
1035 }
1036 switch (val) {
1037 case 0x823a:
1038 PDEBUG(D_PROBE, "Sensor mt9v111");
1039 return SENSOR_MT9V111;
1040 case 0x8243:
1041 PDEBUG(D_PROBE, "Sensor mi0360");
1042 return SENSOR_MI0360;
1043 }
1044 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1045 return SENSOR_MI0360;
1046}
1047
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001048static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001049 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001050{
1051 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001052 const u8 *reg9a;
1053 static const u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001054 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001055 static const u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001056 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001057 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001058
Jean-Francois Moine60017612008-07-18 08:46:19 -03001059 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001060 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001061
1062 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001063 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1064 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001065 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -03001066 switch (sd->bridge) {
1067 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001068 reg9a = reg9a_sn9c325;
1069 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001070 default:
1071 reg9a = reg9a_def;
1072 break;
1073 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001074 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001075
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001076 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001077
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001078 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001079
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001080 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001081 case SENSOR_MT9V111:
1082 reg_w1(gspca_dev, 0x01, 0x61);
1083 reg_w1(gspca_dev, 0x17, 0x61);
1084 reg_w1(gspca_dev, 0x01, 0x60);
1085 reg_w1(gspca_dev, 0x01, 0x40);
1086 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001087 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -03001088 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001089 reg_w1(gspca_dev, 0x01, 0x42);
1090 reg_w1(gspca_dev, 0x17, 0x64);
1091 reg_w1(gspca_dev, 0x01, 0x42);
1092 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001093/*jfm: from win trace */
1094 case SENSOR_OV7630:
1095 reg_w1(gspca_dev, 0x01, 0x61);
1096 reg_w1(gspca_dev, 0x17, 0xe2);
1097 reg_w1(gspca_dev, 0x01, 0x60);
1098 reg_w1(gspca_dev, 0x01, 0x40);
1099 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001100 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001101 reg_w1(gspca_dev, 0x01, 0x63);
1102 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001103 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001104 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001105/*jfm: from win trace */
1106 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001107 if (sd->bridge == BRIDGE_SN9C120) {
1108 reg_w1(gspca_dev, 0x01, 0x61);
1109 reg_w1(gspca_dev, 0x17, 0x20);
1110 reg_w1(gspca_dev, 0x01, 0x60);
1111 reg_w1(gspca_dev, 0x01, 0x40);
1112 break;
1113 }
1114 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001115 case SENSOR_SP80708:
1116 reg_w1(gspca_dev, 0x01, 0x63);
1117 reg_w1(gspca_dev, 0x17, 0x20);
1118 reg_w1(gspca_dev, 0x01, 0x62);
1119 reg_w1(gspca_dev, 0x01, 0x42);
1120 mdelay(100);
1121 reg_w1(gspca_dev, 0x02, 0x62);
1122 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001123 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001124 reg_w1(gspca_dev, 0x01, 0x43);
1125 reg_w1(gspca_dev, 0x17, 0x61);
1126 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001127 if (sd->sensor == SENSOR_HV7131R) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001128 if (hv7131r_probe(gspca_dev) < 0)
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001129 return -ENODEV;
1130 }
1131 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001132 }
1133 return 0;
1134}
1135
1136static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1137{
1138 int i = 0;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001139 static const u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001140 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1141
1142 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001143 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001144 i++;
1145 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001146 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001147}
1148
1149static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1150{
1151 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001152
1153 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001154 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001155 i++;
1156 }
1157}
1158
1159static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1160{
1161 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001162
1163 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001164 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001165 i++;
1166 }
1167}
1168
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001169static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1170{
1171 int i = 0;
1172
1173 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1174 i++;
1175 msleep(20);
1176 while (mt9v111_sensor_init[i][0]) {
1177 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1178 i++;
1179 }
1180}
1181
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001182static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1183{
1184 int i = 0;
1185
1186 while (om6802_sensor_init[i][0]) {
1187 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1188 i++;
1189 }
1190}
1191
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001192static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1193{
1194 int i = 0;
1195
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001196 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1197 i++;
1198 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001199 i++;
1200 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001201 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1202 i++;
1203 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1204 i++;
1205 msleep(20);
1206 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1207 i++;
1208/*jfm:win i2c_r from 00 to 80*/
1209
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001210 while (ov7630_sensor_init[i][0]) {
1211 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1212 i++;
1213 }
1214}
1215
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001216static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1217{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001218 int i = 0;
1219
Jean-Francois Moine62703302008-11-11 08:42:56 -03001220 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1221 i++;
1222/* win: dble reset */
1223 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1224 i++;
1225 msleep(20);
1226/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001227 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001228 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001229 i++;
1230 }
1231}
1232
1233static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1234{
1235 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001236
Jean-Francois Moine60017612008-07-18 08:46:19 -03001237 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1238 i++;
1239 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001240 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001241 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001242 i++;
1243 }
1244}
1245
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001246static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1247{
1248 int i = 0;
1249
1250 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1251 i++;
1252 msleep(20);
1253 while (sp80708_sensor_init[i][0]) {
1254 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1255 i++;
1256 }
1257}
1258
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001259/* this function is called at probe time */
1260static int sd_config(struct gspca_dev *gspca_dev,
1261 const struct usb_device_id *id)
1262{
1263 struct sd *sd = (struct sd *) gspca_dev;
1264 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001265
1266 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001267 cam->cam_mode = vga_mode;
1268 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001269
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001270 sd->bridge = id->driver_info >> 16;
1271 sd->sensor = id->driver_info >> 8;
1272 sd->i2c_base = id->driver_info;
1273
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001274 sd->brightness = BRIGHTNESS_DEF;
1275 sd->contrast = CONTRAST_DEF;
1276 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001277 sd->blue = BLUE_BALANCE_DEF;
1278 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001279 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001280 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001281 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001282 sd->vflip = VFLIP_DEF;
1283 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001284
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001285 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001286 return 0;
1287}
1288
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001289/* this function is called at probe and resume time */
1290static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001291{
1292 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001293 u8 regGpio[] = { 0x29, 0x74 };
1294 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001295
Hans de Goede3647fea2008-07-15 05:36:30 -03001296 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001297 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001298 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001299 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1300 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001301 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001302 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001303 switch (sd->bridge) {
1304 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001305 if (regF1 != 0x11)
1306 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001307 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001308 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001309 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001310 if (regF1 != 0x11)
1311 return -ENODEV;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001312 if (sd->sensor == SENSOR_MI0360) {
1313 sd->sensor = mi0360_probe(gspca_dev);
1314 if (sd->sensor == SENSOR_MT9V111)
1315 sd->i2c_base = 0x5c;
1316 }
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001317 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001318 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001319 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001320 if (regF1 != 0x12)
1321 return -ENODEV;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001322 if (sd->sensor == SENSOR_MI0360) {
1323 sd->sensor = mi0360_probe(gspca_dev);
1324 if (sd->sensor == SENSOR_MT9V111)
1325 sd->i2c_base = 0x5c;
1326 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001327 regGpio[1] = 0x70;
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;
1330 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001331/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001332/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001333 if (regF1 != 0x12)
1334 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001335 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001336 break;
1337 }
1338
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001339 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001340
1341 return 0;
1342}
1343
Jean-Francois Moine98819182009-01-19 07:37:33 -03001344static u32 setexposure(struct gspca_dev *gspca_dev,
1345 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001346{
1347 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001348
1349 switch (sd->sensor) {
1350 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001351 u8 Expodoit[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001352 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1353
1354 Expodoit[3] = expo >> 16;
1355 Expodoit[4] = expo >> 8;
1356 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001357 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001358 break;
1359 }
1360 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001361 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001362 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001363 static const u8 doit[] = /* update sensor */
1364 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1365 static const u8 sensorgo[] = /* sensor on */
1366 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001367
1368 if (expo > 0x0635)
1369 expo = 0x0635;
1370 else if (expo < 0x0001)
1371 expo = 0x0001;
1372 expoMi[3] = expo >> 8;
1373 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001374 i2c_w8(gspca_dev, expoMi);
1375 i2c_w8(gspca_dev, doit);
1376 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001377 break;
1378 }
1379 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001380 u8 expoMof[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001381 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001382 u8 expoMo10[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001383 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001384 static const u8 gainMo[] =
1385 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001386
1387 if (expo > 0x1fff)
1388 expo = 0x1fff;
1389 else if (expo < 0x0001)
1390 expo = 0x0001;
1391 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001392 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001393 expoMo10[3] = ((expo & 0x1c00) >> 10)
1394 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001395 i2c_w8(gspca_dev, expoMo10);
1396 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001397 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001398 ((expoMo10[3] & 0x07) << 10)
1399 | (expoMof[3] << 2)
1400 | ((expoMo10[3] & 0x30) >> 4));
1401 break;
1402 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001403 case SENSOR_MT9V111: {
1404 u8 expo_c1[] =
1405 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1406
1407 if (expo > 0x0280)
1408 expo = 0x0280;
1409 else if (expo < 0x0040)
1410 expo = 0x0040;
1411 expo_c1[3] = expo >> 8;
1412 expo_c1[4] = expo;
1413 i2c_w8(gspca_dev, expo_c1);
1414 break;
1415 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001416 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001417 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001418 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1419
1420 if (expo > 0x03ff)
1421 expo = 0x03ff;
1422 if (expo < 0x0001)
1423 expo = 0x0001;
1424 gainOm[3] = expo >> 2;
1425 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001426 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001427 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001428 break;
1429 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001430 }
1431 return expo;
1432}
1433
1434static void setbrightness(struct gspca_dev *gspca_dev)
1435{
1436 struct sd *sd = (struct sd *) gspca_dev;
1437 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001438 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001439
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001440 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001441 switch (sd->sensor) {
1442 case SENSOR_HV7131R:
1443 expo = sd->brightness << 4;
1444 if (expo > 0x002dc6c0)
1445 expo = 0x002dc6c0;
1446 else if (expo < 0x02a0)
1447 expo = 0x02a0;
1448 sd->exposure = setexposure(gspca_dev, expo);
1449 break;
1450 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 case SENSOR_MO4000:
1452 expo = sd->brightness >> 4;
1453 sd->exposure = setexposure(gspca_dev, expo);
1454 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001455 case SENSOR_MT9V111:
1456 expo = sd->brightness >> 8;
1457 sd->exposure = setexposure(gspca_dev, expo);
1458 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001459 case SENSOR_OM6802:
1460 expo = sd->brightness >> 6;
1461 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001462 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001463 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001464 }
1465
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001466 if (sd->sensor != SENSOR_MT9V111)
1467 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001468}
1469
1470static void setcontrast(struct gspca_dev *gspca_dev)
1471{
1472 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001473 u8 k2;
1474 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001475
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001476 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1477 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001478 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001479 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001480 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001481 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001482 contrast[5] = 0;
1483 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001484}
1485
1486static void setcolors(struct gspca_dev *gspca_dev)
1487{
1488 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001489 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001490 u8 reg8a[12]; /* U & V gains */
1491 static s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001492 -24, -38, 64, /* UR UG UB */
1493 62, -51, -9 /* VR VG VB */
1494 };
1495 for (i = 0; i < 6; i++) {
1496 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001497 reg8a[i * 2] = v;
1498 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001499 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001500 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001501}
1502
1503static void setredblue(struct gspca_dev *gspca_dev)
1504{
1505 struct sd *sd = (struct sd *) gspca_dev;
1506
1507 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001508/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001509 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001510}
1511
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001512static void setgamma(struct gspca_dev *gspca_dev)
1513{
1514 struct sd *sd = (struct sd *) gspca_dev;
1515 int i;
1516 u8 gamma[17];
1517 static const u8 delta[17] = {
1518 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1519 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1520 };
1521
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001522
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001523 for (i = 0; i < sizeof gamma; i++)
1524 gamma[i] = gamma_def[i]
1525 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1526 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1527}
1528
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001529static void setautogain(struct gspca_dev *gspca_dev)
1530{
1531 struct sd *sd = (struct sd *) gspca_dev;
1532
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001533 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1534 return;
1535 if (sd->autogain)
1536 sd->ag_cnt = AG_CNT_START;
1537 else
1538 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001539}
1540
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001541static void setvflip(struct sd *sd)
1542{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001543 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1544 sd->vflip ? 0x82 : 0x02);
1545}
1546
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001547static void setinfrared(struct sd *sd)
1548{
1549/*fixme: different sequence for StarCam Clip and StarCam 370i */
1550/* Clip */
1551 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1552 sd->infrared ? 0x66 : 0x64);
1553}
1554
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001555/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001556static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001557{
1558 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001559 int i;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001560 u8 reg1, reg17, reg18;
1561 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001562 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001563 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1564 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1565 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1566 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001567 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001568
1569 sn9c1xx = sn_tb[(int) sd->sensor];
1570 configure_gpio(gspca_dev, sn9c1xx);
1571
Jean-Francois Moine60017612008-07-18 08:46:19 -03001572 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1573 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1574 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1575 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1576 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1577 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1578 reg_w1(gspca_dev, 0xd3, 0x50);
1579 reg_w1(gspca_dev, 0xc6, 0x00);
1580 reg_w1(gspca_dev, 0xc7, 0x00);
1581 reg_w1(gspca_dev, 0xc8, 0x50);
1582 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001583 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001584 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001585 case SENSOR_MT9V111:
1586 reg17 = 0xe0;
1587 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001588 case SENSOR_OV7630:
1589 reg17 = 0xe2;
1590 break;
1591 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001592 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001593 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001594/*jfm: from win trace */
1595 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001596 if (sd->bridge == BRIDGE_SN9C120) {
1597 reg17 = 0xa0;
1598 break;
1599 }
1600 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001601 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001602 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001603 break;
1604 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001605 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001606/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001607 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1608 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1609 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001610 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001611 setgamma(gspca_dev);
1612
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001613 for (i = 0; i < 8; i++)
1614 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001615 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001616 case SENSOR_MT9V111:
1617 reg_w1(gspca_dev, 0x9a, 0x07);
1618 reg_w1(gspca_dev, 0x99, 0x59);
1619 break;
Jean-Francois Moine62703302008-11-11 08:42:56 -03001620 case SENSOR_OV7648:
1621 reg_w1(gspca_dev, 0x9a, 0x0a);
1622 reg_w1(gspca_dev, 0x99, 0x60);
1623 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001624 case SENSOR_SP80708:
1625 reg_w1(gspca_dev, 0x9a, 0x05);
1626 reg_w1(gspca_dev, 0x99, 0x59);
1627 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001628 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001629 if (sd->bridge == BRIDGE_SN9C120) {
1630 reg_w1(gspca_dev, 0x9a, 0x05);
1631 break;
1632 }
1633 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001634 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001635 reg_w1(gspca_dev, 0x9a, 0x08);
1636 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001637 break;
1638 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001639
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001640 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001641 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001642 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001643 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001644 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1645 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001646 switch (sd->sensor) {
1647 case SENSOR_HV7131R:
1648 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001649 break;
1650 case SENSOR_MI0360:
1651 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001652 break;
1653 case SENSOR_MO4000:
1654 mo4000_InitSensor(gspca_dev);
1655 if (mode) {
1656/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1657 reg1 = 0x06; /* clk 24Mz */
1658 } else {
1659 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001660/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001661 }
1662 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001663 case SENSOR_MT9V111:
1664 mt9v111_InitSensor(gspca_dev);
1665 if (mode) {
1666 reg1 = 0x04; /* 320 clk 48Mhz */
1667 } else {
1668/* reg1 = 0x06; * 640 clk 24Mz (done) */
1669 reg17 = 0xe2;
1670 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03001671 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001672 case SENSOR_OM6802:
1673 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001674 reg17 = 0x64; /* 640 MCKSIZE */
1675 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001676 case SENSOR_OV7630:
1677 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001678 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001679 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001680 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001681 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001682 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001683 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001684 reg17 = 0x21;
1685/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001686 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001687 case SENSOR_OV7660:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001688 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001689 if (sd->bridge == BRIDGE_SN9C120) {
1690 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001691 reg17 = 0xa2;
1692 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001693 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001694 } else {
1695 reg17 = 0x22;
1696 reg1 = 0x06; /* 24 Mhz, video trf eneble
1697 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001698 }
1699 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001700 default:
1701/* case SENSOR_SP80708: */
1702 sp80708_InitSensor(gspca_dev);
1703 if (mode) {
1704/*?? reg1 = 0x04; * 320 clk 48Mhz */
1705 ;
1706 } else {
1707 reg1 = 0x46; /* 640 clk 48Mz */
1708 reg17 = 0xa2;
1709 }
1710 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001711 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001712 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001713 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001714 switch (sd->sensor) {
1715 case SENSOR_OV7630:
1716 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001717 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001718 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001719 break;
1720 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001721 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001722 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1723 break;
1724 }
1725
1726 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001727 reg18 = sn9c1xx[0x18] | (mode << 4);
1728 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001729
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001730 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1731 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001732
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001733 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001734
Jean-Francois Moine60017612008-07-18 08:46:19 -03001735 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001736 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001737 switch (sd->sensor) {
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001738 case SENSOR_OV7630:
1739 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001740 break;
1741 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001742 setbrightness(gspca_dev);
1743 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001744 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001745 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001746}
1747
1748static void sd_stopN(struct gspca_dev *gspca_dev)
1749{
1750 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001751 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001752 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001753 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001754 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001755 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03001756 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001757 u8 data;
1758 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001759
1760 data = 0x0b;
1761 switch (sd->sensor) {
1762 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001763 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001764 data = 0x2b;
1765 break;
1766 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001767 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001768 data = 0x29;
1769 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001770 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001771 i2c_w8(gspca_dev, stopov7648);
1772 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001773 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001774 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001775 data = 0x29;
1776 break;
1777 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001778/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001779/* case SENSOR_OV7660: */
1780 break;
1781 }
1782 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001783 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1784 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1785 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1786 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001787 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001788}
1789
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001790static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001791{
1792 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001793 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001794 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001795 u8 luma_mean = 130;
1796 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001797
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001798 /* Thanks S., without your advice, autobright should not work :) */
1799 if (sd->ag_cnt < 0)
1800 return;
1801 if (--sd->ag_cnt >= 0)
1802 return;
1803 sd->ag_cnt = AG_CNT_START;
1804
1805 delta = atomic_read(&sd->avg_lum);
1806 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001807 if (delta < luma_mean - luma_delta ||
1808 delta > luma_mean + luma_delta) {
1809 switch (sd->sensor) {
1810 case SENSOR_HV7131R:
1811 expotimes = sd->exposure >> 8;
1812 expotimes += (luma_mean - delta) >> 4;
1813 if (expotimes < 0)
1814 expotimes = 0;
1815 sd->exposure = setexposure(gspca_dev,
1816 (unsigned int) (expotimes << 8));
1817 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001818 default:
1819/* case SENSOR_MO4000: */
1820/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001821/* case SENSOR_MT9V111: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001822/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001823 expotimes = sd->exposure;
1824 expotimes += (luma_mean - delta) >> 6;
1825 if (expotimes < 0)
1826 expotimes = 0;
1827 sd->exposure = setexposure(gspca_dev,
1828 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001829 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001830 break;
1831 }
1832 }
1833}
1834
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001835/* scan the URB packets */
1836/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001837static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1838 struct gspca_frame *frame, /* target */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001839 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001840 int len) /* iso packet length */
1841{
1842 struct sd *sd = (struct sd *) gspca_dev;
1843 int sof, avg_lum;
1844
1845 sof = len - 64;
1846 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1847
1848 /* end of frame */
1849 gspca_frame_add(gspca_dev, LAST_PACKET,
1850 frame, data, sof + 2);
1851 if (sd->ag_cnt < 0)
1852 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001853/* w1 w2 w3 */
1854/* w4 w5 w6 */
1855/* w7 w8 */
1856/* w4 */
1857 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1858/* w6 */
1859 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1860/* w2 */
1861 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1862/* w8 */
1863 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1864/* w5 */
1865 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1866 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001867 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001868 return;
1869 }
1870 if (gspca_dev->last_packet_type == LAST_PACKET) {
1871
1872 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001873 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001874 }
1875 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1876}
1877
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001878static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1879{
1880 struct sd *sd = (struct sd *) gspca_dev;
1881
1882 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001883 if (gspca_dev->streaming)
1884 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001885 return 0;
1886}
1887
1888static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1889{
1890 struct sd *sd = (struct sd *) gspca_dev;
1891
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001892 *val = sd->brightness;
1893 return 0;
1894}
1895
1896static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1897{
1898 struct sd *sd = (struct sd *) gspca_dev;
1899
1900 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001901 if (gspca_dev->streaming)
1902 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001903 return 0;
1904}
1905
1906static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1907{
1908 struct sd *sd = (struct sd *) gspca_dev;
1909
1910 *val = sd->contrast;
1911 return 0;
1912}
1913
1914static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1915{
1916 struct sd *sd = (struct sd *) gspca_dev;
1917
1918 sd->colors = val;
1919 if (gspca_dev->streaming)
1920 setcolors(gspca_dev);
1921 return 0;
1922}
1923
1924static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1925{
1926 struct sd *sd = (struct sd *) gspca_dev;
1927
1928 *val = sd->colors;
1929 return 0;
1930}
1931
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001932static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1933{
1934 struct sd *sd = (struct sd *) gspca_dev;
1935
1936 sd->blue = val;
1937 if (gspca_dev->streaming)
1938 setredblue(gspca_dev);
1939 return 0;
1940}
1941
1942static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1943{
1944 struct sd *sd = (struct sd *) gspca_dev;
1945
1946 *val = sd->blue;
1947 return 0;
1948}
1949
1950static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1951{
1952 struct sd *sd = (struct sd *) gspca_dev;
1953
1954 sd->red = val;
1955 if (gspca_dev->streaming)
1956 setredblue(gspca_dev);
1957 return 0;
1958}
1959
1960static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1961{
1962 struct sd *sd = (struct sd *) gspca_dev;
1963
1964 *val = sd->red;
1965 return 0;
1966}
1967
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001968static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1969{
1970 struct sd *sd = (struct sd *) gspca_dev;
1971
1972 sd->gamma = val;
1973 if (gspca_dev->streaming)
1974 setgamma(gspca_dev);
1975 return 0;
1976}
1977
1978static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
1979{
1980 struct sd *sd = (struct sd *) gspca_dev;
1981
1982 *val = sd->gamma;
1983 return 0;
1984}
1985
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001986static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1987{
1988 struct sd *sd = (struct sd *) gspca_dev;
1989
1990 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001991 if (gspca_dev->streaming)
1992 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001993 return 0;
1994}
1995
1996static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1997{
1998 struct sd *sd = (struct sd *) gspca_dev;
1999
2000 *val = sd->autogain;
2001 return 0;
2002}
2003
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002004static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2005{
2006 struct sd *sd = (struct sd *) gspca_dev;
2007
2008 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002009 if (gspca_dev->streaming)
2010 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002011 return 0;
2012}
2013
2014static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2015{
2016 struct sd *sd = (struct sd *) gspca_dev;
2017
2018 *val = sd->vflip;
2019 return 0;
2020}
2021
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002022static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2023{
2024 struct sd *sd = (struct sd *) gspca_dev;
2025
2026 sd->infrared = val;
2027 if (gspca_dev->streaming)
2028 setinfrared(sd);
2029 return 0;
2030}
2031
2032static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2033{
2034 struct sd *sd = (struct sd *) gspca_dev;
2035
2036 *val = sd->infrared;
2037 return 0;
2038}
2039
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002040/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002041static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002042 .name = MODULE_NAME,
2043 .ctrls = sd_ctrls,
2044 .nctrls = ARRAY_SIZE(sd_ctrls),
2045 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002046 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002047 .start = sd_start,
2048 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002049 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002050 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002051};
2052
2053/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002054#define BSI(bridge, sensor, i2c_addr) \
2055 .driver_info = (BRIDGE_ ## bridge << 16) \
2056 | (SENSOR_ ## sensor << 8) \
2057 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002058static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002059#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002060 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03002061 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002062#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002063 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2064 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002065#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002066 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002067#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03002068 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002069 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03002070 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002071 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2072/* bw600.inf:
2073 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2074/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2075/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2076 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2077/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
Jean-Francois Moine661ab252009-01-29 16:03:19 -03002078 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002079/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2080/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2081 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2082/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2083/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2084 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2085 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002086#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2087 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2088#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002089/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2090/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2091/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002092 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2093/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03002094 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002095 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002096 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002097/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002098#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002099 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002100#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002101 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03002102 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002103#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002104 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2105 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2106/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002107#endif
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002108 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002109 {}
2110};
2111MODULE_DEVICE_TABLE(usb, device_table);
2112
2113/* -- device connect -- */
2114static int sd_probe(struct usb_interface *intf,
2115 const struct usb_device_id *id)
2116{
2117 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2118 THIS_MODULE);
2119}
2120
2121static struct usb_driver sd_driver = {
2122 .name = MODULE_NAME,
2123 .id_table = device_table,
2124 .probe = sd_probe,
2125 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002126#ifdef CONFIG_PM
2127 .suspend = gspca_suspend,
2128 .resume = gspca_resume,
2129#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002130};
2131
2132/* -- module insert / remove -- */
2133static int __init sd_mod_init(void)
2134{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002135 int ret;
2136 ret = usb_register(&sd_driver);
2137 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002138 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002139 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002140 return 0;
2141}
2142static void __exit sd_mod_exit(void)
2143{
2144 usb_deregister(&sd_driver);
2145 info("deregistered");
2146}
2147
2148module_init(sd_mod_init);
2149module_exit(sd_mod_exit);