2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
8 * Driver is originally developed by Pavel Sokolov <psokolov@synopsys.com>
11 #include <linux/err.h>
12 #include <linux/module.h>
13 #include <linux/interrupt.h>
14 #include <linux/input.h>
15 #include <linux/serio.h>
16 #include <linux/platform_device.h>
19 #include <linux/kernel.h>
20 #include <linux/slab.h>
22 #define ARC_PS2_PORTS 2
24 #define ARC_ARC_PS2_ID 0x0001f609
26 #define STAT_TIMEOUT 128
28 #define PS2_STAT_RX_FRM_ERR (1)
29 #define PS2_STAT_RX_BUF_OVER (1 << 1)
30 #define PS2_STAT_RX_INT_EN (1 << 2)
31 #define PS2_STAT_RX_VAL (1 << 3)
32 #define PS2_STAT_TX_ISNOT_FUL (1 << 4)
33 #define PS2_STAT_TX_INT_EN (1 << 5)
36 void __iomem
*data_addr
;
37 void __iomem
*status_addr
;
42 struct arc_ps2_port port
[ARC_PS2_PORTS
];
44 unsigned int frame_error
;
45 unsigned int buf_overflow
;
46 unsigned int total_int
;
49 static void arc_ps2_check_rx(struct arc_ps2_data
*arc_ps2
,
50 struct arc_ps2_port
*port
)
52 unsigned int timeout
= 1000;
53 unsigned int flag
, status
;
57 status
= ioread32(port
->status_addr
);
58 if (!(status
& PS2_STAT_RX_VAL
))
61 data
= ioread32(port
->data_addr
) & 0xff;
65 if (status
& PS2_STAT_RX_FRM_ERR
) {
66 arc_ps2
->frame_error
++;
68 } else if (status
& PS2_STAT_RX_BUF_OVER
) {
69 arc_ps2
->buf_overflow
++;
73 serio_interrupt(port
->io
, data
, flag
);
76 dev_err(&port
->io
->dev
, "PS/2 hardware stuck\n");
79 static irqreturn_t
arc_ps2_interrupt(int irq
, void *dev
)
81 struct arc_ps2_data
*arc_ps2
= dev
;
84 for (i
= 0; i
< ARC_PS2_PORTS
; i
++)
85 arc_ps2_check_rx(arc_ps2
, &arc_ps2
->port
[i
]);
90 static int arc_ps2_write(struct serio
*io
, unsigned char val
)
93 struct arc_ps2_port
*port
= io
->port_data
;
94 int timeout
= STAT_TIMEOUT
;
97 status
= ioread32(port
->status_addr
);
100 if (status
& PS2_STAT_TX_ISNOT_FUL
) {
101 iowrite32(val
& 0xff, port
->data_addr
);
107 dev_err(&io
->dev
, "write timeout\n");
111 static int arc_ps2_open(struct serio
*io
)
113 struct arc_ps2_port
*port
= io
->port_data
;
115 iowrite32(PS2_STAT_RX_INT_EN
, port
->status_addr
);
120 static void arc_ps2_close(struct serio
*io
)
122 struct arc_ps2_port
*port
= io
->port_data
;
124 iowrite32(ioread32(port
->status_addr
) & ~PS2_STAT_RX_INT_EN
,
128 static void __iomem
*arc_ps2_calc_addr(struct arc_ps2_data
*arc_ps2
,
129 int index
, bool status
)
133 addr
= arc_ps2
->addr
+ 4 + 4 * index
;
135 addr
+= ARC_PS2_PORTS
* 4;
140 static void arc_ps2_inhibit_ports(struct arc_ps2_data
*arc_ps2
)
146 for (i
= 0; i
< ARC_PS2_PORTS
; i
++) {
147 addr
= arc_ps2_calc_addr(arc_ps2
, i
, true);
148 val
= ioread32(addr
);
149 val
&= ~(PS2_STAT_RX_INT_EN
| PS2_STAT_TX_INT_EN
);
150 iowrite32(val
, addr
);
154 static int arc_ps2_create_port(struct platform_device
*pdev
,
155 struct arc_ps2_data
*arc_ps2
,
158 struct arc_ps2_port
*port
= &arc_ps2
->port
[index
];
161 io
= kzalloc(sizeof(struct serio
), GFP_KERNEL
);
165 io
->id
.type
= SERIO_8042
;
166 io
->write
= arc_ps2_write
;
167 io
->open
= arc_ps2_open
;
168 io
->close
= arc_ps2_close
;
169 snprintf(io
->name
, sizeof(io
->name
), "ARC PS/2 port%d", index
);
170 snprintf(io
->phys
, sizeof(io
->phys
), "arc/serio%d", index
);
171 io
->port_data
= port
;
175 port
->data_addr
= arc_ps2_calc_addr(arc_ps2
, index
, false);
176 port
->status_addr
= arc_ps2_calc_addr(arc_ps2
, index
, true);
178 dev_dbg(&pdev
->dev
, "port%d is allocated (data = 0x%p, status = 0x%p)\n",
179 index
, port
->data_addr
, port
->status_addr
);
181 serio_register_port(port
->io
);
185 static int arc_ps2_probe(struct platform_device
*pdev
)
187 struct arc_ps2_data
*arc_ps2
;
188 struct resource
*res
;
192 irq
= platform_get_irq_byname(pdev
, "arc_ps2_irq");
194 dev_err(&pdev
->dev
, "no IRQ defined\n");
198 arc_ps2
= devm_kzalloc(&pdev
->dev
, sizeof(struct arc_ps2_data
),
201 dev_err(&pdev
->dev
, "out of memory\n");
205 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
206 arc_ps2
->addr
= devm_ioremap_resource(&pdev
->dev
, res
);
207 if (IS_ERR(arc_ps2
->addr
))
208 return PTR_ERR(arc_ps2
->addr
);
210 dev_info(&pdev
->dev
, "irq = %d, address = 0x%p, ports = %i\n",
211 irq
, arc_ps2
->addr
, ARC_PS2_PORTS
);
213 id
= ioread32(arc_ps2
->addr
);
214 if (id
!= ARC_ARC_PS2_ID
) {
215 dev_err(&pdev
->dev
, "device id does not match\n");
219 arc_ps2_inhibit_ports(arc_ps2
);
221 error
= devm_request_irq(&pdev
->dev
, irq
, arc_ps2_interrupt
,
222 0, "arc_ps2", arc_ps2
);
224 dev_err(&pdev
->dev
, "Could not allocate IRQ\n");
228 for (i
= 0; i
< ARC_PS2_PORTS
; i
++) {
229 error
= arc_ps2_create_port(pdev
, arc_ps2
, i
);
232 serio_unregister_port(arc_ps2
->port
[i
].io
);
237 platform_set_drvdata(pdev
, arc_ps2
);
242 static int arc_ps2_remove(struct platform_device
*pdev
)
244 struct arc_ps2_data
*arc_ps2
= platform_get_drvdata(pdev
);
247 for (i
= 0; i
< ARC_PS2_PORTS
; i
++)
248 serio_unregister_port(arc_ps2
->port
[i
].io
);
250 dev_dbg(&pdev
->dev
, "interrupt count = %i\n", arc_ps2
->total_int
);
251 dev_dbg(&pdev
->dev
, "frame error count = %i\n", arc_ps2
->frame_error
);
252 dev_dbg(&pdev
->dev
, "buffer overflow count = %i\n",
253 arc_ps2
->buf_overflow
);
259 static const struct of_device_id arc_ps2_match
[] = {
260 { .compatible
= "snps,arc_ps2" },
263 MODULE_DEVICE_TABLE(of
, arc_ps2_match
);
266 static struct platform_driver arc_ps2_driver
= {
269 .of_match_table
= of_match_ptr(arc_ps2_match
),
271 .probe
= arc_ps2_probe
,
272 .remove
= arc_ps2_remove
,
275 module_platform_driver(arc_ps2_driver
);
277 MODULE_LICENSE("GPL");
278 MODULE_AUTHOR("Pavel Sokolov <psokolov@synopsys.com>");
279 MODULE_DESCRIPTION("ARC PS/2 Driver");