diff --git a/bsp/qemu-vexpress-a9/drivers/drv_keyboard.c b/bsp/qemu-vexpress-a9/drivers/drv_keyboard.c new file mode 100644 index 0000000000000000000000000000000000000000..c0d139aabaee07911c497cfda8aaa972ed4d8999 --- /dev/null +++ b/bsp/qemu-vexpress-a9/drivers/drv_keyboard.c @@ -0,0 +1,474 @@ +#include +#include +#include + +#include "board.h" +#include "interrupt.h" +#include "drv_keyboard.h" + +#define DBG_LEVEL DBG_LOG +// #define DBG_ENABLE +#define DBG_COLOR + +#include "rtdbg.h" + +#define KEYBOARD_ADDRESS (0x10006000) +#define KEYBOARD_IRQ_NUM (IRQ_VEXPRESS_A9_KBD) + +#ifdef RT_USING_GUIENGINE + +#include +#include + +typedef rt_uint32_t virtual_addr_t; + +enum{ + KEYBOARD_CR = 0x00, + KEYBOARD_STAT = 0x04, + KEYBOARD_DATA = 0x08, + KEYBOARD_CLKDIV = 0x0c, + KEYBOARD_IIR = 0x10, +}; + +struct keyboard_pl050_pdata_t +{ + virtual_addr_t virt; + int irq; +}; + +enum decode_state { + DECODE_STATE_MAKE_CODE, + DECODE_STATE_BREAK_CODE, + DECODE_STATE_LONG_MAKE_CODE, + DECODE_STATE_LONG_BREAK_CODE +}; + +struct keymap { + rt_uint8_t data; + rt_uint32_t key; + rt_uint32_t unicode; + char *normal_key; +}; + +enum key_value_t { + KEY_BUTTON_UP, + KEY_BUTTON_DOWN, +}; + +enum { + KBD_LEFT_SHIFT = (0x1 << 0), + KBD_RIGHT_SHIFT = (0x1 << 1), + KBD_LEFT_CTRL = (0x1 << 2), + KBD_RIGHT_CTRL = (0x1 << 3), + KBD_CAPS_LOCK = (0x1 << 6), + KBD_NUM_LOCK = (0x1 << 7), + KBD_SCROLL_LOCK = (0x1 << 8), +}; + +static const struct keymap map[] = { + {0x1c, RTGUIK_a, 0, "a", }, + {0x32, RTGUIK_b, 0, "b", }, + {0x21, RTGUIK_c, 0, "c", }, + {0x23, RTGUIK_d, 0, "d", }, + {0x24, RTGUIK_e, 0, "e", }, + {0x2b, RTGUIK_f, 0, "f", }, + {0x34, RTGUIK_g, 0, "g", }, + {0x33, RTGUIK_h, 0, "h", }, + {0x43, RTGUIK_i, 0, "i", }, + {0x3b, RTGUIK_j, 0, "j", }, + {0x42, RTGUIK_k, 0, "k", }, + {0x4b, RTGUIK_l, 0, "l", }, + {0x3a, RTGUIK_m, 0, "m", }, + {0x31, RTGUIK_n, 0, "n", }, + {0x44, RTGUIK_o, 0, "o", }, + {0x4d, RTGUIK_p, 0, "p", }, + {0x15, RTGUIK_q, 0, "q", }, + {0x2d, RTGUIK_r, 0, "r", }, + {0x1b, RTGUIK_s, 0, "s", }, + {0x2c, RTGUIK_k, 0, "k", }, + {0x3c, RTGUIK_u, 0, "u", }, + {0x2a, RTGUIK_v, 0, "v", }, + {0x1d, RTGUIK_w, 0, "w", }, + {0x22, RTGUIK_x, 0, "x", }, + {0x35, RTGUIK_y, 0, "y", }, + {0x1a, RTGUIK_z, 0, "z", }, + + {0x45, RTGUIK_0, 0, "0", }, + {0x16, RTGUIK_1, 0, "1", }, + {0x1e, RTGUIK_2, 0, "2", }, + {0x26, RTGUIK_3, 0, "3", }, + {0x25, RTGUIK_4, 0, "4", }, + {0x2e, RTGUIK_5, 0, "5", }, + {0x36, RTGUIK_6, 0, "6", }, + {0x3d, RTGUIK_7, 0, "7", }, + {0x3e, RTGUIK_8, 0, "8", }, + {0x46, RTGUIK_9, 0, "9", }, + + {0x05, RTGUIK_F1, 0, "F1", }, + {0x06, RTGUIK_F2, 0, "F2", }, + {0x04, RTGUIK_F3, 0, "F3", }, + {0x0c, RTGUIK_F4, 0, "F4", }, + {0x03, RTGUIK_F5, 0, "F5", }, + {0x0b, RTGUIK_F6, 0, "F6", }, + {0x83, RTGUIK_F7, 0, "F7", }, + {0x0a, RTGUIK_F8, 0, "F8", }, + {0x01, RTGUIK_F9, 0, "F9", }, + {0x09, RTGUIK_F10, 0, "F10", }, + {0x78, RTGUIK_F11, 0, "F11", }, + {0x07, RTGUIK_F12, 0, "F12", }, + + {0x29, RTGUIK_SPACE, 0, "SPACE" }, + {0x71, RTGUIK_DELETE, 0, "DELETE" }, + {0x52, RTGUIK_QUOTE, 0, "'" }, + {0x55, RTGUIK_EQUALS, 0, "=" }, + {0x41, RTGUIK_COMMA, 0, "," }, + {0x4e, RTGUIK_MINUS, 0, "-" }, + // {0x49, RTGUIK_, 0, "." }, + {0x4a, RTGUIK_SLASH, 0, "/" }, + {0x4c, RTGUIK_SEMICOLON, 0, ";" }, + {0x54, RTGUIK_LEFTBRACKET, 0, "[" }, + {0x5d, RTGUIK_BACKSLASH, 0, "\\" }, + {0x5b, RTGUIK_RIGHTBRACKET, 0, "]"}, + {0x75, RTGUIK_UP, 0, "UP" }, + {0x72, RTGUIK_DOWN, 0, "DOWN" }, + {0x6b, RTGUIK_LEFT, 0, "LEFT" }, + {0x74, RTGUIK_RIGHT, 0, "RIGHT" }, + {0x0d, RTGUIK_TAB, 0, "TAB" }, + {0x76, RTGUIK_ESCAPE, 0, "ESC" }, + {0x37, RTGUIK_POWER, 0, "POWER" }, + {0x5a, RTGUIK_KP_ENTER, 0, "ENTER"}, + {0x66, RTGUIK_BACKSPACE, 0, "BACKSPACE"}, +}; + +rt_inline rt_uint8_t read8(uint32_t addr) +{ + return (*((volatile rt_uint8_t *)(addr))); +} + +rt_inline void write8(uint32_t addr, rt_uint8_t value) +{ + *((volatile rt_uint8_t *)(addr)) = value; +} + +rt_inline rt_uint32_t read32(uint32_t addr) +{ + return (*((volatile rt_uint32_t *)(addr))); +} + +rt_inline void write32(uint32_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +rt_inline int kmi_write(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t value) +{ + int timeout = 1000; + + while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 6)) == 0 && timeout--); + + if(timeout) + { + write8(pdat->virt + KEYBOARD_DATA, value); + while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)) == 0); + + if(read8(pdat->virt + KEYBOARD_DATA) == 0xfa) + return RT_TRUE; + } + return RT_FALSE; +} + +rt_inline int kmi_read(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t * value) +{ + if((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4))) + { + *value = read8(pdat->virt + KEYBOARD_DATA); + return RT_TRUE; + } + return RT_FALSE; +} + +static void keyboard_report_event(void * device, rt_uint32_t flag, rt_uint8_t data, enum key_value_t press) +{ + struct rtgui_event_kbd key_event; + rt_uint16_t i = 0, mod = 0, find_key = 0; + + for(i = 0; i < sizeof(map)/sizeof(map[0]); i++) + { + if (map[i].data == data) + { + dbg_log(DBG_LOG,"KEY info:\n"); + if (flag & KBD_CAPS_LOCK) + { + dbg_log(DBG_LOG,"CAPS:LOCK\n"); + } + else + { + dbg_log(DBG_LOG,"CAPS:UNLOCK\n"); + } + + if (flag & KBD_LEFT_SHIFT) + { + mod |= RTGUI_KMOD_LSHIFT; + dbg_log(DBG_LOG,"SHIFT:LEFT\n"); + } + else if (flag & KBD_RIGHT_SHIFT) + { + mod |= RTGUI_KMOD_RSHIFT; + dbg_log(DBG_LOG,"SHIFT:RIGHT\n"); + } + else + { + dbg_log(DBG_LOG,"SHIFT:NULL\n"); + } + + if (flag & KBD_LEFT_CTRL) + { + mod |= RTGUI_KMOD_LCTRL; + dbg_log(DBG_LOG,"CTRL:LEFT\n"); + } + else if (flag & KBD_RIGHT_CTRL) + { + mod |= RTGUI_KMOD_RCTRL; + dbg_log(DBG_LOG,"CTRL:RIGHT\n"); + } + else + { + dbg_log(DBG_LOG,"CTRL:NULL\n"); + } + + dbg_log(DBG_LOG,"flag:0x%08x value:0x%x key:%s status:%s\n", \ + flag, data, map[i].normal_key, press ==0 ? "UP" : "DOWN"); + find_key = 1; + break; + } + } + if (find_key == 0) + { + dbg_log(DBG_LOG,"flag:0x%08x value:0x%x key:%s status:%s\n", \ + flag, data, "UNKNOWN", press ==0 ? "UP" : "DOWN"); + return; + } + + key_event.parent.sender = RT_NULL; + key_event.parent.type = RTGUI_EVENT_KBD; + key_event.type = (press == 0 ? RTGUI_KEYUP : RTGUI_KEYDOWN); + key_event.key = map[i].key; + key_event.mod = mod; + key_event.unicode = map[i].unicode; + rtgui_server_post_event(&key_event.parent, sizeof(key_event)); +} + +static void keyboard_pl050_interrupt(int irq, void *data) +{ + struct keyboard_pl050_pdata_t * pdat = (struct keyboard_pl050_pdata_t *)data; + static enum decode_state ds = DECODE_STATE_MAKE_CODE; + static rt_uint32_t kbd_flag = KBD_NUM_LOCK; + rt_uint8_t status, value; + + status = read8(pdat->virt + KEYBOARD_IIR); + + while(status & (1 << 0)) + { + value = read8(pdat->virt + 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(data, 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(data, 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(data, 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(data, kbd_flag, value, KEY_BUTTON_UP); + } + } + else + { + ds = DECODE_STATE_LONG_BREAK_CODE; + } + break; + + default: + ds = DECODE_STATE_MAKE_CODE; + break; + } + + status = read8(pdat->virt + KEYBOARD_IIR); + } +} + +int rt_hw_keyboard_init(void) +{ + rt_uint8_t value; + rt_uint32_t id; + struct keyboard_pl050_pdata_t *pdat; + virtual_addr_t virt = (virtual_addr_t)KEYBOARD_ADDRESS; + int irq = KEYBOARD_IRQ_NUM; + + id = (((read32(virt + 0xfec) & 0xff) << 24) | + ((read32(virt + 0xfe8) & 0xff) << 16) | + ((read32(virt + 0xfe4) & 0xff) << 8) | + ((read32(virt + 0xfe0) & 0xff) << 0)); + + if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050) + { + dbg_log(DBG_ERROR, "read id fail id:0x%08x\n", id); + return RT_ERROR; + } + + pdat = rt_malloc(sizeof(struct keyboard_pl050_pdata_t)); + if(!pdat) + { + dbg_log(DBG_ERROR, "malloc memory\n", id); + return RT_ERROR; + } + rt_memset(pdat, 0, sizeof(struct keyboard_pl050_pdata_t)); + + pdat->virt = virt; + pdat->irq = irq; + + write8(pdat->virt + KEYBOARD_CLKDIV, 0); + write8(pdat->virt + KEYBOARD_CR, (1 << 2)); + kmi_read(pdat, &value); + kmi_write(pdat, 0xff); + kmi_read(pdat, &value); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 0x2b); + kmi_write(pdat, 0xf0); + kmi_write(pdat, 0x02); + kmi_write(pdat, 0xfa); + kmi_write(pdat, 0xed); + kmi_write(pdat, 0x02); + write8(pdat->virt + KEYBOARD_CR, (1 << 2) | (1 << 4)); + + rt_hw_interrupt_install(irq, keyboard_pl050_interrupt, (void *)pdat, "keyboard"); + rt_hw_interrupt_umask(irq); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_keyboard_init); + +#endif diff --git a/bsp/qemu-vexpress-a9/drivers/drv_keyboard.h b/bsp/qemu-vexpress-a9/drivers/drv_keyboard.h new file mode 100644 index 0000000000000000000000000000000000000000..6d5acb7427c09c23a0329197ed36b83497c60fc1 --- /dev/null +++ b/bsp/qemu-vexpress-a9/drivers/drv_keyboard.h @@ -0,0 +1,6 @@ +#ifndef __DEV_KEYBOARD_H__ +#define __DEV_KEYBOARD_H__ + +int rt_hw_keyboard_init(void); + +#endif diff --git a/bsp/qemu-vexpress-a9/drivers/drv_mouse.c b/bsp/qemu-vexpress-a9/drivers/drv_mouse.c new file mode 100644 index 0000000000000000000000000000000000000000..3b9b5fd774cec339c510c0777a7cf91e05b655d8 --- /dev/null +++ b/bsp/qemu-vexpress-a9/drivers/drv_mouse.c @@ -0,0 +1,298 @@ +#include +#include +#include + +#include "board.h" +#include "interrupt.h" +#include "drv_mouse.h" + +#define DBG_LEVEL DBG_LOG +// #define DBG_ENABLE +#define DBG_COLOR + +#include "rtdbg.h" + +#define MOUSE_ADDRESS (0x10007000) +#define MOUSE_IRQ_NUM (IRQ_VEXPRESS_A9_MOUSE) +#define MOUSE_XMAX (800) +#define MOUSE_YMAX (480) + +#define MOUSE_BUTTON_LEFT (0x01) +#define MOUSE_BUTTON_RIGHT (0x02) +#define MOUSE_BUTTON_MIDDLE (0x04) +#define MOUSE_BUTTON_DOWN (0x10) +#define MOUSE_BUTTON_UP (0x20) +#define MOUSE_BUTTON_MOVE (0x40) +#define MOUSE_BUTTON_WHELL (0x80) + +#ifdef RT_USING_GUIENGINE + +#include +#include + +typedef rt_uint32_t virtual_addr_t; + +enum { + MOUSE_CR = 0x00, + MOUSE_STAT = 0x04, + MOUSE_DATA = 0x08, + MOUSE_CLKDIV = 0x0c, + MOUSE_IIR = 0x10, +}; + +struct mouse_pl050_pdata_t { + virtual_addr_t virt; + int irq; + int xmax, ymax; + int xpos, ypos; + unsigned char packet[4]; + int index; + int obtn; + int type; +}; + +rt_inline rt_uint8_t read8(uint32_t addr) +{ + return (*((volatile rt_uint8_t *)(addr))); +} + +rt_inline void write8(uint32_t addr, rt_uint8_t value) +{ + *((volatile rt_uint8_t *)(addr)) = value; +} + +rt_inline rt_uint32_t read32(uint32_t addr) +{ + return (*((volatile rt_uint32_t *)(addr))); +} + +rt_inline void write32(uint32_t addr, rt_uint32_t value) +{ + *((volatile rt_uint32_t *)(addr)) = value; +} + +rt_inline int kmi_write(struct mouse_pl050_pdata_t * pdat, rt_uint8_t value) +{ + int timeout = 1000; + + while((read8(pdat->virt + MOUSE_STAT) & (1 << 6)) == 0 && timeout--); + + if(timeout) + { + write8(pdat->virt + MOUSE_DATA, value); + while((read8(pdat->virt + MOUSE_STAT) & (1 << 4)) == 0); + + if(read8(pdat->virt + MOUSE_DATA) == 0xfa) + return RT_TRUE; + } + return RT_FALSE; +} + +rt_inline int kmi_read(struct mouse_pl050_pdata_t * pdat, rt_uint8_t * value) +{ + if((read8(pdat->virt + MOUSE_STAT) & (1 << 4))) + { + *value = read8(pdat->virt + MOUSE_DATA); + return RT_TRUE; + } + return RT_FALSE; +} + +static rt_uint32_t emouse_id; + +void push_event_touch_move(int x, int y) +{ + struct rtgui_event_mouse emouse; + + emouse.parent.sender = RT_NULL; + emouse.wid = RT_NULL; + + emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; + emouse.parent.type = RTGUI_EVENT_MOUSE_MOTION; + emouse.x = x; + emouse.y = y; + emouse.ts = rt_tick_get(); + emouse.id = emouse_id; + + dbg_log(DBG_LOG, "[line]:%d motion event id:%d x:%d y:%d\n", __LINE__, emouse.id, x, y); + rtgui_server_post_event(&emouse.parent, sizeof(emouse)); +} + +void push_event_touch_begin(int x, int y) +{ + struct rtgui_event_mouse emouse; + + emouse_id = rt_tick_get(); + + emouse.parent.sender = RT_NULL; + emouse.wid = RT_NULL; + + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN; + emouse.x = x; + emouse.y = y; + emouse.ts = rt_tick_get(); + emouse.id = emouse_id; + dbg_log(DBG_LOG, "[line]:%d down event id:%d x:%d y:%d\n", __LINE__, emouse.id, x, y); + rtgui_server_post_event(&emouse.parent, sizeof(emouse)); +} + +void push_event_touch_end(int x, int y) +{ + struct rtgui_event_mouse emouse; + + emouse.parent.sender = RT_NULL; + emouse.wid = RT_NULL; + + emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON; + emouse.button = RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP; + emouse.x = x; + emouse.y = y; + emouse.ts = rt_tick_get(); + emouse.id = emouse_id; + + dbg_log(DBG_LOG, "[line]:%d up event id:%d x:%d y:%d\n", __LINE__, emouse.id, x, y); + rtgui_server_post_event(&emouse.parent, sizeof(emouse)); +} + +static void mouse_pl050_interrupt(int irq, void * data) +{ + struct mouse_pl050_pdata_t * pdat = (struct mouse_pl050_pdata_t *)data; + int x, y, relx, rely, delta; + int btndown, btnup, btn; + int status = 0; + + status = read8(pdat->virt + MOUSE_IIR); + while(status & (1 << 0)) + { + pdat->packet[pdat->index] = read8(pdat->virt + MOUSE_DATA); + pdat->index = (pdat->index + 1) & 0x3; + + if(pdat->index == 0) + { + btn = pdat->packet[0] & 0x7; + btndown = (btn ^ pdat->obtn) & btn; + btnup = (btn ^ pdat->obtn) & pdat->obtn; + pdat->obtn = btn; + + if(pdat->packet[0] & 0x10) + relx = 0xffffff00 | pdat->packet[1]; + else + relx = pdat->packet[1]; + + if(pdat->packet[0] & 0x20) + rely = 0xffffff00 | pdat->packet[2]; + else + rely = pdat->packet[2]; + rely = -rely; + + delta = pdat->packet[3] & 0xf; + if(delta == 0xf) + delta = -1; + + if(relx != 0) + { + pdat->xpos = pdat->xpos + relx; + if(pdat->xpos < 0) + pdat->xpos = 0; + if(pdat->xpos > pdat->xmax - 1) + pdat->xpos = pdat->xmax - 1; + } + if(rely != 0) + { + pdat->ypos = pdat->ypos + rely; + if(pdat->ypos < 0) + pdat->ypos = 0; + if(pdat->ypos > pdat->ymax - 1) + pdat->ypos = pdat->ymax - 1; + } + x = pdat->xpos; + y = pdat->ypos; + + if((btn & (0x01 << 0)) && ((relx != 0) || (rely != 0))) + push_event_touch_move(x, y); + + if(btndown & (0x01 << 0)) + push_event_touch_begin(x, y); + + if(btnup & (0x01 << 0)) + push_event_touch_end(x, y); + } + + status = read8(pdat->virt + MOUSE_IIR); + } +} + +int rt_hw_mouse_init(void) +{ + rt_uint8_t value; + rt_uint32_t id; + struct mouse_pl050_pdata_t *pdat; + virtual_addr_t virt = MOUSE_ADDRESS; + int irq = MOUSE_IRQ_NUM; + + id = (((read32(virt + 0xfec) & 0xff) << 24) | + ((read32(virt + 0xfe8) & 0xff) << 16) | + ((read32(virt + 0xfe4) & 0xff) << 8) | + ((read32(virt + 0xfe0) & 0xff) << 0)); + + if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050) + { + dbg_log(DBG_ERROR, "read id fail id:0x%08x\n", id); + return RT_ERROR; + } + + pdat = rt_malloc(sizeof(struct mouse_pl050_pdata_t)); + if(!pdat) + { + dbg_log(DBG_ERROR, "malloc memory\n", id); + return RT_ERROR; + } + rt_memset(pdat, 0, sizeof(struct mouse_pl050_pdata_t)); + + pdat->virt = virt; + pdat->irq = irq; + pdat->xmax = MOUSE_XMAX; + pdat->ymax = MOUSE_YMAX; + pdat->xpos = pdat->xmax / 2; + pdat->ypos = pdat->ymax / 2; + pdat->packet[0] = 0; + pdat->packet[1] = 0; + pdat->packet[2] = 0; + pdat->packet[3] = 0; + pdat->index = 0; + pdat->obtn = 0; + + write8(pdat->virt + MOUSE_CLKDIV, 0); + write8(pdat->virt + MOUSE_CR, (1 << 2)); + kmi_write(pdat, 0xff); + kmi_read(pdat, &value); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 200); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 100); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 80); + kmi_write(pdat, 0xf2); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + kmi_write(pdat, 0xf3); + kmi_write(pdat, 100); + kmi_write(pdat, 0xe8); + kmi_write(pdat, 0x02); + kmi_write(pdat, 0xe6); + kmi_write(pdat, 0xf4); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + kmi_read(pdat, &value); + write8(pdat->virt + MOUSE_CR, (1 << 2) | (1 << 4)); + + rt_hw_interrupt_install(pdat->irq, mouse_pl050_interrupt, (void *)pdat, "mouse"); + rt_hw_interrupt_umask(pdat->irq); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_mouse_init); + +#endif diff --git a/bsp/qemu-vexpress-a9/drivers/drv_mouse.h b/bsp/qemu-vexpress-a9/drivers/drv_mouse.h new file mode 100644 index 0000000000000000000000000000000000000000..c5d190950a6e1b49b0ea4ab46130a505b3eab3c3 --- /dev/null +++ b/bsp/qemu-vexpress-a9/drivers/drv_mouse.h @@ -0,0 +1,6 @@ +#ifndef __DRV_MOUSE_H__ +#define __DRV_MOUSE_H__ + +int rt_hw_mouse_init(void); + +#endif \ No newline at end of file