blob: 6df4e204e2913573f5c7d96699a7cca6c9707741 [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.
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030016 */
17
Joe Perches133a9fe2011-08-21 19:56:57 -030018#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030020#define MODULE_NAME "conex"
21
22#include "gspca.h"
23#define CONEX_CAM 1 /* special JPEG header */
24#include "jpeg.h"
25
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030026MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
27MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
28MODULE_LICENSE("GPL");
29
Hans de Goedeb56ab4c2012-06-27 16:48:33 -030030#define QUALITY 50
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030031
Hans Verkuilcbc1c942012-05-14 04:09:17 -030032/* specific webcam descriptor */
33struct sd {
34 struct gspca_dev gspca_dev; /* !! must be the first item */
35 struct v4l2_ctrl *brightness;
36 struct v4l2_ctrl *contrast;
37 struct v4l2_ctrl *sat;
Hans Verkuilcbc1c942012-05-14 04:09:17 -030038
Jean-François Moine9a731a32010-06-04 05:26:42 -030039 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030040};
41
Jean-Francois Moinecc611b82008-12-29 07:49:41 -030042static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030043 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
44 .bytesperline = 176,
45 .sizeimage = 176 * 144 * 3 / 8 + 590,
46 .colorspace = V4L2_COLORSPACE_JPEG,
47 .priv = 3},
48 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
49 .bytesperline = 320,
50 .sizeimage = 320 * 240 * 3 / 8 + 590,
51 .colorspace = V4L2_COLORSPACE_JPEG,
52 .priv = 2},
53 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
54 .bytesperline = 352,
55 .sizeimage = 352 * 288 * 3 / 8 + 590,
56 .colorspace = V4L2_COLORSPACE_JPEG,
57 .priv = 1},
58 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
59 .bytesperline = 640,
60 .sizeimage = 640 * 480 * 3 / 8 + 590,
61 .colorspace = V4L2_COLORSPACE_JPEG,
62 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030063};
64
Jean-Francois Moine739570b2008-07-14 09:38:29 -030065/* the read bytes are found in gspca_dev->usb_buf */
66static void reg_r(struct gspca_dev *gspca_dev,
67 __u16 index,
68 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030069{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030070 struct usb_device *dev = gspca_dev->dev;
71
Jean-Francois Moine8295d992008-09-03 17:12:19 -030072 if (len > USB_BUF_SZ) {
Joe Perches52173c5f2017-09-22 14:33:35 -040073 gspca_err(gspca_dev, "reg_r: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -030074 return;
75 }
Theodore Kilgorec93396e2013-02-04 13:17:55 -030076
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030077 usb_control_msg(dev,
78 usb_rcvctrlpipe(dev, 0),
79 0,
80 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
81 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -030082 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030083 500);
Joe Perches37d5efb2017-09-22 15:20:33 -040084 gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
85 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030086}
87
Jean-Francois Moine739570b2008-07-14 09:38:29 -030088/* the bytes to write are in gspca_dev->usb_buf */
89static void reg_w_val(struct gspca_dev *gspca_dev,
90 __u16 index,
91 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030092{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030093 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -030094
Jean-Francois Moine739570b2008-07-14 09:38:29 -030095 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030096 usb_control_msg(dev,
97 usb_sndctrlpipe(dev, 0),
98 0,
99 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
100 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300101 index, gspca_dev->usb_buf, 1, 500);
102}
103
104static void reg_w(struct gspca_dev *gspca_dev,
105 __u16 index,
106 const __u8 *buffer,
107 __u16 len)
108{
109 struct usb_device *dev = gspca_dev->dev;
110
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300111 if (len > USB_BUF_SZ) {
Joe Perches52173c5f2017-09-22 14:33:35 -0400112 gspca_err(gspca_dev, "reg_w: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300113 return;
114 }
Joe Perches37d5efb2017-09-22 15:20:33 -0400115 gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
116 index, *buffer);
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300117
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300118 memcpy(gspca_dev->usb_buf, buffer, len);
119 usb_control_msg(dev,
120 usb_sndctrlpipe(dev, 0),
121 0,
122 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
123 0,
124 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300125}
126
127static const __u8 cx_sensor_init[][4] = {
128 {0x88, 0x11, 0x01, 0x01},
129 {0x88, 0x12, 0x70, 0x01},
130 {0x88, 0x0f, 0x00, 0x01},
131 {0x88, 0x05, 0x01, 0x01},
132 {}
133};
134
135static const __u8 cx11646_fw1[][3] = {
136 {0x00, 0x02, 0x00},
137 {0x01, 0x43, 0x00},
138 {0x02, 0xA7, 0x00},
139 {0x03, 0x8B, 0x01},
140 {0x04, 0xE9, 0x02},
141 {0x05, 0x08, 0x04},
142 {0x06, 0x08, 0x05},
143 {0x07, 0x07, 0x06},
144 {0x08, 0xE7, 0x06},
145 {0x09, 0xC6, 0x07},
146 {0x0A, 0x86, 0x08},
147 {0x0B, 0x46, 0x09},
148 {0x0C, 0x05, 0x0A},
149 {0x0D, 0xA5, 0x0A},
150 {0x0E, 0x45, 0x0B},
151 {0x0F, 0xE5, 0x0B},
152 {0x10, 0x85, 0x0C},
153 {0x11, 0x25, 0x0D},
154 {0x12, 0xC4, 0x0D},
155 {0x13, 0x45, 0x0E},
156 {0x14, 0xE4, 0x0E},
157 {0x15, 0x64, 0x0F},
158 {0x16, 0xE4, 0x0F},
159 {0x17, 0x64, 0x10},
160 {0x18, 0xE4, 0x10},
161 {0x19, 0x64, 0x11},
162 {0x1A, 0xE4, 0x11},
163 {0x1B, 0x64, 0x12},
164 {0x1C, 0xE3, 0x12},
165 {0x1D, 0x44, 0x13},
166 {0x1E, 0xC3, 0x13},
167 {0x1F, 0x24, 0x14},
168 {0x20, 0xA3, 0x14},
169 {0x21, 0x04, 0x15},
170 {0x22, 0x83, 0x15},
171 {0x23, 0xE3, 0x15},
172 {0x24, 0x43, 0x16},
173 {0x25, 0xA4, 0x16},
174 {0x26, 0x23, 0x17},
175 {0x27, 0x83, 0x17},
176 {0x28, 0xE3, 0x17},
177 {0x29, 0x43, 0x18},
178 {0x2A, 0xA3, 0x18},
179 {0x2B, 0x03, 0x19},
180 {0x2C, 0x63, 0x19},
181 {0x2D, 0xC3, 0x19},
182 {0x2E, 0x22, 0x1A},
183 {0x2F, 0x63, 0x1A},
184 {0x30, 0xC3, 0x1A},
185 {0x31, 0x23, 0x1B},
186 {0x32, 0x83, 0x1B},
187 {0x33, 0xE2, 0x1B},
188 {0x34, 0x23, 0x1C},
189 {0x35, 0x83, 0x1C},
190 {0x36, 0xE2, 0x1C},
191 {0x37, 0x23, 0x1D},
192 {0x38, 0x83, 0x1D},
193 {0x39, 0xE2, 0x1D},
194 {0x3A, 0x23, 0x1E},
195 {0x3B, 0x82, 0x1E},
196 {0x3C, 0xC3, 0x1E},
197 {0x3D, 0x22, 0x1F},
198 {0x3E, 0x63, 0x1F},
199 {0x3F, 0xC1, 0x1F},
200 {}
201};
202static void cx11646_fw(struct gspca_dev*gspca_dev)
203{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300204 int i = 0;
205
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300206 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300207 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300208 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300209 i++;
210 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300211 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300212}
213
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300214static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300215 0x88, 0x12, 0x70, 0x01,
216 0x88, 0x0d, 0x02, 0x01,
217 0x88, 0x0f, 0x00, 0x01,
218 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
219 0x88, 0x02, 0x10, 0x01,
220 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
221 0x88, 0x0B, 0x00, 0x01,
222 0x88, 0x0A, 0x0A, 0x01,
223 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
224 0x88, 0x05, 0x01, 0x01,
225 0xA1, 0x18, 0x00, 0x01,
226 0x00
227};
228
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300229static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
230static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
231static const __u8 reg10[] = { 0xb1, 0xb1 };
232static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
233static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300234 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300235static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300236 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300237static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
238static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300239
240static void cx_sensor(struct gspca_dev*gspca_dev)
241{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300242 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300243 int length;
244 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300245
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300246 reg_w(gspca_dev, 0x0020, reg20, 8);
247 reg_w(gspca_dev, 0x0028, reg28, 8);
Dan Carpenterb1890002012-05-02 02:15:25 -0300248 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300249 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300250
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300251 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300252 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300253 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300254 break;
255 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300256 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300257 break;
258 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300259/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300260 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300261 break;
262 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300263 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300264 break;
265 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300266 reg_w(gspca_dev, 0x007b, reg7b, 6);
267 reg_w_val(gspca_dev, 0x00f8, 0x00);
Dan Carpenterb1890002012-05-02 02:15:25 -0300268 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300269 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300270 for (i = 0; i < 11; i++) {
271 if (i == 3 || i == 5 || i == 8)
272 length = 8;
273 else
274 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300275 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300276 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300277 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300278 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300279 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300280 ptsensor += length;
281 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300282 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300283}
284
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300285static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300286 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
287 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
288 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
289 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
290 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
291 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
292 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
293};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300294static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300295 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
296 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
297 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
298 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
299 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
300 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
301 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
302};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300303static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300304 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
305 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
306 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
307 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
308 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
309 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
310 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
311};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300312static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300313 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
314 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
315 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
316 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
317 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
318 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
319 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
320};
321
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300322static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300323{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300324 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300325 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
326 static const __u8 reg17[] =
327 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
328
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300329 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300330 case 0:
331 cxinit = cx_inits_640;
332 break;
333 case 1:
334 cxinit = cx_inits_352;
335 break;
336 default:
337/* case 2: */
338 cxinit = cx_inits_320;
339 break;
340 case 3:
341 cxinit = cx_inits_176;
342 break;
343 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300344 reg_w_val(gspca_dev, 0x009a, 0x01);
345 reg_w_val(gspca_dev, 0x0010, 0x10);
346 reg_w(gspca_dev, 0x0012, reg12, 5);
347 reg_w(gspca_dev, 0x0017, reg17, 8);
348 reg_w_val(gspca_dev, 0x00c0, 0x00);
349 reg_w_val(gspca_dev, 0x00c1, 0x04);
350 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300351
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300352 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300353 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300354 reg_w(gspca_dev, 0x00ca, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300355 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300356 reg_w(gspca_dev, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300357 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300358 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300359 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300360 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300361 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300362 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300363 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300364 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300365
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300366 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300367}
368
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300369static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300370 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
371 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
372 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
373 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
374 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
375 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
376 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
377 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
378 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
379 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
380 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
381 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
382 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
383 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
384 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
385 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
386 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
387 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
388 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
389 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
390 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
391 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
392 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
393 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
394 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
395 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
396 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
397 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
398 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
399 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
400 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
401 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
402 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
403 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
404 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
405 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
406 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
407 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
408 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
409 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
410 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
411 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
412 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
413 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
414 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
415 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
416 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
417 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
418 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
419 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
420 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
421 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
422 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
423 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
424 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
425 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
426 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
427 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
428 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
429 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
430 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
431 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
432 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
433 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
434 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
435 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
436 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
437 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
438 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
439 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
440 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
441 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
442 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
443 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
444 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
445 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
446 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
447 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
448 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
449};
450
451
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300452static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300453 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
454 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
455 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
456 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
457 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
458 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
459 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
460 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
461 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
462 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
463 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
464 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
465 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
466 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
467 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
468 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
469 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
470 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
471 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
472 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
473 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
474 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
475 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
476 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
477 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
478 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
479 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
480};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300481static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300482 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
483 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
484 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
485 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
486 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
487 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
488 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
489 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
490 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
491 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
492 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
493 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
494 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
495 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
496 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
497 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
498 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
499 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
500 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
501 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
502 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
503 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
504 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
505 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
506 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
507 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
508 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
509};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300510static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300511 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
512 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
513 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
514 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
515 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
516 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
517 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
518 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
519 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
520 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
521 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
522 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
523 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
524 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
525 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
526 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
527 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
528 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
529 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
530 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
531 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
532 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
533 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
534 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
535 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
536 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
537 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
538};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300539static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300540 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
541 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
542 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
543 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
544 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
545 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
546 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
547 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
548 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
549 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
550 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
551 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
552 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
553 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
554 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
555 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
556 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
557 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
558 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
559 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
560 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
561 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
562 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
563 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
564 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
565 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
566 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
567};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300568/* 640 take with the zcx30x part */
569static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300570 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
571 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
572 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
573 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
574 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
575 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
576 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
577 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
578 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
579 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
580 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
581 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
582 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
583 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 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 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
588};
589
590
591static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
592{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300593 int i;
594 int length;
595
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300596 reg_w_val(gspca_dev, 0x00c0, 0x01);
597 reg_w_val(gspca_dev, 0x00c3, 0x00);
598 reg_w_val(gspca_dev, 0x00c0, 0x00);
599 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300600 length = 8;
601 for (i = 0; i < 79; i++) {
602 if (i == 78)
603 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300604 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300605 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300606 reg_r(gspca_dev, 0x0002, 1);
607 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300608}
609
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300610static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
611static const __u8 regE5_8[] =
612 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
613static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
614static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
615static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
616static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300617#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300618
619static void cx11646_jpeg(struct gspca_dev*gspca_dev)
620{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300621 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300622 int length;
623 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300624 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300625
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300626 reg_w_val(gspca_dev, 0x00c0, 0x01);
627 reg_w_val(gspca_dev, 0x00c3, 0x00);
628 reg_w_val(gspca_dev, 0x00c0, 0x00);
629 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300630 length = 8;
Jean-François Moine780e3122010-10-19 04:29:10 -0300631 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300632 case 0:
633 for (i = 0; i < 27; i++) {
634 if (i == 26)
635 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300636 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300637 }
638 Reg55 = 0x28;
639 break;
640 case 1:
641 for (i = 0; i < 27; i++) {
642 if (i == 26)
643 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300644 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300645 }
646 Reg55 = 0x16;
647 break;
648 default:
649/* case 2: */
650 for (i = 0; i < 27; i++) {
651 if (i == 26)
652 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300653 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654 }
655 Reg55 = 0x14;
656 break;
657 case 3:
658 for (i = 0; i < 27; i++) {
659 if (i == 26)
660 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300661 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300662 }
663 Reg55 = 0x0B;
664 break;
665 }
666
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300667 reg_r(gspca_dev, 0x0002, 1);
668 reg_w_val(gspca_dev, 0x0055, Reg55);
669 reg_r(gspca_dev, 0x0002, 1);
670 reg_w(gspca_dev, 0x0010, reg10, 2);
671 reg_w_val(gspca_dev, 0x0054, 0x02);
672 reg_w_val(gspca_dev, 0x0054, 0x01);
673 reg_w_val(gspca_dev, 0x0000, 0x94);
674 reg_w_val(gspca_dev, 0x0053, 0xc0);
675 reg_w_val(gspca_dev, 0x00fc, 0xe1);
676 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300677 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300678 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300679 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300680 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300681 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300682 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300683 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300684 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300685 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686 if (retry == 0)
Joe Perches52173c5f2017-09-22 14:33:35 -0400687 gspca_err(gspca_dev, "Damned Errors sending jpeg Table\n");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300688 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300689 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300690 length = 8;
691 for (i = 0; i < 18; i++) {
692 if (i == 17)
693 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300694 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300695
696 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300697 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
698 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
699 reg_w_val(gspca_dev, 0x0054, 0x02);
700 reg_w_val(gspca_dev, 0x0054, 0x01);
701 reg_w_val(gspca_dev, 0x0000, 0x94);
702 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300703
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300704 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
705 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
706 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
707 reg_w(gspca_dev, 0x0012, reg12, 5);
708 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
709 reg_r(gspca_dev, 0x00e8, 8);
710 reg_w(gspca_dev, 0x00e5, regE5a, 4);
711 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
712 reg_w_val(gspca_dev, 0x009a, 0x01);
713 reg_w(gspca_dev, 0x00e5, regE5b, 4);
714 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
715 reg_w(gspca_dev, 0x00e5, regE5c, 4);
716 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300717
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300718 reg_w(gspca_dev, 0x0051, reg51, 2);
719 reg_w(gspca_dev, 0x0010, reg10, 2);
720 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300721}
722
723static void cx11646_init1(struct gspca_dev *gspca_dev)
724{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300725 int i = 0;
726
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300727 reg_w_val(gspca_dev, 0x0010, 0x00);
728 reg_w_val(gspca_dev, 0x0053, 0x00);
729 reg_w_val(gspca_dev, 0x0052, 0x00);
730 reg_w_val(gspca_dev, 0x009b, 0x2f);
731 reg_w_val(gspca_dev, 0x009c, 0x10);
732 reg_r(gspca_dev, 0x0098, 1);
733 reg_w_val(gspca_dev, 0x0098, 0x40);
734 reg_r(gspca_dev, 0x0099, 1);
735 reg_w_val(gspca_dev, 0x0099, 0x07);
736 reg_w_val(gspca_dev, 0x0039, 0x40);
737 reg_w_val(gspca_dev, 0x003c, 0xff);
738 reg_w_val(gspca_dev, 0x003f, 0x1f);
739 reg_w_val(gspca_dev, 0x003d, 0x40);
740/* reg_w_val(gspca_dev, 0x003d, 0x60); */
741 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742
743 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300744 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
745 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300746 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300747 reg_w_val(gspca_dev, 0x00ed, 0x01);
748 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300749 }
750 i++;
751 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300752 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753}
754
755/* this function is called at probe time */
756static int sd_config(struct gspca_dev *gspca_dev,
757 const struct usb_device_id *id)
758{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300759 struct cam *cam;
760
761 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300762 cam->cam_mode = vga_mode;
Mauro Carvalho Chehabd6f76b92009-07-22 00:02:29 -0300763 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300764 return 0;
765}
766
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300767/* this function is called at probe and resume time */
768static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300769{
770 cx11646_init1(gspca_dev);
771 cx11646_initsize(gspca_dev);
772 cx11646_fw(gspca_dev);
773 cx_sensor(gspca_dev);
774 cx11646_jpegInit(gspca_dev);
775 return 0;
776}
777
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300778static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300779{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300780 struct sd *sd = (struct sd *) gspca_dev;
781
782 /* create the JPEG header */
Ondrej Zary1966bc22013-08-30 17:54:23 -0300783 jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
784 gspca_dev->pixfmt.width,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300785 0x22); /* JPEG 411 */
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300786 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300787
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300788 cx11646_initsize(gspca_dev);
789 cx11646_fw(gspca_dev);
790 cx_sensor(gspca_dev);
791 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300792 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300793}
794
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300795/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300796static void sd_stop0(struct gspca_dev *gspca_dev)
797{
798 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300799
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300800 if (!gspca_dev->present)
801 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300802 reg_w_val(gspca_dev, 0x0000, 0x00);
803 reg_r(gspca_dev, 0x0002, 1);
804 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805
806 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300807/* reg_r(gspca_dev, 0x0002, 1);*/
808 reg_r(gspca_dev, 0x0053, 1);
809 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300810 break;
811 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300812 reg_w_val(gspca_dev, 0x0000, 0x00);
813 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300815 reg_w_val(gspca_dev, 0x0010, 0x00);
816 reg_r(gspca_dev, 0x0033, 1);
817 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300818}
819
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300820static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300821 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822 int len) /* iso packet length */
823{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300824 struct sd *sd = (struct sd *) gspca_dev;
825
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826 if (data[0] == 0xff && data[1] == 0xd8) {
827
828 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300829 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300830
831 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300832 gspca_frame_add(gspca_dev, FIRST_PACKET,
833 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300834 data += 2;
835 len -= 2;
836 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300837 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300838}
839
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300840static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300842 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300843 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300844
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300845 regE5cbx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300846 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
847 reg_r(gspca_dev, 0x00e8, 8);
848 reg_w(gspca_dev, 0x00e5, regE5c, 4);
849 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300850
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300851 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300852 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300853 reg_w(gspca_dev, 0x0051, reg51c, 2);
854 reg_w(gspca_dev, 0x0010, reg10, 2);
855 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300856}
857
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300858static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300860 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300861/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
862 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300864 regE5acx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300865 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
866 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300867 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300868 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300869 reg_w(gspca_dev, 0x0051, reg51c, 2);
870 reg_w(gspca_dev, 0x0010, reg10, 2);
871 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300872}
873
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300874static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300875{
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300876 struct gspca_dev *gspca_dev =
877 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
878 struct sd *sd = (struct sd *)gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300879
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300880 gspca_dev->usb_err = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300881
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300882 if (!gspca_dev->streaming)
883 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300884
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300885 switch (ctrl->id) {
886 case V4L2_CID_BRIGHTNESS:
887 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
888 break;
889 case V4L2_CID_CONTRAST:
890 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
891 break;
892 case V4L2_CID_SATURATION:
893 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
894 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
895 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300896 }
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300897 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300898}
899
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300900static const struct v4l2_ctrl_ops sd_ctrl_ops = {
901 .s_ctrl = sd_s_ctrl,
902};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300903
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300904static int sd_init_controls(struct gspca_dev *gspca_dev)
905{
906 struct sd *sd = (struct sd *)gspca_dev;
907 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
908
909 gspca_dev->vdev.ctrl_handler = hdl;
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300910 v4l2_ctrl_handler_init(hdl, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300911 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
912 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
913 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
914 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
915 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
916 V4L2_CID_SATURATION, 0, 7, 1, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300917 if (hdl->error) {
918 pr_err("Could not initialize controls\n");
919 return hdl->error;
920 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921 return 0;
922}
923
924/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -0300925static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300926 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300927 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300928 .init = sd_init,
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300929 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300931 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300932 .pkt_scan = sd_pkt_scan,
933};
934
935/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300936static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300937 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300938 {}
939};
940MODULE_DEVICE_TABLE(usb, device_table);
941
942/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300943static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300944 const struct usb_device_id *id)
945{
946 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
947 THIS_MODULE);
948}
949
950static struct usb_driver sd_driver = {
951 .name = MODULE_NAME,
952 .id_table = device_table,
953 .probe = sd_probe,
954 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300955#ifdef CONFIG_PM
956 .suspend = gspca_suspend,
957 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -0300958 .reset_resume = gspca_resume,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300959#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300960};
961
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -0800962module_usb_driver(sd_driver);