2 * sonix sn9c102 (bayer) library
3 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
4 * Add Pas106 Stefano Mozzi (C) 2004
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #define MODULE_NAME "sonixb"
27 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
29 MODULE_LICENSE("GPL");
31 /* specific webcam descriptor */
33 struct gspca_dev gspca_dev; /* !! must be the first item */
37 unsigned char exposure;
38 unsigned char brightness;
39 unsigned char autogain;
40 unsigned char autogain_ignore_frames;
41 unsigned char frames_to_drop;
42 unsigned char freq; /* light freq filter setting */
44 __u8 bridge; /* Type of bridge */
46 #define BRIDGE_102 0 /* We make no difference between 101 and 102 */
49 __u8 sensor; /* Type of image sensor chip */
50 #define SENSOR_HV7131R 0
51 #define SENSOR_OV6650 1
52 #define SENSOR_OV7630 2
53 #define SENSOR_PAS106 3
54 #define SENSOR_PAS202 4
55 #define SENSOR_TAS5110 5
56 #define SENSOR_TAS5130CXX 6
60 typedef const __u8 sensor_init_t[8];
63 const __u8 *bridge_init[2];
64 int bridge_init_size[2];
65 sensor_init_t *sensor_init;
67 sensor_init_t *sensor_bridge_init[2];
68 int sensor_bridge_init_size[2];
74 /* sensor_data flags */
75 #define F_GAIN 0x01 /* has gain */
76 #define F_SIF 0x02 /* sif or vga */
78 /* ctrl_dis helper macros */
79 #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
80 #define NO_FREQ (1 << FREQ_IDX)
81 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
84 #define COMP 0xc7 /* 0x87 //0x07 */
85 #define COMP1 0xc9 /* 0x89 //0x09 */
88 #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
92 #define SENS(bridge_1, bridge_3, sensor, sensor_1, \
93 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
95 .bridge_init = { bridge_1, bridge_3 }, \
96 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
97 .sensor_init = sensor, \
98 .sensor_init_size = sizeof(sensor), \
99 .sensor_bridge_init = { sensor_1, sensor_3,}, \
100 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
101 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
104 /* We calculate the autogain at the end of the transfer of a frame, at this
105 moment a frame with the old settings is being transmitted, and a frame is
106 being captured with the old settings. So if we adjust the autogain we must
107 ignore atleast the 2 next frames for the new settings to come into effect
108 before doing any other adjustments */
109 #define AUTOGAIN_IGNORE_FRAMES 3
110 #define AUTOGAIN_DEADZONE 1000
111 #define DESIRED_AVG_LUM 7000
113 /* V4L2 controls supported by the driver */
114 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
115 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
116 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
117 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
118 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
119 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
120 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
121 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
122 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
123 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
125 static struct ctrl sd_ctrls[] = {
126 #define BRIGHTNESS_IDX 0
129 .id = V4L2_CID_BRIGHTNESS,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Brightness",
135 #define BRIGHTNESS_DEF 127
136 .default_value = BRIGHTNESS_DEF,
138 .set = sd_setbrightness,
139 .get = sd_getbrightness,
145 .type = V4L2_CTRL_TYPE_INTEGER,
151 #define GAIN_KNEE 200
152 .default_value = GAIN_DEF,
157 #define EXPOSURE_IDX 2
160 .id = V4L2_CID_EXPOSURE,
161 .type = V4L2_CTRL_TYPE_INTEGER,
163 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
164 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
168 .default_value = EXPOSURE_DEF,
171 .set = sd_setexposure,
172 .get = sd_getexposure,
174 #define AUTOGAIN_IDX 3
177 .id = V4L2_CID_AUTOGAIN,
178 .type = V4L2_CTRL_TYPE_BOOLEAN,
179 .name = "Automatic Gain (and Exposure)",
183 #define AUTOGAIN_DEF 1
184 .default_value = AUTOGAIN_DEF,
187 .set = sd_setautogain,
188 .get = sd_getautogain,
193 .id = V4L2_CID_POWER_LINE_FREQUENCY,
194 .type = V4L2_CTRL_TYPE_MENU,
195 .name = "Light frequency filter",
197 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
200 .default_value = FREQ_DEF,
207 static struct v4l2_pix_format vga_mode[] = {
208 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
210 .sizeimage = 160 * 120,
211 .colorspace = V4L2_COLORSPACE_SRGB,
213 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
215 .sizeimage = 320 * 240,
216 .colorspace = V4L2_COLORSPACE_SRGB,
218 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
220 .sizeimage = 640 * 480,
221 .colorspace = V4L2_COLORSPACE_SRGB,
224 static struct v4l2_pix_format sif_mode[] = {
225 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
227 .sizeimage = 176 * 144,
228 .colorspace = V4L2_COLORSPACE_SRGB,
230 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
232 .sizeimage = 352 * 288,
233 .colorspace = V4L2_COLORSPACE_SRGB,
237 static const __u8 initHv7131[] = {
238 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
240 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */
241 0x28, 0x1e, 0x60, 0x8a, 0x20,
242 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
244 static const __u8 hv7131_sensor_init[][8] = {
245 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
246 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
247 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
248 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
249 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
251 static const __u8 initOv6650[] = {
252 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
253 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
254 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
255 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
257 static const __u8 ov6650_sensor_init[][8] =
259 /* Bright, contrast, etc are set througth SCBB interface.
260 * AVCAP on win2 do not send any data on this controls. */
261 /* Anyway, some registers appears to alter bright and constrat */
264 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
265 /* Set clock register 0x11 low nibble is clock divider */
266 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
267 /* Next some unknown stuff */
268 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
269 /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
270 * THIS SET GREEN SCREEN
271 * (pixels could be innverted in decode kind of "brg",
272 * but blue wont be there. Avoid this data ... */
273 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
274 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
275 {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
276 /* Enable rgb brightness control */
277 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
278 /* HDG: Note windows uses the line below, which sets both register 0x60
279 and 0x61 I believe these registers of the ov6650 are identical as
280 those of the ov7630, because if this is true the windows settings
281 add a bit additional red gain and a lot additional blue gain, which
282 matches my findings that the windows settings make blue much too
283 blue and red a little too red.
284 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
285 /* Some more unknown stuff */
286 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
287 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
290 static const __u8 initOv7630[] = {
291 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
292 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
293 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
294 0x28, 0x1e, /* H & V sizes r15 .. r16 */
295 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
296 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
298 static const __u8 initOv7630_3[] = {
299 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
300 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
301 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
302 0x28, 0x1e, /* H & V sizes r15 .. r16 */
303 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
304 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
305 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
306 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
308 static const __u8 ov7630_sensor_init[][8] = {
309 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
310 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
311 /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
312 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
313 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
314 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
315 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
316 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
317 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
318 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
319 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
320 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
321 /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
322 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
323 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
324 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
325 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
326 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
327 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
330 static const __u8 ov7630_sensor_init_3[][8] = {
331 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
334 static const __u8 initPas106[] = {
335 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
338 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
339 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
341 /* compression 0x86 mckinit1 0x2b */
342 static const __u8 pas106_sensor_init[][8] = {
343 /* Pixel Clock Divider 6 */
344 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
345 /* Frame Time MSB (also seen as 0x12) */
346 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
347 /* Frame Time LSB (also seen as 0x05) */
348 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
349 /* Shutter Time Line Offset (also seen as 0x6d) */
350 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
351 /* Shutter Time Pixel Offset (also seen as 0xb1) */
352 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
353 /* Black Level Subtract Sign (also seen 0x00) */
354 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
355 /* Black Level Subtract Level (also seen 0x01) */
356 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
357 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
358 /* Color Gain B Pixel 5 a */
359 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
360 /* Color Gain G1 Pixel 1 5 */
361 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
362 /* Color Gain G2 Pixel 1 0 5 */
363 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
364 /* Color Gain R Pixel 3 1 */
365 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
366 /* Color GainH Pixel */
367 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
369 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
371 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
372 /* H&V synchro polarity */
373 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
375 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
377 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
379 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
380 /* Validate Settings */
381 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
384 static const __u8 initPas202[] = {
385 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */
388 0x28, 0x1e, 0x28, 0x89, 0x20,
389 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
391 static const __u8 pas202_sensor_init[][8] = {
392 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
393 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
394 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
395 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
396 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
397 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
398 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
399 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
400 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
401 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
402 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
403 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
405 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
406 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
407 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
408 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
409 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
410 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
411 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
412 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
415 static const __u8 initTas5110[] = {
416 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
418 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */
419 0x16, 0x12, 0x60, 0x86, 0x2b,
420 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
422 static const __u8 tas5110_sensor_init[][8] = {
423 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
424 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
425 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
428 static const __u8 initTas5130[] = {
429 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
431 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
432 0x28, 0x1e, 0x60, COMP, MCK_INIT,
433 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
435 static const __u8 tas5130_sensor_init[][8] = {
436 /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
437 * shutter 0x47 short exposure? */
438 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
439 /* shutter 0x01 long exposure */
440 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
443 struct sensor_data sensor_data[] = {
444 SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
445 SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
446 SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
448 SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
450 SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
452 SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
453 NO_BRIGHTNESS|NO_FREQ, 0),
454 SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
458 /* get one byte in gspca_dev->usb_buf */
459 static void reg_r(struct gspca_dev *gspca_dev,
462 usb_control_msg(gspca_dev->dev,
463 usb_rcvctrlpipe(gspca_dev->dev, 0),
465 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
468 gspca_dev->usb_buf, 1,
472 static void reg_w(struct gspca_dev *gspca_dev,
478 if (len > USB_BUF_SZ) {
479 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
483 memcpy(gspca_dev->usb_buf, buffer, len);
484 usb_control_msg(gspca_dev->dev,
485 usb_sndctrlpipe(gspca_dev->dev, 0),
487 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
490 gspca_dev->usb_buf, len,
494 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
499 reg_w(gspca_dev, 0x08, buffer, 8);
502 reg_r(gspca_dev, 0x08);
503 if (gspca_dev->usb_buf[0] & 0x04) {
504 if (gspca_dev->usb_buf[0] & 0x08)
512 static void i2c_w_vector(struct gspca_dev *gspca_dev,
513 const __u8 buffer[][8], int len)
516 reg_w(gspca_dev, 0x08, *buffer, 8);
524 static void setbrightness(struct gspca_dev *gspca_dev)
526 struct sd *sd = (struct sd *) gspca_dev;
529 switch (sd->sensor) {
531 case SENSOR_OV7630: {
533 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
535 /* change reg 0x06 */
536 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
537 i2cOV[3] = sd->brightness;
538 if (i2c_w(gspca_dev, i2cOV) < 0)
542 case SENSOR_PAS106: {
544 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
546 i2c1[3] = sd->brightness >> 3;
548 if (i2c_w(gspca_dev, i2c1) < 0)
552 if (i2c_w(gspca_dev, i2c1) < 0)
556 case SENSOR_PAS202: {
557 /* __u8 i2cpexpo1[] =
558 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
560 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
562 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
563 static __u8 i2cpdoit[] =
564 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
566 /* change reg 0x10 */
567 i2cpexpo[4] = 0xff - sd->brightness;
568 /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
570 /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
572 if (i2c_w(gspca_dev, i2cpexpo) < 0)
574 if (i2c_w(gspca_dev, i2cpdoit) < 0)
576 i2cp202[3] = sd->brightness >> 3;
577 if (i2c_w(gspca_dev, i2cp202) < 0)
579 if (i2c_w(gspca_dev, i2cpdoit) < 0)
583 case SENSOR_TAS5130CXX: {
585 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
587 value = 0xff - sd->brightness;
589 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
590 if (i2c_w(gspca_dev, i2c) < 0)
597 PDEBUG(D_ERR, "i2c error brightness");
600 static void setsensorgain(struct gspca_dev *gspca_dev)
602 struct sd *sd = (struct sd *) gspca_dev;
603 unsigned char gain = sd->gain;
605 switch (sd->sensor) {
607 case SENSOR_TAS5110: {
609 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
612 if (i2c_w(gspca_dev, i2c) < 0)
620 case SENSOR_OV7630: {
621 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
623 i2c[1] = sensor_data[sd->sensor].sensor_addr;
625 if (i2c_w(gspca_dev, i2c) < 0)
632 PDEBUG(D_ERR, "i2c error gain");
635 static void setgain(struct gspca_dev *gspca_dev)
637 struct sd *sd = (struct sd *) gspca_dev;
641 gain = sd->gain >> 4;
643 /* red and blue gain */
644 rgb_value = gain << 4 | gain;
645 reg_w(gspca_dev, 0x10, &rgb_value, 1);
648 reg_w(gspca_dev, 0x11, &rgb_value, 1);
650 if (sensor_data[sd->sensor].flags & F_GAIN)
651 setsensorgain(gspca_dev);
654 static void setexposure(struct gspca_dev *gspca_dev)
656 struct sd *sd = (struct sd *) gspca_dev;
658 switch (sd->sensor) {
659 case SENSOR_TAS5110: {
662 /* register 19's high nibble contains the sn9c10x clock divider
663 The high nibble configures the no fps according to the
664 formula: 60 / high_nibble. With a maximum of 30 fps */
665 reg = 120 * sd->exposure / 1000;
670 reg = (reg << 4) | 0x0b;
671 reg_w(gspca_dev, 0x19, ®, 1);
675 case SENSOR_OV7630: {
676 /* The ov6650 / ov7630 have 2 registers which both influence
677 exposure, register 11, whose low nibble sets the nr off fps
678 according to: fps = 30 / (low_nibble + 1)
680 The fps configures the maximum exposure setting, but it is
681 possible to use less exposure then what the fps maximum
682 allows by setting register 10. register 10 configures the
683 actual exposure as quotient of the full exposure, with 0
684 being no exposure at all (not very usefull) and reg10_max
685 being max exposure possible at that framerate.
687 The code maps our 0 - 510 ms exposure ctrl to these 2
688 registers, trying to keep fps as high as possible.
690 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
691 int reg10, reg11, reg10_max;
693 /* ov6645 datasheet says reg10_max is 9a, but that uses
694 tline * 2 * reg10 as formula for calculating texpo, the
695 ov6650 probably uses the same formula as the 7730 which uses
696 tline * 4 * reg10, which explains why the reg10max we've
697 found experimentally for the ov6650 is exactly half that of
698 the ov6645. The ov7630 datasheet says the max is 0x41. */
699 if (sd->sensor == SENSOR_OV6650) {
701 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
705 reg11 = (60 * sd->exposure + 999) / 1000;
711 /* In 640x480, if the reg11 has less than 3, the image is
712 unstable (not enough bandwidth). */
713 if (gspca_dev->width == 640 && reg11 < 3)
716 /* frame exposure time in ms = 1000 * reg11 / 30 ->
717 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
718 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
720 /* Don't allow this to get below 10 when using autogain, the
721 steps become very large (relatively) when below 10 causing
722 the image to oscilate from much too dark, to much too bright
724 if (sd->autogain && reg10 < 10)
726 else if (reg10 > reg10_max)
729 /* Write reg 10 and reg11 low nibble */
730 i2c[1] = sensor_data[sd->sensor].sensor_addr;
734 /* If register 11 didn't change, don't change it */
735 if (sd->reg11 == reg11 )
738 if (i2c_w(gspca_dev, i2c) == 0)
741 PDEBUG(D_ERR, "i2c error exposure");
747 static void setfreq(struct gspca_dev *gspca_dev)
749 struct sd *sd = (struct sd *) gspca_dev;
751 switch (sd->sensor) {
753 case SENSOR_OV7630: {
754 /* Framerate adjust register for artificial light 50 hz flicker
755 compensation, for the ov6650 this is identical to ov6630
756 0x2b register, see ov6630 datasheet.
757 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
758 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
761 /* case 0: * no filter*/
762 /* case 2: * 60 hz */
766 i2c[3] = (sd->sensor == SENSOR_OV6650)
770 i2c[1] = sensor_data[sd->sensor].sensor_addr;
771 if (i2c_w(gspca_dev, i2c) < 0)
772 PDEBUG(D_ERR, "i2c error setfreq");
778 static void do_autogain(struct gspca_dev *gspca_dev)
780 struct sd *sd = (struct sd *) gspca_dev;
781 int avg_lum = atomic_read(&sd->avg_lum);
786 if (sd->autogain_ignore_frames > 0)
787 sd->autogain_ignore_frames--;
788 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
789 sd->brightness * DESIRED_AVG_LUM / 127,
790 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
791 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
792 (int)sd->gain, (int)sd->exposure);
793 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
797 /* this function is called at probe time */
798 static int sd_config(struct gspca_dev *gspca_dev,
799 const struct usb_device_id *id)
801 struct sd *sd = (struct sd *) gspca_dev;
804 reg_r(gspca_dev, 0x00);
805 if (gspca_dev->usb_buf[0] != 0x10)
808 /* copy the webcam info from the device id */
809 sd->sensor = id->driver_info >> 8;
810 sd->bridge = id->driver_info & 0xff;
811 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
813 cam = &gspca_dev->cam;
815 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
816 cam->cam_mode = vga_mode;
817 cam->nmodes = ARRAY_SIZE(vga_mode);
819 cam->cam_mode = sif_mode;
820 cam->nmodes = ARRAY_SIZE(sif_mode);
822 sd->brightness = BRIGHTNESS_DEF;
824 sd->exposure = EXPOSURE_DEF;
825 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
826 sd->autogain = 0; /* Disable do_autogain callback */
828 sd->autogain = AUTOGAIN_DEF;
834 /* this function is called at probe and resume time */
835 static int sd_init(struct gspca_dev *gspca_dev)
837 const __u8 stop = 0x09; /* Disable stream turn of LED */
839 reg_w(gspca_dev, 0x01, &stop, 1);
844 /* -- start the camera -- */
845 static void sd_start(struct gspca_dev *gspca_dev)
847 struct sd *sd = (struct sd *) gspca_dev;
852 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07;
853 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
854 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
855 reg17_19[0] = sn9c10x[0x17 - 1];
856 reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4);
857 reg17_19[2] = sn9c10x[0x19 - 1];
858 /* Special cases where reg 17 and or 19 value depends on mode */
859 switch (sd->sensor) {
861 reg17_19[0] = mode ? 0x24 : 0x20;
863 case SENSOR_TAS5130CXX:
864 /* probably not mode specific at all most likely the upper
865 nibble of 0x19 is exposure (clock divider) just as with
866 the tas5110, we need someone to test this. */
867 reg17_19[2] = mode ? 0x23 : 0x43;
871 /* reg 0x01 bit 2 video transfert on */
872 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
873 /* reg 0x17 SensorClk enable inv Clk 0x60 */
874 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
875 /* Set the registers from the template */
876 reg_w(gspca_dev, 0x01, sn9c10x, l);
878 /* Init the sensor */
879 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
880 sensor_data[sd->sensor].sensor_init_size);
881 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
882 i2c_w_vector(gspca_dev,
883 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
884 sensor_data[sd->sensor].sensor_bridge_init_size[
887 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
888 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
889 /* compression register */
890 reg_w(gspca_dev, 0x18, ®17_19[1], 1);
892 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
894 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
895 /* reset 0x17 SensorClk enable inv Clk 0x60 */
896 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
897 reg_w(gspca_dev, 0x17, ®17_19[0], 1);
898 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
899 reg_w(gspca_dev, 0x19, ®17_19[2], 1);
900 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
901 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
902 /* Enable video transfert */
903 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
905 reg_w(gspca_dev, 0x18, ®17_19[1], 2);
911 setbrightness(gspca_dev);
912 setexposure(gspca_dev);
915 sd->frames_to_drop = 0;
916 sd->autogain_ignore_frames = 0;
917 atomic_set(&sd->avg_lum, -1);
920 static void sd_stopN(struct gspca_dev *gspca_dev)
925 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
926 struct gspca_frame *frame, /* target */
927 unsigned char *data, /* isoc packet */
928 int len) /* iso packet length */
931 struct sd *sd = (struct sd *) gspca_dev;
933 /* frames start with:
934 * ff ff 00 c4 c4 96 synchro
936 * xx (frame sequence / size / compression)
937 * (xx) (idem - extra byte for sn9c103)
938 * ll mm brightness sum inside auto exposure
939 * ll mm brightness sum outside auto exposure
940 * (xx xx xx xx xx) audio values for snc103
942 if (len > 6 && len < 24) {
943 for (i = 0; i < len - 6; i++) {
944 if (data[0 + i] == 0xff
945 && data[1 + i] == 0xff
946 && data[2 + i] == 0x00
947 && data[3 + i] == 0xc4
948 && data[4 + i] == 0xc4
949 && data[5 + i] == 0x96) { /* start of frame */
951 int pkt_type = LAST_PACKET;
952 int fr_h_sz = (sd->bridge == BRIDGE_103) ?
955 if (len - i < fr_h_sz) {
956 PDEBUG(D_STREAM, "packet too short to"
957 " get avg brightness");
958 } else if (sd->bridge == BRIDGE_103) {
962 lum = data[i + 8] + (data[i + 9] << 8);
966 sd->frames_to_drop = 2;
968 atomic_set(&sd->avg_lum, lum);
970 if (sd->frames_to_drop) {
971 sd->frames_to_drop--;
972 pkt_type = DISCARD_PACKET;
975 frame = gspca_frame_add(gspca_dev, pkt_type,
979 gspca_frame_add(gspca_dev, FIRST_PACKET,
985 gspca_frame_add(gspca_dev, INTER_PACKET,
989 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
991 struct sd *sd = (struct sd *) gspca_dev;
993 sd->brightness = val;
994 if (gspca_dev->streaming)
995 setbrightness(gspca_dev);
999 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1001 struct sd *sd = (struct sd *) gspca_dev;
1003 *val = sd->brightness;
1007 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1009 struct sd *sd = (struct sd *) gspca_dev;
1012 if (gspca_dev->streaming)
1017 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1019 struct sd *sd = (struct sd *) gspca_dev;
1025 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1027 struct sd *sd = (struct sd *) gspca_dev;
1030 if (gspca_dev->streaming)
1031 setexposure(gspca_dev);
1035 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1037 struct sd *sd = (struct sd *) gspca_dev;
1039 *val = sd->exposure;
1043 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1045 struct sd *sd = (struct sd *) gspca_dev;
1048 /* when switching to autogain set defaults to make sure
1049 we are on a valid point of the autogain gain /
1050 exposure knee graph, and give this change time to
1051 take effect before doing autogain. */
1053 sd->exposure = EXPOSURE_DEF;
1054 sd->gain = GAIN_DEF;
1055 if (gspca_dev->streaming) {
1056 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1057 setexposure(gspca_dev);
1065 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1067 struct sd *sd = (struct sd *) gspca_dev;
1069 *val = sd->autogain;
1073 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1075 struct sd *sd = (struct sd *) gspca_dev;
1078 if (gspca_dev->streaming)
1083 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1085 struct sd *sd = (struct sd *) gspca_dev;
1091 static int sd_querymenu(struct gspca_dev *gspca_dev,
1092 struct v4l2_querymenu *menu)
1095 case V4L2_CID_POWER_LINE_FREQUENCY:
1096 switch (menu->index) {
1097 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1098 strcpy((char *) menu->name, "NoFliker");
1100 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1101 strcpy((char *) menu->name, "50 Hz");
1103 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1104 strcpy((char *) menu->name, "60 Hz");
1112 /* sub-driver description */
1113 static const struct sd_desc sd_desc = {
1114 .name = MODULE_NAME,
1116 .nctrls = ARRAY_SIZE(sd_ctrls),
1117 .config = sd_config,
1121 .pkt_scan = sd_pkt_scan,
1122 .querymenu = sd_querymenu,
1123 .dq_callback = do_autogain,
1126 /* -- module initialisation -- */
1127 #define SB(sensor, bridge) \
1128 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1131 static __devinitdata struct usb_device_id device_table[] = {
1132 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1133 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)},
1134 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)},
1135 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)},
1136 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1137 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1139 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1140 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1141 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1142 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1143 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1144 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1145 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1146 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1148 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1149 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1150 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1151 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1152 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1153 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1157 MODULE_DEVICE_TABLE(usb, device_table);
1159 /* -- device connect -- */
1160 static int sd_probe(struct usb_interface *intf,
1161 const struct usb_device_id *id)
1163 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1167 static struct usb_driver sd_driver = {
1168 .name = MODULE_NAME,
1169 .id_table = device_table,
1171 .disconnect = gspca_disconnect,
1173 .suspend = gspca_suspend,
1174 .resume = gspca_resume,
1178 /* -- module insert / remove -- */
1179 static int __init sd_mod_init(void)
1181 if (usb_register(&sd_driver) < 0)
1183 PDEBUG(D_PROBE, "registered");
1186 static void __exit sd_mod_exit(void)
1188 usb_deregister(&sd_driver);
1189 PDEBUG(D_PROBE, "deregistered");
1192 module_init(sd_mod_init);
1193 module_exit(sd_mod_exit);