blob: 882d5e9b436aa183667e00fa90c4a3c067c8987f [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 Moine2687a2f2009-02-01 14:48:55 -0300237 0,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300238 /* SENSOR_MT9V111 3 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300239 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300240 /* SENSOR_OM6802 4 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300241 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300242 /* SENSOR_OV7630 5 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300243 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300244 /* SENSOR_OV7648 6 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300245 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300246 /* SENSOR_OV7660 7 */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300247 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
248 /* SENSOR_SP80708 8 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300249};
250
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300251static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300252 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
253 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300254 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300255 .colorspace = V4L2_COLORSPACE_JPEG,
256 .priv = 2},
257 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
258 .bytesperline = 320,
259 .sizeimage = 320 * 240 * 3 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
261 .priv = 1},
262 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
263 .bytesperline = 640,
264 .sizeimage = 640 * 480 * 3 / 8 + 590,
265 .colorspace = V4L2_COLORSPACE_JPEG,
266 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267};
268
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300269/*Data from sn9c102p+hv7131r */
270static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300271/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
272 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
273/* reg8 reg9 rega regb regc regd rege regf */
274 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
275/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
276 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300277/* reg18 reg19 reg1a reg1b */
278 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300279};
280
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300281static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300282/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
283 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
284/* reg8 reg9 rega regb regc regd rege regf */
285 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
286/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
287 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300288/* reg18 reg19 reg1a reg1b */
289 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300290};
291
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300292static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300293/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300294 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300295/* reg8 reg9 rega regb regc regd rege regf */
296 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
298 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300299/* reg18 reg19 reg1a reg1b */
300 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300301};
302
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300303static const u8 sn_mt9v111[0x1c] = {
304/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
306/* reg8 reg9 rega regb regc regd rege regf */
307 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
308/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
310/* reg18 reg19 reg1a reg1b */
311 0x06, 0x00, 0x00, 0x00
312};
313
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300314static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300315/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
317/* reg8 reg9 rega regb regc regd rege regf */
318 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300321/* reg18 reg19 reg1a reg1b */
322 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300323};
324
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300325static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300326/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
327 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
328/* reg8 reg9 rega regb regc regd rege regf */
329 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
330/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
331 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300332/* reg18 reg19 reg1a reg1b */
333 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300334};
335
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300336static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300337/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300338 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300339/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300340 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300341/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300342 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300343/* reg18 reg19 reg1a reg1b */
344 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300345};
346
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300347static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
350/* reg8 reg9 rega regb regc regd rege regf */
351 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
352/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
353 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300354/* reg18 reg19 reg1a reg1b */
355 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356};
357
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300358static const u8 sn_sp80708[0x1c] = {
359/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
361/* reg8 reg9 rega regb regc regd rege regf */
362 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
363/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
365/* reg18 reg19 reg1a reg1b */
366 0x07, 0x00, 0x00, 0x00
367};
368
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300369/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300370static const u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300371 sn_hv7131,
372 sn_mi0360,
373 sn_mo4000,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300374 sn_mt9v111,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300375 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300376 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300377 sn_ov7648,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300378 sn_ov7660,
379 sn_sp80708
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300380};
381
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300382/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300383static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
385 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
386};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300387/* gamma for sensors HV7131R and MT9V111 */
388static const u8 gamma_spec_1[17] = {
389 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
390 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
391};
392/* gamma for sensor SP80708 */
393static const u8 gamma_spec_2[17] = {
394 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
395 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
396};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300397
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300398/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300399static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300400 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
401 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
402 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
403 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300404};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300405static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300406 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
407 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
408 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
409/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
410 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
411 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
412/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300413
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300414 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
416 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
417 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
418 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
419 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
420 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
421 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300422
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300423 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300428
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300429 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300434 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300435};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300436static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300437 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300438 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300439 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300440 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
441 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
442 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
443 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
444 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
449 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
454 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
456 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300459 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300460 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
462 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
463 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
464 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
465 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
466 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
469 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300470
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300471 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
472 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
473 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
474 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
475 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300476
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300477 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
478 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
479 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
480 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300481
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300482 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
483 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
484/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
485/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
486 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
487 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300488 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300489};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300490static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300491 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
502 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
503 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
504 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
505 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
506 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
508 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
509 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
510 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300511 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300512};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300513static const u8 mt9v111_sensor_init[][8] = {
514 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
515 /* delay 20 ms */
516 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
518 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
519 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300520 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
521 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
522 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
523 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300524 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300525 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
526 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
527 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
528 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
529 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300530 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300531 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300532 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
533 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
534 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
535 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
536 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
537 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
538 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
539 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
540 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
541 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
542 /*******/
543 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
544 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300545 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300546 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
547 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
548 /*******/
549 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
550 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
551 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
552 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
553 {}
554};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300555static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300556 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
557 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
558 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
559 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
560/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
561 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
562 /* white balance & auto-exposure */
563/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
564 * set color mode */
565/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
566 * max AGC value in AE */
567/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
568 * preset AGC */
569/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
570 * preset brightness */
571/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
572 * preset contrast */
573/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
574 * preset gamma */
575 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
576 /* luminance mode (0x4f = AE) */
577 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
578 /* preset shutter */
579/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
580 * auto frame rate */
581/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
582
583/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
584/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
585/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
586/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
587 {}
588};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300589static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300590 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
591 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
592/* win: delay 20ms */
593 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
594 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
595/* win: delay 20ms */
596 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300597/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300598 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
599 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
600 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
601 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
602 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
603 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
605 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
606 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
607 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
608 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
609 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
610 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
611 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
612 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
613 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
614 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
615 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
616 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
617 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
618 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
619 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
620 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
621 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
622 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
623 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
624/* */
625 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
627/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300628/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
629 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300630 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
631 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
632 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300633/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300634 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
636 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300637/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300638 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300639/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300640 {}
641};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300642
Jean-Francois Moine98819182009-01-19 07:37:33 -0300643static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300644 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
645 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
646 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
647 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
648 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
649 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
650 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
651 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
652 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
653 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
654 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
655 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
656 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
657 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
658 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
659 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
660 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
661 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
662 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
663 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
664 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
665
666 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
667/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
668/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
669 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
670/*...*/
671/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
672/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
673 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
674 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
675/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
676/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
677/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
678/*...*/
679 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
680/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
681/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
682/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
683/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
684/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
685
686 {}
687};
688
Jean-Francois Moine98819182009-01-19 07:37:33 -0300689static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300690 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300691/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300692 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300693 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300694 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300695 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300696 /* GAIN BLUE RED VREF */
697 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
698 /* COM 1 BAVE GEAVE AECHH */
699 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
700 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300701 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300702 /* AECH CLKRC COM7 COM8 */
703 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
704 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
705 /* HSTART HSTOP VSTRT VSTOP */
706 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
707 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
708 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
709 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300710/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
711 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300712 /* AEW AEB VPT BBIAS */
713 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
714 /* GbBIAS RSVD EXHCH EXHCL */
715 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
716 /* RBIAS ADVFL ASDVFH YAVE */
717 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
718 /* HSYST HSYEN HREF */
719 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
720 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
721 /* ADC ACOM OFON TSLB */
722 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
723 /* COM11 COM12 COM13 COM14 */
724 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
725 /* EDGE COM15 COM16 COM17 */
726 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
727 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
728 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
729 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
730 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
731 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
732 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
733 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
734 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
735 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
736 /* LCC1 LCC2 LCC3 LCC4 */
737 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300738 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300739 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300740 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300741 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
742 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
743 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
744 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
745 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
746 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
747 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
748 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
749 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300750 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300752 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753 /* bits[3..0]reserved */
754 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
755 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
756 /* VREF vertical frame ctrl */
757 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300758 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
759 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
760 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
761 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
762/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300763/****** (some exchanges in the win trace) ******/
764 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300765 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
766 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
767 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
768/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300769/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300770/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300771 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300775 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300776};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300778static const u8 sp80708_sensor_init[][8] = {
779 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
847 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
848 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
849 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
850 /********/
851 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
852 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
853 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
854 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
856 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
857 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
858 {}
859};
860
Jean-Francois Moine98819182009-01-19 07:37:33 -0300861static const u8 qtable4[] = {
862 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
863 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
864 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
865 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
866 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
867 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
868 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
869 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
870 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
871 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
872 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
873 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
874 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
875 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
876 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
877 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878};
879
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300880/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300881static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300882 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300884#ifdef GSPCA_DEBUG
885 if (len > USB_BUF_SZ) {
886 err("reg_r: buffer overflow");
887 return;
888 }
889#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300890 usb_control_msg(gspca_dev->dev,
891 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300892 0,
893 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
894 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300895 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300896 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300897 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300898}
899
Jean-Francois Moine60017612008-07-18 08:46:19 -0300900static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300901 u16 value,
902 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -0300903{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300904 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300905 gspca_dev->usb_buf[0] = data;
906 usb_control_msg(gspca_dev->dev,
907 usb_sndctrlpipe(gspca_dev->dev, 0),
908 0x08,
909 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
910 value,
911 0,
912 gspca_dev->usb_buf, 1,
913 500);
914}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300915static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300916 u16 value,
917 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300918 int len)
919{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300920 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -0300921 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300922#ifdef GSPCA_DEBUG
923 if (len > USB_BUF_SZ) {
924 err("reg_w: buffer overflow");
925 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300926 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300927#endif
928 memcpy(gspca_dev->usb_buf, buffer, len);
929 usb_control_msg(gspca_dev->dev,
930 usb_sndctrlpipe(gspca_dev->dev, 0),
931 0x08,
932 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
933 value, 0,
934 gspca_dev->usb_buf, len,
935 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936}
937
Jean-Francois Moine60017612008-07-18 08:46:19 -0300938/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300939static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300940{
941 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300942
Jean-Francois Moine60017612008-07-18 08:46:19 -0300943 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
944 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
945 gspca_dev->usb_buf[1] = sd->i2c_base;
946 gspca_dev->usb_buf[2] = reg;
947 gspca_dev->usb_buf[3] = val;
948 gspca_dev->usb_buf[4] = 0;
949 gspca_dev->usb_buf[5] = 0;
950 gspca_dev->usb_buf[6] = 0;
951 gspca_dev->usb_buf[7] = 0x10;
952 usb_control_msg(gspca_dev->dev,
953 usb_sndctrlpipe(gspca_dev->dev, 0),
954 0x08,
955 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
956 0x08, /* value = i2c */
957 0,
958 gspca_dev->usb_buf, 8,
959 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300960}
961
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300962/* I2C write 8 bytes */
963static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300964 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300965{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300966 memcpy(gspca_dev->usb_buf, buffer, 8);
967 usb_control_msg(gspca_dev->dev,
968 usb_sndctrlpipe(gspca_dev->dev, 0),
969 0x08,
970 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
971 0x08, 0, /* value, index */
972 gspca_dev->usb_buf, 8,
973 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300974 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300975}
976
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300977/* read 5 bytes in gspca_dev->usb_buf */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300978static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300979{
980 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -0300981 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300982
Hans de Goede3647fea2008-07-15 05:36:30 -0300983 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300984 mode[1] = sd->i2c_base;
985 mode[2] = reg;
986 mode[3] = 0;
987 mode[4] = 0;
988 mode[5] = 0;
989 mode[6] = 0;
990 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300991 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300992 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300993 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300994 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300995 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300996 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300997 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300998}
999
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001000static int hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001001{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001002 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001003 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001004 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001005 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001006 i2c_r5(gspca_dev, 0); /* read sensor id */
1007 if (gspca_dev->usb_buf[0] == 0x02
1008 && gspca_dev->usb_buf[1] == 0x09
1009 && gspca_dev->usb_buf[2] == 0x01
1010 && gspca_dev->usb_buf[3] == 0x00
1011 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001012 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001013 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001014 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001015 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001016 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1017 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001018 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1019 return -ENODEV;
1020}
1021
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001022static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001023{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001024 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001025 int i, j;
Jean-Francois Moine92e8c912009-02-02 16:25:38 -03001026 u16 val = 0;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001027 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001028 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001029 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1030 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1031 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1032 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1033 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001034 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001035 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1036 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1037 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1038 {}
1039 },
1040 };
1041
1042 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1043 reg_w1(gspca_dev, 0x17, 0x62);
1044 reg_w1(gspca_dev, 0x01, 0x08);
1045 for (j = 0; j < 3; j++)
1046 i2c_w8(gspca_dev, probe_tb[i][j]);
1047 msleep(2);
1048 reg_r(gspca_dev, 0x0a, 5);
1049 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1050 if (probe_tb[i][3][0] != 0)
1051 i2c_w8(gspca_dev, probe_tb[i][3]);
1052 reg_w1(gspca_dev, 0x01, 0x29);
1053 reg_w1(gspca_dev, 0x17, 0x42);
1054 if (val != 0xffff)
1055 break;
1056 }
1057 switch (val) {
1058 case 0x823a:
1059 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001060 sd->sensor = SENSOR_MT9V111;
1061 sd->i2c_base = 0x5c;
1062 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001063 case 0x8243:
1064 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001065 break;
1066 default:
1067 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1068 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001069 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001070}
1071
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001072static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001073 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001074{
1075 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001076 const u8 *reg9a;
1077 static const u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001078 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001079 static const u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001080 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001081 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001082
Jean-Francois Moine60017612008-07-18 08:46:19 -03001083 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001084 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001085
1086 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001087 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1088 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001089 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -03001090 switch (sd->bridge) {
1091 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001092 reg9a = reg9a_sn9c325;
1093 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001094 default:
1095 reg9a = reg9a_def;
1096 break;
1097 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001098 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001099
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001100 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001101
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001102 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001103
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001104 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001105 case SENSOR_MT9V111:
1106 reg_w1(gspca_dev, 0x01, 0x61);
1107 reg_w1(gspca_dev, 0x17, 0x61);
1108 reg_w1(gspca_dev, 0x01, 0x60);
1109 reg_w1(gspca_dev, 0x01, 0x40);
1110 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001111 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -03001112 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001113 reg_w1(gspca_dev, 0x01, 0x42);
1114 reg_w1(gspca_dev, 0x17, 0x64);
1115 reg_w1(gspca_dev, 0x01, 0x42);
1116 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001117/*jfm: from win trace */
1118 case SENSOR_OV7630:
1119 reg_w1(gspca_dev, 0x01, 0x61);
1120 reg_w1(gspca_dev, 0x17, 0xe2);
1121 reg_w1(gspca_dev, 0x01, 0x60);
1122 reg_w1(gspca_dev, 0x01, 0x40);
1123 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001124 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001125 reg_w1(gspca_dev, 0x01, 0x63);
1126 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001127 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001128 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001129/*jfm: from win trace */
1130 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001131 if (sd->bridge == BRIDGE_SN9C120) {
1132 reg_w1(gspca_dev, 0x01, 0x61);
1133 reg_w1(gspca_dev, 0x17, 0x20);
1134 reg_w1(gspca_dev, 0x01, 0x60);
1135 reg_w1(gspca_dev, 0x01, 0x40);
1136 break;
1137 }
1138 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001139 case SENSOR_SP80708:
1140 reg_w1(gspca_dev, 0x01, 0x63);
1141 reg_w1(gspca_dev, 0x17, 0x20);
1142 reg_w1(gspca_dev, 0x01, 0x62);
1143 reg_w1(gspca_dev, 0x01, 0x42);
1144 mdelay(100);
1145 reg_w1(gspca_dev, 0x02, 0x62);
1146 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001147 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001148 reg_w1(gspca_dev, 0x01, 0x43);
1149 reg_w1(gspca_dev, 0x17, 0x61);
1150 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001151 if (sd->sensor == SENSOR_HV7131R) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001152 if (hv7131r_probe(gspca_dev) < 0)
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001153 return -ENODEV;
1154 }
1155 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001156 }
1157 return 0;
1158}
1159
1160static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1161{
1162 int i = 0;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001163 static const u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001164 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1165
1166 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001167 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001168 i++;
1169 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001170 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001171}
1172
1173static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1174{
1175 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001176
1177 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001178 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001179 i++;
1180 }
1181}
1182
1183static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1184{
1185 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001186
1187 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001188 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001189 i++;
1190 }
1191}
1192
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001193static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1194{
1195 int i = 0;
1196
1197 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1198 i++;
1199 msleep(20);
1200 while (mt9v111_sensor_init[i][0]) {
1201 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1202 i++;
1203 }
1204}
1205
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001206static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1207{
1208 int i = 0;
1209
1210 while (om6802_sensor_init[i][0]) {
1211 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1212 i++;
1213 }
1214}
1215
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001216static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1217{
1218 int i = 0;
1219
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001220 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1221 i++;
1222 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001223 i++;
1224 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001225 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1226 i++;
1227 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1228 i++;
1229 msleep(20);
1230 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1231 i++;
1232/*jfm:win i2c_r from 00 to 80*/
1233
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001234 while (ov7630_sensor_init[i][0]) {
1235 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1236 i++;
1237 }
1238}
1239
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001240static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1241{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001242 int i = 0;
1243
Jean-Francois Moine62703302008-11-11 08:42:56 -03001244 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1245 i++;
1246/* win: dble reset */
1247 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1248 i++;
1249 msleep(20);
1250/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001251 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001252 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001253 i++;
1254 }
1255}
1256
1257static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1258{
1259 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001260
Jean-Francois Moine60017612008-07-18 08:46:19 -03001261 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1262 i++;
1263 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001264 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001265 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001266 i++;
1267 }
1268}
1269
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001270static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1271{
1272 int i = 0;
1273
1274 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1275 i++;
1276 msleep(20);
1277 while (sp80708_sensor_init[i][0]) {
1278 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1279 i++;
1280 }
1281}
1282
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001283/* this function is called at probe time */
1284static int sd_config(struct gspca_dev *gspca_dev,
1285 const struct usb_device_id *id)
1286{
1287 struct sd *sd = (struct sd *) gspca_dev;
1288 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001289
1290 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001291 cam->cam_mode = vga_mode;
1292 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001293
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001294 sd->bridge = id->driver_info >> 16;
1295 sd->sensor = id->driver_info >> 8;
1296 sd->i2c_base = id->driver_info;
1297
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001298 sd->brightness = BRIGHTNESS_DEF;
1299 sd->contrast = CONTRAST_DEF;
1300 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001301 sd->blue = BLUE_BALANCE_DEF;
1302 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001303 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001304 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001305 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001306 sd->vflip = VFLIP_DEF;
1307 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001308
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001309 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001310 return 0;
1311}
1312
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001313/* this function is called at probe and resume time */
1314static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001315{
1316 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001317 u8 regGpio[] = { 0x29, 0x74 };
1318 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001319
Hans de Goede3647fea2008-07-15 05:36:30 -03001320 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001321 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001322 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001323 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1324 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001325 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001326 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001327 switch (sd->bridge) {
1328 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001329 if (regF1 != 0x11)
1330 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001331 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001332 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001333 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001334 if (regF1 != 0x11)
1335 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001336 if (sd->sensor == SENSOR_MI0360)
1337 mi0360_probe(gspca_dev);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001338 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001339 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001340 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001341 if (regF1 != 0x12)
1342 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001343 if (sd->sensor == SENSOR_MI0360)
1344 mi0360_probe(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001345 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001346 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001347 break;
1348 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001349/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001350/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001351 if (regF1 != 0x12)
1352 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001353 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001354 break;
1355 }
1356
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001357 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001358
1359 return 0;
1360}
1361
Jean-Francois Moine98819182009-01-19 07:37:33 -03001362static u32 setexposure(struct gspca_dev *gspca_dev,
1363 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001364{
1365 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001366
1367 switch (sd->sensor) {
1368 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001369 u8 Expodoit[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001370 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1371
1372 Expodoit[3] = expo >> 16;
1373 Expodoit[4] = expo >> 8;
1374 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001375 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001376 break;
1377 }
1378 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001379 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001380 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001381 static const u8 doit[] = /* update sensor */
1382 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1383 static const u8 sensorgo[] = /* sensor on */
1384 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001385
1386 if (expo > 0x0635)
1387 expo = 0x0635;
1388 else if (expo < 0x0001)
1389 expo = 0x0001;
1390 expoMi[3] = expo >> 8;
1391 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001392 i2c_w8(gspca_dev, expoMi);
1393 i2c_w8(gspca_dev, doit);
1394 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001395 break;
1396 }
1397 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001398 u8 expoMof[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001399 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001400 u8 expoMo10[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001401 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001402 static const u8 gainMo[] =
1403 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001404
1405 if (expo > 0x1fff)
1406 expo = 0x1fff;
1407 else if (expo < 0x0001)
1408 expo = 0x0001;
1409 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001410 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001411 expoMo10[3] = ((expo & 0x1c00) >> 10)
1412 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001413 i2c_w8(gspca_dev, expoMo10);
1414 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001415 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001416 ((expoMo10[3] & 0x07) << 10)
1417 | (expoMof[3] << 2)
1418 | ((expoMo10[3] & 0x30) >> 4));
1419 break;
1420 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001421 case SENSOR_MT9V111: {
1422 u8 expo_c1[] =
1423 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1424
1425 if (expo > 0x0280)
1426 expo = 0x0280;
1427 else if (expo < 0x0040)
1428 expo = 0x0040;
1429 expo_c1[3] = expo >> 8;
1430 expo_c1[4] = expo;
1431 i2c_w8(gspca_dev, expo_c1);
1432 break;
1433 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001434 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001435 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001436 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1437
1438 if (expo > 0x03ff)
1439 expo = 0x03ff;
1440 if (expo < 0x0001)
1441 expo = 0x0001;
1442 gainOm[3] = expo >> 2;
1443 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001444 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001445 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001446 break;
1447 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001448 }
1449 return expo;
1450}
1451
1452static void setbrightness(struct gspca_dev *gspca_dev)
1453{
1454 struct sd *sd = (struct sd *) gspca_dev;
1455 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001456 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001457
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001458 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001459 switch (sd->sensor) {
1460 case SENSOR_HV7131R:
1461 expo = sd->brightness << 4;
1462 if (expo > 0x002dc6c0)
1463 expo = 0x002dc6c0;
1464 else if (expo < 0x02a0)
1465 expo = 0x02a0;
1466 sd->exposure = setexposure(gspca_dev, expo);
1467 break;
1468 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001469 case SENSOR_MO4000:
1470 expo = sd->brightness >> 4;
1471 sd->exposure = setexposure(gspca_dev, expo);
1472 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001473 case SENSOR_MT9V111:
1474 expo = sd->brightness >> 8;
1475 sd->exposure = setexposure(gspca_dev, expo);
1476 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001477 case SENSOR_OM6802:
1478 expo = sd->brightness >> 6;
1479 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001480 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001481 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001482 }
1483
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001484 if (sd->sensor != SENSOR_MT9V111)
1485 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001486}
1487
1488static void setcontrast(struct gspca_dev *gspca_dev)
1489{
1490 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001491 u8 k2;
1492 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001493
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001494 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1495 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001496 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001497 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001498 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001499 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001500 contrast[5] = 0;
1501 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001502}
1503
1504static void setcolors(struct gspca_dev *gspca_dev)
1505{
1506 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001507 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001508 u8 reg8a[12]; /* U & V gains */
1509 static s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001510 -24, -38, 64, /* UR UG UB */
1511 62, -51, -9 /* VR VG VB */
1512 };
1513 for (i = 0; i < 6; i++) {
1514 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001515 reg8a[i * 2] = v;
1516 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001517 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001518 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001519}
1520
1521static void setredblue(struct gspca_dev *gspca_dev)
1522{
1523 struct sd *sd = (struct sd *) gspca_dev;
1524
1525 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001526/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001527 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001528}
1529
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001530static void setgamma(struct gspca_dev *gspca_dev)
1531{
1532 struct sd *sd = (struct sd *) gspca_dev;
1533 int i;
1534 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001535 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001536 static const u8 delta[17] = {
1537 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1538 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1539 };
1540
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001541 switch (sd->sensor) {
1542 case SENSOR_HV7131R:
1543 case SENSOR_MT9V111:
1544 gamma_base = gamma_spec_1;
1545 break;
1546 case SENSOR_SP80708:
1547 gamma_base = gamma_spec_2;
1548 break;
1549 default:
1550 gamma_base = gamma_def;
1551 break;
1552 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001553
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001554 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001555 gamma[i] = gamma_base[i]
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001556 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1557 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1558}
1559
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001560static void setautogain(struct gspca_dev *gspca_dev)
1561{
1562 struct sd *sd = (struct sd *) gspca_dev;
1563
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001564 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1565 return;
1566 if (sd->autogain)
1567 sd->ag_cnt = AG_CNT_START;
1568 else
1569 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001570}
1571
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001572static void setvflip(struct sd *sd)
1573{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001574 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1575 sd->vflip ? 0x82 : 0x02);
1576}
1577
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001578static void setinfrared(struct sd *sd)
1579{
1580/*fixme: different sequence for StarCam Clip and StarCam 370i */
1581/* Clip */
1582 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1583 sd->infrared ? 0x66 : 0x64);
1584}
1585
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001586/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001587static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001588{
1589 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001590 int i;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001591 u8 reg1, reg17, reg18;
1592 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001593 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001594 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1595 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1596 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1597 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001598 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001599
1600 sn9c1xx = sn_tb[(int) sd->sensor];
1601 configure_gpio(gspca_dev, sn9c1xx);
1602
Jean-Francois Moine60017612008-07-18 08:46:19 -03001603 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1604 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1605 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1606 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1607 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1608 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1609 reg_w1(gspca_dev, 0xd3, 0x50);
1610 reg_w1(gspca_dev, 0xc6, 0x00);
1611 reg_w1(gspca_dev, 0xc7, 0x00);
1612 reg_w1(gspca_dev, 0xc8, 0x50);
1613 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001614 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001615 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001616 case SENSOR_MT9V111:
1617 reg17 = 0xe0;
1618 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001619 case SENSOR_OV7630:
1620 reg17 = 0xe2;
1621 break;
1622 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001623 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001624 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001625/*jfm: from win trace */
1626 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001627 if (sd->bridge == BRIDGE_SN9C120) {
1628 reg17 = 0xa0;
1629 break;
1630 }
1631 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001632 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001633 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001634 break;
1635 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001636 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001637/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001638 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1639 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1640 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001641 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001642
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001643 setgamma(gspca_dev);
1644
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001645 for (i = 0; i < 8; i++)
1646 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001647 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001648 case SENSOR_MT9V111:
1649 reg_w1(gspca_dev, 0x9a, 0x07);
1650 reg_w1(gspca_dev, 0x99, 0x59);
1651 break;
Jean-Francois Moine62703302008-11-11 08:42:56 -03001652 case SENSOR_OV7648:
1653 reg_w1(gspca_dev, 0x9a, 0x0a);
1654 reg_w1(gspca_dev, 0x99, 0x60);
1655 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001656 case SENSOR_SP80708:
1657 reg_w1(gspca_dev, 0x9a, 0x05);
1658 reg_w1(gspca_dev, 0x99, 0x59);
1659 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001660 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001661 if (sd->bridge == BRIDGE_SN9C120) {
1662 reg_w1(gspca_dev, 0x9a, 0x05);
1663 break;
1664 }
1665 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001666 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001667 reg_w1(gspca_dev, 0x9a, 0x08);
1668 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001669 break;
1670 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001671
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001672 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001673 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001674 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001675 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001676 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1677 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001678 switch (sd->sensor) {
1679 case SENSOR_HV7131R:
1680 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001681 break;
1682 case SENSOR_MI0360:
1683 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001684 break;
1685 case SENSOR_MO4000:
1686 mo4000_InitSensor(gspca_dev);
1687 if (mode) {
1688/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1689 reg1 = 0x06; /* clk 24Mz */
1690 } else {
1691 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001692/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001693 }
1694 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001695 case SENSOR_MT9V111:
1696 mt9v111_InitSensor(gspca_dev);
1697 if (mode) {
1698 reg1 = 0x04; /* 320 clk 48Mhz */
1699 } else {
1700/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -03001701 reg17 = 0xc2;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001702 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03001703 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001704 case SENSOR_OM6802:
1705 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001706 reg17 = 0x64; /* 640 MCKSIZE */
1707 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001708 case SENSOR_OV7630:
1709 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001710 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001711 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001712 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001713 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001714 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001715 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001716 reg17 = 0x21;
1717/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001718 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001719 case SENSOR_OV7660:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001720 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001721 if (sd->bridge == BRIDGE_SN9C120) {
1722 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001723 reg17 = 0xa2;
1724 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001725 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001726 } else {
1727 reg17 = 0x22;
1728 reg1 = 0x06; /* 24 Mhz, video trf eneble
1729 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001730 }
1731 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001732 default:
1733/* case SENSOR_SP80708: */
1734 sp80708_InitSensor(gspca_dev);
1735 if (mode) {
1736/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001737 } else {
1738 reg1 = 0x46; /* 640 clk 48Mz */
1739 reg17 = 0xa2;
1740 }
1741 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001742 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001743 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001744 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001745 switch (sd->sensor) {
1746 case SENSOR_OV7630:
1747 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001748 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001749 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001750 break;
1751 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001752 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001753 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1754 break;
1755 }
1756
1757 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001758 reg18 = sn9c1xx[0x18] | (mode << 4);
1759 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001760
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001761 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1762 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001763
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001764 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001765
Jean-Francois Moine60017612008-07-18 08:46:19 -03001766 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001767 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001768 switch (sd->sensor) {
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001769 case SENSOR_OV7630:
1770 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001771 break;
1772 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001773 setbrightness(gspca_dev);
1774 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001775 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001776 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001777}
1778
1779static void sd_stopN(struct gspca_dev *gspca_dev)
1780{
1781 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001782 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001783 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001784 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001785 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001786 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03001787 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001788 u8 data;
1789 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001790
1791 data = 0x0b;
1792 switch (sd->sensor) {
1793 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001794 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001795 data = 0x2b;
1796 break;
1797 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001798 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001799 data = 0x29;
1800 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001801 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001802 i2c_w8(gspca_dev, stopov7648);
1803 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001804 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001805 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001806 data = 0x29;
1807 break;
1808 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001809/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001810/* case SENSOR_OV7660: */
1811 break;
1812 }
1813 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001814 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1815 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1816 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1817 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001818 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001819}
1820
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001821static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001822{
1823 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001824 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001825 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001826 u8 luma_mean = 130;
1827 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001828
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001829 /* Thanks S., without your advice, autobright should not work :) */
1830 if (sd->ag_cnt < 0)
1831 return;
1832 if (--sd->ag_cnt >= 0)
1833 return;
1834 sd->ag_cnt = AG_CNT_START;
1835
1836 delta = atomic_read(&sd->avg_lum);
1837 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001838 if (delta < luma_mean - luma_delta ||
1839 delta > luma_mean + luma_delta) {
1840 switch (sd->sensor) {
1841 case SENSOR_HV7131R:
1842 expotimes = sd->exposure >> 8;
1843 expotimes += (luma_mean - delta) >> 4;
1844 if (expotimes < 0)
1845 expotimes = 0;
1846 sd->exposure = setexposure(gspca_dev,
1847 (unsigned int) (expotimes << 8));
1848 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001849 default:
1850/* case SENSOR_MO4000: */
1851/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001852/* case SENSOR_MT9V111: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001853/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001854 expotimes = sd->exposure;
1855 expotimes += (luma_mean - delta) >> 6;
1856 if (expotimes < 0)
1857 expotimes = 0;
1858 sd->exposure = setexposure(gspca_dev,
1859 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001860 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001861 break;
1862 }
1863 }
1864}
1865
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001866/* scan the URB packets */
1867/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001868static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1869 struct gspca_frame *frame, /* target */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001870 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001871 int len) /* iso packet length */
1872{
1873 struct sd *sd = (struct sd *) gspca_dev;
1874 int sof, avg_lum;
1875
1876 sof = len - 64;
1877 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1878
1879 /* end of frame */
1880 gspca_frame_add(gspca_dev, LAST_PACKET,
1881 frame, data, sof + 2);
1882 if (sd->ag_cnt < 0)
1883 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001884/* w1 w2 w3 */
1885/* w4 w5 w6 */
1886/* w7 w8 */
1887/* w4 */
1888 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1889/* w6 */
1890 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1891/* w2 */
1892 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1893/* w8 */
1894 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1895/* w5 */
1896 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1897 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001898 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001899 return;
1900 }
1901 if (gspca_dev->last_packet_type == LAST_PACKET) {
1902
1903 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001904 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001905 }
1906 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1907}
1908
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001909static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1910{
1911 struct sd *sd = (struct sd *) gspca_dev;
1912
1913 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001914 if (gspca_dev->streaming)
1915 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001916 return 0;
1917}
1918
1919static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1920{
1921 struct sd *sd = (struct sd *) gspca_dev;
1922
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001923 *val = sd->brightness;
1924 return 0;
1925}
1926
1927static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1928{
1929 struct sd *sd = (struct sd *) gspca_dev;
1930
1931 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001932 if (gspca_dev->streaming)
1933 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001934 return 0;
1935}
1936
1937static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1938{
1939 struct sd *sd = (struct sd *) gspca_dev;
1940
1941 *val = sd->contrast;
1942 return 0;
1943}
1944
1945static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1946{
1947 struct sd *sd = (struct sd *) gspca_dev;
1948
1949 sd->colors = val;
1950 if (gspca_dev->streaming)
1951 setcolors(gspca_dev);
1952 return 0;
1953}
1954
1955static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1956{
1957 struct sd *sd = (struct sd *) gspca_dev;
1958
1959 *val = sd->colors;
1960 return 0;
1961}
1962
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001963static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1964{
1965 struct sd *sd = (struct sd *) gspca_dev;
1966
1967 sd->blue = val;
1968 if (gspca_dev->streaming)
1969 setredblue(gspca_dev);
1970 return 0;
1971}
1972
1973static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1974{
1975 struct sd *sd = (struct sd *) gspca_dev;
1976
1977 *val = sd->blue;
1978 return 0;
1979}
1980
1981static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1982{
1983 struct sd *sd = (struct sd *) gspca_dev;
1984
1985 sd->red = val;
1986 if (gspca_dev->streaming)
1987 setredblue(gspca_dev);
1988 return 0;
1989}
1990
1991static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1992{
1993 struct sd *sd = (struct sd *) gspca_dev;
1994
1995 *val = sd->red;
1996 return 0;
1997}
1998
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001999static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2000{
2001 struct sd *sd = (struct sd *) gspca_dev;
2002
2003 sd->gamma = val;
2004 if (gspca_dev->streaming)
2005 setgamma(gspca_dev);
2006 return 0;
2007}
2008
2009static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2010{
2011 struct sd *sd = (struct sd *) gspca_dev;
2012
2013 *val = sd->gamma;
2014 return 0;
2015}
2016
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002017static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2018{
2019 struct sd *sd = (struct sd *) gspca_dev;
2020
2021 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002022 if (gspca_dev->streaming)
2023 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002024 return 0;
2025}
2026
2027static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2028{
2029 struct sd *sd = (struct sd *) gspca_dev;
2030
2031 *val = sd->autogain;
2032 return 0;
2033}
2034
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002035static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2036{
2037 struct sd *sd = (struct sd *) gspca_dev;
2038
2039 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002040 if (gspca_dev->streaming)
2041 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002042 return 0;
2043}
2044
2045static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2046{
2047 struct sd *sd = (struct sd *) gspca_dev;
2048
2049 *val = sd->vflip;
2050 return 0;
2051}
2052
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002053static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2054{
2055 struct sd *sd = (struct sd *) gspca_dev;
2056
2057 sd->infrared = val;
2058 if (gspca_dev->streaming)
2059 setinfrared(sd);
2060 return 0;
2061}
2062
2063static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2064{
2065 struct sd *sd = (struct sd *) gspca_dev;
2066
2067 *val = sd->infrared;
2068 return 0;
2069}
2070
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002071/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002072static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002073 .name = MODULE_NAME,
2074 .ctrls = sd_ctrls,
2075 .nctrls = ARRAY_SIZE(sd_ctrls),
2076 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002077 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002078 .start = sd_start,
2079 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002080 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002081 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002082};
2083
2084/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002085#define BSI(bridge, sensor, i2c_addr) \
2086 .driver_info = (BRIDGE_ ## bridge << 16) \
2087 | (SENSOR_ ## sensor << 8) \
2088 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002089static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002090#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002091 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03002092 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002093#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002094 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2095 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002096#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002097 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002098#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03002099 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002100 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03002101 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002102 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2103/* bw600.inf:
2104 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2105/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2106/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2107 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2108/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
Jean-Francois Moine661ab252009-01-29 16:03:19 -03002109 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002110/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2111/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2112 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2113/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2114/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2115 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2116 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002117#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2118 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2119#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002120/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2121/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2122/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002123 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2124/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03002125 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002126 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002127 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002128/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002129#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002130 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002131#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002132 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03002133 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002134#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002135 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2136 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2137/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002138#endif
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002139 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002140 {}
2141};
2142MODULE_DEVICE_TABLE(usb, device_table);
2143
2144/* -- device connect -- */
2145static int sd_probe(struct usb_interface *intf,
2146 const struct usb_device_id *id)
2147{
2148 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2149 THIS_MODULE);
2150}
2151
2152static struct usb_driver sd_driver = {
2153 .name = MODULE_NAME,
2154 .id_table = device_table,
2155 .probe = sd_probe,
2156 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002157#ifdef CONFIG_PM
2158 .suspend = gspca_suspend,
2159 .resume = gspca_resume,
2160#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002161};
2162
2163/* -- module insert / remove -- */
2164static int __init sd_mod_init(void)
2165{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002166 int ret;
2167 ret = usb_register(&sd_driver);
2168 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002169 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002170 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002171 return 0;
2172}
2173static void __exit sd_mod_exit(void)
2174{
2175 usb_deregister(&sd_driver);
2176 info("deregistered");
2177}
2178
2179module_init(sd_mod_init);
2180module_exit(sd_mod_exit);