1 /* 2 * Driver for PC-speaker like devices found on various Sparc systems. 3 * 4 * Copyright (c) 2002 Vojtech Pavlik 5 * Copyright (c) 2002, 2006 David S. Miller (davem@davemloft.net) 6 */ 7 #include <linux/config.h> 8 #include <linux/kernel.h> 9 #include <linux/module.h> 10 #include <linux/init.h> 11 #include <linux/input.h> 12 #include <linux/platform_device.h> 13 14 #include <asm/io.h> 15 #include <asm/ebus.h> 16 #include <asm/isa.h> 17 18 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>"); 19 MODULE_DESCRIPTION("Sparc Speaker beeper driver"); 20 MODULE_LICENSE("GPL"); 21 22 struct sparcspkr_state { 23 const char *name; 24 unsigned long iobase; 25 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 26 spinlock_t lock; 27 struct input_dev *input_dev; 28 }; 29 30 static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 31 { 32 struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); 33 unsigned int count = 0; 34 unsigned long flags; 35 36 if (type != EV_SND) 37 return -1; 38 39 switch (code) { 40 case SND_BELL: if (value) value = 1000; 41 case SND_TONE: break; 42 default: return -1; 43 } 44 45 if (value > 20 && value < 32767) 46 count = 1193182 / value; 47 48 spin_lock_irqsave(&state->lock, flags); 49 50 /* EBUS speaker only has on/off state, the frequency does not 51 * appear to be programmable. 52 */ 53 if (state->iobase & 0x2UL) 54 outb(!!count, state->iobase); 55 else 56 outl(!!count, state->iobase); 57 58 spin_unlock_irqrestore(&state->lock, flags); 59 60 return 0; 61 } 62 63 static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 64 { 65 struct sparcspkr_state *state = dev_get_drvdata(dev->cdev.dev); 66 unsigned int count = 0; 67 unsigned long flags; 68 69 if (type != EV_SND) 70 return -1; 71 72 switch (code) { 73 case SND_BELL: if (value) value = 1000; 74 case SND_TONE: break; 75 default: return -1; 76 } 77 78 if (value > 20 && value < 32767) 79 count = 1193182 / value; 80 81 spin_lock_irqsave(&state->lock, flags); 82 83 if (count) { 84 /* enable counter 2 */ 85 outb(inb(state->iobase + 0x61) | 3, state->iobase + 0x61); 86 /* set command for counter 2, 2 byte write */ 87 outb(0xB6, state->iobase + 0x43); 88 /* select desired HZ */ 89 outb(count & 0xff, state->iobase + 0x42); 90 outb((count >> 8) & 0xff, state->iobase + 0x42); 91 } else { 92 /* disable counter 2 */ 93 outb(inb_p(state->iobase + 0x61) & 0xFC, state->iobase + 0x61); 94 } 95 96 spin_unlock_irqrestore(&state->lock, flags); 97 98 return 0; 99 } 100 101 static int __devinit sparcspkr_probe(struct device *dev) 102 { 103 struct sparcspkr_state *state = dev_get_drvdata(dev); 104 struct input_dev *input_dev; 105 int error; 106 107 input_dev = input_allocate_device(); 108 if (!input_dev) 109 return -ENOMEM; 110 111 input_dev->name = state->name; 112 input_dev->phys = "sparc/input0"; 113 input_dev->id.bustype = BUS_ISA; 114 input_dev->id.vendor = 0x001f; 115 input_dev->id.product = 0x0001; 116 input_dev->id.version = 0x0100; 117 input_dev->cdev.dev = dev; 118 119 input_dev->evbit[0] = BIT(EV_SND); 120 input_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE); 121 122 input_dev->event = state->event; 123 124 error = input_register_device(input_dev); 125 if (error) { 126 input_free_device(input_dev); 127 return error; 128 } 129 130 state->input_dev = input_dev; 131 132 return 0; 133 } 134 135 static int __devexit sparcspkr_remove(struct of_device *dev) 136 { 137 struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); 138 struct input_dev *input_dev = state->input_dev; 139 140 /* turn off the speaker */ 141 state->event(input_dev, EV_SND, SND_BELL, 0); 142 143 input_unregister_device(input_dev); 144 145 dev_set_drvdata(&dev->dev, NULL); 146 kfree(state); 147 148 return 0; 149 } 150 151 static int sparcspkr_shutdown(struct of_device *dev) 152 { 153 struct sparcspkr_state *state = dev_get_drvdata(&dev->dev); 154 struct input_dev *input_dev = state->input_dev; 155 156 /* turn off the speaker */ 157 state->event(input_dev, EV_SND, SND_BELL, 0); 158 159 return 0; 160 } 161 162 static int __devinit ebus_beep_probe(struct of_device *dev, const struct of_device_id *match) 163 { 164 struct linux_ebus_device *edev = to_ebus_device(&dev->dev); 165 struct sparcspkr_state *state; 166 int err; 167 168 state = kzalloc(sizeof(*state), GFP_KERNEL); 169 if (!state) 170 return -ENOMEM; 171 172 state->name = "Sparc EBUS Speaker"; 173 state->iobase = edev->resource[0].start; 174 state->event = ebus_spkr_event; 175 spin_lock_init(&state->lock); 176 177 dev_set_drvdata(&dev->dev, state); 178 179 err = sparcspkr_probe(&dev->dev); 180 if (err) { 181 dev_set_drvdata(&dev->dev, NULL); 182 kfree(state); 183 } 184 185 return 0; 186 } 187 188 static struct of_device_id ebus_beep_match[] = { 189 { 190 .name = "beep", 191 }, 192 {}, 193 }; 194 195 static struct of_platform_driver ebus_beep_driver = { 196 .name = "beep", 197 .match_table = ebus_beep_match, 198 .probe = ebus_beep_probe, 199 .remove = sparcspkr_remove, 200 .shutdown = sparcspkr_shutdown, 201 }; 202 203 static int __devinit isa_beep_probe(struct of_device *dev, const struct of_device_id *match) 204 { 205 struct sparc_isa_device *idev = to_isa_device(&dev->dev); 206 struct sparcspkr_state *state; 207 int err; 208 209 state = kzalloc(sizeof(*state), GFP_KERNEL); 210 if (!state) 211 return -ENOMEM; 212 213 state->name = "Sparc ISA Speaker"; 214 state->iobase = idev->resource.start; 215 state->event = isa_spkr_event; 216 spin_lock_init(&state->lock); 217 218 dev_set_drvdata(&dev->dev, state); 219 220 err = sparcspkr_probe(&dev->dev); 221 if (err) { 222 dev_set_drvdata(&dev->dev, NULL); 223 kfree(state); 224 } 225 226 return 0; 227 } 228 229 static struct of_device_id isa_beep_match[] = { 230 { 231 .name = "dma", 232 }, 233 {}, 234 }; 235 236 static struct of_platform_driver isa_beep_driver = { 237 .name = "beep", 238 .match_table = isa_beep_match, 239 .probe = isa_beep_probe, 240 .remove = sparcspkr_remove, 241 .shutdown = sparcspkr_shutdown, 242 }; 243 244 static int __init sparcspkr_init(void) 245 { 246 int err = of_register_driver(&ebus_beep_driver, &ebus_bus_type); 247 248 if (!err) { 249 err = of_register_driver(&isa_beep_driver, &isa_bus_type); 250 if (err) 251 of_unregister_driver(&ebus_beep_driver); 252 } 253 254 return err; 255 } 256 257 static void __exit sparcspkr_exit(void) 258 { 259 of_unregister_driver(&ebus_beep_driver); 260 of_unregister_driver(&isa_beep_driver); 261 } 262 263 module_init(sparcspkr_init); 264 module_exit(sparcspkr_exit); 265