]> err.no Git - linux-2.6/blob - drivers/media/video/gspca/sonixb.c
V4L/DVB (8193): gspca: Input buffer may be changed on reg write.
[linux-2.6] / drivers / media / video / gspca / sonixb.c
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
27 #define DRIVER_VERSION_NUMBER   KERNEL_VERSION(2, 1, 3)
28 static const char version[] = "2.1.3";
29
30 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31 MODULE_DESCRIPTION("GSPCA/SN9C102 USB Camera Driver");
32 MODULE_LICENSE("GPL");
33
34 /* specific webcam descriptor */
35 struct sd {
36         struct gspca_dev gspca_dev;     /* !! must be the first item */
37
38         unsigned char brightness;
39         unsigned char contrast;
40
41         char sensor;                    /* Type of image sensor chip */
42 #define SENSOR_HV7131R 0
43 #define SENSOR_OV6650 1
44 #define SENSOR_OV7630 2
45 #define SENSOR_OV7630_3 3
46 #define SENSOR_PAS106 4
47 #define SENSOR_PAS202 5
48 #define SENSOR_TAS5110 6
49 #define SENSOR_TAS5130CXX 7
50 };
51
52 #define COMP2 0x8f
53 #define COMP 0xc7               /* 0x87 //0x07 */
54 #define COMP1 0xc9              /* 0x89 //0x09 */
55
56 #define MCK_INIT 0x63
57 #define MCK_INIT1 0x20          /*fixme: Bayer - 0x50 for JPEG ??*/
58
59 #define SYS_CLK 0x04
60
61 /* V4L2 controls supported by the driver */
62 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
63 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
64 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
65 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
66
67 static struct ctrl sd_ctrls[] = {
68 #define SD_BRIGHTNESS 0
69         {
70             {
71                 .id      = V4L2_CID_BRIGHTNESS,
72                 .type    = V4L2_CTRL_TYPE_INTEGER,
73                 .name    = "Brightness",
74                 .minimum = 0,
75                 .maximum = 255,
76                 .step    = 1,
77                 .default_value = 127,
78             },
79             .set = sd_setbrightness,
80             .get = sd_getbrightness,
81         },
82 #define SD_CONTRAST 1
83         {
84             {
85                 .id      = V4L2_CID_CONTRAST,
86                 .type    = V4L2_CTRL_TYPE_INTEGER,
87                 .name    = "Contrast",
88                 .minimum = 0,
89                 .maximum = 255,
90                 .step    = 1,
91                 .default_value = 127,
92             },
93             .set = sd_setcontrast,
94             .get = sd_getcontrast,
95         },
96 };
97
98 /* fixme: should have V4L2_PIX_FMT_SN9C10X */
99 static struct cam_mode vga_mode[] = {
100         {V4L2_PIX_FMT_SN9C10X, 160, 120, 2},
101         {V4L2_PIX_FMT_SN9C10X, 320, 240, 1},
102         {V4L2_PIX_FMT_SN9C10X, 640, 480, 0},
103 };
104 static struct cam_mode sif_mode[] = {
105         {V4L2_PIX_FMT_SN9C10X, 176, 144, 1},
106         {V4L2_PIX_FMT_SN9C10X, 352, 288, 0},
107 };
108
109 static const __u8 probe_ov7630[] = {0x08, 0x44};
110
111 static const __u8 initHv7131[] = {
112         0x46, 0x77, 0x00, 0x04, 0x00, 0x00, 0x00, 0x80, 0x11, 0x00, 0x00, 0x00,
113         0x00, 0x00,
114         0x00, 0x00, 0x00, 0x03, 0x01, 0x00,     /* shift from 0x02 0x01 0x00 */
115         0x28, 0x1e, 0x60, 0x8a, 0x20,
116         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c
117 };
118 static const __u8 hv7131_sensor_init[][8] = {
119         {0xc0, 0x11, 0x31, 0x38, 0x2a, 0x2e, 0x00, 0x10},
120         {0xa0, 0x11, 0x01, 0x08, 0x2a, 0x2e, 0x00, 0x10},
121         {0xb0, 0x11, 0x20, 0x00, 0xd0, 0x2e, 0x00, 0x10},
122         {0xc0, 0x11, 0x25, 0x03, 0x0e, 0x28, 0x00, 0x16},
123         {0xa0, 0x11, 0x30, 0x10, 0x0e, 0x28, 0x00, 0x15},
124 };
125 static const __u8 initOv6650[] = {
126         0x44, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
127         0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
128         0x00, 0x02, 0x01, 0x0a, 0x16, 0x12, 0x68, 0x0b,
129         0x10, 0x1d, 0x10, 0x00, 0x06, 0x1f, 0x00
130 };
131 static const __u8 ov6650_sensor_init[][8] =
132 {
133         /* Bright, contrast, etc are set througth SCBB interface.
134          * AVCAP on win2 do not send any data on this   controls. */
135         /* Anyway, some registers appears to alter bright and constrat */
136         {0xa0, 0x60, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
137         {0xd0, 0x60, 0x11, 0xc0, 0x1b, 0x18, 0xc1, 0x10},
138         {0xb0, 0x60, 0x15, 0x00, 0x02, 0x18, 0xc1, 0x10},
139 /*      {0xa0, 0x60, 0x1b, 0x01, 0x02, 0x18, 0xc1, 0x10},
140                  * THIS SET GREEN SCREEN
141                  * (pixels could be innverted in decode kind of "brg",
142                  * but blue wont be there. Avoid this data ... */
143         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10}, /* format out? */
144         {0xd0, 0x60, 0x26, 0x01, 0x14, 0xd8, 0xa4, 0x10},
145         {0xa0, 0x60, 0x30, 0x3d, 0x0A, 0xd8, 0xa4, 0x10},
146         {0xb0, 0x60, 0x60, 0x66, 0x68, 0xd8, 0xa4, 0x10},
147         {0xa0, 0x60, 0x68, 0x04, 0x68, 0xd8, 0xa4, 0x10},
148         {0xd0, 0x60, 0x17, 0x24, 0xd6, 0x04, 0x94, 0x10}, /* Clipreg */
149         {0xa0, 0x60, 0x10, 0x5d, 0x99, 0x04, 0x94, 0x16},
150         {0xa0, 0x60, 0x2d, 0x0a, 0x99, 0x04, 0x94, 0x16},
151         {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16},
152         {0xa0, 0x60, 0x33, 0x40, 0x99, 0x04, 0x94, 0x16},
153         {0xa0, 0x60, 0x11, 0xc0, 0x99, 0x04, 0x94, 0x16},
154         {0xa0, 0x60, 0x00, 0x16, 0x99, 0x04, 0x94, 0x15}, /* bright / Lumino */
155         {0xa0, 0x60, 0x2b, 0xab, 0x99, 0x04, 0x94, 0x15},
156                                                         /* ?flicker o brillo */
157         {0xa0, 0x60, 0x2d, 0x2a, 0x99, 0x04, 0x94, 0x15},
158         {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16},
159         {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16},
160         {0xa0, 0x60, 0x33, 0x00, 0x99, 0x04, 0x94, 0x16},
161         {0xa0, 0x60, 0x10, 0x57, 0x99, 0x04, 0x94, 0x16},
162         {0xa0, 0x60, 0x2d, 0x2b, 0x99, 0x04, 0x94, 0x16},
163         {0xa0, 0x60, 0x32, 0x00, 0x99, 0x04, 0x94, 0x16},
164                 /* Low Light (Enabled: 0x32 0x1 | Disabled: 0x32 0x00) */
165         {0xa0, 0x60, 0x33, 0x29, 0x99, 0x04, 0x94, 0x16},
166                 /* Low Ligth (Enabled: 0x33 0x13 | Disabled: 0x33 0x29) */
167 /*      {0xa0, 0x60, 0x11, 0xc1, 0x99, 0x04, 0x94, 0x16}, */
168         {0xa0, 0x60, 0x00, 0x17, 0x99, 0x04, 0x94, 0x15}, /* clip? r */
169         {0xa0, 0x60, 0x00, 0x18, 0x99, 0x04, 0x94, 0x15}, /* clip? r */
170 };
171 static const __u8 initOv7630[] = {
172         0x04, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, /* r01 .. r08 */
173         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* r09 .. r10 */
174         0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
175         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
176         0x68, COMP1, MCK_INIT1,                         /* r17 .. r19 */
177         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
178 };
179 static const __u8 initOv7630_3[] = {
180         0x44, 0x44, 0x00, 0x1a, 0x20, 0x20, 0x20, 0x80, /* r01 .. r08 */
181         0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, /* r09 .. r10 */
182         0x00, 0x02, 0x01, 0x0a,                         /* r11 .. r14 */
183         0x28, 0x1e,                     /* H & V sizes     r15 .. r16 */
184         0x68, COMP1, MCK_INIT1,                         /* r17 .. r19 */
185         0x1d, 0x10, 0x02, 0x03, 0x0f, 0x0c              /* r1a .. r1f */
186 };
187 static const __u8 ov7630_sensor_init_com[][8] = {
188         {0xa0, 0x21, 0x12, 0x80, 0x00, 0x00, 0x00, 0x10},
189         {0xb0, 0x21, 0x01, 0x77, 0x3a, 0x00, 0x00, 0x10},
190 /*      {0xd0, 0x21, 0x12, 0x7c, 0x01, 0x80, 0x34, 0x10},          jfm */
191         {0xd0, 0x21, 0x12, 0x78, 0x00, 0x80, 0x34, 0x10},       /* jfm */
192         {0xa0, 0x21, 0x1b, 0x04, 0x00, 0x80, 0x34, 0x10},
193         {0xa0, 0x21, 0x20, 0x44, 0x00, 0x80, 0x34, 0x10},
194         {0xa0, 0x21, 0x23, 0xee, 0x00, 0x80, 0x34, 0x10},
195         {0xd0, 0x21, 0x26, 0xa0, 0x9a, 0xa0, 0x30, 0x10},
196         {0xb0, 0x21, 0x2a, 0x80, 0x00, 0xa0, 0x30, 0x10},
197         {0xb0, 0x21, 0x2f, 0x3d, 0x24, 0xa0, 0x30, 0x10},
198         {0xa0, 0x21, 0x32, 0x86, 0x24, 0xa0, 0x30, 0x10},
199 /*      {0xb0, 0x21, 0x60, 0xa9, 0x4a, 0xa0, 0x30, 0x10},          jfm */
200         {0xb0, 0x21, 0x60, 0xa9, 0x42, 0xa0, 0x30, 0x10},       /* jfm */
201         {0xa0, 0x21, 0x65, 0x00, 0x42, 0xa0, 0x30, 0x10},
202         {0xa0, 0x21, 0x69, 0x38, 0x42, 0xa0, 0x30, 0x10},
203         {0xc0, 0x21, 0x6f, 0x88, 0x0b, 0x00, 0x30, 0x10},
204         {0xc0, 0x21, 0x74, 0x21, 0x8e, 0x00, 0x30, 0x10},
205         {0xa0, 0x21, 0x7d, 0xf7, 0x8e, 0x00, 0x30, 0x10},
206         {0xd0, 0x21, 0x17, 0x1c, 0xbd, 0x06, 0xf6, 0x10},
207 };
208 static const __u8 ov7630_sensor_init[][8] = {
209         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, /* delay 200ms */
210         {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x10},       /* jfm */
211         {0xa0, 0x21, 0x10, 0x57, 0xbd, 0x06, 0xf6, 0x16},
212         {0xa0, 0x21, 0x76, 0x02, 0xbd, 0x06, 0xf6, 0x16},
213         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
214 };
215 static const __u8 ov7630_sensor_init_3[][8] = {
216         {0xa0, 0x21, 0x10, 0x36, 0xbd, 0x06, 0xf6, 0x16},       /* exposure */
217         {0xa0, 0x21, 0x76, 0x03, 0xbd, 0x06, 0xf6, 0x16},
218         {0xa0, 0x21, 0x11, 0x01, 0xbd, 0x06, 0xf6, 0x16},
219         {0xa0, 0x21, 0x00, 0x10, 0xbd, 0x06, 0xf6, 0x15},       /* gain */
220 /*      {0xb0, 0x21, 0x2a, 0xc0, 0x3c, 0x06, 0xf6, 0x1d},
221                 * a0 1c,a0 1f,c0 3c frame rate ?line interval from ov6630 */
222 /*      {0xb0, 0x21, 0x2a, 0xa0, 0x1f, 0x06, 0xf6, 0x1d},        * from win */
223         {0xb0, 0x21, 0x2a, 0xa0, 0x1c, 0x06, 0xf6, 0x1d},
224 };
225
226 static const __u8 initPas106[] = {
227         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x40, 0x00, 0x00, 0x00,
228         0x00, 0x00,
229         0x00, 0x00, 0x00, 0x05, 0x01, 0x00,
230         0x16, 0x12, 0x28, COMP1, MCK_INIT1,
231         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
232 };
233 /* compression 0x86 mckinit1 0x2b */
234 static const __u8 pas106_data[][2] = {
235         {0x02, 0x04},           /* Pixel Clock Divider 6 */
236         {0x03, 0x13},           /* Frame Time MSB */
237 /*      {0x03, 0x12},            * Frame Time MSB */
238         {0x04, 0x06},           /* Frame Time LSB */
239 /*      {0x04, 0x05},            * Frame Time LSB */
240         {0x05, 0x65},           /* Shutter Time Line Offset */
241 /*      {0x05, 0x6d},            * Shutter Time Line Offset */
242 /*      {0x06, 0xb1},            * Shutter Time Pixel Offset */
243         {0x06, 0xcd},           /* Shutter Time Pixel Offset */
244         {0x07, 0xc1},           /* Black Level Subtract Sign */
245 /*      {0x07, 0x00},            * Black Level Subtract Sign */
246         {0x08, 0x06},           /* Black Level Subtract Level */
247         {0x08, 0x06},           /* Black Level Subtract Level */
248 /*      {0x08, 0x01},            * Black Level Subtract Level */
249         {0x09, 0x05},           /* Color Gain B Pixel 5 a */
250         {0x0a, 0x04},           /* Color Gain G1 Pixel 1 5 */
251         {0x0b, 0x04},           /* Color Gain G2 Pixel 1 0 5 */
252         {0x0c, 0x05},           /* Color Gain R Pixel 3 1 */
253         {0x0d, 0x00},           /* Color GainH  Pixel */
254         {0x0e, 0x0e},           /* Global Gain */
255         {0x0f, 0x00},           /* Contrast */
256         {0x10, 0x06},           /* H&V synchro polarity */
257         {0x11, 0x06},           /* ?default */
258         {0x12, 0x06},           /* DAC scale */
259         {0x14, 0x02},           /* ?default */
260         {0x13, 0x01},           /* Validate Settings */
261 };
262 static const __u8 initPas202[] = {
263         0x44, 0x44, 0x21, 0x30, 0x00, 0x00, 0x00, 0x80, 0x40, 0x00, 0x00, 0x00,
264         0x00, 0x00,
265         0x00, 0x00, 0x00, 0x07, 0x03, 0x0a,     /* 6 */
266         0x28, 0x1e, 0x28, 0x89, 0x30,
267         0x00, 0x00, 0x02, 0x03, 0x0f, 0x0c
268 };
269 static const __u8 pas202_sensor_init[][8] = {
270         {0xa0, 0x40, 0x02, 0x03, 0x00, 0x00, 0x00, 0x10},
271         {0xd0, 0x40, 0x04, 0x07, 0x34, 0x00, 0x09, 0x10},
272         {0xd0, 0x40, 0x08, 0x01, 0x00, 0x00, 0x01, 0x10},
273         {0xd0, 0x40, 0x0C, 0x00, 0x0C, 0x00, 0x32, 0x10},
274         {0xd0, 0x40, 0x10, 0x00, 0x01, 0x00, 0x63, 0x10},
275         {0xa0, 0x40, 0x15, 0x70, 0x01, 0x00, 0x63, 0x10},
276         {0xa0, 0x40, 0x18, 0x00, 0x01, 0x00, 0x63, 0x10},
277         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
278         {0xa0, 0x40, 0x03, 0x56, 0x01, 0x00, 0x63, 0x10},
279         {0xa0, 0x40, 0x11, 0x01, 0x01, 0x00, 0x63, 0x10},
280         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x10},
281         {0xb0, 0x40, 0x0e, 0x00, 0x3d, 0x00, 0x63, 0x10},
282
283         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
284         {0xa0, 0x40, 0x10, 0x08, 0x3d, 0x00, 0x63, 0x15},
285         {0xa0, 0x40, 0x02, 0x04, 0x3d, 0x00, 0x63, 0x16},
286         {0xa0, 0x40, 0x11, 0x01, 0x3d, 0x00, 0x63, 0x16},
287         {0xb0, 0x40, 0x0e, 0x00, 0x31, 0x00, 0x63, 0x16},
288         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
289         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15},
290         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16},
291 };
292
293 static const __u8 initTas5110[] = {
294         0x44, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
295         0x00, 0x00,
296         0x00, 0x01, 0x00, 0x46, 0x09, 0x0a,     /* shift from 0x45 0x09 0x0a */
297         0x16, 0x12, 0x60, 0x86, 0x2b,
298         0x14, 0x0a, 0x02, 0x02, 0x09, 0x07
299 };
300 static const __u8 tas5110_sensor_init[][8] = {
301         {0x30, 0x11, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x10},
302         {0x30, 0x11, 0x02, 0x20, 0xa9, 0x00, 0x00, 0x10},
303         {0xa0, 0x61, 0x9a, 0xca, 0x00, 0x00, 0x00, 0x17},
304 };
305
306 static const __u8 initTas5130[] = {
307         0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x11, 0x00, 0x00, 0x00,
308         0x00, 0x00,
309         0x00, 0x01, 0x00, 0x69, 0x0c, 0x0a,
310         0x28, 0x1e, 0x60, COMP, MCK_INIT,
311         0x18, 0x10, 0x04, 0x03, 0x11, 0x0c
312 };
313 static const __u8 tas5130_sensor_init[][8] = {
314 /*      {0x30, 0x11, 0x00, 0x40, 0x47, 0x00, 0x00, 0x10},
315                                         * shutter 0x47 short exposure? */
316         {0x30, 0x11, 0x00, 0x40, 0x01, 0x00, 0x00, 0x10},
317                                         /* shutter 0x01 long exposure */
318         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10},
319 };
320
321 static void reg_r(struct usb_device *dev,
322                          __u16 value, __u8 *buffer)
323 {
324         usb_control_msg(dev,
325                         usb_rcvctrlpipe(dev, 0),
326                         0,                      /* request */
327                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
328                         value,
329                         0,                      /* index */
330                         buffer, 1,
331                         500);
332 }
333
334 static void reg_w(struct usb_device *dev,
335                           __u16 value,
336                           const __u8 *buffer,
337                           int len)
338 {
339         __u8 tmpbuf[32];
340
341 #ifdef CONFIG_VIDEO_ADV_DEBUG
342         if (len > sizeof tmpbuf) {
343                 PDEBUG(D_ERR|D_PACK, "reg_w: buffer overflow");
344                 return;
345         }
346 #endif
347         memcpy(tmpbuf, buffer, len);
348         usb_control_msg(dev,
349                         usb_sndctrlpipe(dev, 0),
350                         0x08,                   /* request */
351                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
352                         value,
353                         0,                      /* index */
354                         tmpbuf, len,
355                         500);
356 }
357
358 static int i2c_w(struct usb_device *dev, const __u8 *buffer)
359 {
360         int retry = 60;
361         __u8 ByteReceive;
362
363         /* is i2c ready */
364         reg_w(dev, 0x08, buffer, 8);
365         while (retry--) {
366                 msleep(10);
367                 reg_r(dev, 0x08, &ByteReceive);
368                 if (ByteReceive == 4)
369                         return 0;
370         }
371         return -1;
372 }
373
374 static void i2c_w_vector(struct usb_device *dev,
375                         const __u8 buffer[][8], int len)
376 {
377         for (;;) {
378                 reg_w(dev, 0x08, *buffer, 8);
379                 len -= 8;
380                 if (len <= 0)
381                         break;
382                 buffer++;
383         }
384 }
385
386 static void setbrightness(struct gspca_dev *gspca_dev)
387 {
388         struct sd *sd = (struct sd *) gspca_dev;
389         __u8 value;
390
391         switch (sd->sensor) {
392         case SENSOR_OV6650: {
393                 __u8 i2cOV6650[] =
394                         {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
395
396                 i2cOV6650[3] = sd->brightness;
397                 if (i2c_w(gspca_dev->dev, i2cOV6650) < 0)
398                          goto err;
399                 break;
400             }
401         case  SENSOR_OV7630: {
402                 __u8 i2cOV[] =
403                         {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
404
405                 /* change reg 0x06 */
406                 i2cOV[3] = sd->brightness;
407                 if (i2c_w(gspca_dev->dev, i2cOV) < 0)
408                         goto err;
409                 break;
410             }
411         case SENSOR_PAS106: {
412                 __u8 i2c1[] =
413                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
414
415                 i2c1[3] = sd->brightness >> 3;
416                 i2c1[2] = 0x0e;
417                 if (i2c_w(gspca_dev->dev, i2c1) < 0)
418                         goto err;
419                 i2c1[3] = 0x01;
420                 i2c1[2] = 0x13;
421                 if (i2c_w(gspca_dev->dev, i2c1) < 0)
422                         goto err;
423                 break;
424             }
425         case SENSOR_PAS202: {
426                 /* __u8 i2cpexpo1[] =
427                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
428                 __u8 i2cpexpo[] =
429                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
430                 __u8 i2cp202[] =
431                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
432                 static __u8 i2cpdoit[] =
433                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
434
435                 /* change reg 0x10 */
436                 i2cpexpo[4] = 0xff - sd->brightness;
437 /*              if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0)
438                         goto err; */
439 /*              if(i2c_w(gspca_dev->dev,i2cpdoit) < 0)
440                         goto err; */
441                 if (i2c_w(gspca_dev->dev, i2cpexpo) < 0)
442                         goto err;
443                 if (i2c_w(gspca_dev->dev, i2cpdoit) < 0)
444                         goto err;
445                 i2cp202[3] = sd->brightness >> 3;
446                 if (i2c_w(gspca_dev->dev, i2cp202) < 0)
447                         goto err;
448                 if (i2c_w(gspca_dev->dev, i2cpdoit) < 0)
449                         goto err;
450                 break;
451             }
452         case SENSOR_TAS5130CXX:
453         case SENSOR_TAS5110: {
454                 __u8 i2c[] =
455                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
456
457                 value = 0xff - sd->brightness;
458                 i2c[4] = value;
459                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
460                 if (i2c_w(gspca_dev->dev, i2c) < 0)
461                         goto err;
462                 break;
463             }
464         }
465         return;
466 err:
467         PDEBUG(D_ERR, "i2c error brightness");
468 }
469 static void setcontrast(struct gspca_dev *gspca_dev)
470 {
471         struct sd *sd = (struct sd *) gspca_dev;
472         __u8 gain;
473         __u8 rgb_value;
474
475         gain = sd->contrast >> 4;
476         /* red and blue gain */
477         rgb_value = gain << 4 | gain;
478         reg_w(gspca_dev->dev, 0x10, &rgb_value, 1);
479         /* green gain */
480         rgb_value = gain;
481         reg_w(gspca_dev->dev, 0x11, &rgb_value, 1);
482 }
483
484 /* this function is called at probe time */
485 static int sd_config(struct gspca_dev *gspca_dev,
486                         const struct usb_device_id *id)
487 {
488         struct sd *sd = (struct sd *) gspca_dev;
489         struct cam *cam;
490 /*      __u16 vendor; */
491         __u16 product;
492         int sif = 0;
493
494 /*      vendor = id->idVendor; */
495         product = id->idProduct;
496 /*      switch (vendor) { */
497 /*      case 0x0c45:                             * Sonix */
498                 switch (product) {
499                 case 0x6001:                    /* SN9C102 */
500                 case 0x6005:                    /* SN9C101 */
501                 case 0x6007:                    /* SN9C101 */
502                         sd->sensor = SENSOR_TAS5110;
503                         sif = 1;
504                         break;
505                 case 0x6009:                    /* SN9C101 */
506                 case 0x600d:                    /* SN9C101 */
507                 case 0x6029:                    /* SN9C101 */
508                         sd->sensor = SENSOR_PAS106;
509                         sif = 1;
510                         break;
511                 case 0x6011:                    /* SN9C101 - SN9C101G */
512                         sd->sensor = SENSOR_OV6650;
513                         sif = 1;
514                         break;
515                 case 0x6019:                    /* SN9C101 */
516                 case 0x602c:                    /* SN9C102 */
517                 case 0x602e:                    /* SN9C102 */
518                         sd->sensor = SENSOR_OV7630;
519                         break;
520                 case 0x60b0:                    /* SN9C103 */
521                         sd->sensor = SENSOR_OV7630_3;
522                         break;
523                 case 0x6024:                    /* SN9C102 */
524                 case 0x6025:                    /* SN9C102 */
525                         sd->sensor = SENSOR_TAS5130CXX;
526                         break;
527                 case 0x6028:                    /* SN9C102 */
528                         sd->sensor = SENSOR_PAS202;
529                         break;
530                 case 0x602d:                    /* SN9C102 */
531                         sd->sensor = SENSOR_HV7131R;
532                         break;
533                 case 0x60af:                    /* SN9C103 */
534                         sd->sensor = SENSOR_PAS202;
535                         break;
536                 }
537 /*              break; */
538 /*      } */
539
540         cam = &gspca_dev->cam;
541         cam->dev_name = (char *) id->driver_info;
542         cam->epaddr = 0x01;
543         if (!sif) {
544                 cam->cam_mode = vga_mode;
545                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
546         } else {
547                 cam->cam_mode = sif_mode;
548                 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
549         }
550         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
551         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
552         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
553                 reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630);
554         return 0;
555 }
556
557 /* this function is called at open time */
558 static int sd_open(struct gspca_dev *gspca_dev)
559 {
560         __u8 ByteReceive;
561
562         reg_r(gspca_dev->dev, 0x00, &ByteReceive);
563         if (ByteReceive != 0x10)
564                 return -ENODEV;
565         return 0;
566 }
567
568 static void pas106_i2cinit(struct usb_device *dev)
569 {
570         int i;
571         const __u8 *data;
572         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
573
574         i = ARRAY_SIZE(pas106_data);
575         data = pas106_data[0];
576         while (--i >= 0) {
577                 memcpy(&i2c1[2], data, 2);
578                                         /* copy 2 bytes from the template */
579                 if (i2c_w(dev, i2c1) < 0)
580                         PDEBUG(D_ERR, "i2c error pas106");
581                 data += 2;
582         }
583 }
584
585 /* -- start the camera -- */
586 static void sd_start(struct gspca_dev *gspca_dev)
587 {
588         struct sd *sd = (struct sd *) gspca_dev;
589         struct usb_device *dev = gspca_dev->dev;
590         int mode, l;
591         const __u8 *sn9c10x;
592         __u8 reg01, reg17;
593         __u8 reg17_19[3];
594
595         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode;
596         switch (sd->sensor) {
597         case SENSOR_HV7131R:
598                 sn9c10x = initHv7131;
599                 reg17_19[0] = 0x60;
600                 reg17_19[1] = (mode << 4) | 0x8a;
601                 reg17_19[2] = 0x20;
602                 break;
603         case SENSOR_OV6650:
604                 sn9c10x = initOv6650;
605                 reg17_19[0] = 0x68;
606                 reg17_19[1] = (mode << 4) | 0x8b;
607                 reg17_19[2] = 0x20;
608                 break;
609         case SENSOR_OV7630:
610                 sn9c10x = initOv7630;
611                 reg17_19[0] = 0x68;
612                 reg17_19[1] = (mode << 4) | COMP2;
613                 reg17_19[2] = MCK_INIT1;
614                 break;
615         case SENSOR_OV7630_3:
616                 sn9c10x = initOv7630_3;
617                 reg17_19[0] = 0x68;
618                 reg17_19[1] = (mode << 4) | COMP2;
619                 reg17_19[2] = MCK_INIT1;
620                 break;
621         case SENSOR_PAS106:
622                 sn9c10x = initPas106;
623                 reg17_19[0] = 0x24;             /* 0x28 */
624                 reg17_19[1] = (mode << 4) | COMP1;
625                 reg17_19[2] = MCK_INIT1;
626                 break;
627         case SENSOR_PAS202:
628                 sn9c10x = initPas202;
629                 reg17_19[0] = mode ? 0x24 : 0x20;
630                 reg17_19[1] = (mode << 4) | 0x89;
631                 reg17_19[2] = 0x20;
632                 break;
633         case SENSOR_TAS5110:
634                 sn9c10x = initTas5110;
635                 reg17_19[0] = 0x60;
636                 reg17_19[1] = (mode << 4) | 0x86;
637                 reg17_19[2] = 0x2b;             /* 0xf3; */
638                 break;
639         default:
640 /*      case SENSOR_TAS5130CXX: */
641                 sn9c10x = initTas5130;
642                 reg17_19[0] = 0x60;
643                 reg17_19[1] = (mode << 4) | COMP;
644                 reg17_19[2] = mode ? 0x23 : 0x43;
645                 break;
646         }
647         switch (sd->sensor) {
648         case SENSOR_OV7630:
649                 reg01 = 0x06;
650                 reg17 = 0x29;
651                 l = 0x10;
652                 break;
653         case SENSOR_OV7630_3:
654                 reg01 = 0x44;
655                 reg17 = 0x68;
656                 l = 0x10;
657                 break;
658         default:
659                 reg01 = sn9c10x[0];
660                 reg17 = sn9c10x[0x17 - 1];
661                 l = 0x1f;
662                 break;
663         }
664
665         /* reg 0x01 bit 2 video transfert on */
666         reg_w(dev, 0x01, &reg01, 1);
667         /* reg 0x17 SensorClk enable inv Clk 0x60 */
668         reg_w(dev, 0x17, &reg17, 1);
669 /*fixme: for ov7630 102
670         reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */
671         /* Set the registers from the template */
672         reg_w(dev, 0x01, sn9c10x, l);
673         switch (sd->sensor) {
674         case SENSOR_HV7131R:
675                 i2c_w_vector(dev, hv7131_sensor_init,
676                                 sizeof hv7131_sensor_init);
677                 break;
678         case SENSOR_OV6650:
679                 i2c_w_vector(dev, ov6650_sensor_init,
680                                 sizeof ov6650_sensor_init);
681                 break;
682         case SENSOR_OV7630:
683                 i2c_w_vector(dev, ov7630_sensor_init_com,
684                                 sizeof ov7630_sensor_init_com);
685                 msleep(200);
686                 i2c_w_vector(dev, ov7630_sensor_init,
687                                 sizeof ov7630_sensor_init);
688                 break;
689         case SENSOR_OV7630_3:
690                 i2c_w_vector(dev, ov7630_sensor_init_com,
691                                 sizeof ov7630_sensor_init_com);
692                 msleep(200);
693                 i2c_w_vector(dev, ov7630_sensor_init_3,
694                                 sizeof ov7630_sensor_init_3);
695                 break;
696         case SENSOR_PAS106:
697                 pas106_i2cinit(dev);
698                 break;
699         case SENSOR_PAS202:
700                 i2c_w_vector(dev, pas202_sensor_init,
701                                 sizeof pas202_sensor_init);
702                 break;
703         case SENSOR_TAS5110:
704                 i2c_w_vector(dev, tas5110_sensor_init,
705                                 sizeof tas5110_sensor_init);
706                 break;
707         default:
708 /*      case SENSOR_TAS5130CXX: */
709                 i2c_w_vector(dev, tas5130_sensor_init,
710                                 sizeof tas5130_sensor_init);
711                 break;
712         }
713         /* H_size V_size  0x28, 0x1e maybe 640x480 */
714         reg_w(dev, 0x15, &sn9c10x[0x15 - 1], 2);
715         /* compression register */
716         reg_w(dev, 0x18, &reg17_19[1], 1);
717         /* H_start */           /*fixme: not ov7630*/
718         reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1);
719         /* V_START */           /*fixme: not ov7630*/
720         reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1);
721         /* reset 0x17 SensorClk enable inv Clk 0x60 */
722                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
723         reg_w(dev, 0x17, &reg17_19[0], 1);
724         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
725         reg_w(dev, 0x19, &reg17_19[2], 1);
726         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
727         reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4);
728         /* Enable video transfert */
729         reg_w(dev, 0x01, &sn9c10x[0], 1);
730         /* Compression */
731         reg_w(dev, 0x18, &reg17_19[1], 2);
732         msleep(20);
733
734         setcontrast(gspca_dev);
735         setbrightness(gspca_dev);
736 }
737
738 static void sd_stopN(struct gspca_dev *gspca_dev)
739 {
740         __u8 ByteSend = 0;
741
742         ByteSend = 0x09;        /* 0X00 */
743         reg_w(gspca_dev->dev, 0x01, &ByteSend, 1);
744 }
745
746 static void sd_stop0(struct gspca_dev *gspca_dev)
747 {
748 }
749
750 static void sd_close(struct gspca_dev *gspca_dev)
751 {
752 }
753
754 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
755                         struct gspca_frame *frame,      /* target */
756                         unsigned char *data,            /* isoc packet */
757                         int len)                        /* iso packet length */
758 {
759         int i;
760
761         if (len > 6 && len < 24) {
762                 for (i = 0; i < len - 6; i++) {
763                         if (data[0 + i] == 0xff
764                             && data[1 + i] == 0xff
765                             && data[2 + i] == 0x00
766                             && data[3 + i] == 0xc4
767                             && data[4 + i] == 0xc4
768                             && data[5 + i] == 0x96) {   /* start of frame */
769                                 frame = gspca_frame_add(gspca_dev, LAST_PACKET,
770                                                         frame, data, 0);
771                                 data += i + 12;
772                                 len -= i + 12;
773                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
774                                                 frame, data, len);
775                                 return;
776                         }
777                 }
778         }
779         gspca_frame_add(gspca_dev, INTER_PACKET,
780                         frame, data, len);
781 }
782
783 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
784 {
785         struct sd *sd = (struct sd *) gspca_dev;
786
787         sd->brightness = val;
788         if (gspca_dev->streaming)
789                 setbrightness(gspca_dev);
790         return 0;
791 }
792
793 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
794 {
795         struct sd *sd = (struct sd *) gspca_dev;
796
797         *val = sd->brightness;
798         return 0;
799 }
800
801 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
802 {
803         struct sd *sd = (struct sd *) gspca_dev;
804
805         sd->contrast = val;
806         if (gspca_dev->streaming)
807                 setcontrast(gspca_dev);
808         return 0;
809 }
810
811 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
812 {
813         struct sd *sd = (struct sd *) gspca_dev;
814
815         *val = sd->contrast;
816         return 0;
817 }
818
819 /* sub-driver description */
820 static struct sd_desc sd_desc = {
821         .name = MODULE_NAME,
822         .ctrls = sd_ctrls,
823         .nctrls = ARRAY_SIZE(sd_ctrls),
824         .config = sd_config,
825         .open = sd_open,
826         .start = sd_start,
827         .stopN = sd_stopN,
828         .stop0 = sd_stop0,
829         .close = sd_close,
830         .pkt_scan = sd_pkt_scan,
831 };
832
833 /* -- module initialisation -- */
834 #define DVNM(name) .driver_info = (kernel_ulong_t) name
835 static __devinitdata struct usb_device_id device_table[] = {
836         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
837         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
838         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
839         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
840         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
841         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia")},
842         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
843         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
844         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
845         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
846         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
847         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
848         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
849         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
850         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
851         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
852         {}
853 };
854 MODULE_DEVICE_TABLE(usb, device_table);
855
856 /* -- device connect -- */
857 static int sd_probe(struct usb_interface *intf,
858                         const struct usb_device_id *id)
859 {
860         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
861                                 THIS_MODULE);
862 }
863
864 static struct usb_driver sd_driver = {
865         .name = MODULE_NAME,
866         .id_table = device_table,
867         .probe = sd_probe,
868         .disconnect = gspca_disconnect,
869 };
870
871 /* -- module insert / remove -- */
872 static int __init sd_mod_init(void)
873 {
874         if (usb_register(&sd_driver) < 0)
875                 return -1;
876         PDEBUG(D_PROBE, "v%s registered", version);
877         return 0;
878 }
879 static void __exit sd_mod_exit(void)
880 {
881         usb_deregister(&sd_driver);
882         PDEBUG(D_PROBE, "deregistered");
883 }
884
885 module_init(sd_mod_init);
886 module_exit(sd_mod_exit);