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


Priority: normal

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


---

 linux/drivers/media/radio/radio-maestro.c |  396 ++++++++++------------
 1 file changed, 193 insertions(+), 203 deletions(-)

diff -r e505c4f91eb6 -r e3cd68af4c4e linux/drivers/media/radio/radio-maestro.c
--- a/linux/drivers/media/radio/radio-maestro.c Fri Mar 06 17:50:42 2009 +0100
+++ b/linux/drivers/media/radio/radio-maestro.c Fri Mar 06 17:51:08 2009 +0100
@@ -22,28 +22,24 @@
 #include <linux/init.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <asm/io.h>
-#include <asm/uaccess.h>
+#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
 #include <linux/pci.h>
 #include <linux/videodev2.h>
-#include <media/v4l2-common.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+#include <media/v4l2-device.h>
 #include <media/v4l2-ioctl.h>
 #include "compat.h"
 
-#include <linux/version.h>      /* for KERNEL_VERSION MACRO     */
-#define RADIO_VERSION KERNEL_VERSION(0,0,6)
+MODULE_AUTHOR("Adam Tlalka, [email protected]");
+MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
+MODULE_LICENSE("GPL");
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0, 0, 6)
 #define DRIVER_VERSION "0.06"
-
-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,
-       }
-};
 
 #define GPIO_DATA      0x60   /* port offset from ESS_IO_BASE */
 
@@ -73,62 +69,27 @@ static struct v4l2_queryctrl radio_qctrl
 
 #define BITS2FREQ(x)   ((x) * FREQ_STEP - FREQ_IF)
 
-static int radio_nr = -1;
-module_param(radio_nr, int, 0);
-
-static unsigned long in_use;
-
-static int maestro_probe(struct pci_dev *pdev, const struct pci_device_id 
*ent);
-
-static int maestro_exclusive_open(struct file *file)
-{
-       return test_and_set_bit(0, &in_use) ? -EBUSY : 0;
-}
-
-static int maestro_exclusive_release(struct file *file)
-{
-       clear_bit(0, &in_use);
-       return 0;
-}
-
-static void maestro_remove(struct pci_dev *pdev);
-
-static struct pci_device_id maestro_r_pci_tbl[] = {
-       { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
-               .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
-               .class_mask = 0xffff00 },
-       { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
-               .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
-               .class_mask = 0xffff00 },
-       { 0 }
-};
-MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
-
-static struct pci_driver maestro_r_driver = {
-       .name           = "maestro_radio",
-       .id_table       = maestro_r_pci_tbl,
-       .probe          = maestro_probe,
-       .remove         = __devexit_p(maestro_remove),
-};
-
-static const struct v4l2_file_operations maestro_fops = {
-       .owner          = THIS_MODULE,
-       .open           = maestro_exclusive_open,
-       .release        = maestro_exclusive_release,
-       .ioctl          = video_ioctl2,
-};
-
-struct radio_device {
-       u16     io,     /* base of Maestro card radio io (GPIO_DATA)*/
-               muted,  /* VIDEO_AUDIO_MUTE */
-               stereo, /* VIDEO_TUNER_STEREO_ON */
-               tuned;  /* signal strength (0 or 0xffff) */
-};
-
-static u32 radio_bits_get(struct radio_device *dev)
-{
-       register u16 io=dev->io, l, rdata;
-       register u32 data=0;
+struct maestro {
+       struct v4l2_device v4l2_dev;
+       struct video_device vdev;
+       struct pci_dev *pdev;
+       struct mutex lock;
+
+       u16     io;     /* base of Maestro card radio io (GPIO_DATA)*/
+       u16     muted;  /* VIDEO_AUDIO_MUTE */
+       u16     stereo; /* VIDEO_TUNER_STEREO_ON */
+       u16     tuned;  /* signal strength (0 or 0xffff) */
+};
+
+static inline struct maestro *to_maestro(struct v4l2_device *v4l2_dev)
+{
+       return container_of(v4l2_dev, struct maestro, v4l2_dev);
+}
+
+static u32 radio_bits_get(struct maestro *dev)
+{
+       u16 io = dev->io, l, rdata;
+       u32 data = 0;
        u16 omask;
 
        omask = inw(io + IO_MASK);
@@ -136,25 +97,23 @@ static u32 radio_bits_get(struct radio_d
        outw(0, io);
        udelay(16);
 
-       for (l=24;l--;) {
+       for (l = 24; l--;) {
                outw(STR_CLK, io);              /* HI state */
                udelay(2);
-               if(!l)
+               if (!l)
                        dev->tuned = inw(io) & STR_MOST ? 0 : 0xffff;
                outw(0, io);                    /* LO state */
                udelay(2);
                data <<= 1;                     /* shift data */
                rdata = inw(io);
-               if(!l)
-                       dev->stereo =  rdata & STR_MOST ?
-                       0 : 1;
-               else
-                       if(rdata & STR_DATA)
-                               data++;
-               udelay(2);
-       }
-
-       if(dev->muted)
+               if (!l)
+                       dev->stereo = (rdata & STR_MOST) ?  0 : 1;
+               else if (rdata & STR_DATA)
+                       data++;
+               udelay(2);
+       }
+
+       if (dev->muted)
                outw(STR_WREN, io);
 
        udelay(4);
@@ -163,18 +122,18 @@ static u32 radio_bits_get(struct radio_d
        return data & 0x3ffe;
 }
 
-static void radio_bits_set(struct radio_device *dev, u32 data)
-{
-       register u16 io=dev->io, l, bits;
+static void radio_bits_set(struct maestro *dev, u32 data)
+{
+       u16 io = dev->io, l, bits;
        u16 omask, odir;
 
        omask = inw(io + IO_MASK);
-       odir  = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+       odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
        outw(odir | STR_DATA, io + IO_DIR);
        outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK);
        udelay(16);
-       for (l=25;l;l--) {
-               bits = ((data >> 18) & STR_DATA) | STR_WREN ;
+       for (l = 25; l; l--) {
+               bits = ((data >> 18) & STR_DATA) | STR_WREN;
                data <<= 1;                     /* shift data */
                outw(bits, io);                 /* start strobe */
                udelay(2);
@@ -184,7 +143,7 @@ static void radio_bits_set(struct radio_
                udelay(4);
        }
 
-       if(!dev->muted)
+       if (!dev->muted)
                outw(0, io);
 
        udelay(4);
@@ -196,78 +155,79 @@ static int vidioc_querycap(struct file *
 static int vidioc_querycap(struct file *file, void  *priv,
                                        struct v4l2_capability *v)
 {
+       struct maestro *dev = video_drvdata(file);
+
        strlcpy(v->driver, "radio-maestro", sizeof(v->driver));
        strlcpy(v->card, "Maestro Radio", sizeof(v->card));
-       sprintf(v->bus_info, "PCI");
+       snprintf(v->bus_info, sizeof(v->bus_info), "PCI:%s", 
pci_name(dev->pdev));
        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 radio_device *card = video_drvdata(file);
+       struct maestro *dev = video_drvdata(file);
 
        if (v->index > 0)
                return -EINVAL;
 
-       (void)radio_bits_get(card);
-
-       strcpy(v->name, "FM");
+       mutex_lock(&dev->lock);
+       radio_bits_get(dev);
+
+       strlcpy(v->name, "FM", sizeof(v->name));
        v->type = V4L2_TUNER_RADIO;
        v->rangelow = FREQ_LO;
        v->rangehigh = FREQ_HI;
-       v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+       v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO;
        v->capability = V4L2_TUNER_CAP_LOW;
-       if(card->stereo)
+       if (dev->stereo)
                v->audmode = V4L2_TUNER_MODE_STEREO;
        else
                v->audmode = V4L2_TUNER_MODE_MONO;
-       v->signal = card->tuned;
+       v->signal = dev->tuned;
+       mutex_unlock(&dev->lock);
        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 radio_device *card = video_drvdata(file);
+       struct maestro *dev = video_drvdata(file);
 
        if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
                return -EINVAL;
-       radio_bits_set(card, FREQ2BITS(f->frequency));
+       mutex_lock(&dev->lock);
+       radio_bits_set(dev, FREQ2BITS(f->frequency));
+       mutex_unlock(&dev->lock);
        return 0;
 }
 
 static int vidioc_g_frequency(struct file *file, void *priv,
                                        struct v4l2_frequency *f)
 {
-       struct radio_device *card = video_drvdata(file);
+       struct maestro *dev = video_drvdata(file);
 
        f->type = V4L2_TUNER_RADIO;
-       f->frequency = BITS2FREQ(radio_bits_get(card));
+       mutex_lock(&dev->lock);
+       f->frequency = BITS2FREQ(radio_bits_get(dev));
+       mutex_unlock(&dev->lock);
        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);
        }
        return -EINVAL;
 }
@@ -275,11 +235,11 @@ static int vidioc_g_ctrl(struct file *fi
 static int vidioc_g_ctrl(struct file *file, void *priv,
                                        struct v4l2_control *ctrl)
 {
-       struct radio_device *card = video_drvdata(file);
+       struct maestro *dev = video_drvdata(file);
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
-               ctrl->value = card->muted;
+               ctrl->value = dev->muted;
                return 0;
        }
        return -EINVAL;
@@ -288,78 +248,68 @@ static int vidioc_s_ctrl(struct file *fi
 static int vidioc_s_ctrl(struct file *file, void *priv,
                                        struct v4l2_control *ctrl)
 {
-       struct radio_device *card = video_drvdata(file);
-       register u16 io = card->io;
-       register u16 omask = inw(io + IO_MASK);
+       struct maestro *dev = video_drvdata(file);
+       u16 io = dev->io;
+       u16 omask;
 
        switch (ctrl->id) {
        case V4L2_CID_AUDIO_MUTE:
+               mutex_lock(&dev->lock);
+               omask = inw(io + IO_MASK);
                outw(~STR_WREN, io + IO_MASK);
-               outw((card->muted = ctrl->value ) ?
-                               STR_WREN : 0, io);
+               dev->muted = ctrl->value;
+               outw(dev->muted ? STR_WREN : 0, io);
                udelay(4);
                outw(omask, io + IO_MASK);
                msleep(125);
+               mutex_unlock(&dev->lock);
                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 u16 __devinit radio_power_on(struct radio_device *dev)
-{
-       register u16 io = dev->io;
-       register u32 ofreq;
-       u16 omask, odir;
-
-       omask = inw(io + IO_MASK);
-       odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
-       outw(odir & ~STR_WREN, io + IO_DIR);
-       dev->muted = inw(io) & STR_WREN ? 0 : 1;
-       outw(odir, io + IO_DIR);
-       outw(~(STR_WREN | STR_CLK), io + IO_MASK);
-       outw(dev->muted ? 0 : STR_WREN, io);
-       udelay(16);
-       outw(omask, io + IO_MASK);
-       ofreq = radio_bits_get(dev);
-
-       if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
-               ofreq = FREQ2BITS(FREQ_LO);
-       radio_bits_set(dev, ofreq);
-
-       return (ofreq == radio_bits_get(dev));
-}
+       return a->index ? -EINVAL : 0;
+}
+
+static int maestro_open(struct file *file)
+{
+       return 0;
+}
+
+static int maestro_release(struct file *file)
+{
+       return 0;
+}
+
+static const struct v4l2_file_operations maestro_fops = {
+       .owner          = THIS_MODULE,
+       .open           = maestro_open,
+       .release        = maestro_release,
+       .ioctl          = video_ioctl2,
+};
 
 static const struct v4l2_ioctl_ops maestro_ioctl_ops = {
        .vidioc_querycap    = vidioc_querycap,
@@ -376,18 +326,35 @@ static const struct v4l2_ioctl_ops maest
        .vidioc_s_ctrl      = vidioc_s_ctrl,
 };
 
-static struct video_device maestro_radio = {
-       .name           = "Maestro radio",
-       .fops           = &maestro_fops,
-       .ioctl_ops      = &maestro_ioctl_ops,
-       .release        = video_device_release,
-};
+static u16 __devinit radio_power_on(struct maestro *dev)
+{
+       register u16 io = dev->io;
+       register u32 ofreq;
+       u16 omask, odir;
+
+       omask = inw(io + IO_MASK);
+       odir = (inw(io + IO_DIR) & ~STR_DATA) | (STR_CLK | STR_WREN);
+       outw(odir & ~STR_WREN, io + IO_DIR);
+       dev->muted = inw(io) & STR_WREN ? 0 : 1;
+       outw(odir, io + IO_DIR);
+       outw(~(STR_WREN | STR_CLK), io + IO_MASK);
+       outw(dev->muted ? 0 : STR_WREN, io);
+       udelay(16);
+       outw(omask, io + IO_MASK);
+       ofreq = radio_bits_get(dev);
+
+       if ((ofreq < FREQ2BITS(FREQ_LO)) || (ofreq > FREQ2BITS(FREQ_HI)))
+               ofreq = FREQ2BITS(FREQ_LO);
+       radio_bits_set(dev, ofreq);
+
+       return (ofreq == radio_bits_get(dev));
+}
 
 static int __devinit maestro_probe(struct pci_dev *pdev,
        const struct pci_device_id *ent)
 {
-       struct radio_device *radio_unit;
-       struct video_device *maestro_radio_inst;
+       struct maestro *dev;
+       struct v4l2_device *v4l2_dev;
        int retval;
 
        retval = pci_enable_device(pdev);
@@ -398,46 +365,53 @@ static int __devinit maestro_probe(struc
 
        retval = -ENOMEM;
 
-       radio_unit = kzalloc(sizeof(*radio_unit), GFP_KERNEL);
-       if (radio_unit == NULL) {
+       dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+       if (dev == NULL) {
                dev_err(&pdev->dev, "not enough memory\n");
                goto err;
        }
 
-       radio_unit->io = pci_resource_start(pdev, 0) + GPIO_DATA;
-
-       maestro_radio_inst = video_device_alloc();
-       if (maestro_radio_inst == NULL) {
-               dev_err(&pdev->dev, "not enough memory\n");
+       v4l2_dev = &dev->v4l2_dev;
+       mutex_init(&dev->lock);
+       dev->pdev = pdev;
+
+       strlcpy(v4l2_dev->name, "maestro", sizeof(v4l2_dev->name));
+
+       retval = v4l2_device_register(&pdev->dev, v4l2_dev);
+       if (retval < 0) {
+               v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
                goto errfr;
        }
 
-       memcpy(maestro_radio_inst, &maestro_radio, sizeof(maestro_radio));
-       video_set_drvdata(maestro_radio_inst, radio_unit);
-       pci_set_drvdata(pdev, maestro_radio_inst);
-
-       retval = video_register_device(maestro_radio_inst, VFL_TYPE_RADIO, 
radio_nr);
+       dev->io = pci_resource_start(pdev, 0) + GPIO_DATA;
+
+       strlcpy(dev->vdev.name, v4l2_dev->name, sizeof(dev->vdev.name));
+       dev->vdev.v4l2_dev = v4l2_dev;
+       dev->vdev.fops = &maestro_fops;
+       dev->vdev.ioctl_ops = &maestro_ioctl_ops;
+       dev->vdev.release = video_device_release_empty;
+       video_set_drvdata(&dev->vdev, dev);
+
+       retval = video_register_device(&dev->vdev, VFL_TYPE_RADIO, radio_nr);
        if (retval) {
-               printk(KERN_ERR "can't register video device!\n");
+               v4l2_err(v4l2_dev, "can't register video device!\n");
                goto errfr1;
        }
 
-       if (!radio_power_on(radio_unit)) {
+       if (!radio_power_on(dev)) {
                retval = -EIO;
                goto errunr;
        }
 
-       dev_info(&pdev->dev, "version " DRIVER_VERSION " time " __TIME__ "  "
-                __DATE__ "\n");
-       dev_info(&pdev->dev, "radio chip initialized\n");
+       v4l2_info(v4l2_dev, "version " DRIVER_VERSION "\n");
 
        return 0;
 errunr:
-       video_unregister_device(maestro_radio_inst);
+       video_unregister_device(&dev->vdev);
 errfr1:
-       video_device_release(maestro_radio_inst);
+       v4l2_device_unregister(v4l2_dev);
 errfr:
-       kfree(radio_unit);
+       kfree(dev);
 err:
        return retval;
 
@@ -445,10 +419,30 @@ err:
 
 static void __devexit maestro_remove(struct pci_dev *pdev)
 {
-       struct video_device *vdev = pci_get_drvdata(pdev);
-
-       video_unregister_device(vdev);
-}
+       struct v4l2_device *v4l2_dev = dev_get_drvdata(&pdev->dev);
+       struct maestro *dev = to_maestro(v4l2_dev);
+
+       video_unregister_device(&dev->vdev);
+       v4l2_device_unregister(&dev->v4l2_dev);
+}
+
+static struct pci_device_id maestro_r_pci_tbl[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1968),
+               .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+               .class_mask = 0xffff00 },
+       { PCI_DEVICE(PCI_VENDOR_ID_ESS, PCI_DEVICE_ID_ESS_ESS1978),
+               .class = PCI_CLASS_MULTIMEDIA_AUDIO << 8,
+               .class_mask = 0xffff00 },
+       { 0 }
+};
+MODULE_DEVICE_TABLE(pci, maestro_r_pci_tbl);
+
+static struct pci_driver maestro_r_driver = {
+       .name           = "maestro_radio",
+       .id_table       = maestro_r_pci_tbl,
+       .probe          = maestro_probe,
+       .remove         = __devexit_p(maestro_remove),
+};
 
 static int __init maestro_radio_init(void)
 {
@@ -467,7 +461,3 @@ static void __exit maestro_radio_exit(vo
 
 module_init(maestro_radio_init);
 module_exit(maestro_radio_exit);
-
-MODULE_AUTHOR("Adam Tlalka, [email protected]");
-MODULE_DESCRIPTION("Radio driver for the Maestro PCI sound card radio.");
-MODULE_LICENSE("GPL");


---

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

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

Reply via email to