stk014.c revision 4aa0d037a6c8e6b37ecfd986a444f83190c32a21
1/*
2 * Syntek DV4000 (STK014) subdriver
3 *
4 * Copyright (C) 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 "stk014"
23
24#include "gspca.h"
25#include "jpeg.h"
26
27#define DRIVER_VERSION_NUMBER	KERNEL_VERSION(0, 1, 0)
28static const char version[] = "0.1.0";
29
30MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>");
31MODULE_DESCRIPTION("Syntek DV4000 (STK014) USB Camera Driver");
32MODULE_LICENSE("GPL");
33
34/* specific webcam descriptor */
35struct sd {
36	struct gspca_dev gspca_dev;	/* !! must be the first item */
37
38	unsigned char brightness;
39	unsigned char contrast;
40	unsigned char colors;
41};
42
43/* global parameters */
44static int lightfreq = 50;
45static int sd_quant = 7;		/* <= 4 KO - 7: good (enough!) */
46
47/* V4L2 controls supported by the driver */
48static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val);
49static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val);
50static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val);
51static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val);
52static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val);
53static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val);
54
55static struct ctrl sd_ctrls[] = {
56#define SD_BRIGHTNESS 0
57	{
58	    {
59		.id      = V4L2_CID_BRIGHTNESS,
60		.type    = V4L2_CTRL_TYPE_INTEGER,
61		.name    = "Brightness",
62		.minimum = 0,
63		.maximum = 255,
64		.step    = 1,
65		.default_value = 127,
66	    },
67	    .set = sd_setbrightness,
68	    .get = sd_getbrightness,
69	},
70#define SD_CONTRAST 1
71	{
72	    {
73		.id      = V4L2_CID_CONTRAST,
74		.type    = V4L2_CTRL_TYPE_INTEGER,
75		.name    = "Contrast",
76		.minimum = 0,
77		.maximum = 255,
78		.step    = 1,
79		.default_value = 127,
80	    },
81	    .set = sd_setcontrast,
82	    .get = sd_getcontrast,
83	},
84#define SD_COLOR 2
85	{
86	    {
87		.id      = V4L2_CID_SATURATION,
88		.type    = V4L2_CTRL_TYPE_INTEGER,
89		.name    = "Saturation",
90		.minimum = 0,
91		.maximum = 255,
92		.step    = 1,
93		.default_value = 127,
94	    },
95	    .set = sd_setcolors,
96	    .get = sd_getcolors,
97	},
98};
99
100static struct cam_mode vga_mode[] = {
101	{V4L2_PIX_FMT_JPEG, 320, 240},
102	{V4L2_PIX_FMT_JPEG, 640, 480},
103};
104
105/* -- read a register -- */
106static int reg_read(struct gspca_dev *gspca_dev,
107			__u16 index, __u8 *buf)
108{
109	int ret;
110	struct usb_device *dev = gspca_dev->dev;
111
112	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
113			0x00,
114			USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
115			0x00,
116			index,
117			buf, 1,
118			500);
119	if (ret < 0)
120		PDEBUG(D_ERR, "reg_read err %d", ret);
121	return ret;
122}
123
124/* -- write a register -- */
125static int reg_write(struct gspca_dev *gspca_dev,
126			__u16 index, __u16 value)
127{
128	struct usb_device *dev = gspca_dev->dev;
129	int ret;
130
131	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
132			0x01,
133			USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
134			value,
135			index,
136			NULL,
137			0,
138			500);
139	if (ret < 0)
140		PDEBUG(D_ERR, "reg_write err %d", ret);
141	return ret;
142}
143
144/* -- get a value -- */
145static int rcv_val(struct gspca_dev *gspca_dev,
146			int ads,
147			int len)
148{
149	struct usb_device *dev = gspca_dev->dev;
150	int alen, ret;
151	unsigned char bulk_buf[4];
152
153	reg_write(gspca_dev, 0x634, (ads >> 16) & 0xff);
154	reg_write(gspca_dev, 0x635, (ads >> 8) & 0xff);
155	reg_write(gspca_dev, 0x636, ads & 0xff);
156	reg_write(gspca_dev, 0x637, 0);
157	reg_write(gspca_dev, 0x638, len & 0xff);
158	reg_write(gspca_dev, 0x639, len >> 8);
159	reg_write(gspca_dev, 0x63a, 0);
160	reg_write(gspca_dev, 0x63b, 0);
161	reg_write(gspca_dev, 0x630, 5);
162	if (len > sizeof bulk_buf)
163		return -1;
164	ret = usb_bulk_msg(dev,
165			usb_rcvbulkpipe(dev, 5),
166			bulk_buf,
167			len,
168			&alen,
169			500);	/* timeout in milliseconds */
170	return ret;
171}
172
173/* -- send a value -- */
174static int snd_val(struct gspca_dev *gspca_dev,
175			int ads,
176			unsigned int val)
177{
178	struct usb_device *dev = gspca_dev->dev;
179	int alen, ret;
180	__u8 value, seq;
181	unsigned char bulk_buf[4];
182
183	if (ads == 0x003f08) {
184		ret = reg_read(gspca_dev, 0x0704, &value);
185		if (ret < 0)
186			goto ko;
187		ret = reg_read(gspca_dev, 0x0705, &seq);
188		if (ret < 0)
189			goto ko;
190		ret = reg_read(gspca_dev, 0x0650, &value);
191		if (ret < 0)
192			goto ko;
193		reg_write(gspca_dev, 0x654, seq);
194	} else
195		reg_write(gspca_dev, 0x654, (ads >> 16) & 0xff);
196	reg_write(gspca_dev, 0x655, (ads >> 8) & 0xff);
197	reg_write(gspca_dev, 0x656, ads & 0xff);
198	reg_write(gspca_dev, 0x657, 0);
199	reg_write(gspca_dev, 0x658, 0x04);	/* size */
200	reg_write(gspca_dev, 0x659, 0);
201	reg_write(gspca_dev, 0x65a, 0);
202	reg_write(gspca_dev, 0x65b, 0);
203	reg_write(gspca_dev, 0x650, 5);
204	bulk_buf[0] = (val >> 24) & 0xff;
205	bulk_buf[1] = (val >> 16) & 0xff;
206	bulk_buf[2] = (val >> 8) & 0xff;
207	bulk_buf[3] = val & 0xff;
208	ret = usb_bulk_msg(dev,
209			usb_sndbulkpipe(dev, 6),
210			bulk_buf,
211			4,
212			&alen,
213			500);	/* timeout in milliseconds */
214	if (ret < 0)
215		goto ko;
216	if (ads == 0x003f08) {
217		seq += 4;
218		seq &= 0x3f;
219		reg_write(gspca_dev, 0x705, seq);
220	}
221	return ret;
222ko:
223	PDEBUG(D_ERR, "snd_val err %d", ret);
224	return ret;
225}
226
227/* set a camera parameter */
228static int set_par(struct gspca_dev *gspca_dev,
229		   int parval)
230{
231	return snd_val(gspca_dev, 0x003f08, parval);
232}
233
234static void setbrightness(struct gspca_dev *gspca_dev)
235{
236	struct sd *sd = (struct sd *) gspca_dev;
237	int parval;
238
239	PDEBUG(D_CONF, "brightness: %d", sd->brightness);
240	parval = 0x06000000		/* whiteness */
241		+ (sd->brightness << 16);
242	set_par(gspca_dev, parval);
243}
244
245static void setcontrast(struct gspca_dev *gspca_dev)
246{
247	struct sd *sd = (struct sd *) gspca_dev;
248	int parval;
249
250	PDEBUG(D_CONF, "contrast: %d", sd->contrast);
251	parval = 0x07000000		/* contrast */
252		+ (sd->contrast << 16);
253	set_par(gspca_dev, parval);
254}
255
256static void setcolors(struct gspca_dev *gspca_dev)
257{
258	struct sd *sd = (struct sd *) gspca_dev;
259	int parval;
260
261	PDEBUG(D_CONF, "saturation: %d",
262		sd->colors);
263	parval = 0x08000000		/* saturation */
264		+ (sd->colors << 16);
265	set_par(gspca_dev, parval);
266}
267
268/* this function is called at probe time */
269static int sd_config(struct gspca_dev *gspca_dev,
270			const struct usb_device_id *id)
271{
272	struct sd *sd = (struct sd *) gspca_dev;
273	struct cam *cam = &gspca_dev->cam;
274
275	cam->dev_name = (char *) id->driver_info;
276	cam->epaddr = 0x02;
277	gspca_dev->cam.cam_mode = vga_mode;
278	gspca_dev->cam.nmodes = sizeof vga_mode / sizeof vga_mode[0];
279	sd->brightness = sd_ctrls[SD_BRIGHTNESS].qctrl.default_value;
280	sd->contrast = sd_ctrls[SD_CONTRAST].qctrl.default_value;
281	sd->colors = sd_ctrls[SD_COLOR].qctrl.default_value;
282	return 0;
283}
284
285/* this function is called at open time */
286static int sd_open(struct gspca_dev *gspca_dev)
287{
288	__u8 value;
289	int ret;
290
291	/* check if the device responds */
292	usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
293	ret = reg_read(gspca_dev, 0x0740, &value);
294	if (ret < 0)
295		return ret;
296	if (value != 0xff) {
297		PDEBUG(D_ERR|D_STREAM, "init reg: 0x%02x", value);
298		return -1;
299	}
300	return 0;
301}
302
303/* -- start the camera -- */
304static void sd_start(struct gspca_dev *gspca_dev)
305{
306	__u8 dum;
307	int ret, value;
308
309	/* work on alternate 1 */
310	usb_set_interface(gspca_dev->dev, gspca_dev->iface, 1);
311
312	set_par(gspca_dev, 0x10000000);
313	set_par(gspca_dev, 0x00000000);
314	set_par(gspca_dev, 0x8002e001);
315	set_par(gspca_dev, 0x14000000);
316	if (gspca_dev->width > 320)
317		value = 0x8002e001;		/* 640x480 */
318	else
319		value = 0x4001f000;		/* 320x240 */
320	set_par(gspca_dev, value);
321	ret = usb_set_interface(gspca_dev->dev,
322					gspca_dev->iface,
323					gspca_dev->alt);
324	if (ret < 0)
325		goto out;
326	ret = reg_read(gspca_dev, 0x0630, &dum);
327	if (ret < 0)
328		goto out;
329	rcv_val(gspca_dev, 0x000020, 4);	/* << (value ff ff ff ff) */
330	ret = reg_read(gspca_dev, 0x0650, &dum);
331	if (ret < 0)
332		goto out;
333	snd_val(gspca_dev, 0x000020, 0xffffffff);
334	reg_write(gspca_dev, 0x0620, 0);
335	reg_write(gspca_dev, 0x0630, 0);
336	reg_write(gspca_dev, 0x0640, 0);
337	reg_write(gspca_dev, 0x0650, 0);
338	reg_write(gspca_dev, 0x0660, 0);
339	setbrightness(gspca_dev);		/* whiteness */
340	setcontrast(gspca_dev);			/* contrast */
341	setcolors(gspca_dev);			/* saturation */
342	set_par(gspca_dev, 0x09800000);		/* Red ? */
343	set_par(gspca_dev, 0x0a800000);		/* Green ? */
344	set_par(gspca_dev, 0x0b800000);		/* Blue ? */
345	set_par(gspca_dev, 0x0d030000);		/* Gamma ? */
346	set_par(gspca_dev, lightfreq == 60
347			? 0x33780000		/* 60 Hz */
348			: 0x33640000);		/* 50 Hz */
349
350	/* start the video flow */
351	set_par(gspca_dev, 0x01000000);
352	set_par(gspca_dev, 0x01000000);
353	PDEBUG(D_STREAM, "camera started alt: 0x%02x", gspca_dev->alt);
354	return;
355out:
356	PDEBUG(D_ERR|D_STREAM, "camera start err %d", ret);
357}
358
359static void sd_stopN(struct gspca_dev *gspca_dev)
360{
361	struct usb_device *dev = gspca_dev->dev;
362	__u8 value;
363
364	set_par(gspca_dev, 0x02000000);
365	set_par(gspca_dev, 0x02000000);
366	usb_set_interface(dev, gspca_dev->iface, 1);
367	reg_read(gspca_dev, 0x0630, &value);
368	rcv_val(gspca_dev, 0x000020, 4);	/* << (value ff ff ff ff) */
369	reg_read(gspca_dev, 0x0650, &value);
370	snd_val(gspca_dev, 0x000020, 0xffffffff);
371	reg_write(gspca_dev, 0x0620, 0);
372	reg_write(gspca_dev, 0x0630, 0);
373	reg_write(gspca_dev, 0x0640, 0);
374	reg_write(gspca_dev, 0x0650, 0);
375	reg_write(gspca_dev, 0x0660, 0);
376	PDEBUG(D_STREAM, "camera stopped");
377}
378
379static void sd_stop0(struct gspca_dev *gspca_dev)
380{
381}
382
383static void sd_close(struct gspca_dev *gspca_dev)
384{
385}
386
387static void sd_pkt_scan(struct gspca_dev *gspca_dev,
388			struct gspca_frame *frame,	/* target */
389			unsigned char *data,		/* isoc packet */
390			int len)			/* iso packet length */
391{
392	int l;
393	static unsigned char ffd9[] = {0xff, 0xd9};
394
395	/* a frame starts with:
396	 *	- 0xff 0xfe
397	 *	- 0x08 0x00	// length (little endian ?!)
398	 *	- 4 bytes = size of whole frame (big endian - including header)
399	 *	- 0x00 0x0c
400	 *	- 0xff 0xd8
401	 *	- ..	JPEG image with escape sequences (ff 00)
402	 */
403	if (data[0] == 0xff && data[1] == 0xfe) {
404		if (gspca_dev->last_packet_type == INTER_PACKET) {
405			PDEBUG(D_ERR|D_FRAM, "sof actual l: %d init l: %d",
406				frame->data_end - frame->data,
407				frame->v4l2_buf.bytesused);
408		}
409
410		/* put the JPEG headaer */
411		jpeg_put_header(gspca_dev, frame, sd_quant, 0x22);
412
413		/* beginning of the frame */
414#define STKHDRSZ 12
415		l = (data[4] << 24)		/* frame size */
416			+ (data[5] << 16)
417			+ (data[6] << 8)
418			+ data[7]
419			- STKHDRSZ
420			+ (frame->data_end - frame->data)
421			+ 2;			/* EOF (ff d9) */
422		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
423				data + STKHDRSZ, len - STKHDRSZ);
424#undef STKHDRSZ
425		frame->v4l2_buf.bytesused = l;
426		return;
427	}
428	if (gspca_dev->last_packet_type != INTER_PACKET) {
429		if (gspca_dev->last_packet_type == LAST_PACKET) {
430			PDEBUG(D_ERR|D_PACK, "mof actual l: %d init l: %d",
431				frame->data_end - frame->data,
432				frame->v4l2_buf.bytesused);
433		}
434		return;
435	}
436
437	/* intermediate packet */
438	l = frame->data_end - frame->data;
439	if (len < frame->v4l2_buf.bytesused - 2 - l) {
440		gspca_frame_add(gspca_dev, INTER_PACKET, frame,
441				data, len);
442		return;
443	}
444
445	/* last packet */
446	if (len > frame->v4l2_buf.bytesused - 2 - l)
447		len = frame->v4l2_buf.bytesused - 2 - l;
448	gspca_frame_add(gspca_dev, INTER_PACKET, frame, data, len);
449	gspca_frame_add(gspca_dev, LAST_PACKET, frame, ffd9, 2);
450}
451
452static int sd_setbrightness(struct gspca_dev *gspca_dev, __s32 val)
453{
454	struct sd *sd = (struct sd *) gspca_dev;
455
456	sd->brightness = val;
457	if (gspca_dev->streaming)
458		setbrightness(gspca_dev);
459	return 0;
460}
461
462static int sd_getbrightness(struct gspca_dev *gspca_dev, __s32 *val)
463{
464	struct sd *sd = (struct sd *) gspca_dev;
465
466	*val = sd->brightness;
467	return 0;
468}
469
470static int sd_setcontrast(struct gspca_dev *gspca_dev, __s32 val)
471{
472	struct sd *sd = (struct sd *) gspca_dev;
473
474	sd->contrast = val;
475	if (gspca_dev->streaming)
476		setcontrast(gspca_dev);
477	return 0;
478}
479
480static int sd_getcontrast(struct gspca_dev *gspca_dev, __s32 *val)
481{
482	struct sd *sd = (struct sd *) gspca_dev;
483
484	*val = sd->contrast;
485	return 0;
486}
487
488static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val)
489{
490	struct sd *sd = (struct sd *) gspca_dev;
491
492	sd->colors = val;
493	if (gspca_dev->streaming)
494		setcolors(gspca_dev);
495	return 0;
496}
497
498static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val)
499{
500	struct sd *sd = (struct sd *) gspca_dev;
501
502	*val = sd->colors;
503	return 0;
504}
505
506/* sub-driver description */
507static struct sd_desc sd_desc = {
508	.name = MODULE_NAME,
509	.ctrls = sd_ctrls,
510	.nctrls = sizeof sd_ctrls / sizeof sd_ctrls[0],
511	.config = sd_config,
512	.open = sd_open,
513	.start = sd_start,
514	.stopN = sd_stopN,
515	.stop0 = sd_stop0,
516	.close = sd_close,
517	.pkt_scan = sd_pkt_scan,
518};
519
520/* -- module initialisation -- */
521#define DVNM(name) .driver_info = (kernel_ulong_t) name
522static __devinitdata struct usb_device_id device_table[] = {
523	{USB_DEVICE(0x05e1, 0x0893), DVNM("Syntek DV4000")},
524	{}
525};
526MODULE_DEVICE_TABLE(usb, device_table);
527
528/* -- device connect -- */
529static int sd_probe(struct usb_interface *intf,
530			const struct usb_device_id *id)
531{
532	PDEBUG(D_PROBE, "camera probe");
533	return gspca_dev_probe(intf, id, &sd_desc, sizeof(struct sd));
534}
535
536static struct usb_driver sd_driver = {
537	.name = MODULE_NAME,
538	.id_table = device_table,
539	.probe = sd_probe,
540	.disconnect = gspca_disconnect,
541};
542
543/* -- module insert / remove -- */
544static int __init sd_mod_init(void)
545{
546	if (usb_register(&sd_driver) < 0)
547		return -1;
548	info("v%s registered", version);
549	return 0;
550}
551static void __exit sd_mod_exit(void)
552{
553	usb_deregister(&sd_driver);
554	info("deregistered");
555}
556
557module_init(sd_mod_init);
558module_exit(sd_mod_exit);
559
560module_param(lightfreq, int, 0644);
561MODULE_PARM_DESC(lightfreq, "Light frequency 50 or 60 Hz");
562module_param_named(quant, sd_quant, int, 0644);
563MODULE_PARM_DESC(quant, "Quantization index (0..8)");
564