From a966f3e7512084f916049579067f532908ba3a49 Mon Sep 17 00:00:00 2001 From: Luca Risolia Date: Thu, 5 Jan 2006 18:14:04 +0000 Subject: [PATCH] USB: SN9C10x driver updates and bugfixes SN9C10x driver updates and bugfixes. Changes: + new, - removed, * cleanup, @ bugfix: @ fix poll() @ Remove bad get_ctrl()'s * Reduce ioctl stack usage * Remove final ";" from some macro definitions * Better support for SN9C103 + Add sn9c102_write_regs() + Add 0x0c45/0x602d to the list of SN9C10x based devices + Add support for OV7630 image sensors + Provide support for the built-in microphone interface of the SN9C103 + Documentation updates + Add 0x0c45/0x602e to the list of SN9C10x based devices Signed-off-by: Luca Risolia Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/sn9c102.txt | 86 +++++++++++++++++++++++++------------------ 1 file changed, 51 insertions(+), 35 deletions(-) (limited to 'Documentation/usb/sn9c102.txt') diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt index 3f8a119db31b..541b17fd27f6 100644 --- a/Documentation/usb/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt @@ -17,16 +17,15 @@ Index 7. Module parameters 8. Optional device control through "sysfs" 9. Supported devices -10. How to add plug-in's for new image sensors -11. Notes for V4L2 application developers -12. Video frame formats -13. Contact information -14. Credits +10. Notes for V4L2 application developers +11. Video frame formats +12. Contact information +13. Credits 1. Copyright ============ -Copyright (C) 2004-2005 by Luca Risolia +Copyright (C) 2004-2006 by Luca Risolia 2. Disclaimer @@ -54,9 +53,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 4. Overview and features ======================== -This driver attempts to support the video and audio streaming capabilities of -the devices mounting the SONiX SN9C101, SN9C102 and SN9C103 PC Camera -Controllers. +This driver attempts to support the video interface of the devices mounting the +SONiX SN9C101, SN9C102 and SN9C103 PC Camera Controllers. It's worth to note that SONiX has never collaborated with the author during the development of this project, despite several requests for enough detailed @@ -78,6 +76,7 @@ Some of the features of the driver are: - available mmap or read/poll methods for video streaming through isochronous data transfers; - automatic detection of image sensor; +- support for built-in microphone interface; - support for any window resolutions and optional panning within the maximum pixel area of image sensor; - image downscaling with arbitrary scaling factors from 1, 2 and 4 in both @@ -96,7 +95,7 @@ Some of the features of the driver are: parameters" paragraph); - up to 64 cameras can be handled at the same time; they can be connected and disconnected from the host many times without turning off the computer, if - your system supports hotplugging; + the system supports hotplugging; - no known bugs. @@ -125,6 +124,21 @@ necessary: CONFIG_USB_UHCI_HCD=m CONFIG_USB_OHCI_HCD=m +The SN9C103 controller also provides a built-in microphone interface. It is +supported by the USB Audio driver thanks to the ALSA API: + + # Sound + # + CONFIG_SOUND=y + + # Advanced Linux Sound Architecture + # + CONFIG_SND=m + + # USB devices + # + CONFIG_SND_USB_AUDIO=m + And finally: # USB Multimedia devices @@ -153,7 +167,7 @@ analyze kernel messages and verify that the loading process has gone well: Module parameters are listed below: ------------------------------------------------------------------------------- Name: video_nr -Type: int array (min = 0, max = 64) +Type: short array (min = 0, max = 64) Syntax: <-1|n[,...]> Description: Specify V4L2 minor mode number: -1 = use next available @@ -165,19 +179,19 @@ Description: Specify V4L2 minor mode number: other camera. Default: -1 ------------------------------------------------------------------------------- -Name: force_munmap; +Name: force_munmap Type: bool array (min = 0, max = 64) Syntax: <0|1[,...]> Description: Force the application to unmap previously mapped buffer memory before calling any VIDIOC_S_CROP or VIDIOC_S_FMT ioctl's. Not all the applications support this feature. This parameter is specific for each detected camera. - 0 = do not force memory unmapping" - 1 = force memory unmapping (save memory)" + 0 = do not force memory unmapping + 1 = force memory unmapping (save memory) Default: 0 ------------------------------------------------------------------------------- Name: debug -Type: int +Type: ushort Syntax: Description: Debugging information level, from 0 to 3: 0 = none (use carefully) @@ -187,7 +201,7 @@ Description: Debugging information level, from 0 to 3: Level 3 is useful for testing only, when only one device is used. It also shows some more informations about the hardware being detected. This parameter can be changed at - runtime thanks to the /sys filesystem. + runtime thanks to the /sys filesystem interface. Default: 2 ------------------------------------------------------------------------------- @@ -236,7 +250,7 @@ serialized. The sysfs interface also provides the "frame_header" entry, which exports the frame header of the most recent requested and captured video frame. The header -is 12-bytes long and is appended to every video frame by the SN9C10x +is always 18-bytes long and is appended to every video frame by the SN9C10x controllers. As an example, this additional information can be used by the user application for implementing auto-exposure features via software. @@ -250,7 +264,8 @@ Byte # Value Description 0x03 0xC4 Frame synchronisation pattern. 0x04 0xC4 Frame synchronisation pattern. 0x05 0x96 Frame synchronisation pattern. -0x06 0x00 or 0x01 Unknown meaning. The exact value depends on the chip. +0x06 0xXX Unknown meaning. The exact value depends on the chip; + possible values are 0x00, 0x01 and 0x20. 0x07 0xXX Variable value, whose bits are ff00uzzc, where ff is a frame counter, u is unknown, zz is a size indicator (00 = VGA, 01 = SIF, 10 = QSIF) and c stands for @@ -267,12 +282,23 @@ Byte # Value Description times the area outside of the specified AE area. For images that are not pure white, the value scales down according to relative whiteness. + according to relative whiteness. + +The following bytes are used by the SN9C103 bridge only: + +0x0C 0xXX Unknown meaning +0x0D 0xXX Unknown meaning +0x0E 0xXX Unknown meaning +0x0F 0xXX Unknown meaning +0x10 0xXX Unknown meaning +0x11 0xXX Unknown meaning The AE area (sx, sy, ex, ey) in the active window can be set by programming the registers 0x1c, 0x1d, 0x1e and 0x1f of the SN9C10x controllers, where one unit corresponds to 32 pixels. -[1] The frame header has been documented by Bertrik Sikken. +[1] Part of the meaning of the frame header has been documented by Bertrik + Sikken. 9. Supported devices @@ -298,6 +324,7 @@ Vendor ID Product ID 0x0c45 0x602b 0x0c45 0x602c 0x0c45 0x602d +0x0c45 0x602e 0x0c45 0x6030 0x0c45 0x6080 0x0c45 0x6082 @@ -348,18 +375,7 @@ appreciated. Non-available hardware will not be supported by the author of this driver. -10. How to add plug-in's for new image sensors -============================================== -It should be easy to write plug-in's for new sensors by using the small API -that has been created for this purpose, which is present in "sn9c102_sensor.h" -(documentation is included there). As an example, have a look at the code in -"sn9c102_pas106b.c", which uses the mentioned interface. - -At the moment, possible unsupported image sensors are: CIS-VF10 (VGA), -OV7620 (VGA), OV7630 (VGA). - - -11. Notes for V4L2 application developers +10. Notes for V4L2 application developers ========================================= This driver follows the V4L2 API specifications. In particular, it enforces two rules: @@ -394,7 +410,7 @@ initialized (as described in the documentation of the API for the image sensors supplied by this driver). -12. Video frame formats [1] +11. Video frame formats [1] ======================= The SN9C10x PC Camera Controllers can send images in two possible video formats over the USB: either native "Sequential RGB Bayer" or Huffman @@ -455,7 +471,7 @@ The following Huffman codes have been found: documented by Bertrik Sikken. -13. Contact information +12. Contact information ======================= The author may be contacted by e-mail at . @@ -464,7 +480,7 @@ GPG/PGP encrypted e-mail's are accepted. The GPG key ID of the author is the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'. -14. Credits +13. Credits =========== Many thanks to following persons for their contribute (listed in alphabetical order): @@ -480,5 +496,5 @@ order): - Bertrik Sikken, who reverse-engineered and documented the Huffman compression algorithm used in the SN9C10x controllers and implemented the first decoder; - Mizuno Takafumi for the donation of a webcam; -- An "anonymous" donator (who didn't want his name to be revealed) for the +- an "anonymous" donator (who didn't want his name to be revealed) for the donation of a webcam. -- cgit v1.2.3 From cd6fcc555fe278263880abdb93352ab205099db9 Mon Sep 17 00:00:00 2001 From: Luca Risolia Date: Fri, 13 Jan 2006 17:19:43 +0000 Subject: [PATCH] USB: SN9C10x driver updates SN9C10x driver updates: - Use kzalloc() instead of kmalloc() - Move some macro definitions from sn9c102.h to sn9c102_core.c - Use vfree() and vmalloc_32() instead of rvfree() and rvmalloc() - Fix mmap() sys call - Documentation updates Signed-off-by: Luca Risolia Signed-off-by: Greg Kroah-Hartman --- Documentation/usb/sn9c102.txt | 9 +++- drivers/usb/media/sn9c102.h | 27 +++++------ drivers/usb/media/sn9c102_core.c | 92 ++++++++++++-------------------------- drivers/usb/media/sn9c102_sensor.h | 16 +++---- 4 files changed, 54 insertions(+), 90 deletions(-) (limited to 'Documentation/usb/sn9c102.txt') diff --git a/Documentation/usb/sn9c102.txt b/Documentation/usb/sn9c102.txt index 541b17fd27f6..c6b76414172c 100644 --- a/Documentation/usb/sn9c102.txt +++ b/Documentation/usb/sn9c102.txt @@ -111,6 +111,12 @@ corresponding modules must be compiled: # CONFIG_VIDEO_DEV=m +To enable advanced debugging functionality on the device through /sysfs: + + # Multimedia devices + # + CONFIG_VIDEO_ADV_DEBUG=y + # USB support # CONFIG_USB=m @@ -208,7 +214,8 @@ Default: 2 8. Optional device control through "sysfs" [1] ========================================== -It is possible to read and write both the SN9C10x and the image sensor +If the kernel has been compiled with the CONFIG_VIDEO_ADV_DEBUG option enabled, +it is possible to read and write both the SN9C10x and the image sensor registers by using the "sysfs" filesystem interface. Every time a supported device is recognized, a write-only file named "green" is diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h index 967c6b6bc0fa..17d60c1eea7e 100644 --- a/drivers/usb/media/sn9c102.h +++ b/drivers/usb/media/sn9c102.h @@ -23,7 +23,8 @@ #include #include -#include +#include +#include #include #include #include @@ -52,13 +53,6 @@ /*****************************************************************************/ -#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" -#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" -#define SN9C102_AUTHOR_EMAIL "" -#define SN9C102_MODULE_LICENSE "GPL" -#define SN9C102_MODULE_VERSION "1:1.25" -#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 25) - enum sn9c102_bridge { BRIDGE_SN9C101 = 0x01, BRIDGE_SN9C102 = 0x02, @@ -119,8 +113,6 @@ static DECLARE_MUTEX(sn9c102_sysfs_lock); static DECLARE_RWSEM(sn9c102_disconnect); struct sn9c102_device { - struct device dev; - struct video_device* v4ldev; enum sn9c102_bridge bridge; @@ -161,7 +153,6 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, struct sn9c102_sensor* sensor) { cam->sensor = sensor; - cam->sensor->dev = &cam->dev; cam->sensor->usbdev = cam->usbdev; } @@ -174,14 +165,19 @@ sn9c102_attach_sensor(struct sn9c102_device* cam, do { \ if (debug >= (level)) { \ if ((level) == 1) \ - dev_err(&cam->dev, fmt "\n", ## args); \ + dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) == 2) \ - dev_info(&cam->dev, fmt "\n", ## args); \ + dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ else if ((level) >= 3) \ - dev_info(&cam->dev, "[%s:%d] " fmt "\n", \ + dev_info(&cam->usbdev->dev, "[%s:%d] " fmt "\n", \ __FUNCTION__, __LINE__ , ## args); \ } \ } while (0) +# define V4LDBG(level, name, cmd) \ +do { \ + if (debug >= (level)) \ + v4l_print_ioctl(name, cmd); \ +} while (0) # define KDBG(level, fmt, args...) \ do { \ if (debug >= (level)) { \ @@ -193,8 +189,9 @@ do { \ } \ } while (0) #else -# define KDBG(level, fmt, args...) do {;} while(0) # define DBG(level, fmt, args...) do {;} while(0) +# define V4LDBG(level, name, cmd) do {;} while(0) +# define KDBG(level, fmt, args...) do {;} while(0) #endif #undef PDBG diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index 6090439663ee..c81397e4714b 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c @@ -45,6 +45,15 @@ /*****************************************************************************/ +#define SN9C102_MODULE_NAME "V4L2 driver for SN9C10x PC Camera Controllers" +#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia" +#define SN9C102_AUTHOR_EMAIL "" +#define SN9C102_MODULE_LICENSE "GPL" +#define SN9C102_MODULE_VERSION "1:1.26" +#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26) + +/*****************************************************************************/ + MODULE_DEVICE_TABLE(usb, sn9c102_id_table); MODULE_AUTHOR(SN9C102_MODULE_AUTHOR " " SN9C102_AUTHOR_EMAIL); @@ -115,50 +124,6 @@ static sn9c102_eof_header_t sn9c102_eof_header[] = { /*****************************************************************************/ -static void* rvmalloc(size_t size) -{ - void* mem; - unsigned long adr; - - size = PAGE_ALIGN(size); - - mem = vmalloc_32((unsigned long)size); - if (!mem) - return NULL; - - memset(mem, 0, size); - - adr = (unsigned long)mem; - while (size > 0) { - SetPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - return mem; -} - - -static void rvfree(void* mem, size_t size) -{ - unsigned long adr; - - if (!mem) - return; - - size = PAGE_ALIGN(size); - - adr = (unsigned long)mem; - while (size > 0) { - ClearPageReserved(vmalloc_to_page((void *)adr)); - adr += PAGE_SIZE; - size -= PAGE_SIZE; - } - - vfree(mem); -} - - static u32 sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, enum sn9c102_io_method io) @@ -177,7 +142,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, cam->nbuffers = count; while (cam->nbuffers > 0) { - if ((buff = rvmalloc(cam->nbuffers * PAGE_ALIGN(imagesize)))) + if ((buff = vmalloc_32(cam->nbuffers * PAGE_ALIGN(imagesize)))) break; cam->nbuffers--; } @@ -201,8 +166,7 @@ sn9c102_request_buffers(struct sn9c102_device* cam, u32 count, static void sn9c102_release_buffers(struct sn9c102_device* cam) { if (cam->nbuffers) { - rvfree(cam->frame[0].bufmem, - cam->nbuffers * PAGE_ALIGN(cam->frame[0].buf.length)); + vfree(cam->frame[0].bufmem); cam->nbuffers = 0; } cam->frame_current = NULL; @@ -745,7 +709,7 @@ static int sn9c102_start_transfer(struct sn9c102_device* cam) int err = 0; for (i = 0; i < SN9C102_URBS; i++) { - cam->transfer_buffer[i] = kmalloc(SN9C102_ISO_PACKETS * psz, + cam->transfer_buffer[i] = kzalloc(SN9C102_ISO_PACKETS * psz, GFP_KERNEL); if (!cam->transfer_buffer[i]) { err = -ENOMEM; @@ -865,6 +829,7 @@ static int sn9c102_stream_interrupt(struct sn9c102_device* cam) /*****************************************************************************/ +#ifdef CONFIG_VIDEO_ADV_DEBUG static u8 sn9c102_strtou8(const char* buff, size_t len, ssize_t* count) { char str[5]; @@ -1289,6 +1254,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam) video_device_create_file(v4ldev, &class_device_attr_i2c_val); } } +#endif /* CONFIG_VIDEO_ADV_DEBUG */ /*****************************************************************************/ @@ -1754,9 +1720,8 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) { struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp)); unsigned long size = vma->vm_end - vma->vm_start, - start = vma->vm_start, - pos, - page; + start = vma->vm_start; + void *pos; u32 i; if (down_interruptible(&cam->fileop_sem)) @@ -1790,15 +1755,12 @@ static int sn9c102_mmap(struct file* filp, struct vm_area_struct *vma) return -EINVAL; } - /* VM_IO is eventually going to replace PageReserved altogether */ vma->vm_flags |= VM_IO; - vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */ + vma->vm_flags |= VM_RESERVED; - pos = (unsigned long)cam->frame[i].bufmem; + pos = cam->frame[i].bufmem; while (size > 0) { /* size is page-aligned */ - page = vmalloc_to_pfn((void *)pos); - if (remap_pfn_range(vma, start, page, PAGE_SIZE, - vma->vm_page_prot)) { + if (vm_insert_page(vma, start, vmalloc_to_page(pos))) { up(&cam->fileop_sem); return -EAGAIN; } @@ -1831,7 +1793,8 @@ sn9c102_vidioc_querycap(struct sn9c102_device* cam, void __user * arg) strlcpy(cap.card, cam->v4ldev->name, sizeof(cap.card)); if (usb_make_path(cam->usbdev, cap.bus_info, sizeof(cap.bus_info)) < 0) - strlcpy(cap.bus_info, cam->dev.bus_id, sizeof(cap.bus_info)); + strlcpy(cap.bus_info, cam->usbdev->dev.bus_id, + sizeof(cap.bus_info)); if (copy_to_user(arg, &cap, sizeof(cap))) return -EFAULT; @@ -1852,7 +1815,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg) return -EINVAL; memset(&i, 0, sizeof(i)); - strcpy(i.name, "USB"); + strcpy(i.name, "Camera"); if (copy_to_user(arg, &i, sizeof(i))) return -EFAULT; @@ -2708,6 +2671,8 @@ static int sn9c102_ioctl(struct inode* inode, struct file* filp, return -EIO; } + V4LDBG(3, "sn9c102", cmd); + err = sn9c102_ioctl_v4l2(inode, filp, cmd, (void __user *)arg); up(&cam->fileop_sem); @@ -2740,13 +2705,12 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) unsigned int i; int err = 0, r; - if (!(cam = kmalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) + if (!(cam = kzalloc(sizeof(struct sn9c102_device), GFP_KERNEL))) return -ENOMEM; cam->usbdev = udev; - memcpy(&cam->dev, &udev->dev, sizeof(struct device)); - if (!(cam->control_buffer = kmalloc(8, GFP_KERNEL))) { + if (!(cam->control_buffer = kzalloc(8, GFP_KERNEL))) { DBG(1, "kmalloc() failed"); err = -ENOMEM; goto fail; @@ -2806,7 +2770,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) strcpy(cam->v4ldev->name, "SN9C10x PC Camera"); cam->v4ldev->owner = THIS_MODULE; cam->v4ldev->type = VID_TYPE_CAPTURE | VID_TYPE_SCALES; - cam->v4ldev->hardware = VID_HARDWARE_SN9C102; + cam->v4ldev->hardware = 0; cam->v4ldev->fops = &sn9c102_fops; cam->v4ldev->minor = video_nr[dev_nr]; cam->v4ldev->release = video_device_release; @@ -2832,8 +2796,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id) dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0; +#ifdef CONFIG_VIDEO_ADV_DEBUG sn9c102_create_sysfs(cam); DBG(2, "Optional device control through 'sysfs' interface ready"); +#endif usb_set_intfdata(intf, cam); diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h index a0e561b2c852..7d953b24f2f2 100644 --- a/drivers/usb/media/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h @@ -196,10 +196,11 @@ extern int sn9c102_pread_reg(struct sn9c102_device*, u16 index); /* NOTE: there are no exported debugging functions. To uniform the output you must use the dev_info()/dev_warn()/dev_err() macros defined in device.h, - already included here, the argument being the struct device 'dev' of the - sensor structure. Do NOT use these macros before the sensor is attached or - the kernel will crash! However, you should not need to notify the user about - common errors or other messages, since this is done by the master module. + already included here, the argument being the struct device '&usbdev->dev' + of the sensor structure. Do NOT use these macros before the sensor is + attached or the kernel will crash! However, you should not need to notify + the user about common errors or other messages, since this is done by the + master module. */ /*****************************************************************************/ @@ -358,13 +359,6 @@ struct sn9c102_sensor { error code without rolling back. */ - const struct device* dev; - /* - This is the argument for dev_err(), dev_info() and dev_warn(). It - is used for debugging purposes. You must not access the struct - before the sensor is attached. - */ - const struct usb_device* usbdev; /* Points to the usb_device struct after the sensor is attached. -- cgit v1.2.3