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