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