0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/kernel.h>
0012 #include <linux/module.h>
0013 #include <linux/init.h>
0014 #include <linux/input.h>
0015 #include <linux/platform_device.h>
0016 #include <asm/machdep.h>
0017 #include <asm/io.h>
0018
0019 MODULE_AUTHOR("Richard Zidlicky <rz@linux-m68k.org>");
0020 MODULE_DESCRIPTION("m68k beeper driver");
0021 MODULE_LICENSE("GPL");
0022
0023 static struct platform_device *m68kspkr_platform_device;
0024
0025 static int m68kspkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
0026 {
0027 unsigned int count = 0;
0028
0029 if (type != EV_SND)
0030 return -1;
0031
0032 switch (code) {
0033 case SND_BELL: if (value) value = 1000;
0034 case SND_TONE: break;
0035 default: return -1;
0036 }
0037
0038 if (value > 20 && value < 32767)
0039 count = 1193182 / value;
0040
0041 mach_beep(count, -1);
0042
0043 return 0;
0044 }
0045
0046 static int m68kspkr_probe(struct platform_device *dev)
0047 {
0048 struct input_dev *input_dev;
0049 int err;
0050
0051 input_dev = input_allocate_device();
0052 if (!input_dev)
0053 return -ENOMEM;
0054
0055 input_dev->name = "m68k beeper";
0056 input_dev->phys = "m68k/generic";
0057 input_dev->id.bustype = BUS_HOST;
0058 input_dev->id.vendor = 0x001f;
0059 input_dev->id.product = 0x0001;
0060 input_dev->id.version = 0x0100;
0061 input_dev->dev.parent = &dev->dev;
0062
0063 input_dev->evbit[0] = BIT_MASK(EV_SND);
0064 input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE);
0065 input_dev->event = m68kspkr_event;
0066
0067 err = input_register_device(input_dev);
0068 if (err) {
0069 input_free_device(input_dev);
0070 return err;
0071 }
0072
0073 platform_set_drvdata(dev, input_dev);
0074
0075 return 0;
0076 }
0077
0078 static int m68kspkr_remove(struct platform_device *dev)
0079 {
0080 struct input_dev *input_dev = platform_get_drvdata(dev);
0081
0082 input_unregister_device(input_dev);
0083
0084 m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
0085
0086 return 0;
0087 }
0088
0089 static void m68kspkr_shutdown(struct platform_device *dev)
0090 {
0091
0092 m68kspkr_event(NULL, EV_SND, SND_BELL, 0);
0093 }
0094
0095 static struct platform_driver m68kspkr_platform_driver = {
0096 .driver = {
0097 .name = "m68kspkr",
0098 },
0099 .probe = m68kspkr_probe,
0100 .remove = m68kspkr_remove,
0101 .shutdown = m68kspkr_shutdown,
0102 };
0103
0104 static int __init m68kspkr_init(void)
0105 {
0106 int err;
0107
0108 if (!mach_beep) {
0109 printk(KERN_INFO "m68kspkr: no lowlevel beep support\n");
0110 return -ENODEV;
0111 }
0112
0113 err = platform_driver_register(&m68kspkr_platform_driver);
0114 if (err)
0115 return err;
0116
0117 m68kspkr_platform_device = platform_device_alloc("m68kspkr", -1);
0118 if (!m68kspkr_platform_device) {
0119 err = -ENOMEM;
0120 goto err_unregister_driver;
0121 }
0122
0123 err = platform_device_add(m68kspkr_platform_device);
0124 if (err)
0125 goto err_free_device;
0126
0127 return 0;
0128
0129 err_free_device:
0130 platform_device_put(m68kspkr_platform_device);
0131 err_unregister_driver:
0132 platform_driver_unregister(&m68kspkr_platform_driver);
0133
0134 return err;
0135 }
0136
0137 static void __exit m68kspkr_exit(void)
0138 {
0139 platform_device_unregister(m68kspkr_platform_device);
0140 platform_driver_unregister(&m68kspkr_platform_driver);
0141 }
0142
0143 module_init(m68kspkr_init);
0144 module_exit(m68kspkr_exit);