blob: 2e15c80d6e3d11b953d210b553cbc6878110427f [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 */
Ondrej Zary1966bc22013-08-30 17:54:23 -0300786 jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
787 gspca_dev->pixfmt.width,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300788 0x22); /* JPEG 411 */
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300789 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300790
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300791 cx11646_initsize(gspca_dev);
792 cx11646_fw(gspca_dev);
793 cx_sensor(gspca_dev);
794 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300795 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300796}
797
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300798/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300799static void sd_stop0(struct gspca_dev *gspca_dev)
800{
801 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300802
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300803 if (!gspca_dev->present)
804 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300805 reg_w_val(gspca_dev, 0x0000, 0x00);
806 reg_r(gspca_dev, 0x0002, 1);
807 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300808
809 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300810/* reg_r(gspca_dev, 0x0002, 1);*/
811 reg_r(gspca_dev, 0x0053, 1);
812 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300813 break;
814 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300815 reg_w_val(gspca_dev, 0x0000, 0x00);
816 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300817
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300818 reg_w_val(gspca_dev, 0x0010, 0x00);
819 reg_r(gspca_dev, 0x0033, 1);
820 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300821}
822
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300823static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300824 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300825 int len) /* iso packet length */
826{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300827 struct sd *sd = (struct sd *) gspca_dev;
828
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300829 if (data[0] == 0xff && data[1] == 0xd8) {
830
831 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300832 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300833
834 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300835 gspca_frame_add(gspca_dev, FIRST_PACKET,
836 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300837 data += 2;
838 len -= 2;
839 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300840 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841}
842
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300843static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300844{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300845 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300846 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300847
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300848 regE5cbx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300849 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
850 reg_r(gspca_dev, 0x00e8, 8);
851 reg_w(gspca_dev, 0x00e5, regE5c, 4);
852 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300853
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300854 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300855 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300856 reg_w(gspca_dev, 0x0051, reg51c, 2);
857 reg_w(gspca_dev, 0x0010, reg10, 2);
858 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859}
860
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300861static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300864/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
865 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300866
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300867 regE5acx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300868 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
869 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300870 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300871 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300872 reg_w(gspca_dev, 0x0051, reg51c, 2);
873 reg_w(gspca_dev, 0x0010, reg10, 2);
874 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300875}
876
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300877static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878{
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300879 struct gspca_dev *gspca_dev =
880 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
881 struct sd *sd = (struct sd *)gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300882
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300883 gspca_dev->usb_err = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300884
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300885 if (!gspca_dev->streaming)
886 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300887
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300888 switch (ctrl->id) {
889 case V4L2_CID_BRIGHTNESS:
890 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
891 break;
892 case V4L2_CID_CONTRAST:
893 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
894 break;
895 case V4L2_CID_SATURATION:
896 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
897 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
898 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300899 }
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300900 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300901}
902
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300903static const struct v4l2_ctrl_ops sd_ctrl_ops = {
904 .s_ctrl = sd_s_ctrl,
905};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300906
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300907static int sd_init_controls(struct gspca_dev *gspca_dev)
908{
909 struct sd *sd = (struct sd *)gspca_dev;
910 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
911
912 gspca_dev->vdev.ctrl_handler = hdl;
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300913 v4l2_ctrl_handler_init(hdl, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300914 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
915 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
916 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
917 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
918 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
919 V4L2_CID_SATURATION, 0, 7, 1, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300920 if (hdl->error) {
921 pr_err("Could not initialize controls\n");
922 return hdl->error;
923 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300924 return 0;
925}
926
927/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -0300928static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300929 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300931 .init = sd_init,
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300932 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300933 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300934 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300935 .pkt_scan = sd_pkt_scan,
936};
937
938/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300939static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300940 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300941 {}
942};
943MODULE_DEVICE_TABLE(usb, device_table);
944
945/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300946static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300947 const struct usb_device_id *id)
948{
949 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
950 THIS_MODULE);
951}
952
953static struct usb_driver sd_driver = {
954 .name = MODULE_NAME,
955 .id_table = device_table,
956 .probe = sd_probe,
957 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300958#ifdef CONFIG_PM
959 .suspend = gspca_suspend,
960 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -0300961 .reset_resume = gspca_resume,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300962#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300963};
964
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -0800965module_usb_driver(sd_driver);