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