blob: 739ef557c43484bd267c092984f9b09093a99882 [file] [log] [blame]
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001/*
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
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030028MODULE_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[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030052 {
53 {
54 .id = V4L2_CID_BRIGHTNESS,
55 .type = V4L2_CTRL_TYPE_INTEGER,
56 .name = "Brightness",
57 .minimum = 0,
58 .maximum = 255,
59 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030060#define BRIGHTNESS_DEF 0xd4
61 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030062 },
63 .set = sd_setbrightness,
64 .get = sd_getbrightness,
65 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030066 {
67 {
68 .id = V4L2_CID_CONTRAST,
69 .type = V4L2_CTRL_TYPE_INTEGER,
70 .name = "Contrast",
71 .minimum = 0x0a,
72 .maximum = 0x1f,
73 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030074#define CONTRAST_DEF 0x0c
75 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030076 },
77 .set = sd_setcontrast,
78 .get = sd_getcontrast,
79 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030080 {
81 {
82 .id = V4L2_CID_SATURATION,
83 .type = V4L2_CTRL_TYPE_INTEGER,
84 .name = "Color",
85 .minimum = 0,
86 .maximum = 7,
87 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030088#define COLOR_DEF 3
89 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030090 },
91 .set = sd_setcolors,
92 .get = sd_getcolors,
93 },
94};
95
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030096static struct v4l2_pix_format vga_mode[] = {
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},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300117};
118
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300119/* 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)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300123{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300124 struct usb_device *dev = gspca_dev->dev;
125
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300126#ifdef GSPCA_DEBUG
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300127 if (len > sizeof gspca_dev->usb_buf) {
128 err("reg_r: buffer overflow");
129 return;
130 }
131#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300132 usb_control_msg(dev,
133 usb_rcvctrlpipe(dev, 0),
134 0,
135 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
136 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300137 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300138 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300139 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
140 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300141}
142
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300143/* 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)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300147{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300148 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300149
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300150 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300151 usb_control_msg(dev,
152 usb_sndctrlpipe(dev, 0),
153 0,
154 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
155 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300156 index, gspca_dev->usb_buf, 1, 500);
157}
158
159static void reg_w(struct gspca_dev *gspca_dev,
160 __u16 index,
161 const __u8 *buffer,
162 __u16 len)
163{
164 struct usb_device *dev = gspca_dev->dev;
165
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300166#ifdef GSPCA_DEBUG
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300167 if (len > sizeof gspca_dev->usb_buf) {
168 err("reg_w: buffer overflow");
169 return;
170 }
171 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
172#endif
173 memcpy(gspca_dev->usb_buf, buffer, len);
174 usb_control_msg(dev,
175 usb_sndctrlpipe(dev, 0),
176 0,
177 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
178 0,
179 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300180}
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{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300259 int i = 0;
260
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300261 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300262 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300263 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300264 i++;
265 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300266 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267}
268
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300269static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300270 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
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300284static 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 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300289 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300290static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300291 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300292static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
293static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300294
295static void cx_sensor(struct gspca_dev*gspca_dev)
296{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300297 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300298 int length;
299 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300300
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300301 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);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300305
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300306 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300307 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300308 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300309 break;
310 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300311 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300312 break;
313 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300314/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300315 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300316 break;
317 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300318 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300319 break;
320 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300321 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);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300325 for (i = 0; i < 11; i++) {
326 if (i == 3 || i == 5 || i == 8)
327 length = 8;
328 else
329 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300330 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300331 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300332 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300333 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300334 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300335 ptsensor += length;
336 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300337 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300338}
339
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300340static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300341 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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300349static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300350 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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300358static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300359 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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300367static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300368 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
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300377static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300378{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300379 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300380 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
381 static const __u8 reg17[] =
382 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
383
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300384 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300385 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 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300399 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);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300406
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300407 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300408 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300409 reg_w(gspca_dev, 0x00ca, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300410 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300411 reg_w(gspca_dev, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300412 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300413 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300414 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300415 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300416 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300417 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300418 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300419 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300420
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300421 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300422}
423
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300424static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300425 {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
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300507static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300508 {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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300536static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300537 {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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300565static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300566 {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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300594static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300595 {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};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300623/* 640 take with the zcx30x part */
624static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300625 {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{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300648 int i;
649 int length;
650
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300651 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);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300655 length = 8;
656 for (i = 0; i < 79; i++) {
657 if (i == 78)
658 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300659 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300660 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300661 reg_r(gspca_dev, 0x0002, 1);
662 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300663}
664
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300665static 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 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300672#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300673
674static void cx11646_jpeg(struct gspca_dev*gspca_dev)
675{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300676 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300677 int length;
678 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300679 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300680
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300681 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);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300685 length = 8;
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300686 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300687 case 0:
688 for (i = 0; i < 27; i++) {
689 if (i == 26)
690 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300691 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300692 }
693 Reg55 = 0x28;
694 break;
695 case 1:
696 for (i = 0; i < 27; i++) {
697 if (i == 26)
698 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300699 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300700 }
701 Reg55 = 0x16;
702 break;
703 default:
704/* case 2: */
705 for (i = 0; i < 27; i++) {
706 if (i == 26)
707 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300708 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300709 }
710 Reg55 = 0x14;
711 break;
712 case 3:
713 for (i = 0; i < 27; i++) {
714 if (i == 26)
715 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300716 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300717 }
718 Reg55 = 0x0B;
719 break;
720 }
721
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300722 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);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300732 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300733 retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300734 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300735 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300736 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300737 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300738 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300739 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300740 }
741 if (retry == 0)
742 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
743 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300744 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300745 length = 8;
746 for (i = 0; i < 18; i++) {
747 if (i == 17)
748 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300749 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300750
751 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300752 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);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300758
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300759 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 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300772
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300773 reg_w(gspca_dev, 0x0051, reg51, 2);
774 reg_w(gspca_dev, 0x0010, reg10, 2);
775 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300776}
777
778static void cx11646_init1(struct gspca_dev *gspca_dev)
779{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300780 int i = 0;
781
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300782 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 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300797
798 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300799 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
800 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300802 reg_w_val(gspca_dev, 0x00ed, 0x01);
803 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300804 }
805 i++;
806 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300807 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300808}
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;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300818 cam->epaddr = 0x01;
819 cam->cam_mode = vga_mode;
820 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
821
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300822 sd->qindex = 0; /* set the quantization */
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300823 sd->brightness = BRIGHTNESS_DEF;
824 sd->contrast = CONTRAST_DEF;
825 sd->colors = COLOR_DEF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826 return 0;
827}
828
829/* this function is called at open time */
830static int sd_open(struct gspca_dev *gspca_dev)
831{
832 cx11646_init1(gspca_dev);
833 cx11646_initsize(gspca_dev);
834 cx11646_fw(gspca_dev);
835 cx_sensor(gspca_dev);
836 cx11646_jpegInit(gspca_dev);
837 return 0;
838}
839
840static void sd_start(struct gspca_dev *gspca_dev)
841{
842 cx11646_initsize(gspca_dev);
843 cx11646_fw(gspca_dev);
844 cx_sensor(gspca_dev);
845 cx11646_jpeg(gspca_dev);
846}
847
848static void sd_stopN(struct gspca_dev *gspca_dev)
849{
850}
851
852static void sd_stop0(struct gspca_dev *gspca_dev)
853{
854 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300855
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300856 reg_w_val(gspca_dev, 0x0000, 0x00);
857 reg_r(gspca_dev, 0x0002, 1);
858 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859
860 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300861/* reg_r(gspca_dev, 0x0002, 1);*/
862 reg_r(gspca_dev, 0x0053, 1);
863 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300864 break;
865 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300866 reg_w_val(gspca_dev, 0x0000, 0x00);
867 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300868
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300869 reg_w_val(gspca_dev, 0x0010, 0x00);
870 reg_r(gspca_dev, 0x0033, 1);
871 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300872}
873
874static void sd_close(struct gspca_dev *gspca_dev)
875{
876}
877
878static void sd_pkt_scan(struct gspca_dev *gspca_dev,
879 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300880 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300881 int len) /* iso packet length */
882{
883 if (data[0] == 0xff && data[1] == 0xd8) {
884
885 /* start of frame */
886 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
887 data, 0);
888
889 /* put the JPEG header in the new frame */
890 jpeg_put_header(gspca_dev, frame,
891 ((struct sd *) gspca_dev)->qindex,
892 0x22);
893 data += 2;
894 len -= 2;
895 }
896 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
897}
898
899static void setbrightness(struct gspca_dev*gspca_dev)
900{
901 struct sd *sd = (struct sd *) gspca_dev;
902 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300903 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300904 __u8 bright;
905 __u8 colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300906
907 bright = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300908 regE5cbx[2] = bright;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300909 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
910 reg_r(gspca_dev, 0x00e8, 8);
911 reg_w(gspca_dev, 0x00e5, regE5c, 4);
912 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300913
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300914 colors = sd->colors;
915 reg51c[0] = 0x77;
916 reg51c[1] = colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300917 reg_w(gspca_dev, 0x0051, reg51c, 2);
918 reg_w(gspca_dev, 0x0010, reg10, 2);
919 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300920}
921
922static void setcontrast(struct gspca_dev*gspca_dev)
923{
924 struct sd *sd = (struct sd *) gspca_dev;
925 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300926/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
927 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300928
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300929 regE5acx[2] = sd->contrast;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300930 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
931 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300932 reg51c[0] = 0x77;
933 reg51c[1] = sd->colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300934 reg_w(gspca_dev, 0x0051, reg51c, 2);
935 reg_w(gspca_dev, 0x0010, reg10, 2);
936 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300937}
938
939static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
940{
941 struct sd *sd = (struct sd *) gspca_dev;
942
943 sd->brightness = val;
944 if (gspca_dev->streaming)
945 setbrightness(gspca_dev);
946 return 0;
947}
948
949static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
950{
951 struct sd *sd = (struct sd *) gspca_dev;
952
953 *val = sd->brightness;
954 return 0;
955}
956
957static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
958{
959 struct sd *sd = (struct sd *) gspca_dev;
960
961 sd->contrast = val;
962 if (gspca_dev->streaming)
963 setcontrast(gspca_dev);
964 return 0;
965}
966
967static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
968{
969 struct sd *sd = (struct sd *) gspca_dev;
970
971 *val = sd->contrast;
972 return 0;
973}
974
975static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
976{
977 struct sd *sd = (struct sd *) gspca_dev;
978
979 sd->colors = val;
980 if (gspca_dev->streaming) {
981 setbrightness(gspca_dev);
982 setcontrast(gspca_dev);
983 }
984 return 0;
985}
986
987static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
988{
989 struct sd *sd = (struct sd *) gspca_dev;
990
991 *val = sd->colors;
992 return 0;
993}
994
995/* sub-driver description */
996static struct sd_desc sd_desc = {
997 .name = MODULE_NAME,
998 .ctrls = sd_ctrls,
999 .nctrls = ARRAY_SIZE(sd_ctrls),
1000 .config = sd_config,
1001 .open = sd_open,
1002 .start = sd_start,
1003 .stopN = sd_stopN,
1004 .stop0 = sd_stop0,
1005 .close = sd_close,
1006 .pkt_scan = sd_pkt_scan,
1007};
1008
1009/* -- module initialisation -- */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001010static __devinitdata struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001011 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001012 {}
1013};
1014MODULE_DEVICE_TABLE(usb, device_table);
1015
1016/* -- device connect -- */
1017static int sd_probe(struct usb_interface *intf,
1018 const struct usb_device_id *id)
1019{
1020 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1021 THIS_MODULE);
1022}
1023
1024static struct usb_driver sd_driver = {
1025 .name = MODULE_NAME,
1026 .id_table = device_table,
1027 .probe = sd_probe,
1028 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001029#ifdef CONFIG_PM
1030 .suspend = gspca_suspend,
1031 .resume = gspca_resume,
1032#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001033};
1034
1035/* -- module insert / remove -- */
1036static int __init sd_mod_init(void)
1037{
1038 if (usb_register(&sd_driver) < 0)
1039 return -1;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001040 PDEBUG(D_PROBE, "registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001041 return 0;
1042}
1043static void __exit sd_mod_exit(void)
1044{
1045 usb_deregister(&sd_driver);
1046 PDEBUG(D_PROBE, "deregistered");
1047}
1048
1049module_init(sd_mod_init);
1050module_exit(sd_mod_exit);