Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
drivers
input
serio
rpckbd.c
Go to the documentation of this file.
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 <mach/hardware.h>
40
#include <
asm/hardware/iomd.h
>
41
42
MODULE_AUTHOR
(
"Vojtech Pavlik, Russell King"
);
43
MODULE_DESCRIPTION
(
"Acorn RiscPC PS/2 keyboard controller driver"
);
44
MODULE_LICENSE
(
"GPL"
);
45
MODULE_ALIAS
(
"platform:kart"
);
46
47
struct
rpckbd_data
{
48
int
tx_irq
;
49
int
rx_irq
;
50
};
51
52
static
int
rpckbd_write(
struct
serio
*
port
,
unsigned
char
val
)
53
{
54
while
(!(
iomd_readb
(
IOMD_KCTRL
) & (1 << 7)))
55
cpu_relax
();
56
57
iomd_writeb
(val,
IOMD_KARTTX
);
58
59
return
0;
60
}
61
62
static
irqreturn_t
rpckbd_rx(
int
irq,
void
*
dev_id
)
63
{
64
struct
serio
*
port
=
dev_id
;
65
unsigned
int
byte
;
66
int
handled =
IRQ_NONE
;
67
68
while
(
iomd_readb
(
IOMD_KCTRL
) & (1 << 5)) {
69
byte =
iomd_readb
(
IOMD_KARTRX
);
70
71
serio_interrupt
(port, byte, 0);
72
handled =
IRQ_HANDLED
;
73
}
74
return
handled;
75
}
76
77
static
irqreturn_t
rpckbd_tx(
int
irq,
void
*dev_id)
78
{
79
return
IRQ_HANDLED
;
80
}
81
82
static
int
rpckbd_open(
struct
serio
*port)
83
{
84
struct
rpckbd_data
*rpckbd = port->
port_data
;
85
86
/* Reset the keyboard state machine. */
87
iomd_writeb
(0,
IOMD_KCTRL
);
88
iomd_writeb
(8,
IOMD_KCTRL
);
89
iomd_readb
(
IOMD_KARTRX
);
90
91
if
(
request_irq
(rpckbd->
rx_irq
, rpckbd_rx, 0,
"rpckbd"
, port) != 0) {
92
printk
(
KERN_ERR
"rpckbd.c: Could not allocate keyboard receive IRQ\n"
);
93
return
-
EBUSY
;
94
}
95
96
if
(
request_irq
(rpckbd->
tx_irq
, rpckbd_tx, 0,
"rpckbd"
, port) != 0) {
97
printk
(
KERN_ERR
"rpckbd.c: Could not allocate keyboard transmit IRQ\n"
);
98
free_irq
(rpckbd->
rx_irq
, port);
99
return
-
EBUSY
;
100
}
101
102
return
0;
103
}
104
105
static
void
rpckbd_close(
struct
serio
*port)
106
{
107
struct
rpckbd_data
*rpckbd = port->
port_data
;
108
109
free_irq
(rpckbd->
rx_irq
, port);
110
free_irq
(rpckbd->
tx_irq
, port);
111
}
112
113
/*
114
* Allocate and initialize serio structure for subsequent registration
115
* with serio core.
116
*/
117
static
int
__devinit
rpckbd_probe(
struct
platform_device
*
dev
)
118
{
119
struct
rpckbd_data
*rpckbd;
120
struct
serio
*
serio
;
121
int
tx_irq, rx_irq;
122
123
rx_irq =
platform_get_irq
(dev, 0);
124
if
(rx_irq <= 0)
125
return
rx_irq < 0 ? rx_irq : -
ENXIO
;
126
127
tx_irq =
platform_get_irq
(dev, 1);
128
if
(tx_irq <= 0)
129
return
tx_irq < 0 ? tx_irq : -
ENXIO
;
130
131
serio = kzalloc(
sizeof
(
struct
serio),
GFP_KERNEL
);
132
rpckbd = kzalloc(
sizeof
(*rpckbd),
GFP_KERNEL
);
133
if
(!serio || !rpckbd) {
134
kfree
(rpckbd);
135
kfree
(serio);
136
return
-
ENOMEM
;
137
}
138
139
rpckbd->
rx_irq
= rx_irq;
140
rpckbd->
tx_irq
= tx_irq;
141
142
serio->
id
.type =
SERIO_8042
;
143
serio->
write
= rpckbd_write;
144
serio->
open
= rpckbd_open;
145
serio->
close
= rpckbd_close;
146
serio->
dev
.parent = &dev->
dev
;
147
serio->
port_data
= rpckbd;
148
strlcpy
(serio->
name
,
"RiscPC PS/2 kbd port"
,
sizeof
(serio->
name
));
149
strlcpy
(serio->
phys
,
"rpckbd/serio0"
,
sizeof
(serio->
phys
));
150
151
platform_set_drvdata(dev, serio);
152
serio_register_port
(serio);
153
return
0;
154
}
155
156
static
int
__devexit
rpckbd_remove(
struct
platform_device
*dev)
157
{
158
struct
serio *serio = platform_get_drvdata(dev);
159
struct
rpckbd_data
*rpckbd = serio->
port_data
;
160
161
serio_unregister_port
(serio);
162
kfree
(rpckbd);
163
164
return
0;
165
}
166
167
static
struct
platform_driver
rpckbd_driver = {
168
.probe = rpckbd_probe,
169
.remove =
__devexit_p
(rpckbd_remove),
170
.driver = {
171
.name =
"kart"
,
172
.owner =
THIS_MODULE
,
173
},
174
};
175
module_platform_driver
(rpckbd_driver);
Generated on Thu Jan 10 2013 13:39:56 for Linux Kernel by
1.8.2