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