drivers/hid/hid-icade.c

Source file repositories/reference/linux-study-clean/drivers/hid/hid-icade.c

File Facts

System
Linux kernel
Corpus path
drivers/hid/hid-icade.c
Extension
.c
Size
5868 bytes
Lines
240
Domain
Driver Families
Bucket
drivers/hid
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 icade_key {
	u16 to;
	u8 press:1;
};

static const struct icade_key icade_usage_table[30] = {
	[26] = { KEY_UP, 1 },
	[8] = { KEY_UP, 0 },
	[7] = { KEY_RIGHT, 1 },
	[6] = { KEY_RIGHT, 0 },
	[27] = { KEY_DOWN, 1 },
	[29] = { KEY_DOWN, 0 },
	[4] = { KEY_LEFT, 1 },
	[20] = { KEY_LEFT, 0 },
	[28] = { BTN_A, 1 },
	[23] = { BTN_A, 0 },
	[11] = { BTN_B, 1 },
	[21] = { BTN_B, 0 },
	[24] = { BTN_C, 1 },
	[9] = { BTN_C, 0 },
	[13] = { BTN_X, 1 },
	[17] = { BTN_X, 0 },
	[12] = { BTN_Y, 1 },
	[16] = { BTN_Y, 0 },
	[14] = { BTN_Z, 1 },
	[19] = { BTN_Z, 0 },
	[18] = { BTN_THUMBL, 1 },
	[10] = { BTN_THUMBL, 0 },
	[15] = { BTN_THUMBR, 1 },
	[25] = { BTN_THUMBR, 0 },
};

static const struct icade_key *icade_find_translation(u16 from)
{
	if (from > ICADE_MAX_USAGE)
		return NULL;
	return &icade_usage_table[from];
}

static int icade_event(struct hid_device *hdev, struct hid_field *field,
		struct hid_usage *usage, __s32 value)
{
	const struct icade_key *trans;

	if (!(hdev->claimed & HID_CLAIMED_INPUT) || !field->hidinput ||
			!usage->type)
		return 0;

	/* We ignore the fake key up, and act only on key down */
	if (!value)
		return 1;

	trans = icade_find_translation(usage->hid & HID_USAGE);

	if (!trans)
		return 1;

	input_event(field->hidinput->input, usage->type,
			trans->to, trans->press);

	return 1;
}

static int icade_input_mapping(struct hid_device *hdev, struct hid_input *hi,
		struct hid_field *field, struct hid_usage *usage,
		unsigned long **bit, int *max)
{
	const struct icade_key *trans;

	if ((usage->hid & HID_USAGE_PAGE) == HID_UP_KEYBOARD) {
		trans = icade_find_translation(usage->hid & HID_USAGE);

		if (!trans)
			return -1;

		hid_map_usage(hi, usage, bit, max, EV_KEY, trans->to);
		set_bit(trans->to, hi->input->keybit);

		return 1;
	}

	/* ignore others */
	return -1;

}

static int icade_input_mapped(struct hid_device *hdev, struct hid_input *hi,
		struct hid_field *field, struct hid_usage *usage,
		unsigned long **bit, int *max)
{

Annotation

Implementation Notes