blob: edc26d8ad2ad7730a209e26da724a8d99d9d323f [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 Moine2797ba22009-02-05 15:12:24 -030048 u8 vflip; /* ov7630/ov7648 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 Moine2797ba22009-02-05 15:12:24 -0300195/* ov7630/ov7648 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 Moine2797ba22009-02-05 15:12:24 -0300205#define VFLIP_DEF 0 /* vflip def = 1 for ov7630 */
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 Moinec33c02e2009-02-05 15:04:33 -0300237 (1 << VFLIP_IDX),
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 Moine2797ba22009-02-05 15:12:24 -0300243 (1 << INFRARED_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 */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300672/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
673 * set by setvflip */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300674 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
675 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
676/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
677/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
678/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
679/*...*/
680 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
681/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
682/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
683/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
684/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
685/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
686
687 {}
688};
689
Jean-Francois Moine98819182009-01-19 07:37:33 -0300690static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300691 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300692/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300693 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300694 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300695 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300696 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300697 /* GAIN BLUE RED VREF */
698 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
699 /* COM 1 BAVE GEAVE AECHH */
700 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
701 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300702 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300703 /* AECH CLKRC COM7 COM8 */
704 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
705 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
706 /* HSTART HSTOP VSTRT VSTOP */
707 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
708 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
709 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
710 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300711/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
712 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300713 /* AEW AEB VPT BBIAS */
714 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
715 /* GbBIAS RSVD EXHCH EXHCL */
716 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
717 /* RBIAS ADVFL ASDVFH YAVE */
718 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
719 /* HSYST HSYEN HREF */
720 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
721 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
722 /* ADC ACOM OFON TSLB */
723 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
724 /* COM11 COM12 COM13 COM14 */
725 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
726 /* EDGE COM15 COM16 COM17 */
727 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
728 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
729 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
730 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
731 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
732 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
733 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
734 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
735 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
736 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
737 /* LCC1 LCC2 LCC3 LCC4 */
738 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300739 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300740 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300741 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
743 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
744 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
745 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
746 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
747 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
748 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
749 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
750 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300751 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300752/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300753 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300754 /* bits[3..0]reserved */
755 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
756 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
757 /* VREF vertical frame ctrl */
758 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300759 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
760 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
761 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
762 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
763/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300764/****** (some exchanges in the win trace) ******/
765 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300766 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
767 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
768 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
769/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300770/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300771/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300772 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300776 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300778
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300779static const u8 sp80708_sensor_init[][8] = {
780 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
847 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
848 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
849 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
850 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
851 /********/
852 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
853 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
854 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
855 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
856 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
857 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
858 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
859 {}
860};
861
Jean-Francois Moine98819182009-01-19 07:37:33 -0300862static const u8 qtable4[] = {
863 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
864 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
865 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
866 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
867 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
868 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
869 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
870 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
871 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
872 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 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,
878 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300879};
880
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300881/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300882static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300883 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300884{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300885#ifdef GSPCA_DEBUG
886 if (len > USB_BUF_SZ) {
887 err("reg_r: buffer overflow");
888 return;
889 }
890#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300891 usb_control_msg(gspca_dev->dev,
892 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300893 0,
894 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
895 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300896 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300897 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300898 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300899}
900
Jean-Francois Moine60017612008-07-18 08:46:19 -0300901static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300902 u16 value,
903 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -0300904{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300905 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300906 gspca_dev->usb_buf[0] = data;
907 usb_control_msg(gspca_dev->dev,
908 usb_sndctrlpipe(gspca_dev->dev, 0),
909 0x08,
910 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
911 value,
912 0,
913 gspca_dev->usb_buf, 1,
914 500);
915}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300916static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300917 u16 value,
918 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300919 int len)
920{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300921 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -0300922 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300923#ifdef GSPCA_DEBUG
924 if (len > USB_BUF_SZ) {
925 err("reg_w: buffer overflow");
926 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300927 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300928#endif
929 memcpy(gspca_dev->usb_buf, buffer, len);
930 usb_control_msg(gspca_dev->dev,
931 usb_sndctrlpipe(gspca_dev->dev, 0),
932 0x08,
933 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
934 value, 0,
935 gspca_dev->usb_buf, len,
936 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300937}
938
Jean-Francois Moine60017612008-07-18 08:46:19 -0300939/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300940static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300941{
942 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300943
Jean-Francois Moine60017612008-07-18 08:46:19 -0300944 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
945 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
946 gspca_dev->usb_buf[1] = sd->i2c_base;
947 gspca_dev->usb_buf[2] = reg;
948 gspca_dev->usb_buf[3] = val;
949 gspca_dev->usb_buf[4] = 0;
950 gspca_dev->usb_buf[5] = 0;
951 gspca_dev->usb_buf[6] = 0;
952 gspca_dev->usb_buf[7] = 0x10;
953 usb_control_msg(gspca_dev->dev,
954 usb_sndctrlpipe(gspca_dev->dev, 0),
955 0x08,
956 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
957 0x08, /* value = i2c */
958 0,
959 gspca_dev->usb_buf, 8,
960 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300961}
962
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300963/* I2C write 8 bytes */
964static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300965 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300966{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300967 memcpy(gspca_dev->usb_buf, buffer, 8);
968 usb_control_msg(gspca_dev->dev,
969 usb_sndctrlpipe(gspca_dev->dev, 0),
970 0x08,
971 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
972 0x08, 0, /* value, index */
973 gspca_dev->usb_buf, 8,
974 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300975 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300976}
977
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300978/* read 5 bytes in gspca_dev->usb_buf */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300979static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300980{
981 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -0300982 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300983
Hans de Goede3647fea2008-07-15 05:36:30 -0300984 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300985 mode[1] = sd->i2c_base;
986 mode[2] = reg;
987 mode[3] = 0;
988 mode[4] = 0;
989 mode[5] = 0;
990 mode[6] = 0;
991 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300992 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300993 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300994 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300995 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300996 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300997 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300998 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300999}
1000
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001001static int hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001002{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001003 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001004 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001005 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001006 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001007 i2c_r5(gspca_dev, 0); /* read sensor id */
1008 if (gspca_dev->usb_buf[0] == 0x02
1009 && gspca_dev->usb_buf[1] == 0x09
1010 && gspca_dev->usb_buf[2] == 0x01
1011 && gspca_dev->usb_buf[3] == 0x00
1012 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001013 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001014 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001015 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001016 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001017 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1018 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001019 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1020 return -ENODEV;
1021}
1022
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001023static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001024{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001025 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001026 int i, j;
Jean-Francois Moine92e8c912009-02-02 16:25:38 -03001027 u16 val = 0;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001028 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001029 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001030 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1031 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1032 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1033 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1034 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001035 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001036 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1037 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1038 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1039 {}
1040 },
1041 };
1042
1043 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1044 reg_w1(gspca_dev, 0x17, 0x62);
1045 reg_w1(gspca_dev, 0x01, 0x08);
1046 for (j = 0; j < 3; j++)
1047 i2c_w8(gspca_dev, probe_tb[i][j]);
1048 msleep(2);
1049 reg_r(gspca_dev, 0x0a, 5);
1050 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1051 if (probe_tb[i][3][0] != 0)
1052 i2c_w8(gspca_dev, probe_tb[i][3]);
1053 reg_w1(gspca_dev, 0x01, 0x29);
1054 reg_w1(gspca_dev, 0x17, 0x42);
1055 if (val != 0xffff)
1056 break;
1057 }
1058 switch (val) {
1059 case 0x823a:
1060 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001061 sd->sensor = SENSOR_MT9V111;
1062 sd->i2c_base = 0x5c;
1063 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001064 case 0x8243:
1065 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001066 break;
1067 default:
1068 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1069 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001070 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001071}
1072
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001073static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001074 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001075{
1076 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001077 const u8 *reg9a;
1078 static const u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001079 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001080 static const u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001081 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001082 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001083
Jean-Francois Moine60017612008-07-18 08:46:19 -03001084 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001085 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001086
1087 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001088 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1089 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001090 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -03001091 switch (sd->bridge) {
1092 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001093 reg9a = reg9a_sn9c325;
1094 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001095 default:
1096 reg9a = reg9a_def;
1097 break;
1098 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001099 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001100
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001101 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001102
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001103 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001104
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001105 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001106 case SENSOR_MT9V111:
1107 reg_w1(gspca_dev, 0x01, 0x61);
1108 reg_w1(gspca_dev, 0x17, 0x61);
1109 reg_w1(gspca_dev, 0x01, 0x60);
1110 reg_w1(gspca_dev, 0x01, 0x40);
1111 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001112 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -03001113 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001114 reg_w1(gspca_dev, 0x01, 0x42);
1115 reg_w1(gspca_dev, 0x17, 0x64);
1116 reg_w1(gspca_dev, 0x01, 0x42);
1117 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001118/*jfm: from win trace */
1119 case SENSOR_OV7630:
1120 reg_w1(gspca_dev, 0x01, 0x61);
1121 reg_w1(gspca_dev, 0x17, 0xe2);
1122 reg_w1(gspca_dev, 0x01, 0x60);
1123 reg_w1(gspca_dev, 0x01, 0x40);
1124 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001125 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001126 reg_w1(gspca_dev, 0x01, 0x63);
1127 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001128 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001129 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001130/*jfm: from win trace */
1131 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001132 if (sd->bridge == BRIDGE_SN9C120) {
1133 reg_w1(gspca_dev, 0x01, 0x61);
1134 reg_w1(gspca_dev, 0x17, 0x20);
1135 reg_w1(gspca_dev, 0x01, 0x60);
1136 reg_w1(gspca_dev, 0x01, 0x40);
1137 break;
1138 }
1139 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001140 case SENSOR_SP80708:
1141 reg_w1(gspca_dev, 0x01, 0x63);
1142 reg_w1(gspca_dev, 0x17, 0x20);
1143 reg_w1(gspca_dev, 0x01, 0x62);
1144 reg_w1(gspca_dev, 0x01, 0x42);
1145 mdelay(100);
1146 reg_w1(gspca_dev, 0x02, 0x62);
1147 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001148 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001149 reg_w1(gspca_dev, 0x01, 0x43);
1150 reg_w1(gspca_dev, 0x17, 0x61);
1151 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001152 if (sd->sensor == SENSOR_HV7131R) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001153 if (hv7131r_probe(gspca_dev) < 0)
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001154 return -ENODEV;
1155 }
1156 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001157 }
1158 return 0;
1159}
1160
1161static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1162{
1163 int i = 0;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001164 static const u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001165 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1166
1167 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001168 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001169 i++;
1170 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001171 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001172}
1173
1174static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1175{
1176 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001177
1178 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001179 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001180 i++;
1181 }
1182}
1183
1184static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1185{
1186 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001187
1188 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001189 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001190 i++;
1191 }
1192}
1193
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001194static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1195{
1196 int i = 0;
1197
1198 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1199 i++;
1200 msleep(20);
1201 while (mt9v111_sensor_init[i][0]) {
1202 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1203 i++;
1204 }
1205}
1206
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001207static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1208{
1209 int i = 0;
1210
1211 while (om6802_sensor_init[i][0]) {
1212 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1213 i++;
1214 }
1215}
1216
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001217static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1218{
1219 int i = 0;
1220
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001221 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1222 i++;
1223 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001224 i++;
1225 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001226 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1227 i++;
1228 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1229 i++;
1230 msleep(20);
1231 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1232 i++;
1233/*jfm:win i2c_r from 00 to 80*/
1234
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001235 while (ov7630_sensor_init[i][0]) {
1236 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1237 i++;
1238 }
1239}
1240
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001241static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1242{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001243 int i = 0;
1244
Jean-Francois Moine62703302008-11-11 08:42:56 -03001245 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1246 i++;
1247/* win: dble reset */
1248 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1249 i++;
1250 msleep(20);
1251/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001252 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001253 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001254 i++;
1255 }
1256}
1257
1258static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1259{
1260 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001261
Jean-Francois Moine60017612008-07-18 08:46:19 -03001262 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1263 i++;
1264 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001265 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001266 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001267 i++;
1268 }
1269}
1270
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001271static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1272{
1273 int i = 0;
1274
1275 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1276 i++;
1277 msleep(20);
1278 while (sp80708_sensor_init[i][0]) {
1279 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1280 i++;
1281 }
1282}
1283
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001284/* this function is called at probe time */
1285static int sd_config(struct gspca_dev *gspca_dev,
1286 const struct usb_device_id *id)
1287{
1288 struct sd *sd = (struct sd *) gspca_dev;
1289 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001290
1291 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001292 cam->cam_mode = vga_mode;
1293 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001294
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001295 sd->bridge = id->driver_info >> 16;
1296 sd->sensor = id->driver_info >> 8;
1297 sd->i2c_base = id->driver_info;
1298
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001299 sd->brightness = BRIGHTNESS_DEF;
1300 sd->contrast = CONTRAST_DEF;
1301 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001302 sd->blue = BLUE_BALANCE_DEF;
1303 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001304 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001305 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001306 sd->ag_cnt = -1;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001307 if (sd->sensor != SENSOR_OV7630)
1308 sd->vflip = 0;
1309 else
1310 sd->vflip = 1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001311 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001312
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001313 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001314 return 0;
1315}
1316
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001317/* this function is called at probe and resume time */
1318static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001319{
1320 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001321 u8 regGpio[] = { 0x29, 0x74 };
1322 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001323
Hans de Goede3647fea2008-07-15 05:36:30 -03001324 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001325 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001326 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001327 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1328 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001329 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001330 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001331 switch (sd->bridge) {
1332 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001333 if (regF1 != 0x11)
1334 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001335 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001336 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001337 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001338 if (regF1 != 0x11)
1339 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001340 if (sd->sensor == SENSOR_MI0360)
1341 mi0360_probe(gspca_dev);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001342 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001343 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001344 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001345 if (regF1 != 0x12)
1346 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001347 if (sd->sensor == SENSOR_MI0360)
1348 mi0360_probe(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001349 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001350 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001351 break;
1352 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001353/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001354/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001355 if (regF1 != 0x12)
1356 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001357 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001358 break;
1359 }
1360
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001361 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001362
1363 return 0;
1364}
1365
Jean-Francois Moine98819182009-01-19 07:37:33 -03001366static u32 setexposure(struct gspca_dev *gspca_dev,
1367 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368{
1369 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001370
1371 switch (sd->sensor) {
1372 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001373 u8 Expodoit[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001374 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1375
1376 Expodoit[3] = expo >> 16;
1377 Expodoit[4] = expo >> 8;
1378 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001379 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001380 break;
1381 }
1382 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001383 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001384 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001385 static const u8 doit[] = /* update sensor */
1386 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1387 static const u8 sensorgo[] = /* sensor on */
1388 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001389
1390 if (expo > 0x0635)
1391 expo = 0x0635;
1392 else if (expo < 0x0001)
1393 expo = 0x0001;
1394 expoMi[3] = expo >> 8;
1395 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001396 i2c_w8(gspca_dev, expoMi);
1397 i2c_w8(gspca_dev, doit);
1398 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001399 break;
1400 }
1401 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001402 u8 expoMof[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001403 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001404 u8 expoMo10[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001405 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001406 static const u8 gainMo[] =
1407 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001408
1409 if (expo > 0x1fff)
1410 expo = 0x1fff;
1411 else if (expo < 0x0001)
1412 expo = 0x0001;
1413 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001414 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001415 expoMo10[3] = ((expo & 0x1c00) >> 10)
1416 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001417 i2c_w8(gspca_dev, expoMo10);
1418 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001419 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001420 ((expoMo10[3] & 0x07) << 10)
1421 | (expoMof[3] << 2)
1422 | ((expoMo10[3] & 0x30) >> 4));
1423 break;
1424 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001425 case SENSOR_MT9V111: {
1426 u8 expo_c1[] =
1427 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1428
1429 if (expo > 0x0280)
1430 expo = 0x0280;
1431 else if (expo < 0x0040)
1432 expo = 0x0040;
1433 expo_c1[3] = expo >> 8;
1434 expo_c1[4] = expo;
1435 i2c_w8(gspca_dev, expo_c1);
1436 break;
1437 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001438 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001439 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001440 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1441
1442 if (expo > 0x03ff)
1443 expo = 0x03ff;
1444 if (expo < 0x0001)
1445 expo = 0x0001;
1446 gainOm[3] = expo >> 2;
1447 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001448 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001449 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001450 break;
1451 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001452 }
1453 return expo;
1454}
1455
1456static void setbrightness(struct gspca_dev *gspca_dev)
1457{
1458 struct sd *sd = (struct sd *) gspca_dev;
1459 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001460 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001461
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001462 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001463 switch (sd->sensor) {
1464 case SENSOR_HV7131R:
1465 expo = sd->brightness << 4;
1466 if (expo > 0x002dc6c0)
1467 expo = 0x002dc6c0;
1468 else if (expo < 0x02a0)
1469 expo = 0x02a0;
1470 sd->exposure = setexposure(gspca_dev, expo);
1471 break;
1472 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001473 case SENSOR_MO4000:
1474 expo = sd->brightness >> 4;
1475 sd->exposure = setexposure(gspca_dev, expo);
1476 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001477 case SENSOR_MT9V111:
1478 expo = sd->brightness >> 8;
1479 sd->exposure = setexposure(gspca_dev, expo);
1480 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001481 case SENSOR_OM6802:
1482 expo = sd->brightness >> 6;
1483 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001484 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001485 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001486 }
1487
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001488 if (sd->sensor != SENSOR_MT9V111)
1489 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001490}
1491
1492static void setcontrast(struct gspca_dev *gspca_dev)
1493{
1494 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001495 u8 k2;
1496 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001497
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001498 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1499 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001500 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001501 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001502 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001503 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001504 contrast[5] = 0;
1505 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001506}
1507
1508static void setcolors(struct gspca_dev *gspca_dev)
1509{
1510 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001511 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001512 u8 reg8a[12]; /* U & V gains */
1513 static s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001514 -24, -38, 64, /* UR UG UB */
1515 62, -51, -9 /* VR VG VB */
1516 };
1517 for (i = 0; i < 6; i++) {
1518 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001519 reg8a[i * 2] = v;
1520 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001521 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001522 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001523}
1524
1525static void setredblue(struct gspca_dev *gspca_dev)
1526{
1527 struct sd *sd = (struct sd *) gspca_dev;
1528
1529 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001530/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001531 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001532}
1533
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001534static void setgamma(struct gspca_dev *gspca_dev)
1535{
1536 struct sd *sd = (struct sd *) gspca_dev;
1537 int i;
1538 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001539 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001540 static const u8 delta[17] = {
1541 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1542 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1543 };
1544
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001545 switch (sd->sensor) {
1546 case SENSOR_HV7131R:
1547 case SENSOR_MT9V111:
1548 gamma_base = gamma_spec_1;
1549 break;
1550 case SENSOR_SP80708:
1551 gamma_base = gamma_spec_2;
1552 break;
1553 default:
1554 gamma_base = gamma_def;
1555 break;
1556 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001557
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001558 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001559 gamma[i] = gamma_base[i]
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001560 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1561 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1562}
1563
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001564static void setautogain(struct gspca_dev *gspca_dev)
1565{
1566 struct sd *sd = (struct sd *) gspca_dev;
1567
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001568 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1569 return;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001570 switch (sd->sensor) {
1571 case SENSOR_OV7630:
1572 case SENSOR_OV7648: {
1573 u8 comb;
1574
1575 if (sd->sensor == SENSOR_OV7630)
1576 comb = 0xc0;
1577 else
1578 comb = 0xa0;
1579 if (sd->autogain)
1580 comb |= 0x02;
1581 i2c_w1(&sd->gspca_dev, 0x13, comb);
1582 return;
1583 }
1584 }
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001585 if (sd->autogain)
1586 sd->ag_cnt = AG_CNT_START;
1587 else
1588 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001589}
1590
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001591/* ov7630/ov7648 only */
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001592static void setvflip(struct sd *sd)
1593{
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001594 u8 comn;
1595
1596 if (sd->sensor == SENSOR_OV7630)
1597 comn = 0x02;
1598 else
1599 comn = 0x06;
1600 if (sd->vflip)
1601 comn |= 0x80;
1602 i2c_w1(&sd->gspca_dev, 0x75, comn);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001603}
1604
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001605static void setinfrared(struct sd *sd)
1606{
1607/*fixme: different sequence for StarCam Clip and StarCam 370i */
1608/* Clip */
1609 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1610 sd->infrared ? 0x66 : 0x64);
1611}
1612
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001613/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001614static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001615{
1616 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001617 int i;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001618 u8 reg1, reg17, reg18;
1619 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001620 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001621 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1622 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1623 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1624 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001625 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001626
1627 sn9c1xx = sn_tb[(int) sd->sensor];
1628 configure_gpio(gspca_dev, sn9c1xx);
1629
Jean-Francois Moine60017612008-07-18 08:46:19 -03001630 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1631 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1632 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1633 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1634 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1635 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1636 reg_w1(gspca_dev, 0xd3, 0x50);
1637 reg_w1(gspca_dev, 0xc6, 0x00);
1638 reg_w1(gspca_dev, 0xc7, 0x00);
1639 reg_w1(gspca_dev, 0xc8, 0x50);
1640 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001641 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001642 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001643 case SENSOR_MT9V111:
1644 reg17 = 0xe0;
1645 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001646 case SENSOR_OV7630:
1647 reg17 = 0xe2;
1648 break;
1649 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001650 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001651 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001652/*jfm: from win trace */
1653 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001654 if (sd->bridge == BRIDGE_SN9C120) {
1655 reg17 = 0xa0;
1656 break;
1657 }
1658 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001659 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001660 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001661 break;
1662 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001663 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001664/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001665 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1666 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1667 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001668 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001669
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001670 setgamma(gspca_dev);
1671
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001672 for (i = 0; i < 8; i++)
1673 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001674 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001675 case SENSOR_MT9V111:
1676 reg_w1(gspca_dev, 0x9a, 0x07);
1677 reg_w1(gspca_dev, 0x99, 0x59);
1678 break;
Jean-Francois Moine62703302008-11-11 08:42:56 -03001679 case SENSOR_OV7648:
1680 reg_w1(gspca_dev, 0x9a, 0x0a);
1681 reg_w1(gspca_dev, 0x99, 0x60);
1682 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001683 case SENSOR_SP80708:
1684 reg_w1(gspca_dev, 0x9a, 0x05);
1685 reg_w1(gspca_dev, 0x99, 0x59);
1686 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001687 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001688 if (sd->bridge == BRIDGE_SN9C120) {
1689 reg_w1(gspca_dev, 0x9a, 0x05);
1690 break;
1691 }
1692 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001693 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001694 reg_w1(gspca_dev, 0x9a, 0x08);
1695 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001696 break;
1697 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001698
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001699 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001700 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001701 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001702 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001703 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1704 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001705 switch (sd->sensor) {
1706 case SENSOR_HV7131R:
1707 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001708 break;
1709 case SENSOR_MI0360:
1710 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001711 break;
1712 case SENSOR_MO4000:
1713 mo4000_InitSensor(gspca_dev);
1714 if (mode) {
1715/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1716 reg1 = 0x06; /* clk 24Mz */
1717 } else {
1718 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001719/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001720 }
1721 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001722 case SENSOR_MT9V111:
1723 mt9v111_InitSensor(gspca_dev);
1724 if (mode) {
1725 reg1 = 0x04; /* 320 clk 48Mhz */
1726 } else {
1727/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -03001728 reg17 = 0xc2;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001729 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03001730 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001731 case SENSOR_OM6802:
1732 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001733 reg17 = 0x64; /* 640 MCKSIZE */
1734 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001735 case SENSOR_OV7630:
1736 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001737 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001738 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001739 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001740 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001741 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001742 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001743 reg17 = 0x21;
1744/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001745 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001746 case SENSOR_OV7660:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001747 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001748 if (sd->bridge == BRIDGE_SN9C120) {
1749 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001750 reg17 = 0xa2;
1751 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001752 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001753 } else {
1754 reg17 = 0x22;
1755 reg1 = 0x06; /* 24 Mhz, video trf eneble
1756 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001757 }
1758 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001759 default:
1760/* case SENSOR_SP80708: */
1761 sp80708_InitSensor(gspca_dev);
1762 if (mode) {
1763/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001764 } else {
1765 reg1 = 0x46; /* 640 clk 48Mz */
1766 reg17 = 0xa2;
1767 }
1768 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001769 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001770 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001771 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001772 switch (sd->sensor) {
1773 case SENSOR_OV7630:
1774 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001775 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001776 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001777 break;
1778 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001779 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001780 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1781 break;
1782 }
1783
1784 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001785 reg18 = sn9c1xx[0x18] | (mode << 4);
1786 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001787
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001788 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1789 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001790
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001791 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001792
Jean-Francois Moine60017612008-07-18 08:46:19 -03001793 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001794 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001795 switch (sd->sensor) {
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001796 case SENSOR_OV7630:
1797 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001798 break;
1799 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001800 setbrightness(gspca_dev);
1801 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001802 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001803 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001804}
1805
1806static void sd_stopN(struct gspca_dev *gspca_dev)
1807{
1808 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001809 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001810 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001811 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001812 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001813 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03001814 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001815 u8 data;
1816 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001817
1818 data = 0x0b;
1819 switch (sd->sensor) {
1820 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001821 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001822 data = 0x2b;
1823 break;
1824 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001825 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001826 data = 0x29;
1827 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001828 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001829 i2c_w8(gspca_dev, stopov7648);
1830 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001831 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001832 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001833 data = 0x29;
1834 break;
1835 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001836/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001837/* case SENSOR_OV7660: */
1838 break;
1839 }
1840 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001841 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1842 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1843 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1844 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001845 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001846}
1847
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001848static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001849{
1850 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001851 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001852 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001853 u8 luma_mean = 130;
1854 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001855
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001856 /* Thanks S., without your advice, autobright should not work :) */
1857 if (sd->ag_cnt < 0)
1858 return;
1859 if (--sd->ag_cnt >= 0)
1860 return;
1861 sd->ag_cnt = AG_CNT_START;
1862
1863 delta = atomic_read(&sd->avg_lum);
1864 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001865 if (delta < luma_mean - luma_delta ||
1866 delta > luma_mean + luma_delta) {
1867 switch (sd->sensor) {
1868 case SENSOR_HV7131R:
1869 expotimes = sd->exposure >> 8;
1870 expotimes += (luma_mean - delta) >> 4;
1871 if (expotimes < 0)
1872 expotimes = 0;
1873 sd->exposure = setexposure(gspca_dev,
1874 (unsigned int) (expotimes << 8));
1875 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001876 default:
1877/* case SENSOR_MO4000: */
1878/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001879/* case SENSOR_MT9V111: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001880/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001881 expotimes = sd->exposure;
1882 expotimes += (luma_mean - delta) >> 6;
1883 if (expotimes < 0)
1884 expotimes = 0;
1885 sd->exposure = setexposure(gspca_dev,
1886 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001887 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001888 break;
1889 }
1890 }
1891}
1892
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001893/* scan the URB packets */
1894/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001895static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1896 struct gspca_frame *frame, /* target */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001897 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001898 int len) /* iso packet length */
1899{
1900 struct sd *sd = (struct sd *) gspca_dev;
1901 int sof, avg_lum;
1902
1903 sof = len - 64;
1904 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1905
1906 /* end of frame */
1907 gspca_frame_add(gspca_dev, LAST_PACKET,
1908 frame, data, sof + 2);
1909 if (sd->ag_cnt < 0)
1910 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001911/* w1 w2 w3 */
1912/* w4 w5 w6 */
1913/* w7 w8 */
1914/* w4 */
1915 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1916/* w6 */
1917 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1918/* w2 */
1919 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1920/* w8 */
1921 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1922/* w5 */
1923 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1924 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001925 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001926 return;
1927 }
1928 if (gspca_dev->last_packet_type == LAST_PACKET) {
1929
1930 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001931 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001932 }
1933 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1934}
1935
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001936static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1937{
1938 struct sd *sd = (struct sd *) gspca_dev;
1939
1940 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001941 if (gspca_dev->streaming)
1942 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001943 return 0;
1944}
1945
1946static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1947{
1948 struct sd *sd = (struct sd *) gspca_dev;
1949
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001950 *val = sd->brightness;
1951 return 0;
1952}
1953
1954static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1955{
1956 struct sd *sd = (struct sd *) gspca_dev;
1957
1958 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001959 if (gspca_dev->streaming)
1960 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001961 return 0;
1962}
1963
1964static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1965{
1966 struct sd *sd = (struct sd *) gspca_dev;
1967
1968 *val = sd->contrast;
1969 return 0;
1970}
1971
1972static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1973{
1974 struct sd *sd = (struct sd *) gspca_dev;
1975
1976 sd->colors = val;
1977 if (gspca_dev->streaming)
1978 setcolors(gspca_dev);
1979 return 0;
1980}
1981
1982static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1983{
1984 struct sd *sd = (struct sd *) gspca_dev;
1985
1986 *val = sd->colors;
1987 return 0;
1988}
1989
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001990static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1991{
1992 struct sd *sd = (struct sd *) gspca_dev;
1993
1994 sd->blue = val;
1995 if (gspca_dev->streaming)
1996 setredblue(gspca_dev);
1997 return 0;
1998}
1999
2000static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2001{
2002 struct sd *sd = (struct sd *) gspca_dev;
2003
2004 *val = sd->blue;
2005 return 0;
2006}
2007
2008static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2009{
2010 struct sd *sd = (struct sd *) gspca_dev;
2011
2012 sd->red = val;
2013 if (gspca_dev->streaming)
2014 setredblue(gspca_dev);
2015 return 0;
2016}
2017
2018static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2019{
2020 struct sd *sd = (struct sd *) gspca_dev;
2021
2022 *val = sd->red;
2023 return 0;
2024}
2025
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002026static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2027{
2028 struct sd *sd = (struct sd *) gspca_dev;
2029
2030 sd->gamma = val;
2031 if (gspca_dev->streaming)
2032 setgamma(gspca_dev);
2033 return 0;
2034}
2035
2036static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2037{
2038 struct sd *sd = (struct sd *) gspca_dev;
2039
2040 *val = sd->gamma;
2041 return 0;
2042}
2043
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002044static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2045{
2046 struct sd *sd = (struct sd *) gspca_dev;
2047
2048 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002049 if (gspca_dev->streaming)
2050 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002051 return 0;
2052}
2053
2054static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2055{
2056 struct sd *sd = (struct sd *) gspca_dev;
2057
2058 *val = sd->autogain;
2059 return 0;
2060}
2061
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002062static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2063{
2064 struct sd *sd = (struct sd *) gspca_dev;
2065
2066 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002067 if (gspca_dev->streaming)
2068 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002069 return 0;
2070}
2071
2072static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2073{
2074 struct sd *sd = (struct sd *) gspca_dev;
2075
2076 *val = sd->vflip;
2077 return 0;
2078}
2079
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002080static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2081{
2082 struct sd *sd = (struct sd *) gspca_dev;
2083
2084 sd->infrared = val;
2085 if (gspca_dev->streaming)
2086 setinfrared(sd);
2087 return 0;
2088}
2089
2090static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2091{
2092 struct sd *sd = (struct sd *) gspca_dev;
2093
2094 *val = sd->infrared;
2095 return 0;
2096}
2097
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002098/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002099static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002100 .name = MODULE_NAME,
2101 .ctrls = sd_ctrls,
2102 .nctrls = ARRAY_SIZE(sd_ctrls),
2103 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002104 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002105 .start = sd_start,
2106 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002107 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002108 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002109};
2110
2111/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002112#define BSI(bridge, sensor, i2c_addr) \
2113 .driver_info = (BRIDGE_ ## bridge << 16) \
2114 | (SENSOR_ ## sensor << 8) \
2115 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002116static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002117#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002118 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03002119 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002120#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002121 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2122 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002123#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002124 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002125#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03002126 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002127 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03002128 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002129 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2130/* bw600.inf:
2131 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2132/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2133/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2134 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2135/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
Jean-Francois Moine661ab252009-01-29 16:03:19 -03002136 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002137/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2138/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2139 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2140/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2141/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2142 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2143 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002144#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2145 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2146#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002147/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2148/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2149/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002150 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2151/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03002152 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002153 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002154 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002155/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002156#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002157 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002158#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002159 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03002160 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002161#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002162 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moine8d977702009-02-19 15:34:48 -03002163#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002164 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2165/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002166 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002167 {}
2168};
2169MODULE_DEVICE_TABLE(usb, device_table);
2170
2171/* -- device connect -- */
2172static int sd_probe(struct usb_interface *intf,
2173 const struct usb_device_id *id)
2174{
2175 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2176 THIS_MODULE);
2177}
2178
2179static struct usb_driver sd_driver = {
2180 .name = MODULE_NAME,
2181 .id_table = device_table,
2182 .probe = sd_probe,
2183 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002184#ifdef CONFIG_PM
2185 .suspend = gspca_suspend,
2186 .resume = gspca_resume,
2187#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002188};
2189
2190/* -- module insert / remove -- */
2191static int __init sd_mod_init(void)
2192{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002193 int ret;
2194 ret = usb_register(&sd_driver);
2195 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002196 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002197 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002198 return 0;
2199}
2200static void __exit sd_mod_exit(void)
2201{
2202 usb_deregister(&sd_driver);
2203 info("deregistered");
2204}
2205
2206module_init(sd_mod_init);
2207module_exit(sd_mod_exit);