blob: c66688a1d3a30ff3c669855a1e0b7f77e922c891 [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
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030034#define QUALITY_MIN 30
35#define QUALITY_MAX 60
36#define QUALITY_DEF 40
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030037
Hans Verkuilcbc1c942012-05-14 04:09:17 -030038/* specific webcam descriptor */
39struct sd {
40 struct gspca_dev gspca_dev; /* !! must be the first item */
41 struct v4l2_ctrl *brightness;
42 struct v4l2_ctrl *contrast;
43 struct v4l2_ctrl *sat;
44 struct v4l2_ctrl *jpegqual;
45
Jean-François Moine9a731a32010-06-04 05:26:42 -030046 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030047};
48
Jean-Francois Moinecc611b82008-12-29 07:49:41 -030049static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030050 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
51 .bytesperline = 176,
52 .sizeimage = 176 * 144 * 3 / 8 + 590,
53 .colorspace = V4L2_COLORSPACE_JPEG,
54 .priv = 3},
55 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
56 .bytesperline = 320,
57 .sizeimage = 320 * 240 * 3 / 8 + 590,
58 .colorspace = V4L2_COLORSPACE_JPEG,
59 .priv = 2},
60 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
61 .bytesperline = 352,
62 .sizeimage = 352 * 288 * 3 / 8 + 590,
63 .colorspace = V4L2_COLORSPACE_JPEG,
64 .priv = 1},
65 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
66 .bytesperline = 640,
67 .sizeimage = 640 * 480 * 3 / 8 + 590,
68 .colorspace = V4L2_COLORSPACE_JPEG,
69 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030070};
71
Jean-Francois Moine739570b2008-07-14 09:38:29 -030072/* the read bytes are found in gspca_dev->usb_buf */
73static void reg_r(struct gspca_dev *gspca_dev,
74 __u16 index,
75 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030076{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030077 struct usb_device *dev = gspca_dev->dev;
78
Jean-Francois Moine335b3f82008-07-30 04:53:02 -030079#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -030080 if (len > USB_BUF_SZ) {
Joe Perches133a9fe2011-08-21 19:56:57 -030081 pr_err("reg_r: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -030082 return;
83 }
84#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030085 usb_control_msg(dev,
86 usb_rcvctrlpipe(dev, 0),
87 0,
88 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
89 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -030090 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030091 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -030092 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
93 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030094}
95
Jean-Francois Moine739570b2008-07-14 09:38:29 -030096/* the bytes to write are in gspca_dev->usb_buf */
97static void reg_w_val(struct gspca_dev *gspca_dev,
98 __u16 index,
99 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300100{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300101 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300102
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300103 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300104 usb_control_msg(dev,
105 usb_sndctrlpipe(dev, 0),
106 0,
107 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
108 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300109 index, gspca_dev->usb_buf, 1, 500);
110}
111
112static void reg_w(struct gspca_dev *gspca_dev,
113 __u16 index,
114 const __u8 *buffer,
115 __u16 len)
116{
117 struct usb_device *dev = gspca_dev->dev;
118
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300119#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300120 if (len > USB_BUF_SZ) {
Joe Perches133a9fe2011-08-21 19:56:57 -0300121 pr_err("reg_w: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300122 return;
123 }
124 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
125#endif
126 memcpy(gspca_dev->usb_buf, buffer, len);
127 usb_control_msg(dev,
128 usb_sndctrlpipe(dev, 0),
129 0,
130 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
131 0,
132 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300133}
134
135static const __u8 cx_sensor_init[][4] = {
136 {0x88, 0x11, 0x01, 0x01},
137 {0x88, 0x12, 0x70, 0x01},
138 {0x88, 0x0f, 0x00, 0x01},
139 {0x88, 0x05, 0x01, 0x01},
140 {}
141};
142
143static const __u8 cx11646_fw1[][3] = {
144 {0x00, 0x02, 0x00},
145 {0x01, 0x43, 0x00},
146 {0x02, 0xA7, 0x00},
147 {0x03, 0x8B, 0x01},
148 {0x04, 0xE9, 0x02},
149 {0x05, 0x08, 0x04},
150 {0x06, 0x08, 0x05},
151 {0x07, 0x07, 0x06},
152 {0x08, 0xE7, 0x06},
153 {0x09, 0xC6, 0x07},
154 {0x0A, 0x86, 0x08},
155 {0x0B, 0x46, 0x09},
156 {0x0C, 0x05, 0x0A},
157 {0x0D, 0xA5, 0x0A},
158 {0x0E, 0x45, 0x0B},
159 {0x0F, 0xE5, 0x0B},
160 {0x10, 0x85, 0x0C},
161 {0x11, 0x25, 0x0D},
162 {0x12, 0xC4, 0x0D},
163 {0x13, 0x45, 0x0E},
164 {0x14, 0xE4, 0x0E},
165 {0x15, 0x64, 0x0F},
166 {0x16, 0xE4, 0x0F},
167 {0x17, 0x64, 0x10},
168 {0x18, 0xE4, 0x10},
169 {0x19, 0x64, 0x11},
170 {0x1A, 0xE4, 0x11},
171 {0x1B, 0x64, 0x12},
172 {0x1C, 0xE3, 0x12},
173 {0x1D, 0x44, 0x13},
174 {0x1E, 0xC3, 0x13},
175 {0x1F, 0x24, 0x14},
176 {0x20, 0xA3, 0x14},
177 {0x21, 0x04, 0x15},
178 {0x22, 0x83, 0x15},
179 {0x23, 0xE3, 0x15},
180 {0x24, 0x43, 0x16},
181 {0x25, 0xA4, 0x16},
182 {0x26, 0x23, 0x17},
183 {0x27, 0x83, 0x17},
184 {0x28, 0xE3, 0x17},
185 {0x29, 0x43, 0x18},
186 {0x2A, 0xA3, 0x18},
187 {0x2B, 0x03, 0x19},
188 {0x2C, 0x63, 0x19},
189 {0x2D, 0xC3, 0x19},
190 {0x2E, 0x22, 0x1A},
191 {0x2F, 0x63, 0x1A},
192 {0x30, 0xC3, 0x1A},
193 {0x31, 0x23, 0x1B},
194 {0x32, 0x83, 0x1B},
195 {0x33, 0xE2, 0x1B},
196 {0x34, 0x23, 0x1C},
197 {0x35, 0x83, 0x1C},
198 {0x36, 0xE2, 0x1C},
199 {0x37, 0x23, 0x1D},
200 {0x38, 0x83, 0x1D},
201 {0x39, 0xE2, 0x1D},
202 {0x3A, 0x23, 0x1E},
203 {0x3B, 0x82, 0x1E},
204 {0x3C, 0xC3, 0x1E},
205 {0x3D, 0x22, 0x1F},
206 {0x3E, 0x63, 0x1F},
207 {0x3F, 0xC1, 0x1F},
208 {}
209};
210static void cx11646_fw(struct gspca_dev*gspca_dev)
211{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300212 int i = 0;
213
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300214 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300215 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300216 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300217 i++;
218 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300219 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300220}
221
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300222static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300223 0x88, 0x12, 0x70, 0x01,
224 0x88, 0x0d, 0x02, 0x01,
225 0x88, 0x0f, 0x00, 0x01,
226 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
227 0x88, 0x02, 0x10, 0x01,
228 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
229 0x88, 0x0B, 0x00, 0x01,
230 0x88, 0x0A, 0x0A, 0x01,
231 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
232 0x88, 0x05, 0x01, 0x01,
233 0xA1, 0x18, 0x00, 0x01,
234 0x00
235};
236
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300237static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
238static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
239static const __u8 reg10[] = { 0xb1, 0xb1 };
240static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
241static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300242 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300243static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300244 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300245static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
246static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300247
248static void cx_sensor(struct gspca_dev*gspca_dev)
249{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300250 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300251 int length;
252 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300253
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300254 reg_w(gspca_dev, 0x0020, reg20, 8);
255 reg_w(gspca_dev, 0x0028, reg28, 8);
Dan Carpenterb1890002012-05-02 02:15:25 -0300256 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300257 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300258
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300259 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300260 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300261 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300262 break;
263 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300264 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300265 break;
266 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300267/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300268 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300269 break;
270 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300271 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300272 break;
273 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300274 reg_w(gspca_dev, 0x007b, reg7b, 6);
275 reg_w_val(gspca_dev, 0x00f8, 0x00);
Dan Carpenterb1890002012-05-02 02:15:25 -0300276 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300277 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300278 for (i = 0; i < 11; i++) {
279 if (i == 3 || i == 5 || i == 8)
280 length = 8;
281 else
282 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300283 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300284 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300285 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300286 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300287 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300288 ptsensor += length;
289 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300290 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300291}
292
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300293static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300294 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
295 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
296 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
297 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
298 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
299 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
300 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
301};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300302static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300303 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
304 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
305 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
306 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
307 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
308 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
309 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
310};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300311static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300312 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
313 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
314 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
315 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
316 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
317 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
318 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
319};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300320static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300321 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
322 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
323 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
324 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
325 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
326 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
327 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
328};
329
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300330static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300331{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300332 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300333 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
334 static const __u8 reg17[] =
335 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
336
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300337 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300338 case 0:
339 cxinit = cx_inits_640;
340 break;
341 case 1:
342 cxinit = cx_inits_352;
343 break;
344 default:
345/* case 2: */
346 cxinit = cx_inits_320;
347 break;
348 case 3:
349 cxinit = cx_inits_176;
350 break;
351 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300352 reg_w_val(gspca_dev, 0x009a, 0x01);
353 reg_w_val(gspca_dev, 0x0010, 0x10);
354 reg_w(gspca_dev, 0x0012, reg12, 5);
355 reg_w(gspca_dev, 0x0017, reg17, 8);
356 reg_w_val(gspca_dev, 0x00c0, 0x00);
357 reg_w_val(gspca_dev, 0x00c1, 0x04);
358 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300359
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300360 reg_w(gspca_dev, 0x0061, 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, 0x00ca, 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, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300365 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300366 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300367 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300368 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300369 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300370 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300371 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300372 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300373
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300374 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300375}
376
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300377static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300378 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
379 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
380 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
381 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
382 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
383 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
384 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
385 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
386 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
387 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
388 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
389 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
390 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
391 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
392 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
393 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
394 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
395 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
396 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
397 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
398 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
399 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
400 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
401 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
402 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
403 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
404 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
405 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
406 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
407 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
408 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
409 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
410 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
411 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
412 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
413 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
414 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
415 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
416 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
417 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
418 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
419 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
420 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
421 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
422 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
423 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
424 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
425 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
426 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
427 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
428 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
429 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
430 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
431 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
432 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
433 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
434 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
435 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
436 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
437 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
438 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
439 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
440 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
441 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
442 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
443 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
444 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
445 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
446 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
447 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
448 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
449 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
450 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
451 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
452 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
453 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
454 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
455 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
456 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
457};
458
459
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300460static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300461 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
462 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
463 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
464 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
465 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
466 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
467 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
468 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
469 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
470 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
471 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
472 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
473 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
474 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
475 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
476 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
477 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
478 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
479 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
480 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
481 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
482 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
483 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
484 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
485 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
486 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
487 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
488};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300489static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300490 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
491 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
492 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
493 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
494 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
495 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
496 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
497 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
498 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
499 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
500 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
501 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
502 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
503 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
504 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
505 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
506 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
507 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
508 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
509 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
510 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
511 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
512 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
513 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
514 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
515 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
516 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
517};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300518static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300519 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
520 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
521 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
522 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
523 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
524 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
525 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
526 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
527 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
528 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
529 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
530 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
531 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
532 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
533 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
534 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
535 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
536 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
537 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
538 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
539 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
540 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
541 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
542 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
543 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
544 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
545 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
546};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300547static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300548 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
549 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
550 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
551 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
552 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
553 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
554 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
555 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
556 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
557 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
558 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
559 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
560 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
561 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
562 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
563 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
564 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
565 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
566 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
567 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
568 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
569 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
570 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
571 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
572 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
573 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
574 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
575};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300576/* 640 take with the zcx30x part */
577static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300578 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
579 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
580 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
581 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
582 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
583 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
584 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
585 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
586 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
587 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
588 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
589 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
590 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
591 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
592 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
593 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
594 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
595 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
596};
597
598
599static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
600{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300601 int i;
602 int length;
603
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300604 reg_w_val(gspca_dev, 0x00c0, 0x01);
605 reg_w_val(gspca_dev, 0x00c3, 0x00);
606 reg_w_val(gspca_dev, 0x00c0, 0x00);
607 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300608 length = 8;
609 for (i = 0; i < 79; i++) {
610 if (i == 78)
611 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300612 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300613 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300614 reg_r(gspca_dev, 0x0002, 1);
615 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300616}
617
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300618static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
619static const __u8 regE5_8[] =
620 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
621static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
622static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
623static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
624static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300625#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300626
627static void cx11646_jpeg(struct gspca_dev*gspca_dev)
628{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300629 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300630 int length;
631 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300632 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300633
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300634 reg_w_val(gspca_dev, 0x00c0, 0x01);
635 reg_w_val(gspca_dev, 0x00c3, 0x00);
636 reg_w_val(gspca_dev, 0x00c0, 0x00);
637 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300638 length = 8;
Jean-François Moine780e3122010-10-19 04:29:10 -0300639 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300640 case 0:
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_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300645 }
646 Reg55 = 0x28;
647 break;
648 case 1:
649 for (i = 0; i < 27; i++) {
650 if (i == 26)
651 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300652 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300653 }
654 Reg55 = 0x16;
655 break;
656 default:
657/* case 2: */
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_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300662 }
663 Reg55 = 0x14;
664 break;
665 case 3:
666 for (i = 0; i < 27; i++) {
667 if (i == 26)
668 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300669 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300670 }
671 Reg55 = 0x0B;
672 break;
673 }
674
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300675 reg_r(gspca_dev, 0x0002, 1);
676 reg_w_val(gspca_dev, 0x0055, Reg55);
677 reg_r(gspca_dev, 0x0002, 1);
678 reg_w(gspca_dev, 0x0010, reg10, 2);
679 reg_w_val(gspca_dev, 0x0054, 0x02);
680 reg_w_val(gspca_dev, 0x0054, 0x01);
681 reg_w_val(gspca_dev, 0x0000, 0x94);
682 reg_w_val(gspca_dev, 0x0053, 0xc0);
683 reg_w_val(gspca_dev, 0x00fc, 0xe1);
684 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300685 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300686 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300687 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300688 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300689 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300690 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300691 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300692 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300693 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300694 if (retry == 0)
695 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
696 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300697 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300698 length = 8;
699 for (i = 0; i < 18; i++) {
700 if (i == 17)
701 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300702 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300703
704 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300705 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
706 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
707 reg_w_val(gspca_dev, 0x0054, 0x02);
708 reg_w_val(gspca_dev, 0x0054, 0x01);
709 reg_w_val(gspca_dev, 0x0000, 0x94);
710 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300711
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300712 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
713 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
714 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
715 reg_w(gspca_dev, 0x0012, reg12, 5);
716 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
717 reg_r(gspca_dev, 0x00e8, 8);
718 reg_w(gspca_dev, 0x00e5, regE5a, 4);
719 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
720 reg_w_val(gspca_dev, 0x009a, 0x01);
721 reg_w(gspca_dev, 0x00e5, regE5b, 4);
722 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
723 reg_w(gspca_dev, 0x00e5, regE5c, 4);
724 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300725
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300726 reg_w(gspca_dev, 0x0051, reg51, 2);
727 reg_w(gspca_dev, 0x0010, reg10, 2);
728 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300729}
730
731static void cx11646_init1(struct gspca_dev *gspca_dev)
732{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733 int i = 0;
734
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300735 reg_w_val(gspca_dev, 0x0010, 0x00);
736 reg_w_val(gspca_dev, 0x0053, 0x00);
737 reg_w_val(gspca_dev, 0x0052, 0x00);
738 reg_w_val(gspca_dev, 0x009b, 0x2f);
739 reg_w_val(gspca_dev, 0x009c, 0x10);
740 reg_r(gspca_dev, 0x0098, 1);
741 reg_w_val(gspca_dev, 0x0098, 0x40);
742 reg_r(gspca_dev, 0x0099, 1);
743 reg_w_val(gspca_dev, 0x0099, 0x07);
744 reg_w_val(gspca_dev, 0x0039, 0x40);
745 reg_w_val(gspca_dev, 0x003c, 0xff);
746 reg_w_val(gspca_dev, 0x003f, 0x1f);
747 reg_w_val(gspca_dev, 0x003d, 0x40);
748/* reg_w_val(gspca_dev, 0x003d, 0x60); */
749 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300750
751 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300752 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
753 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300754 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300755 reg_w_val(gspca_dev, 0x00ed, 0x01);
756 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300757 }
758 i++;
759 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300760 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300761}
762
763/* this function is called at probe time */
764static int sd_config(struct gspca_dev *gspca_dev,
765 const struct usb_device_id *id)
766{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300767 struct cam *cam;
768
769 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300770 cam->cam_mode = vga_mode;
Mauro Carvalho Chehabd6f76b92009-07-22 00:02:29 -0300771 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300772 return 0;
773}
774
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300775/* this function is called at probe and resume time */
776static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300777{
778 cx11646_init1(gspca_dev);
779 cx11646_initsize(gspca_dev);
780 cx11646_fw(gspca_dev);
781 cx_sensor(gspca_dev);
782 cx11646_jpegInit(gspca_dev);
783 return 0;
784}
785
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300786static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300787{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300788 struct sd *sd = (struct sd *) gspca_dev;
789
790 /* create the JPEG header */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300791 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
792 0x22); /* JPEG 411 */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300793
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300794 cx11646_initsize(gspca_dev);
795 cx11646_fw(gspca_dev);
796 cx_sensor(gspca_dev);
797 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300798 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300799}
800
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300801/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300802static void sd_stop0(struct gspca_dev *gspca_dev)
803{
804 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300806 if (!gspca_dev->present)
807 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300808 reg_w_val(gspca_dev, 0x0000, 0x00);
809 reg_r(gspca_dev, 0x0002, 1);
810 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300811
812 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300813/* reg_r(gspca_dev, 0x0002, 1);*/
814 reg_r(gspca_dev, 0x0053, 1);
815 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300816 break;
817 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300818 reg_w_val(gspca_dev, 0x0000, 0x00);
819 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300820
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300821 reg_w_val(gspca_dev, 0x0010, 0x00);
822 reg_r(gspca_dev, 0x0033, 1);
823 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300824}
825
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300827 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300828 int len) /* iso packet length */
829{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300830 struct sd *sd = (struct sd *) gspca_dev;
831
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300832 if (data[0] == 0xff && data[1] == 0xd8) {
833
834 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300835 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300836
837 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300838 gspca_frame_add(gspca_dev, FIRST_PACKET,
839 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300840 data += 2;
841 len -= 2;
842 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300843 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300844}
845
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300846static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300847{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300848 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300849 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300850
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300851 regE5cbx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300852 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
853 reg_r(gspca_dev, 0x00e8, 8);
854 reg_w(gspca_dev, 0x00e5, regE5c, 4);
855 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300856
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300857 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300858 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300859 reg_w(gspca_dev, 0x0051, reg51c, 2);
860 reg_w(gspca_dev, 0x0010, reg10, 2);
861 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862}
863
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300864static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300866 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300867/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
868 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300869
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300870 regE5acx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300871 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
872 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300873 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300874 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300875 reg_w(gspca_dev, 0x0051, reg51c, 2);
876 reg_w(gspca_dev, 0x0010, reg10, 2);
877 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878}
879
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300880static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300881{
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300882 struct gspca_dev *gspca_dev =
883 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
884 struct sd *sd = (struct sd *)gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300885
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300886 gspca_dev->usb_err = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300887
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300888 if (!gspca_dev->streaming)
889 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300890
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300891 switch (ctrl->id) {
892 case V4L2_CID_BRIGHTNESS:
893 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
894 break;
895 case V4L2_CID_CONTRAST:
896 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
897 break;
898 case V4L2_CID_SATURATION:
899 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
900 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
901 break;
902 case V4L2_CID_JPEG_COMPRESSION_QUALITY:
903 jpeg_set_qual(sd->jpeg_hdr, ctrl->val);
904 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300905 }
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300906 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300907}
908
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300909static const struct v4l2_ctrl_ops sd_ctrl_ops = {
910 .s_ctrl = sd_s_ctrl,
911};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300912
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300913static int sd_init_controls(struct gspca_dev *gspca_dev)
914{
915 struct sd *sd = (struct sd *)gspca_dev;
916 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
917
918 gspca_dev->vdev.ctrl_handler = hdl;
919 v4l2_ctrl_handler_init(hdl, 4);
920 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
921 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
922 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
923 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
924 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
925 V4L2_CID_SATURATION, 0, 7, 1, 3);
926 sd->jpegqual = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
927 V4L2_CID_JPEG_COMPRESSION_QUALITY,
928 QUALITY_MIN, QUALITY_MAX, 1, QUALITY_DEF);
929 if (hdl->error) {
930 pr_err("Could not initialize controls\n");
931 return hdl->error;
932 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300933 return 0;
934}
935
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -0300936static int sd_set_jcomp(struct gspca_dev *gspca_dev,
937 struct v4l2_jpegcompression *jcomp)
938{
939 struct sd *sd = (struct sd *) gspca_dev;
940
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300941 v4l2_ctrl_s_ctrl(sd->jpegqual, jcomp->quality);
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -0300942 return 0;
943}
944
945static int sd_get_jcomp(struct gspca_dev *gspca_dev,
946 struct v4l2_jpegcompression *jcomp)
947{
948 struct sd *sd = (struct sd *) gspca_dev;
949
950 memset(jcomp, 0, sizeof *jcomp);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300951 jcomp->quality = v4l2_ctrl_g_ctrl(sd->jpegqual);
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -0300952 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
953 | V4L2_JPEG_MARKER_DQT;
954 return 0;
955}
956
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300957/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -0300958static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300959 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300960 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300961 .init = sd_init,
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300962 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300963 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300964 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300965 .pkt_scan = sd_pkt_scan,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -0300966 .get_jcomp = sd_get_jcomp,
967 .set_jcomp = sd_set_jcomp,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300968};
969
970/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300971static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300972 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300973 {}
974};
975MODULE_DEVICE_TABLE(usb, device_table);
976
977/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300978static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300979 const struct usb_device_id *id)
980{
981 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
982 THIS_MODULE);
983}
984
985static struct usb_driver sd_driver = {
986 .name = MODULE_NAME,
987 .id_table = device_table,
988 .probe = sd_probe,
989 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300990#ifdef CONFIG_PM
991 .suspend = gspca_suspend,
992 .resume = gspca_resume,
993#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300994};
995
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -0800996module_usb_driver(sd_driver);