Lines Matching +full:bit +full:- +full:banging
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (C) 2011-2013 One Laptop Per Child
19 * The OLPC XO-1.75 and XO-4 laptops do not have a hardware PS/2 controller.
20 * Instead, the OLPC firmware runs a bit-banging PS/2 implementation on an
21 * otherwise-unused slow processor which is included in the Marvell MMP2/MMP3
74 struct olpc_apsp *priv = port->port_data; in olpc_apsp_write()
78 if (port == priv->padio) in olpc_apsp_write()
83 dev_dbg(priv->dev, "olpc_apsp_write which=%x val=%x\n", which, val); in olpc_apsp_write()
85 u32 sts = readl(priv->base + COMMAND_FIFO_STATUS); in olpc_apsp_write()
88 priv->base + SECURE_PROCESSOR_COMMAND); in olpc_apsp_write()
95 dev_dbg(priv->dev, "olpc_apsp_write timeout, status=%x\n", in olpc_apsp_write()
96 readl(priv->base + COMMAND_FIFO_STATUS)); in olpc_apsp_write()
98 return -ETIMEDOUT; in olpc_apsp_write()
111 tmp = readl(priv->base + PJ_RST_INTERRUPT); in olpc_apsp_rx()
113 dev_warn(priv->dev, "spurious interrupt?\n"); in olpc_apsp_rx()
117 w = readl(priv->base + COMMAND_RETURN_STATUS); in olpc_apsp_rx()
118 dev_dbg(priv->dev, "olpc_apsp_rx %x\n", w); in olpc_apsp_rx()
121 serio = priv->kbio; in olpc_apsp_rx()
123 serio = priv->padio; in olpc_apsp_rx()
128 writel(tmp | SP_COMMAND_COMPLETE_RESET, priv->base + PJ_RST_INTERRUPT); in olpc_apsp_rx()
129 writel(PORT_MASK, priv->base + SECURE_PROCESSOR_COMMAND); in olpc_apsp_rx()
131 pm_wakeup_event(priv->dev, 1000); in olpc_apsp_rx()
137 struct olpc_apsp *priv = port->port_data; in olpc_apsp_open()
141 if (priv->open_count++ == 0) { in olpc_apsp_open()
142 l = readl(priv->base + COMMAND_FIFO_STATUS); in olpc_apsp_open()
144 dev_err(priv->dev, "SP cannot accept commands.\n"); in olpc_apsp_open()
145 return -EIO; in olpc_apsp_open()
148 /* Enable interrupt 0 by clearing its bit */ in olpc_apsp_open()
149 tmp = readl(priv->base + PJ_INTERRUPT_MASK); in olpc_apsp_open()
150 writel(tmp & ~INT_0, priv->base + PJ_INTERRUPT_MASK); in olpc_apsp_open()
158 struct olpc_apsp *priv = port->port_data; in olpc_apsp_close()
161 if (--priv->open_count == 0) { in olpc_apsp_close()
163 tmp = readl(priv->base + PJ_INTERRUPT_MASK); in olpc_apsp_close()
164 writel(tmp | INT_0, priv->base + PJ_INTERRUPT_MASK); in olpc_apsp_close()
175 priv = devm_kzalloc(&pdev->dev, sizeof(struct olpc_apsp), GFP_KERNEL); in olpc_apsp_probe()
177 return -ENOMEM; in olpc_apsp_probe()
179 priv->dev = &pdev->dev; in olpc_apsp_probe()
182 priv->base = devm_ioremap_resource(&pdev->dev, res); in olpc_apsp_probe()
183 if (IS_ERR(priv->base)) { in olpc_apsp_probe()
184 dev_err(&pdev->dev, "Failed to map WTM registers\n"); in olpc_apsp_probe()
185 return PTR_ERR(priv->base); in olpc_apsp_probe()
188 priv->irq = platform_get_irq(pdev, 0); in olpc_apsp_probe()
189 if (priv->irq < 0) in olpc_apsp_probe()
190 return priv->irq; in olpc_apsp_probe()
195 return -ENOMEM; in olpc_apsp_probe()
196 kb_serio->id.type = SERIO_8042_XL; in olpc_apsp_probe()
197 kb_serio->write = olpc_apsp_write; in olpc_apsp_probe()
198 kb_serio->open = olpc_apsp_open; in olpc_apsp_probe()
199 kb_serio->close = olpc_apsp_close; in olpc_apsp_probe()
200 kb_serio->port_data = priv; in olpc_apsp_probe()
201 kb_serio->dev.parent = &pdev->dev; in olpc_apsp_probe()
202 strlcpy(kb_serio->name, "sp keyboard", sizeof(kb_serio->name)); in olpc_apsp_probe()
203 strlcpy(kb_serio->phys, "sp/serio0", sizeof(kb_serio->phys)); in olpc_apsp_probe()
204 priv->kbio = kb_serio; in olpc_apsp_probe()
210 error = -ENOMEM; in olpc_apsp_probe()
213 pad_serio->id.type = SERIO_8042; in olpc_apsp_probe()
214 pad_serio->write = olpc_apsp_write; in olpc_apsp_probe()
215 pad_serio->open = olpc_apsp_open; in olpc_apsp_probe()
216 pad_serio->close = olpc_apsp_close; in olpc_apsp_probe()
217 pad_serio->port_data = priv; in olpc_apsp_probe()
218 pad_serio->dev.parent = &pdev->dev; in olpc_apsp_probe()
219 strlcpy(pad_serio->name, "sp touchpad", sizeof(pad_serio->name)); in olpc_apsp_probe()
220 strlcpy(pad_serio->phys, "sp/serio1", sizeof(pad_serio->phys)); in olpc_apsp_probe()
221 priv->padio = pad_serio; in olpc_apsp_probe()
224 error = request_irq(priv->irq, olpc_apsp_rx, 0, "olpc-apsp", priv); in olpc_apsp_probe()
226 dev_err(&pdev->dev, "Failed to request IRQ\n"); in olpc_apsp_probe()
230 device_init_wakeup(priv->dev, 1); in olpc_apsp_probe()
233 dev_dbg(&pdev->dev, "probed successfully.\n"); in olpc_apsp_probe()
247 free_irq(priv->irq, priv); in olpc_apsp_remove()
249 serio_unregister_port(priv->kbio); in olpc_apsp_remove()
250 serio_unregister_port(priv->padio); in olpc_apsp_remove()
256 { .compatible = "olpc,ap-sp", },
265 .name = "olpc-apsp",
270 MODULE_DESCRIPTION("OLPC AP-SP serio driver");