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 */
35 struct sd_desc sd_desc; /* our nctrls differ dependend upon the
36 sensor, so we use a per cam copy */
40 unsigned char exposure;
41 unsigned char brightness;
42 unsigned char autogain;
43 unsigned char autogain_ignore_frames;
44 unsigned char frames_to_drop;
45 unsigned char freq; /* light freq filter setting */
47 unsigned char fr_h_sz; /* size of frame header */
48 char sensor; /* Type of image sensor chip */
49 #define SENSOR_HV7131R 0
50 #define SENSOR_OV6650 1
51 #define SENSOR_OV7630 2
52 #define SENSOR_PAS106 3
53 #define SENSOR_PAS202 4
54 #define SENSOR_TAS5110 5
55 #define SENSOR_TAS5130CXX 6
62 #define COMP 0xc7 /* 0x87 //0x07 */
63 #define COMP1 0xc9 /* 0x89 //0x09 */
66 #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
70 /* We calculate the autogain at the end of the transfer of a frame, at this
71 moment a frame with the old settings is being transmitted, and a frame is
72 being captured with the old settings. So if we adjust the autogain we must
73 ignore atleast the 2 next frames for the new settings to come into effect
74 before doing any other adjustments */
75 #define AUTOGAIN_IGNORE_FRAMES 3
76 #define AUTOGAIN_DEADZONE 1000
77 #define DESIRED_AVG_LUM 7000
79 /* V4L2 controls supported by the driver */
80 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
81 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
82 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
91 static struct ctrl sd_ctrls[] = {
94 .id = V4L2_CID_BRIGHTNESS,
95 .type = V4L2_CTRL_TYPE_INTEGER,
100 #define BRIGHTNESS_DEF 127
101 .default_value = BRIGHTNESS_DEF,
103 .set = sd_setbrightness,
104 .get = sd_getbrightness,
109 .type = V4L2_CTRL_TYPE_INTEGER,
115 #define GAIN_KNEE 200
116 .default_value = GAIN_DEF,
123 .id = V4L2_CID_EXPOSURE,
124 .type = V4L2_CTRL_TYPE_INTEGER,
126 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
127 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
131 .default_value = EXPOSURE_DEF,
134 .set = sd_setexposure,
135 .get = sd_getexposure,
139 .id = V4L2_CID_AUTOGAIN,
140 .type = V4L2_CTRL_TYPE_BOOLEAN,
141 .name = "Automatic Gain (and Exposure)",
145 #define AUTOGAIN_DEF 1
146 .default_value = AUTOGAIN_DEF,
149 .set = sd_setautogain,
150 .get = sd_getautogain,
154 .id = V4L2_CID_POWER_LINE_FREQUENCY,
155 .type = V4L2_CTRL_TYPE_MENU,
156 .name = "Light frequency filter",
158 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
161 .default_value = FREQ_DEF,
168 static struct v4l2_pix_format vga_mode[] = {
169 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
171 .sizeimage = 160 * 120,
172 .colorspace = V4L2_COLORSPACE_SRGB,
174 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
176 .sizeimage = 320 * 240,
177 .colorspace = V4L2_COLORSPACE_SRGB,
179 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
181 .sizeimage = 640 * 480,
182 .colorspace = V4L2_COLORSPACE_SRGB,
185 static struct v4l2_pix_format sif_mode[] = {
186 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
188 .sizeimage = 176 * 144,
189 .colorspace = V4L2_COLORSPACE_SRGB,
191 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
193 .sizeimage = 352 * 288,
194 .colorspace = V4L2_COLORSPACE_SRGB,
198 static const __u8 initHv7131[] = {
199 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
201 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */
202 0x28, 0x1e, 0x60, 0x8a, 0x20,
203 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
205 static const __u8 hv7131_sensor_init[][8] = {
206 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
207 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
208 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
209 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
210 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
212 static const __u8 initOv6650[] = {
213 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
214 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
215 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
216 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
218 static const __u8 ov6650_sensor_init[][8] =
220 /* Bright, contrast, etc are set througth SCBB interface.
221 * AVCAP on win2 do not send any data on this controls. */
222 /* Anyway, some registers appears to alter bright and constrat */
225 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
226 /* Set clock register 0x11 low nibble is clock divider */
227 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
228 /* Next some unknown stuff */
229 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
230 /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
231 * THIS SET GREEN SCREEN
232 * (pixels could be innverted in decode kind of "brg",
233 * but blue wont be there. Avoid this data ... */
234 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
235 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
236 {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
237 /* Enable rgb brightness control */
238 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
239 /* HDG: Note windows uses the line below, which sets both register 0x60
240 and 0x61 I believe these registers of the ov6650 are identical as
241 those of the ov7630, because if this is true the windows settings
242 add a bit additional red gain and a lot additional blue gain, which
243 matches my findings that the windows settings make blue much too
244 blue and red a little too red.
245 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
246 /* Some more unknown stuff */
247 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
248 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
251 static const __u8 initOv7630[] = {
252 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
253 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
254 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
255 0x28, 0x1e, /* H & V sizes r15 .. r16 */
256 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */
257 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
259 static const __u8 initOv7630_3[] = {
260 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
261 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
262 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
263 0x28, 0x1e, /* H & V sizes r15 .. r16 */
264 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
265 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
266 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
267 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
269 static const __u8 ov7630_sensor_init[][8] = {
270 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
271 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
272 /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
273 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
274 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
275 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
276 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
277 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
278 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
279 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
280 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
281 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
282 /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
283 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
284 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
285 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
286 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
287 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
288 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
291 static const __u8 initPas106[] = {
292 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
294 0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
295 0x16, 0x12, 0x28, COMP1, MCK_INIT1,
296 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
298 /* compression 0x86 mckinit1 0x2b */
299 static const __u8 pas106_data[][2] = {
300 {0x02, 0x04}, /* Pixel Clock Divider 6 */
301 {0x03, 0x13}, /* Frame Time MSB */
302 /* {0x03, 0x12}, * Frame Time MSB */
303 {0x04, 0x06}, /* Frame Time LSB */
304 /* {0x04, 0x05}, * Frame Time LSB */
305 {0x05, 0x65}, /* Shutter Time Line Offset */
306 /* {0x05, 0x6d}, * Shutter Time Line Offset */
307 /* {0x06, 0xb1}, * Shutter Time Pixel Offset */
308 {0x06, 0xcd}, /* Shutter Time Pixel Offset */
309 {0x07, 0xc1}, /* Black Level Subtract Sign */
310 /* {0x07, 0x00}, * Black Level Subtract Sign */
311 {0x08, 0x06}, /* Black Level Subtract Level */
312 {0x08, 0x06}, /* Black Level Subtract Level */
313 /* {0x08, 0x01}, * Black Level Subtract Level */
314 {0x09, 0x05}, /* Color Gain B Pixel 5 a */
315 {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */
316 {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */
317 {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */
318 {0x0d, 0x00}, /* Color GainH Pixel */
319 {0x0e, 0x0e}, /* Global Gain */
320 {0x0f, 0x00}, /* Contrast */
321 {0x10, 0x06}, /* H&V synchro polarity */
322 {0x11, 0x06}, /* ?default */
323 {0x12, 0x06}, /* DAC scale */
324 {0x14, 0x02}, /* ?default */
325 {0x13, 0x01}, /* Validate Settings */
327 static const __u8 initPas202[] = {
328 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
330 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */
331 0x28, 0x1e, 0x28, 0x89, 0x30,
332 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
334 static const __u8 pas202_sensor_init[][8] = {
335 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
336 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
337 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
338 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
339 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
340 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
341 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
342 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
343 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
344 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
345 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
346 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
348 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
349 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
350 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
351 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
352 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
353 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
354 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
355 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
358 static const __u8 initTas5110[] = {
359 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
361 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */
362 0x16, 0x12, 0x60, 0x86, 0x2b,
363 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
365 static const __u8 tas5110_sensor_init[][8] = {
366 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
367 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
368 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
371 static const __u8 initTas5130[] = {
372 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
374 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
375 0x28, 0x1e, 0x60, COMP, MCK_INIT,
376 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
378 static const __u8 tas5130_sensor_init[][8] = {
379 /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
380 * shutter 0x47 short exposure? */
381 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
382 /* shutter 0x01 long exposure */
383 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
386 /* get one byte in gspca_dev->usb_buf */
387 static void reg_r(struct gspca_dev *gspca_dev,
390 usb_control_msg(gspca_dev->dev,
391 usb_rcvctrlpipe(gspca_dev->dev, 0),
393 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
396 gspca_dev->usb_buf, 1,
400 static void reg_w(struct gspca_dev *gspca_dev,
405 #ifdef CONFIG_VIDEO_ADV_DEBUG
406 if (len > sizeof gspca_dev->usb_buf) {
407 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
411 memcpy(gspca_dev->usb_buf, buffer, len);
412 usb_control_msg(gspca_dev->dev,
413 usb_sndctrlpipe(gspca_dev->dev, 0),
415 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
418 gspca_dev->usb_buf, len,
422 static void reg_w_big(struct gspca_dev *gspca_dev,
429 tmpbuf = kmalloc(len, GFP_KERNEL);
430 memcpy(tmpbuf, buffer, len);
431 usb_control_msg(gspca_dev->dev,
432 usb_sndctrlpipe(gspca_dev->dev, 0),
434 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
442 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
447 reg_w(gspca_dev, 0x08, buffer, 8);
450 reg_r(gspca_dev, 0x08);
451 if (gspca_dev->usb_buf[0] & 0x04) {
452 if (gspca_dev->usb_buf[0] & 0x08)
460 static void i2c_w_vector(struct gspca_dev *gspca_dev,
461 const __u8 buffer[][8], int len)
464 reg_w(gspca_dev, 0x08, *buffer, 8);
472 static void setbrightness(struct gspca_dev *gspca_dev)
474 struct sd *sd = (struct sd *) gspca_dev;
477 switch (sd->sensor) {
479 case SENSOR_OV7630: {
481 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
483 /* change reg 0x06 */
484 i2cOV[1] = sd->sensor_addr;
485 i2cOV[3] = sd->brightness;
486 if (i2c_w(gspca_dev, i2cOV) < 0)
490 case SENSOR_PAS106: {
492 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
494 i2c1[3] = sd->brightness >> 3;
496 if (i2c_w(gspca_dev, i2c1) < 0)
500 if (i2c_w(gspca_dev, i2c1) < 0)
504 case SENSOR_PAS202: {
505 /* __u8 i2cpexpo1[] =
506 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
508 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
510 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
511 static __u8 i2cpdoit[] =
512 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
514 /* change reg 0x10 */
515 i2cpexpo[4] = 0xff - sd->brightness;
516 /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
518 /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
520 if (i2c_w(gspca_dev, i2cpexpo) < 0)
522 if (i2c_w(gspca_dev, i2cpdoit) < 0)
524 i2cp202[3] = sd->brightness >> 3;
525 if (i2c_w(gspca_dev, i2cp202) < 0)
527 if (i2c_w(gspca_dev, i2cpdoit) < 0)
531 case SENSOR_TAS5130CXX: {
533 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
535 value = 0xff - sd->brightness;
537 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
538 if (i2c_w(gspca_dev, i2c) < 0)
543 /* FIXME figure out howto control brightness on TAS5110 */
548 PDEBUG(D_ERR, "i2c error brightness");
551 static void setsensorgain(struct gspca_dev *gspca_dev)
553 struct sd *sd = (struct sd *) gspca_dev;
554 unsigned char gain = sd->gain;
556 switch (sd->sensor) {
558 case SENSOR_TAS5110: {
560 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
563 if (i2c_w(gspca_dev, i2c) < 0)
571 case SENSOR_OV7630: {
572 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
574 i2c[1] = sd->sensor_addr;
576 if (i2c_w(gspca_dev, i2c) < 0)
583 PDEBUG(D_ERR, "i2c error gain");
586 static void setgain(struct gspca_dev *gspca_dev)
588 struct sd *sd = (struct sd *) gspca_dev;
592 gain = sd->gain >> 4;
594 /* red and blue gain */
595 rgb_value = gain << 4 | gain;
596 reg_w(gspca_dev, 0x10, &rgb_value, 1);
599 reg_w(gspca_dev, 0x11, &rgb_value, 1);
601 if (sd->sensor_has_gain)
602 setsensorgain(gspca_dev);
605 static void setexposure(struct gspca_dev *gspca_dev)
607 struct sd *sd = (struct sd *) gspca_dev;
609 switch (sd->sensor) {
610 case SENSOR_TAS5110: {
613 /* register 19's high nibble contains the sn9c10x clock divider
614 The high nibble configures the no fps according to the
615 formula: 60 / high_nibble. With a maximum of 30 fps */
616 reg = 120 * sd->exposure / 1000;
621 reg = (reg << 4) | 0x0b;
622 reg_w(gspca_dev, 0x19, ®, 1);
626 case SENSOR_OV7630: {
627 /* The ov6650 / ov7630 have 2 registers which both influence
628 exposure, register 11, whose low nibble sets the nr off fps
629 according to: fps = 30 / (low_nibble + 1)
631 The fps configures the maximum exposure setting, but it is
632 possible to use less exposure then what the fps maximum
633 allows by setting register 10. register 10 configures the
634 actual exposure as quotient of the full exposure, with 0
635 being no exposure at all (not very usefull) and reg10_max
636 being max exposure possible at that framerate.
638 The code maps our 0 - 510 ms exposure ctrl to these 2
639 registers, trying to keep fps as high as possible.
641 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
642 int reg10, reg11, reg10_max;
644 /* ov6645 datasheet says reg10_max is 9a, but that uses
645 tline * 2 * reg10 as formula for calculating texpo, the
646 ov6650 probably uses the same formula as the 7730 which uses
647 tline * 4 * reg10, which explains why the reg10max we've
648 found experimentally for the ov6650 is exactly half that of
649 the ov6645. The ov7630 datasheet says the max is 0x41. */
650 if (sd->sensor == SENSOR_OV6650) {
652 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
656 reg11 = (60 * sd->exposure + 999) / 1000;
662 /* frame exposure time in ms = 1000 * reg11 / 30 ->
663 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
664 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
666 /* Don't allow this to get below 10 when using autogain, the
667 steps become very large (relatively) when below 10 causing
668 the image to oscilate from much too dark, to much too bright
670 if (sd->autogain && reg10 < 10)
672 else if (reg10 > reg10_max)
675 /* In 640x480, if the reg11 has less than 3, the image is
676 unstable (not enough bandwidth). */
677 if (gspca_dev->width == 640 && reg11 < 3)
680 /* Write reg 10 and reg11 low nibble */
681 i2c[1] = sd->sensor_addr;
685 /* If register 11 didn't change, don't change it */
686 if (sd->reg11 == reg11 )
689 if (i2c_w(gspca_dev, i2c) == 0)
692 PDEBUG(D_ERR, "i2c error exposure");
698 static void setfreq(struct gspca_dev *gspca_dev)
700 struct sd *sd = (struct sd *) gspca_dev;
702 switch (sd->sensor) {
704 case SENSOR_OV7630: {
705 /* Framerate adjust register for artificial light 50 hz flicker
706 compensation, for the ov6650 this is identical to ov6630
707 0x2b register, see ov6630 datasheet.
708 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
709 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
712 /* case 0: * no filter*/
713 /* case 2: * 60 hz */
717 i2c[3] = (sd->sensor == SENSOR_OV6650)
721 i2c[1] = sd->sensor_addr;
722 if (i2c_w(gspca_dev, i2c) < 0)
723 PDEBUG(D_ERR, "i2c error setfreq");
729 static void do_autogain(struct gspca_dev *gspca_dev)
731 struct sd *sd = (struct sd *) gspca_dev;
732 int avg_lum = atomic_read(&sd->avg_lum);
737 if (sd->autogain_ignore_frames > 0)
738 sd->autogain_ignore_frames--;
739 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
740 sd->brightness * DESIRED_AVG_LUM / 127,
741 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
742 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
743 (int)sd->gain, (int)sd->exposure);
744 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
748 /* this function is called at probe time */
749 static int sd_config(struct gspca_dev *gspca_dev,
750 const struct usb_device_id *id)
752 struct sd *sd = (struct sd *) gspca_dev;
757 /* nctrls depends upon the sensor, so we use a per cam copy */
758 memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
759 gspca_dev->sd_desc = &sd->sd_desc;
761 sd->fr_h_sz = 12; /* default size of the frame header */
762 sd->sd_desc.nctrls = 2; /* default nb of ctrls */
763 product = id->idProduct;
764 /* switch (id->idVendor) { */
765 /* case 0x0c45: * Sonix */
767 case 0x6001: /* SN9C102 */
768 case 0x6005: /* SN9C101 */
769 case 0x6007: /* SN9C101 */
770 sd->sensor = SENSOR_TAS5110;
771 sd->sensor_has_gain = 1;
772 sd->sd_desc.nctrls = 4;
773 sd->sd_desc.dq_callback = do_autogain;
776 case 0x6009: /* SN9C101 */
777 case 0x600d: /* SN9C101 */
778 case 0x6029: /* SN9C101 */
779 sd->sensor = SENSOR_PAS106;
782 case 0x6011: /* SN9C101 - SN9C101G */
783 sd->sensor = SENSOR_OV6650;
784 sd->sensor_has_gain = 1;
785 sd->sensor_addr = 0x60;
786 sd->sd_desc.nctrls = 5;
787 sd->sd_desc.dq_callback = do_autogain;
790 case 0x6019: /* SN9C101 */
791 case 0x602c: /* SN9C102 */
792 case 0x602e: /* SN9C102 */
793 case 0x60b0: /* SN9C103 */
794 sd->sensor = SENSOR_OV7630;
795 sd->sensor_addr = 0x21;
796 sd->sensor_has_gain = 1;
797 sd->sd_desc.nctrls = 5;
798 sd->sd_desc.dq_callback = do_autogain;
799 if (product == 0x60b0)
800 sd->fr_h_sz = 18; /* size of frame header */
802 case 0x6024: /* SN9C102 */
803 case 0x6025: /* SN9C102 */
804 sd->sensor = SENSOR_TAS5130CXX;
806 case 0x6028: /* SN9C102 */
807 sd->sensor = SENSOR_PAS202;
809 case 0x602d: /* SN9C102 */
810 sd->sensor = SENSOR_HV7131R;
812 case 0x60af: /* SN9C103 */
813 sd->sensor = SENSOR_PAS202;
814 sd->fr_h_sz = 18; /* size of frame header (?) */
820 cam = &gspca_dev->cam;
821 cam->dev_name = (char *) id->driver_info;
824 cam->cam_mode = vga_mode;
825 cam->nmodes = ARRAY_SIZE(vga_mode);
827 cam->cam_mode = sif_mode;
828 cam->nmodes = ARRAY_SIZE(sif_mode);
830 sd->brightness = BRIGHTNESS_DEF;
832 sd->exposure = EXPOSURE_DEF;
833 sd->autogain = AUTOGAIN_DEF;
839 /* this function is called at open time */
840 static int sd_open(struct gspca_dev *gspca_dev)
842 reg_r(gspca_dev, 0x00);
843 if (gspca_dev->usb_buf[0] != 0x10)
848 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
852 __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
854 i = ARRAY_SIZE(pas106_data);
855 data = pas106_data[0];
857 memcpy(&i2c1[2], data, 2);
858 /* copy 2 bytes from the template */
859 if (i2c_w(gspca_dev, i2c1) < 0)
860 PDEBUG(D_ERR, "i2c error pas106");
865 /* -- start the camera -- */
866 static void sd_start(struct gspca_dev *gspca_dev)
868 struct sd *sd = (struct sd *) gspca_dev;
874 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
875 switch (sd->sensor) {
877 sn9c10x = initHv7131;
879 reg17_19[1] = (mode << 4) | 0x8a;
883 sn9c10x = initOv6650;
885 reg17_19[1] = (mode << 4) | 0x8b;
889 if (sd->fr_h_sz == 18) { /* SN9C103 */
890 sn9c10x = initOv7630_3;
891 l = sizeof initOv7630_3;
893 sn9c10x = initOv7630;
895 reg17_19[1] = (mode << 4) | COMP2;
896 reg17_19[2] = MCK_INIT1;
899 sn9c10x = initPas106;
900 reg17_19[0] = 0x24; /* 0x28 */
901 reg17_19[1] = (mode << 4) | COMP1;
902 reg17_19[2] = MCK_INIT1;
905 sn9c10x = initPas202;
906 reg17_19[0] = mode ? 0x24 : 0x20;
907 reg17_19[1] = (mode << 4) | 0x89;
911 sn9c10x = initTas5110;
913 reg17_19[1] = (mode << 4) | 0x86;
914 reg17_19[2] = 0x2b; /* 0xf3; */
917 /* case SENSOR_TAS5130CXX: */
918 sn9c10x = initTas5130;
920 reg17_19[1] = (mode << 4) | COMP;
921 reg17_19[2] = mode ? 0x23 : 0x43;
925 /* Special case for SN9C101/2 with OV 7630 */
926 /* HDG: is this really necessary we overwrite the values immediately
927 afterwards with the ones from the template ?? */
928 if (sd->sensor == SENSOR_OV7630 && sd->fr_h_sz == 12) {
933 reg17 = sn9c10x[0x17 - 1];
936 /* reg 0x01 bit 2 video transfert on */
937 reg_w(gspca_dev, 0x01, ®01, 1);
938 /* reg 0x17 SensorClk enable inv Clk 0x60 */
939 reg_w(gspca_dev, 0x17, ®17, 1);
940 /* Set the registers from the template */
941 reg_w_big(gspca_dev, 0x01, sn9c10x, l);
942 switch (sd->sensor) {
944 i2c_w_vector(gspca_dev, hv7131_sensor_init,
945 sizeof hv7131_sensor_init);
948 i2c_w_vector(gspca_dev, ov6650_sensor_init,
949 sizeof ov6650_sensor_init);
952 i2c_w_vector(gspca_dev, ov7630_sensor_init,
953 sizeof ov7630_sensor_init);
954 if (sd->fr_h_sz == 18) { /* SN9C103 */
955 const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
957 i2c_w(gspca_dev, i2c);
961 pas106_i2cinit(gspca_dev);
964 i2c_w_vector(gspca_dev, pas202_sensor_init,
965 sizeof pas202_sensor_init);
968 i2c_w_vector(gspca_dev, tas5110_sensor_init,
969 sizeof tas5110_sensor_init);
972 /* case SENSOR_TAS5130CXX: */
973 i2c_w_vector(gspca_dev, tas5130_sensor_init,
974 sizeof tas5130_sensor_init);
977 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
978 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
979 /* compression register */
980 reg_w(gspca_dev, 0x18, ®17_19[1], 1);
982 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
984 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
985 /* reset 0x17 SensorClk enable inv Clk 0x60 */
986 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
987 reg_w(gspca_dev, 0x17, ®17_19[0], 1);
988 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
989 reg_w(gspca_dev, 0x19, ®17_19[2], 1);
990 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
991 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
992 /* Enable video transfert */
993 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
995 reg_w(gspca_dev, 0x18, ®17_19[1], 2);
1001 setbrightness(gspca_dev);
1002 setexposure(gspca_dev);
1005 sd->frames_to_drop = 0;
1006 sd->autogain_ignore_frames = 0;
1007 atomic_set(&sd->avg_lum, -1);
1010 static void sd_stopN(struct gspca_dev *gspca_dev)
1014 ByteSend = 0x09; /* 0X00 */
1015 reg_w(gspca_dev, 0x01, &ByteSend, 1);
1018 static void sd_stop0(struct gspca_dev *gspca_dev)
1022 static void sd_close(struct gspca_dev *gspca_dev)
1026 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
1027 struct gspca_frame *frame, /* target */
1028 unsigned char *data, /* isoc packet */
1029 int len) /* iso packet length */
1032 struct sd *sd = (struct sd *) gspca_dev;
1034 /* frames start with:
1035 * ff ff 00 c4 c4 96 synchro
1037 * xx (frame sequence / size / compression)
1038 * (xx) (idem - extra byte for sn9c103)
1039 * ll mm brightness sum inside auto exposure
1040 * ll mm brightness sum outside auto exposure
1041 * (xx xx xx xx xx) audio values for snc103
1043 if (len > 6 && len < 24) {
1044 for (i = 0; i < len - 6; i++) {
1045 if (data[0 + i] == 0xff
1046 && data[1 + i] == 0xff
1047 && data[2 + i] == 0x00
1048 && data[3 + i] == 0xc4
1049 && data[4 + i] == 0xc4
1050 && data[5 + i] == 0x96) { /* start of frame */
1052 int pkt_type = LAST_PACKET;
1054 if (len - i < sd->fr_h_sz) {
1055 PDEBUG(D_STREAM, "packet too short to"
1056 " get avg brightness");
1057 } else if (sd->fr_h_sz == 12) {
1058 lum = data[i + 8] + (data[i + 9] << 8);
1061 (data[i + 10] << 8);
1065 sd->frames_to_drop = 2;
1067 atomic_set(&sd->avg_lum, lum);
1069 if (sd->frames_to_drop) {
1070 sd->frames_to_drop--;
1071 pkt_type = DISCARD_PACKET;
1074 frame = gspca_frame_add(gspca_dev, pkt_type,
1076 data += i + sd->fr_h_sz;
1077 len -= i + sd->fr_h_sz;
1078 gspca_frame_add(gspca_dev, FIRST_PACKET,
1084 gspca_frame_add(gspca_dev, INTER_PACKET,
1088 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1090 struct sd *sd = (struct sd *) gspca_dev;
1092 sd->brightness = val;
1093 if (gspca_dev->streaming)
1094 setbrightness(gspca_dev);
1098 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1100 struct sd *sd = (struct sd *) gspca_dev;
1102 *val = sd->brightness;
1106 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1108 struct sd *sd = (struct sd *) gspca_dev;
1111 if (gspca_dev->streaming)
1116 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1118 struct sd *sd = (struct sd *) gspca_dev;
1124 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1126 struct sd *sd = (struct sd *) gspca_dev;
1129 if (gspca_dev->streaming)
1130 setexposure(gspca_dev);
1134 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1136 struct sd *sd = (struct sd *) gspca_dev;
1138 *val = sd->exposure;
1142 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1144 struct sd *sd = (struct sd *) gspca_dev;
1147 /* when switching to autogain set defaults to make sure
1148 we are on a valid point of the autogain gain /
1149 exposure knee graph, and give this change time to
1150 take effect before doing autogain. */
1152 sd->exposure = EXPOSURE_DEF;
1153 sd->gain = GAIN_DEF;
1154 if (gspca_dev->streaming) {
1155 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1156 setexposure(gspca_dev);
1164 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1166 struct sd *sd = (struct sd *) gspca_dev;
1168 *val = sd->autogain;
1172 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1174 struct sd *sd = (struct sd *) gspca_dev;
1177 if (gspca_dev->streaming)
1182 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1184 struct sd *sd = (struct sd *) gspca_dev;
1190 static int sd_querymenu(struct gspca_dev *gspca_dev,
1191 struct v4l2_querymenu *menu)
1194 case V4L2_CID_POWER_LINE_FREQUENCY:
1195 switch (menu->index) {
1196 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1197 strcpy((char *) menu->name, "NoFliker");
1199 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1200 strcpy((char *) menu->name, "50 Hz");
1202 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1203 strcpy((char *) menu->name, "60 Hz");
1211 /* sub-driver description */
1212 static const struct sd_desc sd_desc = {
1213 .name = MODULE_NAME,
1215 .nctrls = ARRAY_SIZE(sd_ctrls),
1216 .config = sd_config,
1222 .pkt_scan = sd_pkt_scan,
1223 .querymenu = sd_querymenu,
1226 /* -- module initialisation -- */
1227 #define DVNM(name) .driver_info = (kernel_ulong_t) name
1228 static __devinitdata struct usb_device_id device_table[] = {
1229 #ifndef CONFIG_USB_SN9C102
1230 {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
1231 {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
1232 {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
1233 {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
1234 {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
1236 {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
1237 #ifndef CONFIG_USB_SN9C102
1238 {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
1239 {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
1240 {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
1241 {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
1242 {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
1243 {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
1244 {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
1245 {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
1246 {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
1247 {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
1251 MODULE_DEVICE_TABLE(usb, device_table);
1253 /* -- device connect -- */
1254 static int sd_probe(struct usb_interface *intf,
1255 const struct usb_device_id *id)
1257 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1261 static struct usb_driver sd_driver = {
1262 .name = MODULE_NAME,
1263 .id_table = device_table,
1265 .disconnect = gspca_disconnect,
1268 /* -- module insert / remove -- */
1269 static int __init sd_mod_init(void)
1271 if (usb_register(&sd_driver) < 0)
1273 PDEBUG(D_PROBE, "registered");
1276 static void __exit sd_mod_exit(void)
1278 usb_deregister(&sd_driver);
1279 PDEBUG(D_PROBE, "deregistered");
1282 module_init(sd_mod_init);
1283 module_exit(sd_mod_exit);