1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * PS/2 driver library
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright (c) 1999-2002 Vojtech Pavlik
6*4882a593Smuzhiyun * Copyright (c) 2004 Dmitry Torokhov
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/delay.h>
11*4882a593Smuzhiyun #include <linux/module.h>
12*4882a593Smuzhiyun #include <linux/sched.h>
13*4882a593Smuzhiyun #include <linux/interrupt.h>
14*4882a593Smuzhiyun #include <linux/input.h>
15*4882a593Smuzhiyun #include <linux/serio.h>
16*4882a593Smuzhiyun #include <linux/i8042.h>
17*4882a593Smuzhiyun #include <linux/libps2.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun #define DRIVER_DESC "PS/2 driver library"
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun MODULE_AUTHOR("Dmitry Torokhov <dtor@mail.ru>");
22*4882a593Smuzhiyun MODULE_DESCRIPTION("PS/2 driver library");
23*4882a593Smuzhiyun MODULE_LICENSE("GPL");
24*4882a593Smuzhiyun
ps2_do_sendbyte(struct ps2dev * ps2dev,u8 byte,unsigned int timeout,unsigned int max_attempts)25*4882a593Smuzhiyun static int ps2_do_sendbyte(struct ps2dev *ps2dev, u8 byte,
26*4882a593Smuzhiyun unsigned int timeout, unsigned int max_attempts)
27*4882a593Smuzhiyun __releases(&ps2dev->serio->lock) __acquires(&ps2dev->serio->lock)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun int attempt = 0;
30*4882a593Smuzhiyun int error;
31*4882a593Smuzhiyun
32*4882a593Smuzhiyun lockdep_assert_held(&ps2dev->serio->lock);
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun do {
35*4882a593Smuzhiyun ps2dev->nak = 1;
36*4882a593Smuzhiyun ps2dev->flags |= PS2_FLAG_ACK;
37*4882a593Smuzhiyun
38*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
39*4882a593Smuzhiyun
40*4882a593Smuzhiyun error = serio_write(ps2dev->serio, byte);
41*4882a593Smuzhiyun if (error)
42*4882a593Smuzhiyun dev_dbg(&ps2dev->serio->dev,
43*4882a593Smuzhiyun "failed to write %#02x: %d\n", byte, error);
44*4882a593Smuzhiyun else
45*4882a593Smuzhiyun wait_event_timeout(ps2dev->wait,
46*4882a593Smuzhiyun !(ps2dev->flags & PS2_FLAG_ACK),
47*4882a593Smuzhiyun msecs_to_jiffies(timeout));
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
50*4882a593Smuzhiyun } while (ps2dev->nak == PS2_RET_NAK && ++attempt < max_attempts);
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_ACK;
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun if (!error) {
55*4882a593Smuzhiyun switch (ps2dev->nak) {
56*4882a593Smuzhiyun case 0:
57*4882a593Smuzhiyun break;
58*4882a593Smuzhiyun case PS2_RET_NAK:
59*4882a593Smuzhiyun error = -EAGAIN;
60*4882a593Smuzhiyun break;
61*4882a593Smuzhiyun case PS2_RET_ERR:
62*4882a593Smuzhiyun error = -EPROTO;
63*4882a593Smuzhiyun break;
64*4882a593Smuzhiyun default:
65*4882a593Smuzhiyun error = -EIO;
66*4882a593Smuzhiyun break;
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun }
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun if (error || attempt > 1)
71*4882a593Smuzhiyun dev_dbg(&ps2dev->serio->dev,
72*4882a593Smuzhiyun "%02x - %d (%x), attempt %d\n",
73*4882a593Smuzhiyun byte, error, ps2dev->nak, attempt);
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun return error;
76*4882a593Smuzhiyun }
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /*
79*4882a593Smuzhiyun * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
80*4882a593Smuzhiyun * It doesn't handle retransmission, the caller is expected to handle
81*4882a593Smuzhiyun * it when needed.
82*4882a593Smuzhiyun *
83*4882a593Smuzhiyun * ps2_sendbyte() can only be called from a process context.
84*4882a593Smuzhiyun */
85*4882a593Smuzhiyun
ps2_sendbyte(struct ps2dev * ps2dev,u8 byte,unsigned int timeout)86*4882a593Smuzhiyun int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun int retval;
89*4882a593Smuzhiyun
90*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun retval = ps2_do_sendbyte(ps2dev, byte, timeout, 1);
93*4882a593Smuzhiyun dev_dbg(&ps2dev->serio->dev, "%02x - %x\n", byte, ps2dev->nak);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun return retval;
98*4882a593Smuzhiyun }
99*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_sendbyte);
100*4882a593Smuzhiyun
ps2_begin_command(struct ps2dev * ps2dev)101*4882a593Smuzhiyun void ps2_begin_command(struct ps2dev *ps2dev)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
104*4882a593Smuzhiyun
105*4882a593Smuzhiyun mutex_lock(m);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_begin_command);
108*4882a593Smuzhiyun
ps2_end_command(struct ps2dev * ps2dev)109*4882a593Smuzhiyun void ps2_end_command(struct ps2dev *ps2dev)
110*4882a593Smuzhiyun {
111*4882a593Smuzhiyun struct mutex *m = ps2dev->serio->ps2_cmd_mutex ?: &ps2dev->cmd_mutex;
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun mutex_unlock(m);
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_end_command);
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun /*
118*4882a593Smuzhiyun * ps2_drain() waits for device to transmit requested number of bytes
119*4882a593Smuzhiyun * and discards them.
120*4882a593Smuzhiyun */
121*4882a593Smuzhiyun
ps2_drain(struct ps2dev * ps2dev,size_t maxbytes,unsigned int timeout)122*4882a593Smuzhiyun void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun if (maxbytes > sizeof(ps2dev->cmdbuf)) {
125*4882a593Smuzhiyun WARN_ON(1);
126*4882a593Smuzhiyun maxbytes = sizeof(ps2dev->cmdbuf);
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun ps2_begin_command(ps2dev);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
132*4882a593Smuzhiyun ps2dev->flags = PS2_FLAG_CMD;
133*4882a593Smuzhiyun ps2dev->cmdcnt = maxbytes;
134*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun wait_event_timeout(ps2dev->wait,
137*4882a593Smuzhiyun !(ps2dev->flags & PS2_FLAG_CMD),
138*4882a593Smuzhiyun msecs_to_jiffies(timeout));
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun ps2_end_command(ps2dev);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_drain);
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun /*
145*4882a593Smuzhiyun * ps2_is_keyboard_id() checks received ID byte against the list of
146*4882a593Smuzhiyun * known keyboard IDs.
147*4882a593Smuzhiyun */
148*4882a593Smuzhiyun
ps2_is_keyboard_id(u8 id_byte)149*4882a593Smuzhiyun bool ps2_is_keyboard_id(u8 id_byte)
150*4882a593Smuzhiyun {
151*4882a593Smuzhiyun static const u8 keyboard_ids[] = {
152*4882a593Smuzhiyun 0xab, /* Regular keyboards */
153*4882a593Smuzhiyun 0xac, /* NCD Sun keyboard */
154*4882a593Smuzhiyun 0x2b, /* Trust keyboard, translated */
155*4882a593Smuzhiyun 0x5d, /* Trust keyboard */
156*4882a593Smuzhiyun 0x60, /* NMB SGI keyboard, translated */
157*4882a593Smuzhiyun 0x47, /* NMB SGI keyboard */
158*4882a593Smuzhiyun };
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun return memchr(keyboard_ids, id_byte, sizeof(keyboard_ids)) != NULL;
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_is_keyboard_id);
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /*
165*4882a593Smuzhiyun * ps2_adjust_timeout() is called after receiving 1st byte of command
166*4882a593Smuzhiyun * response and tries to reduce remaining timeout to speed up command
167*4882a593Smuzhiyun * completion.
168*4882a593Smuzhiyun */
169*4882a593Smuzhiyun
ps2_adjust_timeout(struct ps2dev * ps2dev,unsigned int command,unsigned int timeout)170*4882a593Smuzhiyun static int ps2_adjust_timeout(struct ps2dev *ps2dev,
171*4882a593Smuzhiyun unsigned int command, unsigned int timeout)
172*4882a593Smuzhiyun {
173*4882a593Smuzhiyun switch (command) {
174*4882a593Smuzhiyun case PS2_CMD_RESET_BAT:
175*4882a593Smuzhiyun /*
176*4882a593Smuzhiyun * Device has sent the first response byte after
177*4882a593Smuzhiyun * reset command, reset is thus done, so we can
178*4882a593Smuzhiyun * shorten the timeout.
179*4882a593Smuzhiyun * The next byte will come soon (keyboard) or not
180*4882a593Smuzhiyun * at all (mouse).
181*4882a593Smuzhiyun */
182*4882a593Smuzhiyun if (timeout > msecs_to_jiffies(100))
183*4882a593Smuzhiyun timeout = msecs_to_jiffies(100);
184*4882a593Smuzhiyun break;
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun case PS2_CMD_GETID:
187*4882a593Smuzhiyun /*
188*4882a593Smuzhiyun * Microsoft Natural Elite keyboard responds to
189*4882a593Smuzhiyun * the GET ID command as it were a mouse, with
190*4882a593Smuzhiyun * a single byte. Fail the command so atkbd will
191*4882a593Smuzhiyun * use alternative probe to detect it.
192*4882a593Smuzhiyun */
193*4882a593Smuzhiyun if (ps2dev->cmdbuf[1] == 0xaa) {
194*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
195*4882a593Smuzhiyun ps2dev->flags = 0;
196*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
197*4882a593Smuzhiyun timeout = 0;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun
200*4882a593Smuzhiyun /*
201*4882a593Smuzhiyun * If device behind the port is not a keyboard there
202*4882a593Smuzhiyun * won't be 2nd byte of ID response.
203*4882a593Smuzhiyun */
204*4882a593Smuzhiyun if (!ps2_is_keyboard_id(ps2dev->cmdbuf[1])) {
205*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
206*4882a593Smuzhiyun ps2dev->flags = ps2dev->cmdcnt = 0;
207*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
208*4882a593Smuzhiyun timeout = 0;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun break;
211*4882a593Smuzhiyun
212*4882a593Smuzhiyun default:
213*4882a593Smuzhiyun break;
214*4882a593Smuzhiyun }
215*4882a593Smuzhiyun
216*4882a593Smuzhiyun return timeout;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun /*
220*4882a593Smuzhiyun * ps2_command() sends a command and its parameters to the mouse,
221*4882a593Smuzhiyun * then waits for the response and puts it in the param array.
222*4882a593Smuzhiyun *
223*4882a593Smuzhiyun * ps2_command() can only be called from a process context
224*4882a593Smuzhiyun */
225*4882a593Smuzhiyun
__ps2_command(struct ps2dev * ps2dev,u8 * param,unsigned int command)226*4882a593Smuzhiyun int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
227*4882a593Smuzhiyun {
228*4882a593Smuzhiyun unsigned int timeout;
229*4882a593Smuzhiyun unsigned int send = (command >> 12) & 0xf;
230*4882a593Smuzhiyun unsigned int receive = (command >> 8) & 0xf;
231*4882a593Smuzhiyun int rc;
232*4882a593Smuzhiyun int i;
233*4882a593Smuzhiyun u8 send_param[16];
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun if (receive > sizeof(ps2dev->cmdbuf)) {
236*4882a593Smuzhiyun WARN_ON(1);
237*4882a593Smuzhiyun return -EINVAL;
238*4882a593Smuzhiyun }
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun if (send && !param) {
241*4882a593Smuzhiyun WARN_ON(1);
242*4882a593Smuzhiyun return -EINVAL;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun memcpy(send_param, param, send);
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
248*4882a593Smuzhiyun
249*4882a593Smuzhiyun ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
250*4882a593Smuzhiyun ps2dev->cmdcnt = receive;
251*4882a593Smuzhiyun if (receive && param)
252*4882a593Smuzhiyun for (i = 0; i < receive; i++)
253*4882a593Smuzhiyun ps2dev->cmdbuf[(receive - 1) - i] = param[i];
254*4882a593Smuzhiyun
255*4882a593Smuzhiyun /* Signal that we are sending the command byte */
256*4882a593Smuzhiyun ps2dev->flags |= PS2_FLAG_ACK_CMD;
257*4882a593Smuzhiyun
258*4882a593Smuzhiyun /*
259*4882a593Smuzhiyun * Some devices (Synaptics) peform the reset before
260*4882a593Smuzhiyun * ACKing the reset command, and so it can take a long
261*4882a593Smuzhiyun * time before the ACK arrives.
262*4882a593Smuzhiyun */
263*4882a593Smuzhiyun timeout = command == PS2_CMD_RESET_BAT ? 1000 : 200;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun rc = ps2_do_sendbyte(ps2dev, command & 0xff, timeout, 2);
266*4882a593Smuzhiyun if (rc)
267*4882a593Smuzhiyun goto out_reset_flags;
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun /* Now we are sending command parameters, if any */
270*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_ACK_CMD;
271*4882a593Smuzhiyun
272*4882a593Smuzhiyun for (i = 0; i < send; i++) {
273*4882a593Smuzhiyun rc = ps2_do_sendbyte(ps2dev, param[i], 200, 2);
274*4882a593Smuzhiyun if (rc)
275*4882a593Smuzhiyun goto out_reset_flags;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun /*
281*4882a593Smuzhiyun * The reset command takes a long time to execute.
282*4882a593Smuzhiyun */
283*4882a593Smuzhiyun timeout = msecs_to_jiffies(command == PS2_CMD_RESET_BAT ? 4000 : 500);
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun timeout = wait_event_timeout(ps2dev->wait,
286*4882a593Smuzhiyun !(ps2dev->flags & PS2_FLAG_CMD1), timeout);
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun if (ps2dev->cmdcnt && !(ps2dev->flags & PS2_FLAG_CMD1)) {
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun timeout = ps2_adjust_timeout(ps2dev, command, timeout);
291*4882a593Smuzhiyun wait_event_timeout(ps2dev->wait,
292*4882a593Smuzhiyun !(ps2dev->flags & PS2_FLAG_CMD), timeout);
293*4882a593Smuzhiyun }
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun serio_pause_rx(ps2dev->serio);
296*4882a593Smuzhiyun
297*4882a593Smuzhiyun if (param)
298*4882a593Smuzhiyun for (i = 0; i < receive; i++)
299*4882a593Smuzhiyun param[i] = ps2dev->cmdbuf[(receive - 1) - i];
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun if (ps2dev->cmdcnt &&
302*4882a593Smuzhiyun (command != PS2_CMD_RESET_BAT || ps2dev->cmdcnt != 1)) {
303*4882a593Smuzhiyun rc = -EPROTO;
304*4882a593Smuzhiyun goto out_reset_flags;
305*4882a593Smuzhiyun }
306*4882a593Smuzhiyun
307*4882a593Smuzhiyun rc = 0;
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun out_reset_flags:
310*4882a593Smuzhiyun ps2dev->flags = 0;
311*4882a593Smuzhiyun serio_continue_rx(ps2dev->serio);
312*4882a593Smuzhiyun
313*4882a593Smuzhiyun dev_dbg(&ps2dev->serio->dev,
314*4882a593Smuzhiyun "%02x [%*ph] - %x/%08lx [%*ph]\n",
315*4882a593Smuzhiyun command & 0xff, send, send_param,
316*4882a593Smuzhiyun ps2dev->nak, ps2dev->flags,
317*4882a593Smuzhiyun receive, param ?: send_param);
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun /*
320*4882a593Smuzhiyun * ps_command() handles resends itself, so do not leak -EAGAIN
321*4882a593Smuzhiyun * to the callers.
322*4882a593Smuzhiyun */
323*4882a593Smuzhiyun return rc != -EAGAIN ? rc : -EPROTO;
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun EXPORT_SYMBOL(__ps2_command);
326*4882a593Smuzhiyun
ps2_command(struct ps2dev * ps2dev,u8 * param,unsigned int command)327*4882a593Smuzhiyun int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun int rc;
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun ps2_begin_command(ps2dev);
332*4882a593Smuzhiyun rc = __ps2_command(ps2dev, param, command);
333*4882a593Smuzhiyun ps2_end_command(ps2dev);
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun return rc;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_command);
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /*
340*4882a593Smuzhiyun * ps2_sliced_command() sends an extended PS/2 command to the mouse
341*4882a593Smuzhiyun * using sliced syntax, understood by advanced devices, such as Logitech
342*4882a593Smuzhiyun * or Synaptics touchpads. The command is encoded as:
343*4882a593Smuzhiyun * 0xE6 0xE8 rr 0xE8 ss 0xE8 tt 0xE8 uu where (rr*64)+(ss*16)+(tt*4)+uu
344*4882a593Smuzhiyun * is the command.
345*4882a593Smuzhiyun */
346*4882a593Smuzhiyun
ps2_sliced_command(struct ps2dev * ps2dev,u8 command)347*4882a593Smuzhiyun int ps2_sliced_command(struct ps2dev *ps2dev, u8 command)
348*4882a593Smuzhiyun {
349*4882a593Smuzhiyun int i;
350*4882a593Smuzhiyun int retval;
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun ps2_begin_command(ps2dev);
353*4882a593Smuzhiyun
354*4882a593Smuzhiyun retval = __ps2_command(ps2dev, NULL, PS2_CMD_SETSCALE11);
355*4882a593Smuzhiyun if (retval)
356*4882a593Smuzhiyun goto out;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun for (i = 6; i >= 0; i -= 2) {
359*4882a593Smuzhiyun u8 d = (command >> i) & 3;
360*4882a593Smuzhiyun retval = __ps2_command(ps2dev, &d, PS2_CMD_SETRES);
361*4882a593Smuzhiyun if (retval)
362*4882a593Smuzhiyun break;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun out:
366*4882a593Smuzhiyun dev_dbg(&ps2dev->serio->dev, "%02x - %d\n", command, retval);
367*4882a593Smuzhiyun ps2_end_command(ps2dev);
368*4882a593Smuzhiyun return retval;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_sliced_command);
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun /*
373*4882a593Smuzhiyun * ps2_init() initializes ps2dev structure
374*4882a593Smuzhiyun */
375*4882a593Smuzhiyun
ps2_init(struct ps2dev * ps2dev,struct serio * serio)376*4882a593Smuzhiyun void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
377*4882a593Smuzhiyun {
378*4882a593Smuzhiyun mutex_init(&ps2dev->cmd_mutex);
379*4882a593Smuzhiyun lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
380*4882a593Smuzhiyun init_waitqueue_head(&ps2dev->wait);
381*4882a593Smuzhiyun ps2dev->serio = serio;
382*4882a593Smuzhiyun }
383*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_init);
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun /*
386*4882a593Smuzhiyun * ps2_handle_ack() is supposed to be used in interrupt handler
387*4882a593Smuzhiyun * to properly process ACK/NAK of a command from a PS/2 device.
388*4882a593Smuzhiyun */
389*4882a593Smuzhiyun
ps2_handle_ack(struct ps2dev * ps2dev,u8 data)390*4882a593Smuzhiyun bool ps2_handle_ack(struct ps2dev *ps2dev, u8 data)
391*4882a593Smuzhiyun {
392*4882a593Smuzhiyun switch (data) {
393*4882a593Smuzhiyun case PS2_RET_ACK:
394*4882a593Smuzhiyun ps2dev->nak = 0;
395*4882a593Smuzhiyun break;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun case PS2_RET_NAK:
398*4882a593Smuzhiyun ps2dev->flags |= PS2_FLAG_NAK;
399*4882a593Smuzhiyun ps2dev->nak = PS2_RET_NAK;
400*4882a593Smuzhiyun break;
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun case PS2_RET_ERR:
403*4882a593Smuzhiyun if (ps2dev->flags & PS2_FLAG_NAK) {
404*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_NAK;
405*4882a593Smuzhiyun ps2dev->nak = PS2_RET_ERR;
406*4882a593Smuzhiyun break;
407*4882a593Smuzhiyun }
408*4882a593Smuzhiyun /* Fall through */
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun /*
411*4882a593Smuzhiyun * Workaround for mice which don't ACK the Get ID command.
412*4882a593Smuzhiyun * These are valid mouse IDs that we recognize.
413*4882a593Smuzhiyun */
414*4882a593Smuzhiyun case 0x00:
415*4882a593Smuzhiyun case 0x03:
416*4882a593Smuzhiyun case 0x04:
417*4882a593Smuzhiyun if (ps2dev->flags & PS2_FLAG_WAITID) {
418*4882a593Smuzhiyun ps2dev->nak = 0;
419*4882a593Smuzhiyun break;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun fallthrough;
422*4882a593Smuzhiyun default:
423*4882a593Smuzhiyun /*
424*4882a593Smuzhiyun * Do not signal errors if we get unexpected reply while
425*4882a593Smuzhiyun * waiting for an ACK to the initial (first) command byte:
426*4882a593Smuzhiyun * the device might not be quiesced yet and continue
427*4882a593Smuzhiyun * delivering data.
428*4882a593Smuzhiyun * Note that we reset PS2_FLAG_WAITID flag, so the workaround
429*4882a593Smuzhiyun * for mice not acknowledging the Get ID command only triggers
430*4882a593Smuzhiyun * on the 1st byte; if device spews data we really want to see
431*4882a593Smuzhiyun * a real ACK from it.
432*4882a593Smuzhiyun */
433*4882a593Smuzhiyun dev_dbg(&ps2dev->serio->dev, "unexpected %#02x\n", data);
434*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_WAITID;
435*4882a593Smuzhiyun return ps2dev->flags & PS2_FLAG_ACK_CMD;
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun
438*4882a593Smuzhiyun if (!ps2dev->nak) {
439*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_NAK;
440*4882a593Smuzhiyun if (ps2dev->cmdcnt)
441*4882a593Smuzhiyun ps2dev->flags |= PS2_FLAG_CMD | PS2_FLAG_CMD1;
442*4882a593Smuzhiyun }
443*4882a593Smuzhiyun
444*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_ACK;
445*4882a593Smuzhiyun wake_up(&ps2dev->wait);
446*4882a593Smuzhiyun
447*4882a593Smuzhiyun if (data != PS2_RET_ACK)
448*4882a593Smuzhiyun ps2_handle_response(ps2dev, data);
449*4882a593Smuzhiyun
450*4882a593Smuzhiyun return true;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_handle_ack);
453*4882a593Smuzhiyun
454*4882a593Smuzhiyun /*
455*4882a593Smuzhiyun * ps2_handle_response() is supposed to be used in interrupt handler
456*4882a593Smuzhiyun * to properly store device's response to a command and notify process
457*4882a593Smuzhiyun * waiting for completion of the command.
458*4882a593Smuzhiyun */
459*4882a593Smuzhiyun
ps2_handle_response(struct ps2dev * ps2dev,u8 data)460*4882a593Smuzhiyun bool ps2_handle_response(struct ps2dev *ps2dev, u8 data)
461*4882a593Smuzhiyun {
462*4882a593Smuzhiyun if (ps2dev->cmdcnt)
463*4882a593Smuzhiyun ps2dev->cmdbuf[--ps2dev->cmdcnt] = data;
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun if (ps2dev->flags & PS2_FLAG_CMD1) {
466*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_CMD1;
467*4882a593Smuzhiyun if (ps2dev->cmdcnt)
468*4882a593Smuzhiyun wake_up(&ps2dev->wait);
469*4882a593Smuzhiyun }
470*4882a593Smuzhiyun
471*4882a593Smuzhiyun if (!ps2dev->cmdcnt) {
472*4882a593Smuzhiyun ps2dev->flags &= ~PS2_FLAG_CMD;
473*4882a593Smuzhiyun wake_up(&ps2dev->wait);
474*4882a593Smuzhiyun }
475*4882a593Smuzhiyun
476*4882a593Smuzhiyun return true;
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_handle_response);
479*4882a593Smuzhiyun
ps2_cmd_aborted(struct ps2dev * ps2dev)480*4882a593Smuzhiyun void ps2_cmd_aborted(struct ps2dev *ps2dev)
481*4882a593Smuzhiyun {
482*4882a593Smuzhiyun if (ps2dev->flags & PS2_FLAG_ACK)
483*4882a593Smuzhiyun ps2dev->nak = 1;
484*4882a593Smuzhiyun
485*4882a593Smuzhiyun if (ps2dev->flags & (PS2_FLAG_ACK | PS2_FLAG_CMD))
486*4882a593Smuzhiyun wake_up(&ps2dev->wait);
487*4882a593Smuzhiyun
488*4882a593Smuzhiyun /* reset all flags except last nack */
489*4882a593Smuzhiyun ps2dev->flags &= PS2_FLAG_NAK;
490*4882a593Smuzhiyun }
491*4882a593Smuzhiyun EXPORT_SYMBOL(ps2_cmd_aborted);
492