File: /usr/src/linux/drivers/usb/ov511.c

1     /*
2      * OmniVision OV511 Camera-to-USB Bridge Driver
3      *
4      * Copyright (c) 1999-2000 Mark W. McClelland
5      * Many improvements by Bret Wallach <bwallac1@san.rr.com>
6      * Color fixes by by Orion Sky Lawlor <olawlor@acm.org> (2/26/2000)
7      * Snapshot code by Kevin Moore
8      * OV7620 fixes by Charl P. Botha <cpbotha@ieee.org>
9      * Changes by Claudio Matsuoka <claudio@conectiva.com>
10      * 
11      * Based on the Linux CPiA driver written by Peter Pregler,
12      * Scott J. Bertin and Johannes Erdfelt.
13      * 
14      * Please see the file: linux/Documentation/usb/ov511.txt 
15      * and the website at:  http://alpha.dyndns.org/ov511
16      * for more info.
17      *
18      * This program is free software; you can redistribute it and/or modify it
19      * under the terms of the GNU General Public License as published by the
20      * Free Software Foundation; either version 2 of the License, or (at your
21      * option) any later version.
22      *
23      * This program is distributed in the hope that it will be useful, but
24      * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
25      * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
26      * for more details.
27      *
28      * You should have received a copy of the GNU General Public License
29      * along with this program; if not, write to the Free Software Foundation,
30      * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
31      */
32     
33     #define __NO_VERSION__
34     
35     #include <linux/config.h>
36     #include <linux/module.h>
37     #include <linux/version.h>
38     #include <linux/init.h>
39     #include <linux/fs.h>
40     #include <linux/vmalloc.h>
41     #include <linux/slab.h>
42     #include <linux/proc_fs.h>
43     #include <linux/ctype.h>
44     #include <linux/pagemap.h>
45     #include <linux/usb.h>
46     #include <asm/io.h>
47     #include <asm/semaphore.h>
48     #include <linux/wrapper.h>
49     
50     #include "ov511.h"
51     
52     /*
53      * Version Information
54      */
55     #define DRIVER_VERSION "v1.28"
56     #define DRIVER_AUTHOR "Mark McClelland <mwm@i.am> & Bret Wallach & Orion Sky Lawlor <olawlor@acm.org> & Kevin Moore & Charl P. Botha <cpbotha@ieee.org> & Claudio Matsuoka <claudio@conectiva.com>"
57     #define DRIVER_DESC "OV511 USB Camera Driver"
58     
59     #define OV511_I2C_RETRIES 3
60     
61     /* Video Size 640 x 480 x 3 bytes for RGB */
62     #define MAX_FRAME_SIZE (640 * 480 * 3)
63     #define MAX_DATA_SIZE (MAX_FRAME_SIZE + sizeof(struct timeval))
64     
65     #define GET_SEGSIZE(p) ((p) == VIDEO_PALETTE_GREY ? 256 : 384)
66     
67     /* PARAMETER VARIABLES: */
68     static int autoadjust = 1;    /* CCD dynamically changes exposure, etc... */
69     
70     static int video_nr = -1;
71     
72     /* 0=no debug messages
73      * 1=init/detection/unload and other significant messages,
74      * 2=some warning messages
75      * 3=config/control function calls
76      * 4=most function calls and data parsing messages
77      * 5=highly repetitive mesgs
78      * NOTE: This should be changed to 0, 1, or 2 for production kernels
79      */
80     static int debug = 0;
81     
82     /* Fix vertical misalignment of red and blue at 640x480 */
83     static int fix_rgb_offset = 0;
84     
85     /* Snapshot mode enabled flag */
86     static int snapshot = 0;
87     
88     /* Sensor detection override (global for all attached cameras) */
89     static int sensor = 0;
90     
91     /* Increase this if you are getting "Failed to read sensor ID..." */
92     static int i2c_detect_tries = 5;
93     
94     /* For legal values, see the OV7610/7620 specs under register Common F,
95      * upper nybble  (set to 0-F) */
96     static int aperture = -1;
97     
98     /* Force image to be read in RGB instead of BGR. This option allow
99      * programs that expect RGB data (e.g. gqcam) to work with this driver. */
100     static int force_rgb = 0;
101     
102     /* Number of seconds before inactive buffers are deallocated */
103     static int buf_timeout = 5;
104     
105     /* Number of cameras to stream from simultaneously */
106     static int cams = 1;
107     
108     /* Prevent apps from timing out if frame is not done in time */
109     static int retry_sync = 0;
110     
111     /* Enable compression. This is for experimentation only; compressed images
112      * still cannot be decoded yet. */
113     static int compress = 0;
114     
115     /* Display test pattern - doesn't work yet either */
116     static int testpat = 0;
117     
118     /* Setting this to 1 will make the sensor output GBR422 instead on YUV420. Only
119      * affects RGB24 mode. */
120     static int sensor_gbr = 0;
121     
122     /* Dump raw pixel data, in one of 3 formats. See ov511_dumppix() for details. */
123     static int dumppix = 0;
124     
125     MODULE_PARM(autoadjust, "i");
126     MODULE_PARM_DESC(autoadjust, "CCD dynamically changes exposure");
127     MODULE_PARM(debug, "i");
128     MODULE_PARM_DESC(debug, "Debug level: 0=none, 1=init/detection, 2=warning, 3=config/control, 4=function call, 5=max");
129     MODULE_PARM(fix_rgb_offset, "i");
130     MODULE_PARM_DESC(fix_rgb_offset, "Fix vertical misalignment of red and blue at 640x480");
131     MODULE_PARM(snapshot, "i");
132     MODULE_PARM_DESC(snapshot, "Enable snapshot mode");
133     MODULE_PARM(sensor, "i");
134     MODULE_PARM_DESC(sensor, "Override sensor detection");
135     MODULE_PARM(i2c_detect_tries, "i");
136     MODULE_PARM_DESC(i2c_detect_tries, "Number of tries to detect sensor");
137     MODULE_PARM(aperture, "i");
138     MODULE_PARM_DESC(aperture, "Read the OV7610/7620 specs");
139     MODULE_PARM(force_rgb, "i");
140     MODULE_PARM_DESC(force_rgb, "Read RGB instead of BGR");
141     MODULE_PARM(buf_timeout, "i");
142     MODULE_PARM_DESC(buf_timeout, "Number of seconds before buffer deallocation");
143     MODULE_PARM(cams, "i");
144     MODULE_PARM_DESC(cams, "Number of simultaneous cameras");
145     MODULE_PARM(retry_sync, "i");
146     MODULE_PARM_DESC(retry_sync, "Prevent apps from timing out");
147     MODULE_PARM(compress, "i");
148     MODULE_PARM_DESC(compress, "Turn on compression (not functional yet)");
149     MODULE_PARM(testpat, "i");
150     MODULE_PARM_DESC(testpat, "Replace image with vertical bar testpattern (only partially working)");
151     MODULE_PARM(sensor_gbr, "i");
152     MODULE_PARM_DESC(sensor_gbr, "Make sensor output GBR422 rather than YUV420");
153     MODULE_PARM(dumppix, "i");
154     MODULE_PARM_DESC(dumppix, "Dump raw pixel data, in one of 3 formats. See ov511_dumppix() for details");
155     MODULE_PARM(video_nr,"i");
156     
157     MODULE_AUTHOR( DRIVER_AUTHOR );
158     MODULE_DESCRIPTION( DRIVER_DESC );
159     MODULE_LICENSE("GPL");
160     
161     static struct usb_driver ov511_driver;
162     
163     /* I know, I know, global variables suck. This is only a temporary hack */
164     int output_offset;
165     
166     /**********************************************************************
167      * List of known OV511-based cameras
168      **********************************************************************/
169     
170     static struct cam_list clist[] = {
171     	{   0, "generic model (no ID)" },
172     	{   3, "D-Link DSB-C300" },
173     	{   4, "generic OV511/OV7610" },
174     	{   5, "Puretek PT-6007" },
175     	{  21, "Creative Labs WebCam 3" },
176     	{  36, "Koala-Cam" },
177     	{  38, "Lifeview USB Life TV" },	/* No support yet! */
178     	{ 100, "Lifeview RoboCam" },
179     	{ 102, "AverMedia InterCam Elite" },
180     	{ 112, "MediaForte MV300" },	/* or OV7110 evaluation kit */
181     	{  -1, NULL }
182     };
183     
184     static __devinitdata struct usb_device_id device_table [] = {
185     	{ USB_DEVICE(0x05a9, 0x0511) },  /* OV511 */
186     	{ USB_DEVICE(0x05a9, 0xA511) },  /* OV511+ */
187     	{ USB_DEVICE(0x0813, 0x0002) },  /* Intel Play Me2Cam OV511+ */
188     	{ }  /* Terminating entry */
189     };
190     
191     MODULE_DEVICE_TABLE (usb, device_table);
192     
193     #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
194     static struct palette_list plist[] = {
195     	{ VIDEO_PALETTE_GREY,	"GREY" },
196     	{ VIDEO_PALETTE_HI240,  "HI240" },
197     	{ VIDEO_PALETTE_RGB565, "RGB565" },
198     	{ VIDEO_PALETTE_RGB24,	"RGB24" },
199     	{ VIDEO_PALETTE_RGB32,	"RGB32" },
200     	{ VIDEO_PALETTE_RGB555, "RGB555" },
201     	{ VIDEO_PALETTE_YUV422, "YUV422" },
202     	{ VIDEO_PALETTE_YUYV,   "YUYV" },
203     	{ VIDEO_PALETTE_UYVY,   "UYVY" },
204     	{ VIDEO_PALETTE_YUV420, "YUV420" },
205     	{ VIDEO_PALETTE_YUV411, "YUV411" },
206     	{ VIDEO_PALETTE_RAW,    "RAW" },
207     	{ VIDEO_PALETTE_YUV422P,"YUV422P" },
208     	{ VIDEO_PALETTE_YUV411P,"YUV411P" },
209     	{ VIDEO_PALETTE_YUV420P,"YUV420P" },
210     	{ VIDEO_PALETTE_YUV410P,"YUV410P" },
211     	{ -1, NULL }
212     };
213     #endif
214     
215     /**********************************************************************
216      *
217      * Memory management
218      *
219      * This is a shameless copy from the USB-cpia driver (linux kernel
220      * version 2.3.29 or so, I have no idea what this code actually does ;).
221      * Actually it seems to be a copy of a shameless copy of the bttv-driver.
222      * Or that is a copy of a shameless copy of ... (To the powers: is there
223      * no generic kernel-function to do this sort of stuff?)
224      *
225      * Yes, it was a shameless copy from the bttv-driver. IIRC, Alan says
226      * there will be one, but apparentely not yet -jerdfelt
227      *
228      * So I copied it again for the OV511 driver -claudio
229      **********************************************************************/
230     
231     /* Given PGD from the address space's page table, return the kernel
232      * virtual mapping of the physical memory mapped at ADR.
233      */
234     static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
235     {
236     	unsigned long ret = 0UL;
237     	pmd_t *pmd;
238     	pte_t *ptep, pte;
239     
240     	if (!pgd_none(*pgd)) {
241     		pmd = pmd_offset(pgd, adr);
242     		if (!pmd_none(*pmd)) {
243     			ptep = pte_offset(pmd, adr);
244     			pte = *ptep;
245     			if (pte_present(pte)) {
246     				ret = (unsigned long) page_address(pte_page(pte));
247     				ret |= (adr & (PAGE_SIZE - 1));
248     			}
249     		}
250     	}
251     
252     	return ret;
253     }
254     
255     /* Here we want the physical address of the memory.
256      * This is used when initializing the contents of the
257      * area and marking the pages as reserved.
258      */
259     static inline unsigned long kvirt_to_pa(unsigned long adr)
260     {
261     	unsigned long va, kva, ret;
262     
263     	va = VMALLOC_VMADDR(adr);
264     	kva = uvirt_to_kva(pgd_offset_k(va), va);
265     	ret = __pa(kva);
266     	return ret;
267     }
268     
269     static void *rvmalloc(unsigned long size)
270     {
271     	void *mem;
272     	unsigned long adr, page;
273     
274     	/* Round it off to PAGE_SIZE */
275     	size += (PAGE_SIZE - 1);
276     	size &= ~(PAGE_SIZE - 1);
277     
278     	mem = vmalloc_32(size);
279     	if (!mem)
280     		return NULL;
281     
282     	memset(mem, 0, size); /* Clear the ram out, no junk to the user */
283     	adr = (unsigned long) mem;
284     	while (size > 0) {
285     		page = kvirt_to_pa(adr);
286     		mem_map_reserve(virt_to_page(__va(page)));
287     		adr += PAGE_SIZE;
288     		if (size > PAGE_SIZE)
289     			size -= PAGE_SIZE;
290     		else
291     			size = 0;
292     	}
293     
294     	return mem;
295     }
296     
297     static void rvfree(void *mem, unsigned long size)
298     {
299     	unsigned long adr, page;
300     
301     	if (!mem)
302     		return;
303     
304     	size += (PAGE_SIZE - 1);
305     	size &= ~(PAGE_SIZE - 1);
306     
307     	adr=(unsigned long) mem;
308     	while (size > 0) {
309     		page = kvirt_to_pa(adr);
310     		mem_map_unreserve(virt_to_page(__va(page)));
311     		adr += PAGE_SIZE;
312     		if (size > PAGE_SIZE)
313     			size -= PAGE_SIZE;
314     		else
315     			size = 0;
316     	}
317     	vfree(mem);
318     }
319     
320     /**********************************************************************
321      * /proc interface
322      * Based on the CPiA driver version 0.7.4 -claudio
323      **********************************************************************/
324     
325     #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
326     
327     static struct proc_dir_entry *ov511_proc_entry = NULL;
328     extern struct proc_dir_entry *video_proc_entry;
329     
330     #define YES_NO(x) ((x) ? "yes" : "no")
331     
332     static int ov511_read_proc(char *page, char **start, off_t off,
333                               int count, int *eof, void *data)
334     {
335     	char *out = page;
336     	int i, j, len;
337     	struct usb_ov511 *ov511 = data;
338     
339     	/* IMPORTANT: This output MUST be kept under PAGE_SIZE
340     	 *            or we need to get more sophisticated. */
341     
342     	out += sprintf (out, "driver_version  : %s\n", DRIVER_VERSION);
343     	out += sprintf (out, "custom_id       : %d\n", ov511->customid);
344     	out += sprintf (out, "model           : %s\n", ov511->desc ?
345     		clist[ov511->desc].description : "unknown");
346     	out += sprintf (out, "streaming       : %s\n", YES_NO (ov511->streaming));
347     	out += sprintf (out, "grabbing        : %s\n", YES_NO (ov511->grabbing));
348     	out += sprintf (out, "compress        : %s\n", YES_NO (ov511->compress));
349     	out += sprintf (out, "subcapture      : %s\n", YES_NO (ov511->sub_flag));
350     	out += sprintf (out, "sub_size        : %d %d %d %d\n",
351     		ov511->subx, ov511->suby, ov511->subw, ov511->subh);
352     	out += sprintf (out, "data_format     : %s\n", force_rgb ? "RGB" : "BGR");
353     	out += sprintf (out, "brightness      : %d\n", ov511->brightness >> 8);
354     	out += sprintf (out, "colour          : %d\n", ov511->colour >> 8);
355     	out += sprintf (out, "contrast        : %d\n", ov511->contrast >> 8);
356     	out += sprintf (out, "num_frames      : %d\n", OV511_NUMFRAMES);
357     	for (i = 0; i < OV511_NUMFRAMES; i++) {
358     		out += sprintf (out, "frame           : %d\n", i);
359     		out += sprintf (out, "  depth         : %d\n",
360     			ov511->frame[i].depth);
361     		out += sprintf (out, "  size          : %d %d\n",
362     			ov511->frame[i].width, ov511->frame[i].height);
363     		out += sprintf (out, "  format        : ");
364     		for (j = 0; plist[j].num >= 0; j++) {
365     			if (plist[j].num == ov511->frame[i].format) {
366     				out += sprintf (out, "%s\n", plist[j].name);
367     				break;
368     			}
369     		}
370     		if (plist[j].num < 0)
371     			out += sprintf (out, "unknown\n");
372     		out += sprintf (out, "  segsize       : %d\n",
373     			ov511->frame[i].segsize);
374     		out += sprintf (out, "  data_buffer   : 0x%p\n",
375     			ov511->frame[i].data);
376     	}
377     	out += sprintf (out, "snap_enabled    : %s\n", YES_NO (ov511->snap_enabled));
378     	out += sprintf (out, "bridge          : %s\n",
379     		ov511->bridge == BRG_OV511 ? "OV511" :
380     		ov511->bridge == BRG_OV511PLUS ? "OV511+" :
381     		"unknown");
382     	out += sprintf (out, "sensor          : %s\n",
383     		ov511->sensor == SEN_OV6620 ? "OV6620" :
384     		ov511->sensor == SEN_OV7610 ? "OV7610" :
385     		ov511->sensor == SEN_OV7620 ? "OV7620" :
386     		ov511->sensor == SEN_OV7620AE ? "OV7620AE" :
387     		"unknown");
388     	out += sprintf (out, "packet_size     : %d\n", ov511->packet_size);
389     	out += sprintf (out, "framebuffer     : 0x%p\n", ov511->fbuf);
390     	
391     	len = out - page;
392     	len -= off;
393     	if (len < count) {
394     		*eof = 1;
395     		if (len <= 0) return 0;
396     	} else
397     		len = count;
398     
399     	*start = page + off;
400     
401     	return len;
402     }
403     
404     static int ov511_write_proc(struct file *file, const char *buffer,
405                                unsigned long count, void *data)
406     {
407     	return -EINVAL;
408     }
409     
410     static void create_proc_ov511_cam (struct usb_ov511 *ov511)
411     {
412     	char name[7];
413     	struct proc_dir_entry *ent;
414     	
415     	if (!ov511_proc_entry || !ov511)
416     		return;
417     
418     	sprintf(name, "video%d", ov511->vdev.minor);
419     	PDEBUG (4, "creating /proc/video/ov511/%s", name);
420     	
421     	ent = create_proc_entry(name, S_IFREG|S_IRUGO|S_IWUSR, ov511_proc_entry);
422     
423     	if (!ent)
424     		return;
425     
426     	ent->data = ov511;
427     	ent->read_proc = ov511_read_proc;
428     	ent->write_proc = ov511_write_proc;
429     	ov511->proc_entry = ent;
430     }
431     
432     static void destroy_proc_ov511_cam (struct usb_ov511 *ov511)
433     {
434     	char name[7];
435     	
436     	if (!ov511 || !ov511->proc_entry)
437     		return;
438     	
439     	sprintf(name, "video%d", ov511->vdev.minor);
440     	PDEBUG (4, "destroying %s", name);
441     	remove_proc_entry(name, ov511_proc_entry);
442     	ov511->proc_entry = NULL;
443     }
444     
445     static void proc_ov511_create(void)
446     {
447     	/* No current standard here. Alan prefers /proc/video/ as it keeps
448     	 * /proc "less cluttered than /proc/randomcardifoundintheshed/"
449     	 * -claudio
450     	 */
451     	if (video_proc_entry == NULL) {
452     		err("Unable to initialise /proc/video/ov511");
453     		return;
454     	}
455     
456     	ov511_proc_entry = create_proc_entry("ov511", S_IFDIR, video_proc_entry);
457     
458     	if (ov511_proc_entry)
459     		ov511_proc_entry->owner = THIS_MODULE;
460     	else
461     		err("Unable to initialise /proc/ov511");
462     }
463     
464     static void proc_ov511_destroy(void)
465     {
466     	PDEBUG (3, "removing /proc/video/ov511");
467     
468     	if (ov511_proc_entry == NULL)
469     		return;
470     
471     	remove_proc_entry("ov511", video_proc_entry);
472     }
473     #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
474     
475     /**********************************************************************
476      *
477      * Camera interface
478      *
479      **********************************************************************/
480     
481     static int ov511_reg_write(struct usb_device *dev,
482     			   unsigned char reg,
483     			   unsigned char value)
484     {
485     	int rc;
486     
487     	rc = usb_control_msg(dev,
488     		usb_sndctrlpipe(dev, 0),
489     		2 /* REG_IO */,
490     		USB_TYPE_CLASS | USB_RECIP_DEVICE,
491     		0, (__u16)reg, &value, 1, HZ);	
492     
493     	PDEBUG(5, "reg write: 0x%02X:0x%02X, 0x%x", reg, value, rc);
494     
495     	if (rc < 0)
496     		err("reg write: error %d", rc);
497     
498     	return rc;
499     }
500     
501     /* returns: negative is error, pos or zero is data */
502     static int ov511_reg_read(struct usb_device *dev, unsigned char reg)
503     {
504     	int rc;
505     	unsigned char buffer[1];
506     
507     	rc = usb_control_msg(dev,
508     		usb_rcvctrlpipe(dev, 0),
509     		2 /* REG_IO */,
510     		USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
511     		0, (__u16)reg, buffer, 1, HZ);
512                                    
513     	PDEBUG(5, "reg read: 0x%02X:0x%02X", reg, buffer[0]);
514     	
515     	if (rc < 0) {
516     		err("reg read: error %d", rc);
517     		return rc;
518     	} else {
519     		return buffer[0];	
520     	}
521     }
522     
523     static int ov511_i2c_write(struct usb_device *dev,
524     			   unsigned char reg,
525     			   unsigned char value)
526     {
527     	int rc, retries;
528     
529     	PDEBUG(5, "i2c write: 0x%02X:0x%02X", reg, value);
530     
531     	/* Three byte write cycle */
532     	for (retries = OV511_I2C_RETRIES; ; ) {
533     		/* Select camera register */
534     		rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
535     		if (rc < 0) goto error;
536     
537     		/* Write "value" to I2C data port of OV511 */
538     		rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);	
539     		if (rc < 0) goto error;
540     
541     		/* Initiate 3-byte write cycle */
542     		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
543     		if (rc < 0) goto error;
544     
545     		do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
546     		while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
547     		if (rc < 0) goto error;
548     
549     		if ((rc&2) == 0) /* Ack? */
550     			break;
551     #if 0
552     		/* I2C abort */	
553     		ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
554     #endif
555     		if (--retries < 0) {
556     			err("i2c write retries exhausted");
557     			rc = -1;
558     			goto error;
559     		}
560     	}
561     
562     	return 0;
563     
564     error:
565     	err("i2c write: error %d", rc);
566     	return rc;
567     }
568     
569     /* returns: negative is error, pos or zero is data */
570     static int ov511_i2c_read(struct usb_device *dev, unsigned char reg)
571     {
572     	int rc, value, retries;
573     
574     	/* Two byte write cycle */
575     	for (retries = OV511_I2C_RETRIES; ; ) {
576     		/* Select camera register */
577     		rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
578     		if (rc < 0) goto error;
579     
580     		/* Initiate 2-byte write cycle */
581     		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
582     		if (rc < 0) goto error;
583     
584     		do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
585     		while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
586     		if (rc < 0) goto error;
587     
588     		if ((rc&2) == 0) /* Ack? */
589     			break;
590     
591     		/* I2C abort */	
592     		ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
593     
594     		if (--retries < 0) {
595     			err("i2c write retries exhausted");
596     			rc = -1;
597     			goto error;
598     		}
599     	}
600     
601     	/* Two byte read cycle */
602     	for (retries = OV511_I2C_RETRIES; ; ) {
603     		/* Initiate 2-byte read cycle */
604     		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
605     		if (rc < 0) goto error;
606     
607     		do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
608     		while (rc > 0 && ((rc&1) == 0)); /* Retry until idle */
609     		if (rc < 0) goto error;
610     
611     		if ((rc&2) == 0) /* Ack? */
612     			break;
613     
614     		/* I2C abort */	
615     		rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
616     		if (rc < 0) goto error;
617     
618     		if (--retries < 0) {
619     			err("i2c read retries exhausted");
620     			rc = -1;
621     			goto error;
622     		}
623     	}
624     
625     	value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
626     
627     	PDEBUG(5, "i2c read: 0x%02X:0x%02X", reg, value);
628     		
629     	/* This is needed to make ov511_i2c_write() work */
630     	rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
631     	if (rc < 0)
632     		goto error;
633     	
634     	return value;
635     
636     error:
637     	err("i2c read: error %d", rc);
638     	return rc;
639     }
640     
641     static int ov511_write_regvals(struct usb_device *dev,
642     			       struct ov511_regvals * pRegvals)
643     {
644     	int rc;
645     
646     	while (pRegvals->bus != OV511_DONE_BUS) {
647     		if (pRegvals->bus == OV511_REG_BUS) {
648     			if ((rc = ov511_reg_write(dev, pRegvals->reg,
649     			                           pRegvals->val)) < 0)
650     				goto error;
651     		} else if (pRegvals->bus == OV511_I2C_BUS) {
652     			if ((rc = ov511_i2c_write(dev, pRegvals->reg, 
653     			                           pRegvals->val)) < 0)
654     				goto error;
655     		} else {
656     			err("Bad regval array");
657     			rc = -1;
658     			goto error;
659     		}
660     		pRegvals++;
661     	}
662     	return 0;
663     
664     error:
665     	err("write regvals: error %d", rc);
666     	return rc;
667     }
668     
669     #ifdef OV511_DEBUG 
670     static void ov511_dump_i2c_range(struct usb_device *dev, int reg1, int regn)
671     {
672     	int i;
673     	int rc;
674     	for(i = reg1; i <= regn; i++) {
675     		rc = ov511_i2c_read(dev, i);
676     		PDEBUG(1, "OV7610[0x%X] = 0x%X", i, rc);
677     	}
678     }
679     
680     static void ov511_dump_i2c_regs(struct usb_device *dev)
681     {
682     	PDEBUG(3, "I2C REGS");
683     	ov511_dump_i2c_range(dev, 0x00, 0x7C);
684     }
685     
686     #if 0
687     static void ov511_dump_reg_range(struct usb_device *dev, int reg1, int regn)
688     {
689     	int i;
690     	int rc;
691     	for(i = reg1; i <= regn; i++) {
692     	  rc = ov511_reg_read(dev, i);
693     	  PDEBUG(1, "OV511[0x%X] = 0x%X", i, rc);
694     	}
695     }
696     
697     static void ov511_dump_regs(struct usb_device *dev)
698     {
699     	PDEBUG(1, "CAMERA INTERFACE REGS");
700     	ov511_dump_reg_range(dev, 0x10, 0x1f);
701     	PDEBUG(1, "DRAM INTERFACE REGS");
702     	ov511_dump_reg_range(dev, 0x20, 0x23);
703     	PDEBUG(1, "ISO FIFO REGS");
704     	ov511_dump_reg_range(dev, 0x30, 0x31);
705     	PDEBUG(1, "PIO REGS");
706     	ov511_dump_reg_range(dev, 0x38, 0x39);
707     	ov511_dump_reg_range(dev, 0x3e, 0x3e);
708     	PDEBUG(1, "I2C REGS");
709     	ov511_dump_reg_range(dev, 0x40, 0x49);
710     	PDEBUG(1, "SYSTEM CONTROL REGS");
711     	ov511_dump_reg_range(dev, 0x50, 0x55);
712     	ov511_dump_reg_range(dev, 0x5e, 0x5f);
713     	PDEBUG(1, "OmniCE REGS");
714     	ov511_dump_reg_range(dev, 0x70, 0x79);
715     	ov511_dump_reg_range(dev, 0x80, 0x9f);
716     	ov511_dump_reg_range(dev, 0xa0, 0xbf);
717     
718     }
719     #endif
720     #endif
721     
722     static int ov511_reset(struct usb_device *dev, unsigned char reset_type)
723     {
724     	int rc;
725     	
726     	PDEBUG(4, "Reset: type=0x%X", reset_type);
727     	rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, reset_type);
728     	rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0);
729     
730     	if (rc < 0)
731     		err("reset: command failed");
732     
733     	return rc;
734     }
735     
736     /* Temporarily stops OV511 from functioning. Must do this before changing
737      * registers while the camera is streaming */
738     static inline int ov511_stop(struct usb_device *dev)
739     {
740     	PDEBUG(4, "stopping");
741     	return (ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0x3d));
742     }
743     
744     /* Restarts OV511 after ov511_stop() is called */
745     static inline int ov511_restart(struct usb_device *dev)
746     {
747     	PDEBUG(4, "restarting");
748     	return (ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0x00));
749     }
750     
751     static int ov511_set_packet_size(struct usb_ov511 *ov511, int size)
752     {
753     	int alt, mult;
754     
755     	if (ov511_stop(ov511->dev) < 0)
756     		return -EIO;
757     
758     	mult = size >> 5;
759     
760     	if (ov511->bridge == BRG_OV511) {
761     		if (size == 0) alt = OV511_ALT_SIZE_0;
762     		else if (size == 257) alt = OV511_ALT_SIZE_257;
763     		else if (size == 513) alt = OV511_ALT_SIZE_513;
764     		else if (size == 769) alt = OV511_ALT_SIZE_769;
765     		else if (size == 993) alt = OV511_ALT_SIZE_993;
766     		else {
767     			err("Set packet size: invalid size (%d)", size);
768     			return -EINVAL;
769     		}
770     	} else if (ov511->bridge == BRG_OV511PLUS) {
771     		if (size == 0) alt = OV511PLUS_ALT_SIZE_0;
772     		else if (size == 33) alt = OV511PLUS_ALT_SIZE_33;
773     		else if (size == 129) alt = OV511PLUS_ALT_SIZE_129;
774     		else if (size == 257) alt = OV511PLUS_ALT_SIZE_257;
775     		else if (size == 385) alt = OV511PLUS_ALT_SIZE_385;
776     		else if (size == 513) alt = OV511PLUS_ALT_SIZE_513;
777     		else if (size == 769) alt = OV511PLUS_ALT_SIZE_769;
778     		else if (size == 961) alt = OV511PLUS_ALT_SIZE_961;
779     		else {
780     			err("Set packet size: invalid size (%d)", size);
781     			return -EINVAL;
782     		}
783     	} else {
784     		err("Set packet size: Invalid bridge type");
785     		return -EINVAL;
786     	}
787     
788     	PDEBUG(3, "set packet size: %d, mult=%d, alt=%d", size, mult, alt);
789     
790     	if (ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE, mult) < 0)
791     		return -ENOMEM;
792     	
793     	if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) {
794     		err("Set packet size: set interface error");
795     		return -EBUSY;
796     	}
797     
798     	// FIXME - Should we only reset the FIFO?
799     	if (ov511_reset(ov511->dev, OV511_RESET_NOREGS) < 0)
800     		return -ENOMEM;
801     
802     	ov511->packet_size = size;
803     
804     	if (ov511_restart(ov511->dev) < 0)
805     		return -EIO;
806     
807     	return 0;
808     }
809     
810     
811     static inline int
812     ov7610_set_picture(struct usb_ov511 *ov511, struct video_picture *p)
813     {
814     	int ret;
815     	struct usb_device *dev = ov511->dev;
816     
817     	PDEBUG(4, "ov511_set_picture");
818     
819     	if (ov511_stop(dev) < 0)
820     		return -EIO;
821     
822     	ov511->contrast = p->contrast;
823     	ov511->brightness = p->brightness;
824     	ov511->colour = p->colour;
825     	ov511->hue = p->hue;
826     	ov511->whiteness = p->whiteness;
827     
828     	if ((ret = ov511_i2c_read(dev, OV7610_REG_COM_B)) < 0)
829     		return -EIO;
830     #if 0
831     	/* disable auto adjust mode */
832     	if (ov511_i2c_write(dev, OV7610_REG_COM_B, ret & 0xfe) < 0)
833     		return -EIO;
834     #endif
835     	if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV7620AE
836     		|| ov511->sensor == SEN_OV6620)
837     		if (ov511_i2c_write(dev, OV7610_REG_SAT, p->colour >> 8) < 0)
838     			return -EIO;
839     
840     	if (ov511->sensor == SEN_OV7610 || ov511->sensor == SEN_OV6620) {
841     		if (ov511_i2c_write(dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
842     			return -EIO;
843     
844     		if (ov511_i2c_write(dev, OV7610_REG_RED, 0xFF - (p->hue >> 8)) < 0)
845     			return -EIO;
846     
847     		if (ov511_i2c_write(dev, OV7610_REG_BLUE, p->hue >> 8) < 0)
848     			return -EIO;
849     
850     		if (ov511_i2c_write(dev, OV7610_REG_BRT, p->brightness >> 8) < 0)
851     			return -EIO;
852     	} else if ((ov511->sensor == SEN_OV7620) 
853     	         || (ov511->sensor == SEN_OV7620AE)) {
854     #if 0
855     		int cur_sat, new_sat, tmp;
856     
857     		cur_sat = ov511_i2c_read(dev, OV7610_REG_BLUE);
858     
859     		tmp = (p->hue >> 8) - cur_sat;
860     		new_sat = (tmp < 0) ? (-tmp) | 0x80 : tmp;
861     
862     	        PDEBUG(1, "cur=%d target=%d diff=%d", cur_sat, p->hue >> 8, tmp); 
863     
864     		if (ov511_i2c_write(dev, OV7610_REG_BLUE, new_sat) < 0)
865     			return -EIO;
866     
867     	        // DEBUG_CODE
868     	        PDEBUG(1, "hue=%d", ov511_i2c_read(dev, OV7610_REG_BLUE)); 
869     
870     #endif
871     	}
872     
873     	if (ov511_restart(dev) < 0)
874     		return -EIO;
875     
876     	return 0;
877     }
878     
879     static inline int
880     ov7610_get_picture(struct usb_ov511 *ov511, struct video_picture *p)
881     {
882     	int ret;
883     	struct usb_device *dev = ov511->dev;
884     
885     	PDEBUG(4, "ov511_get_picture");
886     
887     	if (ov511_stop(dev) < 0)
888     		return -EIO;
889     
890     	if ((ret = ov511_i2c_read(dev, OV7610_REG_SAT)) < 0) return -EIO;
891     	p->colour = ret << 8;
892     
893     	if ((ret = ov511_i2c_read(dev, OV7610_REG_CNT)) < 0) return -EIO;
894     	p->contrast = ret << 8;
895     
896     	if ((ret = ov511_i2c_read(dev, OV7610_REG_BRT)) < 0) return -EIO;
897     	p->brightness = ret << 8;
898     
899     	/* This may not be the best way to do it */
900     	if ((ret = ov511_i2c_read(dev, OV7610_REG_BLUE)) < 0) return -EIO;
901     	p->hue = ret << 8;
902     
903     	p->whiteness = 105 << 8;
904     
905     	/* Can we get these from frame[0]? -claudio? */
906     	p->depth = ov511->frame[0].depth;
907     	p->palette = ov511->frame[0].format;
908     
909     	if (ov511_restart(dev) < 0)
910     		return -EIO;
911     
912     	return 0;
913     }
914     
915     /* Returns number of bits per pixel (regardless of where they are located; planar or
916      * not), or zero for unsupported format.
917      */
918     static int ov511_get_depth(int palette)
919     {
920     	switch (palette) {
921     	case VIDEO_PALETTE_GREY:    return 8;
922     	case VIDEO_PALETTE_RGB565:  return 16;
923     	case VIDEO_PALETTE_RGB24:   return 24;  
924     	case VIDEO_PALETTE_YUV422:  return 16;
925     	case VIDEO_PALETTE_YUYV:    return 16;
926     	case VIDEO_PALETTE_YUV420:  return 24;
927     	case VIDEO_PALETTE_YUV422P: return 24; /* Planar */
928     	default:		    return 0;  /* Invalid format */
929     	}
930     }
931     
932     /* LNCNT values fixed by Lawrence Glaister <lg@jfm.bc.ca> */
933     static struct mode_list mlist[] = {
934     	/* W    H   C  PXCNT LNCNT PXDIV LNDIV M420  COMA  COML */
935     	{ 640, 480, 0, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x9e },
936     	{ 640, 480, 1, 0x4f, 0x3b, 0x00, 0x00, 0x03, 0x24, 0x9e },
937     	{ 320, 240, 0, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x1e },
938     	{ 320, 240, 1, 0x27, 0x1d, 0x00, 0x00, 0x03, 0x04, 0x1e },
939     	{ 352, 288, 0, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
940     	{ 352, 288, 1, 0x2b, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
941     	{ 384, 288, 0, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
942     	{ 384, 288, 1, 0x2f, 0x25, 0x00, 0x00, 0x03, 0x04, 0x1e },
943     	{ 448, 336, 0, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x1e },
944     	{ 448, 336, 1, 0x37, 0x29, 0x00, 0x00, 0x03, 0x04, 0x1e },
945     	{ 176, 144, 0, 0x15, 0x12, 0x00, 0x00, 0x03, 0x04, 0x1e },
946     	{ 176, 144, 1, 0x15, 0x12, 0x00, 0x00, 0x03, 0x04, 0x1e },
947     	{ 160, 120, 0, 0x13, 0x0e, 0x00, 0x00, 0x03, 0x04, 0x1e },
948     	{ 160, 120, 1, 0x13, 0x0e, 0x00, 0x00, 0x03, 0x04, 0x1e },
949     	{ 0, 0 }
950     };
951     
952     static int
953     ov511_mode_init_regs(struct usb_ov511 *ov511,
954     		     int width, int height, int mode, int sub_flag)
955     {
956     	int i;
957     	struct usb_device *dev = ov511->dev;
958     	int hwsbase, hwebase, vwsbase, vwebase, hwsize, vwsize; 
959     	int hwscale = 0, vwscale = 0;
960     
961     	PDEBUG(3, "width:%d, height:%d, mode:%d, sub:%d",
962     	       width, height, mode, sub_flag);
963     
964     	if (ov511_stop(ov511->dev) < 0)
965     		return -EIO;
966     
967     	/* Dumppix only works with RGB24 */
968     	if (dumppix && (mode != VIDEO_PALETTE_RGB24)) {
969     		err("dumppix only supported with RGB 24");
970     		return -EINVAL;
971     	}
972     
973     	if (mode == VIDEO_PALETTE_GREY) {
974     		ov511_reg_write(dev, 0x16, 0x00);
975     		if (ov511->sensor == SEN_OV7610
976     		    || ov511->sensor == SEN_OV7620AE) {
977     			/* these aren't valid on the OV6620/OV7620 */
978     			ov511_i2c_write(dev, 0x0e, 0x44);
979     		}
980     		ov511_i2c_write(dev, 0x13, autoadjust ? 0x21 : 0x20);
981     
982     		/* For snapshot */
983     		ov511_reg_write(dev, 0x1e, 0x00);
984     		ov511_reg_write(dev, 0x1f, 0x01);
985     	} else {
986     		ov511_reg_write(dev, 0x16, 0x01);
987     		if (ov511->sensor == SEN_OV7610
988     		    || ov511->sensor == SEN_OV7620AE) {
989     			/* not valid on the OV6620/OV7620 */
990     			ov511_i2c_write(dev, 0x0e, 0x04);
991     		}
992     		ov511_i2c_write(dev, 0x13, autoadjust ? 0x01 : 0x00);
993     
994     		/* For snapshot */
995     		ov511_reg_write(dev, 0x1e, 0x01);
996     		ov511_reg_write(dev, 0x1f, 0x03);
997     	}
998     
999     	/* The different sensor ICs handle setting up of window differently */
1000     	switch (ov511->sensor) {
1001     	case SEN_OV7610:
1002     	case SEN_OV7620AE:
1003     		hwsbase = 0x38;
1004     		hwebase = 0x3a;
1005     		vwsbase = vwebase = 0x05;
1006     		break;
1007     	case SEN_OV6620:
1008     		hwsbase = 0x38;
1009     		hwebase = 0x3a;
1010     		vwsbase = 0x05;
1011     		vwebase = 0x06;
1012     		break;
1013     	case SEN_OV7620:
1014     		hwsbase = 0x2c;
1015     		hwebase = 0x2d;
1016     		vwsbase = vwebase = 0x05;
1017     		break;
1018     	default:
1019     		err("Invalid sensor");
1020     		return -EINVAL;
1021     	}
1022     
1023     	/* Bit 5 of COM C register varies with sensor */ 
1024     	if (ov511->sensor == SEN_OV6620) {
1025     		if (width > 176 && height > 144) {  /* CIF */
1026     			ov511_i2c_write(dev, 0x14, 0x04);
1027     			hwscale = 1;
1028     			vwscale = 1;  /* The datasheet says 0; it's wrong */
1029     			hwsize = 352;
1030     			vwsize = 288;
1031     		} else {			    /* QCIF */
1032     			ov511_i2c_write(dev, 0x14, 0x24);
1033     			hwsize = 176;
1034     			vwsize = 144;
1035     		}
1036     	}
1037     	else {
1038     		if (width > 320 && height > 240) {  /* VGA */
1039     			ov511_i2c_write(dev, 0x14, 0x04);
1040     			hwscale = 2;
1041     			vwscale = 1;
1042     			hwsize = 640;
1043     			vwsize = 480;
1044     		} else {			    /* QVGA */
1045     			ov511_i2c_write(dev, 0x14, 0x24);
1046     			hwscale = 1;
1047     			hwsize = 320;
1048     			vwsize = 240;
1049     		}	
1050     	}
1051     
1052     	/* FIXME! - This needs to be changed to support 160x120 and 6620!!! */
1053     	if (sub_flag) {
1054     		ov511_i2c_write(dev, 0x17, hwsbase+(ov511->subx>>hwscale));
1055     		ov511_i2c_write(dev, 0x18, hwebase+((ov511->subx+ov511->subw)>>hwscale));
1056     		ov511_i2c_write(dev, 0x19, vwsbase+(ov511->suby>>vwscale));
1057     		ov511_i2c_write(dev, 0x1a, vwebase+((ov511->suby+ov511->subh)>>vwscale));
1058     	} else {
1059     		ov511_i2c_write(dev, 0x17, hwsbase);
1060     		ov511_i2c_write(dev, 0x18, hwebase + (hwsize>>hwscale));
1061     		ov511_i2c_write(dev, 0x19, vwsbase);
1062     		ov511_i2c_write(dev, 0x1a, vwebase + (vwsize>>vwscale));
1063     	}
1064     
1065     	for (i = 0; mlist[i].width; i++) {
1066     		int lncnt, pxcnt, clock;
1067     
1068     		if (width != mlist[i].width || height != mlist[i].height)
1069     			continue;
1070     
1071     		if (!mlist[i].color && mode != VIDEO_PALETTE_GREY)
1072     			continue;
1073     
1074     		/* Here I'm assuming that snapshot size == image size.
1075     		 * I hope that's always true. --claudio
1076     		 */
1077     		pxcnt = sub_flag ? (ov511->subw >> 3) - 1 : mlist[i].pxcnt;
1078     		lncnt = sub_flag ? (ov511->subh >> 3) - 1 : mlist[i].lncnt;
1079     
1080     		ov511_reg_write(dev, 0x12, pxcnt);
1081     		ov511_reg_write(dev, 0x13, lncnt);
1082     		ov511_reg_write(dev, 0x14, mlist[i].pxdv);
1083     		ov511_reg_write(dev, 0x15, mlist[i].lndv);
1084     		ov511_reg_write(dev, 0x18, mlist[i].m420);
1085     
1086     		/* Snapshot additions */
1087     		ov511_reg_write(dev, 0x1a, pxcnt);
1088     		ov511_reg_write(dev, 0x1b, lncnt);
1089                     ov511_reg_write(dev, 0x1c, mlist[i].pxdv);
1090                     ov511_reg_write(dev, 0x1d, mlist[i].lndv);
1091     
1092     		/* Calculate and set the clock divisor */
1093     		clock = ((sub_flag ? ov511->subw * ov511->subh : width * height)
1094     			* (mlist[i].color ? 3 : 2) / 2) / 66000;
1095     #if 0
1096     		clock *= cams;
1097     #endif
1098     		ov511_i2c_write(dev, 0x11, clock);
1099     
1100     		/* We only have code to convert GBR -> RGB24 */
1101     		if ((mode == VIDEO_PALETTE_RGB24) && sensor_gbr)
1102     			ov511_i2c_write(dev, 0x12, mlist[i].common_A | (testpat?0x0a:0x08));
1103     		else
1104     			ov511_i2c_write(dev, 0x12, mlist[i].common_A | (testpat?0x02:0x00));
1105     
1106     		/* 7620/6620 don't have register 0x35, so play it safe */
1107     		if (ov511->sensor == SEN_OV7610 ||
1108     		    ov511->sensor == SEN_OV7620AE)
1109     			ov511_i2c_write(dev, 0x35, mlist[i].common_L);
1110     
1111     		break;
1112     	}
1113     
1114     	if (compress) {
1115     		ov511_reg_write(dev, 0x78, 0x03); // Turn on Y compression
1116     		ov511_reg_write(dev, 0x79, 0x00); // Disable LUTs
1117     	}
1118     
1119     	if (ov511_restart(ov511->dev) < 0)
1120     		return -EIO;
1121     
1122     	if (mlist[i].width == 0) {
1123     		err("Unknown mode (%d, %d): %d", width, height, mode);
1124     		return -EINVAL;
1125     	}
1126     
1127     #ifdef OV511_DEBUG
1128     	if (debug >= 5)
1129     		ov511_dump_i2c_regs(dev);
1130     #endif
1131     
1132     	return 0;
1133     }
1134     
1135     /**********************************************************************
1136      *
1137      * Color correction functions
1138      *
1139      **********************************************************************/
1140     
1141     /*
1142      * Turn a YUV4:2:0 block into an RGB block
1143      *
1144      * Video4Linux seems to use the blue, green, red channel
1145      * order convention-- rgb[0] is blue, rgb[1] is green, rgb[2] is red.
1146      *
1147      * Color space conversion coefficients taken from the excellent
1148      * http://www.inforamp.net/~poynton/ColorFAQ.html
1149      * In his terminology, this is a CCIR 601.1 YCbCr -> RGB.
1150      * Y values are given for all 4 pixels, but the U (Pb)
1151      * and V (Pr) are assumed constant over the 2x2 block.
1152      *
1153      * To avoid floating point arithmetic, the color conversion
1154      * coefficients are scaled into 16.16 fixed-point integers.
1155      * They were determined as follows:
1156      *
1157      *	double brightness = 1.0;  (0->black; 1->full scale) 
1158      *	double saturation = 1.0;  (0->greyscale; 1->full color)
1159      *	double fixScale = brightness * 256 * 256;
1160      *	int rvScale = (int)(1.402 * saturation * fixScale);
1161      *	int guScale = (int)(-0.344136 * saturation * fixScale);
1162      *	int gvScale = (int)(-0.714136 * saturation * fixScale);
1163      *	int buScale = (int)(1.772 * saturation * fixScale);
1164      *	int yScale = (int)(fixScale);	
1165      */
1166     
1167     /* LIMIT: convert a 16.16 fixed-point value to a byte, with clipping. */
1168     #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
1169     
1170     static inline void
1171     ov511_move_420_block(int yTL, int yTR, int yBL, int yBR, int u, int v, 
1172     	int rowPixels, unsigned char * rgb, int bits)
1173     {
1174     	const int rvScale = 91881;
1175     	const int guScale = -22553;
1176     	const int gvScale = -46801;
1177     	const int buScale = 116129;
1178     	const int yScale  = 65536;
1179     	int r, g, b;
1180     
1181     	g = guScale * u + gvScale * v;
1182     	if (force_rgb) {
1183     		r = buScale * u;
1184     		b = rvScale * v;
1185     	} else {
1186     		r = rvScale * v;
1187     		b = buScale * u;
1188     	}
1189     
1190     	yTL *= yScale; yTR *= yScale;
1191     	yBL *= yScale; yBR *= yScale;
1192     
1193     	if (bits == 24) {
1194     		/* Write out top two pixels */
1195     		rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); rgb[2] = LIMIT(r+yTL);
1196     		rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); rgb[5] = LIMIT(r+yTR);
1197     
1198     		/* Skip down to next line to write out bottom two pixels */
1199     		rgb += 3 * rowPixels;
1200     		rgb[0] = LIMIT(b+yBL); rgb[1] = LIMIT(g+yBL); rgb[2] = LIMIT(r+yBL);
1201     		rgb[3] = LIMIT(b+yBR); rgb[4] = LIMIT(g+yBR); rgb[5] = LIMIT(r+yBR);
1202     	} else if (bits == 16) {
1203     		/* Write out top two pixels */
1204     		rgb[0] = ((LIMIT(b+yTL) >> 3) & 0x1F) | ((LIMIT(g+yTL) << 3) & 0xE0);
1205     		rgb[1] = ((LIMIT(g+yTL) >> 5) & 0x07) | (LIMIT(r+yTL) & 0xF8);
1206     
1207     		rgb[2] = ((LIMIT(b+yTR) >> 3) & 0x1F) | ((LIMIT(g+yTR) << 3) & 0xE0);
1208     		rgb[3] = ((LIMIT(g+yTR) >> 5) & 0x07) | (LIMIT(r+yTR) & 0xF8);
1209     
1210     		/* Skip down to next line to write out bottom two pixels */
1211     		rgb += 2 * rowPixels;
1212     
1213     		rgb[0] = ((LIMIT(b+yBL) >> 3) & 0x1F) | ((LIMIT(g+yBL) << 3) & 0xE0);
1214     		rgb[1] = ((LIMIT(g+yBL) >> 5) & 0x07) | (LIMIT(r+yBL) & 0xF8);
1215     
1216     		rgb[2] = ((LIMIT(b+yBR) >> 3) & 0x1F) | ((LIMIT(g+yBR) << 3) & 0xE0);
1217     		rgb[3] = ((LIMIT(g+yBR) >> 5) & 0x07) | (LIMIT(r+yBR) & 0xF8);
1218     	}
1219     }
1220     
1221     /*
1222      * For a 640x480 YUV4:2:0 images, data shows up in 1200 384 byte segments.
1223      * The first 64 bytes of each segment are U, the next 64 are V.  The U and
1224      * V are arranged as follows:
1225      *
1226      *      0  1 ...  7
1227      *      8  9 ... 15
1228      *           ...   
1229      *     56 57 ... 63
1230      *
1231      * U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
1232      *
1233      * The next 256 bytes are full resolution Y data and represent 4 squares
1234      * of 8x8 pixels as follows:
1235      *
1236      *      0  1 ...  7    64  65 ...  71   ...  192 193 ... 199
1237      *      8  9 ... 15    72  73 ...  79        200 201 ... 207
1238      *           ...              ...                    ...
1239      *     56 57 ... 63   120 121 ... 127   ...  248 249 ... 255
1240      *
1241      * Note that the U and V data in one segment represents a 16 x 16 pixel
1242      * area, but the Y data represents a 32 x 8 pixel area.
1243      *
1244      * If dumppix module param is set, _parse_data just dumps the incoming segments,
1245      * verbatim, in order, into the frame. When used with vidcat -f ppm -s 640x480
1246      * this puts the data on the standard output and can be analyzed with the
1247      * parseppm.c utility I wrote.  That's a much faster way for figuring out how
1248      * this data is scrambled.
1249      */
1250     
1251     #define HDIV 8
1252     #define WDIV (256/HDIV)
1253     
1254     static void
1255     ov511_parse_gbr422_to_rgb24(unsigned char *pIn0, unsigned char *pOut0,
1256     		       int iOutY, int iOutUV, int iHalf, int iWidth)
1257     {
1258     	int k, l, m;
1259     	unsigned char *pIn;
1260     	unsigned char *pOut, *pOut1;
1261     
1262     	pIn = pIn0;
1263     	pOut = pOut0 + iOutUV + (force_rgb ? 2 : 0);
1264     		
1265     	for (k = 0; k < 8; k++) {
1266     		pOut1 = pOut;
1267     		for (l = 0; l < 8; l++) {
1268     			*pOut1 = *(pOut1 + 3) = *(pOut1 + iWidth*3) =
1269     				*(pOut1 + iWidth*3 + 3) = *pIn++;
1270     			pOut1 += 6;
1271     		}
1272     		pOut += iWidth*3*2;
1273     	}
1274     
1275     	pIn = pIn0 + 64;
1276     	pOut = pOut0 + iOutUV + (force_rgb ? 0 : 2);
1277     	for (k = 0; k < 8; k++) {
1278     		pOut1 = pOut;
1279     		for (l = 0; l < 8; l++) {
1280     			*pOut1 = *(pOut1 + 3) = *(pOut1 + iWidth*3) =
1281     				*(pOut1 + iWidth*3 + 3) = *pIn++;
1282     			pOut1 += 6;
1283     		}
1284     		pOut += iWidth*3*2;
1285     	}
1286     
1287     	pIn = pIn0 + 128;
1288     	pOut = pOut0 + iOutY + 1;
1289     	for (k = 0; k < 4; k++) {
1290     		pOut1 = pOut;
1291     		for (l = 0; l < 8; l++) {
1292     			for (m = 0; m < 8; m++) {
1293     				*pOut1 = *pIn++;
1294     				pOut1 += 3;
1295     			}
1296     			pOut1 += (iWidth - 8) * 3;
1297     		}
1298     		pOut += 8 * 3;
1299     	}
1300     }
1301     
1302     static void
1303     ov511_parse_yuv420_to_rgb(unsigned char *pIn0, unsigned char *pOut0,
1304     		       int iOutY, int iOutUV, int iHalf, int iWidth, int bits)
1305     {
1306     	int k, l, m;
1307     	int bytes = bits >> 3;
1308     	unsigned char *pIn;
1309     	unsigned char *pOut, *pOut1;
1310     
1311     	/* Just copy the Y's if in the first stripe */
1312     	if (!iHalf) {
1313     		pIn = pIn0 + 128;
1314     		pOut = pOut0 + iOutY;
1315     		for (k = 0; k < 4; k++) {
1316     			pOut1 = pOut;
1317     			for (l = 0; l < 8; l++) {
1318     				for (m = 0; m < 8; m++) {
1319     					*pOut1 = *pIn++;
1320     					pOut1 += bytes;
1321     				}
1322     				pOut1 += (iWidth - 8) * bytes;
1323     			}
1324     			pOut += 8 * bytes;
1325     		}
1326     	}
1327     
1328     	/* Use the first half of VUs to calculate value */
1329     	pIn = pIn0;
1330     	pOut = pOut0 + iOutUV;
1331     	for (l = 0; l < 4; l++) {
1332     		for (m=0; m<8; m++) {
1333     			int y00 = *(pOut);
1334     			int y01 = *(pOut+bytes);
1335     			int y10 = *(pOut+iWidth*bytes);
1336     			int y11 = *(pOut+iWidth*bytes+bytes);
1337     			int v   = *(pIn+64) - 128;
1338     			int u   = *pIn++ - 128;
1339     			ov511_move_420_block(y00, y01, y10, y11, u, v, iWidth,
1340     				pOut, bits);
1341     			pOut += 2 * bytes;
1342     		}
1343     		pOut += (iWidth*2 - 16) * bytes;
1344     	}
1345     
1346     	/* Just copy the other UV rows */
1347     	for (l = 0; l < 4; l++) {
1348     		for (m = 0; m < 8; m++) {
1349     			*pOut++ = *(pIn + 64);
1350     			*pOut = *pIn++;
1351     			pOut += 2 * bytes - 1;
1352     		}
1353     		pOut += (iWidth*2 - 16) * bytes;
1354     	}
1355     
1356     	/* Calculate values if it's the second half */
1357     	if (iHalf) {
1358     		pIn = pIn0 + 128;
1359     		pOut = pOut0 + iOutY;
1360     		for (k = 0; k < 4; k++) {
1361     			pOut1 = pOut;
1362     			for (l=0; l<4; l++) {
1363     				for (m=0; m<4; m++) {
1364     					int y10 = *(pIn+8);
1365     					int y00 = *pIn++;
1366     					int y11 = *(pIn+8);
1367     					int y01 = *pIn++;
1368     					int v   = *pOut1 - 128;
1369     					int u   = *(pOut1+1) - 128;
1370     					ov511_move_420_block(y00, y01, y10,
1371     						y11, u, v, iWidth, pOut1, bits);
1372     					pOut1 += 2 * bytes;
1373     				}
1374     				pOut1 += (iWidth*2 - 8) * bytes;
1375     				pIn += 8;
1376     			}
1377     			pOut += 8 * bytes;
1378     		}
1379     	}
1380     }
1381     
1382     static void
1383     ov511_dumppix(unsigned char *pIn0, unsigned char *pOut0,
1384     	      int iOutY, int iOutUV, int iHalf, int iWidth)
1385     {
1386     	int i, j, k;
1387     	unsigned char *pIn, *pOut, *pOut1;
1388     
1389     	switch (dumppix) {
1390     	case 1: /* Just dump YUV data straight out for debug */
1391     		pOut0 += iOutY;
1392     		for (i = 0; i < HDIV; i++) {
1393     			for (j = 0; j < WDIV; j++) {
1394     				*pOut0++ = *pIn0++;
1395     				*pOut0++ = *pIn0++;
1396     				*pOut0++ = *pIn0++;
1397     			}
1398     			pOut0 += (iWidth - WDIV) * 3;
1399     		}
1400     		break;
1401     	case 2: /* This converts the Y data to "black-and-white" RGB data */
1402     		/* Useful for experimenting with compression */
1403     		pIn = pIn0 + 128;
1404     		pOut = pOut0 + iOutY;
1405     		for (i = 0; i < 4; i++) {
1406     			pOut1 = pOut;
1407     			for (j = 0; j < 8; j++) {
1408     				for (k = 0; k < 8; k++) {
1409     					*pOut1++ = *pIn;
1410     					*pOut1++ = *pIn;
1411     					*pOut1++ = *pIn++;
1412     				}
1413     				pOut1 += (iWidth - 8) * 3;
1414     			}
1415     			pOut += 8 * 3;
1416     		}
1417     		break;
1418     	case 3: /* This will dump only the Y channel data stream as-is */
1419     		pIn = pIn0 + 128;
1420     		pOut = pOut0 + output_offset;
1421     		for (i = 0; i < 256; i++) {
1422     			*pOut++ = *pIn;
1423     			*pOut++ = *pIn;
1424     			*pOut++ = *pIn++;
1425     			output_offset += 3;
1426     		}
1427     		break;
1428     	} /* End switch (dumppix) */
1429     }
1430     
1431     /* This converts YUV420 segments to YUYV */
1432     static void
1433     ov511_parse_data_yuv422(unsigned char *pIn0, unsigned char *pOut0,
1434     		        int iOutY, int iOutUV, int iWidth)
1435     {
1436     	int k, l, m;
1437     	unsigned char *pIn, *pOut, *pOut1;
1438     
1439     	pIn = pIn0 + 128;
1440     	pOut = pOut0 + iOutY;
1441     	for (k = 0; k < 4; k++) {
1442     		pOut1 = pOut;
1443     		for (l = 0; l < 8; l++) {
1444     			for (m = 0; m < 8; m++) {
1445     				*pOut1 = (*pIn++);
1446     				pOut1 += 2;
1447     			}
1448     			pOut1 += (iWidth - 8) * 2;
1449     		}
1450     		pOut += 8 * 2;
1451     	}
1452     
1453     	pIn = pIn0;
1454     	pOut = pOut0 + iOutUV + 1;
1455     	for (l = 0; l < 8; l++) {
1456     		for (m=0; m<8; m++) {
1457     			int v   = *(pIn+64);
1458     			int u   = *pIn++;
1459     			
1460     			*pOut = u;
1461     			*(pOut+2) = v;
1462     			*(pOut+iWidth) = u;
1463     			*(pOut+iWidth+2) = v;
1464     			pOut += 4;
1465     		}
1466     		pOut += (iWidth*4 - 32);
1467     	}
1468     }
1469     
1470     static void
1471     ov511_parse_data_yuv420(unsigned char *pIn0, unsigned char *pOut0,
1472     		        int iOutY, int iOutUV, int iWidth, int iHeight)
1473     {
1474     	int k, l, m;
1475     	unsigned char *pIn;
1476     	unsigned char *pOut, *pOut1;
1477     	unsigned a = iWidth * iHeight;
1478     	unsigned w = iWidth / 2;
1479     
1480     	pIn = pIn0;
1481     	pOut = pOut0 + iOutUV + a;
1482     	for (k = 0; k < 8; k++) {
1483     		pOut1 = pOut;
1484     		for (l = 0; l < 8; l++) *pOut1++ = *pIn++;
1485     		pOut += w;
1486     	}
1487     
1488     	pIn = pIn0 + 64;
1489     	pOut = pOut0 + iOutUV + a + a/4;
1490     	for (k = 0; k < 8; k++) {
1491     		pOut1 = pOut;
1492     		for (l = 0; l < 8; l++) *pOut1++ = *pIn++;
1493     		pOut += w;
1494     	}
1495     
1496     	pIn = pIn0 + 128;
1497     	pOut = pOut0 + iOutY;
1498     	for (k = 0; k < 4; k++) {
1499     		pOut1 = pOut;
1500     		for (l = 0; l < 8; l++) {
1501     			for (m = 0; m < 8; m++)
1502     				*pOut1++ =*pIn++;
1503     			pOut1 += iWidth - 8;
1504     		}
1505     		pOut += 8;
1506     	}
1507     }
1508     
1509     static void
1510     ov511_parse_data_yuv422p(unsigned char *pIn0, unsigned char *pOut0,
1511     		       int iOutY, int iOutUV, int iWidth, int iHeight)
1512     {
1513     	int k, l, m;
1514     	unsigned char *pIn;
1515     	unsigned char *pOut, *pOut1;
1516     	unsigned a = iWidth * iHeight;
1517     	unsigned w = iWidth / 2;
1518     
1519     	pIn = pIn0;
1520     	pOut = pOut0 + iOutUV + a;
1521     	for (k = 0; k < 8; k++) {
1522     		pOut1 = pOut;
1523     		for (l = 0; l < 8; l++) {
1524     			*pOut1 = *(pOut1 + w) = *pIn++;
1525     			pOut1++;
1526     		}
1527     		pOut += iWidth;
1528     	}
1529     
1530     	pIn = pIn0 + 64;
1531     	pOut = pOut0 + iOutUV + a + a/2;
1532     	for (k = 0; k < 8; k++) {
1533     		pOut1 = pOut;
1534     		for (l = 0; l < 8; l++) {
1535     			*pOut1 = *(pOut1 + w) = *pIn++;
1536     			pOut1++;
1537     		}
1538     		pOut += iWidth;
1539     	}
1540     
1541     	pIn = pIn0 + 128;
1542     	pOut = pOut0 + iOutY;
1543     	for (k = 0; k < 4; k++) {
1544     		pOut1 = pOut;
1545     		for (l = 0; l < 8; l++) {
1546     			for (m = 0; m < 8; m++)
1547     				*pOut1++ =*pIn++;
1548     			pOut1 += iWidth - 8;
1549     		}
1550     		pOut += 8;
1551     	}
1552     }
1553     
1554     /*
1555      * For 640x480 RAW BW images, data shows up in 1200 256 byte segments.
1556      * The segments represent 4 squares of 8x8 pixels as follows:
1557      *
1558      *      0  1 ...  7    64  65 ...  71   ...  192 193 ... 199
1559      *      8  9 ... 15    72  73 ...  79        200 201 ... 207
1560      *           ...              ...                    ...
1561      *     56 57 ... 63   120 121 ... 127        248 249 ... 255
1562      *
1563      */ 
1564     static void
1565     ov511_parse_data_grey(unsigned char *pIn0, unsigned char *pOut0,
1566     		      int iOutY, int iWidth)		    
1567     {
1568     	int k, l, m;
1569     	unsigned char *pIn;
1570     	unsigned char *pOut, *pOut1;
1571     
1572     	pIn = pIn0;
1573     	pOut = pOut0 + iOutY;
1574     	for (k = 0; k < 4; k++) {
1575     		pOut1 = pOut;
1576     		for (l = 0; l < 8; l++) {
1577     			for (m = 0; m < 8; m++) {
1578     				*pOut1++ = *pIn++;
1579     			}
1580     			pOut1 += iWidth - 8;
1581     		}
1582     		pOut += 8;
1583     	}
1584     }
1585     
1586     /*
1587      * fixFrameRGBoffset--
1588      * My camera seems to return the red channel about 1 pixel
1589      * low, and the blue channel about 1 pixel high. After YUV->RGB
1590      * conversion, we can correct this easily. OSL 2/24/2000.
1591      */
1592     static void fixFrameRGBoffset(struct ov511_frame *frame)
1593     {
1594     	int x, y;
1595     	int rowBytes = frame->width*3, w = frame->width;
1596     	unsigned char *rgb = frame->data;
1597     	const int shift = 1;  /* Distance to shift pixels by, vertically */
1598     
1599     	/* Don't bother with little images */
1600     	if (frame->width < 400) 
1601     		return;
1602     
1603     	/* Shift red channel up */
1604     	for (y = shift; y < frame->height; y++)	{
1605     		int lp = (y-shift)*rowBytes;     /* Previous line offset */
1606     		int lc = y*rowBytes;             /* Current line offset */
1607     		for (x = 0; x < w; x++)
1608     			rgb[lp+x*3+2] = rgb[lc+x*3+2]; /* Shift red up */
1609     	}
1610     
1611     	/* Shift blue channel down */
1612     	for (y = frame->height-shift-1; y >= 0; y--) {
1613     		int ln = (y + shift) * rowBytes;  /* Next line offset */
1614     		int lc = y * rowBytes;            /* Current line offset */
1615     		for (x = 0; x < w; x++)
1616     			rgb[ln+x*3+0] = rgb[lc+x*3+0]; /* Shift blue down */
1617     	}
1618     }
1619     
1620     /**********************************************************************
1621      *
1622      * OV511 data transfer, IRQ handler
1623      *
1624      **********************************************************************/
1625     
1626     static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
1627     {
1628     	unsigned char *cdata;
1629     	int i, totlen = 0;
1630     	int aPackNum[10];
1631     	struct ov511_frame *frame;
1632     	unsigned char *pData;
1633     	int iPix;
1634     
1635     	PDEBUG (4, "Moving %d packets", urb->number_of_packets);
1636     
1637     	for (i = 0; i < urb->number_of_packets; i++) {
1638     		int n = urb->iso_frame_desc[i].actual_length;
1639     		int st = urb->iso_frame_desc[i].status;
1640     
1641     		urb->iso_frame_desc[i].actual_length = 0;
1642     		urb->iso_frame_desc[i].status = 0;
1643     
1644     		cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
1645     
1646     		aPackNum[i] = n ? cdata[ov511->packet_size - 1] : -1;
1647     
1648     		if (!n || ov511->curframe == -1)
1649     			continue;
1650     
1651     		if (st)
1652     			PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
1653     
1654     		frame = &ov511->frame[ov511->curframe];
1655     		
1656     		/* SOF/EOF packets have 1st to 8th bytes zeroed and the 9th
1657     		 * byte non-zero. The EOF packet has image width/height in the
1658     		 * 10th and 11th packets. The 9th bit is given as follows:
1659     		 *
1660     		 * bit 7: EOF
1661     		 *     6: compression enabled
1662     		 *     5: 422/420/400 modes
1663     		 *     4: 422/420/400 modes
1664     		 *     3: 1
1665     		 *     2: snapshot bottom on
1666     		 *     1: snapshot frame
1667     		 *     0: even/odd field
1668     		 */
1669     
1670     		/* Check for SOF/EOF packet */
1671     		if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] | 
1672     		     cdata[4] | cdata[5] | cdata[6] | cdata[7]) ||
1673     		     (~cdata[8] & 0x08))
1674     			goto check_middle;
1675     
1676     		/* Frame end */
1677     		if (cdata[8] & 0x80) {
1678     			struct timeval *ts;
1679     
1680     			ts = (struct timeval *)(frame->data + MAX_FRAME_SIZE);
1681     			do_gettimeofday (ts);
1682     
1683     		 	PDEBUG(4, "Frame end, curframe = %d, packnum=%d, hw=%d, vw=%d",
1684     				ov511->curframe, (int)(cdata[ov511->packet_size - 1]),
1685     				(int)(cdata[9]), (int)(cdata[10]));
1686     
1687     			if (frame->scanstate == STATE_LINES) {
1688     		    		int iFrameNext;
1689     
1690     				if (fix_rgb_offset)
1691     					fixFrameRGBoffset(frame);
1692     				frame->grabstate = FRAME_DONE;
1693     
1694     				if (waitqueue_active(&frame->wq)) {
1695     					frame->grabstate = FRAME_DONE;
1696     					wake_up_interruptible(&frame->wq);
1697     				}
1698     
1699     				/* If next frame is ready or grabbing,
1700                                      * point to it */
1701     				iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
1702     				if (ov511->frame[iFrameNext].grabstate == FRAME_READY
1703     				    || ov511->frame[iFrameNext].grabstate == FRAME_GRABBING) {
1704     					ov511->curframe = iFrameNext;
1705     					ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
1706     				} else {
1707     					if (frame->grabstate == FRAME_DONE) {
1708     						PDEBUG(4, "Frame done! congratulations");
1709     					} else {
1710     						PDEBUG(4, "Frame not ready? state = %d",
1711     							ov511->frame[iFrameNext].grabstate);
1712     					}
1713     
1714     					ov511->curframe = -1;
1715     				}
1716     			}
1717     			/* Image corruption caused by misplaced frame->segment = 0
1718     			 * fixed by carlosf@conectiva.com.br
1719     			 */
1720     		} else {
1721     			/* Frame start */
1722     			PDEBUG(4, "Frame start, framenum = %d", ov511->curframe);
1723     
1724     #if 0
1725     			/* Make sure no previous data carries over; necessary
1726     			 * for compression experimentation */
1727     			memset(frame->data, 0, MAX_DATA_SIZE);
1728     #endif
1729     			output_offset = 0;
1730     
1731     			/* Check to see if it's a snapshot frame */
1732     			/* FIXME?? Should the snapshot reset go here? Performance? */
1733     			if (cdata[8] & 0x02) {
1734     				frame->snapshot = 1;
1735     				PDEBUG(3, "snapshot detected");
1736     			}
1737     
1738     			frame->scanstate = STATE_LINES;
1739     			frame->segment = 0;
1740     		}
1741     
1742     check_middle:
1743     		/* Are we in a frame? */
1744     		if (frame->scanstate != STATE_LINES)
1745     			continue;
1746     
1747     		/* Deal with leftover from last segment, if any */
1748     		if (frame->segment) {
1749     			pData = ov511->scratch;
1750     			iPix = -ov511->scratchlen;
1751     			memmove(pData + ov511->scratchlen, cdata,
1752     				iPix+frame->segsize);
1753     		} else {
1754     			pData = &cdata[iPix = 9];
1755     	 	}
1756     
1757     		/* Parse the segments */
1758     		while (iPix <= (ov511->packet_size - 1) - frame->segsize &&
1759     		    frame->segment < frame->width * frame->height / 256) {
1760     			int iSegY, iSegUV;
1761     			int iY, jY, iUV, jUV;
1762     			int iOutY, iOutYP, iOutUV, iOutUVP;
1763     			unsigned char *pOut;
1764     
1765     			iSegY = iSegUV = frame->segment;
1766     			pOut = frame->data;
1767     			frame->segment++;
1768     			iPix += frame->segsize;
1769     
1770     			/* Handle subwindow */
1771     			if (frame->sub_flag) {
1772     				int iSeg1;
1773     
1774     				iSeg1 = iSegY / (ov511->subw / 32);
1775     				iSeg1 *= frame->width / 32;
1776     				iSegY = iSeg1 + (iSegY % (ov511->subw / 32));
1777     				if (iSegY >= frame->width * ov511->subh / 256)
1778     					break;
1779     
1780     				iSeg1 = iSegUV / (ov511->subw / 16);
1781     				iSeg1 *= frame->width / 16;
1782     				iSegUV = iSeg1 + (iSegUV % (ov511->subw / 16));
1783     
1784     				pOut += (ov511->subx + ov511->suby * frame->width) *
1785     					(frame->depth >> 3);
1786     			}
1787     
1788     			/* 
1789     			 * i counts segment lines
1790     			 * j counts segment columns
1791     			 * iOut is the offset (in bytes) of the upper left corner
1792     			 */
1793     			iY = iSegY / (frame->width / WDIV);
1794     			jY = iSegY - iY * (frame->width / WDIV);
1795     			iOutYP = iY*HDIV*frame->width + jY*WDIV;
1796     			iOutY = iOutYP * (frame->depth >> 3);
1797     			iUV = iSegUV / (frame->width / WDIV * 2);
1798     			jUV = iSegUV - iUV * (frame->width / WDIV * 2);
1799     			iOutUVP = iUV*HDIV*2*frame->width + jUV*WDIV/2;
1800     			iOutUV = iOutUVP * (frame->depth >> 3);
1801     
1802     			switch (frame->format) {
1803     			case VIDEO_PALETTE_GREY:
1804     				ov511_parse_data_grey (pData, pOut, iOutY, frame->width);
1805     				break;
1806     			case VIDEO_PALETTE_RGB24:
1807     				if (dumppix)
1808     					ov511_dumppix(pData, pOut, iOutY, iOutUV,
1809     						iY & 1, frame->width);
1810     				else if (sensor_gbr)
1811     					ov511_parse_gbr422_to_rgb24(pData, pOut, iOutY, iOutUV,
1812     						iY & 1, frame->width);
1813     				else
1814     					ov511_parse_yuv420_to_rgb(pData, pOut, iOutY, iOutUV,
1815     						iY & 1, frame->width, 24);
1816     				break;
1817     			case VIDEO_PALETTE_RGB565:
1818     				ov511_parse_yuv420_to_rgb(pData, pOut, iOutY, iOutUV,
1819     					iY & 1, frame->width, 16);
1820     				break;
1821     			case VIDEO_PALETTE_YUV422:
1822     			case VIDEO_PALETTE_YUYV:
1823     				ov511_parse_data_yuv422(pData, pOut, iOutY, iOutUV, frame->width);
1824     				break;
1825     			case VIDEO_PALETTE_YUV420:
1826     				ov511_parse_data_yuv420 (pData, pOut, iOutYP, iUV*HDIV*frame->width/2 + jUV*WDIV/4,
1827     					frame->width, frame->height);
1828     				break;
1829     			case VIDEO_PALETTE_YUV422P:
1830     				ov511_parse_data_yuv422p (pData, pOut, iOutYP, iOutUVP/2,
1831     					frame->width, frame->height);
1832     				break;
1833     			default:
1834     				err("Unsupported format: %d", frame->format);
1835     			}
1836     
1837     			pData = &cdata[iPix];
1838     		}
1839     
1840     		/* Save extra data for next time */
1841     		if (frame->segment < frame->width * frame->height / 256) {
1842     			ov511->scratchlen = (ov511->packet_size - 1) - iPix;
1843     			if (ov511->scratchlen < frame->segsize)
1844     				memmove(ov511->scratch, pData, ov511->scratchlen);
1845     			else
1846     				ov511->scratchlen = 0;
1847     		}
1848     	}
1849     
1850     	PDEBUG(5, "pn: %d %d %d %d %d %d %d %d %d %d",
1851     	       aPackNum[0], aPackNum[1], aPackNum[2], aPackNum[3], aPackNum[4],
1852     	       aPackNum[5],aPackNum[6], aPackNum[7], aPackNum[8], aPackNum[9]);
1853     
1854     	return totlen;
1855     }
1856     
1857     static void ov511_isoc_irq(struct urb *urb)
1858     {
1859     	int len;
1860     	struct usb_ov511 *ov511;
1861     	struct ov511_sbuf *sbuf;
1862     
1863     	if (!urb->context) {
1864     		PDEBUG(4, "no context");
1865     		return;
1866     	}
1867     
1868     	ov511 = (struct usb_ov511 *) urb->context;
1869     
1870     	if (!ov511->dev || !ov511->user) {
1871     		PDEBUG(4, "no device, or not open");
1872     		return;
1873     	}
1874     
1875     	if (!ov511->streaming) {
1876     		PDEBUG(4, "hmmm... not streaming, but got interrupt");
1877     		return;
1878     	}
1879     	
1880     	sbuf = &ov511->sbuf[ov511->cursbuf];
1881     
1882     	/* Copy the data received into our scratch buffer */
1883     	if (ov511->curframe >= 0) {
1884     		len = ov511_move_data(ov511, urb);
1885     	} else if (waitqueue_active(&ov511->wq)) {
1886     		wake_up_interruptible(&ov511->wq);
1887     	}
1888     
1889     	/* Move to the next sbuf */
1890     	ov511->cursbuf = (ov511->cursbuf + 1) % OV511_NUMSBUF;
1891     
1892     	urb->dev = ov511->dev;
1893     
1894     	return;
1895     }
1896     
1897     static int ov511_init_isoc(struct usb_ov511 *ov511)
1898     {
1899     	urb_t *urb;
1900     	int fx, err, n, size;
1901     
1902     	PDEBUG(3, "*** Initializing capture ***");
1903     
1904     	ov511->compress = 0;
1905     	ov511->curframe = -1;
1906     	ov511->cursbuf = 0;
1907     	ov511->scratchlen = 0;
1908     
1909     	if (ov511->bridge == BRG_OV511)
1910     		if (cams == 1)			 size = 993;
1911     		else if (cams == 2)		 size = 513;
1912     		else if (cams == 3 || cams == 4) size = 257;
1913     		else {
1914     			err("\"cams\" parameter too high!");
1915     			return -1;
1916     		}
1917     	else if (ov511->bridge == BRG_OV511PLUS)
1918     		if (cams == 1)                      size = 961;
1919     		else if (cams == 2)                 size = 513;
1920     		else if (cams == 3 || cams == 4) size = 257;
1921     		else if (cams >= 5 && cams <= 8)    size = 129;
1922     		else if (cams >= 9 && cams <= 31)   size = 33;
1923     		else {
1924     			err("\"cams\" parameter too high!");
1925     			return -1;
1926     		}
1927     	else {
1928     		err("invalid bridge type");
1929     		return -1;
1930     	}
1931     
1932     	ov511_set_packet_size(ov511, size);
1933     
1934     	for (n = 0; n < OV511_NUMSBUF; n++) {
1935     		urb = usb_alloc_urb(FRAMES_PER_DESC);
1936     	
1937     		if (!urb) {
1938     			err("init isoc: usb_alloc_urb ret. NULL");
1939     			return -ENOMEM;
1940     		}
1941     		ov511->sbuf[n].urb = urb;
1942     		urb->dev = ov511->dev;
1943     		urb->context = ov511;
1944     		urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS);
1945     		urb->transfer_flags = USB_ISO_ASAP;
1946     		urb->transfer_buffer = ov511->sbuf[n].data;
1947     		urb->complete = ov511_isoc_irq;
1948     		urb->number_of_packets = FRAMES_PER_DESC;
1949     		urb->transfer_buffer_length = ov511->packet_size * FRAMES_PER_DESC;
1950     		for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
1951     			urb->iso_frame_desc[fx].offset = ov511->packet_size * fx;
1952     			urb->iso_frame_desc[fx].length = ov511->packet_size;
1953     		}
1954     	}
1955     
1956     	ov511->sbuf[OV511_NUMSBUF - 1].urb->next = ov511->sbuf[0].urb;
1957     	for (n = 0; n < OV511_NUMSBUF - 1; n++)
1958     		ov511->sbuf[n].urb->next = ov511->sbuf[n+1].urb;
1959     
1960     	for (n = 0; n < OV511_NUMSBUF; n++) {
1961     		ov511->sbuf[n].urb->dev = ov511->dev;
1962     		err = usb_submit_urb(ov511->sbuf[n].urb);
1963     		if (err)
1964     			err("init isoc: usb_submit_urb(%d) ret %d", n, err);
1965     	}
1966     
1967     	ov511->streaming = 1;
1968     
1969     	return 0;
1970     }
1971     
1972     static void ov511_stop_isoc(struct usb_ov511 *ov511)
1973     {
1974     	int n;
1975     
1976     	if (!ov511->streaming || !ov511->dev)
1977     		return;
1978     
1979     	PDEBUG (3, "*** Stopping capture ***");
1980     
1981     	ov511_set_packet_size(ov511, 0);
1982     
1983     	ov511->streaming = 0;
1984     
1985     	/* Unschedule all of the iso td's */
1986     	for (n = OV511_NUMSBUF - 1; n >= 0; n--) {
1987     		if (ov511->sbuf[n].urb) {
1988     			ov511->sbuf[n].urb->next = NULL;
1989     			usb_unlink_urb(ov511->sbuf[n].urb);
1990     			usb_free_urb(ov511->sbuf[n].urb);
1991     			ov511->sbuf[n].urb = NULL;
1992     		}
1993     	}
1994     }
1995     
1996     static int ov511_new_frame(struct usb_ov511 *ov511, int framenum)
1997     {
1998     	struct ov511_frame *frame;
1999     
2000     	PDEBUG(4, "ov511->curframe = %d, framenum = %d", ov511->curframe,
2001     		framenum);
2002     	if (!ov511->dev)
2003     		return -1;
2004     
2005     	/* If we're not grabbing a frame right now and the other frame is */
2006     	/* ready to be grabbed into, then use it instead */
2007     	if (ov511->curframe == -1) {
2008     		if (ov511->frame[(framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES].grabstate == FRAME_READY)
2009     			framenum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
2010     	} else
2011     		return 0;
2012     
2013     	frame = &ov511->frame[framenum];
2014     
2015     	PDEBUG (4, "framenum = %d, width = %d, height = %d", framenum, 
2016     		frame->width, frame->height);
2017     
2018     	frame->grabstate = FRAME_GRABBING;
2019     	frame->scanstate = STATE_SCANNING;
2020     	frame->scanlength = 0;		/* accumulated in ov511_parse_data() */
2021     	frame->snapshot = 0;
2022     
2023     	ov511->curframe = framenum;
2024     
2025     	/* Make sure it's not too big */
2026     	if (frame->width > ov511->maxwidth)
2027     		frame->width = ov511->maxwidth;
2028     
2029     	frame->width &= ~7L;		/* Multiple of 8 */
2030     
2031     	if (frame->height > ov511->maxheight)
2032     		frame->height = ov511->maxheight;
2033     
2034     	frame->height &= ~3L;		/* Multiple of 4 */
2035     
2036     	return 0;
2037     }
2038     
2039     /****************************************************************************
2040      *
2041      * Buffer management
2042      *
2043      ***************************************************************************/
2044     static int ov511_alloc(struct usb_ov511 *ov511)
2045     {
2046     	int i;
2047     
2048     	PDEBUG(4, "entered");
2049     	down(&ov511->buf_lock);
2050     
2051     	if (ov511->buf_state == BUF_PEND_DEALLOC) {
2052     		ov511->buf_state = BUF_ALLOCATED;
2053     		del_timer(&ov511->buf_timer);
2054     	}
2055     
2056     	if (ov511->buf_state == BUF_ALLOCATED)
2057     		goto out;
2058     
2059     	ov511->fbuf = rvmalloc(OV511_NUMFRAMES * MAX_DATA_SIZE);
2060     	if (!ov511->fbuf)
2061     		goto error;
2062     
2063     	for (i = 0; i < OV511_NUMFRAMES; i++) {
2064     		ov511->frame[i].grabstate = FRAME_UNUSED;
2065     		ov511->frame[i].data = ov511->fbuf + i * MAX_DATA_SIZE;
2066     		PDEBUG(4, "frame[%d] @ %p", i, ov511->frame[i].data);
2067     
2068     		ov511->sbuf[i].data = kmalloc(FRAMES_PER_DESC *
2069     			MAX_FRAME_SIZE_PER_DESC, GFP_KERNEL);
2070     		if (!ov511->sbuf[i].data) {
2071     			while (--i) {
2072     				kfree(ov511->sbuf[i].data);
2073     				ov511->sbuf[i].data = NULL;
2074     			}
2075     			rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE);
2076     			ov511->fbuf = NULL;
2077     			goto error;
2078     		}
2079     		PDEBUG(4, "sbuf[%d] @ %p", i, ov511->sbuf[i].data);
2080     	}
2081     	ov511->buf_state = BUF_ALLOCATED;
2082     out:
2083     	up(&ov511->buf_lock);
2084     	PDEBUG(4, "leaving");
2085     	return 0;
2086     error:
2087     	ov511->buf_state = BUF_NOT_ALLOCATED;
2088     	up(&ov511->buf_lock);
2089     	PDEBUG(4, "errored");
2090     	return -ENOMEM;
2091     }
2092     
2093     /* 
2094      * - You must acquire buf_lock before entering this function.
2095      * - Because this code will free any non-null pointer, you must be sure to null
2096      *   them if you explicitly free them somewhere else!
2097      */
2098     static void ov511_do_dealloc(struct usb_ov511 *ov511)
2099     {
2100     	int i;
2101     	PDEBUG(4, "entered");
2102     
2103     	if (ov511->fbuf) {
2104     		rvfree(ov511->fbuf, OV511_NUMFRAMES * MAX_DATA_SIZE);
2105     		ov511->fbuf = NULL;
2106     	}
2107     
2108     	for (i = 0; i < OV511_NUMFRAMES; i++) {
2109     		if (ov511->sbuf[i].data) {
2110     			kfree(ov511->sbuf[i].data);
2111     			ov511->sbuf[i].data = NULL;
2112     		}
2113     	}
2114     
2115     	PDEBUG(4, "buffer memory deallocated");
2116     	ov511->buf_state = BUF_NOT_ALLOCATED;
2117     	PDEBUG(4, "leaving");
2118     }
2119     
2120     static void ov511_buf_callback(unsigned long data)
2121     {
2122     	struct usb_ov511 *ov511 = (struct usb_ov511 *)data;
2123     	PDEBUG(4, "entered");
2124     	down(&ov511->buf_lock);
2125     
2126     	if (ov511->buf_state == BUF_PEND_DEALLOC)
2127     		ov511_do_dealloc(ov511);
2128     
2129     	up(&ov511->buf_lock);
2130     	PDEBUG(4, "leaving");
2131     }
2132     
2133     static void ov511_dealloc(struct usb_ov511 *ov511, int now)
2134     {
2135     	struct timer_list *bt = &(ov511->buf_timer);
2136     	PDEBUG(4, "entered");
2137     	down(&ov511->buf_lock);
2138     
2139     	PDEBUG(4, "deallocating buffer memory %s", now ? "now" : "later");
2140     
2141     	if (ov511->buf_state == BUF_PEND_DEALLOC) {
2142     		ov511->buf_state = BUF_ALLOCATED;
2143     		del_timer(bt);
2144     	}
2145     
2146     	if (now)
2147     		ov511_do_dealloc(ov511);
2148     	else {
2149     		ov511->buf_state = BUF_PEND_DEALLOC;
2150     		init_timer(bt);
2151     		bt->function = ov511_buf_callback;
2152     		bt->data = (unsigned long)ov511;
2153     		bt->expires = jiffies + buf_timeout * HZ;
2154     		add_timer(bt);
2155     	}
2156     	up(&ov511->buf_lock);
2157     	PDEBUG(4, "leaving");
2158     }
2159     
2160     /****************************************************************************
2161      *
2162      * V4L API
2163      *
2164      ***************************************************************************/
2165     
2166     static int ov511_open(struct video_device *dev, int flags)
2167     {
2168     	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
2169     	int err;
2170     
2171     	MOD_INC_USE_COUNT;
2172     	PDEBUG(4, "opening");
2173     	down(&ov511->lock);
2174     
2175     	err = -EBUSY;
2176     	if (ov511->user) 
2177     		goto out;
2178     
2179     	err = -ENOMEM;
2180     	if (ov511_alloc(ov511))
2181     		goto out;
2182     
2183     	ov511->sub_flag = 0;
2184     
2185     	err = ov511_init_isoc(ov511);
2186     	if (err) {
2187     		ov511_dealloc(ov511, 0);
2188     		goto out;
2189     	}
2190     
2191     	ov511->user++;
2192     
2193     out:
2194     	up(&ov511->lock);
2195     
2196     	if (err)
2197     		MOD_DEC_USE_COUNT;
2198     
2199     	return err;
2200     }
2201     
2202     static void ov511_close(struct video_device *dev)
2203     {
2204     	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
2205     
2206     	PDEBUG(4, "ov511_close");
2207     	
2208     	down(&ov511->lock);
2209     
2210     	ov511->user--;
2211     	ov511_stop_isoc(ov511);
2212     
2213     	if (ov511->dev)
2214     		ov511_dealloc(ov511, 0);
2215     
2216     	up(&ov511->lock);
2217     
2218     	if (!ov511->dev) {
2219     		ov511_dealloc(ov511, 1);
2220     		video_unregister_device(&ov511->vdev);
2221     		kfree(ov511);
2222     		ov511 = NULL;
2223     	}
2224     
2225     	MOD_DEC_USE_COUNT;
2226     }
2227     
2228     static int ov511_init_done(struct video_device *dev)
2229     {
2230     #if defined(CONFIG_PROC_FS) && defined(CONFIG_VIDEO_PROC_FS)
2231     	create_proc_ov511_cam((struct usb_ov511 *)dev);
2232     #endif
2233     
2234     	return 0;
2235     }
2236     
2237     static long ov511_write(struct video_device *dev, const char *buf, unsigned long count, int noblock)
2238     {
2239     	return -EINVAL;
2240     }
2241     
2242     static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
2243     {
2244     	struct usb_ov511 *ov511 = (struct usb_ov511 *)vdev;
2245     
2246     	PDEBUG(4, "IOCtl: 0x%X", cmd);
2247     
2248     	if (!ov511->dev)
2249     		return -EIO;	
2250     
2251     	switch (cmd) {
2252     	case VIDIOCGCAP:
2253     	{
2254     		struct video_capability b;
2255     
2256     		PDEBUG (4, "VIDIOCGCAP");
2257     
2258     		memset(&b, 0, sizeof(b));
2259     		strcpy(b.name, "OV511 USB Camera");
2260     		b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
2261     		b.channels = 1;
2262     		b.audios = 0;
2263     		b.maxwidth = ov511->maxwidth;
2264     		b.maxheight = ov511->maxheight;
2265     		b.minwidth = 160;
2266     		b.minheight = 120;
2267     
2268     		if (copy_to_user(arg, &b, sizeof(b)))
2269     			return -EFAULT;
2270     				
2271     		return 0;
2272     	}
2273     	case VIDIOCGCHAN:
2274     	{
2275     		struct video_channel v;
2276     
2277     		if (copy_from_user(&v, arg, sizeof(v)))
2278     			return -EFAULT;
2279     		if (v.channel != 0)
2280     			return -EINVAL;
2281     
2282     		v.flags = 0;
2283     		v.tuners = 0;
2284     		v.type = VIDEO_TYPE_CAMERA;
2285     		strcpy(v.name, "Camera");
2286     
2287     		if (copy_to_user(arg, &v, sizeof(v)))
2288     			return -EFAULT;
2289     				
2290     		return 0;
2291     	}
2292     	case VIDIOCSCHAN:
2293     	{
2294     		int v;
2295     
2296     		if (copy_from_user(&v, arg, sizeof(v)))
2297     			return -EFAULT;
2298     
2299     		if (v != 0)
2300     			return -EINVAL;
2301     
2302     		return 0;
2303     	}
2304     	case VIDIOCGPICT:
2305     	{
2306     		struct video_picture p;
2307     
2308     		PDEBUG (4, "VIDIOCGPICT");
2309     
2310     		memset(&p, 0, sizeof(p));
2311     
2312     		if (ov7610_get_picture(ov511, &p))
2313     			return -EIO;
2314     
2315     		if (copy_to_user(arg, &p, sizeof(p)))
2316     			return -EFAULT;
2317     
2318     		return 0;
2319     	}
2320     	case VIDIOCSPICT:
2321     	{
2322     		struct video_picture p;
2323     		int i;
2324     
2325     		PDEBUG (4, "VIDIOCSPICT");
2326     
2327     		if (copy_from_user(&p, arg, sizeof(p)))
2328     			return -EFAULT;
2329     
2330     		if (!ov511_get_depth(p.palette))
2331     			return -EINVAL;
2332     			
2333     		if (ov7610_set_picture(ov511, &p))
2334     			return -EIO;
2335     
2336     		PDEBUG(4, "Setting depth=%d, palette=%d", p.depth, p.palette);
2337     		for (i = 0; i < OV511_NUMFRAMES; i++) {
2338     			ov511->frame[i].depth = p.depth;
2339     			ov511->frame[i].format = p.palette;
2340     			ov511->frame[i].segsize = GET_SEGSIZE(p.palette);
2341     		}
2342     
2343     		return 0;
2344     	}
2345     	case VIDIOCGCAPTURE:
2346     	{
2347     		int vf;
2348     
2349     		PDEBUG (4, "VIDIOCGCAPTURE");
2350     
2351     		if (copy_from_user(&vf, arg, sizeof(vf)))
2352     			return -EFAULT;
2353     		ov511->sub_flag = vf;
2354     		return 0;
2355     	}
2356     	case VIDIOCSCAPTURE:
2357     	{
2358     		struct video_capture vc;
2359     
2360     		if (copy_from_user(&vc, arg, sizeof(vc)))
2361     			return -EFAULT;
2362     		if (vc.flags)
2363     			return -EINVAL;
2364     		if (vc.decimation)
2365     			return -EINVAL;
2366     
2367     		vc.x &= ~3L;
2368     		vc.y &= ~1L;
2369     		vc.y &= ~31L;
2370     
2371     		if (vc.width == 0)
2372     			vc.width = 32;
2373     
2374     		vc.height /= 16;
2375     		vc.height *= 16;
2376     		if (vc.height == 0)
2377     			vc.height = 16;
2378     
2379     		ov511->subx = vc.x;
2380     		ov511->suby = vc.y;
2381     		ov511->subw = vc.width;
2382     		ov511->subh = vc.height;
2383     
2384     		return 0;
2385     	}
2386     	case VIDIOCSWIN:
2387     	{
2388     		struct video_window vw;
2389     		int i, result;
2390     
2391     		if (copy_from_user(&vw, arg, sizeof(vw)))
2392     			return -EFAULT;
2393     
2394     		PDEBUG (4, "VIDIOCSWIN: width=%d, height=%d",
2395     			vw.width, vw.height);
2396     
2397     #if 0
2398     		if (vw.flags)
2399     			return -EINVAL;
2400     		if (vw.clipcount)
2401     			return -EINVAL;
2402     		if (vw.height != ov511->maxheight)
2403     			return -EINVAL;
2404     		if (vw.width != ov511->maxwidth)
2405     			return -EINVAL;
2406     #endif
2407     
2408     		/* If we're collecting previous frame wait
2409     		   before changing modes */
2410     		interruptible_sleep_on(&ov511->wq);
2411     		if (signal_pending(current)) return -EINTR;
2412     
2413     		result = ov511_mode_init_regs(ov511, vw.width, vw.height,
2414     			ov511->frame[0].format, ov511->sub_flag);
2415     		if (result < 0)
2416     			return result;
2417     
2418     		for (i = 0; i < OV511_NUMFRAMES; i++) {
2419     			ov511->frame[i].width = vw.width;
2420     			ov511->frame[i].height = vw.height;
2421     		}
2422     
2423     		return 0;
2424     	}
2425     	case VIDIOCGWIN:
2426     	{
2427     		struct video_window vw;
2428     
2429     		memset(&vw, 0, sizeof(vw));
2430     		vw.x = 0;		/* FIXME */
2431     		vw.y = 0;
2432     		vw.width = ov511->frame[0].width;
2433     		vw.height = ov511->frame[0].height;
2434     		vw.flags = 30;
2435     
2436     		PDEBUG (4, "VIDIOCGWIN: %dx%d", vw.width, vw.height);
2437     
2438     		if (copy_to_user(arg, &vw, sizeof(vw)))
2439     			return -EFAULT;
2440     
2441     		return 0;
2442     	}
2443     	case VIDIOCGMBUF:
2444     	{
2445     		struct video_mbuf vm;
2446     		int i;
2447     		
2448     		memset(&vm, 0, sizeof(vm));
2449     		vm.size = OV511_NUMFRAMES * MAX_DATA_SIZE;
2450     		vm.frames = OV511_NUMFRAMES;
2451     		vm.offsets[0] = 0;
2452     		for (i = 1; i < OV511_NUMFRAMES; i++) {
2453     			vm.offsets[i] = vm.offsets[i-1] + MAX_FRAME_SIZE
2454     				+ sizeof (struct timeval);
2455     		}
2456     
2457     		if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
2458     			return -EFAULT;
2459     
2460     		return 0;
2461     	}
2462     	case VIDIOCMCAPTURE:
2463     	{
2464     		struct video_mmap vm;
2465     		int ret, depth;
2466     
2467     		if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
2468     			return -EFAULT;
2469     
2470     		PDEBUG(4, "CMCAPTURE");
2471     		PDEBUG(4, "frame: %d, size: %dx%d, format: %d",
2472     			vm.frame, vm.width, vm.height, vm.format);
2473     
2474     		depth = ov511_get_depth(vm.format);
2475     		if (!depth) {
2476     			err("VIDIOCMCAPTURE: invalid format (%d)", vm.format);
2477     			return -EINVAL;
2478     		}
2479     
2480     		if ((unsigned)vm.frame >= OV511_NUMFRAMES) {
2481     			err("VIDIOCMCAPTURE: invalid frame (%d)", vm.frame);
2482     			return -EINVAL;
2483     		}
2484     
2485     		if (vm.width > ov511->maxwidth || vm.height > ov511->maxheight) {
2486     			err("VIDIOCMCAPTURE: requested dimensions too big");
2487     			return -EINVAL;
2488     		}
2489     
2490     		if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING)
2491     			return -EBUSY;
2492     
2493     		/* Don't compress if the size changed */
2494     		if ((ov511->frame[vm.frame].width != vm.width) ||
2495     		    (ov511->frame[vm.frame].height != vm.height) ||
2496     		    (ov511->frame[vm.frame].format != vm.format) ||
2497     		    (ov511->frame[vm.frame].sub_flag !=
2498     		     ov511->sub_flag)) {
2499     			/* If we're collecting previous frame wait
2500     			   before changing modes */
2501     			interruptible_sleep_on(&ov511->wq);
2502     			if (signal_pending(current)) return -EINTR;
2503     			ret = ov511_mode_init_regs(ov511, vm.width, vm.height,
2504     				vm.format, ov511->sub_flag);
2505     #if 0
2506     			if (ret < 0)
2507     				return ret;
2508     #endif
2509     		}
2510     
2511     		ov511->frame[vm.frame].width = vm.width;
2512     		ov511->frame[vm.frame].height = vm.height;
2513     		ov511->frame[vm.frame].format = vm.format;
2514     		ov511->frame[vm.frame].sub_flag = ov511->sub_flag;
2515     		ov511->frame[vm.frame].segsize = GET_SEGSIZE(vm.format);
2516     		ov511->frame[vm.frame].depth = depth;
2517     
2518     		/* Mark it as ready */
2519     		ov511->frame[vm.frame].grabstate = FRAME_READY;
2520     
2521     		return ov511_new_frame(ov511, vm.frame);
2522     	}
2523     	case VIDIOCSYNC:
2524     	{
2525     		int frame;
2526     
2527     		if (copy_from_user((void *)&frame, arg, sizeof(int)))
2528     			return -EFAULT;
2529     
2530     		if ((unsigned)frame >= OV511_NUMFRAMES) {
2531     			err("VIDIOCSYNC: invalid frame (%d)", frame);
2532     			return -EINVAL;
2533     		}
2534     
2535     		PDEBUG(4, "syncing to frame %d, grabstate = %d", frame,
2536     		       ov511->frame[frame].grabstate);
2537     
2538     		if(frame < 0 || frame >= OV511_NUMFRAMES)
2539     			return -EINVAL;
2540     			
2541     		switch (ov511->frame[frame].grabstate) {
2542     		case FRAME_UNUSED:
2543     			return -EINVAL;
2544     		case FRAME_READY:
2545     		case FRAME_GRABBING:
2546     		case FRAME_ERROR:
2547     redo:
2548     			if (!ov511->dev)
2549     				return -EIO;
2550     
2551     			do {
2552     #if 0
2553     				init_waitqueue_head(&ov511->frame[frame].wq);
2554     #endif
2555     				interruptible_sleep_on(&ov511->frame[frame].wq);
2556     				if (signal_pending(current)) {
2557     					if (retry_sync) {
2558     						PDEBUG(3, "***retry sync***");
2559     
2560     						/* Polling apps will destroy frames with that! */
2561     						ov511_new_frame(ov511, frame);
2562     						ov511->curframe = -1;
2563     
2564     						/* This will request another frame. */
2565     						if (waitqueue_active(&ov511->frame[frame].wq))
2566     							wake_up_interruptible(&ov511->frame[frame].wq);
2567     
2568     						return 0;
2569      					} else {
2570     						return -EINTR;
2571     					}
2572     				}
2573     			} while (ov511->frame[frame].grabstate == FRAME_GRABBING);
2574     
2575     			if (ov511->frame[frame].grabstate == FRAME_ERROR) {
2576     				int ret;
2577     
2578     				if ((ret = ov511_new_frame(ov511, frame)) < 0)
2579     					return ret;
2580     				goto redo;
2581     			}			
2582     		case FRAME_DONE:
2583     			if (ov511->snap_enabled && !ov511->frame[frame].snapshot) {
2584     				int ret;
2585     				if ((ret = ov511_new_frame(ov511, frame)) < 0)
2586     					return ret;
2587     				goto redo;
2588     			}
2589     
2590     			ov511->frame[frame].grabstate = FRAME_UNUSED;
2591     
2592     			/* Reset the hardware snapshot button */
2593     			/* FIXME - Is this the best place for this? */
2594     			if ((ov511->snap_enabled) &&
2595     			    (ov511->frame[frame].snapshot)) {
2596     				ov511->frame[frame].snapshot = 0;
2597     				ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
2598     				ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x03);
2599     				ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
2600     			}
2601     			break;
2602     		} /* end switch */
2603     
2604     		return 0;
2605     	}
2606     	case VIDIOCGFBUF:
2607     	{
2608     		struct video_buffer vb;
2609     
2610     		memset(&vb, 0, sizeof(vb));
2611     		vb.base = NULL;	/* frame buffer not supported, not used */
2612     
2613     		if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
2614     			return -EFAULT;
2615     
2616     		return 0;
2617     	}
2618     	case VIDIOCKEY:
2619     		return 0;
2620     	case VIDIOCCAPTURE:
2621     		return -EINVAL;
2622     	case VIDIOCSFBUF:
2623     		return -EINVAL;
2624     	case VIDIOCGTUNER:
2625     	case VIDIOCSTUNER:
2626     		return -EINVAL;
2627     	case VIDIOCGFREQ:
2628     	case VIDIOCSFREQ:
2629     		return -EINVAL;
2630     	case VIDIOCGAUDIO:
2631     	case VIDIOCSAUDIO:
2632     		return -EINVAL;
2633     	default:
2634     		return -ENOIOCTLCMD;
2635     	} /* end switch */
2636     
2637     	return 0;
2638     }
2639     
2640     static long ov511_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
2641     {
2642     	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
2643     	int i;
2644     	int frmx = -1;
2645     	volatile struct ov511_frame *frame;
2646     
2647     	PDEBUG(4, "%ld bytes, noblock=%d", count, noblock);
2648     
2649     	if (!dev || !buf)
2650     		return -EFAULT;
2651     
2652     	if (!ov511->dev)
2653     		return -EIO;
2654     
2655     	/* See if a frame is completed, then use it. */
2656     	if (ov511->frame[0].grabstate >= FRAME_DONE)	/* _DONE or _ERROR */
2657     		frmx = 0;
2658     	else if (ov511->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
2659     		frmx = 1;
2660     
2661     	/* If nonblocking we return immediately */
2662     	if (noblock && (frmx == -1))
2663     		return -EAGAIN;
2664     
2665     	/* If no FRAME_DONE, look for a FRAME_GRABBING state. */
2666     	/* See if a frame is in process (grabbing), then use it. */
2667     	if (frmx == -1) {
2668     		if (ov511->frame[0].grabstate == FRAME_GRABBING)
2669     			frmx = 0;
2670     		else if (ov511->frame[1].grabstate == FRAME_GRABBING)
2671     			frmx = 1;
2672     	}
2673     
2674     	/* If no frame is active, start one. */
2675     	if (frmx == -1)
2676     		ov511_new_frame(ov511, frmx = 0);
2677     
2678     	frame = &ov511->frame[frmx];
2679     
2680     restart:
2681     	if (!ov511->dev)
2682     		return -EIO;
2683     
2684     	/* Wait while we're grabbing the image */
2685     	PDEBUG(4, "Waiting image grabbing");
2686     	while (frame->grabstate == FRAME_GRABBING) {
2687     		interruptible_sleep_on(&ov511->frame[frmx].wq);
2688     		if (signal_pending(current))
2689     			return -EINTR;
2690     	}
2691     	PDEBUG(4, "Got image, frame->grabstate = %d", frame->grabstate);
2692     
2693     	if (frame->grabstate == FRAME_ERROR) {
2694     		frame->bytes_read = 0;
2695     		err("** ick! ** Errored frame %d", ov511->curframe);
2696     		if (ov511_new_frame(ov511, frmx))
2697     			err("read: ov511_new_frame error");
2698     		goto restart;
2699     	}
2700     
2701     
2702     	/* Repeat until we get a snapshot frame */
2703     	if (ov511->snap_enabled)
2704     		PDEBUG (4, "Waiting snapshot frame");
2705     	if (ov511->snap_enabled && !frame->snapshot) {
2706     		frame->bytes_read = 0;
2707     		if (ov511_new_frame(ov511, frmx))
2708     			err("ov511_new_frame error");
2709     		goto restart;
2710     	}
2711     
2712     	/* Clear the snapshot */
2713     	if (ov511->snap_enabled && frame->snapshot) {
2714     		frame->snapshot = 0;
2715     		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
2716     		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x03);
2717     		ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_SNAPSHOT, 0x01);
2718     	}
2719     
2720     	PDEBUG(4, "frmx=%d, bytes_read=%ld, scanlength=%ld", frmx,
2721     		frame->bytes_read, frame->scanlength);
2722     
2723     	/* copy bytes to user space; we allow for partials reads */
2724     //	if ((count + frame->bytes_read) > frame->scanlength)
2725     //		count = frame->scanlength - frame->bytes_read;
2726     
2727     	/* FIXME - count hardwired to be one frame... */
2728     	count = frame->width * frame->height * (frame->depth >> 3);
2729     
2730     	PDEBUG(4, "Copy to user space: %ld bytes", count);
2731     	if ((i = copy_to_user(buf, frame->data + frame->bytes_read, count))) {
2732     		PDEBUG(4, "Copy failed! %d bytes not copied", i);
2733     		return -EFAULT;
2734     	}
2735     
2736     	frame->bytes_read += count;
2737     	PDEBUG(4, "{copy} count used=%ld, new bytes_read=%ld",
2738     		count, frame->bytes_read);
2739     
2740     	if (frame->bytes_read >= frame->scanlength) { /* All data has been read */
2741     		frame->bytes_read = 0;
2742     
2743     		/* Mark it as available to be used again. */
2744     		ov511->frame[frmx].grabstate = FRAME_UNUSED;
2745     		if (ov511_new_frame(ov511, !frmx))
2746     			err("ov511_new_frame returned error");
2747     	}
2748     
2749     	PDEBUG(4, "read finished, returning %ld (sweet)", count);
2750     
2751     	return count;
2752     }
2753     
2754     static int ov511_mmap(struct video_device *dev, const char *adr,
2755     	unsigned long size)
2756     {
2757     	struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
2758     	unsigned long start = (unsigned long)adr;
2759     	unsigned long page, pos;
2760     
2761     	if (ov511->dev == NULL)
2762     		return -EIO;
2763     
2764     	PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
2765     
2766     	if (size > (((OV511_NUMFRAMES * MAX_DATA_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
2767     		return -EINVAL;
2768     
2769     	pos = (unsigned long)ov511->fbuf;
2770     	while (size > 0) {
2771     		page = kvirt_to_pa(pos);
2772     		if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
2773     			return -EAGAIN;
2774     		start += PAGE_SIZE;
2775     		pos += PAGE_SIZE;
2776     		if (size > PAGE_SIZE)
2777     			size -= PAGE_SIZE;
2778     		else
2779     			size = 0;
2780     	}
2781     
2782     	return 0;
2783     }
2784     
2785     static struct video_device ov511_template = {
2786     	name:		"OV511 USB Camera",
2787     	type:		VID_TYPE_CAPTURE,
2788     	hardware:	VID_HARDWARE_OV511,
2789     	open:		ov511_open,
2790     	close:		ov511_close,
2791     	read:		ov511_read,
2792     	write:		ov511_write,
2793     	ioctl:		ov511_ioctl,
2794     	mmap:		ov511_mmap,
2795     	initialize:	ov511_init_done,
2796     };
2797     
2798     /****************************************************************************
2799      *
2800      * OV511/OV7610 configuration
2801      *
2802      ***************************************************************************/
2803     
2804     static int ov76xx_configure(struct usb_ov511 *ov511)
2805     {
2806     	struct usb_device *dev = ov511->dev;
2807     	int i, success;
2808     	int rc;
2809     
2810     	/* Lawrence Glaister <lg@jfm.bc.ca> reports:
2811     	 *
2812     	 * Register 0x0f in the 7610 has the following effects:
2813     	 *
2814     	 * 0x85 (AEC method 1): Best overall, good contrast range
2815     	 * 0x45 (AEC method 2): Very overexposed
2816     	 * 0xa5 (spec sheet default): Ok, but the black level is
2817     	 *	shifted resulting in loss of contrast
2818     	 * 0x05 (old driver setting): very overexposed, too much
2819     	 *	contrast
2820     	 */
2821     	static struct ov511_regvals aRegvalsNorm7610[] = {
2822     		{ OV511_I2C_BUS, 0x10, 0xff },
2823     		{ OV511_I2C_BUS, 0x16, 0x06 },
2824     		{ OV511_I2C_BUS, 0x28, 0x24 },
2825     		{ OV511_I2C_BUS, 0x2b, 0xac },
2826     		{ OV511_I2C_BUS, 0x12, 0x00 },
2827     		{ OV511_I2C_BUS, 0x38, 0x81 },
2828     		{ OV511_I2C_BUS, 0x28, 0x24 },	/* 0c */
2829     		{ OV511_I2C_BUS, 0x0f, 0x85 },	/* lg's setting */
2830     		{ OV511_I2C_BUS, 0x15, 0x01 },
2831     		{ OV511_I2C_BUS, 0x20, 0x1c },
2832     		{ OV511_I2C_BUS, 0x23, 0x2a },
2833     		{ OV511_I2C_BUS, 0x24, 0x10 },
2834     		{ OV511_I2C_BUS, 0x25, 0x8a },
2835     		{ OV511_I2C_BUS, 0x27, 0xc2 },
2836     		{ OV511_I2C_BUS, 0x2a, 0x04 },
2837     		{ OV511_I2C_BUS, 0x2c, 0xfe },
2838     		{ OV511_I2C_BUS, 0x30, 0x71 },
2839     		{ OV511_I2C_BUS, 0x31, 0x60 },
2840     		{ OV511_I2C_BUS, 0x32, 0x26 },
2841     		{ OV511_I2C_BUS, 0x33, 0x20 },
2842     		{ OV511_I2C_BUS, 0x34, 0x48 },
2843     		{ OV511_I2C_BUS, 0x12, 0x24 },
2844     		{ OV511_I2C_BUS, 0x11, 0x01 },
2845     		{ OV511_I2C_BUS, 0x0c, 0x24 },
2846     		{ OV511_I2C_BUS, 0x0d, 0x24 },
2847     		{ OV511_DONE_BUS, 0x0, 0x00 },
2848     	};
2849     
2850     	static struct ov511_regvals aRegvalsNorm7620[] = {
2851     		{ OV511_I2C_BUS, 0x10, 0xff },
2852     		{ OV511_I2C_BUS, 0x16, 0x06 },
2853     		{ OV511_I2C_BUS, 0x28, 0x24 },
2854     		{ OV511_I2C_BUS, 0x2b, 0xac },
2855     		{ OV511_I2C_BUS, 0x12, 0x00 },
2856     		{ OV511_I2C_BUS, 0x28, 0x24 },
2857     		{ OV511_I2C_BUS, 0x0f, 0x85 },	/* lg's setting */
2858     		{ OV511_I2C_BUS, 0x15, 0x01 },
2859     		{ OV511_I2C_BUS, 0x23, 0x00 },
2860     		{ OV511_I2C_BUS, 0x24, 0x10 },
2861     		{ OV511_I2C_BUS, 0x25, 0x8a },
2862     		{ OV511_I2C_BUS, 0x27, 0xe2 },
2863     		{ OV511_I2C_BUS, 0x2a, 0x00 },
2864     		{ OV511_I2C_BUS, 0x2c, 0xfe },
2865     		{ OV511_I2C_BUS, 0x30, 0x71 },
2866     		{ OV511_I2C_BUS, 0x31, 0x60 },
2867     		{ OV511_I2C_BUS, 0x32, 0x26 },
2868     		{ OV511_I2C_BUS, 0x33, 0x20 },
2869     		{ OV511_I2C_BUS, 0x34, 0x48 },
2870     		{ OV511_I2C_BUS, 0x12, 0x24 },
2871     		{ OV511_I2C_BUS, 0x11, 0x01 },
2872     		{ OV511_I2C_BUS, 0x0c, 0x24 },
2873     		{ OV511_I2C_BUS, 0x0d, 0x24 },
2874     		{ OV511_DONE_BUS, 0x0, 0x00 },
2875     	};
2876     
2877     	PDEBUG (4, "starting configuration");
2878     
2879     	/* This looks redundant, but is necessary for WebCam 3 */
2880     	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
2881     	                    OV7610_I2C_WRITE_ID) < 0)
2882     		return -1;
2883     
2884     	if (ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
2885     	                    OV7610_I2C_READ_ID) < 0)
2886     		return -1;
2887     
2888     	if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)
2889     		return -1;
2890     
2891     	/* Reset the 76xx */ 
2892     	if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
2893     
2894     	/* Wait for it to initialize */ 
2895     	schedule_timeout (1 + 150 * HZ / 1000);
2896     
2897     	for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
2898     		if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) &&
2899     		    (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) {
2900     			success = 1;
2901     			continue;
2902     		}
2903     
2904     		/* Reset the 76xx */ 
2905     		if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
2906     		/* Wait for it to initialize */ 
2907     		schedule_timeout (1 + 150 * HZ / 1000);
2908     		/* Dummy read to sync I2C */
2909     		if (ov511_i2c_read(dev, 0x00) < 0) return -1;
2910     	}
2911     
2912     	if (success) {
2913     		PDEBUG(1, "I2C synced in %d attempt(s) (method 1)", i);
2914     	} else {
2915     		/* Reset the 76xx */
2916     		if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
2917     
2918     		/* Wait for it to initialize */
2919     		schedule_timeout (1 + 150 * HZ / 1000);
2920     
2921     		i = 0;
2922     		success = 0;
2923     		while (i <= i2c_detect_tries) {
2924     			if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) &&
2925     			    (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) {
2926     				success = 1;
2927     				break;
2928     			} else {
2929     				i++;
2930     			}
2931     		}
2932     
2933     		if ((i == i2c_detect_tries) && (success == 0)) {
2934     			err("Failed to read sensor ID. You might not have an OV7610/20,");
2935     			err("or it may be not responding. Report this to");
2936     			err("mwm@i.am");
2937     			return -1;
2938     		} else {
2939     			PDEBUG(1, "I2C synced in %d attempt(s) (method 2)", i+1);
2940     		}
2941     	}
2942     
2943     	/* Detect sensor if user didn't use override param */
2944     	if (sensor == 0) {
2945     		rc = ov511_i2c_read(dev, OV7610_REG_COM_I);
2946     
2947     		if (rc < 0) {
2948     			err("Error detecting sensor type");
2949     			return -1;
2950     		} else if((rc & 3) == 3) {
2951     			info("Sensor is an OV7610");
2952     			ov511->sensor = SEN_OV7610;
2953     		} else if((rc & 3) == 1) {
2954     			info("Sensor is an OV7620AE");
2955     			ov511->sensor = SEN_OV7620AE;
2956     		} else if((rc & 3) == 0) {
2957     			info("Sensor is an OV7620");
2958     			ov511->sensor = SEN_OV7620;
2959     		} else {
2960     			err("Unknown image sensor version: %d", rc & 3);
2961     			return -1;
2962     		}
2963     	} else {	/* sensor != 0; user overrode detection */
2964     		ov511->sensor = sensor;
2965     		info("Sensor set to type %d", ov511->sensor);
2966     	}
2967     
2968     	if (ov511->sensor == SEN_OV7620) {
2969     		PDEBUG(4, "Writing 7620 registers");
2970     		if (ov511_write_regvals(dev, aRegvalsNorm7620))
2971     			return -1;
2972     	} else {
2973     		PDEBUG(4, "Writing 7610 registers");
2974     		if (ov511_write_regvals(dev, aRegvalsNorm7610))
2975     			return -1;
2976     	}
2977     
2978     	/* Set sensor-specific vars */
2979     	ov511->maxwidth = 640;
2980     	ov511->maxheight = 480;
2981     
2982     	if (aperture < 0) {          /* go with the default */
2983     		if (ov511_i2c_write(dev, 0x26, 0xa2) < 0) return -1;
2984     	} else if (aperture <= 0xf) {  /* user overrode default */
2985     		if (ov511_i2c_write(dev, 0x26, (aperture << 4) + 2) < 0)
2986     			return -1;
2987     	} else {
2988     		err("Invalid setting for aperture; legal value: 0 - 15");
2989     		return -1;
2990     	}
2991     
2992     	if (autoadjust) {
2993     		if (ov511_i2c_write(dev, 0x13, 0x01) < 0) return -1;
2994     		if (ov511_i2c_write(dev, 0x2d, 
2995     		     ov511->sensor==SEN_OV7620?0x91:0x93) < 0) return -1;
2996     	} else {
2997     		if (ov511_i2c_write(dev, 0x13, 0x00) < 0) return -1;
2998     		if (ov511_i2c_write(dev, 0x2d, 
2999     		     ov511->sensor==SEN_OV7620?0x81:0x83) < 0) return -1;
3000     		ov511_i2c_write(dev, 0x28, ov511_i2c_read(dev, 0x28) | 8);
3001     	}
3002     
3003     	return 0;
3004     }
3005     
3006     static int ov6xx0_configure(struct usb_ov511 *ov511)
3007     {
3008     	struct usb_device *dev = ov511->dev;
3009     	int i, success, rc;
3010     
3011     	static struct ov511_regvals aRegvalsNorm6x20[] = {
3012     		{ OV511_I2C_BUS, 0x12, 0x80 },  /* reset */
3013     		{ OV511_I2C_BUS, 0x11, 0x01 },
3014     		{ OV511_I2C_BUS, 0x03, 0xd0 },
3015     		{ OV511_I2C_BUS, 0x05, 0x7f },
3016     		{ OV511_I2C_BUS, 0x07, 0xa8 },
3017     		{ OV511_I2C_BUS, 0x0c, 0x24 },
3018     		{ OV511_I2C_BUS, 0x0d, 0x24 },
3019     		{ OV511_I2C_BUS, 0x10, 0xff },  /* ? */
3020     		{ OV511_I2C_BUS, 0x14, 0x04 },
3021     		{ OV511_I2C_BUS, 0x16, 0x06 },  /* ? */
3022     		{ OV511_I2C_BUS, 0x19, 0x04 },
3023     		{ OV511_I2C_BUS, 0x1a, 0x93 },
3024     		{ OV511_I2C_BUS, 0x20, 0x28 },
3025     		{ OV511_I2C_BUS, 0x27, 0xa2 },
3026     		{ OV511_I2C_BUS, 0x28, 0x24 },
3027     		{ OV511_I2C_BUS, 0x2a, 0x04 },  /* 84? */
3028     		{ OV511_I2C_BUS, 0x2b, 0xac },  /* a8? */
3029     		{ OV511_I2C_BUS, 0x2d, 0x95 },
3030     		{ OV511_I2C_BUS, 0x33, 0x28 },
3031     		{ OV511_I2C_BUS, 0x34, 0xc7 },
3032     		{ OV511_I2C_BUS, 0x38, 0x8b },
3033     		{ OV511_I2C_BUS, 0x3c, 0x5c },
3034     		{ OV511_I2C_BUS, 0x3d, 0x80 },
3035     		{ OV511_I2C_BUS, 0x3f, 0x00 },
3036     		{ OV511_I2C_BUS, 0x4a, 0x80 }, /* undocumented */
3037     		{ OV511_I2C_BUS, 0x4b, 0x80 }, /* undocumented */
3038     		{ OV511_I2C_BUS, 0x4d, 0xd2 },
3039     		{ OV511_I2C_BUS, 0x4e, 0xc1 },
3040     		{ OV511_I2C_BUS, 0x4f, 0x04 },
3041     		{ OV511_DONE_BUS, 0x0, 0x00 },
3042     	};
3043     
3044     	PDEBUG (4, "starting sensor configuration");
3045     	
3046     	/* Reset the 6xx0 */ 
3047     	if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
3048     
3049     	/* Wait for it to initialize */ 
3050     	schedule_timeout (1 + 150 * HZ / 1000);
3051     
3052     	for (i = 0, success = 0; i < i2c_detect_tries && !success; i++) {
3053     		if ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) == 0x7F) &&
3054     		    (ov511_i2c_read(dev, OV7610_REG_ID_LOW) == 0xA2)) {
3055     			success = 1;
3056     			continue;
3057     		}
3058     
3059     		/* Reset the 6xx0 */ 
3060     		if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
3061     		/* Wait for it to initialize */ 
3062     		schedule_timeout (1 + 150 * HZ / 1000);
3063     		/* Dummy read to sync I2C */
3064     		if (ov511_i2c_read(dev, 0x00) < 0) return -1;
3065     	}
3066     
3067     	if (success) {
3068     		PDEBUG(1, "I2C synced in %d attempt(s)", i);
3069     	} else {
3070     		err("Failed to read sensor ID. You might not have an OV6xx0,");
3071     		err("or it may be not responding. Report this to");
3072     		err("mwm@i.am");
3073     		return -1;
3074     	}
3075     
3076     	/* Detect sensor if user didn't use override param */
3077     	if (sensor == 0) {
3078     		rc = ov511_i2c_read(dev, OV7610_REG_COM_I);
3079     
3080     		if (rc < 0) {
3081     			err("Error detecting sensor type");
3082     			return -1;
3083     		} else {
3084     			info("Sensor is an OV6xx0 (version %d)", rc & 3);
3085     			ov511->sensor = SEN_OV6620;
3086     		}
3087     	} else {	/* sensor != 0; user overrode detection */
3088     		ov511->sensor = sensor;
3089     		info("Sensor set to type %d", ov511->sensor);
3090     	}
3091     
3092     	/* Set sensor-specific vars */
3093     	ov511->maxwidth = 352;
3094     	ov511->maxheight = 288;
3095     
3096     	PDEBUG(4, "Writing 6x20 registers");
3097     	if (ov511_write_regvals(dev, aRegvalsNorm6x20))
3098     		return -1;
3099     
3100     	if (aperture < 0) {          /* go with the default */
3101     		if (ov511_i2c_write(dev, 0x26, 0xa2) < 0) return -1;
3102     	} else if (aperture <= 0xf) {  /* user overrode default */
3103     		if (ov511_i2c_write(dev, 0x26, (aperture << 4) + 2) < 0)
3104     			return -1;
3105     	} else {
3106     		err("Invalid setting for aperture; legal value: 0 - 15");
3107     		return -1;
3108     	}
3109     
3110     	if (autoadjust) {
3111     		if (ov511_i2c_write(dev, 0x13, 0x01) < 0) return -1;
3112     		if (ov511_i2c_write(dev, 0x2d, 
3113     		     ov511->sensor==SEN_OV7620?0x91:0x93) < 0) return -1;
3114     	} else {
3115     		if (ov511_i2c_write(dev, 0x13, 0x00) < 0) return -1;
3116     		if (ov511_i2c_write(dev, 0x2d, 
3117     		     ov511->sensor==SEN_OV7620?0x81:0x83) < 0) return -1;
3118     		ov511_i2c_write(dev, 0x28, ov511_i2c_read(dev, 0x28) | 8);
3119     	}
3120     
3121     	return 0;
3122     }
3123     
3124     
3125     static int ov511_configure(struct usb_ov511 *ov511)
3126     {
3127     	struct usb_device *dev = ov511->dev;
3128     	int i;
3129     
3130     	static struct ov511_regvals aRegvalsInit[] = {
3131     		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
3132     	 	{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
3133     	 	{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f },
3134     		{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
3135     		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3f },
3136     		{ OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01 },
3137     		{ OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3d },
3138     		{ OV511_DONE_BUS, 0x0, 0x00},
3139     	};
3140     
3141     	static struct ov511_regvals aRegvalsNorm511[] = {
3142     		{ OV511_REG_BUS, OV511_REG_DRAM_ENABLE_FLOW_CONTROL, 0x01 },
3143     		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x02 },
3144     		{ OV511_REG_BUS, OV511_REG_SYSTEM_SNAPSHOT, 0x00 },
3145     		{ OV511_REG_BUS, OV511_REG_FIFO_BITMASK, 0x1f },
3146     		{ OV511_REG_BUS, OV511_OMNICE_PREDICTION_HORIZ_Y, 0x08 },
3147     		{ OV511_REG_BUS, OV511_OMNICE_PREDICTION_HORIZ_UV, 0x01 },
3148     		{ OV511_REG_BUS, OV511_OMNICE_PREDICTION_VERT_Y, 0x08 },
3149     		{ OV511_REG_BUS, OV511_OMNICE_PREDICTION_VERT_UV, 0x01 },
3150     		{ OV511_REG_BUS, OV511_OMNICE_QUANTIZATION_HORIZ_Y, 0x01 },
3151     		{ OV511_REG_BUS, OV511_OMNICE_QUANTIZATION_HORIZ_UV, 0x01 },
3152     		{ OV511_REG_BUS, OV511_OMNICE_QUANTIZATION_VERT_Y, 0x01 },
3153     		{ OV511_REG_BUS, OV511_OMNICE_QUANTIZATION_VERT_UV, 0x01 },
3154     		{ OV511_REG_BUS, OV511_OMNICE_ENABLE, 0x06 },
3155     		{ OV511_REG_BUS, OV511_OMNICE_LUT_ENABLE, 0x03 },
3156     		{ OV511_DONE_BUS, 0x0, 0x00 },<