drv_keyboard.c 13 KB

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