V4L/DVB (8815): gspca: Fix problems with disabled controls.
[linux-2.6-block.git] / drivers / media / video / gspca / sonixb.c
CommitLineData
6a7eba24
JFM
1/*
2 * sonix sn9c102 (bayer) library
3 * Copyright (C) 2003 2004 Michel Xhaard mxhaard@magic.fr
4 * Add Pas106 Stefano Mozzi (C) 2004
5 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
7 *
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.
12 *
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.
17 *
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
21 */
22
23#define MODULE_NAME "sonixb"
24
25#include "gspca.h"
26
6a7eba24
JFM
27MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
28MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
29MODULE_LICENSE("GPL");
30
31/* specific webcam descriptor */
32struct sd {
33 struct gspca_dev gspca_dev; /* !! must be the first item */
34
dcef3237
HG
35 struct sd_desc sd_desc; /* our nctrls differ dependend upon the
36 sensor, so we use a per cam copy */
37 atomic_t avg_lum;
38
ad5ef80d
HG
39 unsigned char gain;
40 unsigned char exposure;
6a7eba24 41 unsigned char brightness;
dcef3237
HG
42 unsigned char autogain;
43 unsigned char autogain_ignore_frames;
6af492e5 44 unsigned char frames_to_drop;
66f35821 45 unsigned char freq; /* light freq filter setting */
6a7eba24 46
553b9fa4 47 unsigned char fr_h_sz; /* size of frame header */
6a7eba24
JFM
48 char sensor; /* Type of image sensor chip */
49#define SENSOR_HV7131R 0
50#define SENSOR_OV6650 1
51#define SENSOR_OV7630 2
6af492e5
HG
52#define SENSOR_PAS106 3
53#define SENSOR_PAS202 4
54#define SENSOR_TAS5110 5
55#define SENSOR_TAS5130CXX 6
a975a527
HG
56 char sensor_has_gain;
57 __u8 sensor_addr;
6af492e5 58 __u8 reg11;
6a7eba24
JFM
59};
60
5da162e7
JFM
61/* flags used in the device id table */
62#define F_GAIN 0x01 /* has gain */
63#define F_AUTO 0x02 /* has autogain */
64#define F_SIF 0x04 /* sif or vga */
65#define F_H18 0x08 /* long (18 b) or short (12 b) frame header */
66
6a7eba24
JFM
67#define COMP2 0x8f
68#define COMP 0xc7 /* 0x87 //0x07 */
69#define COMP1 0xc9 /* 0x89 //0x09 */
70
71#define MCK_INIT 0x63
72#define MCK_INIT1 0x20 /*fixme: Bayer - 0x50 for JPEG ??*/
73
74#define SYS_CLK 0x04
75
dcef3237
HG
76/* We calculate the autogain at the end of the transfer of a frame, at this
77 moment a frame with the old settings is being transmitted, and a frame is
78 being captured with the old settings. So if we adjust the autogain we must
79 ignore atleast the 2 next frames for the new settings to come into effect
80 before doing any other adjustments */
81#define AUTOGAIN_IGNORE_FRAMES 3
ad5ef80d 82#define AUTOGAIN_DEADZONE 1000
dcef3237
HG
83#define DESIRED_AVG_LUM 7000
84
6a7eba24
JFM
85/* V4L2 controls supported by the driver */
86static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
87static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
dcef3237
HG
88static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val);
89static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val);
90static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val);
91static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val);
92static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val);
93static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val);
66f35821
HG
94static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val);
95static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val);
6a7eba24
JFM
96
97static struct ctrl sd_ctrls[] = {
6a7eba24
JFM
98 {
99 {
100 .id = V4L2_CID_BRIGHTNESS,
101 .type = V4L2_CTRL_TYPE_INTEGER,
102 .name = "Brightness",
103 .minimum = 0,
104 .maximum = 255,
105 .step = 1,
dcef3237
HG
106#define BRIGHTNESS_DEF 127
107 .default_value = BRIGHTNESS_DEF,
6a7eba24
JFM
108 },
109 .set = sd_setbrightness,
110 .get = sd_getbrightness,
111 },
6a7eba24
JFM
112 {
113 {
dcef3237 114 .id = V4L2_CID_GAIN,
6a7eba24 115 .type = V4L2_CTRL_TYPE_INTEGER,
dcef3237 116 .name = "Gain",
6a7eba24 117 .minimum = 0,
ad5ef80d 118 .maximum = 255,
6a7eba24 119 .step = 1,
ad5ef80d
HG
120#define GAIN_DEF 127
121#define GAIN_KNEE 200
dcef3237 122 .default_value = GAIN_DEF,
6a7eba24 123 },
dcef3237
HG
124 .set = sd_setgain,
125 .get = sd_getgain,
126 },
dcef3237
HG
127 {
128 {
129 .id = V4L2_CID_EXPOSURE,
130 .type = V4L2_CTRL_TYPE_INTEGER,
131 .name = "Exposure",
f4d52025
HG
132#define EXPOSURE_DEF 16 /* 32 ms / 30 fps */
133#define EXPOSURE_KNEE 50 /* 100 ms / 10 fps */
dcef3237 134 .minimum = 0,
ad5ef80d 135 .maximum = 255,
dcef3237
HG
136 .step = 1,
137 .default_value = EXPOSURE_DEF,
138 .flags = 0,
139 },
140 .set = sd_setexposure,
141 .get = sd_getexposure,
142 },
dcef3237
HG
143 {
144 {
145 .id = V4L2_CID_AUTOGAIN,
146 .type = V4L2_CTRL_TYPE_BOOLEAN,
147 .name = "Automatic Gain (and Exposure)",
148 .minimum = 0,
149 .maximum = 1,
150 .step = 1,
51fc8e3b
AZ
151#define AUTOGAIN_DEF 1
152 .default_value = AUTOGAIN_DEF,
dcef3237
HG
153 .flags = 0,
154 },
155 .set = sd_setautogain,
156 .get = sd_getautogain,
6a7eba24 157 },
66f35821
HG
158 {
159 {
160 .id = V4L2_CID_POWER_LINE_FREQUENCY,
161 .type = V4L2_CTRL_TYPE_MENU,
162 .name = "Light frequency filter",
163 .minimum = 0,
164 .maximum = 2, /* 0: 0, 1: 50Hz, 2:60Hz */
165 .step = 1,
166#define FREQ_DEF 1
167 .default_value = FREQ_DEF,
168 },
169 .set = sd_setfreq,
170 .get = sd_getfreq,
171 },
6a7eba24
JFM
172};
173
c2446b3e
JFM
174static struct v4l2_pix_format vga_mode[] = {
175 {160, 120, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
176 .bytesperline = 160,
177 .sizeimage = 160 * 120,
178 .colorspace = V4L2_COLORSPACE_SRGB,
179 .priv = 2},
180 {320, 240, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
181 .bytesperline = 320,
182 .sizeimage = 320 * 240,
183 .colorspace = V4L2_COLORSPACE_SRGB,
184 .priv = 1},
185 {640, 480, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
186 .bytesperline = 640,
187 .sizeimage = 640 * 480,
188 .colorspace = V4L2_COLORSPACE_SRGB,
189 .priv = 0},
6a7eba24 190};
c2446b3e
JFM
191static struct v4l2_pix_format sif_mode[] = {
192 {176, 144, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
193 .bytesperline = 176,
194 .sizeimage = 176 * 144,
195 .colorspace = V4L2_COLORSPACE_SRGB,
196 .priv = 1},
197 {352, 288, V4L2_PIX_FMT_SN9C10X, V4L2_FIELD_NONE,
198 .bytesperline = 352,
199 .sizeimage = 352 * 288,
200 .colorspace = V4L2_COLORSPACE_SRGB,
201 .priv = 0},
6a7eba24
JFM
202};
203
6a7eba24
JFM
204static const __u8 initHv7131[] = {
205 0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
206 0x00, 0x00,
207 0x00, 0x00, 0x00, 0x03, 0x01, 0x00, /* shift from 0x02 0x01 0x00 */
208 0x28, 0x1e, 0x60, 0x8a, 0x20,
209 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
210};
211static const __u8 hv7131_sensor_init[][8] = {
212 {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
213 {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
214 {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
215 {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
216 {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
217};
218static const __u8 initOv6650[] = {
219 0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
220 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
221 0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
222 0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
223};
224static const __u8 ov6650_sensor_init[][8] =
225{
226 /* Bright, contrast, etc are set througth SCBB interface.
227 * AVCAP on win2 do not send any data on this controls. */
228 /* Anyway, some registers appears to alter bright and constrat */
dcef3237
HG
229
230 /* Reset sensor */
6a7eba24 231 {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
dcef3237 232 /* Set clock register 0x11 low nibble is clock divider */
6a7eba24 233 {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
dcef3237 234 /* Next some unknown stuff */
6a7eba24
JFM
235 {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
236/* {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
237 * THIS SET GREEN SCREEN
238 * (pixels could be innverted in decode kind of "brg",
239 * but blue wont be there. Avoid this data ... */
240 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
241 {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
242 {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
722103e3
HG
243 /* Enable rgb brightness control */
244 {0xa0, 0x60, 0x61, 0x08, 0x00, 0x00, 0x00, 0x10},
245 /* HDG: Note windows uses the line below, which sets both register 0x60
246 and 0x61 I believe these registers of the ov6650 are identical as
247 those of the ov7630, because if this is true the windows settings
248 add a bit additional red gain and a lot additional blue gain, which
249 matches my findings that the windows settings make blue much too
250 blue and red a little too red.
251 {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10}, */
dcef3237 252 /* Some more unknown stuff */
6a7eba24
JFM
253 {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
254 {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
6a7eba24 255};
dcef3237 256
6a7eba24
JFM
257static const __u8 initOv7630[] = {
258 0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
259 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
260 0x00, 0x02, 0x01, 0x0a, /* r11 .. r14 */
261 0x28, 0x1e, /* H & V sizes r15 .. r16 */
262 0x68, COMP1, MCK_INIT1, /* r17 .. r19 */
263 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c /* r1a .. r1f */
264};
265static const __u8 initOv7630_3[] = {
266 0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
267 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
51fc8e3b 268 0x00, 0x01, 0x01, 0x0a, /* r11 .. r14 */
3647fea8 269 0x28, 0x1e, /* H & V sizes r15 .. r16 */
51fc8e3b
AZ
270 0x68, 0x8f, MCK_INIT1, /* r17 .. r19 */
271 0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c, 0x00, /* r1a .. r20 */
272 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80, /* r21 .. r28 */
273 0x90, 0xa0, 0xb0, 0xc0, 0xd0, 0xe0, 0xf0, 0xff /* r29 .. r30 */
6a7eba24 274};
6af492e5 275static const __u8 ov7630_sensor_init[][8] = {
6a7eba24
JFM
276 {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
277 {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
278/* {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10}, jfm */
794af52a 279 {0xd0, 0x21, 0x12, 0x1c, 0x00, 0x80, 0x34, 0x10}, /* jfm */
6a7eba24
JFM
280 {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
281 {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
282 {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
283 {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
284 {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
285 {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
286 {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
794af52a
AZ
287 {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},
288/* {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10}, * jfm */
6a7eba24
JFM
289 {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
290 {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
291 {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
292 {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
293 {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
294 {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
295};
6a7eba24
JFM
296
297static const __u8 initPas106[] = {
298 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
299 0x00, 0x00,
300 0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
301 0x16, 0x12, 0x28, COMP1, MCK_INIT1,
302 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
303};
304/* compression 0x86 mckinit1 0x2b */
305static const __u8 pas106_data[][2] = {
306 {0x02, 0x04}, /* Pixel Clock Divider 6 */
307 {0x03, 0x13}, /* Frame Time MSB */
308/* {0x03, 0x12}, * Frame Time MSB */
309 {0x04, 0x06}, /* Frame Time LSB */
310/* {0x04, 0x05}, * Frame Time LSB */
311 {0x05, 0x65}, /* Shutter Time Line Offset */
312/* {0x05, 0x6d}, * Shutter Time Line Offset */
313/* {0x06, 0xb1}, * Shutter Time Pixel Offset */
314 {0x06, 0xcd}, /* Shutter Time Pixel Offset */
315 {0x07, 0xc1}, /* Black Level Subtract Sign */
316/* {0x07, 0x00}, * Black Level Subtract Sign */
317 {0x08, 0x06}, /* Black Level Subtract Level */
318 {0x08, 0x06}, /* Black Level Subtract Level */
319/* {0x08, 0x01}, * Black Level Subtract Level */
320 {0x09, 0x05}, /* Color Gain B Pixel 5 a */
321 {0x0a, 0x04}, /* Color Gain G1 Pixel 1 5 */
322 {0x0b, 0x04}, /* Color Gain G2 Pixel 1 0 5 */
323 {0x0c, 0x05}, /* Color Gain R Pixel 3 1 */
324 {0x0d, 0x00}, /* Color GainH Pixel */
325 {0x0e, 0x0e}, /* Global Gain */
326 {0x0f, 0x00}, /* Contrast */
327 {0x10, 0x06}, /* H&V synchro polarity */
328 {0x11, 0x06}, /* ?default */
329 {0x12, 0x06}, /* DAC scale */
330 {0x14, 0x02}, /* ?default */
331 {0x13, 0x01}, /* Validate Settings */
332};
333static const __u8 initPas202[] = {
334 0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
335 0x00, 0x00,
336 0x00, 0x00, 0x00, 0x07, 0x03, 0x0a, /* 6 */
337 0x28, 0x1e, 0x28, 0x89, 0x30,
338 0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
339};
340static const __u8 pas202_sensor_init[][8] = {
341 {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
342 {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
343 {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
344 {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
345 {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
346 {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
347 {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
348 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
349 {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
350 {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
351 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
352 {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
353
354 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
355 {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
356 {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
357 {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
358 {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
359 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
360 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
361 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
362};
363
364static const __u8 initTas5110[] = {
365 0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
366 0x00, 0x00,
367 0x00, 0x01, 0x00, 0x46, 0x09, 0x0a, /* shift from 0x45 0x09 0x0a */
368 0x16, 0x12, 0x60, 0x86, 0x2b,
369 0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
370};
371static const __u8 tas5110_sensor_init[][8] = {
372 {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
373 {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
374 {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
375};
376
377static const __u8 initTas5130[] = {
378 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
379 0x00, 0x00,
380 0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
381 0x28, 0x1e, 0x60, COMP, MCK_INIT,
382 0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
383};
384static const __u8 tas5130_sensor_init[][8] = {
385/* {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
386 * shutter 0x47 short exposure? */
387 {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
388 /* shutter 0x01 long exposure */
389 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
390};
391
739570bb
JFM
392/* get one byte in gspca_dev->usb_buf */
393static void reg_r(struct gspca_dev *gspca_dev,
394 __u16 value)
6a7eba24 395{
739570bb
JFM
396 usb_control_msg(gspca_dev->dev,
397 usb_rcvctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
398 0, /* request */
399 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
400 value,
401 0, /* index */
739570bb 402 gspca_dev->usb_buf, 1,
6a7eba24
JFM
403 500);
404}
405
739570bb
JFM
406static void reg_w(struct gspca_dev *gspca_dev,
407 __u16 value,
408 const __u8 *buffer,
409 int len)
6a7eba24 410{
335b3f88 411#ifdef GSPCA_DEBUG
739570bb 412 if (len > sizeof gspca_dev->usb_buf) {
0d2a722d
HG
413 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
414 return;
415 }
416#endif
739570bb
JFM
417 memcpy(gspca_dev->usb_buf, buffer, len);
418 usb_control_msg(gspca_dev->dev,
419 usb_sndctrlpipe(gspca_dev->dev, 0),
420 0x08, /* request */
421 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
422 value,
423 0, /* index */
424 gspca_dev->usb_buf, len,
425 500);
426}
427
428static void reg_w_big(struct gspca_dev *gspca_dev,
429 __u16 value,
430 const __u8 *buffer,
431 int len)
432{
433 __u8 *tmpbuf;
434
435 tmpbuf = kmalloc(len, GFP_KERNEL);
0d2a722d 436 memcpy(tmpbuf, buffer, len);
739570bb
JFM
437 usb_control_msg(gspca_dev->dev,
438 usb_sndctrlpipe(gspca_dev->dev, 0),
6a7eba24
JFM
439 0x08, /* request */
440 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
441 value,
442 0, /* index */
0d2a722d 443 tmpbuf, len,
6a7eba24 444 500);
739570bb 445 kfree(tmpbuf);
6a7eba24
JFM
446}
447
739570bb 448static int i2c_w(struct gspca_dev *gspca_dev, const __u8 *buffer)
6a7eba24
JFM
449{
450 int retry = 60;
6a7eba24
JFM
451
452 /* is i2c ready */
739570bb 453 reg_w(gspca_dev, 0x08, buffer, 8);
6a7eba24
JFM
454 while (retry--) {
455 msleep(10);
739570bb 456 reg_r(gspca_dev, 0x08);
b7474cf9
AZ
457 if (gspca_dev->usb_buf[0] & 0x04) {
458 if (gspca_dev->usb_buf[0] & 0x08)
459 return -1;
6a7eba24 460 return 0;
b7474cf9 461 }
6a7eba24
JFM
462 }
463 return -1;
464}
465
739570bb 466static void i2c_w_vector(struct gspca_dev *gspca_dev,
6a7eba24
JFM
467 const __u8 buffer[][8], int len)
468{
469 for (;;) {
739570bb 470 reg_w(gspca_dev, 0x08, *buffer, 8);
6a7eba24
JFM
471 len -= 8;
472 if (len <= 0)
473 break;
474 buffer++;
475 }
476}
477
478static void setbrightness(struct gspca_dev *gspca_dev)
479{
480 struct sd *sd = (struct sd *) gspca_dev;
481 __u8 value;
482
483 switch (sd->sensor) {
a975a527 484 case SENSOR_OV6650:
6a7eba24
JFM
485 case SENSOR_OV7630: {
486 __u8 i2cOV[] =
a975a527 487 {0xa0, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x10};
6a7eba24
JFM
488
489 /* change reg 0x06 */
a975a527 490 i2cOV[1] = sd->sensor_addr;
6a7eba24 491 i2cOV[3] = sd->brightness;
739570bb 492 if (i2c_w(gspca_dev, i2cOV) < 0)
6a7eba24
JFM
493 goto err;
494 break;
495 }
496 case SENSOR_PAS106: {
497 __u8 i2c1[] =
498 {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
499
500 i2c1[3] = sd->brightness >> 3;
501 i2c1[2] = 0x0e;
739570bb 502 if (i2c_w(gspca_dev, i2c1) < 0)
6a7eba24
JFM
503 goto err;
504 i2c1[3] = 0x01;
505 i2c1[2] = 0x13;
739570bb 506 if (i2c_w(gspca_dev, i2c1) < 0)
6a7eba24
JFM
507 goto err;
508 break;
509 }
510 case SENSOR_PAS202: {
511 /* __u8 i2cpexpo1[] =
512 {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
513 __u8 i2cpexpo[] =
514 {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
515 __u8 i2cp202[] =
516 {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
517 static __u8 i2cpdoit[] =
518 {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
519
520 /* change reg 0x10 */
521 i2cpexpo[4] = 0xff - sd->brightness;
739570bb 522/* if(i2c_w(gspca_dev,i2cpexpo1) < 0)
6a7eba24 523 goto err; */
739570bb 524/* if(i2c_w(gspca_dev,i2cpdoit) < 0)
6a7eba24 525 goto err; */
739570bb 526 if (i2c_w(gspca_dev, i2cpexpo) < 0)
6a7eba24 527 goto err;
739570bb 528 if (i2c_w(gspca_dev, i2cpdoit) < 0)
6a7eba24
JFM
529 goto err;
530 i2cp202[3] = sd->brightness >> 3;
739570bb 531 if (i2c_w(gspca_dev, i2cp202) < 0)
6a7eba24 532 goto err;
739570bb 533 if (i2c_w(gspca_dev, i2cpdoit) < 0)
6a7eba24
JFM
534 goto err;
535 break;
536 }
dcef3237 537 case SENSOR_TAS5130CXX: {
6a7eba24
JFM
538 __u8 i2c[] =
539 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
540
541 value = 0xff - sd->brightness;
542 i2c[4] = value;
543 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
739570bb 544 if (i2c_w(gspca_dev, i2c) < 0)
6a7eba24
JFM
545 goto err;
546 break;
547 }
dcef3237
HG
548 case SENSOR_TAS5110:
549 /* FIXME figure out howto control brightness on TAS5110 */
550 break;
6a7eba24
JFM
551 }
552 return;
553err:
554 PDEBUG(D_ERR, "i2c error brightness");
555}
dcef3237
HG
556
557static void setsensorgain(struct gspca_dev *gspca_dev)
558{
559 struct sd *sd = (struct sd *) gspca_dev;
a975a527 560 unsigned char gain = sd->gain;
dcef3237
HG
561
562 switch (sd->sensor) {
563
564 case SENSOR_TAS5110: {
565 __u8 i2c[] =
566 {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
567
a975a527 568 i2c[4] = 255 - gain;
739570bb 569 if (i2c_w(gspca_dev, i2c) < 0)
dcef3237 570 goto err;
51fc8e3b
AZ
571 break;
572 }
ad5ef80d 573
a975a527
HG
574 case SENSOR_OV6650:
575 gain >>= 1;
576 /* fall thru */
6af492e5 577 case SENSOR_OV7630: {
a975a527 578 __u8 i2c[] = {0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10};
794af52a 579
a975a527
HG
580 i2c[1] = sd->sensor_addr;
581 i2c[3] = gain >> 2;
794af52a
AZ
582 if (i2c_w(gspca_dev, i2c) < 0)
583 goto err;
584 break;
585 }
dcef3237
HG
586 }
587 return;
588err:
589 PDEBUG(D_ERR, "i2c error gain");
590}
591
592static void setgain(struct gspca_dev *gspca_dev)
6a7eba24
JFM
593{
594 struct sd *sd = (struct sd *) gspca_dev;
595 __u8 gain;
596 __u8 rgb_value;
597
ad5ef80d 598 gain = sd->gain >> 4;
dcef3237 599
6a7eba24
JFM
600 /* red and blue gain */
601 rgb_value = gain << 4 | gain;
739570bb 602 reg_w(gspca_dev, 0x10, &rgb_value, 1);
6a7eba24
JFM
603 /* green gain */
604 rgb_value = gain;
739570bb 605 reg_w(gspca_dev, 0x11, &rgb_value, 1);
dcef3237
HG
606
607 if (sd->sensor_has_gain)
608 setsensorgain(gspca_dev);
609}
610
611static void setexposure(struct gspca_dev *gspca_dev)
612{
613 struct sd *sd = (struct sd *) gspca_dev;
dcef3237
HG
614
615 switch (sd->sensor) {
616 case SENSOR_TAS5110: {
617 __u8 reg;
618
619 /* register 19's high nibble contains the sn9c10x clock divider
620 The high nibble configures the no fps according to the
621 formula: 60 / high_nibble. With a maximum of 30 fps */
f4d52025
HG
622 reg = 120 * sd->exposure / 1000;
623 if (reg < 2)
624 reg = 2;
625 else if (reg > 15)
dcef3237
HG
626 reg = 15;
627 reg = (reg << 4) | 0x0b;
739570bb 628 reg_w(gspca_dev, 0x19, &reg, 1);
51fc8e3b
AZ
629 break;
630 }
a975a527 631 case SENSOR_OV6650:
6af492e5 632 case SENSOR_OV7630: {
a975a527
HG
633 /* The ov6650 / ov7630 have 2 registers which both influence
634 exposure, register 11, whose low nibble sets the nr off fps
f4d52025
HG
635 according to: fps = 30 / (low_nibble + 1)
636
637 The fps configures the maximum exposure setting, but it is
638 possible to use less exposure then what the fps maximum
639 allows by setting register 10. register 10 configures the
640 actual exposure as quotient of the full exposure, with 0
641 being no exposure at all (not very usefull) and reg10_max
642 being max exposure possible at that framerate.
643
644 The code maps our 0 - 510 ms exposure ctrl to these 2
645 registers, trying to keep fps as high as possible.
646 */
6af492e5
HG
647 __u8 i2c[] = {0xb0, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x10};
648 int reg10, reg11, reg10_max;
649
66f35821
HG
650 /* ov6645 datasheet says reg10_max is 9a, but that uses
651 tline * 2 * reg10 as formula for calculating texpo, the
652 ov6650 probably uses the same formula as the 7730 which uses
653 tline * 4 * reg10, which explains why the reg10max we've
654 found experimentally for the ov6650 is exactly half that of
a975a527 655 the ov6645. The ov7630 datasheet says the max is 0x41. */
6af492e5
HG
656 if (sd->sensor == SENSOR_OV6650) {
657 reg10_max = 0x4d;
658 i2c[4] = 0xc0; /* OV6650 needs non default vsync pol */
659 } else
660 reg10_max = 0x41;
f4d52025 661
794af52a
AZ
662 reg11 = (60 * sd->exposure + 999) / 1000;
663 if (reg11 < 1)
664 reg11 = 1;
665 else if (reg11 > 16)
666 reg11 = 16;
667
668 /* frame exposure time in ms = 1000 * reg11 / 30 ->
669 reg10 = sd->exposure * 2 * reg10_max / (1000 * reg11 / 30) */
670 reg10 = (sd->exposure * 60 * reg10_max) / (1000 * reg11);
794af52a 671
a975a527
HG
672 /* Don't allow this to get below 10 when using autogain, the
673 steps become very large (relatively) when below 10 causing
674 the image to oscilate from much too dark, to much too bright
675 and back again. */
676 if (sd->autogain && reg10 < 10)
677 reg10 = 10;
f4d52025
HG
678 else if (reg10 > reg10_max)
679 reg10 = reg10_max;
680
6af492e5
HG
681 /* In 640x480, if the reg11 has less than 3, the image is
682 unstable (not enough bandwidth). */
683 if (gspca_dev->width == 640 && reg11 < 3)
684 reg11 = 3;
685
f4d52025 686 /* Write reg 10 and reg11 low nibble */
a975a527 687 i2c[1] = sd->sensor_addr;
f4d52025
HG
688 i2c[3] = reg10;
689 i2c[4] |= reg11 - 1;
6af492e5
HG
690
691 /* If register 11 didn't change, don't change it */
692 if (sd->reg11 == reg11 )
693 i2c[0] = 0xa0;
694
695 if (i2c_w(gspca_dev, i2c) == 0)
696 sd->reg11 = reg11;
697 else
dcef3237 698 PDEBUG(D_ERR, "i2c error exposure");
51fc8e3b
AZ
699 break;
700 }
dcef3237
HG
701 }
702}
703
66f35821
HG
704static void setfreq(struct gspca_dev *gspca_dev)
705{
706 struct sd *sd = (struct sd *) gspca_dev;
707
708 switch (sd->sensor) {
d87616f5 709 case SENSOR_OV6650:
6af492e5 710 case SENSOR_OV7630: {
66f35821 711 /* Framerate adjust register for artificial light 50 hz flicker
6af492e5
HG
712 compensation, for the ov6650 this is identical to ov6630
713 0x2b register, see ov6630 datasheet.
714 0x4f / 0x8a -> (30 fps -> 25 fps), 0x00 -> no adjustment */
d87616f5 715 __u8 i2c[] = {0xa0, 0x00, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x10};
66f35821
HG
716 switch (sd->freq) {
717 default:
718/* case 0: * no filter*/
719/* case 2: * 60 hz */
720 i2c[3] = 0;
721 break;
722 case 1: /* 50 hz */
722103e3
HG
723 i2c[3] = (sd->sensor == SENSOR_OV6650)
724 ? 0x4f : 0x8a;
66f35821
HG
725 break;
726 }
d87616f5 727 i2c[1] = sd->sensor_addr;
66f35821
HG
728 if (i2c_w(gspca_dev, i2c) < 0)
729 PDEBUG(D_ERR, "i2c error setfreq");
730 break;
731 }
732 }
733}
734
dcef3237
HG
735static void do_autogain(struct gspca_dev *gspca_dev)
736{
737 struct sd *sd = (struct sd *) gspca_dev;
738 int avg_lum = atomic_read(&sd->avg_lum);
739
740 if (avg_lum == -1)
741 return;
742
743 if (sd->autogain_ignore_frames > 0)
744 sd->autogain_ignore_frames--;
745 else if (gspca_auto_gain_n_exposure(gspca_dev, avg_lum,
746 sd->brightness * DESIRED_AVG_LUM / 127,
a975a527
HG
747 AUTOGAIN_DEADZONE, GAIN_KNEE, EXPOSURE_KNEE)) {
748 PDEBUG(D_FRAM, "autogain: gain changed: gain: %d expo: %d\n",
749 (int)sd->gain, (int)sd->exposure);
dcef3237 750 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
a975a527 751 }
6a7eba24
JFM
752}
753
754/* this function is called at probe time */
755static int sd_config(struct gspca_dev *gspca_dev,
756 const struct usb_device_id *id)
757{
758 struct sd *sd = (struct sd *) gspca_dev;
759 struct cam *cam;
6a7eba24
JFM
760 int sif = 0;
761
dcef3237
HG
762 /* nctrls depends upon the sensor, so we use a per cam copy */
763 memcpy(&sd->sd_desc, gspca_dev->sd_desc, sizeof(struct sd_desc));
764 gspca_dev->sd_desc = &sd->sd_desc;
765
5da162e7
JFM
766 /* copy the webcam info from the device id */
767 sd->sensor = (id->driver_info >> 24) & 0xff;
768 if (id->driver_info & (F_GAIN << 16))
769 sd->sensor_has_gain = 1;
770 if (id->driver_info & (F_AUTO << 16))
771 sd->sd_desc.dq_callback = do_autogain;
772 if (id->driver_info & (F_SIF << 16))
773 sif = 1;
774 if (id->driver_info & (F_H18 << 16))
775 sd->fr_h_sz = 18; /* size of frame header */
776 else
777 sd->fr_h_sz = 12;
778 sd->sd_desc.nctrls = (id->driver_info >> 8) & 0xff;
779 sd->sensor_addr = id->driver_info & 0xff;
6a7eba24
JFM
780
781 cam = &gspca_dev->cam;
6a7eba24
JFM
782 cam->epaddr = 0x01;
783 if (!sif) {
784 cam->cam_mode = vga_mode;
51fc8e3b 785 cam->nmodes = ARRAY_SIZE(vga_mode);
6a7eba24
JFM
786 } else {
787 cam->cam_mode = sif_mode;
51fc8e3b 788 cam->nmodes = ARRAY_SIZE(sif_mode);
6a7eba24 789 }
dcef3237
HG
790 sd->brightness = BRIGHTNESS_DEF;
791 sd->gain = GAIN_DEF;
792 sd->exposure = EXPOSURE_DEF;
6af492e5 793 sd->autogain = AUTOGAIN_DEF;
12ff9126 794 sd->freq = FREQ_DEF;
6af492e5 795
6a7eba24
JFM
796 return 0;
797}
798
799/* this function is called at open time */
800static int sd_open(struct gspca_dev *gspca_dev)
801{
739570bb
JFM
802 reg_r(gspca_dev, 0x00);
803 if (gspca_dev->usb_buf[0] != 0x10)
6a7eba24
JFM
804 return -ENODEV;
805 return 0;
806}
807
739570bb 808static void pas106_i2cinit(struct gspca_dev *gspca_dev)
6a7eba24
JFM
809{
810 int i;
811 const __u8 *data;
812 __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
813
814 i = ARRAY_SIZE(pas106_data);
815 data = pas106_data[0];
816 while (--i >= 0) {
817 memcpy(&i2c1[2], data, 2);
818 /* copy 2 bytes from the template */
739570bb 819 if (i2c_w(gspca_dev, i2c1) < 0)
6a7eba24
JFM
820 PDEBUG(D_ERR, "i2c error pas106");
821 data += 2;
822 }
823}
824
825/* -- start the camera -- */
826static void sd_start(struct gspca_dev *gspca_dev)
827{
828 struct sd *sd = (struct sd *) gspca_dev;
6af492e5 829 int mode, l = 0x1f;
6a7eba24 830 const __u8 *sn9c10x;
6a7eba24
JFM
831 __u8 reg17_19[3];
832
c2446b3e 833 mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
6a7eba24
JFM
834 switch (sd->sensor) {
835 case SENSOR_HV7131R:
836 sn9c10x = initHv7131;
837 reg17_19[0] = 0x60;
838 reg17_19[1] = (mode << 4) | 0x8a;
839 reg17_19[2] = 0x20;
840 break;
841 case SENSOR_OV6650:
842 sn9c10x = initOv6650;
843 reg17_19[0] = 0x68;
844 reg17_19[1] = (mode << 4) | 0x8b;
845 reg17_19[2] = 0x20;
846 break;
847 case SENSOR_OV7630:
6af492e5
HG
848 if (sd->fr_h_sz == 18) { /* SN9C103 */
849 sn9c10x = initOv7630_3;
850 l = sizeof initOv7630_3;
851 } else
852 sn9c10x = initOv7630;
6a7eba24
JFM
853 reg17_19[0] = 0x68;
854 reg17_19[1] = (mode << 4) | COMP2;
855 reg17_19[2] = MCK_INIT1;
856 break;
857 case SENSOR_PAS106:
858 sn9c10x = initPas106;
859 reg17_19[0] = 0x24; /* 0x28 */
860 reg17_19[1] = (mode << 4) | COMP1;
861 reg17_19[2] = MCK_INIT1;
862 break;
863 case SENSOR_PAS202:
864 sn9c10x = initPas202;
865 reg17_19[0] = mode ? 0x24 : 0x20;
866 reg17_19[1] = (mode << 4) | 0x89;
867 reg17_19[2] = 0x20;
868 break;
869 case SENSOR_TAS5110:
870 sn9c10x = initTas5110;
871 reg17_19[0] = 0x60;
872 reg17_19[1] = (mode << 4) | 0x86;
873 reg17_19[2] = 0x2b; /* 0xf3; */
874 break;
875 default:
876/* case SENSOR_TAS5130CXX: */
877 sn9c10x = initTas5130;
878 reg17_19[0] = 0x60;
879 reg17_19[1] = (mode << 4) | COMP;
880 reg17_19[2] = mode ? 0x23 : 0x43;
881 break;
882 }
6af492e5 883
6a7eba24 884 /* reg 0x01 bit 2 video transfert on */
fff4205f 885 reg_w(gspca_dev, 0x01, &sn9c10x[0x01 - 1], 1);
6a7eba24 886 /* reg 0x17 SensorClk enable inv Clk 0x60 */
fff4205f 887 reg_w(gspca_dev, 0x17, &sn9c10x[0x17 - 1], 1);
6a7eba24 888 /* Set the registers from the template */
739570bb 889 reg_w_big(gspca_dev, 0x01, sn9c10x, l);
6a7eba24
JFM
890 switch (sd->sensor) {
891 case SENSOR_HV7131R:
739570bb 892 i2c_w_vector(gspca_dev, hv7131_sensor_init,
6a7eba24
JFM
893 sizeof hv7131_sensor_init);
894 break;
895 case SENSOR_OV6650:
739570bb 896 i2c_w_vector(gspca_dev, ov6650_sensor_init,
6a7eba24
JFM
897 sizeof ov6650_sensor_init);
898 break;
899 case SENSOR_OV7630:
739570bb 900 i2c_w_vector(gspca_dev, ov7630_sensor_init,
6a7eba24 901 sizeof ov7630_sensor_init);
6af492e5
HG
902 if (sd->fr_h_sz == 18) { /* SN9C103 */
903 const __u8 i2c[] = { 0xa0, 0x21, 0x13, 0x80, 0x00,
904 0x00, 0x00, 0x10 };
905 i2c_w(gspca_dev, i2c);
906 }
6a7eba24
JFM
907 break;
908 case SENSOR_PAS106:
739570bb 909 pas106_i2cinit(gspca_dev);
6a7eba24
JFM
910 break;
911 case SENSOR_PAS202:
739570bb 912 i2c_w_vector(gspca_dev, pas202_sensor_init,
6a7eba24
JFM
913 sizeof pas202_sensor_init);
914 break;
915 case SENSOR_TAS5110:
739570bb 916 i2c_w_vector(gspca_dev, tas5110_sensor_init,
6a7eba24
JFM
917 sizeof tas5110_sensor_init);
918 break;
919 default:
920/* case SENSOR_TAS5130CXX: */
739570bb 921 i2c_w_vector(gspca_dev, tas5130_sensor_init,
6a7eba24
JFM
922 sizeof tas5130_sensor_init);
923 break;
924 }
3647fea8
HG
925 /* H_size V_size 0x28, 0x1e -> 640x480. 0x16, 0x12 -> 352x288 */
926 reg_w(gspca_dev, 0x15, &sn9c10x[0x15 - 1], 2);
6a7eba24 927 /* compression register */
739570bb 928 reg_w(gspca_dev, 0x18, &reg17_19[1], 1);
794af52a
AZ
929 /* H_start */
930 reg_w(gspca_dev, 0x12, &sn9c10x[0x12 - 1], 1);
931 /* V_START */
932 reg_w(gspca_dev, 0x13, &sn9c10x[0x13 - 1], 1);
6a7eba24
JFM
933 /* reset 0x17 SensorClk enable inv Clk 0x60 */
934 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
739570bb 935 reg_w(gspca_dev, 0x17, &reg17_19[0], 1);
6a7eba24 936 /*MCKSIZE ->3 */ /*fixme: not ov7630*/
794af52a 937 reg_w(gspca_dev, 0x19, &reg17_19[2], 1);
6a7eba24 938 /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
739570bb 939 reg_w(gspca_dev, 0x1c, &sn9c10x[0x1c - 1], 4);
6a7eba24 940 /* Enable video transfert */
739570bb 941 reg_w(gspca_dev, 0x01, &sn9c10x[0], 1);
6a7eba24 942 /* Compression */
739570bb 943 reg_w(gspca_dev, 0x18, &reg17_19[1], 2);
6a7eba24
JFM
944 msleep(20);
945
6af492e5
HG
946 sd->reg11 = -1;
947
dcef3237 948 setgain(gspca_dev);
6a7eba24 949 setbrightness(gspca_dev);
dcef3237 950 setexposure(gspca_dev);
66f35821 951 setfreq(gspca_dev);
dcef3237 952
6af492e5 953 sd->frames_to_drop = 0;
dcef3237
HG
954 sd->autogain_ignore_frames = 0;
955 atomic_set(&sd->avg_lum, -1);
6a7eba24
JFM
956}
957
958static void sd_stopN(struct gspca_dev *gspca_dev)
959{
51fc8e3b 960 __u8 ByteSend;
6a7eba24
JFM
961
962 ByteSend = 0x09; /* 0X00 */
739570bb 963 reg_w(gspca_dev, 0x01, &ByteSend, 1);
6a7eba24
JFM
964}
965
966static void sd_stop0(struct gspca_dev *gspca_dev)
967{
968}
969
970static void sd_close(struct gspca_dev *gspca_dev)
971{
972}
973
974static void sd_pkt_scan(struct gspca_dev *gspca_dev,
975 struct gspca_frame *frame, /* target */
976 unsigned char *data, /* isoc packet */
977 int len) /* iso packet length */
978{
0d2a722d 979 int i;
dcef3237 980 struct sd *sd = (struct sd *) gspca_dev;
6a7eba24 981
c36260ee
HG
982 /* frames start with:
983 * ff ff 00 c4 c4 96 synchro
984 * 00 (unknown)
985 * xx (frame sequence / size / compression)
986 * (xx) (idem - extra byte for sn9c103)
987 * ll mm brightness sum inside auto exposure
988 * ll mm brightness sum outside auto exposure
989 * (xx xx xx xx xx) audio values for snc103
990 */
6a7eba24 991 if (len > 6 && len < 24) {
0d2a722d
HG
992 for (i = 0; i < len - 6; i++) {
993 if (data[0 + i] == 0xff
994 && data[1 + i] == 0xff
995 && data[2 + i] == 0x00
996 && data[3 + i] == 0xc4
997 && data[4 + i] == 0xc4
998 && data[5 + i] == 0x96) { /* start of frame */
6af492e5
HG
999 int lum = -1;
1000 int pkt_type = LAST_PACKET;
1001
c36260ee 1002 if (len - i < sd->fr_h_sz) {
c36260ee
HG
1003 PDEBUG(D_STREAM, "packet too short to"
1004 " get avg brightness");
1005 } else if (sd->fr_h_sz == 12) {
6af492e5 1006 lum = data[i + 8] + (data[i + 9] << 8);
dcef3237 1007 } else {
6af492e5
HG
1008 lum = data[i + 9] +
1009 (data[i + 10] << 8);
dcef3237 1010 }
6af492e5
HG
1011 if (lum == 0) {
1012 lum = -1;
1013 sd->frames_to_drop = 2;
1014 }
1015 atomic_set(&sd->avg_lum, lum);
1016
1017 if (sd->frames_to_drop) {
1018 sd->frames_to_drop--;
1019 pkt_type = DISCARD_PACKET;
1020 }
1021
1022 frame = gspca_frame_add(gspca_dev, pkt_type,
1023 frame, data, 0);
553b9fa4
AZ
1024 data += i + sd->fr_h_sz;
1025 len -= i + sd->fr_h_sz;
6a7eba24
JFM
1026 gspca_frame_add(gspca_dev, FIRST_PACKET,
1027 frame, data, len);
1028 return;
1029 }
1030 }
1031 }
1032 gspca_frame_add(gspca_dev, INTER_PACKET,
1033 frame, data, len);
1034}
1035
1036static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
1037{
1038 struct sd *sd = (struct sd *) gspca_dev;
1039
1040 sd->brightness = val;
1041 if (gspca_dev->streaming)
1042 setbrightness(gspca_dev);
1043 return 0;
1044}
1045
1046static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
1047{
1048 struct sd *sd = (struct sd *) gspca_dev;
1049
1050 *val = sd->brightness;
1051 return 0;
1052}
1053
dcef3237
HG
1054static int sd_setgain(struct gspca_dev *gspca_dev, __s32 val)
1055{
1056 struct sd *sd = (struct sd *) gspca_dev;
1057
1058 sd->gain = val;
1059 if (gspca_dev->streaming)
1060 setgain(gspca_dev);
1061 return 0;
1062}
1063
1064static int sd_getgain(struct gspca_dev *gspca_dev, __s32 *val)
6a7eba24
JFM
1065{
1066 struct sd *sd = (struct sd *) gspca_dev;
1067
dcef3237
HG
1068 *val = sd->gain;
1069 return 0;
1070}
1071
1072static int sd_setexposure(struct gspca_dev *gspca_dev, __s32 val)
1073{
1074 struct sd *sd = (struct sd *) gspca_dev;
1075
1076 sd->exposure = val;
6a7eba24 1077 if (gspca_dev->streaming)
dcef3237
HG
1078 setexposure(gspca_dev);
1079 return 0;
1080}
1081
1082static int sd_getexposure(struct gspca_dev *gspca_dev, __s32 *val)
1083{
1084 struct sd *sd = (struct sd *) gspca_dev;
1085
1086 *val = sd->exposure;
1087 return 0;
1088}
1089
1090static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val)
1091{
1092 struct sd *sd = (struct sd *) gspca_dev;
1093
1094 sd->autogain = val;
1095 /* when switching to autogain set defaults to make sure
1096 we are on a valid point of the autogain gain /
1097 exposure knee graph, and give this change time to
1098 take effect before doing autogain. */
1099 if (sd->autogain) {
1100 sd->exposure = EXPOSURE_DEF;
1101 sd->gain = GAIN_DEF;
1102 if (gspca_dev->streaming) {
1103 sd->autogain_ignore_frames = AUTOGAIN_IGNORE_FRAMES;
1104 setexposure(gspca_dev);
1105 setgain(gspca_dev);
1106 }
1107 }
1108
6a7eba24
JFM
1109 return 0;
1110}
1111
dcef3237 1112static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val)
6a7eba24
JFM
1113{
1114 struct sd *sd = (struct sd *) gspca_dev;
1115
dcef3237 1116 *val = sd->autogain;
6a7eba24
JFM
1117 return 0;
1118}
1119
66f35821
HG
1120static int sd_setfreq(struct gspca_dev *gspca_dev, __s32 val)
1121{
1122 struct sd *sd = (struct sd *) gspca_dev;
1123
1124 sd->freq = val;
1125 if (gspca_dev->streaming)
1126 setfreq(gspca_dev);
1127 return 0;
1128}
1129
1130static int sd_getfreq(struct gspca_dev *gspca_dev, __s32 *val)
1131{
1132 struct sd *sd = (struct sd *) gspca_dev;
1133
1134 *val = sd->freq;
1135 return 0;
1136}
1137
1138static int sd_querymenu(struct gspca_dev *gspca_dev,
1139 struct v4l2_querymenu *menu)
1140{
1141 switch (menu->id) {
1142 case V4L2_CID_POWER_LINE_FREQUENCY:
1143 switch (menu->index) {
1144 case 0: /* V4L2_CID_POWER_LINE_FREQUENCY_DISABLED */
1145 strcpy((char *) menu->name, "NoFliker");
1146 return 0;
1147 case 1: /* V4L2_CID_POWER_LINE_FREQUENCY_50HZ */
1148 strcpy((char *) menu->name, "50 Hz");
1149 return 0;
1150 case 2: /* V4L2_CID_POWER_LINE_FREQUENCY_60HZ */
1151 strcpy((char *) menu->name, "60 Hz");
1152 return 0;
1153 }
1154 break;
1155 }
1156 return -EINVAL;
1157}
1158
6a7eba24 1159/* sub-driver description */
dcef3237 1160static const struct sd_desc sd_desc = {
6a7eba24
JFM
1161 .name = MODULE_NAME,
1162 .ctrls = sd_ctrls,
1163 .nctrls = ARRAY_SIZE(sd_ctrls),
1164 .config = sd_config,
1165 .open = sd_open,
1166 .start = sd_start,
1167 .stopN = sd_stopN,
1168 .stop0 = sd_stop0,
1169 .close = sd_close,
1170 .pkt_scan = sd_pkt_scan,
66f35821 1171 .querymenu = sd_querymenu,
6a7eba24
JFM
1172};
1173
1174/* -- module initialisation -- */
5da162e7
JFM
1175#define SFCI(sensor, flags, nctrls, i2c_addr) \
1176 .driver_info = (SENSOR_ ## sensor << 24) \
1177 | ((flags) << 16) \
1178 | ((nctrls) << 8) \
1179 | (i2c_addr)
6a7eba24 1180static __devinitdata struct usb_device_id device_table[] = {
c41492c8 1181#ifndef CONFIG_USB_SN9C102
5da162e7
JFM
1182 {USB_DEVICE(0x0c45, 0x6001), /* SN9C102 */
1183 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1184 {USB_DEVICE(0x0c45, 0x6005), /* SN9C101 */
1185 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1186 {USB_DEVICE(0x0c45, 0x6007), /* SN9C101 */
1187 SFCI(TAS5110, F_GAIN|F_AUTO|F_SIF, 4, 0)},
1188 {USB_DEVICE(0x0c45, 0x6009), /* SN9C101 */
1189 SFCI(PAS106, F_SIF, 2, 0)},
1190 {USB_DEVICE(0x0c45, 0x600d), /* SN9C101 */
1191 SFCI(PAS106, F_SIF, 2, 0)},
5de39b2b 1192#endif
5da162e7
JFM
1193 {USB_DEVICE(0x0c45, 0x6011), /* SN9C101 - SN9C101G */
1194 SFCI(OV6650, F_GAIN|F_AUTO|F_SIF, 5, 0x60)},
5de39b2b 1195#ifndef CONFIG_USB_SN9C102
5da162e7 1196 {USB_DEVICE(0x0c45, 0x6019), /* SN9C101 */
c52e4f58 1197 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
5da162e7
JFM
1198 {USB_DEVICE(0x0c45, 0x6024), /* SN9C102 */
1199 SFCI(TAS5130CXX, 0, 2, 0)},
1200 {USB_DEVICE(0x0c45, 0x6025), /* SN9C102 */
1201 SFCI(TAS5130CXX, 0, 2, 0)},
1202 {USB_DEVICE(0x0c45, 0x6028), /* SN9C102 */
1203 SFCI(PAS202, 0, 2, 0)},
1204 {USB_DEVICE(0x0c45, 0x6029), /* SN9C101 */
1205 SFCI(PAS106, F_SIF, 2, 0)},
1206 {USB_DEVICE(0x0c45, 0x602c), /* SN9C102 */
c52e4f58 1207 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
5da162e7
JFM
1208 {USB_DEVICE(0x0c45, 0x602d), /* SN9C102 */
1209 SFCI(HV7131R, 0, 2, 0)},
1210 {USB_DEVICE(0x0c45, 0x602e), /* SN9C102 */
c52e4f58 1211 SFCI(OV7630, F_GAIN|F_AUTO, 5, 0x21)},
5da162e7
JFM
1212 {USB_DEVICE(0x0c45, 0x60af), /* SN9C103 */
1213 SFCI(PAS202, F_H18, 2, 0)},
1214 {USB_DEVICE(0x0c45, 0x60b0), /* SN9C103 */
c52e4f58 1215 SFCI(OV7630, F_GAIN|F_AUTO|F_H18, 5, 0x21)},
c41492c8 1216#endif
6a7eba24
JFM
1217 {}
1218};
1219MODULE_DEVICE_TABLE(usb, device_table);
1220
1221/* -- device connect -- */
1222static int sd_probe(struct usb_interface *intf,
1223 const struct usb_device_id *id)
1224{
1225 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1226 THIS_MODULE);
1227}
1228
1229static struct usb_driver sd_driver = {
1230 .name = MODULE_NAME,
1231 .id_table = device_table,
1232 .probe = sd_probe,
1233 .disconnect = gspca_disconnect,
6a709749
JFM
1234#ifdef CONFIG_PM
1235 .suspend = gspca_suspend,
1236 .resume = gspca_resume,
1237#endif
6a7eba24
JFM
1238};
1239
1240/* -- module insert / remove -- */
1241static int __init sd_mod_init(void)
1242{
1243 if (usb_register(&sd_driver) < 0)
1244 return -1;
10b0e96e 1245 PDEBUG(D_PROBE, "registered");
6a7eba24
JFM
1246 return 0;
1247}
1248static void __exit sd_mod_exit(void)
1249{
1250 usb_deregister(&sd_driver);
1251 PDEBUG(D_PROBE, "deregistered");
1252}
1253
1254module_init(sd_mod_init);
1255module_exit(sd_mod_exit);