drv_keyboard.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #include <rtdevice.h>
  4. #include "board.h"
  5. #include "interrupt.h"
  6. #include "drv_keyboard.h"
  7. #define DBG_LEVEL DBG_LOG
  8. // #define DBG_ENABLE
  9. #define DBG_COLOR
  10. #include "rtdbg.h"
  11. #define KEYBOARD_ADDRESS (0x10006000)
  12. #define KEYBOARD_IRQ_NUM (IRQ_VEXPRESS_A9_KBD)
  13. #ifdef PKG_USING_GUIENGINE
  14. #include <rtgui/event.h>
  15. #include <rtgui/rtgui_server.h>
  16. typedef rt_uint32_t virtual_addr_t;
  17. enum{
  18. KEYBOARD_CR = 0x00,
  19. KEYBOARD_STAT = 0x04,
  20. KEYBOARD_DATA = 0x08,
  21. KEYBOARD_CLKDIV = 0x0c,
  22. KEYBOARD_IIR = 0x10,
  23. };
  24. struct keyboard_pl050_pdata_t
  25. {
  26. virtual_addr_t virt;
  27. int irq;
  28. };
  29. enum decode_state {
  30. DECODE_STATE_MAKE_CODE,
  31. DECODE_STATE_BREAK_CODE,
  32. DECODE_STATE_LONG_MAKE_CODE,
  33. DECODE_STATE_LONG_BREAK_CODE
  34. };
  35. struct keymap {
  36. rt_uint8_t data;
  37. rt_uint32_t key;
  38. rt_uint32_t unicode;
  39. char *normal_key;
  40. };
  41. enum key_value_t {
  42. KEY_BUTTON_UP,
  43. KEY_BUTTON_DOWN,
  44. };
  45. enum {
  46. KBD_LEFT_SHIFT = (0x1 << 0),
  47. KBD_RIGHT_SHIFT = (0x1 << 1),
  48. KBD_LEFT_CTRL = (0x1 << 2),
  49. KBD_RIGHT_CTRL = (0x1 << 3),
  50. KBD_CAPS_LOCK = (0x1 << 6),
  51. KBD_NUM_LOCK = (0x1 << 7),
  52. KBD_SCROLL_LOCK = (0x1 << 8),
  53. };
  54. static const struct keymap map[] = {
  55. {0x1c, RTGUIK_a, 0, "a", },
  56. {0x32, RTGUIK_b, 0, "b", },
  57. {0x21, RTGUIK_c, 0, "c", },
  58. {0x23, RTGUIK_d, 0, "d", },
  59. {0x24, RTGUIK_e, 0, "e", },
  60. {0x2b, RTGUIK_f, 0, "f", },
  61. {0x34, RTGUIK_g, 0, "g", },
  62. {0x33, RTGUIK_h, 0, "h", },
  63. {0x43, RTGUIK_i, 0, "i", },
  64. {0x3b, RTGUIK_j, 0, "j", },
  65. {0x42, RTGUIK_k, 0, "k", },
  66. {0x4b, RTGUIK_l, 0, "l", },
  67. {0x3a, RTGUIK_m, 0, "m", },
  68. {0x31, RTGUIK_n, 0, "n", },
  69. {0x44, RTGUIK_o, 0, "o", },
  70. {0x4d, RTGUIK_p, 0, "p", },
  71. {0x15, RTGUIK_q, 0, "q", },
  72. {0x2d, RTGUIK_r, 0, "r", },
  73. {0x1b, RTGUIK_s, 0, "s", },
  74. {0x2c, RTGUIK_k, 0, "k", },
  75. {0x3c, RTGUIK_u, 0, "u", },
  76. {0x2a, RTGUIK_v, 0, "v", },
  77. {0x1d, RTGUIK_w, 0, "w", },
  78. {0x22, RTGUIK_x, 0, "x", },
  79. {0x35, RTGUIK_y, 0, "y", },
  80. {0x1a, RTGUIK_z, 0, "z", },
  81. {0x45, RTGUIK_0, 0, "0", },
  82. {0x16, RTGUIK_1, 0, "1", },
  83. {0x1e, RTGUIK_2, 0, "2", },
  84. {0x26, RTGUIK_3, 0, "3", },
  85. {0x25, RTGUIK_4, 0, "4", },
  86. {0x2e, RTGUIK_5, 0, "5", },
  87. {0x36, RTGUIK_6, 0, "6", },
  88. {0x3d, RTGUIK_7, 0, "7", },
  89. {0x3e, RTGUIK_8, 0, "8", },
  90. {0x46, RTGUIK_9, 0, "9", },
  91. {0x05, RTGUIK_F1, 0, "F1", },
  92. {0x06, RTGUIK_F2, 0, "F2", },
  93. {0x04, RTGUIK_F3, 0, "F3", },
  94. {0x0c, RTGUIK_F4, 0, "F4", },
  95. {0x03, RTGUIK_F5, 0, "F5", },
  96. {0x0b, RTGUIK_F6, 0, "F6", },
  97. {0x83, RTGUIK_F7, 0, "F7", },
  98. {0x0a, RTGUIK_F8, 0, "F8", },
  99. {0x01, RTGUIK_F9, 0, "F9", },
  100. {0x09, RTGUIK_F10, 0, "F10", },
  101. {0x78, RTGUIK_F11, 0, "F11", },
  102. {0x07, RTGUIK_F12, 0, "F12", },
  103. {0x29, RTGUIK_SPACE, 0, "SPACE" },
  104. {0x71, RTGUIK_DELETE, 0, "DELETE" },
  105. {0x52, RTGUIK_QUOTE, 0, "'" },
  106. {0x55, RTGUIK_EQUALS, 0, "=" },
  107. {0x41, RTGUIK_COMMA, 0, "," },
  108. {0x4e, RTGUIK_MINUS, 0, "-" },
  109. // {0x49, RTGUIK_, 0, "." },
  110. {0x4a, RTGUIK_SLASH, 0, "/" },
  111. {0x4c, RTGUIK_SEMICOLON, 0, ";" },
  112. {0x54, RTGUIK_LEFTBRACKET, 0, "[" },
  113. {0x5d, RTGUIK_BACKSLASH, 0, "\\" },
  114. {0x5b, RTGUIK_RIGHTBRACKET, 0, "]"},
  115. {0x75, RTGUIK_UP, 0, "UP" },
  116. {0x72, RTGUIK_DOWN, 0, "DOWN" },
  117. {0x6b, RTGUIK_LEFT, 0, "LEFT" },
  118. {0x74, RTGUIK_RIGHT, 0, "RIGHT" },
  119. {0x0d, RTGUIK_TAB, 0, "TAB" },
  120. {0x76, RTGUIK_ESCAPE, 0, "ESC" },
  121. {0x37, RTGUIK_POWER, 0, "POWER" },
  122. {0x5a, RTGUIK_KP_ENTER, 0, "ENTER"},
  123. {0x66, RTGUIK_BACKSPACE, 0, "BACKSPACE"},
  124. };
  125. rt_inline rt_uint8_t read8(uint32_t addr)
  126. {
  127. return (*((volatile rt_uint8_t *)(addr)));
  128. }
  129. rt_inline void write8(uint32_t addr, rt_uint8_t value)
  130. {
  131. *((volatile rt_uint8_t *)(addr)) = value;
  132. }
  133. rt_inline rt_uint32_t read32(uint32_t addr)
  134. {
  135. return (*((volatile rt_uint32_t *)(addr)));
  136. }
  137. rt_inline void write32(uint32_t addr, rt_uint32_t value)
  138. {
  139. *((volatile rt_uint32_t *)(addr)) = value;
  140. }
  141. rt_inline int kmi_write(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t value)
  142. {
  143. int timeout = 1000;
  144. while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 6)) == 0 && timeout--);
  145. if(timeout)
  146. {
  147. write8(pdat->virt + KEYBOARD_DATA, value);
  148. while((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)) == 0);
  149. if(read8(pdat->virt + KEYBOARD_DATA) == 0xfa)
  150. return RT_TRUE;
  151. }
  152. return RT_FALSE;
  153. }
  154. rt_inline int kmi_read(struct keyboard_pl050_pdata_t * pdat, rt_uint8_t * value)
  155. {
  156. if((read8(pdat->virt + KEYBOARD_STAT) & (1 << 4)))
  157. {
  158. *value = read8(pdat->virt + KEYBOARD_DATA);
  159. return RT_TRUE;
  160. }
  161. return RT_FALSE;
  162. }
  163. static void keyboard_report_event(void * device, rt_uint32_t flag, rt_uint8_t data, enum key_value_t press)
  164. {
  165. struct rtgui_event_kbd key_event;
  166. rt_uint16_t i = 0, mod = 0, find_key = 0;
  167. for(i = 0; i < sizeof(map)/sizeof(map[0]); i++)
  168. {
  169. if (map[i].data == data)
  170. {
  171. dbg_log(DBG_LOG,"KEY info:\n");
  172. if (flag & KBD_CAPS_LOCK)
  173. {
  174. dbg_log(DBG_LOG,"CAPS:LOCK\n");
  175. }
  176. else
  177. {
  178. dbg_log(DBG_LOG,"CAPS:UNLOCK\n");
  179. }
  180. if (flag & KBD_LEFT_SHIFT)
  181. {
  182. mod |= RTGUI_KMOD_LSHIFT;
  183. dbg_log(DBG_LOG,"SHIFT:LEFT\n");
  184. }
  185. else if (flag & KBD_RIGHT_SHIFT)
  186. {
  187. mod |= RTGUI_KMOD_RSHIFT;
  188. dbg_log(DBG_LOG,"SHIFT:RIGHT\n");
  189. }
  190. else
  191. {
  192. dbg_log(DBG_LOG,"SHIFT:NULL\n");
  193. }
  194. if (flag & KBD_LEFT_CTRL)
  195. {
  196. mod |= RTGUI_KMOD_LCTRL;
  197. dbg_log(DBG_LOG,"CTRL:LEFT\n");
  198. }
  199. else if (flag & KBD_RIGHT_CTRL)
  200. {
  201. mod |= RTGUI_KMOD_RCTRL;
  202. dbg_log(DBG_LOG,"CTRL:RIGHT\n");
  203. }
  204. else
  205. {
  206. dbg_log(DBG_LOG,"CTRL:NULL\n");
  207. }
  208. dbg_log(DBG_LOG,"flag:0x%08x value:0x%x key:%s status:%s\n", \
  209. flag, data, map[i].normal_key, press ==0 ? "UP" : "DOWN");
  210. find_key = 1;
  211. break;
  212. }
  213. }
  214. if (find_key == 0)
  215. {
  216. dbg_log(DBG_LOG,"flag:0x%08x value:0x%x key:%s status:%s\n", \
  217. flag, data, "UNKNOWN", press ==0 ? "UP" : "DOWN");
  218. return;
  219. }
  220. key_event.parent.sender = RT_NULL;
  221. key_event.parent.type = RTGUI_EVENT_KBD;
  222. key_event.type = (press == 0 ? RTGUI_KEYUP : RTGUI_KEYDOWN);
  223. key_event.key = map[i].key;
  224. key_event.mod = mod;
  225. key_event.unicode = map[i].unicode;
  226. rtgui_server_post_event(&key_event.parent, sizeof(key_event));
  227. }
  228. static void keyboard_pl050_interrupt(int irq, void *data)
  229. {
  230. struct keyboard_pl050_pdata_t * pdat = (struct keyboard_pl050_pdata_t *)data;
  231. static enum decode_state ds = DECODE_STATE_MAKE_CODE;
  232. static rt_uint32_t kbd_flag = KBD_NUM_LOCK;
  233. rt_uint8_t status, value;
  234. status = read8(pdat->virt + KEYBOARD_IIR);
  235. while(status & (1 << 0))
  236. {
  237. value = read8(pdat->virt + KEYBOARD_DATA);
  238. switch(ds)
  239. {
  240. case DECODE_STATE_MAKE_CODE:
  241. /* break code */
  242. if(value == 0xf0)
  243. {
  244. ds = DECODE_STATE_BREAK_CODE;
  245. }
  246. /* long make code */
  247. else if(value == 0xe0)
  248. {
  249. ds = DECODE_STATE_LONG_MAKE_CODE;
  250. }
  251. else
  252. {
  253. ds = DECODE_STATE_MAKE_CODE;
  254. /* left shift */
  255. if(value == 0x12)
  256. {
  257. kbd_flag |= KBD_LEFT_SHIFT;
  258. }
  259. /* right shift */
  260. else if(value == 0x59)
  261. {
  262. kbd_flag |= KBD_RIGHT_SHIFT;
  263. }
  264. /* left ctrl */
  265. else if(value == 0x14)
  266. {
  267. kbd_flag |= KBD_LEFT_CTRL;
  268. }
  269. /* caps lock */
  270. else if(value == 0x58)
  271. {
  272. if(kbd_flag & KBD_CAPS_LOCK)
  273. kbd_flag &= ~KBD_CAPS_LOCK;
  274. else
  275. kbd_flag |= KBD_CAPS_LOCK;
  276. }
  277. /* scroll lock */
  278. else if(value == 0x7e)
  279. {
  280. if(kbd_flag & KBD_SCROLL_LOCK)
  281. kbd_flag &= ~KBD_SCROLL_LOCK;
  282. else
  283. kbd_flag |= KBD_SCROLL_LOCK;
  284. }
  285. /* num lock */
  286. else if(value == 0x77)
  287. {
  288. if(kbd_flag & KBD_NUM_LOCK)
  289. kbd_flag &= ~KBD_NUM_LOCK;
  290. else
  291. kbd_flag |= KBD_NUM_LOCK;
  292. }
  293. /* others */
  294. else
  295. {
  296. keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN);
  297. }
  298. }
  299. break;
  300. case DECODE_STATE_BREAK_CODE:
  301. if( (value != 0xf0) && (value != 0xe0))
  302. {
  303. ds = DECODE_STATE_MAKE_CODE;
  304. /* left shift */
  305. if(value == 0x12)
  306. {
  307. kbd_flag &= ~KBD_LEFT_SHIFT;
  308. }
  309. /* right shift */
  310. else if(value == 0x59)
  311. {
  312. kbd_flag &= ~KBD_RIGHT_SHIFT;
  313. }
  314. /* left ctrl */
  315. else if(value == 0x14)
  316. {
  317. kbd_flag &= ~KBD_LEFT_CTRL;
  318. }
  319. /* others */
  320. else
  321. {
  322. keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP);
  323. }
  324. }
  325. else
  326. {
  327. ds = DECODE_STATE_BREAK_CODE;
  328. }
  329. break;
  330. case DECODE_STATE_LONG_MAKE_CODE:
  331. if( value != 0xf0 && value!= 0xe0)
  332. {
  333. ds = DECODE_STATE_MAKE_CODE;
  334. /* left ctrl */
  335. if(value == 0x14)
  336. {
  337. kbd_flag |= KBD_RIGHT_CTRL;
  338. }
  339. /* others */
  340. else
  341. {
  342. keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_DOWN);
  343. }
  344. }
  345. else
  346. {
  347. ds = DECODE_STATE_LONG_BREAK_CODE;
  348. }
  349. break;
  350. case DECODE_STATE_LONG_BREAK_CODE:
  351. if( (value != 0xf0) && (value != 0xe0))
  352. {
  353. ds = DECODE_STATE_MAKE_CODE;
  354. /* left ctrl */
  355. if(value == 0x14)
  356. {
  357. kbd_flag &= ~KBD_RIGHT_CTRL;
  358. }
  359. /* others */
  360. else
  361. {
  362. keyboard_report_event(data, kbd_flag, value, KEY_BUTTON_UP);
  363. }
  364. }
  365. else
  366. {
  367. ds = DECODE_STATE_LONG_BREAK_CODE;
  368. }
  369. break;
  370. default:
  371. ds = DECODE_STATE_MAKE_CODE;
  372. break;
  373. }
  374. status = read8(pdat->virt + KEYBOARD_IIR);
  375. }
  376. }
  377. int rt_hw_keyboard_init(void)
  378. {
  379. rt_uint8_t value;
  380. rt_uint32_t id;
  381. struct keyboard_pl050_pdata_t *pdat;
  382. virtual_addr_t virt = (virtual_addr_t)KEYBOARD_ADDRESS;
  383. int irq = KEYBOARD_IRQ_NUM;
  384. id = (((read32(virt + 0xfec) & 0xff) << 24) |
  385. ((read32(virt + 0xfe8) & 0xff) << 16) |
  386. ((read32(virt + 0xfe4) & 0xff) << 8) |
  387. ((read32(virt + 0xfe0) & 0xff) << 0));
  388. if(((id >> 12) & 0xff) != 0x41 || (id & 0xfff) != 0x050)
  389. {
  390. dbg_log(DBG_ERROR, "read id fail id:0x%08x\n", id);
  391. return RT_ERROR;
  392. }
  393. pdat = rt_malloc(sizeof(struct keyboard_pl050_pdata_t));
  394. if(!pdat)
  395. {
  396. dbg_log(DBG_ERROR, "malloc memory\n", id);
  397. return RT_ERROR;
  398. }
  399. rt_memset(pdat, 0, sizeof(struct keyboard_pl050_pdata_t));
  400. pdat->virt = virt;
  401. pdat->irq = irq;
  402. write8(pdat->virt + KEYBOARD_CLKDIV, 0);
  403. write8(pdat->virt + KEYBOARD_CR, (1 << 2));
  404. kmi_read(pdat, &value);
  405. kmi_write(pdat, 0xff);
  406. kmi_read(pdat, &value);
  407. kmi_write(pdat, 0xf3);
  408. kmi_write(pdat, 0x2b);
  409. kmi_write(pdat, 0xf0);
  410. kmi_write(pdat, 0x02);
  411. kmi_write(pdat, 0xfa);
  412. kmi_write(pdat, 0xed);
  413. kmi_write(pdat, 0x02);
  414. write8(pdat->virt + KEYBOARD_CR, (1 << 2) | (1 << 4));
  415. rt_hw_interrupt_install(irq, keyboard_pl050_interrupt, (void *)pdat, "keyboard");
  416. rt_hw_interrupt_umask(irq);
  417. return RT_EOK;
  418. }
  419. INIT_DEVICE_EXPORT(rt_hw_keyboard_init);
  420. #endif