The patch number 10881 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-aztech: convert to v4l2_device.
Priority: normal
Signed-off-by: Hans Verkuil <[email protected]>
---
linux/drivers/media/radio/radio-aztech.c | 489 +++++++++++------------
1 file changed, 236 insertions(+), 253 deletions(-)
diff -r 63dd17f7d015 -r 362267a9a1bc linux/drivers/media/radio/radio-aztech.c
--- a/linux/drivers/media/radio/radio-aztech.c Fri Mar 06 17:45:27 2009 +0100
+++ b/linux/drivers/media/radio/radio-aztech.c Fri Mar 06 17:48:18 2009 +0100
@@ -29,34 +29,17 @@
#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/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/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 = 0xff,
- .step = 1,
- .default_value = 0xff,
- .type = V4L2_CTRL_TYPE_INTEGER,
- }
-};
+
+MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott
McGrath, William McGrath");
+MODULE_DESCRIPTION("A driver for the Aztech radio card.");
+MODULE_LICENSE("GPL");
/* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */
@@ -67,55 +50,64 @@ static int io = CONFIG_RADIO_AZTECH_PORT
static int io = CONFIG_RADIO_AZTECH_PORT;
static int radio_nr = -1;
static int radio_wait_time = 1000;
-static struct mutex lock;
-
-struct az_device
-{
- unsigned long in_use;
+
+module_param(io, int, 0);
+module_param(radio_nr, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct aztech
+{
+ struct v4l2_device v4l2_dev;
+ struct video_device vdev;
+ int io;
int curvol;
unsigned long curfreq;
int stereo;
+ struct mutex lock;
};
+static struct aztech aztech_card;
+
static int volconvert(int level)
{
- level>>=14; /* Map 16bits down to 2 bit */
- level&=3;
+ level >>= 14; /* Map 16bits down to 2 bit */
+ level &= 3;
/* convert to card-friendly values */
- switch (level)
- {
- case 0:
- return 0;
- case 1:
- return 1;
- case 2:
- return 4;
- case 3:
- return 5;
+ switch (level) {
+ case 0:
+ return 0;
+ case 1:
+ return 1;
+ case 2:
+ return 4;
+ case 3:
+ return 5;
}
return 0; /* Quieten gcc */
}
-static void send_0_byte (struct az_device *dev)
+static void send_0_byte(struct aztech *az)
{
udelay(radio_wait_time);
- outb_p(2+volconvert(dev->curvol), io);
- outb_p(64+2+volconvert(dev->curvol), io);
-}
-
-static void send_1_byte (struct az_device *dev)
+ outb_p(2 + volconvert(az->curvol), az->io);
+ outb_p(64 + 2 + volconvert(az->curvol), az->io);
+}
+
+static void send_1_byte(struct aztech *az)
{
udelay (radio_wait_time);
- outb_p(128+2+volconvert(dev->curvol), io);
- outb_p(128+64+2+volconvert(dev->curvol), io);
-}
-
-static int az_setvol(struct az_device *dev, int vol)
-{
- mutex_lock(&lock);
- outb (volconvert(vol), io);
- mutex_unlock(&lock);
+ outb_p(128 + 2 + volconvert(az->curvol), az->io);
+ outb_p(128 + 64 + 2 + volconvert(az->curvol), az->io);
+}
+
+static int az_setvol(struct aztech *az, int vol)
+{
+ mutex_lock(&az->lock);
+ outb(volconvert(vol), az->io);
+ mutex_unlock(&az->lock);
return 0;
}
@@ -127,233 +119,221 @@ static int az_setvol(struct az_device *d
*
*/
-static int az_getsigstr(struct az_device *dev)
-{
- if (inb(io) & 2) /* bit set = no signal present */
- return 0;
- return 1; /* signal present */
-}
-
-static int az_getstereo(struct az_device *dev)
-{
- if (inb(io) & 1) /* bit set = mono */
- return 0;
- return 1; /* stereo */
-}
-
-static int az_setfreq(struct az_device *dev, unsigned long frequency)
+static int az_getsigstr(struct aztech *az)
+{
+ int sig = 1;
+
+ mutex_lock(&az->lock);
+ if (inb(az->io) & 2) /* bit set = no signal present */
+ sig = 0;
+ mutex_unlock(&az->lock);
+ return sig;
+}
+
+static int az_getstereo(struct aztech *az)
+{
+ int stereo = 1;
+
+ mutex_lock(&az->lock);
+ if (inb(az->io) & 1) /* bit set = mono */
+ stereo = 0;
+ mutex_unlock(&az->lock);
+ return stereo;
+}
+
+static int az_setfreq(struct aztech *az, unsigned long frequency)
{
int i;
+ mutex_lock(&az->lock);
+
+ az->curfreq = frequency;
frequency += 171200; /* Add 10.7 MHz IF */
frequency /= 800; /* Convert to 50 kHz units */
- mutex_lock(&lock);
-
- send_0_byte (dev); /* 0: LSB of frequency */
+ send_0_byte(az); /* 0: LSB of frequency */
for (i = 0; i < 13; i++) /* : frequency bits (1-13) */
if (frequency & (1 << i))
- send_1_byte (dev);
+ send_1_byte(az);
else
- send_0_byte (dev);
-
- send_0_byte (dev); /* 14: test bit - always 0 */
- send_0_byte (dev); /* 15: test bit - always 0 */
- send_0_byte (dev); /* 16: band data 0 - always 0 */
- if (dev->stereo) /* 17: stereo (1 to enable) */
- send_1_byte (dev);
+ send_0_byte(az);
+
+ send_0_byte(az); /* 14: test bit - always 0 */
+ send_0_byte(az); /* 15: test bit - always 0 */
+ send_0_byte(az); /* 16: band data 0 - always 0 */
+ if (az->stereo) /* 17: stereo (1 to enable) */
+ send_1_byte(az);
else
- send_0_byte (dev);
-
- send_1_byte (dev); /* 18: band data 1 - unknown */
- send_0_byte (dev); /* 19: time base - always 0 */
- send_0_byte (dev); /* 20: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 21: spacing (1 = 25 kHz) */
- send_0_byte (dev); /* 22: spacing (0 = 25 kHz) */
- send_1_byte (dev); /* 23: AM/FM (FM = 1, always) */
+ send_0_byte(az);
+
+ send_1_byte(az); /* 18: band data 1 - unknown */
+ send_0_byte(az); /* 19: time base - always 0 */
+ send_0_byte(az); /* 20: spacing (0 = 25 kHz) */
+ send_1_byte(az); /* 21: spacing (1 = 25 kHz) */
+ send_0_byte(az); /* 22: spacing (0 = 25 kHz) */
+ send_1_byte(az); /* 23: AM/FM (FM = 1, always) */
/* latch frequency */
- udelay (radio_wait_time);
- outb_p(128+64+volconvert(dev->curvol), io);
-
- mutex_unlock(&lock);
-
- return 0;
-}
-
-static int vidioc_querycap (struct file *file, void *priv,
+ udelay(radio_wait_time);
+ outb_p(128 + 64 + volconvert(az->curvol), az->io);
+
+ mutex_unlock(&az->lock);
+
+ return 0;
+}
+
+static int vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *v)
{
- strlcpy(v->driver, "radio-aztech", sizeof (v->driver));
- strlcpy(v->card, "Aztech Radio", sizeof (v->card));
- sprintf(v->bus_info,"ISA");
+ strlcpy(v->driver, "radio-aztech", sizeof(v->driver));
+ strlcpy(v->card, "Aztech Radio", sizeof(v->card));
+ strlcpy(v->bus_info, "ISA", sizeof(v->bus_info));
v->version = RADIO_VERSION;
- v->capabilities = V4L2_CAP_TUNER;
- return 0;
-}
-
-static int vidioc_g_tuner (struct file *file, void *priv,
+ v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO;
+ return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = 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=(87*16000);
- v->rangehigh=(108*16000);
- v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
- v->capability=V4L2_TUNER_CAP_LOW;
- if(az_getstereo(az))
+ v->rangelow = 87 * 16000;
+ v->rangehigh = 108 * 16000;
+ v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
+ v->capability = V4L2_TUNER_CAP_LOW;
+ if (az_getstereo(az))
v->audmode = V4L2_TUNER_MODE_STEREO;
else
v->audmode = V4L2_TUNER_MODE_MONO;
- v->signal=0xFFFF*az_getsigstr(az);
-
- return 0;
-}
-
-
-static int vidioc_s_tuner (struct file *file, void *priv,
+ v->signal = 0xFFFF * az_getsigstr(az);
+
+ return 0;
+}
+
+static int vidioc_s_tuner(struct file *file, void *priv,
struct v4l2_tuner *v)
{
- if (v->index > 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_g_audio (struct file *file, void *priv,
+ return v->index ? -EINVAL : 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)
+{
+ 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,
+static int vidioc_s_audio(struct file *file, void *priv,
struct v4l2_audio *a)
{
- if (a->index != 0)
- return -EINVAL;
-
- return 0;
-}
-
-static int vidioc_s_frequency (struct file *file, void *priv,
+ return a->index ? -EINVAL : 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct az_device *az = video_drvdata(file);
-
- az->curfreq = f->frequency;
- az_setfreq(az, az->curfreq);
- return 0;
-}
-
-static int vidioc_g_frequency (struct file *file, void *priv,
+ struct aztech *az = video_drvdata(file);
+
+ az_setfreq(az, f->frequency);
+ return 0;
+}
+
+static int vidioc_g_frequency(struct file *file, void *priv,
struct v4l2_frequency *f)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
f->type = V4L2_TUNER_RADIO;
f->frequency = az->curfreq;
-
- return 0;
-}
-
-static int vidioc_queryctrl (struct file *file, void *priv,
+ return 0;
+}
+
+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, 0xff, 1, 0xff);
}
return -EINVAL;
}
-static int vidioc_g_ctrl (struct file *file, void *priv,
+static int vidioc_g_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (az->curvol==0)
- ctrl->value=1;
- else
- ctrl->value=0;
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value=az->curvol * 6554;
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ if (az->curvol == 0)
+ ctrl->value = 1;
+ else
+ ctrl->value = 0;
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = az->curvol * 6554;
+ return 0;
}
return -EINVAL;
}
-static int vidioc_s_ctrl (struct file *file, void *priv,
+static int vidioc_s_ctrl(struct file *file, void *priv,
struct v4l2_control *ctrl)
{
- struct az_device *az = video_drvdata(file);
+ struct aztech *az = video_drvdata(file);
switch (ctrl->id) {
- case V4L2_CID_AUDIO_MUTE:
- if (ctrl->value) {
- az_setvol(az,0);
- } else {
- az_setvol(az,az->curvol);
- }
- return (0);
- case V4L2_CID_AUDIO_VOLUME:
- az_setvol(az,ctrl->value);
- return (0);
+ case V4L2_CID_AUDIO_MUTE:
+ if (ctrl->value)
+ az_setvol(az, 0);
+ else
+ az_setvol(az, az->curvol);
+ return 0;
+ case V4L2_CID_AUDIO_VOLUME:
+ az_setvol(az, ctrl->value);
+ return 0;
}
return -EINVAL;
}
-static struct az_device aztech_unit;
-
-static int aztech_exclusive_open(struct file *file)
-{
- return test_and_set_bit(0, &aztech_unit.in_use) ? -EBUSY : 0;
-}
-
-static int aztech_exclusive_release(struct file *file)
-{
- clear_bit(0, &aztech_unit.in_use);
+static int aztech_open(struct file *file)
+{
+ return 0;
+}
+
+static int aztech_release(struct file *file)
+{
return 0;
}
static const struct v4l2_file_operations aztech_fops = {
.owner = THIS_MODULE,
- .open = aztech_exclusive_open,
- .release = aztech_exclusive_release,
+ .open = aztech_open,
+ .release = aztech_release,
.ioctl = video_ioctl2,
};
@@ -372,57 +352,60 @@ static const struct v4l2_ioctl_ops aztec
.vidioc_s_ctrl = vidioc_s_ctrl,
};
-static struct video_device aztech_radio = {
- .name = "Aztech radio",
- .fops = &aztech_fops,
- .ioctl_ops = &aztech_ioctl_ops,
- .release = video_device_release_empty,
-};
-
-module_param_named(debug,aztech_radio.debug, int, 0644);
-MODULE_PARM_DESC(debug,"activates debug info");
-
static int __init aztech_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
+ struct aztech *az = &aztech_card;
+ struct v4l2_device *v4l2_dev = &az->v4l2_dev;
+ int res;
+
+ strlcpy(v4l2_dev->name, "aztech", sizeof(v4l2_dev->name));
+ az->io = io;
+
+ if (az->io == -1) {
+ v4l2_err(v4l2_dev, "you must set an I/O address with
io=0x???\n");
return -EINVAL;
}
- if (!request_region(io, 2, "aztech"))
- {
- printk(KERN_ERR "aztech: port 0x%x already in use\n", io);
+ if (!request_region(az->io, 2, "aztech")) {
+ v4l2_err(v4l2_dev, "port 0x%x already in use\n", az->io);
return -EBUSY;
}
- mutex_init(&lock);
- video_set_drvdata(&aztech_radio, &aztech_unit);
-
- if (video_register_device(&aztech_radio, VFL_TYPE_RADIO, radio_nr) < 0)
{
- release_region(io,2);
+ res = v4l2_device_register(NULL, v4l2_dev);
+ if (res < 0) {
+ release_region(az->io, 2);
+ v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+ return res;
+ }
+
+ mutex_init(&az->lock);
+ strlcpy(az->vdev.name, v4l2_dev->name, sizeof(az->vdev.name));
+ az->vdev.v4l2_dev = v4l2_dev;
+ az->vdev.fops = &aztech_fops;
+ az->vdev.ioctl_ops = &aztech_ioctl_ops;
+ az->vdev.release = video_device_release_empty;
+ video_set_drvdata(&az->vdev, az);
+
+ if (video_register_device(&az->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+ v4l2_device_unregister(v4l2_dev);
+ release_region(az->io, 2);
return -EINVAL;
}
- printk(KERN_INFO "Aztech radio card driver v1.00/19990224
[email protected]\n");
+ v4l2_info(v4l2_dev, "Aztech radio card driver v1.00/19990224
[email protected]\n");
/* mute card - prevents noisy bootups */
- outb (0, io);
- return 0;
-}
-
-MODULE_AUTHOR("Russell Kroll, Quay Lu, Donald Song, Jason Lewis, Scott
McGrath, William McGrath");
-MODULE_DESCRIPTION("A driver for the Aztech radio card.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-module_param(radio_nr, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Aztech card (0x350 or 0x358)");
-
-static void __exit aztech_cleanup(void)
-{
- video_unregister_device(&aztech_radio);
- release_region(io,2);
+ outb(0, az->io);
+ return 0;
+}
+
+static void __exit aztech_exit(void)
+{
+ struct aztech *az = &aztech_card;
+
+ video_unregister_device(&az->vdev);
+ v4l2_device_unregister(&az->v4l2_dev);
+ release_region(az->io, 2);
}
module_init(aztech_init);
-module_exit(aztech_cleanup);
+module_exit(aztech_exit);
---
Patch is available at:
http://linuxtv.org/hg/v4l-dvb/rev/362267a9a1bc01b080b4ba998768db871c279df5
_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits