• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500-V1.0.1.40_1.0.68/src/linux/linux-2.6/drivers/media/video/usbvideo/
1/*
2 * Driver for Logitech Quickcam Messenger usb video camera
3 * Copyright (C) Jaya Kumar
4 *
5 * This work was sponsored by CIS(M) Sdn Bhd.
6 * History:
7 * 05/08/2006 - Jaya Kumar
8 * I wrote this based on the konicawc by Simon Evans.
9 * -
10 * Full credit for reverse engineering and creating an initial
11 * working linux driver for the VV6422 goes to the qce-ga project by
12 * Tuukka Toivonen, Jochen Hoenicke, Peter McConnell,
13 * Cristiano De Michele, Georg Acher, Jean-Frederic Clere as well as
14 * others.
15 * ---
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
29 *
30 */
31
32#include <linux/kernel.h>
33#include <linux/module.h>
34#include <linux/init.h>
35#include <linux/input.h>
36#include <linux/usb/input.h>
37
38#include "usbvideo.h"
39#include "quickcam_messenger.h"
40
41/*
42 * Version Information
43 */
44
45#ifdef CONFIG_USB_DEBUG
46static int debug;
47#define DEBUG(n, format, arg...) \
48	if (n <= debug) {	 \
49		printk(KERN_DEBUG __FILE__ ":%s(): " format "\n", __FUNCTION__ , ## arg); \
50	}
51#else
52#define DEBUG(n, arg...)
53static const int debug = 0;
54#endif
55
56#define DRIVER_VERSION "v0.01"
57#define DRIVER_DESC "Logitech Quickcam Messenger USB"
58
59#define USB_LOGITECH_VENDOR_ID	0x046D
60#define USB_QCM_PRODUCT_ID	0x08F0
61
62#define MAX_CAMERAS	1
63
64#define MAX_COLOUR	32768
65#define MAX_HUE		32768
66#define MAX_BRIGHTNESS	32768
67#define MAX_CONTRAST	32768
68#define MAX_WHITENESS	32768
69
70static int size = SIZE_320X240;
71static int colour = MAX_COLOUR;
72static int hue = MAX_HUE;
73static int brightness =	MAX_BRIGHTNESS;
74static int contrast =	MAX_CONTRAST;
75static int whiteness =	MAX_WHITENESS;
76
77static struct usbvideo *cams;
78
79static struct usb_device_id qcm_table [] = {
80	{ USB_DEVICE(USB_LOGITECH_VENDOR_ID, USB_QCM_PRODUCT_ID) },
81	{ }
82};
83MODULE_DEVICE_TABLE(usb, qcm_table);
84
85#ifdef CONFIG_INPUT
86static void qcm_register_input(struct qcm *cam, struct usb_device *dev)
87{
88	struct input_dev *input_dev;
89	int error;
90
91	usb_make_path(dev, cam->input_physname, sizeof(cam->input_physname));
92	strncat(cam->input_physname, "/input0", sizeof(cam->input_physname));
93
94	cam->input = input_dev = input_allocate_device();
95	if (!input_dev) {
96		warn("insufficient mem for cam input device");
97		return;
98	}
99
100	input_dev->name = "QCM button";
101	input_dev->phys = cam->input_physname;
102	usb_to_input_id(dev, &input_dev->id);
103	input_dev->cdev.dev = &dev->dev;
104
105	input_dev->evbit[0] = BIT(EV_KEY);
106	input_dev->keybit[LONG(BTN_0)] = BIT(BTN_0);
107
108	input_dev->private = cam;
109
110	error = input_register_device(cam->input);
111	if (error) {
112		warn("Failed to register camera's input device, err: %d\n",
113		     error);
114		input_free_device(cam->input);
115		cam->input = NULL;
116	}
117}
118
119static void qcm_unregister_input(struct qcm *cam)
120{
121	if (cam->input) {
122		input_unregister_device(cam->input);
123		cam->input = NULL;
124	}
125}
126
127static void qcm_report_buttonstat(struct qcm *cam)
128{
129	if (cam->input) {
130		input_report_key(cam->input, BTN_0, cam->button_sts);
131		input_sync(cam->input);
132	}
133}
134
135static void qcm_int_irq(struct urb *urb)
136{
137	int ret;
138	struct uvd *uvd = urb->context;
139	struct qcm *cam;
140
141	if (!CAMERA_IS_OPERATIONAL(uvd))
142		return;
143
144	if (!uvd->streaming)
145		return;
146
147	uvd->stats.urb_count++;
148
149	if (urb->status < 0)
150		uvd->stats.iso_err_count++;
151	else {
152		if (urb->actual_length > 0 ) {
153			cam = (struct qcm *) uvd->user_data;
154			if (cam->button_sts_buf == 0x88)
155				cam->button_sts = 0x0;
156			else if (cam->button_sts_buf == 0x80)
157				cam->button_sts = 0x1;
158			qcm_report_buttonstat(cam);
159		}
160	}
161
162	ret = usb_submit_urb(urb, GFP_ATOMIC);
163	if (ret < 0)
164		err("usb_submit_urb error (%d)", ret);
165}
166
167static int qcm_setup_input_int(struct qcm *cam, struct uvd *uvd)
168{
169	int errflag;
170	usb_fill_int_urb(cam->button_urb, uvd->dev,
171			usb_rcvintpipe(uvd->dev, uvd->video_endp + 1),
172			&cam->button_sts_buf,
173			1,
174			qcm_int_irq,
175			uvd, 16);
176
177	errflag = usb_submit_urb(cam->button_urb, GFP_KERNEL);
178	if (errflag)
179		err ("usb_submit_int ret %d", errflag);
180	return errflag;
181}
182
183static void qcm_stop_int_data(struct qcm *cam)
184{
185	usb_kill_urb(cam->button_urb);
186}
187
188static int qcm_alloc_int_urb(struct qcm *cam)
189{
190	cam->button_urb = usb_alloc_urb(0, GFP_KERNEL);
191
192	if (!cam->button_urb)
193		return -ENOMEM;
194
195	return 0;
196}
197
198static void qcm_free_int(struct qcm *cam)
199{
200	usb_free_urb(cam->button_urb);
201}
202#endif /* CONFIG_INPUT */
203
204static int qcm_stv_setb(struct usb_device *dev, u16 reg, u8 val)
205{
206	int ret;
207
208	/* we'll wait up to 3 slices but no more */
209	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
210		0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
211		reg, 0, &val, 1, 3*HZ);
212	return ret;
213}
214
215static int qcm_stv_setw(struct usb_device *dev, u16 reg, u16 val)
216{
217	int ret;
218
219	/* we'll wait up to 3 slices but no more */
220	ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
221		0x04, USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE,
222		reg, 0, &val, 2, 3*HZ);
223	return ret;
224}
225
226static int qcm_stv_getw(struct usb_device *dev, unsigned short reg,
227							__le16 *val)
228{
229	int ret;
230
231	/* we'll wait up to 3 slices but no more */
232	ret = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
233		0x04, USB_TYPE_VENDOR | USB_DIR_IN | USB_RECIP_DEVICE,
234		reg, 0, val, 2, 3*HZ);
235	return ret;
236}
237
238static int qcm_camera_on(struct uvd *uvd)
239{
240	int ret;
241	CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x01));
242	return 0;
243}
244
245static int qcm_camera_off(struct uvd *uvd)
246{
247	int ret;
248	CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
249	return 0;
250}
251
252static void qcm_hsv2rgb(u16 hue, u16 sat, u16 val, u16 *r, u16 *g, u16 *b)
253{
254	unsigned int segment, valsat;
255	signed int   h = (signed int) hue;
256	unsigned int s = (sat - 32768) * 2;	/* rescale */
257	unsigned int v = val;
258	unsigned int p;
259
260	/*
261	the registers controling gain are 8 bit of which
262	we affect only the last 4 bits with our gain.
263	we know that if saturation is 0, (unsaturated) then
264	we're grayscale (center axis of the colour cone) so
265	we set rgb=value. we use a formula obtained from
266	wikipedia to map the cone to the RGB plane. it's
267	as follows for the human value case of h=0..360,
268	s=0..1, v=0..1
269	h_i = h/60 % 6 , f = h/60 - h_i , p = v(1-s)
270	q = v(1 - f*s) , t = v(1 - (1-f)s)
271	h_i==0 => r=v , g=t, b=p
272	h_i==1 => r=q , g=v, b=p
273	h_i==2 => r=p , g=v, b=t
274	h_i==3 => r=p , g=q, b=v
275	h_i==4 => r=t , g=p, b=v
276	h_i==5 => r=v , g=p, b=q
277	the bottom side (the point) and the stuff just up
278	of that is black so we simplify those two cases.
279	*/
280	if (sat < 32768) {
281		/* anything less than this is unsaturated */
282		*r = val;
283		*g = val;
284		*b = val;
285		return;
286	}
287	if (val <= (0xFFFF/8)) {
288		/* anything less than this is black */
289		*r = 0;
290		*g = 0;
291		*b = 0;
292		return;
293	}
294
295	/* the rest of this code is copying tukkat's
296	implementation of the hsv2rgb conversion as taken
297	from qc-usb-messenger code. the 10923 is 0xFFFF/6
298	to divide the cone into 6 sectors.  */
299
300	segment = (h + 10923) & 0xFFFF;
301	segment = segment*3 >> 16;		/* 0..2: 0=R, 1=G, 2=B */
302	hue -= segment * 21845;			/* -10923..10923 */
303	h = hue;
304	h *= 3;
305	valsat = v*s >> 16;			/* 0..65534 */
306	p = v - valsat;
307	if (h >= 0) {
308		unsigned int t = v - (valsat * (32769 - h) >> 15);
309		switch (segment) {
310		case 0:	/* R-> */
311			*r = v;
312			*g = t;
313			*b = p;
314			break;
315		case 1:	/* G-> */
316			*r = p;
317			*g = v;
318			*b = t;
319			break;
320		case 2:	/* B-> */
321			*r = t;
322			*g = p;
323			*b = v;
324			break;
325		}
326	} else {
327		unsigned int q = v - (valsat * (32769 + h) >> 15);
328		switch (segment) {
329		case 0:	/* ->R */
330			*r = v;
331			*g = p;
332			*b = q;
333			break;
334		case 1:	/* ->G */
335			*r = q;
336			*g = v;
337			*b = p;
338			break;
339		case 2:	/* ->B */
340			*r = p;
341			*g = q;
342			*b = v;
343			break;
344		}
345	}
346}
347
348static int qcm_sensor_set_gains(struct uvd *uvd, u16 hue,
349	u16 saturation, u16 value)
350{
351	int ret;
352	u16 r=0,g=0,b=0;
353
354	/* this code is based on qc-usb-messenger */
355	qcm_hsv2rgb(hue, saturation, value, &r, &g, &b);
356
357	r >>= 12;
358	g >>= 12;
359	b >>= 12;
360
361	/* min val is 8 */
362	r = max((u16) 8, r);
363	g = max((u16) 8, g);
364	b = max((u16) 8, b);
365
366	r |= 0x30;
367	g |= 0x30;
368	b |= 0x30;
369
370	/* set the r,g,b gain registers */
371	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x0509, r));
372	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050A, g));
373	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050B, b));
374
375	/* doing as qc-usb did */
376	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050C, 0x2A));
377	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x050D, 0x01));
378	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
379
380	return 0;
381}
382
383static int qcm_sensor_set_exposure(struct uvd *uvd, int exposure)
384{
385	int ret;
386	int formedval;
387
388	/* calculation was from qc-usb-messenger driver */
389	formedval = ( exposure >> 12 );
390
391	/* max value for formedval is 14 */
392	formedval = min(formedval, 14);
393
394	CHECK_RET(ret, qcm_stv_setb(uvd->dev,
395			0x143A, 0xF0 | formedval));
396	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
397	return 0;
398}
399
400static int qcm_sensor_setlevels(struct uvd *uvd, int brightness, int contrast,
401					int hue, int colour)
402{
403	int ret;
404	/* brightness is exposure, contrast is gain, colour is saturation */
405	CHECK_RET(ret,
406		qcm_sensor_set_exposure(uvd, brightness));
407	CHECK_RET(ret, qcm_sensor_set_gains(uvd, hue, colour, contrast));
408
409	return 0;
410}
411
412static int qcm_sensor_setsize(struct uvd *uvd, u8 size)
413{
414	int ret;
415
416	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x1505, size));
417	return 0;
418}
419
420static int qcm_sensor_set_shutter(struct uvd *uvd, int whiteness)
421{
422	int ret;
423	/* some rescaling as done by the qc-usb-messenger code */
424	if (whiteness > 0xC000)
425		whiteness = 0xC000 + (whiteness & 0x3FFF)*8;
426
427	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143D,
428				(whiteness >> 8) & 0xFF));
429	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143E,
430				(whiteness >> 16) & 0x03));
431	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x143F, 0x01));
432
433	return 0;
434}
435
436static int qcm_sensor_init(struct uvd *uvd)
437{
438	struct qcm *cam = (struct qcm *) uvd->user_data;
439	int ret;
440	int i;
441
442	for (i=0; i < sizeof(regval_table)/sizeof(regval_table[0]) ; i++) {
443		CHECK_RET(ret, qcm_stv_setb(uvd->dev,
444					regval_table[i].reg,
445					regval_table[i].val));
446	}
447
448	CHECK_RET(ret, qcm_stv_setw(uvd->dev, 0x15c1,
449				cpu_to_le16(ISOC_PACKET_SIZE)));
450	CHECK_RET(ret, qcm_stv_setb(uvd->dev, 0x15c3, 0x08));
451	CHECK_RET(ret, ret = qcm_stv_setb(uvd->dev, 0x143f, 0x01));
452
453	CHECK_RET(ret, qcm_stv_setb(uvd->dev, STV_ISO_ENABLE, 0x00));
454
455	CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
456
457	CHECK_RET(ret, qcm_sensor_setlevels(uvd, uvd->vpic.brightness,
458			uvd->vpic.contrast, uvd->vpic.hue, uvd->vpic.colour));
459
460	CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
461	CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
462
463	return 0;
464}
465
466static int qcm_set_camera_size(struct uvd *uvd)
467{
468	int ret;
469	struct qcm *cam = (struct qcm *) uvd->user_data;
470
471	CHECK_RET(ret, qcm_sensor_setsize(uvd, camera_sizes[cam->size].cmd));
472	cam->width = camera_sizes[cam->size].width;
473	cam->height = camera_sizes[cam->size].height;
474	uvd->videosize = VIDEOSIZE(cam->width, cam->height);
475
476	return 0;
477}
478
479static int qcm_setup_on_open(struct uvd *uvd)
480{
481	int ret;
482
483	CHECK_RET(ret, qcm_sensor_set_gains(uvd, uvd->vpic.hue,
484				uvd->vpic.colour, uvd->vpic.contrast));
485	CHECK_RET(ret, qcm_sensor_set_exposure(uvd, uvd->vpic.brightness));
486	CHECK_RET(ret, qcm_sensor_set_shutter(uvd, uvd->vpic.whiteness));
487	CHECK_RET(ret, qcm_set_camera_size(uvd));
488	CHECK_RET(ret, qcm_camera_on(uvd));
489	return 0;
490}
491
492static void qcm_adjust_picture(struct uvd *uvd)
493{
494	int ret;
495	struct qcm *cam = (struct qcm *) uvd->user_data;
496
497	ret = qcm_camera_off(uvd);
498	if (ret) {
499		err("can't turn camera off. abandoning pic adjustment");
500		return;
501	}
502
503	/* if there's been a change in contrast, hue, or
504	colour then we need to recalculate hsv in order
505	to update gains */
506	if ((cam->contrast != uvd->vpic.contrast) ||
507		(cam->hue != uvd->vpic.hue) ||
508		(cam->colour != uvd->vpic.colour)) {
509		cam->contrast = uvd->vpic.contrast;
510		cam->hue = uvd->vpic.hue;
511		cam->colour = uvd->vpic.colour;
512		ret = qcm_sensor_set_gains(uvd, cam->hue, cam->colour,
513						cam->contrast);
514		if (ret) {
515			err("can't set gains. abandoning pic adjustment");
516			return;
517		}
518	}
519
520	if (cam->brightness != uvd->vpic.brightness) {
521		cam->brightness = uvd->vpic.brightness;
522		ret = qcm_sensor_set_exposure(uvd, cam->brightness);
523		if (ret) {
524			err("can't set exposure. abandoning pic adjustment");
525			return;
526		}
527	}
528
529	if (cam->whiteness != uvd->vpic.whiteness) {
530		cam->whiteness = uvd->vpic.whiteness;
531		qcm_sensor_set_shutter(uvd, cam->whiteness);
532		if (ret) {
533			err("can't set shutter. abandoning pic adjustment");
534			return;
535		}
536	}
537
538	ret = qcm_camera_on(uvd);
539	if (ret) {
540		err("can't reenable camera. pic adjustment failed");
541		return;
542	}
543}
544
545static int qcm_process_frame(struct uvd *uvd, u8 *cdata, int framelen)
546{
547	int datalen;
548	int totaldata;
549	struct framehdr {
550		__be16 id;
551		__be16 len;
552	};
553	struct framehdr *fhdr;
554
555	totaldata = 0;
556	while (framelen) {
557		fhdr = (struct framehdr *) cdata;
558		datalen = be16_to_cpu(fhdr->len);
559		framelen -= 4;
560		cdata += 4;
561
562		if ((fhdr->id) == cpu_to_be16(0x8001)) {
563			RingQueue_Enqueue(&uvd->dp, marker, 4);
564			totaldata += 4;
565			continue;
566		}
567		if ((fhdr->id & cpu_to_be16(0xFF00)) == cpu_to_be16(0x0200)) {
568			RingQueue_Enqueue(&uvd->dp, cdata, datalen);
569			totaldata += datalen;
570		}
571		framelen -= datalen;
572		cdata += datalen;
573	}
574	return totaldata;
575}
576
577static int qcm_compress_iso(struct uvd *uvd, struct urb *dataurb)
578{
579	int totlen;
580	int i;
581	unsigned char *cdata;
582
583	totlen=0;
584	for (i = 0; i < dataurb->number_of_packets; i++) {
585		int n = dataurb->iso_frame_desc[i].actual_length;
586		int st = dataurb->iso_frame_desc[i].status;
587
588		cdata = dataurb->transfer_buffer +
589			dataurb->iso_frame_desc[i].offset;
590
591		if (st < 0) {
592			warn("Data error: packet=%d. len=%d. status=%d.",
593			      i, n, st);
594			uvd->stats.iso_err_count++;
595			continue;
596		}
597		if (!n)
598			continue;
599
600		totlen += qcm_process_frame(uvd, cdata, n);
601	}
602	return totlen;
603}
604
605static void resubmit_urb(struct uvd *uvd, struct urb *urb)
606{
607	int ret;
608
609	urb->dev = uvd->dev;
610	ret = usb_submit_urb(urb, GFP_ATOMIC);
611	if (ret)
612		err("usb_submit_urb error (%d)", ret);
613}
614
615static void qcm_isoc_irq(struct urb *urb)
616{
617	int len;
618	struct uvd *uvd = urb->context;
619
620	if (!CAMERA_IS_OPERATIONAL(uvd))
621		return;
622
623	if (!uvd->streaming)
624		return;
625
626	uvd->stats.urb_count++;
627
628	if (!urb->actual_length) {
629		resubmit_urb(uvd, urb);
630		return;
631	}
632
633	len = qcm_compress_iso(uvd, urb);
634	resubmit_urb(uvd, urb);
635	uvd->stats.urb_length = len;
636	uvd->stats.data_count += len;
637	if (len)
638		RingQueue_WakeUpInterruptible(&uvd->dp);
639}
640
641static int qcm_start_data(struct uvd *uvd)
642{
643	struct qcm *cam = (struct qcm *) uvd->user_data;
644	int i;
645	int errflag;
646	int pktsz;
647	int err;
648
649	pktsz = uvd->iso_packet_len;
650	if (!CAMERA_IS_OPERATIONAL(uvd)) {
651		err("Camera is not operational");
652		return -EFAULT;
653	}
654
655	err = usb_set_interface(uvd->dev, uvd->iface, uvd->ifaceAltActive);
656	if (err < 0) {
657		err("usb_set_interface error");
658		uvd->last_error = err;
659		return -EBUSY;
660	}
661
662	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
663		int j, k;
664		struct urb *urb = uvd->sbuf[i].urb;
665		urb->dev = uvd->dev;
666		urb->context = uvd;
667		urb->pipe = usb_rcvisocpipe(uvd->dev, uvd->video_endp);
668		urb->interval = 1;
669		urb->transfer_flags = URB_ISO_ASAP;
670		urb->transfer_buffer = uvd->sbuf[i].data;
671		urb->complete = qcm_isoc_irq;
672		urb->number_of_packets = FRAMES_PER_DESC;
673		urb->transfer_buffer_length = pktsz * FRAMES_PER_DESC;
674		for (j=k=0; j < FRAMES_PER_DESC; j++, k += pktsz) {
675			urb->iso_frame_desc[j].offset = k;
676			urb->iso_frame_desc[j].length = pktsz;
677		}
678	}
679
680	uvd->streaming = 1;
681	uvd->curframe = -1;
682	for (i=0; i < USBVIDEO_NUMSBUF; i++) {
683		errflag = usb_submit_urb(uvd->sbuf[i].urb, GFP_KERNEL);
684		if (errflag)
685			err ("usb_submit_isoc(%d) ret %d", i, errflag);
686	}
687
688	CHECK_RET(err, qcm_setup_input_int(cam, uvd));
689	CHECK_RET(err, qcm_camera_on(uvd));
690	return 0;
691}
692
693static void qcm_stop_data(struct uvd *uvd)
694{
695	struct qcm *cam = (struct qcm *) uvd->user_data;
696	int i, j;
697	int ret;
698
699	if ((uvd == NULL) || (!uvd->streaming) || (uvd->dev == NULL))
700		return;
701
702	ret = qcm_camera_off(uvd);
703	if (ret)
704		warn("couldn't turn the cam off.");
705
706	uvd->streaming = 0;
707
708	/* Unschedule all of the iso td's */
709	for (i=0; i < USBVIDEO_NUMSBUF; i++)
710		usb_kill_urb(uvd->sbuf[i].urb);
711
712	qcm_stop_int_data(cam);
713
714	if (!uvd->remove_pending) {
715		/* Set packet size to 0 */
716		j = usb_set_interface(uvd->dev, uvd->iface,
717					uvd->ifaceAltInactive);
718		if (j < 0) {
719			err("usb_set_interface() error %d.", j);
720			uvd->last_error = j;
721		}
722	}
723}
724
725static void qcm_process_isoc(struct uvd *uvd, struct usbvideo_frame *frame)
726{
727	struct qcm *cam = (struct qcm *) uvd->user_data;
728	int x;
729	struct rgb *rgbL0;
730	struct rgb *rgbL1;
731	struct bayL0 *bayL0;
732	struct bayL1 *bayL1;
733	int hor,ver,hordel,verdel;
734	assert(frame != NULL);
735
736	switch (cam->size) {
737	case SIZE_160X120:
738		hor = 162; ver = 124; hordel = 1; verdel = 2;
739		break;
740	case SIZE_320X240:
741	default:
742		hor = 324; ver = 248; hordel = 2; verdel = 4;
743		break;
744	}
745
746	if (frame->scanstate == ScanState_Scanning) {
747		while (RingQueue_GetLength(&uvd->dp) >=
748			 4 + (hor*verdel + hordel)) {
749			if ((RING_QUEUE_PEEK(&uvd->dp, 0) == 0x00) &&
750			    (RING_QUEUE_PEEK(&uvd->dp, 1) == 0xff) &&
751			    (RING_QUEUE_PEEK(&uvd->dp, 2) == 0x00) &&
752			    (RING_QUEUE_PEEK(&uvd->dp, 3) == 0xff)) {
753				frame->curline = 0;
754				frame->scanstate = ScanState_Lines;
755				frame->frameState = FrameState_Grabbing;
756				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 4);
757			/*
758			* if we're starting, we need to discard the first
759			* 4 lines of y bayer data
760			* and the first 2 gr elements of x bayer data
761			*/
762				RING_QUEUE_DEQUEUE_BYTES(&uvd->dp,
763							(hor*verdel + hordel));
764				break;
765			}
766			RING_QUEUE_DEQUEUE_BYTES(&uvd->dp, 1);
767		}
768	}
769
770	if (frame->scanstate == ScanState_Scanning)
771		return;
772
773	/* now we can start processing bayer data so long as we have at least
774	* 2 lines worth of data. this is the simplest demosaicing method that
775	* I could think of. I use each 2x2 bayer element without interpolation
776	* to generate 4 rgb pixels.
777	*/
778	while ( frame->curline < cam->height &&
779		(RingQueue_GetLength(&uvd->dp) >= hor*2)) {
780		/* get 2 lines of bayer for demosaicing
781		 * into 2 lines of RGB */
782		RingQueue_Dequeue(&uvd->dp, cam->scratch, hor*2);
783		bayL0 = (struct bayL0 *) cam->scratch;
784		bayL1 = (struct bayL1 *) (cam->scratch + hor);
785		/* frame->curline is the rgb y line */
786		rgbL0 = (struct rgb *)
787				( frame->data + (cam->width*3*frame->curline));
788		/* w/2 because we're already doing 2 pixels */
789		rgbL1 = rgbL0 + (cam->width/2);
790
791		for (x=0; x < cam->width; x+=2) {
792			rgbL0->r = bayL0->r;
793			rgbL0->g = bayL0->g;
794			rgbL0->b = bayL1->b;
795
796			rgbL0->r2 = bayL0->r;
797			rgbL0->g2 = bayL1->g;
798			rgbL0->b2 = bayL1->b;
799
800			rgbL1->r = bayL0->r;
801			rgbL1->g = bayL1->g;
802			rgbL1->b = bayL1->b;
803
804			rgbL1->r2 = bayL0->r;
805			rgbL1->g2 = bayL1->g;
806			rgbL1->b2 = bayL1->b;
807
808			rgbL0++;
809			rgbL1++;
810
811			bayL0++;
812			bayL1++;
813		}
814
815		frame->seqRead_Length += cam->width*3*2;
816		frame->curline += 2;
817	}
818	/* See if we filled the frame */
819	if (frame->curline == cam->height) {
820		frame->frameState = FrameState_Done_Hold;
821		frame->curline = 0;
822		uvd->curframe = -1;
823		uvd->stats.frame_num++;
824	}
825}
826
827/* taken from konicawc */
828static int qcm_set_video_mode(struct uvd *uvd, struct video_window *vw)
829{
830	int ret;
831	int newsize;
832	int oldsize;
833	int x = vw->width;
834	int y = vw->height;
835	struct qcm *cam = (struct qcm *) uvd->user_data;
836
837	if (x > 0 && y > 0) {
838		DEBUG(2, "trying to find size %d,%d", x, y);
839		for (newsize = 0; newsize <= MAX_FRAME_SIZE; newsize++) {
840			if ((camera_sizes[newsize].width == x) &&
841				(camera_sizes[newsize].height == y))
842				break;
843		}
844	} else
845		newsize = cam->size;
846
847	if (newsize > MAX_FRAME_SIZE) {
848		DEBUG(1, "couldn't find size %d,%d", x, y);
849		return -EINVAL;
850	}
851
852	if (newsize == cam->size) {
853		DEBUG(1, "Nothing to do");
854		return 0;
855	}
856
857	qcm_stop_data(uvd);
858
859	if (cam->size != newsize) {
860		oldsize = cam->size;
861		cam->size = newsize;
862		ret = qcm_set_camera_size(uvd);
863		if (ret) {
864			err("Couldn't set camera size, err=%d",ret);
865			/* restore the original size */
866			cam->size = oldsize;
867			return ret;
868		}
869	}
870
871	/* Flush the input queue and clear any current frame in progress */
872
873	RingQueue_Flush(&uvd->dp);
874	if (uvd->curframe != -1) {
875		uvd->frame[uvd->curframe].curline = 0;
876		uvd->frame[uvd->curframe].seqRead_Length = 0;
877		uvd->frame[uvd->curframe].seqRead_Index = 0;
878	}
879
880	CHECK_RET(ret, qcm_start_data(uvd));
881	return 0;
882}
883
884static int qcm_configure_video(struct uvd *uvd)
885{
886	int ret;
887	memset(&uvd->vpic, 0, sizeof(uvd->vpic));
888	memset(&uvd->vpic_old, 0x55, sizeof(uvd->vpic_old));
889
890	uvd->vpic.colour = colour;
891	uvd->vpic.hue = hue;
892	uvd->vpic.brightness = brightness;
893	uvd->vpic.contrast = contrast;
894	uvd->vpic.whiteness = whiteness;
895	uvd->vpic.depth = 24;
896	uvd->vpic.palette = VIDEO_PALETTE_RGB24;
897
898	memset(&uvd->vcap, 0, sizeof(uvd->vcap));
899	strcpy(uvd->vcap.name, "QCM USB Camera");
900	uvd->vcap.type = VID_TYPE_CAPTURE;
901	uvd->vcap.channels = 1;
902	uvd->vcap.audios = 0;
903
904	uvd->vcap.minwidth = camera_sizes[SIZE_160X120].width;
905	uvd->vcap.minheight = camera_sizes[SIZE_160X120].height;
906	uvd->vcap.maxwidth = camera_sizes[SIZE_320X240].width;
907	uvd->vcap.maxheight = camera_sizes[SIZE_320X240].height;
908
909	memset(&uvd->vchan, 0, sizeof(uvd->vchan));
910	uvd->vchan.flags = 0 ;
911	uvd->vchan.tuners = 0;
912	uvd->vchan.channel = 0;
913	uvd->vchan.type = VIDEO_TYPE_CAMERA;
914	strcpy(uvd->vchan.name, "Camera");
915
916	CHECK_RET(ret, qcm_sensor_init(uvd));
917	return 0;
918}
919
920static int qcm_probe(struct usb_interface *intf,
921			const struct usb_device_id *devid)
922{
923	int err;
924	struct uvd *uvd;
925	struct usb_device *dev = interface_to_usbdev(intf);
926	struct qcm *cam;
927	size_t buffer_size;
928	unsigned char video_ep;
929	struct usb_host_interface *interface;
930	struct usb_endpoint_descriptor *endpoint;
931	int i,j;
932	unsigned int ifacenum, ifacenum_inact=0;
933	__le16 sensor_id;
934
935	/* we don't support multiconfig cams */
936	if (dev->descriptor.bNumConfigurations != 1)
937		return -ENODEV;
938
939	/* first check for the video interface and not
940	* the audio interface */
941	interface = &intf->cur_altsetting[0];
942	if ((interface->desc.bInterfaceClass != USB_CLASS_VENDOR_SPEC)
943		|| (interface->desc.bInterfaceSubClass !=
944			USB_CLASS_VENDOR_SPEC))
945		return -ENODEV;
946
947	/*
948	walk through each endpoint in each setting in the interface
949	stop when we find the one that's an isochronous IN endpoint.
950	*/
951	for (i=0; i < intf->num_altsetting; i++) {
952		interface = &intf->cur_altsetting[i];
953		ifacenum = interface->desc.bAlternateSetting;
954		/* walk the end points */
955		for (j=0; j < interface->desc.bNumEndpoints; j++) {
956			endpoint = &interface->endpoint[j].desc;
957
958			if ((endpoint->bEndpointAddress &
959				USB_ENDPOINT_DIR_MASK) != USB_DIR_IN)
960				continue; /* not input then not good */
961
962			buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
963			if (!buffer_size) {
964				ifacenum_inact = ifacenum;
965				continue; /* 0 pkt size is not what we want */
966			}
967
968			if ((endpoint->bmAttributes &
969				USB_ENDPOINT_XFERTYPE_MASK) ==
970				USB_ENDPOINT_XFER_ISOC) {
971				video_ep = endpoint->bEndpointAddress;
972				/* break out of the search */
973				goto good_videoep;
974			}
975		}
976	}
977	/* failed out since nothing useful was found */
978	err("No suitable endpoint was found\n");
979	return -ENODEV;
980
981good_videoep:
982	/* disable isochronous stream before doing anything else */
983	err = qcm_stv_setb(dev, STV_ISO_ENABLE, 0);
984	if (err < 0) {
985		err("Failed to disable sensor stream");
986		return -EIO;
987	}
988
989	/*
990	Check that this is the same unknown sensor that is known to work. This
991	sensor is suspected to be the ST VV6422C001. I'll check the same value
992	that the qc-usb driver checks. This value is probably not even the
993	sensor ID since it matches the USB dev ID. Oh well. If it doesn't
994	match, it's probably a diff sensor so exit and apologize.
995	*/
996	err = qcm_stv_getw(dev, CMOS_SENSOR_IDREV, &sensor_id);
997	if (err < 0) {
998		err("Couldn't read sensor values. Err %d\n",err);
999		return err;
1000	}
1001	if (sensor_id != cpu_to_le16(0x08F0)) {
1002		err("Sensor ID %x != %x. Unsupported. Sorry\n",
1003			le16_to_cpu(sensor_id), (0x08F0));
1004		return -ENODEV;
1005	}
1006
1007	uvd = usbvideo_AllocateDevice(cams);
1008	if (!uvd)
1009		return -ENOMEM;
1010
1011	cam = (struct qcm *) uvd->user_data;
1012
1013	/* buf for doing demosaicing */
1014	cam->scratch = kmalloc(324*2, GFP_KERNEL);
1015	if (!cam->scratch) /* uvd freed in dereg */
1016		return -ENOMEM;
1017
1018	/* yes, if we fail after here, cam->scratch gets freed
1019	by qcm_free_uvd */
1020
1021	err = qcm_alloc_int_urb(cam);
1022	if (err < 0)
1023		return err;
1024
1025	/* yes, if we fail after here, int urb gets freed
1026	by qcm_free_uvd */
1027
1028	RESTRICT_TO_RANGE(size, SIZE_160X120, SIZE_320X240);
1029	cam->width = camera_sizes[size].width;
1030	cam->height = camera_sizes[size].height;
1031	cam->size = size;
1032
1033	uvd->debug = debug;
1034	uvd->flags = 0;
1035	uvd->dev = dev;
1036	uvd->iface = intf->altsetting->desc.bInterfaceNumber;
1037	uvd->ifaceAltActive = ifacenum;
1038	uvd->ifaceAltInactive = ifacenum_inact;
1039	uvd->video_endp = video_ep;
1040	uvd->iso_packet_len = buffer_size;
1041	uvd->paletteBits = 1L << VIDEO_PALETTE_RGB24;
1042	uvd->defaultPalette = VIDEO_PALETTE_RGB24;
1043	uvd->canvas = VIDEOSIZE(320, 240);
1044	uvd->videosize = VIDEOSIZE(cam->width, cam->height);
1045	err = qcm_configure_video(uvd);
1046	if (err) {
1047		err("failed to configure video settings");
1048		return err;
1049	}
1050
1051	err = usbvideo_RegisterVideoDevice(uvd);
1052	if (err) { /* the uvd gets freed in Deregister */
1053		err("usbvideo_RegisterVideoDevice() failed.");
1054		return err;
1055	}
1056
1057	uvd->max_frame_size = (320 * 240 * 3);
1058	qcm_register_input(cam, dev);
1059	usb_set_intfdata(intf, uvd);
1060	return 0;
1061}
1062
1063static void qcm_free_uvd(struct uvd *uvd)
1064{
1065	struct qcm *cam = (struct qcm *) uvd->user_data;
1066
1067	kfree(cam->scratch);
1068	qcm_unregister_input(cam);
1069	qcm_free_int(cam);
1070}
1071
1072static struct usbvideo_cb qcm_driver = {
1073	.probe = 		qcm_probe,
1074	.setupOnOpen = 		qcm_setup_on_open,
1075	.processData = 		qcm_process_isoc,
1076	.setVideoMode = 	qcm_set_video_mode,
1077	.startDataPump = 	qcm_start_data,
1078	.stopDataPump = 	qcm_stop_data,
1079	.adjustPicture = 	qcm_adjust_picture,
1080	.userFree = 		qcm_free_uvd
1081};
1082
1083static int __init qcm_init(void)
1084{
1085	info(DRIVER_DESC " " DRIVER_VERSION);
1086
1087	return usbvideo_register(
1088		&cams,
1089		MAX_CAMERAS,
1090		sizeof(struct qcm),
1091		"QCM",
1092		&qcm_driver,
1093		THIS_MODULE,
1094		qcm_table);
1095}
1096
1097static void __exit qcm_exit(void)
1098{
1099	usbvideo_Deregister(&cams);
1100}
1101
1102module_param(size, int, 0);
1103MODULE_PARM_DESC(size, "Initial Size 0: 160x120 1: 320x240");
1104module_param(colour, int, 0);
1105MODULE_PARM_DESC(colour, "Initial colour");
1106module_param(hue, int, 0);
1107MODULE_PARM_DESC(hue, "Initial hue");
1108module_param(brightness, int, 0);
1109MODULE_PARM_DESC(brightness, "Initial brightness");
1110module_param(contrast, int, 0);
1111MODULE_PARM_DESC(contrast, "Initial contrast");
1112module_param(whiteness, int, 0);
1113MODULE_PARM_DESC(whiteness, "Initial whiteness");
1114
1115#ifdef CONFIG_USB_DEBUG
1116module_param(debug, int, S_IRUGO | S_IWUSR);
1117MODULE_PARM_DESC(debug, "Debug level: 0-9 (default=0)");
1118#endif
1119
1120module_init(qcm_init);
1121module_exit(qcm_exit);
1122
1123MODULE_LICENSE("GPL");
1124MODULE_AUTHOR("Jaya Kumar");
1125MODULE_DESCRIPTION("QCM USB Camera");
1126MODULE_SUPPORTED_DEVICE("QCM USB Camera");
1127