d26255ddfd5b42f3adc3a0cb2ff497768adba9bb
[linux-2.6.git] / 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, 0)
28 static const char version[] = "2.1.0";
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                           __u16 len)
338 {
339         usb_control_msg(dev,
340                         usb_sndctrlpipe(dev, 0),
341                         0x08,                   /* request */
342                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
343                         value,
344                         0,                      /* index */
345                         (__u8 *) buffer, len,
346                         500);
347 }
348
349 static int i2c_w(struct usb_device *dev, const __u8 *buffer)
350 {
351         int retry = 60;
352         __u8 ByteReceive;
353
354         /* is i2c ready */
355         reg_w(dev, 0x08, buffer, 8);
356         while (retry--) {
357                 msleep(10);
358                 reg_r(dev, 0x08, &ByteReceive);
359                 if (ByteReceive == 4)
360                         return 0;
361         }
362         return -1;
363 }
364
365 static void i2c_w_vector(struct usb_device *dev,
366                         const __u8 buffer[][8], int len)
367 {
368         for (;;) {
369                 reg_w(dev, 0x08, *buffer, 8);
370                 len -= 8;
371                 if (len <= 0)
372                         break;
373                 buffer++;
374         }
375 }
376
377 static void setbrightness(struct gspca_dev *gspca_dev)
378 {
379         struct sd *sd = (struct sd *) gspca_dev;
380         __u8 value;
381
382         switch (sd->sensor) {
383         case SENSOR_OV6650: {
384                 __u8 i2cOV6650[] =
385                         {0xa0, 0x60, 0x06, 0x11, 0x99, 0x04, 0x94, 0x15};
386
387                 i2cOV6650[3] = sd->brightness;
388                 if (i2c_w(gspca_dev->dev, i2cOV6650) < 0)
389                          goto err;
390                 break;
391             }
392         case  SENSOR_OV7630: {
393                 __u8 i2cOV[] =
394                         {0xa0, 0x21, 0x06, 0x36, 0xbd, 0x06, 0xf6, 0x16};
395
396                 /* change reg 0x06 */
397                 i2cOV[3] = sd->brightness;
398                 if (i2c_w(gspca_dev->dev, i2cOV) < 0)
399                         goto err;
400                 break;
401             }
402         case SENSOR_PAS106: {
403                 __u8 i2c1[] =
404                         {0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14};
405
406                 i2c1[3] = sd->brightness >> 3;
407                 i2c1[2] = 0x0e;
408                 if (i2c_w(gspca_dev->dev, i2c1) < 0)
409                         goto err;
410                 i2c1[3] = 0x01;
411                 i2c1[2] = 0x13;
412                 if (i2c_w(gspca_dev->dev, i2c1) < 0)
413                         goto err;
414                 break;
415             }
416         case SENSOR_PAS202: {
417                 /* __u8 i2cpexpo1[] =
418                         {0xb0, 0x40, 0x04, 0x07, 0x2a, 0x00, 0x63, 0x16}; */
419                 __u8 i2cpexpo[] =
420                         {0xb0, 0x40, 0x0e, 0x01, 0xab, 0x00, 0x63, 0x16};
421                 __u8 i2cp202[] =
422                         {0xa0, 0x40, 0x10, 0x0e, 0x31, 0x00, 0x63, 0x15};
423                 static __u8 i2cpdoit[] =
424                         {0xa0, 0x40, 0x11, 0x01, 0x31, 0x00, 0x63, 0x16};
425
426                 /* change reg 0x10 */
427                 i2cpexpo[4] = 0xff - sd->brightness;
428 /*              if(i2c_w(gspca_dev->dev,i2cpexpo1) < 0)
429                         goto err; */
430 /*              if(i2c_w(gspca_dev->dev,i2cpdoit) < 0)
431                         goto err; */
432                 if (i2c_w(gspca_dev->dev, i2cpexpo) < 0)
433                         goto err;
434                 if (i2c_w(gspca_dev->dev, i2cpdoit) < 0)
435                         goto err;
436                 i2cp202[3] = sd->brightness >> 3;
437                 if (i2c_w(gspca_dev->dev, i2cp202) < 0)
438                         goto err;
439                 if (i2c_w(gspca_dev->dev, i2cpdoit) < 0)
440                         goto err;
441                 break;
442             }
443         case SENSOR_TAS5130CXX:
444         case SENSOR_TAS5110: {
445                 __u8 i2c[] =
446                         {0x30, 0x11, 0x02, 0x20, 0x70, 0x00, 0x00, 0x10};
447
448                 value = 0xff - sd->brightness;
449                 i2c[4] = value;
450                 PDEBUG(D_CONF, "brightness %d : %d", value, i2c[4]);
451                 if (i2c_w(gspca_dev->dev, i2c) < 0)
452                         goto err;
453                 break;
454             }
455         }
456         return;
457 err:
458         PDEBUG(D_ERR, "i2c error brightness");
459 }
460 static void setcontrast(struct gspca_dev *gspca_dev)
461 {
462         struct sd *sd = (struct sd *) gspca_dev;
463         __u8 gain;
464         __u8 rgb_value;
465
466         gain = sd->contrast >> 4;
467         /* red and blue gain */
468         rgb_value = gain << 4 | gain;
469         reg_w(gspca_dev->dev, 0x10, &rgb_value, 1);
470         /* green gain */
471         rgb_value = gain;
472         reg_w(gspca_dev->dev, 0x11, &rgb_value, 1);
473 }
474
475 /* this function is called at probe time */
476 static int sd_config(struct gspca_dev *gspca_dev,
477                         const struct usb_device_id *id)
478 {
479         struct sd *sd = (struct sd *) gspca_dev;
480         struct cam *cam;
481 /*      __u16 vendor; */
482         __u16 product;
483         int sif = 0;
484
485 /*      vendor = id->idVendor; */
486         product = id->idProduct;
487 /*      switch (vendor) { */
488 /*      case 0x0c45:                             * Sonix */
489                 switch (product) {
490                 case 0x6001:                    /* SN9C102 */
491                 case 0x6005:                    /* SN9C101 */
492                 case 0x6007:                    /* SN9C101 */
493                         sd->sensor = SENSOR_TAS5110;
494                         sif = 1;
495                         break;
496                 case 0x6009:                    /* SN9C101 */
497                 case 0x600d:                    /* SN9C101 */
498                 case 0x6029:                    /* SN9C101 */
499                         sd->sensor = SENSOR_PAS106;
500                         sif = 1;
501                         break;
502                 case 0x6011:                    /* SN9C101 - SN9C101G */
503                         sd->sensor = SENSOR_OV6650;
504                         sif = 1;
505                         break;
506                 case 0x6019:                    /* SN9C101 */
507                 case 0x602c:                    /* SN9C102 */
508                 case 0x602e:                    /* SN9C102 */
509                         sd->sensor = SENSOR_OV7630;
510                         break;
511                 case 0x60b0:                    /* SN9C103 */
512                         sd->sensor = SENSOR_OV7630_3;
513                         break;
514                 case 0x6024:                    /* SN9C102 */
515                 case 0x6025:                    /* SN9C102 */
516                         sd->sensor = SENSOR_TAS5130CXX;
517                         break;
518                 case 0x6028:                    /* SN9C102 */
519                         sd->sensor = SENSOR_PAS202;
520                         break;
521                 case 0x602d:                    /* SN9C102 */
522                         sd->sensor = SENSOR_HV7131R;
523                         break;
524                 case 0x60af:                    /* SN9C103 */
525                         sd->sensor = SENSOR_PAS202;
526                         break;
527                 }
528 /*              break; */
529 /*      } */
530
531         cam = &gspca_dev->cam;
532         cam->dev_name = (char *) id->driver_info;
533         cam->epaddr = 0x01;
534         if (!sif) {
535                 cam->cam_mode = vga_mode;
536                 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
537         } else {
538                 cam->cam_mode = sif_mode;
539                 cam->nmodes = sizeof sif_mode / sizeof sif_mode[0];
540         }
541         sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
542         sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
543         if (sd->sensor == SENSOR_OV7630_3)      /* jfm: from win trace */
544                 reg_w(gspca_dev->dev, 0x01, probe_ov7630, sizeof probe_ov7630);
545         return 0;
546 }
547
548 /* this function is called at open time */
549 static int sd_open(struct gspca_dev *gspca_dev)
550 {
551         __u8 ByteReceive;
552
553         reg_r(gspca_dev->dev, 0x00, &ByteReceive);
554         if (ByteReceive != 0x10)
555                 return -ENODEV;
556         return 0;
557 }
558
559 static void pas106_i2cinit(struct usb_device *dev)
560 {
561         int i;
562         const __u8 *data;
563         __u8 i2c1[] = { 0xa1, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14 };
564
565         i = ARRAY_SIZE(pas106_data);
566         data = pas106_data[0];
567         while (--i >= 0) {
568                 memcpy(&i2c1[2], data, 2);
569                                         /* copy 2 bytes from the template */
570                 if (i2c_w(dev, i2c1) < 0)
571                         PDEBUG(D_ERR, "i2c error pas106");
572                 data += 2;
573         }
574 }
575
576 /* -- start the camera -- */
577 static void sd_start(struct gspca_dev *gspca_dev)
578 {
579         struct sd *sd = (struct sd *) gspca_dev;
580         struct usb_device *dev = gspca_dev->dev;
581         int mode, l;
582         const __u8 *sn9c10x;
583         __u8 reg01, reg17;
584         __u8 reg17_19[3];
585
586         mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].mode;
587         switch (sd->sensor) {
588         case SENSOR_HV7131R:
589                 sn9c10x = initHv7131;
590                 reg17_19[0] = 0x60;
591                 reg17_19[1] = (mode << 4) | 0x8a;
592                 reg17_19[2] = 0x20;
593                 break;
594         case SENSOR_OV6650:
595                 sn9c10x = initOv6650;
596                 reg17_19[0] = 0x68;
597                 reg17_19[1] = (mode << 4) | 0x8b;
598                 reg17_19[2] = 0x20;
599                 break;
600         case SENSOR_OV7630:
601                 sn9c10x = initOv7630;
602                 reg17_19[0] = 0x68;
603                 reg17_19[1] = (mode << 4) | COMP2;
604                 reg17_19[2] = MCK_INIT1;
605                 break;
606         case SENSOR_OV7630_3:
607                 sn9c10x = initOv7630_3;
608                 reg17_19[0] = 0x68;
609                 reg17_19[1] = (mode << 4) | COMP2;
610                 reg17_19[2] = MCK_INIT1;
611                 break;
612         case SENSOR_PAS106:
613                 sn9c10x = initPas106;
614                 reg17_19[0] = 0x24;             /* 0x28 */
615                 reg17_19[1] = (mode << 4) | COMP1;
616                 reg17_19[2] = MCK_INIT1;
617                 break;
618         case SENSOR_PAS202:
619                 sn9c10x = initPas202;
620                 reg17_19[0] = mode ? 0x24 : 0x20;
621                 reg17_19[1] = (mode << 4) | 0x89;
622                 reg17_19[2] = 0x20;
623                 break;
624         case SENSOR_TAS5110:
625                 sn9c10x = initTas5110;
626                 reg17_19[0] = 0x60;
627                 reg17_19[1] = (mode << 4) | 0x86;
628                 reg17_19[2] = 0x2b;             /* 0xf3; */
629                 break;
630         default:
631 /*      case SENSOR_TAS5130CXX: */
632                 sn9c10x = initTas5130;
633                 reg17_19[0] = 0x60;
634                 reg17_19[1] = (mode << 4) | COMP;
635                 reg17_19[2] = mode ? 0x23 : 0x43;
636                 break;
637         }
638         switch (sd->sensor) {
639         case SENSOR_OV7630:
640                 reg01 = 0x06;
641                 reg17 = 0x29;
642                 l = 0x10;
643                 break;
644         case SENSOR_OV7630_3:
645                 reg01 = 0x44;
646                 reg17 = 0x68;
647                 l = 0x10;
648                 break;
649         default:
650                 reg01 = sn9c10x[0];
651                 reg17 = sn9c10x[0x17 - 1];
652                 l = 0x1f;
653                 break;
654         }
655
656         /* reg 0x01 bit 2 video transfert on */
657         reg_w(dev, 0x01, &reg01, 1);
658         /* reg 0x17 SensorClk enable inv Clk 0x60 */
659         reg_w(dev, 0x17, &reg17, 1);
660 /*fixme: for ov7630 102
661         reg_w(dev, 0x01, {0x06, sn9c10x[1]}, 2); */
662         /* Set the registers from the template */
663         reg_w(dev, 0x01, sn9c10x, l);
664         switch (sd->sensor) {
665         case SENSOR_HV7131R:
666                 i2c_w_vector(dev, hv7131_sensor_init,
667                                 sizeof hv7131_sensor_init);
668                 break;
669         case SENSOR_OV6650:
670                 i2c_w_vector(dev, ov6650_sensor_init,
671                                 sizeof ov6650_sensor_init);
672                 break;
673         case SENSOR_OV7630:
674                 i2c_w_vector(dev, ov7630_sensor_init_com,
675                                 sizeof ov7630_sensor_init_com);
676                 msleep(200);
677                 i2c_w_vector(dev, ov7630_sensor_init,
678                                 sizeof ov7630_sensor_init);
679                 break;
680         case SENSOR_OV7630_3:
681                 i2c_w_vector(dev, ov7630_sensor_init_com,
682                                 sizeof ov7630_sensor_init_com);
683                 msleep(200);
684                 i2c_w_vector(dev, ov7630_sensor_init_3,
685                                 sizeof ov7630_sensor_init_3);
686                 break;
687         case SENSOR_PAS106:
688                 pas106_i2cinit(dev);
689                 break;
690         case SENSOR_PAS202:
691                 i2c_w_vector(dev, pas202_sensor_init,
692                                 sizeof pas202_sensor_init);
693                 break;
694         case SENSOR_TAS5110:
695                 i2c_w_vector(dev, tas5110_sensor_init,
696                                 sizeof tas5110_sensor_init);
697                 break;
698         default:
699 /*      case SENSOR_TAS5130CXX: */
700                 i2c_w_vector(dev, tas5130_sensor_init,
701                                 sizeof tas5130_sensor_init);
702                 break;
703         }
704         /* H_size V_size  0x28, 0x1e maybe 640x480 */
705         reg_w(dev, 0x15, &sn9c10x[0x15 - 1], 2);
706         /* compression register */
707         reg_w(dev, 0x18, &reg17_19[1], 1);
708         /* H_start */           /*fixme: not ov7630*/
709         reg_w(dev, 0x12, &sn9c10x[0x12 - 1], 1);
710         /* V_START */           /*fixme: not ov7630*/
711         reg_w(dev, 0x13, &sn9c10x[0x13 - 1], 1);
712         /* reset 0x17 SensorClk enable inv Clk 0x60 */
713                                 /*fixme: ov7630 [17]=68 8f (+20 if 102)*/
714         reg_w(dev, 0x17, &reg17_19[0], 1);
715         /*MCKSIZE ->3 */        /*fixme: not ov7630*/
716         reg_w(dev, 0x19, &reg17_19[2], 1);
717         /* AE_STRX AE_STRY AE_ENDX AE_ENDY */
718         reg_w(dev, 0x1c, &sn9c10x[0x1c - 1], 4);
719         /* Enable video transfert */
720         reg_w(dev, 0x01, &sn9c10x[0], 1);
721         /* Compression */
722         reg_w(dev, 0x18, &reg17_19[1], 2);
723         msleep(20);
724
725         setcontrast(gspca_dev);
726         setbrightness(gspca_dev);
727 }
728
729 static void sd_stopN(struct gspca_dev *gspca_dev)
730 {
731         __u8 ByteSend = 0;
732
733         ByteSend = 0x09;        /* 0X00 */
734         reg_w(gspca_dev->dev, 0x01, &ByteSend, 1);
735 }
736
737 static void sd_stop0(struct gspca_dev *gspca_dev)
738 {
739 }
740
741 static void sd_close(struct gspca_dev *gspca_dev)
742 {
743 }
744
745 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
746                         struct gspca_frame *frame,      /* target */
747                         unsigned char *data,            /* isoc packet */
748                         int len)                        /* iso packet length */
749 {
750         int p;
751
752         if (len > 6 && len < 24) {
753                 for (p = 0; p < len - 6; p++) {
754                         if (data[0 + p] == 0xff
755                             && data[1 + p] == 0xff
756                             && data[2 + p] == 0x00
757                             && data[3 + p] == 0xc4
758                             && data[4 + p] == 0xc4
759                             && data[5 + p] == 0x96) {   /* start of frame */
760                                 frame = gspca_frame_add(gspca_dev,
761                                                         LAST_PACKET,
762                                                         frame,
763                                                         data, 0);
764                                 data += 12;
765                                 len -= 12;
766                                 gspca_frame_add(gspca_dev, FIRST_PACKET,
767                                                 frame, data, len);
768                                 return;
769                         }
770                 }
771         }
772         gspca_frame_add(gspca_dev, INTER_PACKET,
773                         frame, data, len);
774 }
775
776 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
777 {
778         struct sd *sd = (struct sd *) gspca_dev;
779
780         sd->brightness = val;
781         if (gspca_dev->streaming)
782                 setbrightness(gspca_dev);
783         return 0;
784 }
785
786 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
787 {
788         struct sd *sd = (struct sd *) gspca_dev;
789
790         *val = sd->brightness;
791         return 0;
792 }
793
794 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
795 {
796         struct sd *sd = (struct sd *) gspca_dev;
797
798         sd->contrast = val;
799         if (gspca_dev->streaming)
800                 setcontrast(gspca_dev);
801         return 0;
802 }
803
804 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
805 {
806         struct sd *sd = (struct sd *) gspca_dev;
807
808         *val = sd->contrast;
809         return 0;
810 }
811
812 /* sub-driver description */
813 static struct sd_desc sd_desc = {
814         .name = MODULE_NAME,
815         .ctrls = sd_ctrls,
816         .nctrls = ARRAY_SIZE(sd_ctrls),
817         .config = sd_config,
818         .open = sd_open,
819         .start = sd_start,
820         .stopN = sd_stopN,
821         .stop0 = sd_stop0,
822         .close = sd_close,
823         .pkt_scan = sd_pkt_scan,
824 };
825
826 /* -- module initialisation -- */
827 #define DVNM(name) .driver_info = (kernel_ulong_t) name
828 static __devinitdata struct usb_device_id device_table[] = {
829         {USB_DEVICE(0x0c45, 0x6001), DVNM("Genius VideoCAM NB")},
830         {USB_DEVICE(0x0c45, 0x6005), DVNM("Sweex Tas5110")},
831         {USB_DEVICE(0x0c45, 0x6007), DVNM("Sonix sn9c101 + Tas5110D")},
832         {USB_DEVICE(0x0c45, 0x6009), DVNM("spcaCam@120")},
833         {USB_DEVICE(0x0c45, 0x600d), DVNM("spcaCam@120")},
834         {USB_DEVICE(0x0c45, 0x6011), DVNM("MAX Webcam Microdia-OV6650-SN9C101G")},
835         {USB_DEVICE(0x0c45, 0x6019), DVNM("Generic Sonix OV7630")},
836         {USB_DEVICE(0x0c45, 0x6024), DVNM("Generic Sonix Tas5130c")},
837         {USB_DEVICE(0x0c45, 0x6025), DVNM("Xcam Shanga")},
838         {USB_DEVICE(0x0c45, 0x6028), DVNM("Sonix Btc Pc380")},
839         {USB_DEVICE(0x0c45, 0x6029), DVNM("spcaCam@150")},
840         {USB_DEVICE(0x0c45, 0x602c), DVNM("Generic Sonix OV7630")},
841         {USB_DEVICE(0x0c45, 0x602d), DVNM("LIC-200 LG")},
842         {USB_DEVICE(0x0c45, 0x602e), DVNM("Genius VideoCam Messenger")},
843         {USB_DEVICE(0x0c45, 0x60af), DVNM("Trust WB3100P")},
844         {USB_DEVICE(0x0c45, 0x60b0), DVNM("Genius VideoCam Look")},
845         {}
846 };
847 MODULE_DEVICE_TABLE(usb, device_table);
848
849 /* -- device connect -- */
850 static int sd_probe(struct usb_interface *intf,
851                         const struct usb_device_id *id)
852 {
853         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
854                                 THIS_MODULE);
855 }
856
857 static struct usb_driver sd_driver = {
858         .name = MODULE_NAME,
859         .id_table = device_table,
860         .probe = sd_probe,
861         .disconnect = gspca_disconnect,
862 };
863
864 /* -- module insert / remove -- */
865 static int __init sd_mod_init(void)
866 {
867         if (usb_register(&sd_driver) < 0)
868                 return -1;
869         PDEBUG(D_PROBE, "v%s registered", version);
870         return 0;
871 }
872 static void __exit sd_mod_exit(void)
873 {
874         usb_deregister(&sd_driver);
875         PDEBUG(D_PROBE, "deregistered");
876 }
877
878 module_init(sd_mod_init);
879 module_exit(sd_mod_exit);