From e84fef6b4a9d36fea53354633c590a7800d9fd83 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Tue, 8 Aug 2006 09:10:05 -0300 Subject: [PATCH] V4L/DVB (4364): V4L2 conversion: radio-maxiradio Driver conversion to V4L2 API. Require some testing, since this obsolete hardware is not common those days. Signed-off-by: Mauro Carvalho Chehab --- drivers/media/radio/Kconfig | 2 +- drivers/media/radio/radio-maxiradio.c | 166 +++++++++++++++++++++------------- 2 files changed, 104 insertions(+), 64 deletions(-) diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 34d04b5..96d0dd3 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -145,7 +145,7 @@ config RADIO_GEMTEK_PCI config RADIO_MAXIRADIO tristate "Guillemot MAXI Radio FM 2000 radio" - depends on VIDEO_V4L1 && PCI + depends on VIDEO_V4L2 && PCI ---help--- Choose Y here if you have this radio card. This card may also be found as Gemtek PCI FM. diff --git a/drivers/media/radio/radio-maxiradio.c b/drivers/media/radio/radio-maxiradio.c index f93d7af..c2eeae7 100644 --- a/drivers/media/radio/radio-maxiradio.c +++ b/drivers/media/radio/radio-maxiradio.c @@ -20,13 +20,14 @@ * 0.75b * - better pci interface thanks to Francois Romieu * - * 0.75 + * 0.75 Sun Feb 4 22:51:27 EET 2001 * - tiding up * - removed support for multiple devices as it didn't work anyway * * BUGS: * - card unmutes if you change frequency * + * Converted to V4L2 API by Mauro Carvalho Chehab */ @@ -40,11 +41,24 @@ #include #include -#include +#include #include -/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ -#define DRIVER_VERSION "0.75" +#define DRIVER_VERSION "0.76" + +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,7,6) + +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, + } +}; #ifndef PCI_VENDOR_ID_GUILLEMOT #define PCI_VENDOR_ID_GUILLEMOT 0x5046 @@ -90,7 +104,6 @@ static struct video_device maxiradio_radio = .owner = THIS_MODULE, .name = "Maxi Radio FM2000 radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_SF16MI, .fops = &maxiradio_fops, }; @@ -176,89 +189,116 @@ static inline int radio_function(struct inode *inode, struct file *file, struct radio_device *card=dev->priv; switch(cmd) { - case VIDIOCGCAP: { - struct video_capability *v = arg; - + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - strcpy(v->name, "Maxi Radio FM2000 radio"); - v->type=VID_TYPE_TUNER; - v->channels=v->audios=1; + strlcpy(v->driver, "radio-maxiradio", sizeof (v->driver)); + strlcpy(v->card, "Maxi Radio FM2000 radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: { - struct video_tuner *v = arg; + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *v = arg; - if(v->tuner) + if (v->index > 0) return -EINVAL; - card->stereo = 0xffff * get_stereo(card->io); - card->tuned = 0xffff * get_tune(card->io); - - v->flags = VIDEO_TUNER_LOW | card->stereo; - v->signal = card->tuned; - + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); - - v->rangelow = FREQ_LO; - v->rangehigh = FREQ_HI; - v->mode = VIDEO_MODE_AUTO; + 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; + if(get_stereo(card->io)) + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xffff*get_tune(card->io); return 0; } - case VIDIOCSTUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - return 0; - } - case VIDIOCGFREQ: { - unsigned long *freq = arg; - *freq = card->freq; return 0; } - case VIDIOCSFREQ: { - unsigned long *freq = arg; + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; - if (*freq < FREQ_LO || *freq > FREQ_HI) + if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) return -EINVAL; - card->freq = *freq; + + card->freq = f->frequency; set_freq(card->io, FREQ2BITS(card->freq)); msleep(125); return 0; } - case VIDIOCGAUDIO: { - struct video_audio *v = arg; - memset(v,0,sizeof(*v)); - strcpy(v->name, "Radio"); - v->flags=VIDEO_AUDIO_MUTABLE | card->muted; - v->mode=VIDEO_SOUND_STEREO; - return 0; - } + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *f = arg; - case VIDIOCSAUDIO: { - struct video_audio *v = arg; + f->type = V4L2_TUNER_RADIO; + f->frequency = card->freq; - if(v->audio) - return -EINVAL; - card->muted = v->flags & VIDEO_AUDIO_MUTE; - if(card->muted) - turn_power(card->io, 0); - else - set_freq(card->io, FREQ2BITS(card->freq)); return 0; } - case VIDIOCGUNIT: { - struct video_unit *v = arg; - - v->video=VIDEO_NO_UNIT; - v->vbi=VIDEO_NO_UNIT; - v->radio=dev->minor; - v->audio=0; - v->teletext=VIDEO_NO_UNIT; - return 0; + case VIDIOC_QUERYCTRL: + { + struct v4l2_queryctrl *qc = arg; + 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); + } + } + return -EINVAL; + } + case VIDIOC_G_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=card->muted; + return (0); + } + return -EINVAL; } - default: return -ENOIOCTLCMD; + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + card->muted = ctrl->value; + if(card->muted) + turn_power(card->io, 0); + else + set_freq(card->io, FREQ2BITS(card->freq)); + return 0; + } + return -EINVAL; + } + + default: + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + radio_function); + } } -- 2.7.4