blob: a5b58374333b0395d3ed6be027aa6d7ca8684a5e [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
4 *
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#define MODULE_NAME "sonixj"
23
24#include "gspca.h"
Jean-Francois Moine36e819d2009-01-07 16:49:57 -030025#define QUANT_VAL 4 /* quantization table */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030026#include "jpeg.h"
27
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030028#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030030MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
37
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030038 atomic_t avg_lum;
Jean-Francois Moine98819182009-01-19 07:37:33 -030039 u32 exposure;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030040
Jean-Francois Moine98819182009-01-19 07:37:33 -030041 u16 brightness;
42 u8 contrast;
43 u8 colors;
44 u8 autogain;
45 u8 blue;
46 u8 red;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030047 u8 gamma;
Jean-Francois Moine98819182009-01-19 07:37:33 -030048 u8 vflip; /* ov7630 only */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -030049 u8 infrared; /* mt9v111 only */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030050
Jean-Francois Moine98819182009-01-19 07:37:33 -030051 s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030052#define AG_CNT_START 13
53
Jean-Francois Moine98819182009-01-19 07:37:33 -030054 u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030055#define BRIDGE_SN9C102P 0
56#define BRIDGE_SN9C105 1
57#define BRIDGE_SN9C110 2
58#define BRIDGE_SN9C120 3
59#define BRIDGE_SN9C325 4
Jean-Francois Moine98819182009-01-19 07:37:33 -030060 u8 sensor; /* Type of image sensor chip */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030061#define SENSOR_HV7131R 0
62#define SENSOR_MI0360 1
63#define SENSOR_MO4000 2
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -030064#define SENSOR_MT9V111 3
65#define SENSOR_OM6802 4
66#define SENSOR_OV7630 5
67#define SENSOR_OV7648 6
68#define SENSOR_OV7660 7
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -030069#define SENSOR_SP80708 8
Jean-Francois Moine98819182009-01-19 07:37:33 -030070 u8 i2c_base;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030071};
72
73/* V4L2 controls supported by the driver */
74static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
75static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
76static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
77static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
78static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
79static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030080static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
81static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
82static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
83static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030084static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
85static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030086static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030088static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030090static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030092
93static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030094 {
95 {
96 .id = V4L2_CID_BRIGHTNESS,
97 .type = V4L2_CTRL_TYPE_INTEGER,
98 .name = "Brightness",
99 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300100#define BRIGHTNESS_MAX 0xffff
101 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300102 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -0300103#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300104 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300105 },
106 .set = sd_setbrightness,
107 .get = sd_getbrightness,
108 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300109 {
110 {
111 .id = V4L2_CID_CONTRAST,
112 .type = V4L2_CTRL_TYPE_INTEGER,
113 .name = "Contrast",
114 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300115#define CONTRAST_MAX 127
116 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300117 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300118#define CONTRAST_DEF 63
119 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120 },
121 .set = sd_setcontrast,
122 .get = sd_getcontrast,
123 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300124 {
125 {
126 .id = V4L2_CID_SATURATION,
127 .type = V4L2_CTRL_TYPE_INTEGER,
128 .name = "Color",
129 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300130 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300131 .step = 1,
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -0300132#define COLOR_DEF 32
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300133 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300134 },
135 .set = sd_setcolors,
136 .get = sd_getcolors,
137 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300138 {
139 {
140 .id = V4L2_CID_BLUE_BALANCE,
141 .type = V4L2_CTRL_TYPE_INTEGER,
142 .name = "Blue Balance",
143 .minimum = 24,
144 .maximum = 40,
145 .step = 1,
146#define BLUE_BALANCE_DEF 32
147 .default_value = BLUE_BALANCE_DEF,
148 },
149 .set = sd_setblue_balance,
150 .get = sd_getblue_balance,
151 },
152 {
153 {
154 .id = V4L2_CID_RED_BALANCE,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Red Balance",
157 .minimum = 24,
158 .maximum = 40,
159 .step = 1,
160#define RED_BALANCE_DEF 32
161 .default_value = RED_BALANCE_DEF,
162 },
163 .set = sd_setred_balance,
164 .get = sd_getred_balance,
165 },
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300166 {
167 {
168 .id = V4L2_CID_GAMMA,
169 .type = V4L2_CTRL_TYPE_INTEGER,
170 .name = "Gamma",
171 .minimum = 0,
172 .maximum = 40,
173 .step = 1,
174#define GAMMA_DEF 20
175 .default_value = GAMMA_DEF,
176 },
177 .set = sd_setgamma,
178 .get = sd_getgamma,
179 },
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300180#define AUTOGAIN_IDX 5
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300181 {
182 {
183 .id = V4L2_CID_AUTOGAIN,
184 .type = V4L2_CTRL_TYPE_BOOLEAN,
185 .name = "Auto Gain",
186 .minimum = 0,
187 .maximum = 1,
188 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300189#define AUTOGAIN_DEF 1
190 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300191 },
192 .set = sd_setautogain,
193 .get = sd_getautogain,
194 },
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300195/* ov7630 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300196#define VFLIP_IDX 6
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300197 {
198 {
199 .id = V4L2_CID_VFLIP,
200 .type = V4L2_CTRL_TYPE_BOOLEAN,
201 .name = "Vflip",
202 .minimum = 0,
203 .maximum = 1,
204 .step = 1,
Jean-Francois Moine40e6ec12008-09-22 03:14:25 -0300205#define VFLIP_DEF 1
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300206 .default_value = VFLIP_DEF,
207 },
208 .set = sd_setvflip,
209 .get = sd_getvflip,
210 },
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300211/* mt9v111 only */
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300212#define INFRARED_IDX 7
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300213 {
214 {
215 .id = V4L2_CID_INFRARED,
216 .type = V4L2_CTRL_TYPE_BOOLEAN,
217 .name = "Infrared",
218 .minimum = 0,
219 .maximum = 1,
220 .step = 1,
221#define INFRARED_DEF 0
222 .default_value = INFRARED_DEF,
223 },
224 .set = sd_setinfrared,
225 .get = sd_getinfrared,
226 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300227};
228
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300229/* table of the disabled controls */
230static __u32 ctrl_dis[] = {
231 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
232 /* SENSOR_HV7131R 0 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300233 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300234 /* SENSOR_MI0360 1 */
235 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
236 /* SENSOR_MO4000 2 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300237 (1 << AUTOGAIN_IDX),
238 /* SENSOR_MT9V111 3 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300239 (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300240 /* SENSOR_OM6802 4 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300241 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300242 /* SENSOR_OV7630 5 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300243 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300244 /* SENSOR_OV7648 6 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300245 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300246 /* SENSOR_OV7660 7 */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300247 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
248 /* SENSOR_SP80708 8 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300249};
250
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300251static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300252 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
253 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300254 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300255 .colorspace = V4L2_COLORSPACE_JPEG,
256 .priv = 2},
257 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
258 .bytesperline = 320,
259 .sizeimage = 320 * 240 * 3 / 8 + 590,
260 .colorspace = V4L2_COLORSPACE_JPEG,
261 .priv = 1},
262 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
263 .bytesperline = 640,
264 .sizeimage = 640 * 480 * 3 / 8 + 590,
265 .colorspace = V4L2_COLORSPACE_JPEG,
266 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267};
268
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300269/*Data from sn9c102p+hv7131r */
270static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300271/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
272 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
273/* reg8 reg9 rega regb regc regd rege regf */
274 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10,
275/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
276 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300277/* reg18 reg19 reg1a reg1b */
278 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300279};
280
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300281static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300282/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
283 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
284/* reg8 reg9 rega regb regc regd rege regf */
285 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
286/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
287 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300288/* reg18 reg19 reg1a reg1b */
289 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300290};
291
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300292static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300293/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300294 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300295/* reg8 reg9 rega regb regc regd rege regf */
296 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
297/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
298 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300299/* reg18 reg19 reg1a reg1b */
300 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300301};
302
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300303static const u8 sn_mt9v111[0x1c] = {
304/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
305 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
306/* reg8 reg9 rega regb regc regd rege regf */
307 0x81, 0x5c, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
308/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
309 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
310/* reg18 reg19 reg1a reg1b */
311 0x06, 0x00, 0x00, 0x00
312};
313
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300314static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300315/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
316 0x00, 0x23, 0x72, 0x00, 0x1a, 0x34, 0x27, 0x20,
317/* reg8 reg9 rega regb regc regd rege regf */
318 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
319/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
320 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300321/* reg18 reg19 reg1a reg1b */
322 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300323};
324
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300325static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300326/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
327 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
328/* reg8 reg9 rega regb regc regd rege regf */
329 0xa1, 0x21, 0x76, 0x21, 0x00, 0x00, 0x00, 0x10,
330/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
331 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300332/* reg18 reg19 reg1a reg1b */
333 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300334};
335
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300336static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300337/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300338 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300339/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300340 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300341/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300342 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300343/* reg18 reg19 reg1a reg1b */
344 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300345};
346
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300347static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300348/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
349 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
350/* reg8 reg9 rega regb regc regd rege regf */
351 0x81, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10,
352/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
353 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300354/* reg18 reg19 reg1a reg1b */
355 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356};
357
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300358static const u8 sn_sp80708[0x1c] = {
359/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
360 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
361/* reg8 reg9 rega regb regc regd rege regf */
362 0x81, 0x18, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00,
363/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
364 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
365/* reg18 reg19 reg1a reg1b */
366 0x07, 0x00, 0x00, 0x00
367};
368
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300369/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300370static const u8 *sn_tb[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300371 sn_hv7131,
372 sn_mi0360,
373 sn_mo4000,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300374 sn_mt9v111,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300375 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300376 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300377 sn_ov7648,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300378 sn_ov7660,
379 sn_sp80708
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300380};
381
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300382/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300383static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
385 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
386};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300387/* gamma for sensors HV7131R and MT9V111 */
388static const u8 gamma_spec_1[17] = {
389 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
390 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
391};
392/* gamma for sensor SP80708 */
393static const u8 gamma_spec_2[17] = {
394 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
395 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
396};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300397
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300398/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300399static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300400 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
401 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
402 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
403 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300404};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300405static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300406 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
407 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
408 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
409/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
410 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
411 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
412/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300413
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300414 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
415 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
416 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
417 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
418 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
419 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
420 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
421 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300422
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300423 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
424 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
425 {0xa1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
426 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300428
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300429 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
431 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
433 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300434 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300435};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300436static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300437 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300438 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300439 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300440 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
441 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
442 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
443 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
444 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
445 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
446 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
448 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
449 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
450 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
451 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
452 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
453 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
454 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
455 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
456 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
457 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
458 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300459 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300460 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
462 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
463 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
464 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
465 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
466 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
467 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
468 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
469 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300470
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300471 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
472 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
473 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
474 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
475 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300476
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300477 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
478 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
479 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
480 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300481
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300482 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
483 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
484/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
485/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
486 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
487 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300488 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300489};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300490static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300491 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
492 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
493 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
494 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
495 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
496 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
497 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
498 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
499 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
500 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
501 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
502 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
503 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
504 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
505 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
506 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
507 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
508 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
509 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
510 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300511 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300512};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300513static const u8 mt9v111_sensor_init[][8] = {
514 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
515 /* delay 20 ms */
516 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
517 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
518 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
519 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
520 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
521 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
522 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
523 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
524 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
525 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
526 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
527 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
528 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
529 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
530 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
531 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
532 /*******/
533 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
534 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
535 {0xb1, 0x5c, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10}, /* shutter width */
536 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
537 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
538 /*******/
539 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
540 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
541 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
542 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
543 {}
544};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300545static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300546 {0xa0, 0x34, 0x90, 0x05, 0x00, 0x00, 0x00, 0x10},
547 {0xa0, 0x34, 0x49, 0x85, 0x00, 0x00, 0x00, 0x10},
548 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
549 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
550/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
551 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
552 /* white balance & auto-exposure */
553/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
554 * set color mode */
555/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
556 * max AGC value in AE */
557/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
558 * preset AGC */
559/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
560 * preset brightness */
561/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
562 * preset contrast */
563/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
564 * preset gamma */
565 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
566 /* luminance mode (0x4f = AE) */
567 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
568 /* preset shutter */
569/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
570 * auto frame rate */
571/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
572
573/* {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10}, */
574/* {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10}, */
575/* {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10}, */
576/* {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10}, */
577 {}
578};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300579static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300580 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
581 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
582/* win: delay 20ms */
583 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
584 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
585/* win: delay 20ms */
586 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300587/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300588 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
589 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
590 {0xd1, 0x21, 0x11, 0x00, 0x48, 0xc0, 0x00, 0x10},
591 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
592 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
593 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
594 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
595 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
596 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
597 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
598 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
599 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
600 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
601 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
602 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
603 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
605 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
606 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
607 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
608 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
609 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
610 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
611 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
612 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
613 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
614/* */
615 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
616 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
617/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300618/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
619 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300620 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
621 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
622 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300623/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300624 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300627/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300628 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300629/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300630 {}
631};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300632
Jean-Francois Moine98819182009-01-19 07:37:33 -0300633static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300634 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
636 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
637 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
638 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
639 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
640 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
641 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
642 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
643 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
644 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
645 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
646 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
647 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
648 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
649 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
650 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
651 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
652 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
653 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
654 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
655
656 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
657/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
658/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
659 {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10},
660/*...*/
661/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
662/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, jfm done */
663 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
664 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
665/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
666/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
667/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
668/*...*/
669 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
670/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
671/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
672/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
673/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
674/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
675
676 {}
677};
678
Jean-Francois Moine98819182009-01-19 07:37:33 -0300679static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300680 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine60017612008-07-18 08:46:19 -0300681/* (delay 20ms) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300683 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300684 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300685 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686 /* GAIN BLUE RED VREF */
687 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
688 /* COM 1 BAVE GEAVE AECHH */
689 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
690 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300691 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300692 /* AECH CLKRC COM7 COM8 */
693 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
694 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
695 /* HSTART HSTOP VSTRT VSTOP */
696 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
697 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
698 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
699 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300700/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
701 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300702 /* AEW AEB VPT BBIAS */
703 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
704 /* GbBIAS RSVD EXHCH EXHCL */
705 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
706 /* RBIAS ADVFL ASDVFH YAVE */
707 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
708 /* HSYST HSYEN HREF */
709 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
710 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
711 /* ADC ACOM OFON TSLB */
712 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
713 /* COM11 COM12 COM13 COM14 */
714 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
715 /* EDGE COM15 COM16 COM17 */
716 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
717 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
718 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
719 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
720 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
721 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
722 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
723 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
724 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
725 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
726 /* LCC1 LCC2 LCC3 LCC4 */
727 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300728 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300729 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300730 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300731 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
732 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
733 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
734 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
735 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
736 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
737 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
738 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
739 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300740 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300741/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300742 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300743 /* bits[3..0]reserved */
744 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
745 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
746 /* VREF vertical frame ctrl */
747 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300748 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
749 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
750 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
751 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
752/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753/****** (some exchanges in the win trace) ******/
754 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300755 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
756 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
757 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
758/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300759/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300760/******!! startsensor KO if changed !!****/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300761 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
762 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
763 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
764 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300765 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300766};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300767
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300768static const u8 sp80708_sensor_init[][8] = {
769 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
770 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
771 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
772 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
773 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
774 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
776 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
777 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
778 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
779 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
780 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
781 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
782 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
783 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
784 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
785 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
786 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
787 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
789 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
790 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
811 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
812 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
813 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
814 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
815 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
816 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
817 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
818 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
819 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
820 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
822 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
840 /********/
841 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
842 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
844 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
845 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
846 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
847 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
848 {}
849};
850
Jean-Francois Moine98819182009-01-19 07:37:33 -0300851static const u8 qtable4[] = {
852 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06,
853 0x06, 0x06, 0x08, 0x06, 0x06, 0x08, 0x0a, 0x11,
854 0x0a, 0x0a, 0x08, 0x08, 0x0a, 0x15, 0x0f, 0x0f,
855 0x0c, 0x11, 0x19, 0x15, 0x19, 0x19, 0x17, 0x15,
856 0x17, 0x17, 0x1b, 0x1d, 0x25, 0x21, 0x1b, 0x1d,
857 0x23, 0x1d, 0x17, 0x17, 0x21, 0x2e, 0x21, 0x23,
858 0x27, 0x29, 0x2c, 0x2c, 0x2c, 0x19, 0x1f, 0x30,
859 0x32, 0x2e, 0x29, 0x32, 0x25, 0x29, 0x2c, 0x29,
860 0x06, 0x08, 0x08, 0x0a, 0x08, 0x0a, 0x13, 0x0a,
861 0x0a, 0x13, 0x29, 0x1b, 0x17, 0x1b, 0x29, 0x29,
862 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
863 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
864 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
865 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
866 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
867 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300868};
869
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300870/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300871static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300872 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300873{
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300874#ifdef GSPCA_DEBUG
875 if (len > USB_BUF_SZ) {
876 err("reg_r: buffer overflow");
877 return;
878 }
879#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300880 usb_control_msg(gspca_dev->dev,
881 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300882 0,
883 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
884 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300885 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300887 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888}
889
Jean-Francois Moine60017612008-07-18 08:46:19 -0300890static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300891 u16 value,
892 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -0300893{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300894 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300895 gspca_dev->usb_buf[0] = data;
896 usb_control_msg(gspca_dev->dev,
897 usb_sndctrlpipe(gspca_dev->dev, 0),
898 0x08,
899 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
900 value,
901 0,
902 gspca_dev->usb_buf, 1,
903 500);
904}
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300905static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300906 u16 value,
907 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300908 int len)
909{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300910 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -0300911 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300912#ifdef GSPCA_DEBUG
913 if (len > USB_BUF_SZ) {
914 err("reg_w: buffer overflow");
915 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300916 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300917#endif
918 memcpy(gspca_dev->usb_buf, buffer, len);
919 usb_control_msg(gspca_dev->dev,
920 usb_sndctrlpipe(gspca_dev->dev, 0),
921 0x08,
922 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
923 value, 0,
924 gspca_dev->usb_buf, len,
925 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300926}
927
Jean-Francois Moine60017612008-07-18 08:46:19 -0300928/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300929static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930{
931 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932
Jean-Francois Moine60017612008-07-18 08:46:19 -0300933 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
934 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
935 gspca_dev->usb_buf[1] = sd->i2c_base;
936 gspca_dev->usb_buf[2] = reg;
937 gspca_dev->usb_buf[3] = val;
938 gspca_dev->usb_buf[4] = 0;
939 gspca_dev->usb_buf[5] = 0;
940 gspca_dev->usb_buf[6] = 0;
941 gspca_dev->usb_buf[7] = 0x10;
942 usb_control_msg(gspca_dev->dev,
943 usb_sndctrlpipe(gspca_dev->dev, 0),
944 0x08,
945 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
946 0x08, /* value = i2c */
947 0,
948 gspca_dev->usb_buf, 8,
949 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300950}
951
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300952/* I2C write 8 bytes */
953static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -0300954 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300955{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300956 memcpy(gspca_dev->usb_buf, buffer, 8);
957 usb_control_msg(gspca_dev->dev,
958 usb_sndctrlpipe(gspca_dev->dev, 0),
959 0x08,
960 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
961 0x08, 0, /* value, index */
962 gspca_dev->usb_buf, 8,
963 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -0300964 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300965}
966
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300967/* read 5 bytes in gspca_dev->usb_buf */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300968static void i2c_r5(struct gspca_dev *gspca_dev, u8 reg)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300969{
970 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -0300971 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300972
Hans de Goede3647fea2008-07-15 05:36:30 -0300973 mode[0] = 0x81 | 0x10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300974 mode[1] = sd->i2c_base;
975 mode[2] = reg;
976 mode[3] = 0;
977 mode[4] = 0;
978 mode[5] = 0;
979 mode[6] = 0;
980 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300981 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300982 msleep(2);
Hans de Goede3647fea2008-07-15 05:36:30 -0300983 mode[0] = 0x81 | (5 << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300984 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300985 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300986 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300987 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300988}
989
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300990static int hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300991{
Jean-Francois Moine60017612008-07-18 08:46:19 -0300992 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300993 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -0300994 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300995 msleep(10);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300996 i2c_r5(gspca_dev, 0); /* read sensor id */
997 if (gspca_dev->usb_buf[0] == 0x02
998 && gspca_dev->usb_buf[1] == 0x09
999 && gspca_dev->usb_buf[2] == 0x01
1000 && gspca_dev->usb_buf[3] == 0x00
1001 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001002 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001003 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001004 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001005 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001006 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1007 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001008 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
1009 return -ENODEV;
1010}
1011
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001012static int mi0360_probe(struct gspca_dev *gspca_dev)
1013{
1014 int i, j;
1015 u16 val;
1016 static const u8 probe_tb[][4][8] = {
1017 {
1018 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1019 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1020 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1021 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1022 },
1023 {
1024 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1025 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1026 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1027 {}
1028 },
1029 };
1030
1031 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1032 reg_w1(gspca_dev, 0x17, 0x62);
1033 reg_w1(gspca_dev, 0x01, 0x08);
1034 for (j = 0; j < 3; j++)
1035 i2c_w8(gspca_dev, probe_tb[i][j]);
1036 msleep(2);
1037 reg_r(gspca_dev, 0x0a, 5);
1038 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1039 if (probe_tb[i][3][0] != 0)
1040 i2c_w8(gspca_dev, probe_tb[i][3]);
1041 reg_w1(gspca_dev, 0x01, 0x29);
1042 reg_w1(gspca_dev, 0x17, 0x42);
1043 if (val != 0xffff)
1044 break;
1045 }
1046 switch (val) {
1047 case 0x823a:
1048 PDEBUG(D_PROBE, "Sensor mt9v111");
1049 return SENSOR_MT9V111;
1050 case 0x8243:
1051 PDEBUG(D_PROBE, "Sensor mi0360");
1052 return SENSOR_MI0360;
1053 }
1054 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1055 return SENSOR_MI0360;
1056}
1057
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001058static int configure_gpio(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001059 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001060{
1061 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001062 const u8 *reg9a;
1063 static const u8 reg9a_def[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001064 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001065 static const u8 reg9a_sn9c325[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001066 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001067 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001068
Jean-Francois Moine60017612008-07-18 08:46:19 -03001069 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001070 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001071
1072 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001073 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1074 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001075 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
Hans de Goede3647fea2008-07-15 05:36:30 -03001076 switch (sd->bridge) {
1077 case BRIDGE_SN9C325:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001078 reg9a = reg9a_sn9c325;
1079 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001080 default:
1081 reg9a = reg9a_def;
1082 break;
1083 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001084 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001085
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001086 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4); /*fixme:jfm was 60 only*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001087
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001088 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001089
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001090 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001091 case SENSOR_MT9V111:
1092 reg_w1(gspca_dev, 0x01, 0x61);
1093 reg_w1(gspca_dev, 0x17, 0x61);
1094 reg_w1(gspca_dev, 0x01, 0x60);
1095 reg_w1(gspca_dev, 0x01, 0x40);
1096 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001097 case SENSOR_OM6802:
Jean-Francois Moine4f30f6c2008-09-03 16:48:05 -03001098 reg_w1(gspca_dev, 0x02, 0x71);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001099 reg_w1(gspca_dev, 0x01, 0x42);
1100 reg_w1(gspca_dev, 0x17, 0x64);
1101 reg_w1(gspca_dev, 0x01, 0x42);
1102 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001103/*jfm: from win trace */
1104 case SENSOR_OV7630:
1105 reg_w1(gspca_dev, 0x01, 0x61);
1106 reg_w1(gspca_dev, 0x17, 0xe2);
1107 reg_w1(gspca_dev, 0x01, 0x60);
1108 reg_w1(gspca_dev, 0x01, 0x40);
1109 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001110 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001111 reg_w1(gspca_dev, 0x01, 0x63);
1112 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001113 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001114 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001115/*jfm: from win trace */
1116 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001117 if (sd->bridge == BRIDGE_SN9C120) {
1118 reg_w1(gspca_dev, 0x01, 0x61);
1119 reg_w1(gspca_dev, 0x17, 0x20);
1120 reg_w1(gspca_dev, 0x01, 0x60);
1121 reg_w1(gspca_dev, 0x01, 0x40);
1122 break;
1123 }
1124 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001125 case SENSOR_SP80708:
1126 reg_w1(gspca_dev, 0x01, 0x63);
1127 reg_w1(gspca_dev, 0x17, 0x20);
1128 reg_w1(gspca_dev, 0x01, 0x62);
1129 reg_w1(gspca_dev, 0x01, 0x42);
1130 mdelay(100);
1131 reg_w1(gspca_dev, 0x02, 0x62);
1132 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001133 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001134 reg_w1(gspca_dev, 0x01, 0x43);
1135 reg_w1(gspca_dev, 0x17, 0x61);
1136 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001137 if (sd->sensor == SENSOR_HV7131R) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001138 if (hv7131r_probe(gspca_dev) < 0)
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001139 return -ENODEV;
1140 }
1141 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001142 }
1143 return 0;
1144}
1145
1146static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
1147{
1148 int i = 0;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001149 static const u8 SetSensorClk[] = /* 0x08 Mclk */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001150 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
1151
1152 while (hv7131r_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001153 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001154 i++;
1155 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001156 i2c_w8(gspca_dev, SetSensorClk);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001157}
1158
1159static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
1160{
1161 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001162
1163 while (mi0360_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001164 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001165 i++;
1166 }
1167}
1168
1169static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
1170{
1171 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001172
1173 while (mo4000_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001174 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001175 i++;
1176 }
1177}
1178
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001179static void mt9v111_InitSensor(struct gspca_dev *gspca_dev)
1180{
1181 int i = 0;
1182
1183 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1184 i++;
1185 msleep(20);
1186 while (mt9v111_sensor_init[i][0]) {
1187 i2c_w8(gspca_dev, mt9v111_sensor_init[i]);
1188 i++;
1189 }
1190}
1191
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001192static void om6802_InitSensor(struct gspca_dev *gspca_dev)
1193{
1194 int i = 0;
1195
1196 while (om6802_sensor_init[i][0]) {
1197 i2c_w8(gspca_dev, om6802_sensor_init[i]);
1198 i++;
1199 }
1200}
1201
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001202static void ov7630_InitSensor(struct gspca_dev *gspca_dev)
1203{
1204 int i = 0;
1205
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001206 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 76 01 */
1207 i++;
1208 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 (RGB+SRST) */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001209 i++;
1210 msleep(20);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001211 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1212 i++;
1213 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 c8 */
1214 i++;
1215 msleep(20);
1216 i2c_w8(gspca_dev, ov7630_sensor_init[i]); /* 12 48 */
1217 i++;
1218/*jfm:win i2c_r from 00 to 80*/
1219
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001220 while (ov7630_sensor_init[i][0]) {
1221 i2c_w8(gspca_dev, ov7630_sensor_init[i]);
1222 i++;
1223 }
1224}
1225
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001226static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
1227{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001228 int i = 0;
1229
Jean-Francois Moine62703302008-11-11 08:42:56 -03001230 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
1231 i++;
1232/* win: dble reset */
1233 i2c_w8(gspca_dev, ov7648_sensor_init[i]); /* reset */
1234 i++;
1235 msleep(20);
1236/* win: i2c reg read 00..7f */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001237 while (ov7648_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001238 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001239 i++;
1240 }
1241}
1242
1243static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
1244{
1245 int i = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001246
Jean-Francois Moine60017612008-07-18 08:46:19 -03001247 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
1248 i++;
1249 msleep(20);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001250 while (ov7660_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001251 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001252 i++;
1253 }
1254}
1255
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001256static void sp80708_InitSensor(struct gspca_dev *gspca_dev)
1257{
1258 int i = 0;
1259
1260 i2c_w8(gspca_dev, sp80708_sensor_init[i]); /* reset SCCB */
1261 i++;
1262 msleep(20);
1263 while (sp80708_sensor_init[i][0]) {
1264 i2c_w8(gspca_dev, sp80708_sensor_init[i]);
1265 i++;
1266 }
1267}
1268
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001269/* this function is called at probe time */
1270static int sd_config(struct gspca_dev *gspca_dev,
1271 const struct usb_device_id *id)
1272{
1273 struct sd *sd = (struct sd *) gspca_dev;
1274 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001275
1276 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001277 cam->cam_mode = vga_mode;
1278 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001279
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001280 sd->bridge = id->driver_info >> 16;
1281 sd->sensor = id->driver_info >> 8;
1282 sd->i2c_base = id->driver_info;
1283
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001284 sd->brightness = BRIGHTNESS_DEF;
1285 sd->contrast = CONTRAST_DEF;
1286 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001287 sd->blue = BLUE_BALANCE_DEF;
1288 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001289 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001290 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001291 sd->ag_cnt = -1;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001292 sd->vflip = VFLIP_DEF;
1293 sd->infrared = INFRARED_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001294
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001295 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001296 return 0;
1297}
1298
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001299/* this function is called at probe and resume time */
1300static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001301{
1302 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001303 u8 regGpio[] = { 0x29, 0x74 };
1304 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001305
Hans de Goede3647fea2008-07-15 05:36:30 -03001306 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001307 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001308 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001309 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1310 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001311 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001312 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001313 switch (sd->bridge) {
1314 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001315 if (regF1 != 0x11)
1316 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001317 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001318 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001319 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001320 if (regF1 != 0x11)
1321 return -ENODEV;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001322 if (sd->sensor == SENSOR_MI0360) {
1323 sd->sensor = mi0360_probe(gspca_dev);
1324 if (sd->sensor == SENSOR_MT9V111)
1325 sd->i2c_base = 0x5c;
1326 }
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001327 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001328 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001329 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001330 if (regF1 != 0x12)
1331 return -ENODEV;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001332 if (sd->sensor == SENSOR_MI0360) {
1333 sd->sensor = mi0360_probe(gspca_dev);
1334 if (sd->sensor == SENSOR_MT9V111)
1335 sd->i2c_base = 0x5c;
1336 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001337 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001338 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001339 break;
1340 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001341/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001342/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001343 if (regF1 != 0x12)
1344 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001345 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001346 break;
1347 }
1348
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001349 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001350
1351 return 0;
1352}
1353
Jean-Francois Moine98819182009-01-19 07:37:33 -03001354static u32 setexposure(struct gspca_dev *gspca_dev,
1355 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001356{
1357 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001358
1359 switch (sd->sensor) {
1360 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001361 u8 Expodoit[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001362 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1363
1364 Expodoit[3] = expo >> 16;
1365 Expodoit[4] = expo >> 8;
1366 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001367 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368 break;
1369 }
1370 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001371 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001372 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001373 static const u8 doit[] = /* update sensor */
1374 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1375 static const u8 sensorgo[] = /* sensor on */
1376 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001377
1378 if (expo > 0x0635)
1379 expo = 0x0635;
1380 else if (expo < 0x0001)
1381 expo = 0x0001;
1382 expoMi[3] = expo >> 8;
1383 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001384 i2c_w8(gspca_dev, expoMi);
1385 i2c_w8(gspca_dev, doit);
1386 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001387 break;
1388 }
1389 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001390 u8 expoMof[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001391 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001392 u8 expoMo10[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001393 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001394 static const u8 gainMo[] =
1395 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001396
1397 if (expo > 0x1fff)
1398 expo = 0x1fff;
1399 else if (expo < 0x0001)
1400 expo = 0x0001;
1401 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001402 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001403 expoMo10[3] = ((expo & 0x1c00) >> 10)
1404 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001405 i2c_w8(gspca_dev, expoMo10);
1406 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001407 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001408 ((expoMo10[3] & 0x07) << 10)
1409 | (expoMof[3] << 2)
1410 | ((expoMo10[3] & 0x30) >> 4));
1411 break;
1412 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001413 case SENSOR_MT9V111: {
1414 u8 expo_c1[] =
1415 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1416
1417 if (expo > 0x0280)
1418 expo = 0x0280;
1419 else if (expo < 0x0040)
1420 expo = 0x0040;
1421 expo_c1[3] = expo >> 8;
1422 expo_c1[4] = expo;
1423 i2c_w8(gspca_dev, expo_c1);
1424 break;
1425 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001426 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001427 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001428 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
1429
1430 if (expo > 0x03ff)
1431 expo = 0x03ff;
1432 if (expo < 0x0001)
1433 expo = 0x0001;
1434 gainOm[3] = expo >> 2;
1435 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001436 reg_w1(gspca_dev, 0x96, (expo >> 5) & 0x1f);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001437 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001438 break;
1439 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001440 }
1441 return expo;
1442}
1443
1444static void setbrightness(struct gspca_dev *gspca_dev)
1445{
1446 struct sd *sd = (struct sd *) gspca_dev;
1447 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001448 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001449
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001450 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 switch (sd->sensor) {
1452 case SENSOR_HV7131R:
1453 expo = sd->brightness << 4;
1454 if (expo > 0x002dc6c0)
1455 expo = 0x002dc6c0;
1456 else if (expo < 0x02a0)
1457 expo = 0x02a0;
1458 sd->exposure = setexposure(gspca_dev, expo);
1459 break;
1460 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001461 case SENSOR_MO4000:
1462 expo = sd->brightness >> 4;
1463 sd->exposure = setexposure(gspca_dev, expo);
1464 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001465 case SENSOR_MT9V111:
1466 expo = sd->brightness >> 8;
1467 sd->exposure = setexposure(gspca_dev, expo);
1468 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001469 case SENSOR_OM6802:
1470 expo = sd->brightness >> 6;
1471 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001472 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001473 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001474 }
1475
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001476 if (sd->sensor != SENSOR_MT9V111)
1477 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001478}
1479
1480static void setcontrast(struct gspca_dev *gspca_dev)
1481{
1482 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001483 u8 k2;
1484 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001485
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001486 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1487 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001488 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001489 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001490 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001491 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001492 contrast[5] = 0;
1493 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001494}
1495
1496static void setcolors(struct gspca_dev *gspca_dev)
1497{
1498 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001499 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001500 u8 reg8a[12]; /* U & V gains */
1501 static s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001502 -24, -38, 64, /* UR UG UB */
1503 62, -51, -9 /* VR VG VB */
1504 };
1505 for (i = 0; i < 6; i++) {
1506 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001507 reg8a[i * 2] = v;
1508 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001509 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001510 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001511}
1512
1513static void setredblue(struct gspca_dev *gspca_dev)
1514{
1515 struct sd *sd = (struct sd *) gspca_dev;
1516
1517 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001518/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001519 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001520}
1521
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001522static void setgamma(struct gspca_dev *gspca_dev)
1523{
1524 struct sd *sd = (struct sd *) gspca_dev;
1525 int i;
1526 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001527 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001528 static const u8 delta[17] = {
1529 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1530 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1531 };
1532
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001533 switch (sd->sensor) {
1534 case SENSOR_HV7131R:
1535 case SENSOR_MT9V111:
1536 gamma_base = gamma_spec_1;
1537 break;
1538 case SENSOR_SP80708:
1539 gamma_base = gamma_spec_2;
1540 break;
1541 default:
1542 gamma_base = gamma_def;
1543 break;
1544 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001545
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001546 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001547 gamma[i] = gamma_base[i]
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001548 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1549 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1550}
1551
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001552static void setautogain(struct gspca_dev *gspca_dev)
1553{
1554 struct sd *sd = (struct sd *) gspca_dev;
1555
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001556 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1557 return;
1558 if (sd->autogain)
1559 sd->ag_cnt = AG_CNT_START;
1560 else
1561 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001562}
1563
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001564static void setvflip(struct sd *sd)
1565{
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001566 i2c_w1(&sd->gspca_dev, 0x75, /* COMN */
1567 sd->vflip ? 0x82 : 0x02);
1568}
1569
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001570static void setinfrared(struct sd *sd)
1571{
1572/*fixme: different sequence for StarCam Clip and StarCam 370i */
1573/* Clip */
1574 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1575 sd->infrared ? 0x66 : 0x64);
1576}
1577
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001578/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001579static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001580{
1581 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001582 int i;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001583 u8 reg1, reg17, reg18;
1584 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001585 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001586 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1587 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1588 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1589 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001590 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001591
1592 sn9c1xx = sn_tb[(int) sd->sensor];
1593 configure_gpio(gspca_dev, sn9c1xx);
1594
Jean-Francois Moine60017612008-07-18 08:46:19 -03001595 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1596 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1597 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1598 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1599 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1600 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1601 reg_w1(gspca_dev, 0xd3, 0x50);
1602 reg_w1(gspca_dev, 0xc6, 0x00);
1603 reg_w1(gspca_dev, 0xc7, 0x00);
1604 reg_w1(gspca_dev, 0xc8, 0x50);
1605 reg_w1(gspca_dev, 0xc9, 0x3c);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001606 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001607 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001608 case SENSOR_MT9V111:
1609 reg17 = 0xe0;
1610 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001611 case SENSOR_OV7630:
1612 reg17 = 0xe2;
1613 break;
1614 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001615 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001616 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001617/*jfm: from win trace */
1618 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001619 if (sd->bridge == BRIDGE_SN9C120) {
1620 reg17 = 0xa0;
1621 break;
1622 }
1623 /* fall thru */
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001624 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001625 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001626 break;
1627 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001628 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001629/* set reg1 was here */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001630 reg_w1(gspca_dev, 0x05, sn9c1xx[5]); /* red */
1631 reg_w1(gspca_dev, 0x07, sn9c1xx[7]); /* green */
1632 reg_w1(gspca_dev, 0x06, sn9c1xx[6]); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001633 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001634
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001635 setgamma(gspca_dev);
1636
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001637 for (i = 0; i < 8; i++)
1638 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001639 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001640 case SENSOR_MT9V111:
1641 reg_w1(gspca_dev, 0x9a, 0x07);
1642 reg_w1(gspca_dev, 0x99, 0x59);
1643 break;
Jean-Francois Moine62703302008-11-11 08:42:56 -03001644 case SENSOR_OV7648:
1645 reg_w1(gspca_dev, 0x9a, 0x0a);
1646 reg_w1(gspca_dev, 0x99, 0x60);
1647 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001648 case SENSOR_SP80708:
1649 reg_w1(gspca_dev, 0x9a, 0x05);
1650 reg_w1(gspca_dev, 0x99, 0x59);
1651 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001652 case SENSOR_OV7660:
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001653 if (sd->bridge == BRIDGE_SN9C120) {
1654 reg_w1(gspca_dev, 0x9a, 0x05);
1655 break;
1656 }
1657 /* fall thru */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001658 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001659 reg_w1(gspca_dev, 0x9a, 0x08);
1660 reg_w1(gspca_dev, 0x99, 0x59);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001661 break;
1662 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001663
Jean-Francois Moinec2446b32008-07-05 11:49:20 -03001664 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001665 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001666 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001667 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001668 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
1669 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001670 switch (sd->sensor) {
1671 case SENSOR_HV7131R:
1672 hv7131R_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001673 break;
1674 case SENSOR_MI0360:
1675 mi0360_InitSensor(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001676 break;
1677 case SENSOR_MO4000:
1678 mo4000_InitSensor(gspca_dev);
1679 if (mode) {
1680/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1681 reg1 = 0x06; /* clk 24Mz */
1682 } else {
1683 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001684/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001685 }
1686 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001687 case SENSOR_MT9V111:
1688 mt9v111_InitSensor(gspca_dev);
1689 if (mode) {
1690 reg1 = 0x04; /* 320 clk 48Mhz */
1691 } else {
1692/* reg1 = 0x06; * 640 clk 24Mz (done) */
1693 reg17 = 0xe2;
1694 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03001695 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001696 case SENSOR_OM6802:
1697 om6802_InitSensor(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001698 reg17 = 0x64; /* 640 MCKSIZE */
1699 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001700 case SENSOR_OV7630:
1701 ov7630_InitSensor(gspca_dev);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001702 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001703 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03001704 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001705 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001706 case SENSOR_OV7648:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001707 ov7648_InitSensor(gspca_dev);
Jean-Francois Moine62703302008-11-11 08:42:56 -03001708 reg17 = 0x21;
1709/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001710 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001711 case SENSOR_OV7660:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001712 ov7660_InitSensor(gspca_dev);
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001713 if (sd->bridge == BRIDGE_SN9C120) {
1714 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001715 reg17 = 0xa2;
1716 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001717 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03001718 } else {
1719 reg17 = 0x22;
1720 reg1 = 0x06; /* 24 Mhz, video trf eneble
1721 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001722 }
1723 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001724 default:
1725/* case SENSOR_SP80708: */
1726 sp80708_InitSensor(gspca_dev);
1727 if (mode) {
1728/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001729 } else {
1730 reg1 = 0x46; /* 640 clk 48Mz */
1731 reg17 = 0xa2;
1732 }
1733 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001734 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001735 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001736 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001737 switch (sd->sensor) {
1738 case SENSOR_OV7630:
1739 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001740 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001741 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001742 break;
1743 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001744 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001745 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1746 break;
1747 }
1748
1749 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001750 reg18 = sn9c1xx[0x18] | (mode << 4);
1751 reg_w1(gspca_dev, 0x18, reg18 | 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001752
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001753 reg_w(gspca_dev, 0x0100, qtable4, 0x40);
1754 reg_w(gspca_dev, 0x0140, qtable4 + 0x40, 0x40);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001755
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001756 reg_w1(gspca_dev, 0x18, reg18);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001757
Jean-Francois Moine60017612008-07-18 08:46:19 -03001758 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03001759 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001760 switch (sd->sensor) {
Jean-Francois Moine79a90982008-10-05 04:21:24 -03001761 case SENSOR_OV7630:
1762 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001763 break;
1764 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001765 setbrightness(gspca_dev);
1766 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001767 setautogain(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001768 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001769}
1770
1771static void sd_stopN(struct gspca_dev *gspca_dev)
1772{
1773 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001774 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001775 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001776 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001777 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001778 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03001779 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001780 u8 data;
1781 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001782
1783 data = 0x0b;
1784 switch (sd->sensor) {
1785 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001786 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001787 data = 0x2b;
1788 break;
1789 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001790 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001791 data = 0x29;
1792 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001793 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001794 i2c_w8(gspca_dev, stopov7648);
1795 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001796 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001797 case SENSOR_OV7630:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001798 data = 0x29;
1799 break;
1800 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001801/* case SENSOR_MO4000: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001802/* case SENSOR_OV7660: */
1803 break;
1804 }
1805 sn9c1xx = sn_tb[(int) sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03001806 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1807 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1808 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1809 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001810 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001811}
1812
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001813static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001814{
1815 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001816 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001817 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001818 u8 luma_mean = 130;
1819 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001820
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001821 /* Thanks S., without your advice, autobright should not work :) */
1822 if (sd->ag_cnt < 0)
1823 return;
1824 if (--sd->ag_cnt >= 0)
1825 return;
1826 sd->ag_cnt = AG_CNT_START;
1827
1828 delta = atomic_read(&sd->avg_lum);
1829 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001830 if (delta < luma_mean - luma_delta ||
1831 delta > luma_mean + luma_delta) {
1832 switch (sd->sensor) {
1833 case SENSOR_HV7131R:
1834 expotimes = sd->exposure >> 8;
1835 expotimes += (luma_mean - delta) >> 4;
1836 if (expotimes < 0)
1837 expotimes = 0;
1838 sd->exposure = setexposure(gspca_dev,
1839 (unsigned int) (expotimes << 8));
1840 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001841 default:
1842/* case SENSOR_MO4000: */
1843/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001844/* case SENSOR_MT9V111: */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001845/* case SENSOR_OM6802: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001846 expotimes = sd->exposure;
1847 expotimes += (luma_mean - delta) >> 6;
1848 if (expotimes < 0)
1849 expotimes = 0;
1850 sd->exposure = setexposure(gspca_dev,
1851 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001852 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001853 break;
1854 }
1855 }
1856}
1857
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001858/* scan the URB packets */
1859/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001860static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1861 struct gspca_frame *frame, /* target */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001862 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001863 int len) /* iso packet length */
1864{
1865 struct sd *sd = (struct sd *) gspca_dev;
1866 int sof, avg_lum;
1867
1868 sof = len - 64;
1869 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1870
1871 /* end of frame */
1872 gspca_frame_add(gspca_dev, LAST_PACKET,
1873 frame, data, sof + 2);
1874 if (sd->ag_cnt < 0)
1875 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001876/* w1 w2 w3 */
1877/* w4 w5 w6 */
1878/* w7 w8 */
1879/* w4 */
1880 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1881/* w6 */
1882 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1883/* w2 */
1884 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1885/* w8 */
1886 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1887/* w5 */
1888 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1889 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001890 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001891 return;
1892 }
1893 if (gspca_dev->last_packet_type == LAST_PACKET) {
1894
1895 /* put the JPEG 422 header */
Jean-Francois Moine36e819d2009-01-07 16:49:57 -03001896 jpeg_put_header(gspca_dev, frame, 0x21);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001897 }
1898 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1899}
1900
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001901static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1902{
1903 struct sd *sd = (struct sd *) gspca_dev;
1904
1905 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001906 if (gspca_dev->streaming)
1907 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001908 return 0;
1909}
1910
1911static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1912{
1913 struct sd *sd = (struct sd *) gspca_dev;
1914
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001915 *val = sd->brightness;
1916 return 0;
1917}
1918
1919static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1920{
1921 struct sd *sd = (struct sd *) gspca_dev;
1922
1923 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001924 if (gspca_dev->streaming)
1925 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001926 return 0;
1927}
1928
1929static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1930{
1931 struct sd *sd = (struct sd *) gspca_dev;
1932
1933 *val = sd->contrast;
1934 return 0;
1935}
1936
1937static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1938{
1939 struct sd *sd = (struct sd *) gspca_dev;
1940
1941 sd->colors = val;
1942 if (gspca_dev->streaming)
1943 setcolors(gspca_dev);
1944 return 0;
1945}
1946
1947static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1948{
1949 struct sd *sd = (struct sd *) gspca_dev;
1950
1951 *val = sd->colors;
1952 return 0;
1953}
1954
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001955static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
1956{
1957 struct sd *sd = (struct sd *) gspca_dev;
1958
1959 sd->blue = val;
1960 if (gspca_dev->streaming)
1961 setredblue(gspca_dev);
1962 return 0;
1963}
1964
1965static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
1966{
1967 struct sd *sd = (struct sd *) gspca_dev;
1968
1969 *val = sd->blue;
1970 return 0;
1971}
1972
1973static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
1974{
1975 struct sd *sd = (struct sd *) gspca_dev;
1976
1977 sd->red = val;
1978 if (gspca_dev->streaming)
1979 setredblue(gspca_dev);
1980 return 0;
1981}
1982
1983static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
1984{
1985 struct sd *sd = (struct sd *) gspca_dev;
1986
1987 *val = sd->red;
1988 return 0;
1989}
1990
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001991static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
1992{
1993 struct sd *sd = (struct sd *) gspca_dev;
1994
1995 sd->gamma = val;
1996 if (gspca_dev->streaming)
1997 setgamma(gspca_dev);
1998 return 0;
1999}
2000
2001static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2002{
2003 struct sd *sd = (struct sd *) gspca_dev;
2004
2005 *val = sd->gamma;
2006 return 0;
2007}
2008
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002009static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2010{
2011 struct sd *sd = (struct sd *) gspca_dev;
2012
2013 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002014 if (gspca_dev->streaming)
2015 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002016 return 0;
2017}
2018
2019static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2020{
2021 struct sd *sd = (struct sd *) gspca_dev;
2022
2023 *val = sd->autogain;
2024 return 0;
2025}
2026
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002027static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2028{
2029 struct sd *sd = (struct sd *) gspca_dev;
2030
2031 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002032 if (gspca_dev->streaming)
2033 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002034 return 0;
2035}
2036
2037static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2038{
2039 struct sd *sd = (struct sd *) gspca_dev;
2040
2041 *val = sd->vflip;
2042 return 0;
2043}
2044
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002045static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2046{
2047 struct sd *sd = (struct sd *) gspca_dev;
2048
2049 sd->infrared = val;
2050 if (gspca_dev->streaming)
2051 setinfrared(sd);
2052 return 0;
2053}
2054
2055static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2056{
2057 struct sd *sd = (struct sd *) gspca_dev;
2058
2059 *val = sd->infrared;
2060 return 0;
2061}
2062
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002063/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002064static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002065 .name = MODULE_NAME,
2066 .ctrls = sd_ctrls,
2067 .nctrls = ARRAY_SIZE(sd_ctrls),
2068 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002069 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002070 .start = sd_start,
2071 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002072 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002073 .dq_callback = do_autogain,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002074};
2075
2076/* -- module initialisation -- */
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002077#define BSI(bridge, sensor, i2c_addr) \
2078 .driver_info = (BRIDGE_ ## bridge << 16) \
2079 | (SENSOR_ ## sensor << 8) \
2080 | (i2c_addr)
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002081static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002082#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002083 {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)},
Jean-Francois Moine7b537392008-09-07 11:56:49 -03002084 {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002085#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002086 {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)},
2087 {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002088#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002089 {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002090#endif
Jean-Francois Moine7e21fda2008-11-10 04:45:51 -03002091 {USB_DEVICE(0x0471, 0x0328), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002092 {USB_DEVICE(0x0471, 0x0330), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine3319dc92008-12-01 14:44:02 -03002093 {USB_DEVICE(0x06f8, 0x3004), BSI(SN9C105, OV7660, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002094 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, HV7131R, 0x11)},
2095/* bw600.inf:
2096 {USB_DEVICE(0x0c45, 0x6040), BSI(SN9C102P, MI0360, 0x5d)}, */
2097/* {USB_DEVICE(0x0c45, 0x603a), BSI(SN9C102P, OV7648, 0x??)}, */
2098/* {USB_DEVICE(0x0c45, 0x607a), BSI(SN9C102P, OV7648, 0x??)}, */
2099 {USB_DEVICE(0x0c45, 0x607c), BSI(SN9C102P, HV7131R, 0x11)},
2100/* {USB_DEVICE(0x0c45, 0x607e), BSI(SN9C102P, OV7630, 0x??)}, */
Jean-Francois Moine661ab252009-01-29 16:03:19 -03002101 {USB_DEVICE(0x0c45, 0x60c0), BSI(SN9C105, MI0360, 0x5d)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002102/* {USB_DEVICE(0x0c45, 0x60c8), BSI(SN9C105, OM6801, 0x??)}, */
2103/* {USB_DEVICE(0x0c45, 0x60cc), BSI(SN9C105, HV7131GP, 0x??)}, */
2104 {USB_DEVICE(0x0c45, 0x60ec), BSI(SN9C105, MO4000, 0x21)},
2105/* {USB_DEVICE(0x0c45, 0x60ef), BSI(SN9C105, ICM105C, 0x??)}, */
2106/* {USB_DEVICE(0x0c45, 0x60fa), BSI(SN9C105, OV7648, 0x??)}, */
2107 {USB_DEVICE(0x0c45, 0x60fb), BSI(SN9C105, OV7660, 0x21)},
2108 {USB_DEVICE(0x0c45, 0x60fc), BSI(SN9C105, HV7131R, 0x11)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002109#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
2110 {USB_DEVICE(0x0c45, 0x60fe), BSI(SN9C105, OV7630, 0x21)},
2111#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002112/* {USB_DEVICE(0x0c45, 0x6108), BSI(SN9C120, OM6801, 0x??)}, */
2113/* {USB_DEVICE(0x0c45, 0x6122), BSI(SN9C110, ICM105C, 0x??)}, */
2114/* {USB_DEVICE(0x0c45, 0x6123), BSI(SN9C110, SanyoCCD, 0x??)}, */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002115 {USB_DEVICE(0x0c45, 0x6128), BSI(SN9C110, OM6802, 0x21)}, /*sn9c325?*/
2116/*bw600.inf:*/
Jean-Francois Moine62703302008-11-11 08:42:56 -03002117 {USB_DEVICE(0x0c45, 0x612a), BSI(SN9C120, OV7648, 0x21)}, /*sn9c110?*/
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002118 {USB_DEVICE(0x0c45, 0x612c), BSI(SN9C110, MO4000, 0x21)},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002119 {USB_DEVICE(0x0c45, 0x612e), BSI(SN9C110, OV7630, 0x21)},
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002120/* {USB_DEVICE(0x0c45, 0x612f), BSI(SN9C110, ICM105C, 0x??)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002121#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002122 {USB_DEVICE(0x0c45, 0x6130), BSI(SN9C120, MI0360, 0x5d)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002123#endif
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002124 {USB_DEVICE(0x0c45, 0x6138), BSI(SN9C120, MO4000, 0x21)},
Jean-Francois Moine821ced22008-11-11 07:10:11 -03002125 {USB_DEVICE(0x0c45, 0x613a), BSI(SN9C120, OV7648, 0x21)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002126#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002127 {USB_DEVICE(0x0c45, 0x613b), BSI(SN9C120, OV7660, 0x21)},
2128 {USB_DEVICE(0x0c45, 0x613c), BSI(SN9C120, HV7131R, 0x11)},
2129/* {USB_DEVICE(0x0c45, 0x613e), BSI(SN9C120, OV7630, 0x??)}, */
Jean-Francois Moinec41492c2008-07-07 08:31:16 -03002130#endif
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002131 {USB_DEVICE(0x0c45, 0x6143), BSI(SN9C120, SP80708, 0x18)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002132 {}
2133};
2134MODULE_DEVICE_TABLE(usb, device_table);
2135
2136/* -- device connect -- */
2137static int sd_probe(struct usb_interface *intf,
2138 const struct usb_device_id *id)
2139{
2140 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2141 THIS_MODULE);
2142}
2143
2144static struct usb_driver sd_driver = {
2145 .name = MODULE_NAME,
2146 .id_table = device_table,
2147 .probe = sd_probe,
2148 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002149#ifdef CONFIG_PM
2150 .suspend = gspca_suspend,
2151 .resume = gspca_resume,
2152#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002153};
2154
2155/* -- module insert / remove -- */
2156static int __init sd_mod_init(void)
2157{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002158 int ret;
2159 ret = usb_register(&sd_driver);
2160 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002161 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002162 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002163 return 0;
2164}
2165static void __exit sd_mod_exit(void)
2166{
2167 usb_deregister(&sd_driver);
2168 info("deregistered");
2169}
2170
2171module_init(sd_mod_init);
2172module_exit(sd_mod_exit);