The patch number 10893 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-zoltrix: convert to v4l2_device.


Priority: normal

Signed-off-by: Hans Verkuil <[email protected]>


---

 linux/drivers/media/radio/radio-zoltrix.c |  495 ++++++++++------------
 1 file changed, 236 insertions(+), 259 deletions(-)

diff -r ef2edf459255 -r 9bfa3ce24ab0 linux/drivers/media/radio/radio-zoltrix.c
--- a/linux/drivers/media/radio/radio-zoltrix.c Fri Mar 06 17:54:52 2009 +0100
+++ b/linux/drivers/media/radio/radio-zoltrix.c Fri Mar 06 17:55:34 2009 +0100
@@ -33,34 +33,18 @@
 #include <linux/init.h>                /* Initdata                       */
 #include <linux/ioport.h>      /* request_region                 */
 #include <linux/delay.h>       /* udelay, msleep                 */
-#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/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          = 4096,
-               .default_value = 0xff,
-               .type          = V4L2_CTRL_TYPE_INTEGER,
-       }
-};
+
+MODULE_AUTHOR("C.van Schaik");
+MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
+MODULE_LICENSE("GPL");
 
 #ifndef CONFIG_RADIO_ZOLTRIX_PORT
 #define CONFIG_RADIO_ZOLTRIX_PORT -1
@@ -69,9 +53,16 @@ static int io = CONFIG_RADIO_ZOLTRIX_POR
 static int io = CONFIG_RADIO_ZOLTRIX_PORT;
 static int radio_nr = -1;
 
-struct zol_device {
-       unsigned long in_use;
-       int port;
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct zoltrix {
+       struct v4l2_device v4l2_dev;
+       struct video_device vdev;
+       int io;
        int curvol;
        unsigned long curfreq;
        int muted;
@@ -79,161 +70,158 @@ struct zol_device {
        struct mutex lock;
 };
 
-static int zol_setvol(struct zol_device *dev, int vol)
-{
-       dev->curvol = vol;
-       if (dev->muted)
-               return 0;
-
-       mutex_lock(&dev->lock);
+static struct zoltrix zoltrix_card;
+
+static int zol_setvol(struct zoltrix *zol, int vol)
+{
+       zol->curvol = vol;
+       if (zol->muted)
+               return 0;
+
+       mutex_lock(&zol->lock);
        if (vol == 0) {
-               outb(0, io);
-               outb(0, io);
-               inb(io + 3);    /* Zoltrix needs to be read to confirm */
-               mutex_unlock(&dev->lock);
-               return 0;
-       }
-
-       outb(dev->curvol-1, io);
+               outb(0, zol->io);
+               outb(0, zol->io);
+               inb(zol->io + 3);    /* Zoltrix needs to be read to confirm */
+               mutex_unlock(&zol->lock);
+               return 0;
+       }
+
+       outb(zol->curvol-1, zol->io);
        msleep(10);
-       inb(io + 2);
-       mutex_unlock(&dev->lock);
-       return 0;
-}
-
-static void zol_mute(struct zol_device *dev)
-{
-       dev->muted = 1;
-       mutex_lock(&dev->lock);
-       outb(0, io);
-       outb(0, io);
-       inb(io + 3);            /* Zoltrix needs to be read to confirm */
-       mutex_unlock(&dev->lock);
-}
-
-static void zol_unmute(struct zol_device *dev)
-{
-       dev->muted = 0;
-       zol_setvol(dev, dev->curvol);
-}
-
-static int zol_setfreq(struct zol_device *dev, unsigned long freq)
+       inb(zol->io + 2);
+       mutex_unlock(&zol->lock);
+       return 0;
+}
+
+static void zol_mute(struct zoltrix *zol)
+{
+       zol->muted = 1;
+       mutex_lock(&zol->lock);
+       outb(0, zol->io);
+       outb(0, zol->io);
+       inb(zol->io + 3);            /* Zoltrix needs to be read to confirm */
+       mutex_unlock(&zol->lock);
+}
+
+static void zol_unmute(struct zoltrix *zol)
+{
+       zol->muted = 0;
+       zol_setvol(zol, zol->curvol);
+}
+
+static int zol_setfreq(struct zoltrix *zol, unsigned long freq)
 {
        /* tunes the radio to the desired frequency */
+       struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
        unsigned long long bitmask, f, m;
-       unsigned int stereo = dev->stereo;
+       unsigned int stereo = zol->stereo;
        int i;
 
        if (freq == 0) {
-               printk(KERN_WARNING "zoltrix: received zero freq. Failed to 
set.\n");
+               v4l2_warn(v4l2_dev, "cannot set a frequency of 0.\n");
                return -EINVAL;
        }
 
        m = (freq / 160 - 8800) * 2;
-       f = (unsigned long long) m + 0x4d1c;
+       f = (unsigned long long)m + 0x4d1c;
 
        bitmask = 0xc480402c10080000ull;
        i = 45;
 
-       mutex_lock(&dev->lock);
-
-       outb(0, io);
-       outb(0, io);
-       inb(io + 3);            /* Zoltrix needs to be read to confirm */
-
-       outb(0x40, io);
-       outb(0xc0, io);
-
-       bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ ( 
stereo << 31));
+       mutex_lock(&zol->lock);
+
+       zol->curfreq = freq;
+
+       outb(0, zol->io);
+       outb(0, zol->io);
+       inb(zol->io + 3);            /* Zoltrix needs to be read to confirm */
+
+       outb(0x40, zol->io);
+       outb(0xc0, zol->io);
+
+       bitmask = (bitmask ^ ((f & 0xff) << 47) ^ ((f & 0xff00) << 30) ^ 
(stereo << 31));
        while (i--) {
                if ((bitmask & 0x8000000000000000ull) != 0) {
-                       outb(0x80, io);
-                       udelay(50);
-                       outb(0x00, io);
-                       udelay(50);
-                       outb(0x80, io);
+                       outb(0x80, zol->io);
+                       udelay(50);
+                       outb(0x00, zol->io);
+                       udelay(50);
+                       outb(0x80, zol->io);
                        udelay(50);
                } else {
-                       outb(0xc0, io);
-                       udelay(50);
-                       outb(0x40, io);
-                       udelay(50);
-                       outb(0xc0, io);
+                       outb(0xc0, zol->io);
+                       udelay(50);
+                       outb(0x40, zol->io);
+                       udelay(50);
+                       outb(0xc0, zol->io);
                        udelay(50);
                }
                bitmask *= 2;
        }
        /* termination sequence */
-       outb(0x80, io);
-       outb(0xc0, io);
-       outb(0x40, io);
+       outb(0x80, zol->io);
+       outb(0xc0, zol->io);
+       outb(0x40, zol->io);
        udelay(1000);
-       inb(io+2);
+       inb(zol->io + 2);
 
        udelay(1000);
 
-       if (dev->muted)
-       {
-               outb(0, io);
-               outb(0, io);
-               inb(io + 3);
+       if (zol->muted) {
+               outb(0, zol->io);
+               outb(0, zol->io);
+               inb(zol->io + 3);
                udelay(1000);
        }
 
-       mutex_unlock(&dev->lock);
-
-       if(!dev->muted)
-       {
-               zol_setvol(dev, dev->curvol);
-       }
+       mutex_unlock(&zol->lock);
+
+       if (!zol->muted)
+               zol_setvol(zol, zol->curvol);
        return 0;
 }
 
 /* Get signal strength */
-
-static int zol_getsigstr(struct zol_device *dev)
+static int zol_getsigstr(struct zoltrix *zol)
 {
        int a, b;
 
-       mutex_lock(&dev->lock);
-       outb(0x00, io);         /* This stuff I found to do nothing */
-       outb(dev->curvol, io);
+       mutex_lock(&zol->lock);
+       outb(0x00, zol->io);         /* This stuff I found to do nothing */
+       outb(zol->curvol, zol->io);
        msleep(20);
 
-       a = inb(io);
+       a = inb(zol->io);
        msleep(10);
-       b = inb(io);
-
-       mutex_unlock(&dev->lock);
+       b = inb(zol->io);
+
+       mutex_unlock(&zol->lock);
 
        if (a != b)
-               return (0);
-
-       if ((a == 0xcf) || (a == 0xdf)  /* I found this out by playing */
-               || (a == 0xef))       /* with a binary scanner on the card io */
-               return (1);
-       return (0);
-}
-
-static int zol_is_stereo (struct zol_device *dev)
+               return 0;
+
+       /* I found this out by playing with a binary scanner on the card io */
+       return a == 0xcf || a == 0xdf || a == 0xef;
+}
+
+static int zol_is_stereo(struct zoltrix *zol)
 {
        int x1, x2;
 
-       mutex_lock(&dev->lock);
-
-       outb(0x00, io);
-       outb(dev->curvol, io);
+       mutex_lock(&zol->lock);
+
+       outb(0x00, zol->io);
+       outb(zol->curvol, zol->io);
        msleep(20);
 
-       x1 = inb(io);
+       x1 = inb(zol->io);
        msleep(10);
-       x2 = inb(io);
-
-       mutex_unlock(&dev->lock);
-
-       if ((x1 == x2) && (x1 == 0xcf))
-               return 1;
-       return 0;
+       x2 = inb(zol->io);
+
+       mutex_unlock(&zol->lock);
+
+       return x1 == x2 && x1 == 0xcf;
 }
 
 static int vidioc_querycap(struct file *file, void  *priv,
@@ -241,59 +229,54 @@ static int vidioc_querycap(struct file *
 {
        strlcpy(v->driver, "radio-zoltrix", sizeof(v->driver));
        strlcpy(v->card, "Zoltrix Radio", 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_g_tuner(struct file *file, void *priv,
                                        struct v4l2_tuner *v)
 {
-       struct zol_device *zol = video_drvdata(file);
+       struct zoltrix *zol = 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->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+       v->rangelow = 88 * 16000;
+       v->rangehigh = 108 * 16000;
+       v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
        v->capability = V4L2_TUNER_CAP_LOW;
        if (zol_is_stereo(zol))
                v->audmode = V4L2_TUNER_MODE_STEREO;
        else
                v->audmode = V4L2_TUNER_MODE_MONO;
-       v->signal = 0xFFFF*zol_getsigstr(zol);
+       v->signal = 0xFFFF * zol_getsigstr(zol);
        return 0;
 }
 
 static int vidioc_s_tuner(struct file *file, void *priv,
                                        struct v4l2_tuner *v)
 {
-       if (v->index > 0)
-               return -EINVAL;
-       return 0;
+       return v->index ? -EINVAL : 0;
 }
 
 static int vidioc_s_frequency(struct file *file, void *priv,
                                        struct v4l2_frequency *f)
 {
-       struct zol_device *zol = video_drvdata(file);
-
-       zol->curfreq = f->frequency;
-       if (zol_setfreq(zol, zol->curfreq) != 0) {
-               printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
-               return -EINVAL;
-       }
+       struct zoltrix *zol = video_drvdata(file);
+
+       if (zol_setfreq(zol, f->frequency) != 0)
+               return -EINVAL;
        return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
                                        struct v4l2_frequency *f)
 {
-       struct zol_device *zol = video_drvdata(file);
+       struct zoltrix *zol = video_drvdata(file);
 
        f->type = V4L2_TUNER_RADIO;
        f->frequency = zol->curfreq;
@@ -303,14 +286,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, 4096, 65535);
        }
        return -EINVAL;
 }
@@ -318,7 +298,7 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_g_ctrl(struct file *file, void *priv,
                                struct v4l2_control *ctrl)
 {
-       struct zol_device *zol = video_drvdata(file);
+       struct zoltrix *zol = video_drvdata(file);
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
@@ -334,7 +314,7 @@ static int vidioc_s_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
                                struct v4l2_control *ctrl)
 {
-       struct zol_device *zol = video_drvdata(file);
+       struct zoltrix *zol = video_drvdata(file);
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
@@ -342,82 +322,71 @@ static int vidioc_s_ctrl(struct file *fi
                        zol_mute(zol);
                else {
                        zol_unmute(zol);
-                       zol_setvol(zol,zol->curvol);
+                       zol_setvol(zol, zol->curvol);
                }
                return 0;
        case V4L2_CID_AUDIO_VOLUME:
-               zol_setvol(zol,ctrl->value/4096);
+               zol_setvol(zol, ctrl->value / 4096);
                return 0;
        }
        zol->stereo = 1;
-       if (zol_setfreq(zol, zol->curfreq) != 0) {
-               printk(KERN_WARNING "zoltrix: Set frequency failed.\n");
-               return -EINVAL;
-       }
+       if (zol_setfreq(zol, zol->curfreq) != 0)
+               return -EINVAL;
 #if 0 /*keep*/
 /* FIXME: Implement stereo/mono switch on V4L2 */
-                       if (v->mode & VIDEO_SOUND_STEREO) {
-                               zol->stereo = 1;
-                               zol_setfreq(zol, zol->curfreq);
-                       }
-                       if (v->mode & VIDEO_SOUND_MONO) {
-                               zol->stereo = 0;
-                               zol_setfreq(zol, zol->curfreq);
-                       }
+       if (v->mode & VIDEO_SOUND_STEREO) {
+               zol->stereo = 1;
+               zol_setfreq(zol, zol->curfreq);
+       }
+       if (v->mode & VIDEO_SOUND_MONO) {
+               zol->stereo = 0;
+               zol_setfreq(zol, zol->curfreq);
+       }
 #endif
        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 zol_device zoltrix_unit;
-
-static int zoltrix_exclusive_open(struct file *file)
-{
-       return test_and_set_bit(0, &zoltrix_unit.in_use) ? -EBUSY : 0;
-}
-
-static int zoltrix_exclusive_release(struct file *file)
-{
-       clear_bit(0, &zoltrix_unit.in_use);
+       return a->index ? -EINVAL : 0;
+}
+
+static int zoltrix_open(struct file *file)
+{
+       return 0;
+}
+
+static int zoltrix_release(struct file *file)
+{
        return 0;
 }
 
 static const struct v4l2_file_operations zoltrix_fops =
 {
        .owner          = THIS_MODULE,
-       .open           = zoltrix_exclusive_open,
-       .release        = zoltrix_exclusive_release,
+       .open           = zoltrix_open,
+       .release        = zoltrix_release,
        .ioctl          = video_ioctl2,
 };
 
@@ -436,67 +405,75 @@ static const struct v4l2_ioctl_ops zoltr
        .vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device zoltrix_radio = {
-       .name           = "Zoltrix Radio Plus",
-       .fops           = &zoltrix_fops,
-       .ioctl_ops      = &zoltrix_ioctl_ops,
-       .release        = video_device_release_empty,
-};
-
 static int __init zoltrix_init(void)
 {
-       if (io == -1) {
-               printk(KERN_ERR "You must set an I/O address with io=0x???\n");
-               return -EINVAL;
-       }
-       if ((io != 0x20c) && (io != 0x30c)) {
-               printk(KERN_ERR "zoltrix: invalid port, try 0x20c or 0x30c\n");
+       struct zoltrix *zol = &zoltrix_card;
+       struct v4l2_device *v4l2_dev = &zol->v4l2_dev;
+       int res;
+
+       strlcpy(v4l2_dev->name, "zoltrix", sizeof(v4l2_dev->name));
+       zol->io = io;
+       if (zol->io == -1) {
+               v4l2_err(v4l2_dev, "You must set an I/O address with 
io=0x???\n");
+               return -EINVAL;
+       }
+       if (zol->io != 0x20c && zol->io != 0x30c) {
+               v4l2_err(v4l2_dev, "invalid port, try 0x20c or 0x30c\n");
                return -ENXIO;
        }
 
-       video_set_drvdata(&zoltrix_radio, &zoltrix_unit);
-       if (!request_region(io, 2, "zoltrix")) {
-               printk(KERN_ERR "zoltrix: port 0x%x already in use\n", io);
+       if (!request_region(zol->io, 2, "zoltrix")) {
+               v4l2_err(v4l2_dev, "port 0x%x already in use\n", zol->io);
                return -EBUSY;
        }
 
-       if (video_register_device(&zoltrix_radio, VFL_TYPE_RADIO, radio_nr) < 
0) {
-               release_region(io, 2);
-               return -EINVAL;
-       }
-       printk(KERN_INFO "Zoltrix Radio Plus card driver.\n");
-
-       mutex_init(&zoltrix_unit.lock);
+       res = v4l2_device_register(NULL, v4l2_dev);
+       if (res < 0) {
+               release_region(zol->io, 2);
+               v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+               return res;
+       }
+
+       strlcpy(zol->vdev.name, v4l2_dev->name, sizeof(zol->vdev.name));
+       zol->vdev.v4l2_dev = v4l2_dev;
+       zol->vdev.fops = &zoltrix_fops;
+       zol->vdev.ioctl_ops = &zoltrix_ioctl_ops;
+       zol->vdev.release = video_device_release_empty;
+       video_set_drvdata(&zol->vdev, zol);
+
+       if (video_register_device(&zol->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(zol->io, 2);
+               return -EINVAL;
+       }
+       v4l2_info(v4l2_dev, "Zoltrix Radio Plus card driver.\n");
+
+       mutex_init(&zol->lock);
 
        /* mute card - prevents noisy bootups */
 
        /* this ensures that the volume is all the way down  */
 
-       outb(0, io);
-       outb(0, io);
+       outb(0, zol->io);
+       outb(0, zol->io);
        msleep(20);
-       inb(io + 3);
-
-       zoltrix_unit.curvol = 0;
-       zoltrix_unit.stereo = 1;
-
-       return 0;
-}
-
-MODULE_AUTHOR("C.van Schaik");
-MODULE_DESCRIPTION("A driver for the Zoltrix Radio Plus.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the Zoltrix Radio Plus (0x20c or 0x30c)");
-module_param(radio_nr, int, 0);
-
-static void __exit zoltrix_cleanup_module(void)
-{
-       video_unregister_device(&zoltrix_radio);
-       release_region(io, 2);
+       inb(zol->io + 3);
+
+       zol->curvol = 0;
+       zol->stereo = 1;
+
+       return 0;
+}
+
+static void __exit zoltrix_exit(void)
+{
+       struct zoltrix *zol = &zoltrix_card;
+
+       video_unregister_device(&zol->vdev);
+       v4l2_device_unregister(&zol->v4l2_dev);
+       release_region(zol->io, 2);
 }
 
 module_init(zoltrix_init);
-module_exit(zoltrix_cleanup_module);
-
+module_exit(zoltrix_exit);
+


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/9bfa3ce24ab081d469e78633f9938c7edbcba02e

_______________________________________________
linuxtv-commits mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to