aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Verkuil <hans.verkuil@cisco.com>2013-03-31 11:54:07 +0200
committerHans Verkuil <hans.verkuil@cisco.com>2013-12-19 10:04:14 +0100
commit0b24aa4bbdb30a502df8b792b9572051e0e4865b (patch)
treec76c52492393b26eec5c514a589536f8fddfe1f8
parenta83af4692a61987bdb34c99d2c0a23b2afb94740 (diff)
tuner ownership 2.tuner
Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com>
-rw-r--r--drivers/media/v4l2-core/v4l2-fh.c32
-rw-r--r--drivers/media/v4l2-core/v4l2-ioctl.c34
-rw-r--r--include/media/v4l2-fh.h2
3 files changed, 67 insertions, 1 deletions
diff --git a/drivers/media/v4l2-core/v4l2-fh.c b/drivers/media/v4l2-core/v4l2-fh.c
index e0a2dc20efcb..47ded4c9d4cd 100644
--- a/drivers/media/v4l2-core/v4l2-fh.c
+++ b/drivers/media/v4l2-core/v4l2-fh.c
@@ -29,6 +29,7 @@
#include <media/v4l2-fh.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
+#include <media/v4l2-device.h>
#include <media/tuner-owners.h>
void v4l2_fh_init(struct v4l2_fh *fh, struct video_device *vdev)
@@ -122,3 +123,34 @@ int v4l2_fh_is_singular(struct v4l2_fh *fh)
return is_singular;
}
EXPORT_SYMBOL_GPL(v4l2_fh_is_singular);
+
+int v4l2_fh_tuner_owners_add(struct v4l2_fh *fh)
+{
+ enum tuner_owner_mode mode;
+ int err;
+
+ if (fh == NULL || fh->tuner_owners)
+ return 0;
+
+ mode = (fh->vdev->vfl_type == VFL_TYPE_RADIO) ?
+ TUNER_OWNER_RADIO : TUNER_OWNER_ANALOG_TV;
+ err = tuner_owners_add(&fh->vdev->v4l2_dev->tuner_owners, mode);
+ if (err)
+ return err;
+ fh->tuner_owners = &fh->vdev->v4l2_dev->tuner_owners;
+ return 0;
+}
+EXPORT_SYMBOL_GPL(v4l2_fh_tuner_owners_add);
+
+bool v4l2_fh_owns_tuner(struct v4l2_fh *fh)
+{
+ enum tuner_owner_mode mode;
+
+ if (fh == NULL || fh->tuner_owners)
+ return true;
+
+ mode = (fh->vdev->vfl_type == VFL_TYPE_RADIO) ?
+ TUNER_OWNER_RADIO : TUNER_OWNER_ANALOG_TV;
+ return fh->vdev->v4l2_dev->tuner_owners.mode == mode;
+}
+EXPORT_SYMBOL_GPL(v4l2_fh_owns_tuner);
diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
index 68e6b5e912ff..c3cd74b599a4 100644
--- a/drivers/media/v4l2-core/v4l2-ioctl.c
+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
@@ -1263,10 +1263,16 @@ static int v4l_s_tuner(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct video_device *vfd = video_devdata(file);
+ struct v4l2_fh *vfh =
+ test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
struct v4l2_tuner *p = arg;
+ int err;
p->type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
+ err = v4l2_fh_tuner_owners_add(vfh);
+ if (err)
+ return err;
return ops->vidioc_s_tuner(file, fh, p);
}
@@ -1282,6 +1288,20 @@ static int v4l_g_modulator(const struct v4l2_ioctl_ops *ops,
return err;
}
+static int v4l_s_modulator(const struct v4l2_ioctl_ops *ops,
+ struct file *file, void *fh, void *arg)
+{
+ struct video_device *vfd = video_devdata(file);
+ struct v4l2_fh *vfh =
+ test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
+ int err;
+
+ err = v4l2_fh_tuner_owners_add(vfh);
+ if (err)
+ return err;
+ return ops->vidioc_s_modulator(file, fh, arg);
+}
+
static int v4l_g_frequency(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
@@ -1298,12 +1318,18 @@ static int v4l_s_frequency(const struct v4l2_ioctl_ops *ops,
{
struct video_device *vfd = video_devdata(file);
const struct v4l2_frequency *p = arg;
+ struct v4l2_fh *vfh =
+ test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
enum v4l2_tuner_type type;
+ int err;
type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
if (p->type != type)
return -EINVAL;
+ err = v4l2_fh_tuner_owners_add(vfh);
+ if (err)
+ return err;
return ops->vidioc_s_frequency(file, fh, p);
}
@@ -1380,13 +1406,19 @@ static int v4l_s_hw_freq_seek(const struct v4l2_ioctl_ops *ops,
struct file *file, void *fh, void *arg)
{
struct video_device *vfd = video_devdata(file);
+ struct v4l2_fh *vfh =
+ test_bit(V4L2_FL_USES_V4L2_FH, &vfd->flags) ? fh : NULL;
struct v4l2_hw_freq_seek *p = arg;
enum v4l2_tuner_type type;
+ int err;
type = (vfd->vfl_type == VFL_TYPE_RADIO) ?
V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
if (p->type != type)
return -EINVAL;
+ err = v4l2_fh_tuner_owners_add(vfh);
+ if (err)
+ return err;
return ops->vidioc_s_hw_freq_seek(file, fh, p);
}
@@ -2012,7 +2044,7 @@ static struct v4l2_ioctl_info v4l2_ioctls[] = {
IOCTL_INFO_STD(VIDIOC_G_AUDOUT, vidioc_g_audout, v4l_print_audioout, 0),
IOCTL_INFO_STD(VIDIOC_S_AUDOUT, vidioc_s_audout, v4l_print_audioout, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_G_MODULATOR, v4l_g_modulator, v4l_print_modulator, INFO_FL_CLEAR(v4l2_modulator, index)),
- IOCTL_INFO_STD(VIDIOC_S_MODULATOR, vidioc_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
+ IOCTL_INFO_FNC(VIDIOC_S_MODULATOR, v4l_s_modulator, v4l_print_modulator, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_G_FREQUENCY, v4l_g_frequency, v4l_print_frequency, INFO_FL_CLEAR(v4l2_frequency, tuner)),
IOCTL_INFO_FNC(VIDIOC_S_FREQUENCY, v4l_s_frequency, v4l_print_frequency, INFO_FL_PRIO),
IOCTL_INFO_FNC(VIDIOC_CROPCAP, v4l_cropcap, v4l_print_cropcap, INFO_FL_CLEAR(v4l2_cropcap, type)),
diff --git a/include/media/v4l2-fh.h b/include/media/v4l2-fh.h
index d39ab7854eea..5cd0a1a86c53 100644
--- a/include/media/v4l2-fh.h
+++ b/include/media/v4l2-fh.h
@@ -105,5 +105,7 @@ static inline int v4l2_fh_is_singular_file(struct file *filp)
{
return v4l2_fh_is_singular(filp->private_data);
}
+int v4l2_fh_tuner_owners_add(struct v4l2_fh *fh);
+bool v4l2_fh_owns_tuner(struct v4l2_fh *fh);
#endif /* V4L2_EVENT_H */

Privacy Policy