drivers/input/misc/soc_button_array.c

Source file repositories/reference/linux-study-clean/drivers/input/misc/soc_button_array.c

File Facts

System
Linux kernel
Corpus path
drivers/input/misc/soc_button_array.c
Extension
.c
Size
18589 bytes
Lines
625
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 soc_button_info {
	const char *name;
	int acpi_index;
	unsigned int event_type;
	unsigned int event_code;
	bool autorepeat;
	bool wakeup;
	bool active_low;
};

struct soc_device_data {
	const struct soc_button_info *button_info;
	int (*check)(struct device *dev);
};

/*
 * Some of the buttons like volume up/down are auto repeat, while others
 * are not. To support both, we register two platform devices, and put
 * buttons into them based on whether the key should be auto repeat.
 */
#define BUTTON_TYPES	2

struct soc_button_data {
	struct platform_device *children[BUTTON_TYPES];
};

/*
 * Some 2-in-1s which use the soc_button_array driver have this ugly issue in
 * their DSDT where the _LID method modifies the irq-type settings of the GPIOs
 * used for the power and home buttons. The intend of this AML code is to
 * disable these buttons when the lid is closed.
 * The AML does this by directly poking the GPIO controllers registers. This is
 * problematic because when re-enabling the irq, which happens whenever _LID
 * gets called with the lid open (e.g. on boot and on resume), it sets the
 * irq-type to IRQ_TYPE_LEVEL_LOW. Where as the gpio-keys driver programs the
 * type to, and expects it to be, IRQ_TYPE_EDGE_BOTH.
 * To work around this we don't set gpio_keys_button.gpio on these 2-in-1s,
 * instead we get the irq for the GPIO ourselves, configure it as
 * IRQ_TYPE_LEVEL_LOW (to match how the _LID AML code configures it) and pass
 * the irq in gpio_keys_button.irq. Below is a list of affected devices.
 */
static const struct dmi_system_id dmi_use_low_level_irq[] = {
	{
		/*
		 * Acer Switch 10 SW5-012. _LID method messes with home- and
		 * power-button GPIO IRQ settings. When (re-)enabling the irq
		 * it ors in its own flags without clearing the previous set
		 * ones, leading to an irq-type of IRQ_TYPE_LEVEL_LOW |
		 * IRQ_TYPE_LEVEL_HIGH causing a continuous interrupt storm.
		 */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "Aspire SW5-012"),
		},
	},
	{
		/* Acer Switch V 10 SW5-017, same issue as Acer Switch 10 SW5-012. */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "SW5-017"),
		},
	},
	{
		/*
		 * Acer One S1003. _LID method messes with power-button GPIO
		 * IRQ settings, leading to a non working power-button.
		 */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
			DMI_MATCH(DMI_PRODUCT_NAME, "One S1003"),
		},
	},
	{
		/*
		 * Lenovo Yoga Tab2 1051F/1051L, something messes with the home-button
		 * IRQ settings, leading to a non working home-button.
		 */
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"),
			DMI_MATCH(DMI_PRODUCT_NAME, "60073"),
			DMI_MATCH(DMI_PRODUCT_VERSION, "1051"),
		},
	},
	{} /* Terminating entry */
};

/*
 * Some devices have a wrong entry which points to a GPIO which is
 * required in another driver, so this driver must not claim it.
 */

Annotation

Implementation Notes