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

Subversion Repositories test_project

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  linux/drivers/hil/hilkbd.c
3
 *
4
 *  Copyright (C) 1998 Philip Blundell <philb@gnu.org>
5
 *  Copyright (C) 1999 Matthew Wilcox <willy@bofh.ai>
6
 *  Copyright (C) 1999-2007 Helge Deller <deller@gmx.de>
7
 *
8
 *  Very basic HP Human Interface Loop (HIL) driver.
9
 *  This driver handles the keyboard on HP300 (m68k) and on some
10
 *  HP700 (parisc) series machines.
11
 *
12
 *
13
 * This file is subject to the terms and conditions of the GNU General Public
14
 * License version 2.  See the file COPYING in the main directory of this
15
 * archive for more details.
16
 */
17
 
18
#include <linux/pci_ids.h>
19
#include <linux/ioport.h>
20
#include <linux/module.h>
21
#include <linux/errno.h>
22
#include <linux/input.h>
23
#include <linux/init.h>
24
#include <linux/interrupt.h>
25
#include <linux/hil.h>
26
#include <linux/io.h>
27
#include <linux/spinlock.h>
28
#include <asm/irq.h>
29
#ifdef CONFIG_HP300
30
#include <asm/hwtest.h>
31
#endif
32
 
33
 
34
MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller");
35
MODULE_DESCRIPTION("HIL keyboard driver (basic functionality)");
36
MODULE_LICENSE("GPL v2");
37
 
38
 
39
#if defined(CONFIG_PARISC)
40
 
41
 #include <asm/io.h>
42
 #include <asm/hardware.h>
43
 #include <asm/parisc-device.h>
44
 static unsigned long hil_base; /* HPA for the HIL device */
45
 static unsigned int hil_irq;
46
 #define HILBASE                hil_base /* HPPA (parisc) port address */
47
 #define HIL_DATA               0x800
48
 #define HIL_CMD                0x801
49
 #define HIL_IRQ                hil_irq
50
 #define hil_readb(p)           gsc_readb(p)
51
 #define hil_writeb(v,p)        gsc_writeb((v),(p))
52
 
53
#elif defined(CONFIG_HP300)
54
 
55
 #define HILBASE                0xf0428000UL /* HP300 (m68k) port address */
56
 #define HIL_DATA               0x1
57
 #define HIL_CMD                0x3
58
 #define HIL_IRQ                2
59
 #define hil_readb(p)           readb(p)
60
 #define hil_writeb(v,p)        writeb((v),(p))
61
 
62
#else
63
#error "HIL is not supported on this platform"
64
#endif
65
 
66
 
67
 
68
/* HIL helper functions */
69
 
70
#define hil_busy()              (hil_readb(HILBASE + HIL_CMD) & HIL_BUSY)
71
#define hil_data_available()    (hil_readb(HILBASE + HIL_CMD) & HIL_DATA_RDY)
72
#define hil_status()            (hil_readb(HILBASE + HIL_CMD))
73
#define hil_command(x)          do { hil_writeb((x), HILBASE + HIL_CMD); } while (0)
74
#define hil_read_data()         (hil_readb(HILBASE + HIL_DATA))
75
#define hil_write_data(x)       do { hil_writeb((x), HILBASE + HIL_DATA); } while (0)
76
 
77
/* HIL constants */
78
 
79
#define HIL_BUSY                0x02
80
#define HIL_DATA_RDY            0x01
81
 
82
#define HIL_SETARD              0xA0            /* set auto-repeat delay */
83
#define HIL_SETARR              0xA2            /* set auto-repeat rate */
84
#define HIL_SETTONE             0xA3            /* set tone generator */
85
#define HIL_CNMT                0xB2            /* clear nmi */
86
#define HIL_INTON               0x5C            /* Turn on interrupts. */
87
#define HIL_INTOFF              0x5D            /* Turn off interrupts. */
88
 
89
#define HIL_READKBDSADR         0xF9
90
#define HIL_WRITEKBDSADR        0xE9
91
 
92
static unsigned int hphilkeyb_keycode[HIL_KEYCODES_SET1_TBLSIZE] __read_mostly =
93
        { HIL_KEYCODES_SET1 };
94
 
95
/* HIL structure */
96
static struct {
97
        struct input_dev *dev;
98
 
99
        unsigned int curdev;
100
 
101
        unsigned char s;
102
        unsigned char c;
103
        int valid;
104
 
105
        unsigned char data[16];
106
        unsigned int ptr;
107
        spinlock_t lock;
108
 
109
        void *dev_id;   /* native bus device */
110
} hil_dev;
111
 
112
 
113
static void poll_finished(void)
114
{
115
        int down;
116
        int key;
117
        unsigned char scode;
118
 
119
        switch (hil_dev.data[0]) {
120
        case 0x40:
121
                down = (hil_dev.data[1] & 1) == 0;
122
                scode = hil_dev.data[1] >> 1;
123
                key = hphilkeyb_keycode[scode];
124
                input_report_key(hil_dev.dev, key, down);
125
                break;
126
        }
127
        hil_dev.curdev = 0;
128
}
129
 
130
 
131
static inline void handle_status(unsigned char s, unsigned char c)
132
{
133
        if (c & 0x8) {
134
                /* End of block */
135
                if (c & 0x10)
136
                        poll_finished();
137
        } else {
138
                if (c & 0x10) {
139
                        if (hil_dev.curdev)
140
                                poll_finished();  /* just in case */
141
                        hil_dev.curdev = c & 7;
142
                        hil_dev.ptr = 0;
143
                }
144
        }
145
}
146
 
147
 
148
static inline void handle_data(unsigned char s, unsigned char c)
149
{
150
        if (hil_dev.curdev) {
151
                hil_dev.data[hil_dev.ptr++] = c;
152
                hil_dev.ptr &= 15;
153
        }
154
}
155
 
156
 
157
/* handle HIL interrupts */
158
static irqreturn_t hil_interrupt(int irq, void *handle)
159
{
160
        unsigned char s, c;
161
 
162
        s = hil_status();
163
        c = hil_read_data();
164
 
165
        switch (s >> 4) {
166
        case 0x5:
167
                handle_status(s, c);
168
                break;
169
        case 0x6:
170
                handle_data(s, c);
171
                break;
172
        case 0x4:
173
                hil_dev.s = s;
174
                hil_dev.c = c;
175
                mb();
176
                hil_dev.valid = 1;
177
                break;
178
        }
179
        return IRQ_HANDLED;
180
}
181
 
182
 
183
/* send a command to the HIL */
184
static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
185
{
186
        unsigned long flags;
187
 
188
        spin_lock_irqsave(&hil_dev.lock, flags);
189
        while (hil_busy())
190
                /* wait */;
191
        hil_command(cmd);
192
        while (len--) {
193
                while (hil_busy())
194
                        /* wait */;
195
                hil_write_data(*(data++));
196
        }
197
        spin_unlock_irqrestore(&hil_dev.lock, flags);
198
}
199
 
200
 
201
/* initialise HIL */
202
static int __init
203
hil_keyb_init(void)
204
{
205
        unsigned char c;
206
        unsigned int i, kbid;
207
        wait_queue_head_t hil_wait;
208
        int err;
209
 
210
        if (hil_dev.dev) {
211
                return -ENODEV; /* already initialized */
212
        }
213
 
214
        spin_lock_init(&hil_dev.lock);
215
        hil_dev.dev = input_allocate_device();
216
        if (!hil_dev.dev)
217
                return -ENOMEM;
218
 
219
#if defined(CONFIG_HP300)
220
        if (!hwreg_present((void *)(HILBASE + HIL_DATA))) {
221
                printk(KERN_ERR "HIL: hardware register was not found\n");
222
                err = -ENODEV;
223
                goto err1;
224
        }
225
        if (!request_region(HILBASE + HIL_DATA, 2, "hil")) {
226
                printk(KERN_ERR "HIL: IOPORT region already used\n");
227
                err = -EIO;
228
                goto err1;
229
        }
230
#endif
231
 
232
        err = request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
233
        if (err) {
234
                printk(KERN_ERR "HIL: Can't get IRQ\n");
235
                goto err2;
236
        }
237
 
238
        /* Turn on interrupts */
239
        hil_do(HIL_INTON, NULL, 0);
240
 
241
        /* Look for keyboards */
242
        hil_dev.valid = 0;       /* clear any pending data */
243
        hil_do(HIL_READKBDSADR, NULL, 0);
244
 
245
        init_waitqueue_head(&hil_wait);
246
        wait_event_interruptible_timeout(hil_wait, hil_dev.valid, 3*HZ);
247
        if (!hil_dev.valid) {
248
                printk(KERN_WARNING "HIL: timed out, assuming no keyboard present\n");
249
        }
250
 
251
        c = hil_dev.c;
252
        hil_dev.valid = 0;
253
        if (c == 0) {
254
                kbid = -1;
255
                printk(KERN_WARNING "HIL: no keyboard present\n");
256
        } else {
257
                kbid = ffz(~c);
258
                printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid);
259
        }
260
 
261
        /* set it to raw mode */
262
        c = 0;
263
        hil_do(HIL_WRITEKBDSADR, &c, 1);
264
 
265
        for (i = 0; i < HIL_KEYCODES_SET1_TBLSIZE; i++)
266
                if (hphilkeyb_keycode[i] != KEY_RESERVED)
267
                        set_bit(hphilkeyb_keycode[i], hil_dev.dev->keybit);
268
 
269
        hil_dev.dev->evbit[0]    = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP);
270
        hil_dev.dev->ledbit[0]   = BIT_MASK(LED_NUML) | BIT_MASK(LED_CAPSL) |
271
                BIT_MASK(LED_SCROLLL);
272
        hil_dev.dev->keycodemax = HIL_KEYCODES_SET1_TBLSIZE;
273
        hil_dev.dev->keycodesize= sizeof(hphilkeyb_keycode[0]);
274
        hil_dev.dev->keycode    = hphilkeyb_keycode;
275
        hil_dev.dev->name       = "HIL keyboard";
276
        hil_dev.dev->phys       = "hpkbd/input0";
277
 
278
        hil_dev.dev->id.bustype = BUS_HIL;
279
        hil_dev.dev->id.vendor  = PCI_VENDOR_ID_HP;
280
        hil_dev.dev->id.product = 0x0001;
281
        hil_dev.dev->id.version = 0x0010;
282
 
283
        err = input_register_device(hil_dev.dev);
284
        if (err) {
285
                printk(KERN_ERR "HIL: Can't register device\n");
286
                goto err3;
287
        }
288
        printk(KERN_INFO "input: %s, ID %d at 0x%08lx (irq %d) found and attached\n",
289
               hil_dev.dev->name, kbid, HILBASE, HIL_IRQ);
290
 
291
        return 0;
292
 
293
err3:
294
        hil_do(HIL_INTOFF, NULL, 0);
295
        disable_irq(HIL_IRQ);
296
        free_irq(HIL_IRQ, hil_dev.dev_id);
297
err2:
298
#if defined(CONFIG_HP300)
299
        release_region(HILBASE + HIL_DATA, 2);
300
err1:
301
#endif
302
        input_free_device(hil_dev.dev);
303
        hil_dev.dev = NULL;
304
        return err;
305
}
306
 
307
 
308
#if defined(CONFIG_PARISC)
309
static int __init
310
hil_init_chip(struct parisc_device *dev)
311
{
312
        if (!dev->irq) {
313
                printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
314
                return -ENODEV;
315
        }
316
 
317
        hil_base = dev->hpa.start;
318
        hil_irq  = dev->irq;
319
        hil_dev.dev_id = dev;
320
 
321
        printk(KERN_INFO "Found HIL bus at 0x%08lx, IRQ %d\n", hil_base, hil_irq);
322
 
323
        return hil_keyb_init();
324
}
325
 
326
static struct parisc_device_id hil_tbl[] = {
327
        { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
328
        { 0, }
329
};
330
 
331
MODULE_DEVICE_TABLE(parisc, hil_tbl);
332
 
333
static struct parisc_driver hil_driver = {
334
        .name =         "hil",
335
        .id_table =     hil_tbl,
336
        .probe =        hil_init_chip,
337
};
338
#endif /* CONFIG_PARISC */
339
 
340
 
341
static int __init hil_init(void)
342
{
343
#if defined(CONFIG_PARISC)
344
        return register_parisc_driver(&hil_driver);
345
#else
346
        return hil_keyb_init();
347
#endif
348
}
349
 
350
 
351
static void __exit hil_exit(void)
352
{
353
        if (HIL_IRQ) {
354
                disable_irq(HIL_IRQ);
355
                free_irq(HIL_IRQ, hil_dev.dev_id);
356
        }
357
 
358
        /* Turn off interrupts */
359
        hil_do(HIL_INTOFF, NULL, 0);
360
 
361
        input_unregister_device(hil_dev.dev);
362
 
363
        hil_dev.dev = NULL;
364
 
365
#if defined(CONFIG_PARISC)
366
        unregister_parisc_driver(&hil_driver);
367
#else
368
        release_region(HILBASE+HIL_DATA, 2);
369
#endif
370
}
371
 
372
module_init(hil_init);
373
module_exit(hil_exit);

powered by: WebSVN 2.1.0

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