xref: /linux/drivers/media/usb/gspca/spca500.c (revision e5c86679d5e864947a52fb31e45a425dea3e7fa9)
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 	PDEBUG(D_USBO, "reg write: [0x%02x] = 0x%02x", index, value);
332 	ret = usb_control_msg(gspca_dev->dev,
333 			usb_sndctrlpipe(gspca_dev->dev, 0),
334 			req,
335 			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
336 			value, index, NULL, 0, 500);
337 	if (ret < 0)
338 		pr_err("reg write: error %d\n", ret);
339 	return ret;
340 }
341 
342 /* returns: negative is error, pos or zero is data */
343 static int reg_r_12(struct gspca_dev *gspca_dev,
344 			__u16 req,	/* bRequest */
345 			__u16 index,	/* wIndex */
346 			__u16 length)	/* wLength (1 or 2 only) */
347 {
348 	int ret;
349 
350 	gspca_dev->usb_buf[1] = 0;
351 	ret = usb_control_msg(gspca_dev->dev,
352 			usb_rcvctrlpipe(gspca_dev->dev, 0),
353 			req,
354 			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
355 			0,		/* value */
356 			index,
357 			gspca_dev->usb_buf, length,
358 			500);		/* timeout */
359 	if (ret < 0) {
360 		pr_err("reg_r_12 err %d\n", ret);
361 		return ret;
362 	}
363 	return (gspca_dev->usb_buf[1] << 8) + gspca_dev->usb_buf[0];
364 }
365 
366 /*
367  * Simple function to wait for a given 8-bit value to be returned from
368  * a reg_read call.
369  * Returns: negative is error or timeout, zero is success.
370  */
371 static int reg_r_wait(struct gspca_dev *gspca_dev,
372 			__u16 reg, __u16 index, __u16 value)
373 {
374 	int ret, cnt = 20;
375 
376 	while (--cnt > 0) {
377 		ret = reg_r_12(gspca_dev, reg, index, 1);
378 		if (ret == value)
379 			return 0;
380 		msleep(50);
381 	}
382 	return -EIO;
383 }
384 
385 static int write_vector(struct gspca_dev *gspca_dev,
386 			const __u16 data[][3])
387 {
388 	int ret, i = 0;
389 
390 	while (data[i][0] != 0 || data[i][1] != 0 || data[i][2] != 0) {
391 		ret = reg_w(gspca_dev, data[i][0], data[i][2], data[i][1]);
392 		if (ret < 0)
393 			return ret;
394 		i++;
395 	}
396 	return 0;
397 }
398 
399 static int spca50x_setup_qtable(struct gspca_dev *gspca_dev,
400 				unsigned int request,
401 				unsigned int ybase,
402 				unsigned int cbase,
403 				const __u8 qtable[2][64])
404 {
405 	int i, err;
406 
407 	/* loop over y components */
408 	for (i = 0; i < 64; i++) {
409 		err = reg_w(gspca_dev, request, ybase + i, qtable[0][i]);
410 		if (err < 0)
411 			return err;
412 	}
413 
414 	/* loop over c components */
415 	for (i = 0; i < 64; i++) {
416 		err = reg_w(gspca_dev, request, cbase + i, qtable[1][i]);
417 		if (err < 0)
418 			return err;
419 	}
420 	return 0;
421 }
422 
423 static void spca500_ping310(struct gspca_dev *gspca_dev)
424 {
425 	reg_r(gspca_dev, 0x0d04, 2);
426 	PDEBUG(D_STREAM, "ClickSmart310 ping 0x0d04 0x%02x 0x%02x",
427 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
428 }
429 
430 static void spca500_clksmart310_init(struct gspca_dev *gspca_dev)
431 {
432 	reg_r(gspca_dev, 0x0d05, 2);
433 	PDEBUG(D_STREAM, "ClickSmart310 init 0x0d05 0x%02x 0x%02x",
434 		gspca_dev->usb_buf[0], gspca_dev->usb_buf[1]);
435 	reg_w(gspca_dev, 0x00, 0x8167, 0x5a);
436 	spca500_ping310(gspca_dev);
437 
438 	reg_w(gspca_dev, 0x00, 0x8168, 0x22);
439 	reg_w(gspca_dev, 0x00, 0x816a, 0xc0);
440 	reg_w(gspca_dev, 0x00, 0x816b, 0x0b);
441 	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
442 	reg_w(gspca_dev, 0x00, 0x8157, 0x5b);
443 	reg_w(gspca_dev, 0x00, 0x8158, 0x5b);
444 	reg_w(gspca_dev, 0x00, 0x813f, 0x03);
445 	reg_w(gspca_dev, 0x00, 0x8151, 0x4a);
446 	reg_w(gspca_dev, 0x00, 0x8153, 0x78);
447 	reg_w(gspca_dev, 0x00, 0x0d01, 0x04);
448 						/* 00 for adjust shutter */
449 	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
450 	reg_w(gspca_dev, 0x00, 0x8169, 0x25);
451 	reg_w(gspca_dev, 0x00, 0x0d01, 0x02);
452 }
453 
454 static void spca500_setmode(struct gspca_dev *gspca_dev,
455 			__u8 xmult, __u8 ymult)
456 {
457 	int mode;
458 
459 	/* set x multiplier */
460 	reg_w(gspca_dev, 0, 0x8001, xmult);
461 
462 	/* set y multiplier */
463 	reg_w(gspca_dev, 0, 0x8002, ymult);
464 
465 	/* use compressed mode, VGA, with mode specific subsample */
466 	mode = gspca_dev->cam.cam_mode[(int) gspca_dev->curr_mode].priv;
467 	reg_w(gspca_dev, 0, 0x8003, mode << 4);
468 }
469 
470 static int spca500_full_reset(struct gspca_dev *gspca_dev)
471 {
472 	int err;
473 
474 	/* send the reset command */
475 	err = reg_w(gspca_dev, 0xe0, 0x0001, 0x0000);
476 	if (err < 0)
477 		return err;
478 
479 	/* wait for the reset to complete */
480 	err = reg_r_wait(gspca_dev, 0x06, 0x0000, 0x0000);
481 	if (err < 0)
482 		return err;
483 	err = reg_w(gspca_dev, 0xe0, 0x0000, 0x0000);
484 	if (err < 0)
485 		return err;
486 	err = reg_r_wait(gspca_dev, 0x06, 0, 0);
487 	if (err < 0) {
488 		PERR("reg_r_wait() failed");
489 		return err;
490 	}
491 	/* all ok */
492 	return 0;
493 }
494 
495 /* Synchro the Bridge with sensor */
496 /* Maybe that will work on all spca500 chip */
497 /* because i only own a clicksmart310 try for that chip */
498 /* using spca50x_set_packet_size() cause an Ooops here */
499 /* usb_set_interface from kernel 2.6.x clear all the urb stuff */
500 /* up-port the same feature as in 2.4.x kernel */
501 static int spca500_synch310(struct gspca_dev *gspca_dev)
502 {
503 	if (usb_set_interface(gspca_dev->dev, gspca_dev->iface, 0) < 0) {
504 		PERR("Set packet size: set interface error");
505 		goto error;
506 	}
507 	spca500_ping310(gspca_dev);
508 
509 	reg_r(gspca_dev, 0x0d00, 1);
510 
511 	/* need alt setting here */
512 	PDEBUG(D_PACK, "ClickSmart310 sync alt: %d", gspca_dev->alt);
513 
514 	/* Windoze use pipe with altsetting 6 why 7 here */
515 	if (usb_set_interface(gspca_dev->dev,
516 				gspca_dev->iface,
517 				gspca_dev->alt) < 0) {
518 		PERR("Set packet size: set interface error");
519 		goto error;
520 	}
521 	return 0;
522 error:
523 	return -EBUSY;
524 }
525 
526 static void spca500_reinit(struct gspca_dev *gspca_dev)
527 {
528 	int err;
529 	__u8 Data;
530 
531 	/* some unknown command from Aiptek pocket dv and family300 */
532 
533 	reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
534 	reg_w(gspca_dev, 0x00, 0x0d03, 0x00);
535 	reg_w(gspca_dev, 0x00, 0x0d02, 0x01);
536 
537 	/* enable drop packet */
538 	reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
539 
540 	err = spca50x_setup_qtable(gspca_dev, 0x00, 0x8800, 0x8840,
541 				 qtable_pocketdv);
542 	if (err < 0)
543 		PERR("spca50x_setup_qtable failed on init");
544 
545 	/* set qtable index */
546 	reg_w(gspca_dev, 0x00, 0x8880, 2);
547 	/* family cam Quicksmart stuff */
548 	reg_w(gspca_dev, 0x00, 0x800a, 0x00);
549 	/* Set agc transfer: synced between frames */
550 	reg_w(gspca_dev, 0x00, 0x820f, 0x01);
551 	/* Init SDRAM - needed for SDRAM access */
552 	reg_w(gspca_dev, 0x00, 0x870a, 0x04);
553 	/*Start init sequence or stream */
554 	reg_w(gspca_dev, 0, 0x8003, 0x00);
555 	/* switch to video camera mode */
556 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
557 	msleep(2000);
558 	if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0) {
559 		reg_r(gspca_dev, 0x816b, 1);
560 		Data = gspca_dev->usb_buf[0];
561 		reg_w(gspca_dev, 0x00, 0x816b, Data);
562 	}
563 }
564 
565 /* this function is called at probe time */
566 static int sd_config(struct gspca_dev *gspca_dev,
567 			const struct usb_device_id *id)
568 {
569 	struct sd *sd = (struct sd *) gspca_dev;
570 	struct cam *cam;
571 
572 	cam = &gspca_dev->cam;
573 	sd->subtype = id->driver_info;
574 	if (sd->subtype != LogitechClickSmart310) {
575 		cam->cam_mode = vga_mode;
576 		cam->nmodes = ARRAY_SIZE(vga_mode);
577 	} else {
578 		cam->cam_mode = sif_mode;
579 		cam->nmodes = ARRAY_SIZE(sif_mode);
580 	}
581 	return 0;
582 }
583 
584 /* this function is called at probe and resume time */
585 static int sd_init(struct gspca_dev *gspca_dev)
586 {
587 	struct sd *sd = (struct sd *) gspca_dev;
588 
589 	/* initialisation of spca500 based cameras is deferred */
590 	PDEBUG(D_STREAM, "SPCA500 init");
591 	if (sd->subtype == LogitechClickSmart310)
592 		spca500_clksmart310_init(gspca_dev);
593 /*	else
594 		spca500_initialise(gspca_dev); */
595 	PDEBUG(D_STREAM, "SPCA500 init done");
596 	return 0;
597 }
598 
599 static int sd_start(struct gspca_dev *gspca_dev)
600 {
601 	struct sd *sd = (struct sd *) gspca_dev;
602 	int err;
603 	__u8 Data;
604 	__u8 xmult, ymult;
605 
606 	/* create the JPEG header */
607 	jpeg_define(sd->jpeg_hdr, gspca_dev->pixfmt.height,
608 			gspca_dev->pixfmt.width,
609 			0x22);		/* JPEG 411 */
610 	jpeg_set_qual(sd->jpeg_hdr, QUALITY);
611 
612 	if (sd->subtype == LogitechClickSmart310) {
613 		xmult = 0x16;
614 		ymult = 0x12;
615 	} else {
616 		xmult = 0x28;
617 		ymult = 0x1e;
618 	}
619 
620 	/* is there a sensor here ? */
621 	reg_r(gspca_dev, 0x8a04, 1);
622 	PDEBUG(D_STREAM, "Spca500 Sensor Address 0x%02x",
623 		gspca_dev->usb_buf[0]);
624 	PDEBUG(D_STREAM, "Spca500 curr_mode: %d Xmult: 0x%02x, Ymult: 0x%02x",
625 		gspca_dev->curr_mode, xmult, ymult);
626 
627 	/* setup qtable */
628 	switch (sd->subtype) {
629 	case LogitechClickSmart310:
630 		 spca500_setmode(gspca_dev, xmult, ymult);
631 
632 		/* enable drop packet */
633 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
634 		reg_w(gspca_dev, 0x00, 0x8880, 3);
635 		err = spca50x_setup_qtable(gspca_dev,
636 					   0x00, 0x8800, 0x8840,
637 					   qtable_creative_pccam);
638 		if (err < 0)
639 			PERR("spca50x_setup_qtable failed");
640 		/* Init SDRAM - needed for SDRAM access */
641 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
642 
643 		/* switch to video camera mode */
644 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
645 		msleep(500);
646 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
647 			PERR("reg_r_wait() failed");
648 
649 		reg_r(gspca_dev, 0x816b, 1);
650 		Data = gspca_dev->usb_buf[0];
651 		reg_w(gspca_dev, 0x00, 0x816b, Data);
652 
653 		spca500_synch310(gspca_dev);
654 
655 		write_vector(gspca_dev, spca500_visual_defaults);
656 		spca500_setmode(gspca_dev, xmult, ymult);
657 		/* enable drop packet */
658 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
659 		if (err < 0)
660 			PERR("failed to enable drop packet");
661 		reg_w(gspca_dev, 0x00, 0x8880, 3);
662 		err = spca50x_setup_qtable(gspca_dev,
663 					   0x00, 0x8800, 0x8840,
664 					   qtable_creative_pccam);
665 		if (err < 0)
666 			PERR("spca50x_setup_qtable failed");
667 
668 		/* Init SDRAM - needed for SDRAM access */
669 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
670 
671 		/* switch to video camera mode */
672 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
673 
674 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
675 			PERR("reg_r_wait() failed");
676 
677 		reg_r(gspca_dev, 0x816b, 1);
678 		Data = gspca_dev->usb_buf[0];
679 		reg_w(gspca_dev, 0x00, 0x816b, Data);
680 		break;
681 	case CreativePCCam300:		/* Creative PC-CAM 300 640x480 CCD */
682 	case IntelPocketPCCamera:	/* FIXME: Temporary fix for
683 					 *	Intel Pocket PC Camera
684 					 *	- NWG (Sat 29th March 2003) */
685 
686 		/* do a full reset */
687 		err = spca500_full_reset(gspca_dev);
688 		if (err < 0)
689 			PERR("spca500_full_reset failed");
690 
691 		/* enable drop packet */
692 		err = reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
693 		if (err < 0)
694 			PERR("failed to enable drop packet");
695 		reg_w(gspca_dev, 0x00, 0x8880, 3);
696 		err = spca50x_setup_qtable(gspca_dev,
697 					   0x00, 0x8800, 0x8840,
698 					   qtable_creative_pccam);
699 		if (err < 0)
700 			PERR("spca50x_setup_qtable failed");
701 
702 		spca500_setmode(gspca_dev, xmult, ymult);
703 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
704 
705 		/* switch to video camera mode */
706 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
707 
708 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
709 			PERR("reg_r_wait() failed");
710 
711 		reg_r(gspca_dev, 0x816b, 1);
712 		Data = gspca_dev->usb_buf[0];
713 		reg_w(gspca_dev, 0x00, 0x816b, Data);
714 
715 /*		write_vector(gspca_dev, spca500_visual_defaults); */
716 		break;
717 	case KodakEZ200:		/* Kodak EZ200 */
718 
719 		/* do a full reset */
720 		err = spca500_full_reset(gspca_dev);
721 		if (err < 0)
722 			PERR("spca500_full_reset failed");
723 		/* enable drop packet */
724 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
725 		reg_w(gspca_dev, 0x00, 0x8880, 0);
726 		err = spca50x_setup_qtable(gspca_dev,
727 					   0x00, 0x8800, 0x8840,
728 					   qtable_kodak_ez200);
729 		if (err < 0)
730 			PERR("spca50x_setup_qtable failed");
731 		spca500_setmode(gspca_dev, xmult, ymult);
732 
733 		reg_w(gspca_dev, 0x20, 0x0001, 0x0004);
734 
735 		/* switch to video camera mode */
736 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
737 
738 		if (reg_r_wait(gspca_dev, 0, 0x8000, 0x44) != 0)
739 			PERR("reg_r_wait() failed");
740 
741 		reg_r(gspca_dev, 0x816b, 1);
742 		Data = gspca_dev->usb_buf[0];
743 		reg_w(gspca_dev, 0x00, 0x816b, Data);
744 
745 /*		write_vector(gspca_dev, spca500_visual_defaults); */
746 		break;
747 
748 	case BenqDC1016:
749 	case DLinkDSC350:		/* FamilyCam 300 */
750 	case AiptekPocketDV:		/* Aiptek PocketDV */
751 	case Gsmartmini:		/*Mustek Gsmart Mini */
752 	case MustekGsmart300:		/* Mustek Gsmart 300 */
753 	case PalmPixDC85:
754 	case Optimedia:
755 	case ToptroIndus:
756 	case AgfaCl20:
757 		spca500_reinit(gspca_dev);
758 		reg_w(gspca_dev, 0x00, 0x0d01, 0x01);
759 		/* enable drop packet */
760 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
761 
762 		err = spca50x_setup_qtable(gspca_dev,
763 				   0x00, 0x8800, 0x8840, qtable_pocketdv);
764 		if (err < 0)
765 			PERR("spca50x_setup_qtable failed");
766 		reg_w(gspca_dev, 0x00, 0x8880, 2);
767 
768 		/* familycam Quicksmart pocketDV stuff */
769 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
770 		/* Set agc transfer: synced between frames */
771 		reg_w(gspca_dev, 0x00, 0x820f, 0x01);
772 		/* Init SDRAM - needed for SDRAM access */
773 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
774 
775 		spca500_setmode(gspca_dev, xmult, ymult);
776 		/* switch to video camera mode */
777 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
778 
779 		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
780 
781 		reg_r(gspca_dev, 0x816b, 1);
782 		Data = gspca_dev->usb_buf[0];
783 		reg_w(gspca_dev, 0x00, 0x816b, Data);
784 		break;
785 	case LogitechTraveler:
786 	case LogitechClickSmart510:
787 		reg_w(gspca_dev, 0x02, 0x00, 0x00);
788 		/* enable drop packet */
789 		reg_w(gspca_dev, 0x00, 0x850a, 0x0001);
790 
791 		err = spca50x_setup_qtable(gspca_dev,
792 					0x00, 0x8800,
793 					0x8840, qtable_creative_pccam);
794 		if (err < 0)
795 			PERR("spca50x_setup_qtable failed");
796 		reg_w(gspca_dev, 0x00, 0x8880, 3);
797 		reg_w(gspca_dev, 0x00, 0x800a, 0x00);
798 		/* Init SDRAM - needed for SDRAM access */
799 		reg_w(gspca_dev, 0x00, 0x870a, 0x04);
800 
801 		spca500_setmode(gspca_dev, xmult, ymult);
802 
803 		/* switch to video camera mode */
804 		reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
805 		reg_r_wait(gspca_dev, 0, 0x8000, 0x44);
806 
807 		reg_r(gspca_dev, 0x816b, 1);
808 		Data = gspca_dev->usb_buf[0];
809 		reg_w(gspca_dev, 0x00, 0x816b, Data);
810 		write_vector(gspca_dev, Clicksmart510_defaults);
811 		break;
812 	}
813 	return 0;
814 }
815 
816 static void sd_stopN(struct gspca_dev *gspca_dev)
817 {
818 	reg_w(gspca_dev, 0, 0x8003, 0x00);
819 
820 	/* switch to video camera mode */
821 	reg_w(gspca_dev, 0x00, 0x8000, 0x0004);
822 	reg_r(gspca_dev, 0x8000, 1);
823 	PDEBUG(D_STREAM, "stop SPCA500 done reg8000: 0x%2x",
824 		gspca_dev->usb_buf[0]);
825 }
826 
827 static void sd_pkt_scan(struct gspca_dev *gspca_dev,
828 			u8 *data,			/* isoc packet */
829 			int len)			/* iso packet length */
830 {
831 	struct sd *sd = (struct sd *) gspca_dev;
832 	int i;
833 	static __u8 ffd9[] = {0xff, 0xd9};
834 
835 /* frames are jpeg 4.1.1 without 0xff escape */
836 	if (data[0] == 0xff) {
837 		if (data[1] != 0x01) {	/* drop packet */
838 /*			gspca_dev->last_packet_type = DISCARD_PACKET; */
839 			return;
840 		}
841 		gspca_frame_add(gspca_dev, LAST_PACKET,
842 					ffd9, 2);
843 
844 		/* put the JPEG header in the new frame */
845 		gspca_frame_add(gspca_dev, FIRST_PACKET,
846 			sd->jpeg_hdr, JPEG_HDR_SZ);
847 
848 		data += SPCA500_OFFSET_DATA;
849 		len -= SPCA500_OFFSET_DATA;
850 	} else {
851 		data += 1;
852 		len -= 1;
853 	}
854 
855 	/* add 0x00 after 0xff */
856 	i = 0;
857 	do {
858 		if (data[i] == 0xff) {
859 			gspca_frame_add(gspca_dev, INTER_PACKET,
860 					data, i + 1);
861 			len -= i;
862 			data += i;
863 			*data = 0x00;
864 			i = 0;
865 		}
866 		i++;
867 	} while (i < len);
868 	gspca_frame_add(gspca_dev, INTER_PACKET, data, len);
869 }
870 
871 static void setbrightness(struct gspca_dev *gspca_dev, s32 val)
872 {
873 	reg_w(gspca_dev, 0x00, 0x8167,
874 			(__u8) (val - 128));
875 }
876 
877 static void setcontrast(struct gspca_dev *gspca_dev, s32 val)
878 {
879 	reg_w(gspca_dev, 0x00, 0x8168, val);
880 }
881 
882 static void setcolors(struct gspca_dev *gspca_dev, s32 val)
883 {
884 	reg_w(gspca_dev, 0x00, 0x8169, val);
885 }
886 
887 static int sd_s_ctrl(struct v4l2_ctrl *ctrl)
888 {
889 	struct gspca_dev *gspca_dev =
890 		container_of(ctrl->handler, struct gspca_dev, ctrl_handler);
891 
892 	gspca_dev->usb_err = 0;
893 
894 	if (!gspca_dev->streaming)
895 		return 0;
896 
897 	switch (ctrl->id) {
898 	case V4L2_CID_BRIGHTNESS:
899 		setbrightness(gspca_dev, ctrl->val);
900 		break;
901 	case V4L2_CID_CONTRAST:
902 		setcontrast(gspca_dev, ctrl->val);
903 		break;
904 	case V4L2_CID_SATURATION:
905 		setcolors(gspca_dev, ctrl->val);
906 		break;
907 	}
908 	return gspca_dev->usb_err;
909 }
910 
911 static const struct v4l2_ctrl_ops sd_ctrl_ops = {
912 	.s_ctrl = sd_s_ctrl,
913 };
914 
915 static int sd_init_controls(struct gspca_dev *gspca_dev)
916 {
917 	struct v4l2_ctrl_handler *hdl = &gspca_dev->ctrl_handler;
918 
919 	gspca_dev->vdev.ctrl_handler = hdl;
920 	v4l2_ctrl_handler_init(hdl, 3);
921 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
922 			V4L2_CID_BRIGHTNESS, 0, 255, 1, 127);
923 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
924 			V4L2_CID_CONTRAST, 0, 63, 1, 31);
925 	v4l2_ctrl_new_std(hdl, &sd_ctrl_ops,
926 			V4L2_CID_SATURATION, 0, 63, 1, 31);
927 
928 	if (hdl->error) {
929 		pr_err("Could not initialize controls\n");
930 		return hdl->error;
931 	}
932 	return 0;
933 }
934 
935 /* sub-driver description */
936 static const struct sd_desc sd_desc = {
937 	.name = MODULE_NAME,
938 	.config = sd_config,
939 	.init = sd_init,
940 	.init_controls = sd_init_controls,
941 	.start = sd_start,
942 	.stopN = sd_stopN,
943 	.pkt_scan = sd_pkt_scan,
944 };
945 
946 /* -- module initialisation -- */
947 static const struct usb_device_id device_table[] = {
948 	{USB_DEVICE(0x040a, 0x0300), .driver_info = KodakEZ200},
949 	{USB_DEVICE(0x041e, 0x400a), .driver_info = CreativePCCam300},
950 	{USB_DEVICE(0x046d, 0x0890), .driver_info = LogitechTraveler},
951 	{USB_DEVICE(0x046d, 0x0900), .driver_info = LogitechClickSmart310},
952 	{USB_DEVICE(0x046d, 0x0901), .driver_info = LogitechClickSmart510},
953 	{USB_DEVICE(0x04a5, 0x300c), .driver_info = BenqDC1016},
954 	{USB_DEVICE(0x04fc, 0x7333), .driver_info = PalmPixDC85},
955 	{USB_DEVICE(0x055f, 0xc200), .driver_info = MustekGsmart300},
956 	{USB_DEVICE(0x055f, 0xc220), .driver_info = Gsmartmini},
957 	{USB_DEVICE(0x06bd, 0x0404), .driver_info = AgfaCl20},
958 	{USB_DEVICE(0x06be, 0x0800), .driver_info = Optimedia},
959 	{USB_DEVICE(0x084d, 0x0003), .driver_info = DLinkDSC350},
960 	{USB_DEVICE(0x08ca, 0x0103), .driver_info = AiptekPocketDV},
961 	{USB_DEVICE(0x2899, 0x012c), .driver_info = ToptroIndus},
962 	{USB_DEVICE(0x8086, 0x0630), .driver_info = IntelPocketPCCamera},
963 	{}
964 };
965 MODULE_DEVICE_TABLE(usb, device_table);
966 
967 /* -- device connect -- */
968 static int sd_probe(struct usb_interface *intf,
969 			const struct usb_device_id *id)
970 {
971 	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd),
972 				THIS_MODULE);
973 }
974 
975 static struct usb_driver sd_driver = {
976 	.name = MODULE_NAME,
977 	.id_table = device_table,
978 	.probe = sd_probe,
979 	.disconnect = gspca_disconnect,
980 #ifdef CONFIG_PM
981 	.suspend = gspca_suspend,
982 	.resume = gspca_resume,
983 	.reset_resume = gspca_resume,
984 #endif
985 };
986 
987 module_usb_driver(sd_driver);
988