int kpad_scan_line( SCANINFO *sinfo, unsigned int i) { __u8 col, downkey, upkey; static __u8 row; unsigned int j; if (i == 0) row = 0x01; out_raw(~row); udelay(ROW_DELAY); in_col(&col); sinfo->key[i] = col; if (~(sinfo->key[i])) sinfo->push_flg = 1; sinfo->diffkey[i] = sinfo->key[i] ^ sinfo->lastkey[i]; if (sinfo->diffkey[i]) { downkey = ~sinfo->key[i] & sinfo->diffkey[i]; /* key went down */ upkey = sinfo->key[i] & sinfo->diffkey[i]; /* key went up */ for (j = 0, col=0x80; j < 8; j++, col >>= 1) { if (downkey & col) handle_scancode( KEYCODE(i, j), 1 ); else if ( upkey & col ) handle_scancode( KEYCODE(i, j) | KBUP, 0 ); } }
static int emulate_raw(unsigned int keycode, int down) { #ifdef CONFIG_MAC_EMUMOUSEBTN if (mac_hid_mouse_emulate_buttons(1, keycode, down)) return 0; #endif /* CONFIG_MAC_EMUMOUSEBTN */ #if defined(CONFIG_MAC_ADBKEYCODES) || defined(CONFIG_ADB_KEYBOARD) if (!mac_hid_keyboard_sends_linux_keycodes()) { if (keycode > 255 || !mac_keycodes[keycode]) return -1; handle_scancode((mac_keycodes[keycode] & 0x7f), down); return 0; } #endif /* CONFIG_MAC_ADBKEYCODES || CONFIG_ADB_KEYBOARD */ if (keycode > 255 || !x86_keycodes[keycode]) return -1; if (keycode == KEY_PAUSE) { handle_scancode(0xe1, 1); handle_scancode(0x1d, down); handle_scancode(0x45, down); return 0; } if (keycode == KEY_SYSRQ && x86_sysrq_alt) { handle_scancode(0x54, down); return 0; } #ifdef CONFIG_SPARC64 if (keycode == KEY_A && sparc_l1_a_state) { sparc_l1_a_state = 0; batten_down_hatches(); } #endif if (x86_keycodes[keycode] & 0x100) handle_scancode(0xe0, 1); handle_scancode(x86_keycodes[keycode] & 0x7f, down); if (keycode == KEY_SYSRQ) { handle_scancode(0xe0, 1); handle_scancode(0x37, down); } if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) x86_sysrq_alt = down; #ifdef CONFIG_SPARC64 if (keycode == KEY_STOP) sparc_l1_a_state = down; #endif return 0; }
static int emulate_raw(unsigned int keycode, int down) { if (keycode > 255 || !x86_keycodes[keycode]) return -1; if (keycode == KEY_PAUSE) { handle_scancode(0xe1, 1); handle_scancode(0x1d, down); handle_scancode(0x45, down); return 0; } if (keycode == KEY_SYSRQ && x86_sysrq_alt) { handle_scancode(0x54, down); return 0; } if (x86_keycodes[keycode] & 0x100) handle_scancode(0xe0, 1); handle_scancode(x86_keycodes[keycode] & 0x7f, down); if (keycode == KEY_SYSRQ) { handle_scancode(0xe0, 1); handle_scancode(0x37, down); } if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT) x86_sysrq_alt = down; return 0; }
static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned char status; spin_lock(&kbd_controller_lock); kbd_pt_regs = regs; status = IRQ_KEYB_MASK & master_inb(INTERRUPT_REG); if (status ) { unsigned char scancode,qcode; qcode = master_inb(KEYCODE_REG); if (qcode != 0xf0) { if (qcode == 0xe0) { qprev=0xe0; handle_scancode(qprev , 1); goto exit; } scancode=qprev ? q40ecl[qcode] : q40cl[qcode]; #if 0 /* next line is last resort to hanlde some oddities */ if (qprev && !scancode) scancode=q40cl[qcode]; #endif qprev=0; if (!scancode) { printk("unknown scancode %x\n",qcode); goto exit; } if (scancode==0xff) /* SySrq */ scancode=SYSRQ_KEY; handle_scancode(scancode, ! keyup ); keyup=0; tasklet_schedule(&keyboard_tasklet); } else keyup=1; } exit: spin_unlock(&kbd_controller_lock); master_outb(-1,KEYBOARD_UNLOCK_REG); /* keyb ints reenabled herewith */ }
static inline void handle_keyboard_event(unsigned char scancode) { #ifdef CONFIG_VT handle_scancode(scancode, !(scancode & 0x80)); #endif tasklet_schedule(&keyboard_tasklet); }
/* * This reads the keyboard status port, and does the * appropriate action. * */ static unsigned char handle_kbd_event(void) { unsigned char status = kbd_read_status(); unsigned int work = 10000; while ((--work > 0) && (status & KBD_STAT_OBF)) { unsigned char scancode; scancode = kbd_read_input(); /* Error bytes must be ignored to make the Synaptics touchpads compaq use work */ /* Ignore error bytes */ if (!(status & (KBD_STAT_GTO | KBD_STAT_PERR))) { if (status & KBD_STAT_MOUSE_OBF) ; /* not supported: handle_mouse_event(scancode); */ else handle_scancode(scancode); } status = kbd_read_status(); } if (!work) PRINTF("pc_keyb: controller jammed (0x%02X).\n", status); return status; }
/* Reads in data from the Keyboard and handles it accordingly. */ void do_kybd_isr( ) { SCANCODE bInput; /* Handle Key Board ISR Stuff */ if( *IKBD_STATUS & DATA_READY_MASK ) { bInput = *IKBD_DATA; switch( bKYBD_STATE ) { case KYBD_OPEN_STATE: if( MOUSE_HEADER == (bInput & ~(LEFT_MOUSE_BTN_MASK + RIGHT_MOUSE_BTN_MASK)) ) bKYBD_STATE = KYBD_X_POS_STATE; else handle_scancode( bInput ); break; case KYBD_X_POS_STATE: /* Not Implemented Yet */ bKYBD_STATE = KYBD_Y_POS_STATE; break; case KYBD_Y_POS_STATE: /* Not Implemented Yet */ bKYBD_STATE = KYBD_OPEN_STATE; break; }; } /* Clear bit #6 on the MFP68901 Interrupt In-Service B register */ *MFP_IN_SERVICE_B &= MFP_IN_SERVICE_B_FLAG; }
static int emulate_raw(unsigned int keycode, int down) { if (keycode > 127 || !mac_keycodes[keycode]) return -1; handle_scancode(mac_keycodes[keycode] & 0x7f, down); return 0; }
static inline void handle_keyboard_event(unsigned char scancode) { #ifdef CONFIG_VT kbd_exists = 1; if (do_acknowledge(scancode)) handle_scancode(scancode, !(scancode & 0x80)); #endif tasklet_schedule(&keyboard_tasklet); }
static inline void handle_keyboard_event(unsigned char scancode) { if(scancode != (unsigned char)(KBD_NO_DATA)) { #ifdef CONFIG_VT handle_scancode(scancode, !(scancode & KBD_KEYUP)); #endif tasklet_schedule(&keyboard_tasklet); } }
static void bottom_half(unsigned long data) { #ifdef DEBUG to_tty_string("[simple_keyboard.c] Entring bottom_half.\n\r"); #endif struct tasklet_data_t *keyboard_data = (struct tasklet_data_t *)data; //printk(KERN_INFO "Got scancode %02x in bottom_half.\n", keyboard_data->scancode); handle_scancode(keyboard_data->scancode); }
static void kbd_drv_rx(int irq, void *dev_id, struct pt_regs *regs) { int i; kbd_setregs(regs); #ifndef CONFIG_SA1100_ITSY while (!ignore_kbd_irq && (i=getcFromKBCTL()) != KBCTL_NODATA) { if (i != KBCTL_AGAIN && i != KK_NONE) handle_scancode((unsigned char) i, ((unsigned char)i & 0x80) ? 0 : 1); } #endif // vsync_irq(); reset_timer1( (TIMER1_RATE+30)/60 ); mark_bh(KEYBOARD_BH); }
static void h3600_stowaway_release_all_keys(struct skbd_state *skbd) { int i,j; unsigned long *b = skbd->key_down; SFDEBUG(1,"releasing all keys.\n"); for ( i = 0 ; i < SKBD_MAX_KEYCODES ; i+=BITS_PER_LONG, b++ ) { if ( *b ) { /* Should fix this to use the ffs() function */ for (j=0 ; j<BITS_PER_LONG; j++) if (test_and_clear_bit(j,b)) handle_scancode(i+j, 0); } } }
static void h3600_stowaway_process_char(struct skbd_state *skbd, unsigned char data ) { unsigned char cooked; unsigned char *index; unsigned char key = data & 0x7f; unsigned int down = !(data & 0x80); SFDEBUG(1,"%#02x [%s]", key, (down?"down":" up ")); if (key >= SKBD_KEYMAP_SIZE) { SDEBUG(1," --> discarding\n"); return; } index = skbd->keycode + key * SKBD_MODIFIER_STATES; if ( *index == SKEY_FUNCTION ) { skbd->function = down; SDEBUG(1," --> function\n"); return; } cooked = *index; if (skbd_numlock && index[SKBD_NUMLOCK_OFFSET]) cooked = index[SKBD_NUMLOCK_OFFSET]; if (skbd->function && index[SKBD_FUNCTION_OFFSET]) cooked = index[SKBD_FUNCTION_OFFSET]; if ( !cooked ) { SDEBUG(1," --> invalid keystroke\n"); return; } if ( (test_bit(cooked,skbd->key_down) && down) || (!test_bit(cooked,skbd->key_down) && !down)) { SDEBUG(1," --> already set\n"); return; } if ( down ) set_bit(cooked,skbd->key_down); else clear_bit(cooked,skbd->key_down); SDEBUG(1," --> sending %d (%d)\n", cooked, down); handle_scancode(cooked, down); }
static void atakeyb_rep( unsigned long ignore ) { kbd_pt_regs = NULL; /* Disable keyboard for the time we call handle_scancode(), else a race * in the keyboard tty queue may happen */ atari_disable_irq( IRQ_MFP_ACIA ); del_timer( &atakeyb_rep_timer ); /* A keyboard int may have come in before we disabled the irq, so * double-check whether rep_scancode is still != 0 */ if (rep_scancode) { atakeyb_rep_timer.expires = jiffies + key_repeat_rate; atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL; add_timer( &atakeyb_rep_timer ); handle_scancode(rep_scancode); } atari_enable_irq( IRQ_MFP_ACIA ); }
static void pcikbd_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long flags; unsigned char status; spin_lock_irqsave(&pcikbd_lock, flags); kbd_pt_regs = regs; status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG); do { unsigned char scancode; if(status & pckbd_read_mask & KBD_STAT_MOUSE_OBF) break; scancode = pcikbd_inb(pcikbd_iobase + KBD_DATA_REG); if((status & KBD_STAT_OBF) && do_acknowledge(scancode)) handle_scancode(scancode, !(scancode & 0x80)); status = pcikbd_inb(pcikbd_iobase + KBD_STATUS_REG); } while(status & KBD_STAT_OBF); tasklet_schedule(&keyboard_tasklet); spin_unlock_irqrestore(&pcikbd_lock, flags); }
void handle_at_scancode(int keyval) { static int brk; static int esc0; static int esc1; int scancode = 0; switch (keyval) { case KBD_BREAK : /* sets the "release_key" bit when a key is released. HP keyboard send f0 followed by the keycode while AT keyboard send the keycode with this bit set. */ brk = 0x80; return; case KBD_ESCAPEE0 : /* 2chars sequence, commonly used to differenciate the two ALT keys and the two ENTER keys and so on... */ esc0 = 2; /* e0-xx are 2 chars */ scancode = keyval; break; case KBD_ESCAPEE1 : /* 3chars sequence, only used by the Pause key. */ esc1 = 3; /* e1-xx-xx are 3 chars */ scancode = keyval; break; #if 0 case KBD_RESEND : /* dunno what to do when it happens. RFC */ printk(KERN_INFO "keyboard: KBD_RESEND received.\n"); return; #endif case 0x14 : /* translate e1-14-77-e1-f0-14-f0-77 to e1-1d-45-e1-9d-c5 (the Pause key) */ if (esc1==2) scancode = brk | 0x1d; break; case 0x77 : if (esc1==1) scancode = brk | 0x45; break; case 0x12 : /* an extended key is e0-12-e0-xx e0-f0-xx-e0-f0-12 on HP, while it is e0-2a-e0-xx e0-(xx|80)-f0-aa on AT. */ if (esc0==1) scancode = brk | 0x2a; break; } /* translates HP scancodes to AT scancodes */ if (!scancode) scancode = brk | keycode_translate[keyval]; if (!scancode) printk(KERN_INFO "keyboard: unexpected key code %02x\n",keyval); /* now behave like an AT keyboard */ handle_scancode(scancode,!(scancode&0x80)); if (esc0) esc0--; if (esc1) esc1--; /* release key bit must be unset for the next key */ brk = 0; }
static void lk201_rx_char(unsigned char ch, unsigned char fl) { static unsigned char id[6]; static int id_i; static int shift_state = 0; static int prev_scancode; unsigned char c = scancodeRemap[ch]; if (fl != TTY_NORMAL && fl != TTY_OVERRUN) { printk(KERN_ERR "lk201: keyboard receive error: 0x%02x\n", fl); return; } /* Assume this is a power-up ID. */ if (ch == LK_STAT_PWRUP_ID && !id_i) { id[id_i++] = ch; return; } /* Handle the power-up sequence. */ if (id_i) { id[id_i++] = ch; if (id_i == 4) { /* OK, the power-up concluded. */ lk201_report(id); if (id[2] == LK_STAT_PWRUP_OK) lk201_get_id(); else { id_i = 0; printk(KERN_ERR "lk201: keyboard power-up " "error, skipping initialization\n"); } } else if (id_i == 6) { /* We got the ID; report it and start operation. */ id_i = 0; lk201_id(id); lk201_reset(); } return; } /* Everything else is a scancode/status response. */ id_i = 0; switch (ch) { case LK_STAT_RESUME_ERR: case LK_STAT_ERROR: case LK_STAT_INHIBIT_ACK: case LK_STAT_TEST_ACK: case LK_STAT_MODE_KEYDOWN: case LK_STAT_MODE_ACK: break; case LK_KEY_LOCK: shift_state ^= LK_LOCK; handle_scancode(c, (shift_state & LK_LOCK) ? 1 : 0); break; case LK_KEY_SHIFT: shift_state ^= LK_SHIFT; handle_scancode(c, (shift_state & LK_SHIFT) ? 1 : 0); break; case LK_KEY_CTRL: shift_state ^= LK_CTRL; handle_scancode(c, (shift_state & LK_CTRL) ? 1 : 0); break; case LK_KEY_COMP: shift_state ^= LK_COMP; handle_scancode(c, (shift_state & LK_COMP) ? 1 : 0); break; case LK_KEY_RELEASE: if (shift_state & LK_SHIFT) handle_scancode(scancodeRemap[LK_KEY_SHIFT], 0); if (shift_state & LK_CTRL) handle_scancode(scancodeRemap[LK_KEY_CTRL], 0); if (shift_state & LK_COMP) handle_scancode(scancodeRemap[LK_KEY_COMP], 0); if (shift_state & LK_LOCK) handle_scancode(scancodeRemap[LK_KEY_LOCK], 0); shift_state = 0; break; case LK_KEY_REPEAT: handle_scancode(prev_scancode, 1); break; default: prev_scancode = c; handle_scancode(c, 1); break; } tasklet_schedule(&keyboard_tasklet); }
static inline void handle_keyboard_event(unsigned char scancode) { if (do_acknowledge(scancode)) handle_scancode(scancode, !(scancode & 0x80)); }
void keybdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int down) { if (type != EV_KEY || code > 255) return; //#ifdef __i386__ if (code >= 189) { printk(KERN_WARNING "keybdev.c: can't emulate keycode %d\n", code); return; } else if (code >= 162) { handle_scancode(0x2e0); handle_scancode((code - 161) | (down ? 0:0200)); } else if (code > 125) { handle_scancode(0x2e0); handle_scancode((code - 34) | (down ? 0:0200)); } else if (code == 125 || code == 123 || code == 121) { handle_scancode(code | (down ? 0:0200)); } else if (code == 119) { handle_scancode(0x2e1); handle_scancode(0x1d | (down ? 0:0200)); handle_scancode(0x45 | (down ? 0:0200)); } else if (code == 115 || code == 112) { handle_scancode(code | (down ? 0:0200)); } else if (code >= 96) { handle_scancode(0x2e0); handle_scancode(keybdev_x86_e0s[code - 96] | (down ? 0:0200)); if (code == 99) { handle_scancode(0x2e0); handle_scancode(0x37 | (down ? 0:0200)); } } else handle_scancode(code | (down ? 0:0200)); #ifdef NONE if (code >= 189) { printk(KERN_WARNING "keybdev.c: can't emulate keycode %d\n", code); return; } else if (code >= 162) { handle_scancode(0xe0, 1); handle_scancode(code - 161, down); } else if (code >= 125) { handle_scancode(0xe0, 1); handle_scancode(code - 34, down); } else if (code == 119) { handle_scancode(0xe1, 1); handle_scancode(0x1d, down); handle_scancode(0x45, down); } else if (code >= 96) { handle_scancode(0xe0, 1); handle_scancode(keybdev_x86_e0s[code - 96], down); if (code == 99) { handle_scancode(0xe0, 1); handle_scancode(0x37, down); } } else handle_scancode(code, down); #endif //#elif CONFIG_MAC_KEYBOARD // // if (code < 128 && keybdev_mac_codes[code]) // handle_scancode(keybdev_mac_codes[code] & 0x7f, down); // else // printk(KERN_WARNING "keybdev.c: can't emulate keycode %d\n", code); // //#else //#error "Cannot generate rawmode keyboard for your architecture yet." //#endif mark_bh(KEYBOARD_BH); }
static void keyboard_interrupt(int irq, void *dummy, struct pt_regs *fp) { u_char acia_stat; int scancode; int break_flag; /* save frame for register dump */ kbd_pt_regs = fp; repeat: if (acia.mid_ctrl & ACIA_IRQ) if (atari_MIDI_interrupt_hook) atari_MIDI_interrupt_hook(); acia_stat = acia.key_ctrl; /* check out if the interrupt came from this ACIA */ if (!((acia_stat | acia.mid_ctrl) & ACIA_IRQ)) return; if (acia_stat & ACIA_OVRN) { /* a very fast typist or a slow system, give a warning */ /* ...happens often if interrupts were disabled for too long */ printk( KERN_DEBUG "Keyboard overrun\n" ); scancode = acia.key_data; /* Turn off autorepeating in case a break code has been lost */ del_timer( &atakeyb_rep_timer ); rep_scancode = 0; if (ikbd_self_test) /* During self test, don't do resyncing, just process the code */ goto interpret_scancode; else if (IS_SYNC_CODE(scancode)) { /* This code seem already to be the start of a new packet or a * single scancode */ kb_state.state = KEYBOARD; goto interpret_scancode; } else { /* Go to RESYNC state and skip this byte */ kb_state.state = RESYNC; kb_state.len = 1; /* skip max. 1 another byte */ goto repeat; } } if (acia_stat & ACIA_RDRF) /* received a character */ { scancode = acia.key_data; /* get it or reset the ACIA, I'll get it! */ mark_bh(KEYBOARD_BH); interpret_scancode: switch (kb_state.state) { case KEYBOARD: switch (scancode) { case 0xF7: kb_state.state = AMOUSE; kb_state.len = 0; break; case 0xF8: case 0xF9: case 0xFA: case 0xFB: kb_state.state = RMOUSE; kb_state.len = 1; kb_state.buf[0] = scancode; break; case 0xFC: kb_state.state = CLOCK; kb_state.len = 0; break; case 0xFE: case 0xFF: kb_state.state = JOYSTICK; kb_state.len = 1; kb_state.buf[0] = scancode; break; case 0xF1: /* during self-test, note that 0xf1 received */ if (ikbd_self_test) { ++ikbd_self_test; self_test_last_rcv = jiffies; break; } /* FALL THROUGH */ default: break_flag = scancode & BREAK_MASK; scancode &= ~BREAK_MASK; if (ikbd_self_test) { /* Scancodes sent during the self-test stand for broken * keys (keys being down). The code *should* be a break * code, but nevertheless some AT keyboard interfaces send * make codes instead. Therefore, simply ignore * break_flag... * */ int keyval = plain_map[scancode], keytyp; set_bit( scancode, broken_keys ); self_test_last_rcv = jiffies; keyval = plain_map[scancode]; keytyp = KTYP(keyval) - 0xf0; keyval = KVAL(keyval); printk( KERN_WARNING "Key with scancode %d ", scancode ); if (keytyp == KT_LATIN || keytyp == KT_LETTER) { if (keyval < ' ') printk( "('^%c') ", keyval + '@' ); else printk( "('%c') ", keyval ); } printk( "is broken -- will be ignored.\n" ); break; } else if (test_bit( scancode, broken_keys )) break; if (break_flag) { del_timer( &atakeyb_rep_timer ); rep_scancode = 0; } else { del_timer( &atakeyb_rep_timer ); rep_scancode = scancode; atakeyb_rep_timer.expires = jiffies + key_repeat_delay; atakeyb_rep_timer.prev = atakeyb_rep_timer.next = NULL; add_timer( &atakeyb_rep_timer ); } handle_scancode(break_flag | scancode); break; } break; case AMOUSE: kb_state.buf[kb_state.len++] = scancode; if (kb_state.len == 5) { kb_state.state = KEYBOARD; /* not yet used */ /* wake up someone waiting for this */ } break; case RMOUSE: kb_state.buf[kb_state.len++] = scancode; if (kb_state.len == 3) { kb_state.state = KEYBOARD; if (atari_mouse_interrupt_hook) atari_mouse_interrupt_hook(kb_state.buf); } break; case JOYSTICK: kb_state.buf[1] = scancode; kb_state.state = KEYBOARD; atari_joystick_interrupt(kb_state.buf); break; case CLOCK: kb_state.buf[kb_state.len++] = scancode; if (kb_state.len == 6) { kb_state.state = KEYBOARD; /* wake up someone waiting for this. But will this ever be used, as Linux keeps its own time. Perhaps for synchronization purposes? */ /* wake_up_interruptible(&clock_wait); */ } break; case RESYNC: if (kb_state.len <= 0 || IS_SYNC_CODE(scancode)) { kb_state.state = KEYBOARD; goto interpret_scancode; } kb_state.len--; break; } } #if 0 if (acia_stat & ACIA_CTS) /* cannot happen */; #endif if (acia_stat & (ACIA_FE | ACIA_PE)) { printk("Error in keyboard communication\n"); } /* handle_scancode() can take a lot of time, so check again if * some character arrived */ goto repeat; }
static irqreturn_t ep93xx_keypad_isr(int irq, void *dev_id) { int nkey1,nkey2; #ifdef SCROLL_WHEEL_KEY_SUPPORT int phase,step; #endif unsigned long status; struct ep93xx_keypad_dev* pdev = (struct ep93xx_keypad_dev*)dev_id; status = inl(KEY_REG); status &= 0x3fff; /* printk("status = %08x\n", (int)status); printk("%d\n",wheel_phase_table[pdev->wheelkey]); */ #ifdef SCROLL_WHEEL_KEY_SUPPORT phase = wheel_phase_table[pdev->wheelkey&0x3]; #endif if(status & KEYREG_KEY2) { nkey1 = KeyPadTable[ (status & KEYREG_KEY1_MASK)>>KEYREG_KEY1_SHIFT ]; nkey2 = KeyPadTable[ (status & KEYREG_KEY2_MASK)>>KEYREG_KEY2_SHIFT ]; #ifdef SCROLL_WHEEL_KEY_SUPPORT if( (nkey1 == KEY_WHEEL_1) || (nkey2 == KEY_WHEEL_1) ) { pdev->wheelkey |= WHEEL_FLAG1; } if( (nkey1 == KEY_WHEEL_2) || (nkey2 == KEY_WHEEL_2) ) { pdev->wheelkey |= WHEEL_FLAG2; } if(pdev->last_key1 >0 || pdev->last_key2 >0) { if((pdev->last_key1 > 0) && (nkey1 != pdev->last_key1) && (nkey2 != pdev->last_key1) ) { handle_scancode(pdev, pdev->last_key1, 0); pdev->last_key1 = 0; } if((pdev->last_key2 > 0) && (nkey1 != pdev->last_key2) && (nkey2 != pdev->last_key2) ) { handle_scancode(pdev, pdev->last_key2, 0); pdev->last_key2 = 0; } } if( (nkey1 != KEY_WHEEL_1) && (nkey1 != KEY_WHEEL_2) ) { if( (nkey1 != pdev->last_key1) && (nkey1 != pdev->last_key2) ) { handle_scancode(pdev, nkey1, 1); pdev->last_key1 = nkey1; } } if( (nkey2 != KEY_WHEEL_1) && (nkey2 != KEY_WHEEL_2) ) { if( (nkey2 != pdev->last_key1) && (nkey2 != pdev->last_key2) ) { handle_scancode(pdev, nkey2, 1); pdev->last_key2 = nkey2; } } #else if(pdev->last_key1 >0 || pdev->last_key2 >0) { if((pdev->last_key1 > 0) && (nkey1 != pdev->last_key1) && (nkey2 != pdev->last_key1) ) { handle_scancode(pdev, pdev->last_key1, 0); pdev->last_key1 = 0; } if((pdev->last_key2 > 0) && (nkey1 != pdev->last_key2) && (nkey2 != pdev->last_key2) ) { handle_scancode(pdev, pdev->last_key2, 0); pdev->last_key2 = 0; } } if( (nkey1 != pdev->last_key1) && (nkey1 != pdev->last_key2) ) { handle_scancode(pdev, nkey1, 1); pdev->last_key1 = nkey1; } if( (nkey2 != pdev->last_key1) && (nkey2 != pdev->last_key2) ) { handle_scancode(pdev, nkey2, 1); pdev->last_key2 = nkey2; } #endif }
static inline void ps2kbd_key(unsigned int keycode, unsigned int up_flag) { handle_scancode(keycode, !up_flag); }
static void smartio_interrupt_task(void *arg) { unchar code; unsigned long flags; unchar dummy; spin_lock_irqsave(&smartio_busy_lock, flags); if (atomic_read(&smartio_busy) == 1) { spin_unlock_irqrestore(&smartio_busy_lock, flags); queue_task(&tq_smartio, &tq_timer); } else { atomic_set(&smartio_busy, 1); spin_unlock_irqrestore(&smartio_busy_lock, flags); } /* Read SMARTIO Interrupt Status to check which Interrupt is occurred * and Clear SMARTIO Interrupt */ send_SSP_msg((unchar *) &RD_INT_CMD, 2); code = (unchar) (read_SSP_response(1) & 0xFF); #ifdef CONFIG_VT if (code & 0x04) { // Keyboard Interrupt kbd_int++; /* Read Scan code */ send_SSP_msg((unchar *) &RD_KBD_CMD, 2); code = (unchar) (read_SSP_response(1) & 0xFF); dummy = code & 0x80; if ((code == 0xE0) || (code == 0xE1) || (code == 0xF0)) { // combined code if (code == 0xF0) { if (!previous_code) { code = 0xE0; previous_code = 0xF0; } else { code = mf_two_kbdmap[code & 0x7F] | dummy; previous_code = 0; } } else if (code == 0xE0) { if (previous_code != 0) { code = mf_two_kbdmap[code & 0x7F] | dummy; previous_code = 0; } else previous_code = code; } else { // 0xE1 if (!previous_code) { code = mf_two_kbdmap[code &0x7F] | dummy; previous_code = 0; } else { previous_code = code; } } } else { if (code == 0x03) { f_five_pressed = 1; } else if (code == 0x83) { if (f_five_pressed != 0) { f_five_pressed = 0; code = 0x03; } else if (f_seven_pressed == 0) { f_seven_pressed = 1; code = 2; dummy = 0; } else { f_seven_pressed = 0; code = 2; } } previous_code = 0; code &= 0x7F; code = mf_two_kbdmap[code] | dummy; } sniffed_value = (ushort)code; if (SNIFFER) wake_up_interruptible(&sniffer_queue); if (SNIFFMODE == PASSIVE) { handle_scancode( code, (code & 0x80) ? 0 : 1 ); if (code & 0x80) { wake_up_interruptible(&keyboard_done_queue); mdelay(10); // this makes the whole thing a bit more stable // keyboard handling can be corrupted when hitting // thousands of keys like crazy. kbd_translate might catch up // with irq routine? or there is simply a buffer overflow on // the serial device? somehow it looses some key sequences. // if a break code is lost or coruppted the keyboard starts // to autorepeat like crazy and appears to hang. // this needs further investigations! Thomas kbd_press_flag = 0; } else kbd_press_flag = 1; } code = 0; // prevent furthermore if ... then to react! } #endif // ADC resolution is 10bit (0x000 ~ 0x3FF) if (code & 0x02) { // ADC Complete Interrupt adc_int++; send_SSP_msg((unchar *) &RD_ADC_CMD, 2); adc_value = (ushort) (read_SSP_response(2) & 0x3FF); wake_up_interruptible(&smartio_adc_queue); } if (code & 0x08) { // Keypad interrupt kpd_int++; send_SSP_msg((unchar *) &RD_KPD_CMD, 2); kpd_value = (unchar) (read_SSP_response(1) & 0xFF); wake_up_interruptible(&smartio_kpd_queue); } spin_lock_irqsave(&smartio_busy_lock, flags); atomic_set(&smartio_busy, 0); spin_unlock_irqrestore(&smartio_busy_lock, flags); enable_irq(ADS_AVR_IRQ); wake_up_interruptible(&smartio_queue); }