blob: 4c56dbef6d92fb778bb625a99e941de597beeed1 [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
34/* specific webcam descriptor */
35struct sd {
36 struct gspca_dev gspca_dev; /* !! must be the first item */
37
38 unsigned char brightness;
39 unsigned char contrast;
40 unsigned char colors;
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030041 u8 quality;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -030042#define QUALITY_MIN 30
43#define QUALITY_MAX 60
44#define QUALITY_DEF 40
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030045
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
49/* V4L2 controls supported by the driver */
50static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
54static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
55static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
56
Marton Nemeth7e64dc42009-12-30 09:12:41 -030057static const struct ctrl sd_ctrls[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030058 {
59 {
60 .id = V4L2_CID_BRIGHTNESS,
61 .type = V4L2_CTRL_TYPE_INTEGER,
62 .name = "Brightness",
63 .minimum = 0,
64 .maximum = 255,
65 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030066#define BRIGHTNESS_DEF 0xd4
67 .default_value = BRIGHTNESS_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030068 },
69 .set = sd_setbrightness,
70 .get = sd_getbrightness,
71 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030072 {
73 {
74 .id = V4L2_CID_CONTRAST,
75 .type = V4L2_CTRL_TYPE_INTEGER,
76 .name = "Contrast",
77 .minimum = 0x0a,
78 .maximum = 0x1f,
79 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030080#define CONTRAST_DEF 0x0c
81 .default_value = CONTRAST_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030082 },
83 .set = sd_setcontrast,
84 .get = sd_getcontrast,
85 },
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030086 {
87 {
88 .id = V4L2_CID_SATURATION,
89 .type = V4L2_CTRL_TYPE_INTEGER,
90 .name = "Color",
91 .minimum = 0,
92 .maximum = 7,
93 .step = 1,
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030094#define COLOR_DEF 3
95 .default_value = COLOR_DEF,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030096 },
97 .set = sd_setcolors,
98 .get = sd_getcolors,
99 },
100};
101
Jean-Francois Moinecc611b82008-12-29 07:49:41 -0300102static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300103 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
104 .bytesperline = 176,
105 .sizeimage = 176 * 144 * 3 / 8 + 590,
106 .colorspace = V4L2_COLORSPACE_JPEG,
107 .priv = 3},
108 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
109 .bytesperline = 320,
110 .sizeimage = 320 * 240 * 3 / 8 + 590,
111 .colorspace = V4L2_COLORSPACE_JPEG,
112 .priv = 2},
113 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
114 .bytesperline = 352,
115 .sizeimage = 352 * 288 * 3 / 8 + 590,
116 .colorspace = V4L2_COLORSPACE_JPEG,
117 .priv = 1},
118 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
119 .bytesperline = 640,
120 .sizeimage = 640 * 480 * 3 / 8 + 590,
121 .colorspace = V4L2_COLORSPACE_JPEG,
122 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300123};
124
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300125/* the read bytes are found in gspca_dev->usb_buf */
126static void reg_r(struct gspca_dev *gspca_dev,
127 __u16 index,
128 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300129{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300130 struct usb_device *dev = gspca_dev->dev;
131
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300132#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300133 if (len > USB_BUF_SZ) {
Joe Perches133a9fe2011-08-21 19:56:57 -0300134 pr_err("reg_r: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300135 return;
136 }
137#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300138 usb_control_msg(dev,
139 usb_rcvctrlpipe(dev, 0),
140 0,
141 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
142 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300143 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300144 500);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300145 PDEBUG(D_USBI, "reg read [%02x] -> %02x ..",
146 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300147}
148
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300149/* the bytes to write are in gspca_dev->usb_buf */
150static void reg_w_val(struct gspca_dev *gspca_dev,
151 __u16 index,
152 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300153{
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300154 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300155
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300156 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300157 usb_control_msg(dev,
158 usb_sndctrlpipe(dev, 0),
159 0,
160 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
161 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300162 index, gspca_dev->usb_buf, 1, 500);
163}
164
165static void reg_w(struct gspca_dev *gspca_dev,
166 __u16 index,
167 const __u8 *buffer,
168 __u16 len)
169{
170 struct usb_device *dev = gspca_dev->dev;
171
Jean-Francois Moine335b3f82008-07-30 04:53:02 -0300172#ifdef GSPCA_DEBUG
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300173 if (len > USB_BUF_SZ) {
Joe Perches133a9fe2011-08-21 19:56:57 -0300174 pr_err("reg_w: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300175 return;
176 }
177 PDEBUG(D_USBO, "reg write [%02x] = %02x..", index, *buffer);
178#endif
179 memcpy(gspca_dev->usb_buf, buffer, len);
180 usb_control_msg(dev,
181 usb_sndctrlpipe(dev, 0),
182 0,
183 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
184 0,
185 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300186}
187
188static const __u8 cx_sensor_init[][4] = {
189 {0x88, 0x11, 0x01, 0x01},
190 {0x88, 0x12, 0x70, 0x01},
191 {0x88, 0x0f, 0x00, 0x01},
192 {0x88, 0x05, 0x01, 0x01},
193 {}
194};
195
196static const __u8 cx11646_fw1[][3] = {
197 {0x00, 0x02, 0x00},
198 {0x01, 0x43, 0x00},
199 {0x02, 0xA7, 0x00},
200 {0x03, 0x8B, 0x01},
201 {0x04, 0xE9, 0x02},
202 {0x05, 0x08, 0x04},
203 {0x06, 0x08, 0x05},
204 {0x07, 0x07, 0x06},
205 {0x08, 0xE7, 0x06},
206 {0x09, 0xC6, 0x07},
207 {0x0A, 0x86, 0x08},
208 {0x0B, 0x46, 0x09},
209 {0x0C, 0x05, 0x0A},
210 {0x0D, 0xA5, 0x0A},
211 {0x0E, 0x45, 0x0B},
212 {0x0F, 0xE5, 0x0B},
213 {0x10, 0x85, 0x0C},
214 {0x11, 0x25, 0x0D},
215 {0x12, 0xC4, 0x0D},
216 {0x13, 0x45, 0x0E},
217 {0x14, 0xE4, 0x0E},
218 {0x15, 0x64, 0x0F},
219 {0x16, 0xE4, 0x0F},
220 {0x17, 0x64, 0x10},
221 {0x18, 0xE4, 0x10},
222 {0x19, 0x64, 0x11},
223 {0x1A, 0xE4, 0x11},
224 {0x1B, 0x64, 0x12},
225 {0x1C, 0xE3, 0x12},
226 {0x1D, 0x44, 0x13},
227 {0x1E, 0xC3, 0x13},
228 {0x1F, 0x24, 0x14},
229 {0x20, 0xA3, 0x14},
230 {0x21, 0x04, 0x15},
231 {0x22, 0x83, 0x15},
232 {0x23, 0xE3, 0x15},
233 {0x24, 0x43, 0x16},
234 {0x25, 0xA4, 0x16},
235 {0x26, 0x23, 0x17},
236 {0x27, 0x83, 0x17},
237 {0x28, 0xE3, 0x17},
238 {0x29, 0x43, 0x18},
239 {0x2A, 0xA3, 0x18},
240 {0x2B, 0x03, 0x19},
241 {0x2C, 0x63, 0x19},
242 {0x2D, 0xC3, 0x19},
243 {0x2E, 0x22, 0x1A},
244 {0x2F, 0x63, 0x1A},
245 {0x30, 0xC3, 0x1A},
246 {0x31, 0x23, 0x1B},
247 {0x32, 0x83, 0x1B},
248 {0x33, 0xE2, 0x1B},
249 {0x34, 0x23, 0x1C},
250 {0x35, 0x83, 0x1C},
251 {0x36, 0xE2, 0x1C},
252 {0x37, 0x23, 0x1D},
253 {0x38, 0x83, 0x1D},
254 {0x39, 0xE2, 0x1D},
255 {0x3A, 0x23, 0x1E},
256 {0x3B, 0x82, 0x1E},
257 {0x3C, 0xC3, 0x1E},
258 {0x3D, 0x22, 0x1F},
259 {0x3E, 0x63, 0x1F},
260 {0x3F, 0xC1, 0x1F},
261 {}
262};
263static void cx11646_fw(struct gspca_dev*gspca_dev)
264{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300265 int i = 0;
266
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300267 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300268 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300269 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300270 i++;
271 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300272 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300273}
274
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300275static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300276 0x88, 0x12, 0x70, 0x01,
277 0x88, 0x0d, 0x02, 0x01,
278 0x88, 0x0f, 0x00, 0x01,
279 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
280 0x88, 0x02, 0x10, 0x01,
281 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
282 0x88, 0x0B, 0x00, 0x01,
283 0x88, 0x0A, 0x0A, 0x01,
284 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
285 0x88, 0x05, 0x01, 0x01,
286 0xA1, 0x18, 0x00, 0x01,
287 0x00
288};
289
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300290static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
291static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
292static const __u8 reg10[] = { 0xb1, 0xb1 };
293static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
294static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300295 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300296static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300297 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300298static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
299static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300300
301static void cx_sensor(struct gspca_dev*gspca_dev)
302{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300303 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300304 int length;
305 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300306
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300307 reg_w(gspca_dev, 0x0020, reg20, 8);
308 reg_w(gspca_dev, 0x0028, reg28, 8);
309 reg_w(gspca_dev, 0x0010, reg10, 8);
310 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300311
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300312 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300313 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300314 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300315 break;
316 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300317 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300318 break;
319 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300320/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300321 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300322 break;
323 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300324 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300325 break;
326 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300327 reg_w(gspca_dev, 0x007b, reg7b, 6);
328 reg_w_val(gspca_dev, 0x00f8, 0x00);
329 reg_w(gspca_dev, 0x0010, reg10, 8);
330 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300331 for (i = 0; i < 11; i++) {
332 if (i == 3 || i == 5 || i == 8)
333 length = 8;
334 else
335 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300336 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300337 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300338 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300339 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300340 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300341 ptsensor += length;
342 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300343 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300344}
345
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300346static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300347 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
348 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
349 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
350 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
351 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
352 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
353 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
354};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300355static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
357 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
358 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
359 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
360 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
361 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
362 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
363};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300364static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300365 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
366 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
367 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
368 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
369 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
370 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
371 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
372};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300373static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300374 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
375 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
376 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
377 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
378 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
379 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
380 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
381};
382
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300383static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300384{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300385 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300386 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
387 static const __u8 reg17[] =
388 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
389
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300390 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300391 case 0:
392 cxinit = cx_inits_640;
393 break;
394 case 1:
395 cxinit = cx_inits_352;
396 break;
397 default:
398/* case 2: */
399 cxinit = cx_inits_320;
400 break;
401 case 3:
402 cxinit = cx_inits_176;
403 break;
404 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300405 reg_w_val(gspca_dev, 0x009a, 0x01);
406 reg_w_val(gspca_dev, 0x0010, 0x10);
407 reg_w(gspca_dev, 0x0012, reg12, 5);
408 reg_w(gspca_dev, 0x0017, reg17, 8);
409 reg_w_val(gspca_dev, 0x00c0, 0x00);
410 reg_w_val(gspca_dev, 0x00c1, 0x04);
411 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300412
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300413 reg_w(gspca_dev, 0x0061, 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, 0x00ca, 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, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300418 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300419 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300420 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300421 reg_w(gspca_dev, 0x0041, 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, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300424 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300425 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300426
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300427 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300428}
429
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300430static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300431 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
432 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
433 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
434 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
435 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
436 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
437 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
438 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
439 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
440 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
441 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
442 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
443 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
444 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
445 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
446 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
447 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
448 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
449 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
450 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
451 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
452 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
453 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
454 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
455 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
456 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
457 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
458 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
459 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
460 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
461 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
462 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
463 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
464 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
465 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
466 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
467 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
468 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
469 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
470 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
471 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
472 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
473 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
474 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
475 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
476 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
477 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
478 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
479 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
480 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
481 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
482 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
483 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
484 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
485 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
486 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
487 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
488 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
489 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
490 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
491 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
492 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
493 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
494 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
495 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
496 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
497 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
498 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
499 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
500 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
501 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
502 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
503 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
504 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
505 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
506 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
507 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
508 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
509 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
510};
511
512
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300513static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300514 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
515 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
516 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
517 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
518 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
519 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
520 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
521 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
522 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
523 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
524 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
525 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
526 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
527 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
528 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
529 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
530 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
531 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
532 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
533 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
534 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
535 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
536 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
537 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
538 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
539 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
540 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
541};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300542static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300543 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
544 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
545 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
546 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
547 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
548 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
549 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
550 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
551 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
552 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
553 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
554 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
555 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
556 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
557 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
558 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
559 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
560 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
561 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
562 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
563 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
564 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
565 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
566 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
567 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
568 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
569 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
570};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300571static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300572 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
573 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
574 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
575 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
576 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
577 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
578 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
579 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
580 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
581 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
582 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
583 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
584 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
585 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
586 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
587 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
588 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
589 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
590 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
591 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
592 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
593 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
594 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
595 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
596 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
597 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
598 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
599};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300600static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300601 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
602 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
603 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
604 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
605 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
606 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
607 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
608 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
609 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
610 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
611 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
612 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
613 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
614 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
615 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
616 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
617 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
618 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
619 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
620 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
621 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
622 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
623 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
624 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
625 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
626 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
627 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
628};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300629/* 640 take with the zcx30x part */
630static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300631 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
632 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
633 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
634 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
635 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
636 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
637 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
638 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
639 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
640 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
641 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 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 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
647 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
648 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
649};
650
651
652static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
653{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300654 int i;
655 int length;
656
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300657 reg_w_val(gspca_dev, 0x00c0, 0x01);
658 reg_w_val(gspca_dev, 0x00c3, 0x00);
659 reg_w_val(gspca_dev, 0x00c0, 0x00);
660 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300661 length = 8;
662 for (i = 0; i < 79; i++) {
663 if (i == 78)
664 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300665 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300666 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300667 reg_r(gspca_dev, 0x0002, 1);
668 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300669}
670
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300671static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
672static const __u8 regE5_8[] =
673 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
674static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
675static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
676static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
677static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300678#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300679
680static void cx11646_jpeg(struct gspca_dev*gspca_dev)
681{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300682 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300683 int length;
684 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300685 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300687 reg_w_val(gspca_dev, 0x00c0, 0x01);
688 reg_w_val(gspca_dev, 0x00c3, 0x00);
689 reg_w_val(gspca_dev, 0x00c0, 0x00);
690 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300691 length = 8;
Jean-François Moine780e3122010-10-19 04:29:10 -0300692 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300693 case 0:
694 for (i = 0; i < 27; i++) {
695 if (i == 26)
696 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300697 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300698 }
699 Reg55 = 0x28;
700 break;
701 case 1:
702 for (i = 0; i < 27; i++) {
703 if (i == 26)
704 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300705 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300706 }
707 Reg55 = 0x16;
708 break;
709 default:
710/* case 2: */
711 for (i = 0; i < 27; i++) {
712 if (i == 26)
713 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300714 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300715 }
716 Reg55 = 0x14;
717 break;
718 case 3:
719 for (i = 0; i < 27; i++) {
720 if (i == 26)
721 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300722 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300723 }
724 Reg55 = 0x0B;
725 break;
726 }
727
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300728 reg_r(gspca_dev, 0x0002, 1);
729 reg_w_val(gspca_dev, 0x0055, Reg55);
730 reg_r(gspca_dev, 0x0002, 1);
731 reg_w(gspca_dev, 0x0010, reg10, 2);
732 reg_w_val(gspca_dev, 0x0054, 0x02);
733 reg_w_val(gspca_dev, 0x0054, 0x01);
734 reg_w_val(gspca_dev, 0x0000, 0x94);
735 reg_w_val(gspca_dev, 0x0053, 0xc0);
736 reg_w_val(gspca_dev, 0x00fc, 0xe1);
737 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300738 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300739 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300740 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300741 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300742 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300743 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300744 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300745 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300746 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300747 if (retry == 0)
748 PDEBUG(D_ERR, "Damned Errors sending jpeg Table");
749 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300750 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300751 length = 8;
752 for (i = 0; i < 18; i++) {
753 if (i == 17)
754 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300755 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300756
757 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300758 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
759 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
760 reg_w_val(gspca_dev, 0x0054, 0x02);
761 reg_w_val(gspca_dev, 0x0054, 0x01);
762 reg_w_val(gspca_dev, 0x0000, 0x94);
763 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300764
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300765 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
766 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
767 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
768 reg_w(gspca_dev, 0x0012, reg12, 5);
769 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
770 reg_r(gspca_dev, 0x00e8, 8);
771 reg_w(gspca_dev, 0x00e5, regE5a, 4);
772 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
773 reg_w_val(gspca_dev, 0x009a, 0x01);
774 reg_w(gspca_dev, 0x00e5, regE5b, 4);
775 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
776 reg_w(gspca_dev, 0x00e5, regE5c, 4);
777 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300778
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300779 reg_w(gspca_dev, 0x0051, reg51, 2);
780 reg_w(gspca_dev, 0x0010, reg10, 2);
781 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300782}
783
784static void cx11646_init1(struct gspca_dev *gspca_dev)
785{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300786 int i = 0;
787
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300788 reg_w_val(gspca_dev, 0x0010, 0x00);
789 reg_w_val(gspca_dev, 0x0053, 0x00);
790 reg_w_val(gspca_dev, 0x0052, 0x00);
791 reg_w_val(gspca_dev, 0x009b, 0x2f);
792 reg_w_val(gspca_dev, 0x009c, 0x10);
793 reg_r(gspca_dev, 0x0098, 1);
794 reg_w_val(gspca_dev, 0x0098, 0x40);
795 reg_r(gspca_dev, 0x0099, 1);
796 reg_w_val(gspca_dev, 0x0099, 0x07);
797 reg_w_val(gspca_dev, 0x0039, 0x40);
798 reg_w_val(gspca_dev, 0x003c, 0xff);
799 reg_w_val(gspca_dev, 0x003f, 0x1f);
800 reg_w_val(gspca_dev, 0x003d, 0x40);
801/* reg_w_val(gspca_dev, 0x003d, 0x60); */
802 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300803
804 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300805 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
806 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300807 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300808 reg_w_val(gspca_dev, 0x00ed, 0x01);
809 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300810 }
811 i++;
812 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300813 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300814}
815
816/* this function is called at probe time */
817static int sd_config(struct gspca_dev *gspca_dev,
818 const struct usb_device_id *id)
819{
820 struct sd *sd = (struct sd *) gspca_dev;
821 struct cam *cam;
822
823 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300824 cam->cam_mode = vga_mode;
Mauro Carvalho Chehabd6f76b92009-07-22 00:02:29 -0300825 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300826
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300827 sd->brightness = BRIGHTNESS_DEF;
828 sd->contrast = CONTRAST_DEF;
829 sd->colors = COLOR_DEF;
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -0300830 sd->quality = QUALITY_DEF;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300831 return 0;
832}
833
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300834/* this function is called at probe and resume time */
835static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300836{
837 cx11646_init1(gspca_dev);
838 cx11646_initsize(gspca_dev);
839 cx11646_fw(gspca_dev);
840 cx_sensor(gspca_dev);
841 cx11646_jpegInit(gspca_dev);
842 return 0;
843}
844
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300845static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300846{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300847 struct sd *sd = (struct sd *) gspca_dev;
848
849 /* create the JPEG header */
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300850 jpeg_define(sd->jpeg_hdr, gspca_dev->height, gspca_dev->width,
851 0x22); /* JPEG 411 */
852 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
853
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300854 cx11646_initsize(gspca_dev);
855 cx11646_fw(gspca_dev);
856 cx_sensor(gspca_dev);
857 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300858 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300859}
860
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300861/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300862static void sd_stop0(struct gspca_dev *gspca_dev)
863{
864 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300865
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300866 if (!gspca_dev->present)
867 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300868 reg_w_val(gspca_dev, 0x0000, 0x00);
869 reg_r(gspca_dev, 0x0002, 1);
870 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300871
872 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300873/* reg_r(gspca_dev, 0x0002, 1);*/
874 reg_r(gspca_dev, 0x0053, 1);
875 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300876 break;
877 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300878 reg_w_val(gspca_dev, 0x0000, 0x00);
879 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300880
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300881 reg_w_val(gspca_dev, 0x0010, 0x00);
882 reg_r(gspca_dev, 0x0033, 1);
883 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300884}
885
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300886static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300887 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300888 int len) /* iso packet length */
889{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300890 struct sd *sd = (struct sd *) gspca_dev;
891
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300892 if (data[0] == 0xff && data[1] == 0xd8) {
893
894 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300895 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300896
897 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300898 gspca_frame_add(gspca_dev, FIRST_PACKET,
899 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300900 data += 2;
901 len -= 2;
902 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300903 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300904}
905
Jean-François Moine780e3122010-10-19 04:29:10 -0300906static void setbrightness(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300907{
908 struct sd *sd = (struct sd *) gspca_dev;
909 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300910 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300911 __u8 bright;
912 __u8 colors;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300913
914 bright = sd->brightness;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300915 regE5cbx[2] = bright;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300916 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
917 reg_r(gspca_dev, 0x00e8, 8);
918 reg_w(gspca_dev, 0x00e5, regE5c, 4);
919 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300920
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300921 colors = sd->colors;
922 reg51c[0] = 0x77;
923 reg51c[1] = colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300924 reg_w(gspca_dev, 0x0051, reg51c, 2);
925 reg_w(gspca_dev, 0x0010, reg10, 2);
926 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300927}
928
Jean-François Moine780e3122010-10-19 04:29:10 -0300929static void setcontrast(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300930{
931 struct sd *sd = (struct sd *) gspca_dev;
932 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300933/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
934 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300935
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300936 regE5acx[2] = sd->contrast;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300937 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
938 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300939 reg51c[0] = 0x77;
940 reg51c[1] = sd->colors;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300941 reg_w(gspca_dev, 0x0051, reg51c, 2);
942 reg_w(gspca_dev, 0x0010, reg10, 2);
943 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300944}
945
946static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
947{
948 struct sd *sd = (struct sd *) gspca_dev;
949
950 sd->brightness = val;
951 if (gspca_dev->streaming)
952 setbrightness(gspca_dev);
953 return 0;
954}
955
956static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
957{
958 struct sd *sd = (struct sd *) gspca_dev;
959
960 *val = sd->brightness;
961 return 0;
962}
963
964static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
965{
966 struct sd *sd = (struct sd *) gspca_dev;
967
968 sd->contrast = val;
969 if (gspca_dev->streaming)
970 setcontrast(gspca_dev);
971 return 0;
972}
973
974static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
975{
976 struct sd *sd = (struct sd *) gspca_dev;
977
978 *val = sd->contrast;
979 return 0;
980}
981
982static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
983{
984 struct sd *sd = (struct sd *) gspca_dev;
985
986 sd->colors = val;
987 if (gspca_dev->streaming) {
988 setbrightness(gspca_dev);
989 setcontrast(gspca_dev);
990 }
991 return 0;
992}
993
994static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
995{
996 struct sd *sd = (struct sd *) gspca_dev;
997
998 *val = sd->colors;
999 return 0;
1000}
1001
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001002static int sd_set_jcomp(struct gspca_dev *gspca_dev,
1003 struct v4l2_jpegcompression *jcomp)
1004{
1005 struct sd *sd = (struct sd *) gspca_dev;
1006
1007 if (jcomp->quality < QUALITY_MIN)
1008 sd->quality = QUALITY_MIN;
1009 else if (jcomp->quality > QUALITY_MAX)
1010 sd->quality = QUALITY_MAX;
1011 else
1012 sd->quality = jcomp->quality;
1013 if (gspca_dev->streaming)
1014 jpeg_set_qual(sd->jpeg_hdr, sd->quality);
1015 return 0;
1016}
1017
1018static int sd_get_jcomp(struct gspca_dev *gspca_dev,
1019 struct v4l2_jpegcompression *jcomp)
1020{
1021 struct sd *sd = (struct sd *) gspca_dev;
1022
1023 memset(jcomp, 0, sizeof *jcomp);
1024 jcomp->quality = sd->quality;
1025 jcomp->jpeg_markers = V4L2_JPEG_MARKER_DHT
1026 | V4L2_JPEG_MARKER_DQT;
1027 return 0;
1028}
1029
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001030/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -03001031static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001032 .name = MODULE_NAME,
1033 .ctrls = sd_ctrls,
1034 .nctrls = ARRAY_SIZE(sd_ctrls),
1035 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -03001036 .init = sd_init,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001037 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001038 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001039 .pkt_scan = sd_pkt_scan,
Jean-Francois Moine77ac0ba2009-03-02 06:40:52 -03001040 .get_jcomp = sd_get_jcomp,
1041 .set_jcomp = sd_set_jcomp,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001042};
1043
1044/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03001045static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -03001046 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001047 {}
1048};
1049MODULE_DEVICE_TABLE(usb, device_table);
1050
1051/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -03001052static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001053 const struct usb_device_id *id)
1054{
1055 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
1056 THIS_MODULE);
1057}
1058
1059static struct usb_driver sd_driver = {
1060 .name = MODULE_NAME,
1061 .id_table = device_table,
1062 .probe = sd_probe,
1063 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -03001064#ifdef CONFIG_PM
1065 .suspend = gspca_suspend,
1066 .resume = gspca_resume,
1067#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001068};
1069
1070/* -- module insert / remove -- */
1071static int __init sd_mod_init(void)
1072{
Jean-François Moine54826432010-09-13 04:53:03 -03001073 return usb_register(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001074}
1075static void __exit sd_mod_exit(void)
1076{
1077 usb_deregister(&sd_driver);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03001078}
1079
1080module_init(sd_mod_init);
1081module_exit(sd_mod_exit);