1 /*
2 * FILE NAME
3 * drivers/char/vr41xx_keyb.c
4 *
5 * BRIEF MODULE DESCRIPTION
6 * Keyboard driver for NEC VR4100 series Keyboard Interface Unit.
7 *
8 * Copyright (C) 1999 Bradley D. LaRonde
9 * Copyright (C) 1999 Hiroshi Kawashima <kawashima@iname.com>
10 * Copyright (C) 2000 Michael Klar <wyldfier@iname.com>
11 * Copyright (C) 2002,2003 Yoichi Yuasa <yuasa@hh.iij4u.or.jp>
12 *
13 * This file is subject to the terms and conditions of the GNU General Public
14 * License. See the file "COPYING" in the main directory of this archive
15 * for more details.
16 */
17 /*
18 * Changes:
19 * version 1.0
20 * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> Mon, 25 Mar 2002
21 * - Rewrote extensively because of 2.4.18.
22 *
23 * version 1.1
24 * Yoichi Yuasa <yuasa@hh.iij4u.or.jp> Wed, 9 Sep 200
25 * - Added NEC VRC4173 KIU support.
26 */
27 #include <linux/config.h>
28 #include <linux/init.h>
29 #include <linux/errno.h>
30 #include <linux/kbd_ll.h>
31 #ifdef CONFIG_PCI
32 #include <linux/pci.h>
33 #endif
34 #include <linux/pm.h>
35
36 #include <asm/addrspace.h>
37 #include <asm/cpu.h>
38 #include <asm/io.h>
39 #include <asm/param.h>
40 #include <asm/vr41xx/vr41xx.h>
41 #ifdef CONFIG_VRC4173
42 #include <asm/vr41xx/vrc4173.h>
43 #endif
44
45 #define KIU_BASE KSEG1ADDR(0x0b000180)
46 #define MKIUINTREG KSEG1ADDR(0x0b000092)
47
48 #define VRC4173_KIU_OFFSET 0x100
49 #define VRC4173_MKIUINTREG_OFFSET 0x072
50
51 #define KIUDAT0 0x00
52 #define KIUDAT1 0x02
53 #define KIUDAT2 0x04
54 #define KIUDAT3 0x06
55 #define KIUDAT4 0x08
56 #define KIUDAT5 0x0a
57 #define KIUDAT6 0x0c
58 #define KIUDAT7 0x0e
59 #define KIUSCANREP 0x10
60 #define KIUSCANREP_KEYEN 0x8000
61 #define KIUSCANREP_STPREP(x) ((x) << 4)
62 #define KIUSCANREP_SCANSTP 0x0008
63 #define KIUSCANREP_SCANSTART 0x0004
64 #define KIUSCANREP_ATSTP 0x0002
65 #define KIUSCANREP_ATSCAN 0x0001
66 #define KIUSCANS 0x12
67 #define KIUSCANS_SCANNING 0x0003
68 #define KIUSCANS_INTERVAL 0x0002
69 #define KIUSCANS_WAITKEYIN 0x0001
70 #define KIUSCANS_STOPPED 0x0000
71 #define KIUWKS 0x14
72 #define KIUWKS_T3CNT 0x7c00
73 #define KIUWKS_T3CNT_SHIFT 10
74 #define KIUWKS_T2CNT 0x03e0
75 #define KIUWKS_T2CNT_SHIFT 5
76 #define KIUWKS_T1CNT 0x001f
77 #define KIUWKS_T1CNT_SHIFT 0
78 #define KIUWKS_CNT_USEC(x) (((x) / 30) - 1)
79 #define KIUWKI 0x16
80 #define KIUWKI_INTERVAL_USEC(x) ((x) / 30)
81 #define KIUINT 0x18
82 #define KIUINT_KDATLOST 0x0004
83 #define KIUINT_KDATRDY 0x0002
84 #define KIUINT_SCANINT 0x0001
85 #define KIURST 0x1a
86 #define KIURST_KIURST 0x0001
87 #define KIUGPEN 0x1c
88 #define KIUGPEN_KGPEN(x) ((uint16_t)1 << (x))
89 #define SCANLINE 0x1e
90 #define SCANLINE_DONTUSE 0x0003
91 #define SCANLINE_8LINES 0x0002
92 #define SCANLINE_10LINES 0x0001
93 #define SCANLINE_12LINES 0x0000
94
95 static unsigned long kiu_base;
96 static unsigned long mkiuintreg;
97
98 #ifdef CONFIG_VRC4173
99 #define kiu_readw(offset) vrc4173_inw(kiu_base + (offset))
100 #define kiu_writew(val, offset) vrc4173_outw(val, kiu_base + (offset))
101 #define mkiuintreg_writew(val) vrc4173_outw((val), mkiuintreg)
102 #else
103 #define kiu_readw(offset) readw(kiu_base + (offset))
104 #define kiu_writew(val, offset) writew(val, kiu_base + (offset))
105 #define mkiuintreg_writew(val) writew((val), mkiuintreg)
106 #endif
107
108 #define KIU_CLOCK 0x0008
109
110 #ifdef CONFIG_VRC4173
111 #define KIU_IRQ VRC4173_KIU_IRQ
112 #else
113 #define KIU_IRQ SYSINT1_IRQ(7)
114 #endif
115
116 #define KEY_UP 0
117 #define KEY_DOWN 1
118
119 #define DEFAULT_KIUDAT_REGS 6
120 #define DEFAULT_DATA_NOT_REVERSED 0
121 #define DEFAULT_T3CNT KIUWKS_CNT_USEC(200)
122 #define DEFAULT_T2CNT KIUWKS_CNT_USEC(200)
123 #define DEFAULT_T1CNT KIUWKS_CNT_USEC(200)
124 #define DEFAULT_SCAN_INTERVAL KIUWKI_INTERVAL_USEC(30000)
125 #define DEFAULT_REPEAT_DELAY HZ/4
126 #define DEFAULT_REPEAT_RATE HZ/25
127
128 static char *kiu_driver_name = "Keyboard driver";
129 static char *kiu_driver_version = "1.1";
130 static char *kiu_driver_revdate = "2003-09-09";
131 static char *kiu_driver_device_name = "NEC VR4100 series KIU";
132
133 static unsigned char kiudat_regs = DEFAULT_KIUDAT_REGS;
134 static unsigned char data_reverse = DEFAULT_DATA_NOT_REVERSED;
135 static uint16_t scanlines = SCANLINE_12LINES;
136 static uint16_t t3cnt = DEFAULT_T3CNT;
137 static uint16_t t2cnt = DEFAULT_T2CNT;
138 static uint16_t t1cnt = DEFAULT_T1CNT;
139 static uint16_t scan_interval = DEFAULT_SCAN_INTERVAL;
140
141 static unsigned long repeat_delay = DEFAULT_REPEAT_DELAY;
142 static unsigned long repeat_rate = DEFAULT_REPEAT_RATE;
143
144 static int repeat_scancode = -1;
145 static unsigned long next_handle_time;
146
147 struct kiudat_t {
148 uint32_t reg;
149 uint16_t data;
150 };
151
152 static struct kiudat_t kiudat [8] = {
153 {KIUDAT0, 0}, {KIUDAT1, 0},
154 {KIUDAT2, 0}, {KIUDAT3, 0},
155 {KIUDAT4, 0}, {KIUDAT5, 0},
156 {KIUDAT6, 0}, {KIUDAT7, 0},
157 };
158
kbd_setkeycode(unsigned int scancode,unsigned int keycode)159 int kbd_setkeycode(unsigned int scancode, unsigned int keycode)
160 {
161 return (scancode == keycode) ? 0 : -EINVAL;
162 }
163
kbd_getkeycode(unsigned int scancode)164 int kbd_getkeycode(unsigned int scancode)
165 {
166 return scancode;
167 }
168
kbd_translate(unsigned char scancode,unsigned char * keycode,char raw_mode)169 int kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode)
170 {
171 *keycode = scancode;
172 return 1;
173 }
174
kbd_unexpected_up(unsigned char keycode)175 char kbd_unexpected_up(unsigned char keycode)
176 {
177 printk(KERN_WARNING "vr41xx_keyb: unexpected up, keycode 0x%02x\n", keycode);
178 return 0x80;
179 }
180
kbd_leds(unsigned char leds)181 void kbd_leds(unsigned char leds)
182 {
183 return;
184 }
185
handle_kiudat(uint16_t data,uint16_t cmp_data,int scancode)186 static inline void handle_kiudat(uint16_t data, uint16_t cmp_data, int scancode)
187 {
188 uint16_t mask;
189 int down, candidate_scancode = 0;
190
191 for (mask = 0x0001; mask ; mask <<= 1) {
192 if (cmp_data & mask) {
193 down = data & mask ? KEY_DOWN : KEY_UP;
194 if (down == KEY_DOWN) {
195 repeat_scancode = scancode;
196 next_handle_time = jiffies + repeat_delay;
197 }
198 else {
199 if (repeat_scancode == scancode)
200 repeat_scancode = -1;
201 }
202 handle_scancode(scancode, down);
203 }
204 if (data & mask) {
205 candidate_scancode = scancode;
206 }
207 scancode++;
208 }
209
210 if ((repeat_scancode < 0) && (candidate_scancode > 0)) {
211 repeat_scancode = candidate_scancode;
212 next_handle_time = jiffies + repeat_delay;
213 }
214 }
215
handle_kiu_event(void)216 static inline void handle_kiu_event(void)
217 {
218 struct kiudat_t *kiu = kiudat;
219 uint16_t data, last_data, cmp_data;
220 int i;
221
222 for (i = 0; i < kiudat_regs; i++) {
223 last_data = kiu->data;
224 data = kiu_readw(kiu->reg);
225 if (data_reverse)
226 data = ~data;
227 kiu->data = data;
228 cmp_data = data ^ last_data;
229 handle_kiudat(data, cmp_data, i * 16);
230 kiu++;
231 }
232
233 if ((repeat_scancode >= 0) &&
234 (time_after_eq(jiffies, next_handle_time))) {
235 handle_scancode(repeat_scancode, KEY_DOWN);
236 next_handle_time = jiffies + repeat_rate;
237 }
238 }
239
kiu_interrupt(int irq,void * dev_id,struct pt_regs * regs)240 static void kiu_interrupt(int irq, void *dev_id, struct pt_regs *regs)
241 {
242 uint16_t status;
243
244 mkiuintreg_writew(0);
245
246 status = kiu_readw(KIUINT);
247 kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT);
248
249 if (status & KIUINT_KDATRDY)
250 handle_kiu_event();
251
252 mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY);
253 }
254
255 #ifdef CONFIG_PM
256
pm_kiu_request(struct pm_dev * dev,pm_request_t rqst,void * data)257 static int pm_kiu_request(struct pm_dev *dev, pm_request_t rqst, void *data)
258 {
259 switch (rqst) {
260 case PM_SUSPEND:
261 mkiuintreg_writew(KIUINT_SCANINT);
262 break;
263 case PM_RESUME:
264 kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT);
265 mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY, MKIUINTREG);
266 break;
267 }
268
269 return 0;
270 }
271
272 #endif
273
kbd_init_hw(void)274 void __devinit kbd_init_hw(void)
275 {
276 uint16_t kiugpen = 0;
277 int i;
278
279 if (current_cpu_data.cputype == CPU_VR4111 ||
280 current_cpu_data.cputype == CPU_VR4121) {
281 kiu_base = KIU_BASE;
282 mkiuintreg = MKIUINTREG;
283 #if defined(CONFIG_PCI) && defined(CONFIG_VRC4173)
284 } else if (current_cpu_data.cputype == CPU_VR4122 ||
285 current_cpu_data.cputype == CPU_VR4131) {
286 struct pci_dev *dev;
287 int found = 0;
288 dev = pci_find_device(PCI_VENDOR_ID_NEC,
289 PCI_DEVICE_ID_NEC_VRC4173, NULL);
290 if (dev != NULL) {
291 switch (scanlines) {
292 case SCANLINE_8LINES:
293 vrc4173_select_function(KIU8_SELECT);
294 found = 1;
295 break;
296 case SCANLINE_10LINES:
297 vrc4173_select_function(KIU10_SELECT);
298 found = 1;
299 break;
300 case SCANLINE_12LINES:
301 vrc4173_select_function(KIU12_SELECT);
302 found = 1;
303 break;
304 default:
305 break;
306 }
307
308 if (found != 0) {
309 kiu_base = VRC4173_KIU_OFFSET;
310 mkiuintreg = VRC4173_MKIUINTREG_OFFSET;
311 vrc4173_clock_supply(VRC4173_KIU_CLOCK);
312 }
313 }
314 #endif
315 }
316
317 if (kiu_base == 0 || mkiuintreg == 0)
318 return;
319
320 printk(KERN_INFO "%s version %s (%s) for %s\n",
321 kiu_driver_name, kiu_driver_version,
322 kiu_driver_revdate, kiu_driver_device_name);
323
324 mkiuintreg_writew(0);
325
326 if (current_cpu_data.cputype == CPU_VR4111 ||
327 current_cpu_data.cputype == CPU_VR4121)
328 vr41xx_clock_supply(KIU_CLOCK);
329
330 kiu_writew(KIURST_KIURST, KIURST);
331
332 for (i = 0; i < scanlines; i++)
333 kiugpen &= ~(0x0001 << i);
334
335 kiu_writew(kiugpen, KIUGPEN);
336 kiu_writew(scanlines, SCANLINE);
337 kiu_writew((t3cnt << KIUWKS_T3CNT_SHIFT) |
338 (t2cnt << KIUWKS_T2CNT_SHIFT) |
339 (t1cnt << KIUWKS_T1CNT_SHIFT), KIUWKS);
340 kiu_writew(scan_interval, KIUWKI);
341 kiu_writew(KIUINT_KDATLOST | KIUINT_KDATRDY | KIUINT_SCANINT, KIUINT);
342
343
344 request_irq(KIU_IRQ, kiu_interrupt, 0, "keyboard", NULL);
345
346 mkiuintreg_writew(KIUINT_KDATLOST | KIUINT_KDATRDY);
347 kiu_writew(KIUSCANREP_KEYEN | KIUSCANREP_STPREP(1) |
348 KIUSCANREP_ATSTP | KIUSCANREP_ATSCAN, KIUSCANREP);
349
350 #ifdef CONFIG_PM
351 pm_register(PM_SYS_DEV, PM_SYS_KBC, pm_kiu_request);
352 #endif
353 }
354
vr41xx_kbd_setup(char * options)355 static int __devinit vr41xx_kbd_setup(char *options)
356 {
357 char *this_opt;
358 int num;
359
360 if (!options || !*options)
361 return 1;
362
363 for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) {
364 if (!strncmp(this_opt, "regs:", 5)) {
365 num = simple_strtoul(this_opt+5, NULL, 0);
366 if (num == 6 || num == 8)
367 kiudat_regs = num;
368 } else if (!strncmp(this_opt, "lines:", 6)) {
369 num = simple_strtoul(this_opt+6, NULL, 0);
370 if (num == 8)
371 scanlines = SCANLINE_8LINES;
372 else if (num == 10)
373 scanlines = SCANLINE_10LINES;
374 else if (num == 12)
375 scanlines = SCANLINE_12LINES;
376 } else if (!strncmp(this_opt, "reverse:", 8)) {
377 num = simple_strtoul(this_opt+8, NULL, 0);
378 if (num == 0 || num == 1)
379 data_reverse = num;
380 } else if (!strncmp(this_opt, "t3cnt:", 6)) {
381 num = simple_strtoul(this_opt+6, NULL, 0);
382 if (num >= 60 && num <= 960)
383 t3cnt = KIUWKS_CNT_USEC(num);
384 } else if (!strncmp(this_opt, "t2cnt:", 6)) {
385 num = simple_strtoul(this_opt+6, NULL, 0);
386 if (num >= 60 && num <= 960)
387 t2cnt = KIUWKS_CNT_USEC(num);
388 } else if (!strncmp(this_opt, "t1cnt:", 6)) {
389 num = simple_strtoul(this_opt+6, NULL, 0);
390 if (num >= 60 && num <= 960)
391 t1cnt = KIUWKS_CNT_USEC(num);
392 } else if (!strncmp(this_opt, "interval:", 9)) {
393 num = simple_strtoul(this_opt+9, NULL, 0);
394 if (num >= 30 && num <= 30690)
395 scan_interval = KIUWKI_INTERVAL_USEC(num);
396 } else if (!strncmp(this_opt, "delay:", 6)) {
397 num = simple_strtoul(this_opt+6, NULL, 0);
398 if (num > 0 && num <= HZ)
399 repeat_delay = num;
400 } else if (!strncmp(this_opt, "rate:", 5)) {
401 num = simple_strtoul(this_opt+5, NULL, 0);
402 if (num > 0 && num <= HZ)
403 repeat_rate = num;
404 }
405 }
406
407 return 1;
408 }
409
410 __setup("vr41xx_kbd=", vr41xx_kbd_setup);
411