patch-2.4.9 linux/drivers/media/radio/radio-sf16fmi.c
Next file: linux/drivers/media/video/tvmixer.c
Previous file: linux/drivers/media/radio/Config.in
Back to the patch index
Back to the overall index
- Lines: 140
- Date:
Sun Aug 12 11:16:18 2001
- Orig file:
v2.4.8/linux/drivers/media/radio/radio-sf16fmi.c
- Orig date:
Sat May 19 17:43:06 2001
diff -u --recursive --new-file v2.4.8/linux/drivers/media/radio/radio-sf16fmi.c linux/drivers/media/radio/radio-sf16fmi.c
@@ -5,6 +5,7 @@
*
* Fitted to new interface by Alan Cox <alan.cox@linux.org>
* Made working and cleaned up functions <mikael.hedin@irf.se>
+ * Support for ISAPnP by Ladislav Michl <ladis@psi.cz>
*
* Notes on the hardware
*
@@ -14,14 +15,15 @@
*
*/
+#include <linux/kernel.h> /* __setup */
#include <linux/module.h> /* Modules */
#include <linux/init.h> /* Initdata */
#include <linux/ioport.h> /* check_region, request_region */
#include <linux/delay.h> /* udelay */
+#include <linux/videodev.h> /* kernel radio structs */
+#include <linux/isapnp.h>
#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_SF16MI_PORT */
#include <asm/semaphore.h>
struct fmi_device
@@ -32,13 +34,10 @@
__u32 flags;
};
-#ifndef CONFIG_RADIO_SF16FMI_PORT
-#define CONFIG_RADIO_SF16FMI_PORT -1
-#endif
-
-static int io = CONFIG_RADIO_SF16FMI_PORT;
+static int io = -1;
static int radio_nr = -1;
static int users = 0;
+static struct pci_dev *dev = NULL;
static struct semaphore lock;
/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
@@ -284,16 +283,51 @@
ioctl: fmi_ioctl,
};
+/* ladis: this is my card. does any other types exist? */
+static struct isapnp_device_id id_table[] __devinitdata = {
+ { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
+ ISAPNP_VENDOR('M','F','R'), ISAPNP_FUNCTION(0xad10), 0},
+ { ISAPNP_CARD_END, },
+};
+
+MODULE_DEVICE_TABLE(isapnp, id_table);
+
+static int isapnp_fmi_probe(void)
+{
+ int i = 0;
+
+ while (id_table[i].card_vendor != 0 && dev == NULL) {
+ dev = isapnp_find_dev(NULL, id_table[i].vendor,
+ id_table[i].function, NULL);
+ }
+
+ if (!dev)
+ return -ENODEV;
+ if (dev->prepare(dev) < 0)
+ return -EAGAIN;
+ if (!(dev->resource[0].flags & IORESOURCE_IO))
+ return -ENODEV;
+ if (dev->activate(dev) < 0) {
+ printk ("radio-sf16fmi: ISAPnP configure failed (out of resources?)\n");
+ return -ENOMEM;
+ }
+
+ i = dev->resource[0].start;
+ printk ("radio-sf16fmi: ISAPnP reports card at %#x\n", i);
+
+ return i;
+}
+
static int __init fmi_init(void)
{
- if(io==-1)
- {
- printk(KERN_ERR "You must set an I/O address with io=0x???\n");
- return -EINVAL;
+ if (io < 0)
+ io = isapnp_fmi_probe();
+ if (io < 0) {
+ printk(KERN_ERR "radio-sf16fmi: No PnP card found.");
+ return io;
}
- if (!request_region(io, 2, "fmi"))
- {
- printk(KERN_ERR "fmi: port 0x%x already in use\n", io);
+ if (!request_region(io, 2, "radio-sf16fmi")) {
+ printk(KERN_ERR "radio-sf16fmi: port 0x%x already in use\n", io);
return -EBUSY;
}
@@ -305,14 +339,12 @@
init_MUTEX(&lock);
- if(video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr)==-1)
- {
+ if (video_register_device(&fmi_radio, VFL_TYPE_RADIO, radio_nr) == -1) {
release_region(io, 2);
return -EINVAL;
}
- printk(KERN_INFO "SF16FMx radio card driver at 0x%x.\n", io);
- printk(KERN_INFO "(c) 1998 Petr Vandrovec, vandrove@vc.cvut.cz.\n");
+ printk(KERN_INFO "SF16FMx radio card driver at 0x%x\n", io);
/* mute card - prevents noisy bootups */
fmi_mute(io);
return 0;
@@ -329,9 +361,20 @@
static void __exit fmi_cleanup_module(void)
{
video_unregister_device(&fmi_radio);
- release_region(io,2);
+ release_region(io, 2);
+ if (dev)
+ dev->deactivate(dev);
}
module_init(fmi_init);
module_exit(fmi_cleanup_module);
+#ifndef MODULE
+static int __init fmi_setup_io(char *str)
+{
+ get_option(&str, &io);
+ return 1;
+}
+
+__setup("sf16fm=", fmi_setup_io);
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)