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