blob: 8b2691243f8a3501e9a9d60b7ba0646fd0f79351 [file] [log] [blame]
Thomas Gleixnerfd9871f2019-05-19 15:51:54 +02001// SPDX-License-Identifier: GPL-2.0-or-later
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03002/*
3 * Connexant Cx11646 library
4 * Copyright (C) 2004 Michel Xhaard mxhaard@magic.fr
5 *
6 * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -03007 */
8
Joe Perches133a9fe2011-08-21 19:56:57 -03009#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030011#define MODULE_NAME "conex"
12
13#include "gspca.h"
14#define CONEX_CAM 1 /* special JPEG header */
15#include "jpeg.h"
16
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030017MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
18MODULE_DESCRIPTION("GSPCA USB Conexant Camera Driver");
19MODULE_LICENSE("GPL");
20
Hans de Goedeb56ab4c2012-06-27 16:48:33 -030021#define QUALITY 50
Jean-Francois Moine71cb2762009-03-03 05:33:41 -030022
Hans Verkuilcbc1c942012-05-14 04:09:17 -030023/* specific webcam descriptor */
24struct sd {
25 struct gspca_dev gspca_dev; /* !! must be the first item */
26 struct v4l2_ctrl *brightness;
27 struct v4l2_ctrl *contrast;
28 struct v4l2_ctrl *sat;
Hans Verkuilcbc1c942012-05-14 04:09:17 -030029
Jean-François Moine9a731a32010-06-04 05:26:42 -030030 u8 jpeg_hdr[JPEG_HDR_SZ];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030031};
32
Jean-Francois Moinecc611b82008-12-29 07:49:41 -030033static const struct v4l2_pix_format vga_mode[] = {
Jean-Francois Moinec2446b32008-07-05 11:49:20 -030034 {176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
35 .bytesperline = 176,
36 .sizeimage = 176 * 144 * 3 / 8 + 590,
37 .colorspace = V4L2_COLORSPACE_JPEG,
38 .priv = 3},
39 {320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
40 .bytesperline = 320,
41 .sizeimage = 320 * 240 * 3 / 8 + 590,
42 .colorspace = V4L2_COLORSPACE_JPEG,
43 .priv = 2},
44 {352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
45 .bytesperline = 352,
46 .sizeimage = 352 * 288 * 3 / 8 + 590,
47 .colorspace = V4L2_COLORSPACE_JPEG,
48 .priv = 1},
49 {640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
50 .bytesperline = 640,
51 .sizeimage = 640 * 480 * 3 / 8 + 590,
52 .colorspace = V4L2_COLORSPACE_JPEG,
53 .priv = 0},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030054};
55
Jean-Francois Moine739570b2008-07-14 09:38:29 -030056/* the read bytes are found in gspca_dev->usb_buf */
57static void reg_r(struct gspca_dev *gspca_dev,
58 __u16 index,
59 __u16 len)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030060{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030061 struct usb_device *dev = gspca_dev->dev;
62
Jean-Francois Moine8295d992008-09-03 17:12:19 -030063 if (len > USB_BUF_SZ) {
Joe Perches52173c5f2017-09-22 14:33:35 -040064 gspca_err(gspca_dev, "reg_r: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -030065 return;
66 }
Theodore Kilgorec93396e2013-02-04 13:17:55 -030067
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030068 usb_control_msg(dev,
69 usb_rcvctrlpipe(dev, 0),
70 0,
71 USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
72 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -030073 index, gspca_dev->usb_buf, len,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030074 500);
Joe Perches37d5efb2017-09-22 15:20:33 -040075 gspca_dbg(gspca_dev, D_USBI, "reg read [%02x] -> %02x ..\n",
76 index, gspca_dev->usb_buf[0]);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030077}
78
Jean-Francois Moine739570b2008-07-14 09:38:29 -030079/* the bytes to write are in gspca_dev->usb_buf */
80static void reg_w_val(struct gspca_dev *gspca_dev,
81 __u16 index,
82 __u8 val)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030083{
Jean-Francois Moine739570b2008-07-14 09:38:29 -030084 struct usb_device *dev = gspca_dev->dev;
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -030085
Jean-Francois Moine739570b2008-07-14 09:38:29 -030086 gspca_dev->usb_buf[0] = val;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -030087 usb_control_msg(dev,
88 usb_sndctrlpipe(dev, 0),
89 0,
90 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
91 0,
Jean-Francois Moine739570b2008-07-14 09:38:29 -030092 index, gspca_dev->usb_buf, 1, 500);
93}
94
95static void reg_w(struct gspca_dev *gspca_dev,
96 __u16 index,
97 const __u8 *buffer,
98 __u16 len)
99{
100 struct usb_device *dev = gspca_dev->dev;
101
Jean-Francois Moine8295d992008-09-03 17:12:19 -0300102 if (len > USB_BUF_SZ) {
Joe Perches52173c5f2017-09-22 14:33:35 -0400103 gspca_err(gspca_dev, "reg_w: buffer overflow\n");
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300104 return;
105 }
Joe Perches37d5efb2017-09-22 15:20:33 -0400106 gspca_dbg(gspca_dev, D_USBO, "reg write [%02x] = %02x..\n",
107 index, *buffer);
Theodore Kilgorec93396e2013-02-04 13:17:55 -0300108
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300109 memcpy(gspca_dev->usb_buf, buffer, len);
110 usb_control_msg(dev,
111 usb_sndctrlpipe(dev, 0),
112 0,
113 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
114 0,
115 index, gspca_dev->usb_buf, len, 500);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300116}
117
118static const __u8 cx_sensor_init[][4] = {
119 {0x88, 0x11, 0x01, 0x01},
120 {0x88, 0x12, 0x70, 0x01},
121 {0x88, 0x0f, 0x00, 0x01},
122 {0x88, 0x05, 0x01, 0x01},
123 {}
124};
125
126static const __u8 cx11646_fw1[][3] = {
127 {0x00, 0x02, 0x00},
128 {0x01, 0x43, 0x00},
129 {0x02, 0xA7, 0x00},
130 {0x03, 0x8B, 0x01},
131 {0x04, 0xE9, 0x02},
132 {0x05, 0x08, 0x04},
133 {0x06, 0x08, 0x05},
134 {0x07, 0x07, 0x06},
135 {0x08, 0xE7, 0x06},
136 {0x09, 0xC6, 0x07},
137 {0x0A, 0x86, 0x08},
138 {0x0B, 0x46, 0x09},
139 {0x0C, 0x05, 0x0A},
140 {0x0D, 0xA5, 0x0A},
141 {0x0E, 0x45, 0x0B},
142 {0x0F, 0xE5, 0x0B},
143 {0x10, 0x85, 0x0C},
144 {0x11, 0x25, 0x0D},
145 {0x12, 0xC4, 0x0D},
146 {0x13, 0x45, 0x0E},
147 {0x14, 0xE4, 0x0E},
148 {0x15, 0x64, 0x0F},
149 {0x16, 0xE4, 0x0F},
150 {0x17, 0x64, 0x10},
151 {0x18, 0xE4, 0x10},
152 {0x19, 0x64, 0x11},
153 {0x1A, 0xE4, 0x11},
154 {0x1B, 0x64, 0x12},
155 {0x1C, 0xE3, 0x12},
156 {0x1D, 0x44, 0x13},
157 {0x1E, 0xC3, 0x13},
158 {0x1F, 0x24, 0x14},
159 {0x20, 0xA3, 0x14},
160 {0x21, 0x04, 0x15},
161 {0x22, 0x83, 0x15},
162 {0x23, 0xE3, 0x15},
163 {0x24, 0x43, 0x16},
164 {0x25, 0xA4, 0x16},
165 {0x26, 0x23, 0x17},
166 {0x27, 0x83, 0x17},
167 {0x28, 0xE3, 0x17},
168 {0x29, 0x43, 0x18},
169 {0x2A, 0xA3, 0x18},
170 {0x2B, 0x03, 0x19},
171 {0x2C, 0x63, 0x19},
172 {0x2D, 0xC3, 0x19},
173 {0x2E, 0x22, 0x1A},
174 {0x2F, 0x63, 0x1A},
175 {0x30, 0xC3, 0x1A},
176 {0x31, 0x23, 0x1B},
177 {0x32, 0x83, 0x1B},
178 {0x33, 0xE2, 0x1B},
179 {0x34, 0x23, 0x1C},
180 {0x35, 0x83, 0x1C},
181 {0x36, 0xE2, 0x1C},
182 {0x37, 0x23, 0x1D},
183 {0x38, 0x83, 0x1D},
184 {0x39, 0xE2, 0x1D},
185 {0x3A, 0x23, 0x1E},
186 {0x3B, 0x82, 0x1E},
187 {0x3C, 0xC3, 0x1E},
188 {0x3D, 0x22, 0x1F},
189 {0x3E, 0x63, 0x1F},
190 {0x3F, 0xC1, 0x1F},
191 {}
192};
193static void cx11646_fw(struct gspca_dev*gspca_dev)
194{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300195 int i = 0;
196
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300197 reg_w_val(gspca_dev, 0x006a, 0x02);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300198 while (cx11646_fw1[i][1]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300199 reg_w(gspca_dev, 0x006b, cx11646_fw1[i], 3);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300200 i++;
201 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300202 reg_w_val(gspca_dev, 0x006a, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300203}
204
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300205static const __u8 cxsensor[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300206 0x88, 0x12, 0x70, 0x01,
207 0x88, 0x0d, 0x02, 0x01,
208 0x88, 0x0f, 0x00, 0x01,
209 0x88, 0x03, 0x71, 0x01, 0x88, 0x04, 0x00, 0x01, /* 3 */
210 0x88, 0x02, 0x10, 0x01,
211 0x88, 0x00, 0xD4, 0x01, 0x88, 0x01, 0x01, 0x01, /* 5 */
212 0x88, 0x0B, 0x00, 0x01,
213 0x88, 0x0A, 0x0A, 0x01,
214 0x88, 0x00, 0x08, 0x01, 0x88, 0x01, 0x00, 0x01, /* 8 */
215 0x88, 0x05, 0x01, 0x01,
216 0xA1, 0x18, 0x00, 0x01,
217 0x00
218};
219
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300220static const __u8 reg20[] = { 0x10, 0x42, 0x81, 0x19, 0xd3, 0xff, 0xa7, 0xff };
221static const __u8 reg28[] = { 0x87, 0x00, 0x87, 0x00, 0x8f, 0xff, 0xea, 0xff };
222static const __u8 reg10[] = { 0xb1, 0xb1 };
223static const __u8 reg71a[] = { 0x08, 0x18, 0x0a, 0x1e }; /* 640 */
224static const __u8 reg71b[] = { 0x04, 0x0c, 0x05, 0x0f };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300225 /* 352{0x04,0x0a,0x06,0x12}; //352{0x05,0x0e,0x06,0x11}; //352 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300226static const __u8 reg71c[] = { 0x02, 0x07, 0x03, 0x09 };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300227 /* 320{0x04,0x0c,0x05,0x0f}; //320 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300228static const __u8 reg71d[] = { 0x02, 0x07, 0x03, 0x09 }; /* 176 */
229static const __u8 reg7b[] = { 0x00, 0xff, 0x00, 0xff, 0x00, 0xff };
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300230
231static void cx_sensor(struct gspca_dev*gspca_dev)
232{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300233 int i = 0;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300234 int length;
235 const __u8 *ptsensor = cxsensor;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300236
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300237 reg_w(gspca_dev, 0x0020, reg20, 8);
238 reg_w(gspca_dev, 0x0028, reg28, 8);
Dan Carpenterb1890002012-05-02 02:15:25 -0300239 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300240 reg_w_val(gspca_dev, 0x0092, 0x03);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300241
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300242 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300243 case 0:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300244 reg_w(gspca_dev, 0x0071, reg71a, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300245 break;
246 case 1:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300247 reg_w(gspca_dev, 0x0071, reg71b, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300248 break;
249 default:
Jean-Francois Moinebf7f0b92008-07-03 11:09:12 -0300250/* case 2: */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300251 reg_w(gspca_dev, 0x0071, reg71c, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300252 break;
253 case 3:
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300254 reg_w(gspca_dev, 0x0071, reg71d, 4);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300255 break;
256 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300257 reg_w(gspca_dev, 0x007b, reg7b, 6);
258 reg_w_val(gspca_dev, 0x00f8, 0x00);
Dan Carpenterb1890002012-05-02 02:15:25 -0300259 reg_w(gspca_dev, 0x0010, reg10, 2);
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300260 reg_w_val(gspca_dev, 0x0098, 0x41);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300261 for (i = 0; i < 11; i++) {
262 if (i == 3 || i == 5 || i == 8)
263 length = 8;
264 else
265 length = 4;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300266 reg_w(gspca_dev, 0x00e5, ptsensor, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300267 if (length == 4)
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300268 reg_r(gspca_dev, 0x00e8, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300269 else
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300270 reg_r(gspca_dev, 0x00e8, length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300271 ptsensor += length;
272 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300273 reg_r(gspca_dev, 0x00e7, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300274}
275
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300276static const __u8 cx_inits_176[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300277 0x33, 0x81, 0xB0, 0x00, 0x90, 0x00, 0x0A, 0x03, /* 176x144 */
278 0x00, 0x03, 0x03, 0x03, 0x1B, 0x05, 0x30, 0x03,
279 0x65, 0x15, 0x18, 0x25, 0x03, 0x25, 0x08, 0x30,
280 0x3B, 0x25, 0x10, 0x00, 0x04, 0x00, 0x00, 0x00,
281 0xDC, 0xFF, 0xEE, 0xFF, 0xC5, 0xFF, 0xBF, 0xFF,
282 0xF7, 0xFF, 0x88, 0xFF, 0x66, 0x02, 0x28, 0x02,
283 0x1E, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
284};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300285static const __u8 cx_inits_320[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300286 0x7f, 0x7f, 0x40, 0x01, 0xf0, 0x00, 0x02, 0x01,
287 0x00, 0x01, 0x01, 0x01, 0x10, 0x00, 0x02, 0x01,
288 0x65, 0x45, 0xfa, 0x4c, 0x2c, 0xdf, 0xb9, 0x81,
289 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
290 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
291 0xf5, 0xff, 0x6d, 0xff, 0xf6, 0x01, 0x43, 0x02,
292 0xd3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
293};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300294static const __u8 cx_inits_352[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300295 0x2e, 0x7c, 0x60, 0x01, 0x20, 0x01, 0x05, 0x03,
296 0x00, 0x06, 0x03, 0x06, 0x1b, 0x10, 0x05, 0x3b,
297 0x30, 0x25, 0x18, 0x25, 0x08, 0x30, 0x03, 0x25,
298 0x3b, 0x30, 0x25, 0x1b, 0x10, 0x05, 0x00, 0x00,
299 0xe3, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
300 0xf5, 0xff, 0x6b, 0xff, 0xee, 0x01, 0x43, 0x02,
301 0xe4, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
302};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300303static const __u8 cx_inits_640[] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300304 0x7e, 0x7e, 0x80, 0x02, 0xe0, 0x01, 0x01, 0x01,
305 0x00, 0x02, 0x01, 0x02, 0x10, 0x30, 0x01, 0x01,
306 0x65, 0x45, 0xf7, 0x52, 0x2c, 0xdf, 0xb9, 0x81,
307 0x30, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
308 0xe2, 0xff, 0xf1, 0xff, 0xc2, 0xff, 0xbc, 0xff,
309 0xf6, 0xff, 0x7b, 0xff, 0x01, 0x02, 0x43, 0x02,
310 0x77, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
311};
312
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300313static void cx11646_initsize(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300314{
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300315 const __u8 *cxinit;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300316 static const __u8 reg12[] = { 0x08, 0x05, 0x07, 0x04, 0x24 };
317 static const __u8 reg17[] =
318 { 0x0a, 0x00, 0xf2, 0x01, 0x0f, 0x00, 0x97, 0x02 };
319
Jean-Francois Moinec2446b32008-07-05 11:49:20 -0300320 switch (gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300321 case 0:
322 cxinit = cx_inits_640;
323 break;
324 case 1:
325 cxinit = cx_inits_352;
326 break;
327 default:
328/* case 2: */
329 cxinit = cx_inits_320;
330 break;
331 case 3:
332 cxinit = cx_inits_176;
333 break;
334 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300335 reg_w_val(gspca_dev, 0x009a, 0x01);
336 reg_w_val(gspca_dev, 0x0010, 0x10);
337 reg_w(gspca_dev, 0x0012, reg12, 5);
338 reg_w(gspca_dev, 0x0017, reg17, 8);
339 reg_w_val(gspca_dev, 0x00c0, 0x00);
340 reg_w_val(gspca_dev, 0x00c1, 0x04);
341 reg_w_val(gspca_dev, 0x00c2, 0x04);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300342
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300343 reg_w(gspca_dev, 0x0061, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300344 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300345 reg_w(gspca_dev, 0x00ca, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300346 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300347 reg_w(gspca_dev, 0x00d2, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300348 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300349 reg_w(gspca_dev, 0x00da, cxinit, 6);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300350 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300351 reg_w(gspca_dev, 0x0041, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300352 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300353 reg_w(gspca_dev, 0x0049, cxinit, 8);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300354 cxinit += 8;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300355 reg_w(gspca_dev, 0x0051, cxinit, 2);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300356
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300357 reg_r(gspca_dev, 0x0010, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300358}
359
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300360static const __u8 cx_jpeg_init[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300361 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x15}, /* 1 */
362 {0x0f, 0x10, 0x12, 0x10, 0x0d, 0x15, 0x12, 0x11},
363 {0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35, 0x22},
364 {0x20, 0x1d, 0x1d, 0x20, 0x41, 0x2e, 0x31, 0x26},
365 {0x35, 0x4d, 0x43, 0x51, 0x4f, 0x4b, 0x43, 0x4a},
366 {0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A, 0x73},
367 {0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73, 0x7D},
368 {0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95, 0xA0},
369 {0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83, 0x01},
370 {0x15, 0x0F, 0x10, 0x12, 0x10, 0x0D, 0x15, 0x12},
371 {0x11, 0x12, 0x18, 0x16, 0x15, 0x19, 0x20, 0x35},
372 {0x22, 0x20, 0x1D, 0x1D, 0x20, 0x41, 0x2E, 0x31},
373 {0x26, 0x35, 0x4D, 0x43, 0x51, 0x4F, 0x4B, 0x43},
374 {0x4A, 0x49, 0x55, 0x5F, 0x79, 0x67, 0x55, 0x5A},
375 {0x73, 0x5B, 0x49, 0x4A, 0x6A, 0x90, 0x6B, 0x73},
376 {0x7D, 0x81, 0x88, 0x89, 0x88, 0x52, 0x66, 0x95},
377 {0xA0, 0x94, 0x84, 0x9E, 0x79, 0x85, 0x88, 0x83},
378 {0xFF, 0xC4, 0x01, 0xA2, 0x00, 0x00, 0x01, 0x05},
379 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00},
380 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02},
381 {0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A},
382 {0x0B, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01},
383 {0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00},
384 {0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05},
385 {0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x10, 0x00},
386 {0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05},
387 {0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7D, 0x01},
388 {0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21},
389 {0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22},
390 {0x71, 0x14, 0x32, 0x81, 0x91, 0xA1, 0x08, 0x23},
391 {0x42, 0xB1, 0xC1, 0x15, 0x52, 0xD1, 0xF0, 0x24},
392 {0x33, 0x62, 0x72, 0x82, 0x09, 0x0A, 0x16, 0x17},
393 {0x18, 0x19, 0x1A, 0x25, 0x26, 0x27, 0x28, 0x29},
394 {0x2A, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A},
395 {0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A},
396 {0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A},
397 {0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A},
398 {0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A},
399 {0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A},
400 {0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99},
401 {0x9A, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8},
402 {0xA9, 0xAA, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7},
403 {0xB8, 0xB9, 0xBA, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6},
404 {0xC7, 0xC8, 0xC9, 0xCA, 0xD2, 0xD3, 0xD4, 0xD5},
405 {0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xE1, 0xE2, 0xE3},
406 {0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xF1},
407 {0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9},
408 {0xFA, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04},
409 {0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, 0x01},
410 {0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04},
411 {0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07},
412 {0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, 0x14},
413 {0x42, 0x91, 0xA1, 0xB1, 0xC1, 0x09, 0x23, 0x33},
414 {0x52, 0xF0, 0x15, 0x62, 0x72, 0xD1, 0x0A, 0x16},
415 {0x24, 0x34, 0xE1, 0x25, 0xF1, 0x17, 0x18, 0x19},
416 {0x1A, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x35, 0x36},
417 {0x37, 0x38, 0x39, 0x3A, 0x43, 0x44, 0x45, 0x46},
418 {0x47, 0x48, 0x49, 0x4A, 0x53, 0x54, 0x55, 0x56},
419 {0x57, 0x58, 0x59, 0x5A, 0x63, 0x64, 0x65, 0x66},
420 {0x67, 0x68, 0x69, 0x6A, 0x73, 0x74, 0x75, 0x76},
421 {0x77, 0x78, 0x79, 0x7A, 0x82, 0x83, 0x84, 0x85},
422 {0x86, 0x87, 0x88, 0x89, 0x8A, 0x92, 0x93, 0x94},
423 {0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0xA2, 0xA3},
424 {0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xB2},
425 {0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA},
426 {0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9},
427 {0xCA, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8},
428 {0xD9, 0xDA, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7},
429 {0xE8, 0xE9, 0xEA, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6},
430 {0xF7, 0xF8, 0xF9, 0xFA, 0xFF, 0x20, 0x00, 0x1F},
431 {0x02, 0x0C, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00},
432 {0x00, 0x00, 0x11, 0x00, 0x11, 0x22, 0x00, 0x22},
433 {0x22, 0x11, 0x22, 0x22, 0x11, 0x33, 0x33, 0x11},
434 {0x44, 0x66, 0x22, 0x55, 0x66, 0xFF, 0xDD, 0x00},
435 {0x04, 0x00, 0x14, 0xFF, 0xC0, 0x00, 0x11, 0x08},
436 {0x00, 0xF0, 0x01, 0x40, 0x03, 0x00, 0x21, 0x00},
437 {0x01, 0x11, 0x01, 0x02, 0x11, 0x01, 0xFF, 0xDA},
438 {0x00, 0x0C, 0x03, 0x00, 0x00, 0x01, 0x11, 0x02},
439 {0x11, 0x00, 0x3F, 0x00, 0xFF, 0xD9, 0x00, 0x00} /* 79 */
440};
441
442
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300443static const __u8 cxjpeg_640[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300444 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x10}, /* 1 */
445 {0x0b, 0x0c, 0x0e, 0x0c, 0x0a, 0x10, 0x0e, 0x0d},
446 {0x0e, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28, 0x1a},
447 {0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25, 0x1d},
448 {0x28, 0x3a, 0x33, 0x3D, 0x3C, 0x39, 0x33, 0x38},
449 {0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44, 0x57},
450 {0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57, 0x5F},
451 {0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71, 0x79},
452 {0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63, 0x01},
453 {0x10, 0x0B, 0x0C, 0x0E, 0x0C, 0x0A, 0x10, 0x0E},
454 {0x0D, 0x0E, 0x12, 0x11, 0x10, 0x13, 0x18, 0x28},
455 {0x1A, 0x18, 0x16, 0x16, 0x18, 0x31, 0x23, 0x25},
456 {0x1D, 0x28, 0x3A, 0x33, 0x3D, 0x3C, 0x39, 0x33},
457 {0x38, 0x37, 0x40, 0x48, 0x5C, 0x4E, 0x40, 0x44},
458 {0x57, 0x45, 0x37, 0x38, 0x50, 0x6D, 0x51, 0x57},
459 {0x5F, 0x62, 0x67, 0x68, 0x67, 0x3E, 0x4D, 0x71},
460 {0x79, 0x70, 0x64, 0x78, 0x5C, 0x65, 0x67, 0x63},
461 {0xFF, 0x20, 0x00, 0x1F, 0x00, 0x83, 0x00, 0x00},
462 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
463 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
464 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
465 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x28, 0xFF},
466 {0xC0, 0x00, 0x11, 0x08, 0x01, 0xE0, 0x02, 0x80},
467 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
468 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
469 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
470 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
471};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300472static const __u8 cxjpeg_352[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300473 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
474 {0x09, 0x09, 0x0b, 0x09, 0x08, 0x0D, 0x0b, 0x0a},
475 {0x0b, 0x0e, 0x0d, 0x0d, 0x0f, 0x13, 0x1f, 0x14},
476 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1b, 0x1d, 0x17},
477 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
478 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
479 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
480 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
481 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
482 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
483 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
484 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
485 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
486 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
487 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
488 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
489 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
490 {0xFF, 0x20, 0x00, 0x1F, 0x01, 0x83, 0x00, 0x00},
491 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
492 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
493 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
494 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x16, 0xFF},
495 {0xC0, 0x00, 0x11, 0x08, 0x01, 0x20, 0x01, 0x60},
496 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
497 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
498 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
499 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
500};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300501static const __u8 cxjpeg_320[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300502 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x05},
503 {0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04, 0x04},
504 {0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0c, 0x08},
505 {0x07, 0x07, 0x07, 0x07, 0x0f, 0x0b, 0x0b, 0x09},
506 {0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0f, 0x11},
507 {0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14, 0x1A},
508 {0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A, 0x1D},
509 {0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22, 0x24},
510 {0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E, 0x01},
511 {0x05, 0x03, 0x04, 0x04, 0x04, 0x03, 0x05, 0x04},
512 {0x04, 0x04, 0x05, 0x05, 0x05, 0x06, 0x07, 0x0C},
513 {0x08, 0x07, 0x07, 0x07, 0x07, 0x0F, 0x0B, 0x0B},
514 {0x09, 0x0C, 0x11, 0x0F, 0x12, 0x12, 0x11, 0x0F},
515 {0x11, 0x11, 0x13, 0x16, 0x1C, 0x17, 0x13, 0x14},
516 {0x1A, 0x15, 0x11, 0x11, 0x18, 0x21, 0x18, 0x1A},
517 {0x1D, 0x1D, 0x1F, 0x1F, 0x1F, 0x13, 0x17, 0x22},
518 {0x24, 0x22, 0x1E, 0x24, 0x1C, 0x1E, 0x1F, 0x1E},
519 {0xFF, 0x20, 0x00, 0x1F, 0x02, 0x0C, 0x00, 0x00},
520 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
521 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
522 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
523 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x14, 0xFF},
524 {0xC0, 0x00, 0x11, 0x08, 0x00, 0xF0, 0x01, 0x40},
525 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
526 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
527 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
528 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 27 */
529};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300530static const __u8 cxjpeg_176[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300531 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x0d},
532 {0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B, 0x0A},
533 {0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F, 0x14},
534 {0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D, 0x17},
535 {0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28, 0x2C},
536 {0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35, 0x44},
537 {0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44, 0x4A},
538 {0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58, 0x5F},
539 {0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D, 0x01},
540 {0x0D, 0x09, 0x09, 0x0B, 0x09, 0x08, 0x0D, 0x0B},
541 {0x0A, 0x0B, 0x0E, 0x0D, 0x0D, 0x0F, 0x13, 0x1F},
542 {0x14, 0x13, 0x11, 0x11, 0x13, 0x26, 0x1B, 0x1D},
543 {0x17, 0x1F, 0x2D, 0x28, 0x30, 0x2F, 0x2D, 0x28},
544 {0x2C, 0x2B, 0x32, 0x38, 0x48, 0x3D, 0x32, 0x35},
545 {0x44, 0x36, 0x2B, 0x2C, 0x3F, 0x55, 0x3F, 0x44},
546 {0x4A, 0x4D, 0x50, 0x51, 0x50, 0x30, 0x3C, 0x58},
547 {0x5F, 0x58, 0x4E, 0x5E, 0x48, 0x4F, 0x50, 0x4D},
548 {0xFF, 0x20, 0x00, 0x1F, 0x03, 0xA1, 0x00, 0x00},
549 {0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00},
550 {0x11, 0x22, 0x00, 0x22, 0x22, 0x11, 0x22, 0x22},
551 {0x11, 0x33, 0x33, 0x11, 0x44, 0x66, 0x22, 0x55},
552 {0x66, 0xFF, 0xDD, 0x00, 0x04, 0x00, 0x0B, 0xFF},
553 {0xC0, 0x00, 0x11, 0x08, 0x00, 0x90, 0x00, 0xB0},
554 {0x03, 0x00, 0x21, 0x00, 0x01, 0x11, 0x01, 0x02},
555 {0x11, 0x01, 0xFF, 0xDA, 0x00, 0x0C, 0x03, 0x00},
556 {0x00, 0x01, 0x11, 0x02, 0x11, 0x00, 0x3F, 0x00},
557 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
558};
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300559/* 640 take with the zcx30x part */
560static const __u8 cxjpeg_qtable[][8] = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300561 {0xff, 0xd8, 0xff, 0xdb, 0x00, 0x84, 0x00, 0x08},
562 {0x06, 0x06, 0x07, 0x06, 0x05, 0x08, 0x07, 0x07},
563 {0x07, 0x09, 0x09, 0x08, 0x0a, 0x0c, 0x14, 0x0a},
564 {0x0c, 0x0b, 0x0b, 0x0c, 0x19, 0x12, 0x13, 0x0f},
565 {0x14, 0x1d, 0x1a, 0x1f, 0x1e, 0x1d, 0x1a, 0x1c},
566 {0x1c, 0x20, 0x24, 0x2e, 0x27, 0x20, 0x22, 0x2c},
567 {0x23, 0x1c, 0x1c, 0x28, 0x37, 0x29, 0x2c, 0x30},
568 {0x31, 0x34, 0x34, 0x34, 0x1f, 0x27, 0x39, 0x3d},
569 {0x38, 0x32, 0x3c, 0x2e, 0x33, 0x34, 0x32, 0x01},
570 {0x09, 0x09, 0x09, 0x0c, 0x0b, 0x0c, 0x18, 0x0a},
571 {0x0a, 0x18, 0x32, 0x21, 0x1c, 0x21, 0x32, 0x32},
572 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
573 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
574 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
575 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
576 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
577 {0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32},
578 {0xFF, 0xD9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} /* 18 */
579};
580
581
582static void cx11646_jpegInit(struct gspca_dev*gspca_dev)
583{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300584 int i;
585 int length;
586
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300587 reg_w_val(gspca_dev, 0x00c0, 0x01);
588 reg_w_val(gspca_dev, 0x00c3, 0x00);
589 reg_w_val(gspca_dev, 0x00c0, 0x00);
590 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300591 length = 8;
592 for (i = 0; i < 79; i++) {
593 if (i == 78)
594 length = 6;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300595 reg_w(gspca_dev, 0x0008, cx_jpeg_init[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300596 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300597 reg_r(gspca_dev, 0x0002, 1);
598 reg_w_val(gspca_dev, 0x0055, 0x14);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300599}
600
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300601static const __u8 reg12[] = { 0x0a, 0x05, 0x07, 0x04, 0x19 };
602static const __u8 regE5_8[] =
603 { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
604static const __u8 regE5a[] = { 0x88, 0x0a, 0x0c, 0x01 };
605static const __u8 regE5b[] = { 0x88, 0x0b, 0x12, 0x01 };
606static const __u8 regE5c[] = { 0x88, 0x05, 0x01, 0x01 };
607static const __u8 reg51[] = { 0x77, 0x03 };
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300608#define reg70 0x03
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300609
610static void cx11646_jpeg(struct gspca_dev*gspca_dev)
611{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300612 int i;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300613 int length;
614 __u8 Reg55;
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300615 int retry;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300616
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300617 reg_w_val(gspca_dev, 0x00c0, 0x01);
618 reg_w_val(gspca_dev, 0x00c3, 0x00);
619 reg_w_val(gspca_dev, 0x00c0, 0x00);
620 reg_r(gspca_dev, 0x0001, 1);
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300621 length = 8;
Jean-François Moine780e3122010-10-19 04:29:10 -0300622 switch (gspca_dev->cam.cam_mode[gspca_dev->curr_mode].priv) {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300623 case 0:
624 for (i = 0; i < 27; i++) {
625 if (i == 26)
626 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300627 reg_w(gspca_dev, 0x0008, cxjpeg_640[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300628 }
629 Reg55 = 0x28;
630 break;
631 case 1:
632 for (i = 0; i < 27; i++) {
633 if (i == 26)
634 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300635 reg_w(gspca_dev, 0x0008, cxjpeg_352[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300636 }
637 Reg55 = 0x16;
638 break;
639 default:
640/* case 2: */
641 for (i = 0; i < 27; i++) {
642 if (i == 26)
643 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300644 reg_w(gspca_dev, 0x0008, cxjpeg_320[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300645 }
646 Reg55 = 0x14;
647 break;
648 case 3:
649 for (i = 0; i < 27; i++) {
650 if (i == 26)
651 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300652 reg_w(gspca_dev, 0x0008, cxjpeg_176[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300653 }
654 Reg55 = 0x0B;
655 break;
656 }
657
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300658 reg_r(gspca_dev, 0x0002, 1);
659 reg_w_val(gspca_dev, 0x0055, Reg55);
660 reg_r(gspca_dev, 0x0002, 1);
661 reg_w(gspca_dev, 0x0010, reg10, 2);
662 reg_w_val(gspca_dev, 0x0054, 0x02);
663 reg_w_val(gspca_dev, 0x0054, 0x01);
664 reg_w_val(gspca_dev, 0x0000, 0x94);
665 reg_w_val(gspca_dev, 0x0053, 0xc0);
666 reg_w_val(gspca_dev, 0x00fc, 0xe1);
667 reg_w_val(gspca_dev, 0x0000, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300668 /* wait for completion */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300669 retry = 50;
Li Zefan85610982008-09-02 07:02:50 -0300670 do {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300671 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300672 /* 0x07 until 0x00 */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300673 if (gspca_dev->usb_buf[0] == 0x00)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300674 break;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300675 reg_w_val(gspca_dev, 0x0053, 0x00);
Li Zefan85610982008-09-02 07:02:50 -0300676 } while (--retry);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300677 if (retry == 0)
Joe Perches52173c5f2017-09-22 14:33:35 -0400678 gspca_err(gspca_dev, "Damned Errors sending jpeg Table\n");
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300679 /* send the qtable now */
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300680 reg_r(gspca_dev, 0x0001, 1); /* -> 0x18 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300681 length = 8;
682 for (i = 0; i < 18; i++) {
683 if (i == 17)
684 length = 2;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300685 reg_w(gspca_dev, 0x0008, cxjpeg_qtable[i], length);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300686
687 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300688 reg_r(gspca_dev, 0x0002, 1); /* 0x00 */
689 reg_r(gspca_dev, 0x0053, 1); /* 0x00 */
690 reg_w_val(gspca_dev, 0x0054, 0x02);
691 reg_w_val(gspca_dev, 0x0054, 0x01);
692 reg_w_val(gspca_dev, 0x0000, 0x94);
693 reg_w_val(gspca_dev, 0x0053, 0xc0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300694
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300695 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
696 reg_r(gspca_dev, 0x0038, 1); /* 0x40 */
697 reg_r(gspca_dev, 0x001f, 1); /* 0x38 */
698 reg_w(gspca_dev, 0x0012, reg12, 5);
699 reg_w(gspca_dev, 0x00e5, regE5_8, 8);
700 reg_r(gspca_dev, 0x00e8, 8);
701 reg_w(gspca_dev, 0x00e5, regE5a, 4);
702 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
703 reg_w_val(gspca_dev, 0x009a, 0x01);
704 reg_w(gspca_dev, 0x00e5, regE5b, 4);
705 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
706 reg_w(gspca_dev, 0x00e5, regE5c, 4);
707 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300708
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300709 reg_w(gspca_dev, 0x0051, reg51, 2);
710 reg_w(gspca_dev, 0x0010, reg10, 2);
711 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300712}
713
714static void cx11646_init1(struct gspca_dev *gspca_dev)
715{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300716 int i = 0;
717
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300718 reg_w_val(gspca_dev, 0x0010, 0x00);
719 reg_w_val(gspca_dev, 0x0053, 0x00);
720 reg_w_val(gspca_dev, 0x0052, 0x00);
721 reg_w_val(gspca_dev, 0x009b, 0x2f);
722 reg_w_val(gspca_dev, 0x009c, 0x10);
723 reg_r(gspca_dev, 0x0098, 1);
724 reg_w_val(gspca_dev, 0x0098, 0x40);
725 reg_r(gspca_dev, 0x0099, 1);
726 reg_w_val(gspca_dev, 0x0099, 0x07);
727 reg_w_val(gspca_dev, 0x0039, 0x40);
728 reg_w_val(gspca_dev, 0x003c, 0xff);
729 reg_w_val(gspca_dev, 0x003f, 0x1f);
730 reg_w_val(gspca_dev, 0x003d, 0x40);
731/* reg_w_val(gspca_dev, 0x003d, 0x60); */
732 reg_r(gspca_dev, 0x0099, 1); /* ->0x07 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300733
734 while (cx_sensor_init[i][0]) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300735 reg_w_val(gspca_dev, 0x00e5, cx_sensor_init[i][0]);
736 reg_r(gspca_dev, 0x00e8, 1); /* -> 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300737 if (i == 1) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300738 reg_w_val(gspca_dev, 0x00ed, 0x01);
739 reg_r(gspca_dev, 0x00ed, 1); /* -> 0x01 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300740 }
741 i++;
742 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300743 reg_w_val(gspca_dev, 0x00c3, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300744}
745
746/* this function is called at probe time */
747static int sd_config(struct gspca_dev *gspca_dev,
748 const struct usb_device_id *id)
749{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300750 struct cam *cam;
751
752 cam = &gspca_dev->cam;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300753 cam->cam_mode = vga_mode;
Mauro Carvalho Chehabd6f76b92009-07-22 00:02:29 -0300754 cam->nmodes = ARRAY_SIZE(vga_mode);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300755 return 0;
756}
757
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300758/* this function is called at probe and resume time */
759static int sd_init(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300760{
761 cx11646_init1(gspca_dev);
762 cx11646_initsize(gspca_dev);
763 cx11646_fw(gspca_dev);
764 cx_sensor(gspca_dev);
765 cx11646_jpegInit(gspca_dev);
766 return 0;
767}
768
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300769static int sd_start(struct gspca_dev *gspca_dev)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300770{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300771 struct sd *sd = (struct sd *) gspca_dev;
772
773 /* create the JPEG header */
Ondrej Zary1966bc22013-08-30 17:54:23 -0300774 jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
775 gspca_dev->pixfmt.width,
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300776 0x22); /* JPEG 411 */
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300777 jpeg_set_qual(sd->jpeg_hdr, QUALITY);
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300778
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300779 cx11646_initsize(gspca_dev);
780 cx11646_fw(gspca_dev);
781 cx_sensor(gspca_dev);
782 cx11646_jpeg(gspca_dev);
Jean-Francois Moine72ab97c2008-09-20 06:39:08 -0300783 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300784}
785
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300786/* called on streamoff with alt 0 and on disconnect */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300787static void sd_stop0(struct gspca_dev *gspca_dev)
788{
789 int retry = 50;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300790
Jean-Francois Moine98522a72008-11-18 06:33:08 -0300791 if (!gspca_dev->present)
792 return;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300793 reg_w_val(gspca_dev, 0x0000, 0x00);
794 reg_r(gspca_dev, 0x0002, 1);
795 reg_w_val(gspca_dev, 0x0053, 0x00);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300796
797 while (retry--) {
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300798/* reg_r(gspca_dev, 0x0002, 1);*/
799 reg_r(gspca_dev, 0x0053, 1);
800 if (gspca_dev->usb_buf[0] == 0)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300801 break;
802 }
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300803 reg_w_val(gspca_dev, 0x0000, 0x00);
804 reg_r(gspca_dev, 0x0002, 1);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300805
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300806 reg_w_val(gspca_dev, 0x0010, 0x00);
807 reg_r(gspca_dev, 0x0033, 1);
808 reg_w_val(gspca_dev, 0x00fc, 0xe0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300809}
810
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300811static void sd_pkt_scan(struct gspca_dev *gspca_dev,
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300812 u8 *data, /* isoc packet */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300813 int len) /* iso packet length */
814{
Jean-Francois Moine71cb2762009-03-03 05:33:41 -0300815 struct sd *sd = (struct sd *) gspca_dev;
816
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300817 if (data[0] == 0xff && data[1] == 0xd8) {
818
819 /* start of frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300820 gspca_frame_add(gspca_dev, LAST_PACKET, NULL, 0);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300821
822 /* put the JPEG header in the new frame */
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300823 gspca_frame_add(gspca_dev, FIRST_PACKET,
824 sd->jpeg_hdr, JPEG_HDR_SZ);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300825 data += 2;
826 len -= 2;
827 }
Jean-Francois Moine76dd2722009-11-13 09:21:03 -0300828 gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300829}
830
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300831static void setbrightness(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300832{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300833 __u8 regE5cbx[] = { 0x88, 0x00, 0xd4, 0x01, 0x88, 0x01, 0x01, 0x01 };
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300834 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300835
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300836 regE5cbx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300837 reg_w(gspca_dev, 0x00e5, regE5cbx, 8);
838 reg_r(gspca_dev, 0x00e8, 8);
839 reg_w(gspca_dev, 0x00e5, regE5c, 4);
840 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300841
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300842 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300843 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300844 reg_w(gspca_dev, 0x0051, reg51c, 2);
845 reg_w(gspca_dev, 0x0010, reg10, 2);
846 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300847}
848
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300849static void setcontrast(struct gspca_dev *gspca_dev, s32 val, s32 sat)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300850{
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300851 __u8 regE5acx[] = { 0x88, 0x0a, 0x0c, 0x01 }; /* seem MSB */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300852/* __u8 regE5bcx[] = { 0x88, 0x0b, 0x12, 0x01}; * LSB */
853 __u8 reg51c[2];
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300854
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300855 regE5acx[2] = val;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300856 reg_w(gspca_dev, 0x00e5, regE5acx, 4);
857 reg_r(gspca_dev, 0x00e8, 1); /* 0x00 */
Jean-Francois Moinea5ae2062008-07-04 11:16:16 -0300858 reg51c[0] = 0x77;
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300859 reg51c[1] = sat;
Jean-Francois Moine739570b2008-07-14 09:38:29 -0300860 reg_w(gspca_dev, 0x0051, reg51c, 2);
861 reg_w(gspca_dev, 0x0010, reg10, 2);
862 reg_w_val(gspca_dev, 0x0070, reg70);
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300863}
864
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300865static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300866{
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300867 struct gspca_dev *gspca_dev =
868 container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
869 struct sd *sd = (struct sd *)gspca_dev;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300870
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300871 gspca_dev->usb_err = 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300872
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300873 if (!gspca_dev->streaming)
874 return 0;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300875
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300876 switch (ctrl->id) {
877 case V4L2_CID_BRIGHTNESS:
878 setbrightness(gspca_dev, ctrl->val, sd->sat->cur.val);
879 break;
880 case V4L2_CID_CONTRAST:
881 setcontrast(gspca_dev, ctrl->val, sd->sat->cur.val);
882 break;
883 case V4L2_CID_SATURATION:
884 setbrightness(gspca_dev, sd->brightness->cur.val, ctrl->val);
885 setcontrast(gspca_dev, sd->contrast->cur.val, ctrl->val);
886 break;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300887 }
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300888 return gspca_dev->usb_err;
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300889}
890
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300891static const struct v4l2_ctrl_ops sd_ctrl_ops = {
892 .s_ctrl = sd_s_ctrl,
893};
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300894
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300895static int sd_init_controls(struct gspca_dev *gspca_dev)
896{
897 struct sd *sd = (struct sd *)gspca_dev;
898 struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
899
900 gspca_dev->vdev.ctrl_handler = hdl;
Hans de Goedeb56ab4c2012-06-27 16:48:33 -0300901 v4l2_ctrl_handler_init(hdl, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300902 sd->brightness = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
903 V4L2_CID_BRIGHTNESS, 0, 255, 1, 0xd4);
904 sd->contrast = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
905 V4L2_CID_CONTRAST, 0x0a, 0x1f, 1, 0x0c);
906 sd->sat = v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
907 V4L2_CID_SATURATION, 0, 7, 1, 3);
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300908 if (hdl->error) {
909 pr_err("Could not initialize controls\n");
910 return hdl->error;
911 }
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300912 return 0;
913}
914
915/* sub-driver description */
Márton Némethaabcdfb2010-01-05 12:39:02 -0300916static const struct sd_desc sd_desc = {
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300917 .name = MODULE_NAME,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300918 .config = sd_config,
Jean-Francois Moine012d6b02008-09-03 17:12:16 -0300919 .init = sd_init,
Hans Verkuilcbc1c942012-05-14 04:09:17 -0300920 .init_controls = sd_init_controls,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300921 .start = sd_start,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300922 .stop0 = sd_stop0,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300923 .pkt_scan = sd_pkt_scan,
924};
925
926/* -- module initialisation -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300927static const struct usb_device_id device_table[] = {
Jean-Francois Moine9d64fdb2008-07-25 08:53:03 -0300928 {USB_DEVICE(0x0572, 0x0041)},
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300929 {}
930};
931MODULE_DEVICE_TABLE(usb, device_table);
932
933/* -- device connect -- */
Jean-François Moine95c967c2011-01-13 05:20:29 -0300934static int sd_probe(struct usb_interface *intf,
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300935 const struct usb_device_id *id)
936{
937 return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
938 THIS_MODULE);
939}
940
941static struct usb_driver sd_driver = {
942 .name = MODULE_NAME,
943 .id_table = device_table,
944 .probe = sd_probe,
945 .disconnect = gspca_disconnect,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300946#ifdef CONFIG_PM
947 .suspend = gspca_suspend,
948 .resume = gspca_resume,
Hans de Goede8bb58962012-06-30 06:44:47 -0300949 .reset_resume = gspca_resume,
Jean-Francois Moine6a709742008-09-03 16:48:10 -0300950#endif
Jean-Francois Moine6a7eba22008-06-30 15:50:11 -0300951};
952
Greg Kroah-Hartmanecb3b2b2011-11-18 09:46:12 -0800953module_usb_driver(sd_driver);