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