blob: 94af964772d0a24793655ebdcf25d8a567f1555e [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/*
Jean-Francois Moine5b34e3e2009-11-02 10:00:48 -03002 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) subdriver
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003 *
Jean-Francois Moine5b34e3e2009-11-02 10:00:48 -03004 * Copyright (C) 2009 Jean-Francois Moine <http://moinejf.free.fr>
5 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03006 *
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"
25#include "jpeg.h"
26
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030027#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
28
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030029MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
31MODULE_LICENSE("GPL");
32
33/* specific webcam descriptor */
34struct sd {
35 struct gspca_dev gspca_dev; /* !! must be the first item */
36
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030037 atomic_t avg_lum;
Jean-Francois Moine98819182009-01-19 07:37:33 -030038 u32 exposure;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030039
Jean-Francois Moine98819182009-01-19 07:37:33 -030040 u16 brightness;
41 u8 contrast;
42 u8 colors;
43 u8 autogain;
44 u8 blue;
45 u8 red;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030046 u8 gamma;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -030047 u8 vflip; /* ov7630/ov7648 only */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -030048 u8 sharpness;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -030049 u8 infrared; /* mt9v111 only */
Hans de Goede37c6dbe2009-06-18 07:35:36 -030050 u8 freq; /* ov76xx only */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030051 u8 quality; /* image quality */
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030052#define QUALITY_MIN 60
53#define QUALITY_MAX 95
54#define QUALITY_DEF 80
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030055 u8 jpegqual; /* webcam quality */
56
57 u8 reg18;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030058
Jean-Francois Moine98819182009-01-19 07:37:33 -030059 s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030060#define AG_CNT_START 13
61
Jean-Francois Moine98819182009-01-19 07:37:33 -030062 u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030063#define BRIDGE_SN9C102P 0
64#define BRIDGE_SN9C105 1
65#define BRIDGE_SN9C110 2
66#define BRIDGE_SN9C120 3
Jean-Francois Moine98819182009-01-19 07:37:33 -030067 u8 sensor; /* Type of image sensor chip */
Jean-Francois Moine64677572009-12-20 12:31:28 -030068#define SENSOR_ADCM1700 0
69#define SENSOR_HV7131R 1
70#define SENSOR_MI0360 2
71#define SENSOR_MO4000 3
72#define SENSOR_MT9V111 4
73#define SENSOR_OM6802 5
74#define SENSOR_OV7630 6
75#define SENSOR_OV7648 7
76#define SENSOR_OV7660 8
77#define SENSOR_PO1030 9
78#define SENSOR_SP80708 10
Jean-Francois Moined5aa3852009-11-07 06:10:08 -030079 u8 i2c_addr;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030080
81 u8 *jpeg_hdr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030082};
83
84/* V4L2 controls supported by the driver */
85static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
86static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
87static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
88static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
89static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030091static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030095static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030097static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -030099static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300101static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300103static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300105static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
106static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300107
108static struct ctrl sd_ctrls[] = {
Hans de Goede97643982009-06-18 05:08:11 -0300109#define BRIGHTNESS_IDX 0
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300110 {
111 {
112 .id = V4L2_CID_BRIGHTNESS,
113 .type = V4L2_CTRL_TYPE_INTEGER,
114 .name = "Brightness",
115 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300116#define BRIGHTNESS_MAX 0xffff
117 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -0300119#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300120 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300121 },
122 .set = sd_setbrightness,
123 .get = sd_getbrightness,
124 },
Hans de Goede97643982009-06-18 05:08:11 -0300125#define CONTRAST_IDX 1
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300126 {
127 {
128 .id = V4L2_CID_CONTRAST,
129 .type = V4L2_CTRL_TYPE_INTEGER,
130 .name = "Contrast",
131 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300132#define CONTRAST_MAX 127
133 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300134 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300135#define CONTRAST_DEF 63
136 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300137 },
138 .set = sd_setcontrast,
139 .get = sd_getcontrast,
140 },
Hans de Goede97643982009-06-18 05:08:11 -0300141#define COLOR_IDX 2
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300142 {
143 {
144 .id = V4L2_CID_SATURATION,
145 .type = V4L2_CTRL_TYPE_INTEGER,
Hans de Goede3fb4a572009-06-18 14:31:36 -0300146 .name = "Saturation",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300147 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300148 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300149 .step = 1,
Hans de Goede3fb4a572009-06-18 14:31:36 -0300150#define COLOR_DEF 25
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300151 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300152 },
153 .set = sd_setcolors,
154 .get = sd_getcolors,
155 },
Hans de Goede97643982009-06-18 05:08:11 -0300156#define BLUE_BALANCE_IDX 3
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300157 {
158 {
159 .id = V4L2_CID_BLUE_BALANCE,
160 .type = V4L2_CTRL_TYPE_INTEGER,
161 .name = "Blue Balance",
162 .minimum = 24,
163 .maximum = 40,
164 .step = 1,
165#define BLUE_BALANCE_DEF 32
166 .default_value = BLUE_BALANCE_DEF,
167 },
168 .set = sd_setblue_balance,
169 .get = sd_getblue_balance,
170 },
Hans de Goede97643982009-06-18 05:08:11 -0300171#define RED_BALANCE_IDX 4
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300172 {
173 {
174 .id = V4L2_CID_RED_BALANCE,
175 .type = V4L2_CTRL_TYPE_INTEGER,
176 .name = "Red Balance",
177 .minimum = 24,
178 .maximum = 40,
179 .step = 1,
180#define RED_BALANCE_DEF 32
181 .default_value = RED_BALANCE_DEF,
182 },
183 .set = sd_setred_balance,
184 .get = sd_getred_balance,
185 },
Hans de Goede97643982009-06-18 05:08:11 -0300186#define GAMMA_IDX 5
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300187 {
188 {
189 .id = V4L2_CID_GAMMA,
190 .type = V4L2_CTRL_TYPE_INTEGER,
191 .name = "Gamma",
192 .minimum = 0,
193 .maximum = 40,
194 .step = 1,
195#define GAMMA_DEF 20
196 .default_value = GAMMA_DEF,
197 },
198 .set = sd_setgamma,
199 .get = sd_getgamma,
200 },
Hans de Goede97643982009-06-18 05:08:11 -0300201#define AUTOGAIN_IDX 6
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300202 {
203 {
204 .id = V4L2_CID_AUTOGAIN,
205 .type = V4L2_CTRL_TYPE_BOOLEAN,
206 .name = "Auto Gain",
207 .minimum = 0,
208 .maximum = 1,
209 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300210#define AUTOGAIN_DEF 1
211 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300212 },
213 .set = sd_setautogain,
214 .get = sd_getautogain,
215 },
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300216/* ov7630/ov7648 only */
Hans de Goede97643982009-06-18 05:08:11 -0300217#define VFLIP_IDX 7
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300218 {
219 {
220 .id = V4L2_CID_VFLIP,
221 .type = V4L2_CTRL_TYPE_BOOLEAN,
222 .name = "Vflip",
223 .minimum = 0,
224 .maximum = 1,
225 .step = 1,
Hans de Goedef8009522009-06-18 14:29:20 -0300226#define VFLIP_DEF 0
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300227 .default_value = VFLIP_DEF,
228 },
229 .set = sd_setvflip,
230 .get = sd_getvflip,
231 },
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300232#define SHARPNESS_IDX 8
233 {
234 {
235 .id = V4L2_CID_SHARPNESS,
236 .type = V4L2_CTRL_TYPE_INTEGER,
237 .name = "Sharpness",
238 .minimum = 0,
239 .maximum = 255,
240 .step = 1,
241#define SHARPNESS_DEF 90
242 .default_value = SHARPNESS_DEF,
243 },
244 .set = sd_setsharpness,
245 .get = sd_getsharpness,
246 },
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300247/* mt9v111 only */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300248#define INFRARED_IDX 9
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300249 {
250 {
251 .id = V4L2_CID_INFRARED,
252 .type = V4L2_CTRL_TYPE_BOOLEAN,
253 .name = "Infrared",
254 .minimum = 0,
255 .maximum = 1,
256 .step = 1,
257#define INFRARED_DEF 0
258 .default_value = INFRARED_DEF,
259 },
260 .set = sd_setinfrared,
261 .get = sd_getinfrared,
262 },
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300263/* ov7630/ov7648/ov7660 only */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300264#define FREQ_IDX 10
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300265 {
266 {
267 .id = V4L2_CID_POWER_LINE_FREQUENCY,
268 .type = V4L2_CTRL_TYPE_MENU,
269 .name = "Light frequency filter",
270 .minimum = 0,
271 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
272 .step = 1,
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300273#define FREQ_DEF 1
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300274 .default_value = FREQ_DEF,
275 },
276 .set = sd_setfreq,
277 .get = sd_getfreq,
278 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300279};
280
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300281/* table of the disabled controls */
282static __u32 ctrl_dis[] = {
Jean-Francois Moine64677572009-12-20 12:31:28 -0300283 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX) |
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300284 (1 << AUTOGAIN_IDX), /* SENSOR_ADCM1700 0 */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300285 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300286 /* SENSOR_HV7131R 1 */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300287 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300288 /* SENSOR_MI0360 2 */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300289 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300290 /* SENSOR_MO4000 3 */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300291 (1 << VFLIP_IDX) | (1 << FREQ_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300292 /* SENSOR_MT9V111 4 */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300293 (1 << INFRARED_IDX) | (1 << VFLIP_IDX) | (1 << FREQ_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300294 /* SENSOR_OM6802 5 */
Hans de Goede1fec7472009-06-18 06:05:07 -0300295 (1 << INFRARED_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300296 /* SENSOR_OV7630 6 */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300297 (1 << INFRARED_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300298 /* SENSOR_OV7648 7 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300299 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX),
Jean-Francois Moine64677572009-12-20 12:31:28 -0300300 /* SENSOR_OV7660 8 */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300301 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
Jean-Francois Moine64677572009-12-20 12:31:28 -0300302 (1 << FREQ_IDX), /* SENSOR_PO1030 9 */
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300303 (1 << AUTOGAIN_IDX) | (1 << INFRARED_IDX) | (1 << VFLIP_IDX) |
Jean-Francois Moine64677572009-12-20 12:31:28 -0300304 (1 << FREQ_IDX), /* SENSOR_SP80708 10 */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300305};
306
Jean-Francois Moine64677572009-12-20 12:31:28 -0300307static const struct v4l2_pix_format cif_mode[] = {
308 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
309 .bytesperline = 352,
310 .sizeimage = 352 * 288 * 4 / 8 + 590,
311 .colorspace = V4L2_COLORSPACE_JPEG,
312 .priv = 0},
313};
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300314static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300315 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
316 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300317 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300318 .colorspace = V4L2_COLORSPACE_JPEG,
319 .priv = 2},
320 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
321 .bytesperline = 320,
322 .sizeimage = 320 * 240 * 3 / 8 + 590,
323 .colorspace = V4L2_COLORSPACE_JPEG,
324 .priv = 1},
325 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
326 .bytesperline = 640,
Hans de Goedea5d1cc32009-06-18 06:03:20 -0300327 /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
328 .sizeimage = 640 * 480 * 3 / 4 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300329 .colorspace = V4L2_COLORSPACE_JPEG,
330 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300331};
332
Jean-Francois Moine64677572009-12-20 12:31:28 -0300333static const u8 sn_adcm1700[0x1c] = {
334/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300335 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine64677572009-12-20 12:31:28 -0300336/* reg8 reg9 rega regb regc regd rege regf */
337 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
338/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
339 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
340/* reg18 reg19 reg1a reg1b */
341 0x06, 0x00, 0x00, 0x00
342};
343
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300344/*Data from sn9c102p+hv7131r */
345static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300346/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
347 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
348/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300349 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300350/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
351 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300352/* reg18 reg19 reg1a reg1b */
353 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300354};
355
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300356static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300357/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
358 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
359/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300360 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300361/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
362 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300363/* reg18 reg19 reg1a reg1b */
364 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300365};
366
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300367static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300368/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300369 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300370/* reg8 reg9 rega regb regc regd rege regf */
371 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
372/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
373 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300374/* reg18 reg19 reg1a reg1b */
375 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300376};
377
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300378static const u8 sn_mt9v111[0x1c] = {
379/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
380 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
381/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300382 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300383/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
384 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
385/* reg18 reg19 reg1a reg1b */
386 0x06, 0x00, 0x00, 0x00
387};
388
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300389static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300390/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Amauri Magagna46b4f2a2009-10-17 07:21:29 -0300391 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300392/* reg8 reg9 rega regb regc regd rege regf */
393 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
395 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300396/* reg18 reg19 reg1a reg1b */
397 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300398};
399
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300400static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300401/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
402 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
403/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300404 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300405/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
406 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300407/* reg18 reg19 reg1a reg1b */
408 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300409};
410
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300411static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300412/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300413 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300414/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300415 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300416/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300417 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300418/* reg18 reg19 reg1a reg1b */
419 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300420};
421
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300422static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300423/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -0300424 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300425/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -0300426 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300427/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
428 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300429/* reg18 reg19 reg1a reg1b */
430 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300431};
432
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300433static const u8 sn_po1030[0x1c] = {
434/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
435 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
436/* reg8 reg9 rega regb regc regd rege regf */
437 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
438/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
439 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
440/* reg18 reg19 reg1a reg1b */
441 0x07, 0x00, 0x00, 0x00
442};
443
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300444static const u8 sn_sp80708[0x1c] = {
445/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
446 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
447/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300448 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300449/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
450 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
451/* reg18 reg19 reg1a reg1b */
452 0x07, 0x00, 0x00, 0x00
453};
454
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300455/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300456static const u8 *sn_tb[] = {
Jean-Francois Moine64677572009-12-20 12:31:28 -0300457 sn_adcm1700,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300458 sn_hv7131,
459 sn_mi0360,
460 sn_mo4000,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300461 sn_mt9v111,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300462 sn_om6802,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300463 sn_ov7630,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300464 sn_ov7648,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300465 sn_ov7660,
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300466 sn_po1030,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300467 sn_sp80708
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300468};
469
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300470/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300471static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300472 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
473 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
474};
Jean-Francois Moine64677572009-12-20 12:31:28 -0300475/* gamma for sensor ADCM1700 */
476static const u8 gamma_spec_0[17] = {
477 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
478 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
479};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300480/* gamma for sensors HV7131R and MT9V111 */
481static const u8 gamma_spec_1[17] = {
482 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
483 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
484};
485/* gamma for sensor SP80708 */
486static const u8 gamma_spec_2[17] = {
487 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
488 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
489};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300490
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300491/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300492static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300493 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
494 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
495 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
496 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300497};
Jean-Francois Moine64677572009-12-20 12:31:28 -0300498static const u8 adcm1700_sensor_init[][8] = {
499 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300500 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
Jean-Francois Moine64677572009-12-20 12:31:28 -0300501 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
502 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
503 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
504 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
505 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
506 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
507 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
508 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
509 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
510 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
511 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
512 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
513 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
514 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
515 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
516 {}
517};
518static const u8 adcm1700_sensor_param1[][8] = {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300519 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
Jean-Francois Moine64677572009-12-20 12:31:28 -0300520 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
521
522 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
523 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
524 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
525 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300526 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
Jean-Francois Moine64677572009-12-20 12:31:28 -0300527
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300528 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
529 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
530 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
531 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
Jean-Francois Moine64677572009-12-20 12:31:28 -0300532 {}
533};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300534static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300535 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
536 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
537 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
538/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
539 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
540 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
541/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300542
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300543 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
544 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
545 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
546 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
547 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
548 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
549 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
550 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300551
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300552 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
553 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -0300554 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300555 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
556 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300557
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300558 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
559 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
560 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
561 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
562 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300563 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
564 /* set sensor clock */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300565 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300566};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300567static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300568 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300569 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300570 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300571 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
572 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
573 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
574 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
575 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
576 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
577 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
578 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
579 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
580 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
581 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
582 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
583 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
584 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
585 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
586 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
587 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
588 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
589 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300590 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300591 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
592 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
593 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
594 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
595 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
596 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
597 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
598 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
600 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300601
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300602 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
603 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
604 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
605 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
606 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300607
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300608 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
609 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
610 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
611 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300612
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300613 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
614 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
615/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
616/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
617 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
618 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300619 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300620};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300621static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300622 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
623 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
624 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
625 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
626 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
627 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
628 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
629 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
630 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
631 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
632 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
633 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
634 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
635 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
636 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
637 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
638 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
639 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
640 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
641 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300642 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300643};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300644static const u8 mt9v111_sensor_init[][8] = {
645 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300646 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300647 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
648 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
649 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
650 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300651 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
652 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
653 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
654 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300655 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300656 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
657 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
658 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
659 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
660 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300661 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300662 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300663 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
664 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
665 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
666 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
667 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
668 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
669 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
670 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
671 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
672 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300673 {}
674};
675static const u8 mt9v111_sensor_param1[][8] = {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300676 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
677 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300678 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300679 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
680 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
681 /*******/
682 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
683 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
684 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
685 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
686 {}
687};
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300688static const u8 om6802_init0[2][8] = {
689/*fixme: variable*/
690 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
691 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
692};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300693static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300694 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
695 /* factory mode */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300696 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300697 /* output raw RGB */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300698 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300699/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
700 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300701 /* auto-exposure speed (0) / white balance mode (auto RGB) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300702/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
703 * set color mode */
704/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
705 * max AGC value in AE */
706/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
707 * preset AGC */
708/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
709 * preset brightness */
710/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
711 * preset contrast */
712/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
713 * preset gamma */
714 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300715 /* luminance mode (0x4f -> AutoExpo on) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300716 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
717 /* preset shutter */
718/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
719 * auto frame rate */
720/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300721 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
722 {}
723};
724static const u8 om6802_sensor_param1[][8] = {
725 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
726 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
727 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
728 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300729 {}
730};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300731static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300732 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
733 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300734 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300735 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
736 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300737 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300738 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300739/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300740 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
741 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
Hans de Goedecc7b5b52009-06-18 05:14:42 -0300742/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
743 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
744 {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300745 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
746 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
747 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
748 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
749 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
750 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
751 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
752 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
753 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
754 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
755 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
756 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
757 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
758 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
759 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
760 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
761 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
762 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
763 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
764 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
765 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
766 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
767 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
768/* */
769 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
770 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
771/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300772/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
773 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300774 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
775 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
776 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300777/* */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300778/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
779/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300780/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300781 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300782/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300783 {}
784};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300785
Jean-Francois Moine98819182009-01-19 07:37:33 -0300786static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300787 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
788 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300789 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300790 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
791 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
792 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
793 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
794 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
795 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
796 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
797 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
798 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
799 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
800 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
801 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
802 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
803 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
804 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
805 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
806 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
807 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
808 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
809
810 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
811/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
812/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300813/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300814 {}
815};
816static const u8 ov7648_sensor_param1[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300817/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300818/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
819 * set by setvflip */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300820 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
821 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
822/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
823/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
824/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
825/*...*/
826 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
827/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
828/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
829/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
830/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
831/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
832
833 {}
834};
835
Jean-Francois Moine98819182009-01-19 07:37:33 -0300836static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300837 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300838 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300839 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300840 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -0300842 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300843 /* GAIN BLUE RED VREF */
844 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
845 /* COM 1 BAVE GEAVE AECHH */
846 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
847 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -0300848 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300849 /* AECH CLKRC COM7 COM8 */
850 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
851 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
852 /* HSTART HSTOP VSTRT VSTOP */
853 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
854 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
855 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
856 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300857/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
858 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859 /* AEW AEB VPT BBIAS */
860 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
861 /* GbBIAS RSVD EXHCH EXHCL */
862 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
863 /* RBIAS ADVFL ASDVFH YAVE */
864 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
865 /* HSYST HSYEN HREF */
866 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
867 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
868 /* ADC ACOM OFON TSLB */
869 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
870 /* COM11 COM12 COM13 COM14 */
871 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
872 /* EDGE COM15 COM16 COM17 */
873 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
874 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
875 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
876 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
877 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
878 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
879 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
880 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
881 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
882 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
883 /* LCC1 LCC2 LCC3 LCC4 */
884 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300885 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300887 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
889 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
890 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
891 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
892 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
893 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
894 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
895 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
896 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300897 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300898/* not in all ms-win traces*/
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -0300899 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300900 {}
901};
902static const u8 ov7660_sensor_param1[][8] = {
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300903 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300904 /* bits[3..0]reserved */
905 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
906 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
907 /* VREF vertical frame ctrl */
908 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300909 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
910 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
911 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
912 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
913/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300914/****** (some exchanges in the win trace) ******/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300915/*fixme:param2*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300916 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300917 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
918 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
919 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
920/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300922/******!! startsensor KO if changed !!****/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300923/*fixme: param3*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300924 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
925 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
926 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
927 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300928 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300929};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300931static const u8 po1030_sensor_init[][8] = {
932/* the sensor registers are described in m5602/m5602_po1030.h */
933 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
934 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
935 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
936 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
937 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
938 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
939 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
940 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
941 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
942 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
943 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
944 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
945 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
946 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
947 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
948 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
949 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
950 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
951 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
952 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
953 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
954 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
955 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
956 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
957 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
958 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
959 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
960 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
961
962 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
963 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
964 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
965 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
966 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
967 {}
968};
969static const u8 po1030_sensor_param1[][8] = {
970/* from ms-win traces - these values change with auto gain/expo/wb.. */
971 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
972 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
973/* mean values */
974 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
975 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
976 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
977
978 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
979 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
980 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
981/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
982 {}
983};
984
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300985static const u8 sp80708_sensor_init[][8] = {
986 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
987 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
988 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
989 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
990 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
991 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
992 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
993 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
994 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
995 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
996 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
997 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
998 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
999 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1000 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1001 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1002 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1003 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1004 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1005 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1006 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1007 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1008 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1009 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1010 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1011 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1012 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1013 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1014 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1015 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1016 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1017 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1018 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1019 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1020 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1021 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1022 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1023 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1024 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1025 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1026 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1027 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1028 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1029 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1030 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1031 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1032 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1033 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1034 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1035 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1036 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1037 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1038 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1039 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1040 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1041 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1042 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1043 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1044 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1045 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1046 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1047 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1048 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1049 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1050 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1051 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1052 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1053 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1054 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1055 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1056 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001057 {}
1058};
1059static const u8 sp80708_sensor_param1[][8] = {
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001060 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1061 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1062 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1063 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1064 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1065 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1066 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1067 {}
1068};
1069
Jean-Francois Moine64677572009-12-20 12:31:28 -03001070static const u8 (*sensor_init[11])[8] = {
1071 adcm1700_sensor_init, /* ADCM1700 0 */
1072 hv7131r_sensor_init, /* HV7131R 1 */
1073 mi0360_sensor_init, /* MI0360 2 */
1074 mo4000_sensor_init, /* MO4000 3 */
1075 mt9v111_sensor_init, /* MT9V111 4 */
1076 om6802_sensor_init, /* OM6802 5 */
1077 ov7630_sensor_init, /* OV7630 6 */
1078 ov7648_sensor_init, /* OV7648 7 */
1079 ov7660_sensor_init, /* OV7660 8 */
1080 po1030_sensor_init, /* PO1030 9 */
1081 sp80708_sensor_init, /* SP80708 10 */
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001082};
1083
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001084/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001085static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001086 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001087{
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001088#ifdef GSPCA_DEBUG
1089 if (len > USB_BUF_SZ) {
1090 err("reg_r: buffer overflow");
1091 return;
1092 }
1093#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001094 usb_control_msg(gspca_dev->dev,
1095 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001096 0,
1097 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1098 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001099 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001100 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001101 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001102}
1103
Jean-Francois Moine60017612008-07-18 08:46:19 -03001104static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001105 u16 value,
1106 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -03001107{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001108 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001109 gspca_dev->usb_buf[0] = data;
1110 usb_control_msg(gspca_dev->dev,
1111 usb_sndctrlpipe(gspca_dev->dev, 0),
1112 0x08,
1113 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1114 value,
1115 0,
1116 gspca_dev->usb_buf, 1,
1117 500);
1118}
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001119static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001120 u16 value,
1121 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001122 int len)
1123{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001124 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -03001125 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001126#ifdef GSPCA_DEBUG
1127 if (len > USB_BUF_SZ) {
1128 err("reg_w: buffer overflow");
1129 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -03001130 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001131#endif
1132 memcpy(gspca_dev->usb_buf, buffer, len);
1133 usb_control_msg(gspca_dev->dev,
1134 usb_sndctrlpipe(gspca_dev->dev, 0),
1135 0x08,
1136 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1137 value, 0,
1138 gspca_dev->usb_buf, len,
1139 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001140}
1141
Jean-Francois Moine60017612008-07-18 08:46:19 -03001142/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001143static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001144{
1145 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001146
Jean-Francois Moine60017612008-07-18 08:46:19 -03001147 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001148 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03001149 case SENSOR_ADCM1700:
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001150 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */
1151 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1152 break;
1153 default: /* i2c command = a1 (400 kHz) */
1154 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1155 break;
1156 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001157 gspca_dev->usb_buf[1] = sd->i2c_addr;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001158 gspca_dev->usb_buf[2] = reg;
1159 gspca_dev->usb_buf[3] = val;
1160 gspca_dev->usb_buf[4] = 0;
1161 gspca_dev->usb_buf[5] = 0;
1162 gspca_dev->usb_buf[6] = 0;
1163 gspca_dev->usb_buf[7] = 0x10;
1164 usb_control_msg(gspca_dev->dev,
1165 usb_sndctrlpipe(gspca_dev->dev, 0),
1166 0x08,
1167 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1168 0x08, /* value = i2c */
1169 0,
1170 gspca_dev->usb_buf, 8,
1171 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001172}
1173
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001174/* I2C write 8 bytes */
1175static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001176 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001177{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001178 memcpy(gspca_dev->usb_buf, buffer, 8);
1179 usb_control_msg(gspca_dev->dev,
1180 usb_sndctrlpipe(gspca_dev->dev, 0),
1181 0x08,
1182 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1183 0x08, 0, /* value, index */
1184 gspca_dev->usb_buf, 8,
1185 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -03001186 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001187}
1188
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001189/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1190static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001191{
1192 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001193 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001194
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001195 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03001196 case SENSOR_ADCM1700:
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001197 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */
1198 mode[0] = 0x80 | 0x10;
1199 break;
1200 default: /* i2c command = 91 (400 kHz) */
1201 mode[0] = 0x81 | 0x10;
1202 break;
1203 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001204 mode[1] = sd->i2c_addr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001205 mode[2] = reg;
1206 mode[3] = 0;
1207 mode[4] = 0;
1208 mode[5] = 0;
1209 mode[6] = 0;
1210 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001211 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001212 msleep(2);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001213 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001214 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001215 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001216 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001217 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001218}
1219
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001220static void i2c_w_seq(struct gspca_dev *gspca_dev,
1221 const u8 (*data)[8])
1222{
1223 while ((*data)[0] != 0) {
1224 if ((*data)[0] != 0xdd)
1225 i2c_w8(gspca_dev, *data);
1226 else
1227 msleep((*data)[1]);
1228 data++;
1229 }
1230}
1231
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001232static void hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001233{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001234 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001235 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001236 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001237 msleep(10);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001238 i2c_r(gspca_dev, 0, 5); /* read sensor id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001239 if (gspca_dev->usb_buf[0] == 0x02
1240 && gspca_dev->usb_buf[1] == 0x09
1241 && gspca_dev->usb_buf[2] == 0x01
1242 && gspca_dev->usb_buf[3] == 0x00
1243 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001244 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1245 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001246 }
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001247 PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001248 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1249 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001250}
1251
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001252static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001253{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001254 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001255 int i, j;
Jean-Francois Moine92e8c912009-02-02 16:25:38 -03001256 u16 val = 0;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001257 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001258 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001259 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1260 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1261 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1262 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1263 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001264 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001265 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1266 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1267 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1268 {}
1269 },
1270 };
1271
1272 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1273 reg_w1(gspca_dev, 0x17, 0x62);
1274 reg_w1(gspca_dev, 0x01, 0x08);
1275 for (j = 0; j < 3; j++)
1276 i2c_w8(gspca_dev, probe_tb[i][j]);
1277 msleep(2);
1278 reg_r(gspca_dev, 0x0a, 5);
1279 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1280 if (probe_tb[i][3][0] != 0)
1281 i2c_w8(gspca_dev, probe_tb[i][3]);
1282 reg_w1(gspca_dev, 0x01, 0x29);
1283 reg_w1(gspca_dev, 0x17, 0x42);
1284 if (val != 0xffff)
1285 break;
1286 }
1287 switch (val) {
1288 case 0x823a:
1289 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001290 sd->sensor = SENSOR_MT9V111;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001291 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001292 case 0x8243:
1293 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001294 break;
1295 default:
1296 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1297 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001298 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001299}
1300
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001301static void ov7648_probe(struct gspca_dev *gspca_dev)
1302{
1303 struct sd *sd = (struct sd *) gspca_dev;
1304
1305 /* check ov76xx */
1306 reg_w1(gspca_dev, 0x17, 0x62);
1307 reg_w1(gspca_dev, 0x01, 0x08);
1308 sd->i2c_addr = 0x21;
1309 i2c_r(gspca_dev, 0x0a, 2);
1310 if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */
1311 PDEBUG(D_PROBE, "Sensor ov%02x%02x",
1312 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1313 return;
1314 }
1315
1316 /* reset */
1317 reg_w1(gspca_dev, 0x01, 0x29);
1318 reg_w1(gspca_dev, 0x17, 0x42);
1319
1320 /* check po1030 */
1321 reg_w1(gspca_dev, 0x17, 0x62);
1322 reg_w1(gspca_dev, 0x01, 0x08);
1323 sd->i2c_addr = 0x6e;
1324 i2c_r(gspca_dev, 0x00, 2);
1325 if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */
1326 && gspca_dev->usb_buf[4] == 0x30) {
1327 PDEBUG(D_PROBE, "Sensor po1030");
1328 sd->sensor = SENSOR_PO1030;
1329 return;
1330 }
1331
1332 PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
1333 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1334}
1335
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001336static void bridge_init(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001337 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001338{
1339 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001340 const u8 *reg9a;
1341 static const u8 reg9a_def[] =
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03001342 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1343 static const u8 reg9a_spec[] =
1344 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001345 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001346
Jean-Francois Moine60017612008-07-18 08:46:19 -03001347 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001348 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001349
1350 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001351 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1352 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001353 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03001354 switch (sd->sensor) {
1355 case SENSOR_OV7660:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001356 case SENSOR_PO1030:
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03001357 case SENSOR_SP80708:
1358 reg9a = reg9a_spec;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001359 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001360 default:
1361 reg9a = reg9a_def;
1362 break;
1363 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001364 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001365
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001366 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001367
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001368 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001369
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001370 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03001371 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001372 reg_w1(gspca_dev, 0x01, 0x43);
Jean-Francois Moine64677572009-12-20 12:31:28 -03001373 reg_w1(gspca_dev, 0x17, 0x62);
1374 reg_w1(gspca_dev, 0x01, 0x42);
1375 reg_w1(gspca_dev, 0x01, 0x42);
1376 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001377 case SENSOR_MT9V111:
1378 reg_w1(gspca_dev, 0x01, 0x61);
1379 reg_w1(gspca_dev, 0x17, 0x61);
1380 reg_w1(gspca_dev, 0x01, 0x60);
1381 reg_w1(gspca_dev, 0x01, 0x40);
1382 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001383 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001384 msleep(10);
1385 reg_w1(gspca_dev, 0x02, 0x73);
1386 reg_w1(gspca_dev, 0x17, 0x60);
1387 reg_w1(gspca_dev, 0x01, 0x22);
1388 msleep(100);
1389 reg_w1(gspca_dev, 0x01, 0x62);
1390 reg_w1(gspca_dev, 0x17, 0x64);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001391 reg_w1(gspca_dev, 0x17, 0x64);
1392 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001393 msleep(10);
1394 reg_w1(gspca_dev, 0x01, 0x42);
1395 i2c_w8(gspca_dev, om6802_init0[0]);
1396 i2c_w8(gspca_dev, om6802_init0[1]);
1397 msleep(15);
1398 reg_w1(gspca_dev, 0x02, 0x71);
1399 msleep(150);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001400 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001401 case SENSOR_OV7630:
1402 reg_w1(gspca_dev, 0x01, 0x61);
1403 reg_w1(gspca_dev, 0x17, 0xe2);
1404 reg_w1(gspca_dev, 0x01, 0x60);
1405 reg_w1(gspca_dev, 0x01, 0x40);
1406 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001407 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001408 reg_w1(gspca_dev, 0x01, 0x63);
1409 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03001410 reg_w1(gspca_dev, 0x01, 0x62);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001411 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001412 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001413 case SENSOR_PO1030:
1414 reg_w1(gspca_dev, 0x01, 0x61);
1415 reg_w1(gspca_dev, 0x17, 0x20);
1416 reg_w1(gspca_dev, 0x01, 0x60);
1417 reg_w1(gspca_dev, 0x01, 0x40);
1418 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001419 case SENSOR_OV7660:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001420 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001421 case SENSOR_SP80708:
1422 reg_w1(gspca_dev, 0x01, 0x63);
1423 reg_w1(gspca_dev, 0x17, 0x20);
1424 reg_w1(gspca_dev, 0x01, 0x62);
1425 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine1f78a972009-08-29 07:11:58 -03001426 msleep(100);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001427 reg_w1(gspca_dev, 0x02, 0x62);
1428 break;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001429 default:
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03001430/* case SENSOR_HV7131R: */
1431/* case SENSOR_MI0360: */
1432/* case SENSOR_MO4000: */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001433 reg_w1(gspca_dev, 0x01, 0x43);
1434 reg_w1(gspca_dev, 0x17, 0x61);
1435 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001436 if (sd->sensor == SENSOR_HV7131R
1437 && sd->bridge == BRIDGE_SN9C102P)
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001438 hv7131r_probe(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001439 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001440 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001441}
1442
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001443/* this function is called at probe time */
1444static int sd_config(struct gspca_dev *gspca_dev,
1445 const struct usb_device_id *id)
1446{
1447 struct sd *sd = (struct sd *) gspca_dev;
1448 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001449
1450 cam = &gspca_dev->cam;
Jean-Francois Moine64677572009-12-20 12:31:28 -03001451 if (sd->sensor == SENSOR_ADCM1700) {
1452 cam->cam_mode = cif_mode;
1453 cam->nmodes = ARRAY_SIZE(cif_mode);
1454 } else {
1455 cam->cam_mode = vga_mode;
1456 cam->nmodes = ARRAY_SIZE(vga_mode);
1457 }
Jean-Francois Moine49cb6b02009-04-25 13:29:01 -03001458 cam->npkt = 24; /* 24 packets per ISOC message */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001459
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001460 sd->bridge = id->driver_info >> 16;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001461 sd->sensor = id->driver_info;
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001462
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001463 sd->brightness = BRIGHTNESS_DEF;
1464 sd->contrast = CONTRAST_DEF;
1465 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001466 sd->blue = BLUE_BALANCE_DEF;
1467 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001468 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001469 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001470 sd->ag_cnt = -1;
Hans de Goedef8009522009-06-18 14:29:20 -03001471 sd->vflip = VFLIP_DEF;
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001472 switch (sd->sensor) {
1473 case SENSOR_OM6802:
1474 sd->sharpness = 0x10;
1475 break;
1476 default:
1477 sd->sharpness = SHARPNESS_DEF;
1478 break;
1479 }
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001480 sd->infrared = INFRARED_DEF;
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001481 sd->freq = FREQ_DEF;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001482 sd->quality = QUALITY_DEF;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001483 sd->jpegqual = 80;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001484
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001485 return 0;
1486}
1487
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001488/* this function is called at probe and resume time */
1489static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001490{
1491 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001492 const u8 *sn9c1xx;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001493 u8 regGpio[] = { 0x29, 0x74 };
1494 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001495
Hans de Goede3647fea2008-07-15 05:36:30 -03001496 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001497 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001498 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001499 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1500 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001501 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001502 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001503 switch (sd->bridge) {
1504 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001505 if (regF1 != 0x11)
1506 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001507 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001508 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001509 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001510 if (regF1 != 0x11)
1511 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001512 if (sd->sensor == SENSOR_MI0360)
1513 mi0360_probe(gspca_dev);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001514 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001515 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001516 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001517 if (regF1 != 0x12)
1518 return -ENODEV;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001519 switch (sd->sensor) {
1520 case SENSOR_MI0360:
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001521 mi0360_probe(gspca_dev);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001522 break;
1523 case SENSOR_OV7648:
1524 ov7648_probe(gspca_dev);
1525 break;
1526 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001527 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001528 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001529 break;
1530 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001531/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001532/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001533 if (regF1 != 0x12)
1534 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001535 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001536 break;
1537 }
1538
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03001539 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001540
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001541 /* set the i2c address */
1542 sn9c1xx = sn_tb[sd->sensor];
1543 sd->i2c_addr = sn9c1xx[9];
1544
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001545 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1546
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001547 return 0;
1548}
1549
Jean-Francois Moine98819182009-01-19 07:37:33 -03001550static u32 setexposure(struct gspca_dev *gspca_dev,
1551 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001552{
1553 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001554
1555 switch (sd->sensor) {
1556 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001557 u8 Expodoit[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001558 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001559
1560 Expodoit[3] = expo >> 16;
1561 Expodoit[4] = expo >> 8;
1562 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001563 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001564 break;
1565 }
1566 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001567 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001568 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001569 static const u8 doit[] = /* update sensor */
1570 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1571 static const u8 sensorgo[] = /* sensor on */
1572 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001573
1574 if (expo > 0x0635)
1575 expo = 0x0635;
1576 else if (expo < 0x0001)
1577 expo = 0x0001;
1578 expoMi[3] = expo >> 8;
1579 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001580 i2c_w8(gspca_dev, expoMi);
1581 i2c_w8(gspca_dev, doit);
1582 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001583 break;
1584 }
1585 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001586 u8 expoMof[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001587 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001588 u8 expoMo10[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001589 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001590 static const u8 gainMo[] =
1591 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001592
1593 if (expo > 0x1fff)
1594 expo = 0x1fff;
1595 else if (expo < 0x0001)
1596 expo = 0x0001;
1597 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001598 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001599 expoMo10[3] = ((expo & 0x1c00) >> 10)
1600 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001601 i2c_w8(gspca_dev, expoMo10);
1602 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001603 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001604 ((expoMo10[3] & 0x07) << 10)
1605 | (expoMof[3] << 2)
1606 | ((expoMo10[3] & 0x30) >> 4));
1607 break;
1608 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001609 case SENSOR_MT9V111: {
1610 u8 expo_c1[] =
1611 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1612
1613 if (expo > 0x0280)
1614 expo = 0x0280;
1615 else if (expo < 0x0040)
1616 expo = 0x0040;
1617 expo_c1[3] = expo >> 8;
1618 expo_c1[4] = expo;
1619 i2c_w8(gspca_dev, expo_c1);
1620 break;
1621 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001622 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001623 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001624 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001625 /* preset AGC - works when AutoExpo = off */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001626
1627 if (expo > 0x03ff)
1628 expo = 0x03ff;
1629 if (expo < 0x0001)
1630 expo = 0x0001;
1631 gainOm[3] = expo >> 2;
1632 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001633 reg_w1(gspca_dev, 0x96, expo >> 5);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001634 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001635 break;
1636 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001637 }
1638 return expo;
1639}
1640
1641static void setbrightness(struct gspca_dev *gspca_dev)
1642{
1643 struct sd *sd = (struct sd *) gspca_dev;
1644 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001645 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001646
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001647 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001648 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03001649 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001650 if (k2 > 0x1f)
1651 k2 = 0; /* only positive Y offset */
1652 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001653 case SENSOR_HV7131R:
1654 expo = sd->brightness << 4;
1655 if (expo > 0x002dc6c0)
1656 expo = 0x002dc6c0;
1657 else if (expo < 0x02a0)
1658 expo = 0x02a0;
1659 sd->exposure = setexposure(gspca_dev, expo);
1660 break;
1661 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001662 case SENSOR_MO4000:
1663 expo = sd->brightness >> 4;
1664 sd->exposure = setexposure(gspca_dev, expo);
1665 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001666 case SENSOR_MT9V111:
1667 expo = sd->brightness >> 8;
1668 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001669 return; /* don't set the Y offset */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001670 case SENSOR_OM6802:
1671 expo = sd->brightness >> 6;
1672 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001673 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001674 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001675 }
1676
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001677 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001678}
1679
1680static void setcontrast(struct gspca_dev *gspca_dev)
1681{
1682 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001683 u8 k2;
1684 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001685
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001686 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1687 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001688 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001689 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001690 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001691 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001692 contrast[5] = 0;
1693 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001694}
1695
1696static void setcolors(struct gspca_dev *gspca_dev)
1697{
1698 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001699 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001700 u8 reg8a[12]; /* U & V gains */
1701 static s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001702 -24, -38, 64, /* UR UG UB */
1703 62, -51, -9 /* VR VG VB */
1704 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001705
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001706 for (i = 0; i < 6; i++) {
1707 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001708 reg8a[i * 2] = v;
1709 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001710 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001711 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001712}
1713
1714static void setredblue(struct gspca_dev *gspca_dev)
1715{
1716 struct sd *sd = (struct sd *) gspca_dev;
1717
1718 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001719/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001720 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001721}
1722
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001723static void setgamma(struct gspca_dev *gspca_dev)
1724{
1725 struct sd *sd = (struct sd *) gspca_dev;
1726 int i;
1727 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001728 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001729 static const u8 delta[17] = {
1730 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1731 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1732 };
1733
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001734 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03001735 case SENSOR_ADCM1700:
1736 gamma_base = gamma_spec_0;
1737 break;
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001738 case SENSOR_HV7131R:
1739 case SENSOR_MT9V111:
1740 gamma_base = gamma_spec_1;
1741 break;
1742 case SENSOR_SP80708:
1743 gamma_base = gamma_spec_2;
1744 break;
1745 default:
1746 gamma_base = gamma_def;
1747 break;
1748 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001749
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001750 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001751 gamma[i] = gamma_base[i]
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001752 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1753 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1754}
1755
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001756static void setautogain(struct gspca_dev *gspca_dev)
1757{
1758 struct sd *sd = (struct sd *) gspca_dev;
1759
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001760 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1761 return;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001762 switch (sd->sensor) {
1763 case SENSOR_OV7630:
1764 case SENSOR_OV7648: {
1765 u8 comb;
1766
1767 if (sd->sensor == SENSOR_OV7630)
1768 comb = 0xc0;
1769 else
1770 comb = 0xa0;
1771 if (sd->autogain)
Hans de Goede1fec7472009-06-18 06:05:07 -03001772 comb |= 0x03;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001773 i2c_w1(&sd->gspca_dev, 0x13, comb);
1774 return;
1775 }
1776 }
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001777 if (sd->autogain)
1778 sd->ag_cnt = AG_CNT_START;
1779 else
1780 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001781}
1782
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001783/* ov7630/ov7648 only */
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001784static void setvflip(struct sd *sd)
1785{
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001786 u8 comn;
1787
Jean-Francois Moine0939e262009-11-02 09:58:49 -03001788 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
1789 return;
Hans de Goedef8009522009-06-18 14:29:20 -03001790 if (sd->sensor == SENSOR_OV7630) {
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001791 comn = 0x02;
Hans de Goedef8009522009-06-18 14:29:20 -03001792 if (!sd->vflip)
1793 comn |= 0x80;
1794 } else {
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001795 comn = 0x06;
Hans de Goedef8009522009-06-18 14:29:20 -03001796 if (sd->vflip)
1797 comn |= 0x80;
1798 }
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001799 i2c_w1(&sd->gspca_dev, 0x75, comn);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001800}
1801
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001802static void setsharpness(struct sd *sd)
1803{
1804 reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
1805}
1806
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001807static void setinfrared(struct sd *sd)
1808{
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001809 if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
1810 return;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001811/*fixme: different sequence for StarCam Clip and StarCam 370i */
1812/* Clip */
1813 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1814 sd->infrared ? 0x66 : 0x64);
1815}
1816
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001817static void setfreq(struct gspca_dev *gspca_dev)
1818{
1819 struct sd *sd = (struct sd *) gspca_dev;
1820
Jean-Francois Moine27954932009-07-08 05:21:50 -03001821 if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
1822 return;
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001823 if (sd->sensor == SENSOR_OV7660) {
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001824 u8 com8;
1825
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001826 com8 = 0xdf; /* auto gain/wb/expo */
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001827 switch (sd->freq) {
1828 case 0: /* Banding filter disabled */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001829 i2c_w1(gspca_dev, 0x13, com8 | 0x20);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001830 break;
1831 case 1: /* 50 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001832 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001833 i2c_w1(gspca_dev, 0x3b, 0x0a);
1834 break;
1835 case 2: /* 60 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001836 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001837 i2c_w1(gspca_dev, 0x3b, 0x02);
1838 break;
1839 }
1840 } else {
1841 u8 reg2a = 0, reg2b = 0, reg2d = 0;
1842
1843 /* Get reg2a / reg2d base values */
1844 switch (sd->sensor) {
1845 case SENSOR_OV7630:
1846 reg2a = 0x08;
1847 reg2d = 0x01;
1848 break;
1849 case SENSOR_OV7648:
1850 reg2a = 0x11;
1851 reg2d = 0x81;
1852 break;
1853 }
1854
1855 switch (sd->freq) {
1856 case 0: /* Banding filter disabled */
1857 break;
1858 case 1: /* 50 hz (filter on and framerate adj) */
1859 reg2a |= 0x80;
1860 reg2b = 0xac;
1861 reg2d |= 0x04;
1862 break;
1863 case 2: /* 60 hz (filter on, no framerate adj) */
1864 reg2a |= 0x80;
1865 reg2d |= 0x04;
1866 break;
1867 }
1868 i2c_w1(gspca_dev, 0x2a, reg2a);
1869 i2c_w1(gspca_dev, 0x2b, reg2b);
1870 i2c_w1(gspca_dev, 0x2d, reg2d);
1871 }
1872}
1873
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001874static void setjpegqual(struct gspca_dev *gspca_dev)
1875{
1876 struct sd *sd = (struct sd *) gspca_dev;
1877 int i, sc;
1878
1879 if (sd->jpegqual < 50)
1880 sc = 5000 / sd->jpegqual;
1881 else
1882 sc = 200 - sd->jpegqual * 2;
1883#if USB_BUF_SZ < 64
1884#error "No room enough in usb_buf for quantization table"
1885#endif
1886 for (i = 0; i < 64; i++)
1887 gspca_dev->usb_buf[i] =
1888 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
1889 usb_control_msg(gspca_dev->dev,
1890 usb_sndctrlpipe(gspca_dev->dev, 0),
1891 0x08,
1892 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1893 0x0100, 0,
1894 gspca_dev->usb_buf, 64,
1895 500);
1896 for (i = 0; i < 64; i++)
1897 gspca_dev->usb_buf[i] =
1898 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
1899 usb_control_msg(gspca_dev->dev,
1900 usb_sndctrlpipe(gspca_dev->dev, 0),
1901 0x08,
1902 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1903 0x0140, 0,
1904 gspca_dev->usb_buf, 64,
1905 500);
1906
1907 sd->reg18 ^= 0x40;
1908 reg_w1(gspca_dev, 0x18, sd->reg18);
1909}
1910
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001911/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001912static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001913{
1914 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001915 int i;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001916 u8 reg1, reg2, reg17;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001917 const u8 *sn9c1xx;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001918 const u8 (*init)[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001919 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001920 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1921 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moine64677572009-12-20 12:31:28 -03001922 static const u8 CA_adcm1700[] =
1923 { 0x14, 0xec, 0x0a, 0xf6 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001924 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1925 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001926 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001927
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001928 /* create the JPEG header */
1929 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
Julia Lawall3eb02372009-07-19 07:09:32 -03001930 if (!sd->jpeg_hdr)
1931 return -ENOMEM;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001932 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1933 0x21); /* JPEG 422 */
1934 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1935
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001936 /* initialize the bridge */
1937 sn9c1xx = sn_tb[sd->sensor];
1938 bridge_init(gspca_dev, sn9c1xx);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001939
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001940 /* initialize the sensor */
1941 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
1942
1943 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03001944 case SENSOR_ADCM1700:
1945 reg2 = 0x60;
1946 break;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001947 case SENSOR_OM6802:
1948 reg2 = 0x71;
1949 break;
1950 case SENSOR_SP80708:
1951 reg2 = 0x62;
1952 break;
1953 default:
1954 reg2 = 0x40;
1955 break;
1956 }
1957 reg_w1(gspca_dev, 0x02, reg2);
1958 reg_w1(gspca_dev, 0x02, reg2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001959
Jean-Francois Moine60017612008-07-18 08:46:19 -03001960 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1961 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1962 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1963 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1964 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine64677572009-12-20 12:31:28 -03001965 if (sd->sensor == SENSOR_ADCM1700) {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001966 reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
1967 reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
Jean-Francois Moine64677572009-12-20 12:31:28 -03001968 } else {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001969 reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
1970 reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
Jean-Francois Moine64677572009-12-20 12:31:28 -03001971 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001972 reg_w1(gspca_dev, 0xc6, 0x00);
1973 reg_w1(gspca_dev, 0xc7, 0x00);
Jean-Francois Moine64677572009-12-20 12:31:28 -03001974 if (sd->sensor == SENSOR_ADCM1700) {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001975 reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
1976 reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
Jean-Francois Moine64677572009-12-20 12:31:28 -03001977 } else {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001978 reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
1979 reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
Jean-Francois Moine64677572009-12-20 12:31:28 -03001980 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001981 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001982 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001983 case SENSOR_MT9V111:
1984 reg17 = 0xe0;
1985 break;
Jean-Francois Moine64677572009-12-20 12:31:28 -03001986 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001987 case SENSOR_OV7630:
1988 reg17 = 0xe2;
1989 break;
1990 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001991 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001992 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03001993 case SENSOR_OV7660:
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03001994 reg17 = 0xa0;
1995 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001996 case SENSOR_PO1030:
1997 reg17 = 0xa0;
1998 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03001999 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002000 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002001 break;
2002 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002003 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002004
2005 reg_w1(gspca_dev, 0x05, 0x00); /* red */
2006 reg_w1(gspca_dev, 0x07, 0x00); /* green */
2007 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002008 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002009
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002010 setgamma(gspca_dev);
2011
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002012/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03002013 for (i = 0; i < 8; i++)
2014 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002015 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03002016 case SENSOR_ADCM1700:
Jean-Francois Moinec8b9b2ca2009-04-26 14:46:12 -03002017 case SENSOR_OV7660:
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002018 case SENSOR_SP80708:
2019 reg_w1(gspca_dev, 0x9a, 0x05);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002020 break;
2021 case SENSOR_MT9V111:
2022 reg_w1(gspca_dev, 0x9a, 0x07);
2023 break;
2024 case SENSOR_OV7648:
2025 reg_w1(gspca_dev, 0x9a, 0x0a);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002026 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002027 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03002028 reg_w1(gspca_dev, 0x9a, 0x08);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002029 break;
2030 }
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002031 setsharpness(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002032
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002033 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002034 reg_w1(gspca_dev, 0x05, 0x20); /* red */
2035 reg_w1(gspca_dev, 0x07, 0x20); /* green */
2036 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
Jean-Francois Moine23a98272009-11-02 09:10:25 -03002037
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002038 init = NULL;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002039 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03002040 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002041 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002042 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002043 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
2044 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002045 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03002046 case SENSOR_ADCM1700:
2047 init = adcm1700_sensor_param1;
2048 reg1 = 0x46;
2049 reg17 = 0xe2;
2050 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002051 case SENSOR_MO4000:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002052 if (mode) {
2053/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
2054 reg1 = 0x06; /* clk 24Mz */
2055 } else {
2056 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002057/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002058 }
2059 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002060 case SENSOR_MT9V111:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002061 init = mt9v111_sensor_param1;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002062 if (mode) {
2063 reg1 = 0x04; /* 320 clk 48Mhz */
2064 } else {
2065/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -03002066 reg17 = 0xc2;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002067 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03002068 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002069 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002070 init = om6802_sensor_param1;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002071 reg17 = 0x64; /* 640 MCKSIZE */
2072 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002073 case SENSOR_OV7630:
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002074 setvflip(sd);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002075 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03002076 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002077 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002078 case SENSOR_OV7648:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002079 init = ov7648_sensor_param1;
Jean-Francois Moine62703302008-11-11 08:42:56 -03002080 reg17 = 0x21;
2081/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002082 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002083 case SENSOR_OV7660:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002084 init = ov7660_sensor_param1;
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03002085 if (sd->bridge == BRIDGE_SN9C120) {
2086 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002087 reg17 = 0xa2;
2088 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002089 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03002090 } else {
2091 reg17 = 0x22;
2092 reg1 = 0x06; /* 24 Mhz, video trf eneble
2093 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002094 }
2095 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002096 case SENSOR_PO1030:
2097 init = po1030_sensor_param1;
2098 reg17 = 0xa2;
2099 reg1 = 0x44;
2100 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002101 default:
2102/* case SENSOR_SP80708: */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002103 init = sp80708_sensor_param1;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002104 if (mode) {
2105/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002106 } else {
2107 reg1 = 0x46; /* 640 clk 48Mz */
2108 reg17 = 0xa2;
2109 }
2110 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002111 }
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002112
2113 /* more sensor initialization - param1 */
2114 if (init != NULL) {
2115 i2c_w_seq(gspca_dev, init);
2116/* init = NULL; */
2117 }
2118
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002119 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine64677572009-12-20 12:31:28 -03002120 if (sd->sensor == SENSOR_ADCM1700)
2121 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2122 else
2123 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002124 switch (sd->sensor) {
Jean-Francois Moine64677572009-12-20 12:31:28 -03002125 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002126 case SENSOR_OV7630:
2127 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002128 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002129 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002130 break;
2131 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002132 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002133 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2134 break;
2135 }
2136
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002137
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002138 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002139 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2140 reg_w1(gspca_dev, 0x18, sd->reg18);
2141 setjpegqual(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002142
Jean-Francois Moine60017612008-07-18 08:46:19 -03002143 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002144 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002145
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03002146 switch (sd->sensor) {
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002147 case SENSOR_OV7630:
2148 setvflip(sd);
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03002149 break;
2150 }
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002151 setbrightness(gspca_dev);
2152 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002153 setautogain(gspca_dev);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002154 setfreq(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03002155 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002156}
2157
2158static void sd_stopN(struct gspca_dev *gspca_dev)
2159{
2160 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002161 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002162 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002163 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002164 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002165 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03002166 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002167 u8 data;
2168 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002169
2170 data = 0x0b;
2171 switch (sd->sensor) {
2172 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002173 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002174 data = 0x2b;
2175 break;
2176 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002177 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002178 data = 0x29;
2179 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002180 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002181 i2c_w8(gspca_dev, stopov7648);
2182 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002183 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002184 case SENSOR_OV7630:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002185 case SENSOR_PO1030:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002186 data = 0x29;
2187 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002188 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002189 sn9c1xx = sn_tb[sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03002190 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2191 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2192 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2193 reg_w1(gspca_dev, 0x01, data);
Jean-Francois Moine759aa3c2008-09-03 16:48:03 -03002194 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002195}
2196
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002197static void sd_stop0(struct gspca_dev *gspca_dev)
2198{
2199 struct sd *sd = (struct sd *) gspca_dev;
2200
2201 kfree(sd->jpeg_hdr);
2202}
2203
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002204static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002205{
2206 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002207 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002208 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002209 u8 luma_mean = 130;
2210 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002211
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002212 /* Thanks S., without your advice, autobright should not work :) */
2213 if (sd->ag_cnt < 0)
2214 return;
2215 if (--sd->ag_cnt >= 0)
2216 return;
2217 sd->ag_cnt = AG_CNT_START;
2218
2219 delta = atomic_read(&sd->avg_lum);
2220 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002221 if (delta < luma_mean - luma_delta ||
2222 delta > luma_mean + luma_delta) {
2223 switch (sd->sensor) {
2224 case SENSOR_HV7131R:
2225 expotimes = sd->exposure >> 8;
2226 expotimes += (luma_mean - delta) >> 4;
2227 if (expotimes < 0)
2228 expotimes = 0;
2229 sd->exposure = setexposure(gspca_dev,
2230 (unsigned int) (expotimes << 8));
2231 break;
Amauri Magagna46b4f2a2009-10-17 07:21:29 -03002232 case SENSOR_OM6802:
2233 expotimes = sd->exposure;
2234 expotimes += (luma_mean - delta) >> 2;
2235 if (expotimes < 0)
2236 expotimes = 0;
2237 sd->exposure = setexposure(gspca_dev,
2238 (unsigned int) expotimes);
2239 setredblue(gspca_dev);
2240 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002241 default:
2242/* case SENSOR_MO4000: */
2243/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002244/* case SENSOR_MT9V111: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002245 expotimes = sd->exposure;
2246 expotimes += (luma_mean - delta) >> 6;
2247 if (expotimes < 0)
2248 expotimes = 0;
2249 sd->exposure = setexposure(gspca_dev,
2250 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002251 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002252 break;
2253 }
2254 }
2255}
2256
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002257/* scan the URB packets */
2258/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002259static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03002260 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002261 int len) /* iso packet length */
2262{
2263 struct sd *sd = (struct sd *) gspca_dev;
2264 int sof, avg_lum;
2265
2266 sof = len - 64;
2267 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
2268
2269 /* end of frame */
2270 gspca_frame_add(gspca_dev, LAST_PACKET,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03002271 data, sof + 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002272 if (sd->ag_cnt < 0)
2273 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002274/* w1 w2 w3 */
2275/* w4 w5 w6 */
2276/* w7 w8 */
2277/* w4 */
2278 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2279/* w6 */
2280 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2281/* w2 */
2282 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2283/* w8 */
2284 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2285/* w5 */
2286 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2287 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002288 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002289 return;
2290 }
2291 if (gspca_dev->last_packet_type == LAST_PACKET) {
2292
2293 /* put the JPEG 422 header */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03002294 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002295 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002296 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03002297 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002298}
2299
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002300static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2301{
2302 struct sd *sd = (struct sd *) gspca_dev;
2303
2304 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002305 if (gspca_dev->streaming)
2306 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002307 return 0;
2308}
2309
2310static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2311{
2312 struct sd *sd = (struct sd *) gspca_dev;
2313
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002314 *val = sd->brightness;
2315 return 0;
2316}
2317
2318static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2319{
2320 struct sd *sd = (struct sd *) gspca_dev;
2321
2322 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002323 if (gspca_dev->streaming)
2324 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002325 return 0;
2326}
2327
2328static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2329{
2330 struct sd *sd = (struct sd *) gspca_dev;
2331
2332 *val = sd->contrast;
2333 return 0;
2334}
2335
2336static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2337{
2338 struct sd *sd = (struct sd *) gspca_dev;
2339
2340 sd->colors = val;
2341 if (gspca_dev->streaming)
2342 setcolors(gspca_dev);
2343 return 0;
2344}
2345
2346static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2347{
2348 struct sd *sd = (struct sd *) gspca_dev;
2349
2350 *val = sd->colors;
2351 return 0;
2352}
2353
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002354static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2355{
2356 struct sd *sd = (struct sd *) gspca_dev;
2357
2358 sd->blue = val;
2359 if (gspca_dev->streaming)
2360 setredblue(gspca_dev);
2361 return 0;
2362}
2363
2364static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2365{
2366 struct sd *sd = (struct sd *) gspca_dev;
2367
2368 *val = sd->blue;
2369 return 0;
2370}
2371
2372static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2373{
2374 struct sd *sd = (struct sd *) gspca_dev;
2375
2376 sd->red = val;
2377 if (gspca_dev->streaming)
2378 setredblue(gspca_dev);
2379 return 0;
2380}
2381
2382static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2383{
2384 struct sd *sd = (struct sd *) gspca_dev;
2385
2386 *val = sd->red;
2387 return 0;
2388}
2389
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002390static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2391{
2392 struct sd *sd = (struct sd *) gspca_dev;
2393
2394 sd->gamma = val;
2395 if (gspca_dev->streaming)
2396 setgamma(gspca_dev);
2397 return 0;
2398}
2399
2400static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2401{
2402 struct sd *sd = (struct sd *) gspca_dev;
2403
2404 *val = sd->gamma;
2405 return 0;
2406}
2407
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002408static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2409{
2410 struct sd *sd = (struct sd *) gspca_dev;
2411
2412 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002413 if (gspca_dev->streaming)
2414 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002415 return 0;
2416}
2417
2418static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2419{
2420 struct sd *sd = (struct sd *) gspca_dev;
2421
2422 *val = sd->autogain;
2423 return 0;
2424}
2425
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002426static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2427{
2428 struct sd *sd = (struct sd *) gspca_dev;
2429
2430 sd->sharpness = val;
2431 if (gspca_dev->streaming)
2432 setsharpness(sd);
2433 return 0;
2434}
2435
2436static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2437{
2438 struct sd *sd = (struct sd *) gspca_dev;
2439
2440 *val = sd->sharpness;
2441 return 0;
2442}
2443
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002444static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2445{
2446 struct sd *sd = (struct sd *) gspca_dev;
2447
2448 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002449 if (gspca_dev->streaming)
2450 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002451 return 0;
2452}
2453
2454static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2455{
2456 struct sd *sd = (struct sd *) gspca_dev;
2457
2458 *val = sd->vflip;
2459 return 0;
2460}
2461
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002462static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2463{
2464 struct sd *sd = (struct sd *) gspca_dev;
2465
2466 sd->infrared = val;
2467 if (gspca_dev->streaming)
2468 setinfrared(sd);
2469 return 0;
2470}
2471
2472static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2473{
2474 struct sd *sd = (struct sd *) gspca_dev;
2475
2476 *val = sd->infrared;
2477 return 0;
2478}
2479
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002480static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2481{
2482 struct sd *sd = (struct sd *) gspca_dev;
2483
2484 sd->freq = val;
2485 if (gspca_dev->streaming)
2486 setfreq(gspca_dev);
2487 return 0;
2488}
2489
2490static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2491{
2492 struct sd *sd = (struct sd *) gspca_dev;
2493
2494 *val = sd->freq;
2495 return 0;
2496}
2497
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002498static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2499 struct v4l2_jpegcompression *jcomp)
2500{
2501 struct sd *sd = (struct sd *) gspca_dev;
2502
2503 if (jcomp->quality < QUALITY_MIN)
2504 sd->quality = QUALITY_MIN;
2505 else if (jcomp->quality > QUALITY_MAX)
2506 sd->quality = QUALITY_MAX;
2507 else
2508 sd->quality = jcomp->quality;
2509 if (gspca_dev->streaming)
2510 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2511 return 0;
2512}
2513
2514static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2515 struct v4l2_jpegcompression *jcomp)
2516{
2517 struct sd *sd = (struct sd *) gspca_dev;
2518
2519 memset(jcomp, 0, sizeof *jcomp);
2520 jcomp->quality = sd->quality;
2521 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2522 | V4L2_JPEG_MARKER_DQT;
2523 return 0;
2524}
2525
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002526static int sd_querymenu(struct gspca_dev *gspca_dev,
2527 struct v4l2_querymenu *menu)
2528{
2529 switch (menu->id) {
2530 case V4L2_CID_POWER_LINE_FREQUENCY:
2531 switch (menu->index) {
2532 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2533 strcpy((char *) menu->name, "NoFliker");
2534 return 0;
2535 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2536 strcpy((char *) menu->name, "50 Hz");
2537 return 0;
2538 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2539 strcpy((char *) menu->name, "60 Hz");
2540 return 0;
2541 }
2542 break;
2543 }
2544 return -EINVAL;
2545}
2546
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002547/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002548static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002549 .name = MODULE_NAME,
2550 .ctrls = sd_ctrls,
2551 .nctrls = ARRAY_SIZE(sd_ctrls),
2552 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002553 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002554 .start = sd_start,
2555 .stopN = sd_stopN,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002556 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002557 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002558 .dq_callback = do_autogain,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002559 .get_jcomp = sd_get_jcomp,
2560 .set_jcomp = sd_set_jcomp,
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002561 .querymenu = sd_querymenu,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002562};
2563
2564/* -- module initialisation -- */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002565#define BS(bridge, sensor) \
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002566 .driver_info = (BRIDGE_ ## bridge << 16) \
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002567 | SENSOR_ ## sensor
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002568static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002569#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002570 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2571 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002572#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002573 {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
2574 {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
2575 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2576 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2577 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2578 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2579 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2580/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2581 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2582/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2583/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2584 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2585/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2586 {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
2587/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2588/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2589/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
2590 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2591/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
2592/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
2593 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002594#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002595 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
2596 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002597#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002598 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
2599/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */
2600/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
2601 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
2602 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
2603 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
2604 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
2605/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
2606/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
2607/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2608 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002609/*bw600.inf:*/
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002610 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002611 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2612 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2613/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002614#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002615 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002616#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002617/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
2618 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
2619 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002620#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002621 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
Jean-Francois Moine8d977702009-02-19 15:34:48 -03002622#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002623 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2624 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
2625/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/
2626 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2627 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
Jean-Francois Moine64677572009-12-20 12:31:28 -03002628 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002629 {}
2630};
2631MODULE_DEVICE_TABLE(usb, device_table);
2632
2633/* -- device connect -- */
2634static int sd_probe(struct usb_interface *intf,
2635 const struct usb_device_id *id)
2636{
2637 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2638 THIS_MODULE);
2639}
2640
2641static struct usb_driver sd_driver = {
2642 .name = MODULE_NAME,
2643 .id_table = device_table,
2644 .probe = sd_probe,
2645 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002646#ifdef CONFIG_PM
2647 .suspend = gspca_suspend,
2648 .resume = gspca_resume,
2649#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002650};
2651
2652/* -- module insert / remove -- */
2653static int __init sd_mod_init(void)
2654{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002655 int ret;
2656 ret = usb_register(&sd_driver);
2657 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002658 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002659 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002660 return 0;
2661}
2662static void __exit sd_mod_exit(void)
2663{
2664 usb_deregister(&sd_driver);
2665 info("deregistered");
2666}
2667
2668module_init(sd_mod_init);
2669module_exit(sd_mod_exit);