V4L/DVB (8442): gspca: Remove the version from the subdrivers.
[linux-2.6/kvm.git] / drivers / media / video / gspca / sonixj.c
blob35b1a3ee4c3f806634e4484f3562144b7495a0ed
1 /*
2 * Sonix sn9c102p sn9c105 sn9c120 (jpeg) library
3 * Copyright (C) 2005 Michel Xhaard mxhaard@magic.fr
5 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
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.
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.
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
22 #define MODULE_NAME "sonixj"
24 #include "gspca.h"
25 #include "jpeg.h"
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SONIX JPEG USB Camera Driver");
29 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
32 struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */
35 int avg_lum;
36 unsigned int exposure;
38 unsigned short brightness;
39 unsigned char contrast;
40 unsigned char colors;
41 unsigned char autogain;
43 signed char ag_cnt;
44 #define AG_CNT_START 13
46 char qindex;
47 unsigned char bridge;
48 #define BRIDGE_SN9C102P 0
49 #define BRIDGE_SN9C105 1
50 #define BRIDGE_SN9C110 2
51 #define BRIDGE_SN9C120 3
52 #define BRIDGE_SN9C325 4
53 char sensor; /* Type of image sensor chip */
54 #define SENSOR_HV7131R 0
55 #define SENSOR_MI0360 1
56 #define SENSOR_MO4000 2
57 #define SENSOR_OV7648 3
58 #define SENSOR_OV7660 4
59 unsigned char i2c_base;
62 /* V4L2 controls supported by the driver */
63 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
64 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
65 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
66 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
67 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
68 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
69 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
70 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
72 static struct ctrl sd_ctrls[] = {
75 .id = V4L2_CID_BRIGHTNESS,
76 .type = V4L2_CTRL_TYPE_INTEGER,
77 .name = "Brightness",
78 .minimum = 0,
79 .maximum = 0xffff,
80 .step = 1,
81 #define BRIGHTNESS_DEF 0x7fff
82 .default_value = BRIGHTNESS_DEF,
84 .set = sd_setbrightness,
85 .get = sd_getbrightness,
89 .id = V4L2_CID_CONTRAST,
90 .type = V4L2_CTRL_TYPE_INTEGER,
91 .name = "Contrast",
92 .minimum = 0,
93 .maximum = 127,
94 .step = 1,
95 #define CONTRAST_DEF 63
96 .default_value = CONTRAST_DEF,
98 .set = sd_setcontrast,
99 .get = sd_getcontrast,
103 .id = V4L2_CID_SATURATION,
104 .type = V4L2_CTRL_TYPE_INTEGER,
105 .name = "Color",
106 .minimum = 0,
107 .maximum = 255,
108 .step = 1,
109 #define COLOR_DEF 127
110 .default_value = COLOR_DEF,
112 .set = sd_setcolors,
113 .get = sd_getcolors,
117 .id = V4L2_CID_AUTOGAIN,
118 .type = V4L2_CTRL_TYPE_BOOLEAN,
119 .name = "Auto Gain",
120 .minimum = 0,
121 .maximum = 1,
122 .step = 1,
123 #define AUTOGAIN_DEF 1
124 .default_value = AUTOGAIN_DEF,
126 .set = sd_setautogain,
127 .get = sd_getautogain,
131 static struct v4l2_pix_format vga_mode[] = {
132 {160, 120, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
133 .bytesperline = 160,
134 .sizeimage = 160 * 120 * 3 / 8 + 590,
135 .colorspace = V4L2_COLORSPACE_JPEG,
136 .priv = 2},
137 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
138 .bytesperline = 320,
139 .sizeimage = 320 * 240 * 3 / 8 + 590,
140 .colorspace = V4L2_COLORSPACE_JPEG,
141 .priv = 1},
142 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
143 .bytesperline = 640,
144 .sizeimage = 640 * 480 * 3 / 8 + 590,
145 .colorspace = V4L2_COLORSPACE_JPEG,
146 .priv = 0},
149 /*Data from sn9c102p+hv71331r */
150 static const __u8 sn_hv7131[] = {
151 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
152 0x00, 0x03, 0x64, 0x00, 0x1A, 0x20, 0x20, 0x20, 0xA1, 0x11,
153 /* rega regb regc regd rege regf reg10 reg11 */
154 0x02, 0x09, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, /* 00 */
155 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
156 0x00, 0x01, 0x03, 0x28, 0x1e, 0x41, 0x0a, 0x00, 0x00, 0x00,
157 /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
161 static const __u8 sn_mi0360[] = {
162 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 reg9 */
163 0x00, 0x61, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xb1, 0x5d,
164 /* rega regb regc regd rege regf reg10 reg11 */
165 0x07, 0x00, 0x00, 0x00, 0x00, 0x10, 0x03, 0x00,
166 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a reg1b */
167 0x00, 0x02, 0x0a, 0x28, 0x1e, 0x61, 0x06, 0x00, 0x00, 0x00,
168 /* reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23 */
169 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
172 static const __u8 sn_mo4000[] = {
173 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
174 0x12, 0x23, 0x60, 0x00, 0x1A, 0x00, 0x20, 0x18, 0x81,
175 /* reg9 rega regb regc regd rege regf reg10 reg11*/
176 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
177 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
178 0x0b, 0x0f, 0x14, 0x28, 0x1e, 0x40, 0x08, 0x00, 0x00,
179 /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x25, 0x39, 0x4b,
181 0x5c, 0x6b, 0x79, 0x87, 0x95, 0xa2, 0xaf, 0xbb, 0xc7,
182 0xd3, 0xdf, 0xea, 0xf5
185 static const __u8 sn_ov7648[] = {
186 0x00, 0x21, 0x62, 0x00, 0x1a, 0x20, 0x20, 0x20, 0xA1, 0x6E, 0x18, 0x65,
187 0x00, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x06, 0x06, 0x28, 0x1E, 0x82,
188 0x07, 0x00, 0x00, 0x00, 0x00, 0x00
191 static const __u8 sn_ov7660[] = {
192 /* reg0 reg1 reg2 reg3 reg4 reg5 reg6 reg7 reg8 */
193 0x00, 0x61, 0x40, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x81,
194 /* reg9 rega regb regc regd rege regf reg10 reg11*/
195 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00,
196 /* reg12 reg13 reg14 reg15 reg16 reg17 reg18 reg19 reg1a*/
197 0x01, 0x01, 0x14, 0x28, 0x1e, 0x00, 0x07, 0x00, 0x00,
198 /* reg1b reg1c reg1d reg1e reg1f reg20 reg21 reg22 reg23*/
199 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
202 /* sequence specific to the sensors - !! index = SENSOR_xxx */
203 static const __u8 *sn_tb[] = {
204 sn_hv7131,
205 sn_mi0360,
206 sn_mo4000,
207 sn_ov7648,
208 sn_ov7660
211 static const __u8 regsn20[] = {
212 0x00, 0x2d, 0x46, 0x5a, 0x6c, 0x7c, 0x8b, 0x99,
213 0xa6, 0xb2, 0xbf, 0xca, 0xd5, 0xe0, 0xeb, 0xf5, 0xff
215 static const __u8 regsn20_sn9c120[] = {
216 0x00, 0x25, 0x3c, 0x50, 0x62, 0x72, 0x81, 0x90,
217 0x9e, 0xab, 0xb8, 0xc5, 0xd1, 0xdd, 0xe9, 0xf4, 0xff
219 static const __u8 regsn20_sn9c325[] = {
220 0x0a, 0x3a, 0x56, 0x6c, 0x7e, 0x8d, 0x9a, 0xa4,
221 0xaf, 0xbb, 0xc5, 0xcd, 0xd5, 0xde, 0xe8, 0xed, 0xf5
224 static const __u8 reg84[] = {
225 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe5, 0x0f,
226 0xe4, 0x0f, 0x38, 0x00, 0x3e, 0x00, 0xc3, 0x0f,
227 /* 0x00, 0x00, 0x00, 0x00, 0x00 */
228 0xf7, 0x0f, 0x0a, 0x00, 0x00
230 static const __u8 reg84_sn9c120_1[] = {
231 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
232 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
233 0x00, 0x00, 0x0c, 0x00, 0x00
235 static const __u8 reg84_sn9c120_2[] = {
236 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
237 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
238 0x00, 0x00, 0x0c, 0x02, 0x3b
240 static const __u8 reg84_sn9c120_3[] = {
241 0x14, 0x00, 0x27, 0x00, 0x08, 0x00, 0xeb, 0x0f,
242 0xd5, 0x0f, 0x42, 0x00, 0x41, 0x00, 0xca, 0x0f,
243 0xf5, 0x0f, 0x0c, 0x02, 0x3b
245 static const __u8 reg84_sn9c325[] = {
246 0x14, 0x00, 0x27, 0x00, 0x07, 0x00, 0xe4, 0x0f,
247 0xd3, 0x0f, 0x4b, 0x00, 0x48, 0x00, 0xc0, 0x0f,
248 0xf8, 0x0f, 0x00, 0x00, 0x00
251 static const __u8 hv7131r_sensor_init[][8] = {
252 {0xC1, 0x11, 0x01, 0x08, 0x01, 0x00, 0x00, 0x10},
253 {0xB1, 0x11, 0x34, 0x17, 0x7F, 0x00, 0x00, 0x10},
254 {0xD1, 0x11, 0x40, 0xFF, 0x7F, 0x7F, 0x7F, 0x10},
255 {0x91, 0x11, 0x44, 0x00, 0x00, 0x00, 0x00, 0x10},
256 {0xD1, 0x11, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
257 {0xD1, 0x11, 0x14, 0x01, 0xE2, 0x02, 0x82, 0x10},
258 {0x91, 0x11, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
260 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
261 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
262 {0xC1, 0x11, 0x25, 0x00, 0x61, 0xA8, 0x00, 0x10},
263 {0xA1, 0x11, 0x30, 0x22, 0x00, 0x00, 0x00, 0x10},
264 {0xC1, 0x11, 0x31, 0x20, 0x2E, 0x20, 0x00, 0x10},
265 {0xC1, 0x11, 0x25, 0x00, 0xC3, 0x50, 0x00, 0x10},
266 {0xA1, 0x11, 0x30, 0x07, 0x00, 0x00, 0x00, 0x10}, /* gain14 */
267 {0xC1, 0x11, 0x31, 0x10, 0x10, 0x10, 0x00, 0x10}, /* r g b 101a10 */
269 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
270 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
271 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
272 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
273 {0xA1, 0x11, 0x23, 0x09, 0x00, 0x00, 0x00, 0x10},
275 {0xA1, 0x11, 0x01, 0x08, 0x00, 0x00, 0x00, 0x10},
276 {0xA1, 0x11, 0x20, 0x00, 0x00, 0x00, 0x00, 0x10},
277 {0xA1, 0x11, 0x21, 0xD0, 0x00, 0x00, 0x00, 0x10},
278 {0xA1, 0x11, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
279 {0xA1, 0x11, 0x23, 0x10, 0x00, 0x00, 0x00, 0x10},
282 static const __u8 mi0360_sensor_init[][8] = {
283 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10},
284 {0xB1, 0x5D, 0x0D, 0x00, 0x01, 0x00, 0x00, 0x10},
285 {0xB1, 0x5D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x10},
286 {0xD1, 0x5D, 0x01, 0x00, 0x08, 0x00, 0x16, 0x10},
287 {0xD1, 0x5D, 0x03, 0x01, 0xE2, 0x02, 0x82, 0x10},
288 {0xD1, 0x5D, 0x05, 0x00, 0x09, 0x00, 0x53, 0x10},
289 {0xB1, 0x5D, 0x0D, 0x00, 0x02, 0x00, 0x00, 0x10},
290 {0xD1, 0x5D, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x10},
291 {0xD1, 0x5D, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x10},
292 {0xD1, 0x5D, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x10},
293 {0xD1, 0x5D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
294 {0xD1, 0x5D, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
295 {0xD1, 0x5D, 0x14, 0x00, 0x00, 0x00, 0x00, 0x10},
296 {0xD1, 0x5D, 0x16, 0x00, 0x00, 0x00, 0x00, 0x10},
297 {0xD1, 0x5D, 0x18, 0x00, 0x00, 0x00, 0x00, 0x10},
298 {0xD1, 0x5D, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x10},
299 {0xD1, 0x5D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x10},
300 {0xB1, 0x5D, 0x32, 0x00, 0x00, 0x00, 0x00, 0x10},
301 {0xD1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
302 {0xD1, 0x5D, 0x22, 0x00, 0x00, 0x00, 0x00, 0x10},
303 {0xD1, 0x5D, 0x24, 0x00, 0x00, 0x00, 0x00, 0x10},
304 {0xD1, 0x5D, 0x26, 0x00, 0x00, 0x00, 0x24, 0x10},
305 {0xD1, 0x5D, 0x2F, 0xF7, 0xB0, 0x00, 0x04, 0x10},
306 {0xD1, 0x5D, 0x31, 0x00, 0x00, 0x00, 0x00, 0x10},
307 {0xD1, 0x5D, 0x33, 0x00, 0x00, 0x01, 0x00, 0x10},
308 {0xB1, 0x5D, 0x3D, 0x06, 0x8F, 0x00, 0x00, 0x10},
309 {0xD1, 0x5D, 0x40, 0x01, 0xE0, 0x00, 0xD1, 0x10},
310 {0xB1, 0x5D, 0x44, 0x00, 0x82, 0x00, 0x00, 0x10},
311 {0xD1, 0x5D, 0x58, 0x00, 0x78, 0x00, 0x43, 0x10},
312 {0xD1, 0x5D, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x10},
313 {0xD1, 0x5D, 0x5C, 0x00, 0x00, 0x00, 0x00, 0x10},
314 {0xD1, 0x5D, 0x5E, 0x00, 0x00, 0xA3, 0x1D, 0x10},
315 {0xB1, 0x5D, 0x62, 0x04, 0x11, 0x00, 0x00, 0x10},
317 {0xB1, 0x5D, 0x20, 0x91, 0x01, 0x00, 0x00, 0x10},
318 {0xB1, 0x5D, 0x20, 0x11, 0x01, 0x00, 0x00, 0x10},
319 {0xB1, 0x5D, 0x09, 0x00, 0x64, 0x00, 0x00, 0x10},
320 {0xD1, 0x5D, 0x2B, 0x00, 0xA0, 0x00, 0xB0, 0x10},
321 {0xD1, 0x5D, 0x2D, 0x00, 0xA0, 0x00, 0xA0, 0x10},
323 {0xB1, 0x5D, 0x0A, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor clck ?2 */
324 {0xB1, 0x5D, 0x06, 0x00, 0x30, 0x00, 0x00, 0x10},
325 {0xB1, 0x5D, 0x05, 0x00, 0x0A, 0x00, 0x00, 0x10},
326 {0xB1, 0x5D, 0x09, 0x02, 0x35, 0x00, 0x00, 0x10}, /* exposure 2 */
328 {0xD1, 0x5D, 0x2B, 0x00, 0xB9, 0x00, 0xE3, 0x10},
329 {0xD1, 0x5D, 0x2D, 0x00, 0x5f, 0x00, 0xB9, 0x10}, /* 42 */
330 /* {0xB1, 0x5D, 0x35, 0x00, 0x67, 0x00, 0x00, 0x10}, * gain orig */
331 /* {0xB1, 0x5D, 0x35, 0x00, 0x20, 0x00, 0x00, 0x10}, * gain */
332 {0xB1, 0x5D, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10}, /* update */
333 {0xB1, 0x5D, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10}, /* sensor on */
336 static const __u8 mo4000_sensor_init[][8] = {
337 {0xa1, 0x21, 0x01, 0x02, 0x00, 0x00, 0x00, 0x10},
338 {0xa1, 0x21, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10},
339 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
340 {0xa1, 0x21, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10},
341 {0xa1, 0x21, 0x05, 0x00, 0x00, 0x00, 0x00, 0x10},
342 {0xa1, 0x21, 0x05, 0x04, 0x00, 0x00, 0x00, 0x10},
343 {0xa1, 0x21, 0x06, 0x80, 0x00, 0x00, 0x00, 0x10},
344 {0xa1, 0x21, 0x06, 0x81, 0x00, 0x00, 0x00, 0x10},
345 {0xa1, 0x21, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x10},
346 {0xa1, 0x21, 0x11, 0x00, 0x00, 0x00, 0x00, 0x10},
347 {0xa1, 0x21, 0x11, 0x20, 0x00, 0x00, 0x00, 0x10},
348 {0xa1, 0x21, 0x11, 0x30, 0x00, 0x00, 0x00, 0x10},
349 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
350 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
351 {0xa1, 0x21, 0x12, 0x00, 0x00, 0x00, 0x00, 0x10},
352 {0xa1, 0x21, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10},
353 {0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10},
354 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10},
355 {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10},
356 {0xa1, 0x21, 0x11, 0x38, 0x00, 0x00, 0x00, 0x10},
359 static const __u8 ov7660_sensor_init[][8] = {
360 {0xa1, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10}, /* reset SCCB */
361 /* (delay 20ms) */
362 {0xa1, 0x21, 0x12, 0x05, 0x00, 0x00, 0x00, 0x10},
363 /* Outformat ?? rawRGB */
364 {0xa1, 0x21, 0x13, 0xb8, 0x00, 0x00, 0x00, 0x10}, /* init COM8 */
365 {0xd1, 0x21, 0x00, 0x01, 0x74, 0x92, 0x00, 0x10},
366 /* {0xd1, 0x21, 0x00, 0x01, 0x74, 0x74, 0x00, 0x10}, */
367 /* GAIN BLUE RED VREF */
368 {0xd1, 0x21, 0x04, 0x00, 0x7d, 0x62, 0x00, 0x10},
369 /* COM 1 BAVE GEAVE AECHH */
370 {0xb1, 0x21, 0x08, 0x83, 0x01, 0x00, 0x00, 0x10}, /* RAVE COM2 */
371 {0xd1, 0x21, 0x0c, 0x00, 0x08, 0x04, 0x4f, 0x10}, /* COM 3 4 5 6 */
372 {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xf8, 0x10},
373 /* {0xd1, 0x21, 0x10, 0x7f, 0x40, 0x05, 0xff, 0x10}, */
374 /* AECH CLKRC COM7 COM8 */
375 {0xc1, 0x21, 0x14, 0x2c, 0x00, 0x02, 0x00, 0x10}, /* COM9 COM10 */
376 {0xd1, 0x21, 0x17, 0x10, 0x60, 0x02, 0x7b, 0x10},
377 /* HSTART HSTOP VSTRT VSTOP */
378 {0xa1, 0x21, 0x1b, 0x02, 0x00, 0x00, 0x00, 0x10}, /* PSHFT */
379 {0xb1, 0x21, 0x1e, 0x01, 0x0e, 0x00, 0x00, 0x10}, /* MVFP LAEC */
380 {0xd1, 0x21, 0x20, 0x07, 0x07, 0x07, 0x07, 0x10},
381 /* BOS GBOS GROS ROS (BGGR offset) */
382 {0xd1, 0x21, 0x24, 0x68, 0x58, 0xd4, 0x80, 0x10},
383 /* {0xd1, 0x21, 0x24, 0x78, 0x68, 0xd4, 0x80, 0x10}, */
384 /* AEW AEB VPT BBIAS */
385 {0xd1, 0x21, 0x28, 0x80, 0x30, 0x00, 0x00, 0x10},
386 /* GbBIAS RSVD EXHCH EXHCL */
387 {0xd1, 0x21, 0x2c, 0x80, 0x00, 0x00, 0x62, 0x10},
388 /* RBIAS ADVFL ASDVFH YAVE */
389 {0xc1, 0x21, 0x30, 0x08, 0x30, 0xb4, 0x00, 0x10},
390 /* HSYST HSYEN HREF */
391 {0xd1, 0x21, 0x33, 0x00, 0x07, 0x84, 0x00, 0x10}, /* reserved */
392 {0xd1, 0x21, 0x37, 0x0c, 0x02, 0x43, 0x00, 0x10},
393 /* ADC ACOM OFON TSLB */
394 {0xd1, 0x21, 0x3b, 0x02, 0x6c, 0x19, 0x0e, 0x10},
395 /* COM11 COM12 COM13 COM14 */
396 {0xd1, 0x21, 0x3f, 0x41, 0xc1, 0x22, 0x08, 0x10},
397 /* EDGE COM15 COM16 COM17 */
398 {0xd1, 0x21, 0x43, 0xf0, 0x10, 0x78, 0xa8, 0x10}, /* reserved */
399 {0xd1, 0x21, 0x47, 0x60, 0x80, 0x00, 0x00, 0x10}, /* reserved */
400 {0xd1, 0x21, 0x4b, 0x00, 0x00, 0x00, 0x00, 0x10}, /* reserved */
401 {0xd1, 0x21, 0x4f, 0x46, 0x36, 0x0f, 0x17, 0x10}, /* MTX 1 2 3 4 */
402 {0xd1, 0x21, 0x53, 0x7f, 0x96, 0x40, 0x40, 0x10}, /* MTX 5 6 7 8 */
403 {0xb1, 0x21, 0x57, 0x40, 0x0f, 0x00, 0x00, 0x10}, /* MTX9 MTXS */
404 {0xd1, 0x21, 0x59, 0xba, 0x9a, 0x22, 0xb9, 0x10}, /* reserved */
405 {0xd1, 0x21, 0x5d, 0x9b, 0x10, 0xf0, 0x05, 0x10}, /* reserved */
406 {0xa1, 0x21, 0x61, 0x60, 0x00, 0x00, 0x00, 0x10}, /* reserved */
407 {0xd1, 0x21, 0x62, 0x00, 0x00, 0x50, 0x30, 0x10},
408 /* LCC1 LCC2 LCC3 LCC4 */
409 {0xa1, 0x21, 0x66, 0x00, 0x00, 0x00, 0x00, 0x10}, /* LCC5 */
410 {0xd1, 0x21, 0x67, 0x80, 0x7a, 0x90, 0x80, 0x10},
411 {0xa1, 0x21, 0x6b, 0x0a, 0x00, 0x00, 0x00, 0x10},
412 /* band gap reference [0..3] DBLV */
413 {0xd1, 0x21, 0x6c, 0x30, 0x48, 0x80, 0x74, 0x10}, /* gamma curve */
414 {0xd1, 0x21, 0x70, 0x64, 0x60, 0x5c, 0x58, 0x10}, /* gamma curve */
415 {0xd1, 0x21, 0x74, 0x54, 0x4c, 0x40, 0x38, 0x10}, /* gamma curve */
416 {0xd1, 0x21, 0x78, 0x34, 0x30, 0x2f, 0x2b, 0x10}, /* gamma curve */
417 {0xd1, 0x21, 0x7c, 0x03, 0x07, 0x17, 0x34, 0x10}, /* gamma curve */
418 {0xd1, 0x21, 0x80, 0x41, 0x4d, 0x58, 0x63, 0x10}, /* gamma curve */
419 {0xd1, 0x21, 0x84, 0x6e, 0x77, 0x87, 0x95, 0x10}, /* gamma curve */
420 {0xc1, 0x21, 0x88, 0xaf, 0xc7, 0xdf, 0x00, 0x10}, /* gamma curve */
421 {0xc1, 0x21, 0x8b, 0x99, 0x99, 0xcf, 0x00, 0x10}, /* reserved */
422 {0xb1, 0x21, 0x92, 0x00, 0x00, 0x00, 0x00, 0x10},
423 /****** (some exchanges in the win trace) ******/
424 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
425 /* bits[3..0]reserved */
426 {0xa1, 0x21, 0x1e, 0x01, 0x00, 0x00, 0x00, 0x10},
427 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
428 /* VREF vertical frame ctrl */
429 {0xa1, 0x21, 0x03, 0x00, 0x00, 0x00, 0x00, 0x10},
430 {0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10}, /* 0x20 */
431 {0xa1, 0x21, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x10},
432 {0xa1, 0x21, 0x2e, 0x00, 0x00, 0x00, 0x00, 0x10},
433 /* {0xa1, 0x21, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x10}, */
434 {0xa1, 0x21, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x10},
435 {0xb1, 0x21, 0x01, 0x78, 0x78, 0x00, 0x00, 0x10},
436 /****** (some exchanges in the win trace) ******/
437 {0xa1, 0x21, 0x93, 0x00, 0x00, 0x00, 0x00, 0x10},/* dummy line hight */
438 {0xa1, 0x21, 0x92, 0x25, 0x00, 0x00, 0x00, 0x10},/* dummy line low */
439 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
440 {0xa1, 0x21, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10},
441 {0xa1, 0x21, 0x02, 0x90, 0x00, 0x00, 0x00, 0x10},
442 /****** (some exchanges in the win trace) ******/
443 /**********startsensor KO if changed !!****/
444 {0xa1, 0x21, 0x93, 0x01, 0x00, 0x00, 0x00, 0x10},
445 {0xa1, 0x21, 0x92, 0xff, 0x00, 0x00, 0x00, 0x10},
446 {0xa1, 0x21, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x10},
447 {0xa1, 0x21, 0x2b, 0xc3, 0x00, 0x00, 0x00, 0x10},
448 /* here may start the isoc exchanges */
451 /* reg0x04 reg0x07 reg 0x10 */
452 /* expo = (COM1 & 0x02) | (AECHH & 0x2f <<10) [ (AECh << 2) */
454 static const __u8 ov7648_sensor_init[][8] = {
455 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
456 {0xC1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00},
457 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
458 {0xA1, 0x6E, 0x3F, 0x20, 0x00, 0x00, 0x00, 0x10},
459 {0xA1, 0x6E, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x10},
460 {0xA1, 0x6E, 0x3E, 0x00, 0x00, 0x00, 0x00, 0x10},
461 {0xD1, 0x6E, 0x04, 0x02, 0xB1, 0x02, 0x39, 0x10},
462 {0xD1, 0x6E, 0x08, 0x00, 0x01, 0x00, 0x00, 0x10},
463 {0xD1, 0x6E, 0x0C, 0x02, 0x7F, 0x01, 0xE0, 0x10},
464 {0xD1, 0x6E, 0x12, 0x03, 0x02, 0x00, 0x03, 0x10},
465 {0xD1, 0x6E, 0x16, 0x85, 0x40, 0x4A, 0x40, 0x10},
466 {0xC1, 0x6E, 0x1A, 0x00, 0x80, 0x00, 0x00, 0x10},
467 {0xD1, 0x6E, 0x1D, 0x08, 0x03, 0x00, 0x00, 0x10},
468 {0xD1, 0x6E, 0x23, 0x00, 0xB0, 0x00, 0x94, 0x10},
469 {0xD1, 0x6E, 0x27, 0x58, 0x00, 0x00, 0x00, 0x10},
470 {0xD1, 0x6E, 0x2D, 0x14, 0x35, 0x61, 0x84, 0x10},
471 {0xD1, 0x6E, 0x31, 0xA2, 0xBD, 0xD8, 0xFF, 0x10},
472 {0xD1, 0x6E, 0x35, 0x06, 0x1E, 0x12, 0x02, 0x10},
473 {0xD1, 0x6E, 0x39, 0xAA, 0x53, 0x37, 0xD5, 0x10},
474 {0xA1, 0x6E, 0x3D, 0xF2, 0x00, 0x00, 0x00, 0x10},
475 {0xD1, 0x6E, 0x3E, 0x00, 0x00, 0x80, 0x03, 0x10},
476 {0xD1, 0x6E, 0x42, 0x03, 0x00, 0x00, 0x00, 0x10},
477 {0xC1, 0x6E, 0x46, 0x00, 0x80, 0x80, 0x00, 0x10},
478 {0xD1, 0x6E, 0x4B, 0x02, 0xEF, 0x08, 0xCD, 0x10},
479 {0xD1, 0x6E, 0x4F, 0x00, 0xD0, 0x00, 0xA0, 0x10},
480 {0xD1, 0x6E, 0x53, 0x01, 0xAA, 0x01, 0x40, 0x10},
481 {0xD1, 0x6E, 0x5A, 0x50, 0x04, 0x30, 0x03, 0x10},
482 {0xA1, 0x6E, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x10},
483 {0xD1, 0x6E, 0x5F, 0x10, 0x40, 0xFF, 0x00, 0x10},
484 /* {0xD1, 0x6E, 0x63, 0x40, 0x40, 0x00, 0x00, 0x10},
485 {0xD1, 0x6E, 0x67, 0x00, 0x00, 0x00, 0x00, 0x10},
486 * This is currently setting a
487 * blue tint, and some things more , i leave it here for future test if
488 * somene is having problems with color on this sensor
489 {0xD1, 0x6E, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x10},
490 {0xD1, 0x6E, 0x6F, 0x00, 0x00, 0x00, 0x00, 0x10},
491 {0xC1, 0x6E, 0x73, 0x10, 0x80, 0xEB, 0x00, 0x10},
492 {0xA1, 0x6E, 0x1E, 0x03, 0x00, 0x00, 0x00, 0x10},
493 {0xA1, 0x6E, 0x15, 0x01, 0x00, 0x00, 0x00, 0x10},
494 {0xC1, 0x6E, 0x16, 0x40, 0x40, 0x40, 0x00, 0x10},
495 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
496 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
497 {0xA1, 0x6E, 0x07, 0xB5, 0x00, 0x00, 0x00, 0x10},
498 {0xA1, 0x6E, 0x18, 0x6B, 0x00, 0x00, 0x00, 0x10},
499 {0xA1, 0x6E, 0x1D, 0x08, 0x00, 0x00, 0x00, 0x10},
500 {0xA1, 0x6E, 0x06, 0x02, 0x00, 0x00, 0x00, 0x10},
501 {0xA1, 0x6E, 0x07, 0xB8, 0x00, 0x00, 0x00, 0x10}, */
502 {0xC1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00},
503 {0xA1, 0x6E, 0x06, 0x03, 0x00, 0x00, 0x00, 0x10}, /* Bright... */
504 {0xA1, 0x6E, 0x07, 0x66, 0x00, 0x00, 0x00, 0x10}, /* B.. */
505 {0xC1, 0x6E, 0x1A, 0x03, 0x65, 0x90, 0x00, 0x10}, /* Bright/Witen....*/
506 /* {0xC1, 0x6E, 0x16, 0x45, 0x40, 0x60, 0x00, 0x10}, * Bright/Witene */
510 static const __u8 qtable4[] = {
511 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x06, 0x06, 0x06, 0x08, 0x06,
512 0x06, 0x08, 0x0A, 0x11,
513 0x0A, 0x0A, 0x08, 0x08, 0x0A, 0x15, 0x0F, 0x0F, 0x0C, 0x11, 0x19, 0x15,
514 0x19, 0x19, 0x17, 0x15,
515 0x17, 0x17, 0x1B, 0x1D, 0x25, 0x21, 0x1B, 0x1D, 0x23, 0x1D, 0x17, 0x17,
516 0x21, 0x2E, 0x21, 0x23,
517 0x27, 0x29, 0x2C, 0x2C, 0x2C, 0x19, 0x1F, 0x30, 0x32, 0x2E, 0x29, 0x32,
518 0x25, 0x29, 0x2C, 0x29,
519 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A, 0x13, 0x0A, 0x0A, 0x13, 0x29, 0x1B,
520 0x17, 0x1B, 0x29, 0x29,
521 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
522 0x29, 0x29, 0x29, 0x29,
523 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
524 0x29, 0x29, 0x29, 0x29,
525 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
526 0x29, 0x29, 0x29, 0x29
529 /* read <len> bytes (len < sizeof gspca_dev->usb_buf) to gspca_dev->usb_buf */
530 static void reg_r(struct gspca_dev *gspca_dev,
531 __u16 value, int len)
533 usb_control_msg(gspca_dev->dev,
534 usb_rcvctrlpipe(gspca_dev->dev, 0),
536 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
537 value, 0,
538 gspca_dev->usb_buf, len,
539 500);
540 PDEBUG(D_USBI, "reg_r [%02x] -> %02x", value, gspca_dev->usb_buf[0]);
543 static void reg_w1(struct gspca_dev *gspca_dev,
544 __u16 value,
545 __u8 data)
547 PDEBUG(D_USBO, "reg_w1 [%02x] = %02x", value, data);
548 gspca_dev->usb_buf[0] = data;
549 usb_control_msg(gspca_dev->dev,
550 usb_sndctrlpipe(gspca_dev->dev, 0),
551 0x08,
552 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
553 value,
555 gspca_dev->usb_buf, 1,
556 500);
558 static void reg_w(struct gspca_dev *gspca_dev,
559 __u16 value,
560 const __u8 *buffer,
561 int len)
563 PDEBUG(D_USBO, "reg_w [%02x] = %02x %02x ..",
564 value, buffer[0], buffer[1]);
565 if (len <= sizeof gspca_dev->usb_buf) {
566 memcpy(gspca_dev->usb_buf, buffer, len);
567 usb_control_msg(gspca_dev->dev,
568 usb_sndctrlpipe(gspca_dev->dev, 0),
569 0x08,
570 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
571 value, 0,
572 gspca_dev->usb_buf, len,
573 500);
574 } else {
575 __u8 *tmpbuf;
577 tmpbuf = kmalloc(len, GFP_KERNEL);
578 memcpy(tmpbuf, buffer, len);
579 usb_control_msg(gspca_dev->dev,
580 usb_sndctrlpipe(gspca_dev->dev, 0),
581 0x08,
582 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
583 value, 0,
584 tmpbuf, len,
585 500);
586 kfree(tmpbuf);
590 /* I2C write 1 byte */
591 static void i2c_w1(struct gspca_dev *gspca_dev, __u8 reg, __u8 val)
593 struct sd *sd = (struct sd *) gspca_dev;
595 PDEBUG(D_USBO, "i2c_w2 [%02x] = %02x", reg, val);
596 gspca_dev->usb_buf[0] = 0x81 | (2 << 4); /* = a1 */
597 gspca_dev->usb_buf[1] = sd->i2c_base;
598 gspca_dev->usb_buf[2] = reg;
599 gspca_dev->usb_buf[3] = val;
600 gspca_dev->usb_buf[4] = 0;
601 gspca_dev->usb_buf[5] = 0;
602 gspca_dev->usb_buf[6] = 0;
603 gspca_dev->usb_buf[7] = 0x10;
604 usb_control_msg(gspca_dev->dev,
605 usb_sndctrlpipe(gspca_dev->dev, 0),
606 0x08,
607 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
608 0x08, /* value = i2c */
610 gspca_dev->usb_buf, 8,
611 500);
614 /* I2C write 8 bytes */
615 static void i2c_w8(struct gspca_dev *gspca_dev,
616 const __u8 *buffer)
618 memcpy(gspca_dev->usb_buf, buffer, 8);
619 usb_control_msg(gspca_dev->dev,
620 usb_sndctrlpipe(gspca_dev->dev, 0),
621 0x08,
622 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
623 0x08, 0, /* value, index */
624 gspca_dev->usb_buf, 8,
625 500);
628 /* read 5 bytes in gspca_dev->usb_buf */
629 static void i2c_r5(struct gspca_dev *gspca_dev, __u8 reg)
631 struct sd *sd = (struct sd *) gspca_dev;
632 __u8 mode[8];
634 mode[0] = 0x81 | 0x10;
635 mode[1] = sd->i2c_base;
636 mode[2] = reg;
637 mode[3] = 0;
638 mode[4] = 0;
639 mode[5] = 0;
640 mode[6] = 0;
641 mode[7] = 0x10;
642 i2c_w8(gspca_dev, mode);
643 msleep(2);
644 mode[0] = 0x81 | (5 << 4) | 0x02;
645 mode[2] = 0;
646 i2c_w8(gspca_dev, mode);
647 msleep(2);
648 reg_r(gspca_dev, 0x0a, 5);
651 static int probesensor(struct gspca_dev *gspca_dev)
653 struct sd *sd = (struct sd *) gspca_dev;
655 i2c_w1(gspca_dev, 0x02, 0); /* sensor wakeup */
656 msleep(10);
657 reg_w1(gspca_dev, 0x02, 0x66); /* Gpio on */
658 msleep(10);
659 i2c_r5(gspca_dev, 0); /* read sensor id */
660 if (gspca_dev->usb_buf[0] == 0x02
661 && gspca_dev->usb_buf[1] == 0x09
662 && gspca_dev->usb_buf[2] == 0x01
663 && gspca_dev->usb_buf[3] == 0x00
664 && gspca_dev->usb_buf[4] == 0x00) {
665 PDEBUG(D_PROBE, "Find Sensor sn9c102P HV7131R");
666 sd->sensor = SENSOR_HV7131R;
667 return SENSOR_HV7131R;
669 PDEBUG(D_PROBE, "Find Sensor 0x%02x 0x%02x 0x%02x",
670 gspca_dev->usb_buf[0], gspca_dev->usb_buf[1],
671 gspca_dev->usb_buf[2]);
672 PDEBUG(D_PROBE, "Sensor sn9c102P Not found");
673 return -ENODEV;
676 static int configure_gpio(struct gspca_dev *gspca_dev,
677 const __u8 *sn9c1xx)
679 struct sd *sd = (struct sd *) gspca_dev;
680 const __u8 *reg9a;
681 static const __u8 reg9a_def[] =
682 {0x08, 0x40, 0x20, 0x10, 0x00, 0x04};
683 static const __u8 reg9a_sn9c120[] = /* from win trace */
684 {0x00, 0x40, 0x38, 0x30, 0x00, 0x20};
685 static const __u8 reg9a_sn9c325[] =
686 {0x0a, 0x40, 0x38, 0x30, 0x00, 0x20};
688 reg_w1(gspca_dev, 0xf1, 0x00);
689 reg_w1(gspca_dev, 0x01, sn9c1xx[0]); /*fixme:jfm was [1] en v1*/
691 /* configure gpio */
692 reg_w(gspca_dev, 0x01, &sn9c1xx[1], 2);
693 reg_w(gspca_dev, 0x08, &sn9c1xx[8], 2);
694 reg_w(gspca_dev, 0x17, &sn9c1xx[0x17], 5); /* jfm len was 3 */
695 switch (sd->bridge) {
696 case BRIDGE_SN9C325:
697 reg9a = reg9a_sn9c325;
698 break;
699 case BRIDGE_SN9C120:
700 reg9a = reg9a_sn9c120;
701 break;
702 default:
703 reg9a = reg9a_def;
704 break;
706 reg_w(gspca_dev, 0x9a, reg9a, 6);
708 reg_w1(gspca_dev, 0xd4, 0x60); /*fixme:jfm 60 00 00 (3) ? */
710 reg_w(gspca_dev, 0x03, &sn9c1xx[3], 0x0f);
712 switch (sd->bridge) {
713 case BRIDGE_SN9C120: /* from win trace */
714 reg_w1(gspca_dev, 0x01, 0x61);
715 reg_w1(gspca_dev, 0x17, 0x20);
716 reg_w1(gspca_dev, 0x01, 0x60);
717 break;
718 case BRIDGE_SN9C325:
719 reg_w1(gspca_dev, 0x01, 0x43);
720 reg_w1(gspca_dev, 0x17, 0xae);
721 reg_w1(gspca_dev, 0x01, 0x42);
722 break;
723 default:
724 reg_w1(gspca_dev, 0x01, 0x43);
725 reg_w1(gspca_dev, 0x17, 0x61);
726 reg_w1(gspca_dev, 0x01, 0x42);
729 if (sd->sensor == SENSOR_HV7131R) {
730 if (probesensor(gspca_dev) < 0)
731 return -ENODEV;
733 return 0;
736 static void hv7131R_InitSensor(struct gspca_dev *gspca_dev)
738 int i = 0;
739 static const __u8 SetSensorClk[] = /* 0x08 Mclk */
740 { 0xa1, 0x11, 0x01, 0x18, 0x00, 0x00, 0x00, 0x10 };
742 while (hv7131r_sensor_init[i][0]) {
743 i2c_w8(gspca_dev, hv7131r_sensor_init[i]);
744 i++;
746 i2c_w8(gspca_dev, SetSensorClk);
749 static void mi0360_InitSensor(struct gspca_dev *gspca_dev)
751 int i = 0;
753 while (mi0360_sensor_init[i][0]) {
754 i2c_w8(gspca_dev, mi0360_sensor_init[i]);
755 i++;
759 static void mo4000_InitSensor(struct gspca_dev *gspca_dev)
761 int i = 0;
763 while (mo4000_sensor_init[i][0]) {
764 i2c_w8(gspca_dev, mo4000_sensor_init[i]);
765 i++;
769 static void ov7648_InitSensor(struct gspca_dev *gspca_dev)
771 int i = 0;
773 while (ov7648_sensor_init[i][0]) {
774 i2c_w8(gspca_dev, ov7648_sensor_init[i]);
775 i++;
779 static void ov7660_InitSensor(struct gspca_dev *gspca_dev)
781 int i = 0;
783 i2c_w8(gspca_dev, ov7660_sensor_init[i]); /* reset SCCB */
784 i++;
785 msleep(20);
786 while (ov7660_sensor_init[i][0]) {
787 i2c_w8(gspca_dev, ov7660_sensor_init[i]);
788 i++;
792 /* this function is called at probe time */
793 static int sd_config(struct gspca_dev *gspca_dev,
794 const struct usb_device_id *id)
796 struct sd *sd = (struct sd *) gspca_dev;
797 struct cam *cam;
798 __u16 product;
800 product = id->idProduct;
801 sd->sensor = -1;
802 switch (id->idVendor) {
803 case 0x0458: /* Genius */
804 /* switch (product) {
805 case 0x7025: */
806 sd->bridge = BRIDGE_SN9C120;
807 sd->sensor = SENSOR_MI0360;
808 sd->i2c_base = 0x5d;
809 /* break;
810 } */
811 break;
812 case 0x045e:
813 /* switch (product) {
814 case 0x00f5:
815 case 0x00f7: */
816 sd->bridge = BRIDGE_SN9C105;
817 sd->sensor = SENSOR_OV7660;
818 sd->i2c_base = 0x21;
819 /* break;
820 } */
821 break;
822 case 0x0471: /* Philips */
823 /* switch (product) {
824 case 0x0327:
825 case 0x0328:
826 case 0x0330: */
827 sd->bridge = BRIDGE_SN9C105;
828 sd->sensor = SENSOR_MI0360;
829 sd->i2c_base = 0x5d;
830 /* break;
831 } */
832 break;
833 case 0x0c45: /* Sonix */
834 switch (product) {
835 case 0x6040:
836 sd->bridge = BRIDGE_SN9C102P;
837 /* sd->sensor = SENSOR_MI0360; * from BW600.inf */
838 /*fixme: MI0360 base=5d ? */
839 sd->sensor = SENSOR_HV7131R; /* gspcav1 value */
840 sd->i2c_base = 0x11;
841 break;
842 /* case 0x607a: * from BW600.inf
843 sd->bridge = BRIDGE_SN9C102P;
844 sd->sensor = SENSOR_OV7648;
845 sd->i2c_base = 0x??;
846 break; */
847 case 0x607c:
848 sd->bridge = BRIDGE_SN9C102P;
849 sd->sensor = SENSOR_HV7131R;
850 sd->i2c_base = 0x11;
851 break;
852 /* case 0x607e: * from BW600.inf
853 sd->bridge = BRIDGE_SN9C102P;
854 sd->sensor = SENSOR_OV7630;
855 sd->i2c_base = 0x??;
856 break; */
857 case 0x60c0:
858 sd->bridge = BRIDGE_SN9C105;
859 sd->sensor = SENSOR_MI0360;
860 sd->i2c_base = 0x5d;
861 break;
862 /* case 0x60c8: * from BW600.inf
863 sd->bridge = BRIDGE_SN9C105;
864 sd->sensor = SENSOR_OM6801;
865 sd->i2c_base = 0x??;
866 break; */
867 /* case 0x60cc: * from BW600.inf
868 sd->bridge = BRIDGE_SN9C105;
869 sd->sensor = SENSOR_HV7131GP;
870 sd->i2c_base = 0x??;
871 break; */
872 case 0x60ec:
873 sd->bridge = BRIDGE_SN9C105;
874 sd->sensor = SENSOR_MO4000;
875 sd->i2c_base = 0x21;
876 break;
877 /* case 0x60ef: * from BW600.inf
878 sd->bridge = BRIDGE_SN9C105;
879 sd->sensor = SENSOR_ICM105C;
880 sd->i2c_base = 0x??;
881 break; */
882 /* case 0x60fa: * from BW600.inf
883 sd->bridge = BRIDGE_SN9C105;
884 sd->sensor = SENSOR_OV7648;
885 sd->i2c_base = 0x??;
886 break; */
887 case 0x60fb:
888 sd->bridge = BRIDGE_SN9C105;
889 sd->sensor = SENSOR_OV7660;
890 sd->i2c_base = 0x21;
891 break;
892 case 0x60fc:
893 sd->bridge = BRIDGE_SN9C105;
894 sd->sensor = SENSOR_HV7131R;
895 sd->i2c_base = 0x11;
896 break;
897 /* case 0x60fe: * from BW600.inf
898 sd->bridge = BRIDGE_SN9C105;
899 sd->sensor = SENSOR_OV7630;
900 sd->i2c_base = 0x??;
901 break; */
902 /* case 0x6108: * from BW600.inf
903 sd->bridge = BRIDGE_SN9C120;
904 sd->sensor = SENSOR_OM6801;
905 sd->i2c_base = 0x??;
906 break; */
907 /* case 0x6122: * from BW600.inf
908 sd->bridge = BRIDGE_SN9C110;
909 sd->sensor = SENSOR_ICM105C;
910 sd->i2c_base = 0x??;
911 break; */
912 case 0x612a:
913 /* sd->bridge = BRIDGE_SN9C110; * in BW600.inf */
914 sd->bridge = BRIDGE_SN9C325;
915 sd->sensor = SENSOR_OV7648;
916 sd->i2c_base = 0x21;
917 /*fixme: sensor_init has base = 00 et 6e!*/
918 break;
919 /* case 0x6123: * from BW600.inf
920 sd->bridge = BRIDGE_SN9C110;
921 sd->sensor = SENSOR_SanyoCCD;
922 sd->i2c_base = 0x??;
923 break; */
924 case 0x612c:
925 sd->bridge = BRIDGE_SN9C110;
926 sd->sensor = SENSOR_MO4000;
927 sd->i2c_base = 0x21;
928 break;
929 /* case 0x612e: * from BW600.inf
930 sd->bridge = BRIDGE_SN9C110;
931 sd->sensor = SENSOR_OV7630;
932 sd->i2c_base = 0x??;
933 break; */
934 /* case 0x612f: * from BW600.inf
935 sd->bridge = BRIDGE_SN9C110;
936 sd->sensor = SENSOR_ICM105C;
937 sd->i2c_base = 0x??;
938 break; */
939 case 0x6130:
940 sd->bridge = BRIDGE_SN9C120;
941 sd->sensor = SENSOR_MI0360;
942 sd->i2c_base = 0x5d;
943 break;
944 case 0x6138:
945 sd->bridge = BRIDGE_SN9C120;
946 sd->sensor = SENSOR_MO4000;
947 sd->i2c_base = 0x21;
948 break;
949 /* case 0x613a: * from BW600.inf
950 sd->bridge = BRIDGE_SN9C120;
951 sd->sensor = SENSOR_OV7648;
952 sd->i2c_base = 0x??;
953 break; */
954 case 0x613b:
955 sd->bridge = BRIDGE_SN9C120;
956 sd->sensor = SENSOR_OV7660;
957 sd->i2c_base = 0x21;
958 break;
959 case 0x613c:
960 sd->bridge = BRIDGE_SN9C120;
961 sd->sensor = SENSOR_HV7131R;
962 sd->i2c_base = 0x11;
963 break;
964 /* case 0x613e: * from BW600.inf
965 sd->bridge = BRIDGE_SN9C120;
966 sd->sensor = SENSOR_OV7630;
967 sd->i2c_base = 0x??;
968 break; */
970 break;
972 if (sd->sensor < 0) {
973 PDEBUG(D_ERR, "Invalid vendor/product %04x:%04x",
974 id->idVendor, product);
975 return -EINVAL;
978 cam = &gspca_dev->cam;
979 cam->dev_name = (char *) id->driver_info;
980 cam->epaddr = 0x01;
981 cam->cam_mode = vga_mode;
982 cam->nmodes = ARRAY_SIZE(vga_mode);
984 sd->qindex = 4; /* set the quantization table */
985 sd->brightness = BRIGHTNESS_DEF;
986 sd->contrast = CONTRAST_DEF;
987 sd->colors = COLOR_DEF;
988 sd->autogain = AUTOGAIN_DEF;
989 return 0;
992 /* this function is called at open time */
993 static int sd_open(struct gspca_dev *gspca_dev)
995 struct sd *sd = (struct sd *) gspca_dev;
996 /* const __u8 *sn9c1xx; */
997 __u8 regGpio[] = { 0x29, 0x74 };
998 __u8 regF1;
1000 /* setup a selector by bridge */
1001 reg_w1(gspca_dev, 0xf1, 0x01);
1002 reg_r(gspca_dev, 0x00, 1); /* -> regF1 = 0x00 */
1003 reg_w1(gspca_dev, 0xf1, gspca_dev->usb_buf[0]);
1004 reg_r(gspca_dev, 0x00, 1);
1005 regF1 = gspca_dev->usb_buf[0];
1006 switch (sd->bridge) {
1007 case BRIDGE_SN9C102P:
1008 if (regF1 != 0x11)
1009 return -ENODEV;
1010 reg_w1(gspca_dev, 0x02, regGpio[1]);
1011 break;
1012 case BRIDGE_SN9C105:
1013 if (regF1 != 0x11)
1014 return -ENODEV;
1015 reg_w(gspca_dev, 0x02, regGpio, 2);
1016 break;
1017 case BRIDGE_SN9C120:
1018 if (regF1 != 0x12)
1019 return -ENODEV;
1020 regGpio[1] = 0x70;
1021 reg_w(gspca_dev, 0x02, regGpio, 2);
1022 break;
1023 default:
1024 /* case BRIDGE_SN9C110: */
1025 /* case BRIDGE_SN9C325: */
1026 if (regF1 != 0x12)
1027 return -ENODEV;
1028 reg_w1(gspca_dev, 0x02, 0x62);
1029 break;
1032 reg_w1(gspca_dev, 0xf1, 0x01);
1034 return 0;
1037 static unsigned int setexposure(struct gspca_dev *gspca_dev,
1038 unsigned int expo)
1040 struct sd *sd = (struct sd *) gspca_dev;
1041 static const __u8 doit[] = /* update sensor */
1042 { 0xb1, 0x5d, 0x07, 0x00, 0x03, 0x00, 0x00, 0x10 };
1043 static const __u8 sensorgo[] = /* sensor on */
1044 { 0xb1, 0x5d, 0x07, 0x00, 0x02, 0x00, 0x00, 0x10 };
1045 static const __u8 gainMo[] =
1046 { 0xa1, 0x21, 0x00, 0x10, 0x00, 0x00, 0x00, 0x1d };
1048 switch (sd->sensor) {
1049 case SENSOR_HV7131R: {
1050 __u8 Expodoit[] =
1051 { 0xc1, 0x11, 0x25, 0x07, 0x27, 0xc0, 0x00, 0x16 };
1053 Expodoit[3] = expo >> 16;
1054 Expodoit[4] = expo >> 8;
1055 Expodoit[5] = expo;
1056 i2c_w8(gspca_dev, Expodoit);
1057 break;
1059 case SENSOR_MI0360: {
1060 __u8 expoMi[] = /* exposure 0x0635 -> 4 fp/s 0x10 */
1061 { 0xb1, 0x5d, 0x09, 0x06, 0x35, 0x00, 0x00, 0x16 };
1063 if (expo > 0x0635)
1064 expo = 0x0635;
1065 else if (expo < 0x0001)
1066 expo = 0x0001;
1067 expoMi[3] = expo >> 8;
1068 expoMi[4] = expo;
1069 i2c_w8(gspca_dev, expoMi);
1070 i2c_w8(gspca_dev, doit);
1071 i2c_w8(gspca_dev, sensorgo);
1072 break;
1074 case SENSOR_MO4000: {
1075 __u8 expoMof[] =
1076 { 0xa1, 0x21, 0x0f, 0x20, 0x00, 0x00, 0x00, 0x10 };
1077 __u8 expoMo10[] =
1078 { 0xa1, 0x21, 0x10, 0x20, 0x00, 0x00, 0x00, 0x10 };
1080 if (expo > 0x1fff)
1081 expo = 0x1fff;
1082 else if (expo < 0x0001)
1083 expo = 0x0001;
1084 expoMof[3] = (expo & 0x03fc) >> 2;
1085 i2c_w8(gspca_dev, expoMof);
1086 expoMo10[3] = ((expo & 0x1c00) >> 10)
1087 | ((expo & 0x0003) << 4);
1088 i2c_w8(gspca_dev, expoMo10);
1089 i2c_w8(gspca_dev, gainMo);
1090 PDEBUG(D_CONF, "set exposure %d",
1091 ((expoMo10[3] & 0x07) << 10)
1092 | (expoMof[3] << 2)
1093 | ((expoMo10[3] & 0x30) >> 4));
1094 break;
1097 return expo;
1100 static void setbrightness(struct gspca_dev *gspca_dev)
1102 struct sd *sd = (struct sd *) gspca_dev;
1103 unsigned int expo;
1104 __u8 k2;
1106 switch (sd->sensor) {
1107 case SENSOR_HV7131R:
1108 expo = sd->brightness << 4;
1109 if (expo > 0x002dc6c0)
1110 expo = 0x002dc6c0;
1111 else if (expo < 0x02a0)
1112 expo = 0x02a0;
1113 sd->exposure = setexposure(gspca_dev, expo);
1114 break;
1115 case SENSOR_MI0360:
1116 expo = sd->brightness >> 4;
1117 sd->exposure = setexposure(gspca_dev, expo);
1118 break;
1119 case SENSOR_MO4000:
1120 expo = sd->brightness >> 4;
1121 sd->exposure = setexposure(gspca_dev, expo);
1122 break;
1123 case SENSOR_OV7660:
1124 return; /*jfm??*/
1127 k2 = sd->brightness >> 10;
1128 reg_w1(gspca_dev, 0x96, k2);
1131 static void setcontrast(struct gspca_dev *gspca_dev)
1133 struct sd *sd = (struct sd *) gspca_dev;
1134 __u8 k2;
1135 __u8 contrast[] = { 0x00, 0x00, 0x28, 0x00, 0x07, 0x00 };
1137 if (sd->sensor == SENSOR_OV7660)
1138 return; /*jfm??*/
1139 k2 = sd->contrast;
1140 contrast[2] = k2;
1141 contrast[0] = (k2 + 1) >> 1;
1142 contrast[4] = (k2 + 1) / 5;
1143 reg_w(gspca_dev, 0x84, contrast, 6);
1146 static void setcolors(struct gspca_dev *gspca_dev)
1148 struct sd *sd = (struct sd *) gspca_dev;
1149 __u8 data;
1150 int colour;
1152 colour = sd->colors - 128;
1153 if (colour > 0)
1154 data = (colour + 32) & 0x7f; /* blue */
1155 else
1156 data = (-colour + 32) & 0x7f; /* red */
1157 reg_w1(gspca_dev, 0x05, data);
1160 /* -- start the camera -- */
1161 static void sd_start(struct gspca_dev *gspca_dev)
1163 struct sd *sd = (struct sd *) gspca_dev;
1164 int i;
1165 __u8 data;
1166 __u8 reg1;
1167 __u8 reg17;
1168 const __u8 *sn9c1xx;
1169 int mode;
1170 static const __u8 C0[] = { 0x2d, 0x2d, 0x3a, 0x05, 0x04, 0x3f };
1171 static const __u8 CA[] = { 0x28, 0xd8, 0x14, 0xec };
1172 static const __u8 CA_sn9c120[] =
1173 { 0x14, 0xec, 0x0a, 0xf6 }; /* SN9C120 */
1174 static const __u8 CE[] = { 0x32, 0xdd, 0x2d, 0xdd }; /* MI0360 */
1175 static const __u8 CE_sn9c325[] =
1176 { 0x32, 0xdd, 0x32, 0xdd }; /* OV7648 - SN9C325 */
1178 sn9c1xx = sn_tb[(int) sd->sensor];
1179 configure_gpio(gspca_dev, sn9c1xx);
1181 /*fixme:jfm this sequence should appear at end of sd_start */
1182 /* with
1183 reg_w1(gspca_dev, 0x01, 0x44); */
1184 reg_w1(gspca_dev, 0x15, sn9c1xx[0x15]);
1185 reg_w1(gspca_dev, 0x16, sn9c1xx[0x16]);
1186 reg_w1(gspca_dev, 0x12, sn9c1xx[0x12]);
1187 reg_w1(gspca_dev, 0x13, sn9c1xx[0x13]);
1188 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1189 reg_w1(gspca_dev, 0xd2, 0x6a); /* DC29 */
1190 reg_w1(gspca_dev, 0xd3, 0x50);
1191 reg_w1(gspca_dev, 0xc6, 0x00);
1192 reg_w1(gspca_dev, 0xc7, 0x00);
1193 reg_w1(gspca_dev, 0xc8, 0x50);
1194 reg_w1(gspca_dev, 0xc9, 0x3c);
1195 /*fixme:jfm end of ending sequence */
1196 reg_w1(gspca_dev, 0x18, sn9c1xx[0x18]);
1197 switch (sd->bridge) {
1198 case BRIDGE_SN9C325:
1199 data = 0xae;
1200 break;
1201 case BRIDGE_SN9C120:
1202 data = 0xa0;
1203 break;
1204 default:
1205 data = 0x60;
1206 break;
1208 reg_w1(gspca_dev, 0x17, data);
1209 reg_w1(gspca_dev, 0x05, sn9c1xx[5]);
1210 reg_w1(gspca_dev, 0x07, sn9c1xx[7]);
1211 reg_w1(gspca_dev, 0x06, sn9c1xx[6]);
1212 reg_w1(gspca_dev, 0x14, sn9c1xx[0x14]);
1213 switch (sd->bridge) {
1214 case BRIDGE_SN9C325:
1215 reg_w(gspca_dev, 0x20, regsn20_sn9c325,
1216 sizeof regsn20_sn9c325);
1217 for (i = 0; i < 8; i++)
1218 reg_w(gspca_dev, 0x84, reg84_sn9c325,
1219 sizeof reg84_sn9c325);
1220 reg_w1(gspca_dev, 0x9a, 0x0a);
1221 reg_w1(gspca_dev, 0x99, 0x60);
1222 break;
1223 case BRIDGE_SN9C120:
1224 reg_w(gspca_dev, 0x20, regsn20_sn9c120,
1225 sizeof regsn20_sn9c120);
1226 for (i = 0; i < 2; i++)
1227 reg_w(gspca_dev, 0x84, reg84_sn9c120_1,
1228 sizeof reg84_sn9c120_1);
1229 for (i = 0; i < 6; i++)
1230 reg_w(gspca_dev, 0x84, reg84_sn9c120_2,
1231 sizeof reg84_sn9c120_2);
1232 reg_w(gspca_dev, 0x84, reg84_sn9c120_3,
1233 sizeof reg84_sn9c120_3);
1234 reg_w1(gspca_dev, 0x9a, 0x05);
1235 reg_w1(gspca_dev, 0x99, 0x5b);
1236 break;
1237 default:
1238 reg_w(gspca_dev, 0x20, regsn20, sizeof regsn20);
1239 for (i = 0; i < 8; i++)
1240 reg_w(gspca_dev, 0x84, reg84, sizeof reg84);
1241 reg_w1(gspca_dev, 0x9a, 0x08);
1242 reg_w1(gspca_dev, 0x99, 0x59);
1243 break;
1246 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
1247 if (mode)
1248 reg1 = 0x46; /* 320 clk 48Mhz */
1249 else
1250 reg1 = 0x06; /* 640 clk 24Mz */
1251 reg17 = 0x61;
1252 switch (sd->sensor) {
1253 case SENSOR_HV7131R:
1254 hv7131R_InitSensor(gspca_dev);
1255 break;
1256 case SENSOR_MI0360:
1257 mi0360_InitSensor(gspca_dev);
1258 break;
1259 case SENSOR_MO4000:
1260 mo4000_InitSensor(gspca_dev);
1261 if (mode) {
1262 /* reg1 = 0x46; * 320 clk 48Mhz 60fp/s */
1263 reg1 = 0x06; /* clk 24Mz */
1264 } else {
1265 reg17 = 0x22; /* 640 MCKSIZE */
1266 /* reg1 = 0x06; * 640 clk 24Mz (done) */
1268 break;
1269 case SENSOR_OV7648:
1270 ov7648_InitSensor(gspca_dev);
1271 reg17 = 0xa2;
1272 reg1 = 0x44;
1273 /* if (mode)
1274 ; * 320x2...
1275 else
1276 ; * 640x... */
1277 break;
1278 default:
1279 /* case SENSOR_OV7660: */
1280 ov7660_InitSensor(gspca_dev);
1281 if (mode) {
1282 /* reg17 = 0x21; * 320 */
1283 /* reg1 = 0x44; */
1284 /* reg1 = 0x46; (done) */
1285 } else {
1286 reg17 = 0xa2; /* 640 */
1287 reg1 = 0x40;
1289 break;
1291 reg_w(gspca_dev, 0xc0, C0, 6);
1292 switch (sd->bridge) {
1293 case BRIDGE_SN9C120: /*jfm ?? */
1294 reg_w(gspca_dev, 0xca, CA_sn9c120, 4);
1295 break;
1296 default:
1297 reg_w(gspca_dev, 0xca, CA, 4);
1298 break;
1300 switch (sd->bridge) {
1301 case BRIDGE_SN9C120: /*jfm ?? */
1302 case BRIDGE_SN9C325:
1303 reg_w(gspca_dev, 0xce, CE_sn9c325, 4);
1304 break;
1305 default:
1306 reg_w(gspca_dev, 0xce, CE, 4);
1307 /* ?? {0x1e, 0xdd, 0x2d, 0xe7} */
1308 break;
1311 /* here change size mode 0 -> VGA; 1 -> CIF */
1312 data = 0x40 | sn9c1xx[0x18] | (mode << 4);
1313 reg_w1(gspca_dev, 0x18, data);
1315 reg_w(gspca_dev, 0x100, qtable4, 0x40);
1316 reg_w(gspca_dev, 0x140, qtable4 + 0x40, 0x40);
1318 data = sn9c1xx[0x18] | (mode << 4);
1319 reg_w1(gspca_dev, 0x18, data);
1321 reg_w1(gspca_dev, 0x17, reg17);
1322 reg_w1(gspca_dev, 0x01, reg1);
1323 setbrightness(gspca_dev);
1324 setcontrast(gspca_dev);
1327 static void sd_stopN(struct gspca_dev *gspca_dev)
1329 struct sd *sd = (struct sd *) gspca_dev;
1330 static const __u8 stophv7131[] =
1331 { 0xa1, 0x11, 0x02, 0x09, 0x00, 0x00, 0x00, 0x10 };
1332 static const __u8 stopmi0360[] =
1333 { 0xb1, 0x5d, 0x07, 0x00, 0x00, 0x00, 0x00, 0x10 };
1334 __u8 data;
1335 const __u8 *sn9c1xx;
1337 data = 0x0b;
1338 switch (sd->sensor) {
1339 case SENSOR_HV7131R:
1340 i2c_w8(gspca_dev, stophv7131);
1341 data = 0x2b;
1342 break;
1343 case SENSOR_MI0360:
1344 i2c_w8(gspca_dev, stopmi0360);
1345 data = 0x29;
1346 break;
1347 case SENSOR_MO4000:
1348 break;
1349 case SENSOR_OV7648:
1350 data = 0x29;
1351 break;
1352 default:
1353 /* case SENSOR_OV7660: */
1354 break;
1356 sn9c1xx = sn_tb[(int) sd->sensor];
1357 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1358 reg_w1(gspca_dev, 0x17, sn9c1xx[0x17]);
1359 reg_w1(gspca_dev, 0x01, sn9c1xx[1]);
1360 reg_w1(gspca_dev, 0x01, data);
1361 reg_w1(gspca_dev, 0xf1, 0x01);
1364 static void sd_stop0(struct gspca_dev *gspca_dev)
1368 static void sd_close(struct gspca_dev *gspca_dev)
1372 static void setautogain(struct gspca_dev *gspca_dev)
1374 struct sd *sd = (struct sd *) gspca_dev;
1375 /* Thanks S., without your advice, autobright should not work :) */
1376 int delta;
1377 int expotimes = 0;
1378 __u8 luma_mean = 130;
1379 __u8 luma_delta = 20;
1381 delta = sd->avg_lum;
1382 if (delta < luma_mean - luma_delta ||
1383 delta > luma_mean + luma_delta) {
1384 switch (sd->sensor) {
1385 case SENSOR_HV7131R:
1386 expotimes = sd->exposure >> 8;
1387 expotimes += (luma_mean - delta) >> 4;
1388 if (expotimes < 0)
1389 expotimes = 0;
1390 sd->exposure = setexposure(gspca_dev,
1391 (unsigned int) (expotimes << 8));
1392 break;
1393 case SENSOR_MO4000:
1394 case SENSOR_MI0360:
1395 expotimes = sd->exposure;
1396 expotimes += (luma_mean - delta) >> 6;
1397 if (expotimes < 0)
1398 expotimes = 0;
1399 sd->exposure = setexposure(gspca_dev,
1400 (unsigned int) expotimes);
1401 setcolors(gspca_dev);
1402 break;
1407 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1408 struct gspca_frame *frame, /* target */
1409 __u8 *data, /* isoc packet */
1410 int len) /* iso packet length */
1412 struct sd *sd = (struct sd *) gspca_dev;
1413 int sof, avg_lum;
1415 sof = len - 64;
1416 if (sof >= 0 && data[sof] == 0xff && data[sof + 1] == 0xd9) {
1418 /* end of frame */
1419 gspca_frame_add(gspca_dev, LAST_PACKET,
1420 frame, data, sof + 2);
1421 if (sd->ag_cnt < 0)
1422 return;
1423 if (--sd->ag_cnt >= 0)
1424 return;
1425 sd->ag_cnt = AG_CNT_START;
1426 /* w1 w2 w3 */
1427 /* w4 w5 w6 */
1428 /* w7 w8 */
1429 /* w4 */
1430 avg_lum = ((data[sof + 29] << 8) | data[sof + 30]) >> 6;
1431 /* w6 */
1432 avg_lum += ((data[sof + 33] << 8) | data[sof + 34]) >> 6;
1433 /* w2 */
1434 avg_lum += ((data[sof + 25] << 8) | data[sof + 26]) >> 6;
1435 /* w8 */
1436 avg_lum += ((data[sof + 37] << 8) | data[sof + 38]) >> 6;
1437 /* w5 */
1438 avg_lum += ((data[sof + 31] << 8) | data[sof + 32]) >> 4;
1439 avg_lum >>= 4;
1440 sd->avg_lum = avg_lum;
1441 PDEBUG(D_PACK, "mean lum %d", avg_lum);
1442 setautogain(gspca_dev);
1443 return;
1445 if (gspca_dev->last_packet_type == LAST_PACKET) {
1447 /* put the JPEG 422 header */
1448 jpeg_put_header(gspca_dev, frame, sd->qindex, 0x21);
1450 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
1453 static unsigned int getexposure(struct gspca_dev *gspca_dev)
1455 struct sd *sd = (struct sd *) gspca_dev;
1456 __u8 hexpo, mexpo, lexpo;
1458 switch (sd->sensor) {
1459 case SENSOR_HV7131R:
1460 /* read sensor exposure */
1461 i2c_r5(gspca_dev, 0x25);
1462 return (gspca_dev->usb_buf[0] << 16)
1463 | (gspca_dev->usb_buf[1] << 8)
1464 | gspca_dev->usb_buf[2];
1465 case SENSOR_MI0360:
1466 /* read sensor exposure */
1467 i2c_r5(gspca_dev, 0x09);
1468 return (gspca_dev->usb_buf[0] << 8)
1469 | gspca_dev->usb_buf[1];
1470 case SENSOR_MO4000:
1471 i2c_r5(gspca_dev, 0x0e);
1472 hexpo = 0; /* gspca_dev->usb_buf[1] & 0x07; */
1473 mexpo = 0x40; /* gspca_dev->usb_buf[2] & 0xff; */
1474 lexpo = (gspca_dev->usb_buf[1] & 0x30) >> 4;
1475 PDEBUG(D_CONF, "exposure %d",
1476 (hexpo << 10) | (mexpo << 2) | lexpo);
1477 return (hexpo << 10) | (mexpo << 2) | lexpo;
1478 default:
1479 /* case SENSOR_OV7660: */
1480 /* read sensor exposure */
1481 i2c_r5(gspca_dev, 0x04);
1482 hexpo = gspca_dev->usb_buf[3] & 0x2f;
1483 lexpo = gspca_dev->usb_buf[0] & 0x02;
1484 i2c_r5(gspca_dev, 0x08);
1485 mexpo = gspca_dev->usb_buf[2];
1486 return (hexpo << 10) | (mexpo << 2) | lexpo;
1490 static void getbrightness(struct gspca_dev *gspca_dev)
1492 struct sd *sd = (struct sd *) gspca_dev;
1494 /* hardcoded registers seem not readable */
1495 switch (sd->sensor) {
1496 case SENSOR_HV7131R:
1497 /* sd->brightness = 0x7fff; */
1498 sd->brightness = getexposure(gspca_dev) >> 4;
1499 break;
1500 case SENSOR_MI0360:
1501 sd->brightness = getexposure(gspca_dev) << 4;
1502 break;
1503 case SENSOR_MO4000:
1504 /* sd->brightness = 0x1fff; */
1505 sd->brightness = getexposure(gspca_dev) << 4;
1506 break;
1510 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1512 struct sd *sd = (struct sd *) gspca_dev;
1514 sd->brightness = val;
1515 if (gspca_dev->streaming)
1516 setbrightness(gspca_dev);
1517 return 0;
1520 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1522 struct sd *sd = (struct sd *) gspca_dev;
1524 getbrightness(gspca_dev);
1525 *val = sd->brightness;
1526 return 0;
1529 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
1531 struct sd *sd = (struct sd *) gspca_dev;
1533 sd->contrast = val;
1534 if (gspca_dev->streaming)
1535 setcontrast(gspca_dev);
1536 return 0;
1539 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
1541 struct sd *sd = (struct sd *) gspca_dev;
1543 *val = sd->contrast;
1544 return 0;
1547 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
1549 struct sd *sd = (struct sd *) gspca_dev;
1551 sd->colors = val;
1552 if (gspca_dev->streaming)
1553 setcolors(gspca_dev);
1554 return 0;
1557 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
1559 struct sd *sd = (struct sd *) gspca_dev;
1561 *val = sd->colors;
1562 return 0;
1565 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1567 struct sd *sd = (struct sd *) gspca_dev;
1569 sd->autogain = val;
1570 if (val)
1571 sd->ag_cnt = AG_CNT_START;
1572 else
1573 sd->ag_cnt = -1;
1574 return 0;
1577 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1579 struct sd *sd = (struct sd *) gspca_dev;
1581 *val = sd->autogain;
1582 return 0;
1585 /* sub-driver description */
1586 static const struct sd_desc sd_desc = {
1587 .name = MODULE_NAME,
1588 .ctrls = sd_ctrls,
1589 .nctrls = ARRAY_SIZE(sd_ctrls),
1590 .config = sd_config,
1591 .open = sd_open,
1592 .start = sd_start,
1593 .stopN = sd_stopN,
1594 .stop0 = sd_stop0,
1595 .close = sd_close,
1596 .pkt_scan = sd_pkt_scan,
1599 /* -- module initialisation -- */
1600 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1601 static const __devinitdata struct usb_device_id device_table[] = {
1602 #ifndef CONFIG_USB_SN9C102
1603 {USB_DEVICE(0x0458, 0x7025), DVNM("Genius Eye 311Q")},
1604 {USB_DEVICE(0x045e, 0x00f5), DVNM("MicroSoft VX3000")},
1605 {USB_DEVICE(0x045e, 0x00f7), DVNM("MicroSoft VX1000")},
1606 {USB_DEVICE(0x0471, 0x0327), DVNM("Philips SPC 600 NC")},
1607 {USB_DEVICE(0x0471, 0x0328), DVNM("Philips SPC 700 NC")},
1608 #endif
1609 {USB_DEVICE(0x0471, 0x0330), DVNM("Philips SPC 710NC")},
1610 {USB_DEVICE(0x0c45, 0x6040), DVNM("Speed NVC 350K")},
1611 {USB_DEVICE(0x0c45, 0x607c), DVNM("Sonix sn9c102p Hv7131R")},
1612 {USB_DEVICE(0x0c45, 0x60c0), DVNM("Sangha Sn535")},
1613 {USB_DEVICE(0x0c45, 0x60ec), DVNM("SN9C105+MO4000")},
1614 {USB_DEVICE(0x0c45, 0x60fb), DVNM("Surfer NoName")},
1615 {USB_DEVICE(0x0c45, 0x60fc), DVNM("LG-LIC300")},
1616 {USB_DEVICE(0x0c45, 0x612a), DVNM("Avant Camera")},
1617 {USB_DEVICE(0x0c45, 0x612c), DVNM("Typhoon Rasy Cam 1.3MPix")},
1618 #ifndef CONFIG_USB_SN9C102
1619 {USB_DEVICE(0x0c45, 0x6130), DVNM("Sonix Pccam")},
1620 {USB_DEVICE(0x0c45, 0x6138), DVNM("Sn9c120 Mo4000")},
1621 {USB_DEVICE(0x0c45, 0x613b), DVNM("Surfer SN-206")},
1622 {USB_DEVICE(0x0c45, 0x613c), DVNM("Sonix Pccam168")},
1623 #endif
1626 MODULE_DEVICE_TABLE(usb, device_table);
1628 /* -- device connect -- */
1629 static int sd_probe(struct usb_interface *intf,
1630 const struct usb_device_id *id)
1632 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1633 THIS_MODULE);
1636 static struct usb_driver sd_driver = {
1637 .name = MODULE_NAME,
1638 .id_table = device_table,
1639 .probe = sd_probe,
1640 .disconnect = gspca_disconnect,
1643 /* -- module insert / remove -- */
1644 static int __init sd_mod_init(void)
1646 if (usb_register(&sd_driver) < 0)
1647 return -1;
1648 info("registered");
1649 return 0;
1651 static void __exit sd_mod_exit(void)
1653 usb_deregister(&sd_driver);
1654 info("deregistered");
1657 module_init(sd_mod_init);
1658 module_exit(sd_mod_exit);