Commit e2200d3f authored by Hans de Goede's avatar Hans de Goede
Browse files

platform/x86: x86-android-tablets: Add gpio_keys support to x86_android_tablet_init()



Add gpio_keys instantation support to x86_android_tablet_init(), to avoid
this having to be repeated in various x86_dev_info.init() functions.

Signed-off-by: default avatarHans de Goede <hdegoede@redhat.com>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Link: https://lore.kernel.org/r/20230301092331.7038-10-hdegoede@redhat.com
parent cc183ad4
Loading
Loading
Loading
Loading
+16 −49
Original line number Diff line number Diff line
@@ -8,8 +8,6 @@
 * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com>
 */

#include <linux/gpio_keys.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/input.h>
#include <linux/platform_device.h>
@@ -26,50 +24,19 @@ static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = {
	},
};

static struct gpio_keys_button asus_me176c_tf103c_lid = {
static struct x86_gpio_button asus_me176c_tf103c_lid = {
	.button = {
		.code = SW_LID,
	/* .gpio gets filled in by asus_me176c_tf103c_init() */
		.active_low = true,
		.desc = "lid_sw",
		.type = EV_SW,
		.wakeup = true,
		.debounce_interval = 50,
};

static const struct gpio_keys_platform_data asus_me176c_tf103c_lid_pdata __initconst = {
	.buttons = &asus_me176c_tf103c_lid,
	.nbuttons = 1,
	.name = "lid_sw",
};

static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = {
	{
		.name = "gpio-keys",
		.id = PLATFORM_DEVID_AUTO,
		.data = &asus_me176c_tf103c_lid_pdata,
		.size_data = sizeof(asus_me176c_tf103c_lid_pdata),
	},
	{
		/* For micro USB ID pin handling */
		.name = "intel-int3496",
		.id = PLATFORM_DEVID_NONE,
	},
	.chip = "INT33FC:02",
	.pin = 12,
};

static int __init asus_me176c_tf103c_init(void)
{
	struct gpio_desc *gpiod;
	int ret;

	ret = x86_android_tablet_get_gpiod("INT33FC:02", 12, &gpiod);
	if (ret < 0)
		return ret;
	asus_me176c_tf103c_lid.gpio = desc_to_gpio(gpiod);

	return 0;
}


/* Asus ME176C tablets have an Android factory img with everything hardcoded */
static const char * const asus_me176c_accel_mount_matrix[] = {
	"-1", "0", "0",
@@ -203,15 +170,15 @@ static struct gpiod_lookup_table * const asus_me176c_gpios[] = {
const struct x86_dev_info asus_me176c_info __initconst = {
	.i2c_client_info = asus_me176c_i2c_clients,
	.i2c_client_count = ARRAY_SIZE(asus_me176c_i2c_clients),
	.pdev_info = asus_me176c_tf103c_pdevs,
	.pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
	.pdev_info = int3496_pdevs,
	.pdev_count = 1,
	.serdev_info = asus_me176c_serdevs,
	.serdev_count = ARRAY_SIZE(asus_me176c_serdevs),
	.gpio_button = &asus_me176c_tf103c_lid,
	.gpiod_lookup_tables = asus_me176c_gpios,
	.bat_swnode = &generic_lipo_hv_4v35_battery_node,
	.modules = bq24190_modules,
	.invalid_aei_gpiochip = "INT33FC:02",
	.init = asus_me176c_tf103c_init,
};

/* Asus TF103C tablets have an Android factory img with everything hardcoded */
@@ -348,11 +315,11 @@ static struct gpiod_lookup_table * const asus_tf103c_gpios[] = {
const struct x86_dev_info asus_tf103c_info __initconst = {
	.i2c_client_info = asus_tf103c_i2c_clients,
	.i2c_client_count = ARRAY_SIZE(asus_tf103c_i2c_clients),
	.pdev_info = asus_me176c_tf103c_pdevs,
	.pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs),
	.pdev_info = int3496_pdevs,
	.pdev_count = 1,
	.gpio_button = &asus_me176c_tf103c_lid,
	.gpiod_lookup_tables = asus_tf103c_gpios,
	.bat_swnode = &asus_tf103c_battery_node,
	.modules = bq24190_modules,
	.invalid_aei_gpiochip = "INT33FC:02",
	.init = asus_me176c_tf103c_init,
};
+29 −1
Original line number Diff line number Diff line
@@ -322,7 +322,8 @@ static __init int x86_android_tablet_init(void)
		}
	}

	pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL);
	/* + 1 to make space for (optional) gpio_keys_button pdev */
	pdevs = kcalloc(dev_info->pdev_count + 1, sizeof(*pdevs), GFP_KERNEL);
	if (!pdevs) {
		x86_android_tablet_cleanup();
		return -ENOMEM;
@@ -352,6 +353,33 @@ static __init int x86_android_tablet_init(void)
		}
	}

	if (dev_info->gpio_button) {
		struct gpio_keys_platform_data pdata = {
			.buttons = &dev_info->gpio_button->button,
			.nbuttons = 1,
		};
		struct gpio_desc *gpiod;

		/* Get GPIO for the gpio-button */
		ret = x86_android_tablet_get_gpiod(dev_info->gpio_button->chip,
						   dev_info->gpio_button->pin, &gpiod);
		if (ret < 0) {
			x86_android_tablet_cleanup();
			return ret;
		}

		dev_info->gpio_button->button.gpio = desc_to_gpio(gpiod);

		pdevs[pdev_count] = platform_device_register_data(NULL, "gpio-keys",
								  PLATFORM_DEVID_AUTO,
								  &pdata, sizeof(pdata));
		if (IS_ERR(pdevs[pdev_count])) {
			x86_android_tablet_cleanup();
			return PTR_ERR(pdevs[pdev_count]);
		}
		pdev_count++;
	}

	return 0;
}

+11 −40
Original line number Diff line number Diff line
@@ -9,8 +9,6 @@
 */

#include <linux/acpi.h>
#include <linux/gpio_keys.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h>
#include <linux/input.h>
#include <linux/platform_device.h>
@@ -96,48 +94,21 @@ const struct x86_dev_info acer_b1_750_info __initconst = {
 * which is not described in the ACPI tables in anyway.
 * Use the x86-android-tablets infra to create a gpio-button device for this.
 */
static struct gpio_keys_button advantech_mica_071_button = {
static struct x86_gpio_button advantech_mica_071_button = {
	.button = {
		.code = KEY_PROG1,
	/* .gpio gets filled in by advantech_mica_071_init() */
		.active_low = true,
		.desc = "prog1_key",
		.type = EV_KEY,
		.wakeup = false,
		.debounce_interval = 50,
};

static const struct gpio_keys_platform_data advantech_mica_071_button_pdata __initconst = {
	.buttons = &advantech_mica_071_button,
	.nbuttons = 1,
	.name = "prog1_key",
};

static const struct platform_device_info advantech_mica_071_pdevs[] __initconst = {
	{
		.name = "gpio-keys",
		.id = PLATFORM_DEVID_AUTO,
		.data = &advantech_mica_071_button_pdata,
		.size_data = sizeof(advantech_mica_071_button_pdata),
	},
	.chip = "INT33FC:00",
	.pin = 2,
};

static int __init advantech_mica_071_init(void)
{
	struct gpio_desc *gpiod;
	int ret;

	ret = x86_android_tablet_get_gpiod("INT33FC:00", 2, &gpiod);
	if (ret < 0)
		return ret;
	advantech_mica_071_button.gpio = desc_to_gpio(gpiod);

	return 0;
}

const struct x86_dev_info advantech_mica_071_info __initconst = {
	.pdev_info = advantech_mica_071_pdevs,
	.pdev_count = ARRAY_SIZE(advantech_mica_071_pdevs),
	.init = advantech_mica_071_init,
	.gpio_button = &advantech_mica_071_button,
};

/*
+8 −0
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@
#ifndef __PDX86_X86_ANDROID_TABLETS_H
#define __PDX86_X86_ANDROID_TABLETS_H

#include <linux/gpio_keys.h>
#include <linux/i2c.h>
#include <linux/irqdomain_defs.h>

@@ -58,6 +59,12 @@ struct x86_serdev_info {
	const char *serdev_hid;
};

struct x86_gpio_button {
	struct gpio_keys_button button;
	const char *chip;
	int pin;
};

struct x86_dev_info {
	char *invalid_aei_gpiochip;
	const char * const *modules;
@@ -66,6 +73,7 @@ struct x86_dev_info {
	const struct x86_i2c_client_info *i2c_client_info;
	const struct platform_device_info *pdev_info;
	const struct x86_serdev_info *serdev_info;
	struct x86_gpio_button *gpio_button;
	int i2c_client_count;
	int pdev_count;
	int serdev_count;