X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fmedia%2Fradio%2Fradio-sf16fmr2.c;h=4444dce864a932ddeaad7ec8790ca42354d5c9bd;hb=refs%2Fheads%2Fvserver;hp=7e980d15f317a2c88cce01ce1617941da0b751b6;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/drivers/media/radio/radio-sf16fmr2.c b/drivers/media/radio/radio-sf16fmr2.c index 7e980d15f..4444dce86 100644 --- a/drivers/media/radio/radio-sf16fmr2.c +++ b/drivers/media/radio/radio-sf16fmr2.c @@ -10,18 +10,43 @@ * 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 */ #include /* Modules */ #include /* Initdata */ -#include /* check_region, request_region */ +#include /* request_region */ #include /* udelay */ #include /* outb, outb_p */ #include /* copy to/from user */ -#include /* kernel radio structs */ -#include +#include /* kernel radio structs */ +#include +#include + +static struct mutex lock; + +#include /* for KERNEL_VERSION MACRO */ +#define RADIO_VERSION KERNEL_VERSION(0,0,2) -static struct semaphore lock; +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 @@ -48,7 +73,7 @@ static int io = 0x384; static int radio_nr = -1; /* hw precision is 12.5 kHz - * It is only usefull to give freq in intervall of 200 (=0.0125Mhz), + * It is only useful to give freq in intervall of 200 (=0.0125Mhz), * other bits will be truncated */ #define RSF16_ENCODE(x) ((x)/200+856) @@ -202,7 +227,7 @@ static int fmr2_setvolume(struct fmr2_device *dev) } static int fmr2_do_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, void *arg) + unsigned int cmd, void *arg) { struct video_device *dev = video_devdata(file); struct fmr2_device *fmr2 = dev->priv; @@ -213,138 +238,172 @@ 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; - down(&lock); + 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); - up(&lock); + 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) { - down(&lock); + mutex_lock(&lock); fmr2_setfreq(fmr2); - up(&lock); + 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"); else printk(KERN_DEBUG "mute\n"); #endif - down(&lock); - if (fmr2->curvol && !fmr2->mute) - { + mutex_lock(&lock); + if (fmr2->curvol && !fmr2->mute) { fmr2_setvolume(fmr2); fmr2_setfreq(fmr2); - } - else fmr2_mute(fmr2->port); - up(&lock); - 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; /* How do we find out this??? */ - v->teletext=VIDEO_NO_UNIT; - return 0; + } else + fmr2_mute(fmr2->port); + mutex_unlock(&lock); + return (0); } default: - return -ENOIOCTLCMD; + return v4l_compat_translate_ioctl(inode,file,cmd,arg, + fmr2_do_ioctl); + } } static int fmr2_ioctl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) + unsigned int cmd, unsigned long arg) { return video_usercopy(inode, file, cmd, arg, fmr2_do_ioctl); } @@ -356,6 +415,7 @@ static struct file_operations fmr2_fops = { .open = video_exclusive_open, .release = video_exclusive_release, .ioctl = fmr2_ioctl, + .compat_ioctl = v4l_compat_ioctl32, .llseek = no_llseek, }; @@ -364,7 +424,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, }; @@ -375,11 +435,11 @@ 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; - init_MUTEX(&lock); + mutex_init(&lock); if (request_region(io, 2, "sf16fmr2")) { @@ -394,12 +454,11 @@ 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 */ - down(&lock); + mutex_lock(&lock); fmr2_mute(io); fmr2_product_info(&fmr2_unit); - up(&lock); + mutex_unlock(&lock); debug_print((KERN_DEBUG "card_type %d\n", fmr2_unit.card_type)); return 0; } @@ -408,9 +467,9 @@ MODULE_AUTHOR("Ziglio Frediano, freddy77@angelfire.com"); MODULE_DESCRIPTION("A driver for the SF16FMR2 radio."); MODULE_LICENSE("GPL"); -MODULE_PARM(io, "i"); +module_param(io, int, 0); MODULE_PARM_DESC(io, "I/O address of the SF16FMR2 card (should be 0x384, if do not work try 0x284)"); -MODULE_PARM(radio_nr, "i"); +module_param(radio_nr, int, 0); static void __exit fmr2_cleanup_module(void) {