drv_keyboard.c 13 KB

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