drivers/input/mouse/logips2pp.c

Source file repositories/reference/linux-study-clean/drivers/input/mouse/logips2pp.c

File Facts

System
Linux kernel
Corpus path
drivers/input/mouse/logips2pp.c
Extension
.c
Size
11626 bytes
Lines
445
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct ps2pp_info {
	u8 model;
	u8 kind;
	u16 features;
};

/*
 * Process a PS2++ or PS2T++ packet.
 */

static psmouse_ret_t ps2pp_process_byte(struct psmouse *psmouse)
{
	struct input_dev *dev = psmouse->dev;
	u8 *packet = psmouse->packet;

	if (psmouse->pktcnt < 3)
		return PSMOUSE_GOOD_DATA;

/*
 * Full packet accumulated, process it
 */

	if ((packet[0] & 0x48) == 0x48 && (packet[1] & 0x02) == 0x02) {

		/* Logitech extended packet */
		switch ((packet[1] >> 4) | (packet[0] & 0x30)) {

		case 0x0d: /* Mouse extra info */

			input_report_rel(dev,
				packet[2] & 0x80 ? REL_HWHEEL : REL_WHEEL,
				-sign_extend32(packet[2], 3));
			input_report_key(dev, BTN_SIDE,  packet[2] & BIT(4));
			input_report_key(dev, BTN_EXTRA, packet[2] & BIT(5));

			break;

		case 0x0e: /* buttons 4, 5, 6, 7, 8, 9, 10 info */

			input_report_key(dev, BTN_SIDE,    packet[2] & BIT(0));
			input_report_key(dev, BTN_EXTRA,   packet[2] & BIT(1));
			input_report_key(dev, BTN_TASK,    packet[2] & BIT(2));
			input_report_key(dev, BTN_BACK,    packet[2] & BIT(3));
			input_report_key(dev, BTN_FORWARD, packet[2] & BIT(4));

			break;

		case 0x0f: /* TouchPad extra info */

			input_report_rel(dev,
				packet[2] & 0x08 ? REL_HWHEEL : REL_WHEEL,
				-sign_extend32(packet[2] >> 4, 3));
			packet[0] = packet[2] | BIT(3);
			break;

		default:
			psmouse_dbg(psmouse,
				    "Received PS2++ packet #%x, but don't know how to handle.\n",
				    (packet[1] >> 4) | (packet[0] & 0x30));
			break;
		}

		psmouse_report_standard_buttons(dev, packet[0]);

	} else {
		/* Standard PS/2 motion data */
		psmouse_report_standard_packet(dev, packet);
	}

	input_sync(dev);

	return PSMOUSE_FULL_PACKET;

}

/*
 * ps2pp_cmd() sends a PS2++ command, sliced into two bit
 * pieces through the SETRES command. This is needed to send extended
 * commands to mice on notebooks that try to understand the PS/2 protocol
 * Ugly.
 */

static int ps2pp_cmd(struct psmouse *psmouse, u8 *param, u8 command)
{
	int error;

	error = ps2_sliced_command(&psmouse->ps2dev, command);
	if (error)
		return error;

Annotation

Implementation Notes