spear-keyboard.c 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. /*
  2. * SPEAr Keyboard Driver
  3. * Based on omap-keypad driver
  4. *
  5. * Copyright (C) 2010 ST Microelectronics
  6. * Rajeev Kumar<rajeev-dlh.kumar@st.com>
  7. *
  8. * This file is licensed under the terms of the GNU General Public
  9. * License version 2. This program is licensed "as is" without any
  10. * warranty of any kind, whether express or implied.
  11. */
  12. #include <linux/clk.h>
  13. #include <linux/errno.h>
  14. #include <linux/init.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/input.h>
  17. #include <linux/io.h>
  18. #include <linux/irq.h>
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/platform_device.h>
  22. #include <linux/pm_wakeup.h>
  23. #include <linux/slab.h>
  24. #include <linux/types.h>
  25. #include <plat/keyboard.h>
  26. /* Keyboard Registers */
  27. #define MODE_REG 0x00 /* 16 bit reg */
  28. #define STATUS_REG 0x0C /* 2 bit reg */
  29. #define DATA_REG 0x10 /* 8 bit reg */
  30. #define INTR_MASK 0x54
  31. /* Register Values */
  32. /*
  33. * pclk freq mask = (APB FEQ -1)= 82 MHZ.Programme bit 15-9 in mode
  34. * control register as 1010010(82MHZ)
  35. */
  36. #define PCLK_FREQ_MSK 0xA400 /* 82 MHz */
  37. #define START_SCAN 0x0100
  38. #define SCAN_RATE_10 0x0000
  39. #define SCAN_RATE_20 0x0004
  40. #define SCAN_RATE_40 0x0008
  41. #define SCAN_RATE_80 0x000C
  42. #define MODE_KEYBOARD 0x0002
  43. #define DATA_AVAIL 0x2
  44. #define KEY_MASK 0xFF000000
  45. #define KEY_VALUE 0x00FFFFFF
  46. #define ROW_MASK 0xF0
  47. #define COLUMN_MASK 0x0F
  48. #define ROW_SHIFT 4
  49. #define KEY_MATRIX_SHIFT 6
  50. struct spear_kbd {
  51. struct input_dev *input;
  52. struct resource *res;
  53. void __iomem *io_base;
  54. struct clk *clk;
  55. unsigned int irq;
  56. unsigned int mode;
  57. unsigned short last_key;
  58. unsigned short keycodes[256];
  59. };
  60. static irqreturn_t spear_kbd_interrupt(int irq, void *dev_id)
  61. {
  62. struct spear_kbd *kbd = dev_id;
  63. struct input_dev *input = kbd->input;
  64. unsigned int key;
  65. u8 sts, val;
  66. sts = readb(kbd->io_base + STATUS_REG);
  67. if (!(sts & DATA_AVAIL))
  68. return IRQ_NONE;
  69. if (kbd->last_key != KEY_RESERVED) {
  70. input_report_key(input, kbd->last_key, 0);
  71. kbd->last_key = KEY_RESERVED;
  72. }
  73. /* following reads active (row, col) pair */
  74. val = readb(kbd->io_base + DATA_REG);
  75. key = kbd->keycodes[val];
  76. input_event(input, EV_MSC, MSC_SCAN, val);
  77. input_report_key(input, key, 1);
  78. input_sync(input);
  79. kbd->last_key = key;
  80. /* clear interrupt */
  81. writeb(0, kbd->io_base + STATUS_REG);
  82. return IRQ_HANDLED;
  83. }
  84. static int spear_kbd_open(struct input_dev *dev)
  85. {
  86. struct spear_kbd *kbd = input_get_drvdata(dev);
  87. int error;
  88. u16 val;
  89. kbd->last_key = KEY_RESERVED;
  90. error = clk_enable(kbd->clk);
  91. if (error)
  92. return error;
  93. /* program keyboard */
  94. val = SCAN_RATE_80 | MODE_KEYBOARD | PCLK_FREQ_MSK |
  95. (kbd->mode << KEY_MATRIX_SHIFT);
  96. writew(val, kbd->io_base + MODE_REG);
  97. writeb(1, kbd->io_base + STATUS_REG);
  98. /* start key scan */
  99. val = readw(kbd->io_base + MODE_REG);
  100. val |= START_SCAN;
  101. writew(val, kbd->io_base + MODE_REG);
  102. return 0;
  103. }
  104. static void spear_kbd_close(struct input_dev *dev)
  105. {
  106. struct spear_kbd *kbd = input_get_drvdata(dev);
  107. u16 val;
  108. /* stop key scan */
  109. val = readw(kbd->io_base + MODE_REG);
  110. val &= ~START_SCAN;
  111. writew(val, kbd->io_base + MODE_REG);
  112. clk_disable(kbd->clk);
  113. kbd->last_key = KEY_RESERVED;
  114. }
  115. static int __devinit spear_kbd_probe(struct platform_device *pdev)
  116. {
  117. const struct kbd_platform_data *pdata = pdev->dev.platform_data;
  118. const struct matrix_keymap_data *keymap;
  119. struct spear_kbd *kbd;
  120. struct input_dev *input_dev;
  121. struct resource *res;
  122. int irq;
  123. int error;
  124. if (!pdata) {
  125. dev_err(&pdev->dev, "Invalid platform data\n");
  126. return -EINVAL;
  127. }
  128. keymap = pdata->keymap;
  129. if (!keymap) {
  130. dev_err(&pdev->dev, "no keymap defined\n");
  131. return -EINVAL;
  132. }
  133. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  134. if (!res) {
  135. dev_err(&pdev->dev, "no keyboard resource defined\n");
  136. return -EBUSY;
  137. }
  138. irq = platform_get_irq(pdev, 0);
  139. if (irq < 0) {
  140. dev_err(&pdev->dev, "not able to get irq for the device\n");
  141. return irq;
  142. }
  143. kbd = kzalloc(sizeof(*kbd), GFP_KERNEL);
  144. input_dev = input_allocate_device();
  145. if (!kbd || !input_dev) {
  146. dev_err(&pdev->dev, "out of memory\n");
  147. error = -ENOMEM;
  148. goto err_free_mem;
  149. }
  150. kbd->input = input_dev;
  151. kbd->irq = irq;
  152. kbd->mode = pdata->mode;
  153. kbd->res = request_mem_region(res->start, resource_size(res),
  154. pdev->name);
  155. if (!kbd->res) {
  156. dev_err(&pdev->dev, "keyboard region already claimed\n");
  157. error = -EBUSY;
  158. goto err_free_mem;
  159. }
  160. kbd->io_base = ioremap(res->start, resource_size(res));
  161. if (!kbd->io_base) {
  162. dev_err(&pdev->dev, "ioremap failed for kbd_region\n");
  163. error = -ENOMEM;
  164. goto err_release_mem_region;
  165. }
  166. kbd->clk = clk_get(&pdev->dev, NULL);
  167. if (IS_ERR(kbd->clk)) {
  168. error = PTR_ERR(kbd->clk);
  169. goto err_iounmap;
  170. }
  171. input_dev->name = "Spear Keyboard";
  172. input_dev->phys = "keyboard/input0";
  173. input_dev->dev.parent = &pdev->dev;
  174. input_dev->id.bustype = BUS_HOST;
  175. input_dev->id.vendor = 0x0001;
  176. input_dev->id.product = 0x0001;
  177. input_dev->id.version = 0x0100;
  178. input_dev->open = spear_kbd_open;
  179. input_dev->close = spear_kbd_close;
  180. __set_bit(EV_KEY, input_dev->evbit);
  181. if (pdata->rep)
  182. __set_bit(EV_REP, input_dev->evbit);
  183. input_set_capability(input_dev, EV_MSC, MSC_SCAN);
  184. input_dev->keycode = kbd->keycodes;
  185. input_dev->keycodesize = sizeof(kbd->keycodes[0]);
  186. input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes);
  187. matrix_keypad_build_keymap(keymap, ROW_SHIFT,
  188. input_dev->keycode, input_dev->keybit);
  189. input_set_drvdata(input_dev, kbd);
  190. error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd);
  191. if (error) {
  192. dev_err(&pdev->dev, "request_irq fail\n");
  193. goto err_put_clk;
  194. }
  195. error = input_register_device(input_dev);
  196. if (error) {
  197. dev_err(&pdev->dev, "Unable to register keyboard device\n");
  198. goto err_free_irq;
  199. }
  200. device_init_wakeup(&pdev->dev, 1);
  201. platform_set_drvdata(pdev, kbd);
  202. return 0;
  203. err_free_irq:
  204. free_irq(kbd->irq, kbd);
  205. err_put_clk:
  206. clk_put(kbd->clk);
  207. err_iounmap:
  208. iounmap(kbd->io_base);
  209. err_release_mem_region:
  210. release_mem_region(res->start, resource_size(res));
  211. err_free_mem:
  212. input_free_device(input_dev);
  213. kfree(kbd);
  214. return error;
  215. }
  216. static int __devexit spear_kbd_remove(struct platform_device *pdev)
  217. {
  218. struct spear_kbd *kbd = platform_get_drvdata(pdev);
  219. free_irq(kbd->irq, kbd);
  220. input_unregister_device(kbd->input);
  221. clk_put(kbd->clk);
  222. iounmap(kbd->io_base);
  223. release_mem_region(kbd->res->start, resource_size(kbd->res));
  224. kfree(kbd);
  225. device_init_wakeup(&pdev->dev, 1);
  226. platform_set_drvdata(pdev, NULL);
  227. return 0;
  228. }
  229. #ifdef CONFIG_PM
  230. static int spear_kbd_suspend(struct device *dev)
  231. {
  232. struct platform_device *pdev = to_platform_device(dev);
  233. struct spear_kbd *kbd = platform_get_drvdata(pdev);
  234. struct input_dev *input_dev = kbd->input;
  235. mutex_lock(&input_dev->mutex);
  236. if (input_dev->users)
  237. clk_enable(kbd->clk);
  238. if (device_may_wakeup(&pdev->dev))
  239. enable_irq_wake(kbd->irq);
  240. mutex_unlock(&input_dev->mutex);
  241. return 0;
  242. }
  243. static int spear_kbd_resume(struct device *dev)
  244. {
  245. struct platform_device *pdev = to_platform_device(dev);
  246. struct spear_kbd *kbd = platform_get_drvdata(pdev);
  247. struct input_dev *input_dev = kbd->input;
  248. mutex_lock(&input_dev->mutex);
  249. if (device_may_wakeup(&pdev->dev))
  250. disable_irq_wake(kbd->irq);
  251. if (input_dev->users)
  252. clk_enable(kbd->clk);
  253. mutex_unlock(&input_dev->mutex);
  254. return 0;
  255. }
  256. #endif
  257. static SIMPLE_DEV_PM_OPS(spear_kbd_pm_ops, spear_kbd_suspend, spear_kbd_resume);
  258. static struct platform_driver spear_kbd_driver = {
  259. .probe = spear_kbd_probe,
  260. .remove = __devexit_p(spear_kbd_remove),
  261. .driver = {
  262. .name = "keyboard",
  263. .owner = THIS_MODULE,
  264. .pm = &spear_kbd_pm_ops,
  265. },
  266. };
  267. module_platform_driver(spear_kbd_driver);
  268. MODULE_AUTHOR("Rajeev Kumar");
  269. MODULE_DESCRIPTION("SPEAr Keyboard Driver");
  270. MODULE_LICENSE("GPL");