blob: da64947fc08f594593c478f15ea04f73d79602b1 [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-François Moine27c6f9e2010-04-02 06:59:13 -03004 * Copyright (C) 2009-2010 Jean-François Moine <http://moinejf.free.fr>
Jean-Francois Moine5b34e3e2009-11-02 10:00:48 -03005 * 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>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030025#include "gspca.h"
26#include "jpeg.h"
27
Jean-Francois Moine0cae8962008-10-17 07:48:24 -030028#define V4L2_CID_INFRARED (V4L2_CID_PRIVATE_BASE + 0)
29
Jean-François Moine27c6f9e2010-04-02 06:59:13 -030030MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030031MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
32MODULE_LICENSE("GPL");
33
Jean-François Moine72b667e2010-10-02 04:35:25 -030034/* controls */
35enum e_ctrl {
36 BRIGHTNESS,
37 CONTRAST,
38 COLORS,
39 BLUE,
40 RED,
41 GAMMA,
42 AUTOGAIN,
43 VFLIP,
44 SHARPNESS,
45 INFRARED,
46 FREQ,
47 NCTRLS /* number of controls */
48};
49
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030050/* specific webcam descriptor */
51struct sd {
52 struct gspca_dev gspca_dev; /* !! must be the first item */
53
Jean-François Moine72b667e2010-10-02 04:35:25 -030054 struct gspca_ctrl ctrls[NCTRLS];
55
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030056 atomic_t avg_lum;
Jean-Francois Moine98819182009-01-19 07:37:33 -030057 u32 exposure;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030058
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030059 u8 quality; /* image quality */
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030060#define QUALITY_MIN 60
61#define QUALITY_MAX 95
62#define QUALITY_DEF 80
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030063 u8 jpegqual; /* webcam quality */
64
65 u8 reg18;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030066
Jean-Francois Moine98819182009-01-19 07:37:33 -030067 s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030068#define AG_CNT_START 13
69
Jean-Francois Moine98819182009-01-19 07:37:33 -030070 u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030071#define BRIDGE_SN9C102P 0
72#define BRIDGE_SN9C105 1
73#define BRIDGE_SN9C110 2
74#define BRIDGE_SN9C120 3
Jean-Francois Moine98819182009-01-19 07:37:33 -030075 u8 sensor; /* Type of image sensor chip */
Jean-François Moine11ce8842010-07-26 06:39:40 -030076 u8 i2c_addr;
77
78 u8 jpeg_hdr[JPEG_HDR_SZ];
79};
80enum sensors {
Jean-François Moine9c33afc2010-03-17 15:25:32 -030081 SENSOR_ADCM1700,
Jean-François Moinead98c0f2010-03-18 05:15:30 -030082 SENSOR_GC0307,
Jean-François Moine9c33afc2010-03-17 15:25:32 -030083 SENSOR_HV7131R,
84 SENSOR_MI0360,
Jean-François Moinea067db82010-10-01 07:51:24 -030085 SENSOR_MI0360B,
Jean-François Moine9c33afc2010-03-17 15:25:32 -030086 SENSOR_MO4000,
87 SENSOR_MT9V111,
88 SENSOR_OM6802,
89 SENSOR_OV7630,
90 SENSOR_OV7648,
91 SENSOR_OV7660,
92 SENSOR_PO1030,
Jean-François Moinead98c0f2010-03-18 05:15:30 -030093 SENSOR_PO2030N,
Jean-François Moine03ed2a12010-04-25 14:45:43 -030094 SENSOR_SOI768,
Jean-François Moine9c33afc2010-03-17 15:25:32 -030095 SENSOR_SP80708,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030096};
97
98/* V4L2 controls supported by the driver */
Jean-François Moine72b667e2010-10-02 04:35:25 -030099static void setbrightness(struct gspca_dev *gspca_dev);
100static void setcontrast(struct gspca_dev *gspca_dev);
101static void setcolors(struct gspca_dev *gspca_dev);
102static void setredblue(struct gspca_dev *gspca_dev);
103static void setgamma(struct gspca_dev *gspca_dev);
104static void setautogain(struct gspca_dev *gspca_dev);
105static void setvflip(struct gspca_dev *gspca_dev);
106static void setsharpness(struct gspca_dev *gspca_dev);
107static void setinfrared(struct gspca_dev *gspca_dev);
108static void setfreq(struct gspca_dev *gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300109
Jean-François Moine72b667e2010-10-02 04:35:25 -0300110static const struct ctrl sd_ctrls[NCTRLS] = {
111[BRIGHTNESS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300112 {
113 .id = V4L2_CID_BRIGHTNESS,
114 .type = V4L2_CTRL_TYPE_INTEGER,
115 .name = "Brightness",
116 .minimum = 0,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300117 .maximum = 0xff,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300119 .default_value = 0x80,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300121 .set_control = setbrightness
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300122 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300123[CONTRAST] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300124 {
125 .id = V4L2_CID_CONTRAST,
126 .type = V4L2_CTRL_TYPE_INTEGER,
127 .name = "Contrast",
128 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300129#define CONTRAST_MAX 127
130 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300131 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300132 .default_value = 63,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300133 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300134 .set_control = setcontrast
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300135 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300136[COLORS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300137 {
138 .id = V4L2_CID_SATURATION,
139 .type = V4L2_CTRL_TYPE_INTEGER,
Hans de Goede3fb4a572009-06-18 14:31:36 -0300140 .name = "Saturation",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300141 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300142 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300143 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300144#define COLORS_DEF 25
145 .default_value = COLORS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300146 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300147 .set_control = setcolors
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300148 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300149[BLUE] = {
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300150 {
151 .id = V4L2_CID_BLUE_BALANCE,
152 .type = V4L2_CTRL_TYPE_INTEGER,
153 .name = "Blue Balance",
154 .minimum = 24,
155 .maximum = 40,
156 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300157 .default_value = 32,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300158 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300159 .set_control = setredblue
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300160 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300161[RED] = {
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300162 {
163 .id = V4L2_CID_RED_BALANCE,
164 .type = V4L2_CTRL_TYPE_INTEGER,
165 .name = "Red Balance",
166 .minimum = 24,
167 .maximum = 40,
168 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300169 .default_value = 32,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300170 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300171 .set_control = setredblue
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300172 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300173[GAMMA] = {
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300174 {
175 .id = V4L2_CID_GAMMA,
176 .type = V4L2_CTRL_TYPE_INTEGER,
177 .name = "Gamma",
178 .minimum = 0,
179 .maximum = 40,
180 .step = 1,
181#define GAMMA_DEF 20
182 .default_value = GAMMA_DEF,
183 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300184 .set_control = setgamma
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300185 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300186[AUTOGAIN] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300187 {
188 .id = V4L2_CID_AUTOGAIN,
189 .type = V4L2_CTRL_TYPE_BOOLEAN,
190 .name = "Auto Gain",
191 .minimum = 0,
192 .maximum = 1,
193 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300194 .default_value = 1
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300195 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300196 .set_control = setautogain
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300197 },
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300198/* ov7630/ov7648 only */
Jean-François Moine72b667e2010-10-02 04:35:25 -0300199[VFLIP] = {
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300200 {
201 .id = V4L2_CID_VFLIP,
202 .type = V4L2_CTRL_TYPE_BOOLEAN,
203 .name = "Vflip",
204 .minimum = 0,
205 .maximum = 1,
206 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300207 .default_value = 0,
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300208 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300209 .set_control = setvflip
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300210 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300211[SHARPNESS] = {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300212 {
213 .id = V4L2_CID_SHARPNESS,
214 .type = V4L2_CTRL_TYPE_INTEGER,
215 .name = "Sharpness",
216 .minimum = 0,
217 .maximum = 255,
218 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300219 .default_value = 90,
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300220 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300221 .set_control = setsharpness
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300222 },
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300223/* mt9v111 only */
Jean-François Moine72b667e2010-10-02 04:35:25 -0300224[INFRARED] = {
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300225 {
226 .id = V4L2_CID_INFRARED,
227 .type = V4L2_CTRL_TYPE_BOOLEAN,
228 .name = "Infrared",
229 .minimum = 0,
230 .maximum = 1,
231 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300232 .default_value = 0,
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300233 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300234 .set_control = setinfrared
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300235 },
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300236/* ov7630/ov7648/ov7660 only */
Jean-François Moine72b667e2010-10-02 04:35:25 -0300237[FREQ] = {
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300238 {
239 .id = V4L2_CID_POWER_LINE_FREQUENCY,
240 .type = V4L2_CTRL_TYPE_MENU,
241 .name = "Light frequency filter",
242 .minimum = 0,
243 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
244 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300245 .default_value = 1,
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300246 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300247 .set_control = setfreq
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300248 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300249};
250
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300251/* table of the disabled controls */
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300252static const __u32 ctrl_dis[] = {
Jean-François Moine72b667e2010-10-02 04:35:25 -0300253[SENSOR_ADCM1700] = (1 << AUTOGAIN) |
254 (1 << INFRARED) |
255 (1 << VFLIP) |
256 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300257
Jean-François Moine72b667e2010-10-02 04:35:25 -0300258[SENSOR_GC0307] = (1 << INFRARED) |
259 (1 << VFLIP) |
260 (1 << FREQ),
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300261
Jean-François Moine72b667e2010-10-02 04:35:25 -0300262[SENSOR_HV7131R] = (1 << INFRARED) |
263 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300264
Jean-François Moine72b667e2010-10-02 04:35:25 -0300265[SENSOR_MI0360] = (1 << INFRARED) |
266 (1 << VFLIP) |
267 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300268
Jean-François Moine72b667e2010-10-02 04:35:25 -0300269[SENSOR_MI0360B] = (1 << INFRARED) |
270 (1 << VFLIP) |
271 (1 << FREQ),
Jean-François Moinea067db82010-10-01 07:51:24 -0300272
Jean-François Moine72b667e2010-10-02 04:35:25 -0300273[SENSOR_MO4000] = (1 << INFRARED) |
274 (1 << VFLIP) |
275 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300276
Jean-François Moine72b667e2010-10-02 04:35:25 -0300277[SENSOR_MT9V111] = (1 << VFLIP) |
278 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300279
Jean-François Moine72b667e2010-10-02 04:35:25 -0300280[SENSOR_OM6802] = (1 << INFRARED) |
281 (1 << VFLIP) |
282 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300283
Jean-François Moine72b667e2010-10-02 04:35:25 -0300284[SENSOR_OV7630] = (1 << INFRARED),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300285
Jean-François Moine72b667e2010-10-02 04:35:25 -0300286[SENSOR_OV7648] = (1 << INFRARED),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300287
Jean-François Moine72b667e2010-10-02 04:35:25 -0300288[SENSOR_OV7660] = (1 << AUTOGAIN) |
289 (1 << INFRARED) |
290 (1 << VFLIP),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300291
Jean-François Moine72b667e2010-10-02 04:35:25 -0300292[SENSOR_PO1030] = (1 << AUTOGAIN) |
293 (1 << INFRARED) |
294 (1 << VFLIP) |
295 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300296
Jean-François Moine72b667e2010-10-02 04:35:25 -0300297[SENSOR_PO2030N] = (1 << AUTOGAIN) |
298 (1 << INFRARED) |
299 (1 << VFLIP) |
300 (1 << FREQ),
301[SENSOR_SOI768] = (1 << AUTOGAIN) |
302 (1 << INFRARED) |
303 (1 << VFLIP) |
304 (1 << FREQ),
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300305
Jean-François Moine72b667e2010-10-02 04:35:25 -0300306[SENSOR_SP80708] = (1 << AUTOGAIN) |
307 (1 << INFRARED) |
308 (1 << VFLIP) |
309 (1 << FREQ),
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300310};
311
Jean-Francois Moine646775732009-12-20 12:31:28 -0300312static const struct v4l2_pix_format cif_mode[] = {
313 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
314 .bytesperline = 352,
315 .sizeimage = 352 * 288 * 4 / 8 + 590,
316 .colorspace = V4L2_COLORSPACE_JPEG,
317 .priv = 0},
318};
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300319static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300320 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
321 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300322 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300323 .colorspace = V4L2_COLORSPACE_JPEG,
324 .priv = 2},
325 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
326 .bytesperline = 320,
327 .sizeimage = 320 * 240 * 3 / 8 + 590,
328 .colorspace = V4L2_COLORSPACE_JPEG,
329 .priv = 1},
330 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
331 .bytesperline = 640,
Hans de Goedea5d1cc32009-06-18 06:03:20 -0300332 /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
333 .sizeimage = 640 * 480 * 3 / 4 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300334 .colorspace = V4L2_COLORSPACE_JPEG,
335 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300336};
337
Jean-Francois Moine646775732009-12-20 12:31:28 -0300338static const u8 sn_adcm1700[0x1c] = {
339/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300340 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine646775732009-12-20 12:31:28 -0300341/* reg8 reg9 rega regb regc regd rege regf */
342 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
343/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
344 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
345/* reg18 reg19 reg1a reg1b */
346 0x06, 0x00, 0x00, 0x00
347};
348
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300349static const u8 sn_gc0307[0x1c] = {
350/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
351 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
352/* reg8 reg9 rega regb regc regd rege regf */
353 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
354/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
355 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
356/* reg18 reg19 reg1a reg1b */
357 0x06, 0x00, 0x00, 0x00
358};
359
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300360static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300361/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-François Moine19697b52010-07-14 06:33:51 -0300362 0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300363/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300364 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300365/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
366 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300367/* reg18 reg19 reg1a reg1b */
368 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300369};
370
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300371static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300372/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-François Moine19697b52010-07-14 06:33:51 -0300373 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300374/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300375 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300376/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
377 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300378/* reg18 reg19 reg1a reg1b */
379 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300380};
381
Jean-François Moinea067db82010-10-01 07:51:24 -0300382static const u8 sn_mi0360b[0x1c] = {
383/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
384 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
385/* reg8 reg9 rega regb regc regd rege regf */
386 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
387/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
388 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40,
389/* reg18 reg19 reg1a reg1b */
390 0x06, 0x00, 0x00, 0x00
391};
392
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300393static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300394/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300395 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300396/* reg8 reg9 rega regb regc regd rege regf */
397 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
398/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
399 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300400/* reg18 reg19 reg1a reg1b */
401 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300402};
403
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300404static const u8 sn_mt9v111[0x1c] = {
405/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
406 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
407/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300408 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300409/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
410 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
411/* reg18 reg19 reg1a reg1b */
412 0x06, 0x00, 0x00, 0x00
413};
414
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300415static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300416/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Amauri Magagna46b4f2a2009-10-17 07:21:29 -0300417 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300418/* reg8 reg9 rega regb regc regd rege regf */
419 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
421 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300422/* reg18 reg19 reg1a reg1b */
423 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300424};
425
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300426static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300427/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-François Moine0a85c742010-04-25 14:33:31 -0300428 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300429/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300430 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300431/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
432 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300433/* reg18 reg19 reg1a reg1b */
434 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300435};
436
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300437static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300438/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300439 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300440/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300441 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300442/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300443 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300444/* reg18 reg19 reg1a reg1b */
445 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300446};
447
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300448static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300449/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -0300450 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300451/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -0300452 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300453/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
454 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300455/* reg18 reg19 reg1a reg1b */
456 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300457};
458
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300459static const u8 sn_po1030[0x1c] = {
460/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
461 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
462/* reg8 reg9 rega regb regc regd rege regf */
463 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
464/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
465 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
466/* reg18 reg19 reg1a reg1b */
467 0x07, 0x00, 0x00, 0x00
468};
469
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300470static const u8 sn_po2030n[0x1c] = {
471/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
472 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
473/* reg8 reg9 rega regb regc regd rege regf */
474 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
475/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
476 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
477/* reg18 reg19 reg1a reg1b */
478 0x07, 0x00, 0x00, 0x00
479};
480
Jean-François Moine03ed2a12010-04-25 14:45:43 -0300481static const u8 sn_soi768[0x1c] = {
482/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
483 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
484/* reg8 reg9 rega regb regc regd rege regf */
485 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
486/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
487 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
488/* reg18 reg19 reg1a reg1b */
489 0x07, 0x00, 0x00, 0x00
490};
491
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300492static const u8 sn_sp80708[0x1c] = {
493/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
494 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
495/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300496 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300497/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
498 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
499/* reg18 reg19 reg1a reg1b */
500 0x07, 0x00, 0x00, 0x00
501};
502
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300503/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300504static const u8 *sn_tb[] = {
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300505[SENSOR_ADCM1700] = sn_adcm1700,
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300506[SENSOR_GC0307] = sn_gc0307,
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300507[SENSOR_HV7131R] = sn_hv7131,
508[SENSOR_MI0360] = sn_mi0360,
Jean-François Moinea067db82010-10-01 07:51:24 -0300509[SENSOR_MI0360B] = sn_mi0360b,
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300510[SENSOR_MO4000] = sn_mo4000,
511[SENSOR_MT9V111] = sn_mt9v111,
512[SENSOR_OM6802] = sn_om6802,
513[SENSOR_OV7630] = sn_ov7630,
514[SENSOR_OV7648] = sn_ov7648,
515[SENSOR_OV7660] = sn_ov7660,
516[SENSOR_PO1030] = sn_po1030,
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300517[SENSOR_PO2030N] = sn_po2030n,
Jean-François Moine03ed2a12010-04-25 14:45:43 -0300518[SENSOR_SOI768] = sn_soi768,
519[SENSOR_SP80708] = sn_sp80708,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300520};
521
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300522/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300523static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300524 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
525 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
526};
Jean-Francois Moine646775732009-12-20 12:31:28 -0300527/* gamma for sensor ADCM1700 */
528static const u8 gamma_spec_0[17] = {
529 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
530 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
531};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300532/* gamma for sensors HV7131R and MT9V111 */
533static const u8 gamma_spec_1[17] = {
534 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
535 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
536};
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300537/* gamma for sensor GC0307 */
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300538static const u8 gamma_spec_2[17] = {
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300539 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
540 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
541};
542/* gamma for sensor SP80708 */
543static const u8 gamma_spec_3[17] = {
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300544 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
545 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
546};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300547
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300548/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300549static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300550 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
551 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
552 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
553 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300554};
Németh Mártonccbc5df2010-10-18 07:00:48 -0300555
556#define DELAY 0xdd
557
Jean-Francois Moine646775732009-12-20 12:31:28 -0300558static const u8 adcm1700_sensor_init[][8] = {
559 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300560 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -0300561 {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300562 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300563 {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300564 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
565 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
566 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
567 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
568 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300569 {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300570 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300571 {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300572 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
573 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
574 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
575 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
576 {}
577};
578static const u8 adcm1700_sensor_param1[][8] = {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300579 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300580 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
581
582 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
583 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
584 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
585 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300586 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300587
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300588 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
589 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
590 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
591 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300592 {}
593};
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300594static const u8 gc0307_sensor_init[][8] = {
595 {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
596 {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
597 {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
598 {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
599 {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
600 {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
601 {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
602 {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
603 {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
604 {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
605 {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
606 {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
607 {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
608 {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
609 {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
610 {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
611 {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
612 {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
613 {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
614 {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300615 {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300616 {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
617 {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
618 {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
619 {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
620 {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
621 {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
622 {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
623 {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
624 {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
625 {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
626 {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
627 {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
628 {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
629 {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
630 {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
631 {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
632 {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
633 {}
634};
635static const u8 gc0307_sensor_param1[][8] = {
636 {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
637 {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
638 {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
639 {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
640/*param3*/
641 {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
642 {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300643 {}
644};
645
Jean-Francois Moine98819182009-01-19 07:37:33 -0300646static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300647 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
648 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
649 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
650/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
651 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
652 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
653/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300655 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
656 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
657 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
658 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
659 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
660 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
661 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
662 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300663
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300664 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
665 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -0300666 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300667 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
668 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300669
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300670 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
671 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
672 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
673 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
674 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300675 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
676 /* set sensor clock */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300677 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300678};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300679static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300680 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300681 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300682 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300683 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
684 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
685 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
686 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
687 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
688 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
689 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
690 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
691 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
692 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
693 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
694 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
695 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
696 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
697 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
698 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
699 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
700 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
701 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300702 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300703 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
704 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
705 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
706 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
707 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
708 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
709 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
710 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
711 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
712 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300713
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300714 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
715 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
716 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
717 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
718 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300719
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300720 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
721 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
722 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
723 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300724
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300725 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
726 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
727/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
728/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
729 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
730 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300731 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300732};
Jean-François Moinea067db82010-10-01 07:51:24 -0300733static const u8 mi0360b_sensor_init[][8] = {
734 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
735 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300736 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
Jean-François Moinea067db82010-10-01 07:51:24 -0300737 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300738 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
Jean-François Moinea067db82010-10-01 07:51:24 -0300739 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
740 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
741 {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
742 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
743 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
744 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
745 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
746 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
747 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
748 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
749 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
750 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
751 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
752 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
753 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
754 {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
755 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
756 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
757 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
758 {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
759 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
760 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
761 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
762 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
763 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
764 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
765 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
766 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
767 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
768 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
769
770 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
771 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
772 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
773 {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
774 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
775 {}
776};
777static const u8 mi0360b_sensor_param1[][8] = {
778 {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
779 {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
780 {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
781 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
782
783 {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
784 {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
785 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
786 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
787 {}
788};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300789static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300790 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
791 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
792 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
793 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
794 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
795 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
796 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
797 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
798 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
799 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
800 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
801 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
802 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
803 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
804 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
805 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
806 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
807 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
808 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
809 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300810 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300811};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300812static const u8 mt9v111_sensor_init[][8] = {
813 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
Németh Mártonccbc5df2010-10-18 07:00:48 -0300814 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300815 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
816 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
817 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
818 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300819 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
820 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
821 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
822 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300823 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300824 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
825 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
826 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
827 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
828 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300829 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300830 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300831 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
832 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
833 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
834 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
835 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
836 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
837 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
838 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
839 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
840 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300841 {}
842};
843static const u8 mt9v111_sensor_param1[][8] = {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300844 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
845 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300846 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300847 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
848 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
849 /*******/
850 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
851 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
852 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
853 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
854 {}
855};
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300856static const u8 om6802_init0[2][8] = {
857/*fixme: variable*/
858 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
859 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
860};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300861static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300862 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
863 /* factory mode */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300864 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300865 /* output raw RGB */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300866 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300867/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
868 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300869 /* auto-exposure speed (0) / white balance mode (auto RGB) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300870/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
871 * set color mode */
872/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
873 * max AGC value in AE */
874/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
875 * preset AGC */
876/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
877 * preset brightness */
878/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
879 * preset contrast */
880/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
881 * preset gamma */
882 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300883 /* luminance mode (0x4f -> AutoExpo on) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300884 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
885 /* preset shutter */
886/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
887 * auto frame rate */
888/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300889 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
890 {}
891};
892static const u8 om6802_sensor_param1[][8] = {
893 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
894 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
895 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
896 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300897 {}
898};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300899static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300900 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
901 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300902 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300903 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
904 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300905 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300906 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300907/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300908 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
909 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
Hans de Goedecc7b5b52009-06-18 05:14:42 -0300910/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
911 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
912 {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300913 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
914 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
915 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
916 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
917 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
918 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
919 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
920 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
921 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
922 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
923 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
924 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
925 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
926 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
927 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
928 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
929 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
930 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
931 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
932 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
933 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
934 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
935 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-François Moinebdd2b932010-04-25 14:23:39 -0300936 {}
937};
938static const u8 ov7630_sensor_param1[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300939 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
940 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
941/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300942/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
943 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300944 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
945 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
946 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300947/* */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300948/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
949/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300950/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300951 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300952/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300953 {}
954};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300955
Jean-Francois Moine98819182009-01-19 07:37:33 -0300956static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300957 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
958 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -0300959 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300960 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
961 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
962 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
963 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
964 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
965 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
966 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
967 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
968 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
969 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
970 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
971 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
972 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
973 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
974 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
975 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
976 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
977 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
978 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
979
980 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
981/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
982/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300983/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300984 {}
985};
986static const u8 ov7648_sensor_param1[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300987/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -0300988/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
989 * set by setvflip */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300990 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
991 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
992/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
993/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
994/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
995/*...*/
996 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
997/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
998/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
999/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
1000/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1001/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
1002
1003 {}
1004};
1005
Jean-Francois Moine98819182009-01-19 07:37:33 -03001006static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001007 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Németh Mártonccbc5df2010-10-18 07:00:48 -03001008 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001009 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001010 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001011 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001012 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001013 /* GAIN BLUE RED VREF */
1014 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
1015 /* COM 1 BAVE GEAVE AECHH */
1016 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
1017 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001018 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001019 /* AECH CLKRC COM7 COM8 */
1020 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
1021 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
1022 /* HSTART HSTOP VSTRT VSTOP */
1023 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
1024 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
1025 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
1026 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001027/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
1028 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001029 /* AEW AEB VPT BBIAS */
1030 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
1031 /* GbBIAS RSVD EXHCH EXHCL */
1032 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
1033 /* RBIAS ADVFL ASDVFH YAVE */
1034 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
1035 /* HSYST HSYEN HREF */
1036 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1037 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1038 /* ADC ACOM OFON TSLB */
1039 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1040 /* COM11 COM12 COM13 COM14 */
1041 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1042 /* EDGE COM15 COM16 COM17 */
1043 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1044 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1045 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1046 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1047 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1048 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1049 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1050 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1051 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1052 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1053 /* LCC1 LCC2 LCC3 LCC4 */
1054 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001055 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001056 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001057 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001058 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1059 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1060 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1061 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1062 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1063 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1064 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1065 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1066 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001067 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001068/* not in all ms-win traces*/
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001069 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001070 {}
1071};
1072static const u8 ov7660_sensor_param1[][8] = {
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001073 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001074 /* bits[3..0]reserved */
1075 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1076 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1077 /* VREF vertical frame ctrl */
1078 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001079 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1080 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1081 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1082 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1083/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001084/****** (some exchanges in the win trace) ******/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001085/*fixme:param2*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001086 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001087 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1088 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1089 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1090/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001091/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001092/******!! startsensor KO if changed !!****/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001093/*fixme: param3*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001094 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1095 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1096 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1097 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001098 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001099};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001100
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001101static const u8 po1030_sensor_init[][8] = {
1102/* the sensor registers are described in m5602/m5602_po1030.h */
1103 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -03001104 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001105 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1106 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1107 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1108 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1109 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1110 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1111 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1112 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1113 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1114 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1115 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1116 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1117 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1118 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1119 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1120 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1121 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1122 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1123 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1124 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1125 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1126 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1127 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1128 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1129 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1130 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1131
1132 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1133 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1134 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1135 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1136 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1137 {}
1138};
1139static const u8 po1030_sensor_param1[][8] = {
1140/* from ms-win traces - these values change with auto gain/expo/wb.. */
1141 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1142 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1143/* mean values */
1144 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1145 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1146 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1147
1148 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1149 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1150 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1151/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1152 {}
1153};
1154
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001155static const u8 po2030n_sensor_init[][8] = {
1156 {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1157 {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001158 {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001159 {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1160 {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001161 {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001162 {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1163 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1164 {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1165 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1166 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1167 {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1168 {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1169 {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1170 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1171 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1172 {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1173 {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1174 {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1175 {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1176 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1177 {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1178 {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1179 {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1180 {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1181 {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1182 {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1183 {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1184 {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1185 {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1186 {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1187 {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1188 {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1189 {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1190 {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1191 {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1192 {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1193 {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1194 {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1195 {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1196 {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1197 {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1198 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1199 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1200 {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1201 {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1202 {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1203 {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1204 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1205 {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1206 {}
1207};
1208static const u8 po2030n_sensor_param1[][8] = {
1209 {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001210 {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001211 {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1212 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1213 {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1214/*param2*/
1215 {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1216 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1217 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1218 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1219 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1220 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1221 {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1222/*after start*/
1223 {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001224 {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001225 {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001226 {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001227 {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1228 {}
1229};
1230
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001231static const u8 soi768_sensor_init[][8] = {
1232 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -03001233 {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001234 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1235 {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1236 {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1237 {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1238 {}
1239};
1240static const u8 soi768_sensor_param1[][8] = {
1241 {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1242 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1243 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1244 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1245 {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1246/* */
1247/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1248/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1249 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1250/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1251 {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1252/* the next sequence should be used for auto gain */
1253 {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1254 /* global gain ? : 07 - change with 0x15 at the end */
1255 {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1256 {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1257 {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1258 /* exposure ? : 0200 - change with 0x1e at the end */
1259 {}
1260};
1261
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001262static const u8 sp80708_sensor_init[][8] = {
1263 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1264 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1265 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1266 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1267 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1268 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1269 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1270 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1271 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1272 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1273 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1274 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1275 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1276 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1277 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1278 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1279 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1280 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1281 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1282 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1283 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1284 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1285 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1286 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1287 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1288 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1289 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1290 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1291 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1292 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1293 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1294 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1295 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1296 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1297 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1298 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1299 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1300 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1301 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1302 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1303 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1304 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1305 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1306 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1307 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1308 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1309 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1310 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1311 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1312 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1313 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1314 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1315 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1316 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1317 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1318 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1319 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1320 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1321 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1322 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1323 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1324 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1325 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1326 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1327 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1328 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1329 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1330 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1331 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1332 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1333 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001334 {}
1335};
1336static const u8 sp80708_sensor_param1[][8] = {
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001337 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1338 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1339 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1340 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1341 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1342 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1343 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1344 {}
1345};
1346
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001347static const u8 (*sensor_init[])[8] = {
1348[SENSOR_ADCM1700] = adcm1700_sensor_init,
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001349[SENSOR_GC0307] = gc0307_sensor_init,
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001350[SENSOR_HV7131R] = hv7131r_sensor_init,
1351[SENSOR_MI0360] = mi0360_sensor_init,
Jean-François Moinea067db82010-10-01 07:51:24 -03001352[SENSOR_MI0360B] = mi0360b_sensor_init,
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001353[SENSOR_MO4000] = mo4000_sensor_init,
1354[SENSOR_MT9V111] = mt9v111_sensor_init,
1355[SENSOR_OM6802] = om6802_sensor_init,
1356[SENSOR_OV7630] = ov7630_sensor_init,
1357[SENSOR_OV7648] = ov7648_sensor_init,
1358[SENSOR_OV7660] = ov7660_sensor_init,
1359[SENSOR_PO1030] = po1030_sensor_init,
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001360[SENSOR_PO2030N] = po2030n_sensor_init,
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001361[SENSOR_SOI768] = soi768_sensor_init,
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001362[SENSOR_SP80708] = sp80708_sensor_init,
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001363};
1364
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001365/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001366static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001367 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001368{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001369 int ret;
1370
1371 if (gspca_dev->usb_err < 0)
1372 return;
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001373#ifdef GSPCA_DEBUG
1374 if (len > USB_BUF_SZ) {
1375 err("reg_r: buffer overflow");
1376 return;
1377 }
1378#endif
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001379 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001380 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001381 0,
1382 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1383 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001384 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001385 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001386 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001387 if (ret < 0) {
1388 err("reg_r err %d", ret);
1389 gspca_dev->usb_err = ret;
1390 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001391}
1392
Jean-Francois Moine60017612008-07-18 08:46:19 -03001393static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001394 u16 value,
1395 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -03001396{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001397 int ret;
1398
1399 if (gspca_dev->usb_err < 0)
1400 return;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001401 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001402 gspca_dev->usb_buf[0] = data;
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001403 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine60017612008-07-18 08:46:19 -03001404 usb_sndctrlpipe(gspca_dev->dev, 0),
1405 0x08,
1406 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1407 value,
1408 0,
1409 gspca_dev->usb_buf, 1,
1410 500);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001411 if (ret < 0) {
1412 err("reg_w1 err %d", ret);
1413 gspca_dev->usb_err = ret;
1414 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001415}
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001416static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001417 u16 value,
1418 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001419 int len)
1420{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001421 int ret;
1422
1423 if (gspca_dev->usb_err < 0)
1424 return;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001425 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -03001426 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001427#ifdef GSPCA_DEBUG
1428 if (len > USB_BUF_SZ) {
1429 err("reg_w: buffer overflow");
1430 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -03001431 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001432#endif
1433 memcpy(gspca_dev->usb_buf, buffer, len);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001434 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001435 usb_sndctrlpipe(gspca_dev->dev, 0),
1436 0x08,
1437 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1438 value, 0,
1439 gspca_dev->usb_buf, len,
1440 500);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001441 if (ret < 0) {
1442 err("reg_w err %d", ret);
1443 gspca_dev->usb_err = ret;
1444 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001445}
1446
Jean-Francois Moine60017612008-07-18 08:46:19 -03001447/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001448static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001449{
1450 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001451 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001452
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001453 if (gspca_dev->usb_err < 0)
1454 return;
Jean-François Moinecfd23c82010-04-25 14:27:39 -03001455 PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001456 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001457 case SENSOR_ADCM1700:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001458 case SENSOR_OM6802:
1459 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001460 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1461 break;
1462 default: /* i2c command = a1 (400 kHz) */
1463 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1464 break;
1465 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001466 gspca_dev->usb_buf[1] = sd->i2c_addr;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001467 gspca_dev->usb_buf[2] = reg;
1468 gspca_dev->usb_buf[3] = val;
1469 gspca_dev->usb_buf[4] = 0;
1470 gspca_dev->usb_buf[5] = 0;
1471 gspca_dev->usb_buf[6] = 0;
1472 gspca_dev->usb_buf[7] = 0x10;
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001473 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine60017612008-07-18 08:46:19 -03001474 usb_sndctrlpipe(gspca_dev->dev, 0),
1475 0x08,
1476 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1477 0x08, /* value = i2c */
1478 0,
1479 gspca_dev->usb_buf, 8,
1480 500);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001481 if (ret < 0) {
1482 err("i2c_w1 err %d", ret);
1483 gspca_dev->usb_err = ret;
1484 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001485}
1486
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001487/* I2C write 8 bytes */
1488static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001489 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001490{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001491 int ret;
1492
1493 if (gspca_dev->usb_err < 0)
1494 return;
Jean-François Moinecfd23c82010-04-25 14:27:39 -03001495 PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1496 buffer[2], buffer[3]);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001497 memcpy(gspca_dev->usb_buf, buffer, 8);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001498 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine60017612008-07-18 08:46:19 -03001499 usb_sndctrlpipe(gspca_dev->dev, 0),
1500 0x08,
1501 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1502 0x08, 0, /* value, index */
1503 gspca_dev->usb_buf, 8,
1504 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -03001505 msleep(2);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001506 if (ret < 0) {
1507 err("i2c_w8 err %d", ret);
1508 gspca_dev->usb_err = ret;
1509 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001510}
1511
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001512/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1513static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001514{
1515 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001516 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001517
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001518 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001519 case SENSOR_ADCM1700:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001520 case SENSOR_OM6802:
1521 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001522 mode[0] = 0x80 | 0x10;
1523 break;
1524 default: /* i2c command = 91 (400 kHz) */
1525 mode[0] = 0x81 | 0x10;
1526 break;
1527 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001528 mode[1] = sd->i2c_addr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001529 mode[2] = reg;
1530 mode[3] = 0;
1531 mode[4] = 0;
1532 mode[5] = 0;
1533 mode[6] = 0;
1534 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001535 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001536 msleep(2);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001537 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001538 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001539 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001540 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001541 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001542}
1543
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001544static void i2c_w_seq(struct gspca_dev *gspca_dev,
1545 const u8 (*data)[8])
1546{
1547 while ((*data)[0] != 0) {
Németh Mártonccbc5df2010-10-18 07:00:48 -03001548 if ((*data)[0] != DELAY)
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001549 i2c_w8(gspca_dev, *data);
1550 else
1551 msleep((*data)[1]);
1552 data++;
1553 }
1554}
1555
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001556static void hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001557{
Jean-Francois Moine60017612008-07-18 08:46:19 -03001558 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001559 msleep(10);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001560 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001561 msleep(10);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001562 i2c_r(gspca_dev, 0, 5); /* read sensor id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001563 if (gspca_dev->usb_buf[0] == 0x02
1564 && gspca_dev->usb_buf[1] == 0x09
1565 && gspca_dev->usb_buf[2] == 0x01
1566 && gspca_dev->usb_buf[3] == 0x00
1567 && gspca_dev->usb_buf[4] == 0x00) {
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001568 PDEBUG(D_PROBE, "Sensor sn9c102P HV7131R found");
1569 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001570 }
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001571 PDEBUG(D_PROBE, "Sensor 0x%02x 0x%02x 0x%02x - sn9c102P not found",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001572 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1573 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001574}
1575
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001576static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001577{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001578 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001579 int i, j;
Jean-Francois Moine92e8c912009-02-02 16:25:38 -03001580 u16 val = 0;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001581 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001582 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001583 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1584 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1585 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1586 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1587 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001588 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001589 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1590 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1591 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1592 {}
1593 },
1594 };
1595
1596 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1597 reg_w1(gspca_dev, 0x17, 0x62);
1598 reg_w1(gspca_dev, 0x01, 0x08);
1599 for (j = 0; j < 3; j++)
1600 i2c_w8(gspca_dev, probe_tb[i][j]);
1601 msleep(2);
1602 reg_r(gspca_dev, 0x0a, 5);
1603 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1604 if (probe_tb[i][3][0] != 0)
1605 i2c_w8(gspca_dev, probe_tb[i][3]);
1606 reg_w1(gspca_dev, 0x01, 0x29);
1607 reg_w1(gspca_dev, 0x17, 0x42);
1608 if (val != 0xffff)
1609 break;
1610 }
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001611 if (gspca_dev->usb_err < 0)
1612 return;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001613 switch (val) {
Jean-François Moinea067db82010-10-01 07:51:24 -03001614 case 0x8221:
1615 PDEBUG(D_PROBE, "Sensor mi0360b");
1616 sd->sensor = SENSOR_MI0360B;
1617 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001618 case 0x823a:
1619 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001620 sd->sensor = SENSOR_MT9V111;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001621 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001622 case 0x8243:
1623 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001624 break;
1625 default:
1626 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1627 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001628 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001629}
1630
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001631static void ov7630_probe(struct gspca_dev *gspca_dev)
1632{
1633 struct sd *sd = (struct sd *) gspca_dev;
1634 u16 val;
1635
1636 /* check ov76xx */
1637 reg_w1(gspca_dev, 0x17, 0x62);
1638 reg_w1(gspca_dev, 0x01, 0x08);
1639 sd->i2c_addr = 0x21;
1640 i2c_r(gspca_dev, 0x0a, 2);
1641 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1642 reg_w1(gspca_dev, 0x01, 0x29);
1643 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001644 if (gspca_dev->usb_err < 0)
1645 return;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001646 if (val == 0x7628) { /* soi768 */
1647 sd->sensor = SENSOR_SOI768;
1648/*fixme: only valid for 0c45:613e?*/
1649 gspca_dev->cam.input_flags =
1650 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1651 PDEBUG(D_PROBE, "Sensor soi768");
1652 return;
1653 }
1654 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1655}
1656
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001657static void ov7648_probe(struct gspca_dev *gspca_dev)
1658{
1659 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001660 u16 val;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001661
1662 /* check ov76xx */
1663 reg_w1(gspca_dev, 0x17, 0x62);
1664 reg_w1(gspca_dev, 0x01, 0x08);
1665 sd->i2c_addr = 0x21;
1666 i2c_r(gspca_dev, 0x0a, 2);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001667 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001668 reg_w1(gspca_dev, 0x01, 0x29);
1669 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001670 if ((val & 0xff00) == 0x7600) { /* ov76xx */
1671 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1672 return;
1673 }
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001674
1675 /* check po1030 */
1676 reg_w1(gspca_dev, 0x17, 0x62);
1677 reg_w1(gspca_dev, 0x01, 0x08);
1678 sd->i2c_addr = 0x6e;
1679 i2c_r(gspca_dev, 0x00, 2);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001680 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1681 reg_w1(gspca_dev, 0x01, 0x29);
1682 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001683 if (gspca_dev->usb_err < 0)
1684 return;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001685 if (val == 0x1030) { /* po1030 */
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001686 PDEBUG(D_PROBE, "Sensor po1030");
1687 sd->sensor = SENSOR_PO1030;
1688 return;
1689 }
1690
Jean-François Moine0b656322010-09-13 05:19:58 -03001691 err("Unknown sensor %04x", val);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001692}
1693
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001694/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1695static void po2030n_probe(struct gspca_dev *gspca_dev)
1696{
1697 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001698 u16 val;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001699
1700 /* check gc0307 */
1701 reg_w1(gspca_dev, 0x17, 0x62);
1702 reg_w1(gspca_dev, 0x01, 0x08);
1703 reg_w1(gspca_dev, 0x02, 0x22);
1704 sd->i2c_addr = 0x21;
1705 i2c_r(gspca_dev, 0x00, 1);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001706 val = gspca_dev->usb_buf[4];
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001707 reg_w1(gspca_dev, 0x01, 0x29); /* reset */
1708 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001709 if (val == 0x99) { /* gc0307 (?) */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001710 PDEBUG(D_PROBE, "Sensor gc0307");
1711 sd->sensor = SENSOR_GC0307;
1712 return;
1713 }
1714
1715 /* check po2030n */
1716 reg_w1(gspca_dev, 0x17, 0x62);
1717 reg_w1(gspca_dev, 0x01, 0x0a);
1718 sd->i2c_addr = 0x6e;
1719 i2c_r(gspca_dev, 0x00, 2);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001720 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001721 reg_w1(gspca_dev, 0x01, 0x29);
1722 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001723 if (gspca_dev->usb_err < 0)
1724 return;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001725 if (val == 0x2030) {
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001726 PDEBUG(D_PROBE, "Sensor po2030n");
1727/* sd->sensor = SENSOR_PO2030N; */
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001728 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03001729 err("Unknown sensor ID %04x", val);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001730 }
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001731}
1732
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001733static void bridge_init(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001734 const u8 *sn9c1xx)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001735{
1736 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine19697b52010-07-14 06:33:51 -03001737 u8 reg0102[2];
Jean-Francois Moine98819182009-01-19 07:37:33 -03001738 const u8 *reg9a;
1739 static const u8 reg9a_def[] =
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001740 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
1741 static const u8 reg9a_spec[] =
1742 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
Jean-Francois Moine98819182009-01-19 07:37:33 -03001743 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001744
Hans de Goede9712a8b2010-01-31 12:54:29 -03001745 /* sensor clock already enabled in sd_init */
1746 /* reg_w1(gspca_dev, 0xf1, 0x00); */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001747 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001748
1749 /* configure gpio */
Jean-François Moine19697b52010-07-14 06:33:51 -03001750 reg0102[0] = sn9c1xx[1];
1751 reg0102[1] = sn9c1xx[2];
1752 if (gspca_dev->audio)
1753 reg0102[1] |= 0x04; /* keep the audio connection */
1754 reg_w(gspca_dev, 0x01, reg0102, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001755 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001756 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001757 switch (sd->sensor) {
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001758 case SENSOR_GC0307:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001759 case SENSOR_OV7660:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001760 case SENSOR_PO1030:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001761 case SENSOR_PO2030N:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001762 case SENSOR_SOI768:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001763 case SENSOR_SP80708:
1764 reg9a = reg9a_spec;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001765 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001766 default:
1767 reg9a = reg9a_def;
1768 break;
1769 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001770 reg_w(gspca_dev, 0x9a, reg9a, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001771
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001772 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001773
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001774 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001775
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001776 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001777 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001778 reg_w1(gspca_dev, 0x01, 0x43);
Jean-Francois Moine646775732009-12-20 12:31:28 -03001779 reg_w1(gspca_dev, 0x17, 0x62);
1780 reg_w1(gspca_dev, 0x01, 0x42);
1781 reg_w1(gspca_dev, 0x01, 0x42);
1782 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001783 case SENSOR_GC0307:
1784 msleep(50);
1785 reg_w1(gspca_dev, 0x01, 0x61);
1786 reg_w1(gspca_dev, 0x17, 0x22);
1787 reg_w1(gspca_dev, 0x01, 0x60);
1788 reg_w1(gspca_dev, 0x01, 0x40);
1789 msleep(50);
1790 break;
Jean-François Moinea067db82010-10-01 07:51:24 -03001791 case SENSOR_MI0360B:
1792 reg_w1(gspca_dev, 0x01, 0x61);
1793 reg_w1(gspca_dev, 0x17, 0x60);
1794 reg_w1(gspca_dev, 0x01, 0x60);
1795 reg_w1(gspca_dev, 0x01, 0x40);
1796 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001797 case SENSOR_MT9V111:
1798 reg_w1(gspca_dev, 0x01, 0x61);
1799 reg_w1(gspca_dev, 0x17, 0x61);
1800 reg_w1(gspca_dev, 0x01, 0x60);
1801 reg_w1(gspca_dev, 0x01, 0x40);
1802 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001803 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001804 msleep(10);
1805 reg_w1(gspca_dev, 0x02, 0x73);
1806 reg_w1(gspca_dev, 0x17, 0x60);
1807 reg_w1(gspca_dev, 0x01, 0x22);
1808 msleep(100);
1809 reg_w1(gspca_dev, 0x01, 0x62);
1810 reg_w1(gspca_dev, 0x17, 0x64);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001811 reg_w1(gspca_dev, 0x17, 0x64);
1812 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001813 msleep(10);
1814 reg_w1(gspca_dev, 0x01, 0x42);
1815 i2c_w8(gspca_dev, om6802_init0[0]);
1816 i2c_w8(gspca_dev, om6802_init0[1]);
1817 msleep(15);
1818 reg_w1(gspca_dev, 0x02, 0x71);
1819 msleep(150);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001820 break;
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03001821 case SENSOR_OV7630:
1822 reg_w1(gspca_dev, 0x01, 0x61);
1823 reg_w1(gspca_dev, 0x17, 0xe2);
1824 reg_w1(gspca_dev, 0x01, 0x60);
1825 reg_w1(gspca_dev, 0x01, 0x40);
1826 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001827 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03001828 reg_w1(gspca_dev, 0x01, 0x63);
1829 reg_w1(gspca_dev, 0x17, 0x20);
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001830 reg_w1(gspca_dev, 0x01, 0x62);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001831 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001832 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001833 case SENSOR_PO1030:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001834 case SENSOR_SOI768:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001835 reg_w1(gspca_dev, 0x01, 0x61);
1836 reg_w1(gspca_dev, 0x17, 0x20);
1837 reg_w1(gspca_dev, 0x01, 0x60);
1838 reg_w1(gspca_dev, 0x01, 0x40);
1839 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001840 case SENSOR_PO2030N:
Jean-François Moine19697b52010-07-14 06:33:51 -03001841 case SENSOR_OV7660:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001842 reg_w1(gspca_dev, 0x01, 0x63);
1843 reg_w1(gspca_dev, 0x17, 0x20);
1844 reg_w1(gspca_dev, 0x01, 0x62);
1845 reg_w1(gspca_dev, 0x01, 0x42);
1846 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001847 case SENSOR_SP80708:
1848 reg_w1(gspca_dev, 0x01, 0x63);
1849 reg_w1(gspca_dev, 0x17, 0x20);
1850 reg_w1(gspca_dev, 0x01, 0x62);
1851 reg_w1(gspca_dev, 0x01, 0x42);
Jean-Francois Moine1f78a972009-08-29 07:11:58 -03001852 msleep(100);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001853 reg_w1(gspca_dev, 0x02, 0x62);
1854 break;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001855 default:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03001856/* case SENSOR_HV7131R: */
1857/* case SENSOR_MI0360: */
1858/* case SENSOR_MO4000: */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001859 reg_w1(gspca_dev, 0x01, 0x43);
1860 reg_w1(gspca_dev, 0x17, 0x61);
1861 reg_w1(gspca_dev, 0x01, 0x42);
Jean-François Moine75f05ba2010-10-21 04:09:34 -03001862 if (sd->sensor == SENSOR_HV7131R)
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001863 hv7131r_probe(gspca_dev);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001864 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001865 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001866}
1867
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001868/* this function is called at probe time */
1869static int sd_config(struct gspca_dev *gspca_dev,
1870 const struct usb_device_id *id)
1871{
1872 struct sd *sd = (struct sd *) gspca_dev;
1873 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001874
Jean-Francois Moineeac8f5f2010-01-12 07:12:43 -03001875 sd->bridge = id->driver_info >> 16;
1876 sd->sensor = id->driver_info;
1877
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001878 cam = &gspca_dev->cam;
Jean-Francois Moine646775732009-12-20 12:31:28 -03001879 if (sd->sensor == SENSOR_ADCM1700) {
1880 cam->cam_mode = cif_mode;
1881 cam->nmodes = ARRAY_SIZE(cif_mode);
1882 } else {
1883 cam->cam_mode = vga_mode;
1884 cam->nmodes = ARRAY_SIZE(vga_mode);
1885 }
Jean-Francois Moine49cb6b02009-04-25 13:29:01 -03001886 cam->npkt = 24; /* 24 packets per ISOC message */
Jean-François Moine72b667e2010-10-02 04:35:25 -03001887 cam->ctrls = sd->ctrls;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001888
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001889 sd->ag_cnt = -1;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001890 sd->quality = QUALITY_DEF;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03001891 sd->jpegqual = 80;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001892
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001893 return 0;
1894}
1895
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001896/* this function is called at probe and resume time */
1897static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001898{
1899 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001900 const u8 *sn9c1xx;
Jean-François Moine19697b52010-07-14 06:33:51 -03001901 u8 regGpio[] = { 0x29, 0x74 }; /* with audio */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001902 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001903
Hans de Goede3647fea2008-07-15 05:36:30 -03001904 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001905 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001906 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001907 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1908 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001909 regF1 = gspca_dev->usb_buf[0];
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001910 if (gspca_dev->usb_err < 0)
1911 return gspca_dev->usb_err;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001912 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001913 switch (sd->bridge) {
1914 case BRIDGE_SN9C102P:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001915 if (regF1 != 0x11)
1916 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001917 reg_w1(gspca_dev, 0x02, regGpio[1]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001918 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001919 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001920 if (regF1 != 0x11)
1921 return -ENODEV;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001922 if (sd->sensor == SENSOR_MI0360)
1923 mi0360_probe(gspca_dev);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001924 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001925 break;
Hans de Goede3647fea2008-07-15 05:36:30 -03001926 case BRIDGE_SN9C120:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001927 if (regF1 != 0x12)
1928 return -ENODEV;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001929 switch (sd->sensor) {
1930 case SENSOR_MI0360:
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001931 mi0360_probe(gspca_dev);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001932 break;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001933 case SENSOR_OV7630:
1934 ov7630_probe(gspca_dev);
1935 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001936 case SENSOR_OV7648:
1937 ov7648_probe(gspca_dev);
1938 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001939 case SENSOR_PO2030N:
1940 po2030n_probe(gspca_dev);
1941 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001942 }
Jean-François Moine19697b52010-07-14 06:33:51 -03001943 regGpio[1] = 0x70; /* no audio */
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03001944 reg_w(gspca_dev, 0x01, regGpio, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001945 break;
1946 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001947/* case BRIDGE_SN9C110: */
Hans de Goede3647fea2008-07-15 05:36:30 -03001948/* case BRIDGE_SN9C325: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001949 if (regF1 != 0x12)
1950 return -ENODEV;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001951 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001952 break;
1953 }
1954
Jean-François Moine72b667e2010-10-02 04:35:25 -03001955 if (sd->sensor == SENSOR_OM6802)
1956 sd->ctrls[SHARPNESS].def = 0x10;
1957
Hans de Goede9712a8b2010-01-31 12:54:29 -03001958 /* Note we do not disable the sensor clock here (power saving mode),
1959 as that also disables the button on the cam. */
1960 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001961
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001962 /* set the i2c address */
1963 sn9c1xx = sn_tb[sd->sensor];
1964 sd->i2c_addr = sn9c1xx[9];
1965
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001966 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
1967
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001968 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001969}
1970
Jean-Francois Moine98819182009-01-19 07:37:33 -03001971static u32 setexposure(struct gspca_dev *gspca_dev,
1972 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001973{
1974 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001975
1976 switch (sd->sensor) {
Jean-François Moinec26b12d2010-04-02 07:08:39 -03001977 case SENSOR_GC0307: {
1978 int a, b;
1979
1980 /* expo = 0..255 -> a = 19..43 */
1981 a = 19 + expo * 25 / 256;
1982 i2c_w1(gspca_dev, 0x68, a);
1983 a -= 12;
1984 b = a * a * 4; /* heuristic */
1985 i2c_w1(gspca_dev, 0x03, b >> 8);
1986 i2c_w1(gspca_dev, 0x04, b);
1987 break;
1988 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001989 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001990 u8 Expodoit[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001991 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001992
1993 Expodoit[3] = expo >> 16;
1994 Expodoit[4] = expo >> 8;
1995 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001996 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001997 break;
1998 }
Jean-François Moinea067db82010-10-01 07:51:24 -03001999 case SENSOR_MI0360:
2000 case SENSOR_MI0360B: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002001 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002002 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002003 static const u8 doit[] = /* update sensor */
2004 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
2005 static const u8 sensorgo[] = /* sensor on */
2006 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002007
2008 if (expo > 0x0635)
2009 expo = 0x0635;
2010 else if (expo < 0x0001)
2011 expo = 0x0001;
2012 expoMi[3] = expo >> 8;
2013 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002014 i2c_w8(gspca_dev, expoMi);
2015 i2c_w8(gspca_dev, doit);
2016 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002017 break;
2018 }
2019 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03002020 u8 expoMof[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002021 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002022 u8 expoMo10[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002023 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002024 static const u8 gainMo[] =
2025 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002026
2027 if (expo > 0x1fff)
2028 expo = 0x1fff;
2029 else if (expo < 0x0001)
2030 expo = 0x0001;
2031 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002032 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002033 expoMo10[3] = ((expo & 0x1c00) >> 10)
2034 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002035 i2c_w8(gspca_dev, expoMo10);
2036 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002037 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002038 ((expoMo10[3] & 0x07) << 10)
2039 | (expoMof[3] << 2)
2040 | ((expoMo10[3] & 0x30) >> 4));
2041 break;
2042 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002043 case SENSOR_MT9V111: {
2044 u8 expo_c1[] =
2045 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
2046
2047 if (expo > 0x0280)
2048 expo = 0x0280;
2049 else if (expo < 0x0040)
2050 expo = 0x0040;
2051 expo_c1[3] = expo >> 8;
2052 expo_c1[4] = expo;
2053 i2c_w8(gspca_dev, expo_c1);
2054 break;
2055 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002056 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03002057 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002058 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002059 /* preset AGC - works when AutoExpo = off */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002060
2061 if (expo > 0x03ff)
2062 expo = 0x03ff;
2063 if (expo < 0x0001)
2064 expo = 0x0001;
2065 gainOm[3] = expo >> 2;
2066 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002067 reg_w1(gspca_dev, 0x96, expo >> 5);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002068 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002069 break;
2070 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002071 }
2072 return expo;
2073}
2074
2075static void setbrightness(struct gspca_dev *gspca_dev)
2076{
2077 struct sd *sd = (struct sd *) gspca_dev;
2078 unsigned int expo;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002079 int brightness;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002080 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002081
Jean-François Moine72b667e2010-10-02 04:35:25 -03002082 brightness = sd->ctrls[BRIGHTNESS].val;
2083 k2 = (brightness - 0x80) >> 2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002084 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002085 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002086 if (k2 > 0x1f)
2087 k2 = 0; /* only positive Y offset */
2088 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002089 case SENSOR_HV7131R:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002090 expo = brightness << 12;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002091 if (expo > 0x002dc6c0)
2092 expo = 0x002dc6c0;
2093 else if (expo < 0x02a0)
2094 expo = 0x02a0;
2095 sd->exposure = setexposure(gspca_dev, expo);
2096 break;
2097 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002098 case SENSOR_MO4000:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002099 expo = brightness << 4;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002100 sd->exposure = setexposure(gspca_dev, expo);
2101 break;
Jean-François Moinea067db82010-10-01 07:51:24 -03002102 case SENSOR_MI0360B:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002103 expo = brightness << 2;
Jean-François Moinea067db82010-10-01 07:51:24 -03002104 sd->exposure = setexposure(gspca_dev, expo);
2105 break;
Jean-François Moinec26b12d2010-04-02 07:08:39 -03002106 case SENSOR_GC0307:
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002107 case SENSOR_MT9V111:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002108 expo = brightness;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002109 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002110 return; /* don't set the Y offset */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002111 case SENSOR_OM6802:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002112 expo = brightness << 2;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002113 sd->exposure = setexposure(gspca_dev, expo);
Jean-François Moine72b667e2010-10-02 04:35:25 -03002114 k2 = brightness >> 3;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002115 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002116 }
2117
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002118 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002119}
2120
2121static void setcontrast(struct gspca_dev *gspca_dev)
2122{
2123 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002124 u8 k2;
2125 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002126
Jean-François Moine72b667e2010-10-02 04:35:25 -03002127 k2 = sd->ctrls[CONTRAST].val * 0x30 / (CONTRAST_MAX + 1)
2128 + 0x10; /* 10..40 */
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002129 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03002130 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002131 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03002132 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002133 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03002134 contrast[5] = 0;
2135 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002136}
2137
2138static void setcolors(struct gspca_dev *gspca_dev)
2139{
2140 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002141 int i, v, colors;
Jean-François Moinea067db82010-10-01 07:51:24 -03002142 const s16 *uv;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002143 u8 reg8a[12]; /* U & V gains */
Jean-François Moinea067db82010-10-01 07:51:24 -03002144 static const s16 uv_com[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002145 -24, -38, 64, /* UR UG UB */
2146 62, -51, -9 /* VR VG VB */
2147 };
Jean-François Moinea067db82010-10-01 07:51:24 -03002148 static const s16 uv_mi0360b[6] = {
2149 -20, -38, 64, /* UR UG UB */
2150 60, -51, -9 /* VR VG VB */
2151 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002152
Jean-François Moine72b667e2010-10-02 04:35:25 -03002153 colors = sd->ctrls[COLORS].val;
Jean-François Moinea067db82010-10-01 07:51:24 -03002154 if (sd->sensor == SENSOR_MI0360B)
2155 uv = uv_mi0360b;
2156 else
2157 uv = uv_com;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002158 for (i = 0; i < 6; i++) {
Jean-François Moine72b667e2010-10-02 04:35:25 -03002159 v = uv[i] * colors / COLORS_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03002160 reg8a[i * 2] = v;
2161 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03002162 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03002163 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002164}
2165
2166static void setredblue(struct gspca_dev *gspca_dev)
2167{
2168 struct sd *sd = (struct sd *) gspca_dev;
2169
Jean-François Moine72b667e2010-10-02 04:35:25 -03002170 reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03002171/* reg_w1(gspca_dev, 0x07, 32); */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002172 reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002173}
2174
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002175static void setgamma(struct gspca_dev *gspca_dev)
2176{
2177 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002178 int i, val;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002179 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002180 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002181 static const u8 delta[17] = {
2182 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2183 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2184 };
2185
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002186 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002187 case SENSOR_ADCM1700:
2188 gamma_base = gamma_spec_0;
2189 break;
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002190 case SENSOR_HV7131R:
Jean-François Moinea067db82010-10-01 07:51:24 -03002191 case SENSOR_MI0360B:
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002192 case SENSOR_MT9V111:
2193 gamma_base = gamma_spec_1;
2194 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002195 case SENSOR_GC0307:
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002196 gamma_base = gamma_spec_2;
2197 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002198 case SENSOR_SP80708:
2199 gamma_base = gamma_spec_3;
2200 break;
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002201 default:
2202 gamma_base = gamma_def;
2203 break;
2204 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002205
Jean-François Moine72b667e2010-10-02 04:35:25 -03002206 val = sd->ctrls[GAMMA].val;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002207 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002208 gamma[i] = gamma_base[i]
Jean-François Moine72b667e2010-10-02 04:35:25 -03002209 + delta[i] * (val - GAMMA_DEF) / 32;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002210 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2211}
2212
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002213static void setautogain(struct gspca_dev *gspca_dev)
2214{
2215 struct sd *sd = (struct sd *) gspca_dev;
2216
Jean-François Moine72b667e2010-10-02 04:35:25 -03002217 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03002218 return;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002219 switch (sd->sensor) {
2220 case SENSOR_OV7630:
2221 case SENSOR_OV7648: {
2222 u8 comb;
2223
2224 if (sd->sensor == SENSOR_OV7630)
2225 comb = 0xc0;
2226 else
2227 comb = 0xa0;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002228 if (sd->ctrls[AUTOGAIN].val)
Hans de Goede1fec747c2009-06-18 06:05:07 -03002229 comb |= 0x03;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002230 i2c_w1(&sd->gspca_dev, 0x13, comb);
2231 return;
2232 }
2233 }
Jean-François Moine72b667e2010-10-02 04:35:25 -03002234 if (sd->ctrls[AUTOGAIN].val)
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03002235 sd->ag_cnt = AG_CNT_START;
2236 else
2237 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002238}
2239
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002240/* hv7131r/ov7630/ov7648 only */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002241static void setvflip(struct gspca_dev *gspca_dev)
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002242{
Jean-François Moine72b667e2010-10-02 04:35:25 -03002243 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002244 u8 comn;
2245
Jean-François Moine72b667e2010-10-02 04:35:25 -03002246 if (gspca_dev->ctrl_dis & (1 << VFLIP))
Jean-Francois Moine0939e262009-11-02 09:58:49 -03002247 return;
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002248 switch (sd->sensor) {
2249 case SENSOR_HV7131R:
2250 comn = 0x18; /* clkdiv = 1, ablcen = 1 */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002251 if (sd->ctrls[VFLIP].val)
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002252 comn |= 0x01;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002253 i2c_w1(gspca_dev, 0x01, comn); /* sctra */
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002254 break;
2255 case SENSOR_OV7630:
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002256 comn = 0x02;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002257 if (!sd->ctrls[VFLIP].val)
Hans de Goedef8009522009-06-18 14:29:20 -03002258 comn |= 0x80;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002259 i2c_w1(gspca_dev, 0x75, comn);
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002260 break;
2261 default:
2262/* case SENSOR_OV7648: */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002263 comn = 0x06;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002264 if (sd->ctrls[VFLIP].val)
Hans de Goedef8009522009-06-18 14:29:20 -03002265 comn |= 0x80;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002266 i2c_w1(gspca_dev, 0x75, comn);
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002267 break;
Hans de Goedef8009522009-06-18 14:29:20 -03002268 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002269}
2270
Jean-François Moine72b667e2010-10-02 04:35:25 -03002271static void setsharpness(struct gspca_dev *gspca_dev)
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002272{
Jean-François Moine72b667e2010-10-02 04:35:25 -03002273 struct sd *sd = (struct sd *) gspca_dev;
2274
2275 reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002276}
2277
Jean-François Moine72b667e2010-10-02 04:35:25 -03002278static void setinfrared(struct gspca_dev *gspca_dev)
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002279{
Jean-François Moine72b667e2010-10-02 04:35:25 -03002280 struct sd *sd = (struct sd *) gspca_dev;
2281
2282 if (gspca_dev->ctrl_dis & (1 << INFRARED))
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03002283 return;
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002284/*fixme: different sequence for StarCam Clip and StarCam 370i */
2285/* Clip */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002286 i2c_w1(gspca_dev, 0x02, /* gpio */
2287 sd->ctrls[INFRARED].val ? 0x66 : 0x64);
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002288}
2289
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002290static void setfreq(struct gspca_dev *gspca_dev)
2291{
2292 struct sd *sd = (struct sd *) gspca_dev;
2293
Jean-François Moine72b667e2010-10-02 04:35:25 -03002294 if (gspca_dev->ctrl_dis & (1 << FREQ))
Jean-Francois Moine27954932009-07-08 05:21:50 -03002295 return;
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002296 if (sd->sensor == SENSOR_OV7660) {
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03002297 u8 com8;
2298
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03002299 com8 = 0xdf; /* auto gain/wb/expo */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002300 switch (sd->ctrls[FREQ].val) {
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002301 case 0: /* Banding filter disabled */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03002302 i2c_w1(gspca_dev, 0x13, com8 | 0x20);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002303 break;
2304 case 1: /* 50 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03002305 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002306 i2c_w1(gspca_dev, 0x3b, 0x0a);
2307 break;
2308 case 2: /* 60 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03002309 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002310 i2c_w1(gspca_dev, 0x3b, 0x02);
2311 break;
2312 }
2313 } else {
2314 u8 reg2a = 0, reg2b = 0, reg2d = 0;
2315
2316 /* Get reg2a / reg2d base values */
2317 switch (sd->sensor) {
2318 case SENSOR_OV7630:
2319 reg2a = 0x08;
2320 reg2d = 0x01;
2321 break;
2322 case SENSOR_OV7648:
2323 reg2a = 0x11;
2324 reg2d = 0x81;
2325 break;
2326 }
2327
Jean-François Moine72b667e2010-10-02 04:35:25 -03002328 switch (sd->ctrls[FREQ].val) {
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002329 case 0: /* Banding filter disabled */
2330 break;
2331 case 1: /* 50 hz (filter on and framerate adj) */
2332 reg2a |= 0x80;
2333 reg2b = 0xac;
2334 reg2d |= 0x04;
2335 break;
2336 case 2: /* 60 hz (filter on, no framerate adj) */
2337 reg2a |= 0x80;
2338 reg2d |= 0x04;
2339 break;
2340 }
2341 i2c_w1(gspca_dev, 0x2a, reg2a);
2342 i2c_w1(gspca_dev, 0x2b, reg2b);
2343 i2c_w1(gspca_dev, 0x2d, reg2d);
2344 }
2345}
2346
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002347static void setjpegqual(struct gspca_dev *gspca_dev)
2348{
2349 struct sd *sd = (struct sd *) gspca_dev;
2350 int i, sc;
2351
2352 if (sd->jpegqual < 50)
2353 sc = 5000 / sd->jpegqual;
2354 else
2355 sc = 200 - sd->jpegqual * 2;
2356#if USB_BUF_SZ < 64
2357#error "No room enough in usb_buf for quantization table"
2358#endif
2359 for (i = 0; i < 64; i++)
2360 gspca_dev->usb_buf[i] =
2361 (jpeg_head[JPEG_QT0_OFFSET + i] * sc + 50) / 100;
2362 usb_control_msg(gspca_dev->dev,
2363 usb_sndctrlpipe(gspca_dev->dev, 0),
2364 0x08,
2365 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2366 0x0100, 0,
2367 gspca_dev->usb_buf, 64,
2368 500);
2369 for (i = 0; i < 64; i++)
2370 gspca_dev->usb_buf[i] =
2371 (jpeg_head[JPEG_QT1_OFFSET + i] * sc + 50) / 100;
2372 usb_control_msg(gspca_dev->dev,
2373 usb_sndctrlpipe(gspca_dev->dev, 0),
2374 0x08,
2375 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2376 0x0140, 0,
2377 gspca_dev->usb_buf, 64,
2378 500);
2379
2380 sd->reg18 ^= 0x40;
2381 reg_w1(gspca_dev, 0x18, sd->reg18);
2382}
2383
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002384/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03002385static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002386{
2387 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002388 int i;
Jean-François Moine19697b52010-07-14 06:33:51 -03002389 u8 reg1, reg17;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002390 const u8 *sn9c1xx;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002391 const u8 (*init)[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002392 int mode;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002393 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2394 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moine646775732009-12-20 12:31:28 -03002395 static const u8 CA_adcm1700[] =
2396 { 0x14, 0xec, 0x0a, 0xf6 };
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002397 static const u8 CA_po2030n[] =
2398 { 0x1e, 0xe2, 0x14, 0xec };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002399 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002400 static const u8 CE_gc0307[] =
2401 { 0x32, 0xce, 0x2d, 0xd3 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002402 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002403 { 0x32, 0xdd, 0x32, 0xdd };
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002404 static const u8 CE_po2030n[] =
2405 { 0x14, 0xe7, 0x1e, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002406
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002407 /* create the JPEG header */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002408 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2409 0x21); /* JPEG 422 */
2410 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2411
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002412 /* initialize the bridge */
2413 sn9c1xx = sn_tb[sd->sensor];
2414 bridge_init(gspca_dev, sn9c1xx);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002415
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002416 /* initialize the sensor */
2417 i2c_w_seq(gspca_dev, sensor_init[sd->sensor]);
2418
Jean-Francois Moine60017612008-07-18 08:46:19 -03002419 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
2420 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
2421 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
2422 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
2423 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine646775732009-12-20 12:31:28 -03002424 if (sd->sensor == SENSOR_ADCM1700) {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002425 reg_w1(gspca_dev, 0xd2, 0x3a); /* AE_H_SIZE = 116 */
2426 reg_w1(gspca_dev, 0xd3, 0x30); /* AE_V_SIZE = 96 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002427 } else {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002428 reg_w1(gspca_dev, 0xd2, 0x6a); /* AE_H_SIZE = 212 */
2429 reg_w1(gspca_dev, 0xd3, 0x50); /* AE_V_SIZE = 160 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002430 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03002431 reg_w1(gspca_dev, 0xc6, 0x00);
2432 reg_w1(gspca_dev, 0xc7, 0x00);
Jean-Francois Moine646775732009-12-20 12:31:28 -03002433 if (sd->sensor == SENSOR_ADCM1700) {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002434 reg_w1(gspca_dev, 0xc8, 0x2c); /* AW_H_STOP = 352 */
2435 reg_w1(gspca_dev, 0xc9, 0x24); /* AW_V_STOP = 288 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002436 } else {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002437 reg_w1(gspca_dev, 0xc8, 0x50); /* AW_H_STOP = 640 */
2438 reg_w1(gspca_dev, 0xc9, 0x3c); /* AW_V_STOP = 480 */
Jean-Francois Moine646775732009-12-20 12:31:28 -03002439 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03002440 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002441 switch (sd->sensor) {
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002442 case SENSOR_GC0307:
2443 reg17 = 0xa2;
2444 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002445 case SENSOR_MT9V111:
Jean-François Moinea067db82010-10-01 07:51:24 -03002446 case SENSOR_MI0360B:
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002447 reg17 = 0xe0;
2448 break;
Jean-Francois Moine646775732009-12-20 12:31:28 -03002449 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002450 case SENSOR_OV7630:
2451 reg17 = 0xe2;
2452 break;
2453 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002454 reg17 = 0x20;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002455 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002456 case SENSOR_OV7660:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002457 case SENSOR_SOI768:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03002458 reg17 = 0xa0;
2459 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002460 case SENSOR_PO1030:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002461 case SENSOR_PO2030N:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002462 reg17 = 0xa0;
2463 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002464 default:
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002465 reg17 = 0x60;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002466 break;
2467 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002468 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002469
2470 reg_w1(gspca_dev, 0x05, 0x00); /* red */
2471 reg_w1(gspca_dev, 0x07, 0x00); /* green */
2472 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002473 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002474
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002475 setgamma(gspca_dev);
2476
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002477/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03002478 for (i = 0; i < 8; i++)
2479 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002480 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002481 case SENSOR_ADCM1700:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03002482 case SENSOR_OV7660:
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002483 case SENSOR_SP80708:
2484 reg_w1(gspca_dev, 0x9a, 0x05);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002485 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002486 case SENSOR_GC0307:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002487 case SENSOR_MT9V111:
Jean-François Moinea067db82010-10-01 07:51:24 -03002488 case SENSOR_MI0360B:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002489 reg_w1(gspca_dev, 0x9a, 0x07);
2490 break;
Jean-François Moine0a85c742010-04-25 14:33:31 -03002491 case SENSOR_OV7630:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002492 case SENSOR_OV7648:
2493 reg_w1(gspca_dev, 0x9a, 0x0a);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002494 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002495 case SENSOR_PO2030N:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002496 case SENSOR_SOI768:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002497 reg_w1(gspca_dev, 0x9a, 0x06);
2498 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002499 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03002500 reg_w1(gspca_dev, 0x9a, 0x08);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002501 break;
2502 }
Jean-François Moine72b667e2010-10-02 04:35:25 -03002503 setsharpness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002504
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002505 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002506 reg_w1(gspca_dev, 0x05, 0x20); /* red */
2507 reg_w1(gspca_dev, 0x07, 0x20); /* green */
2508 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
Jean-Francois Moine23a98272009-11-02 09:10:25 -03002509
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002510 init = NULL;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002511 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
Jean-Francois Moine60017612008-07-18 08:46:19 -03002512 if (mode)
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002513 reg1 = 0x46; /* 320x240: clk 48Mhz, video trf enable */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002514 else
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002515 reg1 = 0x06; /* 640x480: clk 24Mhz, video trf enable */
2516 reg17 = 0x61; /* 0x:20: enable sensor clock */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002517 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002518 case SENSOR_ADCM1700:
2519 init = adcm1700_sensor_param1;
2520 reg1 = 0x46;
2521 reg17 = 0xe2;
2522 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002523 case SENSOR_GC0307:
2524 init = gc0307_sensor_param1;
2525 reg17 = 0xa2;
2526 reg1 = 0x44;
2527 break;
Jean-François Moinea067db82010-10-01 07:51:24 -03002528 case SENSOR_MI0360B:
2529 init = mi0360b_sensor_param1;
2530 reg1 &= ~0x02; /* don't inverse pin S_PWR_DN */
2531 reg17 = 0xe2;
2532 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002533 case SENSOR_MO4000:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002534 if (mode) {
2535/* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
2536 reg1 = 0x06; /* clk 24Mz */
2537 } else {
2538 reg17 = 0x22; /* 640 MCKSIZE */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002539/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002540 }
2541 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002542 case SENSOR_MT9V111:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002543 init = mt9v111_sensor_param1;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002544 if (mode) {
2545 reg1 = 0x04; /* 320 clk 48Mhz */
2546 } else {
2547/* reg1 = 0x06; * 640 clk 24Mz (done) */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -03002548 reg17 = 0xc2;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002549 }
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03002550 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002551 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002552 init = om6802_sensor_param1;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002553 reg17 = 0x64; /* 640 MCKSIZE */
2554 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002555 case SENSOR_OV7630:
Jean-François Moinebdd2b932010-04-25 14:23:39 -03002556 init = ov7630_sensor_param1;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002557 reg17 = 0xe2;
Jean-Francois Moine5b064da2008-09-03 16:48:08 -03002558 reg1 = 0x44;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002559 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002560 case SENSOR_OV7648:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002561 init = ov7648_sensor_param1;
Jean-Francois Moine62703302008-11-11 08:42:56 -03002562 reg17 = 0x21;
2563/* reg1 = 0x42; * 42 - 46? */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002564 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002565 case SENSOR_OV7660:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002566 init = ov7660_sensor_param1;
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03002567 if (sd->bridge == BRIDGE_SN9C120) {
2568 if (mode) { /* 320x240 - 160x120 */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002569 reg17 = 0xa2;
2570 reg1 = 0x44; /* 48 Mhz, video trf eneble */
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002571 }
Jean-Francois Moinedaa5cb42008-12-02 15:00:57 -03002572 } else {
2573 reg17 = 0x22;
2574 reg1 = 0x06; /* 24 Mhz, video trf eneble
2575 * inverse power down */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002576 }
2577 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002578 case SENSOR_PO1030:
2579 init = po1030_sensor_param1;
2580 reg17 = 0xa2;
2581 reg1 = 0x44;
2582 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002583 case SENSOR_PO2030N:
2584 init = po2030n_sensor_param1;
2585 reg1 = 0x46;
2586 reg17 = 0xa2;
2587 break;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002588 case SENSOR_SOI768:
2589 init = soi768_sensor_param1;
2590 reg1 = 0x44;
2591 reg17 = 0xa2;
2592 break;
Jean-François Moine0303a902010-10-21 04:05:15 -03002593 case SENSOR_SP80708:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002594 init = sp80708_sensor_param1;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002595 if (mode) {
2596/*?? reg1 = 0x04; * 320 clk 48Mhz */
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002597 } else {
2598 reg1 = 0x46; /* 640 clk 48Mz */
2599 reg17 = 0xa2;
2600 }
2601 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002602 }
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002603
2604 /* more sensor initialization - param1 */
2605 if (init != NULL) {
2606 i2c_w_seq(gspca_dev, init);
2607/* init = NULL; */
2608 }
2609
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002610 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002611 switch (sd->sensor) {
2612 case SENSOR_ADCM1700:
2613 case SENSOR_GC0307:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002614 case SENSOR_SOI768:
Jean-Francois Moine646775732009-12-20 12:31:28 -03002615 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002616 break;
2617 case SENSOR_PO2030N:
2618 reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2619 break;
2620 default:
Jean-Francois Moine646775732009-12-20 12:31:28 -03002621 reg_w(gspca_dev, 0xca, CA, 4);
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002622 break;
2623 }
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002624 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002625 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002626 case SENSOR_OV7630:
2627 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002628 case SENSOR_OV7660:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002629 case SENSOR_SOI768:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002630 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002631 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002632 case SENSOR_GC0307:
2633 reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2634 break;
2635 case SENSOR_PO2030N:
2636 reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2637 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002638 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002639 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002640 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2641 break;
2642 }
2643
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002644
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002645 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002646 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2647 reg_w1(gspca_dev, 0x18, sd->reg18);
2648 setjpegqual(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002649
Jean-Francois Moine60017612008-07-18 08:46:19 -03002650 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine1432f302008-11-21 04:34:15 -03002651 reg_w1(gspca_dev, 0x01, reg1);
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002652
Jean-François Moine72b667e2010-10-02 04:35:25 -03002653 setvflip(gspca_dev);
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002654 setbrightness(gspca_dev);
2655 setcontrast(gspca_dev);
Jean-François Moinefff2f702010-04-25 14:31:05 -03002656 setcolors(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002657 setautogain(gspca_dev);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002658 setfreq(gspca_dev);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03002659 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002660}
2661
2662static void sd_stopN(struct gspca_dev *gspca_dev)
2663{
2664 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002665 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002666 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002667 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002668 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002669 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03002670 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002671 static const u8 stopsoi768[] =
2672 { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002673 u8 data;
2674 const u8 *sn9c1xx;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002675
2676 data = 0x0b;
2677 switch (sd->sensor) {
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002678 case SENSOR_GC0307:
2679 data = 0x29;
2680 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002681 case SENSOR_HV7131R:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002682 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002683 data = 0x2b;
2684 break;
2685 case SENSOR_MI0360:
Jean-François Moinea067db82010-10-01 07:51:24 -03002686 case SENSOR_MI0360B:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002687 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002688 data = 0x29;
2689 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002690 case SENSOR_OV7648:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002691 i2c_w8(gspca_dev, stopov7648);
2692 /* fall thru */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002693 case SENSOR_MT9V111:
Jean-Francois Moine62703302008-11-11 08:42:56 -03002694 case SENSOR_OV7630:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002695 case SENSOR_PO1030:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002696 data = 0x29;
2697 break;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002698 case SENSOR_SOI768:
2699 i2c_w8(gspca_dev, stopsoi768);
2700 data = 0x29;
2701 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002702 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002703 sn9c1xx = sn_tb[sd->sensor];
Jean-Francois Moine60017612008-07-18 08:46:19 -03002704 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2705 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
2706 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
2707 reg_w1(gspca_dev, 0x01, data);
Hans de Goede9712a8b2010-01-31 12:54:29 -03002708 /* Don't disable sensor clock as that disables the button on the cam */
2709 /* reg_w1(gspca_dev, 0xf1, 0x01); */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002710}
2711
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002712static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002713{
2714 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002715 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002716 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002717 u8 luma_mean = 130;
2718 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002719
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002720 /* Thanks S., without your advice, autobright should not work :) */
2721 if (sd->ag_cnt < 0)
2722 return;
2723 if (--sd->ag_cnt >= 0)
2724 return;
2725 sd->ag_cnt = AG_CNT_START;
2726
2727 delta = atomic_read(&sd->avg_lum);
2728 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002729 if (delta < luma_mean - luma_delta ||
2730 delta > luma_mean + luma_delta) {
2731 switch (sd->sensor) {
Jean-François Moinec26b12d2010-04-02 07:08:39 -03002732 case SENSOR_GC0307:
2733 expotimes = sd->exposure;
2734 expotimes += (luma_mean - delta) >> 6;
2735 if (expotimes < 0)
2736 expotimes = 0;
2737 sd->exposure = setexposure(gspca_dev,
2738 (unsigned int) expotimes);
2739 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002740 case SENSOR_HV7131R:
2741 expotimes = sd->exposure >> 8;
2742 expotimes += (luma_mean - delta) >> 4;
2743 if (expotimes < 0)
2744 expotimes = 0;
2745 sd->exposure = setexposure(gspca_dev,
2746 (unsigned int) (expotimes << 8));
2747 break;
Amauri Magagna46b4f2a2009-10-17 07:21:29 -03002748 case SENSOR_OM6802:
2749 expotimes = sd->exposure;
2750 expotimes += (luma_mean - delta) >> 2;
2751 if (expotimes < 0)
2752 expotimes = 0;
2753 sd->exposure = setexposure(gspca_dev,
2754 (unsigned int) expotimes);
2755 setredblue(gspca_dev);
2756 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002757 default:
2758/* case SENSOR_MO4000: */
2759/* case SENSOR_MI0360: */
Jean-François Moinea067db82010-10-01 07:51:24 -03002760/* case SENSOR_MI0360B: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002761/* case SENSOR_MT9V111: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002762 expotimes = sd->exposure;
2763 expotimes += (luma_mean - delta) >> 6;
2764 if (expotimes < 0)
2765 expotimes = 0;
2766 sd->exposure = setexposure(gspca_dev,
2767 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002768 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002769 break;
2770 }
2771 }
2772}
2773
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002774/* scan the URB packets */
2775/* This function is run at interrupt level. */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002776static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03002777 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002778 int len) /* iso packet length */
2779{
2780 struct sd *sd = (struct sd *) gspca_dev;
2781 int sof, avg_lum;
2782
Jean-François Moinea95bd642010-10-01 07:54:30 -03002783 /* the image ends on a 64 bytes block starting with
2784 * ff d9 ff ff 00 c4 c4 96
2785 * and followed by various information including luminosity */
2786 /* this block may be splitted between two packets */
2787 /* a new image always starts in a new packet */
2788 switch (gspca_dev->last_packet_type) {
2789 case DISCARD_PACKET: /* restart image building */
2790 sof = len - 64;
2791 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9)
2792 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2793 return;
2794 case LAST_PACKET: /* put the JPEG 422 header */
2795 gspca_frame_add(gspca_dev, FIRST_PACKET,
2796 sd->jpeg_hdr, JPEG_HDR_SZ);
2797 break;
2798 }
2799 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002800
Jean-François Moinea95bd642010-10-01 07:54:30 -03002801 data = gspca_dev->image;
2802 if (data == NULL)
2803 return;
2804 sof = gspca_dev->image_len - 64;
2805 if (data[sof] != 0xff
2806 || data[sof + 1] != 0xd9)
2807 return;
2808
2809 /* end of image found - remove the trailing data */
2810 gspca_dev->image_len = sof + 2;
2811 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
2812 if (sd->ag_cnt < 0)
2813 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002814/* w1 w2 w3 */
2815/* w4 w5 w6 */
2816/* w7 w8 */
2817/* w4 */
Jean-François Moinea95bd642010-10-01 07:54:30 -03002818 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002819/* w6 */
Jean-François Moinea95bd642010-10-01 07:54:30 -03002820 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002821/* w2 */
Jean-François Moinea95bd642010-10-01 07:54:30 -03002822 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002823/* w8 */
Jean-François Moinea95bd642010-10-01 07:54:30 -03002824 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002825/* w5 */
Jean-François Moinea95bd642010-10-01 07:54:30 -03002826 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
2827 avg_lum >>= 4;
2828 atomic_set(&sd->avg_lum, avg_lum);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002829}
2830
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002831static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2832 struct v4l2_jpegcompression *jcomp)
2833{
2834 struct sd *sd = (struct sd *) gspca_dev;
2835
2836 if (jcomp->quality < QUALITY_MIN)
2837 sd->quality = QUALITY_MIN;
2838 else if (jcomp->quality > QUALITY_MAX)
2839 sd->quality = QUALITY_MAX;
2840 else
2841 sd->quality = jcomp->quality;
2842 if (gspca_dev->streaming)
2843 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
2844 return 0;
2845}
2846
2847static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2848 struct v4l2_jpegcompression *jcomp)
2849{
2850 struct sd *sd = (struct sd *) gspca_dev;
2851
2852 memset(jcomp, 0, sizeof *jcomp);
2853 jcomp->quality = sd->quality;
2854 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2855 | V4L2_JPEG_MARKER_DQT;
2856 return 0;
2857}
2858
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002859static int sd_querymenu(struct gspca_dev *gspca_dev,
2860 struct v4l2_querymenu *menu)
2861{
2862 switch (menu->id) {
2863 case V4L2_CID_POWER_LINE_FREQUENCY:
2864 switch (menu->index) {
2865 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2866 strcpy((char *) menu->name, "NoFliker");
2867 return 0;
2868 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2869 strcpy((char *) menu->name, "50 Hz");
2870 return 0;
2871 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2872 strcpy((char *) menu->name, "60 Hz");
2873 return 0;
2874 }
2875 break;
2876 }
2877 return -EINVAL;
2878}
2879
Jean-François Moine28566432010-10-01 07:33:26 -03002880#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede9712a8b2010-01-31 12:54:29 -03002881static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2882 u8 *data, /* interrupt packet data */
2883 int len) /* interrupt packet length */
2884{
2885 int ret = -EINVAL;
2886
2887 if (len == 1 && data[0] == 1) {
2888 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2889 input_sync(gspca_dev->input_dev);
2890 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2891 input_sync(gspca_dev->input_dev);
2892 ret = 0;
2893 }
2894
2895 return ret;
2896}
2897#endif
2898
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002899/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002900static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002901 .name = MODULE_NAME,
2902 .ctrls = sd_ctrls,
Jean-François Moine72b667e2010-10-02 04:35:25 -03002903 .nctrls = NCTRLS,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002904 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002905 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002906 .start = sd_start,
2907 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002908 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002909 .dq_callback = do_autogain,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002910 .get_jcomp = sd_get_jcomp,
2911 .set_jcomp = sd_set_jcomp,
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002912 .querymenu = sd_querymenu,
Jean-François Moine28566432010-10-01 07:33:26 -03002913#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede9712a8b2010-01-31 12:54:29 -03002914 .int_pkt_scan = sd_int_pkt_scan,
2915#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002916};
2917
2918/* -- module initialisation -- */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002919#define BS(bridge, sensor) \
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002920 .driver_info = (BRIDGE_ ## bridge << 16) \
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002921 | SENSOR_ ## sensor
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002922static const __devinitdata struct usb_device_id device_table[] = {
Hans de Goede222a07f2008-09-03 17:12:20 -03002923#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002924 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2925 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
Jean-Francois Moinea08d81a2008-11-22 04:53:31 -03002926#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002927 {USB_DEVICE(0x045e, 0x00f5), BS(SN9C105, OV7660)},
2928 {USB_DEVICE(0x045e, 0x00f7), BS(SN9C105, OV7660)},
2929 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2930 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2931 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2932 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2933 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2934/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2935 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2936/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2937/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2938 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2939/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
2940 {USB_DEVICE(0x0c45, 0x60c0), BS(SN9C105, MI0360)},
Jean-François Moinea067db82010-10-01 07:51:24 -03002941 /* or MT9V111 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002942/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2943/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2944/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
Warren Bosworth Fockec4f95d82010-05-07 15:40:04 -03002945 {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002946 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2947/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
2948/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
Jean-François Moine68046752010-05-07 15:35:08 -03002949/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002950 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002951#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002952 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
2953 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
Jean-Francois Moine3c41cb72008-09-10 02:57:09 -03002954#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002955 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
Jean-François Moine860e7f42010-09-13 06:40:17 -03002956 {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002957/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
2958 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
2959 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
2960 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
2961 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
2962/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
2963/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
2964/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
2965 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002966/*bw600.inf:*/
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002967 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
Alexander Goncharov2a3b5012010-09-13 06:58:16 -03002968 {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002969 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
2970 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
2971/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002972 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
Jean-François Moinea067db82010-10-01 07:51:24 -03002973 /* or MT9V111 / MI0360B */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002974/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
2975 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
2976 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
Hans de Goede222a07f2008-09-03 17:12:20 -03002977#if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002978 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
Jean-Francois Moine8d977702009-02-19 15:34:48 -03002979#endif
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002980 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
2981 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002982 {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
Jean-François Moine68046752010-05-07 15:35:08 -03002983 /* or GC0305 / GC0307 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002984 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
2985 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
Jean-Francois Moine646775732009-12-20 12:31:28 -03002986 {USB_DEVICE(0x0c45, 0x614a), BS(SN9C120, ADCM1700)}, /*sn9c120b*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002987 {}
2988};
2989MODULE_DEVICE_TABLE(usb, device_table);
2990
2991/* -- device connect -- */
2992static int sd_probe(struct usb_interface *intf,
2993 const struct usb_device_id *id)
2994{
2995 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
2996 THIS_MODULE);
2997}
2998
2999static struct usb_driver sd_driver = {
3000 .name = MODULE_NAME,
3001 .id_table = device_table,
3002 .probe = sd_probe,
3003 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03003004#ifdef CONFIG_PM
3005 .suspend = gspca_suspend,
3006 .resume = gspca_resume,
3007#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003008};
3009
3010/* -- module insert / remove -- */
3011static int __init sd_mod_init(void)
3012{
Jean-François Moine54826432010-09-13 04:53:03 -03003013 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003014}
3015static void __exit sd_mod_exit(void)
3016{
3017 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003018}
3019
3020module_init(sd_mod_init);
3021module_exit(sd_mod_exit);