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