The patch number 10887 was added via Hans Verkuil <[email protected]>
to http://linuxtv.org/hg/v4l-dvb master development tree.
Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel
If anyone has any objections, please let us know by sending a message to:
Linux Media Mailing List <[email protected]>
------
From: Hans Verkuil <[email protected]>
radio-rtrack2: convert to v4l2_device.
Priority: normal
Signed-off-by: Hans Verkuil <[email protected]>
---
linux/drivers/media/radio/radio-rtrack2.c | 360 ++++++++++------------
1 file changed, 170 insertions(+), 190 deletions(-)
diff -r d46a567e0304 -r 1dcad62e9b10 linux/drivers/media/radio/radio-rtrack2.c
--- a/linux/drivers/media/radio/radio-rtrack2.c Fri Mar 06 17:51:33 2009 +0100
+++ b/linux/drivers/media/radio/radio-rtrack2.c Fri Mar 06 17:52:06 2009 +0100
@@ -13,35 +13,18 @@
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* request_region */
#include <linux/delay.h> /* udelay */
-#include <asm/io.h> /* outb, outb_p */
-#include <asm/uaccess.h> /* copy to/from user */
+#include <linux/videodev2.h> /* kernel radio structs */
+#include <linux/mutex.h>
+#include <linux/version.h> /* for KERNEL_VERSION MACRO */
+#include <linux/io.h> /* outb, outb_p */
+#include <linux/uaccess.h> /* copy to/from user */
+#include <media/v4l2-device.h>
+#include <media/v4l2-ioctl.h>
#include "compat.h"
-#include <linux/videodev2.h> /* kernel radio structs */
-#include <media/v4l2-common.h>
-#include <media/v4l2-ioctl.h>
-#include <linux/spinlock.h>
-
-#include <linux/version.h> /* for KERNEL_VERSION MACRO */
-#define RADIO_VERSION KERNEL_VERSION(0,0,2)
-
-static struct v4l2_queryctrl radio_qctrl[] = {
- {
- .id = V4L2_CID_AUDIO_MUTE,
- .name = "Mute",
- .minimum = 0,
- .maximum = 1,
- .default_value = 1,
- .type = V4L2_CTRL_TYPE_BOOLEAN,
- },{
- .id = V4L2_CID_AUDIO_VOLUME,
- .name = "Volume",
- .minimum = 0,
- .maximum = 65535,
- .step = 65535,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+
+MODULE_AUTHOR("Ben Pfaff");
+MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_LICENSE("GPL");
#ifndef CONFIG_RADIO_RTRACK2_PORT
#define CONFIG_RADIO_RTRACK2_PORT -1
@@ -49,79 +32,89 @@ static struct v4l2_queryctrl radio_qctrl
static int io = CONFIG_RADIO_RTRACK2_PORT;
static int radio_nr = -1;
-static spinlock_t lock;
-
-struct rt_device
-{
- unsigned long in_use;
- int port;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct rtrack2
+{
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
unsigned long curfreq;
int muted;
+ struct mutex lock;
};
+static struct rtrack2 rtrack2_card;
+
/* local things */
-static void rt_mute(struct rt_device *dev)
-{
- if(dev->muted)
+static void rt_mute(struct rtrack2 *dev)
+{
+ if (dev->muted)
return;
- spin_lock(&lock);
- outb(1, io);
- spin_unlock(&lock);
+ mutex_lock(&dev->lock);
+ outb(1, dev->io);
+ mutex_unlock(&dev->lock);
+ mutex_unlock(&dev->lock);
dev->muted = 1;
}
-static void rt_unmute(struct rt_device *dev)
+static void rt_unmute(struct rtrack2 *dev)
{
if(dev->muted == 0)
return;
- spin_lock(&lock);
- outb(0, io);
- spin_unlock(&lock);
+ mutex_lock(&dev->lock);
+ outb(0, dev->io);
+ mutex_unlock(&dev->lock);
dev->muted = 0;
}
-static void zero(void)
-{
- outb_p(1, io);
- outb_p(3, io);
- outb_p(1, io);
-}
-
-static void one(void)
-{
- outb_p(5, io);
- outb_p(7, io);
- outb_p(5, io);
-}
-
-static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+static void zero(struct rtrack2 *dev)
+{
+ outb_p(1, dev->io);
+ outb_p(3, dev->io);
+ outb_p(1, dev->io);
+}
+
+static void one(struct rtrack2 *dev)
+{
+ outb_p(5, dev->io);
+ outb_p(7, dev->io);
+ outb_p(5, dev->io);
+}
+
+static int rt_setfreq(struct rtrack2 *dev, unsigned long freq)
{
int i;
+ mutex_lock(&dev->lock);
+ dev->curfreq = freq;
freq = freq / 200 + 856;
- spin_lock(&lock);
-
- outb_p(0xc8, io);
- outb_p(0xc9, io);
- outb_p(0xc9, io);
+ outb_p(0xc8, dev->io);
+ outb_p(0xc9, dev->io);
+ outb_p(0xc9, dev->io);
for (i = 0; i < 10; i++)
- zero ();
+ zero(dev);
for (i = 14; i >= 0; i--)
if (freq & (1 << i))
- one ();
- else
- zero ();
-
- outb_p(0xc8, io);
+ one(dev);
+ else
+ zero(dev);
+
+ outb_p(0xc8, dev->io);
if (!dev->muted)
- outb_p(0, io);
-
- spin_unlock(&lock);
+ outb_p(0, dev->io);
+
+ mutex_unlock(&dev->lock);
return 0;
}
@@ -130,61 +123,61 @@ static int vidioc_querycap(struct file *
{
strlcpy(v->driver, "radio-rtrack2", sizeof(v->driver));
strlcpy(v->card, "RadioTrack II", sizeof(v->card));
- sprintf(v->bus_info, "ISA");
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
return 0;
}
static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
+ return v->index ? -EINVAL : 0;
+}
+
+static int rt_getsigstr(struct rtrack2 *dev)
+{
+ int sig = 1;
+
+ mutex_lock(&dev->lock);
+ if (inb(dev->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&dev->lock);
+ return sig;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+ struct v4l2_tuner *v)
+{
+ struct rtrack2 *rt = video_drvdata(file);
+
if (v->index > 0)
return -EINVAL;
- return 0;
-}
-
-static int rt_getsigstr(struct rt_device *dev)
-{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-static int vidioc_g_tuner(struct file *file, void *priv,
- struct v4l2_tuner *v)
-{
- struct rt_device *rt = video_drvdata(file);
-
- if (v->index > 0)
- return -EINVAL;
-
- strcpy(v->name, "FM");
+ strlcpy(v->name, "FM", sizeof(v->name));
v->type = V4L2_TUNER_RADIO;
- v->rangelow = (88*16000);
- v->rangehigh = (108*16000);
+ v->rangelow = 88 * 16000;
+ v->rangehigh = 108 * 16000;
v->rxsubchans = V4L2_TUNER_SUB_MONO;
v->capability = V4L2_TUNER_CAP_LOW;
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal = 0xFFFF*rt_getsigstr(rt);
+ v->signal = 0xFFFF * rt_getsigstr(rt);
return 0;
}
static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
-
- rt->curfreq = f->frequency;
- rt_setfreq(rt, rt->curfreq);
+ struct rtrack2 *rt = video_drvdata(file);
+
+ rt_setfreq(rt, f->frequency);
return 0;
}
static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = rt->curfreq;
@@ -194,14 +187,11 @@ static int vidioc_queryctrl(struct file
static int vidioc_queryctrl(struct file *file, void *priv,
struct v4l2_queryctrl *qc)
{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) {
- if (qc->id && qc->id == radio_qctrl[i].id) {
- memcpy(qc, &(radio_qctrl[i]),
- sizeof(*qc));
- return 0;
- }
+ switch (qc->id) {
+ case V4L2_CID_AUDIO_MUTE:
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 1);
+ case V4L2_CID_AUDIO_VOLUME:
+ return v4l2_ctrl_query_fill(qc, 0, 65535, 65535, 65535);
}
return -EINVAL;
}
@@ -209,7 +199,7 @@ static int vidioc_g_ctrl(struct file *fi
static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -228,7 +218,7 @@ static int vidioc_s_ctrl(struct file *fi
static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct rt_device *rt = video_drvdata(file);
+ struct rtrack2 *rt = video_drvdata(file);
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
@@ -247,55 +237,46 @@ static int vidioc_s_ctrl(struct file *fi
return -EINVAL;
}
+static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
+{
+ *i = 0;
+ return 0;
+}
+
+static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
+{
+ return i ? -EINVAL : 0;
+}
+
static int vidioc_g_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index > 1)
- return -EINVAL;
-
- strcpy(a->name, "Radio");
+ a->index = 0;
+ strlcpy(a->name, "Radio", sizeof(a->name));
a->capability = V4L2_AUDCAP_STEREO;
- return 0;
-}
-
-static int vidioc_g_input(struct file *filp, void *priv, unsigned int *i)
-{
- *i = 0;
- return 0;
-}
-
-static int vidioc_s_input(struct file *filp, void *priv, unsigned int i)
-{
- if (i != 0)
- return -EINVAL;
return 0;
}
static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
- return 0;
-}
-
-static struct rt_device rtrack2_unit;
-
-static int rtrack2_exclusive_open(struct file *file)
-{
- return test_and_set_bit(0, &rtrack2_unit.in_use) ? -EBUSY : 0;
-}
-
-static int rtrack2_exclusive_release(struct file *file)
-{
- clear_bit(0, &rtrack2_unit.in_use);
+ return a->index ? -EINVAL : 0;
+}
+
+static int rtrack2_open(struct file *file)
+{
+ return 0;
+}
+
+static int rtrack2_release(struct file *file)
+{
return 0;
}
static const struct v4l2_file_operations rtrack2_fops = {
.owner = THIS_MODULE,
- .open = rtrack2_exclusive_open,
- .release = rtrack2_exclusive_release,
+ .open = rtrack2_open,
+ .release = rtrack2_release,
.ioctl = video_ioctl2,
};
@@ -314,62 +295,61 @@ static const struct v4l2_ioctl_ops rtrac
.vidioc_s_input = vidioc_s_input,
};
-static struct video_device rtrack2_radio = {
- .name = "RadioTrack II radio",
- .fops = &rtrack2_fops,
- .ioctl_ops = &rtrack2_ioctl_ops,
- .release = video_device_release_empty,
-};
-
static int __init rtrack2_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x20c or
io=0x30c\n");
+ struct rtrack2 *dev = &rtrack2_card;
+ struct v4l2_device *v4l2_dev = &dev->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "rtrack2", sizeof(v4l2_dev->name));
+ dev->io = io;
+ if (dev->io == -1) {
+ v4l2_err(v4l2_dev, "You must set an I/O address with io=0x20c
or io=0x30c\n");
return -EINVAL;
}
- if (!request_region(io, 4, "rtrack2"))
- {
- printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
+ if (!request_region(dev->io, 4, "rtrack2")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", dev->io);
return -EBUSY;
}
- video_set_drvdata(&rtrack2_radio, &rtrack2_unit);
-
- spin_lock_init(&lock);
- if (video_register_device(&rtrack2_radio, VFL_TYPE_RADIO, radio_nr) <
0) {
- release_region(io, 4);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(dev->io, 4);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+ dev->vdev.v4l2_dev = v4l2_dev;
+ dev->vdev.fops = &rtrack2_fops;
+ dev->vdev.ioctl_ops = &rtrack2_ioctl_ops;
+ dev->vdev.release = video_device_release_empty;
+ video_set_drvdata(&dev->vdev, dev);
+
+ mutex_init(&dev->lock);
+ if (video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(dev->io, 4);
return -EINVAL;
}
- printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
+ v4l2_info(v4l2_dev, "AIMSlab Radiotrack II card driver.\n");
/* mute card - prevents noisy bootups */
- outb(1, io);
- rtrack2_unit.muted = 1;
-
- return 0;
-}
-
-MODULE_AUTHOR("Ben Pfaff");
-MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit rtrack2_cleanup_module(void)
-{
- video_unregister_device(&rtrack2_radio);
- release_region(io,4);
+ outb(1, dev->io);
+ dev->muted = 1;
+
+ return 0;
+}
+
+static void __exit rtrack2_exit(void)
+{
+ struct rtrack2 *dev = &rtrack2_card;
+
+ video_unregister_device(&dev->vdev);
+ v4l2_device_unregister(&dev->v4l2_dev);
+ release_region(dev->io, 4);
}
module_init(rtrack2_init);
-module_exit(rtrack2_cleanup_module);
-
-/*
- Local variables:
- compile-command: "mmake"
- End:
-*/
+module_exit(rtrack2_exit);
---
Patch is available at:
http://linuxtv.org/hg/v4l-dvb/rev/1dcad62e9b104df6c16736dc6fb28e355ff52259
_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits