diff options
Diffstat (limited to 'drivers/platform/x86/x86-android-tablets')
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/Makefile | 2 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/acer.c | 247 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/asus.c | 108 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/core.c | 121 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/dmi.c | 12 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/lenovo.c | 291 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/other.c | 334 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/shared-psy-info.c | 34 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/shared-psy-info.h | 8 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c | 2 | ||||
-rw-r--r-- | drivers/platform/x86/x86-android-tablets/x86-android-tablets.h | 28 |
11 files changed, 707 insertions, 480 deletions
diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index 313be30548bc..a2cf8cbdb351 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -6,4 +6,4 @@ obj-$(CONFIG_X86_ANDROID_TABLETS) += vexia_atla10_ec.o obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o x86-android-tablets-y := core.o dmi.o shared-psy-info.o \ - asus.o lenovo.o other.o + acer.o asus.o lenovo.o other.o diff --git a/drivers/platform/x86/x86-android-tablets/acer.c b/drivers/platform/x86/x86-android-tablets/acer.c new file mode 100644 index 000000000000..d48c70ffd992 --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/acer.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Board info for Acer X86 tablets which ship with Android as the factory image + * and which have broken DSDT tables. The factory kernels shipped on these + * devices typically have a bunch of things hardcoded, rather than specified + * in their DSDT. + * + * Copyright (C) 2021-2025 Hans de Goede <hansg@kernel.org> + */ + +#include <linux/gpio/machine.h> +#include <linux/gpio/property.h> +#include <linux/platform_device.h> +#include <linux/property.h> + +#include "shared-psy-info.h" +#include "x86-android-tablets.h" + +/* Acer Iconia One 8 A1-840 (non FHD version) */ +static const struct property_entry acer_a1_840_bq24190_props[] = { + PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_4v2_battery_node), + PROPERTY_ENTRY_BOOL("omit-battery-class"), + PROPERTY_ENTRY_BOOL("disable-reset"), + { } +}; + +static const struct software_node acer_a1_840_bq24190_node = { + .properties = acer_a1_840_bq24190_props, +}; + +static const struct property_entry acer_a1_840_touchscreen_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 800), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node acer_a1_840_touchscreen_node = { + .properties = acer_a1_840_touchscreen_props, +}; + +static const struct x86_i2c_client_info acer_a1_840_i2c_clients[] __initconst = { + { + /* BQ24297 charger IC */ + .board_info = { + .type = "bq24297", + .addr = 0x6b, + .dev_name = "bq24297", + .swnode = &acer_a1_840_bq24190_node, + .platform_data = &bq24190_pdata, + }, + .adapter_path = "\\_SB_.I2C1", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FC:02", + .index = 2, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + .con_id = "bq24297_irq", + }, + }, { + /* MPU6515 sensors */ + .board_info = { + .type = "mpu6515", + .addr = 0x69, + .dev_name = "mpu6515", + }, + .adapter_path = "\\_SB_.I2C3", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_APIC, + .index = 0x47, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_HIGH, + }, + }, { + /* FT5416 touchscreen controller */ + .board_info = { + .type = "edt-ft5x06", + .addr = 0x38, + .dev_name = "ft5416", + .swnode = &acer_a1_840_touchscreen_node, + }, + .adapter_path = "\\_SB_.I2C4", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_APIC, + .index = 0x45, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_HIGH, + }, + } +}; + +static const struct property_entry acer_a1_840_int3496_props[] __initconst = { + PROPERTY_ENTRY_GPIO("mux-gpios", &baytrail_gpiochip_nodes[2], 1, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 18, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct platform_device_info acer_a1_840_pdevs[] __initconst = { + { + /* For micro USB ID pin handling */ + .name = "intel-int3496", + .id = PLATFORM_DEVID_NONE, + .properties = acer_a1_840_int3496_props, + }, +}; + +/* Properties for the Dollar Cove TI PMIC battery MFD child used as fuel-gauge */ +static const struct property_entry acer_a1_840_fg_props[] = { + PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_4v2_battery_node), + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), + PROPERTY_ENTRY_GPIO("charged-gpios", &baytrail_gpiochip_nodes[2], 10, GPIO_ACTIVE_HIGH), + { } +}; + +static struct device *acer_a1_840_fg_dev; +static struct fwnode_handle *acer_a1_840_fg_node; + +static int __init acer_a1_840_init(struct device *dev) +{ + int ret; + + acer_a1_840_fg_dev = bus_find_device_by_name(&platform_bus_type, NULL, "chtdc_ti_battery"); + if (!acer_a1_840_fg_dev) + return dev_err_probe(dev, -EPROBE_DEFER, "getting chtdc_ti_battery dev\n"); + + acer_a1_840_fg_node = fwnode_create_software_node(acer_a1_840_fg_props, NULL); + if (IS_ERR(acer_a1_840_fg_node)) { + ret = PTR_ERR(acer_a1_840_fg_node); + goto err_put; + } + + ret = device_add_software_node(acer_a1_840_fg_dev, + to_software_node(acer_a1_840_fg_node)); + if (ret) + goto err_put; + + return 0; + +err_put: + fwnode_handle_put(acer_a1_840_fg_node); + acer_a1_840_fg_node = NULL; + put_device(acer_a1_840_fg_dev); + acer_a1_840_fg_dev = NULL; + return ret; +} + +static void acer_a1_840_exit(void) +{ + device_remove_software_node(acer_a1_840_fg_dev); + /* + * Skip fwnode_handle_put(acer_a1_840_fg_node), instead leak the node. + * The intel_dc_ti_battery driver may still reference the strdup-ed + * "supplied-from" string. This string will be free-ed if the node + * is released. + */ + acer_a1_840_fg_node = NULL; + put_device(acer_a1_840_fg_dev); + acer_a1_840_fg_dev = NULL; +} + +static const char * const acer_a1_840_modules[] __initconst = { + "bq24190_charger", /* For the Vbus regulator for intel-int3496 */ + NULL +}; + +const struct x86_dev_info acer_a1_840_info __initconst = { + .i2c_client_info = acer_a1_840_i2c_clients, + .i2c_client_count = ARRAY_SIZE(acer_a1_840_i2c_clients), + .pdev_info = acer_a1_840_pdevs, + .pdev_count = ARRAY_SIZE(acer_a1_840_pdevs), + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, + .swnode_group = generic_lipo_4v2_battery_swnodes, + .modules = acer_a1_840_modules, + .init = acer_a1_840_init, + .exit = acer_a1_840_exit, +}; + +/* Acer Iconia One 7 B1-750 has an Android factory image with everything hardcoded */ +static const char * const acer_b1_750_mount_matrix[] = { + "-1", "0", "0", + "0", "1", "0", + "0", "0", "1" +}; + +static const struct property_entry acer_b1_750_bma250e_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix), + { } +}; + +static const struct software_node acer_b1_750_bma250e_node = { + .properties = acer_b1_750_bma250e_props, +}; + +static const struct property_entry acer_b1_750_novatek_props[] = { + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node acer_b1_750_novatek_node = { + .properties = acer_b1_750_novatek_props, +}; + +static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = { + { + /* Novatek NVT-ts touchscreen */ + .board_info = { + .type = "nt11205-ts", + .addr = 0x34, + .dev_name = "NVT-ts", + .swnode = &acer_b1_750_novatek_node, + }, + .adapter_path = "\\_SB_.I2C4", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FC:02", + .index = 3, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + .con_id = "NVT-ts_irq", + }, + }, { + /* BMA250E accelerometer */ + .board_info = { + .type = "bma250e", + .addr = 0x18, + .swnode = &acer_b1_750_bma250e_node, + }, + .adapter_path = "\\_SB_.I2C3", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FC:02", + .index = 25, + .trigger = ACPI_LEVEL_SENSITIVE, + .polarity = ACPI_ACTIVE_HIGH, + .con_id = "bma250e_irq", + }, + }, +}; + +const struct x86_dev_info acer_b1_750_info __initconst = { + .i2c_client_info = acer_b1_750_i2c_clients, + .i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients), + .pdev_info = int3496_pdevs, + .pdev_count = 1, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, +}; diff --git a/drivers/platform/x86/x86-android-tablets/asus.c b/drivers/platform/x86/x86-android-tablets/asus.c index 97cd14c1fd23..7d29c7654d21 100644 --- a/drivers/platform/x86/x86-android-tablets/asus.c +++ b/drivers/platform/x86/x86-android-tablets/asus.c @@ -5,36 +5,55 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #include <linux/gpio/machine.h> -#include <linux/input.h> +#include <linux/gpio/property.h> +#include <linux/input-event-codes.h> #include <linux/platform_device.h> #include "shared-psy-info.h" #include "x86-android-tablets.h" /* Asus ME176C and TF103C tablets shared data */ -static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = { - .dev_id = "intel-int3496", - .table = { - GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH), - { } - }, +static const struct property_entry asus_me176c_tf103c_int3496_props[] __initconst = { + PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 22, GPIO_ACTIVE_HIGH), + { } }; -static const struct x86_gpio_button asus_me176c_tf103c_lid __initconst = { - .button = { - .code = SW_LID, - .active_low = true, - .desc = "lid_sw", - .type = EV_SW, - .wakeup = true, - .debounce_interval = 50, +static const struct platform_device_info asus_me176c_tf103c_pdevs[] __initconst = { + { + /* For micro USB ID pin handling */ + .name = "intel-int3496", + .id = PLATFORM_DEVID_NONE, + .properties = asus_me176c_tf103c_int3496_props, }, - .chip = "INT33FC:02", - .pin = 12, +}; + +static const struct software_node asus_me176c_tf103c_gpio_keys_node = { + .name = "lid_sw", +}; + +static const struct property_entry asus_me176c_tf103c_lid_props[] = { + PROPERTY_ENTRY_U32("linux,input-type", EV_SW), + PROPERTY_ENTRY_U32("linux,code", SW_LID), + PROPERTY_ENTRY_STRING("label", "lid_sw"), + PROPERTY_ENTRY_GPIO("gpios", &baytrail_gpiochip_nodes[2], 12, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), + PROPERTY_ENTRY_BOOL("wakeup-source"), + { } +}; + +static const struct software_node asus_me176c_tf103c_lid_node = { + .parent = &asus_me176c_tf103c_gpio_keys_node, + .properties = asus_me176c_tf103c_lid_props, +}; + +static const struct software_node *asus_me176c_tf103c_lid_swnodes[] = { + &asus_me176c_tf103c_gpio_keys_node, + &asus_me176c_tf103c_lid_node, + NULL }; /* Asus ME176C tablets have an Android factory image with everything hardcoded */ @@ -77,6 +96,16 @@ static const struct software_node asus_me176c_ug3105_node = { .properties = asus_me176c_ug3105_props, }; +static const struct property_entry asus_me176c_touchscreen_props[] = { + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[0], 60, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("irq-gpios", &baytrail_gpiochip_nodes[2], 28, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node asus_me176c_touchscreen_node = { + .properties = asus_me176c_touchscreen_props, +}; + static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = { { /* bq24297 battery charger */ @@ -132,6 +161,7 @@ static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = .type = "GDIX1001:00", .addr = 0x14, .dev_name = "goodix_ts", + .swnode = &asus_me176c_touchscreen_node, }, .adapter_path = "\\_SB_.I2C6", .irq_data = { @@ -152,33 +182,17 @@ static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = { }, }; -static struct gpiod_lookup_table asus_me176c_goodix_gpios = { - .dev_id = "i2c-goodix_ts", - .table = { - GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:02", 28, "irq", GPIO_ACTIVE_HIGH), - { } - }, -}; - -static struct gpiod_lookup_table * const asus_me176c_gpios[] = { - &int3496_gpo2_pin22_gpios, - &asus_me176c_goodix_gpios, - NULL -}; - 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 = int3496_pdevs, - .pdev_count = 1, + .pdev_info = asus_me176c_tf103c_pdevs, + .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), .serdev_info = asus_me176c_serdevs, .serdev_count = ARRAY_SIZE(asus_me176c_serdevs), - .gpio_button = &asus_me176c_tf103c_lid, - .gpio_button_count = 1, - .gpiod_lookup_tables = asus_me176c_gpios, - .bat_swnode = &generic_lipo_hv_4v35_battery_node, + .gpio_button_swnodes = asus_me176c_tf103c_lid_swnodes, + .swnode_group = generic_lipo_hv_4v35_battery_swnodes, .modules = bq24190_modules, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* Asus TF103C tablets have an Android factory image with everything hardcoded */ @@ -293,19 +307,13 @@ static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = }, }; -static struct gpiod_lookup_table * const asus_tf103c_gpios[] = { - &int3496_gpo2_pin22_gpios, - NULL -}; - 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 = int3496_pdevs, - .pdev_count = 1, - .gpio_button = &asus_me176c_tf103c_lid, - .gpio_button_count = 1, - .gpiod_lookup_tables = asus_tf103c_gpios, - .bat_swnode = &generic_lipo_4v2_battery_node, + .pdev_info = asus_me176c_tf103c_pdevs, + .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), + .gpio_button_swnodes = asus_me176c_tf103c_lid_swnodes, + .swnode_group = generic_lipo_4v2_battery_swnodes, .modules = bq24190_modules, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 2a9c47178505..6588fae30356 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -5,7 +5,7 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt @@ -152,9 +152,9 @@ static struct i2c_client **i2c_clients; static struct spi_device **spi_devs; static struct platform_device **pdevs; static struct serdev_device **serdevs; -static struct gpio_keys_button *buttons; -static struct gpiod_lookup_table * const *gpiod_lookup_tables; -static const struct software_node *bat_swnode; +static const struct software_node **gpio_button_swnodes; +static const struct software_node **swnode_group; +static const struct software_node **gpiochip_node_group; static void (*exit_handler)(void); static __init struct i2c_adapter * @@ -265,8 +265,7 @@ static __init int x86_instantiate_spi_dev(const struct x86_dev_info *dev_info, i spi_devs[idx] = spi_new_device(controller, &board_info); put_device(&controller->dev); if (!spi_devs[idx]) - return dev_err_probe(&controller->dev, -ENOMEM, - "creating SPI-device %d\n", idx); + return -ENOMEM; return 0; } @@ -277,8 +276,10 @@ get_serdev_controller_by_pci_parent(const struct x86_serdev_info *info) struct pci_dev *pdev; pdev = pci_get_domain_bus_and_slot(0, 0, info->ctrl.pci.devfn); - if (!pdev) - return ERR_PTR(-EPROBE_DEFER); + if (!pdev) { + pr_err("error could not get PCI serdev at devfn 0x%02x\n", info->ctrl.pci.devfn); + return ERR_PTR(-ENODEV); + } /* This puts our reference on pdev and returns a ref on the ctrl */ return get_serdev_controller_from_parent(&pdev->dev, 0, info->ctrl_devname); @@ -331,6 +332,34 @@ put_ctrl_dev: return ret; } +const struct software_node baytrail_gpiochip_nodes[] = { + { .name = "INT33FC:00" }, + { .name = "INT33FC:01" }, + { .name = "INT33FC:02" }, +}; + +static const struct software_node *baytrail_gpiochip_node_group[] = { + &baytrail_gpiochip_nodes[0], + &baytrail_gpiochip_nodes[1], + &baytrail_gpiochip_nodes[2], + NULL +}; + +const struct software_node cherryview_gpiochip_nodes[] = { + { .name = "INT33FF:00" }, + { .name = "INT33FF:01" }, + { .name = "INT33FF:02" }, + { .name = "INT33FF:03" }, +}; + +static const struct software_node *cherryview_gpiochip_node_group[] = { + &cherryview_gpiochip_nodes[0], + &cherryview_gpiochip_nodes[1], + &cherryview_gpiochip_nodes[2], + &cherryview_gpiochip_nodes[3], + NULL +}; + static void x86_android_tablet_remove(struct platform_device *pdev) { int i; @@ -346,7 +375,6 @@ static void x86_android_tablet_remove(struct platform_device *pdev) platform_device_unregister(pdevs[i]); kfree(pdevs); - kfree(buttons); for (i = spi_dev_count - 1; i >= 0; i--) spi_unregister_device(spi_devs[i]); @@ -361,10 +389,9 @@ static void x86_android_tablet_remove(struct platform_device *pdev) if (exit_handler) exit_handler(); - for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++) - gpiod_remove_lookup_table(gpiod_lookup_tables[i]); - - software_node_unregister(bat_swnode); + software_node_unregister_node_group(gpio_button_swnodes); + software_node_unregister_node_group(swnode_group); + software_node_unregister_node_group(gpiochip_node_group); } static __init int x86_android_tablet_probe(struct platform_device *pdev) @@ -388,16 +415,28 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) for (i = 0; dev_info->modules && dev_info->modules[i]; i++) request_module(dev_info->modules[i]); - bat_swnode = dev_info->bat_swnode; - if (bat_swnode) { - ret = software_node_register(bat_swnode); - if (ret) - return ret; + switch (dev_info->gpiochip_type) { + case X86_GPIOCHIP_BAYTRAIL: + gpiochip_node_group = baytrail_gpiochip_node_group; + break; + case X86_GPIOCHIP_CHERRYVIEW: + gpiochip_node_group = cherryview_gpiochip_node_group; + break; + case X86_GPIOCHIP_UNSPECIFIED: + gpiochip_node_group = NULL; + break; } - gpiod_lookup_tables = dev_info->gpiod_lookup_tables; - for (i = 0; gpiod_lookup_tables && gpiod_lookup_tables[i]; i++) - gpiod_add_lookup_table(gpiod_lookup_tables[i]); + ret = software_node_register_node_group(gpiochip_node_group); + if (ret) + return ret; + + ret = software_node_register_node_group(dev_info->swnode_group); + if (ret) { + x86_android_tablet_remove(pdev); + return ret; + } + swnode_group = dev_info->swnode_group; if (dev_info->init) { ret = dev_info->init(&pdev->dev); @@ -470,38 +509,22 @@ static __init int x86_android_tablet_probe(struct platform_device *pdev) } } - if (dev_info->gpio_button_count) { - struct gpio_keys_platform_data pdata = { }; - struct gpio_desc *gpiod; + if (dev_info->gpio_button_swnodes) { + struct platform_device_info button_info = { + .name = "gpio-keys", + .id = PLATFORM_DEVID_AUTO, + }; - buttons = kcalloc(dev_info->gpio_button_count, sizeof(*buttons), GFP_KERNEL); - if (!buttons) { + ret = software_node_register_node_group(dev_info->gpio_button_swnodes); + if (ret < 0) { x86_android_tablet_remove(pdev); - return -ENOMEM; - } - - for (i = 0; i < dev_info->gpio_button_count; i++) { - ret = x86_android_tablet_get_gpiod(dev_info->gpio_button[i].chip, - dev_info->gpio_button[i].pin, - dev_info->gpio_button[i].button.desc, - false, GPIOD_IN, &gpiod); - if (ret < 0) { - x86_android_tablet_remove(pdev); - return ret; - } - - buttons[i] = dev_info->gpio_button[i].button; - buttons[i].gpio = desc_to_gpio(gpiod); - /* Release GPIO descriptor so that gpio-keys can request it */ - devm_gpiod_put(&x86_android_tablet_device->dev, gpiod); + return ret; } - pdata.buttons = buttons; - pdata.nbuttons = dev_info->gpio_button_count; + gpio_button_swnodes = dev_info->gpio_button_swnodes; - pdevs[pdev_count] = platform_device_register_data(&pdev->dev, "gpio-keys", - PLATFORM_DEVID_AUTO, - &pdata, sizeof(pdata)); + button_info.fwnode = software_node_fwnode(dev_info->gpio_button_swnodes[0]); + pdevs[pdev_count] = platform_device_register_full(&button_info); if (IS_ERR(pdevs[pdev_count])) { ret = PTR_ERR(pdevs[pdev_count]); x86_android_tablet_remove(pdev); @@ -537,6 +560,6 @@ static void __exit x86_android_tablet_exit(void) } module_exit(x86_android_tablet_exit); -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); +MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>"); MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c index 278c6d151dc4..4a5720d6fc1d 100644 --- a/drivers/platform/x86/x86-android-tablets/dmi.c +++ b/drivers/platform/x86/x86-android-tablets/dmi.c @@ -5,7 +5,7 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #include <linux/dmi.h> @@ -17,6 +17,16 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { { + /* Acer Iconia One 8 A1-840 (non FHD version) */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "BayTrail"), + /* Above strings are too generic also match BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "04/01/2014"), + }, + .driver_data = (void *)&acer_a1_840_info, + }, + { /* Acer Iconia One 7 B1-750 */ .matches = { DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c index 1241a97cda39..e3d3a8290949 100644 --- a/drivers/platform/x86/x86-android-tablets/lenovo.c +++ b/drivers/platform/x86/x86-android-tablets/lenovo.c @@ -5,13 +5,15 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/efi.h> #include <linux/gpio/machine.h> +#include <linux/gpio/property.h> +#include <linux/input-event-codes.h> #include <linux/mfd/arizona/pdata.h> #include <linux/mfd/arizona/registers.h> #include <linux/mfd/intel_soc_pmic.h> @@ -59,11 +61,30 @@ static struct lp855x_platform_data lenovo_lp8557_reg_only_pdata = { .initial_brightness = 128, }; +static const struct software_node arizona_gpiochip_node = { + .name = "arizona", +}; + +static const struct software_node crystalcove_gpiochip_node = { + .name = "gpio_crystalcove", +}; + /* Lenovo Yoga Book X90F / X90L's Android factory image has everything hardcoded */ +static const struct property_entry lenovo_yb1_x90_goodix_props[] = { + PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[1], 53, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("irq-gpios", &cherryview_gpiochip_nodes[1], 56, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node lenovo_yb1_x90_goodix_node = { + .properties = lenovo_yb1_x90_goodix_props, +}; + static const struct property_entry lenovo_yb1_x90_wacom_props[] = { PROPERTY_ENTRY_U32("hid-descr-addr", 0x0001), PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 150), + PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 82, GPIO_ACTIVE_LOW), { } }; @@ -85,6 +106,7 @@ static const struct property_entry lenovo_yb1_x90_hideep_ts_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-y", 1920), PROPERTY_ENTRY_U32("touchscreen-max-pressure", 16384), PROPERTY_ENTRY_BOOL("hideep,force-native-protocol"), + PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 7, GPIO_ACTIVE_LOW), { } }; @@ -108,6 +130,7 @@ static const struct x86_i2c_client_info lenovo_yb1_x90_i2c_clients[] __initconst .type = "GDIX1001:00", .addr = 0x14, .dev_name = "goodix_ts", + .swnode = &lenovo_yb1_x90_goodix_node, }, .adapter_path = "\\_SB_.PCI0.I2C2", .irq_data = { @@ -185,48 +208,33 @@ static const struct x86_serdev_info lenovo_yb1_x90_serdevs[] __initconst = { }, }; -static const struct x86_gpio_button lenovo_yb1_x90_lid __initconst = { - .button = { - .code = SW_LID, - .active_low = true, - .desc = "lid_sw", - .type = EV_SW, - .wakeup = true, - .debounce_interval = 50, - }, - .chip = "INT33FF:02", - .pin = 19, -}; - -static struct gpiod_lookup_table lenovo_yb1_x90_goodix_gpios = { - .dev_id = "i2c-goodix_ts", - .table = { - GPIO_LOOKUP("INT33FF:01", 53, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FF:01", 56, "irq", GPIO_ACTIVE_HIGH), - { } - }, +/* + * Software node attached to gpio-keys device representing the LID and + * serving as a parent to software nodes representing individual keys/buttons + * as required by the device tree binding. + */ +static const struct software_node lenovo_lid_gpio_keys_node = { + .name = "lid_sw", }; -static struct gpiod_lookup_table lenovo_yb1_x90_hideep_gpios = { - .dev_id = "i2c-hideep_ts", - .table = { - GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW), - { } - }, +static const struct property_entry lenovo_yb1_x90_lid_props[] = { + PROPERTY_ENTRY_U32("linux,input-type", EV_SW), + PROPERTY_ENTRY_U32("linux,code", SW_LID), + PROPERTY_ENTRY_STRING("label", "lid_sw"), + PROPERTY_ENTRY_GPIO("gpios", &cherryview_gpiochip_nodes[2], 19, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), + PROPERTY_ENTRY_BOOL("wakeup-source"), + { } }; -static struct gpiod_lookup_table lenovo_yb1_x90_wacom_gpios = { - .dev_id = "i2c-wacom", - .table = { - GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_LOW), - { } - }, +static const struct software_node lenovo_yb1_x90_lid_node = { + .parent = &lenovo_lid_gpio_keys_node, + .properties = lenovo_yb1_x90_lid_props, }; -static struct gpiod_lookup_table * const lenovo_yb1_x90_gpios[] = { - &lenovo_yb1_x90_hideep_gpios, - &lenovo_yb1_x90_goodix_gpios, - &lenovo_yb1_x90_wacom_gpios, +static const struct software_node *lenovo_yb1_x90_lid_swnodes[] = { + &lenovo_lid_gpio_keys_node, + &lenovo_yb1_x90_lid_node, NULL }; @@ -256,9 +264,8 @@ const struct x86_dev_info lenovo_yogabook_x90_info __initconst = { .pdev_count = ARRAY_SIZE(lenovo_yb1_x90_pdevs), .serdev_info = lenovo_yb1_x90_serdevs, .serdev_count = ARRAY_SIZE(lenovo_yb1_x90_serdevs), - .gpio_button = &lenovo_yb1_x90_lid, - .gpio_button_count = 1, - .gpiod_lookup_tables = lenovo_yb1_x90_gpios, + .gpio_button_swnodes = lenovo_yb1_x90_lid_swnodes, + .gpiochip_type = X86_GPIOCHIP_CHERRYVIEW, .init = lenovo_yb1_x90_init, }; @@ -294,17 +301,25 @@ static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = { .properties = lenovo_yoga_tab2_830_1050_bq24190_props, }; -static const struct x86_gpio_button lenovo_yoga_tab2_830_1050_lid __initconst = { - .button = { - .code = SW_LID, - .active_low = true, - .desc = "lid_sw", - .type = EV_SW, - .wakeup = true, - .debounce_interval = 50, - }, - .chip = "INT33FC:02", - .pin = 26, +static const struct property_entry lenovo_yoga_tab2_830_1050_lid_props[] = { + PROPERTY_ENTRY_U32("linux,input-type", EV_SW), + PROPERTY_ENTRY_U32("linux,code", SW_LID), + PROPERTY_ENTRY_STRING("label", "lid_sw"), + PROPERTY_ENTRY_GPIO("gpios", &baytrail_gpiochip_nodes[2], 26, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), + PROPERTY_ENTRY_BOOL("wakeup-source"), + { } +}; + +static const struct software_node lenovo_yoga_tab2_830_1050_lid_node = { + .parent = &lenovo_lid_gpio_keys_node, + .properties = lenovo_yoga_tab2_830_1050_lid_props, +}; + +static const struct software_node *lenovo_yoga_tab2_830_1050_lid_swnodes[] = { + &lenovo_lid_gpio_keys_node, + &lenovo_yoga_tab2_830_1050_lid_node, + NULL }; /* This gets filled by lenovo_yoga_tab2_830_1050_init() */ @@ -384,47 +399,65 @@ static struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __init }, }; -static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_int3496_gpios = { - .dev_id = "intel-int3496", - .table = { - GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_LOW), - GPIO_LOOKUP("INT33FC:02", 24, "id", GPIO_ACTIVE_HIGH), - { } +static const struct property_entry lenovo_yoga_tab2_830_1050_int3496_props[] __initconst = { + PROPERTY_ENTRY_GPIO("mux-gpios", &baytrail_gpiochip_nodes[2], 1, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 24, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct platform_device_info lenovo_yoga_tab2_830_1050_pdevs[] __initconst = { + { + /* For micro USB ID pin handling */ + .name = "intel-int3496", + .id = PLATFORM_DEVID_NONE, + .properties = lenovo_yoga_tab2_830_1050_int3496_props, }, }; #define LENOVO_YOGA_TAB2_830_1050_CODEC_NAME "spi-10WM5102:00" -static struct gpiod_lookup_table lenovo_yoga_tab2_830_1050_codec_gpios = { - .dev_id = LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, - .table = { - GPIO_LOOKUP("gpio_crystalcove", 3, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:01", 23, "wlf,ldoena", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("arizona", 2, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("arizona", 4, "wlf,micd-pol", GPIO_ACTIVE_LOW), - { } - }, +static const struct property_entry lenovo_yoga_tab2_830_1050_wm1502_props[] = { + PROPERTY_ENTRY_GPIO("reset-gpios", + &crystalcove_gpiochip_node, 3, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("wlf,ldoena-gpios", + &baytrail_gpiochip_nodes[1], 23, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("wlf,spkvdd-ena-gpios", + &arizona_gpiochip_node, 2, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("wlf,micd-pol-gpios", + &arizona_gpiochip_node, 4, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node lenovo_yoga_tab2_830_1050_wm5102 = { + .properties = lenovo_yoga_tab2_830_1050_wm1502_props, }; -static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = { - &lenovo_yoga_tab2_830_1050_int3496_gpios, - &lenovo_yoga_tab2_830_1050_codec_gpios, +static const struct software_node *lenovo_yoga_tab2_830_1050_swnodes[] = { + &crystalcove_gpiochip_node, + &arizona_gpiochip_node, + &lenovo_yoga_tab2_830_1050_wm5102, + &generic_lipo_hv_4v35_battery_node, NULL }; static int __init lenovo_yoga_tab2_830_1050_init(struct device *dev); static void lenovo_yoga_tab2_830_1050_exit(void); +static const char * const lenovo_yoga_tab2_modules[] __initconst = { + "spi_pxa2xx_platform", /* For the SPI codec device */ + "bq24190_charger", /* For the Vbus regulator for int3496/lc824206xa */ + NULL +}; + const struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initconst = { .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients, .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients), - .pdev_info = int3496_pdevs, - .pdev_count = 1, - .gpio_button = &lenovo_yoga_tab2_830_1050_lid, - .gpio_button_count = 1, - .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios, - .bat_swnode = &generic_lipo_hv_4v35_battery_node, - .modules = bq24190_modules, + .pdev_info = lenovo_yoga_tab2_830_1050_pdevs, + .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_830_1050_pdevs), + .gpio_button_swnodes = lenovo_yoga_tab2_830_1050_lid_swnodes, + .swnode_group = lenovo_yoga_tab2_830_1050_swnodes, + .modules = lenovo_yoga_tab2_modules, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, .init = lenovo_yoga_tab2_830_1050_init, .exit = lenovo_yoga_tab2_830_1050_exit, }; @@ -481,6 +514,7 @@ static const struct pinctrl_map lenovo_yoga_tab2_830_1050_codec_pinctrl_map = PIN_MAP_MUX_GROUP(LENOVO_YOGA_TAB2_830_1050_CODEC_NAME, "codec_32khz_clk", "INT33FC:02", "pmu_clk2_grp", "pmu_clk"); +static struct device *lenovo_yoga_tab2_830_1050_codec_dev; static struct pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl; static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler; @@ -507,12 +541,18 @@ static int __init lenovo_yoga_tab2_830_1050_init_codec(void) goto err_unregister_mappings; } - /* We're done with the codec_dev now */ - put_device(codec_dev); + ret = device_add_software_node(codec_dev, &lenovo_yoga_tab2_830_1050_wm5102); + if (ret) { + ret = dev_err_probe(codec_dev, ret, "adding software node\n"); + goto err_put_pinctrl; + } + lenovo_yoga_tab2_830_1050_codec_dev = codec_dev; lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl; return 0; +err_put_pinctrl: + pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl); err_unregister_mappings: pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); err_put_device: @@ -560,10 +600,10 @@ static void lenovo_yoga_tab2_830_1050_exit(void) { unregister_sys_off_handler(lenovo_yoga_tab2_830_1050_sys_off_handler); - if (lenovo_yoga_tab2_830_1050_codec_pinctrl) { - pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl); - pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); - } + device_remove_software_node(lenovo_yoga_tab2_830_1050_codec_dev); + pinctrl_put(lenovo_yoga_tab2_830_1050_codec_pinctrl); + pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); + put_device(lenovo_yoga_tab2_830_1050_codec_dev); } /* @@ -718,19 +758,21 @@ static const struct x86_i2c_client_info lenovo_yoga_tab2_1380_i2c_clients[] __in } }; +static const struct property_entry lenovo_yoga_tab2_1380_fc_props[] __initconst = { + PROPERTY_ENTRY_GPIO("uart3_txd-gpios", &baytrail_gpiochip_nodes[0], 57, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("uart3_rxd-gpios", &baytrail_gpiochip_nodes[0], 61, GPIO_ACTIVE_HIGH), + { } +}; + static const struct platform_device_info lenovo_yoga_tab2_1380_pdevs[] __initconst = { { /* For the Tablet 2 Pro 1380's custom fast charging driver */ .name = "lenovo-yoga-tab2-pro-1380-fastcharger", .id = PLATFORM_DEVID_NONE, + .properties = lenovo_yoga_tab2_1380_fc_props, }, }; -static const char * const lenovo_yoga_tab2_1380_modules[] __initconst = { - "bq24190_charger", /* For the Vbus regulator for lc824206xa */ - NULL -}; - static int __init lenovo_yoga_tab2_1380_init(struct device *dev) { int ret; @@ -752,31 +794,15 @@ static int __init lenovo_yoga_tab2_1380_init(struct device *dev) return 0; } -static struct gpiod_lookup_table lenovo_yoga_tab2_1380_fc_gpios = { - .dev_id = "serial0-0", - .table = { - GPIO_LOOKUP("INT33FC:00", 57, "uart3_txd", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:00", 61, "uart3_rxd", GPIO_ACTIVE_HIGH), - { } - }, -}; - -static struct gpiod_lookup_table * const lenovo_yoga_tab2_1380_gpios[] = { - &lenovo_yoga_tab2_830_1050_codec_gpios, - &lenovo_yoga_tab2_1380_fc_gpios, - NULL -}; - const struct x86_dev_info lenovo_yoga_tab2_1380_info __initconst = { .i2c_client_info = lenovo_yoga_tab2_1380_i2c_clients, .i2c_client_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_i2c_clients), .pdev_info = lenovo_yoga_tab2_1380_pdevs, .pdev_count = ARRAY_SIZE(lenovo_yoga_tab2_1380_pdevs), - .gpio_button = &lenovo_yoga_tab2_830_1050_lid, - .gpio_button_count = 1, - .gpiod_lookup_tables = lenovo_yoga_tab2_1380_gpios, - .bat_swnode = &generic_lipo_hv_4v35_battery_node, - .modules = lenovo_yoga_tab2_1380_modules, + .gpio_button_swnodes = lenovo_yoga_tab2_830_1050_lid_swnodes, + .swnode_group = lenovo_yoga_tab2_830_1050_swnodes, + .modules = lenovo_yoga_tab2_modules, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, .init = lenovo_yoga_tab2_1380_init, .exit = lenovo_yoga_tab2_830_1050_exit, }; @@ -824,6 +850,7 @@ static const struct property_entry lenovo_yt3_hideep_ts_props[] = { PROPERTY_ENTRY_U32("touchscreen-size-x", 1600), PROPERTY_ENTRY_U32("touchscreen-size-y", 2560), PROPERTY_ENTRY_U32("touchscreen-max-pressure", 255), + PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 7, GPIO_ACTIVE_LOW), { } }; @@ -958,12 +985,34 @@ static struct arizona_pdata lenovo_yt3_wm5102_pdata = { }, }; +static const struct property_entry lenovo_yt3_wm1502_props[] = { + PROPERTY_ENTRY_GPIO("wlf,spkvdd-ena-gpios", + &cherryview_gpiochip_nodes[0], 75, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("wlf,ldoena-gpios", + &cherryview_gpiochip_nodes[0], 81, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[0], 82, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("wlf,micd-pol-gpios", &arizona_gpiochip_node, 2, GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node lenovo_yt3_wm5102 = { + .properties = lenovo_yt3_wm1502_props, + .name = "wm5102", +}; + +static const struct software_node *lenovo_yt3_swnodes[] = { + &arizona_gpiochip_node, + &lenovo_yt3_wm5102, + NULL +}; + static const struct x86_spi_dev_info lenovo_yt3_spi_devs[] __initconst = { { /* WM5102 codec */ .board_info = { .modalias = "wm5102", .platform_data = &lenovo_yt3_wm5102_pdata, + .swnode = &lenovo_yt3_wm5102, .max_speed_hz = 5000000, }, .ctrl_path = "\\_SB_.PCI0.SPI1", @@ -1013,28 +1062,8 @@ static int __init lenovo_yt3_init(struct device *dev) return 0; } -static struct gpiod_lookup_table lenovo_yt3_hideep_gpios = { - .dev_id = "i2c-hideep_ts", - .table = { - GPIO_LOOKUP("INT33FF:00", 7, "reset", GPIO_ACTIVE_LOW), - { } - }, -}; - -static struct gpiod_lookup_table lenovo_yt3_wm5102_gpios = { - .dev_id = "spi1.0", - .table = { - GPIO_LOOKUP("INT33FF:00", 75, "wlf,spkvdd-ena", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FF:00", 81, "wlf,ldoena", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FF:00", 82, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("arizona", 2, "wlf,micd-pol", GPIO_ACTIVE_HIGH), - { } - }, -}; - -static struct gpiod_lookup_table * const lenovo_yt3_gpios[] = { - &lenovo_yt3_hideep_gpios, - &lenovo_yt3_wm5102_gpios, +static const char * const lenovo_yt3_modules[] __initconst = { + "spi_pxa2xx_platform", /* For the SPI codec device */ NULL }; @@ -1043,6 +1072,8 @@ const struct x86_dev_info lenovo_yt3_info __initconst = { .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), .spi_dev_info = lenovo_yt3_spi_devs, .spi_dev_count = ARRAY_SIZE(lenovo_yt3_spi_devs), - .gpiod_lookup_tables = lenovo_yt3_gpios, + .swnode_group = lenovo_yt3_swnodes, + .modules = lenovo_yt3_modules, + .gpiochip_type = X86_GPIOCHIP_CHERRYVIEW, .init = lenovo_yt3_init, }; diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index f7bd9f863c85..7532af2d72d1 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -5,12 +5,13 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #include <linux/acpi.h> #include <linux/gpio/machine.h> -#include <linux/input.h> +#include <linux/gpio/property.h> +#include <linux/input-event-codes.h> #include <linux/leds.h> #include <linux/pci.h> #include <linux/platform_device.h> @@ -21,102 +22,38 @@ #include "shared-psy-info.h" #include "x86-android-tablets.h" -/* Acer Iconia One 7 B1-750 has an Android factory image with everything hardcoded */ -static const char * const acer_b1_750_mount_matrix[] = { - "-1", "0", "0", - "0", "1", "0", - "0", "0", "1" +/* + * Advantech MICA-071 + * This is a standard Windows tablet, but it has an extra "quick launch" button + * which is not described in the ACPI tables in anyway. + * Use the x86-android-tablets infra to create a gpio-keys device for this. + */ +static const struct software_node advantech_mica_071_gpio_keys_node = { + .name = "prog1_key", }; -static const struct property_entry acer_b1_750_bma250e_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", acer_b1_750_mount_matrix), +static const struct property_entry advantech_mica_071_prog1_key_props[] = { + PROPERTY_ENTRY_U32("linux,code", KEY_PROG1), + PROPERTY_ENTRY_STRING("label", "prog1_key"), + PROPERTY_ENTRY_GPIO("gpios", &baytrail_gpiochip_nodes[0], 2, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), { } }; -static const struct software_node acer_b1_750_bma250e_node = { - .properties = acer_b1_750_bma250e_props, +static const struct software_node advantech_mica_071_prog1_key_node = { + .parent = &advantech_mica_071_gpio_keys_node, + .properties = advantech_mica_071_prog1_key_props, }; -static const struct x86_i2c_client_info acer_b1_750_i2c_clients[] __initconst = { - { - /* Novatek NVT-ts touchscreen */ - .board_info = { - .type = "nt11205-ts", - .addr = 0x34, - .dev_name = "NVT-ts", - }, - .adapter_path = "\\_SB_.I2C4", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_GPIOINT, - .chip = "INT33FC:02", - .index = 3, - .trigger = ACPI_EDGE_SENSITIVE, - .polarity = ACPI_ACTIVE_LOW, - .con_id = "NVT-ts_irq", - }, - }, { - /* BMA250E accelerometer */ - .board_info = { - .type = "bma250e", - .addr = 0x18, - .swnode = &acer_b1_750_bma250e_node, - }, - .adapter_path = "\\_SB_.I2C3", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_GPIOINT, - .chip = "INT33FC:02", - .index = 25, - .trigger = ACPI_LEVEL_SENSITIVE, - .polarity = ACPI_ACTIVE_HIGH, - .con_id = "bma250e_irq", - }, - }, -}; - -static struct gpiod_lookup_table acer_b1_750_nvt_ts_gpios = { - .dev_id = "i2c-NVT-ts", - .table = { - GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW), - { } - }, -}; - -static struct gpiod_lookup_table * const acer_b1_750_gpios[] = { - &acer_b1_750_nvt_ts_gpios, - &int3496_reference_gpios, +static const struct software_node *advantech_mica_071_button_swnodes[] = { + &advantech_mica_071_gpio_keys_node, + &advantech_mica_071_prog1_key_node, NULL }; -const struct x86_dev_info acer_b1_750_info __initconst = { - .i2c_client_info = acer_b1_750_i2c_clients, - .i2c_client_count = ARRAY_SIZE(acer_b1_750_i2c_clients), - .pdev_info = int3496_pdevs, - .pdev_count = 1, - .gpiod_lookup_tables = acer_b1_750_gpios, -}; - -/* - * Advantech MICA-071 - * This is a standard Windows tablet, but it has an extra "quick launch" button - * which is not described in the ACPI tables in anyway. - * Use the x86-android-tablets infra to create a gpio-keys device for this. - */ -static const struct x86_gpio_button advantech_mica_071_button __initconst = { - .button = { - .code = KEY_PROG1, - .active_low = true, - .desc = "prog1_key", - .type = EV_KEY, - .wakeup = false, - .debounce_interval = 50, - }, - .chip = "INT33FC:00", - .pin = 2, -}; - const struct x86_dev_info advantech_mica_071_info __initconst = { - .gpio_button = &advantech_mica_071_button, - .gpio_button_count = 1, + .gpio_button_swnodes = advantech_mica_071_button_swnodes, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* @@ -212,36 +149,46 @@ const struct x86_dev_info chuwi_hi8_info __initconst = { * in the button row with the power + volume-buttons labeled P and F. * Use the x86-android-tablets infra to create a gpio-keys device for these. */ -static const struct x86_gpio_button cyberbook_t116_buttons[] __initconst = { - { - .button = { - .code = KEY_PROG1, - .active_low = true, - .desc = "prog1_key", - .type = EV_KEY, - .wakeup = false, - .debounce_interval = 50, - }, - .chip = "INT33FF:00", - .pin = 30, - }, - { - .button = { - .code = KEY_PROG2, - .active_low = true, - .desc = "prog2_key", - .type = EV_KEY, - .wakeup = false, - .debounce_interval = 50, - }, - .chip = "INT33FF:03", - .pin = 48, - }, +static const struct software_node cyberbook_t116_gpio_keys_node = { + .name = "prog_keys", +}; + +static const struct property_entry cyberbook_t116_prog1_key_props[] = { + PROPERTY_ENTRY_U32("linux,code", KEY_PROG1), + PROPERTY_ENTRY_STRING("label", "prog1_key"), + PROPERTY_ENTRY_GPIO("gpios", &cherryview_gpiochip_nodes[0], 30, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), + { } +}; + +static const struct software_node cyberbook_t116_prog1_key_node = { + .parent = &cyberbook_t116_gpio_keys_node, + .properties = cyberbook_t116_prog1_key_props, +}; + +static const struct property_entry cyberbook_t116_prog2_key_props[] = { + PROPERTY_ENTRY_U32("linux,code", KEY_PROG2), + PROPERTY_ENTRY_STRING("label", "prog2_key"), + PROPERTY_ENTRY_GPIO("gpios", &cherryview_gpiochip_nodes[3], 48, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), + { } +}; + +static const struct software_node cyberbook_t116_prog2_key_node = { + .parent = &cyberbook_t116_gpio_keys_node, + .properties = cyberbook_t116_prog2_key_props, +}; + +static const struct software_node *cyberbook_t116_buttons_swnodes[] = { + &cyberbook_t116_gpio_keys_node, + &cyberbook_t116_prog1_key_node, + &cyberbook_t116_prog2_key_node, + NULL }; const struct x86_dev_info cyberbook_t116_info __initconst = { - .gpio_button = cyberbook_t116_buttons, - .gpio_button_count = ARRAY_SIZE(cyberbook_t116_buttons), + .gpio_button_swnodes = cyberbook_t116_buttons_swnodes, + .gpiochip_type = X86_GPIOCHIP_CHERRYVIEW, }; #define CZC_EC_EXTRA_PORT 0x68 @@ -297,6 +244,8 @@ static const struct software_node medion_lifetab_s10346_accel_node = { static const struct property_entry medion_lifetab_s10346_touchscreen_props[] = { PROPERTY_ENTRY_BOOL("touchscreen-inverted-x"), PROPERTY_ENTRY_BOOL("touchscreen-swapped-x-y"), + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("irq-gpios", &baytrail_gpiochip_nodes[2], 3, GPIO_ACTIVE_HIGH), { } }; @@ -340,24 +289,10 @@ static const struct x86_i2c_client_info medion_lifetab_s10346_i2c_clients[] __in }, }; -static struct gpiod_lookup_table medion_lifetab_s10346_goodix_gpios = { - .dev_id = "i2c-goodix_ts", - .table = { - GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH), - { } - }, -}; - -static struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = { - &medion_lifetab_s10346_goodix_gpios, - NULL -}; - const struct x86_dev_info medion_lifetab_s10346_info __initconst = { .i2c_client_info = medion_lifetab_s10346_i2c_clients, .i2c_client_count = ARRAY_SIZE(medion_lifetab_s10346_i2c_clients), - .gpiod_lookup_tables = medion_lifetab_s10346_gpios, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* Nextbook Ares 8 (BYT) tablets have an Android factory image with everything hardcoded */ @@ -416,17 +351,12 @@ static const struct x86_i2c_client_info nextbook_ares8_i2c_clients[] __initconst }, }; -static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = { - &int3496_reference_gpios, - NULL -}; - const struct x86_dev_info nextbook_ares8_info __initconst = { .i2c_client_info = nextbook_ares8_i2c_clients, .i2c_client_count = ARRAY_SIZE(nextbook_ares8_i2c_clients), .pdev_info = int3496_pdevs, .pdev_count = 1, - .gpiod_lookup_tables = nextbook_ares8_gpios, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* Nextbook Ares 8A (CHT) tablets have an Android factory image with everything hardcoded */ @@ -445,6 +375,17 @@ static const struct software_node nextbook_ares8a_accel_node = { .properties = nextbook_ares8a_accel_props, }; +static const struct property_entry nextbook_ares8a_ft5416_props[] = { + PROPERTY_ENTRY_U32("touchscreen-size-x", 800), + PROPERTY_ENTRY_U32("touchscreen-size-y", 1280), + PROPERTY_ENTRY_GPIO("reset-gpios", &cherryview_gpiochip_nodes[1], 25, GPIO_ACTIVE_LOW), + { } +}; + +static const struct software_node nextbook_ares8a_ft5416_node = { + .properties = nextbook_ares8a_ft5416_props, +}; + static const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initconst = { { /* Freescale MMA8653FC accelerometer */ @@ -461,7 +402,7 @@ static const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initcons .type = "edt-ft5x06", .addr = 0x38, .dev_name = "ft5416", - .swnode = &nextbook_ares8_touchscreen_node, + .swnode = &nextbook_ares8a_ft5416_node, }, .adapter_path = "\\_SB_.PCI0.I2C6", .irq_data = { @@ -475,23 +416,10 @@ static const struct x86_i2c_client_info nextbook_ares8a_i2c_clients[] __initcons }, }; -static struct gpiod_lookup_table nextbook_ares8a_ft5416_gpios = { - .dev_id = "i2c-ft5416", - .table = { - GPIO_LOOKUP("INT33FF:01", 25, "reset", GPIO_ACTIVE_LOW), - { } - }, -}; - -static struct gpiod_lookup_table * const nextbook_ares8a_gpios[] = { - &nextbook_ares8a_ft5416_gpios, - NULL -}; - const struct x86_dev_info nextbook_ares8a_info __initconst = { .i2c_client_info = nextbook_ares8a_i2c_clients, .i2c_client_count = ARRAY_SIZE(nextbook_ares8a_i2c_clients), - .gpiod_lookup_tables = nextbook_ares8a_gpios, + .gpiochip_type = X86_GPIOCHIP_CHERRYVIEW, }; /* @@ -500,22 +428,32 @@ const struct x86_dev_info nextbook_ares8a_info __initconst = { * This button has a WMI interface, but that is broken. Instead of trying to * use the broken WMI interface, instantiate a gpio-keys device for this. */ -static const struct x86_gpio_button peaq_c1010_button __initconst = { - .button = { - .code = KEY_SOUND, - .active_low = true, - .desc = "dolby_key", - .type = EV_KEY, - .wakeup = false, - .debounce_interval = 50, - }, - .chip = "INT33FC:00", - .pin = 3, +static const struct software_node peaq_c1010_gpio_keys_node = { + .name = "gpio_keys", +}; + +static const struct property_entry peaq_c1010_dolby_key_props[] = { + PROPERTY_ENTRY_U32("linux,code", KEY_SOUND), + PROPERTY_ENTRY_STRING("label", "dolby_key"), + PROPERTY_ENTRY_GPIO("gpios", &baytrail_gpiochip_nodes[0], 3, GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_U32("debounce-interval", 50), + { } +}; + +static const struct software_node peaq_c1010_dolby_key_node = { + .parent = &peaq_c1010_gpio_keys_node, + .properties = peaq_c1010_dolby_key_props, +}; + +static const struct software_node *peaq_c1010_button_swnodes[] = { + &peaq_c1010_gpio_keys_node, + &peaq_c1010_dolby_key_node, + NULL }; const struct x86_dev_info peaq_c1010_info __initconst = { - .gpio_button = &peaq_c1010_button, - .gpio_button_count = 1, + .gpio_button_swnodes = peaq_c1010_button_swnodes, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* @@ -543,6 +481,8 @@ static const struct property_entry whitelabel_tm800a550l_goodix_props[] = { PROPERTY_ENTRY_STRING("firmware-name", "gt912-tm800a550l.fw"), PROPERTY_ENTRY_STRING("goodix,config-name", "gt912-tm800a550l.cfg"), PROPERTY_ENTRY_U32("goodix,main-clk", 54), + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("irq-gpios", &baytrail_gpiochip_nodes[2], 3, GPIO_ACTIVE_HIGH), { } }; @@ -578,24 +518,10 @@ static const struct x86_i2c_client_info whitelabel_tm800a550l_i2c_clients[] __in }, }; -static struct gpiod_lookup_table whitelabel_tm800a550l_goodix_gpios = { - .dev_id = "i2c-goodix_ts", - .table = { - GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:02", 3, "irq", GPIO_ACTIVE_HIGH), - { } - }, -}; - -static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = { - &whitelabel_tm800a550l_goodix_gpios, - NULL -}; - const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { .i2c_client_info = whitelabel_tm800a550l_i2c_clients, .i2c_client_count = ARRAY_SIZE(whitelabel_tm800a550l_i2c_clients), - .gpiod_lookup_tables = whitelabel_tm800a550l_gpios, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* @@ -605,6 +531,7 @@ const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { static const struct property_entry vexia_edu_atla10_5v_touchscreen_props[] = { PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000), PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120), + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[1], 26, GPIO_ACTIVE_LOW), { } }; @@ -639,23 +566,10 @@ static const struct x86_i2c_client_info vexia_edu_atla10_5v_i2c_clients[] __init } }; -static struct gpiod_lookup_table vexia_edu_atla10_5v_ft5416_gpios = { - .dev_id = "i2c-FTSC1000", - .table = { - GPIO_LOOKUP("INT33FC:01", 26, "reset", GPIO_ACTIVE_LOW), - { } - }, -}; - -static struct gpiod_lookup_table * const vexia_edu_atla10_5v_gpios[] = { - &vexia_edu_atla10_5v_ft5416_gpios, - NULL -}; - const struct x86_dev_info vexia_edu_atla10_5v_info __initconst = { .i2c_client_info = vexia_edu_atla10_5v_i2c_clients, .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_5v_i2c_clients), - .gpiod_lookup_tables = vexia_edu_atla10_5v_gpios, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* @@ -691,6 +605,7 @@ static const struct software_node vexia_edu_atla10_9v_accel_node = { static const struct property_entry vexia_edu_atla10_9v_touchscreen_props[] = { PROPERTY_ENTRY_U32("hid-descr-addr", 0x0000), PROPERTY_ENTRY_U32("post-reset-deassert-delay-ms", 120), + PROPERTY_ENTRY_GPIO("reset-gpios", &baytrail_gpiochip_nodes[0], 60, GPIO_ACTIVE_LOW), { } }; @@ -783,19 +698,6 @@ static const struct x86_serdev_info vexia_edu_atla10_9v_serdevs[] __initconst = }, }; -static struct gpiod_lookup_table vexia_edu_atla10_9v_ft5416_gpios = { - .dev_id = "i2c-FTSC1000", - .table = { - GPIO_LOOKUP("INT33FC:00", 60, "reset", GPIO_ACTIVE_LOW), - { } - }, -}; - -static struct gpiod_lookup_table * const vexia_edu_atla10_9v_gpios[] = { - &vexia_edu_atla10_9v_ft5416_gpios, - NULL -}; - static int __init vexia_edu_atla10_9v_init(struct device *dev) { struct pci_dev *pdev; @@ -809,8 +711,10 @@ static int __init vexia_edu_atla10_9v_init(struct device *dev) /* Reprobe the SDIO controller to enumerate the now enabled Wifi module */ pdev = pci_get_domain_bus_and_slot(0, 0, PCI_DEVFN(0x11, 0)); - if (!pdev) - return -EPROBE_DEFER; + if (!pdev) { + pr_warn("Could not get PCI SDIO at devfn 0x%02x\n", PCI_DEVFN(0x11, 0)); + return 0; + } ret = device_reprobe(&pdev->dev); if (ret) @@ -825,9 +729,9 @@ const struct x86_dev_info vexia_edu_atla10_9v_info __initconst = { .i2c_client_count = ARRAY_SIZE(vexia_edu_atla10_9v_i2c_clients), .serdev_info = vexia_edu_atla10_9v_serdevs, .serdev_count = ARRAY_SIZE(vexia_edu_atla10_9v_serdevs), - .gpiod_lookup_tables = vexia_edu_atla10_9v_gpios, .init = vexia_edu_atla10_9v_init, .use_pci = true, + .gpiochip_type = X86_GPIOCHIP_BAYTRAIL, }; /* @@ -923,7 +827,6 @@ static int xiaomi_mipad2_brightness_set(struct led_classdev *led_cdev, static int __init xiaomi_mipad2_init(struct device *dev) { struct led_classdev *led_cdev; - int ret; xiaomi_mipad2_led_pwm = devm_pwm_get(dev, "pwm_soc_lpss_2"); if (IS_ERR(xiaomi_mipad2_led_pwm)) @@ -940,16 +843,7 @@ static int __init xiaomi_mipad2_init(struct device *dev) /* Turn LED off during suspend */ led_cdev->flags = LED_CORE_SUSPENDRESUME; - ret = devm_led_classdev_register(dev, led_cdev); - if (ret) - return dev_err_probe(dev, ret, "registering LED\n"); - - return software_node_register_node_group(ktd2026_node_group); -} - -static void xiaomi_mipad2_exit(void) -{ - software_node_unregister_node_group(ktd2026_node_group); + return devm_led_classdev_register(dev, led_cdev); } /* @@ -984,6 +878,6 @@ static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst const struct x86_dev_info xiaomi_mipad2_info __initconst = { .i2c_client_info = xiaomi_mipad2_i2c_clients, .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients), + .swnode_group = ktd2026_node_group, .init = xiaomi_mipad2_init, - .exit = xiaomi_mipad2_exit, }; diff --git a/drivers/platform/x86/x86-android-tablets/shared-psy-info.c b/drivers/platform/x86/x86-android-tablets/shared-psy-info.c index fe34cedb6257..29fc466f76fe 100644 --- a/drivers/platform/x86/x86-android-tablets/shared-psy-info.c +++ b/drivers/platform/x86/x86-android-tablets/shared-psy-info.c @@ -5,16 +5,18 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #include <linux/gpio/machine.h> +#include <linux/gpio/property.h> #include <linux/platform_device.h> #include <linux/power/bq24190_charger.h> #include <linux/property.h> #include <linux/regulator/machine.h> #include "shared-psy-info.h" +#include "x86-android-tablets.h" /* Generic / shared charger / battery settings */ const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" }; @@ -111,6 +113,11 @@ const struct software_node generic_lipo_4v2_battery_node = { .properties = generic_lipo_4v2_battery_props, }; +const struct software_node *generic_lipo_4v2_battery_swnodes[] = { + &generic_lipo_4v2_battery_node, + NULL +}; + /* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV battery */ static const struct property_entry generic_lipo_hv_4v35_battery_props[] = { PROPERTY_ENTRY_STRING("compatible", "simple-battery"), @@ -131,6 +138,11 @@ const struct software_node generic_lipo_hv_4v35_battery_node = { .properties = generic_lipo_hv_4v35_battery_props, }; +const struct software_node *generic_lipo_hv_4v35_battery_swnodes[] = { + &generic_lipo_hv_4v35_battery_node, + NULL +}; + /* For enabling the bq24190 5V boost based on id-pin */ static struct regulator_consumer_supply intel_int3496_consumer = { .supply = "vbus", @@ -156,21 +168,19 @@ const char * const bq24190_modules[] __initconst = { NULL }; -/* Generic platform device array and GPIO lookup table for micro USB ID pin handling */ +static const struct property_entry int3496_reference_props[] __initconst = { + PROPERTY_ENTRY_GPIO("vbus-gpios", &baytrail_gpiochip_nodes[1], 15, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("mux-gpios", &baytrail_gpiochip_nodes[2], 1, GPIO_ACTIVE_HIGH), + PROPERTY_ENTRY_GPIO("id-gpios", &baytrail_gpiochip_nodes[2], 18, GPIO_ACTIVE_HIGH), + { } +}; + +/* Generic pdevs array and gpio-lookups for micro USB ID pin handling */ const struct platform_device_info int3496_pdevs[] __initconst = { { /* For micro USB ID pin handling */ .name = "intel-int3496", .id = PLATFORM_DEVID_NONE, - }, -}; - -struct gpiod_lookup_table int3496_reference_gpios = { - .dev_id = "intel-int3496", - .table = { - GPIO_LOOKUP("INT33FC:01", 15, "vbus", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:02", 1, "mux", GPIO_ACTIVE_HIGH), - GPIO_LOOKUP("INT33FC:02", 18, "id", GPIO_ACTIVE_HIGH), - { } + .properties = int3496_reference_props, }, }; diff --git a/drivers/platform/x86/x86-android-tablets/shared-psy-info.h b/drivers/platform/x86/x86-android-tablets/shared-psy-info.h index bcf9845ad275..149befba3330 100644 --- a/drivers/platform/x86/x86-android-tablets/shared-psy-info.h +++ b/drivers/platform/x86/x86-android-tablets/shared-psy-info.h @@ -5,13 +5,12 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #ifndef __PDX86_SHARED_PSY_INFO_H #define __PDX86_SHARED_PSY_INFO_H struct bq24190_platform_data; -struct gpiod_lookup_table; struct platform_device_info; struct software_node; @@ -21,13 +20,16 @@ extern const char * const bq25890_psy[]; extern const struct software_node fg_bq24190_supply_node; extern const struct software_node fg_bq25890_supply_node; + extern const struct software_node generic_lipo_4v2_battery_node; +extern const struct software_node *generic_lipo_4v2_battery_swnodes[]; + extern const struct software_node generic_lipo_hv_4v35_battery_node; +extern const struct software_node *generic_lipo_hv_4v35_battery_swnodes[]; extern struct bq24190_platform_data bq24190_pdata; extern const char * const bq24190_modules[]; extern const struct platform_device_info int3496_pdevs[]; -extern struct gpiod_lookup_table int3496_reference_gpios; #endif diff --git a/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c b/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c index 5d02af1c5aaa..2f8cd8d9e0ab 100644 --- a/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c +++ b/drivers/platform/x86/x86-android-tablets/vexia_atla10_ec.c @@ -256,6 +256,6 @@ static struct i2c_driver atla10_ec_driver = { }; module_i2c_driver(atla10_ec_driver); -MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); +MODULE_AUTHOR("Hans de Goede <hansg@kernel.org>"); MODULE_DESCRIPTION("Battery driver for Vexia EDU ATLA 10 tablet EC"); MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h index dcf8d49e3b5f..2498390958ad 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -5,19 +5,17 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2023 Hans de Goede <hdegoede@redhat.com> + * Copyright (C) 2021-2023 Hans de Goede <hansg@kernel.org> */ #ifndef __PDX86_X86_ANDROID_TABLETS_H #define __PDX86_X86_ANDROID_TABLETS_H #include <linux/gpio/consumer.h> -#include <linux/gpio_keys.h> #include <linux/i2c.h> #include <linux/irqdomain_defs.h> #include <linux/spi/spi.h> struct gpio_desc; -struct gpiod_lookup_table; struct platform_device_info; struct software_node; @@ -32,6 +30,12 @@ enum x86_acpi_irq_type { X86_ACPI_IRQ_TYPE_PMIC, }; +enum x86_gpiochip_type { + X86_GPIOCHIP_UNSPECIFIED = 0, + X86_GPIOCHIP_BAYTRAIL, + X86_GPIOCHIP_CHERRYVIEW, +}; + struct x86_acpi_irq_data { char *chip; /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */ enum x86_acpi_irq_type type; @@ -76,29 +80,22 @@ 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 { const char * const *modules; - const struct software_node *bat_swnode; - struct gpiod_lookup_table * const *gpiod_lookup_tables; + const struct software_node **swnode_group; const struct x86_i2c_client_info *i2c_client_info; const struct x86_spi_dev_info *spi_dev_info; const struct platform_device_info *pdev_info; const struct x86_serdev_info *serdev_info; - const struct x86_gpio_button *gpio_button; + const struct software_node **gpio_button_swnodes; int i2c_client_count; int spi_dev_count; int pdev_count; int serdev_count; - int gpio_button_count; int (*init)(struct device *dev); void (*exit)(void); bool use_pci; + enum x86_gpiochip_type gpiochip_type; }; int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id, @@ -106,10 +103,15 @@ int x86_android_tablet_get_gpiod(const char *chip, int pin, const char *con_id, struct gpio_desc **desc); int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data); +/* Software nodes representing GPIO chips used by various tablets */ +extern const struct software_node baytrail_gpiochip_nodes[]; +extern const struct software_node cherryview_gpiochip_nodes[]; + /* * Extern declarations of x86_dev_info structs so there can be a single * MODULE_DEVICE_TABLE(dmi, ...), while splitting the board descriptions. */ +extern const struct x86_dev_info acer_a1_840_info; extern const struct x86_dev_info acer_b1_750_info; extern const struct x86_dev_info advantech_mica_071_info; extern const struct x86_dev_info asus_me176c_info; |