1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */ 21da177e4SLinus Torvalds #ifndef _LIBPS2_H 31da177e4SLinus Torvalds #define _LIBPS2_H 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds /* 61da177e4SLinus Torvalds * Copyright (C) 1999-2002 Vojtech Pavlik 71da177e4SLinus Torvalds * Copyright (C) 2004 Dmitry Torokhov 81da177e4SLinus Torvalds */ 91da177e4SLinus Torvalds 103a92dd33SDmitry Torokhov #include <linux/bitops.h> 11*c4c7eac8SDmitry Torokhov #include <linux/interrupt.h> 12b28bad65SDmitry Torokhov #include <linux/mutex.h> 13b28bad65SDmitry Torokhov #include <linux/types.h> 14b28bad65SDmitry Torokhov #include <linux/wait.h> 151da177e4SLinus Torvalds 16*c4c7eac8SDmitry Torokhov struct ps2dev; 171da177e4SLinus Torvalds 18*c4c7eac8SDmitry Torokhov /** 19*c4c7eac8SDmitry Torokhov * enum ps2_disposition - indicates how received byte should be handled 20*c4c7eac8SDmitry Torokhov * @PS2_PROCESS: pass to the main protocol handler, process normally 21*c4c7eac8SDmitry Torokhov * @PS2_IGNORE: skip the byte 22*c4c7eac8SDmitry Torokhov * @PS2_ERROR: do not process the byte, abort command in progress 23*c4c7eac8SDmitry Torokhov */ 24*c4c7eac8SDmitry Torokhov enum ps2_disposition { 25*c4c7eac8SDmitry Torokhov PS2_PROCESS, 26*c4c7eac8SDmitry Torokhov PS2_IGNORE, 27*c4c7eac8SDmitry Torokhov PS2_ERROR, 28*c4c7eac8SDmitry Torokhov }; 291da177e4SLinus Torvalds 30*c4c7eac8SDmitry Torokhov typedef enum ps2_disposition (*ps2_pre_receive_handler_t)(struct ps2dev *, u8, 31*c4c7eac8SDmitry Torokhov unsigned int); 32*c4c7eac8SDmitry Torokhov typedef void (*ps2_receive_handler_t)(struct ps2dev *, u8); 331da177e4SLinus Torvalds 34*c4c7eac8SDmitry Torokhov /** 35*c4c7eac8SDmitry Torokhov * struct ps2dev - represents a device using PS/2 protocol 36*c4c7eac8SDmitry Torokhov * @serio: a serio port used by the PS/2 device 37*c4c7eac8SDmitry Torokhov * @cmd_mutex: a mutex ensuring that only one command is executing at a time 38*c4c7eac8SDmitry Torokhov * @wait: a waitqueue used to signal completion from the serio interrupt handler 39*c4c7eac8SDmitry Torokhov * @flags: various internal flags indicating stages of PS/2 command execution 40*c4c7eac8SDmitry Torokhov * @cmdbuf: buffer holding command response 41*c4c7eac8SDmitry Torokhov * @cmdcnt: outstanding number of bytes of the command response 42*c4c7eac8SDmitry Torokhov * @nak: a byte transmitted by the device when it refuses command 43*c4c7eac8SDmitry Torokhov * @pre_receive_handler: checks communication errors and returns disposition 44*c4c7eac8SDmitry Torokhov * (&enum ps2_disposition) of the received data byte 45*c4c7eac8SDmitry Torokhov * @receive_handler: main handler of particular PS/2 protocol, such as keyboard 46*c4c7eac8SDmitry Torokhov * or mouse protocol 47*c4c7eac8SDmitry Torokhov */ 481da177e4SLinus Torvalds struct ps2dev { 491da177e4SLinus Torvalds struct serio *serio; 50c4e32e9fSArjan van de Ven struct mutex cmd_mutex; 511da177e4SLinus Torvalds wait_queue_head_t wait; 521da177e4SLinus Torvalds unsigned long flags; 53b28bad65SDmitry Torokhov u8 cmdbuf[8]; 54b28bad65SDmitry Torokhov u8 cmdcnt; 55b28bad65SDmitry Torokhov u8 nak; 56*c4c7eac8SDmitry Torokhov 57*c4c7eac8SDmitry Torokhov ps2_pre_receive_handler_t pre_receive_handler; 58*c4c7eac8SDmitry Torokhov ps2_receive_handler_t receive_handler; 591da177e4SLinus Torvalds }; 601da177e4SLinus Torvalds 61*c4c7eac8SDmitry Torokhov void ps2_init(struct ps2dev *ps2dev, struct serio *serio, 62*c4c7eac8SDmitry Torokhov ps2_pre_receive_handler_t pre_receive_handler, 63*c4c7eac8SDmitry Torokhov ps2_receive_handler_t receive_handler); 64b28bad65SDmitry Torokhov int ps2_sendbyte(struct ps2dev *ps2dev, u8 byte, unsigned int timeout); 65b28bad65SDmitry Torokhov void ps2_drain(struct ps2dev *ps2dev, size_t maxbytes, unsigned int timeout); 66181d683dSDmitry Torokhov void ps2_begin_command(struct ps2dev *ps2dev); 67181d683dSDmitry Torokhov void ps2_end_command(struct ps2dev *ps2dev); 68b28bad65SDmitry Torokhov int __ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); 69b28bad65SDmitry Torokhov int ps2_command(struct ps2dev *ps2dev, u8 *param, unsigned int command); 7008be954bSDmitry Torokhov int ps2_sliced_command(struct ps2dev *ps2dev, u8 command); 71b28bad65SDmitry Torokhov bool ps2_is_keyboard_id(u8 id); 721da177e4SLinus Torvalds 73*c4c7eac8SDmitry Torokhov irqreturn_t ps2_interrupt(struct serio *serio, u8 data, unsigned int flags); 74*c4c7eac8SDmitry Torokhov 751da177e4SLinus Torvalds #endif /* _LIBPS2_H */ 76