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