X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Finput%2Fmisc%2Fpcspkr.c;h=afd322185bbff65e20e055f7310bc64228d7f61f;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=cfc821785e256a797cbcf7d626b85b90de0bee15;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/input/misc/pcspkr.c b/drivers/input/misc/pcspkr.c index cfc821785..afd322185 100644 --- a/drivers/input/misc/pcspkr.c +++ b/drivers/input/misc/pcspkr.c @@ -16,17 +16,15 @@ #include #include #include +#include +#include #include MODULE_AUTHOR("Vojtech Pavlik "); MODULE_DESCRIPTION("PC Speaker beeper driver"); MODULE_LICENSE("GPL"); -static char pcspkr_name[] = "PC Speaker"; -static char pcspkr_phys[] = "isa0061/input0"; -static struct input_dev pcspkr_dev; - -spinlock_t i8253_beep_lock = SPIN_LOCK_UNLOCKED; +static DEFINE_SPINLOCK(i8253_beep_lock); static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) { @@ -40,11 +38,11 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c case SND_BELL: if (value) value = 1000; case SND_TONE: break; default: return -1; - } + } if (value > 20 && value < 32767) - count = CLOCK_TICK_RATE / value; - + count = PIT_TICK_RATE / value; + spin_lock_irqsave(&i8253_beep_lock, flags); if (count) { @@ -65,29 +63,83 @@ static int pcspkr_event(struct input_dev *dev, unsigned int type, unsigned int c return 0; } -static int __init pcspkr_init(void) +static int __devinit pcspkr_probe(struct platform_device *dev) { - pcspkr_dev.evbit[0] = BIT(EV_SND); - pcspkr_dev.sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); - pcspkr_dev.event = pcspkr_event; + struct input_dev *pcspkr_dev; + int err; + + pcspkr_dev = input_allocate_device(); + if (!pcspkr_dev) + return -ENOMEM; + + pcspkr_dev->name = "PC Speaker"; + pcspkr_dev->phys = "isa0061/input0"; + pcspkr_dev->id.bustype = BUS_ISA; + pcspkr_dev->id.vendor = 0x001f; + pcspkr_dev->id.product = 0x0001; + pcspkr_dev->id.version = 0x0100; + pcspkr_dev->cdev.dev = &dev->dev; + + pcspkr_dev->evbit[0] = BIT(EV_SND); + pcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); + pcspkr_dev->event = pcspkr_event; + + err = input_register_device(pcspkr_dev); + if (err) { + input_free_device(pcspkr_dev); + return err; + } + + platform_set_drvdata(dev, pcspkr_dev); - pcspkr_dev.name = pcspkr_name; - pcspkr_dev.phys = pcspkr_phys; - pcspkr_dev.id.bustype = BUS_ISA; - pcspkr_dev.id.vendor = 0x001f; - pcspkr_dev.id.product = 0x0001; - pcspkr_dev.id.version = 0x0100; + return 0; +} - input_register_device(&pcspkr_dev); +static int __devexit pcspkr_remove(struct platform_device *dev) +{ + struct input_dev *pcspkr_dev = platform_get_drvdata(dev); - printk(KERN_INFO "input: %s\n", pcspkr_name); + input_unregister_device(pcspkr_dev); + platform_set_drvdata(dev, NULL); + /* turn off the speaker */ + pcspkr_event(NULL, EV_SND, SND_BELL, 0); return 0; } +static int pcspkr_suspend(struct platform_device *dev, pm_message_t state) +{ + pcspkr_event(NULL, EV_SND, SND_BELL, 0); + + return 0; +} + +static void pcspkr_shutdown(struct platform_device *dev) +{ + /* turn off the speaker */ + pcspkr_event(NULL, EV_SND, SND_BELL, 0); +} + +static struct platform_driver pcspkr_platform_driver = { + .driver = { + .name = "pcspkr", + .owner = THIS_MODULE, + }, + .probe = pcspkr_probe, + .remove = __devexit_p(pcspkr_remove), + .suspend = pcspkr_suspend, + .shutdown = pcspkr_shutdown, +}; + + +static int __init pcspkr_init(void) +{ + return platform_driver_register(&pcspkr_platform_driver); +} + static void __exit pcspkr_exit(void) { - input_unregister_device(&pcspkr_dev); + platform_driver_unregister(&pcspkr_platform_driver); } module_init(pcspkr_init);