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 /* Some documentation on known sonixb registers:
26 0x10 high nibble red gain low nibble blue gain
27 0x11 low nibble green gain
30 0x15 hsize (hsize = register-value * 16)
31 0x16 vsize (vsize = register-value * 16)
32 0x17 bit 0 toggle compression quality (according to sn9c102 driver)
33 0x18 bit 7 enables compression, bit 4-5 set image down scaling:
34 00 scale 1, 01 scale 1/2, 10, scale 1/4
35 0x19 high-nibble is sensor clock divider, changes exposure on sensors which
36 use a clock generated by the bridge. Some sensors have their own clock.
37 0x1c auto_exposure area (for avg_lum) startx (startx = register-value * 32)
38 0x1d auto_exposure area (for avg_lum) starty (starty = register-value * 32)
39 0x1e auto_exposure area (for avg_lum) stopx (hsize = (0x1e - 0x1c) * 32)
40 0x1f auto_exposure area (for avg_lum) stopy (vsize = (0x1f - 0x1d) * 32)
43 #define MODULE_NAME "sonixb"
45 #include <linux/input.h>
48 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
49 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
50 MODULE_LICENSE("GPL");
52 /* specific webcam descriptor */
54 struct gspca_dev gspca_dev; /* !! must be the first item */
60 u8 header[12]; /* Header without sof marker */
62 unsigned short exposure;
64 unsigned char brightness;
65 unsigned char autogain;
66 unsigned char autogain_ignore_frames;
67 unsigned char frames_to_drop;
68 unsigned char freq; /* light freq filter setting */
70 __u8 bridge; /* Type of bridge */
72 #define BRIDGE_102 0 /* We make no difference between 101 and 102 */
75 __u8 sensor; /* Type of image sensor chip */
76 #define SENSOR_HV7131D 0
77 #define SENSOR_HV7131R 1
78 #define SENSOR_OV6650 2
79 #define SENSOR_OV7630 3
80 #define SENSOR_PAS106 4
81 #define SENSOR_PAS202 5
82 #define SENSOR_TAS5110C 6
83 #define SENSOR_TAS5110D 7
84 #define SENSOR_TAS5130CXX 8
88 typedef const __u8 sensor_init_t[8];
91 const __u8 *bridge_init[2];
92 int bridge_init_size[2];
93 sensor_init_t *sensor_init;
95 sensor_init_t *sensor_bridge_init[2];
96 int sensor_bridge_init_size[2];
102 /* sensor_data flags */
103 #define F_GAIN 0x01 /* has gain */
104 #define F_SIF 0x02 /* sif or vga */
105 #define F_COARSE_EXPO 0x04 /* exposure control is coarse */
107 /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
108 #define MODE_RAW 0x10 /* raw bayer mode */
109 #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
111 /* ctrl_dis helper macros */
112 #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << COARSE_EXPOSURE_IDX) | \
114 #define NO_FREQ (1 << FREQ_IDX)
115 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
118 #define COMP 0xc7 /* 0x87 //0x07 */
119 #define COMP1 0xc9 /* 0x89 //0x09 */
121 #define MCK_INIT 0x63
122 #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
126 #define SENS(bridge_1, bridge_3, sensor, sensor_1, \
127 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
129 .bridge_init = { bridge_1, bridge_3 }, \
130 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
131 .sensor_init = sensor, \
132 .sensor_init_size = sizeof(sensor), \
133 .sensor_bridge_init = { sensor_1, sensor_3,}, \
134 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
135 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
138 /* We calculate the autogain at the end of the transfer of a frame, at this
139 moment a frame with the old settings is being captured and transmitted. So
140 if we adjust the gain or exposure we must ignore atleast the next frame for
141 the new settings to come into effect before doing any other adjustments. */
142 #define AUTOGAIN_IGNORE_FRAMES 1
144 /* V4L2 controls supported by the driver */
145 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
146 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
147 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
148 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
149 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
150 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
151 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
152 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
153 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
154 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
156 static const struct ctrl sd_ctrls[] = {
157 #define BRIGHTNESS_IDX 0
160 .id = V4L2_CID_BRIGHTNESS,
161 .type = V4L2_CTRL_TYPE_INTEGER,
162 .name = "Brightness",
166 #define BRIGHTNESS_DEF 127
167 .default_value = BRIGHTNESS_DEF,
169 .set = sd_setbrightness,
170 .get = sd_getbrightness,
176 .type = V4L2_CTRL_TYPE_INTEGER,
182 #define GAIN_KNEE 230
183 .default_value = GAIN_DEF,
188 #define EXPOSURE_IDX 2
191 .id = V4L2_CID_EXPOSURE,
192 .type = V4L2_CTRL_TYPE_INTEGER,
194 #define EXPOSURE_DEF 66 /* 33 ms / 30 fps (except on PASXXX) */
195 #define EXPOSURE_KNEE 200 /* 100 ms / 10 fps (except on PASXXX) */
199 .default_value = EXPOSURE_DEF,
202 .set = sd_setexposure,
203 .get = sd_getexposure,
205 #define COARSE_EXPOSURE_IDX 3
208 .id = V4L2_CID_EXPOSURE,
209 .type = V4L2_CTRL_TYPE_INTEGER,
211 #define COARSE_EXPOSURE_DEF 2 /* 30 fps */
215 .default_value = COARSE_EXPOSURE_DEF,
218 .set = sd_setexposure,
219 .get = sd_getexposure,
221 #define AUTOGAIN_IDX 4
224 .id = V4L2_CID_AUTOGAIN,
225 .type = V4L2_CTRL_TYPE_BOOLEAN,
226 .name = "Automatic Gain (and Exposure)",
230 #define AUTOGAIN_DEF 1
231 .default_value = AUTOGAIN_DEF,
234 .set = sd_setautogain,
235 .get = sd_getautogain,
240 .id = V4L2_CID_POWER_LINE_FREQUENCY,
241 .type = V4L2_CTRL_TYPE_MENU,
242 .name = "Light frequency filter",
244 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
247 .default_value = FREQ_DEF,
254 static const struct v4l2_pix_format vga_mode[] = {
255 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
257 .sizeimage = 160 * 120,
258 .colorspace = V4L2_COLORSPACE_SRGB,
259 .priv = 2 | MODE_RAW},
260 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
262 .sizeimage = 160 * 120 * 5 / 4,
263 .colorspace = V4L2_COLORSPACE_SRGB,
265 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
267 .sizeimage = 320 * 240 * 5 / 4,
268 .colorspace = V4L2_COLORSPACE_SRGB,
270 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
272 .sizeimage = 640 * 480 * 5 / 4,
273 .colorspace = V4L2_COLORSPACE_SRGB,
276 static const struct v4l2_pix_format sif_mode[] = {
277 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
279 .sizeimage = 160 * 120,
280 .colorspace = V4L2_COLORSPACE_SRGB,
281 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
282 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
284 .sizeimage = 160 * 120 * 5 / 4,
285 .colorspace = V4L2_COLORSPACE_SRGB,
286 .priv = 1 | MODE_REDUCED_SIF},
287 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
289 .sizeimage = 176 * 144,
290 .colorspace = V4L2_COLORSPACE_SRGB,
291 .priv = 1 | MODE_RAW},
292 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
294 .sizeimage = 176 * 144 * 5 / 4,
295 .colorspace = V4L2_COLORSPACE_SRGB,
297 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
299 .sizeimage = 320 * 240 * 5 / 4,
300 .colorspace = V4L2_COLORSPACE_SRGB,
301 .priv = 0 | MODE_REDUCED_SIF},
302 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
304 .sizeimage = 352 * 288 * 5 / 4,
305 .colorspace = V4L2_COLORSPACE_SRGB,
309 static const __u8 initHv7131d[] = {
310 0x04, 0x03, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
312 0x00, 0x00, 0x00, 0x02, 0x02, 0x00,
313 0x28, 0x1e, 0x60, 0x8e, 0x42,
314 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
316 static const __u8 hv7131d_sensor_init[][8] = {
317 {0xa0, 0x11, 0x01, 0x04, 0x00, 0x00, 0x00, 0x17},
318 {0xa0, 0x11, 0x02, 0x00, 0x00, 0x00, 0x00, 0x17},
319 {0xa0, 0x11, 0x28, 0x00, 0x00, 0x00, 0x00, 0x17},
320 {0xa0, 0x11, 0x30, 0x30, 0x00, 0x00, 0x00, 0x17}, /* reset level */
321 {0xa0, 0x11, 0x34, 0x02, 0x00, 0x00, 0x00, 0x17}, /* pixel bias volt */
324 static const __u8 initHv7131r[] = {
325 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
327 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
328 0x28, 0x1e, 0x60, 0x8a, 0x20,
329 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
331 static const __u8 hv7131r_sensor_init[][8] = {
332 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
333 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
334 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
335 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
336 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
338 static const __u8 initOv6650[] = {
339 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
340 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
341 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
342 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
344 static const __u8 ov6650_sensor_init[][8] = {
345 /* Bright, contrast, etc are set through SCBB interface.
346 * AVCAP on win2 do not send any data on this controls. */
347 /* Anyway, some registers appears to alter bright and constrat */
350 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
351 /* Set clock register 0x11 low nibble is clock divider */
352 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
353 /* Next some unknown stuff */
354 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
355 /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
356 * THIS SET GREEN SCREEN
357 * (pixels could be innverted in decode kind of "brg",
358 * but blue wont be there. Avoid this data ... */
359 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
360 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
361 {0xa0, 0x60, 0x30, 0x3d, 0x0a, 0xd8, 0xa4, 0x10},
362 /* Enable rgb brightness control */
363 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
364 /* HDG: Note windows uses the line below, which sets both register 0x60
365 and 0x61 I believe these registers of the ov6650 are identical as
366 those of the ov7630, because if this is true the windows settings
367 add a bit additional red gain and a lot additional blue gain, which
368 matches my findings that the windows settings make blue much too
369 blue and red a little too red.
370 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
371 /* Some more unknown stuff */
372 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
373 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
376 static const __u8 initOv7630[] = {
377 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
378 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
379 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
380 0x28, 0x1e, /* H & V sizes r15 .. r16 */
381 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
382 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
384 static const __u8 initOv7630_3[] = {
385 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
386 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
387 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
388 0x28, 0x1e, /* H & V sizes r15 .. r16 */
389 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
390 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
391 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
392 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
394 static const __u8 ov7630_sensor_init[][8] = {
395 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
396 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
397 /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
398 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
399 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
400 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
401 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
402 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
403 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
404 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
405 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
406 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
407 /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
408 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
409 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
410 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
411 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
412 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
413 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
416 static const __u8 ov7630_sensor_init_3[][8] = {
417 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
420 static const __u8 initPas106[] = {
421 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
423 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
424 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
425 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
427 /* compression 0x86 mckinit1 0x2b */
429 /* "Known" PAS106B registers:
431 0x03 Variable framerate bits 4-11
432 0x04 Var framerate bits 0-3, one must leave the 4 msb's at 0 !!
433 The variable framerate control must never be set lower then 300,
434 which sets the framerate at 90 / reg02, otherwise vsync is lost.
435 0x05 Shutter Time Line Offset, this can be used as an exposure control:
436 0 = use full frame time, 255 = no exposure at all
437 Note this may never be larger then "var-framerate control" / 2 - 2.
438 When var-framerate control is < 514, no exposure is reached at the max
439 allowed value for the framerate control value, rather then at 255.
440 0x06 Shutter Time Pixel Offset, like reg05 this influences exposure, but
441 only a very little bit, leave at 0xcd
442 0x07 offset sign bit (bit0 1 > negative offset)
449 0x13 Write 1 to commit settings to sensor
452 static const __u8 pas106_sensor_init[][8] = {
453 /* Pixel Clock Divider 6 */
454 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
455 /* Frame Time MSB (also seen as 0x12) */
456 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
457 /* Frame Time LSB (also seen as 0x05) */
458 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
459 /* Shutter Time Line Offset (also seen as 0x6d) */
460 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
461 /* Shutter Time Pixel Offset (also seen as 0xb1) */
462 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
463 /* Black Level Subtract Sign (also seen 0x00) */
464 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
465 /* Black Level Subtract Level (also seen 0x01) */
466 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
467 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
468 /* Color Gain B Pixel 5 a */
469 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
470 /* Color Gain G1 Pixel 1 5 */
471 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
472 /* Color Gain G2 Pixel 1 0 5 */
473 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
474 /* Color Gain R Pixel 3 1 */
475 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
476 /* Color GainH Pixel */
477 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
479 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
481 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
482 /* H&V synchro polarity */
483 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
485 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
487 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
489 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
490 /* Validate Settings */
491 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
494 static const __u8 initPas202[] = {
495 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
497 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
498 0x28, 0x1e, 0x20, 0x89, 0x20,
499 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
502 /* "Known" PAS202BCB registers:
504 0x04 Variable framerate bits 6-11 (*)
505 0x05 Var framerate bits 0-5, one must leave the 2 msb's at 0 !!
509 0x0b offset sign bit (bit0 1 > negative offset)
511 0x0e Unknown image is slightly brighter when bit 0 is 0, if reg0f is 0 too,
512 leave at 1 otherwise we get a jump in our exposure control
513 0x0f Exposure 0-255, 0 = use full frame time, 255 = no exposure at all
514 0x10 Master gain 0 - 31
515 0x11 write 1 to apply changes
516 (*) The variable framerate control must never be set lower then 500
517 which sets the framerate at 30 / reg02, otherwise vsync is lost.
519 static const __u8 pas202_sensor_init[][8] = {
520 /* Set the clock divider to 4 -> 30 / 4 = 7.5 fps, we would like
521 to set it lower, but for some reason the bridge starts missing
523 {0xa0, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x10},
524 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
525 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
526 {0xd0, 0x40, 0x0c, 0x00, 0x0c, 0x01, 0x32, 0x10},
527 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
528 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
529 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
530 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
531 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
532 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
535 static const __u8 initTas5110c[] = {
536 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
538 0x00, 0x00, 0x00, 0x45, 0x09, 0x0a,
539 0x16, 0x12, 0x60, 0x86, 0x2b,
540 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
542 /* Same as above, except a different hstart */
543 static const __u8 initTas5110d[] = {
544 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
546 0x00, 0x00, 0x00, 0x41, 0x09, 0x0a,
547 0x16, 0x12, 0x60, 0x86, 0x2b,
548 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
550 static const __u8 tas5110_sensor_init[][8] = {
551 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
552 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
553 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
556 static const __u8 initTas5130[] = {
557 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
559 0x00, 0x00, 0x00, 0x68, 0x0c, 0x0a,
560 0x28, 0x1e, 0x60, COMP, MCK_INIT,
561 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
563 static const __u8 tas5130_sensor_init[][8] = {
564 /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
565 * shutter 0x47 short exposure? */
566 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
567 /* shutter 0x01 long exposure */
568 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
571 static struct sensor_data sensor_data[] = {
572 SENS(initHv7131d, NULL, hv7131d_sensor_init, NULL, NULL, F_GAIN, NO_BRIGHTNESS|NO_FREQ, 0),
573 SENS(initHv7131r, NULL, hv7131r_sensor_init, NULL, NULL, 0, NO_BRIGHTNESS|NO_EXPO|NO_FREQ, 0),
574 SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
575 SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
577 SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_GAIN|F_SIF, NO_FREQ,
579 SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, F_GAIN,
581 SENS(initTas5110c, NULL, tas5110_sensor_init, NULL, NULL,
582 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
583 SENS(initTas5110d, NULL, tas5110_sensor_init, NULL, NULL,
584 F_GAIN|F_SIF|F_COARSE_EXPO, NO_BRIGHTNESS|NO_FREQ, 0),
585 SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
589 /* get one byte in gspca_dev->usb_buf */
590 static void reg_r(struct gspca_dev *gspca_dev,
593 usb_control_msg(gspca_dev->dev,
594 usb_rcvctrlpipe(gspca_dev->dev, 0),
596 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
599 gspca_dev->usb_buf, 1,
603 static void reg_w(struct gspca_dev *gspca_dev,
609 if (len > USB_BUF_SZ) {
610 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
614 memcpy(gspca_dev->usb_buf, buffer, len);
615 usb_control_msg(gspca_dev->dev,
616 usb_sndctrlpipe(gspca_dev->dev, 0),
618 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
621 gspca_dev->usb_buf, len,
625 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
630 reg_w(gspca_dev, 0x08, buffer, 8);
633 reg_r(gspca_dev, 0x08);
634 if (gspca_dev->usb_buf[0] & 0x04) {
635 if (gspca_dev->usb_buf[0] & 0x08)
643 static void i2c_w_vector(struct gspca_dev *gspca_dev,
644 const __u8 buffer[][8], int len)
647 reg_w(gspca_dev, 0x08, *buffer, 8);
655 static void setbrightness(struct gspca_dev *gspca_dev)
657 struct sd *sd = (struct sd *) gspca_dev;
660 switch (sd->sensor) {
662 case SENSOR_OV7630: {
664 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
666 /* change reg 0x06 */
667 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
668 i2cOV[3] = sd->brightness;
669 if (i2c_w(gspca_dev, i2cOV) < 0)
674 case SENSOR_PAS202: {
676 {0xb0, 0x40, 0x0b, 0x00, 0x00, 0x00, 0x00, 0x16};
678 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
680 /* PAS106 uses reg 7 and 8 instead of b and c */
681 if (sd->sensor == SENSOR_PAS106) {
686 if (sd->brightness < 127) {
687 /* change reg 0x0b, signreg */
688 i2cpbright[3] = 0x01;
689 /* set reg 0x0c, offset */
690 i2cpbright[4] = 127 - sd->brightness;
692 i2cpbright[4] = sd->brightness - 127;
694 if (i2c_w(gspca_dev, i2cpbright) < 0)
696 if (i2c_w(gspca_dev, i2cpdoit) < 0)
700 case SENSOR_TAS5130CXX: {
702 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
704 value = 0xff - sd->brightness;
706 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
707 if (i2c_w(gspca_dev, i2c) < 0)
714 PDEBUG(D_ERR, "i2c error brightness");
717 static void setsensorgain(struct gspca_dev *gspca_dev)
719 struct sd *sd = (struct sd *) gspca_dev;
720 unsigned char gain = sd->gain;
722 switch (sd->sensor) {
723 case SENSOR_HV7131D: {
725 {0xc0, 0x11, 0x31, 0x00, 0x00, 0x00, 0x00, 0x17};
727 i2c[3] = 0x3f - (sd->gain / 4);
728 i2c[4] = 0x3f - (sd->gain / 4);
729 i2c[5] = 0x3f - (sd->gain / 4);
731 if (i2c_w(gspca_dev, i2c) < 0)
735 case SENSOR_TAS5110C:
736 case SENSOR_TAS5110D: {
738 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
741 if (i2c_w(gspca_dev, i2c) < 0)
749 case SENSOR_OV7630: {
750 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
752 i2c[1] = sensor_data[sd->sensor].sensor_addr;
754 if (i2c_w(gspca_dev, i2c) < 0)
759 case SENSOR_PAS202: {
761 {0xa0, 0x40, 0x10, 0x00, 0x00, 0x00, 0x00, 0x15};
762 __u8 i2cpcolorgain[] =
763 {0xc0, 0x40, 0x07, 0x00, 0x00, 0x00, 0x00, 0x15};
765 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
767 /* PAS106 uses different regs (and has split green gains) */
768 if (sd->sensor == SENSOR_PAS106) {
770 i2cpcolorgain[0] = 0xd0;
771 i2cpcolorgain[2] = 0x09;
775 i2cpgain[3] = sd->gain >> 3;
776 i2cpcolorgain[3] = sd->gain >> 4;
777 i2cpcolorgain[4] = sd->gain >> 4;
778 i2cpcolorgain[5] = sd->gain >> 4;
779 i2cpcolorgain[6] = sd->gain >> 4;
781 if (i2c_w(gspca_dev, i2cpgain) < 0)
783 if (i2c_w(gspca_dev, i2cpcolorgain) < 0)
785 if (i2c_w(gspca_dev, i2cpdoit) < 0)
792 PDEBUG(D_ERR, "i2c error gain");
795 static void setgain(struct gspca_dev *gspca_dev)
797 struct sd *sd = (struct sd *) gspca_dev;
799 __u8 buf[2] = { 0, 0 };
801 if (sensor_data[sd->sensor].flags & F_GAIN) {
802 /* Use the sensor gain to do the actual gain */
803 setsensorgain(gspca_dev);
807 gain = sd->gain >> 4;
809 /* red and blue gain */
810 buf[0] = gain << 4 | gain;
813 reg_w(gspca_dev, 0x10, buf, 2);
816 static void setexposure(struct gspca_dev *gspca_dev)
818 struct sd *sd = (struct sd *) gspca_dev;
820 switch (sd->sensor) {
821 case SENSOR_HV7131D: {
822 /* Note the datasheet wrongly says line mode exposure uses reg
823 0x26 and 0x27, testing has shown 0x25 + 0x26 */
824 __u8 i2c[] = {0xc0, 0x11, 0x25, 0x00, 0x00, 0x00, 0x00, 0x17};
825 /* The HV7131D's exposure goes from 0 - 65535, we scale our
826 exposure of 0-1023 to 0-6138. There are 2 reasons for this:
827 1) This puts our exposure knee of 200 at approx the point
828 where the framerate starts dropping
829 2) At 6138 the framerate has already dropped to 2 fps,
830 going any lower makes little sense */
831 __u16 reg = sd->exposure * 6;
834 if (i2c_w(gspca_dev, i2c) != 0)
838 case SENSOR_TAS5110C:
839 case SENSOR_TAS5110D: {
840 /* register 19's high nibble contains the sn9c10x clock divider
841 The high nibble configures the no fps according to the
842 formula: 60 / high_nibble. With a maximum of 30 fps */
843 __u8 reg = sd->exposure;
844 reg = (reg << 4) | 0x0b;
845 reg_w(gspca_dev, 0x19, ®, 1);
849 case SENSOR_OV7630: {
850 /* The ov6650 / ov7630 have 2 registers which both influence
851 exposure, register 11, whose low nibble sets the nr off fps
852 according to: fps = 30 / (low_nibble + 1)
854 The fps configures the maximum exposure setting, but it is
855 possible to use less exposure then what the fps maximum
856 allows by setting register 10. register 10 configures the
857 actual exposure as quotient of the full exposure, with 0
858 being no exposure at all (not very usefull) and reg10_max
859 being max exposure possible at that framerate.
861 The code maps our 0 - 510 ms exposure ctrl to these 2
862 registers, trying to keep fps as high as possible.
864 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
865 int reg10, reg11, reg10_max;
867 /* ov6645 datasheet says reg10_max is 9a, but that uses
868 tline * 2 * reg10 as formula for calculating texpo, the
869 ov6650 probably uses the same formula as the 7730 which uses
870 tline * 4 * reg10, which explains why the reg10max we've
871 found experimentally for the ov6650 is exactly half that of
872 the ov6645. The ov7630 datasheet says the max is 0x41. */
873 if (sd->sensor == SENSOR_OV6650) {
875 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
879 reg11 = (15 * sd->exposure + 999) / 1000;
885 /* In 640x480, if the reg11 has less than 4, the image is
886 unstable (the bridge goes into a higher compression mode
887 which we have not reverse engineered yet). */
888 if (gspca_dev->width == 640 && reg11 < 4)
891 /* frame exposure time in ms = 1000 * reg11 / 30 ->
892 reg10 = (sd->exposure / 2) * reg10_max / (1000 * reg11 / 30) */
893 reg10 = (sd->exposure * 15 * reg10_max) / (1000 * reg11);
895 /* Don't allow this to get below 10 when using autogain, the
896 steps become very large (relatively) when below 10 causing
897 the image to oscilate from much too dark, to much too bright
899 if (sd->autogain && reg10 < 10)
901 else if (reg10 > reg10_max)
904 /* Write reg 10 and reg11 low nibble */
905 i2c[1] = sensor_data[sd->sensor].sensor_addr;
909 /* If register 11 didn't change, don't change it */
910 if (sd->reg11 == reg11)
913 if (i2c_w(gspca_dev, i2c) == 0)
919 case SENSOR_PAS202: {
920 __u8 i2cpframerate[] =
921 {0xb0, 0x40, 0x04, 0x00, 0x00, 0x00, 0x00, 0x16};
923 {0xa0, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x16};
924 const __u8 i2cpdoit[] =
925 {0xa0, 0x40, 0x11, 0x01, 0x00, 0x00, 0x00, 0x16};
928 /* The exposure knee for the autogain algorithm is 200
929 (100 ms / 10 fps on other sensors), for values below this
930 use the control for setting the partial frame expose time,
931 above that use variable framerate. This way we run at max
932 framerate (640x480@7.5 fps, 320x240@10fps) until the knee
933 is reached. Using the variable framerate control above 200
934 is better then playing around with both clockdiv + partial
935 frame exposure times (like we are doing with the ov chips),
936 as that sometimes leads to jumps in the exposure control,
937 which are bad for auto exposure. */
938 if (sd->exposure < 200) {
939 i2cpexpo[3] = 255 - (sd->exposure * 255) / 200;
940 framerate_ctrl = 500;
942 /* The PAS202's exposure control goes from 0 - 4095,
943 but anything below 500 causes vsync issues, so scale
944 our 200-1023 to 500-4095 */
945 framerate_ctrl = (sd->exposure - 200) * 1000 / 229 +
949 i2cpframerate[3] = framerate_ctrl >> 6;
950 i2cpframerate[4] = framerate_ctrl & 0x3f;
951 if (i2c_w(gspca_dev, i2cpframerate) < 0)
953 if (i2c_w(gspca_dev, i2cpexpo) < 0)
955 if (i2c_w(gspca_dev, i2cpdoit) < 0)
959 case SENSOR_PAS106: {
960 __u8 i2cpframerate[] =
961 {0xb1, 0x40, 0x03, 0x00, 0x00, 0x00, 0x00, 0x14};
963 {0xa1, 0x40, 0x05, 0x00, 0x00, 0x00, 0x00, 0x14};
964 const __u8 i2cpdoit[] =
965 {0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14};
968 /* For values below 150 use partial frame exposure, above
969 that use framerate ctrl */
970 if (sd->exposure < 150) {
971 i2cpexpo[3] = 150 - sd->exposure;
972 framerate_ctrl = 300;
974 /* The PAS106's exposure control goes from 0 - 4095,
975 but anything below 300 causes vsync issues, so scale
976 our 150-1023 to 300-4095 */
977 framerate_ctrl = (sd->exposure - 150) * 1000 / 230 +
981 i2cpframerate[3] = framerate_ctrl >> 4;
982 i2cpframerate[4] = framerate_ctrl & 0x0f;
983 if (i2c_w(gspca_dev, i2cpframerate) < 0)
985 if (i2c_w(gspca_dev, i2cpexpo) < 0)
987 if (i2c_w(gspca_dev, i2cpdoit) < 0)
994 PDEBUG(D_ERR, "i2c error exposure");
997 static void setfreq(struct gspca_dev *gspca_dev)
999 struct sd *sd = (struct sd *) gspca_dev;
1001 switch (sd->sensor) {
1003 case SENSOR_OV7630: {
1004 /* Framerate adjust register for artificial light 50 hz flicker
1005 compensation, for the ov6650 this is identical to ov6630
1006 0x2b register, see ov6630 datasheet.
1007 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
1008 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
1011 /* case 0: * no filter*/
1012 /* case 2: * 60 hz */
1016 i2c[3] = (sd->sensor == SENSOR_OV6650)
1020 i2c[1] = sensor_data[sd->sensor].sensor_addr;
1021 if (i2c_w(gspca_dev, i2c) < 0)
1022 PDEBUG(D_ERR, "i2c error setfreq");
1028 #include "coarse_expo_autogain.h"
1030 static void do_autogain(struct gspca_dev *gspca_dev)
1032 int deadzone, desired_avg_lum, result;
1033 struct sd *sd = (struct sd *) gspca_dev;
1034 int avg_lum = atomic_read(&sd->avg_lum);
1036 if (avg_lum == -1 || !sd->autogain)
1039 if (sd->autogain_ignore_frames > 0) {
1040 sd->autogain_ignore_frames--;
1044 /* SIF / VGA sensors have a different autoexposure area and thus
1045 different avg_lum values for the same picture brightness */
1046 if (sensor_data[sd->sensor].flags & F_SIF) {
1048 /* SIF sensors tend to overexpose, so keep this small */
1049 desired_avg_lum = 5000;
1052 desired_avg_lum = 18000;
1055 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO)
1056 result = gspca_coarse_grained_expo_autogain(gspca_dev, avg_lum,
1057 sd->brightness * desired_avg_lum / 127,
1060 result = gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
1061 sd->brightness * desired_avg_lum / 127,
1062 deadzone, GAIN_KNEE, EXPOSURE_KNEE);
1065 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d",
1066 (int)sd->gain, (int)sd->exposure);
1067 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1071 /* this function is called at probe time */
1072 static int sd_config(struct gspca_dev *gspca_dev,
1073 const struct usb_device_id *id)
1075 struct sd *sd = (struct sd *) gspca_dev;
1078 reg_r(gspca_dev, 0x00);
1079 if (gspca_dev->usb_buf[0] != 0x10)
1082 /* copy the webcam info from the device id */
1083 sd->sensor = id->driver_info >> 8;
1084 sd->bridge = id->driver_info & 0xff;
1085 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
1087 cam = &gspca_dev->cam;
1088 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
1089 cam->cam_mode = vga_mode;
1090 cam->nmodes = ARRAY_SIZE(vga_mode);
1092 cam->cam_mode = sif_mode;
1093 cam->nmodes = ARRAY_SIZE(sif_mode);
1095 cam->npkt = 36; /* 36 packets per ISOC message */
1097 sd->brightness = BRIGHTNESS_DEF;
1098 sd->gain = GAIN_DEF;
1099 if (sensor_data[sd->sensor].flags & F_COARSE_EXPO) {
1100 sd->exposure = COARSE_EXPOSURE_DEF;
1101 gspca_dev->ctrl_dis |= (1 << EXPOSURE_IDX);
1103 sd->exposure = EXPOSURE_DEF;
1104 gspca_dev->ctrl_dis |= (1 << COARSE_EXPOSURE_IDX);
1106 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
1107 sd->autogain = 0; /* Disable do_autogain callback */
1109 sd->autogain = AUTOGAIN_DEF;
1110 sd->freq = FREQ_DEF;
1115 /* this function is called at probe and resume time */
1116 static int sd_init(struct gspca_dev *gspca_dev)
1118 const __u8 stop = 0x09; /* Disable stream turn of LED */
1120 reg_w(gspca_dev, 0x01, &stop, 1);
1125 /* -- start the camera -- */
1126 static int sd_start(struct gspca_dev *gspca_dev)
1128 struct sd *sd = (struct sd *) gspca_dev;
1129 struct cam *cam = &gspca_dev->cam;
1131 const __u8 *sn9c10x;
1134 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
1135 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
1136 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
1137 memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
1138 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
1139 /* Special cases where reg 17 and or 19 value depends on mode */
1140 switch (sd->sensor) {
1141 case SENSOR_TAS5130CXX:
1142 /* probably not mode specific at all most likely the upper
1143 nibble of 0x19 is exposure (clock divider) just as with
1144 the tas5110, we need someone to test this. */
1145 reg12_19[7] = mode ? 0x23 : 0x43;
1148 /* Disable compression when the raw bayer format has been selected */
1149 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
1150 reg12_19[6] &= ~0x80;
1152 /* Vga mode emulation on SIF sensor? */
1153 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
1154 reg12_19[0] += 16; /* 0x12: hstart adjust */
1155 reg12_19[1] += 24; /* 0x13: vstart adjust */
1156 reg12_19[3] = 320 / 16; /* 0x15: hsize */
1157 reg12_19[4] = 240 / 16; /* 0x16: vsize */
1160 /* reg 0x01 bit 2 video transfert on */
1161 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
1162 /* reg 0x17 SensorClk enable inv Clk 0x60 */
1163 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
1164 /* Set the registers from the template */
1165 reg_w(gspca_dev, 0x01, sn9c10x, l);
1167 /* Init the sensor */
1168 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
1169 sensor_data[sd->sensor].sensor_init_size);
1170 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
1171 i2c_w_vector(gspca_dev,
1172 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
1173 sensor_data[sd->sensor].sensor_bridge_init_size[
1176 /* Mode specific sensor setup */
1177 switch (sd->sensor) {
1178 case SENSOR_PAS202: {
1179 const __u8 i2cpclockdiv[] =
1180 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10};
1181 /* clockdiv from 4 to 3 (7.5 -> 10 fps) when in low res mode */
1183 i2c_w(gspca_dev, i2cpclockdiv);
1186 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
1187 reg_w(gspca_dev, 0x15, ®12_19[3], 2);
1188 /* compression register */
1189 reg_w(gspca_dev, 0x18, ®12_19[6], 1);
1191 reg_w(gspca_dev, 0x12, ®12_19[0], 1);
1193 reg_w(gspca_dev, 0x13, ®12_19[1], 1);
1194 /* reset 0x17 SensorClk enable inv Clk 0x60 */
1195 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
1196 reg_w(gspca_dev, 0x17, ®12_19[5], 1);
1197 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
1198 reg_w(gspca_dev, 0x19, ®12_19[7], 1);
1199 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
1200 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
1201 /* Enable video transfert */
1202 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
1204 reg_w(gspca_dev, 0x18, ®12_19[6], 2);
1210 setbrightness(gspca_dev);
1211 setexposure(gspca_dev);
1214 sd->frames_to_drop = 0;
1215 sd->autogain_ignore_frames = 0;
1216 sd->exp_too_high_cnt = 0;
1217 sd->exp_too_low_cnt = 0;
1218 atomic_set(&sd->avg_lum, -1);
1222 static void sd_stopN(struct gspca_dev *gspca_dev)
1227 static u8* find_sof(struct gspca_dev *gspca_dev, u8 *data, int len)
1229 struct sd *sd = (struct sd *) gspca_dev;
1230 int i, header_size = (sd->bridge == BRIDGE_103) ? 18 : 12;
1232 /* frames start with:
1233 * ff ff 00 c4 c4 96 synchro
1235 * xx (frame sequence / size / compression)
1236 * (xx) (idem - extra byte for sn9c103)
1237 * ll mm brightness sum inside auto exposure
1238 * ll mm brightness sum outside auto exposure
1239 * (xx xx xx xx xx) audio values for snc103
1241 for (i = 0; i < len; i++) {
1242 switch (sd->header_read) {
1244 if (data[i] == 0xff)
1248 if (data[i] == 0xff)
1251 sd->header_read = 0;
1254 if (data[i] == 0x00)
1256 else if (data[i] != 0xff)
1257 sd->header_read = 0;
1260 if (data[i] == 0xc4)
1262 else if (data[i] == 0xff)
1263 sd->header_read = 1;
1265 sd->header_read = 0;
1268 if (data[i] == 0xc4)
1270 else if (data[i] == 0xff)
1271 sd->header_read = 1;
1273 sd->header_read = 0;
1276 if (data[i] == 0x96)
1278 else if (data[i] == 0xff)
1279 sd->header_read = 1;
1281 sd->header_read = 0;
1284 sd->header[sd->header_read - 6] = data[i];
1286 if (sd->header_read == header_size) {
1287 sd->header_read = 0;
1288 return data + i + 1;
1295 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1296 u8 *data, /* isoc packet */
1297 int len) /* iso packet length */
1299 int fr_h_sz = 0, lum_offset = 0, len_after_sof = 0;
1300 struct sd *sd = (struct sd *) gspca_dev;
1301 struct cam *cam = &gspca_dev->cam;
1304 sof = find_sof(gspca_dev, data, len);
1306 if (sd->bridge == BRIDGE_103) {
1314 len_after_sof = len - (sof - data);
1315 len = (sof - data) - fr_h_sz;
1320 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1321 /* In raw mode we sometimes get some garbage after the frame
1324 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1326 used = gspca_dev->image_len;
1327 if (used + len > size)
1331 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
1334 int lum = sd->header[lum_offset] +
1335 (sd->header[lum_offset + 1] << 8);
1337 /* When exposure changes midway a frame we
1338 get a lum of 0 in this case drop 2 frames
1339 as the frames directly after an exposure
1340 change have an unstable image. Sometimes lum
1341 *really* is 0 (cam used in low light with
1342 low exposure setting), so do not drop frames
1343 if the previous lum was 0 too. */
1344 if (lum == 0 && sd->prev_avg_lum != 0) {
1346 sd->frames_to_drop = 2;
1347 sd->prev_avg_lum = 0;
1349 sd->prev_avg_lum = lum;
1350 atomic_set(&sd->avg_lum, lum);
1352 if (sd->frames_to_drop)
1353 sd->frames_to_drop--;
1355 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
1357 gspca_frame_add(gspca_dev, FIRST_PACKET, sof, len_after_sof);
1361 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1363 struct sd *sd = (struct sd *) gspca_dev;
1365 sd->brightness = val;
1366 if (gspca_dev->streaming)
1367 setbrightness(gspca_dev);
1371 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1373 struct sd *sd = (struct sd *) gspca_dev;
1375 *val = sd->brightness;
1379 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1381 struct sd *sd = (struct sd *) gspca_dev;
1384 if (gspca_dev->streaming)
1389 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1391 struct sd *sd = (struct sd *) gspca_dev;
1397 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1399 struct sd *sd = (struct sd *) gspca_dev;
1402 if (gspca_dev->streaming)
1403 setexposure(gspca_dev);
1407 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1409 struct sd *sd = (struct sd *) gspca_dev;
1411 *val = sd->exposure;
1415 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1417 struct sd *sd = (struct sd *) gspca_dev;
1420 sd->exp_too_high_cnt = 0;
1421 sd->exp_too_low_cnt = 0;
1423 /* when switching to autogain set defaults to make sure
1424 we are on a valid point of the autogain gain /
1425 exposure knee graph, and give this change time to
1426 take effect before doing autogain. */
1427 if (sd->autogain && !(sensor_data[sd->sensor].flags & F_COARSE_EXPO)) {
1428 sd->exposure = EXPOSURE_DEF;
1429 sd->gain = GAIN_DEF;
1430 if (gspca_dev->streaming) {
1431 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1432 setexposure(gspca_dev);
1440 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1442 struct sd *sd = (struct sd *) gspca_dev;
1444 *val = sd->autogain;
1448 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1450 struct sd *sd = (struct sd *) gspca_dev;
1453 if (gspca_dev->streaming)
1458 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1460 struct sd *sd = (struct sd *) gspca_dev;
1466 static int sd_querymenu(struct gspca_dev *gspca_dev,
1467 struct v4l2_querymenu *menu)
1470 case V4L2_CID_POWER_LINE_FREQUENCY:
1471 switch (menu->index) {
1472 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1473 strcpy((char *) menu->name, "NoFliker");
1475 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1476 strcpy((char *) menu->name, "50 Hz");
1478 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1479 strcpy((char *) menu->name, "60 Hz");
1487 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1488 static int sd_int_pkt_scan(struct gspca_dev *gspca_dev,
1489 u8 *data, /* interrupt packet data */
1490 int len) /* interrupt packet length */
1494 if (len == 1 && data[0] == 1) {
1495 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 1);
1496 input_sync(gspca_dev->input_dev);
1497 input_report_key(gspca_dev->input_dev, KEY_CAMERA, 0);
1498 input_sync(gspca_dev->input_dev);
1506 /* sub-driver description */
1507 static const struct sd_desc sd_desc = {
1508 .name = MODULE_NAME,
1510 .nctrls = ARRAY_SIZE(sd_ctrls),
1511 .config = sd_config,
1515 .pkt_scan = sd_pkt_scan,
1516 .querymenu = sd_querymenu,
1517 .dq_callback = do_autogain,
1518 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE)
1519 .int_pkt_scan = sd_int_pkt_scan,
1523 /* -- module initialisation -- */
1524 #define SB(sensor, bridge) \
1525 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1528 static const struct usb_device_id device_table[] __devinitconst = {
1529 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110C, 102)}, /* TAS5110C1B */
1530 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110C, 101)}, /* TAS5110C1B */
1531 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110D, 101)}, /* TAS5110D */
1532 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1533 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1534 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1535 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1536 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1537 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1538 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1540 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1541 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1542 {USB_DEVICE(0x0c45, 0x602a), SB(HV7131D, 102)},
1543 /* {USB_DEVICE(0x0c45, 0x602b), SB(MI0343, 102)}, */
1544 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1545 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1546 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1547 /* {USB_DEVICE(0x0c45, 0x602b), SB(MI03XX, 102)}, */ /* MI0343 MI0360 MI0330 */
1548 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1549 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1550 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1552 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1555 MODULE_DEVICE_TABLE(usb, device_table);
1557 /* -- device connect -- */
1558 static int __devinit sd_probe(struct usb_interface *intf,
1559 const struct usb_device_id *id)
1561 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1565 static struct usb_driver sd_driver = {
1566 .name = MODULE_NAME,
1567 .id_table = device_table,
1569 .disconnect = gspca_disconnect,
1571 .suspend = gspca_suspend,
1572 .resume = gspca_resume,
1576 /* -- module insert / remove -- */
1577 static int __init sd_mod_init(void)
1579 return usb_register(&sd_driver);
1581 static void __exit sd_mod_exit(void)
1583 usb_deregister(&sd_driver);
1586 module_init(sd_mod_init);
1587 module_exit(sd_mod_exit);