drivers/input/rmi4/rmi_f03.c

Source file repositories/reference/linux-study-clean/drivers/input/rmi4/rmi_f03.c

File Facts

System
Linux kernel
Corpus path
drivers/input/rmi4/rmi_f03.c
Extension
.c
Size
7944 bytes
Lines
329
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 f03_data {
	struct rmi_function *fn;

	struct serio *serio;
	bool serio_registered;

	unsigned int overwrite_buttons;

	u8 device_count;
	u8 rx_queue_length;
};

int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
			     int value)
{
	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
	unsigned int bit;

	if (button < BTN_LEFT || button > BTN_MIDDLE)
		return -EINVAL;

	bit = BIT(button - BTN_LEFT);

	if (value)
		f03->overwrite_buttons |= bit;
	else
		f03->overwrite_buttons &= ~bit;

	return 0;
}

void rmi_f03_commit_buttons(struct rmi_function *fn)
{
	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
	struct serio *serio = f03->serio;

	guard(serio_pause_rx)(serio);

	if (serio->drv) {
		serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
				      SERIO_OOB_DATA);
		serio->drv->interrupt(serio, f03->overwrite_buttons,
				      SERIO_OOB_DATA);
	}
}

static int rmi_f03_pt_write(struct serio *id, unsigned char val)
{
	struct f03_data *f03 = id->port_data;
	int error;

	rmi_dbg(RMI_DEBUG_FN, &f03->fn->dev,
		"%s: Wrote %.2hhx to PS/2 passthrough address",
		__func__, val);

	error = rmi_write(f03->fn->rmi_dev, f03->fn->fd.data_base_addr, val);
	if (error) {
		dev_err(&f03->fn->dev,
			"%s: Failed to write to F03 TX register (%d).\n",
			__func__, error);
		return error;
	}

	return 0;
}

static int rmi_f03_initialize(struct f03_data *f03)
{
	struct rmi_function *fn = f03->fn;
	struct device *dev = &fn->dev;
	int error;
	u8 bytes_per_device;
	u8 query1;
	u8 query2[RMI_F03_DEVICE_COUNT * RMI_F03_BYTES_PER_DEVICE];
	size_t query2_len;

	error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &query1);
	if (error) {
		dev_err(dev, "Failed to read query register (%d).\n", error);
		return error;
	}

	f03->device_count = query1 & RMI_F03_DEVICE_COUNT;
	bytes_per_device = (query1 >> RMI_F03_BYTES_PER_DEVICE_SHIFT) &
				RMI_F03_BYTES_PER_DEVICE;

	query2_len = f03->device_count * bytes_per_device;

	/*
	 * The first generation of image sensors don't have a second part to

Annotation

Implementation Notes