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 unsigned char fr_h_sz; /* size of frame header */
45 char sensor; /* Type of image sensor chip */
46 #define SENSOR_HV7131R 0
47 #define SENSOR_OV6650 1
48 #define SENSOR_OV7630 2
49 #define SENSOR_PAS106 3
50 #define SENSOR_PAS202 4
51 #define SENSOR_TAS5110 5
52 #define SENSOR_TAS5130CXX 6
58 /* flags used in the device id table */
59 #define F_GAIN 0x01 /* has gain */
60 #define F_SIF 0x02 /* sif or vga */
61 #define F_H18 0x04 /* long (18 b) or short (12 b) frame header */
64 #define COMP 0xc7 /* 0x87 //0x07 */
65 #define COMP1 0xc9 /* 0x89 //0x09 */
68 #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
72 /* We calculate the autogain at the end of the transfer of a frame, at this
73 moment a frame with the old settings is being transmitted, and a frame is
74 being captured with the old settings. So if we adjust the autogain we must
75 ignore atleast the 2 next frames for the new settings to come into effect
76 before doing any other adjustments */
77 #define AUTOGAIN_IGNORE_FRAMES 3
78 #define AUTOGAIN_DEADZONE 1000
79 #define DESIRED_AVG_LUM 7000
81 /* V4L2 controls supported by the driver */
82 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
83 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
84 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
85 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
86 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
87 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
88 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
89 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
90 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
91 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
93 static struct ctrl sd_ctrls[] = {
94 #define BRIGHTNESS_IDX 0
97 .id = V4L2_CID_BRIGHTNESS,
98 .type = V4L2_CTRL_TYPE_INTEGER,
103 #define BRIGHTNESS_DEF 127
104 .default_value = BRIGHTNESS_DEF,
106 .set = sd_setbrightness,
107 .get = sd_getbrightness,
113 .type = V4L2_CTRL_TYPE_INTEGER,
119 #define GAIN_KNEE 200
120 .default_value = GAIN_DEF,
125 #define EXPOSURE_IDX 2
128 .id = V4L2_CID_EXPOSURE,
129 .type = V4L2_CTRL_TYPE_INTEGER,
131 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
132 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
136 .default_value = EXPOSURE_DEF,
139 .set = sd_setexposure,
140 .get = sd_getexposure,
142 #define AUTOGAIN_IDX 3
145 .id = V4L2_CID_AUTOGAIN,
146 .type = V4L2_CTRL_TYPE_BOOLEAN,
147 .name = "Automatic Gain (and Exposure)",
151 #define AUTOGAIN_DEF 1
152 .default_value = AUTOGAIN_DEF,
155 .set = sd_setautogain,
156 .get = sd_getautogain,
161 .id = V4L2_CID_POWER_LINE_FREQUENCY,
162 .type = V4L2_CTRL_TYPE_MENU,
163 .name = "Light frequency filter",
165 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
168 .default_value = FREQ_DEF,
175 static struct v4l2_pix_format vga_mode[] = {
176 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
178 .sizeimage = 160 * 120,
179 .colorspace = V4L2_COLORSPACE_SRGB,
181 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
183 .sizeimage = 320 * 240,
184 .colorspace = V4L2_COLORSPACE_SRGB,
186 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
188 .sizeimage = 640 * 480,
189 .colorspace = V4L2_COLORSPACE_SRGB,
192 static struct v4l2_pix_format sif_mode[] = {
193 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
195 .sizeimage = 176 * 144,
196 .colorspace = V4L2_COLORSPACE_SRGB,
198 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
200 .sizeimage = 352 * 288,
201 .colorspace = V4L2_COLORSPACE_SRGB,
205 static const __u8 initHv7131[] = {
206 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
208 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */
209 0x28, 0x1e, 0x60, 0x8a, 0x20,
210 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
212 static const __u8 hv7131_sensor_init[][8] = {
213 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
214 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
215 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
216 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
217 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
219 static const __u8 initOv6650[] = {
220 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
221 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
222 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
223 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
225 static const __u8 ov6650_sensor_init[][8] =
227 /* Bright, contrast, etc are set througth SCBB interface.
228 * AVCAP on win2 do not send any data on this controls. */
229 /* Anyway, some registers appears to alter bright and constrat */
232 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
233 /* Set clock register 0x11 low nibble is clock divider */
234 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
235 /* Next some unknown stuff */
236 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
237 /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
238 * THIS SET GREEN SCREEN
239 * (pixels could be innverted in decode kind of "brg",
240 * but blue wont be there. Avoid this data ... */
241 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
242 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
243 {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
244 /* Enable rgb brightness control */
245 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
246 /* HDG: Note windows uses the line below, which sets both register 0x60
247 and 0x61 I believe these registers of the ov6650 are identical as
248 those of the ov7630, because if this is true the windows settings
249 add a bit additional red gain and a lot additional blue gain, which
250 matches my findings that the windows settings make blue much too
251 blue and red a little too red.
252 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
253 /* Some more unknown stuff */
254 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
255 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
258 static const __u8 initOv7630[] = {
259 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
260 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
261 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
262 0x28, 0x1e, /* H & V sizes r15 .. r16 */
263 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */
264 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
266 static const __u8 initOv7630_3[] = {
267 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
268 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
269 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
270 0x28, 0x1e, /* H & V sizes r15 .. r16 */
271 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
272 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
273 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
274 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
276 static const __u8 ov7630_sensor_init[][8] = {
277 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
278 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
279 /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
280 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
281 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
282 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
283 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
284 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
285 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
286 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
287 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
288 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
289 /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
290 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
291 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
292 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
293 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
294 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
295 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
298 static const __u8 initPas106[] = {
299 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
301 0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
302 0x16, 0x12, 0x28, COMP1, MCK_INIT1,
303 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
305 /* compression 0x86 mckinit1 0x2b */
306 static const __u8 pas106_data[][2] = {
307 {0x02, 0x04}, /* Pixel Clock Divider 6 */
308 {0x03, 0x13}, /* Frame Time MSB */
309 /* {0x03, 0x12}, * Frame Time MSB */
310 {0x04, 0x06}, /* Frame Time LSB */
311 /* {0x04, 0x05}, * Frame Time LSB */
312 {0x05, 0x65}, /* Shutter Time Line Offset */
313 /* {0x05, 0x6d}, * Shutter Time Line Offset */
314 /* {0x06, 0xb1}, * Shutter Time Pixel Offset */
315 {0x06, 0xcd}, /* Shutter Time Pixel Offset */
316 {0x07, 0xc1}, /* Black Level Subtract Sign */
317 /* {0x07, 0x00}, * Black Level Subtract Sign */
318 {0x08, 0x06}, /* Black Level Subtract Level */
319 {0x08, 0x06}, /* Black Level Subtract Level */
320 /* {0x08, 0x01}, * Black Level Subtract Level */
321 {0x09, 0x05}, /* Color Gain B Pixel 5 a */
322 {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */
323 {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */
324 {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */
325 {0x0d, 0x00}, /* Color GainH Pixel */
326 {0x0e, 0x0e}, /* Global Gain */
327 {0x0f, 0x00}, /* Contrast */
328 {0x10, 0x06}, /* H&V synchro polarity */
329 {0x11, 0x06}, /* ?default */
330 {0x12, 0x06}, /* DAC scale */
331 {0x14, 0x02}, /* ?default */
332 {0x13, 0x01}, /* Validate Settings */
334 static const __u8 initPas202[] = {
335 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
337 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */
338 0x28, 0x1e, 0x28, 0x89, 0x30,
339 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
341 static const __u8 pas202_sensor_init[][8] = {
342 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
343 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
344 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
345 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
346 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
347 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
348 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
349 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
350 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
351 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
352 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
353 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
355 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
356 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
357 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
358 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
359 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
360 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
361 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
362 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
365 static const __u8 initTas5110[] = {
366 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
368 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */
369 0x16, 0x12, 0x60, 0x86, 0x2b,
370 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
372 static const __u8 tas5110_sensor_init[][8] = {
373 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
374 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
375 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
378 static const __u8 initTas5130[] = {
379 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
381 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
382 0x28, 0x1e, 0x60, COMP, MCK_INIT,
383 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
385 static const __u8 tas5130_sensor_init[][8] = {
386 /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
387 * shutter 0x47 short exposure? */
388 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
389 /* shutter 0x01 long exposure */
390 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
393 /* get one byte in gspca_dev->usb_buf */
394 static void reg_r(struct gspca_dev *gspca_dev,
397 usb_control_msg(gspca_dev->dev,
398 usb_rcvctrlpipe(gspca_dev->dev, 0),
400 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
403 gspca_dev->usb_buf, 1,
407 static void reg_w(struct gspca_dev *gspca_dev,
413 if (len > sizeof gspca_dev->usb_buf) {
414 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
418 memcpy(gspca_dev->usb_buf, buffer, len);
419 usb_control_msg(gspca_dev->dev,
420 usb_sndctrlpipe(gspca_dev->dev, 0),
422 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
425 gspca_dev->usb_buf, len,
429 static void reg_w_big(struct gspca_dev *gspca_dev,
436 tmpbuf = kmalloc(len, GFP_KERNEL);
437 memcpy(tmpbuf, buffer, len);
438 usb_control_msg(gspca_dev->dev,
439 usb_sndctrlpipe(gspca_dev->dev, 0),
441 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
449 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
454 reg_w(gspca_dev, 0x08, buffer, 8);
457 reg_r(gspca_dev, 0x08);
458 if (gspca_dev->usb_buf[0] & 0x04) {
459 if (gspca_dev->usb_buf[0] & 0x08)
467 static void i2c_w_vector(struct gspca_dev *gspca_dev,
468 const __u8 buffer[][8], int len)
471 reg_w(gspca_dev, 0x08, *buffer, 8);
479 static void setbrightness(struct gspca_dev *gspca_dev)
481 struct sd *sd = (struct sd *) gspca_dev;
484 switch (sd->sensor) {
486 case SENSOR_OV7630: {
488 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
490 /* change reg 0x06 */
491 i2cOV[1] = sd->sensor_addr;
492 i2cOV[3] = sd->brightness;
493 if (i2c_w(gspca_dev, i2cOV) < 0)
497 case SENSOR_PAS106: {
499 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
501 i2c1[3] = sd->brightness >> 3;
503 if (i2c_w(gspca_dev, i2c1) < 0)
507 if (i2c_w(gspca_dev, i2c1) < 0)
511 case SENSOR_PAS202: {
512 /* __u8 i2cpexpo1[] =
513 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
515 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
517 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
518 static __u8 i2cpdoit[] =
519 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
521 /* change reg 0x10 */
522 i2cpexpo[4] = 0xff - sd->brightness;
523 /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
525 /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
527 if (i2c_w(gspca_dev, i2cpexpo) < 0)
529 if (i2c_w(gspca_dev, i2cpdoit) < 0)
531 i2cp202[3] = sd->brightness >> 3;
532 if (i2c_w(gspca_dev, i2cp202) < 0)
534 if (i2c_w(gspca_dev, i2cpdoit) < 0)
538 case SENSOR_TAS5130CXX: {
540 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
542 value = 0xff - sd->brightness;
544 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
545 if (i2c_w(gspca_dev, i2c) < 0)
552 PDEBUG(D_ERR, "i2c error brightness");
555 static void setsensorgain(struct gspca_dev *gspca_dev)
557 struct sd *sd = (struct sd *) gspca_dev;
558 unsigned char gain = sd->gain;
560 switch (sd->sensor) {
562 case SENSOR_TAS5110: {
564 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
567 if (i2c_w(gspca_dev, i2c) < 0)
575 case SENSOR_OV7630: {
576 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
578 i2c[1] = sd->sensor_addr;
580 if (i2c_w(gspca_dev, i2c) < 0)
587 PDEBUG(D_ERR, "i2c error gain");
590 static void setgain(struct gspca_dev *gspca_dev)
592 struct sd *sd = (struct sd *) gspca_dev;
596 gain = sd->gain >> 4;
598 /* red and blue gain */
599 rgb_value = gain << 4 | gain;
600 reg_w(gspca_dev, 0x10, &rgb_value, 1);
603 reg_w(gspca_dev, 0x11, &rgb_value, 1);
605 if (sd->sensor_has_gain)
606 setsensorgain(gspca_dev);
609 static void setexposure(struct gspca_dev *gspca_dev)
611 struct sd *sd = (struct sd *) gspca_dev;
613 switch (sd->sensor) {
614 case SENSOR_TAS5110: {
617 /* register 19's high nibble contains the sn9c10x clock divider
618 The high nibble configures the no fps according to the
619 formula: 60 / high_nibble. With a maximum of 30 fps */
620 reg = 120 * sd->exposure / 1000;
625 reg = (reg << 4) | 0x0b;
626 reg_w(gspca_dev, 0x19, ®, 1);
630 case SENSOR_OV7630: {
631 /* The ov6650 / ov7630 have 2 registers which both influence
632 exposure, register 11, whose low nibble sets the nr off fps
633 according to: fps = 30 / (low_nibble + 1)
635 The fps configures the maximum exposure setting, but it is
636 possible to use less exposure then what the fps maximum
637 allows by setting register 10. register 10 configures the
638 actual exposure as quotient of the full exposure, with 0
639 being no exposure at all (not very usefull) and reg10_max
640 being max exposure possible at that framerate.
642 The code maps our 0 - 510 ms exposure ctrl to these 2
643 registers, trying to keep fps as high as possible.
645 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
646 int reg10, reg11, reg10_max;
648 /* ov6645 datasheet says reg10_max is 9a, but that uses
649 tline * 2 * reg10 as formula for calculating texpo, the
650 ov6650 probably uses the same formula as the 7730 which uses
651 tline * 4 * reg10, which explains why the reg10max we've
652 found experimentally for the ov6650 is exactly half that of
653 the ov6645. The ov7630 datasheet says the max is 0x41. */
654 if (sd->sensor == SENSOR_OV6650) {
656 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
660 reg11 = (60 * sd->exposure + 999) / 1000;
666 /* In 640x480, if the reg11 has less than 3, the image is
667 unstable (not enough bandwidth). */
668 if (gspca_dev->width == 640 && reg11 < 3)
671 /* frame exposure time in ms = 1000 * reg11 / 30 ->
672 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
673 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
675 /* Don't allow this to get below 10 when using autogain, the
676 steps become very large (relatively) when below 10 causing
677 the image to oscilate from much too dark, to much too bright
679 if (sd->autogain && reg10 < 10)
681 else if (reg10 > reg10_max)
684 /* Write reg 10 and reg11 low nibble */
685 i2c[1] = sd->sensor_addr;
689 /* If register 11 didn't change, don't change it */
690 if (sd->reg11 == reg11 )
693 if (i2c_w(gspca_dev, i2c) == 0)
696 PDEBUG(D_ERR, "i2c error exposure");
702 static void setfreq(struct gspca_dev *gspca_dev)
704 struct sd *sd = (struct sd *) gspca_dev;
706 switch (sd->sensor) {
708 case SENSOR_OV7630: {
709 /* Framerate adjust register for artificial light 50 hz flicker
710 compensation, for the ov6650 this is identical to ov6630
711 0x2b register, see ov6630 datasheet.
712 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
713 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
716 /* case 0: * no filter*/
717 /* case 2: * 60 hz */
721 i2c[3] = (sd->sensor == SENSOR_OV6650)
725 i2c[1] = sd->sensor_addr;
726 if (i2c_w(gspca_dev, i2c) < 0)
727 PDEBUG(D_ERR, "i2c error setfreq");
733 static void do_autogain(struct gspca_dev *gspca_dev)
735 struct sd *sd = (struct sd *) gspca_dev;
736 int avg_lum = atomic_read(&sd->avg_lum);
741 if (sd->autogain_ignore_frames > 0)
742 sd->autogain_ignore_frames--;
743 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
744 sd->brightness * DESIRED_AVG_LUM / 127,
745 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
746 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
747 (int)sd->gain, (int)sd->exposure);
748 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
752 /* this function is called at probe time */
753 static int sd_config(struct gspca_dev *gspca_dev,
754 const struct usb_device_id *id)
756 struct sd *sd = (struct sd *) gspca_dev;
759 const __u8 stop = 0x09; /* Disable stream turn of LED */
761 reg_r(gspca_dev, 0x00);
762 if (gspca_dev->usb_buf[0] != 0x10)
765 /* copy the webcam info from the device id */
766 sd->sensor = (id->driver_info >> 24) & 0xff;
767 if (id->driver_info & (F_GAIN << 16))
768 sd->sensor_has_gain = 1;
769 if (id->driver_info & (F_SIF << 16))
771 if (id->driver_info & (F_H18 << 16))
772 sd->fr_h_sz = 18; /* size of frame header */
775 gspca_dev->ctrl_dis = (id->driver_info >> 8) & 0xff;
776 sd->sensor_addr = id->driver_info & 0xff;
778 cam = &gspca_dev->cam;
781 cam->cam_mode = vga_mode;
782 cam->nmodes = ARRAY_SIZE(vga_mode);
784 cam->cam_mode = sif_mode;
785 cam->nmodes = ARRAY_SIZE(sif_mode);
787 sd->brightness = BRIGHTNESS_DEF;
789 sd->exposure = EXPOSURE_DEF;
790 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
791 sd->autogain = 0; /* Disable do_autogain callback */
793 sd->autogain = AUTOGAIN_DEF;
796 /* Disable stream turn of LED */
797 reg_w(gspca_dev, 0x01, &stop, 1);
802 /* this function is called at probe and resume time */
803 static int sd_init(struct gspca_dev *gspca_dev)
808 static void pas106_i2cinit(struct gspca_dev *gspca_dev)
812 __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
814 i = ARRAY_SIZE(pas106_data);
815 data = pas106_data[0];
817 memcpy(&i2c1[2], data, 2);
818 /* copy 2 bytes from the template */
819 if (i2c_w(gspca_dev, i2c1) < 0)
820 PDEBUG(D_ERR, "i2c error pas106");
825 /* -- start the camera -- */
826 static void sd_start(struct gspca_dev *gspca_dev)
828 struct sd *sd = (struct sd *) gspca_dev;
833 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
834 switch (sd->sensor) {
836 sn9c10x = initHv7131;
838 reg17_19[1] = (mode << 4) | 0x8a;
842 sn9c10x = initOv6650;
844 reg17_19[1] = (mode << 4) | 0x8b;
848 if (sd->fr_h_sz == 18) { /* SN9C103 */
849 sn9c10x = initOv7630_3;
850 l = sizeof initOv7630_3;
852 sn9c10x = initOv7630;
854 reg17_19[1] = (mode << 4) | COMP2;
855 reg17_19[2] = MCK_INIT1;
858 sn9c10x = initPas106;
859 reg17_19[0] = 0x24; /* 0x28 */
860 reg17_19[1] = (mode << 4) | COMP1;
861 reg17_19[2] = MCK_INIT1;
864 sn9c10x = initPas202;
865 reg17_19[0] = mode ? 0x24 : 0x20;
866 reg17_19[1] = (mode << 4) | 0x89;
870 sn9c10x = initTas5110;
872 reg17_19[1] = (mode << 4) | 0x86;
873 reg17_19[2] = 0x2b; /* 0xf3; */
876 /* case SENSOR_TAS5130CXX: */
877 sn9c10x = initTas5130;
879 reg17_19[1] = (mode << 4) | COMP;
880 reg17_19[2] = mode ? 0x23 : 0x43;
884 /* reg 0x01 bit 2 video transfert on */
885 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
886 /* reg 0x17 SensorClk enable inv Clk 0x60 */
887 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
888 /* Set the registers from the template */
889 reg_w_big(gspca_dev, 0x01, sn9c10x, l);
890 switch (sd->sensor) {
892 i2c_w_vector(gspca_dev, hv7131_sensor_init,
893 sizeof hv7131_sensor_init);
896 i2c_w_vector(gspca_dev, ov6650_sensor_init,
897 sizeof ov6650_sensor_init);
900 i2c_w_vector(gspca_dev, ov7630_sensor_init,
901 sizeof ov7630_sensor_init);
902 if (sd->fr_h_sz == 18) { /* SN9C103 */
903 const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
905 i2c_w(gspca_dev, i2c);
909 pas106_i2cinit(gspca_dev);
912 i2c_w_vector(gspca_dev, pas202_sensor_init,
913 sizeof pas202_sensor_init);
916 i2c_w_vector(gspca_dev, tas5110_sensor_init,
917 sizeof tas5110_sensor_init);
920 /* case SENSOR_TAS5130CXX: */
921 i2c_w_vector(gspca_dev, tas5130_sensor_init,
922 sizeof tas5130_sensor_init);
925 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
926 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
927 /* compression register */
928 reg_w(gspca_dev, 0x18, ®17_19[1], 1);
930 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
932 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
933 /* reset 0x17 SensorClk enable inv Clk 0x60 */
934 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
935 reg_w(gspca_dev, 0x17, ®17_19[0], 1);
936 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
937 reg_w(gspca_dev, 0x19, ®17_19[2], 1);
938 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
939 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
940 /* Enable video transfert */
941 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
943 reg_w(gspca_dev, 0x18, ®17_19[1], 2);
949 setbrightness(gspca_dev);
950 setexposure(gspca_dev);
953 sd->frames_to_drop = 0;
954 sd->autogain_ignore_frames = 0;
955 atomic_set(&sd->avg_lum, -1);
958 static void sd_stopN(struct gspca_dev *gspca_dev)
962 ByteSend = 0x09; /* 0X00 */
963 reg_w(gspca_dev, 0x01, &ByteSend, 1);
966 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
967 struct gspca_frame *frame, /* target */
968 unsigned char *data, /* isoc packet */
969 int len) /* iso packet length */
972 struct sd *sd = (struct sd *) gspca_dev;
974 /* frames start with:
975 * ff ff 00 c4 c4 96 synchro
977 * xx (frame sequence / size / compression)
978 * (xx) (idem - extra byte for sn9c103)
979 * ll mm brightness sum inside auto exposure
980 * ll mm brightness sum outside auto exposure
981 * (xx xx xx xx xx) audio values for snc103
983 if (len > 6 && len < 24) {
984 for (i = 0; i < len - 6; i++) {
985 if (data[0 + i] == 0xff
986 && data[1 + i] == 0xff
987 && data[2 + i] == 0x00
988 && data[3 + i] == 0xc4
989 && data[4 + i] == 0xc4
990 && data[5 + i] == 0x96) { /* start of frame */
992 int pkt_type = LAST_PACKET;
994 if (len - i < sd->fr_h_sz) {
995 PDEBUG(D_STREAM, "packet too short to"
996 " get avg brightness");
997 } else if (sd->fr_h_sz == 12) {
998 lum = data[i + 8] + (data[i + 9] << 8);
1001 (data[i + 10] << 8);
1005 sd->frames_to_drop = 2;
1007 atomic_set(&sd->avg_lum, lum);
1009 if (sd->frames_to_drop) {
1010 sd->frames_to_drop--;
1011 pkt_type = DISCARD_PACKET;
1014 frame = gspca_frame_add(gspca_dev, pkt_type,
1016 data += i + sd->fr_h_sz;
1017 len -= i + sd->fr_h_sz;
1018 gspca_frame_add(gspca_dev, FIRST_PACKET,
1024 gspca_frame_add(gspca_dev, INTER_PACKET,
1028 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1030 struct sd *sd = (struct sd *) gspca_dev;
1032 sd->brightness = val;
1033 if (gspca_dev->streaming)
1034 setbrightness(gspca_dev);
1038 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1040 struct sd *sd = (struct sd *) gspca_dev;
1042 *val = sd->brightness;
1046 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1048 struct sd *sd = (struct sd *) gspca_dev;
1051 if (gspca_dev->streaming)
1056 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1058 struct sd *sd = (struct sd *) gspca_dev;
1064 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1066 struct sd *sd = (struct sd *) gspca_dev;
1069 if (gspca_dev->streaming)
1070 setexposure(gspca_dev);
1074 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1076 struct sd *sd = (struct sd *) gspca_dev;
1078 *val = sd->exposure;
1082 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1084 struct sd *sd = (struct sd *) gspca_dev;
1087 /* when switching to autogain set defaults to make sure
1088 we are on a valid point of the autogain gain /
1089 exposure knee graph, and give this change time to
1090 take effect before doing autogain. */
1092 sd->exposure = EXPOSURE_DEF;
1093 sd->gain = GAIN_DEF;
1094 if (gspca_dev->streaming) {
1095 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1096 setexposure(gspca_dev);
1104 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1106 struct sd *sd = (struct sd *) gspca_dev;
1108 *val = sd->autogain;
1112 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1114 struct sd *sd = (struct sd *) gspca_dev;
1117 if (gspca_dev->streaming)
1122 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1124 struct sd *sd = (struct sd *) gspca_dev;
1130 static int sd_querymenu(struct gspca_dev *gspca_dev,
1131 struct v4l2_querymenu *menu)
1134 case V4L2_CID_POWER_LINE_FREQUENCY:
1135 switch (menu->index) {
1136 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1137 strcpy((char *) menu->name, "NoFliker");
1139 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1140 strcpy((char *) menu->name, "50 Hz");
1142 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1143 strcpy((char *) menu->name, "60 Hz");
1151 /* sub-driver description */
1152 static const struct sd_desc sd_desc = {
1153 .name = MODULE_NAME,
1155 .nctrls = ARRAY_SIZE(sd_ctrls),
1156 .config = sd_config,
1160 .pkt_scan = sd_pkt_scan,
1161 .querymenu = sd_querymenu,
1162 .dq_callback = do_autogain,
1165 /* -- module initialisation -- */
1166 #define SFCI(sensor, flags, disable_ctrls, i2c_addr) \
1167 .driver_info = (SENSOR_ ## sensor << 24) \
1169 | ((disable_ctrls) << 8) \
1171 #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
1172 #define NO_FREQ (1 << FREQ_IDX)
1173 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
1175 static __devinitdata struct usb_device_id device_table[] = {
1176 #ifndef CONFIG_USB_SN9C102
1177 {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */
1178 SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)},
1179 {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */
1180 SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)},
1181 {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */
1182 SFCI(TAS5110, F_GAIN|F_SIF, NO_BRIGHTNESS|NO_FREQ, 0)},
1183 {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
1184 SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)},
1185 {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
1186 SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)},
1188 {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */
1189 SFCI(OV6650, F_GAIN|F_SIF, 0, 0x60)},
1190 #ifndef CONFIG_USB_SN9C102
1191 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */
1192 SFCI(OV7630, F_GAIN, 0, 0x21)},
1193 {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */
1194 SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)},
1195 {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */
1196 SFCI(TAS5130CXX, 0, NO_EXPO|NO_FREQ, 0)},
1197 {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
1198 SFCI(PAS202, 0, NO_EXPO|NO_FREQ, 0)},
1199 {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
1200 SFCI(PAS106, F_SIF, NO_EXPO|NO_FREQ, 0)},
1201 {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
1202 SFCI(OV7630, F_GAIN, 0, 0x21)},
1203 {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
1204 SFCI(HV7131R, 0, NO_EXPO|NO_FREQ, 0)},
1205 {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
1206 SFCI(OV7630, F_GAIN, 0, 0x21)},
1207 {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
1208 SFCI(PAS202, F_H18, NO_EXPO|NO_FREQ, 0)},
1209 {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
1210 SFCI(OV7630, F_GAIN|F_H18, 0, 0x21)},
1214 MODULE_DEVICE_TABLE(usb, device_table);
1216 /* -- device connect -- */
1217 static int sd_probe(struct usb_interface *intf,
1218 const struct usb_device_id *id)
1220 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1224 static struct usb_driver sd_driver = {
1225 .name = MODULE_NAME,
1226 .id_table = device_table,
1228 .disconnect = gspca_disconnect,
1230 .suspend = gspca_suspend,
1231 .resume = gspca_resume,
1235 /* -- module insert / remove -- */
1236 static int __init sd_mod_init(void)
1238 if (usb_register(&sd_driver) < 0)
1240 PDEBUG(D_PROBE, "registered");
1243 static void __exit sd_mod_exit(void)
1245 usb_deregister(&sd_driver);
1246 PDEBUG(D_PROBE, "deregistered");
1249 module_init(sd_mod_init);
1250 module_exit(sd_mod_exit);