Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c611763d authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: add ps2_drain() to libps2 to allow reading and discarding


       given number of bytes from device. Change ps2_command to
       allow using 0 as command ID and actually pass it to the
       device instead of working as a drain.

Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 04df1925
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -270,7 +270,6 @@ static struct alps_model_info *alps_get_model(struct psmouse *psmouse, int *vers
static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
{
{
	struct ps2dev *ps2dev = &psmouse->ps2dev;
	struct ps2dev *ps2dev = &psmouse->ps2dev;
	unsigned char param[3];
	int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;
	int cmd = enable ? PSMOUSE_CMD_SETSCALE21 : PSMOUSE_CMD_SETSCALE11;


	if (ps2_command(ps2dev, NULL, cmd) ||
	if (ps2_command(ps2dev, NULL, cmd) ||
@@ -280,7 +279,7 @@ static int alps_passthrough_mode(struct psmouse *psmouse, int enable)
		return -1;
		return -1;


	/* we may get 3 more bytes, just ignore them */
	/* we may get 3 more bytes, just ignore them */
	ps2_command(ps2dev, param, 0x0300);
	ps2_drain(ps2dev, 3, 100);


	return 0;
	return 0;
}
}
+38 −8
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ MODULE_LICENSE("GPL");


EXPORT_SYMBOL(ps2_init);
EXPORT_SYMBOL(ps2_init);
EXPORT_SYMBOL(ps2_sendbyte);
EXPORT_SYMBOL(ps2_sendbyte);
EXPORT_SYMBOL(ps2_drain);
EXPORT_SYMBOL(ps2_command);
EXPORT_SYMBOL(ps2_command);
EXPORT_SYMBOL(ps2_schedule_command);
EXPORT_SYMBOL(ps2_schedule_command);
EXPORT_SYMBOL(ps2_handle_ack);
EXPORT_SYMBOL(ps2_handle_ack);
@@ -45,11 +46,11 @@ struct ps2work {




/*
/*
 * ps2_sendbyte() sends a byte to the mouse, and waits for acknowledge.
 * ps2_sendbyte() sends a byte to the device and waits for acknowledge.
 * It doesn't handle retransmission, though it could - because when there would
 * It doesn't handle retransmission, though it could - because if there
 * be need for retransmissions, the mouse has to be replaced anyway.
 * is a need for retransmissions device has to be replaced anyway.
 *
 *
 * ps2_sendbyte() can only be called from a process context
 * ps2_sendbyte() can only be called from a process context.
 */
 */


int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
@@ -71,6 +72,31 @@ int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout)
	return -ps2dev->nak;
	return -ps2dev->nak;
}
}


/*
 * ps2_drain() waits for device to transmit requested number of bytes
 * and discards them.
 */

void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout)
{
	if (maxbytes > sizeof(ps2dev->cmdbuf)) {
		WARN_ON(1);
		maxbytes = sizeof(ps2dev->cmdbuf);
	}

	down(&ps2dev->cmd_sem);

	serio_pause_rx(ps2dev->serio);
	ps2dev->flags = PS2_FLAG_CMD;
	ps2dev->cmdcnt = maxbytes;
	serio_continue_rx(ps2dev->serio);

	wait_event_timeout(ps2dev->wait,
			   !(ps2dev->flags & PS2_FLAG_CMD),
			   msecs_to_jiffies(timeout));
	up(&ps2dev->cmd_sem);
}

/*
/*
 * ps2_command() sends a command and its parameters to the mouse,
 * ps2_command() sends a command and its parameters to the mouse,
 * then waits for the response and puts it in the param array.
 * then waits for the response and puts it in the param array.
@@ -86,6 +112,11 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
	int rc = -1;
	int rc = -1;
	int i;
	int i;


	if (receive > sizeof(ps2dev->cmdbuf)) {
		WARN_ON(1);
		return -1;
	}

	down(&ps2dev->cmd_sem);
	down(&ps2dev->cmd_sem);


	serio_pause_rx(ps2dev->serio);
	serio_pause_rx(ps2dev->serio);
@@ -101,7 +132,6 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
	 * ACKing the reset command, and so it can take a long
	 * ACKing the reset command, and so it can take a long
	 * time before the ACK arrrives.
	 * time before the ACK arrrives.
	 */
	 */
	if (command & 0xff)
	if (ps2_sendbyte(ps2dev, command & 0xff,
	if (ps2_sendbyte(ps2dev, command & 0xff,
			 command == PS2_CMD_RESET_BAT ? 1000 : 200))
			 command == PS2_CMD_RESET_BAT ? 1000 : 200))
		goto out;
		goto out;
+1 −0
Original line number Original line Diff line number Diff line
@@ -41,6 +41,7 @@ struct ps2dev {


void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
void ps2_init(struct ps2dev *ps2dev, struct serio *serio);
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
int ps2_sendbyte(struct ps2dev *ps2dev, unsigned char byte, int timeout);
void ps2_drain(struct ps2dev *ps2dev, int maxbytes, int timeout);
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_schedule_command(struct ps2dev *ps2dev, unsigned char *param, int command);
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);
int ps2_handle_ack(struct ps2dev *ps2dev, unsigned char data);