drivers/input/rmi4/rmi_f21.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/rmi4/rmi_f21.c
Extension
.c
Size
4695 bytes
Lines
180
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 f21_data {
	struct input_dev *input;
	u16 key_code;

	unsigned int attn_data_size;
	unsigned int attn_data_button_offset;

	unsigned int data_reg_size;
	unsigned int data_reg_button_offset;
	u8 data_regs[RMI_F21_DATA_REGS_MAX_SIZE];
};

static irqreturn_t rmi_f21_attention(int irq, void *ctx)
{
	struct rmi_function *fn = ctx;
	struct f21_data *f21 = dev_get_drvdata(&fn->dev);
	struct rmi_driver_data *drvdata = dev_get_drvdata(&fn->rmi_dev->dev);
	u8 *pdata;
	int error;
	bool pressed;

	if (drvdata->attn_data.data) {
		if (drvdata->attn_data.size < f21->attn_data_size) {
			dev_warn(&fn->dev, "f21 interrupt, but data is missing\n");
			return IRQ_HANDLED;
		}

		pdata = drvdata->attn_data.data + f21->attn_data_button_offset;

		drvdata->attn_data.data += f21->attn_data_size;
		drvdata->attn_data.size -= f21->attn_data_size;
	} else {
		error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr,
				       f21->data_regs, f21->data_reg_size);
		if (error) {
			dev_err(&fn->dev, "failed to read f21 data registers: %d\n",
				error);
			return IRQ_RETVAL(error);
		}

		pdata = f21->data_regs + f21->data_reg_button_offset;
	}

	pressed = *pdata & RMI_F21_FORCE_CLICK_BIT;
	input_report_key(f21->input, f21->key_code, pressed);

	return IRQ_HANDLED;
}

static int rmi_f21_config(struct rmi_function *fn)
{
	struct rmi_driver *drv = fn->rmi_dev->driver;

	drv->set_irq_bits(fn->rmi_dev, fn->irq_mask);

	return 0;
}

static int rmi_f21_initialize(struct rmi_function *fn, struct f21_data *f21)
{
	struct input_dev *input = f21->input;

	f21->key_code = BTN_LEFT;

	input->keycode = &f21->key_code;
	input->keycodesize = sizeof(f21->key_code);
	input->keycodemax = RMI_F21_FORCEPAD_BUTTON_COUNT;

	input_set_capability(input, EV_KEY, f21->key_code);
	__set_bit(INPUT_PROP_BUTTONPAD, input->propbit);

	return 0;
}

static int rmi_f21_probe(struct rmi_function *fn)
{
	struct rmi_device *rmi_dev = fn->rmi_dev;
	struct rmi_driver_data *drv_data = dev_get_drvdata(&rmi_dev->dev);
	struct f21_data *f21;
	unsigned int sensor_count;
	unsigned int max_fingers;
	unsigned int query15_offset;
	u8 query15_data;
	int error;

	if (!drv_data->input) {
		dev_info(&fn->dev, "f21: no input device found, ignoring\n");
		return -ENXIO;
	}

Annotation

Implementation Notes