Merge branches 'core/debug', 'core/futexes', 'core/locking', 'core/rcu', 'core/signal...
[linux-2.6] / drivers / media / video / gspca / conex.c
1 /*
2  *              Connexant Cx11646 library
3  *              Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
4  *
5  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21
22 #define MODULE_NAME "conex"
23
24 #include "gspca.h"
25 #define CONEX_CAM 1             /* special JPEG header */
26 #include "jpeg.h"
27
28 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29 MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
30 MODULE_LICENSE("GPL");
31
32 /* specific webcam descriptor */
33 struct sd {
34         struct gspca_dev gspca_dev;     /* !! must be the first item */
35
36         unsigned char brightness;
37         unsigned char contrast;
38         unsigned char colors;
39
40         unsigned char qindex;
41 };
42
43 /* V4L2 controls supported by the driver */
44 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
45 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
46 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
47 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
48 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
49 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
50
51 static struct ctrl sd_ctrls[] = {
52         {
53             {
54                 .id      = V4L2_CID_BRIGHTNESS,
55                 .type    = V4L2_CTRL_TYPE_INTEGER,
56                 .name    = "Brightness",
57                 .minimum = 0,
58                 .maximum = 255,
59                 .step    = 1,
60 #define BRIGHTNESS_DEF 0xd4
61                 .default_value = BRIGHTNESS_DEF,
62             },
63             .set = sd_setbrightness,
64             .get = sd_getbrightness,
65         },
66         {
67             {
68                 .id      = V4L2_CID_CONTRAST,
69                 .type    = V4L2_CTRL_TYPE_INTEGER,
70                 .name    = "Contrast",
71                 .minimum = 0x0a,
72                 .maximum = 0x1f,
73                 .step    = 1,
74 #define CONTRAST_DEF 0x0c
75                 .default_value = CONTRAST_DEF,
76             },
77             .set = sd_setcontrast,
78             .get = sd_getcontrast,
79         },
80         {
81             {
82                 .id      = V4L2_CID_SATURATION,
83                 .type    = V4L2_CTRL_TYPE_INTEGER,
84                 .name    = "Color",
85                 .minimum = 0,
86                 .maximum = 7,
87                 .step    = 1,
88 #define COLOR_DEF 3
89                 .default_value = COLOR_DEF,
90             },
91             .set = sd_setcolors,
92             .get = sd_getcolors,
93         },
94 };
95
96 static struct v4l2_pix_format vga_mode[] = {
97         {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
98                 .bytesperline = 176,
99                 .sizeimage = 176 * 144 * 3 / 8 + 590,
100                 .colorspace = V4L2_COLORSPACE_JPEG,
101                 .priv = 3},
102         {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
103                 .bytesperline = 320,
104                 .sizeimage = 320 * 240 * 3 / 8 + 590,
105                 .colorspace = V4L2_COLORSPACE_JPEG,
106                 .priv = 2},
107         {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
108                 .bytesperline = 352,
109                 .sizeimage = 352 * 288 * 3 / 8 + 590,
110                 .colorspace = V4L2_COLORSPACE_JPEG,
111                 .priv = 1},
112         {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
113                 .bytesperline = 640,
114                 .sizeimage = 640 * 480 * 3 / 8 + 590,
115                 .colorspace = V4L2_COLORSPACE_JPEG,
116                 .priv = 0},
117 };
118
119 /* the read bytes are found in gspca_dev->usb_buf */
120 static void reg_r(struct gspca_dev *gspca_dev,
121                   __u16 index,
122                   __u16 len)
123 {
124         struct usb_device *dev = gspca_dev->dev;
125
126 #ifdef GSPCA_DEBUG
127         if (len > USB_BUF_SZ) {
128                 err("reg_r: buffer overflow");
129                 return;
130         }
131 #endif
132         usb_control_msg(dev,
133                         usb_rcvctrlpipe(dev, 0),
134                         0,
135                         USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
136                         0,
137                         index, gspca_dev->usb_buf, len,
138                         500);
139         PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
140                         index, gspca_dev->usb_buf[0]);
141 }
142
143 /* the bytes to write are in gspca_dev->usb_buf */
144 static void reg_w_val(struct gspca_dev *gspca_dev,
145                         __u16 index,
146                         __u8 val)
147 {
148         struct usb_device *dev = gspca_dev->dev;
149
150         gspca_dev->usb_buf[0] = val;
151         usb_control_msg(dev,
152                         usb_sndctrlpipe(dev, 0),
153                         0,
154                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
155                         0,
156                         index, gspca_dev->usb_buf, 1, 500);
157 }
158
159 static void reg_w(struct gspca_dev *gspca_dev,
160                   __u16 index,
161                   const __u8 *buffer,
162                   __u16 len)
163 {
164         struct usb_device *dev = gspca_dev->dev;
165
166 #ifdef GSPCA_DEBUG
167         if (len > USB_BUF_SZ) {
168                 err("reg_w: buffer overflow");
169                 return;
170         }
171         PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
172 #endif
173         memcpy(gspca_dev->usb_buf, buffer, len);
174         usb_control_msg(dev,
175                         usb_sndctrlpipe(dev, 0),
176                         0,
177                         USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
178                         0,
179                         index, gspca_dev->usb_buf, len, 500);
180 }
181
182 static const __u8 cx_sensor_init[][4] = {
183         {0x88, 0x11, 0x01, 0x01},
184         {0x88, 0x12, 0x70, 0x01},
185         {0x88, 0x0f, 0x00, 0x01},
186         {0x88, 0x05, 0x01, 0x01},
187         {}
188 };
189
190 static const __u8 cx11646_fw1[][3] = {
191         {0x00, 0x02, 0x00},
192         {0x01, 0x43, 0x00},
193         {0x02, 0xA7, 0x00},
194         {0x03, 0x8B, 0x01},
195         {0x04, 0xE9, 0x02},
196         {0x05, 0x08, 0x04},
197         {0x06, 0x08, 0x05},
198         {0x07, 0x07, 0x06},
199         {0x08, 0xE7, 0x06},
200         {0x09, 0xC6, 0x07},
201         {0x0A, 0x86, 0x08},
202         {0x0B, 0x46, 0x09},
203         {0x0C, 0x05, 0x0A},
204         {0x0D, 0xA5, 0x0A},
205         {0x0E, 0x45, 0x0B},
206         {0x0F, 0xE5, 0x0B},
207         {0x10, 0x85, 0x0C},
208         {0x11, 0x25, 0x0D},
209         {0x12, 0xC4, 0x0D},
210         {0x13, 0x45, 0x0E},
211         {0x14, 0xE4, 0x0E},
212         {0x15, 0x64, 0x0F},
213         {0x16, 0xE4, 0x0F},
214         {0x17, 0x64, 0x10},
215         {0x18, 0xE4, 0x10},
216         {0x19, 0x64, 0x11},
217         {0x1A, 0xE4, 0x11},
218         {0x1B, 0x64, 0x12},
219         {0x1C, 0xE3, 0x12},
220         {0x1D, 0x44, 0x13},
221         {0x1E, 0xC3, 0x13},
222         {0x1F, 0x24, 0x14},
223         {0x20, 0xA3, 0x14},
224         {0x21, 0x04, 0x15},
225         {0x22, 0x83, 0x15},
226         {0x23, 0xE3, 0x15},
227         {0x24, 0x43, 0x16},
228         {0x25, 0xA4, 0x16},
229         {0x26, 0x23, 0x17},
230         {0x27, 0x83, 0x17},
231         {0x28, 0xE3, 0x17},
232         {0x29, 0x43, 0x18},
233         {0x2A, 0xA3, 0x18},
234         {0x2B, 0x03, 0x19},
235         {0x2C, 0x63, 0x19},
236         {0x2D, 0xC3, 0x19},
237         {0x2E, 0x22, 0x1A},
238         {0x2F, 0x63, 0x1A},
239         {0x30, 0xC3, 0x1A},
240         {0x31, 0x23, 0x1B},
241         {0x32, 0x83, 0x1B},
242         {0x33, 0xE2, 0x1B},
243         {0x34, 0x23, 0x1C},
244         {0x35, 0x83, 0x1C},
245         {0x36, 0xE2, 0x1C},
246         {0x37, 0x23, 0x1D},
247         {0x38, 0x83, 0x1D},
248         {0x39, 0xE2, 0x1D},
249         {0x3A, 0x23, 0x1E},
250         {0x3B, 0x82, 0x1E},
251         {0x3C, 0xC3, 0x1E},
252         {0x3D, 0x22, 0x1F},
253         {0x3E, 0x63, 0x1F},
254         {0x3F, 0xC1, 0x1F},
255         {}
256 };
257 static void cx11646_fw(struct gspca_dev*gspca_dev)
258 {
259         int i = 0;
260
261         reg_w_val(gspca_dev, 0x006a, 0x02);
262         while (cx11646_fw1[i][1]) {
263                 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
264                 i++;
265         }
266         reg_w_val(gspca_dev, 0x006a, 0x00);
267 }
268
269 static const __u8 cxsensor[] = {
270         0x88, 0x12, 0x70, 0x01,
271         0x88, 0x0d, 0x02, 0x01,
272         0x88, 0x0f, 0x00, 0x01,
273         0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
274         0x88, 0x02, 0x10, 0x01,
275         0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
276         0x88, 0x0B, 0x00, 0x01,
277         0x88, 0x0A, 0x0A, 0x01,
278         0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
279         0x88, 0x05, 0x01, 0x01,
280         0xA1, 0x18, 0x00, 0x01,
281         0x00
282 };
283
284 static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
285 static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
286 static const __u8 reg10[] = { 0xb1, 0xb1 };
287 static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e };        /* 640 */
288 static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
289         /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
290 static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
291                                         /* 320{0x04,0x0c,0x05,0x0f}; //320 */
292 static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 };        /* 176 */
293 static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
294
295 static void cx_sensor(struct gspca_dev*gspca_dev)
296 {
297         int i = 0;
298         int length;
299         const __u8 *ptsensor = cxsensor;
300
301         reg_w(gspca_dev, 0x0020, reg20, 8);
302         reg_w(gspca_dev, 0x0028, reg28, 8);
303         reg_w(gspca_dev, 0x0010, reg10, 8);
304         reg_w_val(gspca_dev, 0x0092, 0x03);
305
306         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
307         case 0:
308                 reg_w(gspca_dev, 0x0071, reg71a, 4);
309                 break;
310         case 1:
311                 reg_w(gspca_dev, 0x0071, reg71b, 4);
312                 break;
313         default:
314 /*      case 2: */
315                 reg_w(gspca_dev, 0x0071, reg71c, 4);
316                 break;
317         case 3:
318                 reg_w(gspca_dev, 0x0071, reg71d, 4);
319                 break;
320         }
321         reg_w(gspca_dev, 0x007b, reg7b, 6);
322         reg_w_val(gspca_dev, 0x00f8, 0x00);
323         reg_w(gspca_dev, 0x0010, reg10, 8);
324         reg_w_val(gspca_dev, 0x0098, 0x41);
325         for (i = 0; i < 11; i++) {
326                 if (i == 3 || i == 5 || i == 8)
327                         length = 8;
328                 else
329                         length = 4;
330                 reg_w(gspca_dev, 0x00e5, ptsensor, length);
331                 if (length == 4)
332                         reg_r(gspca_dev, 0x00e8, 1);
333                 else
334                         reg_r(gspca_dev, 0x00e8, length);
335                 ptsensor += length;
336         }
337         reg_r(gspca_dev, 0x00e7, 8);
338 }
339
340 static const __u8 cx_inits_176[] = {
341         0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
342         0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
343         0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
344         0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
345         0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
346         0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
347         0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
348 };
349 static const __u8 cx_inits_320[] = {
350         0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
351         0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
352         0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
353         0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
354         0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
355         0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
356         0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
357 };
358 static const __u8 cx_inits_352[] = {
359         0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
360         0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
361         0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
362         0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
363         0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
364         0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
365         0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
366 };
367 static const __u8 cx_inits_640[] = {
368         0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
369         0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
370         0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
371         0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
372         0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
373         0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
374         0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
375 };
376
377 static void cx11646_initsize(struct gspca_dev *gspca_dev)
378 {
379         const __u8 *cxinit;
380         static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
381         static const __u8 reg17[] =
382                         { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
383
384         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
385         case 0:
386                 cxinit = cx_inits_640;
387                 break;
388         case 1:
389                 cxinit = cx_inits_352;
390                 break;
391         default:
392 /*      case 2: */
393                 cxinit = cx_inits_320;
394                 break;
395         case 3:
396                 cxinit = cx_inits_176;
397                 break;
398         }
399         reg_w_val(gspca_dev, 0x009a, 0x01);
400         reg_w_val(gspca_dev, 0x0010, 0x10);
401         reg_w(gspca_dev, 0x0012, reg12, 5);
402         reg_w(gspca_dev, 0x0017, reg17, 8);
403         reg_w_val(gspca_dev, 0x00c0, 0x00);
404         reg_w_val(gspca_dev, 0x00c1, 0x04);
405         reg_w_val(gspca_dev, 0x00c2, 0x04);
406
407         reg_w(gspca_dev, 0x0061, cxinit, 8);
408         cxinit += 8;
409         reg_w(gspca_dev, 0x00ca, cxinit, 8);
410         cxinit += 8;
411         reg_w(gspca_dev, 0x00d2, cxinit, 8);
412         cxinit += 8;
413         reg_w(gspca_dev, 0x00da, cxinit, 6);
414         cxinit += 8;
415         reg_w(gspca_dev, 0x0041, cxinit, 8);
416         cxinit += 8;
417         reg_w(gspca_dev, 0x0049, cxinit, 8);
418         cxinit += 8;
419         reg_w(gspca_dev, 0x0051, cxinit, 2);
420
421         reg_r(gspca_dev, 0x0010, 1);
422 }
423
424 static const __u8 cx_jpeg_init[][8] = {
425         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15},       /* 1 */
426         {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
427         {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
428         {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
429         {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
430         {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
431         {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
432         {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
433         {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
434         {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
435         {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
436         {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
437         {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
438         {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
439         {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
440         {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
441         {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
442         {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
443         {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
444         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
445         {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
446         {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
447         {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
448         {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
449         {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
450         {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
451         {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
452         {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
453         {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
454         {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
455         {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
456         {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
457         {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
458         {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
459         {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
460         {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
461         {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
462         {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
463         {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
464         {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
465         {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
466         {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
467         {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
468         {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
469         {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
470         {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
471         {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
472         {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
473         {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
474         {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
475         {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
476         {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
477         {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
478         {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
479         {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
480         {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
481         {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
482         {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
483         {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
484         {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
485         {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
486         {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
487         {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
488         {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
489         {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
490         {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
491         {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
492         {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
493         {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
494         {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
495         {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
496         {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
497         {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
498         {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
499         {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
500         {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
501         {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
502         {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
503         {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00}        /* 79 */
504 };
505
506
507 static const __u8 cxjpeg_640[][8] = {
508         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10},       /* 1 */
509         {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
510         {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
511         {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
512         {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
513         {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
514         {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
515         {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
516         {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
517         {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
518         {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
519         {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
520         {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
521         {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
522         {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
523         {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
524         {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
525         {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
526         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
527         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
528         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
529         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
530         {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
531         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
532         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
533         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
534         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}        /* 27 */
535 };
536 static const __u8 cxjpeg_352[][8] = {
537         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
538         {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
539         {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
540         {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
541         {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
542         {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
543         {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
544         {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
545         {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
546         {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
547         {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
548         {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
549         {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
550         {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
551         {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
552         {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
553         {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
554         {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
555         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
556         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
557         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
558         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
559         {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
560         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
561         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
562         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
563         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
564 };
565 static const __u8 cxjpeg_320[][8] = {
566         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
567         {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
568         {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
569         {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
570         {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
571         {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
572         {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
573         {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
574         {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
575         {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
576         {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
577         {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
578         {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
579         {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
580         {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
581         {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
582         {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
583         {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
584         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
585         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
586         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
587         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
588         {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
589         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
590         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
591         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
592         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}        /* 27 */
593 };
594 static const __u8 cxjpeg_176[][8] = {
595         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
596         {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
597         {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
598         {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
599         {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
600         {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
601         {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
602         {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
603         {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
604         {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
605         {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
606         {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
607         {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
608         {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
609         {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
610         {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
611         {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
612         {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
613         {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
614         {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
615         {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
616         {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
617         {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
618         {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
619         {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
620         {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
621         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
622 };
623 /* 640 take with the zcx30x part */
624 static const __u8 cxjpeg_qtable[][8] = {
625         {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
626         {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
627         {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
628         {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
629         {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
630         {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
631         {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
632         {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
633         {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
634         {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
635         {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
636         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
637         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
638         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
639         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
640         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
641         {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
642         {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}        /* 18 */
643 };
644
645
646 static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
647 {
648         int i;
649         int length;
650
651         reg_w_val(gspca_dev, 0x00c0, 0x01);
652         reg_w_val(gspca_dev, 0x00c3, 0x00);
653         reg_w_val(gspca_dev, 0x00c0, 0x00);
654         reg_r(gspca_dev, 0x0001, 1);
655         length = 8;
656         for (i = 0; i < 79; i++) {
657                 if (i == 78)
658                         length = 6;
659                 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
660         }
661         reg_r(gspca_dev, 0x0002, 1);
662         reg_w_val(gspca_dev, 0x0055, 0x14);
663 }
664
665 static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
666 static const __u8 regE5_8[] =
667                 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
668 static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
669 static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
670 static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
671 static const __u8 reg51[] = { 0x77, 0x03 };
672 #define reg70 0x03
673
674 static void cx11646_jpeg(struct gspca_dev*gspca_dev)
675 {
676         int i;
677         int length;
678         __u8 Reg55;
679         int retry;
680
681         reg_w_val(gspca_dev, 0x00c0, 0x01);
682         reg_w_val(gspca_dev, 0x00c3, 0x00);
683         reg_w_val(gspca_dev, 0x00c0, 0x00);
684         reg_r(gspca_dev, 0x0001, 1);
685         length = 8;
686         switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
687         case 0:
688                 for (i = 0; i < 27; i++) {
689                         if (i == 26)
690                                 length = 2;
691                         reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
692                 }
693                 Reg55 = 0x28;
694                 break;
695         case 1:
696                 for (i = 0; i < 27; i++) {
697                         if (i == 26)
698                                 length = 2;
699                         reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
700                 }
701                 Reg55 = 0x16;
702                 break;
703         default:
704 /*      case 2: */
705                 for (i = 0; i < 27; i++) {
706                         if (i == 26)
707                                 length = 2;
708                         reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
709                 }
710                 Reg55 = 0x14;
711                 break;
712         case 3:
713                 for (i = 0; i < 27; i++) {
714                         if (i == 26)
715                                 length = 2;
716                         reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
717                 }
718                 Reg55 = 0x0B;
719                 break;
720         }
721
722         reg_r(gspca_dev, 0x0002, 1);
723         reg_w_val(gspca_dev, 0x0055, Reg55);
724         reg_r(gspca_dev, 0x0002, 1);
725         reg_w(gspca_dev, 0x0010, reg10, 2);
726         reg_w_val(gspca_dev, 0x0054, 0x02);
727         reg_w_val(gspca_dev, 0x0054, 0x01);
728         reg_w_val(gspca_dev, 0x0000, 0x94);
729         reg_w_val(gspca_dev, 0x0053, 0xc0);
730         reg_w_val(gspca_dev, 0x00fc, 0xe1);
731         reg_w_val(gspca_dev, 0x0000, 0x00);
732         /* wait for completion */
733         retry = 50;
734         do {
735                 reg_r(gspca_dev, 0x0002, 1);
736                                                         /* 0x07 until 0x00 */
737                 if (gspca_dev->usb_buf[0] == 0x00)
738                         break;
739                 reg_w_val(gspca_dev, 0x0053, 0x00);
740         } while (--retry);
741         if (retry == 0)
742                 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
743         /* send the qtable now */
744         reg_r(gspca_dev, 0x0001, 1);            /* -> 0x18 */
745         length = 8;
746         for (i = 0; i < 18; i++) {
747                 if (i == 17)
748                         length = 2;
749                 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
750
751         }
752         reg_r(gspca_dev, 0x0002, 1);    /* 0x00 */
753         reg_r(gspca_dev, 0x0053, 1);    /* 0x00 */
754         reg_w_val(gspca_dev, 0x0054, 0x02);
755         reg_w_val(gspca_dev, 0x0054, 0x01);
756         reg_w_val(gspca_dev, 0x0000, 0x94);
757         reg_w_val(gspca_dev, 0x0053, 0xc0);
758
759         reg_r(gspca_dev, 0x0038, 1);            /* 0x40 */
760         reg_r(gspca_dev, 0x0038, 1);            /* 0x40 */
761         reg_r(gspca_dev, 0x001f, 1);            /* 0x38 */
762         reg_w(gspca_dev, 0x0012, reg12, 5);
763         reg_w(gspca_dev, 0x00e5, regE5_8, 8);
764         reg_r(gspca_dev, 0x00e8, 8);
765         reg_w(gspca_dev, 0x00e5, regE5a, 4);
766         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
767         reg_w_val(gspca_dev, 0x009a, 0x01);
768         reg_w(gspca_dev, 0x00e5, regE5b, 4);
769         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
770         reg_w(gspca_dev, 0x00e5, regE5c, 4);
771         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
772
773         reg_w(gspca_dev, 0x0051, reg51, 2);
774         reg_w(gspca_dev, 0x0010, reg10, 2);
775         reg_w_val(gspca_dev, 0x0070, reg70);
776 }
777
778 static void cx11646_init1(struct gspca_dev *gspca_dev)
779 {
780         int i = 0;
781
782         reg_w_val(gspca_dev, 0x0010, 0x00);
783         reg_w_val(gspca_dev, 0x0053, 0x00);
784         reg_w_val(gspca_dev, 0x0052, 0x00);
785         reg_w_val(gspca_dev, 0x009b, 0x2f);
786         reg_w_val(gspca_dev, 0x009c, 0x10);
787         reg_r(gspca_dev, 0x0098, 1);
788         reg_w_val(gspca_dev, 0x0098, 0x40);
789         reg_r(gspca_dev, 0x0099, 1);
790         reg_w_val(gspca_dev, 0x0099, 0x07);
791         reg_w_val(gspca_dev, 0x0039, 0x40);
792         reg_w_val(gspca_dev, 0x003c, 0xff);
793         reg_w_val(gspca_dev, 0x003f, 0x1f);
794         reg_w_val(gspca_dev, 0x003d, 0x40);
795 /*      reg_w_val(gspca_dev, 0x003d, 0x60); */
796         reg_r(gspca_dev, 0x0099, 1);                    /* ->0x07 */
797
798         while (cx_sensor_init[i][0]) {
799                 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
800                 reg_r(gspca_dev, 0x00e8, 1);            /* -> 0x00 */
801                 if (i == 1) {
802                         reg_w_val(gspca_dev, 0x00ed, 0x01);
803                         reg_r(gspca_dev, 0x00ed, 1);    /* -> 0x01 */
804                 }
805                 i++;
806         }
807         reg_w_val(gspca_dev, 0x00c3, 0x00);
808 }
809
810 /* this function is called at probe time */
811 static int sd_config(struct gspca_dev *gspca_dev,
812                         const struct usb_device_id *id)
813 {
814         struct sd *sd = (struct sd *) gspca_dev;
815         struct cam *cam;
816
817         cam = &gspca_dev->cam;
818         cam->epaddr = 0x01;
819         cam->cam_mode = vga_mode;
820         cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
821
822         sd->qindex = 0;                 /* set the quantization */
823         sd->brightness = BRIGHTNESS_DEF;
824         sd->contrast = CONTRAST_DEF;
825         sd->colors = COLOR_DEF;
826         return 0;
827 }
828
829 /* this function is called at probe and resume time */
830 static int sd_init(struct gspca_dev *gspca_dev)
831 {
832         cx11646_init1(gspca_dev);
833         cx11646_initsize(gspca_dev);
834         cx11646_fw(gspca_dev);
835         cx_sensor(gspca_dev);
836         cx11646_jpegInit(gspca_dev);
837         return 0;
838 }
839
840 static int sd_start(struct gspca_dev *gspca_dev)
841 {
842         cx11646_initsize(gspca_dev);
843         cx11646_fw(gspca_dev);
844         cx_sensor(gspca_dev);
845         cx11646_jpeg(gspca_dev);
846         return 0;
847 }
848
849 static void sd_stop0(struct gspca_dev *gspca_dev)
850 {
851         int retry = 50;
852
853         reg_w_val(gspca_dev, 0x0000, 0x00);
854         reg_r(gspca_dev, 0x0002, 1);
855         reg_w_val(gspca_dev, 0x0053, 0x00);
856
857         while (retry--) {
858 /*              reg_r(gspca_dev, 0x0002, 1);*/
859                 reg_r(gspca_dev, 0x0053, 1);
860                 if (gspca_dev->usb_buf[0] == 0)
861                         break;
862         }
863         reg_w_val(gspca_dev, 0x0000, 0x00);
864         reg_r(gspca_dev, 0x0002, 1);
865
866         reg_w_val(gspca_dev, 0x0010, 0x00);
867         reg_r(gspca_dev, 0x0033, 1);
868         reg_w_val(gspca_dev, 0x00fc, 0xe0);
869 }
870
871 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
872                         struct gspca_frame *frame,      /* target */
873                         __u8 *data,                     /* isoc packet */
874                         int len)                        /* iso packet length */
875 {
876         if (data[0] == 0xff && data[1] == 0xd8) {
877
878                 /* start of frame */
879                 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
880                                         data, 0);
881
882                 /* put the JPEG header in the new frame */
883                 jpeg_put_header(gspca_dev, frame,
884                                 ((struct sd *) gspca_dev)->qindex,
885                                 0x22);
886                 data += 2;
887                 len -= 2;
888         }
889         gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
890 }
891
892 static void setbrightness(struct gspca_dev*gspca_dev)
893 {
894         struct sd *sd = (struct sd *) gspca_dev;
895         __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
896         __u8 reg51c[2];
897         __u8 bright;
898         __u8 colors;
899
900         bright = sd->brightness;
901         regE5cbx[2] = bright;
902         reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
903         reg_r(gspca_dev, 0x00e8, 8);
904         reg_w(gspca_dev, 0x00e5, regE5c, 4);
905         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
906
907         colors = sd->colors;
908         reg51c[0] = 0x77;
909         reg51c[1] = colors;
910         reg_w(gspca_dev, 0x0051, reg51c, 2);
911         reg_w(gspca_dev, 0x0010, reg10, 2);
912         reg_w_val(gspca_dev, 0x0070, reg70);
913 }
914
915 static void setcontrast(struct gspca_dev*gspca_dev)
916 {
917         struct sd *sd = (struct sd *) gspca_dev;
918         __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 };   /* seem MSB */
919 /*      __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01};     * LSB */
920         __u8 reg51c[2];
921
922         regE5acx[2] = sd->contrast;
923         reg_w(gspca_dev, 0x00e5, regE5acx, 4);
924         reg_r(gspca_dev, 0x00e8, 1);            /* 0x00 */
925         reg51c[0] = 0x77;
926         reg51c[1] = sd->colors;
927         reg_w(gspca_dev, 0x0051, reg51c, 2);
928         reg_w(gspca_dev, 0x0010, reg10, 2);
929         reg_w_val(gspca_dev, 0x0070, reg70);
930 }
931
932 static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
933 {
934         struct sd *sd = (struct sd *) gspca_dev;
935
936         sd->brightness = val;
937         if (gspca_dev->streaming)
938                 setbrightness(gspca_dev);
939         return 0;
940 }
941
942 static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
943 {
944         struct sd *sd = (struct sd *) gspca_dev;
945
946         *val = sd->brightness;
947         return 0;
948 }
949
950 static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
951 {
952         struct sd *sd = (struct sd *) gspca_dev;
953
954         sd->contrast = val;
955         if (gspca_dev->streaming)
956                 setcontrast(gspca_dev);
957         return 0;
958 }
959
960 static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
961 {
962         struct sd *sd = (struct sd *) gspca_dev;
963
964         *val = sd->contrast;
965         return 0;
966 }
967
968 static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
969 {
970         struct sd *sd = (struct sd *) gspca_dev;
971
972         sd->colors = val;
973         if (gspca_dev->streaming) {
974                 setbrightness(gspca_dev);
975                 setcontrast(gspca_dev);
976         }
977         return 0;
978 }
979
980 static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
981 {
982         struct sd *sd = (struct sd *) gspca_dev;
983
984         *val = sd->colors;
985         return 0;
986 }
987
988 /* sub-driver description */
989 static struct sd_desc sd_desc = {
990         .name = MODULE_NAME,
991         .ctrls = sd_ctrls,
992         .nctrls = ARRAY_SIZE(sd_ctrls),
993         .config = sd_config,
994         .init = sd_init,
995         .start = sd_start,
996         .stop0 = sd_stop0,
997         .pkt_scan = sd_pkt_scan,
998 };
999
1000 /* -- module initialisation -- */
1001 static __devinitdata struct usb_device_id device_table[] = {
1002         {USB_DEVICE(0x0572, 0x0041)},
1003         {}
1004 };
1005 MODULE_DEVICE_TABLE(usb, device_table);
1006
1007 /* -- device connect -- */
1008 static int sd_probe(struct usb_interface *intf,
1009                         const struct usb_device_id *id)
1010 {
1011         return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1012                                 THIS_MODULE);
1013 }
1014
1015 static struct usb_driver sd_driver = {
1016         .name = MODULE_NAME,
1017         .id_table = device_table,
1018         .probe = sd_probe,
1019         .disconnect = gspca_disconnect,
1020 #ifdef CONFIG_PM
1021         .suspend = gspca_suspend,
1022         .resume = gspca_resume,
1023 #endif
1024 };
1025
1026 /* -- module insert / remove -- */
1027 static int __init sd_mod_init(void)
1028 {
1029         if (usb_register(&sd_driver) < 0)
1030                 return -1;
1031         PDEBUG(D_PROBE, "registered");
1032         return 0;
1033 }
1034 static void __exit sd_mod_exit(void)
1035 {
1036         usb_deregister(&sd_driver);
1037         PDEBUG(D_PROBE, "deregistered");
1038 }
1039
1040 module_init(sd_mod_init);
1041 module_exit(sd_mod_exit);