RadioTrack II driver minor bugfix patch

Ben Pfaff (pfaffben@pilot.msu.edu)
Thu, 30 Jul 1998 10:08:27 -0400 (EDT)


There were a couple of little bugs in the RadioTrack II driver that I
posted to the list a few days ago. Here's an incremental patch that
corrects those bugs, as well as a full patch against a clean 2.1.111.

Thanks,

Ben.

******************** incremental patch ********************

diff -urpN linux-2.1.111-rtrack2/drivers/char/radio-rtrack2.c linux-2.1.111-rtrack2-2/drivers/char/radio-rtrack2.c
--- linux-2.1.111-rtrack2/drivers/char/radio-rtrack2.c Thu Jul 30 09:15:58 1998
+++ linux-2.1.111-rtrack2-2/drivers/char/radio-rtrack2.c Thu Jul 30 09:17:05 1998
@@ -68,16 +68,7 @@ static int rt_setfreq(struct rt_device *
{
int i;

-/* The RadioTrack II card allows tuning in 12.5kHz increments.
- Unfortunately many userspace programs assume that radio cards only
- handle tuning in 62.5kHz increments. These programs are
- incompatible with precise tuning. */
-#define PRECISE_TUNING 1
-#if PRECISE_TUNING
freq = freq / 200 + 856;
-#else
- freq = freq * 5 + 856;
-#endif

outb_p(0xc8, io);
outb_p(0xc9, io);
@@ -100,7 +91,7 @@ static int rt_setfreq(struct rt_device *

int rt_getsigstr(struct rt_device *dev)
{
- if (inb(io) & 4) /* bit set = no signal present */
+ if (inb(io) & 2) /* bit set = no signal present */
return 0;
return 1; /* signal present */
}
@@ -133,13 +124,9 @@ static int rt_ioctl(struct video_device
return -EFAULT;
if(v.tuner) /* Only 1 tuner */
return -EINVAL;
- v.rangelow=(int)(88.0*16);
- v.rangehigh=(int)(108.0*16);
-#if PRECISE_TUNING
+ v.rangelow=88*16000;
+ v.rangehigh=108*16000;
v.flags=VIDEO_TUNER_LOW;
-#else
- v.flags=0;
-#endif
v.mode=VIDEO_MODE_AUTO;
v.signal=0xFFFF*rt_getsigstr(rt);
if(copy_to_user(arg,&v, sizeof(v)))

******************** full patch ********************

diff -urpN linux-2.1.111-clean/Documentation/Configure.help linux-2.1.111-rtrack2-2/Documentation/Configure.help
--- linux-2.1.111-clean/Documentation/Configure.help Sun Jul 26 23:29:52 1998
+++ linux-2.1.111-rtrack2-2/Documentation/Configure.help Thu Jul 30 09:50:31 1998
@@ -9169,6 +9169,10 @@ CONFIG_RADIO_RTRACK
Choose Y here if you have one of these FM radio cards, and then fill
in the port address below.

+ Note that newer AIMSlab RadioTrack cards have a different chipset,
+ not supported by this driver. For these cards, use the RadioTrack II
+ driver below.
+
In order to control your radio card, you will need to use programs
that are compatible with the Video for Linux API. Information on
this API and pointers to "v4l" programs may be found on the WWW at
@@ -9184,6 +9188,28 @@ CONFIG_RADIO_RTRACK
RadioTrack i/o port
CONFIG_RADIO_RTRACK_PORT
Enter either 0x30f or 0x20f here. The card default is 0x30f, if you
+ haven't changed the jumper setting on the card.
+
+AIMSlab RadioTrack II support
+CONFIG_RADIO_RTRACK2
+ Choose Y here if you have this FM radio card, and then fill in the
+ port address below.
+
+ In order to control your radio card, you will need to use programs
+ that are compatible with the Video for Linux API. Information on
+ this API and pointers to "v4l" programs may be found on the WWW at
+ http://roadrunner.swansea.uk.linux.org/v4l.shtml; to browse the WWW,
+ you need to have access to a machine on the Internet that has a
+ program like lynx or netscape.
+
+ If you want to compile this driver as a module ( = code which can be
+ inserted in and removed from the running kernel whenever you want),
+ say M here and read Documentation/modules.txt. The module will be
+ called radio-rtrack2.o.
+
+RadioTrack II i/o port
+CONFIG_RADIO_RTRACK2_PORT
+ Enter either 0x30c or 0x20c here. The card default is 0x30c, if you
haven't changed the jumper setting on the card.

Aztech/Packard Bell Radio
diff -urpN linux-2.1.111-clean/drivers/char/Config.in linux-2.1.111-rtrack2-2/drivers/char/Config.in
--- linux-2.1.111-clean/drivers/char/Config.in Sun Jul 26 23:29:52 1998
+++ linux-2.1.111-rtrack2-2/drivers/char/Config.in Thu Jul 30 09:14:58 1998
@@ -109,6 +109,10 @@ if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
hex ' RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
fi
+ dep_tristate 'AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV
+ if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then
+ hex ' RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c
+ fi
dep_tristate 'Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then
hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
diff -urpN linux-2.1.111-clean/drivers/char/Makefile linux-2.1.111-rtrack2-2/drivers/char/Makefile
--- linux-2.1.111-clean/drivers/char/Makefile Sun Jul 26 23:29:52 1998
+++ linux-2.1.111-rtrack2-2/drivers/char/Makefile Thu Jul 30 09:14:56 1998
@@ -381,6 +381,14 @@ else
endif
endif

+ifeq ($(CONFIG_RADIO_RTRACK2),y)
+L_OBJS += radio-rtrack2.o
+else
+ ifeq ($(CONFIG_RADIO_RTRACK2),m)
+ M_OBJS += radio-rtrack2.o
+ endif
+endif
+
ifeq ($(CONFIG_RADIO_ZOLTRIX),y)
L_OBJS += radio-zoltrix.o
else
diff -urpN linux-2.1.111-clean/drivers/char/radio-rtrack2.c linux-2.1.111-rtrack2-2/drivers/char/radio-rtrack2.c
--- linux-2.1.111-clean/drivers/char/radio-rtrack2.c Wed Dec 31 19:00:00 1969
+++ linux-2.1.111-rtrack2-2/drivers/char/radio-rtrack2.c Thu Jul 30 09:17:05 1998
@@ -0,0 +1,271 @@
+/* RadioTrack II driver for Linux radio support (C) 1998 Ben Pfaff
+ *
+ * Based on RadioTrack I/RadioReveal (C) 1997 M. Kirkwood
+ * Coverted to new API by Alan Cox <Alan.Cox@linux.org>
+ * Various bugfixes and enhancements by Russell Kroll <rkroll@exploits.org>
+ *
+ * TODO: Allow for more than one of these foolish entities :-)
+ *
+ */
+
+#include <linux/module.h> /* Modules */
+#include <linux/init.h> /* Initdata */
+#include <linux/ioport.h> /* check_region, request_region */
+#include <linux/delay.h> /* udelay */
+#include <asm/io.h> /* outb, outb_p */
+#include <asm/uaccess.h> /* copy to/from user */
+#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/config.h> /* CONFIG_RADIO_RTRACK2_PORT */
+
+#ifndef CONFIG_RADIO_RTRACK2_PORT
+#define CONFIG_RADIO_RTRACK2_PORT -1
+#endif
+
+static int io = CONFIG_RADIO_RTRACK2_PORT;
+static int users = 0;
+
+struct rt_device
+{
+ int port;
+ unsigned long curfreq;
+ int muted;
+};
+
+
+/* local things */
+
+static void rt_mute(struct rt_device *dev)
+{
+ if(dev->muted)
+ return;
+ outb(1, io);
+ dev->muted = 1;
+}
+
+static void rt_unmute(struct rt_device *dev)
+{
+ if(dev->muted == 0)
+ return;
+ outb(0, io);
+ dev->muted = 0;
+}
+
+static void zero(void)
+{
+ outb_p(1, io);
+ outb_p(3, io);
+ outb_p(1, io);
+}
+
+static void one(void)
+{
+ outb_p(5, io);
+ outb_p(7, io);
+ outb_p(5, io);
+}
+
+static int rt_setfreq(struct rt_device *dev, unsigned long freq)
+{
+ int i;
+
+ freq = freq / 200 + 856;
+
+ outb_p(0xc8, io);
+ outb_p(0xc9, io);
+ outb_p(0xc9, io);
+
+ for (i = 0; i < 10; i++)
+ zero ();
+
+ for (i = 14; i >= 0; i--)
+ if (freq & (1 << i))
+ one ();
+ else
+ zero ();
+
+ outb_p(0xc8, io);
+ if (!dev->muted)
+ outb_p(0, io);
+ return 0;
+}
+
+int rt_getsigstr(struct rt_device *dev)
+{
+ if (inb(io) & 2) /* bit set = no signal present */
+ return 0;
+ return 1; /* signal present */
+}
+
+static int rt_ioctl(struct video_device *dev, unsigned int cmd, void *arg)
+{
+ struct rt_device *rt=dev->priv;
+
+ switch(cmd)
+ {
+ case VIDIOCGCAP:
+ {
+ struct video_capability v;
+ v.type=VID_TYPE_TUNER;
+ v.channels=1;
+ v.audios=1;
+ /* No we don't do pictures */
+ v.maxwidth=0;
+ v.maxheight=0;
+ v.minwidth=0;
+ v.minheight=0;
+ if(copy_to_user(arg,&v,sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCGTUNER:
+ {
+ struct video_tuner v;
+ if(copy_from_user(&v, arg,sizeof(v))!=0)
+ return -EFAULT;
+ if(v.tuner) /* Only 1 tuner */
+ return -EINVAL;
+ v.rangelow=88*16000;
+ v.rangehigh=108*16000;
+ v.flags=VIDEO_TUNER_LOW;
+ v.mode=VIDEO_MODE_AUTO;
+ v.signal=0xFFFF*rt_getsigstr(rt);
+ if(copy_to_user(arg,&v, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSTUNER:
+ {
+ struct video_tuner v;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ if(v.tuner!=0)
+ return -EINVAL;
+ /* Only 1 tuner so no setting needed ! */
+ return 0;
+ }
+ case VIDIOCGFREQ:
+ if(copy_to_user(arg, &rt->curfreq, sizeof(rt->curfreq)))
+ return -EFAULT;
+ return 0;
+ case VIDIOCSFREQ:
+ if(copy_from_user(&rt->curfreq, arg,sizeof(rt->curfreq)))
+ return -EFAULT;
+ rt_setfreq(rt, rt->curfreq);
+ return 0;
+ case VIDIOCGAUDIO:
+ {
+ struct video_audio v;
+ memset(&v,0, sizeof(v));
+ v.flags|=VIDEO_AUDIO_MUTABLE;
+ v.volume=1;
+ strcpy(v.name, "Radio");
+ if(copy_to_user(arg,&v, sizeof(v)))
+ return -EFAULT;
+ return 0;
+ }
+ case VIDIOCSAUDIO:
+ {
+ struct video_audio v;
+ if(copy_from_user(&v, arg, sizeof(v)))
+ return -EFAULT;
+ if(v.audio)
+ return -EINVAL;
+
+ if(v.flags&VIDEO_AUDIO_MUTE)
+ rt_mute(rt);
+ else
+ rt_unmute(rt);
+
+ return 0;
+ }
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
+static int rt_open(struct video_device *dev, int flags)
+{
+ if(users)
+ return -EBUSY;
+ users++;
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static void rt_close(struct video_device *dev)
+{
+ users--;
+ MOD_DEC_USE_COUNT;
+}
+
+static struct rt_device rtrack2_unit;
+
+static struct video_device rtrack2_radio=
+{
+ "RadioTrack II radio",
+ VID_TYPE_TUNER,
+ VID_HARDWARE_RTRACK2,
+ rt_open,
+ rt_close,
+ NULL, /* Can't read (no capture ability) */
+ NULL, /* Can't write */
+ rt_ioctl,
+ NULL,
+ NULL
+};
+
+__initfunc(int rtrack2_init(struct video_init *v))
+{
+ if (check_region(io, 4))
+ {
+ printk(KERN_ERR "rtrack2: port 0x%x already in use\n", io);
+ return -EBUSY;
+ }
+
+ rtrack2_radio.priv=&rtrack2_unit;
+
+ if(video_register_device(&rtrack2_radio, VFL_TYPE_RADIO)==-1)
+ return -EINVAL;
+
+ request_region(io, 4, "rtrack2");
+ printk(KERN_INFO "AIMSlab Radiotrack II card driver.\n");
+
+ /* mute card - prevents noisy bootups */
+ outb(1, io);
+ rtrack2_unit.muted = 1;
+
+ return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Ben Pfaff");
+MODULE_DESCRIPTION("A driver for the RadioTrack II radio card.");
+MODULE_PARM(io, "i");
+MODULE_PARM_DESC(io, "I/O address of the RadioTrack card (0x20c or 0x30c)");
+
+EXPORT_NO_SYMBOLS;
+
+int init_module(void)
+{
+ if(io==-1)
+ {
+ printk(KERN_ERR "You must set an I/O address with io=0x20c or io=0x30c\n");
+ return -EINVAL;
+ }
+ return rtrack2_init(NULL);
+}
+
+void cleanup_module(void)
+{
+ video_unregister_device(&rtrack2_radio);
+ release_region(io,4);
+}
+
+#endif
+
+/*
+ Local variables:
+ compile-command: "gcc -c -DMODVERSIONS -D__KERNEL__ -DMODULE -O6 -Wall -Wstrict-prototypes -I /home/blp/tmp/linux-2.1.111-rtrack/include radio-rtrack2.c"
+ End:
+*/
Binary files linux-2.1.111-clean/drivers/char/radio-rtrack2.o and linux-2.1.111-rtrack2-2/drivers/char/radio-rtrack2.o differ
diff -urpN linux-2.1.111-clean/include/linux/videodev.h linux-2.1.111-rtrack2-2/include/linux/videodev.h
--- linux-2.1.111-clean/include/linux/videodev.h Sun Jul 26 23:29:56 1998
+++ linux-2.1.111-rtrack2-2/include/linux/videodev.h Thu Jul 30 09:14:29 1998
@@ -205,6 +205,7 @@ struct video_key
#define VID_HARDWARE_ZOLTRIX 10
#define VID_HARDWARE_SAA7146 11
#define VID_HARDWARE_VIDEUM 12 /* Reserved for Winnov videum */
+#define VID_HARDWARE_RTRACK2 13

/*
* Initialiser list

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html