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