aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/radio/radio-sf16fmi.c
diff options
context:
space:
mode:
authorOndrej Zary <linux@rainbow-software.org>2009-12-10 15:12:32 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-12-15 21:18:40 -0500
commit67cabf503cd0ad7473cf1856f9c9bb6320098be6 (patch)
tree5b1205db2d1dc6327c3953cdea16cdc5efd30b4d /drivers/media/radio/radio-sf16fmi.c
parent4b8303747474033d6d73828607eafab77c620d96 (diff)
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>
Diffstat (limited to 'drivers/media/radio/radio-sf16fmi.c')
-rw-r--r--drivers/media/radio/radio-sf16fmi.c60
1 files changed, 45 insertions, 15 deletions
diff --git a/drivers/media/radio/radio-sf16fmi.c b/drivers/media/radio/radio-sf16fmi.c
index e9ecfe11cda5..985359d18aa5 100644
--- a/drivers/media/radio/radio-sf16fmi.c
+++ b/drivers/media/radio/radio-sf16fmi.c
@@ -54,6 +54,7 @@ struct fmi
54 54
55static struct fmi fmi_card; 55static struct fmi fmi_card;
56static struct pnp_dev *dev; 56static struct pnp_dev *dev;
57bool pnp_attached;
57 58
58/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */ 59/* freq is in 1/16 kHz to internal number, hw precision is 50 kHz */
59/* It is only useful to give freq in interval of 800 (=0.05Mhz), 60/* It is only useful to give freq in interval of 800 (=0.05Mhz),
@@ -320,26 +321,54 @@ static int __init fmi_init(void)
320{ 321{
321 struct fmi *fmi = &fmi_card; 322 struct fmi *fmi = &fmi_card;
322 struct v4l2_device *v4l2_dev = &fmi->v4l2_dev; 323 struct v4l2_device *v4l2_dev = &fmi->v4l2_dev;
323 int res; 324 int res, i;
325 int probe_ports[] = { 0, 0x284, 0x384 };
326
327 if (io < 0) {
328 for (i = 0; i < ARRAY_SIZE(probe_ports); i++) {
329 io = probe_ports[i];
330 if (io == 0) {
331 io = isapnp_fmi_probe();
332 if (io < 0)
333 continue;
334 pnp_attached = 1;
335 }
336 if (!request_region(io, 2, "radio-sf16fmi")) {
337 if (pnp_attached)
338 pnp_device_detach(dev);
339 io = -1;
340 continue;
341 }
342 if (pnp_attached ||
343 ((inb(io) & 0xf9) == 0xf9 && (inb(io) & 0x4) == 0))
344 break;
345 release_region(io, 2);
346 io = -1;
347 }
348 } else {
349 if (!request_region(io, 2, "radio-sf16fmi")) {
350 printk(KERN_ERR "radio-sf16fmi: port %#x already in use\n", io);
351 return -EBUSY;
352 }
353 if (inb(io) == 0xff) {
354 printk(KERN_ERR "radio-sf16fmi: card not present at %#x\n", io);
355 release_region(io, 2);
356 return -ENODEV;
357 }
358 }
359 if (io < 0) {
360 printk(KERN_ERR "radio-sf16fmi: no cards found\n");
361 return -ENODEV;
362 }
324 363
325 if (io < 0)
326 io = isapnp_fmi_probe();
327 strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name)); 364 strlcpy(v4l2_dev->name, "sf16fmi", sizeof(v4l2_dev->name));
328 fmi->io = io; 365 fmi->io = io;
329 if (fmi->io < 0) {
330 v4l2_err(v4l2_dev, "No PnP card found.\n");
331 return fmi->io;
332 }
333 if (!request_region(io, 2, "radio-sf16fmi")) {
334 v4l2_err(v4l2_dev, "port 0x%x already in use\n", fmi->io);
335 pnp_device_detach(dev);
336 return -EBUSY;
337 }
338 366
339 res = v4l2_device_register(NULL, v4l2_dev); 367 res = v4l2_device_register(NULL, v4l2_dev);
340 if (res < 0) { 368 if (res < 0) {
341 release_region(fmi->io, 2); 369 release_region(fmi->io, 2);
342 pnp_device_detach(dev); 370 if (pnp_attached)
371 pnp_device_detach(dev);
343 v4l2_err(v4l2_dev, "Could not register v4l2_device\n"); 372 v4l2_err(v4l2_dev, "Could not register v4l2_device\n");
344 return res; 373 return res;
345 } 374 }
@@ -356,7 +385,8 @@ static int __init fmi_init(void)
356 if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) { 385 if (video_register_device(&fmi->vdev, VFL_TYPE_RADIO, radio_nr) < 0) {
357 v4l2_device_unregister(v4l2_dev); 386 v4l2_device_unregister(v4l2_dev);
358 release_region(fmi->io, 2); 387 release_region(fmi->io, 2);
359 pnp_device_detach(dev); 388 if (pnp_attached)
389 pnp_device_detach(dev);
360 return -EINVAL; 390 return -EINVAL;
361 } 391 }
362 392
@@ -373,7 +403,7 @@ static void __exit fmi_exit(void)
373 video_unregister_device(&fmi->vdev); 403 video_unregister_device(&fmi->vdev);
374 v4l2_device_unregister(&fmi->v4l2_dev); 404 v4l2_device_unregister(&fmi->v4l2_dev);
375 release_region(fmi->io, 2); 405 release_region(fmi->io, 2);
376 if (dev) 406 if (dev && pnp_attached)
377 pnp_device_detach(dev); 407 pnp_device_detach(dev);
378} 408}
379 409