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
maceps2.c
Go to the documentation of this file.
1
/*
2
* SGI O2 MACE PS2 controller driver for linux
3
*
4
* Copyright (C) 2002 Vivien Chappelier
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License version 2 as
8
* published by the Free Software Foundation
9
*/
10
#include <linux/module.h>
11
#include <
linux/init.h
>
12
#include <linux/serio.h>
13
#include <linux/errno.h>
14
#include <
linux/interrupt.h
>
15
#include <
linux/ioport.h
>
16
#include <
linux/delay.h
>
17
#include <
linux/platform_device.h
>
18
#include <linux/slab.h>
19
#include <
linux/spinlock.h
>
20
#include <
linux/err.h
>
21
22
#include <asm/io.h>
23
#include <asm/irq.h>
24
#include <
asm/ip32/mace.h
>
25
#include <
asm/ip32/ip32_ints.h
>
26
27
MODULE_AUTHOR
(
"Vivien Chappelier <
[email protected]
"
);
28
MODULE_DESCRIPTION
(
"SGI O2 MACE PS2 controller driver"
);
29
MODULE_LICENSE
(
"GPL"
);
30
31
#define MACE_PS2_TIMEOUT 10000
/* in 50us unit */
32
33
#define PS2_STATUS_CLOCK_SIGNAL BIT(0)
/* external clock signal */
34
#define PS2_STATUS_CLOCK_INHIBIT BIT(1)
/* clken output signal */
35
#define PS2_STATUS_TX_INPROGRESS BIT(2)
/* transmission in progress */
36
#define PS2_STATUS_TX_EMPTY BIT(3)
/* empty transmit buffer */
37
#define PS2_STATUS_RX_FULL BIT(4)
/* full receive buffer */
38
#define PS2_STATUS_RX_INPROGRESS BIT(5)
/* reception in progress */
39
#define PS2_STATUS_ERROR_PARITY BIT(6)
/* parity error */
40
#define PS2_STATUS_ERROR_FRAMING BIT(7)
/* framing error */
41
42
#define PS2_CONTROL_TX_CLOCK_DISABLE BIT(0)
/* inhibit clock signal after TX */
43
#define PS2_CONTROL_TX_ENABLE BIT(1)
/* transmit enable */
44
#define PS2_CONTROL_TX_INT_ENABLE BIT(2)
/* enable transmit interrupt */
45
#define PS2_CONTROL_RX_INT_ENABLE BIT(3)
/* enable receive interrupt */
46
#define PS2_CONTROL_RX_CLOCK_ENABLE BIT(4)
/* pause reception if set to 0 */
47
#define PS2_CONTROL_RESET BIT(5)
/* reset */
48
49
struct
maceps2_data
{
50
struct
mace_ps2port
*
port
;
51
int
irq
;
52
};
53
54
static
struct
maceps2_data
port_data[2];
55
static
struct
serio
*maceps2_port[2];
56
static
struct
platform_device
*maceps2_device;
57
58
static
int
maceps2_write(
struct
serio
*
dev
,
unsigned
char
val
)
59
{
60
struct
mace_ps2port
*
port
= ((
struct
maceps2_data
*)dev->
port_data
)->
port
;
61
unsigned
int
timeout
=
MACE_PS2_TIMEOUT
;
62
63
do
{
64
if
(port->
status
&
PS2_STATUS_TX_EMPTY
) {
65
port->
tx
=
val
;
66
return
0;
67
}
68
udelay
(50);
69
}
while
(timeout--);
70
71
return
-1;
72
}
73
74
static
irqreturn_t
maceps2_interrupt(
int
irq
,
void
*
dev_id
)
75
{
76
struct
serio
*dev =
dev_id
;
77
struct
mace_ps2port
*port = ((
struct
maceps2_data
*)dev->
port_data
)->port;
78
unsigned
long
byte
;
79
80
if
(port->
status
&
PS2_STATUS_RX_FULL
) {
81
byte = port->
rx
;
82
serio_interrupt
(dev, byte & 0xff, 0);
83
}
84
85
return
IRQ_HANDLED
;
86
}
87
88
static
int
maceps2_open(
struct
serio
*dev)
89
{
90
struct
maceps2_data
*
data
= (
struct
maceps2_data
*)dev->
port_data
;
91
92
if
(
request_irq
(data->
irq
, maceps2_interrupt, 0,
"PS2 port"
, dev)) {
93
printk
(
KERN_ERR
"Could not allocate PS/2 IRQ\n"
);
94
return
-
EBUSY
;
95
}
96
97
/* Reset port */
98
data->
port
->control =
PS2_CONTROL_TX_CLOCK_DISABLE
|
PS2_CONTROL_RESET
;
99
udelay
(100);
100
101
/* Enable interrupts */
102
data->
port
->control =
PS2_CONTROL_RX_CLOCK_ENABLE
|
103
PS2_CONTROL_TX_ENABLE
|
104
PS2_CONTROL_RX_INT_ENABLE
;
105
106
return
0;
107
}
108
109
static
void
maceps2_close(
struct
serio
*dev)
110
{
111
struct
maceps2_data
*data = (
struct
maceps2_data
*)dev->
port_data
;
112
113
data->
port
->control =
PS2_CONTROL_TX_CLOCK_DISABLE
|
PS2_CONTROL_RESET
;
114
udelay
(100);
115
free_irq
(data->
irq
, dev);
116
}
117
118
119
static
struct
serio
*
__devinit
maceps2_allocate_port(
int
idx
)
120
{
121
struct
serio
*
serio
;
122
123
serio = kzalloc(
sizeof
(
struct
serio),
GFP_KERNEL
);
124
if
(serio) {
125
serio->
id
.type =
SERIO_8042
;
126
serio->
write
= maceps2_write;
127
serio->
open
= maceps2_open;
128
serio->
close
= maceps2_close;
129
snprintf
(serio->
name
,
sizeof
(serio->
name
),
"MACE PS/2 port%d"
, idx);
130
snprintf
(serio->
phys
,
sizeof
(serio->
phys
),
"mace/serio%d"
, idx);
131
serio->
port_data
= &
port_data
[
idx
];
132
serio->
dev
.parent = &maceps2_device->
dev
;
133
}
134
135
return
serio;
136
}
137
138
static
int
__devinit
maceps2_probe(
struct
platform_device
*dev)
139
{
140
maceps2_port[0] = maceps2_allocate_port(0);
141
maceps2_port[1] = maceps2_allocate_port(1);
142
if
(!maceps2_port[0] || !maceps2_port[1]) {
143
kfree
(maceps2_port[0]);
144
kfree
(maceps2_port[1]);
145
return
-
ENOMEM
;
146
}
147
148
serio_register_port
(maceps2_port[0]);
149
serio_register_port
(maceps2_port[1]);
150
151
return
0;
152
}
153
154
static
int
__devexit
maceps2_remove(
struct
platform_device
*dev)
155
{
156
serio_unregister_port
(maceps2_port[0]);
157
serio_unregister_port
(maceps2_port[1]);
158
159
return
0;
160
}
161
162
static
struct
platform_driver
maceps2_driver = {
163
.driver = {
164
.name =
"maceps2"
,
165
.owner =
THIS_MODULE
,
166
},
167
.probe = maceps2_probe,
168
.remove =
__devexit_p
(maceps2_remove),
169
};
170
171
static
int
__init
maceps2_init(
void
)
172
{
173
int
error
;
174
175
error =
platform_driver_register
(&maceps2_driver);
176
if
(error)
177
return
error
;
178
179
maceps2_device =
platform_device_alloc
(
"maceps2"
, -1);
180
if
(!maceps2_device) {
181
error = -
ENOMEM
;
182
goto
err_unregister_driver;
183
}
184
185
port_data[0].port = &
mace
->perif.ps2.keyb;
186
port_data[0].irq =
MACEISA_KEYB_IRQ
;
187
port_data[1].port = &
mace
->perif.ps2.mouse;
188
port_data[1].irq =
MACEISA_MOUSE_IRQ
;
189
190
error =
platform_device_add
(maceps2_device);
191
if
(error)
192
goto
err_free_device;
193
194
return
0;
195
196
err_free_device:
197
platform_device_put
(maceps2_device);
198
err_unregister_driver:
199
platform_driver_unregister
(&maceps2_driver);
200
return
error
;
201
}
202
203
static
void
__exit
maceps2_exit(
void
)
204
{
205
platform_device_unregister
(maceps2_device);
206
platform_driver_unregister
(&maceps2_driver);
207
}
208
209
module_init
(maceps2_init);
210
module_exit
(maceps2_exit);
Generated on Thu Jan 10 2013 13:39:55 for Linux Kernel by
1.8.2