ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / char / hp600_keyb.c
1 /*
2  *      $Id$ 
3  *      Copyright (C) 2000 YAEGASHI Takeshi
4  *      HP600 keyboard scan routine and translation table
5  *      Copyright (C) 2000 Niibe Yutaka
6  *      HP620 keyboard translation table
7  */
8
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/init.h>
12 #include <linux/module.h>
13
14 #include <asm/machvec.h>
15 #include <asm/delay.h>
16 #include <asm/io.h>
17 #include "scan_keyb.h"
18
19 #define PCDR 0xa4000124
20 #define PDDR 0xa4000126
21 #define PEDR 0xa4000128
22 #define PFDR 0xa400012a
23 #define PGDR 0xa400012c
24 #define PHDR 0xa400012e
25 #define PJDR 0xa4000130
26 #define PKDR 0xa4000132
27 #define PLDR 0xa4000134
28
29 static const unsigned char hp620_japanese_table[] = {
30         /* PTD1 */
31         0x0a, 0x0b, 0x0c, 0x00, 0x00, 0x0e, 0x00, 0x00,
32         0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
33         /* PTD5 */
34         0x18, 0x19, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
35         0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
36         /* PTD7 */
37         0x26, 0x1a, 0x2b, 0x00, 0x00, 0x00, 0x00, 0x00,
38         0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25,
39         /* PTE0 */
40         0x27, 0x1b, 0x29, 0x00, 0x00, 0x00, 0x00, 0x00,
41         0x2a, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
42         /* PTE1 */
43         0x35, 0x28, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00,
44         0x70, 0x3a, 0x00, 0x00, 0x2f, 0x00, 0x00, 0x34,
45         /* PTE3 */
46         0x48, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47         0x00, 0x2d, 0x2e, 0x7b, 0x30, 0x31, 0x32, 0x33,
48         /* PTE6 */
49         0x4b, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50         0x00, 0x2c, 0x38, 0x00, 0x39, 0x79, 0x7d, 0x73,
51         /* PTE7 */
52         0x41, 0x42, 0x00, 0x00, 0x1d, 0x00, 0x00, 0x00,
53         0x00, 0x00, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40,
54         /* **** */
55         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 };
58
59
60 static const unsigned char hp680_japanese_table[] = {
61         /* PTD1 */
62         0x3a, 0x70, 0x29, 0x00, 0x01, 0x00, 0x00, 0x00,
63         0x3b, 0x3c, 0x3d, 0x42, 0x41, 0x40, 0x3e, 0x3f,
64         /* PTD5 */
65         0x35, 0x28, 0x1c, 0x00, 0x2c, 0x00, 0x00, 0x00,
66         0x2d, 0x2e, 0x2f, 0x34, 0x33, 0x32, 0x30, 0x31,
67         /* PTD7 */
68         0x50, 0x4d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69         0x00, 0x00, 0x00, 0x4b, 0x00, 0x00, 0x38, 0x7b,
70         /* PTE0 */
71         0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x00, 0x00,
72         0x1d, 0x00, 0x39, 0x53, 0x73, 0xf9, 0x00, 0x00,
73         /* PTE1 */
74         0x27, 0x1b, 0x2b, 0x00, 0x1e, 0x00, 0x00, 0x00,
75         0x1f, 0x20, 0x21, 0x26, 0x25, 0x24, 0x22, 0x23,
76         /* PTE3 */
77         0x48, 0x7d, 0x36, 0x00, 0x0f, 0x00, 0x00, 0x00,
78         0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
79         /* PTE6 */
80         0x19, 0x1a, 0x0e, 0x00, 0x10, 0x00, 0x00, 0x00,
81         0x11, 0x12, 0x13, 0x18, 0x17, 0x16, 0x14, 0x15,
82         /* PTE7 */
83         0x0b, 0x0c, 0x0d, 0x00, 0x02, 0x00, 0x00, 0x00,
84         0x03, 0x04, 0x05, 0x0a, 0x09, 0x08, 0x06, 0x07,
85         /* **** */
86         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
88 };
89
90
91 static int hp620_japanese_scan_kbd(unsigned char *s)
92 {
93         int i;
94         unsigned char matrix_switch[] = {
95                 0xfd, 0xff,     /* PTD1 */
96                 0xdf, 0xff,     /* PTD5 */
97                 0x7f, 0xff,     /* PTD7 */
98                 0xff, 0xfe,     /* PTE0 */
99                 0xff, 0xfd,     /* PTE1 */
100                 0xff, 0xf7,     /* PTE3 */
101                 0xff, 0xbf,     /* PTE6 */
102                 0xff, 0x7f,     /* PTE7 */
103         }, *t=matrix_switch;
104
105         for(i=0; i<8; i++) {
106                 ctrl_outb(*t++, PDDR);
107                 ctrl_outb(*t++, PEDR);
108                 udelay(50);
109                 *s++=ctrl_inb(PCDR);
110                 *s++=ctrl_inb(PFDR);
111         }
112
113         ctrl_outb(0xff, PDDR);
114         ctrl_outb(0xff, PEDR);
115
116         *s++=ctrl_inb(PGDR);
117         *s++=ctrl_inb(PHDR);
118
119         return 0;
120 }
121
122
123 static int hp680_japanese_scan_kbd(unsigned char *s)
124 {
125         int i;
126         unsigned char matrix_switch[] = {
127                 0xfd, 0xff,     /* PTD1 */
128                 0xdf, 0xff,     /* PTD5 */
129                 0x7f, 0xff,     /* PTD7 */
130                 0xff, 0xfe,     /* PTE0 */
131                 0xff, 0xfd,     /* PTE1 */
132                 0xff, 0xf7,     /* PTE3 */
133                 0xff, 0xbf,     /* PTE6 */
134                 0xff, 0x7f,     /* PTE7 */
135         }, *t=matrix_switch;
136
137         for(i=0; i<8; i++) {
138                 ctrl_outb(*t++, PDDR);
139                 ctrl_outb(*t++, PEDR);
140                 *s++=ctrl_inb(PCDR);
141                 *s++=ctrl_inb(PFDR);
142         }
143
144         ctrl_outb(0xff, PDDR);
145         ctrl_outb(0xff, PEDR);
146
147         *s++=ctrl_inb(PGDR);
148         *s++=ctrl_inb(PHDR);
149
150         return 0;
151 }
152
153
154 void __init hp600_kbd_init_hw(void)
155 {
156         scan_kbd_init();
157
158         if (MACH_HP620)
159                 register_scan_keyboard(hp620_japanese_scan_kbd,
160                                        hp620_japanese_table, 18);
161         else if (MACH_HP680 || MACH_HP690) 
162                 register_scan_keyboard(hp680_japanese_scan_kbd,
163                                        hp680_japanese_table, 18);
164
165         printk(KERN_INFO "HP600 matrix scan keyboard registered\n");
166 }
167
168 /****************************************************************
169 HP Jornada 690(Japanese version) keyboard scan matrix
170
171         PTC7    PTC6    PTC5    PTC4    PTC3    PTC2    PTC1    PTC0    
172 PTD1    REC                     Escape  on/off  Han/Zen Hira    Eisu    
173 PTD5    REC                     Z       on/off  Enter   :       /       
174 PTD7    REC                                             Right   Down    
175 PTE0    REC                     Windows on/off                          
176 PTE1    REC                     A       on/off  ]       [       ;       
177 PTE3    REC                     Tab     on/off  ShirtR  \       Up      
178 PTE6    REC                     Q       on/off  BS      @       P       
179 PTE7    REC                     1       on/off  ^       -       0       
180
181         PTF7    PTF6    PTF5    PTF4    PTF3    PTF2    PTF1    PTF0
182 PTD1    F5      F4      F6      F7      F8      F3      F2      F1      
183 PTD5    N       B       M       ,       .       V       C       X       
184 PTD7    Muhen   Alt                     Left                            
185 PTE0                    Henkan  _       Del     Space           Ctrl    
186 PTE1    H       G       J       K       L       F       D       S       
187 PTE3                                                    ShiftL          
188 PTE6    Y       T       U       I       O       R       E       W       
189 PTE7    6       5       7       8       9       4       3       2       
190
191         PTG5    PTG4    PTG3    PTG0    PTH0
192 *       REC     REW     FWW     Cover   on/off
193
194
195                 7       6       5       4       3       2       1       0
196 C: 0xffff 0xdf  IP      IP      IP      IP      IP      IP      IP      IP
197 D: 0x6786 0x59  O       I       O       IP      I       F       O       I
198 E: 0x5045 0x00  O       O       F       F       O       F       O       O
199 F: 0xffff 0xff  IP      IP      IP      IP      IP      IP      IP      IP
200 G: 0xaffe 0xfd  I       I       IP      IP      IP      IP      IP      I
201 H: 0x70f2 0x49  O       IP      F       F       IP      IP      F       I
202 J: 0x0704 0x22  F       F       O       IP      F       F       O       F
203 K: 0x0100 0x10  F       F       F       O       F       F       F       F
204 L: 0x0c3c 0x26  F       F       IP      F       F       IP      IP      F
205
206 ****************************************************************/
207
208 /****************************************************************
209 HP Jornada 620(Japanese version) keyboard scan matrix
210
211         PTC7    PTC6    PTC5    PTC4    PTC3    PTC2    PTC1    PTC0
212 PTD1    EREC            BS      Ctrl    on/off  -       0       9
213 PTD5    EREC            BS      Ctrl    on/off  ^       P       O
214 PTD7    EREC            BS      Ctrl    on/off  ]       @       L
215 PTE0    EREC            BS      Ctrl    on/off  Han/Zen [       ;
216 PTE1    EREC            BS      Ctrl    on/off  Enter   :       /
217 PTE3    EREC            BS      Ctrl    on/off          Right   Up
218 PTE6    EREC            BS      Ctrl    on/off          Down    Left
219 PTE7    EREC            BS      Ctrl    on/off          F8      F7
220
221         PTF7    PTF6    PTF5    PTF4    PTF3    PTF2    PTF1    PTF0
222 PTD1    8       7       6       5       4       3       2       1
223 PTD5    I       U       Y       T       R       E       W       Q
224 PTD7    K       J       H       G       F       D       S       A
225 PTE0                                            ESC     Tab     Shift
226 PTE1    .                       V                       Caps    Hira
227 PTE3    ,       M       N       B       Muhen   C       X
228 PTE6    _       \       Henkan  Space           Alt     Z
229 PTE7    F6      F5      F4      F3      F2      F1              REC
230
231         PTH0
232 *       on/off
233
234                 7       6       5       4       3       2       1       0
235 C: 0xffff 0xff  IP      IP      IP      IP      IP      IP      IP      IP
236 D: 0x4404 0xaf  O       F       O       F       F       F       O       F
237 E: 0x5045 0xff  O       O       F       F       O       F       O       O
238 F: 0xffff 0xff  IP      IP      IP      IP      IP      IP      IP      IP
239 G: 0xd5ff 0x00  IP      O       O       O       IP      IP      IP      IP
240 H: 0x63ff 0xd1  O       I       F       IP      IP      IP      IP      IP
241 J: 0x0004 0x02  F       F       F       F       F       F       O       F
242 K: 0x0401 0xff  F       F       O       F       F       F       F       O
243 L: 0x0c00 0x20  F       F       IP      F       F       F       F       F
244
245 ADCSR: 0x08
246 ADCR: 0x3f
247
248  ****************************************************************/
249
250 /****************************************************************
251 Japanese 109 keyboard scan code layout
252
253                                               E02A-     E1- 
254 01    3B 3C 3D 3E  3F 40 41 42  43 44 57 58   E037  46  1045
255                                                                    
256 29 02 03 04 05 06 07 08 09 0A 0B 0C 0D 7D 0E  E052 E047 E049   45 E035 37  4A
257 0F  10 11 12 13 14 15 16 17 18 19 1A 1B   1C  E053 E04F E051   47  48  49  4E
258 3A   1E 1F 20 21 22 23 24 25 26 27 28 2B                       4B  4C  4D
259 2A    2C 2D 2E 2F 30 31 32 33 34 35 73    36       E048        4F  50  51  E0-
260 1D  DB  38  7B   39   79 70  E038 DC DD E01D  E04B E050 E04D     52    53  1C
261
262 ****************************************************************/
263
264 #if 0
265 int __init hp620_keyboard_test(void)
266 {
267         int i;
268         unsigned char s[18];
269         unsigned long a, b, c, d;
270
271         printk("PCCR: %04lx, PCDR: %02lx\n",
272                ctrl_inw(0xa4000104), ctrl_inb(0xa4000124));
273         printk("PDCR: %04lx, PDDR: %02lx\n",
274                ctrl_inw(0xa4000106), ctrl_inb(0xa4000126));
275         printk("PECR: %04lx, PEDR: %02lx\n",
276                ctrl_inw(0xa4000108), ctrl_inb(0xa4000128));
277         printk("PFCR: %04lx, PFDR: %02lx\n",
278                ctrl_inw(0xa400010a), ctrl_inb(0xa400012a));
279         printk("PGCR: %04lx, PGDR: %02lx\n",
280                ctrl_inw(0xa400010c), ctrl_inb(0xa400012c));
281         printk("PHCR: %04lx, PHDR: %02lx\n",
282                ctrl_inw(0xa400010e), ctrl_inb(0xa400012e));
283         printk("PJCR: %04lx, PJDR: %02lx\n",
284                ctrl_inw(0xa4000110), ctrl_inb(0xa4000130));
285         printk("PKCR: %04lx, PKDR: %02lx\n",
286                ctrl_inw(0xa4000112), ctrl_inb(0xa4000132));
287         printk("PLCR: %04lx, PLDR: %02lx\n",
288                ctrl_inw(0xa4000114), ctrl_inb(0xa4000134));
289
290         printk("ADCSR: %02lx, ADCR: %02lx\n",
291                ctrl_inb(0xa4000090), ctrl_inb(0xa4000092));
292
293         ctrl_inb(0xa4000004);
294         ctrl_inb(0xa4000006);
295         ctrl_inb(0xa4000008);
296         ctrl_outb(0, 0xa4000004);
297         ctrl_outb(0, 0xa4000006);
298         ctrl_outb(0, 0xa4000008);
299         ctrl_outb(0, 0xa4000090);
300         ctrl_outb(0x3b, 0xa4000090);
301
302         while(1) {
303                 hp620_japanese_scan_kbd(s);
304                 for(i=0; i<18; i+=2)
305                         printk("%02x%02x ", s[i], s[i+1]);
306
307 #if 0
308                 ctrl_outb(~2, PJDR);
309                 printk("%02lx%02lx ", ctrl_inb(PCDR), ctrl_inb(PFDR));
310                 ctrl_outb(0xff, PJDR);
311                 ctrl_outb(~1, PKDR);
312                 printk("%02lx%02lx ", ctrl_inb(PCDR), ctrl_inb(PFDR));
313                 ctrl_outb(~32, PKDR);
314                 printk("%02lx%02lx ", ctrl_inb(PCDR), ctrl_inb(PFDR));
315                 ctrl_outb(0xff, PKDR);
316 #endif
317
318                 printk("%02lx%02lx%02lx%02lx ", a, b, c, d);
319                 if(ctrl_inb(0xa4000090)&0x80) {
320                         a=ctrl_inb(0xa4000080);
321                         b=ctrl_inb(0xa4000084);
322                         c=ctrl_inb(0xa4000088);
323                         d=ctrl_inb(0xa400008c);
324                         ctrl_outb(0x3b, 0xa4000090);
325                 }
326                 printk("%02lx%02lx%02lx ",
327                        ctrl_inb(0xa4000004),
328                        ctrl_inb(0xa4000006),
329                        ctrl_inb(0xa4000008));
330
331                 printk("\n");
332         }
333
334         return 0;
335 }
336 module_init(keyboard_probe);
337 #endif
338
339
340 MODULE_LICENSE("GPL");