V4L/DVB (9079): gspca: Return error code from stream start functions.
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / media / video / gspca / sonixb.c
blob6c69bc7778fc2f9cf322d0282a3151a91bcc9f82
1 /*
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
11 * any later version.
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:
25 Reg Use
26 0x10 high nibble red gain low nibble blue gain
27 0x11 low nibble green gain
28 0x12 hstart
29 0x13 vstart
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 "gspca.h"
47 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
48 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
49 MODULE_LICENSE("GPL");
51 /* specific webcam descriptor */
52 struct sd {
53 struct gspca_dev gspca_dev; /* !! must be the first item */
54 atomic_t avg_lum;
55 int prev_avg_lum;
57 unsigned char gain;
58 unsigned char exposure;
59 unsigned char brightness;
60 unsigned char autogain;
61 unsigned char autogain_ignore_frames;
62 unsigned char frames_to_drop;
63 unsigned char freq; /* light freq filter setting */
65 __u8 bridge; /* Type of bridge */
66 #define BRIDGE_101 0
67 #define BRIDGE_102 0 /* We make no difference between 101 and 102 */
68 #define BRIDGE_103 1
70 __u8 sensor; /* Type of image sensor chip */
71 #define SENSOR_HV7131R 0
72 #define SENSOR_OV6650 1
73 #define SENSOR_OV7630 2
74 #define SENSOR_PAS106 3
75 #define SENSOR_PAS202 4
76 #define SENSOR_TAS5110 5
77 #define SENSOR_TAS5130CXX 6
78 __u8 reg11;
81 typedef const __u8 sensor_init_t[8];
83 struct sensor_data {
84 const __u8 *bridge_init[2];
85 int bridge_init_size[2];
86 sensor_init_t *sensor_init;
87 int sensor_init_size;
88 sensor_init_t *sensor_bridge_init[2];
89 int sensor_bridge_init_size[2];
90 int flags;
91 unsigned ctrl_dis;
92 __u8 sensor_addr;
95 /* sensor_data flags */
96 #define F_GAIN 0x01 /* has gain */
97 #define F_SIF 0x02 /* sif or vga */
99 /* priv field of struct v4l2_pix_format flags (do not use low nibble!) */
100 #define MODE_RAW 0x10 /* raw bayer mode */
101 #define MODE_REDUCED_SIF 0x20 /* vga mode (320x240 / 160x120) on sif cam */
103 /* ctrl_dis helper macros */
104 #define NO_EXPO ((1 << EXPOSURE_IDX) | (1 << AUTOGAIN_IDX))
105 #define NO_FREQ (1 << FREQ_IDX)
106 #define NO_BRIGHTNESS (1 << BRIGHTNESS_IDX)
108 #define COMP2 0x8f
109 #define COMP 0xc7 /* 0x87 //0x07 */
110 #define COMP1 0xc9 /* 0x89 //0x09 */
112 #define MCK_INIT 0x63
113 #define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
115 #define SYS_CLK 0x04
117 #define SENS(bridge_1, bridge_3, sensor, sensor_1, \
118 sensor_3, _flags, _ctrl_dis, _sensor_addr) \
120 .bridge_init = { bridge_1, bridge_3 }, \
121 .bridge_init_size = { sizeof(bridge_1), sizeof(bridge_3) }, \
122 .sensor_init = sensor, \
123 .sensor_init_size = sizeof(sensor), \
124 .sensor_bridge_init = { sensor_1, sensor_3,}, \
125 .sensor_bridge_init_size = { sizeof(sensor_1), sizeof(sensor_3)}, \
126 .flags = _flags, .ctrl_dis = _ctrl_dis, .sensor_addr = _sensor_addr \
129 /* We calculate the autogain at the end of the transfer of a frame, at this
130 moment a frame with the old settings is being transmitted, and a frame is
131 being captured with the old settings. So if we adjust the autogain we must
132 ignore atleast the 2 next frames for the new settings to come into effect
133 before doing any other adjustments */
134 #define AUTOGAIN_IGNORE_FRAMES 3
135 #define AUTOGAIN_DEADZONE 1000
136 #define DESIRED_AVG_LUM 7000
138 /* V4L2 controls supported by the driver */
139 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
140 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
141 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
142 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
143 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
144 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
145 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
146 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
147 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
148 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
150 static struct ctrl sd_ctrls[] = {
151 #define BRIGHTNESS_IDX 0
154 .id = V4L2_CID_BRIGHTNESS,
155 .type = V4L2_CTRL_TYPE_INTEGER,
156 .name = "Brightness",
157 .minimum = 0,
158 .maximum = 255,
159 .step = 1,
160 #define BRIGHTNESS_DEF 127
161 .default_value = BRIGHTNESS_DEF,
163 .set = sd_setbrightness,
164 .get = sd_getbrightness,
166 #define GAIN_IDX 1
169 .id = V4L2_CID_GAIN,
170 .type = V4L2_CTRL_TYPE_INTEGER,
171 .name = "Gain",
172 .minimum = 0,
173 .maximum = 255,
174 .step = 1,
175 #define GAIN_DEF 127
176 #define GAIN_KNEE 200
177 .default_value = GAIN_DEF,
179 .set = sd_setgain,
180 .get = sd_getgain,
182 #define EXPOSURE_IDX 2
185 .id = V4L2_CID_EXPOSURE,
186 .type = V4L2_CTRL_TYPE_INTEGER,
187 .name = "Exposure",
188 #define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
189 #define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
190 .minimum = 0,
191 .maximum = 255,
192 .step = 1,
193 .default_value = EXPOSURE_DEF,
194 .flags = 0,
196 .set = sd_setexposure,
197 .get = sd_getexposure,
199 #define AUTOGAIN_IDX 3
202 .id = V4L2_CID_AUTOGAIN,
203 .type = V4L2_CTRL_TYPE_BOOLEAN,
204 .name = "Automatic Gain (and Exposure)",
205 .minimum = 0,
206 .maximum = 1,
207 .step = 1,
208 #define AUTOGAIN_DEF 1
209 .default_value = AUTOGAIN_DEF,
210 .flags = 0,
212 .set = sd_setautogain,
213 .get = sd_getautogain,
215 #define FREQ_IDX 4
218 .id = V4L2_CID_POWER_LINE_FREQUENCY,
219 .type = V4L2_CTRL_TYPE_MENU,
220 .name = "Light frequency filter",
221 .minimum = 0,
222 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
223 .step = 1,
224 #define FREQ_DEF 1
225 .default_value = FREQ_DEF,
227 .set = sd_setfreq,
228 .get = sd_getfreq,
232 static struct v4l2_pix_format vga_mode[] = {
233 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
234 .bytesperline = 160,
235 .sizeimage = 160 * 120,
236 .colorspace = V4L2_COLORSPACE_SRGB,
237 .priv = 2 | MODE_RAW},
238 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
239 .bytesperline = 160,
240 .sizeimage = 160 * 120 * 5 / 4,
241 .colorspace = V4L2_COLORSPACE_SRGB,
242 .priv = 2},
243 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
244 .bytesperline = 320,
245 .sizeimage = 320 * 240 * 5 / 4,
246 .colorspace = V4L2_COLORSPACE_SRGB,
247 .priv = 1},
248 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
249 .bytesperline = 640,
250 .sizeimage = 640 * 480 * 5 / 4,
251 .colorspace = V4L2_COLORSPACE_SRGB,
252 .priv = 0},
254 static struct v4l2_pix_format sif_mode[] = {
255 {160, 120, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
256 .bytesperline = 160,
257 .sizeimage = 160 * 120,
258 .colorspace = V4L2_COLORSPACE_SRGB,
259 .priv = 1 | MODE_RAW | MODE_REDUCED_SIF},
260 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
261 .bytesperline = 160,
262 .sizeimage = 160 * 120 * 5 / 4,
263 .colorspace = V4L2_COLORSPACE_SRGB,
264 .priv = 1 | MODE_REDUCED_SIF},
265 {176, 144, V4L2_PIX_FMT_SBGGR8, V4L2_FIELD_NONE,
266 .bytesperline = 176,
267 .sizeimage = 176 * 144,
268 .colorspace = V4L2_COLORSPACE_SRGB,
269 .priv = 1 | MODE_RAW},
270 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
271 .bytesperline = 176,
272 .sizeimage = 176 * 144 * 5 / 4,
273 .colorspace = V4L2_COLORSPACE_SRGB,
274 .priv = 1},
275 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
276 .bytesperline = 320,
277 .sizeimage = 320 * 240 * 5 / 4,
278 .colorspace = V4L2_COLORSPACE_SRGB,
279 .priv = 0 | MODE_REDUCED_SIF},
280 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
281 .bytesperline = 352,
282 .sizeimage = 352 * 288 * 5 / 4,
283 .colorspace = V4L2_COLORSPACE_SRGB,
284 .priv = 0},
287 static const __u8 initHv7131[] = {
288 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
289 0x00, 0x00,
290 0x00, 0x00, 0x00, 0x02, 0x01, 0x00,
291 0x28, 0x1e, 0x60, 0x8a, 0x20,
292 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
294 static const __u8 hv7131_sensor_init[][8] = {
295 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
296 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
297 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
298 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
299 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
301 static const __u8 initOv6650[] = {
302 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
303 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
304 0x00, 0x01, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x8b,
305 0x10, 0x1d, 0x10, 0x02, 0x02, 0x09, 0x07
307 static const __u8 ov6650_sensor_init[][8] =
309 /* Bright, contrast, etc are set througth SCBB interface.
310 * AVCAP on win2 do not send any data on this controls. */
311 /* Anyway, some registers appears to alter bright and constrat */
313 /* Reset sensor */
314 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
315 /* Set clock register 0x11 low nibble is clock divider */
316 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
317 /* Next some unknown stuff */
318 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
319 /* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
320 * THIS SET GREEN SCREEN
321 * (pixels could be innverted in decode kind of "brg",
322 * but blue wont be there. Avoid this data ... */
323 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
324 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
325 {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
326 /* Enable rgb brightness control */
327 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
328 /* HDG: Note windows uses the line below, which sets both register 0x60
329 and 0x61 I believe these registers of the ov6650 are identical as
330 those of the ov7630, because if this is true the windows settings
331 add a bit additional red gain and a lot additional blue gain, which
332 matches my findings that the windows settings make blue much too
333 blue and red a little too red.
334 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
335 /* Some more unknown stuff */
336 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
337 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
340 static const __u8 initOv7630[] = {
341 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
342 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
343 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
344 0x28, 0x1e, /* H & V sizes r15 .. r16 */
345 0x68, COMP2, MCK_INIT1, /* r17 .. r19 */
346 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
348 static const __u8 initOv7630_3[] = {
349 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
350 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
351 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
352 0x28, 0x1e, /* H & V sizes r15 .. r16 */
353 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
354 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
355 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
356 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
358 static const __u8 ov7630_sensor_init[][8] = {
359 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
360 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
361 /* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
362 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
363 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
364 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
365 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
366 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
367 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
368 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
369 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
370 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
371 /* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
372 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
373 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
374 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
375 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
376 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
377 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
380 static const __u8 ov7630_sensor_init_3[][8] = {
381 {0xa0, 0x21, 0x13, 0x80, 0x00, 0x00, 0x00, 0x10},
384 static const __u8 initPas106[] = {
385 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
386 0x00, 0x00,
387 0x00, 0x00, 0x00, 0x04, 0x01, 0x00,
388 0x16, 0x12, 0x24, COMP1, MCK_INIT1,
389 0x18, 0x10, 0x02, 0x02, 0x09, 0x07
391 /* compression 0x86 mckinit1 0x2b */
392 static const __u8 pas106_sensor_init[][8] = {
393 /* Pixel Clock Divider 6 */
394 { 0xa1, 0x40, 0x02, 0x04, 0x00, 0x00, 0x00, 0x14 },
395 /* Frame Time MSB (also seen as 0x12) */
396 { 0xa1, 0x40, 0x03, 0x13, 0x00, 0x00, 0x00, 0x14 },
397 /* Frame Time LSB (also seen as 0x05) */
398 { 0xa1, 0x40, 0x04, 0x06, 0x00, 0x00, 0x00, 0x14 },
399 /* Shutter Time Line Offset (also seen as 0x6d) */
400 { 0xa1, 0x40, 0x05, 0x65, 0x00, 0x00, 0x00, 0x14 },
401 /* Shutter Time Pixel Offset (also seen as 0xb1) */
402 { 0xa1, 0x40, 0x06, 0xcd, 0x00, 0x00, 0x00, 0x14 },
403 /* Black Level Subtract Sign (also seen 0x00) */
404 { 0xa1, 0x40, 0x07, 0xc1, 0x00, 0x00, 0x00, 0x14 },
405 /* Black Level Subtract Level (also seen 0x01) */
406 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
407 { 0xa1, 0x40, 0x08, 0x06, 0x00, 0x00, 0x00, 0x14 },
408 /* Color Gain B Pixel 5 a */
409 { 0xa1, 0x40, 0x09, 0x05, 0x00, 0x00, 0x00, 0x14 },
410 /* Color Gain G1 Pixel 1 5 */
411 { 0xa1, 0x40, 0x0a, 0x04, 0x00, 0x00, 0x00, 0x14 },
412 /* Color Gain G2 Pixel 1 0 5 */
413 { 0xa1, 0x40, 0x0b, 0x04, 0x00, 0x00, 0x00, 0x14 },
414 /* Color Gain R Pixel 3 1 */
415 { 0xa1, 0x40, 0x0c, 0x05, 0x00, 0x00, 0x00, 0x14 },
416 /* Color GainH Pixel */
417 { 0xa1, 0x40, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x14 },
418 /* Global Gain */
419 { 0xa1, 0x40, 0x0e, 0x0e, 0x00, 0x00, 0x00, 0x14 },
420 /* Contrast */
421 { 0xa1, 0x40, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x14 },
422 /* H&V synchro polarity */
423 { 0xa1, 0x40, 0x10, 0x06, 0x00, 0x00, 0x00, 0x14 },
424 /* ?default */
425 { 0xa1, 0x40, 0x11, 0x06, 0x00, 0x00, 0x00, 0x14 },
426 /* DAC scale */
427 { 0xa1, 0x40, 0x12, 0x06, 0x00, 0x00, 0x00, 0x14 },
428 /* ?default */
429 { 0xa1, 0x40, 0x14, 0x02, 0x00, 0x00, 0x00, 0x14 },
430 /* Validate Settings */
431 { 0xa1, 0x40, 0x13, 0x01, 0x00, 0x00, 0x00, 0x14 },
434 static const __u8 initPas202[] = {
435 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
436 0x00, 0x00,
437 0x00, 0x00, 0x00, 0x06, 0x03, 0x0a,
438 0x28, 0x1e, 0x28, 0x89, 0x20,
439 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
441 static const __u8 pas202_sensor_init[][8] = {
442 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
443 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
444 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
445 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
446 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
447 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
448 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
449 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
450 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
451 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
452 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
453 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
455 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
456 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
457 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
458 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
459 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
460 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
461 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
462 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
465 static const __u8 initTas5110[] = {
466 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
467 0x00, 0x00,
468 0x00, 0x01, 0x00, 0x45, 0x09, 0x0a,
469 0x16, 0x12, 0x60, 0x86, 0x2b,
470 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
472 static const __u8 tas5110_sensor_init[][8] = {
473 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
474 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
475 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
478 static const __u8 initTas5130[] = {
479 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
480 0x00, 0x00,
481 0x00, 0x01, 0x00, 0x68, 0x0c, 0x0a,
482 0x28, 0x1e, 0x60, COMP, MCK_INIT,
483 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
485 static const __u8 tas5130_sensor_init[][8] = {
486 /* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
487 * shutter 0x47 short exposure? */
488 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
489 /* shutter 0x01 long exposure */
490 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
493 static struct sensor_data sensor_data[] = {
494 SENS(initHv7131, NULL, hv7131_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ, 0),
495 SENS(initOv6650, NULL, ov6650_sensor_init, NULL, NULL, F_GAIN|F_SIF, 0, 0x60),
496 SENS(initOv7630, initOv7630_3, ov7630_sensor_init, NULL, ov7630_sensor_init_3,
497 F_GAIN, 0, 0x21),
498 SENS(initPas106, NULL, pas106_sensor_init, NULL, NULL, F_SIF, NO_EXPO|NO_FREQ,
500 SENS(initPas202, initPas202, pas202_sensor_init, NULL, NULL, 0,
501 NO_EXPO|NO_FREQ, 0),
502 SENS(initTas5110, NULL, tas5110_sensor_init, NULL, NULL, F_GAIN|F_SIF,
503 NO_BRIGHTNESS|NO_FREQ, 0),
504 SENS(initTas5130, NULL, tas5130_sensor_init, NULL, NULL, 0, NO_EXPO|NO_FREQ,
508 /* get one byte in gspca_dev->usb_buf */
509 static void reg_r(struct gspca_dev *gspca_dev,
510 __u16 value)
512 usb_control_msg(gspca_dev->dev,
513 usb_rcvctrlpipe(gspca_dev->dev, 0),
514 0, /* request */
515 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
516 value,
517 0, /* index */
518 gspca_dev->usb_buf, 1,
519 500);
522 static void reg_w(struct gspca_dev *gspca_dev,
523 __u16 value,
524 const __u8 *buffer,
525 int len)
527 #ifdef GSPCA_DEBUG
528 if (len > USB_BUF_SZ) {
529 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
530 return;
532 #endif
533 memcpy(gspca_dev->usb_buf, buffer, len);
534 usb_control_msg(gspca_dev->dev,
535 usb_sndctrlpipe(gspca_dev->dev, 0),
536 0x08, /* request */
537 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
538 value,
539 0, /* index */
540 gspca_dev->usb_buf, len,
541 500);
544 static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
546 int retry = 60;
548 /* is i2c ready */
549 reg_w(gspca_dev, 0x08, buffer, 8);
550 while (retry--) {
551 msleep(10);
552 reg_r(gspca_dev, 0x08);
553 if (gspca_dev->usb_buf[0] & 0x04) {
554 if (gspca_dev->usb_buf[0] & 0x08)
555 return -1;
556 return 0;
559 return -1;
562 static void i2c_w_vector(struct gspca_dev *gspca_dev,
563 const __u8 buffer[][8], int len)
565 for (;;) {
566 reg_w(gspca_dev, 0x08, *buffer, 8);
567 len -= 8;
568 if (len <= 0)
569 break;
570 buffer++;
574 static void setbrightness(struct gspca_dev *gspca_dev)
576 struct sd *sd = (struct sd *) gspca_dev;
577 __u8 value;
579 switch (sd->sensor) {
580 case SENSOR_OV6650:
581 case SENSOR_OV7630: {
582 __u8 i2cOV[] =
583 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
585 /* change reg 0x06 */
586 i2cOV[1] = sensor_data[sd->sensor].sensor_addr;
587 i2cOV[3] = sd->brightness;
588 if (i2c_w(gspca_dev, i2cOV) < 0)
589 goto err;
590 break;
592 case SENSOR_PAS106: {
593 __u8 i2c1[] =
594 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
596 i2c1[3] = sd->brightness >> 3;
597 i2c1[2] = 0x0e;
598 if (i2c_w(gspca_dev, i2c1) < 0)
599 goto err;
600 i2c1[3] = 0x01;
601 i2c1[2] = 0x13;
602 if (i2c_w(gspca_dev, i2c1) < 0)
603 goto err;
604 break;
606 case SENSOR_PAS202: {
607 /* __u8 i2cpexpo1[] =
608 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
609 __u8 i2cpexpo[] =
610 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
611 __u8 i2cp202[] =
612 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
613 static __u8 i2cpdoit[] =
614 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
616 /* change reg 0x10 */
617 i2cpexpo[4] = 0xff - sd->brightness;
618 /* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
619 goto err; */
620 /* if(i2c_w(gspca_dev,i2cpdoit) < 0)
621 goto err; */
622 if (i2c_w(gspca_dev, i2cpexpo) < 0)
623 goto err;
624 if (i2c_w(gspca_dev, i2cpdoit) < 0)
625 goto err;
626 i2cp202[3] = sd->brightness >> 3;
627 if (i2c_w(gspca_dev, i2cp202) < 0)
628 goto err;
629 if (i2c_w(gspca_dev, i2cpdoit) < 0)
630 goto err;
631 break;
633 case SENSOR_TAS5130CXX: {
634 __u8 i2c[] =
635 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
637 value = 0xff - sd->brightness;
638 i2c[4] = value;
639 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
640 if (i2c_w(gspca_dev, i2c) < 0)
641 goto err;
642 break;
645 return;
646 err:
647 PDEBUG(D_ERR, "i2c error brightness");
650 static void setsensorgain(struct gspca_dev *gspca_dev)
652 struct sd *sd = (struct sd *) gspca_dev;
653 unsigned char gain = sd->gain;
655 switch (sd->sensor) {
657 case SENSOR_TAS5110: {
658 __u8 i2c[] =
659 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
661 i2c[4] = 255 - gain;
662 if (i2c_w(gspca_dev, i2c) < 0)
663 goto err;
664 break;
667 case SENSOR_OV6650:
668 gain >>= 1;
669 /* fall thru */
670 case SENSOR_OV7630: {
671 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
673 i2c[1] = sensor_data[sd->sensor].sensor_addr;
674 i2c[3] = gain >> 2;
675 if (i2c_w(gspca_dev, i2c) < 0)
676 goto err;
677 break;
680 return;
681 err:
682 PDEBUG(D_ERR, "i2c error gain");
685 static void setgain(struct gspca_dev *gspca_dev)
687 struct sd *sd = (struct sd *) gspca_dev;
688 __u8 gain;
689 __u8 rgb_value;
691 gain = sd->gain >> 4;
693 /* red and blue gain */
694 rgb_value = gain << 4 | gain;
695 reg_w(gspca_dev, 0x10, &rgb_value, 1);
696 /* green gain */
697 rgb_value = gain;
698 reg_w(gspca_dev, 0x11, &rgb_value, 1);
700 if (sensor_data[sd->sensor].flags & F_GAIN)
701 setsensorgain(gspca_dev);
704 static void setexposure(struct gspca_dev *gspca_dev)
706 struct sd *sd = (struct sd *) gspca_dev;
708 switch (sd->sensor) {
709 case SENSOR_TAS5110: {
710 __u8 reg;
712 /* register 19's high nibble contains the sn9c10x clock divider
713 The high nibble configures the no fps according to the
714 formula: 60 / high_nibble. With a maximum of 30 fps */
715 reg = 120 * sd->exposure / 1000;
716 if (reg < 2)
717 reg = 2;
718 else if (reg > 15)
719 reg = 15;
720 reg = (reg << 4) | 0x0b;
721 reg_w(gspca_dev, 0x19, &reg, 1);
722 break;
724 case SENSOR_OV6650:
725 case SENSOR_OV7630: {
726 /* The ov6650 / ov7630 have 2 registers which both influence
727 exposure, register 11, whose low nibble sets the nr off fps
728 according to: fps = 30 / (low_nibble + 1)
730 The fps configures the maximum exposure setting, but it is
731 possible to use less exposure then what the fps maximum
732 allows by setting register 10. register 10 configures the
733 actual exposure as quotient of the full exposure, with 0
734 being no exposure at all (not very usefull) and reg10_max
735 being max exposure possible at that framerate.
737 The code maps our 0 - 510 ms exposure ctrl to these 2
738 registers, trying to keep fps as high as possible.
740 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
741 int reg10, reg11, reg10_max;
743 /* ov6645 datasheet says reg10_max is 9a, but that uses
744 tline * 2 * reg10 as formula for calculating texpo, the
745 ov6650 probably uses the same formula as the 7730 which uses
746 tline * 4 * reg10, which explains why the reg10max we've
747 found experimentally for the ov6650 is exactly half that of
748 the ov6645. The ov7630 datasheet says the max is 0x41. */
749 if (sd->sensor == SENSOR_OV6650) {
750 reg10_max = 0x4d;
751 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
752 } else
753 reg10_max = 0x41;
755 reg11 = (60 * sd->exposure + 999) / 1000;
756 if (reg11 < 1)
757 reg11 = 1;
758 else if (reg11 > 16)
759 reg11 = 16;
761 /* In 640x480, if the reg11 has less than 3, the image is
762 unstable (not enough bandwidth). */
763 if (gspca_dev->width == 640 && reg11 < 3)
764 reg11 = 3;
766 /* frame exposure time in ms = 1000 * reg11 / 30 ->
767 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
768 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
770 /* Don't allow this to get below 10 when using autogain, the
771 steps become very large (relatively) when below 10 causing
772 the image to oscilate from much too dark, to much too bright
773 and back again. */
774 if (sd->autogain && reg10 < 10)
775 reg10 = 10;
776 else if (reg10 > reg10_max)
777 reg10 = reg10_max;
779 /* Write reg 10 and reg11 low nibble */
780 i2c[1] = sensor_data[sd->sensor].sensor_addr;
781 i2c[3] = reg10;
782 i2c[4] |= reg11 - 1;
784 /* If register 11 didn't change, don't change it */
785 if (sd->reg11 == reg11 )
786 i2c[0] = 0xa0;
788 if (i2c_w(gspca_dev, i2c) == 0)
789 sd->reg11 = reg11;
790 else
791 PDEBUG(D_ERR, "i2c error exposure");
792 break;
797 static void setfreq(struct gspca_dev *gspca_dev)
799 struct sd *sd = (struct sd *) gspca_dev;
801 switch (sd->sensor) {
802 case SENSOR_OV6650:
803 case SENSOR_OV7630: {
804 /* Framerate adjust register for artificial light 50 hz flicker
805 compensation, for the ov6650 this is identical to ov6630
806 0x2b register, see ov6630 datasheet.
807 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
808 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
809 switch (sd->freq) {
810 default:
811 /* case 0: * no filter*/
812 /* case 2: * 60 hz */
813 i2c[3] = 0;
814 break;
815 case 1: /* 50 hz */
816 i2c[3] = (sd->sensor == SENSOR_OV6650)
817 ? 0x4f : 0x8a;
818 break;
820 i2c[1] = sensor_data[sd->sensor].sensor_addr;
821 if (i2c_w(gspca_dev, i2c) < 0)
822 PDEBUG(D_ERR, "i2c error setfreq");
823 break;
828 static void do_autogain(struct gspca_dev *gspca_dev)
830 struct sd *sd = (struct sd *) gspca_dev;
831 int avg_lum = atomic_read(&sd->avg_lum);
833 if (avg_lum == -1)
834 return;
836 if (sd->autogain_ignore_frames > 0)
837 sd->autogain_ignore_frames--;
838 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
839 sd->brightness * DESIRED_AVG_LUM / 127,
840 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
841 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
842 (int)sd->gain, (int)sd->exposure);
843 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
847 /* this function is called at probe time */
848 static int sd_config(struct gspca_dev *gspca_dev,
849 const struct usb_device_id *id)
851 struct sd *sd = (struct sd *) gspca_dev;
852 struct cam *cam;
854 reg_r(gspca_dev, 0x00);
855 if (gspca_dev->usb_buf[0] != 0x10)
856 return -ENODEV;
858 /* copy the webcam info from the device id */
859 sd->sensor = id->driver_info >> 8;
860 sd->bridge = id->driver_info & 0xff;
861 gspca_dev->ctrl_dis = sensor_data[sd->sensor].ctrl_dis;
863 cam = &gspca_dev->cam;
864 cam->epaddr = 0x01;
865 if (!(sensor_data[sd->sensor].flags & F_SIF)) {
866 cam->cam_mode = vga_mode;
867 cam->nmodes = ARRAY_SIZE(vga_mode);
868 } else {
869 cam->cam_mode = sif_mode;
870 cam->nmodes = ARRAY_SIZE(sif_mode);
872 sd->brightness = BRIGHTNESS_DEF;
873 sd->gain = GAIN_DEF;
874 sd->exposure = EXPOSURE_DEF;
875 if (gspca_dev->ctrl_dis & (1 << AUTOGAIN_IDX))
876 sd->autogain = 0; /* Disable do_autogain callback */
877 else
878 sd->autogain = AUTOGAIN_DEF;
879 sd->freq = FREQ_DEF;
881 return 0;
884 /* this function is called at probe and resume time */
885 static int sd_init(struct gspca_dev *gspca_dev)
887 const __u8 stop = 0x09; /* Disable stream turn of LED */
889 reg_w(gspca_dev, 0x01, &stop, 1);
891 return 0;
894 /* -- start the camera -- */
895 static int sd_start(struct gspca_dev *gspca_dev)
897 struct sd *sd = (struct sd *) gspca_dev;
898 struct cam *cam = &gspca_dev->cam;
899 int mode, l;
900 const __u8 *sn9c10x;
901 __u8 reg12_19[8];
903 mode = cam->cam_mode[gspca_dev->curr_mode].priv & 0x07;
904 sn9c10x = sensor_data[sd->sensor].bridge_init[sd->bridge];
905 l = sensor_data[sd->sensor].bridge_init_size[sd->bridge];
906 memcpy(reg12_19, &sn9c10x[0x12 - 1], 8);
907 reg12_19[6] = sn9c10x[0x18 - 1] | (mode << 4);
908 /* Special cases where reg 17 and or 19 value depends on mode */
909 switch (sd->sensor) {
910 case SENSOR_PAS202:
911 reg12_19[5] = mode ? 0x24 : 0x20;
912 break;
913 case SENSOR_TAS5130CXX:
914 /* probably not mode specific at all most likely the upper
915 nibble of 0x19 is exposure (clock divider) just as with
916 the tas5110, we need someone to test this. */
917 reg12_19[7] = mode ? 0x23 : 0x43;
918 break;
920 /* Disable compression when the raw bayer format has been selected */
921 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW)
922 reg12_19[6] &= ~0x80;
924 /* Vga mode emulation on SIF sensor? */
925 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_REDUCED_SIF) {
926 reg12_19[0] += 16; /* 0x12: hstart adjust */
927 reg12_19[1] += 24; /* 0x13: vstart adjust */
928 reg12_19[3] = 320 / 16; /* 0x15: hsize */
929 reg12_19[4] = 240 / 16; /* 0x16: vsize */
932 /* reg 0x01 bit 2 video transfert on */
933 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
934 /* reg 0x17 SensorClk enable inv Clk 0x60 */
935 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
936 /* Set the registers from the template */
937 reg_w(gspca_dev, 0x01, sn9c10x, l);
939 /* Init the sensor */
940 i2c_w_vector(gspca_dev, sensor_data[sd->sensor].sensor_init,
941 sensor_data[sd->sensor].sensor_init_size);
942 if (sensor_data[sd->sensor].sensor_bridge_init[sd->bridge])
943 i2c_w_vector(gspca_dev,
944 sensor_data[sd->sensor].sensor_bridge_init[sd->bridge],
945 sensor_data[sd->sensor].sensor_bridge_init_size[
946 sd->bridge]);
948 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
949 reg_w(gspca_dev, 0x15, &reg12_19[3], 2);
950 /* compression register */
951 reg_w(gspca_dev, 0x18, &reg12_19[6], 1);
952 /* H_start */
953 reg_w(gspca_dev, 0x12, &reg12_19[0], 1);
954 /* V_START */
955 reg_w(gspca_dev, 0x13, &reg12_19[1], 1);
956 /* reset 0x17 SensorClk enable inv Clk 0x60 */
957 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
958 reg_w(gspca_dev, 0x17, &reg12_19[5], 1);
959 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
960 reg_w(gspca_dev, 0x19, &reg12_19[7], 1);
961 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
962 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
963 /* Enable video transfert */
964 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
965 /* Compression */
966 reg_w(gspca_dev, 0x18, &reg12_19[6], 2);
967 msleep(20);
969 sd->reg11 = -1;
971 setgain(gspca_dev);
972 setbrightness(gspca_dev);
973 setexposure(gspca_dev);
974 setfreq(gspca_dev);
976 sd->frames_to_drop = 0;
977 sd->autogain_ignore_frames = 0;
978 atomic_set(&sd->avg_lum, -1);
979 return 0;
982 static void sd_stopN(struct gspca_dev *gspca_dev)
984 sd_init(gspca_dev);
987 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
988 struct gspca_frame *frame, /* target */
989 unsigned char *data, /* isoc packet */
990 int len) /* iso packet length */
992 int i;
993 struct sd *sd = (struct sd *) gspca_dev;
994 struct cam *cam = &gspca_dev->cam;
996 /* frames start with:
997 * ff ff 00 c4 c4 96 synchro
998 * 00 (unknown)
999 * xx (frame sequence / size / compression)
1000 * (xx) (idem - extra byte for sn9c103)
1001 * ll mm brightness sum inside auto exposure
1002 * ll mm brightness sum outside auto exposure
1003 * (xx xx xx xx xx) audio values for snc103
1005 if (len > 6 && len < 24) {
1006 for (i = 0; i < len - 6; i++) {
1007 if (data[0 + i] == 0xff
1008 && data[1 + i] == 0xff
1009 && data[2 + i] == 0x00
1010 && data[3 + i] == 0xc4
1011 && data[4 + i] == 0xc4
1012 && data[5 + i] == 0x96) { /* start of frame */
1013 int lum = -1;
1014 int pkt_type = LAST_PACKET;
1015 int fr_h_sz = (sd->bridge == BRIDGE_103) ?
1016 18 : 12;
1018 if (len - i < fr_h_sz) {
1019 PDEBUG(D_STREAM, "packet too short to"
1020 " get avg brightness");
1021 } else if (sd->bridge == BRIDGE_103) {
1022 lum = data[i + 9] +
1023 (data[i + 10] << 8);
1024 } else {
1025 lum = data[i + 8] + (data[i + 9] << 8);
1027 /* When exposure changes midway a frame we
1028 get a lum of 0 in this case drop 2 frames
1029 as the frames directly after an exposure
1030 change have an unstable image. Sometimes lum
1031 *really* is 0 (cam used in low light with
1032 low exposure setting), so do not drop frames
1033 if the previous lum was 0 too. */
1034 if (lum == 0 && sd->prev_avg_lum != 0) {
1035 lum = -1;
1036 sd->frames_to_drop = 2;
1037 sd->prev_avg_lum = 0;
1038 } else
1039 sd->prev_avg_lum = lum;
1040 atomic_set(&sd->avg_lum, lum);
1042 if (sd->frames_to_drop) {
1043 sd->frames_to_drop--;
1044 pkt_type = DISCARD_PACKET;
1047 frame = gspca_frame_add(gspca_dev, pkt_type,
1048 frame, data, 0);
1049 data += i + fr_h_sz;
1050 len -= i + fr_h_sz;
1051 gspca_frame_add(gspca_dev, FIRST_PACKET,
1052 frame, data, len);
1053 return;
1058 if (cam->cam_mode[gspca_dev->curr_mode].priv & MODE_RAW) {
1059 /* In raw mode we sometimes get some garbage after the frame
1060 ignore this */
1061 int used = frame->data_end - frame->data;
1062 int size = cam->cam_mode[gspca_dev->curr_mode].sizeimage;
1064 if (used + len > size)
1065 len = size - used;
1068 gspca_frame_add(gspca_dev, INTER_PACKET,
1069 frame, data, len);
1072 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1074 struct sd *sd = (struct sd *) gspca_dev;
1076 sd->brightness = val;
1077 if (gspca_dev->streaming)
1078 setbrightness(gspca_dev);
1079 return 0;
1082 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1084 struct sd *sd = (struct sd *) gspca_dev;
1086 *val = sd->brightness;
1087 return 0;
1090 static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1092 struct sd *sd = (struct sd *) gspca_dev;
1094 sd->gain = val;
1095 if (gspca_dev->streaming)
1096 setgain(gspca_dev);
1097 return 0;
1100 static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
1102 struct sd *sd = (struct sd *) gspca_dev;
1104 *val = sd->gain;
1105 return 0;
1108 static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1110 struct sd *sd = (struct sd *) gspca_dev;
1112 sd->exposure = val;
1113 if (gspca_dev->streaming)
1114 setexposure(gspca_dev);
1115 return 0;
1118 static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1120 struct sd *sd = (struct sd *) gspca_dev;
1122 *val = sd->exposure;
1123 return 0;
1126 static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1128 struct sd *sd = (struct sd *) gspca_dev;
1130 sd->autogain = val;
1131 /* when switching to autogain set defaults to make sure
1132 we are on a valid point of the autogain gain /
1133 exposure knee graph, and give this change time to
1134 take effect before doing autogain. */
1135 if (sd->autogain) {
1136 sd->exposure = EXPOSURE_DEF;
1137 sd->gain = GAIN_DEF;
1138 if (gspca_dev->streaming) {
1139 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1140 setexposure(gspca_dev);
1141 setgain(gspca_dev);
1145 return 0;
1148 static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
1150 struct sd *sd = (struct sd *) gspca_dev;
1152 *val = sd->autogain;
1153 return 0;
1156 static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1158 struct sd *sd = (struct sd *) gspca_dev;
1160 sd->freq = val;
1161 if (gspca_dev->streaming)
1162 setfreq(gspca_dev);
1163 return 0;
1166 static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1168 struct sd *sd = (struct sd *) gspca_dev;
1170 *val = sd->freq;
1171 return 0;
1174 static int sd_querymenu(struct gspca_dev *gspca_dev,
1175 struct v4l2_querymenu *menu)
1177 switch (menu->id) {
1178 case V4L2_CID_POWER_LINE_FREQUENCY:
1179 switch (menu->index) {
1180 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1181 strcpy((char *) menu->name, "NoFliker");
1182 return 0;
1183 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1184 strcpy((char *) menu->name, "50 Hz");
1185 return 0;
1186 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1187 strcpy((char *) menu->name, "60 Hz");
1188 return 0;
1190 break;
1192 return -EINVAL;
1195 /* sub-driver description */
1196 static const struct sd_desc sd_desc = {
1197 .name = MODULE_NAME,
1198 .ctrls = sd_ctrls,
1199 .nctrls = ARRAY_SIZE(sd_ctrls),
1200 .config = sd_config,
1201 .init = sd_init,
1202 .start = sd_start,
1203 .stopN = sd_stopN,
1204 .pkt_scan = sd_pkt_scan,
1205 .querymenu = sd_querymenu,
1206 .dq_callback = do_autogain,
1209 /* -- module initialisation -- */
1210 #define SB(sensor, bridge) \
1211 .driver_info = (SENSOR_ ## sensor << 8) | BRIDGE_ ## bridge
1214 static __devinitdata struct usb_device_id device_table[] = {
1215 {USB_DEVICE(0x0c45, 0x6001), SB(TAS5110, 102)}, /* TAS5110C1B */
1216 {USB_DEVICE(0x0c45, 0x6005), SB(TAS5110, 101)}, /* TAS5110C1B */
1217 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1218 {USB_DEVICE(0x0c45, 0x6007), SB(TAS5110, 101)}, /* TAS5110D */
1219 {USB_DEVICE(0x0c45, 0x6009), SB(PAS106, 101)},
1220 {USB_DEVICE(0x0c45, 0x600d), SB(PAS106, 101)},
1221 #endif
1222 {USB_DEVICE(0x0c45, 0x6011), SB(OV6650, 101)},
1223 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1224 {USB_DEVICE(0x0c45, 0x6019), SB(OV7630, 101)},
1225 {USB_DEVICE(0x0c45, 0x6024), SB(TAS5130CXX, 102)},
1226 {USB_DEVICE(0x0c45, 0x6025), SB(TAS5130CXX, 102)},
1227 {USB_DEVICE(0x0c45, 0x6028), SB(PAS202, 102)},
1228 {USB_DEVICE(0x0c45, 0x6029), SB(PAS106, 102)},
1229 {USB_DEVICE(0x0c45, 0x602c), SB(OV7630, 102)},
1230 #endif
1231 {USB_DEVICE(0x0c45, 0x602d), SB(HV7131R, 102)},
1232 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1233 {USB_DEVICE(0x0c45, 0x602e), SB(OV7630, 102)},
1234 #endif
1235 {USB_DEVICE(0x0c45, 0x608f), SB(OV7630, 103)},
1236 #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE
1237 {USB_DEVICE(0x0c45, 0x60af), SB(PAS202, 103)},
1238 #endif
1239 {USB_DEVICE(0x0c45, 0x60b0), SB(OV7630, 103)},
1242 MODULE_DEVICE_TABLE(usb, device_table);
1244 /* -- device connect -- */
1245 static int sd_probe(struct usb_interface *intf,
1246 const struct usb_device_id *id)
1248 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1249 THIS_MODULE);
1252 static struct usb_driver sd_driver = {
1253 .name = MODULE_NAME,
1254 .id_table = device_table,
1255 .probe = sd_probe,
1256 .disconnect = gspca_disconnect,
1257 #ifdef CONFIG_PM
1258 .suspend = gspca_suspend,
1259 .resume = gspca_resume,
1260 #endif
1263 /* -- module insert / remove -- */
1264 static int __init sd_mod_init(void)
1266 if (usb_register(&sd_driver) < 0)
1267 return -1;
1268 PDEBUG(D_PROBE, "registered");
1269 return 0;
1271 static void __exit sd_mod_exit(void)
1273 usb_deregister(&sd_driver);
1274 PDEBUG(D_PROBE, "deregistered");
1277 module_init(sd_mod_init);
1278 module_exit(sd_mod_exit);