OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [input/] [serio/] [gscps2.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * drivers/input/serio/gscps2.c
3
 *
4
 * Copyright (c) 2004-2006 Helge Deller <deller@gmx.de>
5
 * Copyright (c) 2002 Laurent Canet <canetl@esiee.fr>
6
 * Copyright (c) 2002 Thibaut Varene <varenet@parisc-linux.org>
7
 *
8
 * Pieces of code based on linux-2.4's hp_mouse.c & hp_keyb.c
9
 *      Copyright (c) 1999 Alex deVries <alex@onefishtwo.ca>
10
 *      Copyright (c) 1999-2000 Philipp Rumpf <prumpf@tux.org>
11
 *      Copyright (c) 2000 Xavier Debacker <debackex@esiee.fr>
12
 *      Copyright (c) 2000-2001 Thomas Marteau <marteaut@esiee.fr>
13
 *
14
 * HP GSC PS/2 port driver, found in PA/RISC Workstations
15
 *
16
 * This file is subject to the terms and conditions of the GNU General Public
17
 * License.  See the file "COPYING" in the main directory of this archive
18
 * for more details.
19
 *
20
 * TODO:
21
 * - Dino testing (did HP ever shipped a machine on which this port
22
 *                 was usable/enabled ?)
23
 */
24
 
25
#include <linux/init.h>
26
#include <linux/module.h>
27
#include <linux/serio.h>
28
#include <linux/input.h>
29
#include <linux/interrupt.h>
30
#include <linux/spinlock.h>
31
#include <linux/delay.h>
32
#include <linux/ioport.h>
33
#include <linux/pci_ids.h>
34
 
35
#include <asm/irq.h>
36
#include <asm/io.h>
37
#include <asm/parisc-device.h>
38
 
39
MODULE_AUTHOR("Laurent Canet <canetl@esiee.fr>, Thibaut Varene <varenet@parisc-linux.org>, Helge Deller <deller@gmx.de>");
40
MODULE_DESCRIPTION("HP GSC PS2 port driver");
41
MODULE_LICENSE("GPL");
42
MODULE_DEVICE_TABLE(parisc, gscps2_device_tbl);
43
 
44
#define PFX "gscps2.c: "
45
 
46
/*
47
 * Driver constants
48
 */
49
 
50
/* various constants */
51
#define ENABLE                  1
52
#define DISABLE                 0
53
 
54
#define GSC_DINO_OFFSET         0x0800  /* offset for DINO controller versus LASI one */
55
 
56
/* PS/2 IO port offsets */
57
#define GSC_ID                  0x00    /* device ID offset (see: GSC_ID_XXX) */
58
#define GSC_RESET               0x00    /* reset port offset */
59
#define GSC_RCVDATA             0x04    /* receive port offset */
60
#define GSC_XMTDATA             0x04    /* transmit port offset */
61
#define GSC_CONTROL             0x08    /* see: Control register bits */
62
#define GSC_STATUS              0x0C    /* see: Status register bits */
63
 
64
/* Control register bits */
65
#define GSC_CTRL_ENBL           0x01    /* enable interface */
66
#define GSC_CTRL_LPBXR          0x02    /* loopback operation */
67
#define GSC_CTRL_DIAG           0x20    /* directly control clock/data line */
68
#define GSC_CTRL_DATDIR         0x40    /* data line direct control */
69
#define GSC_CTRL_CLKDIR         0x80    /* clock line direct control */
70
 
71
/* Status register bits */
72
#define GSC_STAT_RBNE           0x01    /* Receive Buffer Not Empty */
73
#define GSC_STAT_TBNE           0x02    /* Transmit Buffer Not Empty */
74
#define GSC_STAT_TERR           0x04    /* Timeout Error */
75
#define GSC_STAT_PERR           0x08    /* Parity Error */
76
#define GSC_STAT_CMPINTR        0x10    /* Composite Interrupt = irq on any port */
77
#define GSC_STAT_DATSHD         0x40    /* Data Line Shadow */
78
#define GSC_STAT_CLKSHD         0x80    /* Clock Line Shadow */
79
 
80
/* IDs returned by GSC_ID port register */
81
#define GSC_ID_KEYBOARD         0        /* device ID values */
82
#define GSC_ID_MOUSE            1
83
 
84
 
85
static irqreturn_t gscps2_interrupt(int irq, void *dev);
86
 
87
#define BUFFER_SIZE 0x0f
88
 
89
/* GSC PS/2 port device struct */
90
struct gscps2port {
91
        struct list_head node;
92
        struct parisc_device *padev;
93
        struct serio *port;
94
        spinlock_t lock;
95
        char *addr;
96
        u8 act, append; /* position in buffer[] */
97
        struct {
98
                u8 data;
99
                u8 str;
100
        } buffer[BUFFER_SIZE+1];
101
        int id;
102
};
103
 
104
/*
105
 * Various HW level routines
106
 */
107
 
108
#define gscps2_readb_input(x)           readb((x)+GSC_RCVDATA)
109
#define gscps2_readb_control(x)         readb((x)+GSC_CONTROL)
110
#define gscps2_readb_status(x)          readb((x)+GSC_STATUS)
111
#define gscps2_writeb_control(x, y)     writeb((x), (y)+GSC_CONTROL)
112
 
113
 
114
/*
115
 * wait_TBE() - wait for Transmit Buffer Empty
116
 */
117
 
118
static int wait_TBE(char *addr)
119
{
120
        int timeout = 25000; /* device is expected to react within 250 msec */
121
        while (gscps2_readb_status(addr) & GSC_STAT_TBNE) {
122
                if (!--timeout)
123
                        return 0;        /* This should not happen */
124
                udelay(10);
125
        }
126
        return 1;
127
}
128
 
129
 
130
/*
131
 * gscps2_flush() - flush the receive buffer
132
 */
133
 
134
static void gscps2_flush(struct gscps2port *ps2port)
135
{
136
        while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
137
                gscps2_readb_input(ps2port->addr);
138
        ps2port->act = ps2port->append = 0;
139
}
140
 
141
/*
142
 * gscps2_writeb_output() - write a byte to the port
143
 *
144
 * returns 1 on sucess, 0 on error
145
 */
146
 
147
static inline int gscps2_writeb_output(struct gscps2port *ps2port, u8 data)
148
{
149
        unsigned long flags;
150
        char *addr = ps2port->addr;
151
 
152
        if (!wait_TBE(addr)) {
153
                printk(KERN_DEBUG PFX "timeout - could not write byte %#x\n", data);
154
                return 0;
155
        }
156
 
157
        while (gscps2_readb_status(ps2port->addr) & GSC_STAT_RBNE)
158
                /* wait */;
159
 
160
        spin_lock_irqsave(&ps2port->lock, flags);
161
        writeb(data, addr+GSC_XMTDATA);
162
        spin_unlock_irqrestore(&ps2port->lock, flags);
163
 
164
        /* this is ugly, but due to timing of the port it seems to be necessary. */
165
        mdelay(6);
166
 
167
        /* make sure any received data is returned as fast as possible */
168
        /* this is important e.g. when we set the LEDs on the keyboard */
169
        gscps2_interrupt(0, NULL);
170
 
171
        return 1;
172
}
173
 
174
 
175
/*
176
 * gscps2_enable() - enables or disables the port
177
 */
178
 
179
static void gscps2_enable(struct gscps2port *ps2port, int enable)
180
{
181
        unsigned long flags;
182
        u8 data;
183
 
184
        /* now enable/disable the port */
185
        spin_lock_irqsave(&ps2port->lock, flags);
186
        gscps2_flush(ps2port);
187
        data = gscps2_readb_control(ps2port->addr);
188
        if (enable)
189
                data |= GSC_CTRL_ENBL;
190
        else
191
                data &= ~GSC_CTRL_ENBL;
192
        gscps2_writeb_control(data, ps2port->addr);
193
        spin_unlock_irqrestore(&ps2port->lock, flags);
194
        wait_TBE(ps2port->addr);
195
        gscps2_flush(ps2port);
196
}
197
 
198
/*
199
 * gscps2_reset() - resets the PS/2 port
200
 */
201
 
202
static void gscps2_reset(struct gscps2port *ps2port)
203
{
204
        char *addr = ps2port->addr;
205
        unsigned long flags;
206
 
207
        /* reset the interface */
208
        spin_lock_irqsave(&ps2port->lock, flags);
209
        gscps2_flush(ps2port);
210
        writeb(0xff, addr+GSC_RESET);
211
        gscps2_flush(ps2port);
212
        spin_unlock_irqrestore(&ps2port->lock, flags);
213
}
214
 
215
static LIST_HEAD(ps2port_list);
216
 
217
/**
218
 * gscps2_interrupt() - Interruption service routine
219
 *
220
 * This function reads received PS/2 bytes and processes them on
221
 * all interfaces.
222
 * The problematic part here is, that the keyboard and mouse PS/2 port
223
 * share the same interrupt and it's not possible to send data if any
224
 * one of them holds input data. To solve this problem we try to receive
225
 * the data as fast as possible and handle the reporting to the upper layer
226
 * later.
227
 */
228
 
229
static irqreturn_t gscps2_interrupt(int irq, void *dev)
230
{
231
        struct gscps2port *ps2port;
232
 
233
        list_for_each_entry(ps2port, &ps2port_list, node) {
234
 
235
          unsigned long flags;
236
          spin_lock_irqsave(&ps2port->lock, flags);
237
 
238
          while ( (ps2port->buffer[ps2port->append].str =
239
                   gscps2_readb_status(ps2port->addr)) & GSC_STAT_RBNE ) {
240
                ps2port->buffer[ps2port->append].data =
241
                                gscps2_readb_input(ps2port->addr);
242
                ps2port->append = ((ps2port->append+1) & BUFFER_SIZE);
243
          }
244
 
245
          spin_unlock_irqrestore(&ps2port->lock, flags);
246
 
247
        } /* list_for_each_entry */
248
 
249
        /* all data was read from the ports - now report the data to upper layer */
250
 
251
        list_for_each_entry(ps2port, &ps2port_list, node) {
252
 
253
          while (ps2port->act != ps2port->append) {
254
 
255
            unsigned int rxflags;
256
            u8 data, status;
257
 
258
            /* Did new data arrived while we read existing data ?
259
               If yes, exit now and let the new irq handler start over again */
260
            if (gscps2_readb_status(ps2port->addr) & GSC_STAT_CMPINTR)
261
                return IRQ_HANDLED;
262
 
263
            status = ps2port->buffer[ps2port->act].str;
264
            data   = ps2port->buffer[ps2port->act].data;
265
 
266
            ps2port->act = ((ps2port->act+1) & BUFFER_SIZE);
267
            rxflags =   ((status & GSC_STAT_TERR) ? SERIO_TIMEOUT : 0 ) |
268
                        ((status & GSC_STAT_PERR) ? SERIO_PARITY  : 0 );
269
 
270
            serio_interrupt(ps2port->port, data, rxflags);
271
 
272
          } /* while() */
273
 
274
        } /* list_for_each_entry */
275
 
276
        return IRQ_HANDLED;
277
}
278
 
279
 
280
/*
281
 * gscps2_write() - send a byte out through the aux interface.
282
 */
283
 
284
static int gscps2_write(struct serio *port, unsigned char data)
285
{
286
        struct gscps2port *ps2port = port->port_data;
287
 
288
        if (!gscps2_writeb_output(ps2port, data)) {
289
                printk(KERN_DEBUG PFX "sending byte %#x failed.\n", data);
290
                return -1;
291
        }
292
        return 0;
293
}
294
 
295
/*
296
 * gscps2_open() is called when a port is opened by the higher layer.
297
 * It resets and enables the port.
298
 */
299
 
300
static int gscps2_open(struct serio *port)
301
{
302
        struct gscps2port *ps2port = port->port_data;
303
 
304
        gscps2_reset(ps2port);
305
 
306
        /* enable it */
307
        gscps2_enable(ps2port, ENABLE);
308
 
309
        gscps2_interrupt(0, NULL);
310
 
311
        return 0;
312
}
313
 
314
/*
315
 * gscps2_close() disables the port
316
 */
317
 
318
static void gscps2_close(struct serio *port)
319
{
320
        struct gscps2port *ps2port = port->port_data;
321
        gscps2_enable(ps2port, DISABLE);
322
}
323
 
324
/**
325
 * gscps2_probe() - Probes PS2 devices
326
 * @return: success/error report
327
 */
328
 
329
static int __init gscps2_probe(struct parisc_device *dev)
330
{
331
        struct gscps2port *ps2port;
332
        struct serio *serio;
333
        unsigned long hpa = dev->hpa.start;
334
        int ret;
335
 
336
        if (!dev->irq)
337
                return -ENODEV;
338
 
339
        /* Offset for DINO PS/2. Works with LASI even */
340
        if (dev->id.sversion == 0x96)
341
                hpa += GSC_DINO_OFFSET;
342
 
343
        ps2port = kzalloc(sizeof(struct gscps2port), GFP_KERNEL);
344
        serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
345
        if (!ps2port || !serio) {
346
                ret = -ENOMEM;
347
                goto fail_nomem;
348
        }
349
 
350
        dev_set_drvdata(&dev->dev, ps2port);
351
 
352
        ps2port->port = serio;
353
        ps2port->padev = dev;
354
        ps2port->addr = ioremap_nocache(hpa, GSC_STATUS + 4);
355
        spin_lock_init(&ps2port->lock);
356
 
357
        gscps2_reset(ps2port);
358
        ps2port->id = readb(ps2port->addr + GSC_ID) & 0x0f;
359
 
360
        snprintf(serio->name, sizeof(serio->name), "GSC PS/2 %s",
361
                 (ps2port->id == GSC_ID_KEYBOARD) ? "keyboard" : "mouse");
362
        strlcpy(serio->phys, dev->dev.bus_id, sizeof(serio->phys));
363
        serio->id.type          = SERIO_8042;
364
        serio->write            = gscps2_write;
365
        serio->open             = gscps2_open;
366
        serio->close            = gscps2_close;
367
        serio->port_data        = ps2port;
368
        serio->dev.parent       = &dev->dev;
369
 
370
        ret = -EBUSY;
371
        if (request_irq(dev->irq, gscps2_interrupt, IRQF_SHARED, ps2port->port->name, ps2port))
372
                goto fail_miserably;
373
 
374
        if (ps2port->id != GSC_ID_KEYBOARD && ps2port->id != GSC_ID_MOUSE) {
375
                printk(KERN_WARNING PFX "Unsupported PS/2 port at 0x%08lx (id=%d) ignored\n",
376
                                hpa, ps2port->id);
377
                ret = -ENODEV;
378
                goto fail;
379
        }
380
 
381
#if 0
382
        if (!request_mem_region(hpa, GSC_STATUS + 4, ps2port->port.name))
383
                goto fail;
384
#endif
385
 
386
        printk(KERN_INFO "serio: %s port at 0x%p irq %d @ %s\n",
387
                ps2port->port->name,
388
                ps2port->addr,
389
                ps2port->padev->irq,
390
                ps2port->port->phys);
391
 
392
        serio_register_port(ps2port->port);
393
 
394
        list_add_tail(&ps2port->node, &ps2port_list);
395
 
396
        return 0;
397
 
398
fail:
399
        free_irq(dev->irq, ps2port);
400
 
401
fail_miserably:
402
        iounmap(ps2port->addr);
403
        release_mem_region(dev->hpa.start, GSC_STATUS + 4);
404
 
405
fail_nomem:
406
        kfree(ps2port);
407
        kfree(serio);
408
        return ret;
409
}
410
 
411
/**
412
 * gscps2_remove() - Removes PS2 devices
413
 * @return: success/error report
414
 */
415
 
416
static int __devexit gscps2_remove(struct parisc_device *dev)
417
{
418
        struct gscps2port *ps2port = dev_get_drvdata(&dev->dev);
419
 
420
        serio_unregister_port(ps2port->port);
421
        free_irq(dev->irq, ps2port);
422
        gscps2_flush(ps2port);
423
        list_del(&ps2port->node);
424
        iounmap(ps2port->addr);
425
#if 0
426
        release_mem_region(dev->hpa, GSC_STATUS + 4);
427
#endif
428
        dev_set_drvdata(&dev->dev, NULL);
429
        kfree(ps2port);
430
        return 0;
431
}
432
 
433
 
434
static struct parisc_device_id gscps2_device_tbl[] = {
435
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00084 }, /* LASI PS/2 */
436
#ifdef DINO_TESTED
437
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00096 }, /* DINO PS/2 */
438
#endif
439
        { 0, }   /* 0 terminated list */
440
};
441
 
442
static 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
 
449
static int __init gscps2_init(void)
450
{
451
        register_parisc_driver(&parisc_ps2_driver);
452
        return 0;
453
}
454
 
455
static void __exit gscps2_exit(void)
456
{
457
        unregister_parisc_driver(&parisc_ps2_driver);
458
}
459
 
460
 
461
module_init(gscps2_init);
462
module_exit(gscps2_exit);
463
 

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.