blob: 38714df31ac49878d13d64a9e626f26f1813041b [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 Moine8295d992008-09-03 17:12:19 -030076 if (len > USB_BUF_SZ) {
Theodore Kilgorec93396e2013-02-04 13:17:55 -030077 PERR("reg_r: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -030078 return;
79 }
Theodore Kilgorec93396e2013-02-04 13:17:55 -030080
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030081 usb_control_msg(dev,
82 usb_rcvctrlpipe(dev, 0),
83 0,
84 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
85 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -030086 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030087 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -030088 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
89 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030090}
91
Jean-Francois Moine739570b2008-07-14 09:38:29 -030092/* the bytes to write are in gspca_dev->usb_buf */
93static void reg_w_val(struct gspca_dev *gspca_dev,
94 __u16 index,
95 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030096{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030097 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -030098
Jean-Francois Moine739570b2008-07-14 09:38:29 -030099 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300100 usb_control_msg(dev,
101 usb_sndctrlpipe(dev, 0),
102 0,
103 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
104 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300105 index, gspca_dev->usb_buf, 1, 500);
106}
107
108static void reg_w(struct gspca_dev *gspca_dev,
109 __u16 index,
110 const __u8 *buffer,
111 __u16 len)
112{
113 struct usb_device *dev = gspca_dev->dev;
114
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300115 if (len > USB_BUF_SZ) {
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300116 PERR("reg_w: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300117 return;
118 }
119 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300120
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300121 memcpy(gspca_dev->usb_buf, buffer, len);
122 usb_control_msg(dev,
123 usb_sndctrlpipe(dev, 0),
124 0,
125 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
126 0,
127 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300128}
129
130static const __u8 cx_sensor_init[][4] = {
131 {0x88, 0x11, 0x01, 0x01},
132 {0x88, 0x12, 0x70, 0x01},
133 {0x88, 0x0f, 0x00, 0x01},
134 {0x88, 0x05, 0x01, 0x01},
135 {}
136};
137
138static const __u8 cx11646_fw1[][3] = {
139 {0x00, 0x02, 0x00},
140 {0x01, 0x43, 0x00},
141 {0x02, 0xA7, 0x00},
142 {0x03, 0x8B, 0x01},
143 {0x04, 0xE9, 0x02},
144 {0x05, 0x08, 0x04},
145 {0x06, 0x08, 0x05},
146 {0x07, 0x07, 0x06},
147 {0x08, 0xE7, 0x06},
148 {0x09, 0xC6, 0x07},
149 {0x0A, 0x86, 0x08},
150 {0x0B, 0x46, 0x09},
151 {0x0C, 0x05, 0x0A},
152 {0x0D, 0xA5, 0x0A},
153 {0x0E, 0x45, 0x0B},
154 {0x0F, 0xE5, 0x0B},
155 {0x10, 0x85, 0x0C},
156 {0x11, 0x25, 0x0D},
157 {0x12, 0xC4, 0x0D},
158 {0x13, 0x45, 0x0E},
159 {0x14, 0xE4, 0x0E},
160 {0x15, 0x64, 0x0F},
161 {0x16, 0xE4, 0x0F},
162 {0x17, 0x64, 0x10},
163 {0x18, 0xE4, 0x10},
164 {0x19, 0x64, 0x11},
165 {0x1A, 0xE4, 0x11},
166 {0x1B, 0x64, 0x12},
167 {0x1C, 0xE3, 0x12},
168 {0x1D, 0x44, 0x13},
169 {0x1E, 0xC3, 0x13},
170 {0x1F, 0x24, 0x14},
171 {0x20, 0xA3, 0x14},
172 {0x21, 0x04, 0x15},
173 {0x22, 0x83, 0x15},
174 {0x23, 0xE3, 0x15},
175 {0x24, 0x43, 0x16},
176 {0x25, 0xA4, 0x16},
177 {0x26, 0x23, 0x17},
178 {0x27, 0x83, 0x17},
179 {0x28, 0xE3, 0x17},
180 {0x29, 0x43, 0x18},
181 {0x2A, 0xA3, 0x18},
182 {0x2B, 0x03, 0x19},
183 {0x2C, 0x63, 0x19},
184 {0x2D, 0xC3, 0x19},
185 {0x2E, 0x22, 0x1A},
186 {0x2F, 0x63, 0x1A},
187 {0x30, 0xC3, 0x1A},
188 {0x31, 0x23, 0x1B},
189 {0x32, 0x83, 0x1B},
190 {0x33, 0xE2, 0x1B},
191 {0x34, 0x23, 0x1C},
192 {0x35, 0x83, 0x1C},
193 {0x36, 0xE2, 0x1C},
194 {0x37, 0x23, 0x1D},
195 {0x38, 0x83, 0x1D},
196 {0x39, 0xE2, 0x1D},
197 {0x3A, 0x23, 0x1E},
198 {0x3B, 0x82, 0x1E},
199 {0x3C, 0xC3, 0x1E},
200 {0x3D, 0x22, 0x1F},
201 {0x3E, 0x63, 0x1F},
202 {0x3F, 0xC1, 0x1F},
203 {}
204};
205static void cx11646_fw(struct gspca_dev*gspca_dev)
206{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300207 int i = 0;
208
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300209 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300210 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300211 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300212 i++;
213 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300214 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300215}
216
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300217static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300218 0x88, 0x12, 0x70, 0x01,
219 0x88, 0x0d, 0x02, 0x01,
220 0x88, 0x0f, 0x00, 0x01,
221 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
222 0x88, 0x02, 0x10, 0x01,
223 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
224 0x88, 0x0B, 0x00, 0x01,
225 0x88, 0x0A, 0x0A, 0x01,
226 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
227 0x88, 0x05, 0x01, 0x01,
228 0xA1, 0x18, 0x00, 0x01,
229 0x00
230};
231
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300232static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
233static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
234static const __u8 reg10[] = { 0xb1, 0xb1 };
235static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
236static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300237 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300238static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300239 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300240static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
241static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300242
243static void cx_sensor(struct gspca_dev*gspca_dev)
244{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300245 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300246 int length;
247 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300248
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300249 reg_w(gspca_dev, 0x0020, reg20, 8);
250 reg_w(gspca_dev, 0x0028, reg28, 8);
Dan Carpenterb1890002012-05-02 02:15:25 -0300251 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300252 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300253
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300254 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300255 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300256 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300257 break;
258 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300259 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300260 break;
261 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300262/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300263 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300264 break;
265 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300266 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267 break;
268 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300269 reg_w(gspca_dev, 0x007b, reg7b, 6);
270 reg_w_val(gspca_dev, 0x00f8, 0x00);
Dan Carpenterb1890002012-05-02 02:15:25 -0300271 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300272 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300273 for (i = 0; i < 11; i++) {
274 if (i == 3 || i == 5 || i == 8)
275 length = 8;
276 else
277 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300278 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300279 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300280 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300281 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300282 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300283 ptsensor += length;
284 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300285 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300286}
287
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300288static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300289 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
290 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
291 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
292 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
293 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
294 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
295 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
296};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300297static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300298 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
299 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
300 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
301 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
302 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
303 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
304 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
305};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300306static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300307 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
308 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
309 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
310 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
311 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
312 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
313 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
314};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300315static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300316 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
317 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
318 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
319 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
320 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
321 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
322 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
323};
324
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300325static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300326{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300327 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300328 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
329 static const __u8 reg17[] =
330 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
331
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300332 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300333 case 0:
334 cxinit = cx_inits_640;
335 break;
336 case 1:
337 cxinit = cx_inits_352;
338 break;
339 default:
340/* case 2: */
341 cxinit = cx_inits_320;
342 break;
343 case 3:
344 cxinit = cx_inits_176;
345 break;
346 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300347 reg_w_val(gspca_dev, 0x009a, 0x01);
348 reg_w_val(gspca_dev, 0x0010, 0x10);
349 reg_w(gspca_dev, 0x0012, reg12, 5);
350 reg_w(gspca_dev, 0x0017, reg17, 8);
351 reg_w_val(gspca_dev, 0x00c0, 0x00);
352 reg_w_val(gspca_dev, 0x00c1, 0x04);
353 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300354
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300355 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300357 reg_w(gspca_dev, 0x00ca, 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, 0x00d2, 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, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300362 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300363 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300364 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300365 reg_w(gspca_dev, 0x0049, 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, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300368
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300369 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300370}
371
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300372static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300373 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
374 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
375 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
376 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
377 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
378 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
379 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
380 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
381 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
382 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
383 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
384 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
385 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
386 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
387 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
388 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
389 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
390 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
391 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
392 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
393 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
394 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
395 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
396 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
397 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
398 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
399 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
400 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
401 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
402 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
403 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
404 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
405 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
406 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
407 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
408 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
409 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
410 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
411 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
412 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
413 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
414 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
415 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
416 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
417 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
418 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
419 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
420 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
421 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
422 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
423 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
424 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
425 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
426 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
427 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
428 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
429 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
430 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
431 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
432 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
433 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
434 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
435 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
436 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
437 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
438 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
439 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
440 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
441 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
442 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
443 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
444 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
445 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
446 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
447 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
448 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
449 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
450 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
451 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
452};
453
454
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300455static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300456 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
457 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
458 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
459 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
460 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
461 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
462 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
463 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
464 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
465 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
466 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
467 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
468 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
469 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
470 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
471 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
472 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
473 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
474 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
475 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
476 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
477 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
478 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
479 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
480 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
481 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
482 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
483};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300484static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300485 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
486 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
487 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
488 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
489 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
490 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
491 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
492 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
493 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
494 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
495 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
496 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
497 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
498 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
499 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
500 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
501 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
502 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
503 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
504 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
505 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
506 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
507 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
508 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
509 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
510 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
511 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
512};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300513static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300514 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
515 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
516 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
517 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
518 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
519 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
520 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
521 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
522 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
523 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
524 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
525 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
526 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
527 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
528 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
529 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
530 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
531 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
532 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
533 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
534 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
535 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
536 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
537 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
538 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
539 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
540 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
541};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300542static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300543 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
544 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
545 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
546 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
547 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
548 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
549 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
550 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
551 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
552 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
553 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
554 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
555 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
556 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
557 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
558 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
559 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
560 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
561 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
562 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
563 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
564 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
565 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
566 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
567 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
568 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
569 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
570};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300571/* 640 take with the zcx30x part */
572static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300573 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
574 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
575 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
576 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
577 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
578 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
579 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
580 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
581 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
582 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
583 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
584 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
585 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 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 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
591};
592
593
594static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
595{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300596 int i;
597 int length;
598
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300599 reg_w_val(gspca_dev, 0x00c0, 0x01);
600 reg_w_val(gspca_dev, 0x00c3, 0x00);
601 reg_w_val(gspca_dev, 0x00c0, 0x00);
602 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300603 length = 8;
604 for (i = 0; i < 79; i++) {
605 if (i == 78)
606 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300607 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300608 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300609 reg_r(gspca_dev, 0x0002, 1);
610 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300611}
612
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300613static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
614static const __u8 regE5_8[] =
615 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
616static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
617static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
618static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
619static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300620#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300621
622static void cx11646_jpeg(struct gspca_dev*gspca_dev)
623{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300624 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300625 int length;
626 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300627 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300628
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300629 reg_w_val(gspca_dev, 0x00c0, 0x01);
630 reg_w_val(gspca_dev, 0x00c3, 0x00);
631 reg_w_val(gspca_dev, 0x00c0, 0x00);
632 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300633 length = 8;
Jean-François Moine780e3122010-10-19 04:29:10 -0300634 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300635 case 0:
636 for (i = 0; i < 27; i++) {
637 if (i == 26)
638 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300639 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300640 }
641 Reg55 = 0x28;
642 break;
643 case 1:
644 for (i = 0; i < 27; i++) {
645 if (i == 26)
646 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300647 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300648 }
649 Reg55 = 0x16;
650 break;
651 default:
652/* case 2: */
653 for (i = 0; i < 27; i++) {
654 if (i == 26)
655 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300656 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300657 }
658 Reg55 = 0x14;
659 break;
660 case 3:
661 for (i = 0; i < 27; i++) {
662 if (i == 26)
663 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300664 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300665 }
666 Reg55 = 0x0B;
667 break;
668 }
669
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300670 reg_r(gspca_dev, 0x0002, 1);
671 reg_w_val(gspca_dev, 0x0055, Reg55);
672 reg_r(gspca_dev, 0x0002, 1);
673 reg_w(gspca_dev, 0x0010, reg10, 2);
674 reg_w_val(gspca_dev, 0x0054, 0x02);
675 reg_w_val(gspca_dev, 0x0054, 0x01);
676 reg_w_val(gspca_dev, 0x0000, 0x94);
677 reg_w_val(gspca_dev, 0x0053, 0xc0);
678 reg_w_val(gspca_dev, 0x00fc, 0xe1);
679 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300680 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300681 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300682 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300683 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300684 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300685 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300687 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300688 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300689 if (retry == 0)
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300690 PERR("Damned Errors sending jpeg Table");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300691 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300692 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300693 length = 8;
694 for (i = 0; i < 18; i++) {
695 if (i == 17)
696 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300697 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300698
699 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300700 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
701 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
702 reg_w_val(gspca_dev, 0x0054, 0x02);
703 reg_w_val(gspca_dev, 0x0054, 0x01);
704 reg_w_val(gspca_dev, 0x0000, 0x94);
705 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300706
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300707 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
708 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
709 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
710 reg_w(gspca_dev, 0x0012, reg12, 5);
711 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
712 reg_r(gspca_dev, 0x00e8, 8);
713 reg_w(gspca_dev, 0x00e5, regE5a, 4);
714 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
715 reg_w_val(gspca_dev, 0x009a, 0x01);
716 reg_w(gspca_dev, 0x00e5, regE5b, 4);
717 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
718 reg_w(gspca_dev, 0x00e5, regE5c, 4);
719 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300720
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300721 reg_w(gspca_dev, 0x0051, reg51, 2);
722 reg_w(gspca_dev, 0x0010, reg10, 2);
723 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300724}
725
726static void cx11646_init1(struct gspca_dev *gspca_dev)
727{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300728 int i = 0;
729
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300730 reg_w_val(gspca_dev, 0x0010, 0x00);
731 reg_w_val(gspca_dev, 0x0053, 0x00);
732 reg_w_val(gspca_dev, 0x0052, 0x00);
733 reg_w_val(gspca_dev, 0x009b, 0x2f);
734 reg_w_val(gspca_dev, 0x009c, 0x10);
735 reg_r(gspca_dev, 0x0098, 1);
736 reg_w_val(gspca_dev, 0x0098, 0x40);
737 reg_r(gspca_dev, 0x0099, 1);
738 reg_w_val(gspca_dev, 0x0099, 0x07);
739 reg_w_val(gspca_dev, 0x0039, 0x40);
740 reg_w_val(gspca_dev, 0x003c, 0xff);
741 reg_w_val(gspca_dev, 0x003f, 0x1f);
742 reg_w_val(gspca_dev, 0x003d, 0x40);
743/* reg_w_val(gspca_dev, 0x003d, 0x60); */
744 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300745
746 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300747 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
748 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300749 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300750 reg_w_val(gspca_dev, 0x00ed, 0x01);
751 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300752 }
753 i++;
754 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300755 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300756}
757
758/* this function is called at probe time */
759static int sd_config(struct gspca_dev *gspca_dev,
760 const struct usb_device_id *id)
761{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300762 struct cam *cam;
763
764 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300765 cam->cam_mode = vga_mode;
Mauro Carvalho Chehabd6f76b92009-07-22 00:02:29 -0300766 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300767 return 0;
768}
769
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300770/* this function is called at probe and resume time */
771static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300772{
773 cx11646_init1(gspca_dev);
774 cx11646_initsize(gspca_dev);
775 cx11646_fw(gspca_dev);
776 cx_sensor(gspca_dev);
777 cx11646_jpegInit(gspca_dev);
778 return 0;
779}
780
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300781static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300782{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300783 struct sd *sd = (struct sd *) gspca_dev;
784
785 /* create the JPEG header */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300786 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
787 0x22); /* JPEG 411 */
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300788 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300789
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300790 cx11646_initsize(gspca_dev);
791 cx11646_fw(gspca_dev);
792 cx_sensor(gspca_dev);
793 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300794 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300795}
796
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300797/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300798static void sd_stop0(struct gspca_dev *gspca_dev)
799{
800 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300802 if (!gspca_dev->present)
803 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300804 reg_w_val(gspca_dev, 0x0000, 0x00);
805 reg_r(gspca_dev, 0x0002, 1);
806 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300807
808 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300809/* reg_r(gspca_dev, 0x0002, 1);*/
810 reg_r(gspca_dev, 0x0053, 1);
811 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300812 break;
813 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300814 reg_w_val(gspca_dev, 0x0000, 0x00);
815 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300816
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300817 reg_w_val(gspca_dev, 0x0010, 0x00);
818 reg_r(gspca_dev, 0x0033, 1);
819 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300820}
821
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300823 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300824 int len) /* iso packet length */
825{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300826 struct sd *sd = (struct sd *) gspca_dev;
827
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300828 if (data[0] == 0xff && data[1] == 0xd8) {
829
830 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300831 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300832
833 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300834 gspca_frame_add(gspca_dev, FIRST_PACKET,
835 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300836 data += 2;
837 len -= 2;
838 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300839 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300840}
841
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300842static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300843{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300844 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300845 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300846
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300847 regE5cbx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300848 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
849 reg_r(gspca_dev, 0x00e8, 8);
850 reg_w(gspca_dev, 0x00e5, regE5c, 4);
851 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300852
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300853 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300854 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300855 reg_w(gspca_dev, 0x0051, reg51c, 2);
856 reg_w(gspca_dev, 0x0010, reg10, 2);
857 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300858}
859
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300860static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300861{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300863/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
864 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300866 regE5acx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300867 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
868 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300869 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300870 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300871 reg_w(gspca_dev, 0x0051, reg51c, 2);
872 reg_w(gspca_dev, 0x0010, reg10, 2);
873 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300874}
875
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300876static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300877{
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300878 struct gspca_dev *gspca_dev =
879 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
880 struct sd *sd = (struct sd *)gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300881
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300882 gspca_dev->usb_err = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300883
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300884 if (!gspca_dev->streaming)
885 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300887 switch (ctrl->id) {
888 case V4L2_CID_BRIGHTNESS:
889 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
890 break;
891 case V4L2_CID_CONTRAST:
892 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
893 break;
894 case V4L2_CID_SATURATION:
895 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
896 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
897 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300898 }
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300899 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300900}
901
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300902static const struct v4l2_ctrl_ops sd_ctrl_ops = {
903 .s_ctrl = sd_s_ctrl,
904};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300905
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300906static int sd_init_controls(struct gspca_dev *gspca_dev)
907{
908 struct sd *sd = (struct sd *)gspca_dev;
909 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
910
911 gspca_dev->vdev.ctrl_handler = hdl;
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300912 v4l2_ctrl_handler_init(hdl, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300913 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
914 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
915 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
916 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
917 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
918 V4L2_CID_SATURATION, 0, 7, 1, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300919 if (hdl->error) {
920 pr_err("Could not initialize controls\n");
921 return hdl->error;
922 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300923 return 0;
924}
925
926/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -0300927static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300928 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300929 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300930 .init = sd_init,
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300931 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300933 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300934 .pkt_scan = sd_pkt_scan,
935};
936
937/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300938static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300939 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300940 {}
941};
942MODULE_DEVICE_TABLE(usb, device_table);
943
944/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300945static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300946 const struct usb_device_id *id)
947{
948 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
949 THIS_MODULE);
950}
951
952static struct usb_driver sd_driver = {
953 .name = MODULE_NAME,
954 .id_table = device_table,
955 .probe = sd_probe,
956 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300957#ifdef CONFIG_PM
958 .suspend = gspca_suspend,
959 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -0300960 .reset_resume = gspca_resume,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300961#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300962};
963
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -0800964module_usb_driver(sd_driver);