lpc32xx-keys.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * NXP LPC32xx SoC Key Scan Interface
  4. *
  5. * Authors:
  6. * Kevin Wells <kevin.wells@nxp.com>
  7. * Roland Stigge <stigge@antcom.de>
  8. *
  9. * Copyright (C) 2010 NXP Semiconductors
  10. * Copyright (C) 2012 Roland Stigge
  11. *
  12. * This controller supports square key matrices from 1x1 up to 8x8
  13. */
  14. #include <linux/module.h>
  15. #include <linux/interrupt.h>
  16. #include <linux/slab.h>
  17. #include <linux/irq.h>
  18. #include <linux/pm.h>
  19. #include <linux/platform_device.h>
  20. #include <linux/input.h>
  21. #include <linux/clk.h>
  22. #include <linux/io.h>
  23. #include <linux/of.h>
  24. #include <linux/input/matrix_keypad.h>
  25. #define DRV_NAME "lpc32xx_keys"
  26. /*
  27. * Key scanner register offsets
  28. */
  29. #define LPC32XX_KS_DEB(x) ((x) + 0x00)
  30. #define LPC32XX_KS_STATE_COND(x) ((x) + 0x04)
  31. #define LPC32XX_KS_IRQ(x) ((x) + 0x08)
  32. #define LPC32XX_KS_SCAN_CTL(x) ((x) + 0x0C)
  33. #define LPC32XX_KS_FAST_TST(x) ((x) + 0x10)
  34. #define LPC32XX_KS_MATRIX_DIM(x) ((x) + 0x14) /* 1..8 */
  35. #define LPC32XX_KS_DATA(x, y) ((x) + 0x40 + ((y) << 2))
  36. #define LPC32XX_KSCAN_DEB_NUM_DEB_PASS(n) ((n) & 0xFF)
  37. #define LPC32XX_KSCAN_SCOND_IN_IDLE 0x0
  38. #define LPC32XX_KSCAN_SCOND_IN_SCANONCE 0x1
  39. #define LPC32XX_KSCAN_SCOND_IN_IRQGEN 0x2
  40. #define LPC32XX_KSCAN_SCOND_IN_SCAN_MATRIX 0x3
  41. #define LPC32XX_KSCAN_IRQ_PENDING_CLR 0x1
  42. #define LPC32XX_KSCAN_SCTRL_SCAN_DELAY(n) ((n) & 0xFF)
  43. #define LPC32XX_KSCAN_FTST_FORCESCANONCE 0x1
  44. #define LPC32XX_KSCAN_FTST_USE32K_CLK 0x2
  45. #define LPC32XX_KSCAN_MSEL_SELECT(n) ((n) & 0xF)
  46. struct lpc32xx_kscan_drv {
  47. struct input_dev *input;
  48. struct clk *clk;
  49. void __iomem *kscan_base;
  50. unsigned int irq;
  51. u32 matrix_sz; /* Size of matrix in XxY, ie. 3 = 3x3 */
  52. u32 deb_clks; /* Debounce clocks (based on 32KHz clock) */
  53. u32 scan_delay; /* Scan delay (based on 32KHz clock) */
  54. unsigned short *keymap; /* Pointer to key map for the scan matrix */
  55. unsigned int row_shift;
  56. u8 lastkeystates[8];
  57. };
  58. static void lpc32xx_mod_states(struct lpc32xx_kscan_drv *kscandat, int col)
  59. {
  60. struct input_dev *input = kscandat->input;
  61. unsigned row, changed, scancode, keycode;
  62. u8 key;
  63. key = readl(LPC32XX_KS_DATA(kscandat->kscan_base, col));
  64. changed = key ^ kscandat->lastkeystates[col];
  65. kscandat->lastkeystates[col] = key;
  66. for (row = 0; changed; row++, changed >>= 1) {
  67. if (changed & 1) {
  68. /* Key state changed, signal an event */
  69. scancode = MATRIX_SCAN_CODE(row, col,
  70. kscandat->row_shift);
  71. keycode = kscandat->keymap[scancode];
  72. input_event(input, EV_MSC, MSC_SCAN, scancode);
  73. input_report_key(input, keycode, key & (1 << row));
  74. }
  75. }
  76. }
  77. static irqreturn_t lpc32xx_kscan_irq(int irq, void *dev_id)
  78. {
  79. struct lpc32xx_kscan_drv *kscandat = dev_id;
  80. int i;
  81. for (i = 0; i < kscandat->matrix_sz; i++)
  82. lpc32xx_mod_states(kscandat, i);
  83. writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
  84. input_sync(kscandat->input);
  85. return IRQ_HANDLED;
  86. }
  87. static int lpc32xx_kscan_open(struct input_dev *dev)
  88. {
  89. struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev);
  90. int error;
  91. error = clk_prepare_enable(kscandat->clk);
  92. if (error)
  93. return error;
  94. writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
  95. return 0;
  96. }
  97. static void lpc32xx_kscan_close(struct input_dev *dev)
  98. {
  99. struct lpc32xx_kscan_drv *kscandat = input_get_drvdata(dev);
  100. writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
  101. clk_disable_unprepare(kscandat->clk);
  102. }
  103. static int lpc32xx_parse_dt(struct device *dev,
  104. struct lpc32xx_kscan_drv *kscandat)
  105. {
  106. struct device_node *np = dev->of_node;
  107. u32 rows = 0, columns = 0;
  108. int err;
  109. err = matrix_keypad_parse_properties(dev, &rows, &columns);
  110. if (err)
  111. return err;
  112. if (rows != columns) {
  113. dev_err(dev, "rows and columns must be equal!\n");
  114. return -EINVAL;
  115. }
  116. kscandat->matrix_sz = rows;
  117. kscandat->row_shift = get_count_order(columns);
  118. of_property_read_u32(np, "nxp,debounce-delay-ms", &kscandat->deb_clks);
  119. of_property_read_u32(np, "nxp,scan-delay-ms", &kscandat->scan_delay);
  120. if (!kscandat->deb_clks || !kscandat->scan_delay) {
  121. dev_err(dev, "debounce or scan delay not specified\n");
  122. return -EINVAL;
  123. }
  124. return 0;
  125. }
  126. static int lpc32xx_kscan_probe(struct platform_device *pdev)
  127. {
  128. struct lpc32xx_kscan_drv *kscandat;
  129. struct input_dev *input;
  130. struct resource *res;
  131. size_t keymap_size;
  132. int error;
  133. int irq;
  134. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  135. if (!res) {
  136. dev_err(&pdev->dev, "failed to get platform I/O memory\n");
  137. return -EINVAL;
  138. }
  139. irq = platform_get_irq(pdev, 0);
  140. if (irq < 0)
  141. return -EINVAL;
  142. kscandat = devm_kzalloc(&pdev->dev, sizeof(*kscandat),
  143. GFP_KERNEL);
  144. if (!kscandat)
  145. return -ENOMEM;
  146. error = lpc32xx_parse_dt(&pdev->dev, kscandat);
  147. if (error) {
  148. dev_err(&pdev->dev, "failed to parse device tree\n");
  149. return error;
  150. }
  151. keymap_size = sizeof(kscandat->keymap[0]) *
  152. (kscandat->matrix_sz << kscandat->row_shift);
  153. kscandat->keymap = devm_kzalloc(&pdev->dev, keymap_size, GFP_KERNEL);
  154. if (!kscandat->keymap)
  155. return -ENOMEM;
  156. kscandat->input = input = devm_input_allocate_device(&pdev->dev);
  157. if (!input) {
  158. dev_err(&pdev->dev, "failed to allocate input device\n");
  159. return -ENOMEM;
  160. }
  161. /* Setup key input */
  162. input->name = pdev->name;
  163. input->phys = "lpc32xx/input0";
  164. input->id.vendor = 0x0001;
  165. input->id.product = 0x0001;
  166. input->id.version = 0x0100;
  167. input->open = lpc32xx_kscan_open;
  168. input->close = lpc32xx_kscan_close;
  169. input->dev.parent = &pdev->dev;
  170. input_set_capability(input, EV_MSC, MSC_SCAN);
  171. error = matrix_keypad_build_keymap(NULL, NULL,
  172. kscandat->matrix_sz,
  173. kscandat->matrix_sz,
  174. kscandat->keymap, kscandat->input);
  175. if (error) {
  176. dev_err(&pdev->dev, "failed to build keymap\n");
  177. return error;
  178. }
  179. input_set_drvdata(kscandat->input, kscandat);
  180. kscandat->kscan_base = devm_ioremap_resource(&pdev->dev, res);
  181. if (IS_ERR(kscandat->kscan_base))
  182. return PTR_ERR(kscandat->kscan_base);
  183. /* Get the key scanner clock */
  184. kscandat->clk = devm_clk_get(&pdev->dev, NULL);
  185. if (IS_ERR(kscandat->clk)) {
  186. dev_err(&pdev->dev, "failed to get clock\n");
  187. return PTR_ERR(kscandat->clk);
  188. }
  189. /* Configure the key scanner */
  190. error = clk_prepare_enable(kscandat->clk);
  191. if (error)
  192. return error;
  193. writel(kscandat->deb_clks, LPC32XX_KS_DEB(kscandat->kscan_base));
  194. writel(kscandat->scan_delay, LPC32XX_KS_SCAN_CTL(kscandat->kscan_base));
  195. writel(LPC32XX_KSCAN_FTST_USE32K_CLK,
  196. LPC32XX_KS_FAST_TST(kscandat->kscan_base));
  197. writel(kscandat->matrix_sz,
  198. LPC32XX_KS_MATRIX_DIM(kscandat->kscan_base));
  199. writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
  200. clk_disable_unprepare(kscandat->clk);
  201. error = devm_request_irq(&pdev->dev, irq, lpc32xx_kscan_irq, 0,
  202. pdev->name, kscandat);
  203. if (error) {
  204. dev_err(&pdev->dev, "failed to request irq\n");
  205. return error;
  206. }
  207. error = input_register_device(kscandat->input);
  208. if (error) {
  209. dev_err(&pdev->dev, "failed to register input device\n");
  210. return error;
  211. }
  212. platform_set_drvdata(pdev, kscandat);
  213. return 0;
  214. }
  215. #ifdef CONFIG_PM_SLEEP
  216. static int lpc32xx_kscan_suspend(struct device *dev)
  217. {
  218. struct platform_device *pdev = to_platform_device(dev);
  219. struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev);
  220. struct input_dev *input = kscandat->input;
  221. mutex_lock(&input->mutex);
  222. if (input->users) {
  223. /* Clear IRQ and disable clock */
  224. writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
  225. clk_disable_unprepare(kscandat->clk);
  226. }
  227. mutex_unlock(&input->mutex);
  228. return 0;
  229. }
  230. static int lpc32xx_kscan_resume(struct device *dev)
  231. {
  232. struct platform_device *pdev = to_platform_device(dev);
  233. struct lpc32xx_kscan_drv *kscandat = platform_get_drvdata(pdev);
  234. struct input_dev *input = kscandat->input;
  235. int retval = 0;
  236. mutex_lock(&input->mutex);
  237. if (input->users) {
  238. /* Enable clock and clear IRQ */
  239. retval = clk_prepare_enable(kscandat->clk);
  240. if (retval == 0)
  241. writel(1, LPC32XX_KS_IRQ(kscandat->kscan_base));
  242. }
  243. mutex_unlock(&input->mutex);
  244. return retval;
  245. }
  246. #endif
  247. static SIMPLE_DEV_PM_OPS(lpc32xx_kscan_pm_ops, lpc32xx_kscan_suspend,
  248. lpc32xx_kscan_resume);
  249. static const struct of_device_id lpc32xx_kscan_match[] = {
  250. { .compatible = "nxp,lpc3220-key" },
  251. {},
  252. };
  253. MODULE_DEVICE_TABLE(of, lpc32xx_kscan_match);
  254. static struct platform_driver lpc32xx_kscan_driver = {
  255. .probe = lpc32xx_kscan_probe,
  256. .driver = {
  257. .name = DRV_NAME,
  258. .pm = &lpc32xx_kscan_pm_ops,
  259. .of_match_table = lpc32xx_kscan_match,
  260. }
  261. };
  262. module_platform_driver(lpc32xx_kscan_driver);
  263. MODULE_LICENSE("GPL");
  264. MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
  265. MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
  266. MODULE_DESCRIPTION("Key scanner driver for LPC32XX devices");