olpc_apsp.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * OLPC serio driver for multiplexed input from Marvell MMP security processor
  4. *
  5. * Copyright (C) 2011-2013 One Laptop Per Child
  6. */
  7. #include <linux/module.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/serio.h>
  10. #include <linux/err.h>
  11. #include <linux/platform_device.h>
  12. #include <linux/io.h>
  13. #include <linux/of.h>
  14. #include <linux/slab.h>
  15. #include <linux/delay.h>
  16. /*
  17. * The OLPC XO-1.75 and XO-4 laptops do not have a hardware PS/2 controller.
  18. * Instead, the OLPC firmware runs a bit-banging PS/2 implementation on an
  19. * otherwise-unused slow processor which is included in the Marvell MMP2/MMP3
  20. * SoC, known as the "Security Processor" (SP) or "Wireless Trusted Module"
  21. * (WTM). This firmware then reports its results via the WTM registers,
  22. * which we read from the Application Processor (AP, i.e. main CPU) in this
  23. * driver.
  24. *
  25. * On the hardware side we have a PS/2 mouse and an AT keyboard, the data
  26. * is multiplexed through this system. We create a serio port for each one,
  27. * and demultiplex the data accordingly.
  28. */
  29. /* WTM register offsets */
  30. #define SECURE_PROCESSOR_COMMAND 0x40
  31. #define COMMAND_RETURN_STATUS 0x80
  32. #define COMMAND_FIFO_STATUS 0xc4
  33. #define PJ_RST_INTERRUPT 0xc8
  34. #define PJ_INTERRUPT_MASK 0xcc
  35. /*
  36. * The upper byte of SECURE_PROCESSOR_COMMAND and COMMAND_RETURN_STATUS is
  37. * used to identify which port (device) is being talked to. The lower byte
  38. * is the data being sent/received.
  39. */
  40. #define PORT_MASK 0xff00
  41. #define DATA_MASK 0x00ff
  42. #define PORT_SHIFT 8
  43. #define KEYBOARD_PORT 0
  44. #define TOUCHPAD_PORT 1
  45. /* COMMAND_FIFO_STATUS */
  46. #define CMD_CNTR_MASK 0x7 /* Number of pending/unprocessed commands */
  47. #define MAX_PENDING_CMDS 4 /* from device specs */
  48. /* PJ_RST_INTERRUPT */
  49. #define SP_COMMAND_COMPLETE_RESET 0x1
  50. /* PJ_INTERRUPT_MASK */
  51. #define INT_0 (1 << 0)
  52. /* COMMAND_FIFO_STATUS */
  53. #define CMD_STS_MASK 0x100
  54. struct olpc_apsp {
  55. struct device *dev;
  56. struct serio *kbio;
  57. struct serio *padio;
  58. void __iomem *base;
  59. int open_count;
  60. int irq;
  61. };
  62. static int olpc_apsp_write(struct serio *port, unsigned char val)
  63. {
  64. struct olpc_apsp *priv = port->port_data;
  65. unsigned int i;
  66. u32 which = 0;
  67. if (port == priv->padio)
  68. which = TOUCHPAD_PORT << PORT_SHIFT;
  69. else
  70. which = KEYBOARD_PORT << PORT_SHIFT;
  71. dev_dbg(priv->dev, "olpc_apsp_write which=%x val=%x\n", which, val);
  72. for (i = 0; i < 50; i++) {
  73. u32 sts = readl(priv->base + COMMAND_FIFO_STATUS);
  74. if ((sts & CMD_CNTR_MASK) < MAX_PENDING_CMDS) {
  75. writel(which | val,
  76. priv->base + SECURE_PROCESSOR_COMMAND);
  77. return 0;
  78. }
  79. /* SP busy. This has not been seen in practice. */
  80. mdelay(1);
  81. }
  82. dev_dbg(priv->dev, "olpc_apsp_write timeout, status=%x\n",
  83. readl(priv->base + COMMAND_FIFO_STATUS));
  84. return -ETIMEDOUT;
  85. }
  86. static irqreturn_t olpc_apsp_rx(int irq, void *dev_id)
  87. {
  88. struct olpc_apsp *priv = dev_id;
  89. unsigned int w, tmp;
  90. struct serio *serio;
  91. /*
  92. * Write 1 to PJ_RST_INTERRUPT to acknowledge and clear the interrupt
  93. * Write 0xff00 to SECURE_PROCESSOR_COMMAND.
  94. */
  95. tmp = readl(priv->base + PJ_RST_INTERRUPT);
  96. if (!(tmp & SP_COMMAND_COMPLETE_RESET)) {
  97. dev_warn(priv->dev, "spurious interrupt?\n");
  98. return IRQ_NONE;
  99. }
  100. w = readl(priv->base + COMMAND_RETURN_STATUS);
  101. dev_dbg(priv->dev, "olpc_apsp_rx %x\n", w);
  102. if (w >> PORT_SHIFT == KEYBOARD_PORT)
  103. serio = priv->kbio;
  104. else
  105. serio = priv->padio;
  106. serio_interrupt(serio, w & DATA_MASK, 0);
  107. /* Ack and clear interrupt */
  108. writel(tmp | SP_COMMAND_COMPLETE_RESET, priv->base + PJ_RST_INTERRUPT);
  109. writel(PORT_MASK, priv->base + SECURE_PROCESSOR_COMMAND);
  110. pm_wakeup_event(priv->dev, 1000);
  111. return IRQ_HANDLED;
  112. }
  113. static int olpc_apsp_open(struct serio *port)
  114. {
  115. struct olpc_apsp *priv = port->port_data;
  116. unsigned int tmp;
  117. unsigned long l;
  118. if (priv->open_count++ == 0) {
  119. l = readl(priv->base + COMMAND_FIFO_STATUS);
  120. if (!(l & CMD_STS_MASK)) {
  121. dev_err(priv->dev, "SP cannot accept commands.\n");
  122. return -EIO;
  123. }
  124. /* Enable interrupt 0 by clearing its bit */
  125. tmp = readl(priv->base + PJ_INTERRUPT_MASK);
  126. writel(tmp & ~INT_0, priv->base + PJ_INTERRUPT_MASK);
  127. }
  128. return 0;
  129. }
  130. static void olpc_apsp_close(struct serio *port)
  131. {
  132. struct olpc_apsp *priv = port->port_data;
  133. unsigned int tmp;
  134. if (--priv->open_count == 0) {
  135. /* Disable interrupt 0 */
  136. tmp = readl(priv->base + PJ_INTERRUPT_MASK);
  137. writel(tmp | INT_0, priv->base + PJ_INTERRUPT_MASK);
  138. }
  139. }
  140. static int olpc_apsp_probe(struct platform_device *pdev)
  141. {
  142. struct serio *kb_serio, *pad_serio;
  143. struct olpc_apsp *priv;
  144. struct resource *res;
  145. int error;
  146. priv = devm_kzalloc(&pdev->dev, sizeof(struct olpc_apsp), GFP_KERNEL);
  147. if (!priv)
  148. return -ENOMEM;
  149. priv->dev = &pdev->dev;
  150. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  151. priv->base = devm_ioremap_resource(&pdev->dev, res);
  152. if (IS_ERR(priv->base)) {
  153. dev_err(&pdev->dev, "Failed to map WTM registers\n");
  154. return PTR_ERR(priv->base);
  155. }
  156. priv->irq = platform_get_irq(pdev, 0);
  157. if (priv->irq < 0)
  158. return priv->irq;
  159. /* KEYBOARD */
  160. kb_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
  161. if (!kb_serio)
  162. return -ENOMEM;
  163. kb_serio->id.type = SERIO_8042_XL;
  164. kb_serio->write = olpc_apsp_write;
  165. kb_serio->open = olpc_apsp_open;
  166. kb_serio->close = olpc_apsp_close;
  167. kb_serio->port_data = priv;
  168. kb_serio->dev.parent = &pdev->dev;
  169. strlcpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name));
  170. strlcpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys));
  171. priv->kbio = kb_serio;
  172. serio_register_port(kb_serio);
  173. /* TOUCHPAD */
  174. pad_serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
  175. if (!pad_serio) {
  176. error = -ENOMEM;
  177. goto err_pad;
  178. }
  179. pad_serio->id.type = SERIO_8042;
  180. pad_serio->write = olpc_apsp_write;
  181. pad_serio->open = olpc_apsp_open;
  182. pad_serio->close = olpc_apsp_close;
  183. pad_serio->port_data = priv;
  184. pad_serio->dev.parent = &pdev->dev;
  185. strlcpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name));
  186. strlcpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys));
  187. priv->padio = pad_serio;
  188. serio_register_port(pad_serio);
  189. error = request_irq(priv->irq, olpc_apsp_rx, 0, "olpc-apsp", priv);
  190. if (error) {
  191. dev_err(&pdev->dev, "Failed to request IRQ\n");
  192. goto err_irq;
  193. }
  194. device_init_wakeup(priv->dev, 1);
  195. platform_set_drvdata(pdev, priv);
  196. dev_dbg(&pdev->dev, "probed successfully.\n");
  197. return 0;
  198. err_irq:
  199. serio_unregister_port(pad_serio);
  200. err_pad:
  201. serio_unregister_port(kb_serio);
  202. return error;
  203. }
  204. static int olpc_apsp_remove(struct platform_device *pdev)
  205. {
  206. struct olpc_apsp *priv = platform_get_drvdata(pdev);
  207. free_irq(priv->irq, priv);
  208. serio_unregister_port(priv->kbio);
  209. serio_unregister_port(priv->padio);
  210. return 0;
  211. }
  212. static const struct of_device_id olpc_apsp_dt_ids[] = {
  213. { .compatible = "olpc,ap-sp", },
  214. {}
  215. };
  216. MODULE_DEVICE_TABLE(of, olpc_apsp_dt_ids);
  217. static struct platform_driver olpc_apsp_driver = {
  218. .probe = olpc_apsp_probe,
  219. .remove = olpc_apsp_remove,
  220. .driver = {
  221. .name = "olpc-apsp",
  222. .of_match_table = olpc_apsp_dt_ids,
  223. },
  224. };
  225. MODULE_DESCRIPTION("OLPC AP-SP serio driver");
  226. MODULE_LICENSE("GPL");
  227. module_platform_driver(olpc_apsp_driver);