blob: fd4df402bc2ffdc998e5f0a5a4d416dc84713831 [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;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030039 u8 quality;
40
41 u8 *jpeg_hdr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030042};
43
44/* V4L2 controls supported by the driver */
45static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
46static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
47static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
48static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
49static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
50static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
51
52static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030053 {
54 {
55 .id = V4L2_CID_BRIGHTNESS,
56 .type = V4L2_CTRL_TYPE_INTEGER,
57 .name = "Brightness",
58 .minimum = 0,
59 .maximum = 255,
60 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030061#define BRIGHTNESS_DEF 0xd4
62 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030063 },
64 .set = sd_setbrightness,
65 .get = sd_getbrightness,
66 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030067 {
68 {
69 .id = V4L2_CID_CONTRAST,
70 .type = V4L2_CTRL_TYPE_INTEGER,
71 .name = "Contrast",
72 .minimum = 0x0a,
73 .maximum = 0x1f,
74 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030075#define CONTRAST_DEF 0x0c
76 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030077 },
78 .set = sd_setcontrast,
79 .get = sd_getcontrast,
80 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030081 {
82 {
83 .id = V4L2_CID_SATURATION,
84 .type = V4L2_CTRL_TYPE_INTEGER,
85 .name = "Color",
86 .minimum = 0,
87 .maximum = 7,
88 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030089#define COLOR_DEF 3
90 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030091 },
92 .set = sd_setcolors,
93 .get = sd_getcolors,
94 },
95};
96
Jean-Francois Moinecc611b82008-12-29 07:49:41 -030097static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030098 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
99 .bytesperline = 176,
100 .sizeimage = 176 * 144 * 3 / 8 + 590,
101 .colorspace = V4L2_COLORSPACE_JPEG,
102 .priv = 3},
103 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
104 .bytesperline = 320,
105 .sizeimage = 320 * 240 * 3 / 8 + 590,
106 .colorspace = V4L2_COLORSPACE_JPEG,
107 .priv = 2},
108 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
109 .bytesperline = 352,
110 .sizeimage = 352 * 288 * 3 / 8 + 590,
111 .colorspace = V4L2_COLORSPACE_JPEG,
112 .priv = 1},
113 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
114 .bytesperline = 640,
115 .sizeimage = 640 * 480 * 3 / 8 + 590,
116 .colorspace = V4L2_COLORSPACE_JPEG,
117 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300118};
119
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300120/* the read bytes are found in gspca_dev->usb_buf */
121static void reg_r(struct gspca_dev *gspca_dev,
122 __u16 index,
123 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300124{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300125 struct usb_device *dev = gspca_dev->dev;
126
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300127#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300128 if (len > USB_BUF_SZ) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300129 err("reg_r: buffer overflow");
130 return;
131 }
132#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300133 usb_control_msg(dev,
134 usb_rcvctrlpipe(dev, 0),
135 0,
136 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
137 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300138 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300139 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300140 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
141 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300142}
143
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300144/* the bytes to write are in gspca_dev->usb_buf */
145static void reg_w_val(struct gspca_dev *gspca_dev,
146 __u16 index,
147 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300148{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300149 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300150
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300151 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300152 usb_control_msg(dev,
153 usb_sndctrlpipe(dev, 0),
154 0,
155 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
156 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300157 index, gspca_dev->usb_buf, 1, 500);
158}
159
160static void reg_w(struct gspca_dev *gspca_dev,
161 __u16 index,
162 const __u8 *buffer,
163 __u16 len)
164{
165 struct usb_device *dev = gspca_dev->dev;
166
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300167#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300168 if (len > USB_BUF_SZ) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300169 err("reg_w: buffer overflow");
170 return;
171 }
172 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
173#endif
174 memcpy(gspca_dev->usb_buf, buffer, len);
175 usb_control_msg(dev,
176 usb_sndctrlpipe(dev, 0),
177 0,
178 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
179 0,
180 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300181}
182
183static const __u8 cx_sensor_init[][4] = {
184 {0x88, 0x11, 0x01, 0x01},
185 {0x88, 0x12, 0x70, 0x01},
186 {0x88, 0x0f, 0x00, 0x01},
187 {0x88, 0x05, 0x01, 0x01},
188 {}
189};
190
191static const __u8 cx11646_fw1[][3] = {
192 {0x00, 0x02, 0x00},
193 {0x01, 0x43, 0x00},
194 {0x02, 0xA7, 0x00},
195 {0x03, 0x8B, 0x01},
196 {0x04, 0xE9, 0x02},
197 {0x05, 0x08, 0x04},
198 {0x06, 0x08, 0x05},
199 {0x07, 0x07, 0x06},
200 {0x08, 0xE7, 0x06},
201 {0x09, 0xC6, 0x07},
202 {0x0A, 0x86, 0x08},
203 {0x0B, 0x46, 0x09},
204 {0x0C, 0x05, 0x0A},
205 {0x0D, 0xA5, 0x0A},
206 {0x0E, 0x45, 0x0B},
207 {0x0F, 0xE5, 0x0B},
208 {0x10, 0x85, 0x0C},
209 {0x11, 0x25, 0x0D},
210 {0x12, 0xC4, 0x0D},
211 {0x13, 0x45, 0x0E},
212 {0x14, 0xE4, 0x0E},
213 {0x15, 0x64, 0x0F},
214 {0x16, 0xE4, 0x0F},
215 {0x17, 0x64, 0x10},
216 {0x18, 0xE4, 0x10},
217 {0x19, 0x64, 0x11},
218 {0x1A, 0xE4, 0x11},
219 {0x1B, 0x64, 0x12},
220 {0x1C, 0xE3, 0x12},
221 {0x1D, 0x44, 0x13},
222 {0x1E, 0xC3, 0x13},
223 {0x1F, 0x24, 0x14},
224 {0x20, 0xA3, 0x14},
225 {0x21, 0x04, 0x15},
226 {0x22, 0x83, 0x15},
227 {0x23, 0xE3, 0x15},
228 {0x24, 0x43, 0x16},
229 {0x25, 0xA4, 0x16},
230 {0x26, 0x23, 0x17},
231 {0x27, 0x83, 0x17},
232 {0x28, 0xE3, 0x17},
233 {0x29, 0x43, 0x18},
234 {0x2A, 0xA3, 0x18},
235 {0x2B, 0x03, 0x19},
236 {0x2C, 0x63, 0x19},
237 {0x2D, 0xC3, 0x19},
238 {0x2E, 0x22, 0x1A},
239 {0x2F, 0x63, 0x1A},
240 {0x30, 0xC3, 0x1A},
241 {0x31, 0x23, 0x1B},
242 {0x32, 0x83, 0x1B},
243 {0x33, 0xE2, 0x1B},
244 {0x34, 0x23, 0x1C},
245 {0x35, 0x83, 0x1C},
246 {0x36, 0xE2, 0x1C},
247 {0x37, 0x23, 0x1D},
248 {0x38, 0x83, 0x1D},
249 {0x39, 0xE2, 0x1D},
250 {0x3A, 0x23, 0x1E},
251 {0x3B, 0x82, 0x1E},
252 {0x3C, 0xC3, 0x1E},
253 {0x3D, 0x22, 0x1F},
254 {0x3E, 0x63, 0x1F},
255 {0x3F, 0xC1, 0x1F},
256 {}
257};
258static void cx11646_fw(struct gspca_dev*gspca_dev)
259{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300260 int i = 0;
261
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300262 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300263 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300264 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300265 i++;
266 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300267 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300268}
269
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300270static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300271 0x88, 0x12, 0x70, 0x01,
272 0x88, 0x0d, 0x02, 0x01,
273 0x88, 0x0f, 0x00, 0x01,
274 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
275 0x88, 0x02, 0x10, 0x01,
276 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
277 0x88, 0x0B, 0x00, 0x01,
278 0x88, 0x0A, 0x0A, 0x01,
279 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
280 0x88, 0x05, 0x01, 0x01,
281 0xA1, 0x18, 0x00, 0x01,
282 0x00
283};
284
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300285static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
286static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
287static const __u8 reg10[] = { 0xb1, 0xb1 };
288static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
289static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300290 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300291static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300292 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300293static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
294static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300295
296static void cx_sensor(struct gspca_dev*gspca_dev)
297{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300298 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300299 int length;
300 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300301
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300302 reg_w(gspca_dev, 0x0020, reg20, 8);
303 reg_w(gspca_dev, 0x0028, reg28, 8);
304 reg_w(gspca_dev, 0x0010, reg10, 8);
305 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300306
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300307 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300308 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300309 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300310 break;
311 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300312 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300313 break;
314 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300315/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300316 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300317 break;
318 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300319 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300320 break;
321 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300322 reg_w(gspca_dev, 0x007b, reg7b, 6);
323 reg_w_val(gspca_dev, 0x00f8, 0x00);
324 reg_w(gspca_dev, 0x0010, reg10, 8);
325 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300326 for (i = 0; i < 11; i++) {
327 if (i == 3 || i == 5 || i == 8)
328 length = 8;
329 else
330 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300331 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300332 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300333 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300334 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300335 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300336 ptsensor += length;
337 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300338 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300339}
340
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300341static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300342 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
343 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
344 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
345 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
346 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
347 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
348 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
349};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300350static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300351 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
352 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
353 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
354 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
355 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
356 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
357 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
358};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300359static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300360 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
361 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
362 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
363 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
364 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
365 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
366 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
367};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300368static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300369 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
370 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
371 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
372 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
373 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
374 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
375 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
376};
377
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300378static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300379{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300380 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300381 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
382 static const __u8 reg17[] =
383 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
384
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300385 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300386 case 0:
387 cxinit = cx_inits_640;
388 break;
389 case 1:
390 cxinit = cx_inits_352;
391 break;
392 default:
393/* case 2: */
394 cxinit = cx_inits_320;
395 break;
396 case 3:
397 cxinit = cx_inits_176;
398 break;
399 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300400 reg_w_val(gspca_dev, 0x009a, 0x01);
401 reg_w_val(gspca_dev, 0x0010, 0x10);
402 reg_w(gspca_dev, 0x0012, reg12, 5);
403 reg_w(gspca_dev, 0x0017, reg17, 8);
404 reg_w_val(gspca_dev, 0x00c0, 0x00);
405 reg_w_val(gspca_dev, 0x00c1, 0x04);
406 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300407
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300408 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300409 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300410 reg_w(gspca_dev, 0x00ca, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300411 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300412 reg_w(gspca_dev, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300413 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300414 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300415 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300416 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300417 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300418 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300419 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300420 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300421
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300422 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300423}
424
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300425static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300426 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
427 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
428 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
429 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
430 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
431 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
432 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
433 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
434 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
435 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
436 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
437 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
438 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
439 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
440 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
441 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
442 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
443 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
444 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
445 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
446 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
447 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
448 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
449 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
450 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
451 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
452 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
453 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
454 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
455 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
456 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
457 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
458 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
459 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
460 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
461 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
462 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
463 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
464 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
465 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
466 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
467 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
468 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
469 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
470 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
471 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
472 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
473 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
474 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
475 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
476 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
477 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
478 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
479 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
480 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
481 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
482 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
483 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
484 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
485 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
486 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
487 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
488 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
489 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
490 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
491 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
492 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
493 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
494 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
495 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
496 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
497 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
498 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
499 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
500 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
501 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
502 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
503 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
504 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
505};
506
507
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300508static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300509 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
510 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
511 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
512 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
513 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
514 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
515 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
516 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
517 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
518 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
519 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
520 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
521 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
522 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
523 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
524 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
525 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
526 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
527 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
528 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
529 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
530 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
531 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
532 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
533 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
534 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
535 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
536};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300537static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300538 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
539 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
540 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
541 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
542 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
543 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
544 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
545 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
546 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
547 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
548 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
549 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
550 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
551 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
552 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
553 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
554 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
555 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
556 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
557 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
558 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
559 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
560 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
561 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
562 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
563 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
564 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
565};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300566static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300567 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
568 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
569 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
570 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
571 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
572 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
573 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
574 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
575 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
576 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
577 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
578 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
579 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
580 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
581 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
582 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
583 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
584 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
585 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
586 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
587 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
588 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
589 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
590 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
591 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
592 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
593 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
594};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300595static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300596 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
597 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
598 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
599 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
600 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
601 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
602 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
603 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
604 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
605 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
606 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
607 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
608 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
609 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
610 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
611 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
612 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
613 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
614 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
615 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
616 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
617 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
618 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
619 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
620 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
621 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
622 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
623};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300624/* 640 take with the zcx30x part */
625static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300626 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
627 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
628 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
629 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
630 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
631 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
632 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
633 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
634 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
635 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
636 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 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 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
643 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
644};
645
646
647static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
648{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300649 int i;
650 int length;
651
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300652 reg_w_val(gspca_dev, 0x00c0, 0x01);
653 reg_w_val(gspca_dev, 0x00c3, 0x00);
654 reg_w_val(gspca_dev, 0x00c0, 0x00);
655 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300656 length = 8;
657 for (i = 0; i < 79; i++) {
658 if (i == 78)
659 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300660 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300661 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300662 reg_r(gspca_dev, 0x0002, 1);
663 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300664}
665
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300666static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
667static const __u8 regE5_8[] =
668 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
669static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
670static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
671static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
672static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300673#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300674
675static void cx11646_jpeg(struct gspca_dev*gspca_dev)
676{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300677 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300678 int length;
679 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300680 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300681
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300682 reg_w_val(gspca_dev, 0x00c0, 0x01);
683 reg_w_val(gspca_dev, 0x00c3, 0x00);
684 reg_w_val(gspca_dev, 0x00c0, 0x00);
685 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300686 length = 8;
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300687 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300688 case 0:
689 for (i = 0; i < 27; i++) {
690 if (i == 26)
691 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300692 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300693 }
694 Reg55 = 0x28;
695 break;
696 case 1:
697 for (i = 0; i < 27; i++) {
698 if (i == 26)
699 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300700 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300701 }
702 Reg55 = 0x16;
703 break;
704 default:
705/* case 2: */
706 for (i = 0; i < 27; i++) {
707 if (i == 26)
708 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300709 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300710 }
711 Reg55 = 0x14;
712 break;
713 case 3:
714 for (i = 0; i < 27; i++) {
715 if (i == 26)
716 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300717 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300718 }
719 Reg55 = 0x0B;
720 break;
721 }
722
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300723 reg_r(gspca_dev, 0x0002, 1);
724 reg_w_val(gspca_dev, 0x0055, Reg55);
725 reg_r(gspca_dev, 0x0002, 1);
726 reg_w(gspca_dev, 0x0010, reg10, 2);
727 reg_w_val(gspca_dev, 0x0054, 0x02);
728 reg_w_val(gspca_dev, 0x0054, 0x01);
729 reg_w_val(gspca_dev, 0x0000, 0x94);
730 reg_w_val(gspca_dev, 0x0053, 0xc0);
731 reg_w_val(gspca_dev, 0x00fc, 0xe1);
732 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300734 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300735 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300736 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300737 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300738 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300739 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300740 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300741 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742 if (retry == 0)
743 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
744 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300745 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300746 length = 8;
747 for (i = 0; i < 18; i++) {
748 if (i == 17)
749 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300750 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751
752 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300753 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
754 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
755 reg_w_val(gspca_dev, 0x0054, 0x02);
756 reg_w_val(gspca_dev, 0x0054, 0x01);
757 reg_w_val(gspca_dev, 0x0000, 0x94);
758 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300759
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300760 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
761 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
762 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
763 reg_w(gspca_dev, 0x0012, reg12, 5);
764 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
765 reg_r(gspca_dev, 0x00e8, 8);
766 reg_w(gspca_dev, 0x00e5, regE5a, 4);
767 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
768 reg_w_val(gspca_dev, 0x009a, 0x01);
769 reg_w(gspca_dev, 0x00e5, regE5b, 4);
770 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
771 reg_w(gspca_dev, 0x00e5, regE5c, 4);
772 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300773
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300774 reg_w(gspca_dev, 0x0051, reg51, 2);
775 reg_w(gspca_dev, 0x0010, reg10, 2);
776 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777}
778
779static void cx11646_init1(struct gspca_dev *gspca_dev)
780{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300781 int i = 0;
782
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300783 reg_w_val(gspca_dev, 0x0010, 0x00);
784 reg_w_val(gspca_dev, 0x0053, 0x00);
785 reg_w_val(gspca_dev, 0x0052, 0x00);
786 reg_w_val(gspca_dev, 0x009b, 0x2f);
787 reg_w_val(gspca_dev, 0x009c, 0x10);
788 reg_r(gspca_dev, 0x0098, 1);
789 reg_w_val(gspca_dev, 0x0098, 0x40);
790 reg_r(gspca_dev, 0x0099, 1);
791 reg_w_val(gspca_dev, 0x0099, 0x07);
792 reg_w_val(gspca_dev, 0x0039, 0x40);
793 reg_w_val(gspca_dev, 0x003c, 0xff);
794 reg_w_val(gspca_dev, 0x003f, 0x1f);
795 reg_w_val(gspca_dev, 0x003d, 0x40);
796/* reg_w_val(gspca_dev, 0x003d, 0x60); */
797 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300798
799 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300800 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
801 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300802 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300803 reg_w_val(gspca_dev, 0x00ed, 0x01);
804 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805 }
806 i++;
807 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300808 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300809}
810
811/* this function is called at probe time */
812static int sd_config(struct gspca_dev *gspca_dev,
813 const struct usb_device_id *id)
814{
815 struct sd *sd = (struct sd *) gspca_dev;
816 struct cam *cam;
817
818 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300819 cam->cam_mode = vga_mode;
820 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
821
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300822 sd->brightness = BRIGHTNESS_DEF;
823 sd->contrast = CONTRAST_DEF;
824 sd->colors = COLOR_DEF;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300825 sd->quality = 40;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826 return 0;
827}
828
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300829/* this function is called at probe and resume time */
830static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300831{
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
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300840static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300842 struct sd *sd = (struct sd *) gspca_dev;
843
844 /* create the JPEG header */
845 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
846 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
847 0x22); /* JPEG 411 */
848 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
849
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300850 cx11646_initsize(gspca_dev);
851 cx11646_fw(gspca_dev);
852 cx_sensor(gspca_dev);
853 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300854 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300855}
856
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300857/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300858static void sd_stop0(struct gspca_dev *gspca_dev)
859{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300860 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300861 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300863 kfree(sd->jpeg_hdr);
864
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300865 if (!gspca_dev->present)
866 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300867 reg_w_val(gspca_dev, 0x0000, 0x00);
868 reg_r(gspca_dev, 0x0002, 1);
869 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300870
871 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300872/* reg_r(gspca_dev, 0x0002, 1);*/
873 reg_r(gspca_dev, 0x0053, 1);
874 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300875 break;
876 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300877 reg_w_val(gspca_dev, 0x0000, 0x00);
878 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300879
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300880 reg_w_val(gspca_dev, 0x0010, 0x00);
881 reg_r(gspca_dev, 0x0033, 1);
882 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883}
884
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300885static void sd_pkt_scan(struct gspca_dev *gspca_dev,
886 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300887 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888 int len) /* iso packet length */
889{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300890 struct sd *sd = (struct sd *) gspca_dev;
891
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300892 if (data[0] == 0xff && data[1] == 0xd8) {
893
894 /* start of frame */
895 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
896 data, 0);
897
898 /* put the JPEG header in the new frame */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300899 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
900 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300901 data += 2;
902 len -= 2;
903 }
904 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
905}
906
907static void setbrightness(struct gspca_dev*gspca_dev)
908{
909 struct sd *sd = (struct sd *) gspca_dev;
910 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300911 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300912 __u8 bright;
913 __u8 colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300914
915 bright = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300916 regE5cbx[2] = bright;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300917 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
918 reg_r(gspca_dev, 0x00e8, 8);
919 reg_w(gspca_dev, 0x00e5, regE5c, 4);
920 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300922 colors = sd->colors;
923 reg51c[0] = 0x77;
924 reg51c[1] = colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300925 reg_w(gspca_dev, 0x0051, reg51c, 2);
926 reg_w(gspca_dev, 0x0010, reg10, 2);
927 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300928}
929
930static void setcontrast(struct gspca_dev*gspca_dev)
931{
932 struct sd *sd = (struct sd *) gspca_dev;
933 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300934/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
935 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300937 regE5acx[2] = sd->contrast;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300938 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
939 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300940 reg51c[0] = 0x77;
941 reg51c[1] = sd->colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300942 reg_w(gspca_dev, 0x0051, reg51c, 2);
943 reg_w(gspca_dev, 0x0010, reg10, 2);
944 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300945}
946
947static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
948{
949 struct sd *sd = (struct sd *) gspca_dev;
950
951 sd->brightness = val;
952 if (gspca_dev->streaming)
953 setbrightness(gspca_dev);
954 return 0;
955}
956
957static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
958{
959 struct sd *sd = (struct sd *) gspca_dev;
960
961 *val = sd->brightness;
962 return 0;
963}
964
965static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
966{
967 struct sd *sd = (struct sd *) gspca_dev;
968
969 sd->contrast = val;
970 if (gspca_dev->streaming)
971 setcontrast(gspca_dev);
972 return 0;
973}
974
975static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
976{
977 struct sd *sd = (struct sd *) gspca_dev;
978
979 *val = sd->contrast;
980 return 0;
981}
982
983static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
984{
985 struct sd *sd = (struct sd *) gspca_dev;
986
987 sd->colors = val;
988 if (gspca_dev->streaming) {
989 setbrightness(gspca_dev);
990 setcontrast(gspca_dev);
991 }
992 return 0;
993}
994
995static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
996{
997 struct sd *sd = (struct sd *) gspca_dev;
998
999 *val = sd->colors;
1000 return 0;
1001}
1002
1003/* sub-driver description */
1004static struct sd_desc sd_desc = {
1005 .name = MODULE_NAME,
1006 .ctrls = sd_ctrls,
1007 .nctrls = ARRAY_SIZE(sd_ctrls),
1008 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001009 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001010 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001011 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001012 .pkt_scan = sd_pkt_scan,
1013};
1014
1015/* -- module initialisation -- */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001016static __devinitdata struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001017 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001018 {}
1019};
1020MODULE_DEVICE_TABLE(usb, device_table);
1021
1022/* -- device connect -- */
1023static int sd_probe(struct usb_interface *intf,
1024 const struct usb_device_id *id)
1025{
1026 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1027 THIS_MODULE);
1028}
1029
1030static struct usb_driver sd_driver = {
1031 .name = MODULE_NAME,
1032 .id_table = device_table,
1033 .probe = sd_probe,
1034 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001035#ifdef CONFIG_PM
1036 .suspend = gspca_suspend,
1037 .resume = gspca_resume,
1038#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001039};
1040
1041/* -- module insert / remove -- */
1042static int __init sd_mod_init(void)
1043{
Alexey Klimovf69e9522009-01-01 13:02:07 -03001044 int ret;
1045 ret = usb_register(&sd_driver);
1046 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03001047 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001048 PDEBUG(D_PROBE, "registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001049 return 0;
1050}
1051static void __exit sd_mod_exit(void)
1052{
1053 usb_deregister(&sd_driver);
1054 PDEBUG(D_PROBE, "deregistered");
1055}
1056
1057module_init(sd_mod_init);
1058module_exit(sd_mod_exit);