|
@@ -25,11 +25,9 @@
|
|
|
#include <linux/moduleparam.h>
|
|
|
#include <linux/errno.h>
|
|
|
#include <linux/slab.h>
|
|
|
-#include <linux/string.h>
|
|
|
#include <linux/device.h>
|
|
|
#include <linux/fs.h>
|
|
|
#include <linux/delay.h>
|
|
|
-#include <linux/stddef.h>
|
|
|
#include <linux/compiler.h>
|
|
|
#include <linux/ioctl.h>
|
|
|
#include <linux/poll.h>
|
|
@@ -49,8 +47,8 @@
|
|
|
#define SN9C102_MODULE_AUTHOR "(C) 2004-2006 Luca Risolia"
|
|
|
#define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>"
|
|
|
#define SN9C102_MODULE_LICENSE "GPL"
|
|
|
-#define SN9C102_MODULE_VERSION "1:1.26"
|
|
|
-#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 26)
|
|
|
+#define SN9C102_MODULE_VERSION "1:1.27"
|
|
|
+#define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 27)
|
|
|
|
|
|
/*****************************************************************************/
|
|
|
|
|
@@ -89,6 +87,15 @@ MODULE_PARM_DESC(force_munmap,
|
|
|
"\nDefault value is "__MODULE_STRING(SN9C102_FORCE_MUNMAP)"."
|
|
|
"\n");
|
|
|
|
|
|
+static unsigned int frame_timeout[] = {[0 ... SN9C102_MAX_DEVICES-1] =
|
|
|
+ SN9C102_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(SN9C102_FRAME_TIMEOUT)"."
|
|
|
+ "\n");
|
|
|
+
|
|
|
#ifdef SN9C102_DEBUG
|
|
|
static unsigned short debug = SN9C102_DEBUG_LEVEL;
|
|
|
module_param(debug, ushort, 0644);
|
|
@@ -128,8 +135,8 @@ static u32
|
|
|
sn9c102_request_buffers(struct sn9c102_device* cam, u32 count,
|
|
|
enum sn9c102_io_method io)
|
|
|
{
|
|
|
- struct v4l2_pix_format* p = &(cam->sensor->pix_format);
|
|
|
- struct v4l2_rect* r = &(cam->sensor->cropcap.bounds);
|
|
|
+ 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 :
|
|
@@ -449,19 +456,13 @@ sn9c102_i2c_try_write(struct sn9c102_device* cam,
|
|
|
|
|
|
int sn9c102_i2c_read(struct sn9c102_device* cam, u8 address)
|
|
|
{
|
|
|
- if (!cam->sensor)
|
|
|
- return -1;
|
|
|
-
|
|
|
- return sn9c102_i2c_try_read(cam, cam->sensor, address);
|
|
|
+ return sn9c102_i2c_try_read(cam, &cam->sensor, address);
|
|
|
}
|
|
|
|
|
|
|
|
|
int sn9c102_i2c_write(struct sn9c102_device* cam, u8 address, u8 value)
|
|
|
{
|
|
|
- if (!cam->sensor)
|
|
|
- return -1;
|
|
|
-
|
|
|
- return sn9c102_i2c_try_write(cam, cam->sensor, address, value);
|
|
|
+ return sn9c102_i2c_try_write(cam, &cam->sensor, address, value);
|
|
|
}
|
|
|
|
|
|
/*****************************************************************************/
|
|
@@ -505,7 +506,7 @@ sn9c102_find_eof_header(struct sn9c102_device* cam, void* mem, size_t len)
|
|
|
size_t eoflen = sizeof(sn9c102_eof_header_t), i;
|
|
|
unsigned j, n = sizeof(sn9c102_eof_header) / eoflen;
|
|
|
|
|
|
- if (cam->sensor->pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
|
|
|
+ if (cam->sensor.pix_format.pixelformat == V4L2_PIX_FMT_SN9C10X)
|
|
|
return NULL; /* EOF header does not exist in compressed data */
|
|
|
|
|
|
for (i = 0; (len >= eoflen) && (i <= len - eoflen); i++)
|
|
@@ -535,7 +536,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
|
|
|
if ((*f))
|
|
|
(*f)->state = F_QUEUED;
|
|
|
DBG(3, "Stream interrupted");
|
|
|
- wake_up_interruptible(&cam->wait_stream);
|
|
|
+ wake_up(&cam->wait_stream);
|
|
|
}
|
|
|
|
|
|
if (cam->state & DEV_DISCONNECTED)
|
|
@@ -553,9 +554,9 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
|
|
|
(*f) = list_entry(cam->inqueue.next, struct sn9c102_frame_t,
|
|
|
frame);
|
|
|
|
|
|
- imagesize = (cam->sensor->pix_format.width *
|
|
|
- cam->sensor->pix_format.height *
|
|
|
- cam->sensor->pix_format.priv) / 8;
|
|
|
+ imagesize = (cam->sensor.pix_format.width *
|
|
|
+ cam->sensor.pix_format.height *
|
|
|
+ cam->sensor.pix_format.priv) / 8;
|
|
|
|
|
|
soflen = (cam->bridge) == BRIDGE_SN9C103 ?
|
|
|
sizeof(sn9c103_sof_header_t) :
|
|
@@ -579,7 +580,7 @@ static void sn9c102_urb_complete(struct urb *urb, struct pt_regs* regs)
|
|
|
|
|
|
redo:
|
|
|
sof = sn9c102_find_sof_header(cam, pos, len);
|
|
|
- if (!sof) {
|
|
|
+ if (likely(!sof)) {
|
|
|
eof = sn9c102_find_eof_header(cam, pos, len);
|
|
|
if ((*f)->state == F_GRABBING) {
|
|
|
end_of_frame:
|
|
@@ -589,8 +590,9 @@ end_of_frame:
|
|
|
img = (eof > pos) ? eof - pos - 1 : 0;
|
|
|
|
|
|
if ((*f)->buf.bytesused+img > imagesize) {
|
|
|
- u32 b = (*f)->buf.bytesused + img -
|
|
|
- imagesize;
|
|
|
+ u32 b;
|
|
|
+ b = (*f)->buf.bytesused + img -
|
|
|
+ imagesize;
|
|
|
img = imagesize - (*f)->buf.bytesused;
|
|
|
DBG(3, "Expected EOF not found: "
|
|
|
"video frame cut");
|
|
@@ -608,9 +610,10 @@ end_of_frame:
|
|
|
(*f)->buf.bytesused += img;
|
|
|
|
|
|
if ((*f)->buf.bytesused == imagesize ||
|
|
|
- (cam->sensor->pix_format.pixelformat ==
|
|
|
+ (cam->sensor.pix_format.pixelformat ==
|
|
|
V4L2_PIX_FMT_SN9C10X && eof)) {
|
|
|
- u32 b = (*f)->buf.bytesused;
|
|
|
+ u32 b;
|
|
|
+ b = (*f)->buf.bytesused;
|
|
|
(*f)->state = F_DONE;
|
|
|
(*f)->buf.sequence= ++cam->frame_count;
|
|
|
spin_lock(&cam->queue_lock);
|
|
@@ -667,7 +670,7 @@ start_of_frame:
|
|
|
if (eof && eof < sof)
|
|
|
goto end_of_frame; /* (1) */
|
|
|
else {
|
|
|
- if (cam->sensor->pix_format.pixelformat ==
|
|
|
+ if (cam->sensor.pix_format.pixelformat ==
|
|
|
V4L2_PIX_FMT_SN9C10X) {
|
|
|
eof = sof - soflen;
|
|
|
goto end_of_frame;
|
|
@@ -808,20 +811,21 @@ static int sn9c102_stop_transfer(struct sn9c102_device* cam)
|
|
|
|
|
|
static int sn9c102_stream_interrupt(struct sn9c102_device* cam)
|
|
|
{
|
|
|
- int err = 0;
|
|
|
+ long timeout;
|
|
|
|
|
|
cam->stream = STREAM_INTERRUPT;
|
|
|
- err = wait_event_timeout(cam->wait_stream,
|
|
|
- (cam->stream == STREAM_OFF) ||
|
|
|
- (cam->state & DEV_DISCONNECTED),
|
|
|
- SN9C102_URB_TIMEOUT);
|
|
|
+ timeout = wait_event_timeout(cam->wait_stream,
|
|
|
+ (cam->stream == STREAM_OFF) ||
|
|
|
+ (cam->state & DEV_DISCONNECTED),
|
|
|
+ SN9C102_URB_TIMEOUT);
|
|
|
if (cam->state & DEV_DISCONNECTED)
|
|
|
return -ENODEV;
|
|
|
- else if (err) {
|
|
|
+ else if (cam->stream != STREAM_OFF) {
|
|
|
cam->state |= DEV_MISCONFIGURED;
|
|
|
- DBG(1, "The camera is misconfigured. To use it, close and "
|
|
|
- "open /dev/video%d again.", cam->v4ldev->minor);
|
|
|
- return err;
|
|
|
+ DBG(1, "URB timeout reached. The camera is misconfigured. "
|
|
|
+ "To use it, close and open /dev/video%d again.",
|
|
|
+ cam->v4ldev->minor);
|
|
|
+ return -EIO;
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -1057,7 +1061,7 @@ static ssize_t sn9c102_show_i2c_val(struct class_device* cd, char* buf)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- if (!(cam->sensor->sysfs_ops & SN9C102_I2C_READ)) {
|
|
|
+ if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) {
|
|
|
mutex_unlock(&sn9c102_sysfs_lock);
|
|
|
return -ENOSYS;
|
|
|
}
|
|
@@ -1094,7 +1098,7 @@ sn9c102_store_i2c_val(struct class_device* cd, const char* buf, size_t len)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
- if (!(cam->sensor->sysfs_ops & SN9C102_I2C_WRITE)) {
|
|
|
+ if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) {
|
|
|
mutex_unlock(&sn9c102_sysfs_lock);
|
|
|
return -ENOSYS;
|
|
|
}
|
|
@@ -1249,7 +1253,7 @@ static void sn9c102_create_sysfs(struct sn9c102_device* cam)
|
|
|
video_device_create_file(v4ldev, &class_device_attr_blue);
|
|
|
video_device_create_file(v4ldev, &class_device_attr_red);
|
|
|
}
|
|
|
- if (cam->sensor && cam->sensor->sysfs_ops) {
|
|
|
+ if (cam->sensor.sysfs_ops) {
|
|
|
video_device_create_file(v4ldev, &class_device_attr_i2c_reg);
|
|
|
video_device_create_file(v4ldev, &class_device_attr_i2c_val);
|
|
|
}
|
|
@@ -1312,7 +1316,7 @@ static int sn9c102_set_scale(struct sn9c102_device* cam, u8 scale)
|
|
|
|
|
|
static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
u8 h_start = (u8)(rect->left - s->cropcap.bounds.left),
|
|
|
v_start = (u8)(rect->top - s->cropcap.bounds.top),
|
|
|
h_size = (u8)(rect->width / 16),
|
|
@@ -1335,7 +1339,7 @@ static int sn9c102_set_crop(struct sn9c102_device* cam, struct v4l2_rect* rect)
|
|
|
|
|
|
static int sn9c102_init(struct sn9c102_device* cam)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_control ctrl;
|
|
|
struct v4l2_queryctrl *qctrl;
|
|
|
struct v4l2_rect* rect;
|
|
@@ -1428,6 +1432,8 @@ static void sn9c102_release_resources(struct sn9c102_device* cam)
|
|
|
video_set_drvdata(cam->v4ldev, NULL);
|
|
|
video_unregister_device(cam->v4ldev);
|
|
|
|
|
|
+ usb_put_dev(cam->usbdev);
|
|
|
+
|
|
|
mutex_unlock(&sn9c102_sysfs_lock);
|
|
|
|
|
|
kfree(cam->control_buffer);
|
|
@@ -1541,6 +1547,7 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
|
|
|
struct sn9c102_device* cam = video_get_drvdata(video_devdata(filp));
|
|
|
struct sn9c102_frame_t* f, * i;
|
|
|
unsigned long lock_flags;
|
|
|
+ long timeout;
|
|
|
int err = 0;
|
|
|
|
|
|
if (mutex_lock_interruptible(&cam->fileop_mutex))
|
|
@@ -1592,20 +1599,22 @@ sn9c102_read(struct file* filp, char __user * buf, size_t count, loff_t* f_pos)
|
|
|
mutex_unlock(&cam->fileop_mutex);
|
|
|
return -EAGAIN;
|
|
|
}
|
|
|
- err = wait_event_interruptible
|
|
|
- ( cam->wait_frame,
|
|
|
- (!list_empty(&cam->outqueue)) ||
|
|
|
- (cam->state & DEV_DISCONNECTED) ||
|
|
|
- (cam->state & DEV_MISCONFIGURED) );
|
|
|
- if (err) {
|
|
|
+ timeout = wait_event_interruptible_timeout
|
|
|
+ ( cam->wait_frame,
|
|
|
+ (!list_empty(&cam->outqueue)) ||
|
|
|
+ (cam->state & DEV_DISCONNECTED) ||
|
|
|
+ (cam->state & DEV_MISCONFIGURED),
|
|
|
+ cam->module_param.frame_timeout *
|
|
|
+ 1000 * msecs_to_jiffies(1) );
|
|
|
+ if (timeout < 0) {
|
|
|
mutex_unlock(&cam->fileop_mutex);
|
|
|
- return err;
|
|
|
+ return timeout;
|
|
|
}
|
|
|
if (cam->state & DEV_DISCONNECTED) {
|
|
|
mutex_unlock(&cam->fileop_mutex);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
- if (cam->state & DEV_MISCONFIGURED) {
|
|
|
+ if (!timeout || (cam->state & DEV_MISCONFIGURED)) {
|
|
|
mutex_unlock(&cam->fileop_mutex);
|
|
|
return -EIO;
|
|
|
}
|
|
@@ -1816,6 +1825,7 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
|
|
|
|
|
|
memset(&i, 0, sizeof(i));
|
|
|
strcpy(i.name, "Camera");
|
|
|
+ i.type = V4L2_INPUT_TYPE_CAMERA;
|
|
|
|
|
|
if (copy_to_user(arg, &i, sizeof(i)))
|
|
|
return -EFAULT;
|
|
@@ -1825,7 +1835,19 @@ sn9c102_vidioc_enuminput(struct sn9c102_device* cam, void __user * arg)
|
|
|
|
|
|
|
|
|
static int
|
|
|
-sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg)
|
|
|
+sn9c102_vidioc_g_input(struct sn9c102_device* cam, void __user * arg)
|
|
|
+{
|
|
|
+ int index = 0;
|
|
|
+
|
|
|
+ if (copy_to_user(arg, &index, sizeof(index)))
|
|
|
+ return -EFAULT;
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static int
|
|
|
+sn9c102_vidioc_s_input(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
int index;
|
|
|
|
|
@@ -1842,7 +1864,7 @@ sn9c102_vidioc_gs_input(struct sn9c102_device* cam, void __user * arg)
|
|
|
static int
|
|
|
sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_queryctrl qc;
|
|
|
u8 i;
|
|
|
|
|
@@ -1864,7 +1886,7 @@ sn9c102_vidioc_query_ctrl(struct sn9c102_device* cam, void __user * arg)
|
|
|
static int
|
|
|
sn9c102_vidioc_g_ctrl(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_control ctrl;
|
|
|
int err = 0;
|
|
|
u8 i;
|
|
@@ -1896,7 +1918,7 @@ exit:
|
|
|
static int
|
|
|
sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_control ctrl;
|
|
|
u8 i;
|
|
|
int err = 0;
|
|
@@ -1909,6 +1931,8 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
|
|
|
|
|
|
for (i = 0; i < ARRAY_SIZE(s->qctrl); i++)
|
|
|
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 ||
|
|
|
ctrl.value > s->qctrl[i].maximum)
|
|
|
return -ERANGE;
|
|
@@ -1931,7 +1955,7 @@ sn9c102_vidioc_s_ctrl(struct sn9c102_device* cam, void __user * arg)
|
|
|
static int
|
|
|
sn9c102_vidioc_cropcap(struct sn9c102_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->pixelaspect.numerator = 1;
|
|
@@ -1947,7 +1971,7 @@ sn9c102_vidioc_cropcap(struct sn9c102_device* cam, void __user * arg)
|
|
|
static int
|
|
|
sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_crop crop = {
|
|
|
.type = V4L2_BUF_TYPE_VIDEO_CAPTURE,
|
|
|
};
|
|
@@ -1964,7 +1988,7 @@ sn9c102_vidioc_g_crop(struct sn9c102_device* cam, void __user * arg)
|
|
|
static int
|
|
|
sn9c102_vidioc_s_crop(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_crop crop;
|
|
|
struct v4l2_rect* rect;
|
|
|
struct v4l2_rect* bounds = &(s->cropcap.bounds);
|
|
@@ -2105,7 +2129,7 @@ static int
|
|
|
sn9c102_vidioc_g_fmt(struct sn9c102_device* cam, void __user * arg)
|
|
|
{
|
|
|
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)))
|
|
|
return -EFAULT;
|
|
@@ -2130,7 +2154,7 @@ static int
|
|
|
sn9c102_vidioc_try_s_fmt(struct sn9c102_device* cam, unsigned int cmd,
|
|
|
void __user * arg)
|
|
|
{
|
|
|
- struct sn9c102_sensor* s = cam->sensor;
|
|
|
+ struct sn9c102_sensor* s = &cam->sensor;
|
|
|
struct v4l2_format format;
|
|
|
struct v4l2_pix_format* pix;
|
|
|
struct v4l2_pix_format* pfmt = &(s->pix_format);
|
|
@@ -2417,7 +2441,7 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
|
|
|
struct v4l2_buffer b;
|
|
|
struct sn9c102_frame_t *f;
|
|
|
unsigned long lock_flags;
|
|
|
- int err = 0;
|
|
|
+ long timeout;
|
|
|
|
|
|
if (copy_from_user(&b, arg, sizeof(b)))
|
|
|
return -EFAULT;
|
|
@@ -2430,16 +2454,18 @@ sn9c102_vidioc_dqbuf(struct sn9c102_device* cam, struct file* filp,
|
|
|
return -EINVAL;
|
|
|
if (filp->f_flags & O_NONBLOCK)
|
|
|
return -EAGAIN;
|
|
|
- err = wait_event_interruptible
|
|
|
- ( cam->wait_frame,
|
|
|
- (!list_empty(&cam->outqueue)) ||
|
|
|
- (cam->state & DEV_DISCONNECTED) ||
|
|
|
- (cam->state & DEV_MISCONFIGURED) );
|
|
|
- if (err)
|
|
|
- return err;
|
|
|
+ timeout = wait_event_interruptible_timeout
|
|
|
+ ( cam->wait_frame,
|
|
|
+ (!list_empty(&cam->outqueue)) ||
|
|
|
+ (cam->state & DEV_DISCONNECTED) ||
|
|
|
+ (cam->state & DEV_MISCONFIGURED),
|
|
|
+ cam->module_param.frame_timeout *
|
|
|
+ 1000 * msecs_to_jiffies(1) );
|
|
|
+ if (timeout < 0)
|
|
|
+ return timeout;
|
|
|
if (cam->state & DEV_DISCONNECTED)
|
|
|
return -ENODEV;
|
|
|
- if (cam->state & DEV_MISCONFIGURED)
|
|
|
+ if (!timeout || (cam->state & DEV_MISCONFIGURED))
|
|
|
return -EIO;
|
|
|
}
|
|
|
|
|
@@ -2571,8 +2597,10 @@ static int sn9c102_ioctl_v4l2(struct inode* inode, struct file* filp,
|
|
|
return sn9c102_vidioc_enuminput(cam, arg);
|
|
|
|
|
|
case VIDIOC_G_INPUT:
|
|
|
+ return sn9c102_vidioc_g_input(cam, arg);
|
|
|
+
|
|
|
case VIDIOC_S_INPUT:
|
|
|
- return sn9c102_vidioc_gs_input(cam, arg);
|
|
|
+ return sn9c102_vidioc_s_input(cam, arg);
|
|
|
|
|
|
case VIDIOC_QUERYCTRL:
|
|
|
return sn9c102_vidioc_query_ctrl(cam, arg);
|
|
@@ -2752,10 +2780,10 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- if (!err && cam->sensor) {
|
|
|
- DBG(2, "%s image sensor detected", cam->sensor->name);
|
|
|
+ if (!err) {
|
|
|
+ DBG(2, "%s image sensor detected", cam->sensor.name);
|
|
|
DBG(3, "Support for %s maintained by %s",
|
|
|
- cam->sensor->name, cam->sensor->maintainer);
|
|
|
+ cam->sensor.name, cam->sensor.maintainer);
|
|
|
} else {
|
|
|
DBG(1, "No supported image sensor detected");
|
|
|
err = -ENODEV;
|
|
@@ -2793,6 +2821,7 @@ sn9c102_usb_probe(struct usb_interface* intf, const struct usb_device_id* id)
|
|
|
DBG(2, "V4L2 device registered as /dev/video%d", cam->v4ldev->minor);
|
|
|
|
|
|
cam->module_param.force_munmap = force_munmap[dev_nr];
|
|
|
+ cam->module_param.frame_timeout = frame_timeout[dev_nr];
|
|
|
|
|
|
dev_nr = (dev_nr < SN9C102_MAX_DEVICES-1) ? dev_nr+1 : 0;
|
|
|
|
|
@@ -2841,7 +2870,8 @@ static void sn9c102_usb_disconnect(struct usb_interface* intf)
|
|
|
sn9c102_stop_transfer(cam);
|
|
|
cam->state |= DEV_DISCONNECTED;
|
|
|
wake_up_interruptible(&cam->wait_frame);
|
|
|
- wake_up_interruptible(&cam->wait_stream);
|
|
|
+ wake_up(&cam->wait_stream);
|
|
|
+ usb_get_dev(cam->usbdev);
|
|
|
} else {
|
|
|
cam->state |= DEV_DISCONNECTED;
|
|
|
sn9c102_release_resources(cam);
|