drivers/input/touch-overlay.c

Source file repositories/reference/linux-study-clean/drivers/input/touch-overlay.c

File Facts

System
Linux kernel
Corpus path
drivers/input/touch-overlay.c
Extension
.c
Size
7763 bytes
Lines
279
Domain
Driver Families
Bucket
drivers/input
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 touch_overlay_segment {
	struct list_head list;
	u32 x_origin;
	u32 y_origin;
	u32 x_size;
	u32 y_size;
	u32 key;
	bool pressed;
	int slot;
};

static int touch_overlay_get_segment(struct fwnode_handle *segment_node,
				     struct touch_overlay_segment *segment,
				     struct input_dev *input)
{
	int error;

	error = fwnode_property_read_u32(segment_node, "x-origin",
					 &segment->x_origin);
	if (error)
		return error;

	error = fwnode_property_read_u32(segment_node, "y-origin",
					 &segment->y_origin);
	if (error)
		return error;

	error = fwnode_property_read_u32(segment_node, "x-size",
					 &segment->x_size);
	if (error)
		return error;

	error = fwnode_property_read_u32(segment_node, "y-size",
					 &segment->y_size);
	if (error)
		return error;

	error = fwnode_property_read_u32(segment_node, "linux,code",
					 &segment->key);
	if (!error)
		input_set_capability(input, EV_KEY, segment->key);
	else if (error != -EINVAL)
		return error;

	return 0;
}

/**
 * touch_overlay_map - map overlay objects from the device tree and set
 * key capabilities if buttons are defined.
 * @list: pointer to the list that will hold the segments
 * @input: pointer to the already allocated input_dev
 *
 * Returns 0 on success and error number otherwise.
 *
 * If buttons are defined, key capabilities are set accordingly.
 */
int touch_overlay_map(struct list_head *list, struct input_dev *input)
{
	struct fwnode_handle *fw_segment;
	struct device *dev = input->dev.parent;
	struct touch_overlay_segment *segment;
	int error;

	struct fwnode_handle *overlay __free(fwnode_handle) =
		device_get_named_child_node(dev, "touch-overlay");
	if (!overlay)
		return 0;

	fwnode_for_each_available_child_node(overlay, fw_segment) {
		segment = devm_kzalloc(dev, sizeof(*segment), GFP_KERNEL);
		if (!segment) {
			fwnode_handle_put(fw_segment);
			return -ENOMEM;
		}
		error = touch_overlay_get_segment(fw_segment, segment, input);
		if (error) {
			fwnode_handle_put(fw_segment);
			return error;
		}
		list_add_tail(&segment->list, list);
	}

	return 0;
}
EXPORT_SYMBOL(touch_overlay_map);

/**
 * touch_overlay_get_touchscreen_abs - get abs size from the touchscreen area.
 * @list: pointer to the list that holds the segments

Annotation

Implementation Notes