setup enviroment for compilation
[linux-2.4.21-pre4.git] / drivers / hil / 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-2002 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/config.h>
22 #include <linux/errno.h>
23 #include <linux/input.h>
24 #include <linux/init.h>
25 #include <linux/irq.h>
26 #include <linux/hil.h>
27
28
29 MODULE_AUTHOR("Philip Blundell, Matthew Wilcox, Helge Deller");
30 MODULE_DESCRIPTION("HIL driver (basic functionality)");
31 MODULE_LICENSE("GPL");
32 EXPORT_NO_SYMBOLS;
33
34
35 #if defined(CONFIG_PARISC)
36
37  #include <asm/gsc.h>
38  #include <asm/hardware.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 #define HIL_TRIGGER             0xC5            /* trigger command */
84 #define HIL_STARTCMD            0xE0            /* start loop command */
85 #define HIL_TIMEOUT             0xFE            /* timeout */
86 #define HIL_READTIME            0x13            /* Read real time register */
87
88 #define HIL_READBUSY            0x02            /* internal "busy" register */
89 #define HIL_READKBDLANG         0x12            /* read keyboard language code */
90 #define HIL_READKBDSADR         0xF9
91 #define HIL_WRITEKBDSADR        0xE9
92 #define HIL_READLPSTAT          0xFA
93 #define HIL_WRITELPSTAT         0xEA
94 #define HIL_READLPCTRL          0xFB
95 #define HIL_WRITELPCTRL         0xEB
96
97
98 static unsigned char hil_kbd_set1[128] = {
99    KEY_5,               KEY_RESERVED,   KEY_RIGHTALT,   KEY_LEFTALT, 
100    KEY_RIGHTSHIFT,      KEY_LEFTSHIFT,  KEY_LEFTCTRL,   KEY_SYSRQ,
101    KEY_KP4,             KEY_KP8,        KEY_KP5,        KEY_KP9,
102    KEY_KP6,             KEY_KP7,        KEY_KPCOMMA,    KEY_KPENTER,
103    KEY_KP1,             KEY_KPSLASH,    KEY_KP2,        KEY_KPPLUS,
104    KEY_KP3,             KEY_KPASTERISK, KEY_KP0,        KEY_KPMINUS,
105    KEY_B,               KEY_V,          KEY_C,          KEY_X,
106    KEY_Z,               KEY_UNKNOWN,    KEY_RESERVED,   KEY_ESC,
107    KEY_6,               KEY_F10,        KEY_3,          KEY_F11,
108    KEY_KPDOT,           KEY_F9,         KEY_TAB /*KP*/, KEY_F12,
109    KEY_H,               KEY_G,          KEY_F,          KEY_D,
110    KEY_S,               KEY_A,          KEY_RESERVED,   KEY_CAPSLOCK,
111    KEY_U,               KEY_Y,          KEY_T,          KEY_R,
112    KEY_E,               KEY_W,          KEY_Q,          KEY_TAB,
113    KEY_7,               KEY_6,          KEY_5,          KEY_4,
114    KEY_3,               KEY_2,          KEY_1,          KEY_GRAVE,
115    KEY_INTL1,           KEY_INTL2,      KEY_INTL3,      KEY_INTL4, /*Buttons*/
116    KEY_INTL5,           KEY_INTL6,      KEY_INTL7,      KEY_INTL8,
117    KEY_MENU,            KEY_F4,         KEY_F3,         KEY_F2,
118    KEY_F1,              KEY_VOLUMEUP,   KEY_STOP,       KEY_SENDFILE/*Enter/Print*/, 
119    KEY_SYSRQ,           KEY_F5,         KEY_F6,         KEY_F7,
120    KEY_F8,              KEY_VOLUMEDOWN, KEY_CUT /*CLEAR_LINE*/, KEY_REFRESH /*CLEAR_DISPLAY*/,
121    KEY_8,               KEY_9,          KEY_0,          KEY_MINUS,
122    KEY_EQUAL,           KEY_BACKSPACE,  KEY_INSERT/*KPINSERT_LINE*/, KEY_DELETE /*KPDELETE_LINE*/,
123    KEY_I,               KEY_O,          KEY_P,          KEY_LEFTBRACE,
124    KEY_RIGHTBRACE,      KEY_BACKSLASH,  KEY_INSERT,     KEY_DELETE,
125    KEY_J,               KEY_K,          KEY_L,          KEY_SEMICOLON,
126    KEY_APOSTROPHE,      KEY_ENTER,      KEY_HOME,       KEY_SCROLLUP,
127    KEY_M,               KEY_COMMA,      KEY_DOT,        KEY_SLASH,
128    KEY_RESERVED,        KEY_OPEN/*Select*/,KEY_RESERVED,KEY_SCROLLDOWN/*KPNEXT*/,
129    KEY_N,               KEY_SPACE,      KEY_SCROLLDOWN/*Next*/, KEY_UNKNOWN,
130    KEY_LEFT,            KEY_DOWN,       KEY_UP,         KEY_RIGHT
131 };
132
133
134 /* HIL structure */
135 static struct {
136         struct input_dev dev;
137
138         unsigned int curdev;
139         
140         unsigned char s;
141         unsigned char c;
142         int valid;
143         
144         unsigned char data[16];
145         unsigned int ptr;
146
147         void *dev_id;   /* native bus device */
148 } hil_dev;
149
150
151 static void poll_finished(void)
152 {
153         int down;
154         int key;
155         unsigned char scode;
156         
157         switch (hil_dev.data[0]) {
158         case 0x40:
159                 down = (hil_dev.data[1] & 1) == 0;
160                 scode = hil_dev.data[1] >> 1;
161                 key = hil_kbd_set1[scode & 0x7f];
162                 input_report_key(&hil_dev.dev, key, down);
163                 break;
164         }
165         hil_dev.curdev = 0;
166 }
167
168 static inline void handle_status(unsigned char s, unsigned char c)
169 {
170         if (c & 0x8) {
171                 /* End of block */
172                 if (c & 0x10)
173                         poll_finished();
174         } else {
175                 if (c & 0x10) {
176                         if (hil_dev.curdev)
177                                 poll_finished();  /* just in case */
178                         hil_dev.curdev = c & 7;
179                         hil_dev.ptr = 0;
180                 }
181         }
182 }
183
184 static inline void handle_data(unsigned char s, unsigned char c)
185 {
186         if (hil_dev.curdev) {
187                 hil_dev.data[hil_dev.ptr++] = c;
188                 hil_dev.ptr &= 15;
189         }
190 }
191
192
193 /* 
194  * Handle HIL interrupts.
195  */
196 static void hil_interrupt(int irq, void *handle, struct pt_regs *regs)
197 {
198         unsigned char s, c;
199         
200         s = hil_status();
201         c = hil_read_data();
202
203         switch (s >> 4) {
204         case 0x5:
205                 handle_status(s, c);
206                 break;
207         case 0x6:
208                 handle_data(s, c);
209                 break;
210         case 0x4:
211                 hil_dev.s = s;
212                 hil_dev.c = c;
213                 mb();
214                 hil_dev.valid = 1;
215                 break;
216         }
217 }
218
219 /*
220  * Send a command to the HIL
221  */
222
223 static void hil_do(unsigned char cmd, unsigned char *data, unsigned int len)
224 {
225         unsigned long flags;
226
227         save_flags(flags);
228         cli();
229         while (hil_busy())
230                 /* wait */;
231         hil_command(cmd);
232         while (len--) {
233                 while (hil_busy())
234                         /* wait */;
235                 hil_write_data(*(data++));
236         }
237         restore_flags(flags);
238 }
239
240
241 /*
242  * Initialise HIL. 
243  */
244
245 static int __init
246 hil_keyb_init(void)
247 {
248         unsigned char c;
249         unsigned int i, kbid, n = 0;
250
251         if (hil_dev.dev.idbus) {
252                 printk("HIL: already initialized\n");
253                 return -ENODEV;
254         }
255         
256 #if defined(CONFIG_HP300)
257         if (!hwreg_present((void *)(HILBASE + HIL_DATA)))
258                 return -ENODEV;
259         
260         request_region(HILBASE+HIL_DATA, 2, "hil");
261 #endif
262         
263         request_irq(HIL_IRQ, hil_interrupt, 0, "hil", hil_dev.dev_id);
264
265         /* Turn on interrupts */
266         hil_do(HIL_INTON, NULL, 0);
267
268         /* Look for keyboards */
269         hil_dev.valid = 0;      /* clear any pending data */
270         hil_do(HIL_READKBDSADR, NULL, 0);
271         while (!hil_dev.valid) {
272                 if (n++ > 100000) {
273                         printk(KERN_DEBUG "HIL: timed out, assuming no keyboard present.\n");
274                         break;
275                 }
276                 mb();
277         }
278
279         c = hil_dev.c; 
280         hil_dev.valid = 0;
281         if (c == 0) {
282                 kbid = -1;
283                 printk(KERN_WARNING "HIL: no keyboard present.\n");
284         } else {
285                 kbid = ffz(~c);
286                 printk(KERN_INFO "HIL: keyboard found at id %d\n", kbid);
287         }
288
289         /* set it to raw mode */
290         c = 0;
291         hil_do(HIL_WRITEKBDSADR, &c, 1);
292         
293
294         /* register input interface */
295         hil_dev.dev.name        = "HIL keyboard";
296         hil_dev.dev.idbus       = BUS_HIL;
297         hil_dev.dev.idvendor    = PCI_VENDOR_ID_HP;
298         hil_dev.dev.idproduct   = 0x0001;
299         hil_dev.dev.idversion   = 0x0100;
300
301         hil_dev.dev.evbit[0] |= BIT(EV_KEY);
302         for (i = 0; i < 128; i++)
303                 set_bit(hil_kbd_set1[i], hil_dev.dev.keybit);
304         clear_bit(0, hil_dev.dev.keybit);
305
306 #if 1
307         /* XXX: HACK !!!
308          * remove this call if hp_psaux.c/hp_keyb.c is converted
309          * to the input layer... */
310         register_ps2_keybfuncs();
311 #endif
312         
313         input_register_device(&hil_dev.dev);
314         printk(KERN_INFO "input%d: %s on hil%d (id %d)\n",
315                 hil_dev.dev.number, hil_dev.dev.name, 0, kbid);
316
317         /* HIL keyboards don't have a numlock key,
318          * simulate a up-down sequence of numlock to 
319          * make the keypad work at expected. */
320         input_report_key(&hil_dev.dev, KEY_NUMLOCK, 1);
321
322         return 0;
323 }
324
325 #if defined(CONFIG_PARISC)
326 static int __init
327 hil_init_chip(struct parisc_device *dev)
328 {
329         if (!dev->irq) {
330                 printk(KERN_WARNING "HIL: IRQ not found for HIL at 0x%lx\n", dev->hpa);
331                 return -ENODEV;
332         }
333
334         hil_base = dev->hpa;
335         hil_irq  = dev->irq;
336         hil_dev.dev_id = dev;
337         
338         printk(KERN_INFO "Found HIL at 0x%lx, IRQ %d\n", hil_base, hil_irq);
339
340         return hil_keyb_init();
341 }
342
343 static struct parisc_device_id hil_tbl[] = {
344         { HPHW_FIO, HVERSION_REV_ANY_ID, HVERSION_ANY_ID, 0x00073 },
345         { 0, }
346 };
347
348 MODULE_DEVICE_TABLE(parisc, hil_tbl);
349
350 static struct parisc_driver hil_driver = {
351         .name =         "HIL",
352         .id_table =     hil_tbl,
353         .probe =        hil_init_chip,
354 };
355 #endif /* CONFIG_PARISC */
356
357
358
359
360
361 static int __init hil_init(void)
362 {
363 #if defined(CONFIG_PARISC)
364         return register_parisc_driver(&hil_driver);
365 #else
366         return hil_keyb_init();
367 #endif
368 }
369
370
371 static void __exit hil_exit(void)
372 {
373         if (HIL_IRQ) {
374                 disable_irq(HIL_IRQ);
375                 free_irq(HIL_IRQ, hil_dev.dev_id);
376         }
377
378         input_unregister_device(&hil_dev.dev);
379
380 #if defined(CONFIG_PARISC)
381         unregister_parisc_driver(&hil_driver);
382 #else
383         release_region(HILBASE+HIL_DATA, 2);
384 #endif
385 }
386
387 module_init(hil_init);
388 module_exit(hil_exit);
389