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