blob: 219cfa6fb877e2e20353bd0b160ac8933c8bc266 [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
22#define MODULE_NAME "conex"
23
24#include "gspca.h"
25#define CONEX_CAM 1 /* special JPEG header */
26#include "jpeg.h"
27
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030028MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
29MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
30MODULE_LICENSE("GPL");
31
32/* specific webcam descriptor */
33struct sd {
34 struct gspca_dev gspca_dev; /* !! must be the first item */
35
36 unsigned char brightness;
37 unsigned char contrast;
38 unsigned char colors;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030039 u8 quality;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030040#define QUALITY_MIN 30
41#define QUALITY_MAX 60
42#define QUALITY_DEF 40
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030043
44 u8 *jpeg_hdr;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030045};
46
47/* V4L2 controls supported by the driver */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54
55static struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030056 {
57 {
58 .id = V4L2_CID_BRIGHTNESS,
59 .type = V4L2_CTRL_TYPE_INTEGER,
60 .name = "Brightness",
61 .minimum = 0,
62 .maximum = 255,
63 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030064#define BRIGHTNESS_DEF 0xd4
65 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030066 },
67 .set = sd_setbrightness,
68 .get = sd_getbrightness,
69 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030070 {
71 {
72 .id = V4L2_CID_CONTRAST,
73 .type = V4L2_CTRL_TYPE_INTEGER,
74 .name = "Contrast",
75 .minimum = 0x0a,
76 .maximum = 0x1f,
77 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030078#define CONTRAST_DEF 0x0c
79 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030080 },
81 .set = sd_setcontrast,
82 .get = sd_getcontrast,
83 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030084 {
85 {
86 .id = V4L2_CID_SATURATION,
87 .type = V4L2_CTRL_TYPE_INTEGER,
88 .name = "Color",
89 .minimum = 0,
90 .maximum = 7,
91 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030092#define COLOR_DEF 3
93 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030094 },
95 .set = sd_setcolors,
96 .get = sd_getcolors,
97 },
98};
99
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300100static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300101 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
102 .bytesperline = 176,
103 .sizeimage = 176 * 144 * 3 / 8 + 590,
104 .colorspace = V4L2_COLORSPACE_JPEG,
105 .priv = 3},
106 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
107 .bytesperline = 320,
108 .sizeimage = 320 * 240 * 3 / 8 + 590,
109 .colorspace = V4L2_COLORSPACE_JPEG,
110 .priv = 2},
111 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
112 .bytesperline = 352,
113 .sizeimage = 352 * 288 * 3 / 8 + 590,
114 .colorspace = V4L2_COLORSPACE_JPEG,
115 .priv = 1},
116 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
117 .bytesperline = 640,
118 .sizeimage = 640 * 480 * 3 / 8 + 590,
119 .colorspace = V4L2_COLORSPACE_JPEG,
120 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300121};
122
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300123/* the read bytes are found in gspca_dev->usb_buf */
124static void reg_r(struct gspca_dev *gspca_dev,
125 __u16 index,
126 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300127{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300128 struct usb_device *dev = gspca_dev->dev;
129
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300130#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300131 if (len > USB_BUF_SZ) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300132 err("reg_r: buffer overflow");
133 return;
134 }
135#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300136 usb_control_msg(dev,
137 usb_rcvctrlpipe(dev, 0),
138 0,
139 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
140 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300141 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300142 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300143 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
144 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300145}
146
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300147/* the bytes to write are in gspca_dev->usb_buf */
148static void reg_w_val(struct gspca_dev *gspca_dev,
149 __u16 index,
150 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300151{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300152 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300153
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300154 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300155 usb_control_msg(dev,
156 usb_sndctrlpipe(dev, 0),
157 0,
158 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
159 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300160 index, gspca_dev->usb_buf, 1, 500);
161}
162
163static void reg_w(struct gspca_dev *gspca_dev,
164 __u16 index,
165 const __u8 *buffer,
166 __u16 len)
167{
168 struct usb_device *dev = gspca_dev->dev;
169
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300170#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300171 if (len > USB_BUF_SZ) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300172 err("reg_w: buffer overflow");
173 return;
174 }
175 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
176#endif
177 memcpy(gspca_dev->usb_buf, buffer, len);
178 usb_control_msg(dev,
179 usb_sndctrlpipe(dev, 0),
180 0,
181 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
182 0,
183 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300184}
185
186static const __u8 cx_sensor_init[][4] = {
187 {0x88, 0x11, 0x01, 0x01},
188 {0x88, 0x12, 0x70, 0x01},
189 {0x88, 0x0f, 0x00, 0x01},
190 {0x88, 0x05, 0x01, 0x01},
191 {}
192};
193
194static const __u8 cx11646_fw1[][3] = {
195 {0x00, 0x02, 0x00},
196 {0x01, 0x43, 0x00},
197 {0x02, 0xA7, 0x00},
198 {0x03, 0x8B, 0x01},
199 {0x04, 0xE9, 0x02},
200 {0x05, 0x08, 0x04},
201 {0x06, 0x08, 0x05},
202 {0x07, 0x07, 0x06},
203 {0x08, 0xE7, 0x06},
204 {0x09, 0xC6, 0x07},
205 {0x0A, 0x86, 0x08},
206 {0x0B, 0x46, 0x09},
207 {0x0C, 0x05, 0x0A},
208 {0x0D, 0xA5, 0x0A},
209 {0x0E, 0x45, 0x0B},
210 {0x0F, 0xE5, 0x0B},
211 {0x10, 0x85, 0x0C},
212 {0x11, 0x25, 0x0D},
213 {0x12, 0xC4, 0x0D},
214 {0x13, 0x45, 0x0E},
215 {0x14, 0xE4, 0x0E},
216 {0x15, 0x64, 0x0F},
217 {0x16, 0xE4, 0x0F},
218 {0x17, 0x64, 0x10},
219 {0x18, 0xE4, 0x10},
220 {0x19, 0x64, 0x11},
221 {0x1A, 0xE4, 0x11},
222 {0x1B, 0x64, 0x12},
223 {0x1C, 0xE3, 0x12},
224 {0x1D, 0x44, 0x13},
225 {0x1E, 0xC3, 0x13},
226 {0x1F, 0x24, 0x14},
227 {0x20, 0xA3, 0x14},
228 {0x21, 0x04, 0x15},
229 {0x22, 0x83, 0x15},
230 {0x23, 0xE3, 0x15},
231 {0x24, 0x43, 0x16},
232 {0x25, 0xA4, 0x16},
233 {0x26, 0x23, 0x17},
234 {0x27, 0x83, 0x17},
235 {0x28, 0xE3, 0x17},
236 {0x29, 0x43, 0x18},
237 {0x2A, 0xA3, 0x18},
238 {0x2B, 0x03, 0x19},
239 {0x2C, 0x63, 0x19},
240 {0x2D, 0xC3, 0x19},
241 {0x2E, 0x22, 0x1A},
242 {0x2F, 0x63, 0x1A},
243 {0x30, 0xC3, 0x1A},
244 {0x31, 0x23, 0x1B},
245 {0x32, 0x83, 0x1B},
246 {0x33, 0xE2, 0x1B},
247 {0x34, 0x23, 0x1C},
248 {0x35, 0x83, 0x1C},
249 {0x36, 0xE2, 0x1C},
250 {0x37, 0x23, 0x1D},
251 {0x38, 0x83, 0x1D},
252 {0x39, 0xE2, 0x1D},
253 {0x3A, 0x23, 0x1E},
254 {0x3B, 0x82, 0x1E},
255 {0x3C, 0xC3, 0x1E},
256 {0x3D, 0x22, 0x1F},
257 {0x3E, 0x63, 0x1F},
258 {0x3F, 0xC1, 0x1F},
259 {}
260};
261static void cx11646_fw(struct gspca_dev*gspca_dev)
262{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300263 int i = 0;
264
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300265 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300266 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300267 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300268 i++;
269 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300270 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300271}
272
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300273static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300274 0x88, 0x12, 0x70, 0x01,
275 0x88, 0x0d, 0x02, 0x01,
276 0x88, 0x0f, 0x00, 0x01,
277 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
278 0x88, 0x02, 0x10, 0x01,
279 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
280 0x88, 0x0B, 0x00, 0x01,
281 0x88, 0x0A, 0x0A, 0x01,
282 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
283 0x88, 0x05, 0x01, 0x01,
284 0xA1, 0x18, 0x00, 0x01,
285 0x00
286};
287
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300288static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
289static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
290static const __u8 reg10[] = { 0xb1, 0xb1 };
291static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
292static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300293 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300294static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300295 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300296static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
297static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300298
299static void cx_sensor(struct gspca_dev*gspca_dev)
300{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300301 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300302 int length;
303 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300304
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300305 reg_w(gspca_dev, 0x0020, reg20, 8);
306 reg_w(gspca_dev, 0x0028, reg28, 8);
307 reg_w(gspca_dev, 0x0010, reg10, 8);
308 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300309
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300310 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300311 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300312 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300313 break;
314 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300315 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300316 break;
317 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300318/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300319 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300320 break;
321 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300322 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300323 break;
324 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300325 reg_w(gspca_dev, 0x007b, reg7b, 6);
326 reg_w_val(gspca_dev, 0x00f8, 0x00);
327 reg_w(gspca_dev, 0x0010, reg10, 8);
328 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300329 for (i = 0; i < 11; i++) {
330 if (i == 3 || i == 5 || i == 8)
331 length = 8;
332 else
333 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300334 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300335 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300336 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300337 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300338 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300339 ptsensor += length;
340 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300341 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300342}
343
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300344static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300345 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
346 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
347 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
348 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
349 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
350 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
351 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
352};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300353static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300354 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
355 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
356 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
357 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
358 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
359 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
360 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
361};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300362static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300363 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
364 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
365 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
366 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
367 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
368 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
369 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
370};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300371static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300372 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
373 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
374 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
375 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
376 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
377 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
378 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
379};
380
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300381static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300382{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300383 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
385 static const __u8 reg17[] =
386 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
387
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300388 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300389 case 0:
390 cxinit = cx_inits_640;
391 break;
392 case 1:
393 cxinit = cx_inits_352;
394 break;
395 default:
396/* case 2: */
397 cxinit = cx_inits_320;
398 break;
399 case 3:
400 cxinit = cx_inits_176;
401 break;
402 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300403 reg_w_val(gspca_dev, 0x009a, 0x01);
404 reg_w_val(gspca_dev, 0x0010, 0x10);
405 reg_w(gspca_dev, 0x0012, reg12, 5);
406 reg_w(gspca_dev, 0x0017, reg17, 8);
407 reg_w_val(gspca_dev, 0x00c0, 0x00);
408 reg_w_val(gspca_dev, 0x00c1, 0x04);
409 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300410
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300411 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300412 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300413 reg_w(gspca_dev, 0x00ca, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300414 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300415 reg_w(gspca_dev, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300416 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300417 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300418 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300419 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300420 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300421 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300422 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300423 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300424
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300425 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300426}
427
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300428static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300429 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
430 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
431 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
432 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
433 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
434 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
435 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
436 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
437 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
438 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
439 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
440 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
441 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
442 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
443 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
444 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
445 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
446 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
447 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
448 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
449 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
450 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
451 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
452 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
453 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
454 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
455 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
456 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
457 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
458 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
459 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
460 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
461 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
462 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
463 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
464 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
465 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
466 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
467 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
468 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
469 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
470 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
471 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
472 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
473 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
474 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
475 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
476 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
477 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
478 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
479 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
480 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
481 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
482 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
483 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
484 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
485 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
486 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
487 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
488 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
489 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
490 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
491 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
492 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
493 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
494 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
495 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
496 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
497 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
498 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
499 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
500 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
501 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
502 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
503 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
504 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
505 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
506 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
507 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
508};
509
510
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300511static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300512 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
513 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
514 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
515 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
516 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
517 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
518 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
519 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
520 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
521 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
522 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
523 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
524 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
525 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
526 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
527 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
528 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
529 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
530 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
531 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
532 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
533 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
534 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
535 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
536 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
537 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
538 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
539};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300540static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300541 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
542 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
543 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
544 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
545 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
546 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
547 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
548 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
549 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
550 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
551 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
552 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
553 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
554 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
555 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
556 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
557 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
558 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
559 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
560 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
561 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
562 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
563 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
564 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
565 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
566 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
567 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
568};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300569static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300570 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
571 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
572 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
573 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
574 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
575 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
576 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
577 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
578 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
579 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
580 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
581 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
582 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
583 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
584 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
585 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
586 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
587 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
588 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
589 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
590 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
591 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
592 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
593 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
594 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
595 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
596 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
597};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300598static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300599 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
600 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
601 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
602 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
603 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
604 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
605 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
606 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
607 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
608 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
609 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
610 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
611 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
612 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
613 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
614 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
615 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
616 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
617 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
618 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
619 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
620 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
621 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
622 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
623 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
624 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
625 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
626};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300627/* 640 take with the zcx30x part */
628static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300629 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
630 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
631 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
632 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
633 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
634 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
635 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
636 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
637 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
638 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
639 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
640 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
641 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
642 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
643 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
644 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
645 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
646 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
647};
648
649
650static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
651{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300652 int i;
653 int length;
654
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300655 reg_w_val(gspca_dev, 0x00c0, 0x01);
656 reg_w_val(gspca_dev, 0x00c3, 0x00);
657 reg_w_val(gspca_dev, 0x00c0, 0x00);
658 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300659 length = 8;
660 for (i = 0; i < 79; i++) {
661 if (i == 78)
662 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300663 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300664 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300665 reg_r(gspca_dev, 0x0002, 1);
666 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300667}
668
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300669static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
670static const __u8 regE5_8[] =
671 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
672static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
673static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
674static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
675static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300676#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300677
678static void cx11646_jpeg(struct gspca_dev*gspca_dev)
679{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300680 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300681 int length;
682 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300683 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300684
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300685 reg_w_val(gspca_dev, 0x00c0, 0x01);
686 reg_w_val(gspca_dev, 0x00c3, 0x00);
687 reg_w_val(gspca_dev, 0x00c0, 0x00);
688 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300689 length = 8;
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300690 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300691 case 0:
692 for (i = 0; i < 27; i++) {
693 if (i == 26)
694 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300695 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300696 }
697 Reg55 = 0x28;
698 break;
699 case 1:
700 for (i = 0; i < 27; i++) {
701 if (i == 26)
702 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300703 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300704 }
705 Reg55 = 0x16;
706 break;
707 default:
708/* case 2: */
709 for (i = 0; i < 27; i++) {
710 if (i == 26)
711 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300712 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300713 }
714 Reg55 = 0x14;
715 break;
716 case 3:
717 for (i = 0; i < 27; i++) {
718 if (i == 26)
719 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300720 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300721 }
722 Reg55 = 0x0B;
723 break;
724 }
725
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300726 reg_r(gspca_dev, 0x0002, 1);
727 reg_w_val(gspca_dev, 0x0055, Reg55);
728 reg_r(gspca_dev, 0x0002, 1);
729 reg_w(gspca_dev, 0x0010, reg10, 2);
730 reg_w_val(gspca_dev, 0x0054, 0x02);
731 reg_w_val(gspca_dev, 0x0054, 0x01);
732 reg_w_val(gspca_dev, 0x0000, 0x94);
733 reg_w_val(gspca_dev, 0x0053, 0xc0);
734 reg_w_val(gspca_dev, 0x00fc, 0xe1);
735 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300736 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300737 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300738 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300739 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300740 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300741 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300743 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300744 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300745 if (retry == 0)
746 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
747 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300748 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300749 length = 8;
750 for (i = 0; i < 18; i++) {
751 if (i == 17)
752 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300753 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300754
755 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300756 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
757 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
758 reg_w_val(gspca_dev, 0x0054, 0x02);
759 reg_w_val(gspca_dev, 0x0054, 0x01);
760 reg_w_val(gspca_dev, 0x0000, 0x94);
761 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300762
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300763 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
764 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
765 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
766 reg_w(gspca_dev, 0x0012, reg12, 5);
767 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
768 reg_r(gspca_dev, 0x00e8, 8);
769 reg_w(gspca_dev, 0x00e5, regE5a, 4);
770 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
771 reg_w_val(gspca_dev, 0x009a, 0x01);
772 reg_w(gspca_dev, 0x00e5, regE5b, 4);
773 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
774 reg_w(gspca_dev, 0x00e5, regE5c, 4);
775 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300776
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300777 reg_w(gspca_dev, 0x0051, reg51, 2);
778 reg_w(gspca_dev, 0x0010, reg10, 2);
779 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300780}
781
782static void cx11646_init1(struct gspca_dev *gspca_dev)
783{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300784 int i = 0;
785
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300786 reg_w_val(gspca_dev, 0x0010, 0x00);
787 reg_w_val(gspca_dev, 0x0053, 0x00);
788 reg_w_val(gspca_dev, 0x0052, 0x00);
789 reg_w_val(gspca_dev, 0x009b, 0x2f);
790 reg_w_val(gspca_dev, 0x009c, 0x10);
791 reg_r(gspca_dev, 0x0098, 1);
792 reg_w_val(gspca_dev, 0x0098, 0x40);
793 reg_r(gspca_dev, 0x0099, 1);
794 reg_w_val(gspca_dev, 0x0099, 0x07);
795 reg_w_val(gspca_dev, 0x0039, 0x40);
796 reg_w_val(gspca_dev, 0x003c, 0xff);
797 reg_w_val(gspca_dev, 0x003f, 0x1f);
798 reg_w_val(gspca_dev, 0x003d, 0x40);
799/* reg_w_val(gspca_dev, 0x003d, 0x60); */
800 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801
802 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300803 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
804 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300806 reg_w_val(gspca_dev, 0x00ed, 0x01);
807 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300808 }
809 i++;
810 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300811 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300812}
813
814/* this function is called at probe time */
815static int sd_config(struct gspca_dev *gspca_dev,
816 const struct usb_device_id *id)
817{
818 struct sd *sd = (struct sd *) gspca_dev;
819 struct cam *cam;
820
821 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300822 cam->cam_mode = vga_mode;
823 cam->nmodes = sizeof vga_mode / sizeof vga_mode[0];
824
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300825 sd->brightness = BRIGHTNESS_DEF;
826 sd->contrast = CONTRAST_DEF;
827 sd->colors = COLOR_DEF;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -0300828 sd->quality = QUALITY_DEF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300829 return 0;
830}
831
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300832/* this function is called at probe and resume time */
833static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300834{
835 cx11646_init1(gspca_dev);
836 cx11646_initsize(gspca_dev);
837 cx11646_fw(gspca_dev);
838 cx_sensor(gspca_dev);
839 cx11646_jpegInit(gspca_dev);
840 return 0;
841}
842
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300843static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300844{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300845 struct sd *sd = (struct sd *) gspca_dev;
846
847 /* create the JPEG header */
848 sd->jpeg_hdr = kmalloc(JPEG_HDR_SZ, GFP_KERNEL);
849 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
850 0x22); /* JPEG 411 */
851 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
852
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300853 cx11646_initsize(gspca_dev);
854 cx11646_fw(gspca_dev);
855 cx_sensor(gspca_dev);
856 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300857 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300858}
859
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300860/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300861static void sd_stop0(struct gspca_dev *gspca_dev)
862{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300863 struct sd *sd = (struct sd *) gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300864 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300866 kfree(sd->jpeg_hdr);
867
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300868 if (!gspca_dev->present)
869 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300870 reg_w_val(gspca_dev, 0x0000, 0x00);
871 reg_r(gspca_dev, 0x0002, 1);
872 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300873
874 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300875/* reg_r(gspca_dev, 0x0002, 1);*/
876 reg_r(gspca_dev, 0x0053, 1);
877 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300878 break;
879 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300880 reg_w_val(gspca_dev, 0x0000, 0x00);
881 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300882
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300883 reg_w_val(gspca_dev, 0x0010, 0x00);
884 reg_r(gspca_dev, 0x0033, 1);
885 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886}
887
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888static void sd_pkt_scan(struct gspca_dev *gspca_dev,
889 struct gspca_frame *frame, /* target */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300890 __u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300891 int len) /* iso packet length */
892{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300893 struct sd *sd = (struct sd *) gspca_dev;
894
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300895 if (data[0] == 0xff && data[1] == 0xd8) {
896
897 /* start of frame */
898 frame = gspca_frame_add(gspca_dev, LAST_PACKET, frame,
899 data, 0);
900
901 /* put the JPEG header in the new frame */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300902 gspca_frame_add(gspca_dev, FIRST_PACKET, frame,
903 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300904 data += 2;
905 len -= 2;
906 }
907 gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
908}
909
910static void setbrightness(struct gspca_dev*gspca_dev)
911{
912 struct sd *sd = (struct sd *) gspca_dev;
913 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300914 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300915 __u8 bright;
916 __u8 colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300917
918 bright = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300919 regE5cbx[2] = bright;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300920 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
921 reg_r(gspca_dev, 0x00e8, 8);
922 reg_w(gspca_dev, 0x00e5, regE5c, 4);
923 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300924
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300925 colors = sd->colors;
926 reg51c[0] = 0x77;
927 reg51c[1] = colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300928 reg_w(gspca_dev, 0x0051, reg51c, 2);
929 reg_w(gspca_dev, 0x0010, reg10, 2);
930 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300931}
932
933static void setcontrast(struct gspca_dev*gspca_dev)
934{
935 struct sd *sd = (struct sd *) gspca_dev;
936 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300937/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
938 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300939
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300940 regE5acx[2] = sd->contrast;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300941 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
942 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300943 reg51c[0] = 0x77;
944 reg51c[1] = sd->colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300945 reg_w(gspca_dev, 0x0051, reg51c, 2);
946 reg_w(gspca_dev, 0x0010, reg10, 2);
947 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300948}
949
950static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
951{
952 struct sd *sd = (struct sd *) gspca_dev;
953
954 sd->brightness = val;
955 if (gspca_dev->streaming)
956 setbrightness(gspca_dev);
957 return 0;
958}
959
960static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
961{
962 struct sd *sd = (struct sd *) gspca_dev;
963
964 *val = sd->brightness;
965 return 0;
966}
967
968static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
969{
970 struct sd *sd = (struct sd *) gspca_dev;
971
972 sd->contrast = val;
973 if (gspca_dev->streaming)
974 setcontrast(gspca_dev);
975 return 0;
976}
977
978static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
979{
980 struct sd *sd = (struct sd *) gspca_dev;
981
982 *val = sd->contrast;
983 return 0;
984}
985
986static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
987{
988 struct sd *sd = (struct sd *) gspca_dev;
989
990 sd->colors = val;
991 if (gspca_dev->streaming) {
992 setbrightness(gspca_dev);
993 setcontrast(gspca_dev);
994 }
995 return 0;
996}
997
998static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
999{
1000 struct sd *sd = (struct sd *) gspca_dev;
1001
1002 *val = sd->colors;
1003 return 0;
1004}
1005
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001006static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1007 struct v4l2_jpegcompression *jcomp)
1008{
1009 struct sd *sd = (struct sd *) gspca_dev;
1010
1011 if (jcomp->quality < QUALITY_MIN)
1012 sd->quality = QUALITY_MIN;
1013 else if (jcomp->quality > QUALITY_MAX)
1014 sd->quality = QUALITY_MAX;
1015 else
1016 sd->quality = jcomp->quality;
1017 if (gspca_dev->streaming)
1018 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1019 return 0;
1020}
1021
1022static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1023 struct v4l2_jpegcompression *jcomp)
1024{
1025 struct sd *sd = (struct sd *) gspca_dev;
1026
1027 memset(jcomp, 0, sizeof *jcomp);
1028 jcomp->quality = sd->quality;
1029 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1030 | V4L2_JPEG_MARKER_DQT;
1031 return 0;
1032}
1033
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001034/* sub-driver description */
1035static struct sd_desc sd_desc = {
1036 .name = MODULE_NAME,
1037 .ctrls = sd_ctrls,
1038 .nctrls = ARRAY_SIZE(sd_ctrls),
1039 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001040 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001041 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001042 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001043 .pkt_scan = sd_pkt_scan,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001044 .get_jcomp = sd_get_jcomp,
1045 .set_jcomp = sd_set_jcomp,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001046};
1047
1048/* -- module initialisation -- */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001049static __devinitdata struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001050 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001051 {}
1052};
1053MODULE_DEVICE_TABLE(usb, device_table);
1054
1055/* -- device connect -- */
1056static int sd_probe(struct usb_interface *intf,
1057 const struct usb_device_id *id)
1058{
1059 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1060 THIS_MODULE);
1061}
1062
1063static struct usb_driver sd_driver = {
1064 .name = MODULE_NAME,
1065 .id_table = device_table,
1066 .probe = sd_probe,
1067 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001068#ifdef CONFIG_PM
1069 .suspend = gspca_suspend,
1070 .resume = gspca_resume,
1071#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001072};
1073
1074/* -- module insert / remove -- */
1075static int __init sd_mod_init(void)
1076{
Alexey Klimovf69e9522009-01-01 13:02:07 -03001077 int ret;
1078 ret = usb_register(&sd_driver);
1079 if (ret < 0)
Alexey Klimove6b14842009-01-01 13:04:58 -03001080 return ret;
Jean-Francois Moine10b0e962008-07-22 05:35:10 -03001081 PDEBUG(D_PROBE, "registered");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001082 return 0;
1083}
1084static void __exit sd_mod_exit(void)
1085{
1086 usb_deregister(&sd_driver);
1087 PDEBUG(D_PROBE, "deregistered");
1088}
1089
1090module_init(sd_mod_init);
1091module_exit(sd_mod_exit);