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


Priority: normal

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


---

 linux/drivers/media/radio/radio-sf16fmi.c |  372 ++++++++++------------
 1 file changed, 179 insertions(+), 193 deletions(-)

diff -r 1dcad62e9b10 -r 42161b37656e linux/drivers/media/radio/radio-sf16fmi.c
--- a/linux/drivers/media/radio/radio-sf16fmi.c Fri Mar 06 17:52:06 2009 +0100
+++ b/linux/drivers/media/radio/radio-sf16fmi.c Fri Mar 06 17:52:34 2009 +0100
@@ -22,114 +22,111 @@
 #include <linux/init.h>                /* Initdata                     */
 #include <linux/ioport.h>      /* request_region               */
 #include <linux/delay.h>       /* udelay                       */
+#include <linux/isapnp.h>
+#include <linux/mutex.h>
+#include <linux/videodev2.h>   /* kernel radio structs         */
+#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/isapnp.h>
-#include <asm/io.h>            /* outb, outb_p                 */
-#include <asm/uaccess.h>       /* copy to/from user            */
-#include <linux/mutex.h>
-
-#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,
-       }
-};
-
-struct fmi_device
-{
-       unsigned long in_use;
-       int port;
+
+MODULE_AUTHOR("Petr Vandrovec, [email protected] and M. Kirkwood");
+MODULE_DESCRIPTION("A driver for the SF16MI radio.");
+MODULE_LICENSE("GPL");
+
+static int io = -1;
+static int radio_nr = -1;
+
+module_param(io, int, 0);
+MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 2)
+
+struct fmi
+{
+       struct v4l2_device v4l2_dev;
+       struct video_device vdev;
+       int io;
        int curvol; /* 1 or 0 */
        unsigned long curfreq; /* freq in kHz */
        __u32 flags;
-};
-
-static int io = -1;
-static int radio_nr = -1;
-static struct pnp_dev *dev = NULL;
-static struct mutex lock;
+       struct mutex lock;
+};
+
+static struct fmi fmi_card;
+static struct pnp_dev *dev;
 
 /* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
 /* It is only useful to give freq in intervall of 800 (=0.05Mhz),
  * other bits will be truncated, e.g 92.7400016 -> 92.7, but
  * 92.7400017 -> 92.75
  */
-#define RSF16_ENCODE(x)        ((x)/800+214)
-#define RSF16_MINFREQ 87*16000
-#define RSF16_MAXFREQ 108*16000
-
-static void outbits(int bits, unsigned int data, int port)
-{
-       while(bits--) {
-               if(data & 1) {
-                       outb(5, port);
-                       udelay(6);
-                       outb(7, port);
+#define RSF16_ENCODE(x)        ((x) / 800 + 214)
+#define RSF16_MINFREQ (87 * 16000)
+#define RSF16_MAXFREQ (108 * 16000)
+
+static void outbits(int bits, unsigned int data, int io)
+{
+       while (bits--) {
+               if (data & 1) {
+                       outb(5, io);
+                       udelay(6);
+                       outb(7, io);
                        udelay(6);
                } else {
-                       outb(1, port);
-                       udelay(6);
-                       outb(3, port);
+                       outb(1, io);
+                       udelay(6);
+                       outb(3, io);
                        udelay(6);
                }
-               data>>=1;
-       }
-}
-
-static inline void fmi_mute(int port)
-{
-       mutex_lock(&lock);
-       outb(0x00, port);
-       mutex_unlock(&lock);
-}
-
-static inline void fmi_unmute(int port)
-{
-       mutex_lock(&lock);
-       outb(0x08, port);
-       mutex_unlock(&lock);
-}
-
-static inline int fmi_setfreq(struct fmi_device *dev)
-{
-       int myport = dev->port;
-       unsigned long freq = dev->curfreq;
-
-       mutex_lock(&lock);
-
-       outbits(16, RSF16_ENCODE(freq), myport);
-       outbits(8, 0xC0, myport);
+               data >>= 1;
+       }
+}
+
+static inline void fmi_mute(struct fmi *fmi)
+{
+       mutex_lock(&fmi->lock);
+       outb(0x00, fmi->io);
+       mutex_unlock(&fmi->lock);
+}
+
+static inline void fmi_unmute(struct fmi *fmi)
+{
+       mutex_lock(&fmi->lock);
+       outb(0x08, fmi->io);
+       mutex_unlock(&fmi->lock);
+}
+
+static inline int fmi_setfreq(struct fmi *fmi, unsigned long freq)
+{
+       mutex_lock(&fmi->lock);
+       fmi->curfreq = freq;
+
+       outbits(16, RSF16_ENCODE(freq), fmi->io);
+       outbits(8, 0xC0, fmi->io);
        msleep(143);            /* was schedule_timeout(HZ/7) */
-       mutex_unlock(&lock);
-       if (dev->curvol) fmi_unmute(myport);
-       return 0;
-}
-
-static inline int fmi_getsigstr(struct fmi_device *dev)
+       mutex_unlock(&fmi->lock);
+       if (fmi->curvol)
+               fmi_unmute(fmi);
+       return 0;
+}
+
+static inline int fmi_getsigstr(struct fmi *fmi)
 {
        int val;
        int res;
-       int myport = dev->port;
-
-
-       mutex_lock(&lock);
-       val = dev->curvol ? 0x08 : 0x00;        /* unmute/mute */
-       outb(val, myport);
-       outb(val | 0x10, myport);
+
+       mutex_lock(&fmi->lock);
+       val = fmi->curvol ? 0x08 : 0x00;        /* unmute/mute */
+       outb(val, fmi->io);
+       outb(val | 0x10, fmi->io);
        msleep(143);            /* was schedule_timeout(HZ/7) */
-       res = (int)inb(myport+1);
-       outb(val, myport);
-
-       mutex_unlock(&lock);
+       res = (int)inb(fmi->io + 1);
+       outb(val, fmi->io);
+
+       mutex_unlock(&fmi->lock);
        return (res & 2) ? 0 : 0xFFFF;
 }
 
@@ -138,9 +135,9 @@ static int vidioc_querycap(struct file *
 {
        strlcpy(v->driver, "radio-sf16fmi", sizeof(v->driver));
        strlcpy(v->card, "SF16-FMx 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;
 }
 
@@ -148,18 +145,18 @@ static int vidioc_g_tuner(struct file *f
                                        struct v4l2_tuner *v)
 {
        int mult;
-       struct fmi_device *fmi = video_drvdata(file);
+       struct fmi *fmi = 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;
        mult = (fmi->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000;
-       v->rangelow = RSF16_MINFREQ/mult;
-       v->rangehigh = RSF16_MAXFREQ/mult;
+       v->rangelow = RSF16_MINFREQ / mult;
+       v->rangehigh = RSF16_MAXFREQ / mult;
        v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO;
-       v->capability = fmi->flags&V4L2_TUNER_CAP_LOW;
+       v->capability = fmi->flags & V4L2_TUNER_CAP_LOW;
        v->audmode = V4L2_TUNER_MODE_STEREO;
        v->signal = fmi_getsigstr(fmi);
        return 0;
@@ -168,32 +165,29 @@ static int vidioc_s_tuner(struct file *f
 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 fmi_device *fmi = video_drvdata(file);
+       struct fmi *fmi = video_drvdata(file);
 
        if (!(fmi->flags & V4L2_TUNER_CAP_LOW))
                f->frequency *= 1000;
        if (f->frequency < RSF16_MINFREQ ||
-                       f->frequency > RSF16_MAXFREQ )
+                       f->frequency > RSF16_MAXFREQ)
                return -EINVAL;
-       /*rounding in steps of 800 to match th freq
-       that will be used */
-       fmi->curfreq = (f->frequency/800)*800;
-       fmi_setfreq(fmi);
+       /* rounding in steps of 800 to match the freq
+          that will be used */
+       fmi_setfreq(fmi, (f->frequency / 800) * 800);
        return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
                                        struct v4l2_frequency *f)
 {
-       struct fmi_device *fmi = video_drvdata(file);
+       struct fmi *fmi = video_drvdata(file);
 
        f->type = V4L2_TUNER_RADIO;
        f->frequency = fmi->curfreq;
@@ -205,14 +199,9 @@ 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);
        }
        return -EINVAL;
 }
@@ -220,7 +209,7 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_g_ctrl(struct file *file, void *priv,
                                        struct v4l2_control *ctrl)
 {
-       struct fmi_device *fmi = video_drvdata(file);
+       struct fmi *fmi = video_drvdata(file);
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
@@ -233,69 +222,60 @@ static int vidioc_s_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
                                        struct v4l2_control *ctrl)
 {
-       struct fmi_device *fmi = video_drvdata(file);
+       struct fmi *fmi = video_drvdata(file);
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
                if (ctrl->value)
-                       fmi_mute(fmi->port);
+                       fmi_mute(fmi);
                else
-                       fmi_unmute(fmi->port);
+                       fmi_unmute(fmi);
                fmi->curvol = ctrl->value;
                return 0;
        }
        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 fmi_device fmi_unit;
-
-static int fmi_exclusive_open(struct file *file)
-{
-       return test_and_set_bit(0, &fmi_unit.in_use) ? -EBUSY : 0;
-}
-
-static int fmi_exclusive_release(struct file *file)
-{
-       clear_bit(0, &fmi_unit.in_use);
+       return a->index ? -EINVAL : 0;
+}
+
+static int fmi_open(struct file *file)
+{
+       return 0;
+}
+
+static int fmi_release(struct file *file)
+{
        return 0;
 }
 
 static const struct v4l2_file_operations fmi_fops = {
        .owner          = THIS_MODULE,
-       .open           = fmi_exclusive_open,
-       .release        = fmi_exclusive_release,
+       .open           = fmi_open,
+       .release        = fmi_release,
        .ioctl          = video_ioctl2,
 };
 
@@ -314,13 +294,6 @@ static const struct v4l2_ioctl_ops fmi_i
        .vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device fmi_radio = {
-       .name           = "SF16FMx radio",
-       .fops           = &fmi_fops,
-       .ioctl_ops      = &fmi_ioctl_ops,
-       .release        = video_device_release_empty,
-};
-
 /* ladis: this is my card. does any other types exist? */
 static struct isapnp_device_id id_table[] __devinitdata = {
        {       ISAPNP_ANY_ID, ISAPNP_ANY_ID,
@@ -345,7 +318,7 @@ static int __init isapnp_fmi_probe(void)
        if (pnp_device_attach(dev) < 0)
                return -EAGAIN;
        if (pnp_activate_dev(dev) < 0) {
-               printk ("radio-sf16fmi: PnP configure failed (out of 
resources?)\n");
+               printk(KERN_ERR "radio-sf16fmi: PnP configure failed (out of 
resources?)\n");
                pnp_device_detach(dev);
                return -ENOMEM;
        }
@@ -355,59 +328,72 @@ static int __init isapnp_fmi_probe(void)
        }
 
        i = pnp_port_start(dev, 0);
-       printk ("radio-sf16fmi: PnP reports card at %#x\n", i);
+       printk(KERN_INFO "radio-sf16fmi: PnP reports card at %#x\n", i);
 
        return i;
 }
 
 static int __init fmi_init(void)
 {
+       struct fmi *fmi = &fmi_card;
+       struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
+       int res;
+
        if (io < 0)
                io = isapnp_fmi_probe();
-       if (io < 0) {
-               printk(KERN_ERR "radio-sf16fmi: No PnP card found.\n");
-               return io;
+       strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
+       fmi->io = io;
+       if (fmi->io < 0) {
+               v4l2_err(v4l2_dev, "No PnP card found.\n");
+               return fmi->io;
        }
        if (!request_region(io, 2, "radio-sf16fmi")) {
-               printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", 
io);
+               v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
                pnp_device_detach(dev);
                return -EBUSY;
        }
 
-       fmi_unit.port = io;
-       fmi_unit.curvol = 0;
-       fmi_unit.curfreq = 0;
-       fmi_unit.flags = V4L2_TUNER_CAP_LOW;
-       video_set_drvdata(&fmi_radio, &fmi_unit);
-
-       mutex_init(&lock);
-
-       if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) < 0) {
-               release_region(io, 2);
+       res = v4l2_device_register(NULL, v4l2_dev);
+       if (res < 0) {
+               release_region(fmi->io, 2);
+               pnp_device_detach(dev);
+               v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
+               return res;
+       }
+
+       fmi->flags = V4L2_TUNER_CAP_LOW;
+       strlcpy(fmi->vdev.name, v4l2_dev->name, sizeof(fmi->vdev.name));
+       fmi->vdev.v4l2_dev = v4l2_dev;
+       fmi->vdev.fops = &fmi_fops;
+       fmi->vdev.ioctl_ops = &fmi_ioctl_ops;
+       fmi->vdev.release = video_device_release_empty;
+       video_set_drvdata(&fmi->vdev, fmi);
+
+       mutex_init(&fmi->lock);
+
+       if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
+               v4l2_device_unregister(v4l2_dev);
+               release_region(fmi->io, 2);
+               pnp_device_detach(dev);
                return -EINVAL;
        }
 
-       printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
+       v4l2_info(v4l2_dev, "card driver at 0x%x\n", fmi->io);
        /* mute card - prevents noisy bootups */
-       fmi_mute(io);
-       return 0;
-}
-
-MODULE_AUTHOR("Petr Vandrovec, [email protected] and M. Kirkwood");
-MODULE_DESCRIPTION("A driver for the SF16MI radio.");
-MODULE_LICENSE("GPL");
-
-module_param(io, int, 0);
-MODULE_PARM_DESC(io, "I/O address of the SF16MI card (0x284 or 0x384)");
-module_param(radio_nr, int, 0);
-
-static void __exit fmi_cleanup_module(void)
-{
-       video_unregister_device(&fmi_radio);
-       release_region(io, 2);
+       fmi_mute(fmi);
+       return 0;
+}
+
+static void __exit fmi_exit(void)
+{
+       struct fmi *fmi = &fmi_card;
+
+       video_unregister_device(&fmi->vdev);
+       v4l2_device_unregister(&fmi->v4l2_dev);
+       release_region(fmi->io, 2);
        if (dev)
                pnp_device_detach(dev);
 }
 
 module_init(fmi_init);
-module_exit(fmi_cleanup_module);
+module_exit(fmi_exit);


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/42161b37656e6e011ef0fc1f20e5f724718b1f62

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

Reply via email to