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 */
77 #define F_RAW 0x04 /* sensor tested ok with raw bayer mode */
79 /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
80 #define MODE_RAW 0x10 /* raw bayer mode */
82 /* ctrl_dis helper macros */
83 #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
84 #define NO_FREQ (1 << FREQ_IDX)
85 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
88 #define COMP 0xc7 /* 0x87 //0x07 */
89 #define COMP1 0xc9 /* 0x89 //0x09 */
92 #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
96 #define SENS(bridge_1, bridge_3, sensor, sensor_1, \
97 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
99 .bridge_init = { bridge_1, bridge_3 }, \
100 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
101 .sensor_init = sensor, \
102 .sensor_init_size = sizeof(sensor), \
103 .sensor_bridge_init = { sensor_1, sensor_3,}, \
104 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
105 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
108 /* We calculate the autogain at the end of the transfer of a frame, at this
109 moment a frame with the old settings is being transmitted, and a frame is
110 being captured with the old settings. So if we adjust the autogain we must
111 ignore atleast the 2 next frames for the new settings to come into effect
112 before doing any other adjustments */
113 #define AUTOGAIN_IGNORE_FRAMES 3
114 #define AUTOGAIN_DEADZONE 1000
115 #define DESIRED_AVG_LUM 7000
117 /* V4L2 controls supported by the driver */
118 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
119 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
120 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
121 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
122 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
123 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
124 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
125 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
126 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
127 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
129 static struct ctrl sd_ctrls[] = {
130 #define BRIGHTNESS_IDX 0
133 .id = V4L2_CID_BRIGHTNESS,
134 .type = V4L2_CTRL_TYPE_INTEGER,
135 .name = "Brightness",
139 #define BRIGHTNESS_DEF 127
140 .default_value = BRIGHTNESS_DEF,
142 .set = sd_setbrightness,
143 .get = sd_getbrightness,
149 .type = V4L2_CTRL_TYPE_INTEGER,
155 #define GAIN_KNEE 200
156 .default_value = GAIN_DEF,
161 #define EXPOSURE_IDX 2
164 .id = V4L2_CID_EXPOSURE,
165 .type = V4L2_CTRL_TYPE_INTEGER,
167 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
168 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
172 .default_value = EXPOSURE_DEF,
175 .set = sd_setexposure,
176 .get = sd_getexposure,
178 #define AUTOGAIN_IDX 3
181 .id = V4L2_CID_AUTOGAIN,
182 .type = V4L2_CTRL_TYPE_BOOLEAN,
183 .name = "Automatic Gain (and Exposure)",
187 #define AUTOGAIN_DEF 1
188 .default_value = AUTOGAIN_DEF,
191 .set = sd_setautogain,
192 .get = sd_getautogain,
197 .id = V4L2_CID_POWER_LINE_FREQUENCY,
198 .type = V4L2_CTRL_TYPE_MENU,
199 .name = "Light frequency filter",
201 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
204 .default_value = FREQ_DEF,
211 static struct v4l2_pix_format vga_mode[] = {
212 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
214 .sizeimage = 160 * 120,
215 .colorspace = V4L2_COLORSPACE_SRGB,
216 .priv = 2 | MODE_RAW},
217 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
219 .sizeimage = 160 * 120 * 5 / 4,
220 .colorspace = V4L2_COLORSPACE_SRGB,
222 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
224 .sizeimage = 320 * 240 * 5 / 4,
225 .colorspace = V4L2_COLORSPACE_SRGB,
227 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
229 .sizeimage = 640 * 480 * 5 / 4,
230 .colorspace = V4L2_COLORSPACE_SRGB,
233 static struct v4l2_pix_format sif_mode[] = {
234 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
236 .sizeimage = 176 * 144,
237 .colorspace = V4L2_COLORSPACE_SRGB,
238 .priv = 1 | MODE_RAW},
239 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
241 .sizeimage = 176 * 144 * 5 / 4,
242 .colorspace = V4L2_COLORSPACE_SRGB,
244 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
246 .sizeimage = 352 * 288 * 5 / 4,
247 .colorspace = V4L2_COLORSPACE_SRGB,
251 static const __u8 initHv7131[] = {
252 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
254 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
255 0x28, 0x1e, 0x60, 0x8a, 0x20,
256 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
258 static const __u8 hv7131_sensor_init[][8] = {
259 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
260 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
261 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
262 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
263 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
265 static const __u8 initOv6650[] = {
266 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
267 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
268 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
269 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
271 static const __u8 ov6650_sensor_init[][8] =
273 /* Bright, contrast, etc are set througth SCBB interface.
274 * AVCAP on win2 do not send any data on this controls. */
275 /* Anyway, some registers appears to alter bright and constrat */
278 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
279 /* Set clock register 0x11 low nibble is clock divider */
280 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
281 /* Next some unknown stuff */
282 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
283 /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
284 * THIS SET GREEN SCREEN
285 * (pixels could be innverted in decode kind of "brg",
286 * but blue wont be there. Avoid this data ... */
287 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
288 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
289 {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
290 /* Enable rgb brightness control */
291 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
292 /* HDG: Note windows uses the line below, which sets both register 0x60
293 and 0x61 I believe these registers of the ov6650 are identical as
294 those of the ov7630, because if this is true the windows settings
295 add a bit additional red gain and a lot additional blue gain, which
296 matches my findings that the windows settings make blue much too
297 blue and red a little too red.
298 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
299 /* Some more unknown stuff */
300 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
301 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
304 static const __u8 initOv7630[] = {
305 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
306 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
307 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
308 0x28, 0x1e, /* H & V sizes r15 .. r16 */
309 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
310 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
312 static const __u8 initOv7630_3[] = {
313 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
314 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
315 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
316 0x28, 0x1e, /* H & V sizes r15 .. r16 */
317 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
318 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
319 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
320 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
322 static const __u8 ov7630_sensor_init[][8] = {
323 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
324 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
325 /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
326 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
327 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
328 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
329 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
330 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
331 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
332 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
333 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
334 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
335 /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
336 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
337 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
338 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
339 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
340 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
341 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
344 static const __u8 ov7630_sensor_init_3[][8] = {
345 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
348 static const __u8 initPas106[] = {
349 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
351 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
352 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
353 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
355 /* compression 0x86 mckinit1 0x2b */
356 static const __u8 pas106_sensor_init[][8] = {
357 /* Pixel Clock Divider 6 */
358 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
359 /* Frame Time MSB (also seen as 0x12) */
360 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
361 /* Frame Time LSB (also seen as 0x05) */
362 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
363 /* Shutter Time Line Offset (also seen as 0x6d) */
364 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
365 /* Shutter Time Pixel Offset (also seen as 0xb1) */
366 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
367 /* Black Level Subtract Sign (also seen 0x00) */
368 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
369 /* Black Level Subtract Level (also seen 0x01) */
370 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
371 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
372 /* Color Gain B Pixel 5 a */
373 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
374 /* Color Gain G1 Pixel 1 5 */
375 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
376 /* Color Gain G2 Pixel 1 0 5 */
377 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
378 /* Color Gain R Pixel 3 1 */
379 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
380 /* Color GainH Pixel */
381 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
383 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
385 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
386 /* H&V synchro polarity */
387 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
389 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
391 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
393 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
394 /* Validate Settings */
395 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
398 static const __u8 initPas202[] = {
399 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
401 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
402 0x28, 0x1e, 0x28, 0x89, 0x20,
403 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
405 static const __u8 pas202_sensor_init[][8] = {
406 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
407 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
408 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
409 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
410 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
411 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
412 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
413 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
414 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
415 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
416 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
417 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
419 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
420 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
421 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
422 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
423 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
424 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
425 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
426 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
429 static const __u8 initTas5110[] = {
430 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
432 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
433 0x16, 0x12, 0x60, 0x86, 0x2b,
434 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
436 static const __u8 tas5110_sensor_init[][8] = {
437 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
438 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
439 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
442 static const __u8 initTas5130[] = {
443 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
445 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
446 0x28, 0x1e, 0x60, COMP, MCK_INIT,
447 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
449 static const __u8 tas5130_sensor_init[][8] = {
450 /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
451 * shutter 0x47 short exposure? */
452 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
453 /* shutter 0x01 long exposure */
454 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
457 struct sensor_data sensor_data[] = {
458 SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
459 SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW, 0,
461 SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
463 SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
465 SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_RAW,
467 SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF|F_RAW,
468 NO_BRIGHTNESS|NO_FREQ, 0),
469 SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
473 /* get one byte in gspca_dev->usb_buf */
474 static void reg_r(struct gspca_dev *gspca_dev,
477 usb_control_msg(gspca_dev->dev,
478 usb_rcvctrlpipe(gspca_dev->dev, 0),
480 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
483 gspca_dev->usb_buf, 1,
487 static void reg_w(struct gspca_dev *gspca_dev,
493 if (len > USB_BUF_SZ) {
494 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
498 memcpy(gspca_dev->usb_buf, buffer, len);
499 usb_control_msg(gspca_dev->dev,
500 usb_sndctrlpipe(gspca_dev->dev, 0),
502 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
505 gspca_dev->usb_buf, len,
509 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
514 reg_w(gspca_dev, 0x08, buffer, 8);
517 reg_r(gspca_dev, 0x08);
518 if (gspca_dev->usb_buf[0] & 0x04) {
519 if (gspca_dev->usb_buf[0] & 0x08)
527 static void i2c_w_vector(struct gspca_dev *gspca_dev,
528 const __u8 buffer[][8], int len)
531 reg_w(gspca_dev, 0x08, *buffer, 8);
539 static void setbrightness(struct gspca_dev *gspca_dev)
541 struct sd *sd = (struct sd *) gspca_dev;
544 switch (sd->sensor) {
546 case SENSOR_OV7630: {
548 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
550 /* change reg 0x06 */
551 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
552 i2cOV[3] = sd->brightness;
553 if (i2c_w(gspca_dev, i2cOV) < 0)
557 case SENSOR_PAS106: {
559 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
561 i2c1[3] = sd->brightness >> 3;
563 if (i2c_w(gspca_dev, i2c1) < 0)
567 if (i2c_w(gspca_dev, i2c1) < 0)
571 case SENSOR_PAS202: {
572 /* __u8 i2cpexpo1[] =
573 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
575 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
577 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
578 static __u8 i2cpdoit[] =
579 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
581 /* change reg 0x10 */
582 i2cpexpo[4] = 0xff - sd->brightness;
583 /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
585 /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
587 if (i2c_w(gspca_dev, i2cpexpo) < 0)
589 if (i2c_w(gspca_dev, i2cpdoit) < 0)
591 i2cp202[3] = sd->brightness >> 3;
592 if (i2c_w(gspca_dev, i2cp202) < 0)
594 if (i2c_w(gspca_dev, i2cpdoit) < 0)
598 case SENSOR_TAS5130CXX: {
600 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
602 value = 0xff - sd->brightness;
604 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
605 if (i2c_w(gspca_dev, i2c) < 0)
612 PDEBUG(D_ERR, "i2c error brightness");
615 static void setsensorgain(struct gspca_dev *gspca_dev)
617 struct sd *sd = (struct sd *) gspca_dev;
618 unsigned char gain = sd->gain;
620 switch (sd->sensor) {
622 case SENSOR_TAS5110: {
624 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
627 if (i2c_w(gspca_dev, i2c) < 0)
635 case SENSOR_OV7630: {
636 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
638 i2c[1] = sensor_data[sd->sensor].sensor_addr;
640 if (i2c_w(gspca_dev, i2c) < 0)
647 PDEBUG(D_ERR, "i2c error gain");
650 static void setgain(struct gspca_dev *gspca_dev)
652 struct sd *sd = (struct sd *) gspca_dev;
656 gain = sd->gain >> 4;
658 /* red and blue gain */
659 rgb_value = gain << 4 | gain;
660 reg_w(gspca_dev, 0x10, &rgb_value, 1);
663 reg_w(gspca_dev, 0x11, &rgb_value, 1);
665 if (sensor_data[sd->sensor].flags & F_GAIN)
666 setsensorgain(gspca_dev);
669 static void setexposure(struct gspca_dev *gspca_dev)
671 struct sd *sd = (struct sd *) gspca_dev;
673 switch (sd->sensor) {
674 case SENSOR_TAS5110: {
677 /* register 19's high nibble contains the sn9c10x clock divider
678 The high nibble configures the no fps according to the
679 formula: 60 / high_nibble. With a maximum of 30 fps */
680 reg = 120 * sd->exposure / 1000;
685 reg = (reg << 4) | 0x0b;
686 reg_w(gspca_dev, 0x19, ®, 1);
690 case SENSOR_OV7630: {
691 /* The ov6650 / ov7630 have 2 registers which both influence
692 exposure, register 11, whose low nibble sets the nr off fps
693 according to: fps = 30 / (low_nibble + 1)
695 The fps configures the maximum exposure setting, but it is
696 possible to use less exposure then what the fps maximum
697 allows by setting register 10. register 10 configures the
698 actual exposure as quotient of the full exposure, with 0
699 being no exposure at all (not very usefull) and reg10_max
700 being max exposure possible at that framerate.
702 The code maps our 0 - 510 ms exposure ctrl to these 2
703 registers, trying to keep fps as high as possible.
705 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
706 int reg10, reg11, reg10_max;
708 /* ov6645 datasheet says reg10_max is 9a, but that uses
709 tline * 2 * reg10 as formula for calculating texpo, the
710 ov6650 probably uses the same formula as the 7730 which uses
711 tline * 4 * reg10, which explains why the reg10max we've
712 found experimentally for the ov6650 is exactly half that of
713 the ov6645. The ov7630 datasheet says the max is 0x41. */
714 if (sd->sensor == SENSOR_OV6650) {
716 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
720 reg11 = (60 * sd->exposure + 999) / 1000;
726 /* In 640x480, if the reg11 has less than 3, the image is
727 unstable (not enough bandwidth). */
728 if (gspca_dev->width == 640 && reg11 < 3)
731 /* frame exposure time in ms = 1000 * reg11 / 30 ->
732 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
733 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
735 /* Don't allow this to get below 10 when using autogain, the
736 steps become very large (relatively) when below 10 causing
737 the image to oscilate from much too dark, to much too bright
739 if (sd->autogain && reg10 < 10)
741 else if (reg10 > reg10_max)
744 /* Write reg 10 and reg11 low nibble */
745 i2c[1] = sensor_data[sd->sensor].sensor_addr;
749 /* If register 11 didn't change, don't change it */
750 if (sd->reg11 == reg11 )
753 if (i2c_w(gspca_dev, i2c) == 0)
756 PDEBUG(D_ERR, "i2c error exposure");
762 static void setfreq(struct gspca_dev *gspca_dev)
764 struct sd *sd = (struct sd *) gspca_dev;
766 switch (sd->sensor) {
768 case SENSOR_OV7630: {
769 /* Framerate adjust register for artificial light 50 hz flicker
770 compensation, for the ov6650 this is identical to ov6630
771 0x2b register, see ov6630 datasheet.
772 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
773 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
776 /* case 0: * no filter*/
777 /* case 2: * 60 hz */
781 i2c[3] = (sd->sensor == SENSOR_OV6650)
785 i2c[1] = sensor_data[sd->sensor].sensor_addr;
786 if (i2c_w(gspca_dev, i2c) < 0)
787 PDEBUG(D_ERR, "i2c error setfreq");
793 static void do_autogain(struct gspca_dev *gspca_dev)
795 struct sd *sd = (struct sd *) gspca_dev;
796 int avg_lum = atomic_read(&sd->avg_lum);
801 if (sd->autogain_ignore_frames > 0)
802 sd->autogain_ignore_frames--;
803 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
804 sd->brightness * DESIRED_AVG_LUM / 127,
805 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
806 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
807 (int)sd->gain, (int)sd->exposure);
808 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
812 /* this function is called at probe time */
813 static int sd_config(struct gspca_dev *gspca_dev,
814 const struct usb_device_id *id)
816 struct sd *sd = (struct sd *) gspca_dev;
819 reg_r(gspca_dev, 0x00);
820 if (gspca_dev->usb_buf[0] != 0x10)
823 /* copy the webcam info from the device id */
824 sd->sensor = id->driver_info >> 8;
825 sd->bridge = id->driver_info & 0xff;
826 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
828 cam = &gspca_dev->cam;
830 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
831 cam->cam_mode = vga_mode;
832 cam->nmodes = ARRAY_SIZE(vga_mode);
834 cam->cam_mode = sif_mode;
835 cam->nmodes = ARRAY_SIZE(sif_mode);
837 if (!(sensor_data[sd->sensor].flags & F_RAW)) {
841 sd->brightness = BRIGHTNESS_DEF;
843 sd->exposure = EXPOSURE_DEF;
844 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
845 sd->autogain = 0; /* Disable do_autogain callback */
847 sd->autogain = AUTOGAIN_DEF;
853 /* this function is called at probe and resume time */
854 static int sd_init(struct gspca_dev *gspca_dev)
856 const __u8 stop = 0x09; /* Disable stream turn of LED */
858 reg_w(gspca_dev, 0x01, &stop, 1);
863 /* -- start the camera -- */
864 static void sd_start(struct gspca_dev *gspca_dev)
866 struct sd *sd = (struct sd *) gspca_dev;
871 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv & 0x07;
872 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
873 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
874 reg17_19[0] = sn9c10x[0x17 - 1];
875 reg17_19[1] = sn9c10x[0x18 - 1] | (mode << 4);
876 reg17_19[2] = sn9c10x[0x19 - 1];
877 /* Special cases where reg 17 and or 19 value depends on mode */
878 switch (sd->sensor) {
880 reg17_19[0] = mode ? 0x24 : 0x20;
882 case SENSOR_TAS5130CXX:
883 /* probably not mode specific at all most likely the upper
884 nibble of 0x19 is exposure (clock divider) just as with
885 the tas5110, we need someone to test this. */
886 reg17_19[2] = mode ? 0x23 : 0x43;
889 /* Disable compression when the raw bayer format has been selected */
890 if (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
891 reg17_19[1] &= ~0x80;
893 /* reg 0x01 bit 2 video transfert on */
894 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
895 /* reg 0x17 SensorClk enable inv Clk 0x60 */
896 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
897 /* Set the registers from the template */
898 reg_w(gspca_dev, 0x01, sn9c10x, l);
900 /* Init the sensor */
901 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
902 sensor_data[sd->sensor].sensor_init_size);
903 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
904 i2c_w_vector(gspca_dev,
905 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
906 sensor_data[sd->sensor].sensor_bridge_init_size[
909 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
910 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
911 /* compression register */
912 reg_w(gspca_dev, 0x18, ®17_19[1], 1);
914 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
916 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
917 /* reset 0x17 SensorClk enable inv Clk 0x60 */
918 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
919 reg_w(gspca_dev, 0x17, ®17_19[0], 1);
920 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
921 reg_w(gspca_dev, 0x19, ®17_19[2], 1);
922 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
923 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
924 /* Enable video transfert */
925 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
927 reg_w(gspca_dev, 0x18, ®17_19[1], 2);
933 setbrightness(gspca_dev);
934 setexposure(gspca_dev);
937 sd->frames_to_drop = 0;
938 sd->autogain_ignore_frames = 0;
939 atomic_set(&sd->avg_lum, -1);
942 static void sd_stopN(struct gspca_dev *gspca_dev)
947 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
948 struct gspca_frame *frame, /* target */
949 unsigned char *data, /* isoc packet */
950 int len) /* iso packet length */
953 struct sd *sd = (struct sd *) gspca_dev;
954 struct cam *cam = &gspca_dev->cam;
956 /* frames start with:
957 * ff ff 00 c4 c4 96 synchro
959 * xx (frame sequence / size / compression)
960 * (xx) (idem - extra byte for sn9c103)
961 * ll mm brightness sum inside auto exposure
962 * ll mm brightness sum outside auto exposure
963 * (xx xx xx xx xx) audio values for snc103
965 if (len > 6 && len < 24) {
966 for (i = 0; i < len - 6; i++) {
967 if (data[0 + i] == 0xff
968 && data[1 + i] == 0xff
969 && data[2 + i] == 0x00
970 && data[3 + i] == 0xc4
971 && data[4 + i] == 0xc4
972 && data[5 + i] == 0x96) { /* start of frame */
974 int pkt_type = LAST_PACKET;
975 int fr_h_sz = (sd->bridge == BRIDGE_103) ?
978 if (len - i < fr_h_sz) {
979 PDEBUG(D_STREAM, "packet too short to"
980 " get avg brightness");
981 } else if (sd->bridge == BRIDGE_103) {
985 lum = data[i + 8] + (data[i + 9] << 8);
989 sd->frames_to_drop = 2;
991 atomic_set(&sd->avg_lum, lum);
993 if (sd->frames_to_drop) {
994 sd->frames_to_drop--;
995 pkt_type = DISCARD_PACKET;
998 frame = gspca_frame_add(gspca_dev, pkt_type,
1000 data += i + fr_h_sz;
1002 gspca_frame_add(gspca_dev, FIRST_PACKET,
1009 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1010 /* In raw mode we sometimes get some garbage after the frame
1012 int used = frame->data_end - frame->data;
1013 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1015 if (used + len > size)
1019 gspca_frame_add(gspca_dev, INTER_PACKET,
1023 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1025 struct sd *sd = (struct sd *) gspca_dev;
1027 sd->brightness = val;
1028 if (gspca_dev->streaming)
1029 setbrightness(gspca_dev);
1033 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1035 struct sd *sd = (struct sd *) gspca_dev;
1037 *val = sd->brightness;
1041 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1043 struct sd *sd = (struct sd *) gspca_dev;
1046 if (gspca_dev->streaming)
1051 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1053 struct sd *sd = (struct sd *) gspca_dev;
1059 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1061 struct sd *sd = (struct sd *) gspca_dev;
1064 if (gspca_dev->streaming)
1065 setexposure(gspca_dev);
1069 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1071 struct sd *sd = (struct sd *) gspca_dev;
1073 *val = sd->exposure;
1077 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1079 struct sd *sd = (struct sd *) gspca_dev;
1082 /* when switching to autogain set defaults to make sure
1083 we are on a valid point of the autogain gain /
1084 exposure knee graph, and give this change time to
1085 take effect before doing autogain. */
1087 sd->exposure = EXPOSURE_DEF;
1088 sd->gain = GAIN_DEF;
1089 if (gspca_dev->streaming) {
1090 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1091 setexposure(gspca_dev);
1099 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1101 struct sd *sd = (struct sd *) gspca_dev;
1103 *val = sd->autogain;
1107 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1109 struct sd *sd = (struct sd *) gspca_dev;
1112 if (gspca_dev->streaming)
1117 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1119 struct sd *sd = (struct sd *) gspca_dev;
1125 static int sd_querymenu(struct gspca_dev *gspca_dev,
1126 struct v4l2_querymenu *menu)
1129 case V4L2_CID_POWER_LINE_FREQUENCY:
1130 switch (menu->index) {
1131 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1132 strcpy((char *) menu->name, "NoFliker");
1134 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1135 strcpy((char *) menu->name, "50 Hz");
1137 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1138 strcpy((char *) menu->name, "60 Hz");
1146 /* sub-driver description */
1147 static const struct sd_desc sd_desc = {
1148 .name = MODULE_NAME,
1150 .nctrls = ARRAY_SIZE(sd_ctrls),
1151 .config = sd_config,
1155 .pkt_scan = sd_pkt_scan,
1156 .querymenu = sd_querymenu,
1157 .dq_callback = do_autogain,
1160 /* -- module initialisation -- */
1161 #define SB(sensor, bridge) \
1162 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1165 static __devinitdata struct usb_device_id device_table[] = {
1166 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1167 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)},
1168 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)},
1169 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)},
1170 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1171 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1173 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1174 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1175 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1176 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1177 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1178 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1179 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1180 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1182 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1183 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1184 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1185 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1186 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1187 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1191 MODULE_DEVICE_TABLE(usb, device_table);
1193 /* -- device connect -- */
1194 static int sd_probe(struct usb_interface *intf,
1195 const struct usb_device_id *id)
1197 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1201 static struct usb_driver sd_driver = {
1202 .name = MODULE_NAME,
1203 .id_table = device_table,
1205 .disconnect = gspca_disconnect,
1207 .suspend = gspca_suspend,
1208 .resume = gspca_resume,
1212 /* -- module insert / remove -- */
1213 static int __init sd_mod_init(void)
1215 if (usb_register(&sd_driver) < 0)
1217 PDEBUG(D_PROBE, "registered");
1220 static void __exit sd_mod_exit(void)
1222 usb_deregister(&sd_driver);
1223 PDEBUG(D_PROBE, "deregistered");
1226 module_init(sd_mod_init);
1227 module_exit(sd_mod_exit);