drivers/input/keyboard/hil_kbd.c

Source file repositories/reference/linux-study-clean/drivers/input/keyboard/hil_kbd.c

File Facts

System
Linux kernel
Corpus path
drivers/input/keyboard/hil_kbd.c
Extension
.c
Size
14902 bytes
Lines
587
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 hil_dev {
	struct input_dev *dev;
	struct serio *serio;

	/* Input buffer and index for packets from HIL bus. */
	hil_packet data[HIL_PACKET_MAX_LENGTH];
	int idx4; /* four counts per packet */

	/* Raw device info records from HIL bus, see hil.h for fields. */
	char	idd[HIL_PACKET_MAX_LENGTH];	/* DID byte and IDD record */
	char	rsc[HIL_PACKET_MAX_LENGTH];	/* RSC record */
	char	exd[HIL_PACKET_MAX_LENGTH];	/* EXD record */
	char	rnm[HIL_PACKET_MAX_LENGTH + 1];	/* RNM record + NULL term. */

	struct completion cmd_done;

	bool is_pointer;
	/* Extra device details needed for pointing devices. */
	unsigned int nbtn, naxes;
	unsigned int btnmap[7];
};

static bool hil_dev_is_command_response(hil_packet p)
{
	if ((p & ~HIL_CMDCT_POL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_POL))
		return false;

	if ((p & ~HIL_CMDCT_RPL) == (HIL_ERR_INT | HIL_PKT_CMD | HIL_CMD_RPL))
		return false;

	return true;
}

static void hil_dev_handle_command_response(struct hil_dev *dev)
{
	hil_packet p;
	char *buf;
	int i, idx;

	idx = dev->idx4 / 4;
	p = dev->data[idx - 1];

	switch (p & HIL_PKT_DATA_MASK) {
	case HIL_CMD_IDD:
		buf = dev->idd;
		break;

	case HIL_CMD_RSC:
		buf = dev->rsc;
		break;

	case HIL_CMD_EXD:
		buf = dev->exd;
		break;

	case HIL_CMD_RNM:
		dev->rnm[HIL_PACKET_MAX_LENGTH] = 0;
		buf = dev->rnm;
		break;

	default:
		/* These occur when device isn't present */
		if (p != (HIL_ERR_INT | HIL_PKT_CMD)) {
			/* Anything else we'd like to know about. */
			printk(KERN_WARNING PREFIX "Device sent unknown record %x\n", p);
		}
		goto out;
	}

	for (i = 0; i < idx; i++)
		buf[i] = dev->data[i] & HIL_PKT_DATA_MASK;
	for (; i < HIL_PACKET_MAX_LENGTH; i++)
		buf[i] = 0;
 out:
	complete(&dev->cmd_done);
}

static void hil_dev_handle_kbd_events(struct hil_dev *kbd)
{
	struct input_dev *dev = kbd->dev;
	int idx = kbd->idx4 / 4;
	int i;

	switch (kbd->data[0] & HIL_POL_CHARTYPE_MASK) {
	case HIL_POL_CHARTYPE_NONE:
		return;

	case HIL_POL_CHARTYPE_ASCII:
		for (i = 1; i < idx - 1; i++)
			input_report_key(dev, kbd->data[i] & 0x7f, 1);

Annotation

Implementation Notes