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