Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/input/serio/libps2.c
15111 views
1
/*
2
* PS/2 driver library
3
*
4
* Copyright (c) 1999-2002 Vojtech Pavlik
5
* Copyright (c) 2004 Dmitry Torokhov
6
*/
7
8
/*
9
* This program is free software; you can redistribute it and/or modify it
10
* under the terms of the GNU General Public License version 2 as published by
11
* the Free Software Foundation.
12
*/
13
14
#include <linux/delay.h>
15
#include <linux/module.h>
16
#include <linux/sched.h>
17
#include <linux/interrupt.h>
18
#include <linux/input.h>
19
#include <linux/serio.h>
20
#include <linux/i8042.h>
21
#include <linux/init.h>
22
#include <linux/libps2.h>
23
24
#define DRIVER_DESC "PS/2 driver library"
25
26
MODULE_AUTHOR("Dmitry Torokhov <[email protected]>");
27
MODULE_DESCRIPTION("PS/2 driver library");
28
MODULE_LICENSE("GPL");
29
30
/*
31
* ps2_sendbyte() sends a byte to the device and waits for acknowledge.
32
* It doesn't handle retransmission, though it could - because if there
33
* is a need for retransmissions device has to be replaced anyway.
34
*
35
* ps2_sendbyte() can only be called from a process context.
36
*/
37
38
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
39
{
40
serio_pause_rx(ps2dev->serio);
41
ps2dev->nak = 1;
42
ps2dev->flags |= PS2_FLAG_ACK;
43
serio_continue_rx(ps2dev->serio);
44
45
if (serio_write(ps2dev->serio, byte) == 0)
46
wait_event_timeout(ps2dev->wait,
47
!(ps2dev->flags & PS2_FLAG_ACK),
48
msecs_to_jiffies(timeout));
49
50
serio_pause_rx(ps2dev->serio);
51
ps2dev->flags &= ~PS2_FLAG_ACK;
52
serio_continue_rx(ps2dev->serio);
53
54
return -ps2dev->nak;
55
}
56
EXPORT_SYMBOL(ps2_sendbyte);
57
58
void ps2_begin_command(struct ps2dev *ps2dev)
59
{
60
mutex_lock(&ps2dev->cmd_mutex);
61
62
if (i8042_check_port_owner(ps2dev->serio))
63
i8042_lock_chip();
64
}
65
EXPORT_SYMBOL(ps2_begin_command);
66
67
void ps2_end_command(struct ps2dev *ps2dev)
68
{
69
if (i8042_check_port_owner(ps2dev->serio))
70
i8042_unlock_chip();
71
72
mutex_unlock(&ps2dev->cmd_mutex);
73
}
74
EXPORT_SYMBOL(ps2_end_command);
75
76
/*
77
* ps2_drain() waits for device to transmit requested number of bytes
78
* and discards them.
79
*/
80
81
void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
82
{
83
if (maxbytes > sizeof(ps2dev->cmdbuf)) {
84
WARN_ON(1);
85
maxbytes = sizeof(ps2dev->cmdbuf);
86
}
87
88
ps2_begin_command(ps2dev);
89
90
serio_pause_rx(ps2dev->serio);
91
ps2dev->flags = PS2_FLAG_CMD;
92
ps2dev->cmdcnt = maxbytes;
93
serio_continue_rx(ps2dev->serio);
94
95
wait_event_timeout(ps2dev->wait,
96
!(ps2dev->flags & PS2_FLAG_CMD),
97
msecs_to_jiffies(timeout));
98
99
ps2_end_command(ps2dev);
100
}
101
EXPORT_SYMBOL(ps2_drain);
102
103
/*
104
* ps2_is_keyboard_id() checks received ID byte against the list of
105
* known keyboard IDs.
106
*/
107
108
int ps2_is_keyboard_id(char id_byte)
109
{
110
static const char keyboard_ids[] = {
111
0xab, /* Regular keyboards */
112
0xac, /* NCD Sun keyboard */
113
0x2b, /* Trust keyboard, translated */
114
0x5d, /* Trust keyboard */
115
0x60, /* NMB SGI keyboard, translated */
116
0x47, /* NMB SGI keyboard */
117
};
118
119
return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
120
}
121
EXPORT_SYMBOL(ps2_is_keyboard_id);
122
123
/*
124
* ps2_adjust_timeout() is called after receiving 1st byte of command
125
* response and tries to reduce remaining timeout to speed up command
126
* completion.
127
*/
128
129
static int ps2_adjust_timeout(struct ps2dev *ps2dev, int command, int timeout)
130
{
131
switch (command) {
132
case PS2_CMD_RESET_BAT:
133
/*
134
* Device has sent the first response byte after
135
* reset command, reset is thus done, so we can
136
* shorten the timeout.
137
* The next byte will come soon (keyboard) or not
138
* at all (mouse).
139
*/
140
if (timeout > msecs_to_jiffies(100))
141
timeout = msecs_to_jiffies(100);
142
break;
143
144
case PS2_CMD_GETID:
145
/*
146
* Microsoft Natural Elite keyboard responds to
147
* the GET ID command as it were a mouse, with
148
* a single byte. Fail the command so atkbd will
149
* use alternative probe to detect it.
150
*/
151
if (ps2dev->cmdbuf[1] == 0xaa) {
152
serio_pause_rx(ps2dev->serio);
153
ps2dev->flags = 0;
154
serio_continue_rx(ps2dev->serio);
155
timeout = 0;
156
}
157
158
/*
159
* If device behind the port is not a keyboard there
160
* won't be 2nd byte of ID response.
161
*/
162
if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
163
serio_pause_rx(ps2dev->serio);
164
ps2dev->flags = ps2dev->cmdcnt = 0;
165
serio_continue_rx(ps2dev->serio);
166
timeout = 0;
167
}
168
break;
169
170
default:
171
break;
172
}
173
174
return timeout;
175
}
176
177
/*
178
* ps2_command() sends a command and its parameters to the mouse,
179
* then waits for the response and puts it in the param array.
180
*
181
* ps2_command() can only be called from a process context
182
*/
183
184
int __ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
185
{
186
int timeout;
187
int send = (command >> 12) & 0xf;
188
int receive = (command >> 8) & 0xf;
189
int rc = -1;
190
int i;
191
192
if (receive > sizeof(ps2dev->cmdbuf)) {
193
WARN_ON(1);
194
return -1;
195
}
196
197
if (send && !param) {
198
WARN_ON(1);
199
return -1;
200
}
201
202
serio_pause_rx(ps2dev->serio);
203
ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
204
ps2dev->cmdcnt = receive;
205
if (receive && param)
206
for (i = 0; i < receive; i++)
207
ps2dev->cmdbuf[(receive - 1) - i] = param[i];
208
serio_continue_rx(ps2dev->serio);
209
210
/*
211
* Some devices (Synaptics) peform the reset before
212
* ACKing the reset command, and so it can take a long
213
* time before the ACK arrrives.
214
*/
215
if (ps2_sendbyte(ps2dev, command & 0xff,
216
command == PS2_CMD_RESET_BAT ? 1000 : 200))
217
goto out;
218
219
for (i = 0; i < send; i++)
220
if (ps2_sendbyte(ps2dev, param[i], 200))
221
goto out;
222
223
/*
224
* The reset command takes a long time to execute.
225
*/
226
timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
227
228
timeout = wait_event_timeout(ps2dev->wait,
229
!(ps2dev->flags & PS2_FLAG_CMD1), timeout);
230
231
if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
232
233
timeout = ps2_adjust_timeout(ps2dev, command, timeout);
234
wait_event_timeout(ps2dev->wait,
235
!(ps2dev->flags & PS2_FLAG_CMD), timeout);
236
}
237
238
if (param)
239
for (i = 0; i < receive; i++)
240
param[i] = ps2dev->cmdbuf[(receive - 1) - i];
241
242
if (ps2dev->cmdcnt && (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1))
243
goto out;
244
245
rc = 0;
246
247
out:
248
serio_pause_rx(ps2dev->serio);
249
ps2dev->flags = 0;
250
serio_continue_rx(ps2dev->serio);
251
252
return rc;
253
}
254
EXPORT_SYMBOL(__ps2_command);
255
256
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
257
{
258
int rc;
259
260
ps2_begin_command(ps2dev);
261
rc = __ps2_command(ps2dev, param, command);
262
ps2_end_command(ps2dev);
263
264
return rc;
265
}
266
EXPORT_SYMBOL(ps2_command);
267
268
/*
269
* ps2_init() initializes ps2dev structure
270
*/
271
272
void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
273
{
274
mutex_init(&ps2dev->cmd_mutex);
275
lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
276
init_waitqueue_head(&ps2dev->wait);
277
ps2dev->serio = serio;
278
}
279
EXPORT_SYMBOL(ps2_init);
280
281
/*
282
* ps2_handle_ack() is supposed to be used in interrupt handler
283
* to properly process ACK/NAK of a command from a PS/2 device.
284
*/
285
286
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data)
287
{
288
switch (data) {
289
case PS2_RET_ACK:
290
ps2dev->nak = 0;
291
break;
292
293
case PS2_RET_NAK:
294
ps2dev->flags |= PS2_FLAG_NAK;
295
ps2dev->nak = PS2_RET_NAK;
296
break;
297
298
case PS2_RET_ERR:
299
if (ps2dev->flags & PS2_FLAG_NAK) {
300
ps2dev->flags &= ~PS2_FLAG_NAK;
301
ps2dev->nak = PS2_RET_ERR;
302
break;
303
}
304
305
/*
306
* Workaround for mice which don't ACK the Get ID command.
307
* These are valid mouse IDs that we recognize.
308
*/
309
case 0x00:
310
case 0x03:
311
case 0x04:
312
if (ps2dev->flags & PS2_FLAG_WAITID) {
313
ps2dev->nak = 0;
314
break;
315
}
316
/* Fall through */
317
default:
318
return 0;
319
}
320
321
322
if (!ps2dev->nak) {
323
ps2dev->flags &= ~PS2_FLAG_NAK;
324
if (ps2dev->cmdcnt)
325
ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
326
}
327
328
ps2dev->flags &= ~PS2_FLAG_ACK;
329
wake_up(&ps2dev->wait);
330
331
if (data != PS2_RET_ACK)
332
ps2_handle_response(ps2dev, data);
333
334
return 1;
335
}
336
EXPORT_SYMBOL(ps2_handle_ack);
337
338
/*
339
* ps2_handle_response() is supposed to be used in interrupt handler
340
* to properly store device's response to a command and notify process
341
* waiting for completion of the command.
342
*/
343
344
int ps2_handle_response(struct ps2dev *ps2dev, unsigned char data)
345
{
346
if (ps2dev->cmdcnt)
347
ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
348
349
if (ps2dev->flags & PS2_FLAG_CMD1) {
350
ps2dev->flags &= ~PS2_FLAG_CMD1;
351
if (ps2dev->cmdcnt)
352
wake_up(&ps2dev->wait);
353
}
354
355
if (!ps2dev->cmdcnt) {
356
ps2dev->flags &= ~PS2_FLAG_CMD;
357
wake_up(&ps2dev->wait);
358
}
359
360
return 1;
361
}
362
EXPORT_SYMBOL(ps2_handle_response);
363
364
void ps2_cmd_aborted(struct ps2dev *ps2dev)
365
{
366
if (ps2dev->flags & PS2_FLAG_ACK)
367
ps2dev->nak = 1;
368
369
if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
370
wake_up(&ps2dev->wait);
371
372
/* reset all flags except last nack */
373
ps2dev->flags &= PS2_FLAG_NAK;
374
}
375
EXPORT_SYMBOL(ps2_cmd_aborted);
376
377