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
8 * Based on the Linux CPiA driver.
10 * Released under GPL v.2 license.
14 * Please see the file: linux/Documentation/usb/ov511.txt
15 * and the website at: http://alpha.dyndns.org/ov511
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
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>
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>
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
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;
114 if (!pgd_none(*pgd
)) {
115 pmd
= pmd_offset(pgd
, adr
);
116 if (!pmd_none(*pmd
)) {
117 ptep
= pte_offset(pmd
, adr
);
119 if (pte_present(pte
))
120 ret
= page_address(pte_page(pte
)) | (adr
& (PAGE_SIZE
-1));
123 MDEBUG(printk("uv2kva(%lx-->%lx)", adr
, 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
));
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
));
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
);
159 MDEBUG(printk("kv2pa(%lx-->%lx)", adr
, ret
));
163 static void *rvmalloc(unsigned long size
)
166 unsigned long adr
, page
;
168 /* Round it off to PAGE_SIZE */
169 size
+= (PAGE_SIZE
- 1);
170 size
&= ~(PAGE_SIZE
- 1);
176 memset(mem
, 0, size
); /* Clear the ram out, no junk to the user */
177 adr
= (unsigned long) mem
;
179 page
= kvirt_to_pa(adr
);
180 mem_map_reserve(MAP_NR(__va(page
)));
182 if (size
> PAGE_SIZE
)
191 static void rvfree(void *mem
, unsigned long size
)
193 unsigned long adr
, page
;
198 size
+= (PAGE_SIZE
- 1);
199 size
&= ~(PAGE_SIZE
- 1);
201 adr
=(unsigned long) mem
;
203 page
= kvirt_to_pa(adr
);
204 mem_map_unreserve(MAP_NR(__va(page
)));
206 if (size
> PAGE_SIZE
)
214 int ov511_reg_write(struct usb_device
*dev
, unsigned char reg
, unsigned char value
)
218 rc
= usb_control_msg(dev
,
219 usb_sndctrlpipe(dev
, 0),
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
);
229 /* returns: negative is error, pos or zero is data */
230 int ov511_reg_read(struct usb_device
*dev
, unsigned char reg
)
233 unsigned char buffer
[1];
235 rc
= usb_control_msg(dev
,
236 usb_rcvctrlpipe(dev
, 0),
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]);
249 int ov511_i2c_write(struct usb_device
*dev
, unsigned char reg
, unsigned char value
)
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? */
277 ov511_reg_write(dev
, OV511_REG_I2C_CONTROL
, 0x10);
279 if (--retries
< 0) return -1;
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? */
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? */
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
;
345 // This version doesn't always work
347 /* returns: negative is error, pos or zero is data */
348 int ov511_i2c_read(struct usb_device
*dev
, unsigned char reg
)
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
);
374 static int ov511_write_regvals(struct usb_device
*dev
,
375 struct ov511_regvals
* pRegvals
)
378 while(pRegvals
->bus
!= OV511_DONE_BUS
) {
379 if (pRegvals
->bus
== OV511_REG_BUS
) {
380 if ((ret
= ov511_reg_write(dev
, pRegvals
->reg
,
383 } else if (pRegvals
->bus
== OV511_I2C_BUS
) {
384 if ((ret
= ov511_i2c_write(dev
, pRegvals
->reg
,
388 err("Bad regval array");
396 static void ov511_dump_i2c_range( struct usb_device
*dev
, int reg1
, int regn
)
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
)
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);
447 int ov511_reset(struct usb_device
*dev
, unsigned char reset_type
)
451 PDEBUG(3, "Reset: type=0x%X", reset_type
);
452 rc
= ov511_reg_write(dev
, OV511_REG_SYSTEM_RESET
, reset_type
);
454 err("reset: command failed");
456 rc
= ov511_reg_write(dev
, OV511_REG_SYSTEM_RESET
, 0);
458 err("reset: command failed");
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
);
500 multiplier
= 1; // FIXME - is this correct?
503 err("Set packet size: invalid size (%d)", size
);
507 rc
= ov511_reg_write(ov511
->dev
, OV511_REG_FIFO_PACKET_SIZE
,
510 err("Set packet size: Set FIFO size ret %d", rc
);
514 if (usb_set_interface(ov511
->dev
, ov511
->iface
, alt
) < 0) {
515 err("Set packet size: set interface error");
519 // FIXME - Should we only reset the FIFO?
520 if (ov511_reset(ov511
->dev
, OV511_RESET_NOREGS
) < 0)
526 static inline int ov7610_set_picture(struct usb_ov511
*ov511
,
527 struct video_picture
*p
)
531 /* Stop the camera */
532 if (ov511_reg_write(ov511
->dev
, OV511_REG_SYSTEM_RESET
, 0x3d) < 0) {
533 err("reset: command failed");
537 if((ret
= ov511_i2c_read(ov511
->dev
, OV7610_REG_COM_B
)) < 0)
540 if(ov511_i2c_write(ov511
->dev
, OV7610_REG_COM_B
, ret
& 0xfe) < 0)
544 if(ov511_i2c_write(ov511
->dev
, OV7610_REG_SAT
, p
->colour
>> 8) < 0)
547 if(ov511_i2c_write(ov511
->dev
, OV7610_REG_CNT
, p
->contrast
>> 8) < 0)
550 if(ov511_i2c_write(ov511
->dev
, OV7610_REG_BRT
, p
->brightness
>> 8) < 0)
553 /* Restart the camera */
554 if (ov511_reg_write(ov511
->dev
, OV511_REG_SYSTEM_RESET
, 0x0) < 0) {
555 err("reset: command failed");
562 static inline int ov7610_get_picture(struct usb_ov511
*ov511
,
563 struct video_picture
*p
)
567 /* Stop the camera */
568 if (ov511_reg_write(ov511
->dev
, OV511_REG_SYSTEM_RESET
, 0x3d) < 0) {
569 err("reset: command failed");
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;
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");
596 static int ov511_mode_init_regs(struct usb_ov511
*ov511
,
597 int width
, int height
, int mode
, int sub_flag
)
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");
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);
616 ov511_reg_write(dev
, 0x1e, 0x00);
617 ov511_reg_write(dev
, 0x1f, 0x01);
619 ov511_reg_write(dev
, 0x16, 0x01);
620 ov511_i2c_write(dev
, 0x0e, 0x04);
621 ov511_i2c_write(dev
, 0x13, 0x01);
623 ov511_reg_write(dev
, 0x1e, 0x01);
624 ov511_reg_write(dev
, 0x1f, 0x03);
627 if (width
== 640 && height
== 480) {
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);
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 */
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 */
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);
697 err("Unknown mode (%d, %d): %d", width
, height
, mode
);
701 // ov511_set_packet_size(ov511, 993);
703 if (ov511_reg_write(dev
, OV511_REG_SYSTEM_RESET
, 0x00) < 0) {
704 err("reset: command failed");
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
,
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
);
746 int g
= guScale
* u
+ gvScale
* v
;
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:
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
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 ****************************************************************/
793 #define WDIV (256/HDIV)
796 static void ov511_parse_data_rgb24(unsigned char * pIn0
,
797 unsigned char * pOut0
,
804 #ifndef OV511_DUMPPIX
807 unsigned char * pOut
, * pOut1
;
809 /* Just copy the Y's if in the first stripe */
812 pOut
= pOut0
+ iOutY
;
820 pOut1
+= (iWidth
- 8) * 3;
826 /* Use the first half of VUs to calculate value */
828 pOut
= pOut0
+ iOutUV
;
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
);
840 pOut
+= (iWidth
*2 - 16) * 3;
843 /* Just copy the other UV rows */
846 *pOut
++ = *(pIn
+ 64);
850 pOut
+= (iWidth
*2 - 16) * 3;
853 /* Calculate values if it's the second half */
856 pOut
= pOut0
+ iOutY
;
865 int v
= *pOut1
- 128;
866 int u
= *(pOut1
+1) - 128;
867 ov511_move_420_block(y00
, y01
, y10
, y11
, u
, v
, iWidth
, pOut1
);
870 pOut1
+= (iWidth
*2 - 8) * 3;
878 /* Just dump pix data straight out for debug */
880 pOut0
+= iSegmentY
* 384;
881 for(i
=0; i
<384; i
++) {
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
893 0 1 ... 7 64 65 ... 71 ... 192 193 ... 199
894 8 9 ... 15 72 73 ... 79 200 201 ... 207
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
,
907 unsigned char * pOut
, * pOut1
;
910 pOut
= pOut0
+ iOutY
;
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
)
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
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
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
;
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;
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)) {
988 ts
= (struct timeval
*)(frame
->data
+ MAX_FRAME_SIZE
);
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
) {
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
;
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 &&
1025 PDEBUG(4, "ov511: Found Frame Start!, framenum = %d",
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
;
1039 /* Are we in a frame? */
1040 if (frame
->scanstate
== STATE_LINES
) {
1041 unsigned char * pData
;
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
);
1051 pData
= &cdata
[iPix
= 9];
1054 /* Parse the segments */
1055 while(iPix
<= 992 - frame
->segsize
&&
1056 frame
->segment
< frame
->width
* frame
->height
/ 256) {
1059 int iY
, jY
, iUV
, jUV
;
1061 unsigned char * pOut
;
1063 iSegY
= iSegUV
= frame
->segment
;
1067 iPix
+= frame
->segsize
;
1069 if (frame
->sub_flag
) {
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)
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,
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
);
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]);
1121 static void ov511_isoc_irq(struct urb
*urb
)
1124 struct usb_ov511
*ov511
= urb
->context
;
1125 struct ov511_sbuf
*sbuf
;
1130 if (!ov511
->streaming
) {
1131 PDEBUG(2, "hmmm... not streaming, but got interrupt");
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
;
1149 static int ov511_init_isoc(struct usb_ov511
*ov511
)
1154 ov511
->compress
= 0;
1155 ov511
->curframe
= -1;
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
);
1165 err("ov511_init_isoc: usb_alloc_urb ret. NULL");
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
);
1184 err("ov511_init_isoc: usb_alloc_urb ret. NULL");
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
);
1206 err("ov511_init_isoc: usb_submit_urb(0) ret %d", err
);
1207 err
= usb_submit_urb(ov511
->sbuf
[1].urb
);
1209 err("ov511_init_isoc: usb_submit_urb(1) ret %d", err
);
1211 ov511
->streaming
= 1;
1217 static void ov511_stop_isoc(struct usb_ov511
*ov511
)
1219 if (!ov511
->streaming
|| !ov511
->dev
)
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
)
1244 struct ov511_frame
*frame
;
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
;
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;
1286 /* Video 4 Linux API */
1287 static int ov511_open(struct video_device
*dev
, int flags
)
1290 struct usb_ov511
*ov511
= (struct usb_ov511
*)dev
;
1292 PDEBUG(4, "ov511_open");
1298 ov511
->frame
[0].grabstate
= FRAME_UNUSED
;
1299 ov511
->frame
[1].grabstate
= FRAME_UNUSED
;
1303 /* Allocate memory for the frame buffers */
1304 ov511
->fbuf
= rvmalloc(2 * MAX_DATA_SIZE
);
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
)
1318 ov511
->sbuf
[1].data
= kmalloc(FRAMES_PER_DESC
* FRAME_SIZE_PER_DESC
, GFP_KERNEL
);
1319 if (!ov511
->sbuf
[1].data
)
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
);
1337 kfree (ov511
->sbuf
[1].data
);
1339 kfree (ov511
->sbuf
[0].data
);
1341 rvfree(ov511
->fbuf
, 2 * MAX_DATA_SIZE
);
1350 static void ov511_close(struct video_device
*dev
)
1352 struct usb_ov511
*ov511
= (struct usb_ov511
*)dev
;
1354 PDEBUG(4, "ov511_close");
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
);
1371 video_unregister_device(&ov511
->vdev
);
1376 static int ov511_init_done(struct video_device
*dev
)
1381 static long ov511_write(struct video_device
*dev
, const char *buf
, unsigned long count
, int noblock
)
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
);
1398 struct video_capability b
;
1400 strcpy(b
.name
, "OV511 USB Camera");
1401 b
.type
= VID_TYPE_CAPTURE
| VID_TYPE_SUBCAPTURE
;
1404 b
.maxwidth
= DEFAULT_WIDTH
;
1405 b
.maxheight
= DEFAULT_HEIGHT
;
1409 if (copy_to_user(arg
, &b
, sizeof(b
)))
1416 struct video_channel v
;
1418 if (copy_from_user(&v
, arg
, sizeof(v
)))
1425 v
.type
= VIDEO_TYPE_CAMERA
;
1426 strcpy(v
.name
, "Camera");
1428 if (copy_to_user(arg
, &v
, sizeof(v
)))
1437 if (copy_from_user(&v
, arg
, sizeof(v
)))
1448 struct video_picture p
;
1450 if (ov7610_get_picture(ov511
, &p
))
1453 if (copy_to_user(arg
, &p
, sizeof(p
)))
1460 struct video_picture p
;
1462 if (copy_from_user(&p
, arg
, sizeof(p
)))
1465 if (ov7610_set_picture(ov511
, &p
))
1470 case VIDIOCGCAPTURE
:
1473 if (copy_from_user(&vf
, arg
, sizeof(vf
)))
1475 ov511
->sub_flag
= vf
;
1478 case VIDIOCSCAPTURE
:
1480 struct video_capture vc
;
1482 if (copy_from_user(&vc
, arg
, sizeof(vc
)))
1494 if (vc
.width
== 0) vc
.width
= 32;
1497 if (vc
.height
== 0) vc
.height
= 16;
1501 ov511
->subw
= vc
.width
;
1502 ov511
->subh
= vc
.height
;
1508 struct video_window vw
;
1510 if (copy_from_user(&vw
, arg
, sizeof(vw
)))
1516 if (vw
.height
!= DEFAULT_HEIGHT
)
1518 if (vw
.width
!= DEFAULT_WIDTH
)
1521 ov511
->compress
= 0;
1527 struct video_window vw
;
1531 vw
.width
= DEFAULT_WIDTH
;
1532 vw
.height
= DEFAULT_HEIGHT
;
1536 if (copy_to_user(arg
, &vw
, sizeof(vw
)))
1543 struct video_mbuf vm
;
1545 memset(&vm
, 0, sizeof(vm
));
1546 vm
.size
= 2 * MAX_DATA_SIZE
;
1549 vm
.offsets
[1] = MAX_FRAME_SIZE
+ sizeof (struct timeval
);
1551 if (copy_to_user((void *)arg
, (void *)&vm
, sizeof(vm
)))
1556 case VIDIOCMCAPTURE
:
1558 struct video_mmap vm
;
1560 if (copy_from_user((void *)&vm
, (void *)arg
, sizeof(vm
)))
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
)
1571 if ((vm
.frame
!= 0) && (vm
.frame
!= 1))
1574 if (ov511
->frame
[vm
.frame
].grabstate
== FRAME_GRABBING
)
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
!=
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
);
1610 if (copy_from_user((void *)&frame
, arg
, sizeof(int)))
1613 PDEBUG(4, "syncing to frame %d, grabstate = %d", frame
,
1614 ov511
->frame
[frame
].grabstate
);
1616 switch (ov511
->frame
[frame
].grabstate
) {
1620 case FRAME_GRABBING
:
1628 init_waitqueue_head(&ov511
->frame
[frame
].wq
);
1630 interruptible_sleep_on(&ov511
->frame
[frame
].wq
);
1631 if (signal_pending(current
))
1633 } while (ov511
->frame
[frame
].grabstate
== FRAME_GRABBING
);
1635 if (ov511
->frame
[frame
].grabstate
== FRAME_ERROR
) {
1638 if ((ret
= ov511_new_frame(ov511
, frame
)) < 0)
1643 ov511
->frame
[frame
].grabstate
= FRAME_UNUSED
;
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);
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
)))
1689 return -ENOIOCTLCMD
;
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
;
1698 volatile struct ov511_frame
*frame
;
1700 PDEBUG(4, "ov511_read: %ld bytes, noblock=%d", count
, noblock
);
1708 /* See if a frame is completed, then use it. */
1709 if (ov511
->frame
[0].grabstate
>= FRAME_DONE
) /* _DONE or _ERROR */
1711 else if (ov511
->frame
[1].grabstate
>= FRAME_DONE
)/* _DONE or _ERROR */
1714 if (noblock
&& (frmx
== -1))
1717 /* If no FRAME_DONE, look for a FRAME_GRABBING state. */
1718 /* See if a frame is in process (grabbing), then use it. */
1720 if (ov511
->frame
[0].grabstate
== FRAME_GRABBING
)
1722 else if (ov511
->frame
[1].grabstate
== FRAME_GRABBING
)
1726 /* If no frame is active, start one. */
1728 ov511_new_frame(ov511
, frmx
= 0);
1730 frame
= &ov511
->frame
[frmx
];
1736 while (frame
->grabstate
== FRAME_GRABBING
) {
1737 interruptible_sleep_on(&ov511
->frame
[frmx
].wq
);
1738 if (signal_pending(current
))
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");
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");
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
))
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");
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
;
1804 PDEBUG(4, "mmap: %ld (%lX) bytes", size
, size
);
1806 if (size
> (((2 * MAX_DATA_SIZE
) + PAGE_SIZE
- 1) & ~(PAGE_SIZE
- 1)))
1809 pos
= (unsigned long)ov511
->fbuf
;
1812 page
= kvirt_to_pa(pos
);
1813 if (remap_page_range(start
, page
, PAGE_SIZE
, PAGE_SHARED
))
1817 if (size
> PAGE_SIZE
)
1826 static struct video_device ov511_template
= {
1827 name
: "OV511 USB Camera",
1828 type
: VID_TYPE_CAPTURE
,
1829 hardware
: VID_HARDWARE_OV511
,
1836 initialize
: ov511_init_done
,
1839 static int ov7610_configure(struct usb_device
*dev
)
1843 if(ov511_reg_write(dev
, OV511_REG_I2C_SLAVE_ID_WRITE
,
1844 OV7610_I2C_WRITE_ID
) < 0)
1847 if(ov511_reg_write(dev
, OV511_REG_I2C_SLAVE_ID_READ
,
1848 OV7610_I2C_READ_ID
) < 0)
1851 if (ov511_reset(dev
, OV511_RESET_NOREGS
) < 0)
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)
1863 while((tries
> 0) &&
1864 ((ov511_i2c_read(dev
, OV7610_REG_ID_HIGH
) != 0x7F) ||
1865 (ov511_i2c_read(dev
, OV7610_REG_ID_LOW
) != 0xA2))) {
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");
1879 static int ov511_configure(struct usb_ov511
*ov511
)
1881 struct usb_device
*dev
= ov511
->dev
;
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},
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},
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");
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");
1967 if ((rc
= ov511_write_regvals(dev
, aRegvalsInit
)))
1970 if(ov7610_configure(dev
) < 0) {
1971 err("failed to configure OV7610");
1975 /* Disable compression */
1976 if (ov511_reg_write(dev
, OV511_OMNICE_ENABLE
, 0x00) < 0) {
1977 err("disable compression: command failed");
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
;
1999 if (ov511_i2c_write(dev
, 0x13, 0x01) < 0) goto error
;
2002 if (ov511_i2c_write(dev
, 0x13, 0x00) < 0 ) goto error
;
2008 video_unregister_device(&ov511
->vdev
);
2009 usb_driver_release_interface(&ov511_driver
,
2010 &dev
->actconfig
->interface
[ov511
->iface
]);
2017 static void* ov511_probe(struct usb_device
*dev
, unsigned int ifnum
)
2019 struct usb_interface_descriptor
*interface
;
2020 struct usb_ov511
*ov511
;
2023 PDEBUG(1, "probing for device...");
2025 /* We don't handle multi-config cameras */
2026 if (dev
->descriptor
.bNumConfigurations
!= 1)
2029 interface
= &dev
->actconfig
->interface
[ifnum
].altsetting
[0];
2031 /* Is it an OV511? */
2032 if (dev
->descriptor
.idVendor
!= 0x05a9)
2034 if (dev
->descriptor
.idProduct
!= 0x0511)
2037 /* Checking vendor/product should be enough, but what the hell */
2038 if (interface
->bInterfaceClass
!= 0xFF)
2040 if (interface
->bInterfaceSubClass
!= 0x00)
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");
2051 memset(ov511
, 0, sizeof(*ov511
));
2054 ov511
->iface
= interface
->bInterfaceNumber
;
2056 rc
= ov511_reg_read(dev
, OV511_REG_SYSTEM_CUSTOM_ID
);
2058 err("Unable to read camera bridge registers");
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");
2067 printk("ov511: Camera is a D-Link DSB-C300\n");
2070 printk("ov511: Camera is a generic OV511/OV7610\n");
2073 printk("ov511: Camera is a Puretek PT-6007\n");
2076 printk("ov511: Camera is a Creative Labs WebCam 3\n");
2079 printk("ov511: Camera is a Koala-Cam\n");
2082 printk("ov511: Camera is a Lifeview RoboCam\n");
2085 printk("ov511: Camera is a AverMedia InterCam Elite\n");
2087 case 112: /* The OmniVision OV7110 evaluation kit uses this too */
2088 printk("ov511: Camera is a MediaForte MV300\n");
2091 err("Specific camera type (%d) not recognized", rc
);
2092 err("Please contact mmcclelland@delphi.com to request");
2093 err("support for your camera.");
2097 if (!ov511_configure(ov511
)) {
2099 init_MUTEX(&ov511
->lock
); /* to 1 == available */
2103 err("Failed to configure camera");
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 */
2119 video_unregister_device(&ov511
->vdev
);
2121 usb_driver_release_interface(&ov511_driver
,
2122 &ov511
->dev
->actconfig
->interface
[ov511
->iface
]);
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 */
2160 static struct usb_driver ov511_driver
= {
2167 static int __init
usb_ov511_init(void)
2169 if (usb_register(&ov511_driver
) < 0)
2172 info("ov511 driver registered");
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
);