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