summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/media/usb/usbvision
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/media/usb/usbvision')
-rw-r--r--kernel/drivers/media/usb/usbvision/usbvision-core.c75
-rw-r--r--kernel/drivers/media/usb/usbvision/usbvision-i2c.c2
-rw-r--r--kernel/drivers/media/usb/usbvision/usbvision-video.c263
-rw-r--r--kernel/drivers/media/usb/usbvision/usbvision.h10
4 files changed, 118 insertions, 232 deletions
diff --git a/kernel/drivers/media/usb/usbvision/usbvision-core.c b/kernel/drivers/media/usb/usbvision/usbvision-core.c
index 44b0c28d6..dc3b4d515 100644
--- a/kernel/drivers/media/usb/usbvision/usbvision-core.c
+++ b/kernel/drivers/media/usb/usbvision/usbvision-core.c
@@ -1367,7 +1367,7 @@ static void usbvision_isoc_irq(struct urb *urb)
int usbvision_read_reg(struct usb_usbvision *usbvision, unsigned char reg)
{
int err_code = 0;
- unsigned char buffer[1];
+ unsigned char *buffer = usbvision->ctrl_urb_buffer;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return -1;
@@ -1401,10 +1401,12 @@ int usbvision_write_reg(struct usb_usbvision *usbvision, unsigned char reg,
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
+ usbvision->ctrl_urb_buffer[0] = value;
err_code = usb_control_msg(usbvision->dev, usb_sndctrlpipe(usbvision->dev, 1),
USBVISION_OP_CODE,
USB_DIR_OUT | USB_TYPE_VENDOR |
- USB_RECIP_ENDPOINT, 0, (__u16) reg, &value, 1, HZ);
+ USB_RECIP_ENDPOINT, 0, (__u16) reg,
+ usbvision->ctrl_urb_buffer, 1, HZ);
if (err_code < 0) {
dev_err(&usbvision->dev->dev,
@@ -1596,7 +1598,7 @@ static int usbvision_init_webcam(struct usb_usbvision *usbvision)
{ 0x27, 0x00, 0x00 }, { 0x28, 0x00, 0x00 }, { 0x29, 0x00, 0x00 }, { 0x08, 0x80, 0x60 },
{ 0x0f, 0x2d, 0x24 }, { 0x0c, 0x80, 0x80 }
};
- char value[3];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
/* the only difference between PAL and NTSC init_values */
if (usbvision_device_data[usbvision->dev_model].video_norm == V4L2_STD_NTSC)
@@ -1635,8 +1637,8 @@ static int usbvision_init_webcam(struct usb_usbvision *usbvision)
static int usbvision_set_video_format(struct usb_usbvision *usbvision, int format)
{
static const char proc[] = "usbvision_set_video_format";
+ unsigned char *value = usbvision->ctrl_urb_buffer;
int rc;
- unsigned char value[2];
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
@@ -1677,7 +1679,7 @@ int usbvision_set_output(struct usb_usbvision *usbvision, int width,
int err_code = 0;
int usb_width, usb_height;
unsigned int frame_rate = 0, frame_drop = 0;
- unsigned char value[4];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
if (!USBVISION_IS_OPERATIONAL(usbvision))
return 0;
@@ -1789,10 +1791,6 @@ int usbvision_frames_alloc(struct usb_usbvision *usbvision, int number_of_frames
usbvision->num_frames--;
}
- spin_lock_init(&usbvision->queue_lock);
- init_waitqueue_head(&usbvision->wait_frame);
- init_waitqueue_head(&usbvision->wait_stream);
-
/* Allocate all buffers */
for (i = 0; i < usbvision->num_frames; i++) {
usbvision->frame[i].index = i;
@@ -1872,7 +1870,7 @@ static int usbvision_set_compress_params(struct usb_usbvision *usbvision)
{
static const char proc[] = "usbvision_set_compresion_params: ";
int rc;
- unsigned char value[6];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
value[0] = 0x0F; /* Intra-Compression cycle */
value[1] = 0x01; /* Reg.45 one line per strip */
@@ -1946,7 +1944,7 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
{
static const char proc[] = "usbvision_set_input: ";
int rc;
- unsigned char value[8];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
unsigned char dvi_yuv_value;
if (!USBVISION_IS_OPERATIONAL(usbvision))
@@ -2062,8 +2060,8 @@ int usbvision_set_input(struct usb_usbvision *usbvision)
static int usbvision_set_dram_settings(struct usb_usbvision *usbvision)
{
+ unsigned char *value = usbvision->ctrl_urb_buffer;
int rc;
- unsigned char value[8];
if (usbvision->isoc_mode == ISOC_MODE_COMPRESS) {
value[0] = 0x42;
@@ -2161,55 +2159,6 @@ int usbvision_power_on(struct usb_usbvision *usbvision)
/*
- * usbvision timer stuff
- */
-
-/* to call usbvision_power_off from task queue */
-static void call_usbvision_power_off(struct work_struct *work)
-{
- struct usb_usbvision *usbvision = container_of(work, struct usb_usbvision, power_off_work);
-
- PDEBUG(DBG_FUNC, "");
- if (mutex_lock_interruptible(&usbvision->v4l2_lock))
- return;
-
- if (usbvision->user == 0) {
- usbvision_i2c_unregister(usbvision);
-
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- mutex_unlock(&usbvision->v4l2_lock);
-}
-
-static void usbvision_power_off_timer(unsigned long data)
-{
- struct usb_usbvision *usbvision = (void *)data;
-
- PDEBUG(DBG_FUNC, "");
- del_timer(&usbvision->power_off_timer);
- INIT_WORK(&usbvision->power_off_work, call_usbvision_power_off);
- (void) schedule_work(&usbvision->power_off_work);
-}
-
-void usbvision_init_power_off_timer(struct usb_usbvision *usbvision)
-{
- setup_timer(&usbvision->power_off_timer, usbvision_power_off_timer,
- (unsigned long)usbvision);
-}
-
-void usbvision_set_power_off_timer(struct usb_usbvision *usbvision)
-{
- mod_timer(&usbvision->power_off_timer, jiffies + USBVISION_POWEROFF_TIME);
-}
-
-void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision)
-{
- if (timer_pending(&usbvision->power_off_timer))
- del_timer(&usbvision->power_off_timer);
-}
-
-/*
* usbvision_begin_streaming()
* Sure you have to put bit 7 to 0, if not incoming frames are droped, but no
* idea about the rest
@@ -2390,8 +2339,8 @@ int usbvision_init_isoc(struct usb_usbvision *usbvision)
/* Submit all URBs */
for (buf_idx = 0; buf_idx < USBVISION_NUMSBUF; buf_idx++) {
- err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb,
- GFP_KERNEL);
+ err_code = usb_submit_urb(usbvision->sbuf[buf_idx].urb,
+ GFP_KERNEL);
if (err_code) {
dev_err(&usbvision->dev->dev,
"%s: usb_submit_urb(%d) failed: error %d\n",
diff --git a/kernel/drivers/media/usb/usbvision/usbvision-i2c.c b/kernel/drivers/media/usb/usbvision/usbvision-i2c.c
index 26dbcb114..120de2e02 100644
--- a/kernel/drivers/media/usb/usbvision/usbvision-i2c.c
+++ b/kernel/drivers/media/usb/usbvision/usbvision-i2c.c
@@ -343,7 +343,7 @@ static int usbvision_i2c_write_max4(struct usb_usbvision *usbvision,
{
int rc, retries;
int i;
- unsigned char value[6];
+ unsigned char *value = usbvision->ctrl_urb_buffer;
unsigned char ser_cont;
ser_cont = (len & 0x07) | 0x10;
diff --git a/kernel/drivers/media/usb/usbvision/usbvision-video.c b/kernel/drivers/media/usb/usbvision/usbvision-video.c
index 12b403e78..b693206f6 100644
--- a/kernel/drivers/media/usb/usbvision/usbvision-video.c
+++ b/kernel/drivers/media/usb/usbvision/usbvision-video.c
@@ -62,6 +62,7 @@
#include <media/saa7115.h>
#include <media/v4l2-common.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-event.h>
#include <media/tuner.h>
#include <linux/workqueue.h>
@@ -122,8 +123,6 @@ static void usbvision_release(struct usb_usbvision *usbvision);
static int isoc_mode = ISOC_MODE_COMPRESS;
/* Set the default Debug Mode of the device driver */
static int video_debug;
-/* Set the default device to power on at startup */
-static int power_on_at_open = 1;
/* Sequential Number of Video Device */
static int video_nr = -1;
/* Sequential Number of Radio Device */
@@ -134,13 +133,11 @@ static int radio_nr = -1;
/* Showing parameters under SYSFS */
module_param(isoc_mode, int, 0444);
module_param(video_debug, int, 0444);
-module_param(power_on_at_open, int, 0444);
module_param(video_nr, int, 0444);
module_param(radio_nr, int, 0444);
MODULE_PARM_DESC(isoc_mode, " Set the default format for ISOC endpoint. Default: 0x60 (Compression On)");
MODULE_PARM_DESC(video_debug, " Set the default Debug Mode of the device driver. Default: 0 (Off)");
-MODULE_PARM_DESC(power_on_at_open, " Set the default device to power on when device is opened. Default: 1 (On)");
MODULE_PARM_DESC(video_nr, "Set video device number (/dev/videoX). Default: -1 (autodetect)");
MODULE_PARM_DESC(radio_nr, "Set radio device number (/dev/radioX). Default: -1 (autodetect)");
@@ -351,11 +348,14 @@ static int usbvision_v4l2_open(struct file *file)
if (mutex_lock_interruptible(&usbvision->v4l2_lock))
return -ERESTARTSYS;
- usbvision_reset_power_off_timer(usbvision);
- if (usbvision->user)
+ if (usbvision->user) {
err_code = -EBUSY;
- else {
+ } else {
+ err_code = v4l2_fh_open(file);
+ if (err_code)
+ goto unlock;
+
/* Allocate memory for the scratch ring buffer */
err_code = usbvision_scratch_alloc(usbvision);
if (isoc_mode == ISOC_MODE_COMPRESS) {
@@ -372,11 +372,6 @@ static int usbvision_v4l2_open(struct file *file)
/* If so far no errors then we shall start the camera */
if (!err_code) {
- if (usbvision->power == 0) {
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
-
/* Send init sequence only once, it's large! */
if (!usbvision->initialized) {
int setup_ok = 0;
@@ -392,18 +387,14 @@ static int usbvision_v4l2_open(struct file *file)
err_code = usbvision_init_isoc(usbvision);
/* device must be initialized before isoc transfer */
usbvision_muxsel(usbvision, 0);
+
+ /* prepare queues */
+ usbvision_empty_framequeues(usbvision);
usbvision->user++;
- } else {
- if (power_on_at_open) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
}
}
- /* prepare queues */
- usbvision_empty_framequeues(usbvision);
+unlock:
mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
@@ -435,23 +426,16 @@ static int usbvision_v4l2_close(struct file *file)
usbvision_scratch_free(usbvision);
usbvision->user--;
-
- if (power_on_at_open) {
- /* power off in a little while
- to avoid off/on every close/open short sequences */
- usbvision_set_power_off_timer(usbvision);
- usbvision->initialized = 0;
- }
+ mutex_unlock(&usbvision->v4l2_lock);
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
usbvision_release(usbvision);
return 0;
}
- mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
- return 0;
+ return v4l2_fh_release(file);
}
@@ -503,18 +487,24 @@ static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *vc)
{
struct usb_usbvision *usbvision = video_drvdata(file);
+ struct video_device *vdev = video_devdata(file);
strlcpy(vc->driver, "USBVision", sizeof(vc->driver));
strlcpy(vc->card,
usbvision_device_data[usbvision->dev_model].model_string,
sizeof(vc->card));
usb_make_path(usbvision->dev, vc->bus_info, sizeof(vc->bus_info));
- vc->device_caps = V4L2_CAP_VIDEO_CAPTURE |
- V4L2_CAP_AUDIO |
- V4L2_CAP_READWRITE |
- V4L2_CAP_STREAMING |
- (usbvision->have_tuner ? V4L2_CAP_TUNER : 0);
- vc->capabilities = vc->device_caps | V4L2_CAP_DEVICE_CAPS;
+ vc->device_caps = usbvision->have_tuner ? V4L2_CAP_TUNER : 0;
+ if (vdev->vfl_type == VFL_TYPE_GRABBER)
+ vc->device_caps |= V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE | V4L2_CAP_STREAMING;
+ else
+ vc->device_caps |= V4L2_CAP_RADIO;
+
+ vc->capabilities = vc->device_caps | V4L2_CAP_VIDEO_CAPTURE |
+ V4L2_CAP_READWRITE | V4L2_CAP_STREAMING | V4L2_CAP_DEVICE_CAPS;
+ if (usbvision_device_data[usbvision->dev_model].radio)
+ vc->capabilities |= V4L2_CAP_RADIO;
return 0;
}
@@ -540,7 +530,6 @@ static int vidioc_enum_input(struct file *file, void *priv,
} else {
strcpy(vi->name, "Television");
vi->type = V4L2_INPUT_TYPE_TUNER;
- vi->audioset = 1;
vi->tuner = chan;
vi->std = USBVISION_NORMS;
}
@@ -551,7 +540,7 @@ static int vidioc_enum_input(struct file *file, void *priv,
strcpy(vi->name, "Green Video Input");
else
strcpy(vi->name, "Composite Video Input");
- vi->std = V4L2_STD_PAL;
+ vi->std = USBVISION_NORMS;
break;
case 2:
vi->type = V4L2_INPUT_TYPE_CAMERA;
@@ -559,12 +548,12 @@ static int vidioc_enum_input(struct file *file, void *priv,
strcpy(vi->name, "Yellow Video Input");
else
strcpy(vi->name, "S-Video Input");
- vi->std = V4L2_STD_PAL;
+ vi->std = USBVISION_NORMS;
break;
case 3:
vi->type = V4L2_INPUT_TYPE_CAMERA;
strcpy(vi->name, "Red Video Input");
- vi->std = V4L2_STD_PAL;
+ vi->std = USBVISION_NORMS;
break;
}
return 0;
@@ -619,14 +608,13 @@ static int vidioc_g_tuner(struct file *file, void *priv,
{
struct usb_usbvision *usbvision = video_drvdata(file);
- if (!usbvision->have_tuner || vt->index) /* Only tuner 0 */
+ if (vt->index) /* Only tuner 0 */
return -EINVAL;
- if (usbvision->radio) {
+ if (vt->type == V4L2_TUNER_RADIO)
strcpy(vt->name, "Radio");
- vt->type = V4L2_TUNER_RADIO;
- } else {
+ else
strcpy(vt->name, "Television");
- }
+
/* Let clients fill in the remainder of this struct */
call_all(usbvision, tuner, g_tuner, vt);
@@ -638,8 +626,8 @@ static int vidioc_s_tuner(struct file *file, void *priv,
{
struct usb_usbvision *usbvision = video_drvdata(file);
- /* Only no or one tuner for now */
- if (!usbvision->have_tuner || vt->index)
+ /* Only one tuner for now */
+ if (vt->index)
return -EINVAL;
/* let clients handle this */
call_all(usbvision, tuner, s_tuner, vt);
@@ -652,12 +640,13 @@ static int vidioc_g_frequency(struct file *file, void *priv,
{
struct usb_usbvision *usbvision = video_drvdata(file);
- freq->tuner = 0; /* Only one tuner */
- if (usbvision->radio)
- freq->type = V4L2_TUNER_RADIO;
+ /* Only one tuner */
+ if (freq->tuner)
+ return -EINVAL;
+ if (freq->type == V4L2_TUNER_RADIO)
+ freq->frequency = usbvision->radio_freq;
else
- freq->type = V4L2_TUNER_ANALOG_TV;
- freq->frequency = usbvision->freq;
+ freq->frequency = usbvision->tv_freq;
return 0;
}
@@ -666,68 +655,22 @@ static int vidioc_s_frequency(struct file *file, void *priv,
const struct v4l2_frequency *freq)
{
struct usb_usbvision *usbvision = video_drvdata(file);
+ struct v4l2_frequency new_freq = *freq;
- /* Only no or one tuner for now */
- if (!usbvision->have_tuner || freq->tuner)
+ /* Only one tuner for now */
+ if (freq->tuner)
return -EINVAL;
- usbvision->freq = freq->frequency;
call_all(usbvision, tuner, s_frequency, freq);
-
- return 0;
-}
-
-static int vidioc_g_audio(struct file *file, void *priv, struct v4l2_audio *a)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- if (usbvision->radio)
- strcpy(a->name, "Radio");
+ call_all(usbvision, tuner, g_frequency, &new_freq);
+ if (freq->type == V4L2_TUNER_RADIO)
+ usbvision->radio_freq = new_freq.frequency;
else
- strcpy(a->name, "TV");
+ usbvision->tv_freq = new_freq.frequency;
return 0;
}
-static int vidioc_s_audio(struct file *file, void *fh,
- const struct v4l2_audio *a)
-{
- if (a->index)
- return -EINVAL;
- return 0;
-}
-
-static int vidioc_queryctrl(struct file *file, void *priv,
- struct v4l2_queryctrl *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, queryctrl, ctrl);
-
- if (!ctrl->type)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, g_ctrl, ctrl);
- return 0;
-}
-
-static int vidioc_s_ctrl(struct file *file, void *priv,
- struct v4l2_control *ctrl)
-{
- struct usb_usbvision *usbvision = video_drvdata(file);
-
- call_all(usbvision, core, s_ctrl, ctrl);
- return 0;
-}
-
static int vidioc_reqbufs(struct file *file,
void *priv, struct v4l2_requestbuffers *vr)
{
@@ -937,6 +880,8 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
vf->fmt.pix.bytesperline = vf->fmt.pix.width*
usbvision->palette.bytes_per_pixel;
vf->fmt.pix.sizeimage = vf->fmt.pix.bytesperline*vf->fmt.pix.height;
+ vf->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
+ vf->fmt.pix.field = V4L2_FIELD_NONE; /* Always progressive image */
return 0;
}
@@ -1061,13 +1006,24 @@ static ssize_t usbvision_read(struct file *file, char __user *buf,
__func__,
(unsigned long)count, frame->bytes_read);
- /* For now, forget the frame if it has not been read in one shot. */
-/* if (frame->bytes_read >= frame->scanlength) {*/ /* All data has been read */
+#if 1
+ /*
+ * FIXME:
+ * For now, forget the frame if it has not been read in one shot.
+ */
+ frame->bytes_read = 0;
+
+ /* Mark it as available to be used again. */
+ frame->grabstate = frame_state_unused;
+#else
+ if (frame->bytes_read >= frame->scanlength) {
+ /* All data has been read */
frame->bytes_read = 0;
/* Mark it as available to be used again. */
frame->grabstate = frame_state_unused;
-/* } */
+ }
+#endif
return count;
}
@@ -1156,20 +1112,15 @@ static int usbvision_radio_open(struct file *file)
if (mutex_lock_interruptible(&usbvision->v4l2_lock))
return -ERESTARTSYS;
+ err_code = v4l2_fh_open(file);
+ if (err_code)
+ goto out;
if (usbvision->user) {
dev_err(&usbvision->rdev.dev,
"%s: Someone tried to open an already opened USBVision Radio!\n",
__func__);
err_code = -EBUSY;
} else {
- if (power_on_at_open) {
- usbvision_reset_power_off_timer(usbvision);
- if (usbvision->power == 0) {
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
- }
-
/* Alternate interface 1 is is the biggest frame size */
err_code = usbvision_set_alternate(usbvision);
if (err_code < 0) {
@@ -1184,14 +1135,6 @@ static int usbvision_radio_open(struct file *file)
usbvision_set_audio(usbvision, USBVISION_AUDIO_RADIO);
usbvision->user++;
}
-
- if (err_code) {
- if (power_on_at_open) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- usbvision->initialized = 0;
- }
- }
out:
mutex_unlock(&usbvision->v4l2_lock);
return err_code;
@@ -1201,34 +1144,29 @@ out:
static int usbvision_radio_close(struct file *file)
{
struct usb_usbvision *usbvision = video_drvdata(file);
- int err_code = 0;
PDEBUG(DBG_IO, "");
mutex_lock(&usbvision->v4l2_lock);
/* Set packet size to 0 */
usbvision->iface_alt = 0;
- err_code = usb_set_interface(usbvision->dev, usbvision->iface,
+ usb_set_interface(usbvision->dev, usbvision->iface,
usbvision->iface_alt);
usbvision_audio_off(usbvision);
usbvision->radio = 0;
usbvision->user--;
- if (power_on_at_open) {
- usbvision_set_power_off_timer(usbvision);
- usbvision->initialized = 0;
- }
-
if (usbvision->remove_pending) {
printk(KERN_INFO "%s: Final disconnect\n", __func__);
+ v4l2_fh_release(file);
usbvision_release(usbvision);
- return err_code;
+ return 0;
}
mutex_unlock(&usbvision->v4l2_lock);
PDEBUG(DBG_IO, "success");
- return err_code;
+ return v4l2_fh_release(file);
}
/* Video registration stuff */
@@ -1241,7 +1179,6 @@ static const struct v4l2_file_operations usbvision_fops = {
.read = usbvision_v4l2_read,
.mmap = usbvision_v4l2_mmap,
.unlocked_ioctl = video_ioctl2,
-/* .poll = video_poll, */
};
static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
@@ -1259,17 +1196,15 @@ static const struct v4l2_ioctl_ops usbvision_ioctl_ops = {
.vidioc_enum_input = vidioc_enum_input,
.vidioc_g_input = vidioc_g_input,
.vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_streamon = vidioc_streamon,
.vidioc_streamoff = vidioc_streamoff,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
#ifdef CONFIG_VIDEO_ADV_DEBUG
.vidioc_g_register = vidioc_g_register,
.vidioc_s_register = vidioc_s_register,
@@ -1290,23 +1225,19 @@ static const struct v4l2_file_operations usbvision_radio_fops = {
.owner = THIS_MODULE,
.open = usbvision_radio_open,
.release = usbvision_radio_close,
+ .poll = v4l2_ctrl_poll,
.unlocked_ioctl = video_ioctl2,
};
static const struct v4l2_ioctl_ops usbvision_radio_ioctl_ops = {
.vidioc_querycap = vidioc_querycap,
- .vidioc_enum_input = vidioc_enum_input,
- .vidioc_g_input = vidioc_g_input,
- .vidioc_s_input = vidioc_s_input,
- .vidioc_queryctrl = vidioc_queryctrl,
- .vidioc_g_audio = vidioc_g_audio,
- .vidioc_s_audio = vidioc_s_audio,
- .vidioc_g_ctrl = vidioc_g_ctrl,
- .vidioc_s_ctrl = vidioc_s_ctrl,
.vidioc_g_tuner = vidioc_g_tuner,
.vidioc_s_tuner = vidioc_s_tuner,
.vidioc_g_frequency = vidioc_g_frequency,
.vidioc_s_frequency = vidioc_s_frequency,
+ .vidioc_log_status = v4l2_ctrl_log_status,
+ .vidioc_subscribe_event = v4l2_ctrl_subscribe_event,
+ .vidioc_unsubscribe_event = v4l2_event_unsubscribe,
};
static struct video_device usbvision_radio_template = {
@@ -1358,9 +1289,17 @@ static void usbvision_unregister_video(struct usb_usbvision *usbvision)
/* register video4linux devices */
static int usbvision_register_video(struct usb_usbvision *usbvision)
{
+ int res = -ENOMEM;
+
/* Video Device: */
usbvision_vdev_init(usbvision, &usbvision->vdev,
&usbvision_video_template, "USBVision Video");
+ if (!usbvision->have_tuner) {
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_G_FREQUENCY);
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_S_TUNER);
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_G_FREQUENCY);
+ v4l2_disable_ioctl(&usbvision->vdev, VIDIOC_S_TUNER);
+ }
if (video_register_device(&usbvision->vdev, VFL_TYPE_GRABBER, video_nr) < 0)
goto err_exit;
printk(KERN_INFO "USBVision[%d]: registered USBVision Video device %s [v4l2]\n",
@@ -1384,7 +1323,7 @@ static int usbvision_register_video(struct usb_usbvision *usbvision)
"USBVision[%d]: video_register_device() failed\n",
usbvision->nr);
usbvision_unregister_video(usbvision);
- return -1;
+ return res;
}
/*
@@ -1409,6 +1348,9 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
if (v4l2_device_register(&intf->dev, &usbvision->v4l2_dev))
goto err_free;
+ if (v4l2_ctrl_handler_init(&usbvision->hdl, 4))
+ goto err_unreg;
+ usbvision->v4l2_dev.ctrl_handler = &usbvision->hdl;
mutex_init(&usbvision->v4l2_lock);
/* prepare control urb for control messages during interrupts */
@@ -1417,11 +1359,10 @@ static struct usb_usbvision *usbvision_alloc(struct usb_device *dev,
goto err_unreg;
init_waitqueue_head(&usbvision->ctrl_urb_wq);
- usbvision_init_power_off_timer(usbvision);
-
return usbvision;
err_unreg:
+ v4l2_ctrl_handler_free(&usbvision->hdl);
v4l2_device_unregister(&usbvision->v4l2_dev);
err_free:
kfree(usbvision);
@@ -1439,8 +1380,6 @@ static void usbvision_release(struct usb_usbvision *usbvision)
{
PDEBUG(DBG_PROBE, "");
- usbvision_reset_power_off_timer(usbvision);
-
usbvision->initialized = 0;
usbvision_remove_sysfs(&usbvision->vdev);
@@ -1449,6 +1388,7 @@ static void usbvision_release(struct usb_usbvision *usbvision)
usb_free_urb(usbvision->ctrl_urb);
+ v4l2_ctrl_handler_free(&usbvision->hdl);
v4l2_device_unregister(&usbvision->v4l2_dev);
kfree(usbvision);
@@ -1476,19 +1416,18 @@ static void usbvision_configure_video(struct usb_usbvision *usbvision)
}
usbvision->tvnorm_id = usbvision_device_data[model].video_norm;
-
usbvision->video_inputs = usbvision_device_data[model].video_channels;
usbvision->ctl_input = 0;
+ usbvision->radio_freq = 87.5 * 16000;
+ usbvision->tv_freq = 400 * 16;
/* This should be here to make i2c clients to be able to register */
/* first switch off audio */
if (usbvision_device_data[model].audio_channels > 0)
usbvision_audio_off(usbvision);
- if (!power_on_at_open) {
- /* and then power up the noisy tuner */
- usbvision_power_on(usbvision);
- usbvision_i2c_register(usbvision);
- }
+ /* and then power up the tuner */
+ usbvision_power_on(usbvision);
+ usbvision_i2c_register(usbvision);
}
/*
@@ -1581,6 +1520,10 @@ static int usbvision_probe(struct usb_interface *intf,
usbvision->nr = usbvision_nr++;
+ spin_lock_init(&usbvision->queue_lock);
+ init_waitqueue_head(&usbvision->wait_frame);
+ init_waitqueue_head(&usbvision->wait_stream);
+
usbvision->have_tuner = usbvision_device_data[model].tuner;
if (usbvision->have_tuner)
usbvision->tuner_type = usbvision_device_data[model].tuner_type;
@@ -1635,11 +1578,7 @@ static void usbvision_disconnect(struct usb_interface *intf)
usbvision_stop_isoc(usbvision);
v4l2_device_disconnect(&usbvision->v4l2_dev);
-
- if (usbvision->power) {
- usbvision_i2c_unregister(usbvision);
- usbvision_power_off(usbvision);
- }
+ usbvision_i2c_unregister(usbvision);
usbvision->remove_pending = 1; /* Now all ISO data will be ignored */
usb_put_dev(usbvision->dev);
diff --git a/kernel/drivers/media/usb/usbvision/usbvision.h b/kernel/drivers/media/usb/usbvision/usbvision.h
index 140a1f675..4f2e4fde3 100644
--- a/kernel/drivers/media/usb/usbvision/usbvision.h
+++ b/kernel/drivers/media/usb/usbvision/usbvision.h
@@ -36,6 +36,7 @@
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <media/v4l2-device.h>
+#include <media/v4l2-ctrls.h>
#include <media/tuner.h>
#include <linux/videodev2.h>
@@ -357,6 +358,7 @@ extern struct usb_device_id usbvision_table[];
struct usb_usbvision {
struct v4l2_device v4l2_dev;
+ struct v4l2_ctrl_handler hdl;
struct video_device vdev; /* Video Device */
struct video_device rdev; /* Radio Device */
@@ -376,7 +378,8 @@ struct usb_usbvision {
int bridge_type; /* NT1003, NT1004, NT1005 */
int radio;
int video_inputs; /* # of inputs */
- unsigned long freq;
+ unsigned long radio_freq;
+ unsigned long tv_freq;
int audio_mute;
int audio_channel;
int isoc_mode; /* format of video data for the usb isoc-transfer */
@@ -391,8 +394,6 @@ struct usb_usbvision {
unsigned char iface_alt; /* Alt settings */
unsigned char vin_reg2_preset;
struct mutex v4l2_lock;
- struct timer_list power_off_timer;
- struct work_struct power_off_work;
int power; /* is the device powered on? */
int user; /* user count for exclusive use */
int initialized; /* Had we already sent init sequence? */
@@ -510,9 +511,6 @@ int usbvision_muxsel(struct usb_usbvision *usbvision, int channel);
int usbvision_set_input(struct usb_usbvision *usbvision);
int usbvision_set_output(struct usb_usbvision *usbvision, int width, int height);
-void usbvision_init_power_off_timer(struct usb_usbvision *usbvision);
-void usbvision_set_power_off_timer(struct usb_usbvision *usbvision);
-void usbvision_reset_power_off_timer(struct usb_usbvision *usbvision);
int usbvision_power_off(struct usb_usbvision *usbvision);
int usbvision_power_on(struct usb_usbvision *usbvision);