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 
poll_finished(void)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 
handle_status(unsigned char s,unsigned char c)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 
handle_data(unsigned char s,unsigned char c)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  */
hil_interrupt(int irq,void * handle,struct pt_regs * regs)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 
hil_do(unsigned char cmd,unsigned char * data,unsigned int len)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
hil_keyb_init(void)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
hil_init_chip(struct parisc_device * dev)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 
hil_init(void)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 
hil_exit(void)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 
390