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