mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-04-14 10:24:47 +00:00
[PATCH] USB: ZC0301 driver updates
ZC0301 driver updates. Changes: + new, - removed, * cleanup, @ bugfix @ Need usb_get|put_dev() when disconnecting, if the device is open * Cleanups and updates in the documentation + Use per-device sensor structures + Add frame_timeout module parameter Signed-off-by: Luca Risolia <luca.risolia@studio.unibo.it> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
ccad7789d5
commit
a847423905
5 changed files with 108 additions and 62 deletions
|
@ -68,11 +68,6 @@ Some of the features of the driver are:
|
||||||
data transfers;
|
data transfers;
|
||||||
- automatic detection of image sensor;
|
- automatic detection of image sensor;
|
||||||
- video format is standard JPEG;
|
- video format is standard JPEG;
|
||||||
- full support for the capabilities of every possible image sensors that can
|
|
||||||
be connected to the ZC0301 bridges, including, for istance, red, green,
|
|
||||||
blue and global gain adjustments and exposure control (see "Supported
|
|
||||||
devices" paragraph for details);
|
|
||||||
- use of default color settings for sunlight conditions;
|
|
||||||
- dynamic driver control thanks to various module parameters (see "Module
|
- dynamic driver control thanks to various module parameters (see "Module
|
||||||
parameters" paragraph);
|
parameters" paragraph);
|
||||||
- up to 64 cameras can be handled at the same time; they can be connected and
|
- up to 64 cameras can be handled at the same time; they can be connected and
|
||||||
|
@ -171,6 +166,14 @@ Description: Force the application to unmap previously mapped buffer memory
|
||||||
1 = force memory unmapping (save memory)
|
1 = force memory unmapping (save memory)
|
||||||
Default: 0
|
Default: 0
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
|
Name: frame_timeout
|
||||||
|
Type: uint array (min = 0, max = 64)
|
||||||
|
Syntax: <n[,...]>
|
||||||
|
Description: Timeout for a video frame in seconds. This parameter is
|
||||||
|
specific for each detected camera. This parameter can be
|
||||||
|
changed at runtime thanks to the /sys filesystem interface.
|
||||||
|
Default: 2
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
Name: debug
|
Name: debug
|
||||||
Type: ushort
|
Type: ushort
|
||||||
Syntax: <n>
|
Syntax: <n>
|
||||||
|
@ -198,17 +201,23 @@ devices mounting the ZC0301 Image Processor and Control Chips:
|
||||||
|
|
||||||
Vendor ID Product ID
|
Vendor ID Product ID
|
||||||
--------- ----------
|
--------- ----------
|
||||||
|
0x10fd 0x8050
|
||||||
|
0x041e 0x0417
|
||||||
|
0x041e 0x041e
|
||||||
|
0x041e 0x081c
|
||||||
|
0x041e 0x0834
|
||||||
|
0x041e 0x0835
|
||||||
0x046d 0x08ae
|
0x046d 0x08ae
|
||||||
|
0x0ac8 0x0301
|
||||||
|
|
||||||
The following image sensors are supported:
|
The list above does not imply that all those devices work with this driver: up
|
||||||
|
until now only the ones that mount the following image sensors are supported;
|
||||||
|
kernel messages will always tell you whether this is the case:
|
||||||
|
|
||||||
Model Manufacturer
|
Model Manufacturer
|
||||||
----- ------------
|
----- ------------
|
||||||
PAS202BCB PixArt Imaging, Inc.
|
PAS202BCB PixArt Imaging, Inc.
|
||||||
|
|
||||||
All the available control settings of each image sensor are supported through
|
|
||||||
the V4L2 interface.
|
|
||||||
|
|
||||||
|
|
||||||
9. Notes for V4L2 application developers
|
9. Notes for V4L2 application developers
|
||||||
========================================
|
========================================
|
||||||
|
@ -240,6 +249,6 @@ the fingerprint is: '88E8 F32F 7244 68BA 3958 5D40 99DA 5D2A FCE6 35A4'.
|
||||||
- Informations about the chip internals needed to enable the I2C protocol have
|
- Informations about the chip internals needed to enable the I2C protocol have
|
||||||
been taken from the documentation of the ZC030x Video4Linux1 driver written
|
been taken from the documentation of the ZC030x Video4Linux1 driver written
|
||||||
by Andrew Birkett <andy@nobugs.org>;
|
by Andrew Birkett <andy@nobugs.org>;
|
||||||
- Initialization values of the ZC0301 controller connected to the PAS202BCB
|
- The initialization values of the ZC0301 controller connected to the PAS202BCB
|
||||||
image sensor have been taken from the SPCA5XX driver maintained by
|
image sensor have been taken from the SPCA5XX driver maintained by
|
||||||
Michel Xhaard <mxhaard@magic.fr>.
|
Michel Xhaard <mxhaard@magic.fr>.
|
||||||
|
|
|
@ -34,7 +34,8 @@
|
||||||
#include <linux/param.h>
|
#include <linux/param.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/rwsem.h>
|
#include <linux/rwsem.h>
|
||||||
#include <asm/semaphore.h>
|
#include <linux/stddef.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
|
||||||
#include "zc0301_sensor.h"
|
#include "zc0301_sensor.h"
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@
|
||||||
#define ZC0301_ALTERNATE_SETTING 7
|
#define ZC0301_ALTERNATE_SETTING 7
|
||||||
#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS)
|
#define ZC0301_URB_TIMEOUT msecs_to_jiffies(2 * ZC0301_ISO_PACKETS)
|
||||||
#define ZC0301_CTRL_TIMEOUT 100
|
#define ZC0301_CTRL_TIMEOUT 100
|
||||||
#define ZC0301_FRAME_TIMEOUT 2 * 1000 * msecs_to_jiffies(1)
|
#define ZC0301_FRAME_TIMEOUT 2
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@ -94,6 +95,7 @@ enum zc0301_stream_state {
|
||||||
|
|
||||||
struct zc0301_module_param {
|
struct zc0301_module_param {
|
||||||
u8 force_munmap;
|
u8 force_munmap;
|
||||||
|
u16 frame_timeout;
|
||||||
};
|
};
|
||||||
|
|
||||||
static DECLARE_RWSEM(zc0301_disconnect);
|
static DECLARE_RWSEM(zc0301_disconnect);
|
||||||
|
@ -101,7 +103,7 @@ static DECLARE_RWSEM(zc0301_disconnect);
|
||||||
struct zc0301_device {
|
struct zc0301_device {
|
||||||
struct video_device* v4ldev;
|
struct video_device* v4ldev;
|
||||||
|
|
||||||
struct zc0301_sensor* sensor;
|
struct zc0301_sensor sensor;
|
||||||
|
|
||||||
struct usb_device* usbdev;
|
struct usb_device* usbdev;
|
||||||
struct urb* urb[ZC0301_URBS];
|
struct urb* urb[ZC0301_URBS];
|
||||||
|
@ -129,11 +131,19 @@ struct zc0301_device {
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
struct zc0301_device*
|
||||||
|
zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id)
|
||||||
|
{
|
||||||
|
if (usb_match_id(usb_ifnum_to_if(cam->usbdev, 0), id))
|
||||||
|
return cam;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor)
|
zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor)
|
||||||
{
|
{
|
||||||
cam->sensor = sensor;
|
memcpy(&cam->sensor, sensor, sizeof(struct zc0301_sensor));
|
||||||
cam->sensor->usbdev = cam->usbdev;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
|
@ -29,11 +29,9 @@
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/stddef.h>
|
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/ioctl.h>
|
#include <linux/ioctl.h>
|
||||||
#include <linux/poll.h>
|
#include <linux/poll.h>
|
||||||
|
@ -54,8 +52,8 @@
|
||||||
#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia"
|
#define ZC0301_MODULE_AUTHOR "(C) 2006 Luca Risolia"
|
||||||
#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
|
#define ZC0301_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
|
||||||
#define ZC0301_MODULE_LICENSE "GPL"
|
#define ZC0301_MODULE_LICENSE "GPL"
|
||||||
#define ZC0301_MODULE_VERSION "1:1.01"
|
#define ZC0301_MODULE_VERSION "1:1.02"
|
||||||
#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 1)
|
#define ZC0301_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 2)
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
@ -94,6 +92,15 @@ MODULE_PARM_DESC(force_munmap,
|
||||||
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
||||||
"\n");
|
"\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
|
#ifdef ZC0301_DEBUG
|
||||||
static unsigned short debug = ZC0301_DEBUG_LEVEL;
|
static unsigned short debug = ZC0301_DEBUG_LEVEL;
|
||||||
module_param(debug, ushort, 0644);
|
module_param(debug, ushort, 0644);
|
||||||
|
@ -115,8 +122,8 @@ static u32
|
||||||
zc0301_request_buffers(struct zc0301_device* cam, u32 count,
|
zc0301_request_buffers(struct zc0301_device* cam, u32 count,
|
||||||
enum zc0301_io_method io)
|
enum zc0301_io_method io)
|
||||||
{
|
{
|
||||||
struct v4l2_pix_format* p = &(cam->sensor->pix_format);
|
struct v4l2_pix_format* p = &(cam->sensor.pix_format);
|
||||||
struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
|
struct v4l2_rect* r = &(cam->sensor.cropcap.bounds);
|
||||||
const size_t imagesize = cam->module_param.force_munmap ||
|
const size_t imagesize = cam->module_param.force_munmap ||
|
||||||
io == IO_READ ?
|
io == IO_READ ?
|
||||||
(p->width * p->height * p->priv) / 8 :
|
(p->width * p->height * p->priv) / 8 :
|
||||||
|
@ -332,9 +339,9 @@ static void zc0301_urb_complete(struct urb *urb, struct pt_regs* regs)
|
||||||
(*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t,
|
(*f) = list_entry(cam->inqueue.next, struct zc0301_frame_t,
|
||||||
frame);
|
frame);
|
||||||
|
|
||||||
imagesize = (cam->sensor->pix_format.width *
|
imagesize = (cam->sensor.pix_format.width *
|
||||||
cam->sensor->pix_format.height *
|
cam->sensor.pix_format.height *
|
||||||
cam->sensor->pix_format.priv) / 8;
|
cam->sensor.pix_format.priv) / 8;
|
||||||
|
|
||||||
for (i = 0; i < urb->number_of_packets; i++) {
|
for (i = 0; i < urb->number_of_packets; i++) {
|
||||||
unsigned int len, status;
|
unsigned int len, status;
|
||||||
|
@ -555,7 +562,7 @@ zc0301_set_compression(struct zc0301_device* cam,
|
||||||
|
|
||||||
static int zc0301_init(struct zc0301_device* cam)
|
static int zc0301_init(struct zc0301_device* cam)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_control ctrl;
|
struct v4l2_control ctrl;
|
||||||
struct v4l2_queryctrl *qctrl;
|
struct v4l2_queryctrl *qctrl;
|
||||||
struct v4l2_rect* rect;
|
struct v4l2_rect* rect;
|
||||||
|
@ -630,6 +637,7 @@ static void zc0301_release_resources(struct zc0301_device* cam)
|
||||||
DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
|
DBG(2, "V4L2 device /dev/video%d deregistered", cam->v4ldev->minor);
|
||||||
video_set_drvdata(cam->v4ldev, NULL);
|
video_set_drvdata(cam->v4ldev, NULL);
|
||||||
video_unregister_device(cam->v4ldev);
|
video_unregister_device(cam->v4ldev);
|
||||||
|
usb_put_dev(cam->usbdev);
|
||||||
kfree(cam->control_buffer);
|
kfree(cam->control_buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -798,7 +806,8 @@ zc0301_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
|
||||||
(!list_empty(&cam->outqueue)) ||
|
(!list_empty(&cam->outqueue)) ||
|
||||||
(cam->state & DEV_DISCONNECTED) ||
|
(cam->state & DEV_DISCONNECTED) ||
|
||||||
(cam->state & DEV_MISCONFIGURED),
|
(cam->state & DEV_MISCONFIGURED),
|
||||||
ZC0301_FRAME_TIMEOUT );
|
cam->module_param.frame_timeout *
|
||||||
|
1000 * msecs_to_jiffies(1) );
|
||||||
if (timeout < 0) {
|
if (timeout < 0) {
|
||||||
mutex_unlock(&cam->fileop_mutex);
|
mutex_unlock(&cam->fileop_mutex);
|
||||||
return timeout;
|
return timeout;
|
||||||
|
@ -1056,7 +1065,7 @@ zc0301_vidioc_s_input(struct zc0301_device* cam, void __user * arg)
|
||||||
static int
|
static int
|
||||||
zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_queryctrl qc;
|
struct v4l2_queryctrl qc;
|
||||||
u8 i;
|
u8 i;
|
||||||
|
|
||||||
|
@ -1078,7 +1087,7 @@ zc0301_vidioc_query_ctrl(struct zc0301_device* cam, void __user * arg)
|
||||||
static int
|
static int
|
||||||
zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_g_ctrl(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_control ctrl;
|
struct v4l2_control ctrl;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
u8 i;
|
u8 i;
|
||||||
|
@ -1110,7 +1119,7 @@ exit:
|
||||||
static int
|
static int
|
||||||
zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_control ctrl;
|
struct v4l2_control ctrl;
|
||||||
u8 i;
|
u8 i;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -1123,6 +1132,8 @@ zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
|
for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
|
||||||
if (ctrl.id == s->qctrl[i].id) {
|
if (ctrl.id == s->qctrl[i].id) {
|
||||||
|
if (s->qctrl[i].flags & V4L2_CTRL_FLAG_DISABLED)
|
||||||
|
return -EINVAL;
|
||||||
if (ctrl.value < s->qctrl[i].minimum ||
|
if (ctrl.value < s->qctrl[i].minimum ||
|
||||||
ctrl.value > s->qctrl[i].maximum)
|
ctrl.value > s->qctrl[i].maximum)
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
|
@ -1142,7 +1153,7 @@ zc0301_vidioc_s_ctrl(struct zc0301_device* cam, void __user * arg)
|
||||||
static int
|
static int
|
||||||
zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct v4l2_cropcap* cc = &(cam->sensor->cropcap);
|
struct v4l2_cropcap* cc = &(cam->sensor.cropcap);
|
||||||
|
|
||||||
cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
cc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
cc->pixelaspect.numerator = 1;
|
cc->pixelaspect.numerator = 1;
|
||||||
|
@ -1158,7 +1169,7 @@ zc0301_vidioc_cropcap(struct zc0301_device* cam, void __user * arg)
|
||||||
static int
|
static int
|
||||||
zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_crop crop = {
|
struct v4l2_crop crop = {
|
||||||
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
||||||
};
|
};
|
||||||
|
@ -1175,7 +1186,7 @@ zc0301_vidioc_g_crop(struct zc0301_device* cam, void __user * arg)
|
||||||
static int
|
static int
|
||||||
zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_s_crop(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_crop crop;
|
struct v4l2_crop crop;
|
||||||
struct v4l2_rect* rect;
|
struct v4l2_rect* rect;
|
||||||
struct v4l2_rect* bounds = &(s->cropcap.bounds);
|
struct v4l2_rect* bounds = &(s->cropcap.bounds);
|
||||||
|
@ -1304,7 +1315,7 @@ static int
|
||||||
zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg)
|
zc0301_vidioc_g_fmt(struct zc0301_device* cam, void __user * arg)
|
||||||
{
|
{
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
struct v4l2_pix_format* pfmt = &(cam->sensor->pix_format);
|
struct v4l2_pix_format* pfmt = &(cam->sensor.pix_format);
|
||||||
|
|
||||||
if (copy_from_user(&format, arg, sizeof(format)))
|
if (copy_from_user(&format, arg, sizeof(format)))
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
@ -1328,7 +1339,7 @@ static int
|
||||||
zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
|
zc0301_vidioc_try_s_fmt(struct zc0301_device* cam, unsigned int cmd,
|
||||||
void __user * arg)
|
void __user * arg)
|
||||||
{
|
{
|
||||||
struct zc0301_sensor* s = cam->sensor;
|
struct zc0301_sensor* s = &cam->sensor;
|
||||||
struct v4l2_format format;
|
struct v4l2_format format;
|
||||||
struct v4l2_pix_format* pix;
|
struct v4l2_pix_format* pix;
|
||||||
struct v4l2_pix_format* pfmt = &(s->pix_format);
|
struct v4l2_pix_format* pfmt = &(s->pix_format);
|
||||||
|
@ -1612,7 +1623,8 @@ zc0301_vidioc_dqbuf(struct zc0301_device* cam, struct file* filp,
|
||||||
(!list_empty(&cam->outqueue)) ||
|
(!list_empty(&cam->outqueue)) ||
|
||||||
(cam->state & DEV_DISCONNECTED) ||
|
(cam->state & DEV_DISCONNECTED) ||
|
||||||
(cam->state & DEV_MISCONFIGURED),
|
(cam->state & DEV_MISCONFIGURED),
|
||||||
ZC0301_FRAME_TIMEOUT );
|
cam->module_param.frame_timeout *
|
||||||
|
1000 * msecs_to_jiffies(1) );
|
||||||
if (timeout < 0)
|
if (timeout < 0)
|
||||||
return timeout;
|
return timeout;
|
||||||
if (cam->state & DEV_DISCONNECTED)
|
if (cam->state & DEV_DISCONNECTED)
|
||||||
|
@ -1911,8 +1923,8 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!err && cam->sensor)
|
if (!err)
|
||||||
DBG(2, "%s image sensor detected", cam->sensor->name);
|
DBG(2, "%s image sensor detected", cam->sensor.name);
|
||||||
else {
|
else {
|
||||||
DBG(1, "No supported image sensor detected");
|
DBG(1, "No supported image sensor detected");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
|
@ -1950,6 +1962,7 @@ zc0301_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
||||||
DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
|
DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
|
||||||
|
|
||||||
cam->module_param.force_munmap = force_munmap[dev_nr];
|
cam->module_param.force_munmap = force_munmap[dev_nr];
|
||||||
|
cam->module_param.frame_timeout = frame_timeout[dev_nr];
|
||||||
|
|
||||||
dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
|
dev_nr = (dev_nr < ZC0301_MAX_DEVICES-1) ? dev_nr+1 : 0;
|
||||||
|
|
||||||
|
@ -1994,6 +2007,7 @@ static void zc0301_usb_disconnect(struct usb_interface* intf)
|
||||||
cam->state |= DEV_DISCONNECTED;
|
cam->state |= DEV_DISCONNECTED;
|
||||||
wake_up_interruptible(&cam->wait_frame);
|
wake_up_interruptible(&cam->wait_frame);
|
||||||
wake_up(&cam->wait_stream);
|
wake_up(&cam->wait_stream);
|
||||||
|
usb_get_dev(cam->usbdev);
|
||||||
} else {
|
} else {
|
||||||
cam->state |= DEV_DISCONNECTED;
|
cam->state |= DEV_DISCONNECTED;
|
||||||
zc0301_release_resources(cam);
|
zc0301_release_resources(cam);
|
||||||
|
|
|
@ -22,6 +22,14 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
NOTE: Sensor controls are disabled for now, becouse changing them while
|
||||||
|
streaming sometimes results in out-of-sync video frames. We'll use
|
||||||
|
the default initialization, until we know how to stop and start video
|
||||||
|
in the chip. However, the image quality still looks good under various
|
||||||
|
light conditions.
|
||||||
|
*/
|
||||||
|
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include "zc0301_sensor.h"
|
#include "zc0301_sensor.h"
|
||||||
|
|
||||||
|
@ -245,7 +253,7 @@ static struct zc0301_sensor pas202bcb = {
|
||||||
.maximum = 0x3fff,
|
.maximum = 0x3fff,
|
||||||
.step = 0x0001,
|
.step = 0x0001,
|
||||||
.default_value = 0x01e5,
|
.default_value = 0x01e5,
|
||||||
.flags = 0,
|
.flags = V4L2_CTRL_FLAG_DISABLED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = V4L2_CID_GAIN,
|
.id = V4L2_CID_GAIN,
|
||||||
|
@ -255,7 +263,17 @@ static struct zc0301_sensor pas202bcb = {
|
||||||
.maximum = 0x1f,
|
.maximum = 0x1f,
|
||||||
.step = 0x01,
|
.step = 0x01,
|
||||||
.default_value = 0x0c,
|
.default_value = 0x0c,
|
||||||
.flags = 0,
|
.flags = V4L2_CTRL_FLAG_DISABLED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.id = ZC0301_V4L2_CID_DAC_MAGNITUDE,
|
||||||
|
.type = V4L2_CTRL_TYPE_INTEGER,
|
||||||
|
.name = "DAC magnitude",
|
||||||
|
.minimum = 0x00,
|
||||||
|
.maximum = 0xff,
|
||||||
|
.step = 0x01,
|
||||||
|
.default_value = 0x00,
|
||||||
|
.flags = V4L2_CTRL_FLAG_DISABLED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = V4L2_CID_RED_BALANCE,
|
.id = V4L2_CID_RED_BALANCE,
|
||||||
|
@ -265,7 +283,7 @@ static struct zc0301_sensor pas202bcb = {
|
||||||
.maximum = 0x0f,
|
.maximum = 0x0f,
|
||||||
.step = 0x01,
|
.step = 0x01,
|
||||||
.default_value = 0x01,
|
.default_value = 0x01,
|
||||||
.flags = 0,
|
.flags = V4L2_CTRL_FLAG_DISABLED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = V4L2_CID_BLUE_BALANCE,
|
.id = V4L2_CID_BLUE_BALANCE,
|
||||||
|
@ -275,7 +293,7 @@ static struct zc0301_sensor pas202bcb = {
|
||||||
.maximum = 0x0f,
|
.maximum = 0x0f,
|
||||||
.step = 0x01,
|
.step = 0x01,
|
||||||
.default_value = 0x05,
|
.default_value = 0x05,
|
||||||
.flags = 0,
|
.flags = V4L2_CTRL_FLAG_DISABLED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.id = ZC0301_V4L2_CID_GREEN_BALANCE,
|
.id = ZC0301_V4L2_CID_GREEN_BALANCE,
|
||||||
|
@ -285,17 +303,7 @@ static struct zc0301_sensor pas202bcb = {
|
||||||
.maximum = 0x0f,
|
.maximum = 0x0f,
|
||||||
.step = 0x01,
|
.step = 0x01,
|
||||||
.default_value = 0x00,
|
.default_value = 0x00,
|
||||||
.flags = 0,
|
.flags = V4L2_CTRL_FLAG_DISABLED,
|
||||||
},
|
|
||||||
{
|
|
||||||
.id = ZC0301_V4L2_CID_DAC_MAGNITUDE,
|
|
||||||
.type = V4L2_CTRL_TYPE_INTEGER,
|
|
||||||
.name = "DAC magnitude",
|
|
||||||
.minimum = 0x00,
|
|
||||||
.maximum = 0xff,
|
|
||||||
.step = 0x01,
|
|
||||||
.default_value = 0x04,
|
|
||||||
.flags = 0,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.get_ctrl = &pas202bcb_get_ctrl,
|
.get_ctrl = &pas202bcb_get_ctrl,
|
||||||
|
|
|
@ -43,9 +43,11 @@ static int (*zc0301_sensor_table[])(struct zc0301_device*) = { \
|
||||||
NULL, \
|
NULL, \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern struct zc0301_device*
|
||||||
|
zc0301_match_id(struct zc0301_device* cam, const struct usb_device_id *id);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
zc0301_attach_sensor(struct zc0301_device* cam,
|
zc0301_attach_sensor(struct zc0301_device* cam, struct zc0301_sensor* sensor);
|
||||||
struct zc0301_sensor* sensor);
|
|
||||||
|
|
||||||
#define ZC0301_USB_DEVICE(vend, prod, intclass) \
|
#define ZC0301_USB_DEVICE(vend, prod, intclass) \
|
||||||
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
|
.match_flags = USB_DEVICE_ID_MATCH_DEVICE | \
|
||||||
|
@ -56,7 +58,14 @@ zc0301_attach_sensor(struct zc0301_device* cam,
|
||||||
|
|
||||||
#define ZC0301_ID_TABLE \
|
#define ZC0301_ID_TABLE \
|
||||||
static const struct usb_device_id zc0301_id_table[] = { \
|
static const struct usb_device_id zc0301_id_table[] = { \
|
||||||
|
{ ZC0301_USB_DEVICE(0x10fd, 0x8050, 0xff), }, /* TAS5130D */ \
|
||||||
|
{ ZC0301_USB_DEVICE(0x041e, 0x0417, 0xff), }, \
|
||||||
|
{ ZC0301_USB_DEVICE(0x041e, 0x041e, 0xff), }, /* HV7131B */ \
|
||||||
|
{ ZC0301_USB_DEVICE(0x041e, 0x081c, 0xff), }, /* PAS106 */ \
|
||||||
|
{ ZC0301_USB_DEVICE(0x041e, 0x0834, 0xff), }, /* PAS106 */ \
|
||||||
|
{ ZC0301_USB_DEVICE(0x041e, 0x0835, 0xff), }, /* PAS106 */ \
|
||||||
{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \
|
{ ZC0301_USB_DEVICE(0x046d, 0x08ae, 0xff), }, /* PAS202BCB */ \
|
||||||
|
{ ZC0301_USB_DEVICE(0x0ac8, 0x0301, 0xff), }, \
|
||||||
{ } \
|
{ } \
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -80,15 +89,11 @@ struct zc0301_sensor {
|
||||||
struct v4l2_cropcap cropcap;
|
struct v4l2_cropcap cropcap;
|
||||||
struct v4l2_pix_format pix_format;
|
struct v4l2_pix_format pix_format;
|
||||||
|
|
||||||
int (*init)(struct zc0301_device* cam);
|
int (*init)(struct zc0301_device*);
|
||||||
int (*get_ctrl)(struct zc0301_device* cam,
|
int (*get_ctrl)(struct zc0301_device*, struct v4l2_control* ctrl);
|
||||||
struct v4l2_control* ctrl);
|
int (*set_ctrl)(struct zc0301_device*,
|
||||||
int (*set_ctrl)(struct zc0301_device* cam,
|
|
||||||
const struct v4l2_control* ctrl);
|
const struct v4l2_control* ctrl);
|
||||||
int (*set_crop)(struct zc0301_device* cam,
|
int (*set_crop)(struct zc0301_device*, const struct v4l2_rect* rect);
|
||||||
const struct v4l2_rect* rect);
|
|
||||||
|
|
||||||
const struct usb_device* usbdev;
|
|
||||||
|
|
||||||
/* Private */
|
/* Private */
|
||||||
struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS];
|
struct v4l2_queryctrl _qctrl[ZC0301_MAX_CTRLS];
|
||||||
|
|
Loading…
Add table
Reference in a new issue