blob: c9052f20435ef00c2fc17cc2c870ebbfaedc0896 [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
Joe Perches133a9fe2011-08-21 19:56:57 -030022#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030024#define MODULE_NAME "conex"
25
26#include "gspca.h"
27#define CONEX_CAM 1 /* special JPEG header */
28#include "jpeg.h"
29
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030030MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
31MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
32MODULE_LICENSE("GPL");
33
Hans de Goedeb56ab4c2012-06-27 16:48:33 -030034#define QUALITY 50
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030035
Hans Verkuilcbc1c942012-05-14 04:09:17 -030036/* specific webcam descriptor */
37struct sd {
38 struct gspca_dev gspca_dev; /* !! must be the first item */
39 struct v4l2_ctrl *brightness;
40 struct v4l2_ctrl *contrast;
41 struct v4l2_ctrl *sat;
Hans Verkuilcbc1c942012-05-14 04:09:17 -030042
Jean-François Moine9a731a32010-06-04 05:26:42 -030043 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030044};
45
Jean-Francois Moinecc611b82008-12-29 07:49:41 -030046static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030047 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
48 .bytesperline = 176,
49 .sizeimage = 176 * 144 * 3 / 8 + 590,
50 .colorspace = V4L2_COLORSPACE_JPEG,
51 .priv = 3},
52 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
53 .bytesperline = 320,
54 .sizeimage = 320 * 240 * 3 / 8 + 590,
55 .colorspace = V4L2_COLORSPACE_JPEG,
56 .priv = 2},
57 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
58 .bytesperline = 352,
59 .sizeimage = 352 * 288 * 3 / 8 + 590,
60 .colorspace = V4L2_COLORSPACE_JPEG,
61 .priv = 1},
62 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
63 .bytesperline = 640,
64 .sizeimage = 640 * 480 * 3 / 8 + 590,
65 .colorspace = V4L2_COLORSPACE_JPEG,
66 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030067};
68
Jean-Francois Moine739570b2008-07-14 09:38:29 -030069/* the read bytes are found in gspca_dev->usb_buf */
70static void reg_r(struct gspca_dev *gspca_dev,
71 __u16 index,
72 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030073{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030074 struct usb_device *dev = gspca_dev->dev;
75
Jean-Francois Moine335b3f82008-07-30 04:53:02 -030076#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -030077 if (len > USB_BUF_SZ) {
Joe Perches133a9fe2011-08-21 19:56:57 -030078 pr_err("reg_r: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -030079 return;
80 }
81#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030082 usb_control_msg(dev,
83 usb_rcvctrlpipe(dev, 0),
84 0,
85 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
86 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -030087 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030088 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -030089 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
90 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030091}
92
Jean-Francois Moine739570b2008-07-14 09:38:29 -030093/* the bytes to write are in gspca_dev->usb_buf */
94static void reg_w_val(struct gspca_dev *gspca_dev,
95 __u16 index,
96 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030097{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030098 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -030099
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300100 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300101 usb_control_msg(dev,
102 usb_sndctrlpipe(dev, 0),
103 0,
104 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
105 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300106 index, gspca_dev->usb_buf, 1, 500);
107}
108
109static void reg_w(struct gspca_dev *gspca_dev,
110 __u16 index,
111 const __u8 *buffer,
112 __u16 len)
113{
114 struct usb_device *dev = gspca_dev->dev;
115
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300116#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300117 if (len > USB_BUF_SZ) {
Joe Perches133a9fe2011-08-21 19:56:57 -0300118 pr_err("reg_w: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300119 return;
120 }
121 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
122#endif
123 memcpy(gspca_dev->usb_buf, buffer, len);
124 usb_control_msg(dev,
125 usb_sndctrlpipe(dev, 0),
126 0,
127 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
128 0,
129 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300130}
131
132static const __u8 cx_sensor_init[][4] = {
133 {0x88, 0x11, 0x01, 0x01},
134 {0x88, 0x12, 0x70, 0x01},
135 {0x88, 0x0f, 0x00, 0x01},
136 {0x88, 0x05, 0x01, 0x01},
137 {}
138};
139
140static const __u8 cx11646_fw1[][3] = {
141 {0x00, 0x02, 0x00},
142 {0x01, 0x43, 0x00},
143 {0x02, 0xA7, 0x00},
144 {0x03, 0x8B, 0x01},
145 {0x04, 0xE9, 0x02},
146 {0x05, 0x08, 0x04},
147 {0x06, 0x08, 0x05},
148 {0x07, 0x07, 0x06},
149 {0x08, 0xE7, 0x06},
150 {0x09, 0xC6, 0x07},
151 {0x0A, 0x86, 0x08},
152 {0x0B, 0x46, 0x09},
153 {0x0C, 0x05, 0x0A},
154 {0x0D, 0xA5, 0x0A},
155 {0x0E, 0x45, 0x0B},
156 {0x0F, 0xE5, 0x0B},
157 {0x10, 0x85, 0x0C},
158 {0x11, 0x25, 0x0D},
159 {0x12, 0xC4, 0x0D},
160 {0x13, 0x45, 0x0E},
161 {0x14, 0xE4, 0x0E},
162 {0x15, 0x64, 0x0F},
163 {0x16, 0xE4, 0x0F},
164 {0x17, 0x64, 0x10},
165 {0x18, 0xE4, 0x10},
166 {0x19, 0x64, 0x11},
167 {0x1A, 0xE4, 0x11},
168 {0x1B, 0x64, 0x12},
169 {0x1C, 0xE3, 0x12},
170 {0x1D, 0x44, 0x13},
171 {0x1E, 0xC3, 0x13},
172 {0x1F, 0x24, 0x14},
173 {0x20, 0xA3, 0x14},
174 {0x21, 0x04, 0x15},
175 {0x22, 0x83, 0x15},
176 {0x23, 0xE3, 0x15},
177 {0x24, 0x43, 0x16},
178 {0x25, 0xA4, 0x16},
179 {0x26, 0x23, 0x17},
180 {0x27, 0x83, 0x17},
181 {0x28, 0xE3, 0x17},
182 {0x29, 0x43, 0x18},
183 {0x2A, 0xA3, 0x18},
184 {0x2B, 0x03, 0x19},
185 {0x2C, 0x63, 0x19},
186 {0x2D, 0xC3, 0x19},
187 {0x2E, 0x22, 0x1A},
188 {0x2F, 0x63, 0x1A},
189 {0x30, 0xC3, 0x1A},
190 {0x31, 0x23, 0x1B},
191 {0x32, 0x83, 0x1B},
192 {0x33, 0xE2, 0x1B},
193 {0x34, 0x23, 0x1C},
194 {0x35, 0x83, 0x1C},
195 {0x36, 0xE2, 0x1C},
196 {0x37, 0x23, 0x1D},
197 {0x38, 0x83, 0x1D},
198 {0x39, 0xE2, 0x1D},
199 {0x3A, 0x23, 0x1E},
200 {0x3B, 0x82, 0x1E},
201 {0x3C, 0xC3, 0x1E},
202 {0x3D, 0x22, 0x1F},
203 {0x3E, 0x63, 0x1F},
204 {0x3F, 0xC1, 0x1F},
205 {}
206};
207static void cx11646_fw(struct gspca_dev*gspca_dev)
208{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300209 int i = 0;
210
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300211 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300212 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300213 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300214 i++;
215 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300216 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300217}
218
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300219static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300220 0x88, 0x12, 0x70, 0x01,
221 0x88, 0x0d, 0x02, 0x01,
222 0x88, 0x0f, 0x00, 0x01,
223 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
224 0x88, 0x02, 0x10, 0x01,
225 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
226 0x88, 0x0B, 0x00, 0x01,
227 0x88, 0x0A, 0x0A, 0x01,
228 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
229 0x88, 0x05, 0x01, 0x01,
230 0xA1, 0x18, 0x00, 0x01,
231 0x00
232};
233
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300234static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
235static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
236static const __u8 reg10[] = { 0xb1, 0xb1 };
237static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
238static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300239 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300240static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300241 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300242static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
243static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300244
245static void cx_sensor(struct gspca_dev*gspca_dev)
246{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300247 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300248 int length;
249 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300250
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300251 reg_w(gspca_dev, 0x0020, reg20, 8);
252 reg_w(gspca_dev, 0x0028, reg28, 8);
Dan Carpenterb1890002012-05-02 02:15:25 -0300253 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300254 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300255
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300256 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300257 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300258 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300259 break;
260 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300261 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300262 break;
263 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300264/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300265 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300266 break;
267 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300268 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300269 break;
270 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300271 reg_w(gspca_dev, 0x007b, reg7b, 6);
272 reg_w_val(gspca_dev, 0x00f8, 0x00);
Dan Carpenterb1890002012-05-02 02:15:25 -0300273 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300274 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300275 for (i = 0; i < 11; i++) {
276 if (i == 3 || i == 5 || i == 8)
277 length = 8;
278 else
279 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300280 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300281 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300282 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300283 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300284 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300285 ptsensor += length;
286 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300287 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300288}
289
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300290static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300291 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
292 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
293 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
294 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
295 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
296 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
297 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
298};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300299static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300300 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
301 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
302 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
303 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
304 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
305 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
306 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
307};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300308static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300309 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
310 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
311 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
312 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
313 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
314 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
315 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
316};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300317static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300318 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
319 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
320 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
321 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
322 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
323 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
324 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
325};
326
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300327static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300328{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300329 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300330 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
331 static const __u8 reg17[] =
332 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
333
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300334 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300335 case 0:
336 cxinit = cx_inits_640;
337 break;
338 case 1:
339 cxinit = cx_inits_352;
340 break;
341 default:
342/* case 2: */
343 cxinit = cx_inits_320;
344 break;
345 case 3:
346 cxinit = cx_inits_176;
347 break;
348 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300349 reg_w_val(gspca_dev, 0x009a, 0x01);
350 reg_w_val(gspca_dev, 0x0010, 0x10);
351 reg_w(gspca_dev, 0x0012, reg12, 5);
352 reg_w(gspca_dev, 0x0017, reg17, 8);
353 reg_w_val(gspca_dev, 0x00c0, 0x00);
354 reg_w_val(gspca_dev, 0x00c1, 0x04);
355 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300357 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300358 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300359 reg_w(gspca_dev, 0x00ca, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300360 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300361 reg_w(gspca_dev, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300362 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300363 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300364 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300365 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300366 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300367 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300368 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300369 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300370
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300371 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300372}
373
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300374static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300375 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
376 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
377 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
378 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
379 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
380 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
381 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
382 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
383 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
384 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
385 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
386 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
387 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
388 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
389 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
390 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
391 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
392 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
393 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
394 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
395 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
396 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
397 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
398 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
399 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
400 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
401 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
402 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
403 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
404 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
405 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
406 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
407 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
408 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
409 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
410 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
411 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
412 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
413 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
414 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
415 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
416 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
417 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
418 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
419 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
420 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
421 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
422 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
423 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
424 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
425 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
426 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
427 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
428 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
429 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
430 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
431 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
432 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
433 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
434 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
435 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
436 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
437 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
438 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
439 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
440 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
441 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
442 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
443 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
444 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
445 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
446 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
447 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
448 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
449 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
450 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
451 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
452 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
453 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
454};
455
456
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300457static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300458 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
459 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
460 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
461 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
462 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
463 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
464 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
465 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
466 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
467 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
468 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
469 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
470 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
471 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
472 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
473 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
474 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
475 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
476 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
477 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
478 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
479 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
480 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
481 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
482 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
483 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
484 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
485};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300486static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300487 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
488 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
489 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
490 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
491 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
492 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
493 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
494 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
495 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
496 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
497 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
498 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
499 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
500 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
501 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
502 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
503 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
504 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
505 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
506 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
507 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
508 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
509 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
510 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
511 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
512 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
513 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
514};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300515static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300516 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
517 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
518 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
519 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
520 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
521 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
522 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
523 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
524 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
525 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
526 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
527 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
528 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
529 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
530 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
531 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
532 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
533 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
534 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
535 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
536 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
537 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
538 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
539 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
540 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
541 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
542 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
543};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300544static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300545 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
546 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
547 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
548 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
549 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
550 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
551 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
552 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
553 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
554 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
555 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
556 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
557 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
558 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
559 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
560 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
561 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
562 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
563 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
564 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
565 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
566 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
567 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
568 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
569 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
570 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
571 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
572};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300573/* 640 take with the zcx30x part */
574static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300575 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
576 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
577 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
578 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
579 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
580 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
581 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
582 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
583 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
584 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
585 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
586 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
587 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
588 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
589 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
590 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
591 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
592 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
593};
594
595
596static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
597{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300598 int i;
599 int length;
600
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300601 reg_w_val(gspca_dev, 0x00c0, 0x01);
602 reg_w_val(gspca_dev, 0x00c3, 0x00);
603 reg_w_val(gspca_dev, 0x00c0, 0x00);
604 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300605 length = 8;
606 for (i = 0; i < 79; i++) {
607 if (i == 78)
608 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300609 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300610 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300611 reg_r(gspca_dev, 0x0002, 1);
612 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300613}
614
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300615static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
616static const __u8 regE5_8[] =
617 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
618static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
619static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
620static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
621static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300622#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300623
624static void cx11646_jpeg(struct gspca_dev*gspca_dev)
625{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300626 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300627 int length;
628 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300629 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300630
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300631 reg_w_val(gspca_dev, 0x00c0, 0x01);
632 reg_w_val(gspca_dev, 0x00c3, 0x00);
633 reg_w_val(gspca_dev, 0x00c0, 0x00);
634 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300635 length = 8;
Jean-François Moine780e3122010-10-19 04:29:10 -0300636 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300637 case 0:
638 for (i = 0; i < 27; i++) {
639 if (i == 26)
640 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300641 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300642 }
643 Reg55 = 0x28;
644 break;
645 case 1:
646 for (i = 0; i < 27; i++) {
647 if (i == 26)
648 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300649 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300650 }
651 Reg55 = 0x16;
652 break;
653 default:
654/* case 2: */
655 for (i = 0; i < 27; i++) {
656 if (i == 26)
657 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300658 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300659 }
660 Reg55 = 0x14;
661 break;
662 case 3:
663 for (i = 0; i < 27; i++) {
664 if (i == 26)
665 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300666 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300667 }
668 Reg55 = 0x0B;
669 break;
670 }
671
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300672 reg_r(gspca_dev, 0x0002, 1);
673 reg_w_val(gspca_dev, 0x0055, Reg55);
674 reg_r(gspca_dev, 0x0002, 1);
675 reg_w(gspca_dev, 0x0010, reg10, 2);
676 reg_w_val(gspca_dev, 0x0054, 0x02);
677 reg_w_val(gspca_dev, 0x0054, 0x01);
678 reg_w_val(gspca_dev, 0x0000, 0x94);
679 reg_w_val(gspca_dev, 0x0053, 0xc0);
680 reg_w_val(gspca_dev, 0x00fc, 0xe1);
681 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300683 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300684 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300685 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300687 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300688 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300689 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300690 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300691 if (retry == 0)
692 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
693 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300694 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300695 length = 8;
696 for (i = 0; i < 18; i++) {
697 if (i == 17)
698 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300699 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300700
701 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300702 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
703 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
704 reg_w_val(gspca_dev, 0x0054, 0x02);
705 reg_w_val(gspca_dev, 0x0054, 0x01);
706 reg_w_val(gspca_dev, 0x0000, 0x94);
707 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300708
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300709 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
710 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
711 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
712 reg_w(gspca_dev, 0x0012, reg12, 5);
713 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
714 reg_r(gspca_dev, 0x00e8, 8);
715 reg_w(gspca_dev, 0x00e5, regE5a, 4);
716 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
717 reg_w_val(gspca_dev, 0x009a, 0x01);
718 reg_w(gspca_dev, 0x00e5, regE5b, 4);
719 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
720 reg_w(gspca_dev, 0x00e5, regE5c, 4);
721 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300722
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300723 reg_w(gspca_dev, 0x0051, reg51, 2);
724 reg_w(gspca_dev, 0x0010, reg10, 2);
725 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300726}
727
728static void cx11646_init1(struct gspca_dev *gspca_dev)
729{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300730 int i = 0;
731
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300732 reg_w_val(gspca_dev, 0x0010, 0x00);
733 reg_w_val(gspca_dev, 0x0053, 0x00);
734 reg_w_val(gspca_dev, 0x0052, 0x00);
735 reg_w_val(gspca_dev, 0x009b, 0x2f);
736 reg_w_val(gspca_dev, 0x009c, 0x10);
737 reg_r(gspca_dev, 0x0098, 1);
738 reg_w_val(gspca_dev, 0x0098, 0x40);
739 reg_r(gspca_dev, 0x0099, 1);
740 reg_w_val(gspca_dev, 0x0099, 0x07);
741 reg_w_val(gspca_dev, 0x0039, 0x40);
742 reg_w_val(gspca_dev, 0x003c, 0xff);
743 reg_w_val(gspca_dev, 0x003f, 0x1f);
744 reg_w_val(gspca_dev, 0x003d, 0x40);
745/* reg_w_val(gspca_dev, 0x003d, 0x60); */
746 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300747
748 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300749 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
750 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300752 reg_w_val(gspca_dev, 0x00ed, 0x01);
753 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300754 }
755 i++;
756 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300757 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300758}
759
760/* this function is called at probe time */
761static int sd_config(struct gspca_dev *gspca_dev,
762 const struct usb_device_id *id)
763{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300764 struct cam *cam;
765
766 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300767 cam->cam_mode = vga_mode;
Mauro Carvalho Chehabd6f76b92009-07-22 00:02:29 -0300768 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300769 return 0;
770}
771
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300772/* this function is called at probe and resume time */
773static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300774{
775 cx11646_init1(gspca_dev);
776 cx11646_initsize(gspca_dev);
777 cx11646_fw(gspca_dev);
778 cx_sensor(gspca_dev);
779 cx11646_jpegInit(gspca_dev);
780 return 0;
781}
782
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300783static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300784{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300785 struct sd *sd = (struct sd *) gspca_dev;
786
787 /* create the JPEG header */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300788 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
789 0x22); /* JPEG 411 */
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300790 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300791
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300792 cx11646_initsize(gspca_dev);
793 cx11646_fw(gspca_dev);
794 cx_sensor(gspca_dev);
795 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300796 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300797}
798
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300799/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300800static void sd_stop0(struct gspca_dev *gspca_dev)
801{
802 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300803
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300804 if (!gspca_dev->present)
805 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300806 reg_w_val(gspca_dev, 0x0000, 0x00);
807 reg_r(gspca_dev, 0x0002, 1);
808 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300809
810 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300811/* reg_r(gspca_dev, 0x0002, 1);*/
812 reg_r(gspca_dev, 0x0053, 1);
813 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814 break;
815 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300816 reg_w_val(gspca_dev, 0x0000, 0x00);
817 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300818
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300819 reg_w_val(gspca_dev, 0x0010, 0x00);
820 reg_r(gspca_dev, 0x0033, 1);
821 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822}
823
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300824static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300825 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826 int len) /* iso packet length */
827{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300828 struct sd *sd = (struct sd *) gspca_dev;
829
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300830 if (data[0] == 0xff && data[1] == 0xd8) {
831
832 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300833 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300834
835 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300836 gspca_frame_add(gspca_dev, FIRST_PACKET,
837 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300838 data += 2;
839 len -= 2;
840 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300841 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300842}
843
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300844static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300845{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300846 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300847 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300848
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300849 regE5cbx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300850 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
851 reg_r(gspca_dev, 0x00e8, 8);
852 reg_w(gspca_dev, 0x00e5, regE5c, 4);
853 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300854
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300855 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300856 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300857 reg_w(gspca_dev, 0x0051, reg51c, 2);
858 reg_w(gspca_dev, 0x0010, reg10, 2);
859 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300860}
861
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300862static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300864 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300865/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
866 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300867
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300868 regE5acx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300869 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
870 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300871 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300872 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300873 reg_w(gspca_dev, 0x0051, reg51c, 2);
874 reg_w(gspca_dev, 0x0010, reg10, 2);
875 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300876}
877
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300878static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300879{
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300880 struct gspca_dev *gspca_dev =
881 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
882 struct sd *sd = (struct sd *)gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300884 gspca_dev->usb_err = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300885
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300886 if (!gspca_dev->streaming)
887 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300889 switch (ctrl->id) {
890 case V4L2_CID_BRIGHTNESS:
891 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
892 break;
893 case V4L2_CID_CONTRAST:
894 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
895 break;
896 case V4L2_CID_SATURATION:
897 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
898 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
899 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300900 }
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300901 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300902}
903
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300904static const struct v4l2_ctrl_ops sd_ctrl_ops = {
905 .s_ctrl = sd_s_ctrl,
906};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300907
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300908static int sd_init_controls(struct gspca_dev *gspca_dev)
909{
910 struct sd *sd = (struct sd *)gspca_dev;
911 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
912
913 gspca_dev->vdev.ctrl_handler = hdl;
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300914 v4l2_ctrl_handler_init(hdl, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300915 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
916 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
917 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
918 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
919 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
920 V4L2_CID_SATURATION, 0, 7, 1, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300921 if (hdl->error) {
922 pr_err("Could not initialize controls\n");
923 return hdl->error;
924 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300925 return 0;
926}
927
928/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -0300929static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300931 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300932 .init = sd_init,
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300933 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300934 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300935 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936 .pkt_scan = sd_pkt_scan,
937};
938
939/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300940static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300941 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300942 {}
943};
944MODULE_DEVICE_TABLE(usb, device_table);
945
946/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300947static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300948 const struct usb_device_id *id)
949{
950 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
951 THIS_MODULE);
952}
953
954static struct usb_driver sd_driver = {
955 .name = MODULE_NAME,
956 .id_table = device_table,
957 .probe = sd_probe,
958 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300959#ifdef CONFIG_PM
960 .suspend = gspca_suspend,
961 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -0300962 .reset_resume = gspca_resume,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300963#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300964};
965
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -0800966module_usb_driver(sd_driver);