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