patch-2.1.118 linux/drivers/char/radio-sf16fmi.c
Next file: linux/drivers/char/radio-zoltrix.c
Previous file: linux/drivers/char/radio-rtrack2.c
Back to the patch index
Back to the overall index
- Lines: 171
- Date:
Sun Aug 23 13:32:25 1998
- Orig file:
v2.1.117/linux/drivers/char/radio-sf16fmi.c
- Orig date:
Thu Aug 20 17:05:16 1998
diff -u --recursive --new-file v2.1.117/linux/drivers/char/radio-sf16fmi.c linux/drivers/char/radio-sf16fmi.c
@@ -22,14 +22,12 @@
#include <linux/videodev.h> /* kernel radio structs */
#include <linux/config.h> /* CONFIG_RADIO_SF16MI_PORT */
-#include "rsf16fmi.h"
-
struct fmi_device
{
int port;
- int curvol;
- unsigned long curfreq;
- int flags;
+ int curvol; /* 1 or 0 */
+ unsigned long curfreq; /* RSF16_PREC * freq in MHz */
+ __u32 flags;
};
#ifndef CONFIG_RADIO_SF16FMI_PORT
@@ -39,11 +37,16 @@
static int io = CONFIG_RADIO_SF16FMI_PORT;
static int users = 0;
-/* local things */
-/* freq in 1/16kHz to internal number */
-#define RSF16_ENCODE(x) ((x/16+10700)/50)
+/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
+/* It is only usefull to give freq in intervall of 800 (=0.05Mhz),
+ * other bits will be truncated, e.g 92.7400016 -> 92.7, but
+ * 92.7400017 -> 92.75
+ */
+#define RSF16_ENCODE(x) ((x)/800+214)
+#define RSF16_MINFREQ 88*16000
+#define RSF16_MAXFREQ 108*16000
-static void outbits(int bits, int data, int port)
+static void outbits(int bits, unsigned int data, int port)
{
while(bits--) {
if(data & 1) {
@@ -73,7 +76,7 @@
static int fmi_setfreq(struct fmi_device *dev, unsigned long freq)
{
- int myport = dev->port;
+ int myport = dev->port;
outbits(16, RSF16_ENCODE(freq), myport);
outbits(8, 0xC0, myport);
@@ -105,6 +108,7 @@
case VIDIOCGCAP:
{
struct video_capability v;
+ strcpy(v.name, "SF16-FMx radio");
v.type=VID_TYPE_TUNER;
v.channels=1;
v.audios=1;
@@ -120,17 +124,16 @@
case VIDIOCGTUNER:
{
struct video_tuner v;
+ int mult;
+
if(copy_from_user(&v, arg,sizeof(v))!=0)
return -EFAULT;
if(v.tuner) /* Only 1 tuner */
return -EINVAL;
- if (fmi->flags & VIDEO_TUNER_LOW) {
- v.rangelow = 87500 * 16;
- v.rangehigh = 108000 * 16;
- } else {
- v.rangelow=(int)(175*8 /* 87.5 *16 */);
- v.rangehigh=(int)(108*16);
- }
+ strcpy(v.name, "FM");
+ mult = (fmi->flags & VIDEO_TUNER_LOW) ? 1 : 1000;
+ v.rangelow = RSF16_MINFREQ/mult;
+ v.rangehigh = RSF16_MAXFREQ/mult;
v.flags=fmi->flags;
v.mode=VIDEO_MODE_AUTO;
v.signal=0xFFFF*fmi_getsigstr(fmi);
@@ -165,6 +168,8 @@
return -EFAULT;
if (!(fmi->flags & VIDEO_TUNER_LOW))
tmp *= 1000;
+ if ( tmp<RSF16_MINFREQ || tmp>RSF16_MAXFREQ )
+ return -EINVAL;
fmi->curfreq = tmp;
fmi_setfreq(fmi, fmi->curfreq);
return 0;
@@ -172,12 +177,15 @@
case VIDIOCGAUDIO:
{
struct video_audio v;
- memset(&v,0, sizeof(v));
- v.flags|=VIDEO_AUDIO_MUTABLE;
- v.mode=VIDEO_SOUND_MONO;
- v.volume=fmi->curvol;
- v.step=65535;
+ v.audio=0;
+ v.volume=0;
+ v.bass=0;
+ v.treble=0;
+ v.flags=( (!fmi->curvol)*VIDEO_AUDIO_MUTE | VIDEO_AUDIO_MUTABLE);
strcpy(v.name, "Radio");
+ v.mode=VIDEO_SOUND_MONO;
+ v.balance=0;
+ v.step=0; /* No volume, just (un)mute */
if(copy_to_user(arg,&v, sizeof(v)))
return -EFAULT;
return 0;
@@ -189,15 +197,23 @@
return -EFAULT;
if(v.audio)
return -EINVAL;
- fmi->curvol=v.volume;
- if(v.flags&VIDEO_AUDIO_MUTE)
- fmi_mute(fmi->port);
- else if(fmi->curvol)
- fmi_unmute(fmi->port);
- else
- fmi_mute(fmi->port);
+ fmi->curvol= v.flags&VIDEO_AUDIO_MUTE ? 0 : 1;
+ fmi->curvol ?
+ fmi_unmute(fmi->port) : fmi_mute(fmi->port);
return 0;
}
+ case VIDIOCGUNIT:
+ {
+ struct video_unit v;
+ 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;
+ if(copy_to_user(arg, &v, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
default:
return -ENOIOCTLCMD;
}
@@ -222,7 +238,7 @@
static struct video_device fmi_radio=
{
- "SF16FMI radio",
+ "SF16FMx radio",
VID_TYPE_TUNER,
VID_HARDWARE_SF16MI,
fmi_open,
@@ -243,15 +259,17 @@
return -EBUSY;
}
- fmi_unit.port=io;
+ fmi_unit.port = io;
+ fmi_unit.curvol = 0;
+ fmi_unit.curfreq = 0;
fmi_unit.flags = VIDEO_TUNER_LOW;
- fmi_radio.priv=&fmi_unit;
+ fmi_radio.priv = &fmi_unit;
if(video_register_device(&fmi_radio, VFL_TYPE_RADIO)==-1)
return -EINVAL;
request_region(io, 2, "fmi");
- printk(KERN_INFO "SF16FMI radio card driver.\n");
+ printk(KERN_INFO "SF16FMx radio card driver at 0x%x.\n", io);
printk(KERN_INFO "(c) 1998 Petr Vandrovec, [email protected].\n");
/* mute card - prevents noisy bootups */
fmi_mute(io);
FUNET's LINUX-ADM group, [email protected]
TCL-scripts by Sam Shen, [email protected]