diff options
author | Amerigo Wang <amwang@redhat.com> | 2010-05-31 03:16:17 -0300 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2010-08-02 15:27:16 -0300 |
commit | 0d58cef664e01fb1848833455bfdbe1a3d91044c (patch) | |
tree | 8e5a9f5fe56fdfc1b42fd871116209af5add65bd | |
parent | a96076096bca746ddad3a5d8bfd3bbb1d9b96444 (diff) |
V4L/DVB: Remove obsolete zc0301 v4l driver
On 05/29/10 01:30, Jean-Francois Moine wrote:
> On Fri, 28 May 2010 13:03:28 -0400
> Amerigo Wang<amwang@redhat.com> wrote:
>
>> Subject: [PATCH 6/6] Remove obsolete zc0301 v4l driver
>>
>> Duplicate functionality with the gspca_zc3xx driver, zc0301 only
>> supports 2 USB-ID's (because it only supports a limited set of
>> sensors) wich are also supported by the gspca_zc3xx driver
>> (which supports 53 USB-ID's in total).
>
> You forgot to remove the conditionnal compilation in the gspca_zc3xx
> driver (USB_DEVICE(0x046d, 0x08ae) in gspca/zc3xx.c)
>
Right, thanks for pointing this out!
Attached is the updated patch, please use this one instead.
Thanks!
Duplicate functionality with the gspca_zc3xx driver, zc0301 only
supports 2 USB-ID's (because it only supports a limited set of
sensors) wich are also supported by the gspca_zc3xx driver
(which supports 53 USB-ID's in total).
Signed-off-by: Amerigo Wang <amwang@redhat.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | Documentation/feature-removal-schedule.txt | 11 | ||||
-rw-r--r-- | drivers/media/video/Kconfig | 2 | ||||
-rw-r--r-- | drivers/media/video/Makefile | 1 | ||||
-rw-r--r-- | drivers/media/video/gspca/zc3xx.c | 2 | ||||
-rw-r--r-- | drivers/media/video/zc0301/Kconfig | 15 | ||||
-rw-r--r-- | drivers/media/video/zc0301/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/video/zc0301/zc0301.h | 196 | ||||
-rw-r--r-- | drivers/media/video/zc0301/zc0301_core.c | 2098 | ||||
-rw-r--r-- | drivers/media/video/zc0301/zc0301_pas202bcb.c | 362 | ||||
-rw-r--r-- | drivers/media/video/zc0301/zc0301_pb0330.c | 188 | ||||
-rw-r--r-- | drivers/media/video/zc0301/zc0301_sensor.h | 107 |
11 files changed, 0 insertions, 2985 deletions
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 61a54fddbd4..79cb554761a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -459,17 +459,6 @@ Who: Corentin Chary <corentin.chary@gmail.com> ---------------------------- -What: zc0301 v4l driver -When: 2.6.35 -Files: drivers/media/video/zc0301/* -Why: Duplicate functionality with the gspca_zc3xx driver, zc0301 only - supports 2 USB-ID's (because it only supports a limited set of - sensors) wich are also supported by the gspca_zc3xx driver - (which supports 53 USB-ID's in total) -Who: Hans de Goede <hdegoede@redhat.com> - ----------------------------- - What: sysfs-class-rfkill state file When: Feb 2014 Files: net/rfkill/core.c diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index de098649c3b..686fa7ada85 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -1014,8 +1014,6 @@ config USB_SE401 source "drivers/media/video/sn9c102/Kconfig" -source "drivers/media/video/zc0301/Kconfig" - source "drivers/media/video/pwc/Kconfig" config USB_ZR364XX diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 5c2a38e6015..2beb4e415e6 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -133,7 +133,6 @@ obj-$(CONFIG_USB_STKWEBCAM) += stkwebcam.o obj-$(CONFIG_USB_SN9C102) += sn9c102/ obj-$(CONFIG_USB_ET61X251) += et61x251/ obj-$(CONFIG_USB_PWC) += pwc/ -obj-$(CONFIG_USB_ZC0301) += zc0301/ obj-$(CONFIG_USB_GSPCA) += gspca/ obj-$(CONFIG_VIDEO_HDPVR) += hdpvr/ diff --git a/drivers/media/video/gspca/zc3xx.c b/drivers/media/video/gspca/zc3xx.c index d7587cd5a26..4473f0fb8b7 100644 --- a/drivers/media/video/gspca/zc3xx.c +++ b/drivers/media/video/gspca/zc3xx.c @@ -7193,9 +7193,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x046d, 0x08aa)}, {USB_DEVICE(0x046d, 0x08ac)}, {USB_DEVICE(0x046d, 0x08ad)}, -#if !defined CONFIG_USB_ZC0301 && !defined CONFIG_USB_ZC0301_MODULE {USB_DEVICE(0x046d, 0x08ae)}, -#endif {USB_DEVICE(0x046d, 0x08af)}, {USB_DEVICE(0x046d, 0x08b9)}, {USB_DEVICE(0x046d, 0x08d7)}, diff --git a/drivers/media/video/zc0301/Kconfig b/drivers/media/video/zc0301/Kconfig deleted file mode 100644 index a7e610e0be9..00000000000 --- a/drivers/media/video/zc0301/Kconfig +++ /dev/null @@ -1,15 +0,0 @@ -config USB_ZC0301 - tristate "USB ZC0301[P] webcam support (DEPRECATED)" - depends on VIDEO_V4L2 - default n - ---help--- - This driver is DEPRECATED please use the gspca zc3xx module - instead. - - Say Y here if you want support for cameras based on the ZC0301 or - ZC0301P Image Processors and Control Chips. - - See <file:Documentation/video4linux/zc0301.txt> for more info. - - To compile this driver as a module, choose M here: the - module will be called zc0301. diff --git a/drivers/media/video/zc0301/Makefile b/drivers/media/video/zc0301/Makefile deleted file mode 100644 index d9e6d97fade..00000000000 --- a/drivers/media/video/zc0301/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -zc0301-objs := zc0301_core.o zc0301_pb0330.o zc0301_pas202bcb.o - -obj-$(CONFIG_USB_ZC0301) += zc0301.o diff --git a/drivers/media/video/zc0301/zc0301.h b/drivers/media/video/zc0301/zc0301.h deleted file mode 100644 index b1b5cceb4ba..00000000000 --- a/drivers/media/video/zc0301/zc0301.h +++ /dev/null @@ -1,196 +0,0 @@ -/*************************************************************************** - * V4L2 driver for ZC0301[P] Image Processor and Control Chip * - * * - * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software * - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - ***************************************************************************/ - -#ifndef _ZC0301_H_ -#define _ZC0301_H_ - -#include <linux/version.h> -#include <linux/usb.h> -#include <linux/videodev2.h> -#include <media/v4l2-common.h> -#include <media/v4l2-ioctl.h> -#include <linux/device.h> -#include <linux/list.h> -#include <linux/spinlock.h> -#include <linux/time.h> -#include <linux/wait.h> -#include <linux/types.h> -#include <linux/param.h> -#include <linux/mutex.h> -#include <linux/rwsem.h> -#include <linux/stddef.h> -#include <linux/string.h> -#include <linux/kref.h> - -#include "zc0301_sensor.h" - -/*****************************************************************************/ - -#define ZC0301_DEBUG -#define ZC0301_DEBUG_LEVEL 2 -#define ZC0301_MAX_DEVICES 64 -#define ZC0301_FORCE_MUNMAP 0 -#define ZC0301_MAX_FRAMES 32 -#define ZC0301_COMPRESSION_QUALITY 0 -#define ZC0301_URBS 2 -#define ZC0301_ISO_PACKETS 7 -#define ZC0301_ALTERNATE_SETTING 7 -#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS) -#define ZC0301_CTRL_TIMEOUT 100 -#define ZC0301_FRAME_TIMEOUT 2 - -/*****************************************************************************/ - -ZC0301_ID_TABLE -ZC0301_SENSOR_TABLE - -enum zc0301_frame_state { - F_UNUSED, - F_QUEUED, - F_GRABBING, - F_DONE, - F_ERROR, -}; - -struct zc0301_frame_t { - void* bufmem; - struct v4l2_buffer buf; - enum zc0301_frame_state state; - struct list_head frame; - unsigned long vma_use_count; -}; - -enum zc0301_dev_state { - DEV_INITIALIZED = 0x01, - DEV_DISCONNECTED = 0x02, - DEV_MISCONFIGURED = 0x04, -}; - -enum zc0301_io_method { - IO_NONE, - IO_READ, - IO_MMAP, -}; - -enum zc0301_stream_state { - STREAM_OFF, - STREAM_INTERRUPT, - STREAM_ON, -}; - -struct zc0301_module_param { - u8 force_munmap; - u16 frame_timeout; -}; - -static DECLARE_RWSEM(zc0301_dev_lock); - -struct zc0301_device { - struct video_device* v4ldev; - - struct zc0301_sensor sensor; - - struct usb_device* usbdev; - struct urb* urb[ZC0301_URBS]; - void* transfer_buffer[ZC0301_URBS]; - u8* control_buffer; - - struct zc0301_frame_t *frame_current, frame[ZC0301_MAX_FRAMES]; - struct list_head inqueue, outqueue; - u32 frame_count, nbuffers, nreadbuffers; - - enum zc0301_io_method io; - enum zc0301_stream_state stream; - - struct v4l2_jpegcompression compression; - - struct zc0301_module_param module_param; - - struct kref kref; - enum zc0301_dev_state state; - u8 users; - - struct completion probe; - struct mutex open_mutex, fileop_mutex; - spinlock_t queue_lock; - wait_queue_head_t wait_open, wait_frame, wait_stream; -}; - -/*****************************************************************************/ - -struct zc0301_device* -zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id) -{ - return usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id) ? cam : NULL; -} - -void -zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor) -{ - memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor)); -} - -/*****************************************************************************/ - -#undef DBG -#undef KDBG -#ifdef ZC0301_DEBUG -# define DBG(level, fmt, args...) \ -do { \ - if (debug >= (level)) { \ - if ((level) == 1) \ - dev_err(&cam->usbdev->dev, fmt "\n", ## args); \ - else if ((level) == 2) \ - dev_info(&cam->usbdev->dev, fmt "\n", ## args); \ - else if ((level) >= 3) \ - dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", \ - __FILE__, __func__, __LINE__ , ## args); \ - } \ -} while (0) -# define KDBG(level, fmt, args...) \ -do { \ - if (debug >= (level)) { \ - if ((level) == 1 || (level) == 2) \ - pr_info("zc0301: " fmt "\n", ## args); \ - else if ((level) == 3) \ - pr_debug("sn9c102: [%s:%s:%d] " fmt "\n", __FILE__, \ - __func__, __LINE__ , ## args); \ - } \ -} while (0) -# define V4LDBG(level, name, cmd) \ -do { \ - if (debug >= (level)) \ - v4l_print_ioctl(name, cmd); \ -} while (0) -#else -# define DBG(level, fmt, args...) do {;} while(0) -# define KDBG(level, fmt, args...) do {;} while(0) -# define V4LDBG(level, name, cmd) do {;} while(0) -#endif - -#undef PDBG -#define PDBG(fmt, args...) \ -dev_info(&cam->usbdev->dev, "[%s:%s:%d] " fmt "\n", __FILE__, __func__, \ - __LINE__ , ## args) - -#undef PDBGG -#define PDBGG(fmt, args...) do {;} while(0) /* placeholder */ - -#endif /* _ZC0301_H_ */ diff --git a/drivers/media/video/zc0301/zc0301_core.c b/drivers/media/video/zc0301/zc0301_core.c deleted file mode 100644 index bb51cfb0c64..00000000000 --- a/drivers/media/video/zc0301/zc0301_core.c +++ /dev/null @@ -1,2098 +0,0 @@ -/*************************************************************************** - * Video4Linux2 driver for ZC0301[P] Image Processor and Control Chip * - * * - * Copyright (C) 2006-2007 by Luca Risolia <luca.risolia@studio.unibo.it> * - * * - * Informations about the chip internals needed to enable the I2C protocol * - * have been taken from the documentation of the ZC030x Video4Linux1 * - * driver written by Andrew Birkett <andy@nobugs.org> * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the Free Software * - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - ***************************************************************************/ - -#include <linux/module.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/param.h> -#include <linux/errno.h> -#include <linux/slab.h> -#include <linux/device.h> -#include <linux/fs.h> -#include <linux/delay.h> -#include <linux/compiler.h> -#include <linux/ioctl.h> -#include <linux/poll.h> -#include <linux/stat.h> -#include <linux/mm.h> -#include <linux/vmalloc.h> -#include <linux/page-flags.h> -#include <asm/byteorder.h> -#include <asm/page.h> -#include <asm/uaccess.h> - -#include "zc0301.h" - -/*****************************************************************************/ - -#define ZC0301_MODULE_NAME "V4L2 driver for ZC0301[P] " \ - "Image Processor and Control Chip" -#define ZC0301_MODULE_AUTHOR "(C) 2006-2007 Luca Risolia" -#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" -#define ZC0301_MODULE_LICENSE "GPL" -#define ZC0301_MODULE_VERSION "1:1.10" -#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 1, 10) - -/*****************************************************************************/ - -MODULE_DEVICE_TABLE(usb, zc0301_id_table); - -MODULE_AUTHOR(ZC0301_MODULE_AUTHOR " " ZC0301_AUTHOR_EMAIL); -MODULE_DESCRIPTION(ZC0301_MODULE_NAME); -MODULE_VERSION(ZC0301_MODULE_VERSION); -MODULE_LICENSE(ZC0301_MODULE_LICENSE); - -static short video_nr[] = {[0 ... ZC0301_MAX_DEVICES-1] = -1}; -module_param_array(video_nr, short, NULL, 0444); -MODULE_PARM_DESC(video_nr, - "\n<-1|n[,...]> Specify V4L2 minor mode number." - "\n -1 = use next available (default)" - "\n n = use minor number n (integer >= 0)" - "\nYou can specify up to " - __MODULE_STRING(ZC0301_MAX_DEVICES) " cameras this way." - "\nFor example:" - "\nvideo_nr=-1,2,-1 would assign minor number 2 to" - "\nthe second registered camera and use auto for the first" - "\none and for every other camera." - "\n"); - -static short force_munmap[] = {[0 ... ZC0301_MAX_DEVICES-1] = - ZC0301_FORCE_MUNMAP}; -module_param_array(force_munmap, bool, NULL, 0444); -MODULE_PARM_DESC(force_munmap, - "\n<0|1[,...]> Force the application to unmap previously" - "\nmapped buffer memory before calling any VIDIOC_S_CROP or" - "\nVIDIOC_S_FMT ioctl's. Not all the applications support" - "\nthis feature. This parameter is specific for each" - "\ndetected camera." - "\n 0 = do not force memory unmapping" - "\n 1 = force memory unmapping (save memory)" - "\nDefault value is "__MODULE_STRING(ZC0301_FORCE_MUNMAP)"." - "\n"); - -static unsigned int frame_timeout[] = {[0 ... ZC0301_MAX_DEVICES-1] = - ZC0301_FRAME_TIMEOUT}; -module_param_array(frame_timeout, uint, NULL, 0644); -MODULE_PARM_DESC(frame_timeout, - "\n<n[,...]> Timeout for a video frame in seconds." - "\nThis parameter is specific for each detected camera." - "\nDefault value is "__MODULE_STRING(ZC0301_FRAME_TIMEOUT)"." - "\n"); - -#ifdef ZC0301_DEBUG -static unsigned short debug = ZC0301_DEBUG_LEVEL; -module_param(debug, ushort, 0644); -MODULE_PARM_DESC(debug, - "\n<n> Debugging information level, from 0 to 3:" - "\n0 = none (use carefully)" - "\n1 = critical errors" - "\n2 = significant informations" - "\n3 = more verbose messages" - "\nLevel 3 is useful for testing only, when only " - "one device is used." - "\nDefault value is "__MODULE_STRING(ZC0301_DEBUG_LEVEL)"." - "\n"); -#endif - -/*****************************************************************************/ - -static u32 -zc0301_request_buffers(struct zc0301_device* cam, u32 count, - enum zc0301_io_method io) -{ - struct v4l2_pix_format* p = &(cam->sensor.pix_format); - struct v4l2_rect* r = &(cam->sensor.cropcap.bounds); - const size_t imagesize = cam->module_param.force_munmap || - io == IO_READ ? - (p->width * p->height * p->priv) / 8 : - (r->width * r->height * p->priv) / 8; - void* buff = NULL; - u32 i; - - if (count > ZC0301_MAX_FRAMES) - count = ZC0301_MAX_FRAMES; - - cam->nbuffers = count; - while (cam->nbuffers > 0) { - if ((buff = vmalloc_32_user(cam->nbuffers * - PAGE_ALIGN(imagesize)))) - break; - cam->nbuffers--; - } - - for (i = 0; i < cam->nbuffers; i++) { - cam->frame[i].bufmem = buff + i*PAGE_ALIGN(imagesize); - cam->frame[i].buf.index = i; - cam->frame[i].buf.m.offset = i*PAGE_ALIGN(imagesize); - cam->frame[i].buf.length = imagesize; - cam->frame[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - cam->frame[i].buf.sequence = 0; - cam->frame[i].buf.field = V4L2_FIELD_NONE; - cam->frame[i].buf.memory = V4L2_MEMORY_MMAP; - cam->frame[i].buf.flags = 0; - } - - return cam->nbuffers; -} - - -static void zc0301_release_buffers(struct zc0301_device* cam) -{ - if (cam->nbuffers) { - vfree(cam->frame[0].bufmem); - cam->nbuffers = 0; - } - cam->frame_current = NULL; -} - - -static void zc0301_empty_framequeues(struct zc0301_device* cam) -{ - u32 i; - - INIT_LIST_HEAD(&cam->inqueue); - INIT_LIST_HEAD(&cam->outqueue); - - for (i = 0; i < ZC0301_MAX_FRAMES; i++) { - cam->frame[i].state = F_UNUSED; - cam->frame[i].buf.bytesused = 0; - } -} - - -static void zc0301_requeue_outqueue(struct zc0301_device* cam) -{ - struct zc0301_frame_t *i; - - list_for_each_entry(i, &cam->outqueue, frame) { - i->state = F_QUEUED; - list_add(&i->frame, &cam->inqueue); - } - - INIT_LIST_HEAD(&cam->outqueue); -} - - -static void zc0301_queue_unusedframes(struct zc0301_device* cam) -{ - unsigned long lock_flags; - u32 i; - - for (i = 0; i < cam->nbuffers; i++) - if (cam->frame[i].state == F_UNUSED) { - cam->frame[i].state = F_QUEUED; - spin_lock_irqsave(&cam->queue_lock, lock_flags); - list_add_tail(&cam->frame[i].frame, &cam->inqueue); - spin_unlock_irqrestore(&cam->queue_lock, lock_flags); - } -} - -/*****************************************************************************/ - -int zc0301_write_reg(struct zc0301_device* cam, u16 index, u16 value) -{ - struct usb_device* udev = cam->usbdev; - int res; - - res = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), 0xa0, 0x40, - value, index, NULL, 0, ZC0301_CTRL_TIMEOUT); - if (res < 0) { - DBG(3, "Failed to write a register (index 0x%04X, " - "value 0x%02X, error %d)",index, value, res); - return -1; - } - - return 0; -} - - -int zc0301_read_reg(struct zc0301_device* cam, u16 index) -{ - struct usb_device* udev = cam->usbdev; - u8* buff = cam->control_buffer; - int res; - - res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), 0xa1, 0xc0, - 0x0001, index, buff, 1, ZC0301_CTRL_TIMEOUT); - if (res < 0) - DBG(3, "Failed to read a register (index 0x%04X, error %d)", - index, res); - - PDBGG("Read: index 0x%04X, value: 0x%04X", index, (int)(*buff)); - - return (res >= 0) ? (int)(*buff) : -1; -} - - -int zc0301_i2c_read(struct zc0301_device* cam, u16 address, u8 length) -{ - int err = 0, res, r0, r1; - - err += zc0301_write_reg(cam, 0x0092, address); - err += zc0301_write_reg(cam, 0x0090, 0x02); - - msleep(1); - - res = zc0301_read_reg(cam, 0x0091); - if (res < 0) - err += res; - r0 = zc0301_read_reg(cam, 0x0095); - if (r0 < 0) - err += r0; - r1 = zc0301_read_reg(cam, 0x0096); - if (r1 < 0) - err += r1; - - res = (length <= 1) ? r0 : r0 | (r1 << 8); - - if (err) - DBG(3, "I2C read failed at address 0x%04X, value: 0x%04X", - address, res); - - - PDBGG("I2C read: address 0x%04X, value: 0x%04X", address, res); - - return err ? -1 : res; -} - - -int zc0301_i2c_write(struct zc0301_device* cam, u16 address, u16 value) -{ - int err = 0, res; - - err += zc0301_write_reg(cam, 0x0092, address); - err += zc0301_write_reg(cam, 0x0093, value & 0xff); - err += zc0301_write_reg(cam, 0x0094, value >> 8); - err += zc0301_write_reg(cam, 0x0090, 0x01); - - msleep(1); - - res = zc0301_read_reg(cam, 0x0091); - if (res < 0) - err += res; - - if (err) - DBG(3, "I2C write failed at address 0x%04X, value: 0x%04X", - address, value); - - PDBGG("I2C write: address 0x%04X, value: 0x%04X", address, value); - - return err ? -1 : 0; -} - -/*****************************************************************************/ - -static void zc0301_urb_complete(struct urb *urb) -{ - struct zc0301_device* cam = urb->context; - struct zc0301_frame_t** f; - size_t imagesize; - u8 i; - int err = 0; - - if (urb->status == -ENOENT) - return; - - f = &cam->frame_current; - - if (cam->stream == STREAM_INTERRUPT) { - cam->stream = STREAM_OFF; - if ((*f)) - (*f)->state = F_QUEUED; - DBG(3, "Stream interrupted"); - wake_up(&cam->wait_stream); - } - - if (cam->state & DEV_DISCONNECTED) - return; - - if (cam->state & DEV_MISCONFIGURED) { - wake_up_interruptible(&cam->wait_frame); - return; - } - - if (cam->stream == STREAM_OFF || list_empty(&cam->inqueue)) - goto resubmit_urb; - - if (!(*f)) - (*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t, - frame); - - imagesize = (cam->sensor.pix_format.width * - cam->sensor.pix_format.height * - cam->sensor.pix_format.priv) / 8; - - for (i = 0; i < urb->number_of_packets; i++) { - unsigned int len, status; - void *pos; - u16* soi; - u8 sof; - - len = urb->iso_frame_desc[i].actual_length; - status = urb->iso_frame_desc[i].status; - pos = urb->iso_frame_desc[i].offset + urb->transfer_buffer; - - if (status) { - DBG(3, "Error in isochronous frame"); - (*f)->state = F_ERROR; - continue; - } - - sof = (*(soi = pos) == 0xd8ff); - - PDBGG("Isochrnous frame: length %u, #%u i,", len, i); - - if ((*f)->state == F_QUEUED || (*f)->state == F_ERROR) -start_of_frame: - if (sof) { - (*f)->state = F_GRABBING; - (*f)->buf.bytesused = 0; - do_gettimeofday(&(*f)->buf.timestamp); - DBG(3, "SOF detected: new video frame"); - } - - if ((*f)->state == F_GRABBING) { - if (sof && (*f)->buf.bytesused) - goto end_of_frame; - - if ((*f)->buf.bytesused + len > imagesize) { - DBG(3, "Video frame size exceeded"); - (*f)->state = F_ERROR; - continue; - } - - memcpy((*f)->bufmem+(*f)->buf.bytesused, pos, len); - (*f)->buf.bytesused += len; - - if ((*f)->buf.bytesused == imagesize) { - u32 b; -end_of_frame: - b = (*f)->buf.bytesused; - (*f)->state = F_DONE; - (*f)->buf.sequence= ++cam->frame_count; - spin_lock(&cam->queue_lock); - list_move_tail(&(*f)->frame, &cam->outqueue); - if (!list_empty(&cam->inqueue)) - (*f) = list_entry(cam->inqueue.next, - struct zc0301_frame_t, - frame); - else - (*f) = NULL; - spin_unlock(&cam->queue_lock); - DBG(3, "Video frame captured: : %lu bytes", - (unsigned long)(b)); - - if (!(*f)) - goto resubmit_urb; - - if (sof) - goto start_of_frame; - } - } - } - -resubmit_urb: - urb->dev = cam->usbdev; - err = usb_submit_urb(urb, GFP_ATOMIC); - if (err < 0 && err != -EPERM) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "usb_submit_urb() failed"); - } - - wake_up_interruptible(&cam->wait_frame); -} - - -static int zc0301_start_transfer(struct zc0301_device* cam) -{ - struct usb_device *udev = cam->usbdev; - struct usb_host_interface* altsetting = usb_altnum_to_altsetting( - usb_ifnum_to_if(udev, 0), - ZC0301_ALTERNATE_SETTING); - const unsigned int psz = le16_to_cpu(altsetting-> - endpoint[0].desc.wMaxPacketSize); - struct urb* urb; - s8 i, j; - int err = 0; - - for (i = 0; i < ZC0301_URBS; i++) { - cam->transfer_buffer[i] = kzalloc(ZC0301_ISO_PACKETS * psz, - GFP_KERNEL); - if (!cam->transfer_buffer[i]) { - err = -ENOMEM; - DBG(1, "Not enough memory"); - goto free_buffers; - } - } - - for (i = 0; i < ZC0301_URBS; i++) { - urb = usb_alloc_urb(ZC0301_ISO_PACKETS, GFP_KERNEL); - cam->urb[i] = urb; - if (!urb) { - err = -ENOMEM; - DBG(1, "usb_alloc_urb() failed"); - goto free_urbs; - } - urb->dev = udev; - urb->context = cam; - urb->pipe = usb_rcvisocpipe(udev, 1); - urb->transfer_flags = URB_ISO_ASAP; - urb->number_of_packets = ZC0301_ISO_PACKETS; - urb->complete = zc0301_urb_complete; - urb->transfer_buffer = cam->transfer_buffer[i]; - urb->transfer_buffer_length = psz * ZC0301_ISO_PACKETS; - urb->interval = 1; - for (j = 0; j < ZC0301_ISO_PACKETS; j++) { - urb->iso_frame_desc[j].offset = psz * j; - urb->iso_frame_desc[j].length = psz; - } - } - - err = usb_set_interface(udev, 0, ZC0301_ALTERNATE_SETTING); - if (err) { - DBG(1, "usb_set_interface() failed"); - goto free_urbs; - } - - cam->frame_current = NULL; - - for (i = 0; i < ZC0301_URBS; i++) { - err = usb_submit_urb(cam->urb[i], GFP_KERNEL); - if (err) { - for (j = i-1; j >= 0; j--) - usb_kill_urb(cam->urb[j]); - DBG(1, "usb_submit_urb() failed, error %d", err); - goto free_urbs; - } - } - - return 0; - -free_urbs: - for (i = 0; (i < ZC0301_URBS) && cam->urb[i]; i++) - usb_free_urb(cam->urb[i]); - -free_buffers: - for (i = 0; (i < ZC0301_URBS) && cam->transfer_buffer[i]; i++) - kfree(cam->transfer_buffer[i]); - - return err; -} - - -static int zc0301_stop_transfer(struct zc0301_device* cam) -{ - struct usb_device *udev = cam->usbdev; - s8 i; - int err = 0; - - if (cam->state & DEV_DISCONNECTED) - return 0; - - for (i = ZC0301_URBS-1; i >= 0; i--) { - usb_kill_urb(cam->urb[i]); - usb_free_urb(cam->urb[i]); - kfree(cam->transfer_buffer[i]); - } - - err = usb_set_interface(udev, 0, 0); /* 0 Mb/s */ - if (err) - DBG(3, "usb_set_interface() failed"); - - return err; -} - - -static int zc0301_stream_interrupt(struct zc0301_device* cam) -{ - long timeout; - - cam->stream = STREAM_INTERRUPT; - timeout = wait_event_timeout(cam->wait_stream, - (cam->stream == STREAM_OFF) || - (cam->state & DEV_DISCONNECTED), - ZC0301_URB_TIMEOUT); - if (cam->state & DEV_DISCONNECTED) - return -ENODEV; - else if (cam->stream != STREAM_OFF) { - cam->state |= DEV_MISCONFIGURED; - DBG(1, "URB timeout reached. The camera is misconfigured. To " - "use it, close and open %s again.", - video_device_node_name(cam->v4ldev)); - return -EIO; - } - - return 0; -} - -/*****************************************************************************/ - -static int -zc0301_set_compression(struct zc0301_device* cam, - struct v4l2_jpegcompression* compression) -{ - int r, err = 0; - - if ((r = zc0301_read_reg(cam, 0x0008)) < 0) - err += r; - err += zc0301_write_reg(cam, 0x0008, r | 0x11 | compression->quality); - - return err ? -EIO : 0; -} - - -static int zc0301_init(struct zc0301_device* cam) -{ - struct zc0301_sensor* s = &cam->sensor; - struct v4l2_control ctrl; - struct v4l2_queryctrl *qctrl; - struct v4l2_rect* rect; - u8 i = 0; - int err = 0; - - if (!(cam->state & DEV_INITIALIZED)) { - mutex_init(&cam->open_mutex); - init_waitqueue_head(&cam->wait_open); - qctrl = s->qctrl; - rect = &(s->cropcap.defrect); - cam->compression.quality = ZC0301_COMPRESSION_QUALITY; - } else { /* use current values */ - qctrl = s->_qctrl; - rect = &(s->_rect); - } - - if (s->init) { - err = s->init(cam); - if (err) { - DBG(3, "Sensor initialization failed"); - return err; - } - } - - if ((err = zc0301_set_compression(cam, &cam->compression))) { - DBG(3, "set_compression() failed"); - return err; - } - - if (s->set_crop) - if ((err = s->set_crop(cam, rect))) { - DBG(3, "set_crop() failed"); - return err; - } - - if (s->set_ctrl) { - for (i = 0; i < ARRAY_SIZE(s->qctrl); i++) - if (s->qctrl[i].id != 0 && - !(s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)) { - ctrl.id = s->qctrl[i].id; - ctrl.value = qctrl[i].default_value; - err = s->set_ctrl(cam, &ctrl); - if (err) { - DBG(3, "Set %s control failed", - s->qctrl[i].name); - return err; - } - DBG(3, "Image sensor supports '%s' control", - s->qctrl[i].name); - } - } - - if (!(cam->state & DEV_INITIALIZED)) { - mutex_init(&cam->fileop_mutex); - spin_lock_init(&cam->queue_lock); - init_waitqueue_head(&cam->wait_frame); - init_waitqueue_head(&cam->wait_stream); - cam->nreadbuffers = 2; - memcpy(s->_qctrl, s->qctrl, sizeof(s->qctrl)); - memcpy(&(s->_rect), &(s->cropcap.defrect), - sizeof(struct v4l2_rect)); - cam->state |= DEV_INITIALIZED; - } - - DBG(2, "Initialization succeeded"); - return 0; -} - -/*****************************************************************************/ - -static void zc0301_release_resources(struct kref *kref) -{ - struct zc0301_device *cam = container_of(kref, struct zc0301_device, - kref); - DBG(2, "V4L2 device %s deregistered", - video_device_node_name(cam->v4ldev)); - video_set_drvdata(cam->v4ldev, NULL); - video_unregister_device(cam->v4ldev); - usb_put_dev(cam->usbdev); - kfree(cam->control_buffer); - kfree(cam); -} - - -static int zc0301_open(struct file *filp) -{ - struct zc0301_device* cam; - int err = 0; - - if (!down_read_trylock(&zc0301_dev_lock)) - return -EAGAIN; - - cam = video_drvdata(filp); - - if (wait_for_completion_interruptible(&cam->probe)) { - up_read(&zc0301_dev_lock); - return -ERESTARTSYS; - } - - kref_get(&cam->kref); - - if (mutex_lock_interruptible(&cam->open_mutex)) { - kref_put(&cam->kref, zc0301_release_resources); - up_read(&zc0301_dev_lock); - return -ERESTARTSYS; - } - - if (cam->state & DEV_DISCONNECTED) { - DBG(1, "Device not present"); - err = -ENODEV; - goto out; - } - - if (cam->users) { - DBG(2, "Device %s is busy...", - video_device_node_name(cam->v4ldev)); - DBG(3, "Simultaneous opens are not supported"); - if ((filp->f_flags & O_NONBLOCK) || - (filp->f_flags & O_NDELAY)) { - err = -EWOULDBLOCK; - goto out; - } - DBG(2, "A blocking open() has been requested. Wait for the " - "device to be released..."); - up_read(&zc0301_dev_lock); - err = wait_event_interruptible_exclusive(cam->wait_open, - (cam->state & DEV_DISCONNECTED) - || !cam->users); - down_read(&am |