The patch number 10771 was added via Mauro Carvalho Chehab <mche...@redhat.com>
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 <linux-me...@vger.kernel.org>

------

From: Mauro Carvalho Chehab  <mche...@redhat.com>
tea575x-tuner: convert it to V4L2 API


Priority: normal

Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com>


---

 linux/include/sound/tea575x-tuner.h   |   22 -
 linux/sound/i2c/other/tea575x-tuner.c |  346 ++++++++++++++++----------
 2 files changed, 224 insertions(+), 144 deletions(-)

diff -r b338640f0f67 -r 378d905783b1 linux/include/sound/tea575x-tuner.h
--- a/linux/include/sound/tea575x-tuner.h       Fri Feb 27 09:48:16 2009 -0300
+++ b/linux/include/sound/tea575x-tuner.h       Fri Feb 27 11:51:24 2009 -0300
@@ -23,24 +23,16 @@
  */
 
 #include "compat.h"
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
 #include <media/v4l2-dev.h>
+#include <media/v4l2-ioctl.h>
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-typedef struct snd_tea575x tea575x_t;
-#else
 struct snd_tea575x;
-#endif
 
 struct snd_tea575x_ops {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-       void (*write)(tea575x_t *tea, unsigned int val);
-       unsigned int (*read)(tea575x_t *tea);
-#else
        void (*write)(struct snd_tea575x *tea, unsigned int val);
        unsigned int (*read)(struct snd_tea575x *tea);
        void (*mute)(struct snd_tea575x *tea, unsigned int mute);
-#endif
 };
 
 struct snd_tea575x {
@@ -49,11 +41,10 @@ struct snd_tea575x {
 #else
        struct snd_card *card;
 #endif
-       struct video_device vd;         /* video device */
-       struct v4l2_file_operations fops;
+       struct video_device *vd;        /* video device */
        int dev_nr;                     /* requested device number + 1 */
-       int vd_registered;              /* video device is registered */
        int tea5759;                    /* 5759 chip is present */
+       int mute;                       /* Device is muted? */
        unsigned int freq_fixup;        /* crystal onboard */
        unsigned int val;               /* hw value */
        unsigned long freq;             /* frequency */
@@ -62,12 +53,7 @@ struct snd_tea575x {
        void *private_data;
 };
 
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-void snd_tea575x_init(tea575x_t *tea);
-void snd_tea575x_exit(tea575x_t *tea);
-#else
 void snd_tea575x_init(struct snd_tea575x *tea);
 void snd_tea575x_exit(struct snd_tea575x *tea);
-#endif
 
 #endif /* __SOUND_TEA575X_TUNER_H */
diff -r b338640f0f67 -r 378d905783b1 linux/sound/i2c/other/tea575x-tuner.c
--- a/linux/sound/i2c/other/tea575x-tuner.c     Fri Feb 27 09:48:16 2009 -0300
+++ b/linux/sound/i2c/other/tea575x-tuner.c     Fri Feb 27 11:51:24 2009 -0300
@@ -31,6 +31,13 @@ MODULE_AUTHOR("Jaroslav Kysela <pe...@pe
 MODULE_AUTHOR("Jaroslav Kysela <pe...@perex.cz>");
 MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio 
tuner chips");
 MODULE_LICENSE("GPL");
+
+static int radio_nr = -1;
+module_param(radio_nr, int, 0);
+
+#define RADIO_VERSION KERNEL_VERSION(0,0,2)
+#define FREQ_LO                 87*16000
+#define FREQ_HI                108*16000
 
 /*
  * definitions
@@ -54,6 +61,17 @@ MODULE_LICENSE("GPL");
 #define TEA575X_BIT_DUMMY      (1<<15)         /* buffer */
 #define TEA575X_BIT_FREQ_MASK  0x7fff
 
+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,
+       }
+};
+
 /*
  * lowlevel part
  */
@@ -89,124 +107,195 @@ static void snd_tea575x_set_freq(struct 
  * Linux Video interface
  */
 
-static long snd_tea575x_ioctl(struct file *file,
-                            unsigned int cmd, unsigned long data)
-{
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-       tea575x_t *tea = video_drvdata(file);
-#else
-       struct snd_tea575x *tea = video_drvdata(file);
-#endif
-       void __user *arg = (void __user *)data;
-
-       switch(cmd) {
-               case VIDIOCGCAP:
-               {
-                       struct video_capability v;
-                       v.type = VID_TYPE_TUNER;
-                       v.channels = 1;
-                       v.audios = 1;
-                       /* No we don't do pictures */
-                       v.maxwidth = 0;
-                       v.maxheight = 0;
-                       v.minwidth = 0;
-                       v.minheight = 0;
-                       strcpy(v.name, tea->tea5759 ? "TEA5759" : "TEA5757");
-                       if (copy_to_user(arg,&v,sizeof(v)))
-                               return -EFAULT;
+static int vidioc_querycap(struct file *file, void  *priv,
+                                       struct v4l2_capability *v)
+{
+       struct snd_tea575x *tea = video_drvdata(file);
+
+       strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757");
+       strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver));
+       strlcpy(v->card, "Maestro Radio", sizeof(v->card));
+       sprintf(v->bus_info, "PCI");
+       v->version = RADIO_VERSION;
+       v->capabilities = V4L2_CAP_TUNER;
+       return 0;
+}
+
+static int vidioc_g_tuner(struct file *file, void *priv,
+                                       struct v4l2_tuner *v)
+{
+       if (v->index > 0)
+               return -EINVAL;
+
+       strcpy(v->name, "FM");
+       v->type = V4L2_TUNER_RADIO;
+       v->rangelow = FREQ_LO;
+       v->rangehigh = FREQ_HI;
+       v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO;
+       v->capability = V4L2_TUNER_CAP_LOW;
+       v->audmode = V4L2_TUNER_MODE_MONO;
+       v->signal = 0xffff;
+       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_frequency(struct file *file, void *priv,
+                                       struct v4l2_frequency *f)
+{
+       struct snd_tea575x *tea = video_drvdata(file);
+
+       f->type = V4L2_TUNER_RADIO;
+       f->frequency = tea->freq;
+       return 0;
+}
+
+static int vidioc_s_frequency(struct file *file, void *priv,
+                                       struct v4l2_frequency *f)
+{
+       struct snd_tea575x *tea = video_drvdata(file);
+
+       if (f->frequency < FREQ_LO || f->frequency > FREQ_HI)
+               return -EINVAL;
+
+       tea->freq = f->frequency;
+
+       snd_tea575x_set_freq(tea);
+
+       return 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->capability = V4L2_AUDCAP_STEREO;
+       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 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;
                }
-               case VIDIOCGTUNER:
-               {
-                       struct video_tuner v;
-                       if (copy_from_user(&v, arg,sizeof(v))!=0)
-                               return -EFAULT;
-                       if (v.tuner)    /* Only 1 tuner */
-                               return -EINVAL;
-                       v.rangelow = (87*16000);
-                       v.rangehigh = (108*16000);
-                       v.flags = VIDEO_TUNER_LOW;
-                       v.mode = VIDEO_MODE_AUTO;
-                       strcpy(v.name, "FM");
-                       v.signal = 0xFFFF;
-                       if (copy_to_user(arg, &v, sizeof(v)))
-                               return -EFAULT;
+       }
+       return -EINVAL;
+}
+
+static int vidioc_g_ctrl(struct file *file, void *priv,
+                                       struct v4l2_control *ctrl)
+{
+       struct snd_tea575x *tea = video_drvdata(file);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
+       switch (ctrl->id) {
+       case V4L2_CID_AUDIO_MUTE:
+               if (tea->ops->mute) {
+                       ctrl->value = tea->mute;
                        return 0;
                }
-               case VIDIOCSTUNER:
-               {
-                       struct video_tuner v;
-                       if(copy_from_user(&v, arg, sizeof(v)))
-                               return -EFAULT;
-                       if(v.tuner!=0)
-                               return -EINVAL;
-                       /* Only 1 tuner so no setting needed ! */
+       }
+#endif
+       return -EINVAL;
+}
+
+static int vidioc_s_ctrl(struct file *file, void *priv,
+                                       struct v4l2_control *ctrl)
+{
+       struct snd_tea575x *tea = video_drvdata(file);
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
+       switch (ctrl->id) {
+       case V4L2_CID_AUDIO_MUTE:
+               if (tea->ops->mute) {
+                       tea->ops->mute(tea, ctrl->value);
+                       tea->mute = 1;
                        return 0;
                }
-               case VIDIOCGFREQ:
-                       if(copy_to_user(arg, &tea->freq, sizeof(tea->freq)))
-                               return -EFAULT;
-                       return 0;
-               case VIDIOCSFREQ:
-                       if(copy_from_user(&tea->freq, arg, sizeof(tea->freq)))
-                               return -EFAULT;
-                       snd_tea575x_set_freq(tea);
-                       return 0;
-               case VIDIOCGAUDIO:
-               {
-                       struct video_audio v;
-                       memset(&v, 0, sizeof(v));
-                       strcpy(v.name, "Radio");
-                       if(copy_to_user(arg,&v, sizeof(v)))
-                               return -EFAULT;
-                       return 0;
-               }
-               case VIDIOCSAUDIO:
-               {
-                       struct video_audio v;
-                       if(copy_from_user(&v, arg, sizeof(v)))
-                               return -EFAULT;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
-                       if (tea->ops->mute)
-                               tea->ops->mute(tea,
-                                              (v.flags &
-                                               VIDEO_AUDIO_MUTE) ? 1 : 0);
-#endif
-                       if(v.audio)
-                               return -EINVAL;
-                       return 0;
-               }
-               default:
-                       return -ENOIOCTLCMD;
-       }
-}
-
-static void snd_tea575x_release(struct video_device *vfd)
-{
+       }
+#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)
+{
+       if (i != 0)
+               return -EINVAL;
+       return 0;
 }
 
 static int snd_tea575x_exclusive_open(struct file *file)
 {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-       tea575x_t *tea = video_drvdata(file);
-#else
-       struct snd_tea575x *tea = video_drvdata(file);
-#endif
+       struct snd_tea575x *tea = video_drvdata(file);
 
        return test_and_set_bit(0, &tea->in_use) ? -EBUSY : 0;
 }
 
 static int snd_tea575x_exclusive_release(struct file *file)
 {
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-       tea575x_t *tea = video_drvdata(file);
-#else
-       struct snd_tea575x *tea = video_drvdata(file);
-#endif
+       struct snd_tea575x *tea = video_drvdata(file);
 
        clear_bit(0, &tea->in_use);
        return 0;
 }
+
+static const struct v4l2_file_operations tea575x_fops = {
+       .owner          = THIS_MODULE,
+       .open           = snd_tea575x_exclusive_open,
+       .release        = snd_tea575x_exclusive_release,
+       .ioctl          = video_ioctl2,
+};
+
+static const struct v4l2_ioctl_ops tea575x_ioctl_ops = {
+       .vidioc_querycap    = vidioc_querycap,
+       .vidioc_g_tuner     = vidioc_g_tuner,
+       .vidioc_s_tuner     = vidioc_s_tuner,
+       .vidioc_g_audio     = vidioc_g_audio,
+       .vidioc_s_audio     = vidioc_s_audio,
+       .vidioc_g_input     = vidioc_g_input,
+       .vidioc_s_input     = vidioc_s_input,
+       .vidioc_g_frequency = vidioc_g_frequency,
+       .vidioc_s_frequency = vidioc_s_frequency,
+       .vidioc_queryctrl   = vidioc_queryctrl,
+       .vidioc_g_ctrl      = vidioc_g_ctrl,
+       .vidioc_s_ctrl      = vidioc_s_ctrl,
+};
+
+static struct video_device tea575x_radio = {
+       .name           = "tea575x-tuner",
+       .fops           = &tea575x_fops,
+       .ioctl_ops      = &tea575x_ioctl_ops,
+       .release        = video_device_release,
+};
 
 /*
  * initialize all the tea575x chips
@@ -217,51 +306,56 @@ void snd_tea575x_init(struct snd_tea575x
 void snd_tea575x_init(struct snd_tea575x *tea)
 #endif
 {
+       int retval;
        unsigned int val;
+       struct video_device *tea575x_radio_inst;
 
        val = tea->ops->read(tea);
        if (val == 0x1ffffff || val == 0) {
-               snd_printk(KERN_ERR "Cannot find TEA575x chip\n");
+               snd_printk(KERN_ERR "tea575x-tuner: Cannot find TEA575x 
chip\n");
                return;
        }
 
-       memset(&tea->vd, 0, sizeof(tea->vd));
-       strcpy(tea->vd.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 radio");
-       tea->vd.release = snd_tea575x_release;
-       video_set_drvdata(&tea->vd, tea);
-       tea->vd.fops = &tea->fops;
        tea->in_use = 0;
-       tea->fops.owner = tea->card->module;
-       tea->fops.open = snd_tea575x_exclusive_open;
-       tea->fops.release = snd_tea575x_exclusive_release;
-       tea->fops.ioctl = snd_tea575x_ioctl;
-       if (video_register_device(&tea->vd, VFL_TYPE_RADIO, tea->dev_nr - 1) < 
0) {
-               snd_printk(KERN_ERR "unable to register tea575x tuner\n");
-               return;
-       }
-       tea->vd_registered = 1;
-
        tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40;
        tea->freq = 90500 * 16;         /* 90.5Mhz default */
 
+       tea575x_radio_inst = video_device_alloc();
+       if (tea575x_radio_inst == NULL) {
+               printk(KERN_ERR "tea575x-tuner: not enough memory\n");
+               return;
+       }
+
+       memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio));
+
+       strcpy(tea575x_radio.name, tea->tea5759 ? "TEA5759 radio" : "TEA5757 
radio");
+
+       video_set_drvdata(tea575x_radio_inst, tea);
+
+       retval = video_register_device(tea575x_radio_inst, VFL_TYPE_RADIO, 
radio_nr);
+       if (retval) {
+               printk(KERN_ERR "tea575x-tuner: can't register video 
device!\n");
+               kfree (tea575x_radio_inst);
+               return;
+       }
+
        snd_tea575x_set_freq(tea);
 
 #if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17)
        /* mute on init */
-       if (tea->ops->mute)
+       if (tea->ops->mute) {
                tea->ops->mute(tea, 1);
-#endif
-}
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,17)
-void snd_tea575x_exit(tea575x_t *tea)
-#else
+               tea->mute = 1;
+       }
+#endif
+       tea->vd = tea575x_radio_inst;
+}
+
 void snd_tea575x_exit(struct snd_tea575x *tea)
-#endif
-{
-       if (tea->vd_registered) {
-               video_unregister_device(&tea->vd);
-               tea->vd_registered = 0;
+{
+       if (tea->vd) {
+               video_unregister_device(tea->vd);
+               tea->vd = NULL;
        }
 }
 


---

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

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to