static void keyboard_interrupt(void) { static enum decode_state ds = DECODE_STATE_MAKE_CODE; static u32_t kbd_flag = KBD_NUM_LOCK; u8_t status, data; status = readb(REALVIEW_KEYBOARD_IIR); while(status & REALVIEW_KEYBOARD_IIR_RXINTR) { data = readb(REALVIEW_KEYBOARD_DATA); switch(ds) { case DECODE_STATE_MAKE_CODE: /* break code */ if(data == 0xf0) { ds = DECODE_STATE_BREAK_CODE; } /* long make code */ else if(data == 0xe0) { ds = DECODE_STATE_LONG_MAKE_CODE; } else { ds = DECODE_STATE_MAKE_CODE; /* left shift */ if(data == 0x12) { kbd_flag |= KBD_LEFT_SHIFT; } /* right shift */ else if(data == 0x59) { kbd_flag |= KBD_RIGHT_SHIFT; } /* left ctrl */ else if(data == 0x14) { kbd_flag |= KBD_LEFT_CTRL; } /* caps lock */ else if(data == 0x58) { if(kbd_flag & KBD_CAPS_LOCK) kbd_flag &= ~KBD_CAPS_LOCK; else kbd_flag |= KBD_CAPS_LOCK; } /* scroll lock */ else if(data == 0x7e) { if(kbd_flag & KBD_SCROLL_LOCK) kbd_flag &= ~KBD_SCROLL_LOCK; else kbd_flag |= KBD_SCROLL_LOCK; } /* num lock */ else if(data == 0x77) { if(kbd_flag & KBD_NUM_LOCK) kbd_flag &= ~KBD_NUM_LOCK; else kbd_flag |= KBD_NUM_LOCK; } /* others */ else { keyboard_report_event(kbd_flag, data, KEY_BUTTON_DOWN); } } break; case DECODE_STATE_BREAK_CODE: if( (data != 0xf0) && (data != 0xe0)) { ds = DECODE_STATE_MAKE_CODE; /* left shift */ if(data == 0x12) { kbd_flag &= ~KBD_LEFT_SHIFT; } /* right shift */ else if(data == 0x59) { kbd_flag &= ~KBD_RIGHT_SHIFT; } /* left ctrl */ else if(data == 0x14) { kbd_flag &= ~KBD_LEFT_CTRL; } /* others */ else { keyboard_report_event(kbd_flag, data, KEY_BUTTON_UP); } } else { ds = DECODE_STATE_BREAK_CODE; } break; case DECODE_STATE_LONG_MAKE_CODE: if( data != 0xf0 && data!= 0xe0) { ds = DECODE_STATE_MAKE_CODE; /* left ctrl */ if(data == 0x14) { kbd_flag |= KBD_RIGHT_CTRL; } /* others */ else { keyboard_report_event(kbd_flag, data, KEY_BUTTON_DOWN); } } else { ds = DECODE_STATE_LONG_BREAK_CODE; } break; case DECODE_STATE_LONG_BREAK_CODE: if( (data != 0xf0) && (data != 0xe0)) { ds = DECODE_STATE_MAKE_CODE; /* left ctrl */ if(data == 0x14) { kbd_flag &= ~KBD_RIGHT_CTRL; } /* others */ else { keyboard_report_event(kbd_flag, data, KEY_BUTTON_UP); } } else { ds = DECODE_STATE_LONG_BREAK_CODE; } break; default: ds = DECODE_STATE_MAKE_CODE; break; } status = readb(REALVIEW_KEYBOARD_IIR); } }
static void keyboard_interrupt(void * data) { struct input_t * input = (struct input_t *)data; struct resource_t * res = (struct resource_t *)input->priv; struct realview_keyboard_data_t * dat = (struct realview_keyboard_data_t *)res->data; static enum decode_state ds = DECODE_STATE_MAKE_CODE; static u32_t kbd_flag = KBD_NUM_LOCK; u8_t status, value; status = read8(phys_to_virt(dat->regbase + KEYBOARD_IIR)); while(status & KEYBOARD_IIR_RXINTR) { value = read8(phys_to_virt(dat->regbase + KEYBOARD_DATA)); switch(ds) { case DECODE_STATE_MAKE_CODE: /* break code */ if(value == 0xf0) { ds = DECODE_STATE_BREAK_CODE; } /* long make code */ else if(value == 0xe0) { ds = DECODE_STATE_LONG_MAKE_CODE; } else { ds = DECODE_STATE_MAKE_CODE; /* left shift */ if(value == 0x12) { kbd_flag |= KBD_LEFT_SHIFT; } /* right shift */ else if(value == 0x59) { kbd_flag |= KBD_RIGHT_SHIFT; } /* left ctrl */ else if(value == 0x14) { kbd_flag |= KBD_LEFT_CTRL; } /* caps lock */ else if(value == 0x58) { if(kbd_flag & KBD_CAPS_LOCK) kbd_flag &= ~KBD_CAPS_LOCK; else kbd_flag |= KBD_CAPS_LOCK; } /* scroll lock */ else if(value == 0x7e) { if(kbd_flag & KBD_SCROLL_LOCK) kbd_flag &= ~KBD_SCROLL_LOCK; else kbd_flag |= KBD_SCROLL_LOCK; } /* num lock */ else if(value == 0x77) { if(kbd_flag & KBD_NUM_LOCK) kbd_flag &= ~KBD_NUM_LOCK; else kbd_flag |= KBD_NUM_LOCK; } /* others */ else { keyboard_report_event(input, kbd_flag, value, KEY_BUTTON_DOWN); } } break; case DECODE_STATE_BREAK_CODE: if( (value != 0xf0) && (value != 0xe0)) { ds = DECODE_STATE_MAKE_CODE; /* left shift */ if(value == 0x12) { kbd_flag &= ~KBD_LEFT_SHIFT; } /* right shift */ else if(value == 0x59) { kbd_flag &= ~KBD_RIGHT_SHIFT; } /* left ctrl */ else if(value == 0x14) { kbd_flag &= ~KBD_LEFT_CTRL; } /* others */ else { keyboard_report_event(input, kbd_flag, value, KEY_BUTTON_UP); } } else { ds = DECODE_STATE_BREAK_CODE; } break; case DECODE_STATE_LONG_MAKE_CODE: if( value != 0xf0 && value!= 0xe0) { ds = DECODE_STATE_MAKE_CODE; /* left ctrl */ if(value == 0x14) { kbd_flag |= KBD_RIGHT_CTRL; } /* others */ else { keyboard_report_event(input, kbd_flag, value, KEY_BUTTON_DOWN); } } else { ds = DECODE_STATE_LONG_BREAK_CODE; } break; case DECODE_STATE_LONG_BREAK_CODE: if( (value != 0xf0) && (value != 0xe0)) { ds = DECODE_STATE_MAKE_CODE; /* left ctrl */ if(value == 0x14) { kbd_flag &= ~KBD_RIGHT_CTRL; } /* others */ else { keyboard_report_event(input, kbd_flag, value, KEY_BUTTON_UP); } } else { ds = DECODE_STATE_LONG_BREAK_CODE; } break; default: ds = DECODE_STATE_MAKE_CODE; break; } status = read8(phys_to_virt(dat->regbase + KEYBOARD_IIR)); } }