drivers/input/keyboard/pxa27x_keypad.c

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

File Facts

System
Linux kernel
Corpus path
drivers/input/keyboard/pxa27x_keypad.c
Extension
.c
Size
18620 bytes
Lines
707
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 pxa27x_keypad_rotary {
	unsigned short *key_codes;
	int rel_code;
	bool enabled;
};

struct pxa27x_keypad {
	struct clk *clk;
	struct input_dev *input_dev;
	void __iomem *mmio_base;

	int irq;

	unsigned int matrix_key_rows;
	unsigned int matrix_key_cols;
	unsigned int row_shift;

	unsigned int direct_key_num;
	unsigned int direct_key_mask;
	bool direct_key_low_active;

	/* key debounce interval */
	unsigned int debounce_interval;

	unsigned short keycodes[MAX_KEYPAD_KEYS];

	/* state row bits of each column scan */
	u32 matrix_key_state[MAX_MATRIX_KEY_COLS];
	u32 direct_key_state;

	struct pxa27x_keypad_rotary rotary[MAX_ROTARY_ENCODERS];
};

static int pxa27x_keypad_matrix_key_parse(struct pxa27x_keypad *keypad)
{
	struct input_dev *input_dev = keypad->input_dev;
	struct device *dev = input_dev->dev.parent;
	int error;

	error = matrix_keypad_parse_properties(dev, &keypad->matrix_key_rows,
					       &keypad->matrix_key_cols);
	if (error)
		return error;

	if (keypad->matrix_key_rows > MAX_MATRIX_KEY_ROWS ||
	    keypad->matrix_key_cols > MAX_MATRIX_KEY_COLS) {
		dev_err(dev, "rows or cols exceeds maximum value\n");
		return -EINVAL;
	}

	keypad->row_shift = get_count_order(keypad->matrix_key_cols);

	error = matrix_keypad_build_keymap(NULL, NULL,
					   keypad->matrix_key_rows,
					   keypad->matrix_key_cols,
					   keypad->keycodes, input_dev);
	if (error)
		return error;

	return 0;
}

static int pxa27x_keypad_direct_key_parse(struct pxa27x_keypad *keypad)
{
	struct input_dev *input_dev = keypad->input_dev;
	struct device *dev = input_dev->dev.parent;
	unsigned short code;
	int count;
	int i;
	int error;

	error = device_property_read_u32(dev, "marvell,direct-key-count",
					 &keypad->direct_key_num);
	if (error) {
		/*
		 * If do not have marvel,direct-key-count defined,
		 * it means direct key is not supported.
		 */
		return error == -EINVAL ? 0 : error;
	}

	error = device_property_read_u32(dev, "marvell,direct-key-mask",
					 &keypad->direct_key_mask);
	if (error) {
		if (error != -EINVAL)
			return error;

		/*
		 * If marvell,direct-key-mask is not defined, driver will use
		 * a default value based on number of direct keys set up.

Annotation

Implementation Notes