mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-24 21:24:00 +08:00
V4L/DVB (13609): radio-sf16fmi: add autoprobing
Add automatic probing of ports 0x284 and 0x384 to radio-sf16fmi if no card is found using PnP. Signed-off-by: Ondrej Zary <linux@rainbow-software.org> Signed-off-by: Douglas Schilling Landgraf <dougsland@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
4b83037474
commit
67cabf503c
@ -218,10 +218,7 @@ config RADIO_SF16FMI
|
||||
tristate "SF16-FMI/SF16-FMP Radio"
|
||||
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
|
||||
have to add "sf16fm=<io>" to the kernel command line (I/O address is
|
||||
0x284 or 0x384).
|
||||
Choose Y here if you have one of these FM radio cards.
|
||||
|
||||
In order to control your radio card, you will need to use programs
|
||||
that are compatible with the Video For Linux API. Information on
|
||||
|
@ -54,6 +54,7 @@ struct fmi
|
||||
|
||||
static struct fmi fmi_card;
|
||||
static struct pnp_dev *dev;
|
||||
bool pnp_attached;
|
||||
|
||||
/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
|
||||
/* It is only useful to give freq in interval of 800 (=0.05Mhz),
|
||||
@ -320,25 +321,53 @@ static int __init fmi_init(void)
|
||||
{
|
||||
struct fmi *fmi = &fmi_card;
|
||||
struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
|
||||
int res;
|
||||
int res, i;
|
||||
int probe_ports[] = { 0, 0x284, 0x384 };
|
||||
|
||||
if (io < 0)
|
||||
if (io < 0) {
|
||||
for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
|
||||
io = probe_ports[i];
|
||||
if (io == 0) {
|
||||
io = isapnp_fmi_probe();
|
||||
strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
|
||||
fmi->io = io;
|
||||
if (fmi->io < 0) {
|
||||
v4l2_err(v4l2_dev, "No PnP card found.\n");
|
||||
return fmi->io;
|
||||
if (io < 0)
|
||||
continue;
|
||||
pnp_attached = 1;
|
||||
}
|
||||
if (!request_region(io, 2, "radio-sf16fmi")) {
|
||||
v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
|
||||
if (pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
io = -1;
|
||||
continue;
|
||||
}
|
||||
if (pnp_attached ||
|
||||
((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
|
||||
break;
|
||||
release_region(io, 2);
|
||||
io = -1;
|
||||
}
|
||||
} else {
|
||||
if (!request_region(io, 2, "radio-sf16fmi")) {
|
||||
printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
|
||||
return -EBUSY;
|
||||
}
|
||||
if (inb(io) == 0xff) {
|
||||
printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
|
||||
release_region(io, 2);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
if (io < 0) {
|
||||
printk(KERN_ERR "radio-sf16fmi: no cards found\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
|
||||
fmi->io = io;
|
||||
|
||||
res = v4l2_device_register(NULL, v4l2_dev);
|
||||
if (res < 0) {
|
||||
release_region(fmi->io, 2);
|
||||
if (pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
|
||||
return res;
|
||||
@ -356,6 +385,7 @@ static int __init fmi_init(void)
|
||||
if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
|
||||
v4l2_device_unregister(v4l2_dev);
|
||||
release_region(fmi->io, 2);
|
||||
if (pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -373,7 +403,7 @@ static void __exit fmi_exit(void)
|
||||
video_unregister_device(&fmi->vdev);
|
||||
v4l2_device_unregister(&fmi->v4l2_dev);
|
||||
release_region(fmi->io, 2);
|
||||
if (dev)
|
||||
if (dev && pnp_attached)
|
||||
pnp_device_detach(dev);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user