Esempio n. 1
0
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);
	}
}
Esempio n. 2
0
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));
	}
}