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