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