Rev 671 | Rev 893 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 671 | Rev 878 | ||
---|---|---|---|
Line 45... | Line 45... | ||
45 | * It takes care of low-level keyboard functions. |
45 | * It takes care of low-level keyboard functions. |
46 | */ |
46 | */ |
47 | 47 | ||
48 | #define i8042_DATA 0x60 |
48 | #define i8042_DATA 0x60 |
49 | #define i8042_STATUS 0x64 |
49 | #define i8042_STATUS 0x64 |
- | 50 | #define i8042_BUFFER_FULL_MASK 0x01 |
|
50 | 51 | ||
51 | 52 | ||
52 | /** Keyboard commands. */ |
53 | /** Keyboard commands. */ |
53 | #define KBD_ENABLE 0xf4 |
54 | #define KBD_ENABLE 0xf4 |
54 | #define KBD_DISABLE 0xf5 |
55 | #define KBD_DISABLE 0xf5 |
Line 77... | Line 78... | ||
77 | #define SPECIAL '?' |
78 | #define SPECIAL '?' |
78 | #define KEY_RELEASE 0x80 |
79 | #define KEY_RELEASE 0x80 |
79 | 80 | ||
80 | static void key_released(__u8 sc); |
81 | static void key_released(__u8 sc); |
81 | static void key_pressed(__u8 sc); |
82 | static void key_pressed(__u8 sc); |
- | 83 | static char key_read(chardev_t *d); |
|
82 | 84 | ||
83 | #define PRESSED_SHIFT (1<<0) |
85 | #define PRESSED_SHIFT (1<<0) |
84 | #define PRESSED_CAPSLOCK (1<<1) |
86 | #define PRESSED_CAPSLOCK (1<<1) |
85 | #define LOCKED_CAPSLOCK (1<<0) |
87 | #define LOCKED_CAPSLOCK (1<<0) |
86 | 88 | ||
- | 89 | #define ACTIVE_READ_BUFF_SIZE 16 /*Must be power of 2*/ |
|
- | 90 | ||
- | 91 | ||
- | 92 | __u8 active_read_buff[ACTIVE_READ_BUFF_SIZE]={0}; |
|
- | 93 | ||
87 | SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
94 | SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
88 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
95 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
89 | static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
96 | static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
90 | 97 | ||
91 | static void i8042_suspend(chardev_t *); |
98 | static void i8042_suspend(chardev_t *); |
92 | static void i8042_resume(chardev_t *); |
99 | static void i8042_resume(chardev_t *); |
93 | 100 | ||
94 | static chardev_t kbrd; |
101 | static chardev_t kbrd; |
95 | static chardev_operations_t ops = { |
102 | static chardev_operations_t ops = { |
96 | .suspend = i8042_suspend, |
103 | .suspend = i8042_suspend, |
97 | .resume = i8042_resume |
104 | .resume = i8042_resume, |
- | 105 | .read = key_read |
|
98 | }; |
106 | }; |
99 | 107 | ||
100 | /** Primary meaning of scancodes. */ |
108 | /** Primary meaning of scancodes. */ |
101 | static char sc_primary_map[] = { |
109 | static char sc_primary_map[] = { |
102 | SPECIAL, /* 0x00 */ |
110 | SPECIAL, /* 0x00 */ |
Line 394... | Line 402... | ||
394 | 402 | ||
395 | /* Called from getc(). */ |
403 | /* Called from getc(). */ |
396 | void i8042_suspend(chardev_t *d) |
404 | void i8042_suspend(chardev_t *d) |
397 | { |
405 | { |
398 | } |
406 | } |
- | 407 | ||
- | 408 | ||
- | 409 | static __u8 active_read_buff_read(void) |
|
- | 410 | { |
|
- | 411 | static int i=0; |
|
- | 412 | i&=(ACTIVE_READ_BUFF_SIZE-1); |
|
- | 413 | if(!active_read_buff[i]) |
|
- | 414 | { |
|
- | 415 | return 0; |
|
- | 416 | } |
|
- | 417 | return active_read_buff[i++]; |
|
- | 418 | } |
|
- | 419 | ||
- | 420 | static void active_read_buff_write(__u8 ch) |
|
- | 421 | { |
|
- | 422 | static int i=0; |
|
- | 423 | active_read_buff[i]=ch; |
|
- | 424 | i++; |
|
- | 425 | i&=(ACTIVE_READ_BUFF_SIZE-1); |
|
- | 426 | active_read_buff[i]=0; |
|
- | 427 | } |
|
- | 428 | ||
- | 429 | ||
- | 430 | static void active_readed_key_pressed(__u8 sc) |
|
- | 431 | { |
|
- | 432 | char *map = sc_primary_map; |
|
- | 433 | char ascii = sc_primary_map[sc]; |
|
- | 434 | bool shift, capslock; |
|
- | 435 | bool letter = false; |
|
- | 436 | ||
- | 437 | /*spinlock_lock(&keylock);*/ |
|
- | 438 | switch (sc) { |
|
- | 439 | case SC_LSHIFT: |
|
- | 440 | case SC_RSHIFT: |
|
- | 441 | keyflags |= PRESSED_SHIFT; |
|
- | 442 | break; |
|
- | 443 | case SC_CAPSLOCK: |
|
- | 444 | keyflags |= PRESSED_CAPSLOCK; |
|
- | 445 | break; |
|
- | 446 | case SC_SPEC_ESCAPE: |
|
- | 447 | break; |
|
- | 448 | case SC_LEFTARR: |
|
- | 449 | active_read_buff_write(0x1b); |
|
- | 450 | active_read_buff_write(0x5b); |
|
- | 451 | active_read_buff_write(0x44); |
|
- | 452 | break; |
|
- | 453 | case SC_RIGHTARR: |
|
- | 454 | active_read_buff_write(0x1b); |
|
- | 455 | active_read_buff_write(0x5b); |
|
- | 456 | active_read_buff_write(0x43); |
|
- | 457 | break; |
|
- | 458 | case SC_UPARR: |
|
- | 459 | active_read_buff_write(0x1b); |
|
- | 460 | active_read_buff_write(0x5b); |
|
- | 461 | active_read_buff_write(0x41); |
|
- | 462 | break; |
|
- | 463 | case SC_DOWNARR: |
|
- | 464 | active_read_buff_write(0x1b); |
|
- | 465 | active_read_buff_write(0x5b); |
|
- | 466 | active_read_buff_write(0x42); |
|
- | 467 | break; |
|
- | 468 | case SC_HOME: |
|
- | 469 | active_read_buff_write(0x1b); |
|
- | 470 | active_read_buff_write(0x4f); |
|
- | 471 | active_read_buff_write(0x48); |
|
- | 472 | break; |
|
- | 473 | case SC_END: |
|
- | 474 | active_read_buff_write(0x1b); |
|
- | 475 | active_read_buff_write(0x4f); |
|
- | 476 | active_read_buff_write(0x46); |
|
- | 477 | break; |
|
- | 478 | case SC_DELETE: |
|
- | 479 | active_read_buff_write(0x1b); |
|
- | 480 | active_read_buff_write(0x5b); |
|
- | 481 | active_read_buff_write(0x33); |
|
- | 482 | active_read_buff_write(0x7e); |
|
- | 483 | break; |
|
- | 484 | default: |
|
- | 485 | letter = is_lower(ascii); |
|
- | 486 | capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
|
- | 487 | shift = keyflags & PRESSED_SHIFT; |
|
- | 488 | if (letter && capslock) |
|
- | 489 | shift = !shift; |
|
- | 490 | if (shift) |
|
- | 491 | map = sc_secondary_map; |
|
- | 492 | active_read_buff_write(map[sc]); |
|
- | 493 | break; |
|
- | 494 | } |
|
- | 495 | /*spinlock_unlock(&keylock);*/ |
|
- | 496 | ||
- | 497 | } |
|
- | 498 | ||
- | 499 | ||
- | 500 | static char key_read(chardev_t *d) |
|
- | 501 | { |
|
- | 502 | char ch; |
|
- | 503 | ||
- | 504 | ||
- | 505 | while(!(ch=active_read_buff_read())) |
|
- | 506 | { |
|
- | 507 | __u8 x; |
|
- | 508 | while (!((x=inb(i8042_STATUS))&i8042_BUFFER_FULL_MASK)); |
|
- | 509 | x = inb(i8042_DATA); |
|
- | 510 | if (x & KEY_RELEASE) |
|
- | 511 | key_released(x ^ KEY_RELEASE); |
|
- | 512 | else |
|
- | 513 | active_readed_key_pressed(x); |
|
- | 514 | } |
|
- | 515 | return ch; |
|
- | 516 | } |
|
- | 517 | ||
- | 518 |