Import 2.3.52pre1
[davej-history.git] / drivers / usb / ov511.c
blob764b37753d82bccd5b9cb96ef3bcdeb46f614009
1 /*
2 * OmniVision OV511 Camera-to-USB Bridge Driver
3 * Copyright (c) 1999/2000 Mark W. McClelland
4 * Many improvements by Bret Wallach
5 * Color fixes by by Orion Sky Lawlor, olawlor@acm.org, 2/26/2000
6 * Snapshot code by Kevin Moore
7 *
8 * Based on the Linux CPiA driver.
9 *
10 * Released under GPL v.2 license.
12 * Version: 1.09
14 * Please see the file: linux/Documentation/usb/ov511.txt
15 * and the website at: http://alpha.dyndns.org/ov511
16 * for more info.
20 * This program is free software; you can redistribute it and/or modify it
21 * under the terms of the GNU General Public License as published by the
22 * Free Software Foundation; either version 2 of the License, or (at your
23 * option) any later version.
25 * This program is distributed in the hope that it will be useful, but
26 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
27 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 * for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software Foundation,
32 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 #define __NO_VERSION__
37 /* Handle mangled (versioned) external symbols */
39 #include <linux/config.h> /* retrieve the CONFIG_* macros */
40 #include <linux/kernel.h>
41 #include <linux/sched.h>
42 #include <linux/list.h>
43 #include <linux/malloc.h>
44 #include <linux/mm.h>
45 #include <linux/smp_lock.h>
46 #include <linux/videodev.h>
47 #include <linux/vmalloc.h>
48 #include <linux/wrapper.h>
49 #include <linux/module.h>
50 #include <linux/init.h>
51 #include <linux/spinlock.h>
52 #include <linux/time.h>
53 #include <linux/usb.h>
54 #include <asm/io.h>
56 #include "ov511.h"
58 #define OV511_I2C_RETRIES 3
60 /* Video Size 640 x 480 x 3 bytes for RGB */
61 #define MAX_FRAME_SIZE (640 * 480 * 3)
62 #define MAX_DATA_SIZE (MAX_FRAME_SIZE + sizeof(struct timeval))
64 // FIXME - Should find a better way to do this.
65 #define DEFAULT_WIDTH 640
66 #define DEFAULT_HEIGHT 480
68 // PARAMETER VARIABLES:
69 static int autoadjust = 1; /* CCD dynamically changes exposure, etc... */
71 /* 0=no debug messages
72 * 1=init/detection/unload and other significant messages,
73 * 2=some warning messages
74 * 3=config/control function calls
75 * 4=most function calls and data parsing messages
76 * 5=highly repetitive mesgs
77 * NOTE: This should be changed to 0, 1, or 2 for production kernels
79 static int debug = 3;
81 /* Fix vertical misalignment of red and blue at 640x480 */
82 static int fix_rgb_offset = 0;
84 /* Snapshot mode enabled flag */
85 static int snapshot = 0;
87 MODULE_PARM(autoadjust, "i");
88 MODULE_PARM(debug, "i");
89 MODULE_PARM(fix_rgb_offset, "i");
90 MODULE_PARM(snapshot, "i");
92 MODULE_AUTHOR("Mark McClelland (and others)");
93 MODULE_DESCRIPTION("OV511 USB Camera Driver");
95 char kernel_version[] = UTS_RELEASE;
97 /*******************************/
98 /* Memory management functions */
99 /*******************************/
101 #define MDEBUG(x) do { } while(0) /* Debug memory management */
103 static struct usb_driver ov511_driver;
105 /* Given PGD from the address space's page table, return the kernel
106 * virtual mapping of the physical memory mapped at ADR.
108 static inline unsigned long uvirt_to_kva(pgd_t *pgd, unsigned long adr)
110 unsigned long ret = 0UL;
111 pmd_t *pmd;
112 pte_t *ptep, pte;
114 if (!pgd_none(*pgd)) {
115 pmd = pmd_offset(pgd, adr);
116 if (!pmd_none(*pmd)) {
117 ptep = pte_offset(pmd, adr);
118 pte = *ptep;
119 if (pte_present(pte))
120 ret = page_address(pte_page(pte)) | (adr & (PAGE_SIZE-1));
123 MDEBUG(printk("uv2kva(%lx-->%lx)", adr, ret));
124 return ret;
127 static inline unsigned long uvirt_to_bus(unsigned long adr)
129 unsigned long kva, ret;
131 kva = uvirt_to_kva(pgd_offset(current->mm, adr), adr);
132 ret = virt_to_bus((void *)kva);
133 MDEBUG(printk("uv2b(%lx-->%lx)", adr, ret));
134 return ret;
137 static inline unsigned long kvirt_to_bus(unsigned long adr)
139 unsigned long va, kva, ret;
141 va = VMALLOC_VMADDR(adr);
142 kva = uvirt_to_kva(pgd_offset_k(va), va);
143 ret = virt_to_bus((void *)kva);
144 MDEBUG(printk("kv2b(%lx-->%lx)", adr, ret));
145 return ret;
148 /* Here we want the physical address of the memory.
149 * This is used when initializing the contents of the
150 * area and marking the pages as reserved.
152 static inline unsigned long kvirt_to_pa(unsigned long adr)
154 unsigned long va, kva, ret;
156 va = VMALLOC_VMADDR(adr);
157 kva = uvirt_to_kva(pgd_offset_k(va), va);
158 ret = __pa(kva);
159 MDEBUG(printk("kv2pa(%lx-->%lx)", adr, ret));
160 return ret;
163 static void *rvmalloc(unsigned long size)
165 void *mem;
166 unsigned long adr, page;
168 /* Round it off to PAGE_SIZE */
169 size += (PAGE_SIZE - 1);
170 size &= ~(PAGE_SIZE - 1);
172 mem = vmalloc(size);
173 if (!mem)
174 return NULL;
176 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
177 adr = (unsigned long) mem;
178 while (size > 0) {
179 page = kvirt_to_pa(adr);
180 mem_map_reserve(MAP_NR(__va(page)));
181 adr += PAGE_SIZE;
182 if (size > PAGE_SIZE)
183 size -= PAGE_SIZE;
184 else
185 size = 0;
188 return mem;
191 static void rvfree(void *mem, unsigned long size)
193 unsigned long adr, page;
195 if (!mem)
196 return;
198 size += (PAGE_SIZE - 1);
199 size &= ~(PAGE_SIZE - 1);
201 adr=(unsigned long) mem;
202 while (size > 0) {
203 page = kvirt_to_pa(adr);
204 mem_map_unreserve(MAP_NR(__va(page)));
205 adr += PAGE_SIZE;
206 if (size > PAGE_SIZE)
207 size -= PAGE_SIZE;
208 else
209 size = 0;
211 vfree(mem);
214 int ov511_reg_write(struct usb_device *dev, unsigned char reg, unsigned char value)
216 int rc;
218 rc = usb_control_msg(dev,
219 usb_sndctrlpipe(dev, 0),
220 2 /* REG_IO */,
221 USB_TYPE_CLASS | USB_RECIP_DEVICE,
222 0, (__u16)reg, &value, 1, HZ);
224 PDEBUG(5, "reg write: 0x%02X:0x%02X, 0x%x", reg, value, rc);
226 return rc;
229 /* returns: negative is error, pos or zero is data */
230 int ov511_reg_read(struct usb_device *dev, unsigned char reg)
232 int rc;
233 unsigned char buffer[1];
235 rc = usb_control_msg(dev,
236 usb_rcvctrlpipe(dev, 0),
237 2 /* REG_IO */,
238 USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_DEVICE,
239 0, (__u16)reg, buffer, 1, HZ);
241 PDEBUG(5, "reg read: 0x%02X:0x%02X", reg, buffer[0]);
243 if(rc < 0)
244 return rc;
245 else
246 return buffer[0];
249 int ov511_i2c_write(struct usb_device *dev, unsigned char reg, unsigned char value)
251 int rc, retries;
253 PDEBUG(5, "i2c write: 0x%02X:0x%02X", reg, value);
255 /* Three byte write cycle */
256 for(retries = OV511_I2C_RETRIES;;) {
257 /* Select camera register */
258 rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_3_BYTE, reg);
259 if (rc < 0) return rc;
261 /* Write "value" to I2C data port of OV511 */
262 rc = ov511_reg_write(dev, OV511_REG_I2C_DATA_PORT, value);
263 if (rc < 0) return rc;
265 /* Initiate 3-byte write cycle */
266 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x01);
267 if (rc < 0) return rc;
269 do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
270 while(rc > 0 && ((rc&1) == 0)); /* Retry until idle */
271 if (rc < 0) return rc;
273 if((rc&2) == 0) /* Ack? */
274 break;
275 #if 0
276 /* I2C abort */
277 ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
278 #endif
279 if (--retries < 0) return -1;
282 return 0;
285 /* returns: negative is error, pos or zero is data */
286 int ov511_i2c_read(struct usb_device *dev, unsigned char reg)
288 int rc, value, retries;
290 /* Two byte write cycle */
291 for(retries = OV511_I2C_RETRIES;;) {
292 /* Select camera register */
293 rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
294 if (rc < 0) return rc;
296 /* Initiate 2-byte write cycle */
297 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
298 if (rc < 0) return rc;
300 do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
301 while(rc > 0 && ((rc&1) == 0)); /* Retry until idle */
302 if (rc < 0) return rc;
304 if((rc&2) == 0) /* Ack? */
305 break;
307 /* I2C abort */
308 ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
310 if (--retries < 0) return -1;
313 /* Two byte read cycle */
314 for(retries = OV511_I2C_RETRIES;;) {
315 /* Initiate 2-byte read cycle */
316 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
317 if (rc < 0) return rc;
319 do rc = ov511_reg_read(dev, OV511_REG_I2C_CONTROL);
320 while(rc > 0 && ((rc&1) == 0)); /* Retry until idle */
321 if (rc < 0) return rc;
323 if((rc&2) == 0) /* Ack? */
324 break;
326 /* I2C abort */
327 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x10);
328 if (rc < 0) return rc;
330 if (--retries < 0) return -1;
333 value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
335 PDEBUG(5, "i2c read: 0x%02X:0x%02X", reg, value);
337 /* This is needed to make ov511_i2c_write() work */
338 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
339 if (rc < 0) return rc;
341 return (value);
345 // This version doesn't always work
346 #if 0
347 /* returns: negative is error, pos or zero is data */
348 int ov511_i2c_read(struct usb_device *dev, unsigned char reg)
350 int rc, value;
352 /* Select camera register */
353 rc = ov511_reg_write(dev, OV511_REG_I2C_SUB_ADDRESS_2_BYTE, reg);
354 if (rc < 0) return rc;
357 /* Initiate 2-byte write cycle */
358 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x03);
359 if (rc < 0) return rc;
362 /* Initiate 2-byte read cycle */
363 rc = ov511_reg_write(dev, OV511_REG_I2C_CONTROL, 0x05);
364 if (rc < 0) return rc;
366 value = ov511_reg_read(dev, OV511_REG_I2C_DATA_PORT);
368 PDEBUG(5, "i2c read: 0x%02X:0x%02X", reg, value);
370 return (value);
372 #endif
374 static int ov511_write_regvals(struct usb_device *dev,
375 struct ov511_regvals * pRegvals)
377 int ret;
378 while(pRegvals->bus != OV511_DONE_BUS) {
379 if (pRegvals->bus == OV511_REG_BUS) {
380 if ((ret = ov511_reg_write(dev, pRegvals->reg,
381 pRegvals->val)) < 0)
382 return ret;
383 } else if (pRegvals->bus == OV511_I2C_BUS) {
384 if ((ret = ov511_i2c_write(dev, pRegvals->reg,
385 pRegvals->val)) < 0)
386 return ret;
387 } else {
388 err("Bad regval array");
390 pRegvals++;
392 return 0;
395 #if 0
396 static void ov511_dump_i2c_range( struct usb_device *dev, int reg1, int regn)
398 int i;
399 int rc;
400 for(i=reg1; i<=regn; i++) {
401 rc = ov511_i2c_read(dev, i);
403 PDEBUG(1, "OV7610[0x%X] = 0x%X", i, rc);
407 static void ov511_dump_i2c_regs( struct usb_device *dev)
409 PDEBUG(3, "I2C REGS");
410 ov511_dump_i2c_range(dev, 0x00, 0x38);
413 static void ov511_dump_reg_range( struct usb_device *dev, int reg1, int regn)
415 int i;
416 int rc;
417 for(i=reg1; i<=regn; i++) {
418 rc = ov511_reg_read(dev, i);
419 PDEBUG(1, "OV511[0x%X] = 0x%X", i, rc);
423 static void ov511_dump_regs( struct usb_device *dev)
425 PDEBUG(1, "CAMERA INTERFACE REGS");
426 ov511_dump_reg_range(dev, 0x10, 0x1f);
427 PDEBUG(1, "DRAM INTERFACE REGS");
428 ov511_dump_reg_range(dev, 0x20, 0x23);
429 PDEBUG(1, "ISO FIFO REGS");
430 ov511_dump_reg_range(dev, 0x30, 0x31);
431 PDEBUG(1, "PIO REGS");
432 ov511_dump_reg_range(dev, 0x38, 0x39);
433 ov511_dump_reg_range(dev, 0x3e, 0x3e);
434 PDEBUG(1, "I2C REGS");
435 ov511_dump_reg_range(dev, 0x40, 0x49);
436 PDEBUG(1, "SYSTEM CONTROL REGS");
437 ov511_dump_reg_range(dev, 0x50, 0x53);
438 ov511_dump_reg_range(dev, 0x5e, 0x5f);
439 PDEBUG(1, "OmniCE REGS");
440 ov511_dump_reg_range(dev, 0x70, 0x79);
441 ov511_dump_reg_range(dev, 0x80, 0x9f);
442 ov511_dump_reg_range(dev, 0xa0, 0xbf);
445 #endif
447 int ov511_reset(struct usb_device *dev, unsigned char reset_type)
449 int rc;
451 PDEBUG(3, "Reset: type=0x%X", reset_type);
452 rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, reset_type);
453 if (rc < 0)
454 err("reset: command failed");
456 rc = ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0);
457 if (rc < 0)
458 err("reset: command failed");
460 return rc;
463 int ov511_set_packet_size(struct usb_ov511 *ov511, int size)
465 int alt, multiplier, rc;
467 PDEBUG(3, "set packet size: %d", size);
469 switch (size) {
470 case 992:
471 alt = 0;
472 multiplier = 31;
473 break;
474 case 993:
475 alt = 1;
476 multiplier = 31;
477 break;
478 case 768:
479 alt = 2;
480 multiplier = 24;
481 break;
482 case 769:
483 alt = 3;
484 multiplier = 24;
485 break;
486 case 512:
487 alt = 4;
488 multiplier = 16;
489 break;
490 case 513:
491 alt = 5;
492 multiplier = 16;
493 break;
494 case 257:
495 alt = 6;
496 multiplier = 8;
497 break;
498 case 0:
499 alt = 7;
500 multiplier = 1; // FIXME - is this correct?
501 break;
502 default:
503 err("Set packet size: invalid size (%d)", size);
504 return -EINVAL;
507 rc = ov511_reg_write(ov511->dev, OV511_REG_FIFO_PACKET_SIZE,
508 multiplier);
509 if (rc < 0) {
510 err("Set packet size: Set FIFO size ret %d", rc);
511 return -ENOMEM;
514 if (usb_set_interface(ov511->dev, ov511->iface, alt) < 0) {
515 err("Set packet size: set interface error");
516 return -EBUSY;
519 // FIXME - Should we only reset the FIFO?
520 if (ov511_reset(ov511->dev, OV511_RESET_NOREGS) < 0)
521 return -ENOMEM;
523 return 0;
526 static inline int ov7610_set_picture(struct usb_ov511 *ov511,
527 struct video_picture *p)
529 int ret;
531 /* Stop the camera */
532 if (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0x3d) < 0) {
533 err("reset: command failed");
534 return -EIO;
537 if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_COM_B)) < 0)
538 return -EIO;
539 #if 0
540 if(ov511_i2c_write(ov511->dev, OV7610_REG_COM_B, ret & 0xfe) < 0)
541 return -EIO;
542 #endif
544 if(ov511_i2c_write(ov511->dev, OV7610_REG_SAT, p->colour >> 8) < 0)
545 return -EIO;
547 if(ov511_i2c_write(ov511->dev, OV7610_REG_CNT, p->contrast >> 8) < 0)
548 return -EIO;
550 if(ov511_i2c_write(ov511->dev, OV7610_REG_BRT, p->brightness >> 8) < 0)
551 return -EIO;
553 /* Restart the camera */
554 if (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0x0) < 0) {
555 err("reset: command failed");
556 return -EIO;
559 return 0;
562 static inline int ov7610_get_picture(struct usb_ov511 *ov511,
563 struct video_picture *p)
565 int ret;
567 /* Stop the camera */
568 if (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0x3d) < 0) {
569 err("reset: command failed");
570 return -EIO;
573 if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_SAT)) < 0) return -EIO;
574 p->colour = ret << 8;
576 if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_CNT)) < 0) return -EIO;
577 p->contrast = ret << 8;
579 if((ret = ov511_i2c_read(ov511->dev, OV7610_REG_BRT)) < 0) return -EIO;
580 p->brightness = ret << 8;
582 p->hue = 0x8000;
583 p->whiteness = 105 << 8;
584 p->depth = 3; /* Don't know if this is right */
585 p->palette = VIDEO_PALETTE_RGB24;
587 /* Restart the camera */
588 if (ov511_reg_write(ov511->dev, OV511_REG_SYSTEM_RESET, 0x0) < 0) {
589 err("reset: command failed");
590 return -EIO;
593 return 0;
596 static int ov511_mode_init_regs(struct usb_ov511 *ov511,
597 int width, int height, int mode, int sub_flag)
599 int rc = 0;
600 struct usb_device *dev = ov511->dev;
602 PDEBUG(3, "ov511_mode_init_regs(ov511, w:%d, h:%d, mode:%d, sub:%d)",
603 width, height, mode, sub_flag);
605 // ov511_set_packet_size(ov511, 0);
606 if (ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0x3d) < 0) {
607 err("reset: command failed");
608 return -EIO;
611 if (mode == VIDEO_PALETTE_GREY) {
612 ov511_reg_write(dev, 0x16, 0x00);
613 ov511_i2c_write(dev, 0x0e, 0x44);
614 ov511_i2c_write(dev, 0x13, 0x21);
615 /* For snapshot */
616 ov511_reg_write(dev, 0x1e, 0x00);
617 ov511_reg_write(dev, 0x1f, 0x01);
618 } else {
619 ov511_reg_write(dev, 0x16, 0x01);
620 ov511_i2c_write(dev, 0x0e, 0x04);
621 ov511_i2c_write(dev, 0x13, 0x01);
622 /* For snapshot */
623 ov511_reg_write(dev, 0x1e, 0x01);
624 ov511_reg_write(dev, 0x1f, 0x03);
627 if (width == 640 && height == 480) {
628 if (sub_flag) {
629 ov511_i2c_write(ov511->dev, 0x17, 0x38+(ov511->subx>>2));
630 ov511_i2c_write(ov511->dev, 0x18,
631 0x3a+((ov511->subx+ov511->subw)>>2));
632 ov511_i2c_write(ov511->dev, 0x19, 0x5+(ov511->suby>>1));
633 ov511_i2c_write(ov511->dev, 0x1a,
634 0x5+((ov511->suby+ov511->subh)>>1));
635 ov511_reg_write(ov511->dev, 0x12, (ov511->subw>>3)-1);
636 ov511_reg_write(ov511->dev, 0x13, (ov511->subh>>3)-1);
637 ov511_i2c_write(dev, 0x11, 0x01);
639 /* Snapshot additions */
640 ov511_reg_write(ov511->dev, 0x1a, (ov511->subw>>3)-1);
641 ov511_reg_write(ov511->dev, 0x1b, (ov511->subh>>3)-1);
642 ov511_reg_write(ov511->dev, 0x1c, 0x00);
643 ov511_reg_write(ov511->dev, 0x1d, 0x00);
644 } else {
645 ov511_i2c_write(ov511->dev, 0x17, 0x38);
646 ov511_i2c_write(ov511->dev, 0x18, 0x3a + (640>>2));
647 ov511_i2c_write(ov511->dev, 0x19, 0x5);
648 ov511_i2c_write(ov511->dev, 0x1a, 5 + (480>>1));
649 ov511_reg_write(dev, 0x12, 0x4f);
650 ov511_reg_write(dev, 0x13, 0x3d);
652 /* Snapshot additions */
653 ov511_reg_write(ov511->dev, 0x1a, 0x4f);
654 ov511_reg_write(ov511->dev, 0x1b, 0x3d);
655 ov511_reg_write(ov511->dev, 0x1c, 0x00);
656 ov511_reg_write(ov511->dev, 0x1d, 0x00);
658 if (mode == VIDEO_PALETTE_GREY) {
659 ov511_i2c_write(dev, 0x11, 4); /* check */
660 } else {
661 ov511_i2c_write(dev, 0x11, 6); /* check */
665 ov511_reg_write(dev, 0x14, 0x00);
666 ov511_reg_write(dev, 0x15, 0x00);
668 /* FIXME?? Shouldn't below be true only for YUV420? */
669 ov511_reg_write(dev, 0x18, 0x03);
671 ov511_i2c_write(dev, 0x12, 0x24);
672 ov511_i2c_write(dev, 0x14, 0x04);
673 ov511_i2c_write(dev, 0x35, 0x9e);
674 } else if (width == 320 && height == 240) {
675 ov511_reg_write(dev, 0x12, 0x27);
676 ov511_reg_write(dev, 0x13, 0x1f);
677 ov511_reg_write(dev, 0x14, 0x00);
678 ov511_reg_write(dev, 0x15, 0x00);
679 ov511_reg_write(dev, 0x18, 0x03);
681 /* Snapshot additions */
682 ov511_reg_write(dev, 0x1a, 0x27);
683 ov511_reg_write(dev, 0x1b, 0x1f);
684 ov511_reg_write(dev, 0x1c, 0x00);
685 ov511_reg_write(dev, 0x1d, 0x00);
687 if (mode == VIDEO_PALETTE_GREY) {
688 ov511_i2c_write(dev, 0x11, 1); /* check */
689 } else {
690 ov511_i2c_write(dev, 0x11, 1); /* check */
693 ov511_i2c_write(dev, 0x12, 0x04);
694 ov511_i2c_write(dev, 0x14, 0x24);
695 ov511_i2c_write(dev, 0x35, 0x1e);
696 } else {
697 err("Unknown mode (%d, %d): %d", width, height, mode);
698 rc = -EINVAL;
701 // ov511_set_packet_size(ov511, 993);
703 if (ov511_reg_write(dev, OV511_REG_SYSTEM_RESET, 0x00) < 0) {
704 err("reset: command failed");
705 return -EIO;
708 return rc;
712 /*************************************************************
714 Turn a YUV4:2:0 block into an RGB block
716 Video4Linux seems to use the blue, green, red channel
717 order convention-- rgb[0] is blue, rgb[1] is green, rgb[2] is red.
719 Color space conversion coefficients taken from the excellent
720 http://www.inforamp.net/~poynton/ColorFAQ.html
721 In his terminology, this is a CCIR 601.1 YCbCr -> RGB.
722 Y values are given for all 4 pixels, but the U (Pb)
723 and V (Pr) are assumed constant over the 2x2 block.
725 To avoid floating point arithmetic, the color conversion
726 coefficients are scaled into 16.16 fixed-point integers.
728 *************************************************************/
729 // LIMIT: convert a 16.16 fixed-point value to a byte, with clipping.
730 #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))
731 static inline void ov511_move_420_block(
732 int yTL, int yTR, int yBL, int yBR,
733 int u, int v,
734 int rowPixels, unsigned char * rgb)
736 const double brightness=1.0;//0->black; 1->full scale
737 const double saturation=1.0;//0->greyscale; 1->full color
738 const double fixScale=brightness*256*256;
739 const int rvScale=(int)(1.402*saturation*fixScale);
740 const int guScale=(int)(-0.344136*saturation*fixScale);
741 const int gvScale=(int)(-0.714136*saturation*fixScale);
742 const int buScale=(int)(1.772*saturation*fixScale);
743 const int yScale=(int)(fixScale);
745 int r = rvScale * v;
746 int g = guScale * u + gvScale * v;
747 int b = buScale * u;
748 yTL *= yScale; yTR *= yScale;
749 yBL *= yScale; yBR *= yScale;
751 //Write out top two pixels
752 rgb[0]=LIMIT(b+yTL); rgb[1]=LIMIT(g+yTL); rgb[2]=LIMIT(r+yTL);
753 rgb[3]=LIMIT(b+yTR); rgb[4]=LIMIT(g+yTR); rgb[5]=LIMIT(r+yTR);
754 rgb+=3*rowPixels;//Skip down to next line to write out bottom two pixels
755 rgb[0]=LIMIT(b+yBL); rgb[1]=LIMIT(g+yBL); rgb[2]=LIMIT(r+yBL);
756 rgb[3]=LIMIT(b+yBR); rgb[4]=LIMIT(g+yBR); rgb[5]=LIMIT(r+yBR);
760 /***************************************************************
762 For a 640x480 YUV4:2:0 images, data shows up in 1200 384 byte segments. The
763 first 64 bytes of each segment are U, the next 64 are V. The U and
764 V are arranged as follows:
766 0 1 ... 7
767 8 9 ... 15
768 ...
769 56 57 ... 63
771 U and V are shipped at half resolution (1 U,V sample -> one 2x2 block).
773 The next 256 bytes are full resolution Y data and represent 4
774 squares of 8x8 pixels as follows:
776 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
777 8 9 ... 15 72 73 ... 79 200 201 ... 207
778 ... ... ...
779 56 57 ... 63 120 121 127 248 249 ... 255
781 Note that the U and V data in one segment represents a 16 x 16 pixel
782 area, but the Y data represents a 32 x 8 pixel area.
784 If OV511_DUMPPIX is defined, _parse_data just dumps the
785 incoming segments, verbatim, in order, into the frame.
786 When used with vidcat -f ppm -s 640x480 this puts the data
787 on the standard output and can be analyzed with the parseppm.c
788 utility I wrote. That's a much faster way for figuring out how
789 this data is scrambled.
791 ****************************************************************/
792 #define HDIV 8
793 #define WDIV (256/HDIV)
796 static void ov511_parse_data_rgb24(unsigned char * pIn0,
797 unsigned char * pOut0,
798 int iOutY,
799 int iOutUV,
800 int iHalf,
801 int iWidth)
804 #ifndef OV511_DUMPPIX
805 int k, l, m;
806 unsigned char * pIn;
807 unsigned char * pOut, * pOut1;
809 /* Just copy the Y's if in the first stripe */
810 if (!iHalf) {
811 pIn = pIn0 + 128;
812 pOut = pOut0 + iOutY;
813 for(k=0; k<4; k++) {
814 pOut1 = pOut;
815 for(l=0; l<8; l++) {
816 for(m=0; m<8; m++) {
817 *pOut1 = *pIn++;
818 pOut1 += 3;
820 pOut1 += (iWidth - 8) * 3;
822 pOut += 8 * 3;
826 /* Use the first half of VUs to calculate value */
827 pIn = pIn0;
828 pOut = pOut0 + iOutUV;
829 for(l=0; l<4; l++) {
830 for(m=0; m<8; m++) {
831 int y00 = *(pOut);
832 int y01 = *(pOut+3);
833 int y10 = *(pOut+iWidth*3);
834 int y11 = *(pOut+iWidth*3+3);
835 int v = *(pIn+64) - 128;
836 int u = *pIn++ - 128;
837 ov511_move_420_block(y00, y01, y10, y11, u, v, iWidth, pOut);
838 pOut += 6;
840 pOut += (iWidth*2 - 16) * 3;
843 /* Just copy the other UV rows */
844 for(l=0; l<4; l++) {
845 for(m=0; m<8; m++) {
846 *pOut++ = *(pIn + 64);
847 *pOut = *pIn++;
848 pOut += 5;
850 pOut += (iWidth*2 - 16) * 3;
853 /* Calculate values if it's the second half */
854 if (iHalf) {
855 pIn = pIn0 + 128;
856 pOut = pOut0 + iOutY;
857 for(k=0; k<4; k++) {
858 pOut1 = pOut;
859 for(l=0; l<4; l++) {
860 for(m=0; m<4; m++) {
861 int y10 = *(pIn+8);
862 int y00 = *pIn++;
863 int y11 = *(pIn+8);
864 int y01 = *pIn++;
865 int v = *pOut1 - 128;
866 int u = *(pOut1+1) - 128;
867 ov511_move_420_block(y00, y01, y10, y11, u, v, iWidth, pOut1);
868 pOut1 += 6;
870 pOut1 += (iWidth*2 - 8) * 3;
871 pIn += 8;
873 pOut += 8 * 3;
877 #else
878 /* Just dump pix data straight out for debug */
879 int i;
880 pOut0 += iSegmentY * 384;
881 for(i=0; i<384; i++) {
882 *pOut0++ = *pIn0++;
884 #endif
887 /***************************************************************
889 For 640x480 RAW BW images, data shows up in 1200 256 byte segments.
890 The segments represent 4 squares of 8x8 pixels as
891 follows:
893 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
894 8 9 ... 15 72 73 ... 79 200 201 ... 207
895 ... ... ...
896 56 57 ... 63 120 121 127 248 249 ... 255
898 ****************************************************************/
899 static void ov511_parse_data_grey(unsigned char * pIn0,
900 unsigned char * pOut0,
901 int iOutY,
902 int iWidth)
905 int k, l, m;
906 unsigned char * pIn;
907 unsigned char * pOut, * pOut1;
909 pIn = pIn0;
910 pOut = pOut0 + iOutY;
911 for(k=0; k<4; k++) {
912 pOut1 = pOut;
913 for(l=0; l<8; l++) {
914 for(m=0; m<8; m++) {
915 *pOut1++ = *pIn++;
917 pOut1 += iWidth - 8;
919 pOut += 8;
924 /**************************************************************
925 * fixFrameRGBoffset--
926 * My camera seems to return the red channel about 1 pixel
927 * low, and the blue channel about 1 pixel high. After YUV->RGB
928 * conversion, we can correct this easily. OSL 2/24/2000.
929 *************************************************************/
930 static void fixFrameRGBoffset(struct ov511_frame *frame)
932 int x,y;
933 int rowBytes=frame->width*3,w=frame->width;
934 unsigned char *rgb=frame->data;
935 const int shift=1;//Distance to shift pixels by, vertically
937 if (frame->width<400)
938 return;//Don't bother with little images
940 //Shift red channel up
941 for (y=shift;y<frame->height;y++)
943 int lp=(y-shift)*rowBytes;//Previous line offset
944 int lc=y*rowBytes;//Current line offset
945 for (x=0;x<w;x++)
946 rgb[lp+x*3+2]=rgb[lc+x*3+2];//Shift red up
948 //Shift blue channel down
949 for (y=frame->height-shift-1;y>=0;y--)
951 int ln=(y+shift)*rowBytes;//Next line offset
952 int lc=y*rowBytes;//Current line offset
953 for (x=0;x<w;x++)
954 rgb[ln+x*3+0]=rgb[lc+x*3+0];//Shift blue down
959 static int ov511_move_data(struct usb_ov511 *ov511, urb_t *urb)
961 unsigned char *cdata;
962 int i, totlen = 0;
963 int aPackNum[10];
964 struct ov511_frame *frame;
966 for (i = 0; i < urb->number_of_packets; i++) {
967 int n = urb->iso_frame_desc[i].actual_length;
968 int st = urb->iso_frame_desc[i].status;
969 urb->iso_frame_desc[i].actual_length = 0;
970 urb->iso_frame_desc[i].status = 0;
971 cdata = urb->transfer_buffer + urb->iso_frame_desc[i].offset;
973 aPackNum[i] = n ? cdata[992] : -1;
975 if (!n || ov511->curframe == -1) continue;
977 if (st)
978 PDEBUG(2, "data error: [%d] len=%d, status=%d", i, n, st);
980 frame = &ov511->frame[ov511->curframe];
982 /* Can we find a frame end */
983 if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] |
984 cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
985 (cdata[8] & 8) && (cdata[8] & 0x80)) {
987 struct timeval *ts;
988 ts = (struct timeval *)(frame->data + MAX_FRAME_SIZE);
989 do_gettimeofday(ts);
991 PDEBUG(4, "Frame End, curframe = %d, packnum=%d, hw=%d, vw=%d",
992 ov511->curframe, (int)(cdata[992]),
993 (int)(cdata[9]), (int)(cdata[10]));
995 if (frame->scanstate == STATE_LINES) {
996 int iFrameNext;
997 if (fix_rgb_offset)
998 fixFrameRGBoffset(frame);
999 frame->grabstate = FRAME_DONE;
1000 if (waitqueue_active(&frame->wq)) {
1001 frame->grabstate = FRAME_DONE;
1002 wake_up_interruptible(&frame->wq);
1004 /* If next frame is ready or grabbing, point to it */
1005 iFrameNext = (ov511->curframe + 1) % OV511_NUMFRAMES;
1006 if (ov511->frame[iFrameNext].grabstate== FRAME_READY ||
1007 ov511->frame[iFrameNext].grabstate== FRAME_GRABBING) {
1008 ov511->curframe = iFrameNext;
1009 ov511->frame[iFrameNext].scanstate = STATE_SCANNING;
1010 } else {
1012 PDEBUG(4, "Frame not ready? state = %d",
1013 ov511->frame[iFrameNext].grabstate);
1015 ov511->curframe = -1;
1020 /* Can we find a frame start */
1021 else if ((cdata[0] | cdata[1] | cdata[2] | cdata[3] |
1022 cdata[4] | cdata[5] | cdata[6] | cdata[7]) == 0 &&
1023 (cdata[8] & 8)) {
1025 PDEBUG(4, "ov511: Found Frame Start!, framenum = %d",
1026 ov511->curframe);
1028 /* Check to see if it's a snapshot frame */
1029 /* FIXME?? Should the snapshot reset go here? Performance? */
1030 if (cdata[8] & 0x02) {
1031 frame->snapshot = 1;
1032 PDEBUG(3, "ov511_move_data: snapshot detected");
1035 frame->scanstate = STATE_LINES;
1036 frame->segment = 0;
1039 /* Are we in a frame? */
1040 if (frame->scanstate == STATE_LINES) {
1041 unsigned char * pData;
1042 int iPix;
1044 /* Deal with leftover from last segment, if any */
1045 if (frame->segment) {
1046 pData = ov511->scratch;
1047 iPix = - ov511->scratchlen;
1048 memmove(pData + ov511->scratchlen, cdata,
1049 iPix+frame->segsize);
1050 } else {
1051 pData = &cdata[iPix = 9];
1054 /* Parse the segments */
1055 while(iPix <= 992 - frame->segsize &&
1056 frame->segment < frame->width * frame->height / 256) {
1057 int iSegY;
1058 int iSegUV;
1059 int iY, jY, iUV, jUV;
1060 int iOutY, iOutUV;
1061 unsigned char * pOut;
1063 iSegY = iSegUV = frame->segment;
1064 pOut = frame->data;
1066 frame->segment++;
1067 iPix += frame->segsize;
1069 if (frame->sub_flag) {
1070 int iSeg1;
1071 iSeg1 = iSegY / (ov511->subw / 32);
1072 iSeg1 *= frame->width / 32;
1073 iSegY = iSeg1 + (iSegY % (ov511->subw / 32));
1074 if (iSegY >= frame->width * ov511->subh / 256)
1075 break;
1077 iSeg1 = iSegUV / (ov511->subw / 16);
1078 iSeg1 *= frame->width / 16;
1079 iSegUV = iSeg1 + (iSegUV % (ov511->subw / 16));
1081 pOut += (ov511->subx +
1082 ov511->suby * frame->width) * frame->depth;
1085 iY = iSegY / (frame->width / WDIV);
1086 jY = iSegY - iY * (frame->width / WDIV);
1087 iOutY = (iY*HDIV*frame->width + jY*WDIV) * frame->depth;
1088 iUV = iSegUV / (frame->width / WDIV * 2);
1089 jUV = iSegUV - iUV * (frame->width / WDIV * 2);
1090 iOutUV = (iUV*HDIV*2*frame->width + jUV*WDIV/2) * frame->depth;
1092 if (frame->format == VIDEO_PALETTE_GREY) {
1093 ov511_parse_data_grey(pData, pOut, iOutY, frame->width);
1094 } else if (frame->format == VIDEO_PALETTE_RGB24) {
1095 ov511_parse_data_rgb24(pData, pOut, iOutY, iOutUV, iY & 1,
1096 frame->width);
1098 pData = &cdata[iPix];
1101 /* Save extra data for next time */
1102 if (frame->segment < frame->width * frame->height / 256) {
1103 ov511->scratchlen = 992 - iPix;
1104 if (ov511->scratchlen < frame->segsize) {
1105 memmove(ov511->scratch, pData, ov511->scratchlen);
1106 } else {
1107 ov511->scratchlen = 0;
1114 PDEBUG(5, "pn: %d %d %d %d %d %d %d %d %d %d\n",
1115 aPackNum[0], aPackNum[1], aPackNum[2], aPackNum[3], aPackNum[4],
1116 aPackNum[5],aPackNum[6], aPackNum[7], aPackNum[8], aPackNum[9]);
1118 return totlen;
1121 static void ov511_isoc_irq(struct urb *urb)
1123 int len;
1124 struct usb_ov511 *ov511 = urb->context;
1125 struct ov511_sbuf *sbuf;
1127 if (!ov511->dev)
1128 return;
1130 if (!ov511->streaming) {
1131 PDEBUG(2, "hmmm... not streaming, but got interrupt");
1132 return;
1135 sbuf = &ov511->sbuf[ov511->cursbuf];
1137 /* Copy the data received into our scratch buffer */
1138 if (ov511->curframe >= 0)
1139 len = ov511_move_data(ov511, urb);
1140 else if (waitqueue_active(&ov511->wq))
1141 wake_up_interruptible(&ov511->wq);
1143 /* Move to the next sbuf */
1144 ov511->cursbuf = (ov511->cursbuf + 1) % OV511_NUMSBUF;
1146 return;
1149 static int ov511_init_isoc(struct usb_ov511 *ov511)
1151 urb_t *urb;
1152 int fx, err;
1154 ov511->compress = 0;
1155 ov511->curframe = -1;
1156 ov511->cursbuf = 0;
1157 ov511->scratchlen = 0;
1159 ov511_set_packet_size(ov511, 993);
1161 /* We double buffer the Iso lists */
1162 urb = usb_alloc_urb(FRAMES_PER_DESC);
1164 if (!urb) {
1165 err("ov511_init_isoc: usb_alloc_urb ret. NULL");
1166 return -ENOMEM;
1168 ov511->sbuf[0].urb = urb;
1169 urb->dev = ov511->dev;
1170 urb->context = ov511;
1171 urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS);
1172 urb->transfer_flags = USB_ISO_ASAP;
1173 urb->transfer_buffer = ov511->sbuf[0].data;
1174 urb->complete = ov511_isoc_irq;
1175 urb->number_of_packets = FRAMES_PER_DESC;
1176 urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
1177 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
1178 urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
1179 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
1182 urb = usb_alloc_urb(FRAMES_PER_DESC);
1183 if (!urb) {
1184 err("ov511_init_isoc: usb_alloc_urb ret. NULL");
1185 return -ENOMEM;
1187 ov511->sbuf[1].urb = urb;
1188 urb->dev = ov511->dev;
1189 urb->context = ov511;
1190 urb->pipe = usb_rcvisocpipe(ov511->dev, OV511_ENDPOINT_ADDRESS);
1191 urb->transfer_flags = USB_ISO_ASAP;
1192 urb->transfer_buffer = ov511->sbuf[1].data;
1193 urb->complete = ov511_isoc_irq;
1194 urb->number_of_packets = FRAMES_PER_DESC;
1195 urb->transfer_buffer_length = FRAME_SIZE_PER_DESC * FRAMES_PER_DESC;
1196 for (fx = 0; fx < FRAMES_PER_DESC; fx++) {
1197 urb->iso_frame_desc[fx].offset = FRAME_SIZE_PER_DESC * fx;
1198 urb->iso_frame_desc[fx].length = FRAME_SIZE_PER_DESC;
1201 ov511->sbuf[1].urb->next = ov511->sbuf[0].urb;
1202 ov511->sbuf[0].urb->next = ov511->sbuf[1].urb;
1204 err = usb_submit_urb(ov511->sbuf[0].urb);
1205 if (err)
1206 err("ov511_init_isoc: usb_submit_urb(0) ret %d", err);
1207 err = usb_submit_urb(ov511->sbuf[1].urb);
1208 if (err)
1209 err("ov511_init_isoc: usb_submit_urb(1) ret %d", err);
1211 ov511->streaming = 1;
1213 return 0;
1217 static void ov511_stop_isoc(struct usb_ov511 *ov511)
1219 if (!ov511->streaming || !ov511->dev)
1220 return;
1222 ov511_set_packet_size(ov511, 0);
1224 ov511->streaming = 0;
1226 /* Unschedule all of the iso td's */
1227 if (ov511->sbuf[1].urb) {
1228 ov511->sbuf[1].urb->next = NULL;
1229 usb_unlink_urb(ov511->sbuf[1].urb);
1230 usb_free_urb(ov511->sbuf[1].urb);
1231 ov511->sbuf[1].urb = NULL;
1233 if (ov511->sbuf[0].urb) {
1234 ov511->sbuf[0].urb->next = NULL;
1235 usb_unlink_urb(ov511->sbuf[0].urb);
1236 usb_free_urb(ov511->sbuf[0].urb);
1237 ov511->sbuf[0].urb = NULL;
1241 static int ov511_new_frame(struct usb_ov511 *ov511, int framenum)
1243 #if 1
1244 struct ov511_frame *frame;
1245 int width, height;
1247 if (!ov511->dev)
1248 return -1;
1250 /* If we're not grabbing a frame right now and the other frame is */
1251 /* ready to be grabbed into, then use it instead */
1252 if (ov511->curframe == -1) {
1253 if (ov511->frame[(framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES].grabstate == FRAME_READY)
1254 framenum = (framenum - 1 + OV511_NUMFRAMES) % OV511_NUMFRAMES;
1255 } else
1256 return 0;
1258 frame = &ov511->frame[framenum];
1259 width = frame->width;
1260 height = frame->height;
1262 frame->grabstate = FRAME_GRABBING;
1263 frame->scanstate = STATE_SCANNING;
1264 frame->scanlength = 0; /* accumulated in ov511_parse_data() */
1265 frame->snapshot = 0;
1267 ov511->curframe = framenum;
1269 /* Make sure it's not too big */
1270 if (width > DEFAULT_WIDTH)
1271 width = DEFAULT_WIDTH;
1272 width = (width / 8) * 8; /* Multiple of 8 */
1274 if (height > DEFAULT_HEIGHT)
1275 height = DEFAULT_HEIGHT;
1276 height = (height / 4) * 4; /* Multiple of 4 */
1278 // /* We want a fresh frame every 30 we get */
1279 // ov511->compress = (ov511->compress + 1) % 30;
1281 #endif
1282 return 0;
1286 /* Video 4 Linux API */
1287 static int ov511_open(struct video_device *dev, int flags)
1289 int err = -EBUSY;
1290 struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
1292 PDEBUG(4, "ov511_open");
1294 down(&ov511->lock);
1295 if (ov511->user)
1296 goto out_unlock;
1298 ov511->frame[0].grabstate = FRAME_UNUSED;
1299 ov511->frame[1].grabstate = FRAME_UNUSED;
1301 err = -ENOMEM;
1303 /* Allocate memory for the frame buffers */
1304 ov511->fbuf = rvmalloc(2 * MAX_DATA_SIZE);
1305 if (!ov511->fbuf)
1306 goto open_err_ret;
1308 ov511->frame[0].data = ov511->fbuf;
1309 ov511->frame[1].data = ov511->fbuf + MAX_DATA_SIZE;
1310 ov511->sub_flag = 0;
1312 PDEBUG(4, "frame [0] @ %p", ov511->frame[0].data);
1313 PDEBUG(4, "frame [1] @ %p", ov511->frame[1].data);
1315 ov511->sbuf[0].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
1316 if (!ov511->sbuf[0].data)
1317 goto open_err_on0;
1318 ov511->sbuf[1].data = kmalloc(FRAMES_PER_DESC * FRAME_SIZE_PER_DESC, GFP_KERNEL);
1319 if (!ov511->sbuf[1].data)
1320 goto open_err_on1;
1322 PDEBUG(4, "sbuf[0] @ %p", ov511->sbuf[0].data);
1323 PDEBUG(4, "sbuf[1] @ %p", ov511->sbuf[1].data);
1325 err = ov511_init_isoc(ov511);
1326 if (err)
1327 goto open_err_on2;
1329 ov511->user++;
1330 up(&ov511->lock);
1332 MOD_INC_USE_COUNT;
1334 return 0;
1336 open_err_on2:
1337 kfree (ov511->sbuf[1].data);
1338 open_err_on1:
1339 kfree (ov511->sbuf[0].data);
1340 open_err_on0:
1341 rvfree(ov511->fbuf, 2 * MAX_DATA_SIZE);
1342 open_err_ret:
1343 return err;
1344 out_unlock:
1345 up(&ov511->lock);
1346 return err;
1350 static void ov511_close(struct video_device *dev)
1352 struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
1354 PDEBUG(4, "ov511_close");
1356 down(&ov511->lock);
1357 ov511->user--;
1359 MOD_DEC_USE_COUNT;
1361 ov511_stop_isoc(ov511);
1363 rvfree(ov511->fbuf, 2 * MAX_DATA_SIZE);
1365 kfree(ov511->sbuf[1].data);
1366 kfree(ov511->sbuf[0].data);
1368 up(&ov511->lock);
1370 if (!ov511->dev) {
1371 video_unregister_device(&ov511->vdev);
1372 kfree(ov511);
1376 static int ov511_init_done(struct video_device *dev)
1378 return 0;
1381 static long ov511_write(struct video_device *dev, const char *buf, unsigned long count, int noblock)
1383 return -EINVAL;
1386 static int ov511_ioctl(struct video_device *vdev, unsigned int cmd, void *arg)
1388 struct usb_ov511 *ov511 = (struct usb_ov511 *)vdev;
1390 PDEBUG(4, "IOCtl: 0x%X", cmd);
1392 if (!ov511->dev)
1393 return -EIO;
1395 switch (cmd) {
1396 case VIDIOCGCAP:
1398 struct video_capability b;
1400 strcpy(b.name, "OV511 USB Camera");
1401 b.type = VID_TYPE_CAPTURE | VID_TYPE_SUBCAPTURE;
1402 b.channels = 1;
1403 b.audios = 0;
1404 b.maxwidth = DEFAULT_WIDTH;
1405 b.maxheight = DEFAULT_HEIGHT;
1406 b.minwidth = 32;
1407 b.minheight = 16;
1409 if (copy_to_user(arg, &b, sizeof(b)))
1410 return -EFAULT;
1412 return 0;
1414 case VIDIOCGCHAN:
1416 struct video_channel v;
1418 if (copy_from_user(&v, arg, sizeof(v)))
1419 return -EFAULT;
1420 if (v.channel != 0)
1421 return -EINVAL;
1423 v.flags = 0;
1424 v.tuners = 0;
1425 v.type = VIDEO_TYPE_CAMERA;
1426 strcpy(v.name, "Camera");
1428 if (copy_to_user(arg, &v, sizeof(v)))
1429 return -EFAULT;
1431 return 0;
1433 case VIDIOCSCHAN:
1435 int v;
1437 if (copy_from_user(&v, arg, sizeof(v)))
1438 return -EFAULT;
1440 if (v != 0)
1441 return -EINVAL;
1443 return 0;
1446 case VIDIOCGPICT:
1448 struct video_picture p;
1450 if (ov7610_get_picture(ov511, &p))
1451 return -EIO;
1453 if (copy_to_user(arg, &p, sizeof(p)))
1454 return -EFAULT;
1456 return 0;
1458 case VIDIOCSPICT:
1460 struct video_picture p;
1462 if (copy_from_user(&p, arg, sizeof(p)))
1463 return -EFAULT;
1465 if (ov7610_set_picture(ov511, &p))
1466 return -EIO;
1468 return 0;
1470 case VIDIOCGCAPTURE:
1472 int vf;
1473 if (copy_from_user(&vf, arg, sizeof(vf)))
1474 return -EFAULT;
1475 ov511->sub_flag = vf;
1476 return 0;
1478 case VIDIOCSCAPTURE:
1480 struct video_capture vc;
1482 if (copy_from_user(&vc, arg, sizeof(vc)))
1483 return -EFAULT;
1484 if (vc.flags)
1485 return -EINVAL;
1486 if (vc.decimation)
1487 return -EINVAL;
1488 vc.x /= 4;
1489 vc.x *= 4;
1490 vc.y /= 2;
1491 vc.y *= 2;
1492 vc.width /= 32;
1493 vc.width *= 32;
1494 if (vc.width == 0) vc.width = 32;
1495 vc.height /= 16;
1496 vc.height *= 16;
1497 if (vc.height == 0) vc.height = 16;
1499 ov511->subx = vc.x;
1500 ov511->suby = vc.y;
1501 ov511->subw = vc.width;
1502 ov511->subh = vc.height;
1504 return 0;
1506 case VIDIOCSWIN:
1508 struct video_window vw;
1510 if (copy_from_user(&vw, arg, sizeof(vw)))
1511 return -EFAULT;
1512 if (vw.flags)
1513 return -EINVAL;
1514 if (vw.clipcount)
1515 return -EINVAL;
1516 if (vw.height != DEFAULT_HEIGHT)
1517 return -EINVAL;
1518 if (vw.width != DEFAULT_WIDTH)
1519 return -EINVAL;
1521 ov511->compress = 0;
1523 return 0;
1525 case VIDIOCGWIN:
1527 struct video_window vw;
1529 vw.x = 0;
1530 vw.y = 0;
1531 vw.width = DEFAULT_WIDTH;
1532 vw.height = DEFAULT_HEIGHT;
1533 vw.chromakey = 0;
1534 vw.flags = 30;
1536 if (copy_to_user(arg, &vw, sizeof(vw)))
1537 return -EFAULT;
1539 return 0;
1541 case VIDIOCGMBUF:
1543 struct video_mbuf vm;
1545 memset(&vm, 0, sizeof(vm));
1546 vm.size = 2 * MAX_DATA_SIZE;
1547 vm.frames = 2;
1548 vm.offsets[0] = 0;
1549 vm.offsets[1] = MAX_FRAME_SIZE + sizeof (struct timeval);
1551 if (copy_to_user((void *)arg, (void *)&vm, sizeof(vm)))
1552 return -EFAULT;
1554 return 0;
1556 case VIDIOCMCAPTURE:
1558 struct video_mmap vm;
1560 if (copy_from_user((void *)&vm, (void *)arg, sizeof(vm)))
1561 return -EFAULT;
1563 PDEBUG(4, "MCAPTURE");
1564 PDEBUG(4, "frame: %d, size: %dx%d, format: %d",
1565 vm.frame, vm.width, vm.height, vm.format);
1567 if (vm.format != VIDEO_PALETTE_RGB24 &&
1568 vm.format != VIDEO_PALETTE_GREY)
1569 return -EINVAL;
1571 if ((vm.frame != 0) && (vm.frame != 1))
1572 return -EINVAL;
1574 if (ov511->frame[vm.frame].grabstate == FRAME_GRABBING)
1575 return -EBUSY;
1577 /* Don't compress if the size changed */
1578 if ((ov511->frame[vm.frame].width != vm.width) ||
1579 (ov511->frame[vm.frame].height != vm.height) ||
1580 (ov511->frame[vm.frame].format != vm.format) ||
1581 (ov511->frame[vm.frame].sub_flag !=
1582 ov511->sub_flag)) {
1583 /* If we're collecting previous frame wait
1584 before changing modes */
1585 interruptible_sleep_on(&ov511->wq);
1586 if (signal_pending(current)) return -EINTR;
1587 ov511_mode_init_regs(ov511,
1588 vm.width, vm.height,
1589 vm.format, ov511->sub_flag);
1592 ov511->frame[vm.frame].width = vm.width;
1593 ov511->frame[vm.frame].height = vm.height;
1594 ov511->frame[vm.frame].format = vm.format;
1595 ov511->frame[vm.frame].sub_flag = ov511->sub_flag;
1596 ov511->frame[vm.frame].segsize =
1597 vm.format == VIDEO_PALETTE_RGB24 ? 384 : 256;
1598 ov511->frame[vm.frame].depth =
1599 vm.format == VIDEO_PALETTE_RGB24 ? 3 : 1;
1601 /* Mark it as ready */
1602 ov511->frame[vm.frame].grabstate = FRAME_READY;
1604 return ov511_new_frame(ov511, vm.frame);
1606 case VIDIOCSYNC:
1608 int frame;
1610 if (copy_from_user((void *)&frame, arg, sizeof(int)))
1611 return -EFAULT;
1613 PDEBUG(4, "syncing to frame %d, grabstate = %d", frame,
1614 ov511->frame[frame].grabstate);
1616 switch (ov511->frame[frame].grabstate) {
1617 case FRAME_UNUSED:
1618 return -EINVAL;
1619 case FRAME_READY:
1620 case FRAME_GRABBING:
1621 case FRAME_ERROR:
1622 redo:
1623 if (!ov511->dev)
1624 return -EIO;
1626 do {
1627 #if 0
1628 init_waitqueue_head(&ov511->frame[frame].wq);
1629 #endif
1630 interruptible_sleep_on(&ov511->frame[frame].wq);
1631 if (signal_pending(current))
1632 return -EINTR;
1633 } while (ov511->frame[frame].grabstate == FRAME_GRABBING);
1635 if (ov511->frame[frame].grabstate == FRAME_ERROR) {
1636 int ret;
1638 if ((ret = ov511_new_frame(ov511, frame)) < 0)
1639 return ret;
1640 goto redo;
1642 case FRAME_DONE:
1643 ov511->frame[frame].grabstate = FRAME_UNUSED;
1644 break;
1647 ov511->frame[frame].grabstate = FRAME_UNUSED;
1649 /* Reset the hardware snapshot button */
1650 /* FIXME - Is this the best place for this? */
1651 if ((ov511->snap_enabled) &&
1652 (ov511->frame[frame].snapshot)) {
1653 ov511->frame[frame].snapshot = 0;
1654 ov511_reg_write(ov511->dev, 0x52, 0x01);
1655 ov511_reg_write(ov511->dev, 0x52, 0x03);
1656 ov511_reg_write(ov511->dev, 0x52, 0x01);
1659 return 0;
1661 case VIDIOCGFBUF:
1663 struct video_buffer vb;
1665 memset(&vb, 0, sizeof(vb));
1666 vb.base = NULL; /* frame buffer not supported, not used */
1668 if (copy_to_user((void *)arg, (void *)&vb, sizeof(vb)))
1669 return -EFAULT;
1671 return 0;
1673 case VIDIOCKEY:
1674 return 0;
1675 case VIDIOCCAPTURE:
1676 return -EINVAL;
1677 case VIDIOCSFBUF:
1678 return -EINVAL;
1679 case VIDIOCGTUNER:
1680 case VIDIOCSTUNER:
1681 return -EINVAL;
1682 case VIDIOCGFREQ:
1683 case VIDIOCSFREQ:
1684 return -EINVAL;
1685 case VIDIOCGAUDIO:
1686 case VIDIOCSAUDIO:
1687 return -EINVAL;
1688 default:
1689 return -ENOIOCTLCMD;
1691 return 0;
1694 static long ov511_read(struct video_device *dev, char *buf, unsigned long count, int noblock)
1696 struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
1697 int frmx = -1;
1698 volatile struct ov511_frame *frame;
1700 PDEBUG(4, "ov511_read: %ld bytes, noblock=%d", count, noblock);
1702 if (!dev || !buf)
1703 return -EFAULT;
1705 if (!ov511->dev)
1706 return -EIO;
1708 /* See if a frame is completed, then use it. */
1709 if (ov511->frame[0].grabstate >= FRAME_DONE) /* _DONE or _ERROR */
1710 frmx = 0;
1711 else if (ov511->frame[1].grabstate >= FRAME_DONE)/* _DONE or _ERROR */
1712 frmx = 1;
1714 if (noblock && (frmx == -1))
1715 return -EAGAIN;
1717 /* If no FRAME_DONE, look for a FRAME_GRABBING state. */
1718 /* See if a frame is in process (grabbing), then use it. */
1719 if (frmx == -1) {
1720 if (ov511->frame[0].grabstate == FRAME_GRABBING)
1721 frmx = 0;
1722 else if (ov511->frame[1].grabstate == FRAME_GRABBING)
1723 frmx = 1;
1726 /* If no frame is active, start one. */
1727 if (frmx == -1)
1728 ov511_new_frame(ov511, frmx = 0);
1730 frame = &ov511->frame[frmx];
1732 restart:
1733 if (!ov511->dev)
1734 return -EIO;
1736 while (frame->grabstate == FRAME_GRABBING) {
1737 interruptible_sleep_on(&ov511->frame[frmx].wq);
1738 if (signal_pending(current))
1739 return -EINTR;
1742 if (frame->grabstate == FRAME_ERROR) {
1743 frame->bytes_read = 0;
1744 err("ov511_read: errored frame %d", ov511->curframe);
1745 if (ov511_new_frame(ov511, frmx))
1746 err("ov511_read: ov511_new_frame error");
1747 goto restart;
1751 /* Repeat until we get a snapshot frame */
1752 if (ov511->snap_enabled && !frame->snapshot) {
1753 frame->bytes_read = 0;
1754 if (ov511_new_frame(ov511, frmx))
1755 err("ov511_read: ov511_new_frame error");
1756 goto restart;
1759 /* Clear the snapshot */
1760 if (ov511->snap_enabled && frame->snapshot) {
1761 frame->snapshot = 0;
1762 ov511_reg_write(ov511->dev, 0x52, 0x01);
1763 ov511_reg_write(ov511->dev, 0x52, 0x03);
1764 ov511_reg_write(ov511->dev, 0x52, 0x01);
1767 PDEBUG(4, "ov511_read: frmx=%d, bytes_read=%ld, scanlength=%ld", frmx,
1768 frame->bytes_read, frame->scanlength);
1770 /* copy bytes to user space; we allow for partials reads */
1771 // if ((count + frame->bytes_read) > frame->scanlength)
1772 // count = frame->scanlength - frame->bytes_read;
1773 /* FIXME - count hardwired to be one frame... */
1774 count = frame->width * frame->height * frame->depth;
1776 if (copy_to_user(buf, frame->data + frame->bytes_read, count))
1777 return -EFAULT;
1779 frame->bytes_read += count;
1780 PDEBUG(4, "ov511_read: {copy} count used=%ld, new bytes_read=%ld",
1781 count, frame->bytes_read);
1783 if (frame->bytes_read >= frame->scanlength) { /* All data has been read */
1784 frame->bytes_read = 0;
1786 /* Mark it as available to be used again. */
1787 ov511->frame[frmx].grabstate = FRAME_UNUSED;
1788 if (ov511_new_frame(ov511, frmx ? 0 : 1))
1789 err("ov511_read: ov511_new_frame returned error");
1792 return count;
1795 static int ov511_mmap(struct video_device *dev, const char *adr, unsigned long size)
1797 struct usb_ov511 *ov511 = (struct usb_ov511 *)dev;
1798 unsigned long start = (unsigned long)adr;
1799 unsigned long page, pos;
1801 if (!ov511->dev)
1802 return -EIO;
1804 PDEBUG(4, "mmap: %ld (%lX) bytes", size, size);
1806 if (size > (((2 * MAX_DATA_SIZE) + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1)))
1807 return -EINVAL;
1809 pos = (unsigned long)ov511->fbuf;
1810 while (size > 0)
1812 page = kvirt_to_pa(pos);
1813 if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED))
1814 return -EAGAIN;
1815 start += PAGE_SIZE;
1816 pos += PAGE_SIZE;
1817 if (size > PAGE_SIZE)
1818 size -= PAGE_SIZE;
1819 else
1820 size = 0;
1823 return 0;
1826 static struct video_device ov511_template = {
1827 name: "OV511 USB Camera",
1828 type: VID_TYPE_CAPTURE,
1829 hardware: VID_HARDWARE_OV511,
1830 open: ov511_open,
1831 close: ov511_close,
1832 read: ov511_read,
1833 write: ov511_write,
1834 ioctl: ov511_ioctl,
1835 mmap: ov511_mmap,
1836 initialize: ov511_init_done,
1839 static int ov7610_configure(struct usb_device *dev)
1841 int tries;
1843 if(ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_WRITE,
1844 OV7610_I2C_WRITE_ID) < 0)
1845 return -1;
1847 if(ov511_reg_write(dev, OV511_REG_I2C_SLAVE_ID_READ,
1848 OV7610_I2C_READ_ID) < 0)
1849 return -1;
1851 if (ov511_reset(dev, OV511_RESET_NOREGS) < 0)
1852 return -1;
1854 /* Reset the 7610 and wait a bit for it to initialize */
1855 if (ov511_i2c_write(dev, 0x12, 0x80) < 0) return -1;
1856 schedule_timeout (1 + 150 * HZ / 1000);
1858 /* Dummy read to sync I2C */
1859 if(ov511_i2c_read(dev, 0x00) < 0)
1860 return -1;
1862 tries = 5;
1863 while((tries > 0) &&
1864 ((ov511_i2c_read(dev, OV7610_REG_ID_HIGH) != 0x7F) ||
1865 (ov511_i2c_read(dev, OV7610_REG_ID_LOW) != 0xA2))) {
1866 --tries;
1869 if (tries == 0) {
1870 err("Failed to read OV7610 ID. You might not have an OV7610,");
1871 err("or it may be not responding. Report this to");
1872 err("mmcclelland@delphi.com");
1873 return -1;
1876 return 0;
1879 static int ov511_configure(struct usb_ov511 *ov511)
1881 struct usb_device *dev = ov511->dev;
1882 int rc;
1884 static struct ov511_regvals aRegvalsInit[] =
1885 {{OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f},
1886 {OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01},
1887 {OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x7f},
1888 {OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01},
1889 {OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3f},
1890 {OV511_REG_BUS, OV511_REG_SYSTEM_INIT, 0x01},
1891 {OV511_REG_BUS, OV511_REG_SYSTEM_RESET, 0x3d},
1892 {OV511_DONE_BUS, 0x0, 0x00},
1894 static struct ov511_regvals aRegvalsNorm[] =
1895 {{OV511_REG_BUS, 0x20, 1},
1896 #if 1
1897 {OV511_REG_BUS, 0x52, 0x02},
1898 {OV511_REG_BUS, 0x52, 0x00},
1899 {OV511_REG_BUS, 0x31, 0x1f}, /* 0f */
1900 {OV511_REG_BUS, 0x70, 0x3f},
1901 {OV511_REG_BUS, 0x71, 0x3f},
1902 {OV511_REG_BUS, 0x72, 0x01},
1903 {OV511_REG_BUS, 0x73, 0x01},
1904 {OV511_REG_BUS, 0x74, 0x01},
1905 {OV511_REG_BUS, 0x75, 0x01},
1906 {OV511_REG_BUS, 0x76, 0x01},
1907 {OV511_REG_BUS, 0x77, 0x01},
1908 {OV511_REG_BUS, 0x78, 0x06},
1909 {OV511_REG_BUS, 0x79, 0x03},
1912 {OV511_I2C_BUS, 0x10, 0xff},
1913 {OV511_I2C_BUS, 0x16, 0x06},
1914 {OV511_I2C_BUS, 0x28, 0x24}, /* 24 */
1915 {OV511_I2C_BUS, 0x2b, 0xac},
1916 {OV511_I2C_BUS, 0x05, 0x00},
1917 {OV511_I2C_BUS, 0x06, 0x00},
1919 {OV511_I2C_BUS, 0x12, 0x00},
1920 // {OV511_I2C_BUS, 0x13, 0x00},
1921 {OV511_I2C_BUS, 0x38, 0x81},
1922 {OV511_I2C_BUS, 0x28, 0x24}, /* 0c */
1923 {OV511_I2C_BUS, 0x05, 0x00},
1924 {OV511_I2C_BUS, 0x0f, 0x05},
1925 {OV511_I2C_BUS, 0x15, 0x01},
1926 {OV511_I2C_BUS, 0x20, 0x1c},
1927 {OV511_I2C_BUS, 0x23, 0x2a},
1928 {OV511_I2C_BUS, 0x24, 0x10},
1929 {OV511_I2C_BUS, 0x25, 0x8a},
1930 {OV511_I2C_BUS, 0x26, 0x90},
1931 {OV511_I2C_BUS, 0x27, 0xc2},
1932 {OV511_I2C_BUS, 0x29, 0x03}, /* 91 */
1933 {OV511_I2C_BUS, 0x2a, 0x04},
1934 {OV511_I2C_BUS, 0x2c, 0xfe},
1935 {OV511_I2C_BUS, 0x2d, 0x93}, /* d7 */
1936 {OV511_I2C_BUS, 0x30, 0x71},
1937 {OV511_I2C_BUS, 0x31, 0x60},
1938 {OV511_I2C_BUS, 0x32, 0x26},
1939 {OV511_I2C_BUS, 0x33, 0x20},
1940 {OV511_I2C_BUS, 0x34, 0x48},
1941 {OV511_I2C_BUS, 0x12, 0x24},
1942 // {OV511_I2C_BUS, 0x13, 0x01},
1943 {OV511_I2C_BUS, 0x11, 0x01},
1944 {OV511_I2C_BUS, 0x0c, 0x24},
1945 {OV511_I2C_BUS, 0x0d, 0x24},
1946 #endif
1947 {OV511_DONE_BUS, 0x0, 0x00},
1950 /* Set altsetting 0 */
1951 if (usb_set_interface(dev, ov511->iface, 0) < 0) {
1952 err("usb_set_interface error");
1953 return -EBUSY;
1956 memcpy(&ov511->vdev, &ov511_template, sizeof(ov511_template));
1958 init_waitqueue_head(&ov511->frame[0].wq);
1959 init_waitqueue_head(&ov511->frame[1].wq);
1960 init_waitqueue_head(&ov511->wq);
1962 if (video_register_device(&ov511->vdev, VFL_TYPE_GRABBER) == -1) {
1963 err("video_register_device failed");
1964 return -EBUSY;
1967 if ((rc = ov511_write_regvals(dev, aRegvalsInit)))
1968 return rc;
1970 if(ov7610_configure(dev) < 0) {
1971 err("failed to configure OV7610");
1972 goto error;
1975 /* Disable compression */
1976 if (ov511_reg_write(dev, OV511_OMNICE_ENABLE, 0x00) < 0) {
1977 err("disable compression: command failed");
1978 goto error;
1981 ov511->compress = 0;
1982 ov511->snap_enabled = snapshot;
1984 /* Set default sizes in case IOCTL (VIDIOCMCAPTURE) is not used
1985 * (using read() instead). */
1986 ov511->frame[0].width = DEFAULT_WIDTH;
1987 ov511->frame[0].height = DEFAULT_HEIGHT;
1988 ov511->frame[0].bytes_read = 0;
1989 ov511->frame[1].width = DEFAULT_WIDTH;
1990 ov511->frame[1].height = DEFAULT_HEIGHT;
1991 ov511->frame[1].bytes_read = 0;
1993 /* Initialize to DEFAULT_WIDTH, DEFAULT_HEIGHT, YUV4:2:0 */
1994 if ((rc = ov511_write_regvals(dev, aRegvalsNorm))) goto error;
1995 if ((rc = ov511_mode_init_regs(ov511, DEFAULT_WIDTH, DEFAULT_HEIGHT,
1996 VIDEO_PALETTE_RGB24, 0)) < 0) goto error;
1998 if (autoadjust) {
1999 if (ov511_i2c_write(dev, 0x13, 0x01) < 0) goto error;
2001 else {
2002 if (ov511_i2c_write(dev, 0x13, 0x00) < 0 ) goto error;
2005 return 0;
2007 error:
2008 video_unregister_device(&ov511->vdev);
2009 usb_driver_release_interface(&ov511_driver,
2010 &dev->actconfig->interface[ov511->iface]);
2012 kfree(ov511);
2014 return -EBUSY;
2017 static void* ov511_probe(struct usb_device *dev, unsigned int ifnum)
2019 struct usb_interface_descriptor *interface;
2020 struct usb_ov511 *ov511;
2021 int rc;
2023 PDEBUG(1, "probing for device...");
2025 /* We don't handle multi-config cameras */
2026 if (dev->descriptor.bNumConfigurations != 1)
2027 return NULL;
2029 interface = &dev->actconfig->interface[ifnum].altsetting[0];
2031 /* Is it an OV511? */
2032 if (dev->descriptor.idVendor != 0x05a9)
2033 return NULL;
2034 if (dev->descriptor.idProduct != 0x0511)
2035 return NULL;
2037 /* Checking vendor/product should be enough, but what the hell */
2038 if (interface->bInterfaceClass != 0xFF)
2039 return NULL;
2040 if (interface->bInterfaceSubClass != 0x00)
2041 return NULL;
2043 /* We found one */
2044 printk(KERN_INFO "ov511: USB OV511-based camera found\n");
2046 if ((ov511 = kmalloc(sizeof(*ov511), GFP_KERNEL)) == NULL) {
2047 err("couldn't kmalloc ov511 struct");
2048 return NULL;
2051 memset(ov511, 0, sizeof(*ov511));
2053 ov511->dev = dev;
2054 ov511->iface = interface->bInterfaceNumber;
2056 rc = ov511_reg_read(dev, OV511_REG_SYSTEM_CUSTOM_ID);
2057 if (rc < 0) {
2058 err("Unable to read camera bridge registers");
2059 return NULL;
2062 switch(ov511->customid = rc) {
2063 case 0: /* This also means that no custom ID was set */
2064 printk("ov511: Camera is probably a MediaForte MV300\n");
2065 break;
2066 case 3:
2067 printk("ov511: Camera is a D-Link DSB-C300\n");
2068 break;
2069 case 4:
2070 printk("ov511: Camera is a generic OV511/OV7610\n");
2071 break;
2072 case 5:
2073 printk("ov511: Camera is a Puretek PT-6007\n");
2074 break;
2075 case 21:
2076 printk("ov511: Camera is a Creative Labs WebCam 3\n");
2077 break;
2078 case 36:
2079 printk("ov511: Camera is a Koala-Cam\n");
2080 break;
2081 case 100:
2082 printk("ov511: Camera is a Lifeview RoboCam\n");
2083 break;
2084 case 102:
2085 printk("ov511: Camera is a AverMedia InterCam Elite\n");
2086 break;
2087 case 112: /* The OmniVision OV7110 evaluation kit uses this too */
2088 printk("ov511: Camera is a MediaForte MV300\n");
2089 break;
2090 default:
2091 err("Specific camera type (%d) not recognized", rc);
2092 err("Please contact mmcclelland@delphi.com to request");
2093 err("support for your camera.");
2094 return NULL;
2097 if (!ov511_configure(ov511)) {
2098 ov511->user=0;
2099 init_MUTEX(&ov511->lock); /* to 1 == available */
2100 return ov511;
2102 else {
2103 err("Failed to configure camera");
2104 return NULL;
2107 return ov511;
2110 static void ov511_disconnect(struct usb_device *dev, void *ptr)
2113 struct usb_ov511 *ov511 = (struct usb_ov511 *) ptr;
2115 // video_unregister_device(&ov511->vdev);
2117 /* We don't want people trying to open up the device */
2118 if (!ov511->user)
2119 video_unregister_device(&ov511->vdev);
2121 usb_driver_release_interface(&ov511_driver,
2122 &ov511->dev->actconfig->interface[ov511->iface]);
2124 ov511->dev = NULL;
2125 ov511->frame[0].grabstate = FRAME_ERROR;
2126 ov511->frame[1].grabstate = FRAME_ERROR;
2127 ov511->curframe = -1;
2129 /* This will cause the process to request another frame */
2130 if (waitqueue_active(&ov511->frame[0].wq))
2131 wake_up_interruptible(&ov511->frame[0].wq);
2132 if (waitqueue_active(&ov511->frame[1].wq))
2133 wake_up_interruptible(&ov511->frame[1].wq);
2134 if (waitqueue_active(&ov511->wq))
2135 wake_up_interruptible(&ov511->wq);
2137 ov511->streaming = 0;
2139 /* Unschedule all of the iso td's */
2140 if (ov511->sbuf[1].urb) {
2141 ov511->sbuf[1].urb->next = NULL;
2142 usb_unlink_urb(ov511->sbuf[1].urb);
2143 usb_free_urb(ov511->sbuf[1].urb);
2144 ov511->sbuf[1].urb = NULL;
2146 if (ov511->sbuf[0].urb) {
2147 ov511->sbuf[0].urb->next = NULL;
2148 usb_unlink_urb(ov511->sbuf[0].urb);
2149 usb_free_urb(ov511->sbuf[0].urb);
2150 ov511->sbuf[0].urb = NULL;
2153 /* Free the memory */
2154 if (!ov511->user) {
2155 kfree(ov511);
2156 ov511 = NULL;
2160 static struct usb_driver ov511_driver = {
2161 "ov511",
2162 ov511_probe,
2163 ov511_disconnect,
2164 { NULL, NULL }
2167 static int __init usb_ov511_init(void)
2169 if (usb_register(&ov511_driver) < 0)
2170 return -1;
2172 info("ov511 driver registered");
2174 return 0;
2177 static void __exit usb_ov511_exit(void)
2179 usb_deregister(&ov511_driver);
2180 info("ov511 driver deregistered");
2183 module_init(usb_ov511_init);
2184 module_exit(usb_ov511_exit);