[PATCH] missing bits in sparkspkr conversion
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / drivers / input / misc / sparcspkr.c
blob29d97b12be7a4bc1753e7279e774b7e007fe7b6f
1 /*
2 * Driver for PC-speaker like devices found on various Sparc systems.
4 * Copyright (c) 2002 Vojtech Pavlik
5 * Copyright (c) 2002 David S. Miller (davem@redhat.com)
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>
13 #include <asm/io.h>
14 #include <asm/ebus.h>
15 #ifdef CONFIG_SPARC64
16 #include <asm/isa.h>
17 #endif
19 MODULE_AUTHOR("David S. Miller <davem@redhat.com>");
20 MODULE_DESCRIPTION("Sparc Speaker beeper driver");
21 MODULE_LICENSE("GPL");
23 static unsigned long beep_iobase;
24 static struct input_dev *sparcspkr_dev;
26 DEFINE_SPINLOCK(beep_lock);
28 static void __init init_sparcspkr_struct(void)
30 sparcspkr_dev->evbit[0] = BIT(EV_SND);
31 sparcspkr_dev->sndbit[0] = BIT(SND_BELL) | BIT(SND_TONE);
33 sparcspkr_dev->phys = "sparc/input0";
34 sparcspkr_dev->id.bustype = BUS_ISA;
35 sparcspkr_dev->id.vendor = 0x001f;
36 sparcspkr_dev->id.product = 0x0001;
37 sparcspkr_dev->id.version = 0x0100;
40 static int ebus_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
42 unsigned int count = 0;
43 unsigned long flags;
45 if (type != EV_SND)
46 return -1;
48 switch (code) {
49 case SND_BELL: if (value) value = 1000;
50 case SND_TONE: break;
51 default: return -1;
54 if (value > 20 && value < 32767)
55 count = 1193182 / value;
57 spin_lock_irqsave(&beep_lock, flags);
59 /* EBUS speaker only has on/off state, the frequency does not
60 * appear to be programmable.
62 if (count) {
63 if (beep_iobase & 0x2UL)
64 outb(1, beep_iobase);
65 else
66 outl(1, beep_iobase);
67 } else {
68 if (beep_iobase & 0x2UL)
69 outb(0, beep_iobase);
70 else
71 outl(0, beep_iobase);
74 spin_unlock_irqrestore(&beep_lock, flags);
76 return 0;
79 static int __init init_ebus_beep(struct linux_ebus_device *edev)
81 beep_iobase = edev->resource[0].start;
83 sparcspkr_dev = input_allocate_device();
84 if (!sparcspkr_dev)
85 return -ENOMEM;
87 sparcspkr_dev->name = "Sparc EBUS Speaker";
88 sparcspkr_dev->event = ebus_spkr_event;
90 input_register_device(sparcspkr_dev);
92 return 0;
95 #ifdef CONFIG_SPARC64
96 static int isa_spkr_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
98 unsigned int count = 0;
99 unsigned long flags;
101 if (type != EV_SND)
102 return -1;
104 switch (code) {
105 case SND_BELL: if (value) value = 1000;
106 case SND_TONE: break;
107 default: return -1;
110 if (value > 20 && value < 32767)
111 count = 1193182 / value;
113 spin_lock_irqsave(&beep_lock, flags);
115 if (count) {
116 /* enable counter 2 */
117 outb(inb(beep_iobase + 0x61) | 3, beep_iobase + 0x61);
118 /* set command for counter 2, 2 byte write */
119 outb(0xB6, beep_iobase + 0x43);
120 /* select desired HZ */
121 outb(count & 0xff, beep_iobase + 0x42);
122 outb((count >> 8) & 0xff, beep_iobase + 0x42);
123 } else {
124 /* disable counter 2 */
125 outb(inb_p(beep_iobase + 0x61) & 0xFC, beep_iobase + 0x61);
128 spin_unlock_irqrestore(&beep_lock, flags);
130 return 0;
133 static int __init init_isa_beep(struct sparc_isa_device *isa_dev)
135 beep_iobase = isa_dev->resource.start;
137 sparcspkr_dev = input_allocate_device();
138 if (!sparcspkr_dev)
139 return -ENOMEM;
141 init_sparcspkr_struct();
143 sparcspkr_dev->name = "Sparc ISA Speaker";
144 sparcspkr_dev->event = isa_spkr_event;
146 input_register_device(sparcspkr_dev);
148 return 0;
150 #endif
152 static int __init sparcspkr_init(void)
154 struct linux_ebus *ebus;
155 struct linux_ebus_device *edev = NULL;
156 #ifdef CONFIG_SPARC64
157 struct sparc_isa_bridge *isa_br;
158 struct sparc_isa_device *isa_dev;
159 #endif
161 for_each_ebus(ebus) {
162 for_each_ebusdev(edev, ebus) {
163 if (!strcmp(edev->prom_name, "beep"))
164 return init_ebus_beep(edev);
167 #ifdef CONFIG_SPARC64
168 for_each_isa(isa_br) {
169 for_each_isadev(isa_dev, isa_br) {
170 /* A hack, the beep device's base lives in
171 * the DMA isa node.
173 if (!strcmp(isa_dev->prom_name, "dma"))
174 return init_isa_beep(isa_dev);
177 #endif
179 return -ENODEV;
182 static void __exit sparcspkr_exit(void)
184 input_unregister_device(sparcspkr_dev);
187 module_init(sparcspkr_init);
188 module_exit(sparcspkr_exit);