1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
5 * Driver is originally developed by Pavel Sokolov <psokolov@synopsys.com>
9 #include <linux/module.h>
10 #include <linux/interrupt.h>
11 #include <linux/input.h>
12 #include <linux/serio.h>
13 #include <linux/platform_device.h>
16 #include <linux/kernel.h>
17 #include <linux/slab.h>
19 #define ARC_PS2_PORTS 2
21 #define ARC_ARC_PS2_ID 0x0001f609
23 #define STAT_TIMEOUT 128
25 #define PS2_STAT_RX_FRM_ERR (1)
26 #define PS2_STAT_RX_BUF_OVER (1 << 1)
27 #define PS2_STAT_RX_INT_EN (1 << 2)
28 #define PS2_STAT_RX_VAL (1 << 3)
29 #define PS2_STAT_TX_ISNOT_FUL (1 << 4)
30 #define PS2_STAT_TX_INT_EN (1 << 5)
33 void __iomem
*data_addr
;
34 void __iomem
*status_addr
;
39 struct arc_ps2_port port
[ARC_PS2_PORTS
];
41 unsigned int frame_error
;
42 unsigned int buf_overflow
;
43 unsigned int total_int
;
46 static void arc_ps2_check_rx(struct arc_ps2_data
*arc_ps2
,
47 struct arc_ps2_port
*port
)
49 unsigned int timeout
= 1000;
50 unsigned int flag
, status
;
54 status
= ioread32(port
->status_addr
);
55 if (!(status
& PS2_STAT_RX_VAL
))
58 data
= ioread32(port
->data_addr
) & 0xff;
62 if (status
& PS2_STAT_RX_FRM_ERR
) {
63 arc_ps2
->frame_error
++;
65 } else if (status
& PS2_STAT_RX_BUF_OVER
) {
66 arc_ps2
->buf_overflow
++;
70 serio_interrupt(port
->io
, data
, flag
);
73 dev_err(&port
->io
->dev
, "PS/2 hardware stuck\n");
76 static irqreturn_t
arc_ps2_interrupt(int irq
, void *dev
)
78 struct arc_ps2_data
*arc_ps2
= dev
;
81 for (i
= 0; i
< ARC_PS2_PORTS
; i
++)
82 arc_ps2_check_rx(arc_ps2
, &arc_ps2
->port
[i
]);
87 static int arc_ps2_write(struct serio
*io
, unsigned char val
)
90 struct arc_ps2_port
*port
= io
->port_data
;
91 int timeout
= STAT_TIMEOUT
;
94 status
= ioread32(port
->status_addr
);
97 if (status
& PS2_STAT_TX_ISNOT_FUL
) {
98 iowrite32(val
& 0xff, port
->data_addr
);
104 dev_err(&io
->dev
, "write timeout\n");
108 static int arc_ps2_open(struct serio
*io
)
110 struct arc_ps2_port
*port
= io
->port_data
;
112 iowrite32(PS2_STAT_RX_INT_EN
, port
->status_addr
);
117 static void arc_ps2_close(struct serio
*io
)
119 struct arc_ps2_port
*port
= io
->port_data
;
121 iowrite32(ioread32(port
->status_addr
) & ~PS2_STAT_RX_INT_EN
,
125 static void __iomem
*arc_ps2_calc_addr(struct arc_ps2_data
*arc_ps2
,
126 int index
, bool status
)
130 addr
= arc_ps2
->addr
+ 4 + 4 * index
;
132 addr
+= ARC_PS2_PORTS
* 4;
137 static void arc_ps2_inhibit_ports(struct arc_ps2_data
*arc_ps2
)
143 for (i
= 0; i
< ARC_PS2_PORTS
; i
++) {
144 addr
= arc_ps2_calc_addr(arc_ps2
, i
, true);
145 val
= ioread32(addr
);
146 val
&= ~(PS2_STAT_RX_INT_EN
| PS2_STAT_TX_INT_EN
);
147 iowrite32(val
, addr
);
151 static int arc_ps2_create_port(struct platform_device
*pdev
,
152 struct arc_ps2_data
*arc_ps2
,
155 struct arc_ps2_port
*port
= &arc_ps2
->port
[index
];
158 io
= kzalloc(sizeof(struct serio
), GFP_KERNEL
);
162 io
->id
.type
= SERIO_8042
;
163 io
->write
= arc_ps2_write
;
164 io
->open
= arc_ps2_open
;
165 io
->close
= arc_ps2_close
;
166 snprintf(io
->name
, sizeof(io
->name
), "ARC PS/2 port%d", index
);
167 snprintf(io
->phys
, sizeof(io
->phys
), "arc/serio%d", index
);
168 io
->port_data
= port
;
172 port
->data_addr
= arc_ps2_calc_addr(arc_ps2
, index
, false);
173 port
->status_addr
= arc_ps2_calc_addr(arc_ps2
, index
, true);
175 dev_dbg(&pdev
->dev
, "port%d is allocated (data = 0x%p, status = 0x%p)\n",
176 index
, port
->data_addr
, port
->status_addr
);
178 serio_register_port(port
->io
);
182 static int arc_ps2_probe(struct platform_device
*pdev
)
184 struct arc_ps2_data
*arc_ps2
;
185 struct resource
*res
;
189 irq
= platform_get_irq_byname(pdev
, "arc_ps2_irq");
193 arc_ps2
= devm_kzalloc(&pdev
->dev
, sizeof(struct arc_ps2_data
),
196 dev_err(&pdev
->dev
, "out of memory\n");
200 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
201 arc_ps2
->addr
= devm_ioremap_resource(&pdev
->dev
, res
);
202 if (IS_ERR(arc_ps2
->addr
))
203 return PTR_ERR(arc_ps2
->addr
);
205 dev_info(&pdev
->dev
, "irq = %d, address = 0x%p, ports = %i\n",
206 irq
, arc_ps2
->addr
, ARC_PS2_PORTS
);
208 id
= ioread32(arc_ps2
->addr
);
209 if (id
!= ARC_ARC_PS2_ID
) {
210 dev_err(&pdev
->dev
, "device id does not match\n");
214 arc_ps2_inhibit_ports(arc_ps2
);
216 error
= devm_request_irq(&pdev
->dev
, irq
, arc_ps2_interrupt
,
217 0, "arc_ps2", arc_ps2
);
219 dev_err(&pdev
->dev
, "Could not allocate IRQ\n");
223 for (i
= 0; i
< ARC_PS2_PORTS
; i
++) {
224 error
= arc_ps2_create_port(pdev
, arc_ps2
, i
);
227 serio_unregister_port(arc_ps2
->port
[i
].io
);
232 platform_set_drvdata(pdev
, arc_ps2
);
237 static int arc_ps2_remove(struct platform_device
*pdev
)
239 struct arc_ps2_data
*arc_ps2
= platform_get_drvdata(pdev
);
242 for (i
= 0; i
< ARC_PS2_PORTS
; i
++)
243 serio_unregister_port(arc_ps2
->port
[i
].io
);
245 dev_dbg(&pdev
->dev
, "interrupt count = %i\n", arc_ps2
->total_int
);
246 dev_dbg(&pdev
->dev
, "frame error count = %i\n", arc_ps2
->frame_error
);
247 dev_dbg(&pdev
->dev
, "buffer overflow count = %i\n",
248 arc_ps2
->buf_overflow
);
254 static const struct of_device_id arc_ps2_match
[] = {
255 { .compatible
= "snps,arc_ps2" },
258 MODULE_DEVICE_TABLE(of
, arc_ps2_match
);
261 static struct platform_driver arc_ps2_driver
= {
264 .of_match_table
= of_match_ptr(arc_ps2_match
),
266 .probe
= arc_ps2_probe
,
267 .remove
= arc_ps2_remove
,
270 module_platform_driver(arc_ps2_driver
);
272 MODULE_LICENSE("GPL");
273 MODULE_AUTHOR("Pavel Sokolov <psokolov@synopsys.com>");
274 MODULE_DESCRIPTION("ARC PS/2 Driver");