1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/slab.h>
28#include <linux/serio.h>
29#include <linux/input.h>
30#include <linux/interrupt.h>
31#include <linux/spinlock.h>
32#include <linux/delay.h>
33#include <linux/ioport.h>
34
35#include <asm/irq.h>
36#include <asm/io.h>
37#include <asm/parisc-device.h>
38
39MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>");
40MODULE_DESCRIPTION("HP GSC PS2 port driver");
41MODULE_LICENSE("GPL");
42
43#define PFX "gscps2.c: "
44
45
46
47
48
49
50#define ENABLE 1
51#define DISABLE 0
52
53#define GSC_DINO_OFFSET 0x0800
54
55
56#define GSC_ID 0x00
57#define GSC_RESET 0x00
58#define GSC_RCVDATA 0x04
59#define GSC_XMTDATA 0x04
60#define GSC_CONTROL 0x08
61#define GSC_STATUS 0x0C
62
63
64#define GSC_CTRL_ENBL 0x01
65#define GSC_CTRL_LPBXR 0x02
66#define GSC_CTRL_DIAG 0x20
67#define GSC_CTRL_DATDIR 0x40
68#define GSC_CTRL_CLKDIR 0x80
69
70
71#define GSC_STAT_RBNE 0x01
72#define GSC_STAT_TBNE 0x02
73#define GSC_STAT_TERR 0x04
74#define GSC_STAT_PERR 0x08
75#define GSC_STAT_CMPINTR 0x10
76#define GSC_STAT_DATSHD 0x40
77#define GSC_STAT_CLKSHD 0x80
78
79
80#define GSC_ID_KEYBOARD 0
81#define GSC_ID_MOUSE 1
82
83
84static irqreturn_t gscps2_interrupt(int irq, void *dev);
85
86#define BUFFER_SIZE 0x0f
87
88
89struct gscps2port {
90 struct list_head node;
91 struct parisc_device *padev;
92 struct serio *port;
93 spinlock_t lock;
94 char *addr;
95 u8 act, append;
96 struct {
97 u8 data;
98 u8 str;
99 } buffer[BUFFER_SIZE+1];
100 int id;
101};
102
103
104
105
106
107#define gscps2_readb_input(x) readb((x)+GSC_RCVDATA)
108#define gscps2_readb_control(x) readb((x)+GSC_CONTROL)
109#define gscps2_readb_status(x) readb((x)+GSC_STATUS)
110#define gscps2_writeb_control(x, y) writeb((x), (y)+GSC_CONTROL)
111
112
113
114
115
116
117static int wait_TBE(char *addr)
118{
119 int timeout = 25000;
120 while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
121 if (!--timeout)
122 return 0;
123 udelay(10);
124 }
125 return 1;
126}
127
128
129
130
131
132
133static void gscps2_flush(struct gscps2port *ps2port)
134{
135 while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
136 gscps2_readb_input(ps2port->addr);
137 ps2port->act = ps2port->append = 0;
138}
139
140
141
142
143
144
145
146static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
147{
148 unsigned long flags;
149 char *addr = ps2port->addr;
150
151 if (!wait_TBE(addr)) {
152 printk(KERN_DEBUG PFX "timeout - could not write byte %#x\n", data);
153 return 0;
154 }
155
156 while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
157 ;
158
159 spin_lock_irqsave(&ps2port->lock, flags);
160 writeb(data, addr+GSC_XMTDATA);
161 spin_unlock_irqrestore(&ps2port->lock, flags);
162
163
164 mdelay(6);
165
166
167
168 gscps2_interrupt(0, NULL);
169
170 return 1;
171}
172
173
174
175
176
177
178static void gscps2_enable(struct gscps2port *ps2port, int enable)
179{
180 unsigned long flags;
181 u8 data;
182
183
184 spin_lock_irqsave(&ps2port->lock, flags);
185 gscps2_flush(ps2port);
186 data = gscps2_readb_control(ps2port->addr);
187 if (enable)
188 data |= GSC_CTRL_ENBL;
189 else
190 data &= ~GSC_CTRL_ENBL;
191 gscps2_writeb_control(data, ps2port->addr);
192 spin_unlock_irqrestore(&ps2port->lock, flags);
193 wait_TBE(ps2port->addr);
194 gscps2_flush(ps2port);
195}
196
197
198
199
200
201static void gscps2_reset(struct gscps2port *ps2port)
202{
203 char *addr = ps2port->addr;
204 unsigned long flags;
205
206
207 spin_lock_irqsave(&ps2port->lock, flags);
208 gscps2_flush(ps2port);
209 writeb(0xff, addr+GSC_RESET);
210 gscps2_flush(ps2port);
211 spin_unlock_irqrestore(&ps2port->lock, flags);
212}
213
214static LIST_HEAD(ps2port_list);
215
216
217
218
219
220
221
222
223
224
225
226
227
228static irqreturn_t gscps2_interrupt(int irq, void *dev)
229{
230 struct gscps2port *ps2port;
231
232 list_for_each_entry(ps2port, &ps2port_list, node) {
233
234 unsigned long flags;
235 spin_lock_irqsave(&ps2port->lock, flags);
236
237 while ( (ps2port->buffer[ps2port->append].str =
238 gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
239 ps2port->buffer[ps2port->append].data =
240 gscps2_readb_input(ps2port->addr);
241 ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
242 }
243
244 spin_unlock_irqrestore(&ps2port->lock, flags);
245
246 }
247
248
249
250 list_for_each_entry(ps2port, &ps2port_list, node) {
251
252 while (ps2port->act != ps2port->append) {
253
254 unsigned int rxflags;
255 u8 data, status;
256
257
258
259 if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
260 return IRQ_HANDLED;
261
262 status = ps2port->buffer[ps2port->act].str;
263 data = ps2port->buffer[ps2port->act].data;
264
265 ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
266 rxflags = ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
267 ((status & GSC_STAT_PERR) ? SERIO_PARITY : 0 );
268
269 serio_interrupt(ps2port->port, data, rxflags);
270
271 }
272
273 }
274
275 return IRQ_HANDLED;
276}
277
278
279
280
281
282
283static int gscps2_write(struct serio *port, unsigned char data)
284{
285 struct gscps2port *ps2port = port->port_data;
286
287 if (!gscps2_writeb_output(ps2port, data)) {
288 printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
289 return -1;
290 }
291 return 0;
292}
293
294
295
296
297
298
299static int gscps2_open(struct serio *port)
300{
301 struct gscps2port *ps2port = port->port_data;
302
303 gscps2_reset(ps2port);
304
305
306 gscps2_enable(ps2port, ENABLE);
307
308 gscps2_interrupt(0, NULL);
309
310 return 0;
311}
312
313
314
315
316
317static void gscps2_close(struct serio *port)
318{
319 struct gscps2port *ps2port = port->port_data;
320 gscps2_enable(ps2port, DISABLE);
321}
322
323
324
325
326
327
328static int gscps2_probe(struct parisc_device *dev)
329{
330 struct gscps2port *ps2port;
331 struct serio *serio;
332 unsigned long hpa = dev->hpa.start;
333 int ret;
334
335 if (!dev->irq)
336 return -ENODEV;
337
338
339 if (dev->id.sversion == 0x96)
340 hpa += GSC_DINO_OFFSET;
341
342 ps2port = kzalloc(sizeof(struct gscps2port), GFP_KERNEL);
343 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
344 if (!ps2port || !serio) {
345 ret = -ENOMEM;
346 goto fail_nomem;
347 }
348
349 dev_set_drvdata(&dev->dev, ps2port);
350
351 ps2port->port = serio;
352 ps2port->padev = dev;
353 ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4);
354 spin_lock_init(&ps2port->lock);
355
356 gscps2_reset(ps2port);
357 ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
358
359 snprintf(serio->name, sizeof(serio->name), "gsc-ps2-%s",
360 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
361 strlcpy(serio->phys, dev_name(&dev->dev), sizeof(serio->phys));
362 serio->id.type = SERIO_8042;
363 serio->write = gscps2_write;
364 serio->open = gscps2_open;
365 serio->close = gscps2_close;
366 serio->port_data = ps2port;
367 serio->dev.parent = &dev->dev;
368
369 ret = -EBUSY;
370 if (request_irq(dev->irq, gscps2_interrupt, IRQF_SHARED, ps2port->port->name, ps2port))
371 goto fail_miserably;
372
373 if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
374 printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
375 hpa, ps2port->id);
376 ret = -ENODEV;
377 goto fail;
378 }
379
380#if 0
381 if (!request_mem_region(hpa, GSC_STATUS + 4, ps2port->port.name))
382 goto fail;
383#endif
384
385 printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
386 ps2port->port->name,
387 ps2port->addr,
388 ps2port->padev->irq,
389 ps2port->port->phys);
390
391 serio_register_port(ps2port->port);
392
393 list_add_tail(&ps2port->node, &ps2port_list);
394
395 return 0;
396
397fail:
398 free_irq(dev->irq, ps2port);
399
400fail_miserably:
401 iounmap(ps2port->addr);
402 release_mem_region(dev->hpa.start, GSC_STATUS + 4);
403
404fail_nomem:
405 kfree(ps2port);
406 kfree(serio);
407 return ret;
408}
409
410
411
412
413
414
415static int gscps2_remove(struct parisc_device *dev)
416{
417 struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
418
419 serio_unregister_port(ps2port->port);
420 free_irq(dev->irq, ps2port);
421 gscps2_flush(ps2port);
422 list_del(&ps2port->node);
423 iounmap(ps2port->addr);
424#if 0
425 release_mem_region(dev->hpa, GSC_STATUS + 4);
426#endif
427 dev_set_drvdata(&dev->dev, NULL);
428 kfree(ps2port);
429 return 0;
430}
431
432
433static struct parisc_device_id gscps2_device_tbl[] = {
434 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 },
435#ifdef DINO_TESTED
436 { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 },
437#endif
438 { 0, }
439};
440MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
441
442static struct parisc_driver parisc_ps2_driver = {
443 .name = "gsc_ps2",
444 .id_table = gscps2_device_tbl,
445 .probe = gscps2_probe,
446 .remove = gscps2_remove,
447};
448
449static int __init gscps2_init(void)
450{
451 register_parisc_driver(&parisc_ps2_driver);
452 return 0;
453}
454
455static void __exit gscps2_exit(void)
456{
457 unregister_parisc_driver(&parisc_ps2_driver);
458}
459
460
461module_init(gscps2_init);
462module_exit(gscps2_exit);
463
464