blob: d465022b8022549aa3930c3f3710eca67c16fa2c [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-François Moine27c6f9e2010-04-02 06:59:13 -030028MODULE_AUTHOR("Jean-François Moine <http://moinejf.free.fr>");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030029MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
30MODULE_LICENSE("GPL");
31
Jean-François Moine3afef852011-01-13 06:39:11 -030032static int starcam;
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,
Németh Márton76ad3b62010-10-19 03:33:47 -030043 HFLIP,
Jean-François Moine72b667e2010-10-02 04:35:25 -030044 VFLIP,
45 SHARPNESS,
Jean-François Moine3afef852011-01-13 06:39:11 -030046 ILLUM,
Jean-François Moine72b667e2010-10-02 04:35:25 -030047 FREQ,
48 NCTRLS /* number of controls */
49};
50
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030051/* specific webcam descriptor */
52struct sd {
53 struct gspca_dev gspca_dev; /* !! must be the first item */
54
Jean-François Moine72b667e2010-10-02 04:35:25 -030055 struct gspca_ctrl ctrls[NCTRLS];
56
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -030057 atomic_t avg_lum;
Jean-Francois Moine98819182009-01-19 07:37:33 -030058 u32 exposure;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030059
Jean-François Moinea4a30762011-02-10 07:15:24 -030060 s8 short_mark;
61
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030062 u8 quality; /* image quality */
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030063#define QUALITY_MIN 60
64#define QUALITY_MAX 95
65#define QUALITY_DEF 80
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030066
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -030067 u8 reg01;
68 u8 reg17;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030069 u8 reg18;
Jean-Francois Moinec6c14332010-12-14 16:15:37 -030070 u8 flags;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030071
Jean-Francois Moine98819182009-01-19 07:37:33 -030072 s8 ag_cnt;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030073#define AG_CNT_START 13
74
Jean-Francois Moine98819182009-01-19 07:37:33 -030075 u8 bridge;
Hans de Goede3647fea2008-07-15 05:36:30 -030076#define BRIDGE_SN9C102P 0
77#define BRIDGE_SN9C105 1
78#define BRIDGE_SN9C110 2
79#define BRIDGE_SN9C120 3
Jean-Francois Moine98819182009-01-19 07:37:33 -030080 u8 sensor; /* Type of image sensor chip */
Jean-François Moine11ce8842010-07-26 06:39:40 -030081 u8 i2c_addr;
82
83 u8 jpeg_hdr[JPEG_HDR_SZ];
84};
85enum sensors {
Jean-François Moine9c33afc2010-03-17 15:25:32 -030086 SENSOR_ADCM1700,
Jean-François Moinead98c0f2010-03-18 05:15:30 -030087 SENSOR_GC0307,
Jean-François Moine9c33afc2010-03-17 15:25:32 -030088 SENSOR_HV7131R,
89 SENSOR_MI0360,
Jean-François Moinea067db82010-10-01 07:51:24 -030090 SENSOR_MI0360B,
Jean-François Moine9c33afc2010-03-17 15:25:32 -030091 SENSOR_MO4000,
92 SENSOR_MT9V111,
93 SENSOR_OM6802,
94 SENSOR_OV7630,
95 SENSOR_OV7648,
96 SENSOR_OV7660,
97 SENSOR_PO1030,
Jean-François Moinead98c0f2010-03-18 05:15:30 -030098 SENSOR_PO2030N,
Jean-François Moine03ed2a12010-04-25 14:45:43 -030099 SENSOR_SOI768,
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300100 SENSOR_SP80708,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300101};
102
Jean-Francois Moineb2272a42010-12-14 16:16:16 -0300103/* device flags */
Jean-François Moine3afef852011-01-13 06:39:11 -0300104#define F_PDN_INV 0x01 /* inverse pin S_PWR_DN / sn_xxx tables */
105#define F_ILLUM 0x02 /* presence of illuminator */
Jean-Francois Moineb2272a42010-12-14 16:16:16 -0300106
Jean-Francois Moine4fd350ee2010-12-14 16:16:58 -0300107/* sn9c1xx definitions */
108/* register 0x01 */
109#define S_PWR_DN 0x01 /* sensor power down */
110#define S_PDN_INV 0x02 /* inverse pin S_PWR_DN */
111#define V_TX_EN 0x04 /* video transfer enable */
112#define LED 0x08 /* output to pin LED */
113#define SCL_SEL_OD 0x20 /* open-drain mode */
114#define SYS_SEL_48M 0x40 /* system clock 0: 24MHz, 1: 48MHz */
115/* register 0x17 */
116#define MCK_SIZE_MASK 0x1f /* sensor master clock */
117#define SEN_CLK_EN 0x20 /* enable sensor clock */
118#define DEF_EN 0x80 /* defect pixel by 0: soft, 1: hard */
119
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300120/* V4L2 controls supported by the driver */
Jean-François Moine72b667e2010-10-02 04:35:25 -0300121static void setbrightness(struct gspca_dev *gspca_dev);
122static void setcontrast(struct gspca_dev *gspca_dev);
123static void setcolors(struct gspca_dev *gspca_dev);
124static void setredblue(struct gspca_dev *gspca_dev);
125static void setgamma(struct gspca_dev *gspca_dev);
126static void setautogain(struct gspca_dev *gspca_dev);
Németh Márton76ad3b62010-10-19 03:33:47 -0300127static void sethvflip(struct gspca_dev *gspca_dev);
Jean-François Moine72b667e2010-10-02 04:35:25 -0300128static void setsharpness(struct gspca_dev *gspca_dev);
Jean-François Moine3afef852011-01-13 06:39:11 -0300129static void setillum(struct gspca_dev *gspca_dev);
Jean-François Moine72b667e2010-10-02 04:35:25 -0300130static void setfreq(struct gspca_dev *gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300131
Jean-François Moine72b667e2010-10-02 04:35:25 -0300132static const struct ctrl sd_ctrls[NCTRLS] = {
133[BRIGHTNESS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300134 {
135 .id = V4L2_CID_BRIGHTNESS,
136 .type = V4L2_CTRL_TYPE_INTEGER,
137 .name = "Brightness",
138 .minimum = 0,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300139 .maximum = 0xff,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300140 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300141 .default_value = 0x80,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300142 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300143 .set_control = setbrightness
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300144 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300145[CONTRAST] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300146 {
147 .id = V4L2_CID_CONTRAST,
148 .type = V4L2_CTRL_TYPE_INTEGER,
149 .name = "Contrast",
150 .minimum = 0,
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300151#define CONTRAST_MAX 127
152 .maximum = CONTRAST_MAX,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300153 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300154 .default_value = 63,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300155 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300156 .set_control = setcontrast
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300157 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300158[COLORS] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300159 {
160 .id = V4L2_CID_SATURATION,
161 .type = V4L2_CTRL_TYPE_INTEGER,
Hans de Goede3fb4a572009-06-18 14:31:36 -0300162 .name = "Saturation",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300163 .minimum = 0,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300164 .maximum = 40,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300165 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300166#define COLORS_DEF 25
167 .default_value = COLORS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300168 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300169 .set_control = setcolors
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300170 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300171[BLUE] = {
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300172 {
173 .id = V4L2_CID_BLUE_BALANCE,
174 .type = V4L2_CTRL_TYPE_INTEGER,
175 .name = "Blue Balance",
176 .minimum = 24,
177 .maximum = 40,
178 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300179 .default_value = 32,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300180 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300181 .set_control = setredblue
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300182 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300183[RED] = {
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300184 {
185 .id = V4L2_CID_RED_BALANCE,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "Red Balance",
188 .minimum = 24,
189 .maximum = 40,
190 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300191 .default_value = 32,
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300192 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300193 .set_control = setredblue
Jean-Francois Moine403123d2008-11-26 04:46:15 -0300194 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300195[GAMMA] = {
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300196 {
197 .id = V4L2_CID_GAMMA,
198 .type = V4L2_CTRL_TYPE_INTEGER,
199 .name = "Gamma",
200 .minimum = 0,
201 .maximum = 40,
202 .step = 1,
203#define GAMMA_DEF 20
204 .default_value = GAMMA_DEF,
205 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300206 .set_control = setgamma
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300207 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300208[AUTOGAIN] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300209 {
210 .id = V4L2_CID_AUTOGAIN,
211 .type = V4L2_CTRL_TYPE_BOOLEAN,
212 .name = "Auto Gain",
213 .minimum = 0,
214 .maximum = 1,
215 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300216 .default_value = 1
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300217 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300218 .set_control = setautogain
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300219 },
Németh Márton76ad3b62010-10-19 03:33:47 -0300220[HFLIP] = {
221 {
222 .id = V4L2_CID_HFLIP,
223 .type = V4L2_CTRL_TYPE_BOOLEAN,
224 .name = "Mirror",
225 .minimum = 0,
226 .maximum = 1,
227 .step = 1,
228 .default_value = 0,
229 },
230 .set_control = sethvflip
231 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300232[VFLIP] = {
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300233 {
234 .id = V4L2_CID_VFLIP,
235 .type = V4L2_CTRL_TYPE_BOOLEAN,
236 .name = "Vflip",
237 .minimum = 0,
238 .maximum = 1,
239 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300240 .default_value = 0,
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300241 },
Németh Márton76ad3b62010-10-19 03:33:47 -0300242 .set_control = sethvflip
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300243 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300244[SHARPNESS] = {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300245 {
246 .id = V4L2_CID_SHARPNESS,
247 .type = V4L2_CTRL_TYPE_INTEGER,
248 .name = "Sharpness",
249 .minimum = 0,
250 .maximum = 255,
251 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300252 .default_value = 90,
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300253 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300254 .set_control = setsharpness
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300255 },
Jean-François Moine3afef852011-01-13 06:39:11 -0300256[ILLUM] = {
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300257 {
Jean-François Moine3afef852011-01-13 06:39:11 -0300258 .id = V4L2_CID_ILLUMINATORS_1,
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300259 .type = V4L2_CTRL_TYPE_BOOLEAN,
Jean-François Moine3afef852011-01-13 06:39:11 -0300260 .name = "Illuminator / infrared",
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300261 .minimum = 0,
262 .maximum = 1,
263 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300264 .default_value = 0,
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300265 },
Jean-François Moine3afef852011-01-13 06:39:11 -0300266 .set_control = setillum
Jean-Francois Moine0cae8962008-10-17 07:48:24 -0300267 },
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300268/* ov7630/ov7648/ov7660 only */
Jean-François Moine72b667e2010-10-02 04:35:25 -0300269[FREQ] = {
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300270 {
271 .id = V4L2_CID_POWER_LINE_FREQUENCY,
272 .type = V4L2_CTRL_TYPE_MENU,
273 .name = "Light frequency filter",
274 .minimum = 0,
275 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
276 .step = 1,
Jean-François Moine72b667e2010-10-02 04:35:25 -0300277 .default_value = 1,
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300278 },
Jean-François Moine72b667e2010-10-02 04:35:25 -0300279 .set_control = setfreq
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300280 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300281};
282
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300283/* table of the disabled controls */
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300284static const __u32 ctrl_dis[] = {
Jean-François Moine72b667e2010-10-02 04:35:25 -0300285[SENSOR_ADCM1700] = (1 << AUTOGAIN) |
Németh Márton76ad3b62010-10-19 03:33:47 -0300286 (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300287 (1 << VFLIP) |
288 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300289
Jean-François Moine3afef852011-01-13 06:39:11 -0300290[SENSOR_GC0307] = (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300291 (1 << VFLIP) |
292 (1 << FREQ),
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300293
Jean-François Moine3afef852011-01-13 06:39:11 -0300294[SENSOR_HV7131R] = (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300295 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300296
Jean-François Moine3afef852011-01-13 06:39:11 -0300297[SENSOR_MI0360] = (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300298 (1 << VFLIP) |
299 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300300
Jean-François Moine3afef852011-01-13 06:39:11 -0300301[SENSOR_MI0360B] = (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300302 (1 << VFLIP) |
303 (1 << FREQ),
Jean-François Moinea067db82010-10-01 07:51:24 -0300304
Jean-François Moine3afef852011-01-13 06:39:11 -0300305[SENSOR_MO4000] = (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300306 (1 << VFLIP) |
307 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300308
Németh Márton76ad3b62010-10-19 03:33:47 -0300309[SENSOR_MT9V111] = (1 << HFLIP) |
310 (1 << VFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300311 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300312
Jean-François Moine3afef852011-01-13 06:39:11 -0300313[SENSOR_OM6802] = (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300314 (1 << VFLIP) |
315 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300316
Jean-François Moine3afef852011-01-13 06:39:11 -0300317[SENSOR_OV7630] = (1 << HFLIP),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300318
Jean-François Moine3afef852011-01-13 06:39:11 -0300319[SENSOR_OV7648] = (1 << HFLIP),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300320
Jean-François Moine72b667e2010-10-02 04:35:25 -0300321[SENSOR_OV7660] = (1 << AUTOGAIN) |
Németh Márton76ad3b62010-10-19 03:33:47 -0300322 (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300323 (1 << VFLIP),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300324
Jean-François Moine72b667e2010-10-02 04:35:25 -0300325[SENSOR_PO1030] = (1 << AUTOGAIN) |
Németh Márton76ad3b62010-10-19 03:33:47 -0300326 (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300327 (1 << VFLIP) |
328 (1 << FREQ),
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300329
Jean-François Moine72b667e2010-10-02 04:35:25 -0300330[SENSOR_PO2030N] = (1 << AUTOGAIN) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300331 (1 << FREQ),
Jean-François Moine780e3122010-10-19 04:29:10 -0300332
Jean-François Moine72b667e2010-10-02 04:35:25 -0300333[SENSOR_SOI768] = (1 << AUTOGAIN) |
Németh Márton76ad3b62010-10-19 03:33:47 -0300334 (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300335 (1 << VFLIP) |
336 (1 << FREQ),
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300337
Jean-François Moine72b667e2010-10-02 04:35:25 -0300338[SENSOR_SP80708] = (1 << AUTOGAIN) |
Németh Márton76ad3b62010-10-19 03:33:47 -0300339 (1 << HFLIP) |
Jean-François Moine72b667e2010-10-02 04:35:25 -0300340 (1 << VFLIP) |
341 (1 << FREQ),
Jean-Francois Moine577cbf42008-12-05 06:18:37 -0300342};
343
Jean-Francois Moine646775732009-12-20 12:31:28 -0300344static const struct v4l2_pix_format cif_mode[] = {
345 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
346 .bytesperline = 352,
347 .sizeimage = 352 * 288 * 4 / 8 + 590,
348 .colorspace = V4L2_COLORSPACE_JPEG,
349 .priv = 0},
350};
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300351static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300352 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
353 .bytesperline = 160,
Jean-Francois Moine5d052942008-09-03 16:48:09 -0300354 .sizeimage = 160 * 120 * 4 / 8 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300355 .colorspace = V4L2_COLORSPACE_JPEG,
356 .priv = 2},
357 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
358 .bytesperline = 320,
359 .sizeimage = 320 * 240 * 3 / 8 + 590,
360 .colorspace = V4L2_COLORSPACE_JPEG,
361 .priv = 1},
362 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
363 .bytesperline = 640,
Hans de Goedea5d1cc32009-06-18 06:03:20 -0300364 /* Note 3 / 8 is not large enough, not even 5 / 8 is ?! */
365 .sizeimage = 640 * 480 * 3 / 4 + 590,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300366 .colorspace = V4L2_COLORSPACE_JPEG,
367 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300368};
369
Jean-Francois Moine646775732009-12-20 12:31:28 -0300370static const u8 sn_adcm1700[0x1c] = {
371/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300372 0x00, 0x43, 0x60, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine646775732009-12-20 12:31:28 -0300373/* reg8 reg9 rega regb regc regd rege regf */
374 0x80, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
375/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
376 0x03, 0x00, 0x05, 0x01, 0x05, 0x16, 0x12, 0x42,
377/* reg18 reg19 reg1a reg1b */
378 0x06, 0x00, 0x00, 0x00
379};
380
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300381static const u8 sn_gc0307[0x1c] = {
382/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
383 0x00, 0x61, 0x62, 0x00, 0x1a, 0x00, 0x00, 0x00,
384/* reg8 reg9 rega regb regc regd rege regf */
385 0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
386/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
387 0x03, 0x00, 0x03, 0x01, 0x08, 0x28, 0x1e, 0x02,
388/* reg18 reg19 reg1a reg1b */
389 0x06, 0x00, 0x00, 0x00
390};
391
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300392static const u8 sn_hv7131[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300393/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-François Moine19697b52010-07-14 06:33:51 -0300394 0x00, 0x03, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300395/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300396 0x81, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300397/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
398 0x03, 0x00, 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300399/* reg18 reg19 reg1a reg1b */
400 0x0a, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300401};
402
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300403static const u8 sn_mi0360[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300404/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-François Moine19697b52010-07-14 06:33:51 -0300405 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300406/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300407 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300408/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
409 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300410/* reg18 reg19 reg1a reg1b */
411 0x06, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300412};
413
Jean-François Moinea067db82010-10-01 07:51:24 -0300414static const u8 sn_mi0360b[0x1c] = {
415/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
416 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
417/* reg8 reg9 rega regb regc regd rege regf */
418 0x81, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
420 0x03, 0x00, 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x40,
421/* reg18 reg19 reg1a reg1b */
422 0x06, 0x00, 0x00, 0x00
423};
424
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300425static const u8 sn_mo4000[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300426/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300427 0x00, 0x23, 0x60, 0x00, 0x1a, 0x00, 0x20, 0x18,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300428/* reg8 reg9 rega regb regc regd rege regf */
429 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
430/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
431 0x03, 0x00, 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300432/* reg18 reg19 reg1a reg1b */
433 0x08, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300434};
435
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300436static const u8 sn_mt9v111[0x1c] = {
437/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
438 0x00, 0x61, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
439/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300440 0x81, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300441/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
442 0x03, 0x00, 0x00, 0x02, 0x1c, 0x28, 0x1e, 0x40,
443/* reg18 reg19 reg1a reg1b */
444 0x06, 0x00, 0x00, 0x00
445};
446
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300447static const u8 sn_om6802[0x1c] = {
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300448/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Amauri Magagna46b4f2a2009-10-17 07:21:29 -0300449 0x00, 0x23, 0x72, 0x00, 0x1a, 0x20, 0x20, 0x19,
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300450/* reg8 reg9 rega regb regc regd rege regf */
451 0x80, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
452/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
453 0x03, 0x00, 0x51, 0x01, 0x00, 0x28, 0x1e, 0x40,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300454/* reg18 reg19 reg1a reg1b */
455 0x05, 0x00, 0x00, 0x00
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300456};
457
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300458static const u8 sn_ov7630[0x1c] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300459/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-François Moine0a85c742010-04-25 14:33:31 -0300460 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300461/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300462 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300463/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
464 0x03, 0x00, 0x04, 0x01, 0x0a, 0x28, 0x1e, 0xc2,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300465/* reg18 reg19 reg1a reg1b */
466 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300467};
468
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300469static const u8 sn_ov7648[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300470/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300471 0x00, 0x63, 0x40, 0x00, 0x1a, 0x20, 0x20, 0x20,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300472/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300473 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300474/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300475 0x03, 0x00, 0x00, 0x01, 0x00, 0x28, 0x1e, 0x00,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300476/* reg18 reg19 reg1a reg1b */
477 0x0b, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300478};
479
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300480static const u8 sn_ov7660[0x1c] = {
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300481/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -0300482 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300483/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -0300484 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -0300485/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
486 0x03, 0x00, 0x01, 0x01, 0x08, 0x28, 0x1e, 0x20,
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300487/* reg18 reg19 reg1a reg1b */
488 0x07, 0x00, 0x00, 0x00
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300489};
490
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -0300491static const u8 sn_po1030[0x1c] = {
492/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
493 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20,
494/* reg8 reg9 rega regb regc regd rege regf */
495 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
496/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
497 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1e, 0x00,
498/* reg18 reg19 reg1a reg1b */
499 0x07, 0x00, 0x00, 0x00
500};
501
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300502static const u8 sn_po2030n[0x1c] = {
503/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
504 0x00, 0x63, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
505/* reg8 reg9 rega regb regc regd rege regf */
506 0x81, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
507/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
508 0x03, 0x00, 0x00, 0x01, 0x14, 0x28, 0x1e, 0x00,
509/* reg18 reg19 reg1a reg1b */
510 0x07, 0x00, 0x00, 0x00
511};
512
Jean-François Moine03ed2a12010-04-25 14:45:43 -0300513static const u8 sn_soi768[0x1c] = {
514/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
515 0x00, 0x21, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00,
516/* reg8 reg9 rega regb regc regd rege regf */
517 0x81, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
518/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
519 0x03, 0x00, 0x00, 0x01, 0x08, 0x28, 0x1e, 0x00,
520/* reg18 reg19 reg1a reg1b */
521 0x07, 0x00, 0x00, 0x00
522};
523
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300524static const u8 sn_sp80708[0x1c] = {
525/* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 */
526 0x00, 0x63, 0x60, 0x00, 0x1a, 0x20, 0x20, 0x20,
527/* reg8 reg9 rega regb regc regd rege regf */
Jean-Francois Moine98941e42009-11-02 09:56:59 -0300528 0x81, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -0300529/* reg10 reg11 reg12 reg13 reg14 reg15 reg16 reg17 */
530 0x03, 0x00, 0x00, 0x03, 0x04, 0x28, 0x1e, 0x00,
531/* reg18 reg19 reg1a reg1b */
532 0x07, 0x00, 0x00, 0x00
533};
534
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300535/* sequence specific to the sensors - !! index = SENSOR_xxx */
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300536static const u8 *sn_tb[] = {
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300537[SENSOR_ADCM1700] = sn_adcm1700,
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300538[SENSOR_GC0307] = sn_gc0307,
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300539[SENSOR_HV7131R] = sn_hv7131,
540[SENSOR_MI0360] = sn_mi0360,
Jean-François Moinea067db82010-10-01 07:51:24 -0300541[SENSOR_MI0360B] = sn_mi0360b,
Jean-François Moine9c33afc2010-03-17 15:25:32 -0300542[SENSOR_MO4000] = sn_mo4000,
543[SENSOR_MT9V111] = sn_mt9v111,
544[SENSOR_OM6802] = sn_om6802,
545[SENSOR_OV7630] = sn_ov7630,
546[SENSOR_OV7648] = sn_ov7648,
547[SENSOR_OV7660] = sn_ov7660,
548[SENSOR_PO1030] = sn_po1030,
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300549[SENSOR_PO2030N] = sn_po2030n,
Jean-François Moine03ed2a12010-04-25 14:45:43 -0300550[SENSOR_SOI768] = sn_soi768,
551[SENSOR_SP80708] = sn_sp80708,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300552};
553
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300554/* default gamma table */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300555static const u8 gamma_def[17] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300556 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
557 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
558};
Jean-Francois Moine646775732009-12-20 12:31:28 -0300559/* gamma for sensor ADCM1700 */
560static const u8 gamma_spec_0[17] = {
561 0x0f, 0x39, 0x5a, 0x74, 0x86, 0x95, 0xa6, 0xb4,
562 0xbd, 0xc4, 0xcc, 0xd4, 0xd5, 0xde, 0xe4, 0xed, 0xf5
563};
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300564/* gamma for sensors HV7131R and MT9V111 */
565static const u8 gamma_spec_1[17] = {
566 0x08, 0x3a, 0x52, 0x65, 0x75, 0x83, 0x91, 0x9d,
567 0xa9, 0xb4, 0xbe, 0xc8, 0xd2, 0xdb, 0xe4, 0xed, 0xf5
568};
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300569/* gamma for sensor GC0307 */
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300570static const u8 gamma_spec_2[17] = {
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300571 0x14, 0x37, 0x50, 0x6a, 0x7c, 0x8d, 0x9d, 0xab,
572 0xb5, 0xbf, 0xc2, 0xcb, 0xd1, 0xd6, 0xdb, 0xe1, 0xeb
573};
574/* gamma for sensor SP80708 */
575static const u8 gamma_spec_3[17] = {
Jean-Francois Moineb083b922009-02-01 14:20:07 -0300576 0x0a, 0x2d, 0x4e, 0x68, 0x7d, 0x8f, 0x9f, 0xab,
577 0xb7, 0xc2, 0xcc, 0xd3, 0xd8, 0xde, 0xe2, 0xe5, 0xe6
578};
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -0300579
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300580/* color matrix and offsets */
Jean-Francois Moine98819182009-01-19 07:37:33 -0300581static const u8 reg84[] = {
Jean-Francois Moine803f9cc2008-10-04 14:17:02 -0300582 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, /* YR YG YB gains */
583 0xe8, 0x0f, 0xda, 0x0f, 0x40, 0x00, /* UR UG UB */
584 0x3e, 0x00, 0xcd, 0x0f, 0xf7, 0x0f, /* VR VG VB */
585 0x00, 0x00, 0x00 /* YUV offsets */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300586};
Németh Mártonccbc5df2010-10-18 07:00:48 -0300587
588#define DELAY 0xdd
589
Jean-Francois Moine646775732009-12-20 12:31:28 -0300590static const u8 adcm1700_sensor_init[][8] = {
591 {0xa0, 0x51, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300592 {0xb0, 0x51, 0x04, 0x08, 0x00, 0x00, 0x00, 0x10}, /* reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -0300593 {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300594 {0xb0, 0x51, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300595 {DELAY, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300596 {0xb0, 0x51, 0x0c, 0xe0, 0x2e, 0x00, 0x00, 0x10},
597 {0xb0, 0x51, 0x10, 0x02, 0x02, 0x00, 0x00, 0x10},
598 {0xb0, 0x51, 0x14, 0x0e, 0x0e, 0x00, 0x00, 0x10},
599 {0xb0, 0x51, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x10},
600 {0xb0, 0x51, 0x20, 0x01, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300601 {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300602 {0xb0, 0x51, 0x04, 0x04, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300603 {DELAY, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300604 {0xb0, 0x51, 0x04, 0x01, 0x00, 0x00, 0x00, 0x10},
605 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
606 {0xb0, 0x51, 0x14, 0x01, 0x00, 0x00, 0x00, 0x10},
607 {0xb0, 0x51, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
608 {}
609};
610static const u8 adcm1700_sensor_param1[][8] = {
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300611 {0xb0, 0x51, 0x26, 0xf9, 0x01, 0x00, 0x00, 0x10}, /* exposure? */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300612 {0xd0, 0x51, 0x1e, 0x8e, 0x8e, 0x8e, 0x8e, 0x10},
613
614 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
615 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
616 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
617 {0xb0, 0x51, 0x32, 0x00, 0x72, 0x00, 0x00, 0x10},
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300618 {0xd0, 0x51, 0x1e, 0xbe, 0xd7, 0xe8, 0xbe, 0x10}, /* exposure? */
Jean-Francois Moine646775732009-12-20 12:31:28 -0300619
Jean-Francois Moine878b35a2009-12-30 04:53:07 -0300620 {0xa0, 0x51, 0xfe, 0x01, 0x00, 0x00, 0x00, 0x10},
621 {0xb0, 0x51, 0x00, 0x02, 0x00, 0x00, 0x00, 0x10},
622 {0xa0, 0x51, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x10},
623 {0xb0, 0x51, 0x32, 0x00, 0xa2, 0x00, 0x00, 0x10},
Jean-Francois Moine646775732009-12-20 12:31:28 -0300624 {}
625};
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300626static const u8 gc0307_sensor_init[][8] = {
627 {0xa0, 0x21, 0x43, 0x00, 0x00, 0x00, 0x00, 0x10},
628 {0xa0, 0x21, 0x44, 0xa2, 0x00, 0x00, 0x00, 0x10},
629 {0xa0, 0x21, 0x01, 0x6a, 0x00, 0x00, 0x00, 0x10},
630 {0xa0, 0x21, 0x02, 0x70, 0x00, 0x00, 0x00, 0x10},
631 {0xa0, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
632 {0xa0, 0x21, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
633 {0xa0, 0x21, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
634 {0xa0, 0x21, 0x11, 0x05, 0x00, 0x00, 0x00, 0x10},
635 {0xa0, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
636 {0xa0, 0x21, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
637 {0xa0, 0x21, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10},
638 {0xa0, 0x21, 0x08, 0x02, 0x00, 0x00, 0x00, 0x10},
639 {0xa0, 0x21, 0x09, 0x01, 0x00, 0x00, 0x00, 0x10},
640 {0xa0, 0x21, 0x0a, 0xe8, 0x00, 0x00, 0x00, 0x10},
641 {0xa0, 0x21, 0x0b, 0x02, 0x00, 0x00, 0x00, 0x10},
642 {0xa0, 0x21, 0x0c, 0x80, 0x00, 0x00, 0x00, 0x10},
643 {0xa0, 0x21, 0x0d, 0x22, 0x00, 0x00, 0x00, 0x10},
644 {0xa0, 0x21, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x10},
645 {0xa0, 0x21, 0x0f, 0xb2, 0x00, 0x00, 0x00, 0x10},
646 {0xa0, 0x21, 0x12, 0x70, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300647 {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 10ms*/
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300648 {0xa0, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00, 0x10},
649 {0xa0, 0x21, 0x15, 0xb8, 0x00, 0x00, 0x00, 0x10},
650 {0xa0, 0x21, 0x16, 0x13, 0x00, 0x00, 0x00, 0x10},
651 {0xa0, 0x21, 0x17, 0x52, 0x00, 0x00, 0x00, 0x10},
652 {0xa0, 0x21, 0x18, 0x50, 0x00, 0x00, 0x00, 0x10},
653 {0xa0, 0x21, 0x1e, 0x0d, 0x00, 0x00, 0x00, 0x10},
654 {0xa0, 0x21, 0x1f, 0x32, 0x00, 0x00, 0x00, 0x10},
655 {0xa0, 0x21, 0x61, 0x90, 0x00, 0x00, 0x00, 0x10},
656 {0xa0, 0x21, 0x63, 0x70, 0x00, 0x00, 0x00, 0x10},
657 {0xa0, 0x21, 0x65, 0x98, 0x00, 0x00, 0x00, 0x10},
658 {0xa0, 0x21, 0x67, 0x90, 0x00, 0x00, 0x00, 0x10},
659 {0xa0, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
660 {0xa0, 0x21, 0x04, 0x96, 0x00, 0x00, 0x00, 0x10},
661 {0xa0, 0x21, 0x45, 0x27, 0x00, 0x00, 0x00, 0x10},
662 {0xa0, 0x21, 0x47, 0x2c, 0x00, 0x00, 0x00, 0x10},
663 {0xa0, 0x21, 0x43, 0x47, 0x00, 0x00, 0x00, 0x10},
664 {0xa0, 0x21, 0x44, 0xd8, 0x00, 0x00, 0x00, 0x10},
665 {}
666};
667static const u8 gc0307_sensor_param1[][8] = {
668 {0xa0, 0x21, 0x68, 0x13, 0x00, 0x00, 0x00, 0x10},
669 {0xd0, 0x21, 0x61, 0x80, 0x00, 0x80, 0x00, 0x10},
670 {0xc0, 0x21, 0x65, 0x80, 0x00, 0x80, 0x00, 0x10},
671 {0xc0, 0x21, 0x63, 0xa0, 0x00, 0xa6, 0x00, 0x10},
672/*param3*/
673 {0xa0, 0x21, 0x01, 0x6e, 0x00, 0x00, 0x00, 0x10},
674 {0xa0, 0x21, 0x02, 0x88, 0x00, 0x00, 0x00, 0x10},
Jean-François Moinead98c0f2010-03-18 05:15:30 -0300675 {}
676};
677
Jean-Francois Moine98819182009-01-19 07:37:33 -0300678static const u8 hv7131r_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300679 {0xc1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
680 {0xb1, 0x11, 0x34, 0x17, 0x7f, 0x00, 0x00, 0x10},
681 {0xd1, 0x11, 0x40, 0xff, 0x7f, 0x7f, 0x7f, 0x10},
682/* {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10}, */
683 {0xd1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
684 {0xd1, 0x11, 0x14, 0x01, 0xe2, 0x02, 0x82, 0x10},
685/* {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300687 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
688 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
689 {0xc1, 0x11, 0x25, 0x00, 0x61, 0xa8, 0x00, 0x10},
690 {0xa1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
691 {0xc1, 0x11, 0x31, 0x20, 0x2e, 0x20, 0x00, 0x10},
692 {0xc1, 0x11, 0x25, 0x00, 0xc3, 0x50, 0x00, 0x10},
693 {0xa1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
694 {0xc1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300695
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300696 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
697 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -0300698 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300699 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
700 {0xa1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300701
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300702 {0xa1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
703 {0xa1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
704 {0xa1, 0x11, 0x21, 0xd0, 0x00, 0x00, 0x00, 0x10},
705 {0xa1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
706 {0xa1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine23a98272009-11-02 09:10:25 -0300707 {0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10},
708 /* set sensor clock */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300709 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300710};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300711static const u8 mi0360_sensor_init[][8] = {
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300712 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300713 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300714 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300715 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
716 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
717 {0xd1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
718 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
719 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
720 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
721 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
722 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
723 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
724 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
725 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
726 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
727 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
728 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
729 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
730 {0xd1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
731 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
732 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
733 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
Jean-Francois Moine98819182009-01-19 07:37:33 -0300734 {0xd1, 0x5d, 0x2f, 0xf7, 0xB0, 0x00, 0x04, 0x10},
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300735 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
736 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
737 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
738 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
739 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
740 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
741 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
742 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
743 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
744 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300745
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300746 {0xb1, 0x5d, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
747 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
748 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
749 {0xd1, 0x5d, 0x2b, 0x00, 0xa0, 0x00, 0xb0, 0x10},
750 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0xa0, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300752 {0xb1, 0x5d, 0x0a, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
753 {0xb1, 0x5d, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
754 {0xb1, 0x5d, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10},
755 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300756
Jean-Francois Moine8c2ba442009-01-13 05:55:40 -0300757 {0xd1, 0x5d, 0x2b, 0x00, 0xb9, 0x00, 0xe3, 0x10},
758 {0xd1, 0x5d, 0x2d, 0x00, 0x5f, 0x00, 0xb9, 0x10}, /* 42 */
759/* {0xb1, 0x5d, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
760/* {0xb1, 0x5d, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
761 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
762 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300763 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300764};
Jean-François Moinea067db82010-10-01 07:51:24 -0300765static const u8 mi0360b_sensor_init[][8] = {
766 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
767 {0xb1, 0x5d, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300768 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
Jean-François Moinea067db82010-10-01 07:51:24 -0300769 {0xb1, 0x5d, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300770 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /*delay 20ms*/
Jean-François Moinea067db82010-10-01 07:51:24 -0300771 {0xd1, 0x5d, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
772 {0xd1, 0x5d, 0x03, 0x01, 0xe2, 0x02, 0x82, 0x10},
773 {0xd1, 0x5d, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
774 {0xb1, 0x5d, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x10},
775 {0xd1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
776 {0xd1, 0x5d, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10},
777 {0xd1, 0x5d, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
778 {0xd1, 0x5d, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
779 {0xd1, 0x5d, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
780 {0xd1, 0x5d, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
781 {0xd1, 0x5d, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
782 {0xd1, 0x5d, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
783 {0xd1, 0x5d, 0x1a, 0x00, 0x00, 0x00, 0x00, 0x10},
784 {0xd1, 0x5d, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x10},
785 {0xb1, 0x5d, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
786 {0xd1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
787 {0xd1, 0x5d, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
788 {0xd1, 0x5d, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
789 {0xd1, 0x5d, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
790 {0xd1, 0x5d, 0x2f, 0xf7, 0xb0, 0x00, 0x04, 0x10},
791 {0xd1, 0x5d, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
792 {0xd1, 0x5d, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
793 {0xb1, 0x5d, 0x3d, 0x06, 0x8f, 0x00, 0x00, 0x10},
794 {0xd1, 0x5d, 0x40, 0x01, 0xe0, 0x00, 0xd1, 0x10},
795 {0xb1, 0x5d, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
796 {0xd1, 0x5d, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
797 {0xd1, 0x5d, 0x5a, 0x00, 0x00, 0x00, 0x00, 0x10},
798 {0xd1, 0x5d, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x10},
799 {0xd1, 0x5d, 0x5e, 0x00, 0x00, 0xa3, 0x1d, 0x10},
800 {0xb1, 0x5d, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
801
802 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
803 {0xb1, 0x5d, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
804 {0xb1, 0x5d, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
805 {0xd1, 0x5d, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10},
806 {0xd1, 0x5d, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10},
807 {}
808};
809static const u8 mi0360b_sensor_param1[][8] = {
810 {0xb1, 0x5d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
811 {0xb1, 0x5d, 0x06, 0x00, 0x53, 0x00, 0x00, 0x10},
812 {0xb1, 0x5d, 0x05, 0x00, 0x09, 0x00, 0x00, 0x10},
813 {0xb1, 0x5d, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
814
815 {0xd1, 0x5d, 0x2b, 0x00, 0xd1, 0x01, 0xc9, 0x10},
816 {0xd1, 0x5d, 0x2d, 0x00, 0xed, 0x00, 0xd1, 0x10},
817 {0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
818 {0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
819 {}
820};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300821static const u8 mo4000_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
823 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
824 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
825 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
826 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
827 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
828 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
829 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
830 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
831 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
832 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
833 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
834 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
835 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
836 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
837 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
838 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
839 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
840 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
841 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300842 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300843};
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300844static const u8 mt9v111_sensor_init[][8] = {
845 {0xb1, 0x5c, 0x0d, 0x00, 0x01, 0x00, 0x00, 0x10}, /* reset? */
Németh Mártonccbc5df2010-10-18 07:00:48 -0300846 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300847 {0xb1, 0x5c, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x10},
848 {0xb1, 0x5c, 0x01, 0x00, 0x01, 0x00, 0x00, 0x10}, /* IFP select */
849 {0xb1, 0x5c, 0x08, 0x04, 0x80, 0x00, 0x00, 0x10}, /* output fmt ctrl */
850 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10}, /* op mode ctrl */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300851 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
852 {0xb1, 0x5c, 0x03, 0x01, 0xe1, 0x00, 0x00, 0x10},
853 {0xb1, 0x5c, 0x04, 0x02, 0x81, 0x00, 0x00, 0x10},
854 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300855 {0xb1, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10}, /* sensor select */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300856 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10},
857 {0xb1, 0x5c, 0x03, 0x01, 0xe6, 0x00, 0x00, 0x10},
858 {0xb1, 0x5c, 0x04, 0x02, 0x86, 0x00, 0x00, 0x10},
859 {0xb1, 0x5c, 0x05, 0x00, 0x04, 0x00, 0x00, 0x10},
860 {0xb1, 0x5c, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300861 {0xb1, 0x5c, 0x08, 0x00, 0x08, 0x00, 0x00, 0x10}, /* row start */
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300862 {0xb1, 0x5c, 0x0e, 0x00, 0x08, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300863 {0xb1, 0x5c, 0x02, 0x00, 0x16, 0x00, 0x00, 0x10}, /* col start */
864 {0xb1, 0x5c, 0x03, 0x01, 0xe7, 0x00, 0x00, 0x10}, /* window height */
865 {0xb1, 0x5c, 0x04, 0x02, 0x87, 0x00, 0x00, 0x10}, /* window width */
866 {0xb1, 0x5c, 0x07, 0x30, 0x02, 0x00, 0x00, 0x10}, /* output ctrl */
867 {0xb1, 0x5c, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x10}, /* shutter delay */
868 {0xb1, 0x5c, 0x12, 0x00, 0xb0, 0x00, 0x00, 0x10}, /* zoom col start */
869 {0xb1, 0x5c, 0x13, 0x00, 0x7c, 0x00, 0x00, 0x10}, /* zoom row start */
870 {0xb1, 0x5c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* digital zoom */
871 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10}, /* read mode */
872 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300873 {}
874};
875static const u8 mt9v111_sensor_param1[][8] = {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300876 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
877 {0xb1, 0x5c, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine2687a2f2009-02-01 14:48:55 -0300878 {0xb1, 0x5c, 0x09, 0x01, 0x2c, 0x00, 0x00, 0x10},
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -0300879 {0xd1, 0x5c, 0x2b, 0x00, 0x33, 0x00, 0xa0, 0x10}, /* green1 gain */
880 {0xd1, 0x5c, 0x2d, 0x00, 0xa0, 0x00, 0x33, 0x10}, /* red gain */
881 /*******/
882 {0xb1, 0x5c, 0x06, 0x00, 0x1e, 0x00, 0x00, 0x10}, /* vert blanking */
883 {0xb1, 0x5c, 0x05, 0x00, 0x0a, 0x00, 0x00, 0x10}, /* horiz blanking */
884 {0xd1, 0x5c, 0x2c, 0x00, 0xad, 0x00, 0xad, 0x10}, /* blue gain */
885 {0xb1, 0x5c, 0x35, 0x01, 0xc0, 0x00, 0x00, 0x10}, /* global gain */
886 {}
887};
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300888static const u8 om6802_init0[2][8] = {
889/*fixme: variable*/
890 {0xa0, 0x34, 0x29, 0x0e, 0x00, 0x00, 0x00, 0x10},
891 {0xa0, 0x34, 0x23, 0xb0, 0x00, 0x00, 0x00, 0x10},
892};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300893static const u8 om6802_sensor_init[][8] = {
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300894 {0xa0, 0x34, 0xdf, 0x6d, 0x00, 0x00, 0x00, 0x10},
895 /* factory mode */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300896 {0xa0, 0x34, 0xdd, 0x18, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300897 /* output raw RGB */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300898 {0xa0, 0x34, 0x5a, 0xc0, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300899/* {0xa0, 0x34, 0xfb, 0x11, 0x00, 0x00, 0x00, 0x10}, */
900 {0xa0, 0x34, 0xf0, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300901 /* auto-exposure speed (0) / white balance mode (auto RGB) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300902/* {0xa0, 0x34, 0xf1, 0x02, 0x00, 0x00, 0x00, 0x10},
903 * set color mode */
904/* {0xa0, 0x34, 0xfe, 0x5b, 0x00, 0x00, 0x00, 0x10},
905 * max AGC value in AE */
906/* {0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10},
907 * preset AGC */
908/* {0xa0, 0x34, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x10},
909 * preset brightness */
910/* {0xa0, 0x34, 0xe7, 0x00, 0x00, 0x00, 0x00, 0x10},
911 * preset contrast */
912/* {0xa0, 0x34, 0xe8, 0x31, 0x00, 0x00, 0x00, 0x10},
913 * preset gamma */
914 {0xa0, 0x34, 0xe9, 0x0f, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -0300915 /* luminance mode (0x4f -> AutoExpo on) */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300916 {0xa0, 0x34, 0xe4, 0xff, 0x00, 0x00, 0x00, 0x10},
917 /* preset shutter */
918/* {0xa0, 0x34, 0xef, 0x00, 0x00, 0x00, 0x00, 0x10},
919 * auto frame rate */
920/* {0xa0, 0x34, 0xfb, 0xee, 0x00, 0x00, 0x00, 0x10}, */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -0300921 {0xa0, 0x34, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
922 {}
923};
924static const u8 om6802_sensor_param1[][8] = {
925 {0xa0, 0x34, 0x71, 0x84, 0x00, 0x00, 0x00, 0x10},
926 {0xa0, 0x34, 0x72, 0x05, 0x00, 0x00, 0x00, 0x10},
927 {0xa0, 0x34, 0x68, 0x80, 0x00, 0x00, 0x00, 0x10},
928 {0xa0, 0x34, 0x69, 0x01, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moined2d16e92008-09-03 16:47:23 -0300929 {}
930};
Jean-Francois Moine98819182009-01-19 07:37:33 -0300931static const u8 ov7630_sensor_init[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300932 {0xa1, 0x21, 0x76, 0x01, 0x00, 0x00, 0x00, 0x10},
933 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300934 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300935 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
936 {0xa1, 0x21, 0x12, 0xc8, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -0300937 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300938 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300939/* win: i2c_r from 00 to 80 */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300940 {0xd1, 0x21, 0x03, 0x80, 0x10, 0x20, 0x80, 0x10},
941 {0xb1, 0x21, 0x0c, 0x20, 0x20, 0x00, 0x00, 0x10},
Hans de Goedecc7b5b52009-06-18 05:14:42 -0300942/* HDG: 0x11 was 0x00 change to 0x01 for better exposure (15 fps instead of 30)
943 0x13 was 0xc0 change to 0xc3 for auto gain and exposure */
944 {0xd1, 0x21, 0x11, 0x01, 0x48, 0xc3, 0x00, 0x10},
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300945 {0xb1, 0x21, 0x15, 0x80, 0x03, 0x00, 0x00, 0x10},
946 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
947 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
948 {0xd1, 0x21, 0x1f, 0x00, 0x80, 0x80, 0x80, 0x10},
949 {0xd1, 0x21, 0x23, 0xde, 0x10, 0x8a, 0xa0, 0x10},
950 {0xc1, 0x21, 0x27, 0xca, 0xa2, 0x74, 0x00, 0x10},
951 {0xd1, 0x21, 0x2a, 0x88, 0x00, 0x88, 0x01, 0x10},
952 {0xc1, 0x21, 0x2e, 0x80, 0x00, 0x18, 0x00, 0x10},
953 {0xa1, 0x21, 0x21, 0x08, 0x00, 0x00, 0x00, 0x10},
954 {0xa1, 0x21, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
955 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
956 {0xb1, 0x21, 0x32, 0xc2, 0x08, 0x00, 0x00, 0x10},
957 {0xb1, 0x21, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x10},
958 {0xd1, 0x21, 0x60, 0x05, 0x40, 0x12, 0x57, 0x10},
959 {0xa1, 0x21, 0x64, 0x73, 0x00, 0x00, 0x00, 0x10},
960 {0xd1, 0x21, 0x65, 0x00, 0x55, 0x01, 0xac, 0x10},
961 {0xa1, 0x21, 0x69, 0x38, 0x00, 0x00, 0x00, 0x10},
962 {0xd1, 0x21, 0x6f, 0x1f, 0x01, 0x00, 0x10, 0x10},
963 {0xd1, 0x21, 0x73, 0x50, 0x20, 0x02, 0x01, 0x10},
964 {0xd1, 0x21, 0x77, 0xf3, 0x90, 0x98, 0x98, 0x10},
965 {0xc1, 0x21, 0x7b, 0x00, 0x4c, 0xf7, 0x00, 0x10},
966 {0xd1, 0x21, 0x17, 0x1b, 0xbd, 0x05, 0xf6, 0x10},
967 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
Jean-François Moinebdd2b932010-04-25 14:23:39 -0300968 {}
969};
970static const u8 ov7630_sensor_param1[][8] = {
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300971 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
972 {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10},
973/*fixme: + 0x12, 0x04*/
Jean-Francois Moine6c862742008-09-08 04:57:26 -0300974/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN
975 * set by setvflip */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300976 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
977 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
978 {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10},
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300979/* */
Hans de Goede37c6dbe2009-06-18 07:35:36 -0300980/* {0xa1, 0x21, 0x2a, 0x88, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
981/* {0xa1, 0x21, 0x2b, 0x34, 0x00, 0x00, 0x00, 0x10}, * set by setfreq */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -0300982/* */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300983 {0xa1, 0x21, 0x10, 0x83, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine91de65a2008-09-03 17:12:18 -0300984/* {0xb1, 0x21, 0x01, 0x88, 0x70, 0x00, 0x00, 0x10}, */
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -0300985 {}
986};
Jean-Francois Moine62703302008-11-11 08:42:56 -0300987
Jean-Francois Moine98819182009-01-19 07:37:33 -0300988static const u8 ov7648_sensor_init[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -0300989 {0xa1, 0x21, 0x76, 0x00, 0x00, 0x00, 0x00, 0x10},
990 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -0300991 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine62703302008-11-11 08:42:56 -0300992 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
993 {0xd1, 0x21, 0x03, 0xa4, 0x30, 0x88, 0x00, 0x10},
994 {0xb1, 0x21, 0x11, 0x80, 0x08, 0x00, 0x00, 0x10},
995 {0xc1, 0x21, 0x13, 0xa0, 0x04, 0x84, 0x00, 0x10},
996 {0xd1, 0x21, 0x17, 0x1a, 0x02, 0xba, 0xf4, 0x10},
997 {0xa1, 0x21, 0x1b, 0x04, 0x00, 0x00, 0x00, 0x10},
998 {0xd1, 0x21, 0x1f, 0x41, 0xc0, 0x80, 0x80, 0x10},
999 {0xd1, 0x21, 0x23, 0xde, 0xa0, 0x80, 0x32, 0x10},
1000 {0xd1, 0x21, 0x27, 0xfe, 0xa0, 0x00, 0x91, 0x10},
1001 {0xd1, 0x21, 0x2b, 0x00, 0x88, 0x85, 0x80, 0x10},
1002 {0xc1, 0x21, 0x2f, 0x9c, 0x00, 0xc4, 0x00, 0x10},
1003 {0xd1, 0x21, 0x60, 0xa6, 0x60, 0x88, 0x12, 0x10},
1004 {0xd1, 0x21, 0x64, 0x88, 0x00, 0x00, 0x94, 0x10},
1005 {0xd1, 0x21, 0x68, 0x7a, 0x0c, 0x00, 0x00, 0x10},
1006 {0xd1, 0x21, 0x6c, 0x11, 0x33, 0x22, 0x00, 0x10},
1007 {0xd1, 0x21, 0x70, 0x11, 0x00, 0x10, 0x50, 0x10},
1008 {0xd1, 0x21, 0x74, 0x20, 0x06, 0x00, 0xb5, 0x10},
1009 {0xd1, 0x21, 0x78, 0x8a, 0x00, 0x00, 0x00, 0x10},
1010 {0xb1, 0x21, 0x7c, 0x00, 0x43, 0x00, 0x00, 0x10},
1011
1012 {0xd1, 0x21, 0x21, 0x86, 0x00, 0xde, 0xa0, 0x10},
1013/* {0xd1, 0x21, 0x25, 0x80, 0x32, 0xfe, 0xa0, 0x10}, jfm done */
1014/* {0xd1, 0x21, 0x29, 0x00, 0x91, 0x00, 0x88, 0x10}, jfm done */
Hans de Goede37c6dbe2009-06-18 07:35:36 -03001015/* {0xb1, 0x21, 0x2d, 0x85, 0x00, 0x00, 0x00, 0x10}, set by setfreq */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001016 {}
1017};
1018static const u8 ov7648_sensor_param1[][8] = {
Jean-Francois Moine62703302008-11-11 08:42:56 -03001019/* {0xa1, 0x21, 0x12, 0x08, 0x00, 0x00, 0x00, 0x10}, jfm done */
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03001020/* {0xa1, 0x21, 0x75, 0x06, 0x00, 0x00, 0x00, 0x10}, * COMN
1021 * set by setvflip */
Jean-Francois Moine62703302008-11-11 08:42:56 -03001022 {0xa1, 0x21, 0x19, 0x02, 0x00, 0x00, 0x00, 0x10},
1023 {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10},
1024/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1025/* {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, * GAIN - def */
1026/* {0xb1, 0x21, 0x01, 0x6c, 0x6c, 0x00, 0x00, 0x10}, * B R - def: 80 */
1027/*...*/
1028 {0xa1, 0x21, 0x11, 0x81, 0x00, 0x00, 0x00, 0x10}, /* CLKRC */
1029/* {0xa1, 0x21, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1030/* {0xa1, 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1031/* {0xa1, 0x21, 0x2a, 0x91, 0x00, 0x00, 0x00, 0x10}, jfm done */
1032/* {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, jfm done */
1033/* {0xb1, 0x21, 0x01, 0x64, 0x84, 0x00, 0x00, 0x10}, * B R - def: 80 */
1034
1035 {}
1036};
1037
Jean-Francois Moine98819182009-01-19 07:37:33 -03001038static const u8 ov7660_sensor_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001039 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
Németh Mártonccbc5df2010-10-18 07:00:48 -03001040 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001041 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001042 /* Outformat = rawRGB */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001043 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03001044 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001045 /* GAIN BLUE RED VREF */
1046 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
1047 /* COM 1 BAVE GEAVE AECHH */
1048 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
1049 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001050 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001051 /* AECH CLKRC COM7 COM8 */
1052 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
1053 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
1054 /* HSTART HSTOP VSTRT VSTOP */
1055 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
1056 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
1057 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
1058 /* BOS GBOS GROS ROS (BGGR offset) */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001059/* {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10}, */
1060 {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001061 /* AEW AEB VPT BBIAS */
1062 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
1063 /* GbBIAS RSVD EXHCH EXHCL */
1064 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
1065 /* RBIAS ADVFL ASDVFH YAVE */
1066 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
1067 /* HSYST HSYEN HREF */
1068 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
1069 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
1070 /* ADC ACOM OFON TSLB */
1071 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
1072 /* COM11 COM12 COM13 COM14 */
1073 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
1074 /* EDGE COM15 COM16 COM17 */
1075 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
1076 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
1077 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1078 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
1079 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
1080 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
1081 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
1082 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
1083 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
1084 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
1085 /* LCC1 LCC2 LCC3 LCC4 */
1086 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001087 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10}, /* MANU */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001088 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001089 /* band gap reference [0:3] DBLV */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001090 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
1091 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
1092 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
1093 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
1094 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
1095 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
1096 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
1097 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
1098 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001099 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10}, /* DM_LNL/H */
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001100/* not in all ms-win traces*/
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03001101 {0xa1, 0x21, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001102 {}
1103};
1104static const u8 ov7660_sensor_param1[][8] = {
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001105 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10}, /* MVFP */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001106 /* bits[3..0]reserved */
1107 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
1108 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
1109 /* VREF vertical frame ctrl */
1110 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001111 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* AECH 0x20 */
1112 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFL */
1113 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, /* ADVFH */
1114 {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, /* GAIN */
1115/* {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10}, * BLUE */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001116/****** (some exchanges in the win trace) ******/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001117/*fixme:param2*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001118 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001119 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10}, /* dummy line low */
1120 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCH */
1121 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* EXHCL */
1122/* {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10}, * RED */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001123/****** (some exchanges in the win trace) ******/
Jean-Francois Moine738608a2008-07-28 06:41:51 -03001124/******!! startsensor KO if changed !!****/
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001125/*fixme: param3*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001126 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
1127 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
1128 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
1129 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001130 {}
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001131};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001132
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001133static const u8 po1030_sensor_init[][8] = {
1134/* the sensor registers are described in m5602/m5602_po1030.h */
1135 {0xa1, 0x6e, 0x3f, 0x20, 0x00, 0x00, 0x00, 0x10}, /* sensor reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -03001136 {DELAY, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 20ms */
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001137 {0xa1, 0x6e, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x10},
1138 {0xa1, 0x6e, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x10},
1139 {0xd1, 0x6e, 0x04, 0x02, 0xb1, 0x02, 0x39, 0x10},
1140 {0xd1, 0x6e, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
1141 {0xd1, 0x6e, 0x0c, 0x02, 0x7f, 0x01, 0xe0, 0x10},
1142 {0xd1, 0x6e, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
1143 {0xd1, 0x6e, 0x16, 0x85, 0x40, 0x4a, 0x40, 0x10}, /* r/g1/b/g2 gains */
1144 {0xc1, 0x6e, 0x1a, 0x00, 0x80, 0x00, 0x00, 0x10},
1145 {0xd1, 0x6e, 0x1d, 0x08, 0x03, 0x00, 0x00, 0x10},
1146 {0xd1, 0x6e, 0x23, 0x00, 0xb0, 0x00, 0x94, 0x10},
1147 {0xd1, 0x6e, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
1148 {0xb1, 0x6e, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1149 {0xd1, 0x6e, 0x2d, 0x14, 0x35, 0x61, 0x84, 0x10}, /* gamma corr */
1150 {0xd1, 0x6e, 0x31, 0xa2, 0xbd, 0xd8, 0xff, 0x10},
1151 {0xd1, 0x6e, 0x35, 0x06, 0x1e, 0x12, 0x02, 0x10}, /* color matrix */
1152 {0xd1, 0x6e, 0x39, 0xaa, 0x53, 0x37, 0xd5, 0x10},
1153 {0xa1, 0x6e, 0x3d, 0xf2, 0x00, 0x00, 0x00, 0x10},
1154 {0xd1, 0x6e, 0x3e, 0x00, 0x00, 0x80, 0x03, 0x10},
1155 {0xd1, 0x6e, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
1156 {0xc1, 0x6e, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
1157 {0xd1, 0x6e, 0x4b, 0x02, 0xef, 0x08, 0xcd, 0x10},
1158 {0xd1, 0x6e, 0x4f, 0x00, 0xd0, 0x00, 0xa0, 0x10},
1159 {0xd1, 0x6e, 0x53, 0x01, 0xaa, 0x01, 0x40, 0x10},
1160 {0xd1, 0x6e, 0x5a, 0x50, 0x04, 0x30, 0x03, 0x10}, /* raw rgb bayer */
1161 {0xa1, 0x6e, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x10},
1162 {0xd1, 0x6e, 0x5f, 0x10, 0x40, 0xff, 0x00, 0x10},
1163
1164 {0xd1, 0x6e, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
1165 {0xd1, 0x6e, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
1166 {0xd1, 0x6e, 0x6b, 0x00, 0x00, 0x00, 0x00, 0x10},
1167 {0xd1, 0x6e, 0x6f, 0x00, 0x00, 0x00, 0x00, 0x10},
1168 {0xc1, 0x6e, 0x73, 0x10, 0x80, 0xeb, 0x00, 0x10},
1169 {}
1170};
1171static const u8 po1030_sensor_param1[][8] = {
1172/* from ms-win traces - these values change with auto gain/expo/wb.. */
1173 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1174 {0xa1, 0x6e, 0x1e, 0x03, 0x00, 0x00, 0x00, 0x10},
1175/* mean values */
1176 {0xc1, 0x6e, 0x1a, 0x02, 0xd4, 0xa4, 0x00, 0x10}, /* integlines */
1177 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10}, /* global gain */
1178 {0xc1, 0x6e, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10}, /* r/g1/b gains */
1179
1180 {0xa1, 0x6e, 0x1d, 0x08, 0x00, 0x00, 0x00, 0x10}, /* control1 */
1181 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10}, /* frameheight */
1182 {0xa1, 0x6e, 0x07, 0xd5, 0x00, 0x00, 0x00, 0x10},
1183/* {0xc1, 0x6e, 0x16, 0x49, 0x40, 0x45, 0x00, 0x10}, */
1184 {}
1185};
1186
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001187static const u8 po2030n_sensor_init[][8] = {
1188 {0xa1, 0x6e, 0x1e, 0x1a, 0x00, 0x00, 0x00, 0x10},
1189 {0xa1, 0x6e, 0x1f, 0x99, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001190 {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001191 {0xa1, 0x6e, 0x1e, 0x0a, 0x00, 0x00, 0x00, 0x10},
1192 {0xa1, 0x6e, 0x1f, 0x19, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001193 {DELAY, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 10ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001194 {0xa1, 0x6e, 0x20, 0x44, 0x00, 0x00, 0x00, 0x10},
1195 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1196 {0xa1, 0x6e, 0x05, 0x70, 0x00, 0x00, 0x00, 0x10},
1197 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1198 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1199 {0xd1, 0x6e, 0x08, 0x00, 0xd0, 0x00, 0x08, 0x10},
1200 {0xd1, 0x6e, 0x0c, 0x03, 0x50, 0x01, 0xe8, 0x10},
1201 {0xd1, 0x6e, 0x1d, 0x20, 0x0a, 0x19, 0x44, 0x10},
1202 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1203 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x00, 0x10},
1204 {0xd1, 0x6e, 0x29, 0x00, 0x00, 0x00, 0x00, 0x10},
1205 {0xd1, 0x6e, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1206 {0xd1, 0x6e, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
1207 {0xd1, 0x6e, 0x35, 0x00, 0x00, 0x00, 0x00, 0x10},
1208 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x00, 0x00, 0x10},
1209 {0xd1, 0x6e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x10},
1210 {0xd1, 0x6e, 0x41, 0x00, 0x00, 0x00, 0x00, 0x10},
1211 {0xd1, 0x6e, 0x45, 0x00, 0x00, 0x00, 0x00, 0x10},
1212 {0xd1, 0x6e, 0x49, 0x00, 0x00, 0x00, 0x00, 0x10},
1213 {0xd1, 0x6e, 0x4d, 0x00, 0x00, 0x00, 0xed, 0x10},
1214 {0xd1, 0x6e, 0x51, 0x17, 0x4a, 0x2f, 0xc0, 0x10},
1215 {0xd1, 0x6e, 0x55, 0x00, 0x00, 0x00, 0x00, 0x10},
1216 {0xd1, 0x6e, 0x59, 0x00, 0x00, 0x00, 0x00, 0x10},
1217 {0xd1, 0x6e, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x10},
1218 {0xd1, 0x6e, 0x61, 0x00, 0x00, 0x00, 0x00, 0x10},
1219 {0xd1, 0x6e, 0x65, 0x00, 0x00, 0x00, 0x00, 0x10},
1220 {0xd1, 0x6e, 0x69, 0x00, 0x00, 0x00, 0x00, 0x10},
1221 {0xd1, 0x6e, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x10},
1222 {0xd1, 0x6e, 0x71, 0x00, 0x00, 0x00, 0x00, 0x10},
1223 {0xd1, 0x6e, 0x75, 0x00, 0x00, 0x00, 0x00, 0x10},
1224 {0xd1, 0x6e, 0x79, 0x00, 0x00, 0x00, 0x00, 0x10},
1225 {0xd1, 0x6e, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x10},
1226 {0xd1, 0x6e, 0x81, 0x00, 0x00, 0x00, 0x00, 0x10},
1227 {0xd1, 0x6e, 0x85, 0x00, 0x00, 0x00, 0x08, 0x10},
1228 {0xd1, 0x6e, 0x89, 0x01, 0xe8, 0x00, 0x01, 0x10},
1229 {0xa1, 0x6e, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x10},
1230 {0xd1, 0x6e, 0x21, 0x00, 0x00, 0x00, 0x00, 0x10},
1231 {0xd1, 0x6e, 0x25, 0x00, 0x00, 0x00, 0x01, 0x10},
1232 {0xd1, 0x6e, 0x29, 0xe6, 0x00, 0xbd, 0x03, 0x10},
1233 {0xd1, 0x6e, 0x2d, 0x41, 0x38, 0x68, 0x40, 0x10},
1234 {0xd1, 0x6e, 0x31, 0x2b, 0x00, 0x36, 0x00, 0x10},
1235 {0xd1, 0x6e, 0x35, 0x30, 0x30, 0x08, 0x00, 0x10},
1236 {0xd1, 0x6e, 0x39, 0x00, 0x00, 0x33, 0x06, 0x10},
1237 {0xb1, 0x6e, 0x3d, 0x06, 0x02, 0x00, 0x00, 0x10},
1238 {}
1239};
1240static const u8 po2030n_sensor_param1[][8] = {
1241 {0xa1, 0x6e, 0x1a, 0x01, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001242 {DELAY, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 8ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001243 {0xa1, 0x6e, 0x1b, 0xf4, 0x00, 0x00, 0x00, 0x10},
1244 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1245 {0xd1, 0x6e, 0x16, 0x50, 0x40, 0x49, 0x40, 0x10},
1246/*param2*/
1247 {0xa1, 0x6e, 0x1d, 0x00, 0x00, 0x00, 0x00, 0x10},
1248 {0xa1, 0x6e, 0x04, 0x03, 0x00, 0x00, 0x00, 0x10},
1249 {0xa1, 0x6e, 0x05, 0x6f, 0x00, 0x00, 0x00, 0x10},
1250 {0xa1, 0x6e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
1251 {0xa1, 0x6e, 0x07, 0x25, 0x00, 0x00, 0x00, 0x10},
1252 {0xa1, 0x6e, 0x15, 0x04, 0x00, 0x00, 0x00, 0x10},
1253 {0xc1, 0x6e, 0x16, 0x52, 0x40, 0x48, 0x00, 0x10},
1254/*after start*/
1255 {0xa1, 0x6e, 0x15, 0x0f, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001256 {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001257 {0xa1, 0x6e, 0x1a, 0x05, 0x00, 0x00, 0x00, 0x10},
Németh Mártonccbc5df2010-10-18 07:00:48 -03001258 {DELAY, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 5ms */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001259 {0xa1, 0x6e, 0x1b, 0x53, 0x00, 0x00, 0x00, 0x10},
1260 {}
1261};
1262
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001263static const u8 soi768_sensor_init[][8] = {
1264 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset */
Németh Mártonccbc5df2010-10-18 07:00:48 -03001265 {DELAY, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 96ms */
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001266 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
1267 {0xa1, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
1268 {0xa1, 0x21, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x10},
1269 {0xa1, 0x21, 0x19, 0x00, 0x00, 0x00, 0x00, 0x10},
1270 {}
1271};
1272static const u8 soi768_sensor_param1[][8] = {
1273 {0xa1, 0x21, 0x10, 0x10, 0x00, 0x00, 0x00, 0x10},
1274 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
1275 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
1276 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1277 {0xb1, 0x21, 0x01, 0x7f, 0x7f, 0x00, 0x00, 0x10},
1278/* */
1279/* {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1280/* {0xa1, 0x21, 0x2d, 0x25, 0x00, 0x00, 0x00, 0x10}, */
1281 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
1282/* {0xb1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10}, */
1283 {0xa1, 0x21, 0x02, 0x8d, 0x00, 0x00, 0x00, 0x10},
1284/* the next sequence should be used for auto gain */
1285 {0xa1, 0x21, 0x00, 0x07, 0x00, 0x00, 0x00, 0x10},
1286 /* global gain ? : 07 - change with 0x15 at the end */
1287 {0xa1, 0x21, 0x10, 0x3f, 0x00, 0x00, 0x00, 0x10}, /* ???? : 063f */
1288 {0xa1, 0x21, 0x04, 0x06, 0x00, 0x00, 0x00, 0x10},
1289 {0xb1, 0x21, 0x2d, 0x00, 0x02, 0x00, 0x00, 0x10},
1290 /* exposure ? : 0200 - change with 0x1e at the end */
1291 {}
1292};
1293
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001294static const u8 sp80708_sensor_init[][8] = {
1295 {0xa1, 0x18, 0x06, 0xf9, 0x00, 0x00, 0x00, 0x10},
1296 {0xa1, 0x18, 0x09, 0x1f, 0x00, 0x00, 0x00, 0x10},
1297 {0xa1, 0x18, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x10},
1298 {0xa1, 0x18, 0x0d, 0xc0, 0x00, 0x00, 0x00, 0x10},
1299 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1300 {0xa1, 0x18, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x10},
1301 {0xa1, 0x18, 0x10, 0x40, 0x00, 0x00, 0x00, 0x10},
1302 {0xa1, 0x18, 0x11, 0x4e, 0x00, 0x00, 0x00, 0x10},
1303 {0xa1, 0x18, 0x12, 0x53, 0x00, 0x00, 0x00, 0x10},
1304 {0xa1, 0x18, 0x15, 0x80, 0x00, 0x00, 0x00, 0x10},
1305 {0xa1, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x10},
1306 {0xa1, 0x18, 0x19, 0x18, 0x00, 0x00, 0x00, 0x10},
1307 {0xa1, 0x18, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x10},
1308 {0xa1, 0x18, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x10},
1309 {0xa1, 0x18, 0x1c, 0x28, 0x00, 0x00, 0x00, 0x10},
1310 {0xa1, 0x18, 0x1d, 0x02, 0x00, 0x00, 0x00, 0x10},
1311 {0xa1, 0x18, 0x1e, 0x10, 0x00, 0x00, 0x00, 0x10},
1312 {0xa1, 0x18, 0x26, 0x04, 0x00, 0x00, 0x00, 0x10},
1313 {0xa1, 0x18, 0x27, 0x1e, 0x00, 0x00, 0x00, 0x10},
1314 {0xa1, 0x18, 0x28, 0x5a, 0x00, 0x00, 0x00, 0x10},
1315 {0xa1, 0x18, 0x29, 0x28, 0x00, 0x00, 0x00, 0x10},
1316 {0xa1, 0x18, 0x2a, 0x78, 0x00, 0x00, 0x00, 0x10},
1317 {0xa1, 0x18, 0x2b, 0x01, 0x00, 0x00, 0x00, 0x10},
1318 {0xa1, 0x18, 0x2c, 0xf7, 0x00, 0x00, 0x00, 0x10},
1319 {0xa1, 0x18, 0x2d, 0x2d, 0x00, 0x00, 0x00, 0x10},
1320 {0xa1, 0x18, 0x2e, 0xd5, 0x00, 0x00, 0x00, 0x10},
1321 {0xa1, 0x18, 0x39, 0x42, 0x00, 0x00, 0x00, 0x10},
1322 {0xa1, 0x18, 0x3a, 0x67, 0x00, 0x00, 0x00, 0x10},
1323 {0xa1, 0x18, 0x3b, 0x87, 0x00, 0x00, 0x00, 0x10},
1324 {0xa1, 0x18, 0x3c, 0xa3, 0x00, 0x00, 0x00, 0x10},
1325 {0xa1, 0x18, 0x3d, 0xb0, 0x00, 0x00, 0x00, 0x10},
1326 {0xa1, 0x18, 0x3e, 0xbc, 0x00, 0x00, 0x00, 0x10},
1327 {0xa1, 0x18, 0x3f, 0xc8, 0x00, 0x00, 0x00, 0x10},
1328 {0xa1, 0x18, 0x40, 0xd4, 0x00, 0x00, 0x00, 0x10},
1329 {0xa1, 0x18, 0x41, 0xdf, 0x00, 0x00, 0x00, 0x10},
1330 {0xa1, 0x18, 0x42, 0xea, 0x00, 0x00, 0x00, 0x10},
1331 {0xa1, 0x18, 0x43, 0xf5, 0x00, 0x00, 0x00, 0x10},
1332 {0xa1, 0x18, 0x45, 0x80, 0x00, 0x00, 0x00, 0x10},
1333 {0xa1, 0x18, 0x46, 0x60, 0x00, 0x00, 0x00, 0x10},
1334 {0xa1, 0x18, 0x47, 0x50, 0x00, 0x00, 0x00, 0x10},
1335 {0xa1, 0x18, 0x48, 0x30, 0x00, 0x00, 0x00, 0x10},
1336 {0xa1, 0x18, 0x49, 0x01, 0x00, 0x00, 0x00, 0x10},
1337 {0xa1, 0x18, 0x4d, 0xae, 0x00, 0x00, 0x00, 0x10},
1338 {0xa1, 0x18, 0x4e, 0x03, 0x00, 0x00, 0x00, 0x10},
1339 {0xa1, 0x18, 0x4f, 0x66, 0x00, 0x00, 0x00, 0x10},
1340 {0xa1, 0x18, 0x50, 0x1c, 0x00, 0x00, 0x00, 0x10},
1341 {0xa1, 0x18, 0x44, 0x10, 0x00, 0x00, 0x00, 0x10},
1342 {0xa1, 0x18, 0x4a, 0x30, 0x00, 0x00, 0x00, 0x10},
1343 {0xa1, 0x18, 0x51, 0x80, 0x00, 0x00, 0x00, 0x10},
1344 {0xa1, 0x18, 0x52, 0x80, 0x00, 0x00, 0x00, 0x10},
1345 {0xa1, 0x18, 0x53, 0x80, 0x00, 0x00, 0x00, 0x10},
1346 {0xa1, 0x18, 0x54, 0x80, 0x00, 0x00, 0x00, 0x10},
1347 {0xa1, 0x18, 0x55, 0x80, 0x00, 0x00, 0x00, 0x10},
1348 {0xa1, 0x18, 0x56, 0x80, 0x00, 0x00, 0x00, 0x10},
1349 {0xa1, 0x18, 0x57, 0xe0, 0x00, 0x00, 0x00, 0x10},
1350 {0xa1, 0x18, 0x58, 0xc0, 0x00, 0x00, 0x00, 0x10},
1351 {0xa1, 0x18, 0x59, 0xab, 0x00, 0x00, 0x00, 0x10},
1352 {0xa1, 0x18, 0x5a, 0xa0, 0x00, 0x00, 0x00, 0x10},
1353 {0xa1, 0x18, 0x5b, 0x99, 0x00, 0x00, 0x00, 0x10},
1354 {0xa1, 0x18, 0x5c, 0x90, 0x00, 0x00, 0x00, 0x10},
1355 {0xa1, 0x18, 0x5e, 0x24, 0x00, 0x00, 0x00, 0x10},
1356 {0xa1, 0x18, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x10},
1357 {0xa1, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x10},
1358 {0xa1, 0x18, 0x61, 0x73, 0x00, 0x00, 0x00, 0x10},
1359 {0xa1, 0x18, 0x63, 0x42, 0x00, 0x00, 0x00, 0x10},
1360 {0xa1, 0x18, 0x64, 0x42, 0x00, 0x00, 0x00, 0x10},
1361 {0xa1, 0x18, 0x65, 0x42, 0x00, 0x00, 0x00, 0x10},
1362 {0xa1, 0x18, 0x66, 0x24, 0x00, 0x00, 0x00, 0x10},
1363 {0xa1, 0x18, 0x67, 0x24, 0x00, 0x00, 0x00, 0x10},
1364 {0xa1, 0x18, 0x68, 0x08, 0x00, 0x00, 0x00, 0x10},
1365 {0xa1, 0x18, 0x2f, 0xc9, 0x00, 0x00, 0x00, 0x10},
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03001366 {}
1367};
1368static const u8 sp80708_sensor_param1[][8] = {
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03001369 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1370 {0xa1, 0x18, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x10},
1371 {0xa1, 0x18, 0x03, 0x01, 0x00, 0x00, 0x00, 0x10},
1372 {0xa1, 0x18, 0x04, 0xa4, 0x00, 0x00, 0x00, 0x10},
1373 {0xa1, 0x18, 0x14, 0x3f, 0x00, 0x00, 0x00, 0x10},
1374 {0xa1, 0x18, 0x5d, 0x80, 0x00, 0x00, 0x00, 0x10},
1375 {0xb1, 0x18, 0x11, 0x40, 0x40, 0x00, 0x00, 0x10},
1376 {}
1377};
1378
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001379static const u8 (*sensor_init[])[8] = {
1380[SENSOR_ADCM1700] = adcm1700_sensor_init,
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001381[SENSOR_GC0307] = gc0307_sensor_init,
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001382[SENSOR_HV7131R] = hv7131r_sensor_init,
1383[SENSOR_MI0360] = mi0360_sensor_init,
Jean-François Moinea067db82010-10-01 07:51:24 -03001384[SENSOR_MI0360B] = mi0360b_sensor_init,
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001385[SENSOR_MO4000] = mo4000_sensor_init,
1386[SENSOR_MT9V111] = mt9v111_sensor_init,
1387[SENSOR_OM6802] = om6802_sensor_init,
1388[SENSOR_OV7630] = ov7630_sensor_init,
1389[SENSOR_OV7648] = ov7648_sensor_init,
1390[SENSOR_OV7660] = ov7660_sensor_init,
1391[SENSOR_PO1030] = po1030_sensor_init,
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001392[SENSOR_PO2030N] = po2030n_sensor_init,
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001393[SENSOR_SOI768] = soi768_sensor_init,
Jean-François Moine9c33afc2010-03-17 15:25:32 -03001394[SENSOR_SP80708] = sp80708_sensor_init,
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001395};
1396
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001397/* read <len> bytes to gspca_dev->usb_buf */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001398static void reg_r(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001399 u16 value, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001400{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001401 int ret;
1402
1403 if (gspca_dev->usb_err < 0)
1404 return;
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001405#ifdef GSPCA_DEBUG
1406 if (len > USB_BUF_SZ) {
1407 err("reg_r: buffer overflow");
1408 return;
1409 }
1410#endif
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001411 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001412 usb_rcvctrlpipe(gspca_dev->dev, 0),
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001413 0,
1414 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1415 value, 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001416 gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001417 500);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001418 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001419 if (ret < 0) {
1420 err("reg_r err %d", ret);
1421 gspca_dev->usb_err = ret;
1422 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001423}
1424
Jean-Francois Moine60017612008-07-18 08:46:19 -03001425static void reg_w1(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001426 u16 value,
1427 u8 data)
Jean-Francois Moine60017612008-07-18 08:46:19 -03001428{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001429 int ret;
1430
1431 if (gspca_dev->usb_err < 0)
1432 return;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001433 PDEBUG(D_USBO, "reg_w1 [%04x] = %02x", value, data);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001434 gspca_dev->usb_buf[0] = data;
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001435 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine60017612008-07-18 08:46:19 -03001436 usb_sndctrlpipe(gspca_dev->dev, 0),
1437 0x08,
1438 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1439 value,
1440 0,
1441 gspca_dev->usb_buf, 1,
1442 500);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001443 if (ret < 0) {
1444 err("reg_w1 err %d", ret);
1445 gspca_dev->usb_err = ret;
1446 }
Jean-Francois Moine60017612008-07-18 08:46:19 -03001447}
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001448static void reg_w(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001449 u16 value,
1450 const u8 *buffer,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001451 int len)
1452{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001453 int ret;
1454
1455 if (gspca_dev->usb_err < 0)
1456 return;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001457 PDEBUG(D_USBO, "reg_w [%04x] = %02x %02x ..",
Jean-Francois Moine60017612008-07-18 08:46:19 -03001458 value, buffer[0], buffer[1]);
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001459#ifdef GSPCA_DEBUG
1460 if (len > USB_BUF_SZ) {
1461 err("reg_w: buffer overflow");
1462 return;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -03001463 }
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001464#endif
1465 memcpy(gspca_dev->usb_buf, buffer, len);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001466 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine8295d992008-09-03 17:12:19 -03001467 usb_sndctrlpipe(gspca_dev->dev, 0),
1468 0x08,
1469 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1470 value, 0,
1471 gspca_dev->usb_buf, len,
1472 500);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001473 if (ret < 0) {
1474 err("reg_w err %d", ret);
1475 gspca_dev->usb_err = ret;
1476 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001477}
1478
Jean-Francois Moine60017612008-07-18 08:46:19 -03001479/* I2C write 1 byte */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001480static void i2c_w1(struct gspca_dev *gspca_dev, u8 reg, u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001481{
1482 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001483 int ret;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001484
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001485 if (gspca_dev->usb_err < 0)
1486 return;
Jean-François Moinecfd23c82010-04-25 14:27:39 -03001487 PDEBUG(D_USBO, "i2c_w1 [%02x] = %02x", reg, val);
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001488 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001489 case SENSOR_ADCM1700:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001490 case SENSOR_OM6802:
1491 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001492 gspca_dev->usb_buf[0] = 0x80 | (2 << 4);
1493 break;
1494 default: /* i2c command = a1 (400 kHz) */
1495 gspca_dev->usb_buf[0] = 0x81 | (2 << 4);
1496 break;
1497 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001498 gspca_dev->usb_buf[1] = sd->i2c_addr;
Jean-Francois Moine60017612008-07-18 08:46:19 -03001499 gspca_dev->usb_buf[2] = reg;
1500 gspca_dev->usb_buf[3] = val;
1501 gspca_dev->usb_buf[4] = 0;
1502 gspca_dev->usb_buf[5] = 0;
1503 gspca_dev->usb_buf[6] = 0;
1504 gspca_dev->usb_buf[7] = 0x10;
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001505 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine60017612008-07-18 08:46:19 -03001506 usb_sndctrlpipe(gspca_dev->dev, 0),
1507 0x08,
1508 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1509 0x08, /* value = i2c */
1510 0,
1511 gspca_dev->usb_buf, 8,
1512 500);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001513 if (ret < 0) {
1514 err("i2c_w1 err %d", ret);
1515 gspca_dev->usb_err = ret;
1516 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001517}
1518
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001519/* I2C write 8 bytes */
1520static void i2c_w8(struct gspca_dev *gspca_dev,
Jean-Francois Moine98819182009-01-19 07:37:33 -03001521 const u8 *buffer)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001522{
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001523 int ret;
1524
1525 if (gspca_dev->usb_err < 0)
1526 return;
Jean-François Moinecfd23c82010-04-25 14:27:39 -03001527 PDEBUG(D_USBO, "i2c_w8 [%02x] = %02x ..",
1528 buffer[2], buffer[3]);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001529 memcpy(gspca_dev->usb_buf, buffer, 8);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001530 ret = usb_control_msg(gspca_dev->dev,
Jean-Francois Moine60017612008-07-18 08:46:19 -03001531 usb_sndctrlpipe(gspca_dev->dev, 0),
1532 0x08,
1533 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
1534 0x08, 0, /* value, index */
1535 gspca_dev->usb_buf, 8,
1536 500);
Jean-Francois Moine8d768e12008-09-21 03:28:55 -03001537 msleep(2);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001538 if (ret < 0) {
1539 err("i2c_w8 err %d", ret);
1540 gspca_dev->usb_err = ret;
1541 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001542}
1543
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001544/* sensor read 'len' (1..5) bytes in gspca_dev->usb_buf */
1545static void i2c_r(struct gspca_dev *gspca_dev, u8 reg, int len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001546{
1547 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001548 u8 mode[8];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001549
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001550 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001551 case SENSOR_ADCM1700:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001552 case SENSOR_OM6802:
1553 case SENSOR_GC0307: /* i2c command = a0 (100 kHz) */
Jean-Francois Moinea7826362009-11-02 09:21:06 -03001554 mode[0] = 0x80 | 0x10;
1555 break;
1556 default: /* i2c command = 91 (400 kHz) */
1557 mode[0] = 0x81 | 0x10;
1558 break;
1559 }
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001560 mode[1] = sd->i2c_addr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001561 mode[2] = reg;
1562 mode[3] = 0;
1563 mode[4] = 0;
1564 mode[5] = 0;
1565 mode[6] = 0;
1566 mode[7] = 0x10;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001567 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001568 msleep(2);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001569 mode[0] = (mode[0] & 0x81) | (len << 4) | 0x02;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001570 mode[2] = 0;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001571 i2c_w8(gspca_dev, mode);
Jean-Francois Moine60017612008-07-18 08:46:19 -03001572 msleep(2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001573 reg_r(gspca_dev, 0x0a, 5);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001574}
1575
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001576static void i2c_w_seq(struct gspca_dev *gspca_dev,
1577 const u8 (*data)[8])
1578{
1579 while ((*data)[0] != 0) {
Németh Mártonccbc5df2010-10-18 07:00:48 -03001580 if ((*data)[0] != DELAY)
Jean-Francois Moine23a98272009-11-02 09:10:25 -03001581 i2c_w8(gspca_dev, *data);
1582 else
1583 msleep((*data)[1]);
1584 data++;
1585 }
1586}
1587
Jean-François Moinea79cc7b2010-10-29 08:10:37 -03001588/* check the ID of the hv7131 sensor */
1589/* this sequence is needed because it activates the sensor */
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001590static void hv7131r_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001591{
Jean-François Moinea79cc7b2010-10-29 08:10:37 -03001592 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001593 msleep(10);
Jean-François Moinea79cc7b2010-10-29 08:10:37 -03001594 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001595 msleep(10);
Jean-François Moinea79cc7b2010-10-29 08:10:37 -03001596 i2c_r(gspca_dev, 0, 5); /* read sensor id */
1597 if (gspca_dev->usb_buf[0] == 0x02 /* chip ID (02 is R) */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001598 && gspca_dev->usb_buf[1] == 0x09
Jean-François Moinea79cc7b2010-10-29 08:10:37 -03001599 && gspca_dev->usb_buf[2] == 0x01) {
1600 PDEBUG(D_PROBE, "Sensor HV7131R found");
Jean-Francois Moine7fb101a2009-10-22 06:27:14 -03001601 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001602 }
Jean-François Moinea79cc7b2010-10-29 08:10:37 -03001603 warn("Erroneous HV7131R ID 0x%02x 0x%02x 0x%02x",
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001604 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
1605 gspca_dev->usb_buf[2]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001606}
1607
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001608static void mi0360_probe(struct gspca_dev *gspca_dev)
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001609{
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001610 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001611 int i, j;
Jean-Francois Moine92e8c912009-02-02 16:25:38 -03001612 u16 val = 0;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001613 static const u8 probe_tb[][4][8] = {
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001614 { /* mi0360 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001615 {0xb0, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
1616 {0x90, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1617 {0xa2, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1618 {0xb0, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10}
1619 },
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001620 { /* mt9v111 */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001621 {0xb0, 0x5c, 0x01, 0x00, 0x04, 0x00, 0x00, 0x10},
1622 {0x90, 0x5c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x10},
1623 {0xa2, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
1624 {}
1625 },
1626 };
1627
1628 for (i = 0; i < ARRAY_SIZE(probe_tb); i++) {
1629 reg_w1(gspca_dev, 0x17, 0x62);
1630 reg_w1(gspca_dev, 0x01, 0x08);
1631 for (j = 0; j < 3; j++)
1632 i2c_w8(gspca_dev, probe_tb[i][j]);
1633 msleep(2);
1634 reg_r(gspca_dev, 0x0a, 5);
1635 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1636 if (probe_tb[i][3][0] != 0)
1637 i2c_w8(gspca_dev, probe_tb[i][3]);
1638 reg_w1(gspca_dev, 0x01, 0x29);
1639 reg_w1(gspca_dev, 0x17, 0x42);
1640 if (val != 0xffff)
1641 break;
1642 }
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001643 if (gspca_dev->usb_err < 0)
1644 return;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001645 switch (val) {
Jean-François Moinea067db82010-10-01 07:51:24 -03001646 case 0x8221:
1647 PDEBUG(D_PROBE, "Sensor mi0360b");
1648 sd->sensor = SENSOR_MI0360B;
1649 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001650 case 0x823a:
1651 PDEBUG(D_PROBE, "Sensor mt9v111");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001652 sd->sensor = SENSOR_MT9V111;
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001653 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001654 case 0x8243:
1655 PDEBUG(D_PROBE, "Sensor mi0360");
Jean-Francois Moine65c52592009-02-01 14:26:51 -03001656 break;
1657 default:
1658 PDEBUG(D_PROBE, "Unknown sensor %04x - forced to mi0360", val);
1659 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001660 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001661}
1662
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001663static void ov7630_probe(struct gspca_dev *gspca_dev)
1664{
1665 struct sd *sd = (struct sd *) gspca_dev;
1666 u16 val;
1667
1668 /* check ov76xx */
1669 reg_w1(gspca_dev, 0x17, 0x62);
1670 reg_w1(gspca_dev, 0x01, 0x08);
1671 sd->i2c_addr = 0x21;
1672 i2c_r(gspca_dev, 0x0a, 2);
1673 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1674 reg_w1(gspca_dev, 0x01, 0x29);
1675 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001676 if (gspca_dev->usb_err < 0)
1677 return;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03001678 if (val == 0x7628) { /* soi768 */
1679 sd->sensor = SENSOR_SOI768;
1680/*fixme: only valid for 0c45:613e?*/
1681 gspca_dev->cam.input_flags =
1682 V4L2_IN_ST_VFLIP | V4L2_IN_ST_HFLIP;
1683 PDEBUG(D_PROBE, "Sensor soi768");
1684 return;
1685 }
1686 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1687}
1688
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001689static void ov7648_probe(struct gspca_dev *gspca_dev)
1690{
1691 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001692 u16 val;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001693
1694 /* check ov76xx */
1695 reg_w1(gspca_dev, 0x17, 0x62);
1696 reg_w1(gspca_dev, 0x01, 0x08);
1697 sd->i2c_addr = 0x21;
1698 i2c_r(gspca_dev, 0x0a, 2);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001699 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001700 reg_w1(gspca_dev, 0x01, 0x29);
1701 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001702 if ((val & 0xff00) == 0x7600) { /* ov76xx */
1703 PDEBUG(D_PROBE, "Sensor ov%04x", val);
1704 return;
1705 }
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001706
1707 /* check po1030 */
1708 reg_w1(gspca_dev, 0x17, 0x62);
1709 reg_w1(gspca_dev, 0x01, 0x08);
1710 sd->i2c_addr = 0x6e;
1711 i2c_r(gspca_dev, 0x00, 2);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001712 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
1713 reg_w1(gspca_dev, 0x01, 0x29);
1714 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001715 if (gspca_dev->usb_err < 0)
1716 return;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001717 if (val == 0x1030) { /* po1030 */
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001718 PDEBUG(D_PROBE, "Sensor po1030");
1719 sd->sensor = SENSOR_PO1030;
1720 return;
1721 }
Jean-François Moine0b656322010-09-13 05:19:58 -03001722 err("Unknown sensor %04x", val);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001723}
1724
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001725/* 0c45:6142 sensor may be po2030n, gc0305 or gc0307 */
1726static void po2030n_probe(struct gspca_dev *gspca_dev)
1727{
1728 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001729 u16 val;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001730
1731 /* check gc0307 */
1732 reg_w1(gspca_dev, 0x17, 0x62);
1733 reg_w1(gspca_dev, 0x01, 0x08);
1734 reg_w1(gspca_dev, 0x02, 0x22);
1735 sd->i2c_addr = 0x21;
1736 i2c_r(gspca_dev, 0x00, 1);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001737 val = gspca_dev->usb_buf[4];
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001738 reg_w1(gspca_dev, 0x01, 0x29); /* reset */
1739 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001740 if (val == 0x99) { /* gc0307 (?) */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001741 PDEBUG(D_PROBE, "Sensor gc0307");
1742 sd->sensor = SENSOR_GC0307;
1743 return;
1744 }
1745
1746 /* check po2030n */
1747 reg_w1(gspca_dev, 0x17, 0x62);
1748 reg_w1(gspca_dev, 0x01, 0x0a);
1749 sd->i2c_addr = 0x6e;
1750 i2c_r(gspca_dev, 0x00, 2);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001751 val = (gspca_dev->usb_buf[3] << 8) | gspca_dev->usb_buf[4];
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001752 reg_w1(gspca_dev, 0x01, 0x29);
1753 reg_w1(gspca_dev, 0x17, 0x42);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001754 if (gspca_dev->usb_err < 0)
1755 return;
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001756 if (val == 0x2030) {
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001757 PDEBUG(D_PROBE, "Sensor po2030n");
1758/* sd->sensor = SENSOR_PO2030N; */
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001759 } else {
Jean-François Moine0b656322010-09-13 05:19:58 -03001760 err("Unknown sensor ID %04x", val);
Jean-François Moinee3302ca2010-04-25 14:41:51 -03001761 }
Jean-François Moinead98c0f2010-03-18 05:15:30 -03001762}
1763
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001764/* this function is called at probe time */
1765static int sd_config(struct gspca_dev *gspca_dev,
1766 const struct usb_device_id *id)
1767{
1768 struct sd *sd = (struct sd *) gspca_dev;
1769 struct cam *cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001770
Jean-Francois Moineeac8f5f2010-01-12 07:12:43 -03001771 sd->bridge = id->driver_info >> 16;
Jean-Francois Moinec6c14332010-12-14 16:15:37 -03001772 sd->sensor = id->driver_info >> 8;
1773 sd->flags = id->driver_info;
Jean-Francois Moineeac8f5f2010-01-12 07:12:43 -03001774
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001775 cam = &gspca_dev->cam;
Jean-Francois Moine646775732009-12-20 12:31:28 -03001776 if (sd->sensor == SENSOR_ADCM1700) {
1777 cam->cam_mode = cif_mode;
1778 cam->nmodes = ARRAY_SIZE(cif_mode);
1779 } else {
1780 cam->cam_mode = vga_mode;
1781 cam->nmodes = ARRAY_SIZE(vga_mode);
1782 }
Jean-Francois Moine49cb6b02009-04-25 13:29:01 -03001783 cam->npkt = 24; /* 24 packets per ISOC message */
Jean-François Moine72b667e2010-10-02 04:35:25 -03001784 cam->ctrls = sd->ctrls;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03001785
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001786 sd->ag_cnt = -1;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001787 sd->quality = QUALITY_DEF;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03001788
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001789 return 0;
1790}
1791
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001792/* this function is called at probe and resume time */
1793static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001794{
1795 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001796 const u8 *sn9c1xx;
Jean-François Moine19697b52010-07-14 06:33:51 -03001797 u8 regGpio[] = { 0x29, 0x74 }; /* with audio */
Jean-Francois Moine98819182009-01-19 07:37:33 -03001798 u8 regF1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001799
Hans de Goede3647fea2008-07-15 05:36:30 -03001800 /* setup a selector by bridge */
Jean-Francois Moine60017612008-07-18 08:46:19 -03001801 reg_w1(gspca_dev, 0xf1, 0x01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001802 reg_r(gspca_dev, 0x00, 1);
Jean-Francois Moine4f67f3a2010-12-14 16:15:00 -03001803 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001804 reg_r(gspca_dev, 0x00, 1); /* get sonix chip id */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001805 regF1 = gspca_dev->usb_buf[0];
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001806 if (gspca_dev->usb_err < 0)
1807 return gspca_dev->usb_err;
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03001808 PDEBUG(D_PROBE, "Sonix chip id: %02x", regF1);
Hans de Goede3647fea2008-07-15 05:36:30 -03001809 switch (sd->bridge) {
1810 case BRIDGE_SN9C102P:
Hans de Goede3647fea2008-07-15 05:36:30 -03001811 case BRIDGE_SN9C105:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001812 if (regF1 != 0x11)
1813 return -ENODEV;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001814 break;
1815 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001816/* case BRIDGE_SN9C110: */
Hans de Goedee530a5e2011-01-06 15:23:55 -03001817/* case BRIDGE_SN9C120: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001818 if (regF1 != 0x12)
1819 return -ENODEV;
Hans de Goedee530a5e2011-01-06 15:23:55 -03001820 }
1821
1822 switch (sd->sensor) {
1823 case SENSOR_MI0360:
1824 mi0360_probe(gspca_dev);
1825 break;
1826 case SENSOR_OV7630:
1827 ov7630_probe(gspca_dev);
1828 break;
1829 case SENSOR_OV7648:
1830 ov7648_probe(gspca_dev);
1831 break;
1832 case SENSOR_PO2030N:
1833 po2030n_probe(gspca_dev);
1834 break;
1835 }
1836
1837 switch (sd->bridge) {
1838 case BRIDGE_SN9C102P:
1839 reg_w1(gspca_dev, 0x02, regGpio[1]);
1840 break;
1841 case BRIDGE_SN9C105:
1842 reg_w(gspca_dev, 0x01, regGpio, 2);
1843 break;
1844 case BRIDGE_SN9C110:
Jean-Francois Moine60017612008-07-18 08:46:19 -03001845 reg_w1(gspca_dev, 0x02, 0x62);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001846 break;
Hans de Goedee530a5e2011-01-06 15:23:55 -03001847 case BRIDGE_SN9C120:
1848 regGpio[1] = 0x70; /* no audio */
1849 reg_w(gspca_dev, 0x01, regGpio, 2);
1850 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001851 }
1852
Jean-François Moine72b667e2010-10-02 04:35:25 -03001853 if (sd->sensor == SENSOR_OM6802)
1854 sd->ctrls[SHARPNESS].def = 0x10;
1855
Hans de Goede9712a8b2010-01-31 12:54:29 -03001856 /* Note we do not disable the sensor clock here (power saving mode),
1857 as that also disables the button on the cam. */
1858 reg_w1(gspca_dev, 0xf1, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001859
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001860 /* set the i2c address */
1861 sn9c1xx = sn_tb[sd->sensor];
1862 sd->i2c_addr = sn9c1xx[9];
1863
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001864 gspca_dev->ctrl_dis = ctrl_dis[sd->sensor];
Jean-François Moine3afef852011-01-13 06:39:11 -03001865 if (!(sd->flags & F_ILLUM))
1866 gspca_dev->ctrl_dis |= (1 << ILLUM);
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03001867
Jean-François Moine4bf8b672010-09-25 06:12:44 -03001868 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001869}
1870
Jean-Francois Moine98819182009-01-19 07:37:33 -03001871static u32 setexposure(struct gspca_dev *gspca_dev,
1872 u32 expo)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001873{
1874 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001875
1876 switch (sd->sensor) {
Jean-François Moinec26b12d2010-04-02 07:08:39 -03001877 case SENSOR_GC0307: {
1878 int a, b;
1879
1880 /* expo = 0..255 -> a = 19..43 */
1881 a = 19 + expo * 25 / 256;
1882 i2c_w1(gspca_dev, 0x68, a);
1883 a -= 12;
1884 b = a * a * 4; /* heuristic */
1885 i2c_w1(gspca_dev, 0x03, b >> 8);
1886 i2c_w1(gspca_dev, 0x04, b);
1887 break;
1888 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001889 case SENSOR_HV7131R: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001890 u8 Expodoit[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001891 { 0xc1, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001892
1893 Expodoit[3] = expo >> 16;
1894 Expodoit[4] = expo >> 8;
1895 Expodoit[5] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001896 i2c_w8(gspca_dev, Expodoit);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001897 break;
1898 }
Jean-François Moinea067db82010-10-01 07:51:24 -03001899 case SENSOR_MI0360:
1900 case SENSOR_MI0360B: {
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001901 u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001902 { 0xb1, 0x5d, 0x09, 0x00, 0x00, 0x00, 0x00, 0x16 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001903 static const u8 doit[] = /* update sensor */
1904 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1905 static const u8 sensorgo[] = /* sensor on */
1906 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001907
1908 if (expo > 0x0635)
1909 expo = 0x0635;
1910 else if (expo < 0x0001)
1911 expo = 0x0001;
1912 expoMi[3] = expo >> 8;
1913 expoMi[4] = expo;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001914 i2c_w8(gspca_dev, expoMi);
1915 i2c_w8(gspca_dev, doit);
1916 i2c_w8(gspca_dev, sensorgo);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001917 break;
1918 }
1919 case SENSOR_MO4000: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001920 u8 expoMof[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001921 { 0xa1, 0x21, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001922 u8 expoMo10[] =
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001923 { 0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03001924 static const u8 gainMo[] =
1925 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001926
1927 if (expo > 0x1fff)
1928 expo = 0x1fff;
1929 else if (expo < 0x0001)
1930 expo = 0x0001;
1931 expoMof[3] = (expo & 0x03fc) >> 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001932 i2c_w8(gspca_dev, expoMof);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001933 expoMo10[3] = ((expo & 0x1c00) >> 10)
1934 | ((expo & 0x0003) << 4);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03001935 i2c_w8(gspca_dev, expoMo10);
1936 i2c_w8(gspca_dev, gainMo);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001937 PDEBUG(D_FRAM, "set exposure %d",
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001938 ((expoMo10[3] & 0x07) << 10)
1939 | (expoMof[3] << 2)
1940 | ((expoMo10[3] & 0x30) >> 4));
1941 break;
1942 }
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001943 case SENSOR_MT9V111: {
1944 u8 expo_c1[] =
1945 { 0xb1, 0x5c, 0x09, 0x00, 0x00, 0x00, 0x00, 0x10 };
1946
1947 if (expo > 0x0280)
1948 expo = 0x0280;
1949 else if (expo < 0x0040)
1950 expo = 0x0040;
1951 expo_c1[3] = expo >> 8;
1952 expo_c1[4] = expo;
1953 i2c_w8(gspca_dev, expo_c1);
1954 break;
1955 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001956 case SENSOR_OM6802: {
Jean-Francois Moine98819182009-01-19 07:37:33 -03001957 u8 gainOm[] =
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001958 { 0xa0, 0x34, 0xe5, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001959 /* preset AGC - works when AutoExpo = off */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001960
1961 if (expo > 0x03ff)
1962 expo = 0x03ff;
1963 if (expo < 0x0001)
1964 expo = 0x0001;
1965 gainOm[3] = expo >> 2;
1966 i2c_w8(gspca_dev, gainOm);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03001967 reg_w1(gspca_dev, 0x96, expo >> 5);
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03001968 PDEBUG(D_FRAM, "set exposure %d", gainOm[3]);
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03001969 break;
1970 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001971 }
1972 return expo;
1973}
1974
1975static void setbrightness(struct gspca_dev *gspca_dev)
1976{
1977 struct sd *sd = (struct sd *) gspca_dev;
1978 unsigned int expo;
Jean-François Moine72b667e2010-10-02 04:35:25 -03001979 int brightness;
Jean-Francois Moine98819182009-01-19 07:37:33 -03001980 u8 k2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001981
Jean-François Moine72b667e2010-10-02 04:35:25 -03001982 brightness = sd->ctrls[BRIGHTNESS].val;
1983 k2 = (brightness - 0x80) >> 2;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001984 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03001985 case SENSOR_ADCM1700:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03001986 if (k2 > 0x1f)
1987 k2 = 0; /* only positive Y offset */
1988 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001989 case SENSOR_HV7131R:
Jean-François Moine72b667e2010-10-02 04:35:25 -03001990 expo = brightness << 12;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001991 if (expo > 0x002dc6c0)
1992 expo = 0x002dc6c0;
1993 else if (expo < 0x02a0)
1994 expo = 0x02a0;
1995 sd->exposure = setexposure(gspca_dev, expo);
1996 break;
1997 case SENSOR_MI0360:
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001998 case SENSOR_MO4000:
Jean-François Moine72b667e2010-10-02 04:35:25 -03001999 expo = brightness << 4;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002000 sd->exposure = setexposure(gspca_dev, expo);
2001 break;
Jean-François Moinea067db82010-10-01 07:51:24 -03002002 case SENSOR_MI0360B:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002003 expo = brightness << 2;
Jean-François Moinea067db82010-10-01 07:51:24 -03002004 sd->exposure = setexposure(gspca_dev, expo);
2005 break;
Jean-François Moinec26b12d2010-04-02 07:08:39 -03002006 case SENSOR_GC0307:
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002007 case SENSOR_MT9V111:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002008 expo = brightness;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002009 sd->exposure = setexposure(gspca_dev, expo);
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002010 return; /* don't set the Y offset */
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002011 case SENSOR_OM6802:
Jean-François Moine72b667e2010-10-02 04:35:25 -03002012 expo = brightness << 2;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002013 sd->exposure = setexposure(gspca_dev, expo);
Jean-François Moine72b667e2010-10-02 04:35:25 -03002014 k2 = brightness >> 3;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002015 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002016 }
2017
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002018 reg_w1(gspca_dev, 0x96, k2); /* color matrix Y offset */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002019}
2020
2021static void setcontrast(struct gspca_dev *gspca_dev)
2022{
2023 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002024 u8 k2;
2025 u8 contrast[6];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002026
Jean-François Moine72b667e2010-10-02 04:35:25 -03002027 k2 = sd->ctrls[CONTRAST].val * 0x30 / (CONTRAST_MAX + 1)
2028 + 0x10; /* 10..40 */
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002029 contrast[0] = (k2 + 1) / 2; /* red */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03002030 contrast[1] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002031 contrast[2] = k2; /* green */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03002032 contrast[3] = 0;
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002033 contrast[4] = (k2 + 1) / 5; /* blue */
Jean-Francois Moine577cbf42008-12-05 06:18:37 -03002034 contrast[5] = 0;
2035 reg_w(gspca_dev, 0x84, contrast, sizeof contrast);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002036}
2037
2038static void setcolors(struct gspca_dev *gspca_dev)
2039{
2040 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002041 int i, v, colors;
Jean-François Moinea067db82010-10-01 07:51:24 -03002042 const s16 *uv;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002043 u8 reg8a[12]; /* U & V gains */
Jean-François Moinea067db82010-10-01 07:51:24 -03002044 static const s16 uv_com[6] = { /* same as reg84 in signed decimal */
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002045 -24, -38, 64, /* UR UG UB */
2046 62, -51, -9 /* VR VG VB */
2047 };
Jean-François Moinea067db82010-10-01 07:51:24 -03002048 static const s16 uv_mi0360b[6] = {
2049 -20, -38, 64, /* UR UG UB */
2050 60, -51, -9 /* VR VG VB */
2051 };
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002052
Jean-François Moine72b667e2010-10-02 04:35:25 -03002053 colors = sd->ctrls[COLORS].val;
Jean-François Moinea067db82010-10-01 07:51:24 -03002054 if (sd->sensor == SENSOR_MI0360B)
2055 uv = uv_mi0360b;
2056 else
2057 uv = uv_com;
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002058 for (i = 0; i < 6; i++) {
Jean-François Moine72b667e2010-10-02 04:35:25 -03002059 v = uv[i] * colors / COLORS_DEF;
Jean-Francois Moinebd088832008-12-02 06:58:57 -03002060 reg8a[i * 2] = v;
2061 reg8a[i * 2 + 1] = (v >> 8) & 0x0f;
Jean-Francois Moined55b83d2008-09-03 16:48:01 -03002062 }
Jean-Francois Moinebd088832008-12-02 06:58:57 -03002063 reg_w(gspca_dev, 0x8a, reg8a, sizeof reg8a);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002064}
2065
2066static void setredblue(struct gspca_dev *gspca_dev)
2067{
2068 struct sd *sd = (struct sd *) gspca_dev;
2069
Jean-François Moine72b667e2010-10-02 04:35:25 -03002070 reg_w1(gspca_dev, 0x05, sd->ctrls[RED].val);
Jean-Francois Moine9c5f70f2008-09-03 16:48:04 -03002071/* reg_w1(gspca_dev, 0x07, 32); */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002072 reg_w1(gspca_dev, 0x06, sd->ctrls[BLUE].val);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002073}
2074
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002075static void setgamma(struct gspca_dev *gspca_dev)
2076{
2077 struct sd *sd = (struct sd *) gspca_dev;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002078 int i, val;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002079 u8 gamma[17];
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002080 const u8 *gamma_base;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002081 static const u8 delta[17] = {
2082 0x00, 0x14, 0x1c, 0x1c, 0x1c, 0x1c, 0x1b, 0x1a,
2083 0x18, 0x13, 0x10, 0x0e, 0x08, 0x07, 0x04, 0x02, 0x00
2084 };
2085
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002086 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002087 case SENSOR_ADCM1700:
2088 gamma_base = gamma_spec_0;
2089 break;
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002090 case SENSOR_HV7131R:
Jean-François Moinea067db82010-10-01 07:51:24 -03002091 case SENSOR_MI0360B:
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002092 case SENSOR_MT9V111:
2093 gamma_base = gamma_spec_1;
2094 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002095 case SENSOR_GC0307:
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002096 gamma_base = gamma_spec_2;
2097 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002098 case SENSOR_SP80708:
2099 gamma_base = gamma_spec_3;
2100 break;
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002101 default:
2102 gamma_base = gamma_def;
2103 break;
2104 }
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002105
Jean-François Moine72b667e2010-10-02 04:35:25 -03002106 val = sd->ctrls[GAMMA].val;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002107 for (i = 0; i < sizeof gamma; i++)
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002108 gamma[i] = gamma_base[i]
Jean-François Moine72b667e2010-10-02 04:35:25 -03002109 + delta[i] * (val - GAMMA_DEF) / 32;
Jean-Francois Moine592f4eb2009-01-15 08:01:32 -03002110 reg_w(gspca_dev, 0x20, gamma, sizeof gamma);
2111}
2112
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002113static void setautogain(struct gspca_dev *gspca_dev)
2114{
2115 struct sd *sd = (struct sd *) gspca_dev;
2116
Jean-François Moine72b667e2010-10-02 04:35:25 -03002117 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN))
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03002118 return;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002119 switch (sd->sensor) {
2120 case SENSOR_OV7630:
2121 case SENSOR_OV7648: {
2122 u8 comb;
2123
2124 if (sd->sensor == SENSOR_OV7630)
2125 comb = 0xc0;
2126 else
2127 comb = 0xa0;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002128 if (sd->ctrls[AUTOGAIN].val)
Hans de Goede1fec747c2009-06-18 06:05:07 -03002129 comb |= 0x03;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002130 i2c_w1(&sd->gspca_dev, 0x13, comb);
2131 return;
2132 }
2133 }
Jean-François Moine72b667e2010-10-02 04:35:25 -03002134 if (sd->ctrls[AUTOGAIN].val)
Jean-Francois Moinef50ba1b2008-09-03 17:12:14 -03002135 sd->ag_cnt = AG_CNT_START;
2136 else
2137 sd->ag_cnt = -1;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002138}
2139
Németh Márton76ad3b62010-10-19 03:33:47 -03002140static void sethvflip(struct gspca_dev *gspca_dev)
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002141{
Jean-François Moine72b667e2010-10-02 04:35:25 -03002142 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002143 u8 comn;
2144
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002145 switch (sd->sensor) {
2146 case SENSOR_HV7131R:
2147 comn = 0x18; /* clkdiv = 1, ablcen = 1 */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002148 if (sd->ctrls[VFLIP].val)
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002149 comn |= 0x01;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002150 i2c_w1(gspca_dev, 0x01, comn); /* sctra */
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002151 break;
2152 case SENSOR_OV7630:
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002153 comn = 0x02;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002154 if (!sd->ctrls[VFLIP].val)
Hans de Goedef8009522009-06-18 14:29:20 -03002155 comn |= 0x80;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002156 i2c_w1(gspca_dev, 0x75, comn);
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002157 break;
Németh Márton76ad3b62010-10-19 03:33:47 -03002158 case SENSOR_OV7648:
Jean-Francois Moine2797ba22009-02-05 15:12:24 -03002159 comn = 0x06;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002160 if (sd->ctrls[VFLIP].val)
Hans de Goedef8009522009-06-18 14:29:20 -03002161 comn |= 0x80;
Jean-François Moine72b667e2010-10-02 04:35:25 -03002162 i2c_w1(gspca_dev, 0x75, comn);
Jean-François Moinef6b22e52010-02-18 04:12:06 -03002163 break;
Németh Márton76ad3b62010-10-19 03:33:47 -03002164 case SENSOR_PO2030N:
2165 /* Reg. 0x1E: Timing Generator Control Register 2 (Tgcontrol2)
2166 * (reset value: 0x0A)
2167 * bit7: HM: Horizontal Mirror: 0: disable, 1: enable
2168 * bit6: VM: Vertical Mirror: 0: disable, 1: enable
2169 * bit5: ST: Shutter Selection: 0: electrical, 1: mechanical
2170 * bit4: FT: Single Frame Transfer: 0: disable, 1: enable
2171 * bit3-0: X
2172 */
2173 comn = 0x0a;
2174 if (sd->ctrls[HFLIP].val)
2175 comn |= 0x80;
2176 if (sd->ctrls[VFLIP].val)
2177 comn |= 0x40;
2178 i2c_w1(&sd->gspca_dev, 0x1e, comn);
2179 break;
Hans de Goedef8009522009-06-18 14:29:20 -03002180 }
Jean-Francois Moine6c862742008-09-08 04:57:26 -03002181}
2182
Jean-François Moine72b667e2010-10-02 04:35:25 -03002183static void setsharpness(struct gspca_dev *gspca_dev)
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002184{
Jean-François Moine72b667e2010-10-02 04:35:25 -03002185 struct sd *sd = (struct sd *) gspca_dev;
2186
2187 reg_w1(gspca_dev, 0x99, sd->ctrls[SHARPNESS].val);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002188}
2189
Jean-François Moine3afef852011-01-13 06:39:11 -03002190static void setillum(struct gspca_dev *gspca_dev)
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002191{
Jean-François Moine72b667e2010-10-02 04:35:25 -03002192 struct sd *sd = (struct sd *) gspca_dev;
2193
Jean-François Moine3afef852011-01-13 06:39:11 -03002194 if (gspca_dev->ctrl_dis & (1 << ILLUM))
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03002195 return;
Jean-François Moinea63d6012011-01-13 07:56:00 -03002196 switch (sd->sensor) {
2197 case SENSOR_ADCM1700:
2198 reg_w1(gspca_dev, 0x02, /* gpio */
2199 sd->ctrls[ILLUM].val ? 0x64 : 0x60);
2200 break;
2201 case SENSOR_MT9V111:
2202 if (starcam)
2203 reg_w1(gspca_dev, 0x02,
2204 sd->ctrls[ILLUM].val ?
2205 0x55 : 0x54); /* 370i */
2206 else
2207 reg_w1(gspca_dev, 0x02,
2208 sd->ctrls[ILLUM].val ?
2209 0x66 : 0x64); /* Clip */
2210 break;
2211 }
Jean-Francois Moine0cae8962008-10-17 07:48:24 -03002212}
2213
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002214static void setfreq(struct gspca_dev *gspca_dev)
2215{
2216 struct sd *sd = (struct sd *) gspca_dev;
2217
Jean-François Moine72b667e2010-10-02 04:35:25 -03002218 if (gspca_dev->ctrl_dis & (1 << FREQ))
Jean-Francois Moine27954932009-07-08 05:21:50 -03002219 return;
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002220 if (sd->sensor == SENSOR_OV7660) {
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03002221 u8 com8;
2222
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03002223 com8 = 0xdf; /* auto gain/wb/expo */
Jean-François Moine72b667e2010-10-02 04:35:25 -03002224 switch (sd->ctrls[FREQ].val) {
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002225 case 0: /* Banding filter disabled */
Jean-Francois Moine47f7f6f2009-08-25 06:14:54 -03002226 i2c_w1(gspca_dev, 0x13, com8 | 0x20);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002227 break;
2228 case 1: /* 50 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03002229 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002230 i2c_w1(gspca_dev, 0x3b, 0x0a);
2231 break;
2232 case 2: /* 60 hz */
Jean-Francois Moined8f400e2009-07-08 06:33:44 -03002233 i2c_w1(gspca_dev, 0x13, com8);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002234 i2c_w1(gspca_dev, 0x3b, 0x02);
2235 break;
2236 }
2237 } else {
2238 u8 reg2a = 0, reg2b = 0, reg2d = 0;
2239
2240 /* Get reg2a / reg2d base values */
2241 switch (sd->sensor) {
2242 case SENSOR_OV7630:
2243 reg2a = 0x08;
2244 reg2d = 0x01;
2245 break;
2246 case SENSOR_OV7648:
2247 reg2a = 0x11;
2248 reg2d = 0x81;
2249 break;
2250 }
2251
Jean-François Moine72b667e2010-10-02 04:35:25 -03002252 switch (sd->ctrls[FREQ].val) {
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002253 case 0: /* Banding filter disabled */
2254 break;
2255 case 1: /* 50 hz (filter on and framerate adj) */
2256 reg2a |= 0x80;
2257 reg2b = 0xac;
2258 reg2d |= 0x04;
2259 break;
2260 case 2: /* 60 hz (filter on, no framerate adj) */
2261 reg2a |= 0x80;
2262 reg2d |= 0x04;
2263 break;
2264 }
2265 i2c_w1(gspca_dev, 0x2a, reg2a);
2266 i2c_w1(gspca_dev, 0x2b, reg2b);
2267 i2c_w1(gspca_dev, 0x2d, reg2d);
2268 }
2269}
2270
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002271static void setjpegqual(struct gspca_dev *gspca_dev)
2272{
2273 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002274
Jean-François Moinedccdccc2011-02-10 07:30:03 -03002275 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002276#if USB_BUF_SZ < 64
2277#error "No room enough in usb_buf for quantization table"
2278#endif
Jean-François Moinedccdccc2011-02-10 07:30:03 -03002279 memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT0_OFFSET], 64);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002280 usb_control_msg(gspca_dev->dev,
2281 usb_sndctrlpipe(gspca_dev->dev, 0),
2282 0x08,
2283 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2284 0x0100, 0,
2285 gspca_dev->usb_buf, 64,
2286 500);
Jean-François Moinedccdccc2011-02-10 07:30:03 -03002287 memcpy(gspca_dev->usb_buf, &sd->jpeg_hdr[JPEG_QT1_OFFSET], 64);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002288 usb_control_msg(gspca_dev->dev,
2289 usb_sndctrlpipe(gspca_dev->dev, 0),
2290 0x08,
2291 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
2292 0x0140, 0,
2293 gspca_dev->usb_buf, 64,
2294 500);
2295
2296 sd->reg18 ^= 0x40;
2297 reg_w1(gspca_dev, 0x18, sd->reg18);
2298}
2299
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002300/* -- start the camera -- */
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -03002301static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002302{
2303 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002304 int i;
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002305 u8 reg01, reg17;
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002306 u8 reg0102[2];
Jean-Francois Moine98819182009-01-19 07:37:33 -03002307 const u8 *sn9c1xx;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002308 const u8 (*init)[8];
Jean-Francois Moine4f67f3a2010-12-14 16:15:00 -03002309 const u8 *reg9a;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002310 int mode;
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002311 static const u8 reg9a_def[] =
2312 {0x00, 0x40, 0x20, 0x00, 0x00, 0x00};
2313 static const u8 reg9a_spec[] =
2314 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
2315 static const u8 regd4[] = {0x60, 0x00, 0x00};
Jean-Francois Moine98819182009-01-19 07:37:33 -03002316 static const u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
2317 static const u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
Jean-Francois Moine646775732009-12-20 12:31:28 -03002318 static const u8 CA_adcm1700[] =
2319 { 0x14, 0xec, 0x0a, 0xf6 };
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002320 static const u8 CA_po2030n[] =
2321 { 0x1e, 0xe2, 0x14, 0xec };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002322 static const u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002323 static const u8 CE_gc0307[] =
2324 { 0x32, 0xce, 0x2d, 0xd3 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002325 static const u8 CE_ov76xx[] =
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002326 { 0x32, 0xdd, 0x32, 0xdd };
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002327 static const u8 CE_po2030n[] =
2328 { 0x14, 0xe7, 0x1e, 0xdd };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002329
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002330 /* create the JPEG header */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002331 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
2332 0x21); /* JPEG 422 */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002333
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002334 /* initialize the bridge */
2335 sn9c1xx = sn_tb[sd->sensor];
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002336
2337 /* sensor clock already enabled in sd_init */
2338 /* reg_w1(gspca_dev, 0xf1, 0x00); */
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002339 reg01 = sn9c1xx[1];
Jean-François Moine3afef852011-01-13 06:39:11 -03002340 if (sd->flags & F_PDN_INV)
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002341 reg01 ^= S_PDN_INV; /* power down inverted */
2342 reg_w1(gspca_dev, 0x01, reg01);
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002343
2344 /* configure gpio */
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002345 reg0102[0] = reg01;
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002346 reg0102[1] = sn9c1xx[2];
2347 if (gspca_dev->audio)
2348 reg0102[1] |= 0x04; /* keep the audio connection */
2349 reg_w(gspca_dev, 0x01, reg0102, 2);
2350 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
2351 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5);
2352 switch (sd->sensor) {
2353 case SENSOR_GC0307:
2354 case SENSOR_OV7660:
2355 case SENSOR_PO1030:
2356 case SENSOR_PO2030N:
2357 case SENSOR_SOI768:
2358 case SENSOR_SP80708:
2359 reg9a = reg9a_spec;
2360 break;
2361 default:
2362 reg9a = reg9a_def;
2363 break;
2364 }
2365 reg_w(gspca_dev, 0x9a, reg9a, 6);
2366
2367 reg_w(gspca_dev, 0xd4, regd4, sizeof regd4);
2368
2369 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
2370
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002371 reg17 = sn9c1xx[0x17];
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002372 switch (sd->sensor) {
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002373 case SENSOR_GC0307:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002374 msleep(50); /*fixme: is it useful? */
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002375 break;
2376 case SENSOR_OM6802:
2377 msleep(10);
2378 reg_w1(gspca_dev, 0x02, 0x73);
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002379 reg17 |= SEN_CLK_EN;
2380 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002381 reg_w1(gspca_dev, 0x01, 0x22);
2382 msleep(100);
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002383 reg01 = SCL_SEL_OD | S_PDN_INV;
2384 reg17 &= MCK_SIZE_MASK;
2385 reg17 |= 0x04; /* clock / 4 */
2386 break;
2387 }
2388 reg01 |= SYS_SEL_48M;
2389 reg_w1(gspca_dev, 0x01, reg01);
2390 reg17 |= SEN_CLK_EN;
2391 reg_w1(gspca_dev, 0x17, reg17);
2392 reg01 &= ~S_PWR_DN; /* sensor power on */
2393 reg_w1(gspca_dev, 0x01, reg01);
2394 reg01 &= ~SYS_SEL_48M;
2395 reg_w1(gspca_dev, 0x01, reg01);
2396
2397 switch (sd->sensor) {
2398 case SENSOR_HV7131R:
2399 hv7131r_probe(gspca_dev); /*fixme: is it useful? */
2400 break;
2401 case SENSOR_OM6802:
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002402 msleep(10);
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002403 reg_w1(gspca_dev, 0x01, reg01);
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002404 i2c_w8(gspca_dev, om6802_init0[0]);
2405 i2c_w8(gspca_dev, om6802_init0[1]);
2406 msleep(15);
2407 reg_w1(gspca_dev, 0x02, 0x71);
2408 msleep(150);
2409 break;
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002410 case SENSOR_SP80708:
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002411 msleep(100);
2412 reg_w1(gspca_dev, 0x02, 0x62);
2413 break;
Jean-Francois Moine5e68f402010-12-14 16:14:10 -03002414 }
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-Francois Moine0e4d4132010-12-14 16:17:40 -03002442 case SENSOR_OM6802:
2443/* case SENSOR_OV7648: * fixme: sometimes */
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002444 break;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002445 default:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002446 reg17 |= DEF_EN;
Jean-Francois Moine568788a2008-07-15 11:46:06 -03002447 break;
2448 }
Jean-Francois Moine8f47a3c2008-07-29 14:14:04 -03002449 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002450
2451 reg_w1(gspca_dev, 0x05, 0x00); /* red */
2452 reg_w1(gspca_dev, 0x07, 0x00); /* green */
2453 reg_w1(gspca_dev, 0x06, 0x00); /* blue */
Jean-Francois Moine60017612008-07-18 08:46:19 -03002454 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
Jean-Francois Moineb083b922009-02-01 14:20:07 -03002455
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002456 setgamma(gspca_dev);
2457
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002458/*fixme: 8 times with all zeroes and 1 or 2 times with normal values */
Jean-Francois Moine05b809c2008-09-03 16:47:59 -03002459 for (i = 0; i < 8; i++)
2460 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002461 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002462 case SENSOR_ADCM1700:
Jean-Francois Moinec8b9b2c2009-04-26 14:46:12 -03002463 case SENSOR_OV7660:
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002464 case SENSOR_SP80708:
2465 reg_w1(gspca_dev, 0x9a, 0x05);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002466 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002467 case SENSOR_GC0307:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002468 case SENSOR_MT9V111:
Jean-François Moinea067db82010-10-01 07:51:24 -03002469 case SENSOR_MI0360B:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002470 reg_w1(gspca_dev, 0x9a, 0x07);
2471 break;
Jean-François Moine0a85c742010-04-25 14:33:31 -03002472 case SENSOR_OV7630:
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002473 case SENSOR_OV7648:
2474 reg_w1(gspca_dev, 0x9a, 0x0a);
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002475 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002476 case SENSOR_PO2030N:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002477 case SENSOR_SOI768:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002478 reg_w1(gspca_dev, 0x9a, 0x06);
2479 break;
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002480 default:
Jean-Francois Moine60017612008-07-18 08:46:19 -03002481 reg_w1(gspca_dev, 0x9a, 0x08);
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002482 break;
2483 }
Jean-François Moine72b667e2010-10-02 04:35:25 -03002484 setsharpness(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002485
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002486 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
Jean-Francois Moine878b35a2009-12-30 04:53:07 -03002487 reg_w1(gspca_dev, 0x05, 0x20); /* red */
2488 reg_w1(gspca_dev, 0x07, 0x20); /* green */
2489 reg_w1(gspca_dev, 0x06, 0x20); /* blue */
Jean-Francois Moine23a98272009-11-02 09:10:25 -03002490
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002491 init = NULL;
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002492 mode = gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv;
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002493 reg01 |= SYS_SEL_48M | V_TX_EN;
2494 reg17 &= ~MCK_SIZE_MASK;
2495 reg17 |= 0x02; /* clock / 2 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002496 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002497 case SENSOR_ADCM1700:
2498 init = adcm1700_sensor_param1;
Jean-Francois Moine646775732009-12-20 12:31:28 -03002499 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002500 case SENSOR_GC0307:
2501 init = gc0307_sensor_param1;
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002502 break;
2503 case SENSOR_HV7131R:
2504 case SENSOR_MI0360:
2505 if (mode)
2506 reg01 |= SYS_SEL_48M; /* 320x240: clk 48Mhz */
2507 else
2508 reg01 &= ~SYS_SEL_48M; /* 640x480: clk 24Mhz */
2509 reg17 &= ~MCK_SIZE_MASK;
2510 reg17 |= 0x01; /* clock / 1 */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002511 break;
Jean-François Moinea067db82010-10-01 07:51:24 -03002512 case SENSOR_MI0360B:
2513 init = mi0360b_sensor_param1;
Jean-François Moinea067db82010-10-01 07:51:24 -03002514 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002515 case SENSOR_MO4000:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002516 if (mode) { /* if 320x240 */
2517 reg01 &= ~SYS_SEL_48M; /* clk 24Mz */
2518 reg17 &= ~MCK_SIZE_MASK;
2519 reg17 |= 0x01; /* clock / 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002520 }
2521 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002522 case SENSOR_MT9V111:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002523 init = mt9v111_sensor_param1;
Jean-Francois Moine0fbe0572009-01-30 12:14:02 -03002524 break;
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002525 case SENSOR_OM6802:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002526 init = om6802_sensor_param1;
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002527 if (!mode) { /* if 640x480 */
2528 reg17 &= ~MCK_SIZE_MASK;
Jean-François Moineaa777a82010-12-28 07:39:13 -03002529 reg17 |= 0x04; /* clock / 4 */
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002530 }
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03002531 break;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002532 case SENSOR_OV7630:
Jean-François Moinebdd2b932010-04-25 14:23:39 -03002533 init = ov7630_sensor_param1;
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002534 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002535 case SENSOR_OV7648:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002536 init = ov7648_sensor_param1;
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002537 reg17 &= ~MCK_SIZE_MASK;
2538 reg17 |= 0x01; /* clock / 1 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002539 break;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002540 case SENSOR_OV7660:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002541 init = ov7660_sensor_param1;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002542 break;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002543 case SENSOR_PO1030:
2544 init = po1030_sensor_param1;
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002545 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002546 case SENSOR_PO2030N:
2547 init = po2030n_sensor_param1;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002548 break;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002549 case SENSOR_SOI768:
2550 init = soi768_sensor_param1;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002551 break;
Jean-François Moine0303a902010-10-21 04:05:15 -03002552 case SENSOR_SP80708:
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002553 init = sp80708_sensor_param1;
Jean-Francois Moine5e31dc82009-02-01 13:59:42 -03002554 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002555 }
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002556
2557 /* more sensor initialization - param1 */
2558 if (init != NULL) {
2559 i2c_w_seq(gspca_dev, init);
2560/* init = NULL; */
2561 }
2562
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002563 reg_w(gspca_dev, 0xc0, C0, 6);
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002564 switch (sd->sensor) {
2565 case SENSOR_ADCM1700:
2566 case SENSOR_GC0307:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002567 case SENSOR_SOI768:
Jean-Francois Moine646775732009-12-20 12:31:28 -03002568 reg_w(gspca_dev, 0xca, CA_adcm1700, 4);
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002569 break;
2570 case SENSOR_PO2030N:
2571 reg_w(gspca_dev, 0xca, CA_po2030n, 4);
2572 break;
2573 default:
Jean-Francois Moine646775732009-12-20 12:31:28 -03002574 reg_w(gspca_dev, 0xca, CA, 4);
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002575 break;
2576 }
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002577 switch (sd->sensor) {
Jean-Francois Moine646775732009-12-20 12:31:28 -03002578 case SENSOR_ADCM1700:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002579 case SENSOR_OV7630:
2580 case SENSOR_OV7648:
Jean-Francois Moine674cbc62008-10-02 08:06:59 -03002581 case SENSOR_OV7660:
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002582 case SENSOR_SOI768:
Jean-Francois Moine6ab0b172008-09-03 16:47:34 -03002583 reg_w(gspca_dev, 0xce, CE_ov76xx, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002584 break;
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002585 case SENSOR_GC0307:
2586 reg_w(gspca_dev, 0xce, CE_gc0307, 4);
2587 break;
2588 case SENSOR_PO2030N:
2589 reg_w(gspca_dev, 0xce, CE_po2030n, 4);
2590 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002591 default:
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002592 reg_w(gspca_dev, 0xce, CE, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002593 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
2594 break;
2595 }
2596
2597 /* here change size mode 0 -> VGA; 1 -> CIF */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -03002598 sd->reg18 = sn9c1xx[0x18] | (mode << 4) | 0x40;
2599 reg_w1(gspca_dev, 0x18, sd->reg18);
2600 setjpegqual(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002601
Jean-Francois Moine60017612008-07-18 08:46:19 -03002602 reg_w1(gspca_dev, 0x17, reg17);
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002603 reg_w1(gspca_dev, 0x01, reg01);
2604 sd->reg01 = reg01;
2605 sd->reg17 = reg17;
Jean-Francois Moine3fccb772009-11-02 09:54:04 -03002606
Németh Márton76ad3b62010-10-19 03:33:47 -03002607 sethvflip(gspca_dev);
Jean-Francois Moine91bd3412008-11-23 14:47:50 -03002608 setbrightness(gspca_dev);
2609 setcontrast(gspca_dev);
Jean-François Moinefff2f702010-04-25 14:31:05 -03002610 setcolors(gspca_dev);
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002611 setautogain(gspca_dev);
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002612 setfreq(gspca_dev);
Jean-François Moine4bf8b672010-09-25 06:12:44 -03002613 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002614}
2615
2616static void sd_stopN(struct gspca_dev *gspca_dev)
2617{
2618 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002619 static const u8 stophv7131[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002620 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002621 static const u8 stopmi0360[] =
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002622 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine98819182009-01-19 07:37:33 -03002623 static const u8 stopov7648[] =
Jean-Francois Moine62703302008-11-11 08:42:56 -03002624 { 0xa1, 0x21, 0x76, 0x20, 0x00, 0x00, 0x00, 0x10 };
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002625 static const u8 stopsoi768[] =
2626 { 0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10 };
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002627 u8 reg01;
2628 u8 reg17;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002629
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002630 reg01 = sd->reg01;
2631 reg17 = sd->reg17 & ~SEN_CLK_EN;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002632 switch (sd->sensor) {
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002633 case SENSOR_ADCM1700:
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002634 case SENSOR_GC0307:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002635 case SENSOR_PO2030N:
2636 case SENSOR_SP80708:
2637 reg01 |= LED;
2638 reg_w1(gspca_dev, 0x01, reg01);
2639 reg01 &= ~(LED | V_TX_EN);
2640 reg_w1(gspca_dev, 0x01, reg01);
2641/* reg_w1(gspca_dev, 0x02, 0x??); * LED off ? */
Jean-François Moinead98c0f2010-03-18 05:15:30 -03002642 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002643 case SENSOR_HV7131R:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002644 reg01 &= ~V_TX_EN;
2645 reg_w1(gspca_dev, 0x01, reg01);
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002646 i2c_w8(gspca_dev, stophv7131);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002647 break;
2648 case SENSOR_MI0360:
Jean-François Moinea067db82010-10-01 07:51:24 -03002649 case SENSOR_MI0360B:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002650 reg01 &= ~V_TX_EN;
2651 reg_w1(gspca_dev, 0x01, reg01);
2652/* reg_w1(gspca_dev, 0x02, 0x40); * LED off ? */
Jean-Francois Moine739570b2008-07-14 09:38:29 -03002653 i2c_w8(gspca_dev, stopmi0360);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002654 break;
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002655 case SENSOR_MT9V111:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002656 case SENSOR_OM6802:
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03002657 case SENSOR_PO1030:
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002658 reg01 &= ~V_TX_EN;
2659 reg_w1(gspca_dev, 0x01, reg01);
2660 break;
2661 case SENSOR_OV7630:
2662 case SENSOR_OV7648:
2663 reg01 &= ~V_TX_EN;
2664 reg_w1(gspca_dev, 0x01, reg01);
2665 i2c_w8(gspca_dev, stopov7648);
2666 break;
2667 case SENSOR_OV7660:
2668 reg01 &= ~V_TX_EN;
2669 reg_w1(gspca_dev, 0x01, reg01);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002670 break;
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002671 case SENSOR_SOI768:
2672 i2c_w8(gspca_dev, stopsoi768);
Jean-François Moine03ed2a12010-04-25 14:45:43 -03002673 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002674 }
Jean-Francois Moine0e4d4132010-12-14 16:17:40 -03002675
2676 reg01 |= SCL_SEL_OD;
2677 reg_w1(gspca_dev, 0x01, reg01);
2678 reg01 |= S_PWR_DN; /* sensor power down */
2679 reg_w1(gspca_dev, 0x01, reg01);
2680 reg_w1(gspca_dev, 0x17, reg17);
2681 reg01 &= ~SYS_SEL_48M; /* clock 24MHz */
2682 reg_w1(gspca_dev, 0x01, reg01);
2683 reg01 |= LED;
2684 reg_w1(gspca_dev, 0x01, reg01);
Hans de Goede9712a8b2010-01-31 12:54:29 -03002685 /* Don't disable sensor clock as that disables the button on the cam */
2686 /* reg_w1(gspca_dev, 0xf1, 0x01); */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002687}
2688
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002689static void do_autogain(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002690{
2691 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002692 int delta;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002693 int expotimes;
Jean-Francois Moine98819182009-01-19 07:37:33 -03002694 u8 luma_mean = 130;
2695 u8 luma_delta = 20;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002696
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002697 /* Thanks S., without your advice, autobright should not work :) */
2698 if (sd->ag_cnt < 0)
2699 return;
2700 if (--sd->ag_cnt >= 0)
2701 return;
2702 sd->ag_cnt = AG_CNT_START;
2703
2704 delta = atomic_read(&sd->avg_lum);
2705 PDEBUG(D_FRAM, "mean lum %d", delta);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002706 if (delta < luma_mean - luma_delta ||
2707 delta > luma_mean + luma_delta) {
2708 switch (sd->sensor) {
Jean-François Moinec26b12d2010-04-02 07:08:39 -03002709 case SENSOR_GC0307:
2710 expotimes = sd->exposure;
2711 expotimes += (luma_mean - delta) >> 6;
2712 if (expotimes < 0)
2713 expotimes = 0;
2714 sd->exposure = setexposure(gspca_dev,
2715 (unsigned int) expotimes);
2716 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002717 case SENSOR_HV7131R:
2718 expotimes = sd->exposure >> 8;
2719 expotimes += (luma_mean - delta) >> 4;
2720 if (expotimes < 0)
2721 expotimes = 0;
2722 sd->exposure = setexposure(gspca_dev,
2723 (unsigned int) (expotimes << 8));
2724 break;
Amauri Magagna46b4f2a2009-10-17 07:21:29 -03002725 case SENSOR_OM6802:
2726 expotimes = sd->exposure;
2727 expotimes += (luma_mean - delta) >> 2;
2728 if (expotimes < 0)
2729 expotimes = 0;
2730 sd->exposure = setexposure(gspca_dev,
2731 (unsigned int) expotimes);
2732 setredblue(gspca_dev);
2733 break;
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002734 default:
2735/* case SENSOR_MO4000: */
2736/* case SENSOR_MI0360: */
Jean-François Moinea067db82010-10-01 07:51:24 -03002737/* case SENSOR_MI0360B: */
Jean-Francois Moine3ef2c5b2009-01-29 04:59:45 -03002738/* case SENSOR_MT9V111: */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002739 expotimes = sd->exposure;
2740 expotimes += (luma_mean - delta) >> 6;
2741 if (expotimes < 0)
2742 expotimes = 0;
2743 sd->exposure = setexposure(gspca_dev,
2744 (unsigned int) expotimes);
Jean-Francois Moine403123d2008-11-26 04:46:15 -03002745 setredblue(gspca_dev);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002746 break;
2747 }
2748 }
2749}
2750
Jean-François Moine0f77f402011-02-10 07:01:30 -03002751/* set the average luminosity from an isoc marker */
2752static void set_lum(struct sd *sd,
2753 u8 *data)
2754{
2755 int avg_lum;
2756
2757 /* w0 w1 w2
2758 * w3 w4 w5
2759 * w6 w7 w8
2760 */
2761 avg_lum = (data[27] << 8) + data[28] /* w3 */
2762
2763 + (data[31] << 8) + data[32] /* w5 */
2764
2765 + (data[23] << 8) + data[24] /* w1 */
2766
2767 + (data[35] << 8) + data[36] /* w7 */
2768
2769 + (data[29] << 10) + (data[30] << 2); /* w4 * 4 */
2770 avg_lum >>= 10;
2771 atomic_set(&sd->avg_lum, avg_lum);
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;
Jean-François Moinea4a30762011-02-10 07:15:24 -03002781 int i;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002782
Jean-François Moinea4a30762011-02-10 07:15:24 -03002783 /*
2784 * A frame ends on the marker
2785 * ff ff 00 c4 c4 96 ..
2786 * which is 62 bytes long and is followed by various information
2787 * including statuses and luminosity.
2788 *
2789 * A marker may be splitted on two packets.
2790 *
2791 * The 6th byte of a marker contains the bits:
2792 * 0x08: USB full
2793 * 0xc0: frame sequence
2794 * When the bit 'USB full' is set, the frame must be discarded;
2795 * this is also the case when the 2 bytes before the marker are
2796 * not the JPEG end of frame ('ff d9').
2797 */
2798
2799/*fixme: assumption about the following code:
2800 * - there can be only one marker in a packet
2801 */
2802
2803 /* skip the remaining bytes of a short marker */
2804 i = sd->short_mark;
2805 if (i != 0) {
2806 sd->short_mark = 0;
2807 if (i < 0 /* if 'ff' at end of previous packet */
2808 && data[0] == 0xff
2809 && data[1] == 0x00)
2810 goto marker_found;
2811 if (data[0] == 0xff && data[1] == 0xff) {
2812 i = 0;
2813 goto marker_found;
2814 }
2815 len -= i;
2816 if (len <= 0)
2817 return;
2818 data += i;
2819 }
2820
2821 /* search backwards if there is a marker in the packet */
2822 for (i = len - 1; --i >= 0; ) {
2823 if (data[i] != 0xff) {
2824 i--;
2825 continue;
2826 }
2827 if (data[i + 1] == 0xff) {
2828
2829 /* (there may be 'ff ff' inside a marker) */
2830 if (i + 2 >= len || data[i + 2] == 0x00)
2831 goto marker_found;
2832 }
2833 }
2834
2835 /* no marker found */
2836 /* add the JPEG header if first fragment */
2837 if (data[len - 1] == 0xff)
2838 sd->short_mark = -1;
2839 if (gspca_dev->last_packet_type == LAST_PACKET)
Jean-François Moinea95bd642010-10-01 07:54:30 -03002840 gspca_frame_add(gspca_dev, FIRST_PACKET,
2841 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-François Moinea95bd642010-10-01 07:54:30 -03002842 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-François Moinea4a30762011-02-10 07:15:24 -03002843 return;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002844
Jean-François Moinea4a30762011-02-10 07:15:24 -03002845 /* marker found */
2846 /* if some error, discard the frame */
2847marker_found:
2848 if (i > 2) {
2849 if (data[i - 2] != 0xff || data[i - 1] != 0xd9) {
2850 gspca_dev->last_packet_type = DISCARD_PACKET;
2851 }
2852 } else if (i + 6 < len) {
2853 if (data[i + 6] & 0x08) {
2854 gspca_dev->last_packet_type = DISCARD_PACKET;
2855 }
2856 }
Jean-François Moinea95bd642010-10-01 07:54:30 -03002857
Jean-François Moinea4a30762011-02-10 07:15:24 -03002858 gspca_frame_add(gspca_dev, LAST_PACKET, data, i);
2859
2860 /* if the marker is smaller than 62 bytes,
2861 * memorize the number of bytes to skip in the next packet */
2862 if (i + 62 > len) { /* no more usable data */
2863 sd->short_mark = i + 62 - len;
2864 return;
2865 }
2866
Jean-François Moine0f77f402011-02-10 07:01:30 -03002867 if (sd->ag_cnt >= 0)
Jean-François Moinea4a30762011-02-10 07:15:24 -03002868 set_lum(sd, data + i);
2869
2870 /* if more data, start a new frame */
2871 i += 62;
2872 if (i < len) {
2873 data += i;
2874 len -= i;
2875 gspca_frame_add(gspca_dev, FIRST_PACKET,
2876 sd->jpeg_hdr, JPEG_HDR_SZ);
2877 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
2878 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002879}
2880
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002881static int sd_set_jcomp(struct gspca_dev *gspca_dev,
2882 struct v4l2_jpegcompression *jcomp)
2883{
2884 struct sd *sd = (struct sd *) gspca_dev;
2885
2886 if (jcomp->quality < QUALITY_MIN)
2887 sd->quality = QUALITY_MIN;
2888 else if (jcomp->quality > QUALITY_MAX)
2889 sd->quality = QUALITY_MAX;
2890 else
2891 sd->quality = jcomp->quality;
2892 if (gspca_dev->streaming)
Jean-François Moinedccdccc2011-02-10 07:30:03 -03002893 setjpegqual(gspca_dev);
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002894 return 0;
2895}
2896
2897static int sd_get_jcomp(struct gspca_dev *gspca_dev,
2898 struct v4l2_jpegcompression *jcomp)
2899{
2900 struct sd *sd = (struct sd *) gspca_dev;
2901
2902 memset(jcomp, 0, sizeof *jcomp);
2903 jcomp->quality = sd->quality;
2904 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
2905 | V4L2_JPEG_MARKER_DQT;
2906 return 0;
2907}
2908
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002909static int sd_querymenu(struct gspca_dev *gspca_dev,
2910 struct v4l2_querymenu *menu)
2911{
2912 switch (menu->id) {
2913 case V4L2_CID_POWER_LINE_FREQUENCY:
2914 switch (menu->index) {
2915 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
2916 strcpy((char *) menu->name, "NoFliker");
2917 return 0;
2918 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
2919 strcpy((char *) menu->name, "50 Hz");
2920 return 0;
2921 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
2922 strcpy((char *) menu->name, "60 Hz");
2923 return 0;
2924 }
2925 break;
2926 }
2927 return -EINVAL;
2928}
2929
Jean-François Moine28566432010-10-01 07:33:26 -03002930#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede9712a8b2010-01-31 12:54:29 -03002931static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
2932 u8 *data, /* interrupt packet data */
2933 int len) /* interrupt packet length */
2934{
2935 int ret = -EINVAL;
2936
2937 if (len == 1 && data[0] == 1) {
2938 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
2939 input_sync(gspca_dev->input_dev);
2940 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
2941 input_sync(gspca_dev->input_dev);
2942 ret = 0;
2943 }
2944
2945 return ret;
2946}
2947#endif
2948
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002949/* sub-driver description */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -03002950static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002951 .name = MODULE_NAME,
2952 .ctrls = sd_ctrls,
Jean-François Moine72b667e2010-10-02 04:35:25 -03002953 .nctrls = NCTRLS,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002954 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03002955 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002956 .start = sd_start,
2957 .stopN = sd_stopN,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002958 .pkt_scan = sd_pkt_scan,
Jean-Francois Moinecebf3b62008-08-03 07:52:53 -03002959 .dq_callback = do_autogain,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03002960 .get_jcomp = sd_get_jcomp,
2961 .set_jcomp = sd_set_jcomp,
Hans de Goede37c6dbe2009-06-18 07:35:36 -03002962 .querymenu = sd_querymenu,
Jean-François Moine28566432010-10-01 07:33:26 -03002963#if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
Hans de Goede9712a8b2010-01-31 12:54:29 -03002964 .int_pkt_scan = sd_int_pkt_scan,
2965#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002966};
2967
2968/* -- module initialisation -- */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002969#define BS(bridge, sensor) \
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03002970 .driver_info = (BRIDGE_ ## bridge << 16) \
Jean-Francois Moinec6c14332010-12-14 16:15:37 -03002971 | (SENSOR_ ## sensor << 8)
2972#define BSF(bridge, sensor, flags) \
2973 .driver_info = (BRIDGE_ ## bridge << 16) \
2974 | (SENSOR_ ## sensor << 8) \
2975 | (flags)
Jean-François Moine95c967c2011-01-13 05:20:29 -03002976static const struct usb_device_id device_table[] = {
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002977 {USB_DEVICE(0x0458, 0x7025), BS(SN9C120, MI0360)},
2978 {USB_DEVICE(0x0458, 0x702e), BS(SN9C120, OV7660)},
Jean-François Moine3afef852011-01-13 06:39:11 -03002979 {USB_DEVICE(0x045e, 0x00f5), BSF(SN9C105, OV7660, F_PDN_INV)},
2980 {USB_DEVICE(0x045e, 0x00f7), BSF(SN9C105, OV7660, F_PDN_INV)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002981 {USB_DEVICE(0x0471, 0x0327), BS(SN9C105, MI0360)},
2982 {USB_DEVICE(0x0471, 0x0328), BS(SN9C105, MI0360)},
2983 {USB_DEVICE(0x0471, 0x0330), BS(SN9C105, MI0360)},
2984 {USB_DEVICE(0x06f8, 0x3004), BS(SN9C105, OV7660)},
2985 {USB_DEVICE(0x06f8, 0x3008), BS(SN9C105, OV7660)},
2986/* {USB_DEVICE(0x0c45, 0x603a), BS(SN9C102P, OV7648)}, */
2987 {USB_DEVICE(0x0c45, 0x6040), BS(SN9C102P, HV7131R)},
2988/* {USB_DEVICE(0x0c45, 0x607a), BS(SN9C102P, OV7648)}, */
2989/* {USB_DEVICE(0x0c45, 0x607b), BS(SN9C102P, OV7660)}, */
2990 {USB_DEVICE(0x0c45, 0x607c), BS(SN9C102P, HV7131R)},
2991/* {USB_DEVICE(0x0c45, 0x607e), BS(SN9C102P, OV7630)}, */
Jean-François Moine3afef852011-01-13 06:39:11 -03002992 {USB_DEVICE(0x0c45, 0x60c0), BSF(SN9C105, MI0360, F_ILLUM)},
Jean-François Moinea067db82010-10-01 07:51:24 -03002993 /* or MT9V111 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002994/* {USB_DEVICE(0x0c45, 0x60c2), BS(SN9C105, P1030xC)}, */
2995/* {USB_DEVICE(0x0c45, 0x60c8), BS(SN9C105, OM6802)}, */
2996/* {USB_DEVICE(0x0c45, 0x60cc), BS(SN9C105, HV7131GP)}, */
Warren Bosworth Fockec4f95d82010-05-07 15:40:04 -03002997 {USB_DEVICE(0x0c45, 0x60ce), BS(SN9C105, SP80708)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03002998 {USB_DEVICE(0x0c45, 0x60ec), BS(SN9C105, MO4000)},
2999/* {USB_DEVICE(0x0c45, 0x60ef), BS(SN9C105, ICM105C)}, */
3000/* {USB_DEVICE(0x0c45, 0x60fa), BS(SN9C105, OV7648)}, */
Jean-François Moine68046752010-05-07 15:35:08 -03003001/* {USB_DEVICE(0x0c45, 0x60f2), BS(SN9C105, OV7660)}, */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003002 {USB_DEVICE(0x0c45, 0x60fb), BS(SN9C105, OV7660)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003003 {USB_DEVICE(0x0c45, 0x60fc), BS(SN9C105, HV7131R)},
3004 {USB_DEVICE(0x0c45, 0x60fe), BS(SN9C105, OV7630)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003005 {USB_DEVICE(0x0c45, 0x6100), BS(SN9C120, MI0360)}, /*sn9c128*/
Jean-François Moine860e7f42010-09-13 06:40:17 -03003006 {USB_DEVICE(0x0c45, 0x6102), BS(SN9C120, PO2030N)}, /* /GC0305*/
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003007/* {USB_DEVICE(0x0c45, 0x6108), BS(SN9C120, OM6802)}, */
3008 {USB_DEVICE(0x0c45, 0x610a), BS(SN9C120, OV7648)}, /*sn9c128*/
3009 {USB_DEVICE(0x0c45, 0x610b), BS(SN9C120, OV7660)}, /*sn9c128*/
3010 {USB_DEVICE(0x0c45, 0x610c), BS(SN9C120, HV7131R)}, /*sn9c128*/
3011 {USB_DEVICE(0x0c45, 0x610e), BS(SN9C120, OV7630)}, /*sn9c128*/
3012/* {USB_DEVICE(0x0c45, 0x610f), BS(SN9C120, S5K53BEB)}, */
3013/* {USB_DEVICE(0x0c45, 0x6122), BS(SN9C110, ICM105C)}, */
3014/* {USB_DEVICE(0x0c45, 0x6123), BS(SN9C110, SanyoCCD)}, */
3015 {USB_DEVICE(0x0c45, 0x6128), BS(SN9C120, OM6802)}, /*sn9c325?*/
Jean-Francois Moined2d16e92008-09-03 16:47:23 -03003016/*bw600.inf:*/
Jean-Francois Moineb8c8a5b2009-11-23 06:46:35 -03003017 {USB_DEVICE(0x0c45, 0x612a), BS(SN9C120, OV7648)}, /*sn9c325?*/
Alexander Goncharov2a3b5012010-09-13 06:58:16 -03003018 {USB_DEVICE(0x0c45, 0x612b), BS(SN9C110, ADCM1700)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003019 {USB_DEVICE(0x0c45, 0x612c), BS(SN9C110, MO4000)},
3020 {USB_DEVICE(0x0c45, 0x612e), BS(SN9C110, OV7630)},
3021/* {USB_DEVICE(0x0c45, 0x612f), BS(SN9C110, ICM105C)}, */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003022 {USB_DEVICE(0x0c45, 0x6130), BS(SN9C120, MI0360)},
Jean-François Moinea067db82010-10-01 07:51:24 -03003023 /* or MT9V111 / MI0360B */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003024/* {USB_DEVICE(0x0c45, 0x6132), BS(SN9C120, OV7670)}, */
3025 {USB_DEVICE(0x0c45, 0x6138), BS(SN9C120, MO4000)},
3026 {USB_DEVICE(0x0c45, 0x613a), BS(SN9C120, OV7648)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003027 {USB_DEVICE(0x0c45, 0x613b), BS(SN9C120, OV7660)},
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003028 {USB_DEVICE(0x0c45, 0x613c), BS(SN9C120, HV7131R)},
3029 {USB_DEVICE(0x0c45, 0x613e), BS(SN9C120, OV7630)},
Jean-François Moinead98c0f2010-03-18 05:15:30 -03003030 {USB_DEVICE(0x0c45, 0x6142), BS(SN9C120, PO2030N)}, /*sn9c120b*/
Jean-François Moine68046752010-05-07 15:35:08 -03003031 /* or GC0305 / GC0307 */
Jean-Francois Moined5aa3852009-11-07 06:10:08 -03003032 {USB_DEVICE(0x0c45, 0x6143), BS(SN9C120, SP80708)}, /*sn9c120b*/
3033 {USB_DEVICE(0x0c45, 0x6148), BS(SN9C120, OM6802)}, /*sn9c120b*/
Jean-François Moinea63d6012011-01-13 07:56:00 -03003034 {USB_DEVICE(0x0c45, 0x614a), BSF(SN9C120, ADCM1700, F_ILLUM)},
Hans de Goedee48d38f2011-01-06 16:21:57 -03003035/* {USB_DEVICE(0x0c45, 0x614c), BS(SN9C120, GC0306)}, */ /*sn9c120b*/
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003036 {}
3037};
3038MODULE_DEVICE_TABLE(usb, device_table);
3039
3040/* -- device connect -- */
3041static int sd_probe(struct usb_interface *intf,
3042 const struct usb_device_id *id)
3043{
3044 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
3045 THIS_MODULE);
3046}
3047
3048static struct usb_driver sd_driver = {
3049 .name = MODULE_NAME,
3050 .id_table = device_table,
3051 .probe = sd_probe,
3052 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03003053#ifdef CONFIG_PM
3054 .suspend = gspca_suspend,
3055 .resume = gspca_resume,
3056#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003057};
3058
3059/* -- module insert / remove -- */
3060static int __init sd_mod_init(void)
3061{
Jean-François Moine54826432010-09-13 04:53:03 -03003062 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003063}
3064static void __exit sd_mod_exit(void)
3065{
3066 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03003067}
3068
3069module_init(sd_mod_init);
3070module_exit(sd_mod_exit);
Jean-François Moine3afef852011-01-13 06:39:11 -03003071
3072module_param(starcam, int, 0644);
3073MODULE_PARM_DESC(starcam,
3074 "StarCam model. 0: Clip, 1: 370i");