Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/input/serio/rpckbd.c
15112 views
1
/*
2
* Copyright (c) 2000-2001 Vojtech Pavlik
3
* Copyright (c) 2002 Russell King
4
*/
5
6
/*
7
* Acorn RiscPC PS/2 keyboard controller driver for Linux/ARM
8
*/
9
10
/*
11
* This program is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
15
*
16
* This program is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
20
*
21
* You should have received a copy of the GNU General Public License
22
* along with this program; if not, write to the Free Software
23
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
*
25
* Should you need to contact me, the author, you can do so either by
26
* e-mail - mail your message to <[email protected]>, or by paper mail:
27
* Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic
28
*/
29
30
#include <linux/module.h>
31
#include <linux/interrupt.h>
32
#include <linux/init.h>
33
#include <linux/serio.h>
34
#include <linux/err.h>
35
#include <linux/platform_device.h>
36
#include <linux/io.h>
37
#include <linux/slab.h>
38
39
#include <asm/irq.h>
40
#include <mach/hardware.h>
41
#include <asm/hardware/iomd.h>
42
#include <asm/system.h>
43
44
MODULE_AUTHOR("Vojtech Pavlik, Russell King");
45
MODULE_DESCRIPTION("Acorn RiscPC PS/2 keyboard controller driver");
46
MODULE_LICENSE("GPL");
47
MODULE_ALIAS("platform:kart");
48
49
static int rpckbd_write(struct serio *port, unsigned char val)
50
{
51
while (!(iomd_readb(IOMD_KCTRL) & (1 << 7)))
52
cpu_relax();
53
54
iomd_writeb(val, IOMD_KARTTX);
55
56
return 0;
57
}
58
59
static irqreturn_t rpckbd_rx(int irq, void *dev_id)
60
{
61
struct serio *port = dev_id;
62
unsigned int byte;
63
int handled = IRQ_NONE;
64
65
while (iomd_readb(IOMD_KCTRL) & (1 << 5)) {
66
byte = iomd_readb(IOMD_KARTRX);
67
68
serio_interrupt(port, byte, 0);
69
handled = IRQ_HANDLED;
70
}
71
return handled;
72
}
73
74
static irqreturn_t rpckbd_tx(int irq, void *dev_id)
75
{
76
return IRQ_HANDLED;
77
}
78
79
static int rpckbd_open(struct serio *port)
80
{
81
/* Reset the keyboard state machine. */
82
iomd_writeb(0, IOMD_KCTRL);
83
iomd_writeb(8, IOMD_KCTRL);
84
iomd_readb(IOMD_KARTRX);
85
86
if (request_irq(IRQ_KEYBOARDRX, rpckbd_rx, 0, "rpckbd", port) != 0) {
87
printk(KERN_ERR "rpckbd.c: Could not allocate keyboard receive IRQ\n");
88
return -EBUSY;
89
}
90
91
if (request_irq(IRQ_KEYBOARDTX, rpckbd_tx, 0, "rpckbd", port) != 0) {
92
printk(KERN_ERR "rpckbd.c: Could not allocate keyboard transmit IRQ\n");
93
free_irq(IRQ_KEYBOARDRX, port);
94
return -EBUSY;
95
}
96
97
return 0;
98
}
99
100
static void rpckbd_close(struct serio *port)
101
{
102
free_irq(IRQ_KEYBOARDRX, port);
103
free_irq(IRQ_KEYBOARDTX, port);
104
}
105
106
/*
107
* Allocate and initialize serio structure for subsequent registration
108
* with serio core.
109
*/
110
static int __devinit rpckbd_probe(struct platform_device *dev)
111
{
112
struct serio *serio;
113
114
serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
115
if (!serio)
116
return -ENOMEM;
117
118
serio->id.type = SERIO_8042;
119
serio->write = rpckbd_write;
120
serio->open = rpckbd_open;
121
serio->close = rpckbd_close;
122
serio->dev.parent = &dev->dev;
123
strlcpy(serio->name, "RiscPC PS/2 kbd port", sizeof(serio->name));
124
strlcpy(serio->phys, "rpckbd/serio0", sizeof(serio->phys));
125
126
platform_set_drvdata(dev, serio);
127
serio_register_port(serio);
128
return 0;
129
}
130
131
static int __devexit rpckbd_remove(struct platform_device *dev)
132
{
133
struct serio *serio = platform_get_drvdata(dev);
134
serio_unregister_port(serio);
135
return 0;
136
}
137
138
static struct platform_driver rpckbd_driver = {
139
.probe = rpckbd_probe,
140
.remove = __devexit_p(rpckbd_remove),
141
.driver = {
142
.name = "kart",
143
.owner = THIS_MODULE,
144
},
145
};
146
147
static int __init rpckbd_init(void)
148
{
149
return platform_driver_register(&rpckbd_driver);
150
}
151
152
static void __exit rpckbd_exit(void)
153
{
154
platform_driver_unregister(&rpckbd_driver);
155
}
156
157
module_init(rpckbd_init);
158
module_exit(rpckbd_exit);
159
160