diff options
Diffstat (limited to 'linux/drivers/media/radio')
-rw-r--r-- | linux/drivers/media/radio/Kconfig | 26 | ||||
-rw-r--r-- | linux/drivers/media/radio/miropcm20-rds.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-aimslab.c | 151 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-aztech.c | 166 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-gemtek-pci.c | 171 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-gemtek.c | 165 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-maestro.c | 206 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-maxiradio.c | 160 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-rtrack2.c | 163 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-sf16fmi.c | 154 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-sf16fmr2.c | 215 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-terratec.c | 154 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-trust.c | 189 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-typhoon.c | 171 | ||||
-rw-r--r-- | linux/drivers/media/radio/radio-zoltrix.c | 183 |
15 files changed, 1551 insertions, 724 deletions
diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index de3128a31..f43f5a21a 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -25,7 +25,7 @@ config RADIO_CADET config RADIO_RTRACK tristate "AIMSlab RadioTrack (aka RadioReveal) support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -59,7 +59,7 @@ config RADIO_RTRACK_PORT config RADIO_RTRACK2 tristate "AIMSlab RadioTrack II support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. @@ -82,7 +82,7 @@ config RADIO_RTRACK2_PORT config RADIO_AZTECH tristate "Aztech/Packard Bell Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. @@ -106,7 +106,7 @@ config RADIO_AZTECH_PORT config RADIO_GEMTEK tristate "GemTek Radio Card support" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. @@ -131,7 +131,7 @@ config RADIO_GEMTEK_PORT config RADIO_GEMTEK_PCI tristate "GemTek PCI Radio Card support" - depends on VIDEO_V4L1 && PCI + depends on VIDEO_V4L2 && PCI ---help--- Choose Y here if you have this PCI FM radio card. @@ -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. @@ -160,7 +160,7 @@ config RADIO_MAXIRADIO config RADIO_MAESTRO tristate "Maestro on board radio" - depends on VIDEO_V4L1 + depends on VIDEO_V4L2 && PCI ---help--- Say Y here to directly support the on-board radio tuner on the Maestro 2 or 2E sound card. @@ -208,7 +208,7 @@ config RADIO_MIROPCM20_RDS config RADIO_SF16FMI tristate "SF16FMI Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards. If you compile the driver into the kernel and your card is not PnP one, you @@ -225,7 +225,7 @@ config RADIO_SF16FMI config RADIO_SF16FMR2 tristate "SF16FMR2 Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards. @@ -239,7 +239,7 @@ config RADIO_SF16FMR2 config RADIO_TERRATEC tristate "TerraTec ActiveRadio ISA Standalone" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have this FM radio card, and then fill in the port address below. (TODO) @@ -268,7 +268,7 @@ config RADIO_TERRATEC_PORT config RADIO_TRUST tristate "Trust FM radio card" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 help This is a driver for the Trust FM radio cards. Say Y if you have such a card and want to use it under Linux. @@ -286,7 +286,7 @@ config RADIO_TRUST_PORT config RADIO_TYPHOON tristate "Typhoon Radio (a.k.a. EcoRadio)" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address and the frequency used for muting below. @@ -330,7 +330,7 @@ config RADIO_TYPHOON_MUTEFREQ config RADIO_ZOLTRIX tristate "Zoltrix Radio" - depends on ISA && VIDEO_V4L1 + depends on ISA && VIDEO_V4L2 ---help--- Choose Y here if you have one of these FM radio cards, and then fill in the port address below. diff --git a/linux/drivers/media/radio/miropcm20-rds.c b/linux/drivers/media/radio/miropcm20-rds.c index 87b37b769..c1b1db65e 100644 --- a/linux/drivers/media/radio/miropcm20-rds.c +++ b/linux/drivers/media/radio/miropcm20-rds.c @@ -115,7 +115,6 @@ static struct file_operations rds_fops = { static struct miscdevice rds_miscdev = { .minor = MISC_DYNAMIC_MINOR, .name = "radiotext", - .devfs_name = "v4l/rds/radiotext", .fops = &rds_fops, }; diff --git a/linux/drivers/media/radio/radio-aimslab.c b/linux/drivers/media/radio/radio-aimslab.c index d4fc66948..66c0ceb16 100644 --- a/linux/drivers/media/radio/radio-aimslab.c +++ b/linux/drivers/media/radio/radio-aimslab.c @@ -1,5 +1,6 @@ /* radiotrack (radioreveal) driver for Linux radio support * (c) 1997 M. Kirkwood + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> * Converted to new API by Alan Cox <Alan.Cox@linux.org> * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org> * @@ -34,11 +35,13 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_RTRACK_PORT */ #include <asm/semaphore.h> /* Lock for the I/O */ +#include <linux/version.h> /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) + #ifndef CONFIG_RADIO_RTRACK_PORT #define CONFIG_RADIO_RTRACK_PORT -1 #endif @@ -214,6 +217,25 @@ static int rt_getsigstr(struct rt_device *dev) return 1; /* signal present */ } +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 = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + static int rt_do_ioctl(struct inode *inode, struct file *file, unsigned int cmd, void *arg) { @@ -222,73 +244,114 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; - strcpy(v->name, "RadioTrack"); + strlcpy(v->driver, "radio-aimslab", sizeof (v->driver)); + strlcpy(v->card, "RadioTrack", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; + + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + v->rangelow=(87*16000); v->rangehigh=(108*16000); - v->flags=VIDEO_TUNER_LOW; - v->mode=VIDEO_MODE_AUTO; - strcpy(v->name, "FM"); + v->rxsubchans =V4L2_TUNER_SUB_MONO; + v->capability=V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; v->signal=0xFFFF*rt_getsigstr(rt); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - /* Only 1 tuner so no setting needed ! */ + return 0; } - case VIDIOCGFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - *freq = rt->curfreq; + struct v4l2_frequency *f = arg; + + rt->curfreq = f->frequency; + rt_setfreq(rt, rt->curfreq); return 0; } - case VIDIOCSFREQ: + case VIDIOC_G_FREQUENCY: { - unsigned long *freq = arg; - rt->curfreq = *freq; - rt_setfreq(rt, rt->curfreq); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = rt->curfreq; + return 0; } - case VIDIOCGAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; - v->volume=rt->curvol * 6554; - v->step=6554; - strcpy(v->name, "Radio"); - return 0; + 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 VIDIOCSAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - if(v->flags&VIDEO_AUDIO_MUTE) - rt_mute(rt); - else - rt_setvol(rt,v->volume/6554); - return 0; + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=rt->muted; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=rt->curvol * 6554; + return (0); + } + return -EINVAL; } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + rt_mute(rt); + } else { + rt_setvol(rt,rt->curvol); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + rt_setvol(rt,ctrl->value); + return (0); + } + return -EINVAL; + } + default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + rt_do_ioctl); } } @@ -314,7 +377,7 @@ static struct video_device rtrack_radio= .owner = THIS_MODULE, .name = "RadioTrack radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_RTRACK, + .hardware = 0, .fops = &rtrack_fops, }; diff --git a/linux/drivers/media/radio/radio-aztech.c b/linux/drivers/media/radio/radio-aztech.c index cfce2c89d..a59a6d209 100644 --- a/linux/drivers/media/radio/radio-aztech.c +++ b/linux/drivers/media/radio/radio-aztech.c @@ -1,5 +1,6 @@ /* radio-aztech.c - Aztech radio card driver for Linux 2.2 * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> * Adapted to support the Video for Linux API by * Russell Kroll <rkroll@exploits.org>. Based on original tuner code by: * @@ -31,9 +32,30 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_AZTECH_PORT */ + +#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 = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ @@ -171,81 +193,121 @@ static int az_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; - strcpy(v->name, "Aztech Radio"); + strlcpy(v->driver, "radio-aztech", sizeof (v->driver)); + strlcpy(v->card, "Aztech Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; + + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + v->rangelow=(87*16000); v->rangehigh=(108*16000); - v->flags=VIDEO_TUNER_LOW; - v->mode=VIDEO_MODE_AUTO; - v->signal=0xFFFF*az_getsigstr(az); + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; if(az_getstereo(az)) - v->flags|=VIDEO_TUNER_STEREO_ON; - strcpy(v->name, "FM"); + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xFFFF*az_getsigstr(az); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; + return 0; } - case VIDIOCGFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - *freq = az->curfreq; + struct v4l2_frequency *f = arg; + + az->curfreq = f->frequency; + az_setfreq(az, az->curfreq); return 0; } - case VIDIOCSFREQ: + case VIDIOC_G_FREQUENCY: { - unsigned long *freq = arg; - az->curfreq = *freq; - az_setfreq(az, az->curfreq); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = az->curfreq; + return 0; } - case VIDIOCGAUDIO: + + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; - if(az->stereo) - v->mode=VIDEO_SOUND_STEREO; - else - v->mode=VIDEO_SOUND_MONO; - v->volume=az->curvol; - v->step=16384; - strcpy(v->name, "Radio"); - return 0; + 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 VIDIOCSAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - az->curvol=v->volume; - - az->stereo=(v->mode&VIDEO_SOUND_STEREO)?1:0; - if(v->flags&VIDEO_AUDIO_MUTE) - az_setvol(az,0); - else - az_setvol(az,az->curvol); - return 0; + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (az->curvol==0) + ctrl->value=1; + else + ctrl->value=0; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=az->curvol * 6554; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + az_setvol(az,0); + } else { + az_setvol(az,az->curvol); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + az_setvol(az,ctrl->value); + return (0); + } + return -EINVAL; } + default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + az_do_ioctl); } } @@ -271,7 +333,7 @@ static struct video_device aztech_radio= .owner = THIS_MODULE, .name = "Aztech radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_AZTECH, + .hardware = 0, .fops = &aztech_fops, }; diff --git a/linux/drivers/media/radio/radio-gemtek-pci.c b/linux/drivers/media/radio/radio-gemtek-pci.c index 4afe9fb25..83c7e0e5c 100644 --- a/linux/drivers/media/radio/radio-gemtek-pci.c +++ b/linux/drivers/media/radio/radio-gemtek-pci.c @@ -34,20 +34,43 @@ * * TODO: multiple device support and portability were not tested * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> + * *************************************************************************** */ -#include <linux/config.h> #include <linux/types.h> #include <linux/list.h> #include <linux/module.h> #include <linux/init.h> #include <linux/pci.h> #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <media/v4l2-common.h> #include <linux/errno.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 = 65535, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #include <asm/io.h> #include <asm/uaccess.h> @@ -185,91 +208,117 @@ static int gemtek_pci_do_ioctl(struct inode *inode, struct file *file, struct gemtek_pci_card *card = dev->priv; switch ( cmd ) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *c = arg; + struct v4l2_capability *v = arg; + memset(v,0,sizeof(*v)); + strlcpy(v->driver, "radio-gemtek-pci", sizeof (v->driver)); + strlcpy(v->card, "GemTek PCI Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; - memset(c,0,sizeof(*c)); - c->type = VID_TYPE_TUNER; - c->channels = 1; - c->audios = 1; - strcpy( c->name, "Gemtek PCI Radio" ); return 0; } - - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *t = arg; + struct v4l2_tuner *v = arg; - if ( t->tuner ) + if (v->index > 0) return -EINVAL; - t->rangelow = GEMTEK_PCI_RANGE_LOW; - t->rangehigh = GEMTEK_PCI_RANGE_HIGH; - t->flags = VIDEO_TUNER_LOW; - t->mode = VIDEO_MODE_AUTO; - t->signal = 0xFFFF * gemtek_pci_getsignal( card ); - strcpy( t->name, "FM" ); + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + + v->rangelow = GEMTEK_PCI_RANGE_LOW; + v->rangehigh = GEMTEK_PCI_RANGE_HIGH; + v->rxsubchans =V4L2_TUNER_SUB_MONO; + v->capability=V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xFFFF*gemtek_pci_getsignal( card ); + return 0; } - - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *t = arg; - if ( t->tuner ) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - return 0; - } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = card->current_frequency; return 0; } - case VIDIOCSFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; + struct v4l2_frequency *f = arg; - if ( (*freq < GEMTEK_PCI_RANGE_LOW) || - (*freq > GEMTEK_PCI_RANGE_HIGH) ) + if ( (f->frequency < GEMTEK_PCI_RANGE_LOW) || + (f->frequency > GEMTEK_PCI_RANGE_HIGH) ) return -EINVAL; - gemtek_pci_setfrequency( card, *freq ); - card->current_frequency = *freq; - card->mute = FALSE; + gemtek_pci_setfrequency( card, f->frequency ); + card->current_frequency = f->frequency; + card->mute = FALSE; return 0; } - - case VIDIOCGAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *a = arg; - - memset( a, 0, sizeof( *a ) ); - a->flags |= VIDEO_AUDIO_MUTABLE; - a->volume = 1; - a->step = 65535; - strcpy( a->name, "Radio" ); - return 0; + 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 VIDIOCSAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *a = arg; - - if ( a->audio ) - return -EINVAL; - - if ( a->flags & VIDEO_AUDIO_MUTE ) - gemtek_pci_mute( card ); - else - gemtek_pci_unmute( card ); - return 0; + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=card->mute; + return (0); + case V4L2_CID_AUDIO_VOLUME: + if (card->mute) + ctrl->value=0; + else + ctrl->value=65535; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + gemtek_pci_mute(card); + } else { + gemtek_pci_unmute(card); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + if (ctrl->value) { + gemtek_pci_unmute(card); + } else { + gemtek_pci_mute(card); + } + return (0); + } + return -EINVAL; } - default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + gemtek_pci_do_ioctl); } } @@ -311,7 +360,7 @@ static struct video_device vdev_template = { .owner = THIS_MODULE, .name = "Gemtek PCI Radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_GEMTEK, + .hardware = 0, .fops = &gemtek_pci_fops, }; diff --git a/linux/drivers/media/radio/radio-gemtek.c b/linux/drivers/media/radio/radio-gemtek.c index f4b324148..c73f359a9 100644 --- a/linux/drivers/media/radio/radio-gemtek.c +++ b/linux/drivers/media/radio/radio-gemtek.c @@ -13,6 +13,7 @@ * * TODO: Allow for more than one of these foolish entities :-) * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> /* Modules */ @@ -22,11 +23,32 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_GEMTEK_PORT */ #include <linux/spinlock.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 = 65535, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #ifndef CONFIG_RADIO_GEMTEK_PORT #define CONFIG_RADIO_GEMTEK_PORT -1 #endif @@ -148,77 +170,122 @@ static int gemtek_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; - strcpy(v->name, "GemTek"); + strlcpy(v->driver, "radio-gemtek", sizeof (v->driver)); + strlcpy(v->card, "GemTek", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - v->rangelow=87*16000; - v->rangehigh=108*16000; - v->flags=VIDEO_TUNER_LOW; - v->mode=VIDEO_MODE_AUTO; - v->signal=0xFFFF*gemtek_getsigstr(rt); + + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + + v->rangelow=(87*16000); + v->rangehigh=(108*16000); + v->rxsubchans =V4L2_TUNER_SUB_MONO; + v->capability=V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xFFFF*gemtek_getsigstr(rt); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - /* Only 1 tuner so no setting needed ! */ - return 0; - } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = rt->curfreq; + return 0; } - case VIDIOCSFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - rt->curfreq = *freq; + struct v4l2_frequency *f = arg; + + rt->curfreq = f->frequency; /* needs to be called twice in order for getsigstr to work */ gemtek_setfreq(rt, rt->curfreq); gemtek_setfreq(rt, rt->curfreq); return 0; } - case VIDIOCGAUDIO: - { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags|=VIDEO_AUDIO_MUTABLE; - v->volume=1; - v->step=65535; - strcpy(v->name, "Radio"); - return 0; - } - case VIDIOCSAUDIO: + case VIDIOC_G_FREQUENCY: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; + struct v4l2_frequency *f = arg; - if(v->flags&VIDEO_AUDIO_MUTE) - gemtek_mute(rt); - else - gemtek_unmute(rt); + f->type = V4L2_TUNER_RADIO; + f->frequency = rt->curfreq; 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=rt->muted; + return (0); + case V4L2_CID_AUDIO_VOLUME: + if (rt->muted) + ctrl->value=0; + else + ctrl->value=65535; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + gemtek_mute(rt); + } else { + gemtek_unmute(rt); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + if (ctrl->value) { + gemtek_unmute(rt); + } else { + gemtek_mute(rt); + } + return (0); + } + return -EINVAL; + } default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + gemtek_do_ioctl); } } @@ -244,7 +311,7 @@ static struct video_device gemtek_radio= .owner = THIS_MODULE, .name = "GemTek radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_GEMTEK, + .hardware = 0, .fops = &gemtek_fops, }; diff --git a/linux/drivers/media/radio/radio-maestro.c b/linux/drivers/media/radio/radio-maestro.c index 972521d59..b23151fb0 100644 --- a/linux/drivers/media/radio/radio-maestro.c +++ b/linux/drivers/media/radio/radio-maestro.c @@ -14,6 +14,8 @@ * version 0.04 * + code improvements * + VIDEO_TUNER_LOW is permanent + * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> @@ -28,10 +30,23 @@ #include <linux/mutex.h> #endif #include <linux/pci.h> -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <media/v4l2-common.h> -#define DRIVER_VERSION "0.05" +#include <linux/version.h> /* for KERNEL_VERSION MACRO */ +#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 */ @@ -99,7 +114,7 @@ static struct file_operations maestro_fops = { static struct video_device maestro_radio = { .name = "Maestro radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_SF16MI, + .hardware = 0, .fops = &maestro_fops, }; @@ -137,7 +152,7 @@ static u32 radio_bits_get(struct radio_device *dev) rdata = inw(io); if(!l) dev->stereo = rdata & STR_MOST ? - 0 : VIDEO_TUNER_STEREO_ON; + 0 : 1; else if(rdata & STR_DATA) data++; @@ -190,72 +205,131 @@ static inline int radio_function(struct inode *inode, struct file *file, struct radio_device *card = video_get_drvdata(dev); switch (cmd) { - case VIDIOCGCAP: { - struct video_capability *v = arg; - memset(v, 0, sizeof(*v)); - strcpy(v->name, "Maestro radio"); - v->type = VID_TYPE_TUNER; - v->channels = v->audios = 1; - return 0; - } case VIDIOCGTUNER: { - struct video_tuner *v = arg; - if (v->tuner) - return -EINVAL; - (void)radio_bits_get(card); - v->flags = VIDEO_TUNER_LOW | card->stereo; - v->signal = card->tuned; - strcpy(v->name, "FM"); - v->rangelow = FREQ_LO; - v->rangehigh = FREQ_HI; - v->mode = VIDEO_MODE_AUTO; - return 0; - } case VIDIOCSTUNER: { - struct video_tuner *v = arg; - if (v->tuner != 0) - return -EINVAL; - return 0; - } case VIDIOCGFREQ: { - unsigned long *freq = arg; - *freq = BITS2FREQ(radio_bits_get(card)); - return 0; - } case VIDIOCSFREQ: { - unsigned long *freq = arg; - if (*freq < FREQ_LO || *freq > FREQ_HI) + case VIDIOC_QUERYCAP: + { + struct v4l2_capability *v = arg; + memset(v,0,sizeof(*v)); + strlcpy(v->driver, "radio-maestro", 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; + } + case VIDIOC_G_TUNER: + { + struct v4l2_tuner *v = arg; + + if (v->index > 0) + return -EINVAL; + + (void)radio_bits_get(card); + + memset(v,0,sizeof(*v)); + 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; + if(card->stereo) + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=card->tuned; + + return 0; + } + case VIDIOC_S_TUNER: + { + struct v4l2_tuner *v = arg; + + if (v->index > 0) + return -EINVAL; + + return 0; + } + case VIDIOC_S_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) + return -EINVAL; + radio_bits_set(card, FREQ2BITS(f->frequency)); + + return 0; + } + case VIDIOC_G_FREQUENCY: + { + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = BITS2FREQ(radio_bits_get(card)); + + 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; - radio_bits_set(card, FREQ2BITS(*freq)); - 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 VIDIOCSAUDIO: { - struct video_audio *v = arg; - if (v->audio) + } + 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; + } + case VIDIOC_S_CTRL: { - register u16 io = card->io; - register u16 omask = inw(io + IO_MASK); - outw(~STR_WREN, io + IO_MASK); - outw((card->muted = v->flags & VIDEO_AUDIO_MUTE) ? - STR_WREN : 0, io); - udelay(4); - outw(omask, io + IO_MASK); - msleep(125); + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + { + register u16 io = card->io; + register u16 omask = inw(io + IO_MASK); + outw(~STR_WREN, io + IO_MASK); + outw((card->muted = ctrl->value ) ? + STR_WREN : 0, io); + udelay(4); + outw(omask, io + IO_MASK); + msleep(125); + + return (0); + } + } + return -EINVAL; + } +#if 0 /* Probably, this is useless */ + 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 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; - } default: - return -ENOIOCTLCMD; +#endif + default: + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + radio_function); } } @@ -282,7 +356,7 @@ static u16 __devinit radio_power_on(struct radio_device *dev) 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 : VIDEO_AUDIO_MUTE; + 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); diff --git a/linux/drivers/media/radio/radio-maxiradio.c b/linux/drivers/media/radio/radio-maxiradio.c index a763e5630..151f14232 100644 --- a/linux/drivers/media/radio/radio-maxiradio.c +++ b/linux/drivers/media/radio/radio-maxiradio.c @@ -20,13 +20,14 @@ * 0.75b * - better pci interface thanks to Francois Romieu <romieu@cogenit.fr> * - * 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 <mchehab@infradead.org> */ @@ -43,11 +44,24 @@ #endif #include <linux/pci.h> -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <media/v4l2-common.h> -/* version 0.75 Sun Feb 4 22:51:27 EET 2001 */ -#define DRIVER_VERSION "0.75" +#define DRIVER_VERSION "0.76" + +#include <linux/version.h> /* 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 @@ -93,7 +107,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, }; @@ -183,78 +196,117 @@ 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 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; + } + 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); + +#if 0 /* Probably, this is useless */ case VIDIOCGUNIT: { struct video_unit *v = arg; @@ -265,7 +317,7 @@ static inline int radio_function(struct inode *inode, struct file *file, v->teletext=VIDEO_NO_UNIT; return 0; } - default: return -ENOIOCTLCMD; +#endif } } diff --git a/linux/drivers/media/radio/radio-rtrack2.c b/linux/drivers/media/radio/radio-rtrack2.c index c506262c4..b67baa467 100644 --- a/linux/drivers/media/radio/radio-rtrack2.c +++ b/linux/drivers/media/radio/radio-rtrack2.c @@ -6,6 +6,7 @@ * * TODO: Allow for more than one of these foolish entities :-) * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> /* Modules */ @@ -15,11 +16,32 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */ #include <linux/spinlock.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 = 65535, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #ifndef CONFIG_RADIO_RTRACK2_PORT #define CONFIG_RADIO_RTRACK2_PORT -1 #endif @@ -116,75 +138,120 @@ static int rt_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; - strcpy(v->name, "RadioTrack II"); + strlcpy(v->driver, "radio-rtrack2", sizeof (v->driver)); + strlcpy(v->card, "RadioTrack II", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - v->rangelow=88*16000; - v->rangehigh=108*16000; - v->flags=VIDEO_TUNER_LOW; - v->mode=VIDEO_MODE_AUTO; - v->signal=0xFFFF*rt_getsigstr(rt); + + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + + v->rangelow=(88*16000); + v->rangehigh=(108*16000); + v->rxsubchans =V4L2_TUNER_SUB_MONO; + v->capability=V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=0xFFFF*rt_getsigstr(rt); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - /* Only 1 tuner so no setting needed ! */ + return 0; } - case VIDIOCGFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - *freq = rt->curfreq; + struct v4l2_frequency *f = arg; + + rt->curfreq = f->frequency; + rt_setfreq(rt, rt->curfreq); return 0; } - case VIDIOCSFREQ: + case VIDIOC_G_FREQUENCY: { - unsigned long *freq = arg; - rt->curfreq = *freq; - rt_setfreq(rt, rt->curfreq); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = rt->curfreq; + return 0; } - case VIDIOCGAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags|=VIDEO_AUDIO_MUTABLE; - v->volume=1; - v->step=65535; - strcpy(v->name, "Radio"); - return 0; + 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 VIDIOCSAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - - if(v->flags&VIDEO_AUDIO_MUTE) - rt_mute(rt); - else - rt_unmute(rt); - - return 0; + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=rt->muted; + return (0); + case V4L2_CID_AUDIO_VOLUME: + if (rt->muted) + ctrl->value=0; + else + ctrl->value=65535; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + rt_mute(rt); + } else { + rt_unmute(rt); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + if (ctrl->value) { + rt_unmute(rt); + } else { + rt_mute(rt); + } + return (0); + } + return -EINVAL; } default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + rt_do_ioctl); } } @@ -210,7 +277,7 @@ static struct video_device rtrack2_radio= .owner = THIS_MODULE, .name = "RadioTrack II radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_RTRACK2, + .hardware = 0, .fops = &rtrack2_fops, }; diff --git a/linux/drivers/media/radio/radio-sf16fmi.c b/linux/drivers/media/radio/radio-sf16fmi.c index 68ff1782d..d01be8852 100644 --- a/linux/drivers/media/radio/radio-sf16fmi.c +++ b/linux/drivers/media/radio/radio-sf16fmi.c @@ -13,15 +13,17 @@ * No volume control - only mute/unmute - you have to use line volume * control on SB-part of SF16FMI * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ +#include <linux/version.h> #include <linux/kernel.h> /* __setup */ #include <linux/module.h> /* Modules */ #include <linux/init.h> /* Initdata */ #include <linux/ioport.h> /* request_region */ #include <linux/delay.h> /* udelay */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> #include <linux/isapnp.h> #include <asm/io.h> /* outb, outb_p */ @@ -30,6 +32,19 @@ #include <linux/mutex.h> #endif +#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 { int port; @@ -130,81 +145,120 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - strcpy(v->name, "SF16-FMx radio"); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; + strlcpy(v->driver, "radio-sf16fmi", sizeof (v->driver)); + strlcpy(v->card, "SF16-FMx radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; + struct v4l2_tuner *v = arg; int mult; - if(v->tuner) /* Only 1 tuner */ + if (v->index > 0) return -EINVAL; + + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); - mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000; + 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->flags=fmi->flags; - v->mode=VIDEO_MODE_AUTO; + v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; + v->capability=fmi->flags&V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_STEREO; v->signal = fmi_getsigstr(fmi); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - fmi->flags = v->flags & VIDEO_TUNER_LOW; - /* Only 1 tuner so no setting needed ! */ - return 0; - } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = fmi->curfreq; - if (!(fmi->flags & VIDEO_TUNER_LOW)) - *freq /= 1000; + return 0; } - case VIDIOCSFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - if (!(fmi->flags & VIDEO_TUNER_LOW)) - *freq *= 1000; - if (*freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ ) + struct v4l2_frequency *f = arg; + + if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) + f->frequency *= 1000; + if (f->frequency < RSF16_MINFREQ || + f->frequency > RSF16_MAXFREQ ) return -EINVAL; /*rounding in steps of 800 to match th freq that will be used */ - fmi->curfreq = (*freq/800)*800; + fmi->curfreq = (f->frequency/800)*800; fmi_setfreq(fmi); + return 0; } - case VIDIOCGAUDIO: + case VIDIOC_G_FREQUENCY: { - struct video_audio *v = arg; - memset(v,0,sizeof(*v)); - v->flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE); - strcpy(v->name, "Radio"); - v->mode=VIDEO_SOUND_STEREO; + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = fmi->curfreq; + if (!(fmi->flags & V4L2_TUNER_CAP_LOW)) + f->frequency /= 1000; + return 0; } - case VIDIOCSAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - fmi->curvol= v->flags&VIDEO_AUDIO_MUTE ? 0 : 1; - fmi->curvol ? - fmi_unmute(fmi->port) : fmi_mute(fmi->port); - return 0; + 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=fmi->curvol; + return (0); + } + return -EINVAL; } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + { + if (ctrl->value) + fmi_mute(fmi->port); + else + fmi_unmute(fmi->port); + + fmi->curvol=ctrl->value; + return (0); + } + } + return -EINVAL; + } +#if 0 /* Probably, this is useless */ case VIDIOCGUNIT: { struct video_unit *v = arg; @@ -215,8 +269,10 @@ static int fmi_do_ioctl(struct inode *inode, struct file *file, v->teletext=VIDEO_NO_UNIT; return 0; } +#endif default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + fmi_do_ioctl); } } @@ -242,7 +298,7 @@ static struct video_device fmi_radio= .owner = THIS_MODULE, .name = "SF16FMx radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_SF16MI, + .hardware = 0, .fops = &fmi_fops, }; @@ -301,7 +357,7 @@ static int __init fmi_init(void) fmi_unit.port = io; fmi_unit.curvol = 0; fmi_unit.curfreq = 0; - fmi_unit.flags = VIDEO_TUNER_LOW; + fmi_unit.flags = V4L2_TUNER_CAP_LOW; fmi_radio.priv = &fmi_unit; mutex_init(&lock); diff --git a/linux/drivers/media/radio/radio-sf16fmr2.c b/linux/drivers/media/radio/radio-sf16fmr2.c index b292fe54e..bb5ccf55d 100644 --- a/linux/drivers/media/radio/radio-sf16fmr2.c +++ b/linux/drivers/media/radio/radio-sf16fmr2.c @@ -10,6 +10,8 @@ * For read stereo/mono you must wait 0.1 sec after set frequency and * card unmuted so I set frequency on unmute * Signal handling seem to work only on autoscanning (not implemented) + * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> /* Modules */ @@ -19,7 +21,7 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,15) #include <linux/mutex.h> @@ -29,6 +31,28 @@ static struct mutex lock; static struct semaphore lock; #endif +#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 = 1<<12, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #undef DEBUG //#define DEBUG 1 @@ -219,63 +243,65 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - strcpy(v->name, "SF16-FMR2 radio"); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; + strlcpy(v->driver, "radio-sf16fmr2", sizeof (v->driver)); + strlcpy(v->card, "SF16-FMR2 radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; + struct v4l2_tuner *v = arg; int mult; - if(v->tuner) /* Only 1 tuner */ + if (v->index > 0) return -EINVAL; + + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); - mult = (fmr2->flags & VIDEO_TUNER_LOW) ? 1 : 1000; + v->type = V4L2_TUNER_RADIO; + + mult = (fmr2->flags & V4L2_TUNER_CAP_LOW) ? 1 : 1000; v->rangelow = RSF16_MINFREQ/mult; v->rangehigh = RSF16_MAXFREQ/mult; - v->flags = fmr2->flags | VIDEO_AUDIO_MUTABLE; - if (fmr2->mute) - v->flags |= VIDEO_AUDIO_MUTE; - v->mode=VIDEO_MODE_AUTO; + v->rxsubchans =V4L2_TUNER_SUB_MONO | V4L2_TUNER_MODE_STEREO; + v->capability=fmr2->flags&V4L2_TUNER_CAP_LOW; + + v->audmode = fmr2->stereo ? V4L2_TUNER_MODE_STEREO: + V4L2_TUNER_MODE_MONO; mutex_lock(&lock); v->signal = fmr2_getsigstr(fmr2); mutex_unlock(&lock); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if (v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - fmr2->flags = v->flags & VIDEO_TUNER_LOW; - return 0; - } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = fmr2->curfreq; - if (!(fmr2->flags & VIDEO_TUNER_LOW)) - *freq /= 1000; + return 0; } - case VIDIOCSFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - if (!(fmr2->flags & VIDEO_TUNER_LOW)) - *freq *= 1000; - if ( *freq < RSF16_MINFREQ || *freq > RSF16_MAXFREQ ) + struct v4l2_frequency *f = arg; + + if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) + f->frequency *= 1000; + if (f->frequency < RSF16_MINFREQ || + f->frequency > RSF16_MAXFREQ ) return -EINVAL; - /* rounding in steps of 200 to match th freq - * that will be used - */ - fmr2->curfreq = (*freq/200)*200; + /*rounding in steps of 200 to match th freq + that will be used */ + fmr2->curfreq = (f->frequency/200)*200; /* set card freq (if not muted) */ if (fmr2->curvol && !fmr2->mute) @@ -284,40 +310,81 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, fmr2_setfreq(fmr2); mutex_unlock(&lock); } + return 0; } - case VIDIOCGAUDIO: + case VIDIOC_G_FREQUENCY: { - struct video_audio *v = arg; - memset(v,0,sizeof(*v)); - /* !!! do not return VIDEO_AUDIO_MUTE */ - v->flags = VIDEO_AUDIO_MUTABLE; - strcpy(v->name, "Radio"); - /* get current stereo mode */ - v->mode = fmr2->stereo ? VIDEO_SOUND_STEREO: VIDEO_SOUND_MONO; - /* volume supported ? */ - if (fmr2->card_type == 11) - { - v->flags |= VIDEO_AUDIO_VOLUME; - v->step = 1 << 12; - v->volume = fmr2->curvol; - } - debug_print((KERN_DEBUG "Get flags %d vol %d\n", v->flags, v->volume)); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = fmr2->curfreq; + if (!(fmr2->flags & V4L2_TUNER_CAP_LOW)) + f->frequency /= 1000; + return 0; } - case VIDIOCSAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - debug_print((KERN_DEBUG "Set flags %d vol %d\n", v->flags, v->volume)); - /* set volume */ - if (v->flags & VIDEO_AUDIO_VOLUME) - fmr2->curvol = v->volume; /* !!! set with precision */ - if (fmr2->card_type != 11) fmr2->curvol = 65535; - fmr2->mute = 0; - if (v->flags & VIDEO_AUDIO_MUTE) - fmr2->mute = 1; + struct v4l2_queryctrl *qc = arg; + int i; + + for (i = 0; i < ARRAY_SIZE(radio_qctrl); i++) { + if ((fmr2->card_type != 11) + && V4L2_CID_AUDIO_VOLUME) + radio_qctrl[i].step=65535; + 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=fmr2->mute; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=fmr2->curvol; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + fmr2->mute=ctrl->value; + if (fmr2->card_type != 11) { + if (!fmr2->mute) { + fmr2->curvol = 65535; + } else { + fmr2->curvol = 0; + } + } + break; + case V4L2_CID_AUDIO_VOLUME: + fmr2->curvol = ctrl->value; + if (fmr2->card_type != 11) { + if (fmr2->curvol) { + fmr2->curvol = 65535; + fmr2->mute = 0; + } else { + fmr2->curvol = 0; + fmr2->mute = 1; + } + } + break; + default: + return -EINVAL; + } #ifdef DEBUG if (fmr2->curvol && !fmr2->mute) printk(KERN_DEBUG "unmute\n"); @@ -325,15 +392,15 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, printk(KERN_DEBUG "mute\n"); #endif mutex_lock(&lock); - if (fmr2->curvol && !fmr2->mute) - { + if (fmr2->curvol && !fmr2->mute) { fmr2_setvolume(fmr2); fmr2_setfreq(fmr2); - } - else fmr2_mute(fmr2->port); + } else + fmr2_mute(fmr2->port); mutex_unlock(&lock); - return 0; + return (0); } +#if 0 case VIDIOCGUNIT: { struct video_unit *v = arg; @@ -344,8 +411,11 @@ static int fmr2_do_ioctl(struct inode *inode, struct file *file, v->teletext=VIDEO_NO_UNIT; return 0; } +#endif default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + fmr2_do_ioctl); + } } @@ -371,7 +441,7 @@ static struct video_device fmr2_radio= .owner = THIS_MODULE, .name = "SF16FMR2 radio", . type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_SF16FMR2, + .hardware = 0, .fops = &fmr2_fops, }; @@ -382,7 +452,7 @@ static int __init fmr2_init(void) fmr2_unit.mute = 0; fmr2_unit.curfreq = 0; fmr2_unit.stereo = 1; - fmr2_unit.flags = VIDEO_TUNER_LOW; + fmr2_unit.flags = V4L2_TUNER_CAP_LOW; fmr2_unit.card_type = 0; fmr2_radio.priv = &fmr2_unit; @@ -401,7 +471,6 @@ static int __init fmr2_init(void) } printk(KERN_INFO "SF16FMR2 radio card driver at 0x%x.\n", io); - debug_print((KERN_DEBUG "Mute %d Low %d\n",VIDEO_AUDIO_MUTE,VIDEO_TUNER_LOW)); /* mute card - prevents noisy bootups */ mutex_lock(&lock); fmr2_mute(io); diff --git a/linux/drivers/media/radio/radio-terratec.c b/linux/drivers/media/radio/radio-terratec.c index a12c5e6de..5641510ef 100644 --- a/linux/drivers/media/radio/radio-terratec.c +++ b/linux/drivers/media/radio/radio-terratec.c @@ -21,6 +21,7 @@ * If you can help me out with that, please contact me!! * * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> /* Modules */ @@ -30,11 +31,32 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_TERRATEC_PORT */ #include <linux/spinlock.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 = 0xff, + .step = 1, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #ifndef CONFIG_RADIO_TERRATEC_PORT #define CONFIG_RADIO_TERRATEC_PORT 0x590 #endif @@ -195,73 +217,117 @@ static int tt_do_ioctl(struct inode *inode, struct file *file, switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; - strcpy(v->name, "ActiveRadio"); + strlcpy(v->driver, "radio-terratec", sizeof (v->driver)); + strlcpy(v->card, "ActiveRadio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; + + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + v->rangelow=(87*16000); v->rangehigh=(108*16000); - v->flags=VIDEO_TUNER_LOW; - v->mode=VIDEO_MODE_AUTO; - strcpy(v->name, "FM"); + v->rxsubchans =V4L2_TUNER_SUB_MONO; + v->capability=V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; v->signal=0xFFFF*tt_getsigstr(tt); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner!=0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - /* Only 1 tuner so no setting needed ! */ + return 0; } - case VIDIOCGFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - *freq = tt->curfreq; + struct v4l2_frequency *f = arg; + + tt->curfreq = f->frequency; + tt_setfreq(tt, tt->curfreq); return 0; } - case VIDIOCSFREQ: + case VIDIOC_G_FREQUENCY: { - unsigned long *freq = arg; - tt->curfreq = *freq; - tt_setfreq(tt, tt->curfreq); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = tt->curfreq; + return 0; } - case VIDIOCGAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - memset(v,0, sizeof(*v)); - v->flags|=VIDEO_AUDIO_MUTABLE|VIDEO_AUDIO_VOLUME; - v->volume=tt->curvol * 6554; - v->step=6554; - strcpy(v->name, "Radio"); - return 0; + 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 VIDIOCSAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *v = arg; - if(v->audio) - return -EINVAL; - if(v->flags&VIDEO_AUDIO_MUTE) - tt_mute(tt); - else - tt_setvol(tt,v->volume/6554); - return 0; + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (tt->muted) + ctrl->value=1; + else + ctrl->value=0; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=tt->curvol * 6554; + return (0); + } + return -EINVAL; } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + tt_mute(tt); + } else { + tt_setvol(tt,tt->curvol); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + tt_setvol(tt,ctrl->value); + return (0); + } + return -EINVAL; + } + default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + tt_do_ioctl); } } @@ -287,7 +353,7 @@ static struct video_device terratec_radio= .owner = THIS_MODULE, .name = "TerraTec ActiveRadio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_TERRATEC, + .hardware = 0, .fops = &terratec_fops, }; diff --git a/linux/drivers/media/radio/radio-trust.c b/linux/drivers/media/radio/radio-trust.c index 40ca85954..e0c13a913 100644 --- a/linux/drivers/media/radio/radio-trust.c +++ b/linux/drivers/media/radio/radio-trust.c @@ -12,7 +12,7 @@ * Scott McGrath (smcgrath@twilight.vtc.vsc.edu) * William McGrath (wmcgrath@twilight.vtc.vsc.edu) * - * The basis for this code may be found at http://bigbang.vtc.vsc.edu/fmradio/ + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <stdarg.h> @@ -22,9 +22,46 @@ #include <asm/io.h> #include <asm/uaccess.h> #include "compat.h" -#include <linux/videodev.h> +#include <linux/videodev2.h> #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_TRUST_PORT */ + +#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 = 2048, + .default_value = 65535, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_BASS, + .name = "Bass", + .minimum = 0, + .maximum = 65535, + .step = 4370, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, + },{ + .id = V4L2_CID_AUDIO_TREBLE, + .name = "Treble", + .minimum = 0, + .maximum = 65535, + .step = 4370, + .default_value = 32768, + .type = V4L2_CTRL_TYPE_INTEGER, + }, +}; /* acceptable ports: 0x350 (JP3 shorted), 0x358 (JP3 open) */ @@ -161,88 +198,128 @@ static int tr_do_ioctl(struct inode *inode, struct file *file, { switch(cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; - + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type=VID_TYPE_TUNER; - v->channels=1; - v->audios=1; - strcpy(v->name, "Trust FM Radio"); + strlcpy(v->driver, "radio-trust", sizeof (v->driver)); + strlcpy(v->card, "Trust FM Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; + struct v4l2_tuner *v = arg; - if(v->tuner) /* Only 1 tuner */ + if (v->index > 0) return -EINVAL; - v->rangelow = 87500 * 16; - v->rangehigh = 108000 * 16; - v->flags = VIDEO_TUNER_LOW; - v->mode = VIDEO_MODE_AUTO; + memset(v,0,sizeof(*v)); + strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; - v->signal = tr_getsigstr(); + v->rangelow=(87.5*16000); + v->rangehigh=(108*16000); + v->rxsubchans =V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; + v->capability=V4L2_TUNER_CAP_LOW; if(tr_getstereo()) - v->flags |= VIDEO_TUNER_STEREO_ON; - - strcpy(v->name, "FM"); + v->audmode = V4L2_TUNER_MODE_STEREO; + else + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal=tr_getsigstr(); return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if(v->tuner != 0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; + return 0; } - case VIDIOCGFREQ: + case VIDIOC_S_FREQUENCY: { - unsigned long *freq = arg; - *freq = curfreq; + struct v4l2_frequency *f = arg; + + curfreq = f->frequency; + tr_setfreq(curfreq); return 0; } - case VIDIOCSFREQ: + case VIDIOC_G_FREQUENCY: { - unsigned long *freq = arg; - tr_setfreq(*freq); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = curfreq; + return 0; } - case VIDIOCGAUDIO: + case VIDIOC_QUERYCTRL: { - struct video_audio *v = arg; - - memset(v,0, sizeof(*v)); - v->flags = VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME | - VIDEO_AUDIO_BASS | VIDEO_AUDIO_TREBLE; - v->mode = curstereo? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; - v->volume = curvol * 2048; - v->step = 2048; - v->bass = curbass * 4370; - v->treble = curtreble * 4370; - - strcpy(v->name, "Trust FM Radio"); - return 0; + 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 VIDIOCSAUDIO: + case VIDIOC_G_CTRL: { - struct video_audio *v = arg; - - if(v->audio) - return -EINVAL; - tr_setvol(v->volume); - tr_setbass(v->bass); - tr_settreble(v->treble); + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + ctrl->value=curmute; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value= curvol * 2048; + return (0); + case V4L2_CID_AUDIO_BASS: + ctrl->value= curbass * 4370; + return (0); + case V4L2_CID_AUDIO_TREBLE: + ctrl->value= curtreble * 4370; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + tr_setmute(ctrl->value); + return 0; + case V4L2_CID_AUDIO_VOLUME: + tr_setvol(ctrl->value); + return 0; + case V4L2_CID_AUDIO_BASS: + tr_setbass(ctrl->value); + return 0; + case V4L2_CID_AUDIO_TREBLE: + tr_settreble(ctrl->value); + return (0); + } +#if 0 /* Should implement mono/stereo on V4L2 */ tr_setstereo(v->mode & VIDEO_SOUND_STEREO); - tr_setmute(v->flags & VIDEO_AUDIO_MUTE); - return 0; +#endif + return -EINVAL; } + default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + tr_do_ioctl); } } @@ -266,7 +343,7 @@ static struct video_device trust_radio= .owner = THIS_MODULE, .name = "Trust FM Radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_TRUST, + .hardware = 0, .fops = &trust_fops, }; diff --git a/linux/drivers/media/radio/radio-typhoon.c b/linux/drivers/media/radio/radio-typhoon.c index 4f5adce15..121acd778 100644 --- a/linux/drivers/media/radio/radio-typhoon.c +++ b/linux/drivers/media/radio/radio-typhoon.c @@ -27,6 +27,8 @@ * value where I do expect just noise and turn the speaker volume down. * The frequency change is necessary since the card never seems to be * completely silent. + * + * Converted to V4L2 API by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> /* Modules */ @@ -36,11 +38,32 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_TYPHOON_* */ -#define BANNER "Typhoon Radio Card driver v0.1\n" +#include <linux/version.h> /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,1,1) +#define BANNER "Typhoon Radio Card driver v0.1.1\n" + +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 = 1<<14, + .default_value = 0xff, + .type = V4L2_CTRL_TYPE_INTEGER, + } +}; + #ifndef CONFIG_RADIO_TYPHOON_PORT #define CONFIG_RADIO_TYPHOON_PORT -1 @@ -176,76 +199,114 @@ static int typhoon_do_ioctl(struct inode *inode, struct file *file, struct typhoon_device *typhoon = dev->priv; switch (cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type = VID_TYPE_TUNER; - v->channels = 1; - v->audios = 1; - strcpy(v->name, "Typhoon Radio"); + strlcpy(v->driver, "radio-typhoon", sizeof (v->driver)); + strlcpy(v->card, "Typhoon Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if (v->tuner) /* Only 1 tuner */ + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - v->rangelow = 875 * 1600; - v->rangehigh = 1080 * 1600; - v->flags = VIDEO_TUNER_LOW; - v->mode = VIDEO_MODE_AUTO; - v->signal = 0xFFFF; /* We can't get the signal strength */ + + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); + v->type = V4L2_TUNER_RADIO; + + v->rangelow=(87.5*16000); + v->rangehigh=(108*16000); + v->rxsubchans =V4L2_TUNER_SUB_MONO; + v->capability=V4L2_TUNER_CAP_LOW; + v->audmode = V4L2_TUNER_MODE_MONO; + v->signal = 0xFFFF; /* We can't get the signal strength */ + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if (v->tuner != 0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - /* Only 1 tuner so no setting needed ! */ + return 0; } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = typhoon->curfreq; - return 0; - } - case VIDIOCSFREQ: - { - unsigned long *freq = arg; - typhoon->curfreq = *freq; - typhoon_setfreq(typhoon, typhoon->curfreq); - return 0; - } - case VIDIOCGAUDIO: + case VIDIOC_S_FREQUENCY: { - struct video_audio *v = arg; - memset(v, 0, sizeof(*v)); - v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; - v->mode |= VIDEO_SOUND_MONO; - v->volume = typhoon->curvol; - v->step = 1 << 14; - strcpy(v->name, "Typhoon Radio"); + struct v4l2_frequency *f = arg; + + typhoon->curfreq = f->frequency; + typhoon_setfreq(typhoon, typhoon->curfreq); return 0; } - case VIDIOCSAUDIO: + case VIDIOC_G_FREQUENCY: { - struct video_audio *v = arg; - if (v->audio) - return -EINVAL; - if (v->flags & VIDEO_AUDIO_MUTE) - typhoon_mute(typhoon); - else - typhoon_unmute(typhoon); - if (v->flags & VIDEO_AUDIO_VOLUME) - typhoon_setvol(typhoon, v->volume); + struct v4l2_frequency *f = arg; + + f->type = V4L2_TUNER_RADIO; + f->frequency = typhoon->curfreq; + return 0; } - default: - return -ENOIOCTLCMD; + 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=typhoon->muted; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=typhoon->curvol; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + typhoon_mute(typhoon); + } else { + typhoon_unmute(typhoon); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + typhoon_setvol(typhoon, ctrl->value); + return (0); + } + return -EINVAL; + } + + default: + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + typhoon_do_ioctl); } } @@ -276,7 +337,7 @@ static struct video_device typhoon_radio = .owner = THIS_MODULE, .name = "Typhoon Radio", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_TYPHOON, + .hardware = 0, .fops = &typhoon_fops, }; diff --git a/linux/drivers/media/radio/radio-zoltrix.c b/linux/drivers/media/radio/radio-zoltrix.c index 0f7e54952..db3681267 100644 --- a/linux/drivers/media/radio/radio-zoltrix.c +++ b/linux/drivers/media/radio/radio-zoltrix.c @@ -24,6 +24,9 @@ * - Added unmute function * - Reworked ioctl functions * 2002-07-15 - Fix Stereo typo + * + * 2006-07-24 - Converted to V4L2 API + * by Mauro Carvalho Chehab <mchehab@infradead.org> */ #include <linux/module.h> /* Modules */ @@ -33,9 +36,30 @@ #include <asm/io.h> /* outb, outb_p */ #include <asm/uaccess.h> /* copy to/from user */ #include "compat.h" -#include <linux/videodev.h> /* kernel radio structs */ +#include <linux/videodev2.h> /* kernel radio structs */ #include <media/v4l2-common.h> -#include <linux/config.h> /* CONFIG_RADIO_ZOLTRIX_PORT */ + +#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, + } +}; #ifndef CONFIG_RADIO_ZOLTRIX_PORT #define CONFIG_RADIO_ZOLTRIX_PORT -1 @@ -218,78 +242,116 @@ static int zol_do_ioctl(struct inode *inode, struct file *file, struct zol_device *zol = dev->priv; switch (cmd) { - case VIDIOCGCAP: + case VIDIOC_QUERYCAP: { - struct video_capability *v = arg; - + struct v4l2_capability *v = arg; memset(v,0,sizeof(*v)); - v->type = VID_TYPE_TUNER; - v->channels = 1 + zol->stereo; - v->audios = 1; - strcpy(v->name, "Zoltrix Radio"); + strlcpy(v->driver, "radio-zoltrix", sizeof (v->driver)); + strlcpy(v->card, "Zoltrix Radio", sizeof (v->card)); + sprintf(v->bus_info,"ISA"); + v->version = RADIO_VERSION; + v->capabilities = V4L2_CAP_TUNER; + return 0; } - case VIDIOCGTUNER: + case VIDIOC_G_TUNER: { - struct video_tuner *v = arg; - if (v->tuner) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; + + memset(v,0,sizeof(*v)); strcpy(v->name, "FM"); - v->rangelow = (int) (88.0 * 16000); - v->rangehigh = (int) (108.0 * 16000); - v->flags = zol_is_stereo(zol) - ? VIDEO_TUNER_STEREO_ON : 0; - v->flags |= VIDEO_TUNER_LOW; - v->mode = VIDEO_MODE_AUTO; - v->signal = 0xFFFF * zol_getsigstr(zol); + v->type = V4L2_TUNER_RADIO; + + 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); + return 0; } - case VIDIOCSTUNER: + case VIDIOC_S_TUNER: { - struct video_tuner *v = arg; - if (v->tuner != 0) + struct v4l2_tuner *v = arg; + + if (v->index > 0) return -EINVAL; - /* Only 1 tuner so no setting needed ! */ + return 0; } - case VIDIOCGFREQ: - { - unsigned long *freq = arg; - *freq = zol->curfreq; - return 0; - } - case VIDIOCSFREQ: - { - unsigned long *freq = arg; - zol->curfreq = *freq; - zol_setfreq(zol, zol->curfreq); - return 0; - } - case VIDIOCGAUDIO: + case VIDIOC_S_FREQUENCY: { - struct video_audio *v = arg; - memset(v, 0, sizeof(*v)); - v->flags |= VIDEO_AUDIO_MUTABLE | VIDEO_AUDIO_VOLUME; - v->mode |= zol_is_stereo(zol) - ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO; - v->volume = zol->curvol * 4096; - v->step = 4096; - strcpy(v->name, "Zoltrix Radio"); + struct v4l2_frequency *f = arg; + + zol->curfreq = f->frequency; + zol_setfreq(zol, zol->curfreq); return 0; } - case VIDIOCSAUDIO: + case VIDIOC_G_FREQUENCY: { - struct video_audio *v = arg; - if (v->audio) - return -EINVAL; + struct v4l2_frequency *f = arg; - if (v->flags & VIDEO_AUDIO_MUTE) - zol_mute(zol); - else { - zol_unmute(zol); - zol_setvol(zol, v->volume / 4096); - } + f->type = V4L2_TUNER_RADIO; + f->frequency = zol->curfreq; + 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=zol->muted; + return (0); + case V4L2_CID_AUDIO_VOLUME: + ctrl->value=zol->curvol * 4096; + return (0); + } + return -EINVAL; + } + case VIDIOC_S_CTRL: + { + struct v4l2_control *ctrl= arg; + + switch (ctrl->id) { + case V4L2_CID_AUDIO_MUTE: + if (ctrl->value) { + zol_mute(zol); + } else { + zol_unmute(zol); + zol_setvol(zol,zol->curvol); + } + return (0); + case V4L2_CID_AUDIO_VOLUME: + zol_setvol(zol,ctrl->value/4096); + return (0); + } + zol->stereo = 1; + zol_setfreq(zol, zol->curfreq); +#if 0 /*keep*/ +/* FIXME: Implement stereo/mono switch on V4L2 */ if (v->mode & VIDEO_SOUND_STEREO) { zol->stereo = 1; zol_setfreq(zol, zol->curfreq); @@ -298,10 +360,13 @@ static int zol_do_ioctl(struct inode *inode, struct file *file, zol->stereo = 0; zol_setfreq(zol, zol->curfreq); } - return 0; +#endif + return -EINVAL; } - default: - return -ENOIOCTLCMD; + + default: + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + zol_do_ioctl); } } @@ -328,7 +393,7 @@ static struct video_device zoltrix_radio = .owner = THIS_MODULE, .name = "Zoltrix Radio Plus", .type = VID_TYPE_TUNER, - .hardware = VID_HARDWARE_ZOLTRIX, + .hardware = 0, .fops = &zoltrix_fops, }; |