blob: 20ca161bc3d0b9fbe4c362b6cb9e6942dc2acb90 [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
Hans de Goede9712a8b2010-01-31 12:54:29 -030024#include <linux/input.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090025#include <linux/slab.h>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030026#include "gspca.h"
27#include "jpeg.h"
28
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030029#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
30
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030031MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
32MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
33MODULE_LICENSE("GPL");
34
35/* specific webcam descriptor */
36struct sd {
37 struct gspca_dev gspca_dev; /* !! must be the first item */
38
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030039 atomic_t avg_lum;
Jean-Francois Moine98819182009-01-19 07:37:33 -030040 u32 exposure;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030041
Jean-Francois Moine98819182009-01-19 07:37:33 -030042 u16 brightness;
43 u8 contrast;
44 u8 colors;
45 u8 autogain;
46 u8 blue;
47 u8 red;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030048 u8 gamma;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -030049 u8 vflip; /* ov7630/ov7648 only */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -030050 u8 sharpness;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -030051 u8 infrared; /* mt9v111 only */
Hans de Goede37c6dbe2009-06-18 07:35:36 -030052 u8 freq; /* ov76xx only */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030053 u8 quality; /* image quality */
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030054#define QUALITY_MIN 60
55#define QUALITY_MAX 95
56#define QUALITY_DEF 80
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030057 u8 jpegqual; /* webcam quality */
58
59 u8 reg18;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030060
Jean-Francois Moine98819182009-01-19 07:37:33 -030061 s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030062#define AG_CNT_START 13
63
Jean-Francois Moine98819182009-01-19 07:37:33 -030064 u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030065#define BRIDGE_SN9C102P 0
66#define BRIDGE_SN9C105 1
67#define BRIDGE_SN9C110 2
68#define BRIDGE_SN9C120 3
Jean-Francois Moine98819182009-01-19 07:37:33 -030069 u8 sensor; /* Type of image sensor chip */
Jean-François Moine9c33afc2010-03-17 15:25:32 -030070enum {
71 SENSOR_ADCM1700,
72 SENSOR_HV7131R,
73 SENSOR_MI0360,
74 SENSOR_MO4000,
75 SENSOR_MT9V111,
76 SENSOR_OM6802,
77 SENSOR_OV7630,
78 SENSOR_OV7648,
79 SENSOR_OV7660,
80 SENSOR_PO1030,
81 SENSOR_SP80708,
82} sensors;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -030083 u8 i2c_addr;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030084
85 u8 *jpeg_hdr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030086};
87
88/* V4L2 controls supported by the driver */
89static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
90static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
91static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
92static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
93static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
94static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine403123d2008-11-26 04:46:15 -030095static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val);
96static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val);
97static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val);
98static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -030099static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val);
100static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300101static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
102static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300103static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val);
104static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300105static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val);
106static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300107static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val);
108static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val);
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300109static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
110static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300111
Marton Nemeth7e64dc42009-12-30 09:12:41 -0300112static const struct ctrl sd_ctrls[] = {
Hans de Goede97643982009-06-18 05:08:11 -0300113#define BRIGHTNESS_IDX 0
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300114 {
115 {
116 .id = V4L2_CID_BRIGHTNESS,
117 .type = V4L2_CTRL_TYPE_INTEGER,
118 .name = "Brightness",
119 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300120#define BRIGHTNESS_MAX 0xffff
121 .maximum = BRIGHTNESS_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300122 .step = 1,
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -0300123#define BRIGHTNESS_DEF 0x8000
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300124 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300125 },
126 .set = sd_setbrightness,
127 .get = sd_getbrightness,
128 },
Hans de Goede97643982009-06-18 05:08:11 -0300129#define CONTRAST_IDX 1
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300130 {
131 {
132 .id = V4L2_CID_CONTRAST,
133 .type = V4L2_CTRL_TYPE_INTEGER,
134 .name = "Contrast",
135 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300136#define CONTRAST_MAX 127
137 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300138 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300139#define CONTRAST_DEF 63
140 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300141 },
142 .set = sd_setcontrast,
143 .get = sd_getcontrast,
144 },
Hans de Goede97643982009-06-18 05:08:11 -0300145#define COLOR_IDX 2
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300146 {
147 {
148 .id = V4L2_CID_SATURATION,
149 .type = V4L2_CTRL_TYPE_INTEGER,
Hans de Goede3fb4a572009-06-18 14:31:36 -0300150 .name = "Saturation",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300151 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300152 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300153 .step = 1,
Hans de Goede3fb4a572009-06-18 14:31:36 -0300154#define COLOR_DEF 25
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300155 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300156 },
157 .set = sd_setcolors,
158 .get = sd_getcolors,
159 },
Hans de Goede97643982009-06-18 05:08:11 -0300160#define BLUE_BALANCE_IDX 3
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300161 {
162 {
163 .id = V4L2_CID_BLUE_BALANCE,
164 .type = V4L2_CTRL_TYPE_INTEGER,
165 .name = "Blue Balance",
166 .minimum = 24,
167 .maximum = 40,
168 .step = 1,
169#define BLUE_BALANCE_DEF 32
170 .default_value = BLUE_BALANCE_DEF,
171 },
172 .set = sd_setblue_balance,
173 .get = sd_getblue_balance,
174 },
Hans de Goede97643982009-06-18 05:08:11 -0300175#define RED_BALANCE_IDX 4
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300176 {
177 {
178 .id = V4L2_CID_RED_BALANCE,
179 .type = V4L2_CTRL_TYPE_INTEGER,
180 .name = "Red Balance",
181 .minimum = 24,
182 .maximum = 40,
183 .step = 1,
184#define RED_BALANCE_DEF 32
185 .default_value = RED_BALANCE_DEF,
186 },
187 .set = sd_setred_balance,
188 .get = sd_getred_balance,
189 },
Hans de Goede97643982009-06-18 05:08:11 -0300190#define GAMMA_IDX 5
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300191 {
192 {
193 .id = V4L2_CID_GAMMA,
194 .type = V4L2_CTRL_TYPE_INTEGER,
195 .name = "Gamma",
196 .minimum = 0,
197 .maximum = 40,
198 .step = 1,
199#define GAMMA_DEF 20
200 .default_value = GAMMA_DEF,
201 },
202 .set = sd_setgamma,
203 .get = sd_getgamma,
204 },
Hans de Goede97643982009-06-18 05:08:11 -0300205#define AUTOGAIN_IDX 6
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300206 {
207 {
208 .id = V4L2_CID_AUTOGAIN,
209 .type = V4L2_CTRL_TYPE_BOOLEAN,
210 .name = "Auto Gain",
211 .minimum = 0,
212 .maximum = 1,
213 .step = 1,
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300214#define AUTOGAIN_DEF 1
215 .default_value = AUTOGAIN_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300216 },
217 .set = sd_setautogain,
218 .get = sd_getautogain,
219 },
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300220/* ov7630/ov7648 only */
Hans de Goede97643982009-06-18 05:08:11 -0300221#define VFLIP_IDX 7
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300222 {
223 {
224 .id = V4L2_CID_VFLIP,
225 .type = V4L2_CTRL_TYPE_BOOLEAN,
226 .name = "Vflip",
227 .minimum = 0,
228 .maximum = 1,
229 .step = 1,
Hans de Goedef8009522009-06-18 14:29:20 -0300230#define VFLIP_DEF 0
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300231 .default_value = VFLIP_DEF,
232 },
233 .set = sd_setvflip,
234 .get = sd_getvflip,
235 },
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300236#define SHARPNESS_IDX 8
237 {
238 {
239 .id = V4L2_CID_SHARPNESS,
240 .type = V4L2_CTRL_TYPE_INTEGER,
241 .name = "Sharpness",
242 .minimum = 0,
243 .maximum = 255,
244 .step = 1,
245#define SHARPNESS_DEF 90
246 .default_value = SHARPNESS_DEF,
247 },
248 .set = sd_setsharpness,
249 .get = sd_getsharpness,
250 },
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300251/* mt9v111 only */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300252#define INFRARED_IDX 9
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300253 {
254 {
255 .id = V4L2_CID_INFRARED,
256 .type = V4L2_CTRL_TYPE_BOOLEAN,
257 .name = "Infrared",
258 .minimum = 0,
259 .maximum = 1,
260 .step = 1,
261#define INFRARED_DEF 0
262 .default_value = INFRARED_DEF,
263 },
264 .set = sd_setinfrared,
265 .get = sd_getinfrared,
266 },
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300267/* ov7630/ov7648/ov7660 only */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300268#define FREQ_IDX 10
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300269 {
270 {
271 .id = V4L2_CID_POWER_LINE_FREQUENCY,
272 .type = V4L2_CTRL_TYPE_MENU,
273 .name = "Light frequency filter",
274 .minimum = 0,
275 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
276 .step = 1,
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300277#define FREQ_DEF 1
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300278 .default_value = FREQ_DEF,
279 },
280 .set = sd_setfreq,
281 .get = sd_getfreq,
282 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300283};
284
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300285/* table of the disabled controls */
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300286static const __u32 ctrl_dis[] = {
287[SENSOR_ADCM1700] = (1 << AUTOGAIN_IDX) |
288 (1 << INFRARED_IDX) |
289 (1 << VFLIP_IDX) |
290 (1 << FREQ_IDX),
291
292[SENSOR_HV7131R] = (1 << INFRARED_IDX) |
293 (1 << FREQ_IDX),
294
295[SENSOR_MI0360] = (1 << INFRARED_IDX) |
296 (1 << VFLIP_IDX) |
297 (1 << FREQ_IDX),
298
299[SENSOR_MO4000] = (1 << INFRARED_IDX) |
300 (1 << VFLIP_IDX) |
301 (1 << FREQ_IDX),
302
303[SENSOR_MT9V111] = (1 << VFLIP_IDX) |
304 (1 << FREQ_IDX),
305
306[SENSOR_OM6802] = (1 << INFRARED_IDX) |
307 (1 << VFLIP_IDX) |
308 (1 << FREQ_IDX),
309
310[SENSOR_OV7630] = (1 << INFRARED_IDX),
311
312[SENSOR_OV7648] = (1 << INFRARED_IDX),
313
314[SENSOR_OV7660] = (1 << AUTOGAIN_IDX) |
315 (1 << INFRARED_IDX) |
316 (1 << VFLIP_IDX),
317
318[SENSOR_PO1030] = (1 << AUTOGAIN_IDX) |
319 (1 << INFRARED_IDX) |
320 (1 << VFLIP_IDX) |
321 (1 << FREQ_IDX),
322
323[SENSOR_SP80708] = (1 << AUTOGAIN_IDX) |
324 (1 << INFRARED_IDX) |
325 (1 << VFLIP_IDX) |
326 (1 << FREQ_IDX),
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300327};
328
Jean-Francois Moine646775732009-12-20 12:31:28 -0300329static const struct v4l2_pix_format cif_mode[] = {
330 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
331 .bytesperline = 352,
332 .sizeimage = 352 * 288 * 4 / 8 + 590,
333 .colorspace = V4L2_COLORSPACE_JPEG,
334 .priv = 0},
335};
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300336static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300337 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
338 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300339 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300340 .colorspace = V4L2_COLORSPACE_JPEG,
341 .priv = 2},
342 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
343 .bytesperline = 320,
344 .sizeimage = 320 * 240 * 3 / 8 + 590,
345 .colorspace = V4L2_COLORSPACE_JPEG,
346 .priv = 1},
347 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
348 .bytesperline = 640,
Hans de Goedea5d1cc32009-06-18 06:03:20 -0300349 /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
350 .sizeimage = 640 * 480 * 3 / 4 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300351 .colorspace = V4L2_COLORSPACE_JPEG,
352 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300353};
354
Jean-Francois Moine646775732009-12-20 12:31:28 -0300355static const u8 sn_adcm1700[0x1c] = {
356/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300357 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine646775732009-12-20 12:31:28 -0300358/* reg8 reg9 rega regb regc regd rege regf */
359 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
361 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
362/* reg18 reg19 reg1a reg1b */
363 0x06, 0x00, 0x00, 0x00
364};
365
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300366/*Data from sn9c102p+hv7131r */
367static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300368/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
369 0x00, 0x03, 0x64, 0x00, 0x1a, 0x20, 0x20, 0x20,
370/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300371 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300372/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
373 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300374/* reg18 reg19 reg1a reg1b */
375 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300376};
377
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300378static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300379/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
380 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20,
381/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300382 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300383/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
384 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300385/* reg18 reg19 reg1a reg1b */
386 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300387};
388
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300389static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300390/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300391 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300392/* reg8 reg9 rega regb regc regd rege regf */
393 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
394/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
395 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300396/* reg18 reg19 reg1a reg1b */
397 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300398};
399
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300400static const u8 sn_mt9v111[0x1c] = {
401/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
402 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
403/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300404 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300405/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
406 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
407/* reg18 reg19 reg1a reg1b */
408 0x06, 0x00, 0x00, 0x00
409};
410
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300411static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300412/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Amauri Magagna46b4f2a2009-10-17 07:21:29 -0300413 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300414/* reg8 reg9 rega regb regc regd rege regf */
415 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
417 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300418/* reg18 reg19 reg1a reg1b */
419 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300420};
421
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300422static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300423/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
424 0x00, 0x21, 0x40, 0x00, 0x1a, 0x20, 0x1f, 0x20,
425/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300426 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300427/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
428 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300429/* reg18 reg19 reg1a reg1b */
430 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300431};
432
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300433static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300434/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300435 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300436/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300437 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300438/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300439 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300440/* reg18 reg19 reg1a reg1b */
441 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300442};
443
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300444static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300445/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -0300446 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300447/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -0300448 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300449/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
450 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300451/* reg18 reg19 reg1a reg1b */
452 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300453};
454
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300455static const u8 sn_po1030[0x1c] = {
456/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
457 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
458/* reg8 reg9 rega regb regc regd rege regf */
459 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
460/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
461 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
462/* reg18 reg19 reg1a reg1b */
463 0x07, 0x00, 0x00, 0x00
464};
465
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300466static const u8 sn_sp80708[0x1c] = {
467/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
468 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
469/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300470 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300471/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
472 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
473/* reg18 reg19 reg1a reg1b */
474 0x07, 0x00, 0x00, 0x00
475};
476
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300477/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300478static const u8 *sn_tb[] = {
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300479[SENSOR_ADCM1700] = sn_adcm1700,
480[SENSOR_HV7131R] = sn_hv7131,
481[SENSOR_MI0360] = sn_mi0360,
482[SENSOR_MO4000] = sn_mo4000,
483[SENSOR_MT9V111] = sn_mt9v111,
484[SENSOR_OM6802] = sn_om6802,
485[SENSOR_OV7630] = sn_ov7630,
486[SENSOR_OV7648] = sn_ov7648,
487[SENSOR_OV7660] = sn_ov7660,
488[SENSOR_PO1030] = sn_po1030,
489[SENSOR_SP80708] = sn_sp80708
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300490};
491
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300492/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300493static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300494 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
495 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
496};
Jean-Francois Moine646775732009-12-20 12:31:28 -0300497/* gamma for sensor ADCM1700 */
498static const u8 gamma_spec_0[17] = {
499 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
500 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
501};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300502/* gamma for sensors HV7131R and MT9V111 */
503static const u8 gamma_spec_1[17] = {
504 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
505 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
506};
507/* gamma for sensor SP80708 */
508static const u8 gamma_spec_2[17] = {
509 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
510 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
511};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300512
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300513/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300514static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300515 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
516 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
517 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
518 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300519};
Jean-Francois Moine646775732009-12-20 12:31:28 -0300520static const u8 adcm1700_sensor_init[][8] = {
521 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300522 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300523 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
524 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
525 {0xdd, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
526 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
527 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
528 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
529 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
530 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
531 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
532 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
533 {0xdd, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
534 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
535 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
536 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
537 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
538 {}
539};
540static const u8 adcm1700_sensor_param1[][8] = {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300541 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300542 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
543
544 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
545 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
546 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
547 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300548 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300549
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300550 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
551 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
552 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
553 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300554 {}
555};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300556static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300557 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
558 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
559 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
560/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
561 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
562 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
563/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300564
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300565 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
566 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
567 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
568 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
569 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
570 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
571 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
572 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300573
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300574 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
575 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -0300576 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300577 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
578 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300579
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300580 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
581 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
582 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
583 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
584 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300585 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
586 /* set sensor clock */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300587 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300588};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300589static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300590 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300591 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300592 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300593 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
594 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
595 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
596 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
597 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
598 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
599 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
601 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
602 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
603 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
604 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
605 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
606 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
607 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
608 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
609 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
610 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
611 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300612 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300613 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
614 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
615 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
616 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
617 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
618 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
619 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
620 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
621 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
622 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300623
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300624 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
625 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
626 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
627 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
628 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300629
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300630 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
631 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
632 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
633 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300634
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300635 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
636 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
637/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
638/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
639 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
640 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300641 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300642};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300643static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300644 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
645 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
646 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
647 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
648 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
649 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
650 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
651 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
652 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
653 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
654 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
655 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
656 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
657 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
658 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
659 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
660 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
661 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
662 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
663 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300664 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300665};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300666static const u8 mt9v111_sensor_init[][8] = {
667 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300668 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300669 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
670 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
671 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
672 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300673 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
674 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
675 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
676 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300677 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300678 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
679 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
680 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
681 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
682 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300683 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300684 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300685 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
686 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
687 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
688 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
689 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
690 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
691 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
692 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
693 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
694 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300695 {}
696};
697static const u8 mt9v111_sensor_param1[][8] = {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300698 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
699 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300700 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300701 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
702 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
703 /*******/
704 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
705 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
706 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
707 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
708 {}
709};
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300710static const u8 om6802_init0[2][8] = {
711/*fixme: variable*/
712 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
713 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
714};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300715static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300716 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
717 /* factory mode */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300718 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300719 /* output raw RGB */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300720 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300721/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
722 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300723 /* auto-exposure speed (0) / white balance mode (auto RGB) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300724/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
725 * set color mode */
726/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
727 * max AGC value in AE */
728/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
729 * preset AGC */
730/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
731 * preset brightness */
732/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
733 * preset contrast */
734/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
735 * preset gamma */
736 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300737 /* luminance mode (0x4f -> AutoExpo on) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300738 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
739 /* preset shutter */
740/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
741 * auto frame rate */
742/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300743 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
744 {}
745};
746static const u8 om6802_sensor_param1[][8] = {
747 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
748 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
749 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
750 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300751 {}
752};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300753static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300754 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
755 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300756 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300757 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
758 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300759 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300760 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300761/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300762 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
763 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
Hans de Goedecc7b5b52009-06-18 05:14:42 -0300764/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
765 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
766 {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300767 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
768 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
769 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
770 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
771 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
772 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
773 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
774 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
775 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
776 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
777 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
778 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
779 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
780 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
781 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
782 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
783 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
784 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
785 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
786 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
787 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
788 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
789 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
790/* */
791 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
793/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300794/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
795 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300796 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
798 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300799/* */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300800/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
801/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300802/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300803 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300804/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300805 {}
806};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300807
Jean-Francois Moine98819182009-01-19 07:37:33 -0300808static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300809 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
810 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300811 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300812 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
813 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
814 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
815 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
816 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
817 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
818 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
819 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
820 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
821 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
822 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
823 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
824 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
825 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
826 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
827 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
828 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
829 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
830 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
831
832 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
833/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
834/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300835/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300836 {}
837};
838static const u8 ov7648_sensor_param1[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300839/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300840/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
841 * set by setvflip */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300842 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
843 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
844/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
845/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
846/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
847/*...*/
848 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
849/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
850/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
851/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
852/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
853/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
854
855 {}
856};
857
Jean-Francois Moine98819182009-01-19 07:37:33 -0300858static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300860 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300861 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300862 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -0300864 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865 /* GAIN BLUE RED VREF */
866 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
867 /* COM 1 BAVE GEAVE AECHH */
868 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
869 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -0300870 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300871 /* AECH CLKRC COM7 COM8 */
872 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
873 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
874 /* HSTART HSTOP VSTRT VSTOP */
875 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
876 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
877 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
878 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300879/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
880 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300881 /* AEW AEB VPT BBIAS */
882 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
883 /* GbBIAS RSVD EXHCH EXHCL */
884 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
885 /* RBIAS ADVFL ASDVFH YAVE */
886 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
887 /* HSYST HSYEN HREF */
888 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
889 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
890 /* ADC ACOM OFON TSLB */
891 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
892 /* COM11 COM12 COM13 COM14 */
893 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
894 /* EDGE COM15 COM16 COM17 */
895 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
896 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
897 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
898 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
899 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
900 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
901 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
902 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
903 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
904 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
905 /* LCC1 LCC2 LCC3 LCC4 */
906 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300907 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300908 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300909 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300910 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
911 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
912 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
913 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
914 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
915 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
916 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
917 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
918 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300919 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300920/* not in all ms-win traces*/
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -0300921 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300922 {}
923};
924static const u8 ov7660_sensor_param1[][8] = {
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300925 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300926 /* bits[3..0]reserved */
927 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
928 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
929 /* VREF vertical frame ctrl */
930 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300931 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
932 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
933 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
934 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
935/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936/****** (some exchanges in the win trace) ******/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300937/*fixme:param2*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300938 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300939 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
940 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
941 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
942/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300943/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -0300944/******!! startsensor KO if changed !!****/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300945/*fixme: param3*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300946 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
947 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
948 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
949 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300950 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300951};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300952
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300953static const u8 po1030_sensor_init[][8] = {
954/* the sensor registers are described in m5602/m5602_po1030.h */
955 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
956 {0xdd, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
957 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
958 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
959 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
960 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
961 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
962 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
963 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
964 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
965 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
966 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
967 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
968 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
969 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
970 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
971 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
972 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
973 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
974 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
975 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
976 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
977 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
978 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
979 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
980 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
981 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
982 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
983
984 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
985 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
986 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
987 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
988 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
989 {}
990};
991static const u8 po1030_sensor_param1[][8] = {
992/* from ms-win traces - these values change with auto gain/expo/wb.. */
993 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
994 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
995/* mean values */
996 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
997 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
998 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
999
1000 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1001 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1002 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1003/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1004 {}
1005};
1006
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001007static const u8 sp80708_sensor_init[][8] = {
1008 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1009 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1010 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1011 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1012 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1013 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1014 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1015 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1016 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1017 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1018 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1019 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1020 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1021 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1022 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1023 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1024 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1025 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1026 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1027 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1028 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1029 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1030 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1031 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1032 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1033 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1034 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1035 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1036 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1037 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1038 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1039 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1040 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1041 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1042 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1043 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1044 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1045 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1046 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1047 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1048 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1049 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1050 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1051 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1052 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1053 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1054 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1055 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1056 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1057 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1058 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1059 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1060 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1061 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1062 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1063 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1064 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1065 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1066 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1067 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1068 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1069 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1070 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1071 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1072 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1073 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1074 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1075 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1076 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1077 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1078 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001079 {}
1080};
1081static const u8 sp80708_sensor_param1[][8] = {
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001082 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1083 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1084 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1085 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1086 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1087 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1088 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1089 {}
1090};
1091
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001092static const u8 (*sensor_init[])[8] = {
1093[SENSOR_ADCM1700] = adcm1700_sensor_init,
1094[SENSOR_HV7131R] = hv7131r_sensor_init,
1095[SENSOR_MI0360] = mi0360_sensor_init,
1096[SENSOR_MO4000] = mo4000_sensor_init,
1097[SENSOR_MT9V111] = mt9v111_sensor_init,
1098[SENSOR_OM6802] = om6802_sensor_init,
1099[SENSOR_OV7630] = ov7630_sensor_init,
1100[SENSOR_OV7648] = ov7648_sensor_init,
1101[SENSOR_OV7660] = ov7660_sensor_init,
1102[SENSOR_PO1030] = po1030_sensor_init,
1103[SENSOR_SP80708] = sp80708_sensor_init,
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001104};
1105
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001106/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001107static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001108 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001109{
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001110#ifdef GSPCA_DEBUG
1111 if (len > USB_BUF_SZ) {
1112 err("reg_r: buffer overflow");
1113 return;
1114 }
1115#endif
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001116 usb_control_msg(gspca_dev->dev,
1117 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001118 0,
1119 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1120 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001121 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001122 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001123 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001124}
1125
Jean-Francois Moine60017612008-07-18 08:46:19 -03001126static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001127 u16 value,
1128 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -03001129{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001130 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001131 gspca_dev->usb_buf[0] = data;
1132 usb_control_msg(gspca_dev->dev,
1133 usb_sndctrlpipe(gspca_dev->dev, 0),
1134 0x08,
1135 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1136 value,
1137 0,
1138 gspca_dev->usb_buf, 1,
1139 500);
1140}
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001141static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001142 u16 value,
1143 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001144 int len)
1145{
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001146 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -03001147 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001148#ifdef GSPCA_DEBUG
1149 if (len > USB_BUF_SZ) {
1150 err("reg_w: buffer overflow");
1151 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -03001152 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001153#endif
1154 memcpy(gspca_dev->usb_buf, buffer, len);
1155 usb_control_msg(gspca_dev->dev,
1156 usb_sndctrlpipe(gspca_dev->dev, 0),
1157 0x08,
1158 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1159 value, 0,
1160 gspca_dev->usb_buf, len,
1161 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001162}
1163
Jean-Francois Moine60017612008-07-18 08:46:19 -03001164/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001165static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001166{
1167 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001168
Jean-Francois Moine60017612008-07-18 08:46:19 -03001169 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001170 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001171 case SENSOR_ADCM1700:
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001172 case SENSOR_OM6802: /* i2c command = a0 (100 kHz) */
1173 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1174 break;
1175 default: /* i2c command = a1 (400 kHz) */
1176 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1177 break;
1178 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001179 gspca_dev->usb_buf[1] = sd->i2c_addr;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001180 gspca_dev->usb_buf[2] = reg;
1181 gspca_dev->usb_buf[3] = val;
1182 gspca_dev->usb_buf[4] = 0;
1183 gspca_dev->usb_buf[5] = 0;
1184 gspca_dev->usb_buf[6] = 0;
1185 gspca_dev->usb_buf[7] = 0x10;
1186 usb_control_msg(gspca_dev->dev,
1187 usb_sndctrlpipe(gspca_dev->dev, 0),
1188 0x08,
1189 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1190 0x08, /* value = i2c */
1191 0,
1192 gspca_dev->usb_buf, 8,
1193 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001194}
1195
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001196/* I2C write 8 bytes */
1197static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001198 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001199{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001200 memcpy(gspca_dev->usb_buf, buffer, 8);
1201 usb_control_msg(gspca_dev->dev,
1202 usb_sndctrlpipe(gspca_dev->dev, 0),
1203 0x08,
1204 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1205 0x08, 0, /* value, index */
1206 gspca_dev->usb_buf, 8,
1207 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -03001208 msleep(2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001209}
1210
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001211/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1212static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001213{
1214 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001215 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001216
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001217 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001218 case SENSOR_ADCM1700:
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001219 case SENSOR_OM6802: /* i2c command = 90 (100 kHz) */
1220 mode[0] = 0x80 | 0x10;
1221 break;
1222 default: /* i2c command = 91 (400 kHz) */
1223 mode[0] = 0x81 | 0x10;
1224 break;
1225 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001226 mode[1] = sd->i2c_addr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001227 mode[2] = reg;
1228 mode[3] = 0;
1229 mode[4] = 0;
1230 mode[5] = 0;
1231 mode[6] = 0;
1232 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001233 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001234 msleep(2);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001235 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001236 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001237 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001238 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001239 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001240}
1241
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001242static void i2c_w_seq(struct gspca_dev *gspca_dev,
1243 const u8 (*data)[8])
1244{
1245 while ((*data)[0] != 0) {
1246 if ((*data)[0] != 0xdd)
1247 i2c_w8(gspca_dev, *data);
1248 else
1249 msleep((*data)[1]);
1250 data++;
1251 }
1252}
1253
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001254static void hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001255{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001256 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001257 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001258 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001259 msleep(10);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001260 i2c_r(gspca_dev, 0, 5); /* read sensor id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001261 if (gspca_dev->usb_buf[0] == 0x02
1262 && gspca_dev->usb_buf[1] == 0x09
1263 && gspca_dev->usb_buf[2] == 0x01
1264 && gspca_dev->usb_buf[3] == 0x00
1265 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001266 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1267 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001268 }
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001269 PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001270 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1271 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001272}
1273
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001274static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001275{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001276 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001277 int i, j;
Jean-Francois Moine92e8c912009-02-02 16:25:38 -03001278 u16 val = 0;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001279 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001280 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001281 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1282 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1283 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1284 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1285 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001286 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001287 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1288 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1289 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1290 {}
1291 },
1292 };
1293
1294 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1295 reg_w1(gspca_dev, 0x17, 0x62);
1296 reg_w1(gspca_dev, 0x01, 0x08);
1297 for (j = 0; j < 3; j++)
1298 i2c_w8(gspca_dev, probe_tb[i][j]);
1299 msleep(2);
1300 reg_r(gspca_dev, 0x0a, 5);
1301 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1302 if (probe_tb[i][3][0] != 0)
1303 i2c_w8(gspca_dev, probe_tb[i][3]);
1304 reg_w1(gspca_dev, 0x01, 0x29);
1305 reg_w1(gspca_dev, 0x17, 0x42);
1306 if (val != 0xffff)
1307 break;
1308 }
1309 switch (val) {
1310 case 0x823a:
1311 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001312 sd->sensor = SENSOR_MT9V111;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001313 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001314 case 0x8243:
1315 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001316 break;
1317 default:
1318 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1319 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001320 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001321}
1322
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001323static void ov7648_probe(struct gspca_dev *gspca_dev)
1324{
1325 struct sd *sd = (struct sd *) gspca_dev;
1326
1327 /* check ov76xx */
1328 reg_w1(gspca_dev, 0x17, 0x62);
1329 reg_w1(gspca_dev, 0x01, 0x08);
1330 sd->i2c_addr = 0x21;
1331 i2c_r(gspca_dev, 0x0a, 2);
1332 if (gspca_dev->usb_buf[3] == 0x76) { /* ov76xx */
1333 PDEBUG(D_PROBE, "Sensor ov%02x%02x",
1334 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1335 return;
1336 }
1337
1338 /* reset */
1339 reg_w1(gspca_dev, 0x01, 0x29);
1340 reg_w1(gspca_dev, 0x17, 0x42);
1341
1342 /* check po1030 */
1343 reg_w1(gspca_dev, 0x17, 0x62);
1344 reg_w1(gspca_dev, 0x01, 0x08);
1345 sd->i2c_addr = 0x6e;
1346 i2c_r(gspca_dev, 0x00, 2);
1347 if (gspca_dev->usb_buf[3] == 0x10 /* po1030 */
1348 && gspca_dev->usb_buf[4] == 0x30) {
1349 PDEBUG(D_PROBE, "Sensor po1030");
1350 sd->sensor = SENSOR_PO1030;
1351 return;
1352 }
1353
1354 PDEBUG(D_PROBE, "Unknown sensor %02x%02x",
1355 gspca_dev->usb_buf[3], gspca_dev->usb_buf[4]);
1356}
1357
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001358static void bridge_init(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001359 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001360{
1361 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001362 const u8 *reg9a;
1363 static const u8 reg9a_def[] =
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001364 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1365 static const u8 reg9a_spec[] =
1366 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001367 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368
Hans de Goede9712a8b2010-01-31 12:54:29 -03001369 /* sensor clock already enabled in sd_init */
1370 /* reg_w1(gspca_dev, 0xf1, 0x00); */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001371 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001372
1373 /* configure gpio */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001374 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
1375 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001376 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001377 switch (sd->sensor) {
1378 case SENSOR_OV7660:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001379 case SENSOR_PO1030:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001380 case SENSOR_SP80708:
1381 reg9a = reg9a_spec;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001382 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001383 default:
1384 reg9a = reg9a_def;
1385 break;
1386 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001387 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001388
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001389 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001390
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001391 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001392
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001393 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001394 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001395 reg_w1(gspca_dev, 0x01, 0x43);
Jean-Francois Moine646775732009-12-20 12:31:28 -03001396 reg_w1(gspca_dev, 0x17, 0x62);
1397 reg_w1(gspca_dev, 0x01, 0x42);
1398 reg_w1(gspca_dev, 0x01, 0x42);
1399 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001400 case SENSOR_MT9V111:
1401 reg_w1(gspca_dev, 0x01, 0x61);
1402 reg_w1(gspca_dev, 0x17, 0x61);
1403 reg_w1(gspca_dev, 0x01, 0x60);
1404 reg_w1(gspca_dev, 0x01, 0x40);
1405 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001406 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001407 msleep(10);
1408 reg_w1(gspca_dev, 0x02, 0x73);
1409 reg_w1(gspca_dev, 0x17, 0x60);
1410 reg_w1(gspca_dev, 0x01, 0x22);
1411 msleep(100);
1412 reg_w1(gspca_dev, 0x01, 0x62);
1413 reg_w1(gspca_dev, 0x17, 0x64);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001414 reg_w1(gspca_dev, 0x17, 0x64);
1415 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001416 msleep(10);
1417 reg_w1(gspca_dev, 0x01, 0x42);
1418 i2c_w8(gspca_dev, om6802_init0[0]);
1419 i2c_w8(gspca_dev, om6802_init0[1]);
1420 msleep(15);
1421 reg_w1(gspca_dev, 0x02, 0x71);
1422 msleep(150);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001423 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001424 case SENSOR_OV7630:
1425 reg_w1(gspca_dev, 0x01, 0x61);
1426 reg_w1(gspca_dev, 0x17, 0xe2);
1427 reg_w1(gspca_dev, 0x01, 0x60);
1428 reg_w1(gspca_dev, 0x01, 0x40);
1429 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001430 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001431 reg_w1(gspca_dev, 0x01, 0x63);
1432 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001433 reg_w1(gspca_dev, 0x01, 0x62);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001434 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001435 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001436 case SENSOR_PO1030:
1437 reg_w1(gspca_dev, 0x01, 0x61);
1438 reg_w1(gspca_dev, 0x17, 0x20);
1439 reg_w1(gspca_dev, 0x01, 0x60);
1440 reg_w1(gspca_dev, 0x01, 0x40);
1441 break;
Jean-Francois Moine91de65a2008-09-03 17:12:18 -03001442 case SENSOR_OV7660:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001443 /* fall thru */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001444 case SENSOR_SP80708:
1445 reg_w1(gspca_dev, 0x01, 0x63);
1446 reg_w1(gspca_dev, 0x17, 0x20);
1447 reg_w1(gspca_dev, 0x01, 0x62);
1448 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine1f78a972009-08-29 07:11:58 -03001449 msleep(100);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001450 reg_w1(gspca_dev, 0x02, 0x62);
1451 break;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001452 default:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001453/* case SENSOR_HV7131R: */
1454/* case SENSOR_MI0360: */
1455/* case SENSOR_MO4000: */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001456 reg_w1(gspca_dev, 0x01, 0x43);
1457 reg_w1(gspca_dev, 0x17, 0x61);
1458 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001459 if (sd->sensor == SENSOR_HV7131R
1460 && sd->bridge == BRIDGE_SN9C102P)
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001461 hv7131r_probe(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001462 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001463 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001464}
1465
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001466/* this function is called at probe time */
1467static int sd_config(struct gspca_dev *gspca_dev,
1468 const struct usb_device_id *id)
1469{
1470 struct sd *sd = (struct sd *) gspca_dev;
1471 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001472
Jean-Francois Moineeac8f5f2010-01-12 07:12:43 -03001473 sd->bridge = id->driver_info >> 16;
1474 sd->sensor = id->driver_info;
1475
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001476 cam = &gspca_dev->cam;
Jean-Francois Moine646775732009-12-20 12:31:28 -03001477 if (sd->sensor == SENSOR_ADCM1700) {
1478 cam->cam_mode = cif_mode;
1479 cam->nmodes = ARRAY_SIZE(cif_mode);
1480 } else {
1481 cam->cam_mode = vga_mode;
1482 cam->nmodes = ARRAY_SIZE(vga_mode);
1483 }
Jean-Francois Moine49cb6b02009-04-25 13:29:01 -03001484 cam->npkt = 24; /* 24 packets per ISOC message */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001485
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001486 sd->brightness = BRIGHTNESS_DEF;
1487 sd->contrast = CONTRAST_DEF;
1488 sd->colors = COLOR_DEF;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001489 sd->blue = BLUE_BALANCE_DEF;
1490 sd->red = RED_BALANCE_DEF;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001491 sd->gamma = GAMMA_DEF;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001492 sd->autogain = AUTOGAIN_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001493 sd->ag_cnt = -1;
Hans de Goedef8009522009-06-18 14:29:20 -03001494 sd->vflip = VFLIP_DEF;
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001495 switch (sd->sensor) {
1496 case SENSOR_OM6802:
1497 sd->sharpness = 0x10;
1498 break;
1499 default:
1500 sd->sharpness = SHARPNESS_DEF;
1501 break;
1502 }
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001503 sd->infrared = INFRARED_DEF;
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001504 sd->freq = FREQ_DEF;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001505 sd->quality = QUALITY_DEF;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001506 sd->jpegqual = 80;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001507
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001508 return 0;
1509}
1510
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001511/* this function is called at probe and resume time */
1512static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001513{
1514 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001515 const u8 *sn9c1xx;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001516 u8 regGpio[] = { 0x29, 0x74 };
1517 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001518
Hans de Goede3647fea2008-07-15 05:36:30 -03001519 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001520 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001521 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001522 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1523 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001524 regF1 = gspca_dev->usb_buf[0];
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001525 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001526 switch (sd->bridge) {
1527 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001528 if (regF1 != 0x11)
1529 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001530 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001531 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001532 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001533 if (regF1 != 0x11)
1534 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001535 if (sd->sensor == SENSOR_MI0360)
1536 mi0360_probe(gspca_dev);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001537 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001538 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001539 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001540 if (regF1 != 0x12)
1541 return -ENODEV;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001542 switch (sd->sensor) {
1543 case SENSOR_MI0360:
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001544 mi0360_probe(gspca_dev);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001545 break;
1546 case SENSOR_OV7648:
1547 ov7648_probe(gspca_dev);
1548 break;
1549 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001550 regGpio[1] = 0x70;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001551 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001552 break;
1553 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001554/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001555/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001556 if (regF1 != 0x12)
1557 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001558 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001559 break;
1560 }
1561
Hans de Goede9712a8b2010-01-31 12:54:29 -03001562 /* Note we do not disable the sensor clock here (power saving mode),
1563 as that also disables the button on the cam. */
1564 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001565
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001566 /* set the i2c address */
1567 sn9c1xx = sn_tb[sd->sensor];
1568 sd->i2c_addr = sn9c1xx[9];
1569
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001570 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1571
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001572 return 0;
1573}
1574
Jean-Francois Moine98819182009-01-19 07:37:33 -03001575static u32 setexposure(struct gspca_dev *gspca_dev,
1576 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001577{
1578 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001579
1580 switch (sd->sensor) {
1581 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001582 u8 Expodoit[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001583 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001584
1585 Expodoit[3] = expo >> 16;
1586 Expodoit[4] = expo >> 8;
1587 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001588 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001589 break;
1590 }
1591 case SENSOR_MI0360: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001592 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001593 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001594 static const u8 doit[] = /* update sensor */
1595 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1596 static const u8 sensorgo[] = /* sensor on */
1597 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001598
1599 if (expo > 0x0635)
1600 expo = 0x0635;
1601 else if (expo < 0x0001)
1602 expo = 0x0001;
1603 expoMi[3] = expo >> 8;
1604 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001605 i2c_w8(gspca_dev, expoMi);
1606 i2c_w8(gspca_dev, doit);
1607 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001608 break;
1609 }
1610 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001611 u8 expoMof[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001612 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001613 u8 expoMo10[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001614 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001615 static const u8 gainMo[] =
1616 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001617
1618 if (expo > 0x1fff)
1619 expo = 0x1fff;
1620 else if (expo < 0x0001)
1621 expo = 0x0001;
1622 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001623 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001624 expoMo10[3] = ((expo & 0x1c00) >> 10)
1625 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001626 i2c_w8(gspca_dev, expoMo10);
1627 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001628 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001629 ((expoMo10[3] & 0x07) << 10)
1630 | (expoMof[3] << 2)
1631 | ((expoMo10[3] & 0x30) >> 4));
1632 break;
1633 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001634 case SENSOR_MT9V111: {
1635 u8 expo_c1[] =
1636 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1637
1638 if (expo > 0x0280)
1639 expo = 0x0280;
1640 else if (expo < 0x0040)
1641 expo = 0x0040;
1642 expo_c1[3] = expo >> 8;
1643 expo_c1[4] = expo;
1644 i2c_w8(gspca_dev, expo_c1);
1645 break;
1646 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001647 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001648 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001649 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001650 /* preset AGC - works when AutoExpo = off */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001651
1652 if (expo > 0x03ff)
1653 expo = 0x03ff;
1654 if (expo < 0x0001)
1655 expo = 0x0001;
1656 gainOm[3] = expo >> 2;
1657 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001658 reg_w1(gspca_dev, 0x96, expo >> 5);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001659 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001660 break;
1661 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001662 }
1663 return expo;
1664}
1665
1666static void setbrightness(struct gspca_dev *gspca_dev)
1667{
1668 struct sd *sd = (struct sd *) gspca_dev;
1669 unsigned int expo;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001670 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001671
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001672 k2 = ((int) sd->brightness - 0x8000) >> 10;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001673 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001674 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001675 if (k2 > 0x1f)
1676 k2 = 0; /* only positive Y offset */
1677 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001678 case SENSOR_HV7131R:
1679 expo = sd->brightness << 4;
1680 if (expo > 0x002dc6c0)
1681 expo = 0x002dc6c0;
1682 else if (expo < 0x02a0)
1683 expo = 0x02a0;
1684 sd->exposure = setexposure(gspca_dev, expo);
1685 break;
1686 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001687 case SENSOR_MO4000:
1688 expo = sd->brightness >> 4;
1689 sd->exposure = setexposure(gspca_dev, expo);
1690 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001691 case SENSOR_MT9V111:
1692 expo = sd->brightness >> 8;
1693 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001694 return; /* don't set the Y offset */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001695 case SENSOR_OM6802:
1696 expo = sd->brightness >> 6;
1697 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moineb1b056a2008-11-25 04:47:09 -03001698 k2 = sd->brightness >> 11;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001699 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001700 }
1701
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001702 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001703}
1704
1705static void setcontrast(struct gspca_dev *gspca_dev)
1706{
1707 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001708 u8 k2;
1709 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001710
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001711 k2 = sd->contrast * 0x30 / (CONTRAST_MAX + 1) + 0x10; /* 10..40 */
1712 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001713 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001714 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001715 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03001716 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03001717 contrast[5] = 0;
1718 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001719}
1720
1721static void setcolors(struct gspca_dev *gspca_dev)
1722{
1723 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001724 int i, v;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001725 u8 reg8a[12]; /* U & V gains */
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001726 static const s16 uv[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001727 -24, -38, 64, /* UR UG UB */
1728 62, -51, -9 /* VR VG VB */
1729 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001730
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001731 for (i = 0; i < 6; i++) {
1732 v = uv[i] * sd->colors / COLOR_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001733 reg8a[i * 2] = v;
1734 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03001735 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03001736 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001737}
1738
1739static void setredblue(struct gspca_dev *gspca_dev)
1740{
1741 struct sd *sd = (struct sd *) gspca_dev;
1742
1743 reg_w1(gspca_dev, 0x05, sd->red);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03001744/* reg_w1(gspca_dev, 0x07, 32); */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03001745 reg_w1(gspca_dev, 0x06, sd->blue);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001746}
1747
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001748static void setgamma(struct gspca_dev *gspca_dev)
1749{
1750 struct sd *sd = (struct sd *) gspca_dev;
1751 int i;
1752 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001753 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001754 static const u8 delta[17] = {
1755 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
1756 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
1757 };
1758
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001759 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001760 case SENSOR_ADCM1700:
1761 gamma_base = gamma_spec_0;
1762 break;
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001763 case SENSOR_HV7131R:
1764 case SENSOR_MT9V111:
1765 gamma_base = gamma_spec_1;
1766 break;
1767 case SENSOR_SP80708:
1768 gamma_base = gamma_spec_2;
1769 break;
1770 default:
1771 gamma_base = gamma_def;
1772 break;
1773 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001774
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001775 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03001776 gamma[i] = gamma_base[i]
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03001777 + delta[i] * (sd->gamma - GAMMA_DEF) / 32;
1778 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
1779}
1780
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001781static void setautogain(struct gspca_dev *gspca_dev)
1782{
1783 struct sd *sd = (struct sd *) gspca_dev;
1784
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001785 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1786 return;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001787 switch (sd->sensor) {
1788 case SENSOR_OV7630:
1789 case SENSOR_OV7648: {
1790 u8 comb;
1791
1792 if (sd->sensor == SENSOR_OV7630)
1793 comb = 0xc0;
1794 else
1795 comb = 0xa0;
1796 if (sd->autogain)
Hans de Goede1fec747c2009-06-18 06:05:07 -03001797 comb |= 0x03;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001798 i2c_w1(&sd->gspca_dev, 0x13, comb);
1799 return;
1800 }
1801 }
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03001802 if (sd->autogain)
1803 sd->ag_cnt = AG_CNT_START;
1804 else
1805 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001806}
1807
Jean-François Moinef6b22e52010-02-18 04:12:06 -03001808/* hv7131r/ov7630/ov7648 only */
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001809static void setvflip(struct sd *sd)
1810{
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001811 u8 comn;
1812
Jean-Francois Moine0939e262009-11-02 09:58:49 -03001813 if (sd->gspca_dev.ctrl_dis & (1 << VFLIP_IDX))
1814 return;
Jean-François Moinef6b22e52010-02-18 04:12:06 -03001815 switch (sd->sensor) {
1816 case SENSOR_HV7131R:
1817 comn = 0x18; /* clkdiv = 1, ablcen = 1 */
1818 if (sd->vflip)
1819 comn |= 0x01;
1820 i2c_w1(&sd->gspca_dev, 0x01, comn); /* sctra */
1821 break;
1822 case SENSOR_OV7630:
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001823 comn = 0x02;
Hans de Goedef8009522009-06-18 14:29:20 -03001824 if (!sd->vflip)
1825 comn |= 0x80;
Jean-François Moinef6b22e52010-02-18 04:12:06 -03001826 i2c_w1(&sd->gspca_dev, 0x75, comn);
1827 break;
1828 default:
1829/* case SENSOR_OV7648: */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001830 comn = 0x06;
Hans de Goedef8009522009-06-18 14:29:20 -03001831 if (sd->vflip)
1832 comn |= 0x80;
Jean-François Moinef6b22e52010-02-18 04:12:06 -03001833 i2c_w1(&sd->gspca_dev, 0x75, comn);
1834 break;
Hans de Goedef8009522009-06-18 14:29:20 -03001835 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -03001836}
1837
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001838static void setsharpness(struct sd *sd)
1839{
1840 reg_w1(&sd->gspca_dev, 0x99, sd->sharpness);
1841}
1842
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001843static void setinfrared(struct sd *sd)
1844{
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001845 if (sd->gspca_dev.ctrl_dis & (1 << INFRARED_IDX))
1846 return;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03001847/*fixme: different sequence for StarCam Clip and StarCam 370i */
1848/* Clip */
1849 i2c_w1(&sd->gspca_dev, 0x02, /* gpio */
1850 sd->infrared ? 0x66 : 0x64);
1851}
1852
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001853static void setfreq(struct gspca_dev *gspca_dev)
1854{
1855 struct sd *sd = (struct sd *) gspca_dev;
1856
Jean-Francois Moine27954932009-07-08 05:21:50 -03001857 if (gspca_dev->ctrl_dis & (1 << FREQ_IDX))
1858 return;
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001859 if (sd->sensor == SENSOR_OV7660) {
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001860 u8 com8;
1861
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001862 com8 = 0xdf; /* auto gain/wb/expo */
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001863 switch (sd->freq) {
1864 case 0: /* Banding filter disabled */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001865 i2c_w1(gspca_dev, 0x13, com8 | 0x20);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001866 break;
1867 case 1: /* 50 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001868 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001869 i2c_w1(gspca_dev, 0x3b, 0x0a);
1870 break;
1871 case 2: /* 60 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001872 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001873 i2c_w1(gspca_dev, 0x3b, 0x02);
1874 break;
1875 }
1876 } else {
1877 u8 reg2a = 0, reg2b = 0, reg2d = 0;
1878
1879 /* Get reg2a / reg2d base values */
1880 switch (sd->sensor) {
1881 case SENSOR_OV7630:
1882 reg2a = 0x08;
1883 reg2d = 0x01;
1884 break;
1885 case SENSOR_OV7648:
1886 reg2a = 0x11;
1887 reg2d = 0x81;
1888 break;
1889 }
1890
1891 switch (sd->freq) {
1892 case 0: /* Banding filter disabled */
1893 break;
1894 case 1: /* 50 hz (filter on and framerate adj) */
1895 reg2a |= 0x80;
1896 reg2b = 0xac;
1897 reg2d |= 0x04;
1898 break;
1899 case 2: /* 60 hz (filter on, no framerate adj) */
1900 reg2a |= 0x80;
1901 reg2d |= 0x04;
1902 break;
1903 }
1904 i2c_w1(gspca_dev, 0x2a, reg2a);
1905 i2c_w1(gspca_dev, 0x2b, reg2b);
1906 i2c_w1(gspca_dev, 0x2d, reg2d);
1907 }
1908}
1909
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001910static void setjpegqual(struct gspca_dev *gspca_dev)
1911{
1912 struct sd *sd = (struct sd *) gspca_dev;
1913 int i, sc;
1914
1915 if (sd->jpegqual < 50)
1916 sc = 5000 / sd->jpegqual;
1917 else
1918 sc = 200 - sd->jpegqual * 2;
1919#if USB_BUF_SZ < 64
1920#error "No room enough in usb_buf for quantization table"
1921#endif
1922 for (i = 0; i < 64; i++)
1923 gspca_dev->usb_buf[i] =
1924 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
1925 usb_control_msg(gspca_dev->dev,
1926 usb_sndctrlpipe(gspca_dev->dev, 0),
1927 0x08,
1928 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1929 0x0100, 0,
1930 gspca_dev->usb_buf, 64,
1931 500);
1932 for (i = 0; i < 64; i++)
1933 gspca_dev->usb_buf[i] =
1934 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
1935 usb_control_msg(gspca_dev->dev,
1936 usb_sndctrlpipe(gspca_dev->dev, 0),
1937 0x08,
1938 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1939 0x0140, 0,
1940 gspca_dev->usb_buf, 64,
1941 500);
1942
1943 sd->reg18 ^= 0x40;
1944 reg_w1(gspca_dev, 0x18, sd->reg18);
1945}
1946
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001947/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03001948static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001949{
1950 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001951 int i;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001952 u8 reg1, reg2, reg17;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001953 const u8 *sn9c1xx;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001954 const u8 (*init)[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001955 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001956 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1957 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moine646775732009-12-20 12:31:28 -03001958 static const u8 CA_adcm1700[] =
1959 { 0x14, 0xec, 0x0a, 0xf6 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001960 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1961 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001962 { 0x32, 0xdd, 0x32, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001963
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001964 /* create the JPEG header */
1965 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
Julia Lawall3eb02372009-07-19 07:09:32 -03001966 if (!sd->jpeg_hdr)
1967 return -ENOMEM;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001968 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
1969 0x21); /* JPEG 422 */
1970 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1971
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001972 /* initialize the bridge */
1973 sn9c1xx = sn_tb[sd->sensor];
1974 bridge_init(gspca_dev, sn9c1xx);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001975
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001976 /* initialize the sensor */
1977 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
1978
1979 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001980 case SENSOR_ADCM1700:
1981 reg2 = 0x60;
1982 break;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001983 case SENSOR_OM6802:
1984 reg2 = 0x71;
1985 break;
1986 case SENSOR_SP80708:
1987 reg2 = 0x62;
1988 break;
1989 default:
1990 reg2 = 0x40;
1991 break;
1992 }
1993 reg_w1(gspca_dev, 0x02, reg2);
1994 reg_w1(gspca_dev, 0x02, reg2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001995
Jean-Francois Moine60017612008-07-18 08:46:19 -03001996 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1997 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1998 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1999 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2000 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine646775732009-12-20 12:31:28 -03002001 if (sd->sensor == SENSOR_ADCM1700) {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002002 reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
2003 reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002004 } else {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002005 reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
2006 reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002007 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03002008 reg_w1(gspca_dev, 0xc6, 0x00);
2009 reg_w1(gspca_dev, 0xc7, 0x00);
Jean-Francois Moine646775732009-12-20 12:31:28 -03002010 if (sd->sensor == SENSOR_ADCM1700) {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002011 reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
2012 reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002013 } else {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002014 reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
2015 reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002016 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03002017 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002018 switch (sd->sensor) {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002019 case SENSOR_MT9V111:
2020 reg17 = 0xe0;
2021 break;
Jean-Francois Moine646775732009-12-20 12:31:28 -03002022 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002023 case SENSOR_OV7630:
2024 reg17 = 0xe2;
2025 break;
2026 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002027 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002028 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002029 case SENSOR_OV7660:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03002030 reg17 = 0xa0;
2031 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002032 case SENSOR_PO1030:
2033 reg17 = 0xa0;
2034 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002035 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002036 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002037 break;
2038 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002039 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002040
2041 reg_w1(gspca_dev, 0x05, 0x00); /* red */
2042 reg_w1(gspca_dev, 0x07, 0x00); /* green */
2043 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002044 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002045
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002046 setgamma(gspca_dev);
2047
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002048/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03002049 for (i = 0; i < 8; i++)
2050 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002051 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002052 case SENSOR_ADCM1700:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03002053 case SENSOR_OV7660:
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002054 case SENSOR_SP80708:
2055 reg_w1(gspca_dev, 0x9a, 0x05);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002056 break;
2057 case SENSOR_MT9V111:
2058 reg_w1(gspca_dev, 0x9a, 0x07);
2059 break;
2060 case SENSOR_OV7648:
2061 reg_w1(gspca_dev, 0x9a, 0x0a);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002062 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002063 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03002064 reg_w1(gspca_dev, 0x9a, 0x08);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002065 break;
2066 }
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002067 setsharpness(sd);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002068
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002069 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002070 reg_w1(gspca_dev, 0x05, 0x20); /* red */
2071 reg_w1(gspca_dev, 0x07, 0x20); /* green */
2072 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
Jean-Francois Moine23a98272009-11-02 09:10:25 -03002073
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002074 init = NULL;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002075 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03002076 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002077 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002078 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002079 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
2080 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002081 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002082 case SENSOR_ADCM1700:
2083 init = adcm1700_sensor_param1;
2084 reg1 = 0x46;
2085 reg17 = 0xe2;
2086 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002087 case SENSOR_MO4000:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002088 if (mode) {
2089/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
2090 reg1 = 0x06; /* clk 24Mz */
2091 } else {
2092 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002093/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002094 }
2095 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002096 case SENSOR_MT9V111:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002097 init = mt9v111_sensor_param1;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002098 if (mode) {
2099 reg1 = 0x04; /* 320 clk 48Mhz */
2100 } else {
2101/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -03002102 reg17 = 0xc2;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002103 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03002104 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002105 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002106 init = om6802_sensor_param1;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002107 reg17 = 0x64; /* 640 MCKSIZE */
2108 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002109 case SENSOR_OV7630:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002110 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03002111 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002112 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002113 case SENSOR_OV7648:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002114 init = ov7648_sensor_param1;
Jean-Francois Moine62703302008-11-11 08:42:56 -03002115 reg17 = 0x21;
2116/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002117 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002118 case SENSOR_OV7660:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002119 init = ov7660_sensor_param1;
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03002120 if (sd->bridge == BRIDGE_SN9C120) {
2121 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002122 reg17 = 0xa2;
2123 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002124 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03002125 } else {
2126 reg17 = 0x22;
2127 reg1 = 0x06; /* 24 Mhz, video trf eneble
2128 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002129 }
2130 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002131 case SENSOR_PO1030:
2132 init = po1030_sensor_param1;
2133 reg17 = 0xa2;
2134 reg1 = 0x44;
2135 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002136 default:
2137/* case SENSOR_SP80708: */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002138 init = sp80708_sensor_param1;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002139 if (mode) {
2140/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002141 } else {
2142 reg1 = 0x46; /* 640 clk 48Mz */
2143 reg17 = 0xa2;
2144 }
2145 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002146 }
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002147
2148 /* more sensor initialization - param1 */
2149 if (init != NULL) {
2150 i2c_w_seq(gspca_dev, init);
2151/* init = NULL; */
2152 }
2153
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002154 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-Francois Moine646775732009-12-20 12:31:28 -03002155 if (sd->sensor == SENSOR_ADCM1700)
2156 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
2157 else
2158 reg_w(gspca_dev, 0xca, CA, 4);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002159 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002160 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002161 case SENSOR_OV7630:
2162 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002163 case SENSOR_OV7660:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002164 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002165 break;
2166 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002167 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002168 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2169 break;
2170 }
2171
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002172
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002173 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002174 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2175 reg_w1(gspca_dev, 0x18, sd->reg18);
2176 setjpegqual(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002177
Jean-Francois Moine60017612008-07-18 08:46:19 -03002178 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002179 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002180
Jean-François Moine1e5eb112010-02-18 14:56:33 -03002181 setvflip(sd);
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002182 setbrightness(gspca_dev);
2183 setcontrast(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002184 setautogain(gspca_dev);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002185 setfreq(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03002186 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002187}
2188
2189static void sd_stopN(struct gspca_dev *gspca_dev)
2190{
2191 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002192 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002193 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002194 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002195 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002196 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03002197 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002198 u8 data;
2199 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002200
2201 data = 0x0b;
2202 switch (sd->sensor) {
2203 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002204 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002205 data = 0x2b;
2206 break;
2207 case SENSOR_MI0360:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002208 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002209 data = 0x29;
2210 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002211 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002212 i2c_w8(gspca_dev, stopov7648);
2213 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002214 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002215 case SENSOR_OV7630:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002216 case SENSOR_PO1030:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002217 data = 0x29;
2218 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002219 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002220 sn9c1xx = sn_tb[sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03002221 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2222 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2223 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2224 reg_w1(gspca_dev, 0x01, data);
Hans de Goede9712a8b2010-01-31 12:54:29 -03002225 /* Don't disable sensor clock as that disables the button on the cam */
2226 /* reg_w1(gspca_dev, 0xf1, 0x01); */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002227}
2228
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002229static void sd_stop0(struct gspca_dev *gspca_dev)
2230{
2231 struct sd *sd = (struct sd *) gspca_dev;
2232
2233 kfree(sd->jpeg_hdr);
2234}
2235
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002236static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002237{
2238 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002239 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002240 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002241 u8 luma_mean = 130;
2242 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002243
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002244 /* Thanks S., without your advice, autobright should not work :) */
2245 if (sd->ag_cnt < 0)
2246 return;
2247 if (--sd->ag_cnt >= 0)
2248 return;
2249 sd->ag_cnt = AG_CNT_START;
2250
2251 delta = atomic_read(&sd->avg_lum);
2252 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002253 if (delta < luma_mean - luma_delta ||
2254 delta > luma_mean + luma_delta) {
2255 switch (sd->sensor) {
2256 case SENSOR_HV7131R:
2257 expotimes = sd->exposure >> 8;
2258 expotimes += (luma_mean - delta) >> 4;
2259 if (expotimes < 0)
2260 expotimes = 0;
2261 sd->exposure = setexposure(gspca_dev,
2262 (unsigned int) (expotimes << 8));
2263 break;
Amauri Magagna46b4f2a2009-10-17 07:21:29 -03002264 case SENSOR_OM6802:
2265 expotimes = sd->exposure;
2266 expotimes += (luma_mean - delta) >> 2;
2267 if (expotimes < 0)
2268 expotimes = 0;
2269 sd->exposure = setexposure(gspca_dev,
2270 (unsigned int) expotimes);
2271 setredblue(gspca_dev);
2272 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002273 default:
2274/* case SENSOR_MO4000: */
2275/* case SENSOR_MI0360: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002276/* case SENSOR_MT9V111: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002277 expotimes = sd->exposure;
2278 expotimes += (luma_mean - delta) >> 6;
2279 if (expotimes < 0)
2280 expotimes = 0;
2281 sd->exposure = setexposure(gspca_dev,
2282 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002283 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002284 break;
2285 }
2286 }
2287}
2288
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002289/* scan the URB packets */
2290/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002291static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03002292 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002293 int len) /* iso packet length */
2294{
2295 struct sd *sd = (struct sd *) gspca_dev;
2296 int sof, avg_lum;
2297
2298 sof = len - 64;
2299 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
2300
2301 /* end of frame */
2302 gspca_frame_add(gspca_dev, LAST_PACKET,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03002303 data, sof + 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002304 if (sd->ag_cnt < 0)
2305 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002306/* w1 w2 w3 */
2307/* w4 w5 w6 */
2308/* w7 w8 */
2309/* w4 */
2310 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
2311/* w6 */
2312 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
2313/* w2 */
2314 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
2315/* w8 */
2316 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
2317/* w5 */
2318 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2319 avg_lum >>= 4;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002320 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002321 return;
2322 }
2323 if (gspca_dev->last_packet_type == LAST_PACKET) {
2324
2325 /* put the JPEG 422 header */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03002326 gspca_frame_add(gspca_dev, FIRST_PACKET,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002327 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002328 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -03002329 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002330}
2331
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002332static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
2333{
2334 struct sd *sd = (struct sd *) gspca_dev;
2335
2336 sd->brightness = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002337 if (gspca_dev->streaming)
2338 setbrightness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002339 return 0;
2340}
2341
2342static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
2343{
2344 struct sd *sd = (struct sd *) gspca_dev;
2345
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002346 *val = sd->brightness;
2347 return 0;
2348}
2349
2350static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
2351{
2352 struct sd *sd = (struct sd *) gspca_dev;
2353
2354 sd->contrast = val;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002355 if (gspca_dev->streaming)
2356 setcontrast(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002357 return 0;
2358}
2359
2360static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
2361{
2362 struct sd *sd = (struct sd *) gspca_dev;
2363
2364 *val = sd->contrast;
2365 return 0;
2366}
2367
2368static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
2369{
2370 struct sd *sd = (struct sd *) gspca_dev;
2371
2372 sd->colors = val;
2373 if (gspca_dev->streaming)
2374 setcolors(gspca_dev);
2375 return 0;
2376}
2377
2378static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
2379{
2380 struct sd *sd = (struct sd *) gspca_dev;
2381
2382 *val = sd->colors;
2383 return 0;
2384}
2385
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002386static int sd_setblue_balance(struct gspca_dev *gspca_dev, __s32 val)
2387{
2388 struct sd *sd = (struct sd *) gspca_dev;
2389
2390 sd->blue = val;
2391 if (gspca_dev->streaming)
2392 setredblue(gspca_dev);
2393 return 0;
2394}
2395
2396static int sd_getblue_balance(struct gspca_dev *gspca_dev, __s32 *val)
2397{
2398 struct sd *sd = (struct sd *) gspca_dev;
2399
2400 *val = sd->blue;
2401 return 0;
2402}
2403
2404static int sd_setred_balance(struct gspca_dev *gspca_dev, __s32 val)
2405{
2406 struct sd *sd = (struct sd *) gspca_dev;
2407
2408 sd->red = val;
2409 if (gspca_dev->streaming)
2410 setredblue(gspca_dev);
2411 return 0;
2412}
2413
2414static int sd_getred_balance(struct gspca_dev *gspca_dev, __s32 *val)
2415{
2416 struct sd *sd = (struct sd *) gspca_dev;
2417
2418 *val = sd->red;
2419 return 0;
2420}
2421
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002422static int sd_setgamma(struct gspca_dev *gspca_dev, __s32 val)
2423{
2424 struct sd *sd = (struct sd *) gspca_dev;
2425
2426 sd->gamma = val;
2427 if (gspca_dev->streaming)
2428 setgamma(gspca_dev);
2429 return 0;
2430}
2431
2432static int sd_getgamma(struct gspca_dev *gspca_dev, __s32 *val)
2433{
2434 struct sd *sd = (struct sd *) gspca_dev;
2435
2436 *val = sd->gamma;
2437 return 0;
2438}
2439
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002440static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
2441{
2442 struct sd *sd = (struct sd *) gspca_dev;
2443
2444 sd->autogain = val;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002445 if (gspca_dev->streaming)
2446 setautogain(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002447 return 0;
2448}
2449
2450static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
2451{
2452 struct sd *sd = (struct sd *) gspca_dev;
2453
2454 *val = sd->autogain;
2455 return 0;
2456}
2457
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002458static int sd_setsharpness(struct gspca_dev *gspca_dev, __s32 val)
2459{
2460 struct sd *sd = (struct sd *) gspca_dev;
2461
2462 sd->sharpness = val;
2463 if (gspca_dev->streaming)
2464 setsharpness(sd);
2465 return 0;
2466}
2467
2468static int sd_getsharpness(struct gspca_dev *gspca_dev, __s32 *val)
2469{
2470 struct sd *sd = (struct sd *) gspca_dev;
2471
2472 *val = sd->sharpness;
2473 return 0;
2474}
2475
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002476static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val)
2477{
2478 struct sd *sd = (struct sd *) gspca_dev;
2479
2480 sd->vflip = val;
Jean-Francois Moine79a90982008-10-05 04:21:24 -03002481 if (gspca_dev->streaming)
2482 setvflip(sd);
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002483 return 0;
2484}
2485
2486static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val)
2487{
2488 struct sd *sd = (struct sd *) gspca_dev;
2489
2490 *val = sd->vflip;
2491 return 0;
2492}
2493
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002494static int sd_setinfrared(struct gspca_dev *gspca_dev, __s32 val)
2495{
2496 struct sd *sd = (struct sd *) gspca_dev;
2497
2498 sd->infrared = val;
2499 if (gspca_dev->streaming)
2500 setinfrared(sd);
2501 return 0;
2502}
2503
2504static int sd_getinfrared(struct gspca_dev *gspca_dev, __s32 *val)
2505{
2506 struct sd *sd = (struct sd *) gspca_dev;
2507
2508 *val = sd->infrared;
2509 return 0;
2510}
2511
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002512static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
2513{
2514 struct sd *sd = (struct sd *) gspca_dev;
2515
2516 sd->freq = val;
2517 if (gspca_dev->streaming)
2518 setfreq(gspca_dev);
2519 return 0;
2520}
2521
2522static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
2523{
2524 struct sd *sd = (struct sd *) gspca_dev;
2525
2526 *val = sd->freq;
2527 return 0;
2528}
2529
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002530static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2531 struct v4l2_jpegcompression *jcomp)
2532{
2533 struct sd *sd = (struct sd *) gspca_dev;
2534
2535 if (jcomp->quality < QUALITY_MIN)
2536 sd->quality = QUALITY_MIN;
2537 else if (jcomp->quality > QUALITY_MAX)
2538 sd->quality = QUALITY_MAX;
2539 else
2540 sd->quality = jcomp->quality;
2541 if (gspca_dev->streaming)
2542 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2543 return 0;
2544}
2545
2546static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2547 struct v4l2_jpegcompression *jcomp)
2548{
2549 struct sd *sd = (struct sd *) gspca_dev;
2550
2551 memset(jcomp, 0, sizeof *jcomp);
2552 jcomp->quality = sd->quality;
2553 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2554 | V4L2_JPEG_MARKER_DQT;
2555 return 0;
2556}
2557
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002558static int sd_querymenu(struct gspca_dev *gspca_dev,
2559 struct v4l2_querymenu *menu)
2560{
2561 switch (menu->id) {
2562 case V4L2_CID_POWER_LINE_FREQUENCY:
2563 switch (menu->index) {
2564 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2565 strcpy((char *) menu->name, "NoFliker");
2566 return 0;
2567 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2568 strcpy((char *) menu->name, "50 Hz");
2569 return 0;
2570 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2571 strcpy((char *) menu->name, "60 Hz");
2572 return 0;
2573 }
2574 break;
2575 }
2576 return -EINVAL;
2577}
2578
Hans de Goede9712a8b2010-01-31 12:54:29 -03002579#ifdef CONFIG_INPUT
2580static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2581 u8 *data, /* interrupt packet data */
2582 int len) /* interrupt packet length */
2583{
2584 int ret = -EINVAL;
2585
2586 if (len == 1 && data[0] == 1) {
2587 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2588 input_sync(gspca_dev->input_dev);
2589 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2590 input_sync(gspca_dev->input_dev);
2591 ret = 0;
2592 }
2593
2594 return ret;
2595}
2596#endif
2597
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002598/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002599static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002600 .name = MODULE_NAME,
2601 .ctrls = sd_ctrls,
2602 .nctrls = ARRAY_SIZE(sd_ctrls),
2603 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002604 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002605 .start = sd_start,
2606 .stopN = sd_stopN,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002607 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002608 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002609 .dq_callback = do_autogain,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002610 .get_jcomp = sd_get_jcomp,
2611 .set_jcomp = sd_set_jcomp,
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002612 .querymenu = sd_querymenu,
Hans de Goede9712a8b2010-01-31 12:54:29 -03002613#ifdef CONFIG_INPUT
2614 .int_pkt_scan = sd_int_pkt_scan,
2615#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002616};
2617
2618/* -- module initialisation -- */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002619#define BS(bridge, sensor) \
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002620 .driver_info = (BRIDGE_ ## bridge << 16) \
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002621 | SENSOR_ ## sensor
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002622static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002623#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002624 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2625 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002626#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002627 {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
2628 {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
2629 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2630 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2631 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2632 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2633 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2634/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2635 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2636/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2637/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2638 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2639/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2640 {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
2641/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2642/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2643/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
2644 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2645/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
2646/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
2647 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002648#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002649 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
2650 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002651#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002652 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
2653/* {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, P1030xC)}, */
2654/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
2655 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
2656 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
2657 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
2658 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
2659/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
2660/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
2661/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2662 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002663/*bw600.inf:*/
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002664 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002665 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2666 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2667/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
Hans de Goede222a07f2008-09-03 17:12:20 -03002668#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002669 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002670#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002671/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
2672 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
2673 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002674#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002675 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
Jean-Francois Moine8d977702009-02-19 15:34:48 -03002676#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002677 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2678 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
2679/* {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, *sn9c120b*/
2680 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2681 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
Jean-Francois Moine646775732009-12-20 12:31:28 -03002682 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002683 {}
2684};
2685MODULE_DEVICE_TABLE(usb, device_table);
2686
2687/* -- device connect -- */
2688static int sd_probe(struct usb_interface *intf,
2689 const struct usb_device_id *id)
2690{
2691 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2692 THIS_MODULE);
2693}
2694
2695static struct usb_driver sd_driver = {
2696 .name = MODULE_NAME,
2697 .id_table = device_table,
2698 .probe = sd_probe,
2699 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03002700#ifdef CONFIG_PM
2701 .suspend = gspca_suspend,
2702 .resume = gspca_resume,
2703#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002704};
2705
2706/* -- module insert / remove -- */
2707static int __init sd_mod_init(void)
2708{
Alexey Klimovf69e9522009-01-01 13:02:07 -03002709 int ret;
2710 ret = usb_register(&sd_driver);
2711 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03002712 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03002713 info("registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002714 return 0;
2715}
2716static void __exit sd_mod_exit(void)
2717{
2718 usb_deregister(&sd_driver);
2719 info("deregistered");
2720}
2721
2722module_init(sd_mod_init);
2723module_exit(sd_mod_exit);