xref: /openbmc/linux/drivers/media/usb/gspca/spca500.c (revision 62e7ca52)
1 /*
2  * SPCA500 chip based cameras initialization data
3  *
4  * V4L2 by Jean-Francois Moine <http://moinejf.free.fr>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  */
21 
22 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
23 
24 #define MODULE_NAME "spca500"
25 
26 #include "gspca.h"
27 #include "jpeg.h"
28 
29 MODULE_AUTHOR("Michel Xhaard <mxhaard@users.sourceforge.net>");
30 MODULE_DESCRIPTION("GSPCA/SPCA500 USB Camera Driver");
31 MODULE_LICENSE("GPL");
32 
33 #define QUALITY 85
34 
35 /* specific webcam descriptor */
36 struct sd {
37 	struct gspca_dev gspca_dev;		/* !! must be the first item */
38 
39 	char subtype;
40 #define AgfaCl20 0
41 #define AiptekPocketDV 1
42 #define BenqDC1016 2
43 #define CreativePCCam300 3
44 #define DLinkDSC350 4
45 #define Gsmartmini 5
46 #define IntelPocketPCCamera 6
47 #define KodakEZ200 7
48 #define LogitechClickSmart310 8
49 #define LogitechClickSmart510 9
50 #define LogitechTraveler 10
51 #define MustekGsmart300 11
52 #define Optimedia 12
53 #define PalmPixDC85 13
54 #define ToptroIndus 14
55 
56 	u8 jpeg_hdr[JPEG_HDR_SZ];
57 };
58 
59 static const struct v4l2_pix_format vga_mode[] = {
60 	{320, 240, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
61 		.bytesperline = 320,
62 		.sizeimage = 320 * 240 * 3 / 8 + 590,
63 		.colorspace = V4L2_COLORSPACE_JPEG,
64 		.priv = 1},
65 	{640, 480, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
66 		.bytesperline = 640,
67 		.sizeimage = 640 * 480 * 3 / 8 + 590,
68 		.colorspace = V4L2_COLORSPACE_JPEG,
69 		.priv = 0},
70 };
71 
72 static const struct v4l2_pix_format sif_mode[] = {
73 	{176, 144, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
74 		.bytesperline = 176,
75 		.sizeimage = 176 * 144 * 3 / 8 + 590,
76 		.colorspace = V4L2_COLORSPACE_JPEG,
77 		.priv = 1},
78 	{352, 288, V4L2_PIX_FMT_JPEG, V4L2_FIELD_NONE,
79 		.bytesperline = 352,
80 		.sizeimage = 352 * 288 * 3 / 8 + 590,
81 		.colorspace = V4L2_COLORSPACE_JPEG,
82 		.priv = 0},
83 };
84 
85 /* Frame packet header offsets for the spca500 */
86 #define SPCA500_OFFSET_PADDINGLB 2
87 #define SPCA500_OFFSET_PADDINGHB 3
88 #define SPCA500_OFFSET_MODE      4
89 #define SPCA500_OFFSET_IMGWIDTH  5
90 #define SPCA500_OFFSET_IMGHEIGHT 6
91 #define SPCA500_OFFSET_IMGMODE   7
92 #define SPCA500_OFFSET_QTBLINDEX 8
93 #define SPCA500_OFFSET_FRAMSEQ   9
94 #define SPCA500_OFFSET_CDSPINFO  10
95 #define SPCA500_OFFSET_GPIO      11
96 #define SPCA500_OFFSET_AUGPIO    12
97 #define SPCA500_OFFSET_DATA      16
98 
99 
100 static const __u16 spca500_visual_defaults[][3] = {
101 	{0x00, 0x0003, 0x816b},	/* SSI not active sync with vsync,
102 				 * hue (H byte) = 0,
103 				 * saturation/hue enable,
104 				 * brightness/contrast enable.
105 				 */
106 	{0x00, 0x0000, 0x8167},	/* brightness = 0 */
107 	{0x00, 0x0020, 0x8168},	/* contrast = 0 */
108 	{0x00, 0x0003, 0x816b},	/* SSI not active sync with vsync,
109 				 * hue (H byte) = 0, saturation/hue enable,
110 				 * brightness/contrast enable.
111 				 * was 0x0003, now 0x0000.
112 				 */
113 	{0x00, 0x0000, 0x816a},	/* hue (L byte) = 0 */
114 	{0x00, 0x0020, 0x8169},	/* saturation = 0x20 */
115 	{0x00, 0x0050, 0x8157},	/* edge gain high threshold */
116 	{0x00, 0x0030, 0x8158},	/* edge gain low threshold */
117 	{0x00, 0x0028, 0x8159},	/* edge bandwidth high threshold */
118 	{0x00, 0x000a, 0x815a},	/* edge bandwidth low threshold */
119 	{0x00, 0x0001, 0x8202},	/* clock rate compensation = 1/25 sec/frame */
120 	{0x0c, 0x0004, 0x0000},
121 	/* set interface */
122 	{}
123 };
124 static const __u16 Clicksmart510_defaults[][3] = {
125 	{0x00, 0x00, 0x8211},
126 	{0x00, 0x01, 0x82c0},
127 	{0x00, 0x10, 0x82cb},
128 	{0x00, 0x0f, 0x800d},
129 	{0x00, 0x82, 0x8225},
130 	{0x00, 0x21, 0x8228},
131 	{0x00, 0x00, 0x8203},
132 	{0x00, 0x00, 0x8204},
133 	{0x00, 0x08, 0x8205},
134 	{0x00, 0xf8, 0x8206},
135 	{0x00, 0x28, 0x8207},
136 	{0x00, 0xa0, 0x8208},
137 	{0x00, 0x08, 0x824a},
138 	{0x00, 0x08, 0x8214},
139 	{0x00, 0x80, 0x82c1},
140 	{0x00, 0x00, 0x82c2},
141 	{0x00, 0x00, 0x82ca},
142 	{0x00, 0x80, 0x82c1},
143 	{0x00, 0x04, 0x82c2},
144 	{0x00, 0x00, 0x82ca},
145 	{0x00, 0xfc, 0x8100},
146 	{0x00, 0xfc, 0x8105},
147 	{0x00, 0x30, 0x8101},
148 	{0x00, 0x00, 0x8102},
149 	{0x00, 0x00, 0x8103},
150 	{0x00, 0x66, 0x8107},
151 	{0x00, 0x00, 0x816b},
152 	{0x00, 0x00, 0x8155},
153 	{0x00, 0x01, 0x8156},
154 	{0x00, 0x60, 0x8157},
155 	{0x00, 0x40, 0x8158},
156 	{0x00, 0x0a, 0x8159},
157 	{0x00, 0x06, 0x815a},
158 	{0x00, 0x00, 0x813f},
159 	{0x00, 0x00, 0x8200},
160 	{0x00, 0x19, 0x8201},
161 	{0x00, 0x00, 0x82c1},
162 	{0x00, 0xa0, 0x82c2},
163 	{0x00, 0x00, 0x82ca},
164 	{0x00, 0x00, 0x8117},
165 	{0x00, 0x00, 0x8118},
166 	{0x00, 0x65, 0x8119},
167 	{0x00, 0x00, 0x811a},
168 	{0x00, 0x00, 0x811b},
169 	{0x00, 0x55, 0x811c},
170 	{0x00, 0x65, 0x811d},
171 	{0x00, 0x55, 0x811e},
172 	{0x00, 0x16, 0x811f},
173 	{0x00, 0x19, 0x8120},
174 	{0x00, 0x80, 0x8103},
175 	{0x00, 0x83, 0x816b},
176 	{0x00, 0x25, 0x8168},
177 	{0x00, 0x01, 0x820f},
178 	{0x00, 0xff, 0x8115},
179 	{0x00, 0x48, 0x8116},
180 	{0x00, 0x50, 0x8151},
181 	{0x00, 0x40, 0x8152},
182 	{0x00, 0x78, 0x8153},
183 	{0x00, 0x40, 0x8154},
184 	{0x00, 0x00, 0x8167},
185 	{0x00, 0x20, 0x8168},
186 	{0x00, 0x00, 0x816a},
187 	{0x00, 0x03, 0x816b},
188 	{0x00, 0x20, 0x8169},
189 	{0x00, 0x60, 0x8157},
190 	{0x00, 0x00, 0x8190},
191 	{0x00, 0x00, 0x81a1},
192 	{0x00, 0x00, 0x81b2},
193 	{0x00, 0x27, 0x8191},
194 	{0x00, 0x27, 0x81a2},
195 	{0x00, 0x27, 0x81b3},
196 	{0x00, 0x4b, 0x8192},
197 	{0x00, 0x4b, 0x81a3},
198 	{0x00, 0x4b, 0x81b4},
199 	{0x00, 0x66, 0x8193},
200 	{0x00, 0x66, 0x81a4},
201 	{0x00, 0x66, 0x81b5},
202 	{0x00, 0x79, 0x8194},
203 	{0x00, 0x79, 0x81a5},
204 	{0x00, 0x79, 0x81b6},
205 	{0x00, 0x8a, 0x8195},
206 	{0x00, 0x8a, 0x81a6},
207 	{0x00, 0x8a, 0x81b7},
208 	{0x00, 0x9b, 0x8196},
209 	{0x00, 0x9b, 0x81a7},
210 	{0x00, 0x9b, 0x81b8},
211 	{0x00, 0xa6, 0x8197},
212 	{0x00, 0xa6, 0x81a8},
213 	{0x00, 0xa6, 0x81b9},
214 	{0x00, 0xb2, 0x8198},
215 	{0x00, 0xb2, 0x81a9},
216 	{0x00, 0xb2, 0x81ba},
217 	{0x00, 0xbe, 0x8199},
218 	{0x00, 0xbe, 0x81aa},
219 	{0x00, 0xbe, 0x81bb},
220 	{0x00, 0xc8, 0x819a},
221 	{0x00, 0xc8, 0x81ab},
222 	{0x00, 0xc8, 0x81bc},
223 	{0x00, 0xd2, 0x819b},
224 	{0x00, 0xd2, 0x81ac},
225 	{0x00, 0xd2, 0x81bd},
226 	{0x00, 0xdb, 0x819c},
227 	{0x00, 0xdb, 0x81ad},
228 	{0x00, 0xdb, 0x81be},
229 	{0x00, 0xe4, 0x819d},
230 	{0x00, 0xe4, 0x81ae},
231 	{0x00, 0xe4, 0x81bf},
232 	{0x00, 0xed, 0x819e},
233 	{0x00, 0xed, 0x81af},
234 	{0x00, 0xed, 0x81c0},
235 	{0x00, 0xf7, 0x819f},
236 	{0x00, 0xf7, 0x81b0},
237 	{0x00, 0xf7, 0x81c1},
238 	{0x00, 0xff, 0x81a0},
239 	{0x00, 0xff, 0x81b1},
240 	{0x00, 0xff, 0x81c2},
241 	{0x00, 0x03, 0x8156},
242 	{0x00, 0x00, 0x8211},
243 	{0x00, 0x20, 0x8168},
244 	{0x00, 0x01, 0x8202},
245 	{0x00, 0x30, 0x8101},
246 	{0x00, 0x00, 0x8111},
247 	{0x00, 0x00, 0x8112},
248 	{0x00, 0x00, 0x8113},
249 	{0x00, 0x00, 0x8114},
250 	{}
251 };
252 
253 static const __u8 qtable_creative_pccam[2][64] = {
254 	{				/* Q-table Y-components */
255 	 0x05, 0x03, 0x03, 0x05, 0x07, 0x0c, 0x0f, 0x12,
256 	 0x04, 0x04, 0x04, 0x06, 0x08, 0x11, 0x12, 0x11,
257 	 0x04, 0x04, 0x05, 0x07, 0x0c, 0x11, 0x15, 0x11,
258 	 0x04, 0x05, 0x07, 0x09, 0x0f, 0x1a, 0x18, 0x13,
259 	 0x05, 0x07, 0x0b, 0x11, 0x14, 0x21, 0x1f, 0x17,
260 	 0x07, 0x0b, 0x11, 0x13, 0x18, 0x1f, 0x22, 0x1c,
261 	 0x0f, 0x13, 0x17, 0x1a, 0x1f, 0x24, 0x24, 0x1e,
262 	 0x16, 0x1c, 0x1d, 0x1d, 0x22, 0x1e, 0x1f, 0x1e},
263 	{				/* Q-table C-components */
264 	 0x05, 0x05, 0x07, 0x0e, 0x1e, 0x1e, 0x1e, 0x1e,
265 	 0x05, 0x06, 0x08, 0x14, 0x1e, 0x1e, 0x1e, 0x1e,
266 	 0x07, 0x08, 0x11, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
267 	 0x0e, 0x14, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
268 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
269 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
270 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
271 	 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e}
272 };
273 
274 static const __u8 qtable_kodak_ez200[2][64] = {
275 	{				/* Q-table Y-components */
276 	 0x02, 0x01, 0x01, 0x02, 0x02, 0x04, 0x05, 0x06,
277 	 0x01, 0x01, 0x01, 0x02, 0x03, 0x06, 0x06, 0x06,
278 	 0x01, 0x01, 0x02, 0x02, 0x04, 0x06, 0x07, 0x06,
279 	 0x01, 0x02, 0x02, 0x03, 0x05, 0x09, 0x08, 0x06,
280 	 0x02, 0x02, 0x04, 0x06, 0x07, 0x0b, 0x0a, 0x08,
281 	 0x02, 0x04, 0x06, 0x06, 0x08, 0x0a, 0x0b, 0x09,
282 	 0x05, 0x06, 0x08, 0x09, 0x0a, 0x0c, 0x0c, 0x0a,
283 	 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x0a},
284 	{				/* Q-table C-components */
285 	 0x02, 0x02, 0x02, 0x05, 0x0a, 0x0a, 0x0a, 0x0a,
286 	 0x02, 0x02, 0x03, 0x07, 0x0a, 0x0a, 0x0a, 0x0a,
287 	 0x02, 0x03, 0x06, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
288 	 0x05, 0x07, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
289 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
290 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
291 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
292 	 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}
293 };
294 
295 static const __u8 qtable_pocketdv[2][64] = {
296 	{		/* Q-table Y-components start registers 0x8800 */
297 	 0x06, 0x04, 0x04, 0x06, 0x0a, 0x10, 0x14, 0x18,
298 	 0x05, 0x05, 0x06, 0x08, 0x0a, 0x17, 0x18, 0x16,
299 	 0x06, 0x05, 0x06, 0x0a, 0x10, 0x17, 0x1c, 0x16,
300 	 0x06, 0x07, 0x09, 0x0c, 0x14, 0x23, 0x20, 0x19,
301 	 0x07, 0x09, 0x0f, 0x16, 0x1b, 0x2c, 0x29, 0x1f,
302 	 0x0a, 0x0e, 0x16, 0x1a, 0x20, 0x2a, 0x2d, 0x25,
303 	 0x14, 0x1a, 0x1f, 0x23, 0x29, 0x30, 0x30, 0x28,
304 	 0x1d, 0x25, 0x26, 0x27, 0x2d, 0x28, 0x29, 0x28,
305 	 },
306 	{		/* Q-table C-components start registers 0x8840 */
307 	 0x07, 0x07, 0x0a, 0x13, 0x28, 0x28, 0x28, 0x28,
308 	 0x07, 0x08, 0x0a, 0x1a, 0x28, 0x28, 0x28, 0x28,
309 	 0x0a, 0x0a, 0x16, 0x28, 0x28, 0x28, 0x28, 0x28,
310 	 0x13, 0x1a, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
311 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
312 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
313 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
314 	 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28}
315 };
316 
317 /* read 'len' bytes to gspca_dev->usb_buf */
318 static void reg_r(struct gspca_dev *gspca_dev,
319 		  __u16 index,
320 		  __u16 length)
321 {
322 	usb_control_msg(gspca_dev->dev,
323 			usb_rcvctrlpipe(gspca_dev->dev, 0),
324 			0,
325 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
326 			0,		/* value */
327 			index, gspca_dev->usb_buf, length, 500);
328 }
329 
330 static int reg_w(struct gspca_dev *gspca_dev,
331 		     __u16 req, __u16 index, __u16 value)
332 {
333 	int ret;
334 
335 	PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
336 	ret = usb_control_msg(gspca_dev->dev,
337 			usb_sndctrlpipe(gspca_dev->dev, 0),
338 			req,
339 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
340 			value, index, NULL, 0, 500);
341 	if (ret < 0)
342 		pr_err("reg write: error %d\n", ret);
343 	return ret;
344 }
345 
346 /* returns: negative is error, pos or zero is data */
347 static int reg_r_12(struct gspca_dev *gspca_dev,
348 			__u16 req,	/* bRequest */
349 			__u16 index,	/* wIndex */
350 			__u16 length)	/* wLength (1 or 2 only) */
351 {
352 	int ret;
353 
354 	gspca_dev->usb_buf[1] = 0;
355 	ret = usb_control_msg(gspca_dev->dev,
356 			usb_rcvctrlpipe(gspca_dev->dev, 0),
357 			req,
358 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
359 			0,		/* value */
360 			index,
361 			gspca_dev->usb_buf, length,
362 			500);		/* timeout */
363 	if (ret < 0) {
364 		pr_err("reg_r_12 err %d\n", ret);
365 		return ret;
366 	}
367 	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
368 }
369 
370 /*
371  * Simple function to wait for a given 8-bit value to be returned from
372  * a reg_read call.
373  * Returns: negative is error or timeout, zero is success.
374  */
375 static int reg_r_wait(struct gspca_dev *gspca_dev,
376 			__u16 reg, __u16 index, __u16 value)
377 {
378 	int ret, cnt = 20;
379 
380 	while (--cnt > 0) {
381 		ret = reg_r_12(gspca_dev, reg, index, 1);
382 		if (ret == value)
383 			return 0;
384 		msleep(50);
385 	}
386 	return -EIO;
387 }
388 
389 static int write_vector(struct gspca_dev *gspca_dev,
390 			const __u16 data[][3])
391 {
392 	int ret, i = 0;
393 
394 	while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
395 		ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
396 		if (ret < 0)
397 			return ret;
398 		i++;
399 	}
400 	return 0;
401 }
402 
403 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
404 				unsigned int request,
405 				unsigned int ybase,
406 				unsigned int cbase,
407 				const __u8 qtable[2][64])
408 {
409 	int i, err;
410 
411 	/* loop over y components */
412 	for (i = 0; i < 64; i++) {
413 		err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
414 		if (err < 0)
415 			return err;
416 	}
417 
418 	/* loop over c components */
419 	for (i = 0; i < 64; i++) {
420 		err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
421 		if (err < 0)
422 			return err;
423 	}
424 	return 0;
425 }
426 
427 static void spca500_ping310(struct gspca_dev *gspca_dev)
428 {
429 	reg_r(gspca_dev, 0x0d04, 2);
430 	PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
431 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
432 }
433 
434 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
435 {
436 	reg_r(gspca_dev, 0x0d05, 2);
437 	PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
438 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
439 	reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
440 	spca500_ping310(gspca_dev);
441 
442 	reg_w(gspca_dev, 0x00, 0x8168, 0x22);
443 	reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
444 	reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
445 	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
446 	reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
447 	reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
448 	reg_w(gspca_dev, 0x00, 0x813f, 0x03);
449 	reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
450 	reg_w(gspca_dev, 0x00, 0x8153, 0x78);
451 	reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
452 						/* 00 for adjust shutter */
453 	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
454 	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
455 	reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
456 }
457 
458 static void spca500_setmode(struct gspca_dev *gspca_dev,
459 			__u8 xmult, __u8 ymult)
460 {
461 	int mode;
462 
463 	/* set x multiplier */
464 	reg_w(gspca_dev, 0, 0x8001, xmult);
465 
466 	/* set y multiplier */
467 	reg_w(gspca_dev, 0, 0x8002, ymult);
468 
469 	/* use compressed mode, VGA, with mode specific subsample */
470 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
471 	reg_w(gspca_dev, 0, 0x8003, mode << 4);
472 }
473 
474 static int spca500_full_reset(struct gspca_dev *gspca_dev)
475 {
476 	int err;
477 
478 	/* send the reset command */
479 	err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
480 	if (err < 0)
481 		return err;
482 
483 	/* wait for the reset to complete */
484 	err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
485 	if (err < 0)
486 		return err;
487 	err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
488 	if (err < 0)
489 		return err;
490 	err = reg_r_wait(gspca_dev, 0x06, 0, 0);
491 	if (err < 0) {
492 		PERR("reg_r_wait() failed");
493 		return err;
494 	}
495 	/* all ok */
496 	return 0;
497 }
498 
499 /* Synchro the Bridge with sensor */
500 /* Maybe that will work on all spca500 chip */
501 /* because i only own a clicksmart310 try for that chip */
502 /* using spca50x_set_packet_size() cause an Ooops here */
503 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
504 /* up-port the same feature as in 2.4.x kernel */
505 static int spca500_synch310(struct gspca_dev *gspca_dev)
506 {
507 	if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
508 		PERR("Set packet size: set interface error");
509 		goto error;
510 	}
511 	spca500_ping310(gspca_dev);
512 
513 	reg_r(gspca_dev, 0x0d00, 1);
514 
515 	/* need alt setting here */
516 	PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
517 
518 	/* Windoze use pipe with altsetting 6 why 7 here */
519 	if (usb_set_interface(gspca_dev->dev,
520 				gspca_dev->iface,
521 				gspca_dev->alt) < 0) {
522 		PERR("Set packet size: set interface error");
523 		goto error;
524 	}
525 	return 0;
526 error:
527 	return -EBUSY;
528 }
529 
530 static void spca500_reinit(struct gspca_dev *gspca_dev)
531 {
532 	int err;
533 	__u8 Data;
534 
535 	/* some unknown command from Aiptek pocket dv and family300 */
536 
537 	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
538 	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
539 	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
540 
541 	/* enable drop packet */
542 	reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
543 
544 	err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
545 				 qtable_pocketdv);
546 	if (err < 0)
547 		PERR("spca50x_setup_qtable failed on init");
548 
549 	/* set qtable index */
550 	reg_w(gspca_dev, 0x00, 0x8880, 2);
551 	/* family cam Quicksmart stuff */
552 	reg_w(gspca_dev, 0x00, 0x800a, 0x00);
553 	/* Set agc transfer: synced between frames */
554 	reg_w(gspca_dev, 0x00, 0x820f, 0x01);
555 	/* Init SDRAM - needed for SDRAM access */
556 	reg_w(gspca_dev, 0x00, 0x870a, 0x04);
557 	/*Start init sequence or stream */
558 	reg_w(gspca_dev, 0, 0x8003, 0x00);
559 	/* switch to video camera mode */
560 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
561 	msleep(2000);
562 	if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
563 		reg_r(gspca_dev, 0x816b, 1);
564 		Data = gspca_dev->usb_buf[0];
565 		reg_w(gspca_dev, 0x00, 0x816b, Data);
566 	}
567 }
568 
569 /* this function is called at probe time */
570 static int sd_config(struct gspca_dev *gspca_dev,
571 			const struct usb_device_id *id)
572 {
573 	struct sd *sd = (struct sd *) gspca_dev;
574 	struct cam *cam;
575 
576 	cam = &gspca_dev->cam;
577 	sd->subtype = id->driver_info;
578 	if (sd->subtype != LogitechClickSmart310) {
579 		cam->cam_mode = vga_mode;
580 		cam->nmodes = ARRAY_SIZE(vga_mode);
581 	} else {
582 		cam->cam_mode = sif_mode;
583 		cam->nmodes = ARRAY_SIZE(sif_mode);
584 	}
585 	return 0;
586 }
587 
588 /* this function is called at probe and resume time */
589 static int sd_init(struct gspca_dev *gspca_dev)
590 {
591 	struct sd *sd = (struct sd *) gspca_dev;
592 
593 	/* initialisation of spca500 based cameras is deferred */
594 	PDEBUG(D_STREAM, "SPCA500 init");
595 	if (sd->subtype == LogitechClickSmart310)
596 		spca500_clksmart310_init(gspca_dev);
597 /*	else
598 		spca500_initialise(gspca_dev); */
599 	PDEBUG(D_STREAM, "SPCA500 init done");
600 	return 0;
601 }
602 
603 static int sd_start(struct gspca_dev *gspca_dev)
604 {
605 	struct sd *sd = (struct sd *) gspca_dev;
606 	int err;
607 	__u8 Data;
608 	__u8 xmult, ymult;
609 
610 	/* create the JPEG header */
611 	jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
612 			gspca_dev->pixfmt.width,
613 			0x22);		/* JPEG 411 */
614 	jpeg_set_qual(sd->jpeg_hdr, QUALITY);
615 
616 	if (sd->subtype == LogitechClickSmart310) {
617 		xmult = 0x16;
618 		ymult = 0x12;
619 	} else {
620 		xmult = 0x28;
621 		ymult = 0x1e;
622 	}
623 
624 	/* is there a sensor here ? */
625 	reg_r(gspca_dev, 0x8a04, 1);
626 	PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
627 		gspca_dev->usb_buf[0]);
628 	PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
629 		gspca_dev->curr_mode, xmult, ymult);
630 
631 	/* setup qtable */
632 	switch (sd->subtype) {
633 	case LogitechClickSmart310:
634 		 spca500_setmode(gspca_dev, xmult, ymult);
635 
636 		/* enable drop packet */
637 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
638 		reg_w(gspca_dev, 0x00, 0x8880, 3);
639 		err = spca50x_setup_qtable(gspca_dev,
640 					   0x00, 0x8800, 0x8840,
641 					   qtable_creative_pccam);
642 		if (err < 0)
643 			PERR("spca50x_setup_qtable failed");
644 		/* Init SDRAM - needed for SDRAM access */
645 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
646 
647 		/* switch to video camera mode */
648 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
649 		msleep(500);
650 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
651 			PERR("reg_r_wait() failed");
652 
653 		reg_r(gspca_dev, 0x816b, 1);
654 		Data = gspca_dev->usb_buf[0];
655 		reg_w(gspca_dev, 0x00, 0x816b, Data);
656 
657 		spca500_synch310(gspca_dev);
658 
659 		write_vector(gspca_dev, spca500_visual_defaults);
660 		spca500_setmode(gspca_dev, xmult, ymult);
661 		/* enable drop packet */
662 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
663 		if (err < 0)
664 			PERR("failed to enable drop packet");
665 		reg_w(gspca_dev, 0x00, 0x8880, 3);
666 		err = spca50x_setup_qtable(gspca_dev,
667 					   0x00, 0x8800, 0x8840,
668 					   qtable_creative_pccam);
669 		if (err < 0)
670 			PERR("spca50x_setup_qtable failed");
671 
672 		/* Init SDRAM - needed for SDRAM access */
673 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
674 
675 		/* switch to video camera mode */
676 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
677 
678 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
679 			PERR("reg_r_wait() failed");
680 
681 		reg_r(gspca_dev, 0x816b, 1);
682 		Data = gspca_dev->usb_buf[0];
683 		reg_w(gspca_dev, 0x00, 0x816b, Data);
684 		break;
685 	case CreativePCCam300:		/* Creative PC-CAM 300 640x480 CCD */
686 	case IntelPocketPCCamera:	/* FIXME: Temporary fix for
687 					 *	Intel Pocket PC Camera
688 					 *	- NWG (Sat 29th March 2003) */
689 
690 		/* do a full reset */
691 		err = spca500_full_reset(gspca_dev);
692 		if (err < 0)
693 			PERR("spca500_full_reset failed");
694 
695 		/* enable drop packet */
696 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
697 		if (err < 0)
698 			PERR("failed to enable drop packet");
699 		reg_w(gspca_dev, 0x00, 0x8880, 3);
700 		err = spca50x_setup_qtable(gspca_dev,
701 					   0x00, 0x8800, 0x8840,
702 					   qtable_creative_pccam);
703 		if (err < 0)
704 			PERR("spca50x_setup_qtable failed");
705 
706 		spca500_setmode(gspca_dev, xmult, ymult);
707 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
708 
709 		/* switch to video camera mode */
710 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
711 
712 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
713 			PERR("reg_r_wait() failed");
714 
715 		reg_r(gspca_dev, 0x816b, 1);
716 		Data = gspca_dev->usb_buf[0];
717 		reg_w(gspca_dev, 0x00, 0x816b, Data);
718 
719 /*		write_vector(gspca_dev, spca500_visual_defaults); */
720 		break;
721 	case KodakEZ200:		/* Kodak EZ200 */
722 
723 		/* do a full reset */
724 		err = spca500_full_reset(gspca_dev);
725 		if (err < 0)
726 			PERR("spca500_full_reset failed");
727 		/* enable drop packet */
728 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
729 		reg_w(gspca_dev, 0x00, 0x8880, 0);
730 		err = spca50x_setup_qtable(gspca_dev,
731 					   0x00, 0x8800, 0x8840,
732 					   qtable_kodak_ez200);
733 		if (err < 0)
734 			PERR("spca50x_setup_qtable failed");
735 		spca500_setmode(gspca_dev, xmult, ymult);
736 
737 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
738 
739 		/* switch to video camera mode */
740 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
741 
742 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
743 			PERR("reg_r_wait() failed");
744 
745 		reg_r(gspca_dev, 0x816b, 1);
746 		Data = gspca_dev->usb_buf[0];
747 		reg_w(gspca_dev, 0x00, 0x816b, Data);
748 
749 /*		write_vector(gspca_dev, spca500_visual_defaults); */
750 		break;
751 
752 	case BenqDC1016:
753 	case DLinkDSC350:		/* FamilyCam 300 */
754 	case AiptekPocketDV:		/* Aiptek PocketDV */
755 	case Gsmartmini:		/*Mustek Gsmart Mini */
756 	case MustekGsmart300:		/* Mustek Gsmart 300 */
757 	case PalmPixDC85:
758 	case Optimedia:
759 	case ToptroIndus:
760 	case AgfaCl20:
761 		spca500_reinit(gspca_dev);
762 		reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
763 		/* enable drop packet */
764 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
765 
766 		err = spca50x_setup_qtable(gspca_dev,
767 				   0x00, 0x8800, 0x8840, qtable_pocketdv);
768 		if (err < 0)
769 			PERR("spca50x_setup_qtable failed");
770 		reg_w(gspca_dev, 0x00, 0x8880, 2);
771 
772 		/* familycam Quicksmart pocketDV stuff */
773 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
774 		/* Set agc transfer: synced between frames */
775 		reg_w(gspca_dev, 0x00, 0x820f, 0x01);
776 		/* Init SDRAM - needed for SDRAM access */
777 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
778 
779 		spca500_setmode(gspca_dev, xmult, ymult);
780 		/* switch to video camera mode */
781 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
782 
783 		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
784 
785 		reg_r(gspca_dev, 0x816b, 1);
786 		Data = gspca_dev->usb_buf[0];
787 		reg_w(gspca_dev, 0x00, 0x816b, Data);
788 		break;
789 	case LogitechTraveler:
790 	case LogitechClickSmart510:
791 		reg_w(gspca_dev, 0x02, 0x00, 0x00);
792 		/* enable drop packet */
793 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
794 
795 		err = spca50x_setup_qtable(gspca_dev,
796 					0x00, 0x8800,
797 					0x8840, qtable_creative_pccam);
798 		if (err < 0)
799 			PERR("spca50x_setup_qtable failed");
800 		reg_w(gspca_dev, 0x00, 0x8880, 3);
801 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
802 		/* Init SDRAM - needed for SDRAM access */
803 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
804 
805 		spca500_setmode(gspca_dev, xmult, ymult);
806 
807 		/* switch to video camera mode */
808 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
809 		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
810 
811 		reg_r(gspca_dev, 0x816b, 1);
812 		Data = gspca_dev->usb_buf[0];
813 		reg_w(gspca_dev, 0x00, 0x816b, Data);
814 		write_vector(gspca_dev, Clicksmart510_defaults);
815 		break;
816 	}
817 	return 0;
818 }
819 
820 static void sd_stopN(struct gspca_dev *gspca_dev)
821 {
822 	reg_w(gspca_dev, 0, 0x8003, 0x00);
823 
824 	/* switch to video camera mode */
825 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
826 	reg_r(gspca_dev, 0x8000, 1);
827 	PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
828 		gspca_dev->usb_buf[0]);
829 }
830 
831 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
832 			u8 *data,			/* isoc packet */
833 			int len)			/* iso packet length */
834 {
835 	struct sd *sd = (struct sd *) gspca_dev;
836 	int i;
837 	static __u8 ffd9[] = {0xff, 0xd9};
838 
839 /* frames are jpeg 4.1.1 without 0xff escape */
840 	if (data[0] == 0xff) {
841 		if (data[1] != 0x01) {	/* drop packet */
842 /*			gspca_dev->last_packet_type = DISCARD_PACKET; */
843 			return;
844 		}
845 		gspca_frame_add(gspca_dev, LAST_PACKET,
846 					ffd9, 2);
847 
848 		/* put the JPEG header in the new frame */
849 		gspca_frame_add(gspca_dev, FIRST_PACKET,
850 			sd->jpeg_hdr, JPEG_HDR_SZ);
851 
852 		data += SPCA500_OFFSET_DATA;
853 		len -= SPCA500_OFFSET_DATA;
854 	} else {
855 		data += 1;
856 		len -= 1;
857 	}
858 
859 	/* add 0x00 after 0xff */
860 	i = 0;
861 	do {
862 		if (data[i] == 0xff) {
863 			gspca_frame_add(gspca_dev, INTER_PACKET,
864 					data, i + 1);
865 			len -= i;
866 			data += i;
867 			*data = 0x00;
868 			i = 0;
869 		}
870 		i++;
871 	} while (i < len);
872 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
873 }
874 
875 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
876 {
877 	reg_w(gspca_dev, 0x00, 0x8167,
878 			(__u8) (val - 128));
879 }
880 
881 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
882 {
883 	reg_w(gspca_dev, 0x00, 0x8168, val);
884 }
885 
886 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
887 {
888 	reg_w(gspca_dev, 0x00, 0x8169, val);
889 }
890 
891 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
892 {
893 	struct gspca_dev *gspca_dev =
894 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
895 
896 	gspca_dev->usb_err = 0;
897 
898 	if (!gspca_dev->streaming)
899 		return 0;
900 
901 	switch (ctrl->id) {
902 	case V4L2_CID_BRIGHTNESS:
903 		setbrightness(gspca_dev, ctrl->val);
904 		break;
905 	case V4L2_CID_CONTRAST:
906 		setcontrast(gspca_dev, ctrl->val);
907 		break;
908 	case V4L2_CID_SATURATION:
909 		setcolors(gspca_dev, ctrl->val);
910 		break;
911 	}
912 	return gspca_dev->usb_err;
913 }
914 
915 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
916 	.s_ctrl = sd_s_ctrl,
917 };
918 
919 static int sd_init_controls(struct gspca_dev *gspca_dev)
920 {
921 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
922 
923 	gspca_dev->vdev.ctrl_handler = hdl;
924 	v4l2_ctrl_handler_init(hdl, 3);
925 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
926 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
927 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
928 			V4L2_CID_CONTRAST, 0, 63, 1, 31);
929 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
930 			V4L2_CID_SATURATION, 0, 63, 1, 31);
931 
932 	if (hdl->error) {
933 		pr_err("Could not initialize controls\n");
934 		return hdl->error;
935 	}
936 	return 0;
937 }
938 
939 /* sub-driver description */
940 static const struct sd_desc sd_desc = {
941 	.name = MODULE_NAME,
942 	.config = sd_config,
943 	.init = sd_init,
944 	.init_controls = sd_init_controls,
945 	.start = sd_start,
946 	.stopN = sd_stopN,
947 	.pkt_scan = sd_pkt_scan,
948 };
949 
950 /* -- module initialisation -- */
951 static const struct usb_device_id device_table[] = {
952 	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
953 	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
954 	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
955 	{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
956 	{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
957 	{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
958 	{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
959 	{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
960 	{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
961 	{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
962 	{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
963 	{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
964 	{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
965 	{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
966 	{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
967 	{}
968 };
969 MODULE_DEVICE_TABLE(usb, device_table);
970 
971 /* -- device connect -- */
972 static int sd_probe(struct usb_interface *intf,
973 			const struct usb_device_id *id)
974 {
975 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
976 				THIS_MODULE);
977 }
978 
979 static struct usb_driver sd_driver = {
980 	.name = MODULE_NAME,
981 	.id_table = device_table,
982 	.probe = sd_probe,
983 	.disconnect = gspca_disconnect,
984 #ifdef CONFIG_PM
985 	.suspend = gspca_suspend,
986 	.resume = gspca_resume,
987 	.reset_resume = gspca_resume,
988 #endif
989 };
990 
991 module_usb_driver(sd_driver);
992