From patchwork Mon Feb 20 22:12:04 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2CDA6C61DA3 for ; Mon, 20 Feb 2023 22:13:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231806AbjBTWNK (ORCPT ); Mon, 20 Feb 2023 17:13:10 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33248 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232615AbjBTWNI (ORCPT ); Mon, 20 Feb 2023 17:13:08 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E378BDEF for ; Mon, 20 Feb 2023 14:12:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931143; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sbV+1dqv46AkMCmBuYC+I1uqY+gWC+dQhqqBUcNEsDQ=; b=MVYOOXVBq0hORInZuY4AhaGwCc6Fpf+3qJCzzw+nDattC3GZjcV2gei7twXwA+CUcDUdti eORn5jf6KiIlQxCoptTD/NQ+4AKg0ghlQmE3wLSU9cN5Oydygp1XT2pybAue+iet2ICIzZ eHdvHjtpGR/pXnYKuYD7xWsNXTJ/E78= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-674-1rrOExrEOJ-M9wdpSiokNg-1; Mon, 20 Feb 2023 17:12:22 -0500 X-MC-Unique: 1rrOExrEOJ-M9wdpSiokNg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 474B129AA2EA; Mon, 20 Feb 2023 22:12:22 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id A2531140EBF6; Mon, 20 Feb 2023 22:12:21 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 1/9] platform/x86: x86-android-tablets: Move into its own subdir Date: Mon, 20 Feb 2023 23:12:04 +0100 Message-Id: <20230220221212.196009-2-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Move the x86-android-tablets code into its own subdir, this is a preparation patch for splitting the somewhat large file into multiple smaller files. Signed-off-by: Hans de Goede --- MAINTAINERS | 2 +- drivers/platform/x86/Kconfig | 17 +-------------- drivers/platform/x86/Makefile | 2 +- .../platform/x86/x86-android-tablets/Kconfig | 21 +++++++++++++++++++ .../platform/x86/x86-android-tablets/Makefile | 8 +++++++ .../x86-android-tablets-main.c} | 4 ++-- 6 files changed, 34 insertions(+), 20 deletions(-) create mode 100644 drivers/platform/x86/x86-android-tablets/Kconfig create mode 100644 drivers/platform/x86/x86-android-tablets/Makefile rename drivers/platform/x86/{x86-android-tablets.c => x86-android-tablets/x86-android-tablets-main.c} (99%) diff --git a/MAINTAINERS b/MAINTAINERS index 0c051a973e6b..87cc1e6b37c0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22634,7 +22634,7 @@ M: Hans de Goede L: platform-driver-x86@vger.kernel.org S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/pdx86/platform-drivers-x86.git -F: drivers/platform/x86/x86-android-tablets.c +F: drivers/platform/x86/x86-android-tablets/ X86 PLATFORM DRIVERS M: Hans de Goede diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index ec7c2b4e1721..8b4e03fe5bff 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -977,22 +977,7 @@ config TOUCHSCREEN_DMI the OS-image for the device. This option supplies the missing info. Enable this for x86 tablets with Silead or Chipone touchscreens. -config X86_ANDROID_TABLETS - tristate "X86 Android tablet support" - depends on I2C && SPI && SERIAL_DEV_BUS && ACPI && EFI && GPIOLIB - help - X86 tablets which ship with Android as (part of) the factory image - typically have various problems with their DSDTs. The factory kernels - shipped on these devices typically have device addresses and GPIOs - hardcoded in the kernel, rather than specified in their DSDT. - - With the DSDT containing a random collection of devices which may or - may not actually be present. This driver contains various fixes for - such tablets, including instantiating kernel devices for devices which - are missing from the DSDT. - - If you have a x86 Android tablet say Y or M here, for a generic x86 - distro config say M here. +source "drivers/platform/x86/x86-android-tablets/Kconfig" config FW_ATTR_CLASS tristate diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 1d3d1b02541b..0d9cc9af6ba7 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -112,7 +112,7 @@ obj-$(CONFIG_SERIAL_MULTI_INSTANTIATE) += serial-multi-instantiate.o obj-$(CONFIG_MLX_PLATFORM) += mlx-platform.o obj-$(CONFIG_TOUCHSCREEN_DMI) += touchscreen_dmi.o obj-$(CONFIG_WIRELESS_HOTKEY) += wireless-hotkey.o -obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o +obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets/ # Intel uncore drivers obj-$(CONFIG_INTEL_IPS) += intel_ips.o diff --git a/drivers/platform/x86/x86-android-tablets/Kconfig b/drivers/platform/x86/x86-android-tablets/Kconfig new file mode 100644 index 000000000000..8a0a0242ed92 --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/Kconfig @@ -0,0 +1,21 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# X86 Android tablet support Kconfig +# + +config X86_ANDROID_TABLETS + tristate "X86 Android tablet support" + depends on I2C && SPI && SERIAL_DEV_BUS && ACPI && EFI && GPIOLIB + help + X86 tablets which ship with Android as (part of) the factory image + typically have various problems with their DSDTs. The factory kernels + shipped on these devices typically have device addresses and GPIOs + hardcoded in the kernel, rather than specified in their DSDT. + + With the DSDT containing a random collection of devices which may or + may not actually be present. This driver contains various fixes for + such tablets, including instantiating kernel devices for devices which + are missing from the DSDT. + + If you have a x86 Android tablet say Y or M here, for a generic x86 + distro config say M here. diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile new file mode 100644 index 000000000000..b4d789ff6e70 --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# X86 Android tablet support Makefile +# + +obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o + +x86-android-tablets-y := x86-android-tablets-main.o diff --git a/drivers/platform/x86/x86-android-tablets.c b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c similarity index 99% rename from drivers/platform/x86/x86-android-tablets.c rename to drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c index 8405e1c58d52..08cc5e158460 100644 --- a/drivers/platform/x86/x86-android-tablets.c +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c @@ -34,8 +34,8 @@ #include #include /* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */ -#include "../../gpio/gpiolib.h" -#include "../../gpio/gpiolib-acpi.h" +#include "../../../gpio/gpiolib.h" +#include "../../../gpio/gpiolib-acpi.h" /* * Helper code to get Linux IRQ numbers given a description of the IRQ source From patchwork Mon Feb 20 22:12:05 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147162 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A725DC6379F for ; Mon, 20 Feb 2023 22:13:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232507AbjBTWNJ (ORCPT ); Mon, 20 Feb 2023 17:13:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33266 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232613AbjBTWNI (ORCPT ); Mon, 20 Feb 2023 17:13:08 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9F6EBC64F for ; Mon, 20 Feb 2023 14:12:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931146; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=iAvXZZvhc94ue4hVltlfU0CLna0TdDqs4RnbChDojrU=; b=Zbn81aeg9xHwM089aJueTYCDI+ymyG6Z2RHxA82AcSOh2fXV8tW+ursdZkxr924A1oklRr Wb79rfZmmZQrvEnaZut6WNXUjDelnU2CDBe6MEm+RL109uLCIFyKRElJtNnx4hNmy0snOl 6nJ+0EL8dQ0bVstX9eP2VnLsz5etKcw= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-454-YZh5VSCvPw-jyJS6aLRL3w-1; Mon, 20 Feb 2023 17:12:23 -0500 X-MC-Unique: YZh5VSCvPw-jyJS6aLRL3w-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 380B1101A52E; Mon, 20 Feb 2023 22:12:23 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7760D140EBF6; Mon, 20 Feb 2023 22:12:22 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 2/9] platform/x86: x86-android-tablets: Move core code into new core.c file Date: Mon, 20 Feb 2023 23:12:05 +0100 Message-Id: <20230220221212.196009-3-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Move the helpers to get irqs + gpios as well as the core code for instantiating all the devices missing from ACPI into a new core.c file. Signed-off-by: Hans de Goede --- .../platform/x86/x86-android-tablets/Makefile | 2 +- .../platform/x86/x86-android-tablets/core.c | 363 ++++++++++++++++ .../x86-android-tablets-main.c | 406 +----------------- .../x86-android-tablets/x86-android-tablets.h | 77 ++++ 4 files changed, 443 insertions(+), 405 deletions(-) create mode 100644 drivers/platform/x86/x86-android-tablets/core.c create mode 100644 drivers/platform/x86/x86-android-tablets/x86-android-tablets.h diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index b4d789ff6e70..49c6bda1f817 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o -x86-android-tablets-y := x86-android-tablets-main.o +x86-android-tablets-y := core.o x86-android-tablets-main.o diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c new file mode 100644 index 000000000000..5d04e63e1ebc --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -0,0 +1,363 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DMI based code to deal with broken DSDTs on X86 tablets which ship with + * Android as (part of) the factory image. The factory kernels shipped on these + * devices typically have a bunch of things hardcoded, rather than specified + * in their DSDT. + * + * Copyright (C) 2021-2023 Hans de Goede + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include "x86-android-tablets.h" +/* For gpiochip_get_desc() which is EXPORT_SYMBOL_GPL() */ +#include "../../../gpio/gpiolib.h" +#include "../../../gpio/gpiolib-acpi.h" + +static int gpiochip_find_match_label(struct gpio_chip *gc, void *data) +{ + return gc->label && !strcmp(gc->label, data); +} + +int x86_android_tablet_get_gpiod(const char *label, int pin, struct gpio_desc **desc) +{ + struct gpio_desc *gpiod; + struct gpio_chip *chip; + + chip = gpiochip_find((void *)label, gpiochip_find_match_label); + if (!chip) { + pr_err("error cannot find GPIO chip %s\n", label); + return -ENODEV; + } + + gpiod = gpiochip_get_desc(chip, pin); + if (IS_ERR(gpiod)) { + pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin); + return PTR_ERR(gpiod); + } + + *desc = gpiod; + return 0; +} + +int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data) +{ + struct irq_fwspec fwspec = { }; + struct irq_domain *domain; + struct acpi_device *adev; + struct gpio_desc *gpiod; + unsigned int irq_type; + acpi_handle handle; + acpi_status status; + int irq, ret; + + switch (data->type) { + case X86_ACPI_IRQ_TYPE_APIC: + /* + * The DSDT may already reference the GSI in a device skipped by + * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI + * to avoid EBUSY errors in this case. + */ + acpi_unregister_gsi(data->index); + irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity); + if (irq < 0) + pr_err("error %d getting APIC IRQ %d\n", irq, data->index); + + return irq; + case X86_ACPI_IRQ_TYPE_GPIOINT: + /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */ + ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod); + if (ret) + return ret; + + irq = gpiod_to_irq(gpiod); + if (irq < 0) { + pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index); + return irq; + } + + irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity); + if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq)) + irq_set_irq_type(irq, irq_type); + + return irq; + case X86_ACPI_IRQ_TYPE_PMIC: + status = acpi_get_handle(NULL, data->chip, &handle); + if (ACPI_FAILURE(status)) { + pr_err("error could not get %s handle\n", data->chip); + return -ENODEV; + } + + adev = acpi_fetch_acpi_dev(handle); + if (!adev) { + pr_err("error could not get %s adev\n", data->chip); + return -ENODEV; + } + + fwspec.fwnode = acpi_fwnode_handle(adev); + domain = irq_find_matching_fwspec(&fwspec, data->domain); + if (!domain) { + pr_err("error could not find IRQ domain for %s\n", data->chip); + return -ENODEV; + } + + return irq_create_mapping(domain, data->index); + default: + return 0; + } +} + +static int i2c_client_count; +static int pdev_count; +static int serdev_count; +static struct i2c_client **i2c_clients; +static struct platform_device **pdevs; +static struct serdev_device **serdevs; +static struct gpiod_lookup_table * const *gpiod_lookup_tables; +static const struct software_node *bat_swnode; +static void (*exit_handler)(void); + +static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info, + int idx) +{ + const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx]; + struct i2c_board_info board_info = client_info->board_info; + struct i2c_adapter *adap; + acpi_handle handle; + acpi_status status; + + board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data); + if (board_info.irq < 0) + return board_info.irq; + + status = acpi_get_handle(NULL, client_info->adapter_path, &handle); + if (ACPI_FAILURE(status)) { + pr_err("Error could not get %s handle\n", client_info->adapter_path); + return -ENODEV; + } + + adap = i2c_acpi_find_adapter_by_handle(handle); + if (!adap) { + pr_err("error could not get %s adapter\n", client_info->adapter_path); + return -ENODEV; + } + + i2c_clients[idx] = i2c_new_client_device(adap, &board_info); + put_device(&adap->dev); + if (IS_ERR(i2c_clients[idx])) + return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]), + "creating I2C-client %d\n", idx); + + return 0; +} + +static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx) +{ + struct acpi_device *ctrl_adev, *serdev_adev; + struct serdev_device *serdev; + struct device *ctrl_dev; + int ret = -ENODEV; + + ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1); + if (!ctrl_adev) { + pr_err("error could not get %s/%s ctrl adev\n", + info->ctrl_hid, info->ctrl_uid); + return -ENODEV; + } + + serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1); + if (!serdev_adev) { + pr_err("error could not get %s serdev adev\n", info->serdev_hid); + goto put_ctrl_adev; + } + + /* get_first_physical_node() returns a weak ref, no need to put() it */ + ctrl_dev = acpi_get_first_physical_node(ctrl_adev); + if (!ctrl_dev) { + pr_err("error could not get %s/%s ctrl physical dev\n", + info->ctrl_hid, info->ctrl_uid); + goto put_serdev_adev; + } + + /* ctrl_dev now points to the controller's parent, get the controller */ + ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname); + if (!ctrl_dev) { + pr_err("error could not get %s/%s %s ctrl dev\n", + info->ctrl_hid, info->ctrl_uid, info->ctrl_devname); + goto put_serdev_adev; + } + + serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev)); + if (!serdev) { + ret = -ENOMEM; + goto put_serdev_adev; + } + + ACPI_COMPANION_SET(&serdev->dev, serdev_adev); + acpi_device_set_enumerated(serdev_adev); + + ret = serdev_device_add(serdev); + if (ret) { + dev_err(&serdev->dev, "error %d adding serdev\n", ret); + serdev_device_put(serdev); + goto put_serdev_adev; + } + + serdevs[idx] = serdev; + +put_serdev_adev: + acpi_dev_put(serdev_adev); +put_ctrl_adev: + acpi_dev_put(ctrl_adev); + return ret; +} + +static void x86_android_tablet_cleanup(void) +{ + int i; + + for (i = 0; i < serdev_count; i++) { + if (serdevs[i]) + serdev_device_remove(serdevs[i]); + } + + kfree(serdevs); + + for (i = 0; i < pdev_count; i++) + platform_device_unregister(pdevs[i]); + + kfree(pdevs); + + for (i = 0; i < i2c_client_count; i++) + i2c_unregister_device(i2c_clients[i]); + + kfree(i2c_clients); + + 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); +} + +extern const struct dmi_system_id x86_android_tablet_ids[]; + +static __init int x86_android_tablet_init(void) +{ + const struct x86_dev_info *dev_info; + const struct dmi_system_id *id; + struct gpio_chip *chip; + int i, ret = 0; + + id = dmi_first_match(x86_android_tablet_ids); + if (!id) + return -ENODEV; + + dev_info = id->driver_data; + + /* + * The broken DSDTs on these devices often also include broken + * _AEI (ACPI Event Interrupt) handlers, disable these. + */ + if (dev_info->invalid_aei_gpiochip) { + chip = gpiochip_find(dev_info->invalid_aei_gpiochip, + gpiochip_find_match_label); + if (!chip) { + pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip); + return -ENODEV; + } + acpi_gpiochip_free_interrupts(chip); + } + + /* + * Since this runs from module_init() it cannot use -EPROBE_DEFER, + * instead pre-load any modules which are listed as requirements. + */ + 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; + } + + 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]); + + if (dev_info->init) { + ret = dev_info->init(); + if (ret < 0) { + x86_android_tablet_cleanup(); + return ret; + } + exit_handler = dev_info->exit; + } + + i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); + if (!i2c_clients) { + x86_android_tablet_cleanup(); + return -ENOMEM; + } + + i2c_client_count = dev_info->i2c_client_count; + for (i = 0; i < i2c_client_count; i++) { + ret = x86_instantiate_i2c_client(dev_info, i); + if (ret < 0) { + x86_android_tablet_cleanup(); + return ret; + } + } + + pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL); + if (!pdevs) { + x86_android_tablet_cleanup(); + return -ENOMEM; + } + + pdev_count = dev_info->pdev_count; + for (i = 0; i < pdev_count; i++) { + pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); + if (IS_ERR(pdevs[i])) { + x86_android_tablet_cleanup(); + return PTR_ERR(pdevs[i]); + } + } + + serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL); + if (!serdevs) { + x86_android_tablet_cleanup(); + return -ENOMEM; + } + + serdev_count = dev_info->serdev_count; + for (i = 0; i < serdev_count; i++) { + ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i); + if (ret < 0) { + x86_android_tablet_cleanup(); + return ret; + } + } + + return 0; +} + +module_init(x86_android_tablet_init); +module_exit(x86_android_tablet_cleanup); + +MODULE_AUTHOR("Hans de Goede "); +MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c index 08cc5e158460..05e862756953 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c @@ -14,175 +14,17 @@ #include #include #include -#include -#include -#include -#include #include -#include -#include -#include #include #include #include #include -#include #include #include #include -#include #include -#include -/* For gpio_get_desc() which is EXPORT_SYMBOL_GPL() */ -#include "../../../gpio/gpiolib.h" -#include "../../../gpio/gpiolib-acpi.h" -/* - * Helper code to get Linux IRQ numbers given a description of the IRQ source - * (either IOAPIC index, or GPIO chip name + pin-number). - */ -enum x86_acpi_irq_type { - X86_ACPI_IRQ_TYPE_NONE, - X86_ACPI_IRQ_TYPE_APIC, - X86_ACPI_IRQ_TYPE_GPIOINT, - X86_ACPI_IRQ_TYPE_PMIC, -}; - -struct x86_acpi_irq_data { - char *chip; /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */ - enum x86_acpi_irq_type type; - enum irq_domain_bus_token domain; - int index; - int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */ - int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */ -}; - -static int gpiochip_find_match_label(struct gpio_chip *gc, void *data) -{ - return gc->label && !strcmp(gc->label, data); -} - -static int x86_android_tablet_get_gpiod(char *label, int pin, struct gpio_desc **desc) -{ - struct gpio_desc *gpiod; - struct gpio_chip *chip; - - chip = gpiochip_find(label, gpiochip_find_match_label); - if (!chip) { - pr_err("error cannot find GPIO chip %s\n", label); - return -ENODEV; - } - - gpiod = gpiochip_get_desc(chip, pin); - if (IS_ERR(gpiod)) { - pr_err("error %ld getting GPIO %s %d\n", PTR_ERR(gpiod), label, pin); - return PTR_ERR(gpiod); - } - - *desc = gpiod; - return 0; -} - -static int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data) -{ - struct irq_fwspec fwspec = { }; - struct irq_domain *domain; - struct acpi_device *adev; - struct gpio_desc *gpiod; - unsigned int irq_type; - acpi_handle handle; - acpi_status status; - int irq, ret; - - switch (data->type) { - case X86_ACPI_IRQ_TYPE_APIC: - /* - * The DSDT may already reference the GSI in a device skipped by - * acpi_quirk_skip_i2c_client_enumeration(). Unregister the GSI - * to avoid EBUSY errors in this case. - */ - acpi_unregister_gsi(data->index); - irq = acpi_register_gsi(NULL, data->index, data->trigger, data->polarity); - if (irq < 0) - pr_err("error %d getting APIC IRQ %d\n", irq, data->index); - - return irq; - case X86_ACPI_IRQ_TYPE_GPIOINT: - /* Like acpi_dev_gpio_irq_get(), but without parsing ACPI resources */ - ret = x86_android_tablet_get_gpiod(data->chip, data->index, &gpiod); - if (ret) - return ret; - - irq = gpiod_to_irq(gpiod); - if (irq < 0) { - pr_err("error %d getting IRQ %s %d\n", irq, data->chip, data->index); - return irq; - } - - irq_type = acpi_dev_get_irq_type(data->trigger, data->polarity); - if (irq_type != IRQ_TYPE_NONE && irq_type != irq_get_trigger_type(irq)) - irq_set_irq_type(irq, irq_type); - - return irq; - case X86_ACPI_IRQ_TYPE_PMIC: - status = acpi_get_handle(NULL, data->chip, &handle); - if (ACPI_FAILURE(status)) { - pr_err("error could not get %s handle\n", data->chip); - return -ENODEV; - } - - adev = acpi_fetch_acpi_dev(handle); - if (!adev) { - pr_err("error could not get %s adev\n", data->chip); - return -ENODEV; - } - - fwspec.fwnode = acpi_fwnode_handle(adev); - domain = irq_find_matching_fwspec(&fwspec, data->domain); - if (!domain) { - pr_err("error could not find IRQ domain for %s\n", data->chip); - return -ENODEV; - } - - return irq_create_mapping(domain, data->index); - default: - return 0; - } -} - -struct x86_i2c_client_info { - struct i2c_board_info board_info; - char *adapter_path; - struct x86_acpi_irq_data irq_data; -}; - -struct x86_serdev_info { - const char *ctrl_hid; - const char *ctrl_uid; - const char *ctrl_devname; - /* - * ATM the serdev core only supports of or ACPI matching; and sofar all - * Android x86 tablets DSDTs have usable serdev nodes, but sometimes - * under the wrong controller. So we just tie the existing serdev ACPI - * node to the right controller. - */ - const char *serdev_hid; -}; - -struct x86_dev_info { - char *invalid_aei_gpiochip; - const char * const *modules; - const struct software_node *bat_swnode; - struct gpiod_lookup_table * const *gpiod_lookup_tables; - const struct x86_i2c_client_info *i2c_client_info; - const struct platform_device_info *pdev_info; - const struct x86_serdev_info *serdev_info; - int i2c_client_count; - int pdev_count; - int serdev_count; - int (*init)(void); - void (*exit)(void); -}; +#include "x86-android-tablets.h" /* Generic / shared charger / battery settings */ static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" }; @@ -1507,7 +1349,7 @@ static const struct x86_dev_info xiaomi_mipad2_info __initconst = { .i2c_client_count = ARRAY_SIZE(xiaomi_mipad2_i2c_clients), }; -static const struct dmi_system_id x86_android_tablet_ids[] __initconst = { +const struct dmi_system_id x86_android_tablet_ids[] __initconst = { { /* Acer Iconia One 7 B1-750 */ .matches = { @@ -1638,247 +1480,3 @@ static const struct dmi_system_id x86_android_tablet_ids[] __initconst = { { } }; MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids); - -static int i2c_client_count; -static int pdev_count; -static int serdev_count; -static struct i2c_client **i2c_clients; -static struct platform_device **pdevs; -static struct serdev_device **serdevs; -static struct gpiod_lookup_table * const *gpiod_lookup_tables; -static const struct software_node *bat_swnode; -static void (*exit_handler)(void); - -static __init int x86_instantiate_i2c_client(const struct x86_dev_info *dev_info, - int idx) -{ - const struct x86_i2c_client_info *client_info = &dev_info->i2c_client_info[idx]; - struct i2c_board_info board_info = client_info->board_info; - struct i2c_adapter *adap; - acpi_handle handle; - acpi_status status; - - board_info.irq = x86_acpi_irq_helper_get(&client_info->irq_data); - if (board_info.irq < 0) - return board_info.irq; - - status = acpi_get_handle(NULL, client_info->adapter_path, &handle); - if (ACPI_FAILURE(status)) { - pr_err("Error could not get %s handle\n", client_info->adapter_path); - return -ENODEV; - } - - adap = i2c_acpi_find_adapter_by_handle(handle); - if (!adap) { - pr_err("error could not get %s adapter\n", client_info->adapter_path); - return -ENODEV; - } - - i2c_clients[idx] = i2c_new_client_device(adap, &board_info); - put_device(&adap->dev); - if (IS_ERR(i2c_clients[idx])) - return dev_err_probe(&adap->dev, PTR_ERR(i2c_clients[idx]), - "creating I2C-client %d\n", idx); - - return 0; -} - -static __init int x86_instantiate_serdev(const struct x86_serdev_info *info, int idx) -{ - struct acpi_device *ctrl_adev, *serdev_adev; - struct serdev_device *serdev; - struct device *ctrl_dev; - int ret = -ENODEV; - - ctrl_adev = acpi_dev_get_first_match_dev(info->ctrl_hid, info->ctrl_uid, -1); - if (!ctrl_adev) { - pr_err("error could not get %s/%s ctrl adev\n", - info->ctrl_hid, info->ctrl_uid); - return -ENODEV; - } - - serdev_adev = acpi_dev_get_first_match_dev(info->serdev_hid, NULL, -1); - if (!serdev_adev) { - pr_err("error could not get %s serdev adev\n", info->serdev_hid); - goto put_ctrl_adev; - } - - /* get_first_physical_node() returns a weak ref, no need to put() it */ - ctrl_dev = acpi_get_first_physical_node(ctrl_adev); - if (!ctrl_dev) { - pr_err("error could not get %s/%s ctrl physical dev\n", - info->ctrl_hid, info->ctrl_uid); - goto put_serdev_adev; - } - - /* ctrl_dev now points to the controller's parent, get the controller */ - ctrl_dev = device_find_child_by_name(ctrl_dev, info->ctrl_devname); - if (!ctrl_dev) { - pr_err("error could not get %s/%s %s ctrl dev\n", - info->ctrl_hid, info->ctrl_uid, info->ctrl_devname); - goto put_serdev_adev; - } - - serdev = serdev_device_alloc(to_serdev_controller(ctrl_dev)); - if (!serdev) { - ret = -ENOMEM; - goto put_serdev_adev; - } - - ACPI_COMPANION_SET(&serdev->dev, serdev_adev); - acpi_device_set_enumerated(serdev_adev); - - ret = serdev_device_add(serdev); - if (ret) { - dev_err(&serdev->dev, "error %d adding serdev\n", ret); - serdev_device_put(serdev); - goto put_serdev_adev; - } - - serdevs[idx] = serdev; - -put_serdev_adev: - acpi_dev_put(serdev_adev); -put_ctrl_adev: - acpi_dev_put(ctrl_adev); - return ret; -} - -static void x86_android_tablet_cleanup(void) -{ - int i; - - for (i = 0; i < serdev_count; i++) { - if (serdevs[i]) - serdev_device_remove(serdevs[i]); - } - - kfree(serdevs); - - for (i = 0; i < pdev_count; i++) - platform_device_unregister(pdevs[i]); - - kfree(pdevs); - - for (i = 0; i < i2c_client_count; i++) - i2c_unregister_device(i2c_clients[i]); - - kfree(i2c_clients); - - 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); -} - -static __init int x86_android_tablet_init(void) -{ - const struct x86_dev_info *dev_info; - const struct dmi_system_id *id; - struct gpio_chip *chip; - int i, ret = 0; - - id = dmi_first_match(x86_android_tablet_ids); - if (!id) - return -ENODEV; - - dev_info = id->driver_data; - - /* - * The broken DSDTs on these devices often also include broken - * _AEI (ACPI Event Interrupt) handlers, disable these. - */ - if (dev_info->invalid_aei_gpiochip) { - chip = gpiochip_find(dev_info->invalid_aei_gpiochip, - gpiochip_find_match_label); - if (!chip) { - pr_err("error cannot find GPIO chip %s\n", dev_info->invalid_aei_gpiochip); - return -ENODEV; - } - acpi_gpiochip_free_interrupts(chip); - } - - /* - * Since this runs from module_init() it cannot use -EPROBE_DEFER, - * instead pre-load any modules which are listed as requirements. - */ - 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; - } - - 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]); - - if (dev_info->init) { - ret = dev_info->init(); - if (ret < 0) { - x86_android_tablet_cleanup(); - return ret; - } - exit_handler = dev_info->exit; - } - - i2c_clients = kcalloc(dev_info->i2c_client_count, sizeof(*i2c_clients), GFP_KERNEL); - if (!i2c_clients) { - x86_android_tablet_cleanup(); - return -ENOMEM; - } - - i2c_client_count = dev_info->i2c_client_count; - for (i = 0; i < i2c_client_count; i++) { - ret = x86_instantiate_i2c_client(dev_info, i); - if (ret < 0) { - x86_android_tablet_cleanup(); - return ret; - } - } - - pdevs = kcalloc(dev_info->pdev_count, sizeof(*pdevs), GFP_KERNEL); - if (!pdevs) { - x86_android_tablet_cleanup(); - return -ENOMEM; - } - - pdev_count = dev_info->pdev_count; - for (i = 0; i < pdev_count; i++) { - pdevs[i] = platform_device_register_full(&dev_info->pdev_info[i]); - if (IS_ERR(pdevs[i])) { - x86_android_tablet_cleanup(); - return PTR_ERR(pdevs[i]); - } - } - - serdevs = kcalloc(dev_info->serdev_count, sizeof(*serdevs), GFP_KERNEL); - if (!serdevs) { - x86_android_tablet_cleanup(); - return -ENOMEM; - } - - serdev_count = dev_info->serdev_count; - for (i = 0; i < serdev_count; i++) { - ret = x86_instantiate_serdev(&dev_info->serdev_info[i], i); - if (ret < 0) { - x86_android_tablet_cleanup(); - return ret; - } - } - - return 0; -} - -module_init(x86_android_tablet_init); -module_exit(x86_android_tablet_cleanup); - -MODULE_AUTHOR("Hans de Goede "); -MODULE_DESCRIPTION("X86 Android tablets DSDT fixups driver"); -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 new file mode 100644 index 000000000000..2023b53e0df2 --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -0,0 +1,77 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * DMI based code to deal with broken DSDTs on X86 tablets which ship with + * Android as (part of) the factory image. The factory kernels shipped on these + * devices typically have a bunch of things hardcoded, rather than specified + * in their DSDT. + * + * Copyright (C) 2021-2023 Hans de Goede + */ +#ifndef __X86_ANDROID_TABLETS_H +#define __X86_ANDROID_TABLETS_H + +#include +#include +#include +#include +#include + +/* + * Helpers to get Linux IRQ numbers given a description of the IRQ source + * (either IOAPIC index, or GPIO chip name + pin-number). + */ +enum x86_acpi_irq_type { + X86_ACPI_IRQ_TYPE_NONE, + X86_ACPI_IRQ_TYPE_APIC, + X86_ACPI_IRQ_TYPE_GPIOINT, + X86_ACPI_IRQ_TYPE_PMIC, +}; + +struct x86_acpi_irq_data { + char *chip; /* GPIO chip label (GPIOINT) or PMIC ACPI path (PMIC) */ + enum x86_acpi_irq_type type; + enum irq_domain_bus_token domain; + int index; + int trigger; /* ACPI_EDGE_SENSITIVE / ACPI_LEVEL_SENSITIVE */ + int polarity; /* ACPI_ACTIVE_HIGH / ACPI_ACTIVE_LOW / ACPI_ACTIVE_BOTH */ +}; + +/* Structs to describe devices to instantiate */ +struct x86_i2c_client_info { + struct i2c_board_info board_info; + char *adapter_path; + struct x86_acpi_irq_data irq_data; +}; + +struct x86_serdev_info { + const char *ctrl_hid; + const char *ctrl_uid; + const char *ctrl_devname; + /* + * ATM the serdev core only supports of or ACPI matching; and sofar all + * Android x86 tablets DSDTs have usable serdev nodes, but sometimes + * under the wrong controller. So we just tie the existing serdev ACPI + * node to the right controller. + */ + const char *serdev_hid; +}; + +struct x86_dev_info { + char *invalid_aei_gpiochip; + const char * const *modules; + const struct software_node *bat_swnode; + struct gpiod_lookup_table * const *gpiod_lookup_tables; + const struct x86_i2c_client_info *i2c_client_info; + const struct platform_device_info *pdev_info; + const struct x86_serdev_info *serdev_info; + int i2c_client_count; + int pdev_count; + int serdev_count; + int (*init)(void); + void (*exit)(void); +}; + +int x86_android_tablet_get_gpiod(const char *label, int pin, struct gpio_desc **desc); +int x86_acpi_irq_helper_get(const struct x86_acpi_irq_data *data); + +#endif From patchwork Mon Feb 20 22:12:06 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147165 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 02726C636D6 for ; Mon, 20 Feb 2023 22:13:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232630AbjBTWNO (ORCPT ); Mon, 20 Feb 2023 17:13:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232615AbjBTWNN (ORCPT ); Mon, 20 Feb 2023 17:13:13 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5480F1E280 for ; Mon, 20 Feb 2023 14:12:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931148; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=c6Usd3s6Lao8WuFKMO+XOf44ZFSAu8HX6pOWf1ftPx8=; b=hWig0mIIVw+wJ/jMJj3JZJLfSu3C017a4Wa8x5l6b82JAQECLc/y9XQmAd6+hrsMNcFhCK ypMXex+dZDrOp4NnF77TQoYgoM/YvpUjfulDjH0mg38tApbG5/QsCIGu7kBQ6yDFRHZKpK CDu0owwtgxBdpWla1IXJfgPT1ofd8dM= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-100-FtXai-nYOGqwKbtulAdyxg-1; Mon, 20 Feb 2023 17:12:24 -0500 X-MC-Unique: FtXai-nYOGqwKbtulAdyxg-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 0D06285A5A3; Mon, 20 Feb 2023 22:12:24 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6831A140EBF6; Mon, 20 Feb 2023 22:12:23 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 3/9] platform/x86: x86-android-tablets: Move DMI match table into its own dmi.c file Date: Mon, 20 Feb 2023 23:12:06 +0100 Message-Id: <20230220221212.196009-4-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org In order to have a single MODULE_DEVICE_TABLE(dmi, ...), while allowing splitting the board descriptions into multiple files, add a new separate file for the DMI match table. Signed-off-by: Hans de Goede --- .../platform/x86/x86-android-tablets/Makefile | 2 +- .../platform/x86/x86-android-tablets/dmi.c | 166 ++++++++++++++++++ .../x86-android-tablets-main.c | 160 ++--------------- 3 files changed, 180 insertions(+), 148 deletions(-) create mode 100644 drivers/platform/x86/x86-android-tablets/dmi.c diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index 49c6bda1f817..ba16dc014e03 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o -x86-android-tablets-y := core.o x86-android-tablets-main.o +x86-android-tablets-y := core.o dmi.o x86-android-tablets-main.o diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c new file mode 100644 index 000000000000..ec7c0af8d73d --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/dmi.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DMI based code to deal with broken DSDTs on X86 tablets which ship with + * Android as (part of) the factory image. The factory kernels shipped on these + * devices typically have a bunch of things hardcoded, rather than specified + * in their DSDT. + * + * Copyright (C) 2021-2023 Hans de Goede + */ + +#include +#include + +#include "x86-android-tablets.h" + +/* + * In order to have a single MODULE_DEVICE_TABLE(dmi, ...), while allowing + * splitting the board descriptions into multiple files, add extern declarations + * of the x86_dev_info structs here. + */ +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; +extern const struct x86_dev_info asus_tf103c_info; +extern const struct x86_dev_info chuwi_hi8_info; +extern const struct x86_dev_info czc_p10t; +extern const struct x86_dev_info lenovo_yogabook_x9x_info; +/* Not const as this gets modified by its init callback */ +extern struct x86_dev_info lenovo_yoga_tab2_830_1050_info; +extern const struct x86_dev_info lenovo_yt3_info; +extern const struct x86_dev_info medion_lifetab_s10346_info; +extern const struct x86_dev_info nextbook_ares8_info; +extern const struct x86_dev_info whitelabel_tm800a550l_info; +extern const struct x86_dev_info xiaomi_mipad2_info; + +const struct dmi_system_id x86_android_tablet_ids[] __initconst = { + { + /* Acer Iconia One 7 B1-750 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "VESPA2"), + }, + .driver_data = (void *)&acer_b1_750_info, + }, + { + /* Advantech MICA-071 */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"), + }, + .driver_data = (void *)&advantech_mica_071_info, + }, + { + /* Asus MeMO Pad 7 ME176C */ + .matches = { + DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"), + }, + .driver_data = (void *)&asus_me176c_info, + }, + { + /* Asus TF103C */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), + }, + .driver_data = (void *)&asus_tf103c_info, + }, + { + /* Chuwi Hi8 (CWI509) */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), + DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"), + DMI_MATCH(DMI_SYS_VENDOR, "ilife"), + DMI_MATCH(DMI_PRODUCT_NAME, "S806"), + }, + .driver_data = (void *)&chuwi_hi8_info, + }, + { + /* CZC P10T */ + .ident = "CZC ODEON TPC-10 (\"P10T\")", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "CZC"), + DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"), + }, + .driver_data = (void *)&czc_p10t, + }, + { + /* CZC P10T variant */ + .ident = "ViewSonic ViewPad 10", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"), + DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"), + }, + .driver_data = (void *)&czc_p10t, + }, + { + /* Lenovo Yoga Book X90F / X91F / X91L */ + .matches = { + /* Non exact match to match all versions */ + DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), + }, + .driver_data = (void *)&lenovo_yogabook_x9x_info, + }, + { + /* + * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10" + * Lenovo Yoga Tablet 2 use the same mainboard) + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), + DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), + DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"), + /* Partial match on beginning of BIOS version */ + DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), + }, + .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info, + }, + { + /* Lenovo Yoga Tab 3 Pro YT3-X90F */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), + DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), + }, + .driver_data = (void *)&lenovo_yt3_info, + }, + { + /* Medion Lifetab S10346 */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are much too generic, also match on BIOS date */ + DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"), + }, + .driver_data = (void *)&medion_lifetab_s10346_info, + }, + { + /* Nextbook Ares 8 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), + DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"), + }, + .driver_data = (void *)&nextbook_ares8_info, + }, + { + /* Whitelabel (sold as various brands) TM800A550L */ + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), + DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), + /* Above strings are too generic, also match on BIOS version */ + DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), + }, + .driver_data = (void *)&whitelabel_tm800a550l_info, + }, + { + /* Xiaomi Mi Pad 2 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), + DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), + }, + .driver_data = (void *)&xiaomi_mipad2_info, + }, + { } +}; +MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids); diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c index 05e862756953..4914b43eb4cd 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c @@ -11,11 +11,9 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include -#include #include #include #include -#include #include #include #include @@ -181,7 +179,7 @@ static struct gpiod_lookup_table * const acer_b1_750_gpios[] = { NULL }; -static const struct x86_dev_info acer_b1_750_info __initconst = { +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, @@ -233,7 +231,7 @@ static int __init advantech_mica_071_init(void) return 0; } -static const struct x86_dev_info advantech_mica_071_info __initconst = { +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, @@ -414,7 +412,7 @@ static struct gpiod_lookup_table * const asus_me176c_gpios[] = { NULL }; -static const struct x86_dev_info asus_me176c_info __initconst = { +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, @@ -559,7 +557,7 @@ static struct gpiod_lookup_table * const asus_tf103c_gpios[] = { NULL }; -static const struct x86_dev_info asus_tf103c_info __initconst = { +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, @@ -650,7 +648,7 @@ static int __init chuwi_hi8_init(void) return 0; } -static const struct x86_dev_info chuwi_hi8_info __initconst = { +const struct x86_dev_info chuwi_hi8_info __initconst = { .i2c_client_info = chuwi_hi8_i2c_clients, .i2c_client_count = ARRAY_SIZE(chuwi_hi8_i2c_clients), .init = chuwi_hi8_init, @@ -685,7 +683,7 @@ static int __init czc_p10t_init(void) return 0; } -static const struct x86_dev_info czc_p10t __initconst = { +const struct x86_dev_info czc_p10t __initconst = { .init = czc_p10t_init, }; @@ -703,7 +701,7 @@ static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __init }, }; -static const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = { +const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = { .i2c_client_info = lenovo_yogabook_x9x_i2c_clients, .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients), }; @@ -814,7 +812,7 @@ static struct gpiod_lookup_table * const lenovo_yoga_tab2_830_1050_gpios[] = { static int __init lenovo_yoga_tab2_830_1050_init(void); static void lenovo_yoga_tab2_830_1050_exit(void); -static struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = { +struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = { .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients, /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */ .pdev_info = int3496_pdevs, @@ -1079,7 +1077,7 @@ static int __init lenovo_yt3_init(void) return 0; } -static const struct x86_dev_info lenovo_yt3_info __initconst = { +const struct x86_dev_info lenovo_yt3_info __initconst = { .i2c_client_info = lenovo_yt3_i2c_clients, .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), .init = lenovo_yt3_init, @@ -1161,7 +1159,7 @@ static struct gpiod_lookup_table * const medion_lifetab_s10346_gpios[] = { NULL }; -static const struct x86_dev_info medion_lifetab_s10346_info __initconst = { +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, @@ -1227,7 +1225,7 @@ static struct gpiod_lookup_table * const nextbook_ares8_gpios[] = { NULL }; -static const struct x86_dev_info nextbook_ares8_info __initconst = { +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, @@ -1310,7 +1308,7 @@ static struct gpiod_lookup_table * const whitelabel_tm800a550l_gpios[] = { NULL }; -static const struct x86_dev_info whitelabel_tm800a550l_info __initconst = { +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, @@ -1344,139 +1342,7 @@ static const struct x86_i2c_client_info xiaomi_mipad2_i2c_clients[] __initconst }, }; -static const struct x86_dev_info xiaomi_mipad2_info __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), }; - -const struct dmi_system_id x86_android_tablet_ids[] __initconst = { - { - /* Acer Iconia One 7 B1-750 */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), - DMI_MATCH(DMI_PRODUCT_NAME, "VESPA2"), - }, - .driver_data = (void *)&acer_b1_750_info, - }, - { - /* Advantech MICA-071 */ - .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Advantech"), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "MICA-071"), - }, - .driver_data = (void *)&advantech_mica_071_info, - }, - { - /* Asus MeMO Pad 7 ME176C */ - .matches = { - DMI_EXACT_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "ME176C"), - }, - .driver_data = (void *)&asus_me176c_info, - }, - { - /* Asus TF103C */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), - DMI_MATCH(DMI_PRODUCT_NAME, "TF103C"), - }, - .driver_data = (void *)&asus_tf103c_info, - }, - { - /* Chuwi Hi8 (CWI509) */ - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "Hampoo"), - DMI_MATCH(DMI_BOARD_NAME, "BYT-PA03C"), - DMI_MATCH(DMI_SYS_VENDOR, "ilife"), - DMI_MATCH(DMI_PRODUCT_NAME, "S806"), - }, - .driver_data = (void *)&chuwi_hi8_info, - }, - { - /* CZC P10T */ - .ident = "CZC ODEON TPC-10 (\"P10T\")", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "CZC"), - DMI_MATCH(DMI_PRODUCT_NAME, "ODEON*TPC-10"), - }, - .driver_data = (void *)&czc_p10t, - }, - { - /* CZC P10T variant */ - .ident = "ViewSonic ViewPad 10", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "ViewSonic"), - DMI_MATCH(DMI_PRODUCT_NAME, "VPAD10"), - }, - .driver_data = (void *)&czc_p10t, - }, - { - /* Lenovo Yoga Book X90F / X91F / X91L */ - .matches = { - /* Non exact match to match all versions */ - DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), - }, - .driver_data = (void *)&lenovo_yogabook_x9x_info, - }, - { - /* - * Lenovo Yoga Tablet 2 830F/L or 1050F/L (The 8" and 10" - * Lenovo Yoga Tablet 2 use the same mainboard) - */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp."), - DMI_MATCH(DMI_PRODUCT_NAME, "VALLEYVIEW C0 PLATFORM"), - DMI_MATCH(DMI_BOARD_NAME, "BYT-T FFD8"), - /* Partial match on beginning of BIOS version */ - DMI_MATCH(DMI_BIOS_VERSION, "BLADE_21"), - }, - .driver_data = (void *)&lenovo_yoga_tab2_830_1050_info, - }, - { - /* Lenovo Yoga Tab 3 Pro YT3-X90F */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation"), - DMI_MATCH(DMI_PRODUCT_NAME, "CHERRYVIEW D1 PLATFORM"), - DMI_MATCH(DMI_PRODUCT_VERSION, "Blade3-10A-001"), - }, - .driver_data = (void *)&lenovo_yt3_info, - }, - { - /* Medion Lifetab S10346 */ - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), - /* Above strings are much too generic, also match on BIOS date */ - DMI_MATCH(DMI_BIOS_DATE, "10/22/2015"), - }, - .driver_data = (void *)&medion_lifetab_s10346_info, - }, - { - /* Nextbook Ares 8 */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Insyde"), - DMI_MATCH(DMI_PRODUCT_NAME, "M890BAP"), - }, - .driver_data = (void *)&nextbook_ares8_info, - }, - { - /* Whitelabel (sold as various brands) TM800A550L */ - .matches = { - DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), - DMI_MATCH(DMI_BOARD_NAME, "Aptio CRB"), - /* Above strings are too generic, also match on BIOS version */ - DMI_MATCH(DMI_BIOS_VERSION, "ZY-8-BI-PX4S70VTR400-X423B-005-D"), - }, - .driver_data = (void *)&whitelabel_tm800a550l_info, - }, - { - /* Xiaomi Mi Pad 2 */ - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "Xiaomi Inc"), - DMI_MATCH(DMI_PRODUCT_NAME, "Mipad2"), - }, - .driver_data = (void *)&xiaomi_mipad2_info, - }, - { } -}; -MODULE_DEVICE_TABLE(dmi, x86_android_tablet_ids); From patchwork Mon Feb 20 22:12:07 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147164 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 81A49C6379F for ; Mon, 20 Feb 2023 22:13:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232613AbjBTWNO (ORCPT ); Mon, 20 Feb 2023 17:13:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33256 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232630AbjBTWNN (ORCPT ); Mon, 20 Feb 2023 17:13:13 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F854BDE7 for ; Mon, 20 Feb 2023 14:12:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931148; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=IcF78M6iyssoLqi9p/oufhgm/m06FrucinefHodPjbg=; b=J8FlHGu4pPb29R7HpmAwi2GGNXdBGe55bxZ102PjxjiVq3NH/w81sCwrHW2B/Ywti54ttg Ycio8sK1moGQek7plSUL6BcZJH+QnpWdFFi9lRxbJIe7sS1oXZl91K//mZpotkHyECyl5l bGjqMGUh/ENExoO+VewLyZx+peNSJH4= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-275-jVQz51OHPMikUbGWpTl1oA-1; Mon, 20 Feb 2023 17:12:25 -0500 X-MC-Unique: jVQz51OHPMikUbGWpTl1oA-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id D7958380662E; Mon, 20 Feb 2023 22:12:24 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3CDAA140EBF6; Mon, 20 Feb 2023 22:12:24 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 4/9] platform/x86: x86-android-tablets: Move shared power-supply fw-nodes to a separate file Date: Mon, 20 Feb 2023 23:12:07 +0100 Message-Id: <20230220221212.196009-5-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Move the shared power-supply fw-nodes and related files to a new separate shared-psy-info.c file. Signed-off-by: Hans de Goede --- .../platform/x86/x86-android-tablets/Makefile | 2 +- .../x86/x86-android-tablets/shared-psy-info.c | 100 +++++++++++++++++ .../x86/x86-android-tablets/shared-psy-info.h | 32 ++++++ .../x86-android-tablets-main.c | 101 ++---------------- 4 files changed, 142 insertions(+), 93 deletions(-) create mode 100644 drivers/platform/x86/x86-android-tablets/shared-psy-info.c create mode 100644 drivers/platform/x86/x86-android-tablets/shared-psy-info.h diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index ba16dc014e03..6383a1b26481 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o -x86-android-tablets-y := core.o dmi.o x86-android-tablets-main.o +x86-android-tablets-y := core.o dmi.o shared-psy-info.o x86-android-tablets-main.o diff --git a/drivers/platform/x86/x86-android-tablets/shared-psy-info.c b/drivers/platform/x86/x86-android-tablets/shared-psy-info.c new file mode 100644 index 000000000000..5af601f6bee4 --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/shared-psy-info.c @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Shared psy info for 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-2023 Hans de Goede + */ + +#include +#include +#include +#include +#include + +#include "shared-psy-info.h" + +/* Generic / shared charger / battery settings */ +const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" }; +const char * const bq24190_psy[] = { "bq24190-charger" }; +const char * const bq25890_psy[] = { "bq25890-charger-0" }; + +static const struct property_entry fg_bq24190_supply_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy), + { } +}; + +const struct software_node fg_bq24190_supply_node = { + .properties = fg_bq24190_supply_props, +}; + +static const struct property_entry fg_bq25890_supply_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy), + { } +}; + +const struct software_node fg_bq25890_supply_node = { + .properties = fg_bq25890_supply_props, +}; + +/* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV bat. */ +static const struct property_entry generic_lipo_hv_4v35_battery_props[] = { + PROPERTY_ENTRY_STRING("compatible", "simple-battery"), + PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion"), + PROPERTY_ENTRY_U32("precharge-current-microamp", 256000), + PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000), + PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 1856000), + PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4352000), + PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000), + { } +}; + +const struct software_node generic_lipo_hv_4v35_battery_node = { + .properties = generic_lipo_hv_4v35_battery_props, +}; + +/* For enabling the bq24190 5V boost based on id-pin */ +static struct regulator_consumer_supply intel_int3496_consumer = { + .supply = "vbus", + .dev_name = "intel-int3496", +}; + +static const struct regulator_init_data bq24190_vbus_init_data = { + .constraints = { + .name = "bq24190_vbus", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .consumer_supplies = &intel_int3496_consumer, + .num_consumer_supplies = 1, +}; + +struct bq24190_platform_data bq24190_pdata = { + .regulator_init_data = &bq24190_vbus_init_data, +}; + +const char * const bq24190_modules[] __initconst = { + "intel_crystal_cove_charger", /* For the bq24190 IRQ */ + "bq24190_charger", /* For the Vbus regulator for intel-int3496 */ + NULL +}; + +/* 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), + { } + }, +}; diff --git a/drivers/platform/x86/x86-android-tablets/shared-psy-info.h b/drivers/platform/x86/x86-android-tablets/shared-psy-info.h new file mode 100644 index 000000000000..bff3c82a16fb --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/shared-psy-info.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Shared psy info for 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-2023 Hans de Goede + */ +#ifndef __SHARED_PSY_INFO_H +#define __SHARED_PSY_INFO_H + +#include +#include +#include +#include + +extern const char * const tusb1211_chg_det_psy[]; +extern const char * const bq24190_psy[]; +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_hv_4v35_battery_node; + +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/x86-android-tablets-main.c b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c index 4914b43eb4cd..ebe3cdeeb33a 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c @@ -17,86 +17,13 @@ #include #include #include -#include #include #include #include +#include "shared-psy-info.h" #include "x86-android-tablets.h" -/* Generic / shared charger / battery settings */ -static const char * const tusb1211_chg_det_psy[] = { "tusb1211-charger-detect" }; -static const char * const bq24190_psy[] = { "bq24190-charger" }; -static const char * const bq25890_psy[] = { "bq25890-charger-0" }; - -static const struct property_entry fg_bq24190_supply_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy), - { } -}; - -static const struct software_node fg_bq24190_supply_node = { - .properties = fg_bq24190_supply_props, -}; - -static const struct property_entry fg_bq25890_supply_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_psy), - { } -}; - -static const struct software_node fg_bq25890_supply_node = { - .properties = fg_bq25890_supply_props, -}; - -/* LiPo HighVoltage (max 4.35V) settings used by most devs with a HV bat. */ -static const struct property_entry generic_lipo_hv_4v35_battery_props[] = { - PROPERTY_ENTRY_STRING("compatible", "simple-battery"), - PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion"), - PROPERTY_ENTRY_U32("precharge-current-microamp", 256000), - PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000), - PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 1856000), - PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4352000), - PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000), - { } -}; - -static const struct software_node generic_lipo_hv_4v35_battery_node = { - .properties = generic_lipo_hv_4v35_battery_props, -}; - -/* For enabling the bq24190 5V boost based on id-pin */ -static struct regulator_consumer_supply intel_int3496_consumer = { - .supply = "vbus", - .dev_name = "intel-int3496", -}; - -static const struct regulator_init_data bq24190_vbus_init_data = { - .constraints = { - .name = "bq24190_vbus", - .valid_ops_mask = REGULATOR_CHANGE_STATUS, - }, - .consumer_supplies = &intel_int3496_consumer, - .num_consumer_supplies = 1, -}; - -static struct bq24190_platform_data bq24190_pdata = { - .regulator_init_data = &bq24190_vbus_init_data, -}; - -static const char * const bq24190_modules[] __initconst = { - "intel_crystal_cove_charger", /* For the bq24190 IRQ */ - "bq24190_charger", /* For the Vbus regulator for intel-int3496 */ - NULL -}; - -/* Generic pdevs array and gpio-lookups for micro USB ID pin handling */ -static const struct platform_device_info int3496_pdevs[] __initconst = { - { - /* For micro USB ID pin handling */ - .name = "intel-int3496", - .id = PLATFORM_DEVID_NONE, - }, -}; - static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = { .dev_id = "intel-int3496", .table = { @@ -105,16 +32,6 @@ static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = { }, }; -static 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), - { } - }, -}; - /* Acer Iconia One 7 B1-750 has an Android factory img with everything hardcoded */ static const char * const acer_b1_750_mount_matrix[] = { "-1", "0", "0", @@ -183,7 +100,7 @@ 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 = ARRAY_SIZE(int3496_pdevs), + .pdev_count = 1, .gpiod_lookup_tables = acer_b1_750_gpios, }; @@ -299,7 +216,7 @@ static const struct software_node asus_me176c_accel_node = { }; static const struct property_entry asus_me176c_bq24190_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy), + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000), PROPERTY_ENTRY_BOOL("omit-battery-class"), @@ -312,7 +229,7 @@ static const struct software_node asus_me176c_bq24190_node = { }; static const struct property_entry asus_me176c_ug3105_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy), + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000), { } @@ -467,7 +384,7 @@ static const struct software_node asus_tf103c_battery_node = { }; static const struct property_entry asus_tf103c_bq24190_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy), + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node), PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000), PROPERTY_ENTRY_BOOL("omit-battery-class"), @@ -480,7 +397,7 @@ static const struct software_node asus_tf103c_bq24190_node = { }; static const struct property_entry asus_tf103c_ug3105_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq24190_psy), + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node), PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000), { } @@ -708,7 +625,7 @@ const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = { /* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */ static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", tusb1211_chg_det_psy), + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), PROPERTY_ENTRY_BOOL("omit-battery-class"), PROPERTY_ENTRY_BOOL("disable-reset"), @@ -816,7 +733,7 @@ struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = { .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients, /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */ .pdev_info = int3496_pdevs, - .pdev_count = ARRAY_SIZE(int3496_pdevs), + .pdev_count = 1, .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios, .bat_swnode = &generic_lipo_hv_4v35_battery_node, .modules = bq24190_modules, @@ -1229,7 +1146,7 @@ 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 = ARRAY_SIZE(int3496_pdevs), + .pdev_count = 1, .gpiod_lookup_tables = nextbook_ares8_gpios, .invalid_aei_gpiochip = "INT33FC:02", }; From patchwork Mon Feb 20 22:12:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1ADFDC636D6 for ; Mon, 20 Feb 2023 22:13:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232637AbjBTWNJ (ORCPT ); Mon, 20 Feb 2023 17:13:09 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33300 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232507AbjBTWNI (ORCPT ); Mon, 20 Feb 2023 17:13:08 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1B350CC01 for ; Mon, 20 Feb 2023 14:12:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931149; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=glzpkaHz/PdkPHM5pKSV7nhEe/mVpRFAaScWWQKx2dE=; b=I42PAgs9s43zcFnvKRMpbBRePVnuztWNeaoBD/XPGEFlp+D/zJpvVnzyu3NyqRgY+4TlUg Q2NS6QH4qVppTS5j1p7sfZ5+l5kt+zz0kH3paWJ+DrGcD3R5WsbUS8nPNujb3+br9azel8 pBbY1vD/A9vdiE2Y7mzAGZwZ7ss5MIg= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-192-HGiLMPsQPI-wqBlRzCMKkw-1; Mon, 20 Feb 2023 17:12:26 -0500 X-MC-Unique: HGiLMPsQPI-wqBlRzCMKkw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id C54A529AA2D3; Mon, 20 Feb 2023 22:12:25 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 12A1A140EBF6; Mon, 20 Feb 2023 22:12:24 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 5/9] platform/x86: x86-android-tablets: Move Asus tablets to their own file Date: Mon, 20 Feb 2023 23:12:08 +0100 Message-Id: <20230220221212.196009-6-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Move the info for the Asus tablets to their own asus.c file. Signed-off-by: Hans de Goede --- .../platform/x86/x86-android-tablets/Makefile | 2 +- .../platform/x86/x86-android-tablets/asus.c | 355 ++++++++++++++++++ .../x86-android-tablets-main.c | 340 ----------------- 3 files changed, 356 insertions(+), 341 deletions(-) create mode 100644 drivers/platform/x86/x86-android-tablets/asus.c diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index 6383a1b26481..a527f0a94034 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -5,4 +5,4 @@ obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o -x86-android-tablets-y := core.o dmi.o shared-psy-info.o x86-android-tablets-main.o +x86-android-tablets-y := core.o dmi.o shared-psy-info.o asus.o x86-android-tablets-main.o diff --git a/drivers/platform/x86/x86-android-tablets/asus.c b/drivers/platform/x86/x86-android-tablets/asus.c new file mode 100644 index 000000000000..c7d3ca73ebd3 --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/asus.c @@ -0,0 +1,355 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Board info for Asus 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-2023 Hans de Goede + */ + +#include +#include + +#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 struct gpio_keys_button asus_me176c_tf103c_lid = { + .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, + }, +}; + +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", + "0", "1", "0", + "0", "0", "1" +}; + +static const struct property_entry asus_me176c_accel_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix), + { } +}; + +static const struct software_node asus_me176c_accel_node = { + .properties = asus_me176c_accel_props, +}; + +static const struct property_entry asus_me176c_bq24190_props[] = { + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), + PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), + PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000), + PROPERTY_ENTRY_BOOL("omit-battery-class"), + PROPERTY_ENTRY_BOOL("disable-reset"), + { } +}; + +static const struct software_node asus_me176c_bq24190_node = { + .properties = asus_me176c_bq24190_props, +}; + +static const struct property_entry asus_me176c_ug3105_props[] = { + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), + PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), + PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000), + { } +}; + +static const struct software_node asus_me176c_ug3105_node = { + .properties = asus_me176c_ug3105_props, +}; + +static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = { + { + /* bq24297 battery charger */ + .board_info = { + .type = "bq24190", + .addr = 0x6b, + .dev_name = "bq24297", + .swnode = &asus_me176c_bq24190_node, + .platform_data = &bq24190_pdata, + }, + .adapter_path = "\\_SB_.I2C1", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_PMIC, + .chip = "\\_SB_.I2C7.PMIC", + .domain = DOMAIN_BUS_WAKEUP, + .index = 0, + }, + }, { + /* ug3105 battery monitor */ + .board_info = { + .type = "ug3105", + .addr = 0x70, + .dev_name = "ug3105", + .swnode = &asus_me176c_ug3105_node, + }, + .adapter_path = "\\_SB_.I2C1", + }, { + /* ak09911 compass */ + .board_info = { + .type = "ak09911", + .addr = 0x0c, + .dev_name = "ak09911", + }, + .adapter_path = "\\_SB_.I2C5", + }, { + /* kxtj21009 accel */ + .board_info = { + .type = "kxtj21009", + .addr = 0x0f, + .dev_name = "kxtj21009", + .swnode = &asus_me176c_accel_node, + }, + .adapter_path = "\\_SB_.I2C5", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_APIC, + .index = 0x44, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + }, + }, { + /* goodix touchscreen */ + .board_info = { + .type = "GDIX1001:00", + .addr = 0x14, + .dev_name = "goodix_ts", + }, + .adapter_path = "\\_SB_.I2C6", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_APIC, + .index = 0x45, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + }, + }, +}; + +static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = { + { + .ctrl_hid = "80860F0A", + .ctrl_uid = "2", + .ctrl_devname = "serial0", + .serdev_hid = "BCM2E3A", + }, +}; + +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 = asus_me176c_tf103c_pdevs, + .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), + .serdev_info = asus_me176c_serdevs, + .serdev_count = ARRAY_SIZE(asus_me176c_serdevs), + .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 */ +static const char * const asus_tf103c_accel_mount_matrix[] = { + "0", "-1", "0", + "-1", "0", "0", + "0", "0", "1" +}; + +static const struct property_entry asus_tf103c_accel_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix), + { } +}; + +static const struct software_node asus_tf103c_accel_node = { + .properties = asus_tf103c_accel_props, +}; + +static const struct property_entry asus_tf103c_touchscreen_props[] = { + PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"), + { } +}; + +static const struct software_node asus_tf103c_touchscreen_node = { + .properties = asus_tf103c_touchscreen_props, +}; + +static const struct property_entry asus_tf103c_battery_props[] = { + PROPERTY_ENTRY_STRING("compatible", "simple-battery"), + PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"), + PROPERTY_ENTRY_U32("precharge-current-microamp", 256000), + PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000), + PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000), + PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000), + PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000), + { } +}; + +static const struct software_node asus_tf103c_battery_node = { + .properties = asus_tf103c_battery_props, +}; + +static const struct property_entry asus_tf103c_bq24190_props[] = { + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), + PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node), + PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000), + PROPERTY_ENTRY_BOOL("omit-battery-class"), + PROPERTY_ENTRY_BOOL("disable-reset"), + { } +}; + +static const struct software_node asus_tf103c_bq24190_node = { + .properties = asus_tf103c_bq24190_props, +}; + +static const struct property_entry asus_tf103c_ug3105_props[] = { + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), + PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node), + PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000), + { } +}; + +static const struct software_node asus_tf103c_ug3105_node = { + .properties = asus_tf103c_ug3105_props, +}; + +static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = { + { + /* bq24297 battery charger */ + .board_info = { + .type = "bq24190", + .addr = 0x6b, + .dev_name = "bq24297", + .swnode = &asus_tf103c_bq24190_node, + .platform_data = &bq24190_pdata, + }, + .adapter_path = "\\_SB_.I2C1", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_PMIC, + .chip = "\\_SB_.I2C7.PMIC", + .domain = DOMAIN_BUS_WAKEUP, + .index = 0, + }, + }, { + /* ug3105 battery monitor */ + .board_info = { + .type = "ug3105", + .addr = 0x70, + .dev_name = "ug3105", + .swnode = &asus_tf103c_ug3105_node, + }, + .adapter_path = "\\_SB_.I2C1", + }, { + /* ak09911 compass */ + .board_info = { + .type = "ak09911", + .addr = 0x0c, + .dev_name = "ak09911", + }, + .adapter_path = "\\_SB_.I2C5", + }, { + /* kxtj21009 accel */ + .board_info = { + .type = "kxtj21009", + .addr = 0x0f, + .dev_name = "kxtj21009", + .swnode = &asus_tf103c_accel_node, + }, + .adapter_path = "\\_SB_.I2C5", + }, { + /* atmel touchscreen */ + .board_info = { + .type = "atmel_mxt_ts", + .addr = 0x4a, + .dev_name = "atmel_mxt_ts", + .swnode = &asus_tf103c_touchscreen_node, + }, + .adapter_path = "\\_SB_.I2C6", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FC:02", + .index = 28, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + }, + }, +}; + +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 = asus_me176c_tf103c_pdevs, + .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), + .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, +}; diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c index ebe3cdeeb33a..27b4fe94250f 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c @@ -24,14 +24,6 @@ #include "shared-psy-info.h" #include "x86-android-tablets.h" -static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = { - .dev_id = "intel-int3496", - .table = { - GPIO_LOOKUP("INT33FC:02", 22, "id", GPIO_ACTIVE_HIGH), - { } - }, -}; - /* Acer Iconia One 7 B1-750 has an Android factory img with everything hardcoded */ static const char * const acer_b1_750_mount_matrix[] = { "-1", "0", "0", @@ -154,338 +146,6 @@ const struct x86_dev_info advantech_mica_071_info __initconst = { .init = advantech_mica_071_init, }; -/* Asus ME176C and TF103C tablets shared data */ -static struct gpio_keys_button asus_me176c_tf103c_lid = { - .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, - }, -}; - -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", - "0", "1", "0", - "0", "0", "1" -}; - -static const struct property_entry asus_me176c_accel_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_me176c_accel_mount_matrix), - { } -}; - -static const struct software_node asus_me176c_accel_node = { - .properties = asus_me176c_accel_props, -}; - -static const struct property_entry asus_me176c_bq24190_props[] = { - PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), - PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), - PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000), - PROPERTY_ENTRY_BOOL("omit-battery-class"), - PROPERTY_ENTRY_BOOL("disable-reset"), - { } -}; - -static const struct software_node asus_me176c_bq24190_node = { - .properties = asus_me176c_bq24190_props, -}; - -static const struct property_entry asus_me176c_ug3105_props[] = { - PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), - PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), - PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 10000), - { } -}; - -static const struct software_node asus_me176c_ug3105_node = { - .properties = asus_me176c_ug3105_props, -}; - -static const struct x86_i2c_client_info asus_me176c_i2c_clients[] __initconst = { - { - /* bq24297 battery charger */ - .board_info = { - .type = "bq24190", - .addr = 0x6b, - .dev_name = "bq24297", - .swnode = &asus_me176c_bq24190_node, - .platform_data = &bq24190_pdata, - }, - .adapter_path = "\\_SB_.I2C1", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_PMIC, - .chip = "\\_SB_.I2C7.PMIC", - .domain = DOMAIN_BUS_WAKEUP, - .index = 0, - }, - }, { - /* ug3105 battery monitor */ - .board_info = { - .type = "ug3105", - .addr = 0x70, - .dev_name = "ug3105", - .swnode = &asus_me176c_ug3105_node, - }, - .adapter_path = "\\_SB_.I2C1", - }, { - /* ak09911 compass */ - .board_info = { - .type = "ak09911", - .addr = 0x0c, - .dev_name = "ak09911", - }, - .adapter_path = "\\_SB_.I2C5", - }, { - /* kxtj21009 accel */ - .board_info = { - .type = "kxtj21009", - .addr = 0x0f, - .dev_name = "kxtj21009", - .swnode = &asus_me176c_accel_node, - }, - .adapter_path = "\\_SB_.I2C5", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_APIC, - .index = 0x44, - .trigger = ACPI_EDGE_SENSITIVE, - .polarity = ACPI_ACTIVE_LOW, - }, - }, { - /* goodix touchscreen */ - .board_info = { - .type = "GDIX1001:00", - .addr = 0x14, - .dev_name = "goodix_ts", - }, - .adapter_path = "\\_SB_.I2C6", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_APIC, - .index = 0x45, - .trigger = ACPI_EDGE_SENSITIVE, - .polarity = ACPI_ACTIVE_LOW, - }, - }, -}; - -static const struct x86_serdev_info asus_me176c_serdevs[] __initconst = { - { - .ctrl_hid = "80860F0A", - .ctrl_uid = "2", - .ctrl_devname = "serial0", - .serdev_hid = "BCM2E3A", - }, -}; - -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 = asus_me176c_tf103c_pdevs, - .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), - .serdev_info = asus_me176c_serdevs, - .serdev_count = ARRAY_SIZE(asus_me176c_serdevs), - .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 */ -static const char * const asus_tf103c_accel_mount_matrix[] = { - "0", "-1", "0", - "-1", "0", "0", - "0", "0", "1" -}; - -static const struct property_entry asus_tf103c_accel_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("mount-matrix", asus_tf103c_accel_mount_matrix), - { } -}; - -static const struct software_node asus_tf103c_accel_node = { - .properties = asus_tf103c_accel_props, -}; - -static const struct property_entry asus_tf103c_touchscreen_props[] = { - PROPERTY_ENTRY_STRING("compatible", "atmel,atmel_mxt_ts"), - { } -}; - -static const struct software_node asus_tf103c_touchscreen_node = { - .properties = asus_tf103c_touchscreen_props, -}; - -static const struct property_entry asus_tf103c_battery_props[] = { - PROPERTY_ENTRY_STRING("compatible", "simple-battery"), - PROPERTY_ENTRY_STRING("device-chemistry", "lithium-ion-polymer"), - PROPERTY_ENTRY_U32("precharge-current-microamp", 256000), - PROPERTY_ENTRY_U32("charge-term-current-microamp", 128000), - PROPERTY_ENTRY_U32("constant-charge-current-max-microamp", 2048000), - PROPERTY_ENTRY_U32("constant-charge-voltage-max-microvolt", 4208000), - PROPERTY_ENTRY_U32("factory-internal-resistance-micro-ohms", 150000), - { } -}; - -static const struct software_node asus_tf103c_battery_node = { - .properties = asus_tf103c_battery_props, -}; - -static const struct property_entry asus_tf103c_bq24190_props[] = { - PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), - PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node), - PROPERTY_ENTRY_U32("ti,system-minimum-microvolt", 3600000), - PROPERTY_ENTRY_BOOL("omit-battery-class"), - PROPERTY_ENTRY_BOOL("disable-reset"), - { } -}; - -static const struct software_node asus_tf103c_bq24190_node = { - .properties = asus_tf103c_bq24190_props, -}; - -static const struct property_entry asus_tf103c_ug3105_props[] = { - PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", bq24190_psy, 1), - PROPERTY_ENTRY_REF("monitored-battery", &asus_tf103c_battery_node), - PROPERTY_ENTRY_U32("upisemi,rsns-microohm", 5000), - { } -}; - -static const struct software_node asus_tf103c_ug3105_node = { - .properties = asus_tf103c_ug3105_props, -}; - -static const struct x86_i2c_client_info asus_tf103c_i2c_clients[] __initconst = { - { - /* bq24297 battery charger */ - .board_info = { - .type = "bq24190", - .addr = 0x6b, - .dev_name = "bq24297", - .swnode = &asus_tf103c_bq24190_node, - .platform_data = &bq24190_pdata, - }, - .adapter_path = "\\_SB_.I2C1", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_PMIC, - .chip = "\\_SB_.I2C7.PMIC", - .domain = DOMAIN_BUS_WAKEUP, - .index = 0, - }, - }, { - /* ug3105 battery monitor */ - .board_info = { - .type = "ug3105", - .addr = 0x70, - .dev_name = "ug3105", - .swnode = &asus_tf103c_ug3105_node, - }, - .adapter_path = "\\_SB_.I2C1", - }, { - /* ak09911 compass */ - .board_info = { - .type = "ak09911", - .addr = 0x0c, - .dev_name = "ak09911", - }, - .adapter_path = "\\_SB_.I2C5", - }, { - /* kxtj21009 accel */ - .board_info = { - .type = "kxtj21009", - .addr = 0x0f, - .dev_name = "kxtj21009", - .swnode = &asus_tf103c_accel_node, - }, - .adapter_path = "\\_SB_.I2C5", - }, { - /* atmel touchscreen */ - .board_info = { - .type = "atmel_mxt_ts", - .addr = 0x4a, - .dev_name = "atmel_mxt_ts", - .swnode = &asus_tf103c_touchscreen_node, - }, - .adapter_path = "\\_SB_.I2C6", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_GPIOINT, - .chip = "INT33FC:02", - .index = 28, - .trigger = ACPI_EDGE_SENSITIVE, - .polarity = ACPI_ACTIVE_LOW, - }, - }, -}; - -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 = asus_me176c_tf103c_pdevs, - .pdev_count = ARRAY_SIZE(asus_me176c_tf103c_pdevs), - .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, -}; - /* * When booted with the BIOS set to Android mode the Chuwi Hi8 (CWI509) DSDT * contains a whole bunch of bogus ACPI I2C devices and is missing entries From patchwork Mon Feb 20 22:12:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147168 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0ECA1C677F1 for ; Mon, 20 Feb 2023 22:13:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232636AbjBTWNO (ORCPT ); Mon, 20 Feb 2023 17:13:14 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33258 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232638AbjBTWNN (ORCPT ); Mon, 20 Feb 2023 17:13:13 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 29AE07ED7 for ; Mon, 20 Feb 2023 14:12:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931148; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=hA0Z1T1RAwCaC4Lczh6N5zLeHtSQOPKKwIssfQFL3KM=; b=WLGEOYXHAE4Znt7Z+mbpHnW3XniJf9MDGPUDEuvrnenrmxOoh0FoSnFshIPRmA7i8pe4xK y7hhejddewNQf/Gpz0T3UNhwsNY7cyQGbXNQ6Wf3XYXUroMn4+Igf8yq6uosY9vxn3T93L XcpCY/ONnAidBuiWg1zreuZ78EZkJY8= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-335-u7VszYotNxSjYqXA_XIOlQ-1; Mon, 20 Feb 2023 17:12:27 -0500 X-MC-Unique: u7VszYotNxSjYqXA_XIOlQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 99B1885A5A3; Mon, 20 Feb 2023 22:12:26 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 00C69140EBF6; Mon, 20 Feb 2023 22:12:25 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 6/9] platform/x86: x86-android-tablets: Move Lenovo tablets to their own file Date: Mon, 20 Feb 2023 23:12:09 +0100 Message-Id: <20230220221212.196009-7-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org Move the info for the Lenovo tablets to their own lenovo.c file. Signed-off-by: Hans de Goede --- .../platform/x86/x86-android-tablets/Makefile | 3 +- .../platform/x86/x86-android-tablets/lenovo.c | 417 ++++++++++++++++++ .../x86-android-tablets-main.c | 405 ----------------- 3 files changed, 419 insertions(+), 406 deletions(-) create mode 100644 drivers/platform/x86/x86-android-tablets/lenovo.c diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index a527f0a94034..d0e4f0353a00 100644 --- a/drivers/platform/x86/x86-android-tablets/Makefile +++ b/drivers/platform/x86/x86-android-tablets/Makefile @@ -5,4 +5,5 @@ obj-$(CONFIG_X86_ANDROID_TABLETS) += x86-android-tablets.o -x86-android-tablets-y := core.o dmi.o shared-psy-info.o asus.o x86-android-tablets-main.o +x86-android-tablets-y := core.o dmi.o shared-psy-info.o \ + asus.o lenovo.o x86-android-tablets-main.o diff --git a/drivers/platform/x86/x86-android-tablets/lenovo.c b/drivers/platform/x86/x86-android-tablets/lenovo.c new file mode 100644 index 000000000000..6bdf25c030ed --- /dev/null +++ b/drivers/platform/x86/x86-android-tablets/lenovo.c @@ -0,0 +1,417 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Board info for Lenovo 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-2023 Hans de Goede + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include +#include + +#include "shared-psy-info.h" +#include "x86-android-tablets.h" + +/* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */ +static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = { + { + /* BQ27542 fuel-gauge */ + .board_info = { + .type = "bq27542", + .addr = 0x55, + .dev_name = "bq27542", + .swnode = &fg_bq25890_supply_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C1", + }, +}; + +const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = { + .i2c_client_info = lenovo_yogabook_x9x_i2c_clients, + .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients), +}; + +/* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */ +static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = { + PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), + PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), + PROPERTY_ENTRY_BOOL("omit-battery-class"), + PROPERTY_ENTRY_BOOL("disable-reset"), + { } +}; + +static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = { + .properties = lenovo_yoga_tab2_830_1050_bq24190_props, +}; + +/* This gets filled by lenovo_yoga_tab2_830_1050_init() */ +static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { }; + +static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = { + .device_control = 0x86, + .initial_brightness = 128, +}; + +static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = { + { + /* bq24292i battery charger */ + .board_info = { + .type = "bq24190", + .addr = 0x6b, + .dev_name = "bq24292i", + .swnode = &lenovo_yoga_tab2_830_1050_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_HIGH, + }, + }, { + /* BQ27541 fuel-gauge */ + .board_info = { + .type = "bq27541", + .addr = 0x55, + .dev_name = "bq27541", + .swnode = &fg_bq24190_supply_node, + }, + .adapter_path = "\\_SB_.I2C1", + }, { + /* Synaptics RMI touchscreen */ + .board_info = { + .type = "rmi4_i2c", + .addr = 0x38, + .dev_name = "rmi4_i2c", + .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata, + }, + .adapter_path = "\\_SB_.I2C6", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_APIC, + .index = 0x45, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_HIGH, + }, + }, { + /* LP8557 Backlight controller */ + .board_info = { + .type = "lp8557", + .addr = 0x2c, + .dev_name = "lp8557", + .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata, + }, + .adapter_path = "\\_SB_.I2C3", + }, +}; + +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), + { } + }, +}; + +#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 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, + NULL +}; + +static int __init lenovo_yoga_tab2_830_1050_init(void); +static void lenovo_yoga_tab2_830_1050_exit(void); + +struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = { + .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients, + /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */ + .pdev_info = int3496_pdevs, + .pdev_count = 1, + .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios, + .bat_swnode = &generic_lipo_hv_4v35_battery_node, + .modules = bq24190_modules, + .init = lenovo_yoga_tab2_830_1050_init, + .exit = lenovo_yoga_tab2_830_1050_exit, +}; + +/* + * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same + * mainboard, but they need some different treatment related to the display: + * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring + * the touchscreen driver to adjust the touch-coords to match the LCD. + * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's + * PWM input is connected to the PMIC's PWM output and everything works fine + * with the defaults programmed into the LP8557 by the BIOS. + * But on the 830 the LP8557's PWM input is connected to a PWM output coming + * from the LCD panel's controller. The Android code has a hack in the i915 + * driver to write the non-standard DSI reg 0x9f with the desired backlight + * level to set the duty-cycle of the LCD's PWM output. + * + * To avoid having to have a similar hack in the mainline kernel the LP8557 + * entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the + * LP8557 to directly set the level, ignoring the PWM input. This means that + * the LP8557 i2c_client should only be instantiated on the 830. + */ +static int __init lenovo_yoga_tab2_830_1050_init_display(void) +{ + struct gpio_desc *gpiod; + int ret; + + /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */ + ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod); + if (ret) + return ret; + + ret = gpiod_get_value_cansleep(gpiod); + if (ret) { + pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n"); + lenovo_yoga_tab2_830_1050_info.i2c_client_count = + ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1; + } else { + pr_info("detected Lenovo Yoga Tablet 2 830F/L\n"); + lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true; + lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true; + lenovo_yoga_tab2_830_1050_info.i2c_client_count = + ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients); + } + + return 0; +} + +/* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */ +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 pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl; +static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler; + +static int __init lenovo_yoga_tab2_830_1050_init_codec(void) +{ + struct device *codec_dev; + struct pinctrl *pinctrl; + int ret; + + codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, + LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); + if (!codec_dev) { + pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); + return -ENODEV; + } + + ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1); + if (ret) + goto err_put_device; + + pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk"); + if (IS_ERR(pinctrl)) { + ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n"); + goto err_unregister_mappings; + } + + /* We're done with the codec_dev now */ + put_device(codec_dev); + + lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl; + return 0; + +err_unregister_mappings: + pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); +err_put_device: + put_device(codec_dev); + return ret; +} + +/* + * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off + * gets used as pm_power_off handler. This causes "poweroff" on these tablets + * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice* + * followed by a normal 3 second press to recover. Avoid this by doing an EFI + * poweroff instead. + */ +static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data) +{ + efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); + + return NOTIFY_DONE; +} + +static int __init lenovo_yoga_tab2_830_1050_init(void) +{ + int ret; + + ret = lenovo_yoga_tab2_830_1050_init_display(); + if (ret) + return ret; + + ret = lenovo_yoga_tab2_830_1050_init_codec(); + if (ret) + return ret; + + /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */ + lenovo_yoga_tab2_830_1050_sys_off_handler = + register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1, + lenovo_yoga_tab2_830_1050_power_off, NULL); + if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler)) + return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler); + + return 0; +} + +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); + } +} + +/* Lenovo Yoga Tab 3 Pro YT3-X90F */ + +/* + * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers, + * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c. + */ +static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" }; +static const char * const bq25890_1_psy[] = { "bq25890-charger-1" }; + +static const struct property_entry fg_bq25890_1_supply_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy), + { } +}; + +static const struct software_node fg_bq25890_1_supply_node = { + .properties = fg_bq25890_1_supply_props, +}; + +/* bq25892 charger settings for the flat lipo battery behind the screen */ +static const struct property_entry lenovo_yt3_bq25892_0_props[] = { + PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers), + PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"), + PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40), + PROPERTY_ENTRY_BOOL("linux,skip-reset"), + /* Values taken from Android Factory Image */ + PROPERTY_ENTRY_U32("ti,charge-current", 2048000), + PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000), + PROPERTY_ENTRY_U32("ti,termination-current", 128000), + PROPERTY_ENTRY_U32("ti,precharge-current", 128000), + PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000), + PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000), + PROPERTY_ENTRY_U32("ti,boost-max-current", 500000), + PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"), + { } +}; + +static const struct software_node lenovo_yt3_bq25892_0_node = { + .properties = lenovo_yt3_bq25892_0_props, +}; + +static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { + { + /* bq27500 fuel-gauge for the flat lipo battery behind the screen */ + .board_info = { + .type = "bq27500", + .addr = 0x55, + .dev_name = "bq27500_0", + .swnode = &fg_bq25890_supply_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C1", + }, { + /* bq25892 charger for the flat lipo battery behind the screen */ + .board_info = { + .type = "bq25892", + .addr = 0x6b, + .dev_name = "bq25892_0", + .swnode = &lenovo_yt3_bq25892_0_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C1", + .irq_data = { + .type = X86_ACPI_IRQ_TYPE_GPIOINT, + .chip = "INT33FF:01", + .index = 5, + .trigger = ACPI_EDGE_SENSITIVE, + .polarity = ACPI_ACTIVE_LOW, + }, + }, { + /* bq27500 fuel-gauge for the round li-ion cells in the hinge */ + .board_info = { + .type = "bq27500", + .addr = 0x55, + .dev_name = "bq27500_1", + .swnode = &fg_bq25890_1_supply_node, + }, + .adapter_path = "\\_SB_.PCI0.I2C2", + } +}; + +static int __init lenovo_yt3_init(void) +{ + struct gpio_desc *gpiod; + int ret; + + /* + * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins + * connected to GPIOs, rather then having them hardwired to the correct + * values as is normally done. + * + * The bq25890_charger driver controls these through I2C, but this only + * works if not overridden by the pins. Set these pins here: + * 1. Set /CE to 0 to allow charging. + * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of + * the main "bq25892_1" charger is used when necessary. + */ + + /* /CE pin */ + ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod); + if (ret < 0) + return ret; + + /* + * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw" + * gpio_desc, that is there is no way to pass lookup-flags like + * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since + * the /CE pin is active-low, but not marked as such in the gpio_desc. + */ + gpiod_set_value(gpiod, 0); + + /* OTG pin */ + ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod); + if (ret < 0) + return ret; + + gpiod_set_value(gpiod, 0); + + return 0; +} + +const struct x86_dev_info lenovo_yt3_info __initconst = { + .i2c_client_info = lenovo_yt3_i2c_clients, + .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), + .init = lenovo_yt3_init, +}; diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c index 27b4fe94250f..cb8d84983503 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c @@ -8,18 +8,9 @@ * Copyright (C) 2021-2022 Hans de Goede */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - #include -#include #include #include -#include -#include -#include -#include -#include -#include #include "shared-psy-info.h" #include "x86-android-tablets.h" @@ -264,402 +255,6 @@ const struct x86_dev_info czc_p10t __initconst = { .init = czc_p10t_init, }; -/* Lenovo Yoga Book X90F / X91F / X91L need manual instantiation of the fg client */ -static const struct x86_i2c_client_info lenovo_yogabook_x9x_i2c_clients[] __initconst = { - { - /* BQ27542 fuel-gauge */ - .board_info = { - .type = "bq27542", - .addr = 0x55, - .dev_name = "bq27542", - .swnode = &fg_bq25890_supply_node, - }, - .adapter_path = "\\_SB_.PCI0.I2C1", - }, -}; - -const struct x86_dev_info lenovo_yogabook_x9x_info __initconst = { - .i2c_client_info = lenovo_yogabook_x9x_i2c_clients, - .i2c_client_count = ARRAY_SIZE(lenovo_yogabook_x9x_i2c_clients), -}; - -/* Lenovo Yoga Tablet 2 1050F/L's Android factory img has everything hardcoded */ -static const struct property_entry lenovo_yoga_tab2_830_1050_bq24190_props[] = { - PROPERTY_ENTRY_STRING_ARRAY_LEN("supplied-from", tusb1211_chg_det_psy, 1), - PROPERTY_ENTRY_REF("monitored-battery", &generic_lipo_hv_4v35_battery_node), - PROPERTY_ENTRY_BOOL("omit-battery-class"), - PROPERTY_ENTRY_BOOL("disable-reset"), - { } -}; - -static const struct software_node lenovo_yoga_tab2_830_1050_bq24190_node = { - .properties = lenovo_yoga_tab2_830_1050_bq24190_props, -}; - -/* This gets filled by lenovo_yoga_tab2_830_1050_init() */ -static struct rmi_device_platform_data lenovo_yoga_tab2_830_1050_rmi_pdata = { }; - -static struct lp855x_platform_data lenovo_yoga_tab2_830_1050_lp8557_pdata = { - .device_control = 0x86, - .initial_brightness = 128, -}; - -static const struct x86_i2c_client_info lenovo_yoga_tab2_830_1050_i2c_clients[] __initconst = { - { - /* bq24292i battery charger */ - .board_info = { - .type = "bq24190", - .addr = 0x6b, - .dev_name = "bq24292i", - .swnode = &lenovo_yoga_tab2_830_1050_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_HIGH, - }, - }, { - /* BQ27541 fuel-gauge */ - .board_info = { - .type = "bq27541", - .addr = 0x55, - .dev_name = "bq27541", - .swnode = &fg_bq24190_supply_node, - }, - .adapter_path = "\\_SB_.I2C1", - }, { - /* Synaptics RMI touchscreen */ - .board_info = { - .type = "rmi4_i2c", - .addr = 0x38, - .dev_name = "rmi4_i2c", - .platform_data = &lenovo_yoga_tab2_830_1050_rmi_pdata, - }, - .adapter_path = "\\_SB_.I2C6", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_APIC, - .index = 0x45, - .trigger = ACPI_EDGE_SENSITIVE, - .polarity = ACPI_ACTIVE_HIGH, - }, - }, { - /* LP8557 Backlight controller */ - .board_info = { - .type = "lp8557", - .addr = 0x2c, - .dev_name = "lp8557", - .platform_data = &lenovo_yoga_tab2_830_1050_lp8557_pdata, - }, - .adapter_path = "\\_SB_.I2C3", - }, -}; - -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), - { } - }, -}; - -#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 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, - NULL -}; - -static int __init lenovo_yoga_tab2_830_1050_init(void); -static void lenovo_yoga_tab2_830_1050_exit(void); - -struct x86_dev_info lenovo_yoga_tab2_830_1050_info __initdata = { - .i2c_client_info = lenovo_yoga_tab2_830_1050_i2c_clients, - /* i2c_client_count gets set by lenovo_yoga_tab2_830_1050_init() */ - .pdev_info = int3496_pdevs, - .pdev_count = 1, - .gpiod_lookup_tables = lenovo_yoga_tab2_830_1050_gpios, - .bat_swnode = &generic_lipo_hv_4v35_battery_node, - .modules = bq24190_modules, - .invalid_aei_gpiochip = "INT33FC:02", - .init = lenovo_yoga_tab2_830_1050_init, - .exit = lenovo_yoga_tab2_830_1050_exit, -}; - -/* - * The Lenovo Yoga Tablet 2 830 and 1050 (8" vs 10") versions use the same - * mainboard, but they need some different treatment related to the display: - * 1. The 830 uses a portrait LCD panel with a landscape touchscreen, requiring - * the touchscreen driver to adjust the touch-coords to match the LCD. - * 2. Both use an TI LP8557 LED backlight controller. On the 1050 the LP8557's - * PWM input is connected to the PMIC's PWM output and everything works fine - * with the defaults programmed into the LP8557 by the BIOS. - * But on the 830 the LP8557's PWM input is connected to a PWM output coming - * from the LCD panel's controller. The Android code has a hack in the i915 - * driver to write the non-standard DSI reg 0x9f with the desired backlight - * level to set the duty-cycle of the LCD's PWM output. - * - * To avoid having to have a similar hack in the mainline kernel the LP8557 - * entry in lenovo_yoga_tab2_830_1050_i2c_clients instead just programs the - * LP8557 to directly set the level, ignoring the PWM input. This means that - * the LP8557 i2c_client should only be instantiated on the 830. - */ -static int __init lenovo_yoga_tab2_830_1050_init_display(void) -{ - struct gpio_desc *gpiod; - int ret; - - /* Use PMIC GPIO 10 bootstrap pin to differentiate 830 vs 1050 */ - ret = x86_android_tablet_get_gpiod("gpio_crystalcove", 10, &gpiod); - if (ret) - return ret; - - ret = gpiod_get_value_cansleep(gpiod); - if (ret) { - pr_info("detected Lenovo Yoga Tablet 2 1050F/L\n"); - lenovo_yoga_tab2_830_1050_info.i2c_client_count = - ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients) - 1; - } else { - pr_info("detected Lenovo Yoga Tablet 2 830F/L\n"); - lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.swap_axes = true; - lenovo_yoga_tab2_830_1050_rmi_pdata.sensor_pdata.axis_align.flip_y = true; - lenovo_yoga_tab2_830_1050_info.i2c_client_count = - ARRAY_SIZE(lenovo_yoga_tab2_830_1050_i2c_clients); - } - - return 0; -} - -/* SUS (INT33FC:02) pin 6 needs to be configured as pmu_clk for the audio codec */ -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 pinctrl *lenovo_yoga_tab2_830_1050_codec_pinctrl; -static struct sys_off_handler *lenovo_yoga_tab2_830_1050_sys_off_handler; - -static int __init lenovo_yoga_tab2_830_1050_init_codec(void) -{ - struct device *codec_dev; - struct pinctrl *pinctrl; - int ret; - - codec_dev = bus_find_device_by_name(&spi_bus_type, NULL, - LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); - if (!codec_dev) { - pr_err("error cannot find %s device\n", LENOVO_YOGA_TAB2_830_1050_CODEC_NAME); - return -ENODEV; - } - - ret = pinctrl_register_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map, 1); - if (ret) - goto err_put_device; - - pinctrl = pinctrl_get_select(codec_dev, "codec_32khz_clk"); - if (IS_ERR(pinctrl)) { - ret = dev_err_probe(codec_dev, PTR_ERR(pinctrl), "selecting codec_32khz_clk\n"); - goto err_unregister_mappings; - } - - /* We're done with the codec_dev now */ - put_device(codec_dev); - - lenovo_yoga_tab2_830_1050_codec_pinctrl = pinctrl; - return 0; - -err_unregister_mappings: - pinctrl_unregister_mappings(&lenovo_yoga_tab2_830_1050_codec_pinctrl_map); -err_put_device: - put_device(codec_dev); - return ret; -} - -/* - * These tablet's DSDT does not set acpi_gbl_reduced_hardware, so acpi_power_off - * gets used as pm_power_off handler. This causes "poweroff" on these tablets - * to hang hard. Requiring pressing the powerbutton for 30 seconds *twice* - * followed by a normal 3 second press to recover. Avoid this by doing an EFI - * poweroff instead. - */ -static int lenovo_yoga_tab2_830_1050_power_off(struct sys_off_data *data) -{ - efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); - - return NOTIFY_DONE; -} - -static int __init lenovo_yoga_tab2_830_1050_init(void) -{ - int ret; - - ret = lenovo_yoga_tab2_830_1050_init_display(); - if (ret) - return ret; - - ret = lenovo_yoga_tab2_830_1050_init_codec(); - if (ret) - return ret; - - /* SYS_OFF_PRIO_FIRMWARE + 1 so that it runs before acpi_power_off */ - lenovo_yoga_tab2_830_1050_sys_off_handler = - register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, SYS_OFF_PRIO_FIRMWARE + 1, - lenovo_yoga_tab2_830_1050_power_off, NULL); - if (IS_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler)) - return PTR_ERR(lenovo_yoga_tab2_830_1050_sys_off_handler); - - return 0; -} - -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); - } -} - -/* Lenovo Yoga Tab 3 Pro YT3-X90F */ - -/* - * There are 2 batteries, with 2 bq27500 fuel-gauges and 2 bq25892 chargers, - * "bq25890-charger-1" is instantiated from: drivers/i2c/busses/i2c-cht-wc.c. - */ -static const char * const lenovo_yt3_bq25892_0_suppliers[] = { "cht_wcove_pwrsrc" }; -static const char * const bq25890_1_psy[] = { "bq25890-charger-1" }; - -static const struct property_entry fg_bq25890_1_supply_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", bq25890_1_psy), - { } -}; - -static const struct software_node fg_bq25890_1_supply_node = { - .properties = fg_bq25890_1_supply_props, -}; - -/* bq25892 charger settings for the flat lipo battery behind the screen */ -static const struct property_entry lenovo_yt3_bq25892_0_props[] = { - PROPERTY_ENTRY_STRING_ARRAY("supplied-from", lenovo_yt3_bq25892_0_suppliers), - PROPERTY_ENTRY_STRING("linux,power-supply-name", "bq25892-second-chrg"), - PROPERTY_ENTRY_U32("linux,iinlim-percentage", 40), - PROPERTY_ENTRY_BOOL("linux,skip-reset"), - /* Values taken from Android Factory Image */ - PROPERTY_ENTRY_U32("ti,charge-current", 2048000), - PROPERTY_ENTRY_U32("ti,battery-regulation-voltage", 4352000), - PROPERTY_ENTRY_U32("ti,termination-current", 128000), - PROPERTY_ENTRY_U32("ti,precharge-current", 128000), - PROPERTY_ENTRY_U32("ti,minimum-sys-voltage", 3700000), - PROPERTY_ENTRY_U32("ti,boost-voltage", 4998000), - PROPERTY_ENTRY_U32("ti,boost-max-current", 500000), - PROPERTY_ENTRY_BOOL("ti,use-ilim-pin"), - { } -}; - -static const struct software_node lenovo_yt3_bq25892_0_node = { - .properties = lenovo_yt3_bq25892_0_props, -}; - -static const struct x86_i2c_client_info lenovo_yt3_i2c_clients[] __initconst = { - { - /* bq27500 fuel-gauge for the flat lipo battery behind the screen */ - .board_info = { - .type = "bq27500", - .addr = 0x55, - .dev_name = "bq27500_0", - .swnode = &fg_bq25890_supply_node, - }, - .adapter_path = "\\_SB_.PCI0.I2C1", - }, { - /* bq25892 charger for the flat lipo battery behind the screen */ - .board_info = { - .type = "bq25892", - .addr = 0x6b, - .dev_name = "bq25892_0", - .swnode = &lenovo_yt3_bq25892_0_node, - }, - .adapter_path = "\\_SB_.PCI0.I2C1", - .irq_data = { - .type = X86_ACPI_IRQ_TYPE_GPIOINT, - .chip = "INT33FF:01", - .index = 5, - .trigger = ACPI_EDGE_SENSITIVE, - .polarity = ACPI_ACTIVE_LOW, - }, - }, { - /* bq27500 fuel-gauge for the round li-ion cells in the hinge */ - .board_info = { - .type = "bq27500", - .addr = 0x55, - .dev_name = "bq27500_1", - .swnode = &fg_bq25890_1_supply_node, - }, - .adapter_path = "\\_SB_.PCI0.I2C2", - } -}; - -static int __init lenovo_yt3_init(void) -{ - struct gpio_desc *gpiod; - int ret; - - /* - * The "bq25892_0" charger IC has its /CE (Charge-Enable) and OTG pins - * connected to GPIOs, rather then having them hardwired to the correct - * values as is normally done. - * - * The bq25890_charger driver controls these through I2C, but this only - * works if not overridden by the pins. Set these pins here: - * 1. Set /CE to 0 to allow charging. - * 2. Set OTG to 0 disable V5 boost output since the 5V boost output of - * the main "bq25892_1" charger is used when necessary. - */ - - /* /CE pin */ - ret = x86_android_tablet_get_gpiod("INT33FF:02", 22, &gpiod); - if (ret < 0) - return ret; - - /* - * The gpio_desc returned by x86_android_tablet_get_gpiod() is a "raw" - * gpio_desc, that is there is no way to pass lookup-flags like - * GPIO_ACTIVE_LOW. Set the GPIO to 0 here to enable charging since - * the /CE pin is active-low, but not marked as such in the gpio_desc. - */ - gpiod_set_value(gpiod, 0); - - /* OTG pin */ - ret = x86_android_tablet_get_gpiod("INT33FF:03", 19, &gpiod); - if (ret < 0) - return ret; - - gpiod_set_value(gpiod, 0); - - return 0; -} - -const struct x86_dev_info lenovo_yt3_info __initconst = { - .i2c_client_info = lenovo_yt3_i2c_clients, - .i2c_client_count = ARRAY_SIZE(lenovo_yt3_i2c_clients), - .init = lenovo_yt3_init, -}; - /* Medion Lifetab S10346 tablets have an Android factory img with everything hardcoded */ static const char * const medion_lifetab_s10346_accel_mount_matrix[] = { "0", "1", "0", From patchwork Mon Feb 20 22:12:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147167 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03932C64ED9 for ; Mon, 20 Feb 2023 22:13:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232638AbjBTWNQ (ORCPT ); Mon, 20 Feb 2023 17:13:16 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232635AbjBTWNO (ORCPT ); Mon, 20 Feb 2023 17:13:14 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15F97FF23 for ; Mon, 20 Feb 2023 14:12:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931151; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LB1IfrYiKWTFv3wKasILM3M/u7uPBEpqy5sdAX+kceg=; b=UaPUBHLSPaBEVhCSxTxhWn5RCtg1Q9ifMpeFko2f6+1jdg1N33ZSWh826gk+IthmG9p/aH uSAJ+5SMppPdEKA0Lhcq/umbEnITMw4boBPxEmxDc0QvidTbdqVTjAloWLe2delaw4Vp2Y fhW8WObuc9jab9sXTYD2E50C6deEujk= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-395-LOsK0yvcNWqvsntdO-a35w-1; Mon, 20 Feb 2023 17:12:27 -0500 X-MC-Unique: LOsK0yvcNWqvsntdO-a35w-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6E4E73806625; Mon, 20 Feb 2023 22:12:27 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id C9A5C140EBF6; Mon, 20 Feb 2023 22:12:26 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 7/9] platform/x86: x86-android-tablets: Move remaining tablets to other.c Date: Mon, 20 Feb 2023 23:12:10 +0100 Message-Id: <20230220221212.196009-8-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org All that remains now in x86-android-tablets-main.c is info for other (non Asus / Lenovo) tablets. Rename it to other.c to reflect this. Signed-off-by: Hans de Goede --- drivers/platform/x86/x86-android-tablets/Makefile | 2 +- .../x86-android-tablets/{x86-android-tablets-main.c => other.c} | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename drivers/platform/x86/x86-android-tablets/{x86-android-tablets-main.c => other.c} (99%) diff --git a/drivers/platform/x86/x86-android-tablets/Makefile b/drivers/platform/x86/x86-android-tablets/Makefile index d0e4f0353a00..12f5eb2c9b84 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) += x86-android-tablets.o x86-android-tablets-y := core.o dmi.o shared-psy-info.o \ - asus.o lenovo.o x86-android-tablets-main.o + asus.o lenovo.o other.o diff --git a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c b/drivers/platform/x86/x86-android-tablets/other.c similarity index 99% rename from drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c rename to drivers/platform/x86/x86-android-tablets/other.c index cb8d84983503..a0f8c4bb3237 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets-main.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -5,7 +5,7 @@ * devices typically have a bunch of things hardcoded, rather than specified * in their DSDT. * - * Copyright (C) 2021-2022 Hans de Goede + * Copyright (C) 2021-2023 Hans de Goede */ #include From patchwork Mon Feb 20 22:12:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147169 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9DA51C61DA3 for ; Mon, 20 Feb 2023 22:13:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232648AbjBTWNS (ORCPT ); Mon, 20 Feb 2023 17:13:18 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33296 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232640AbjBTWNR (ORCPT ); Mon, 20 Feb 2023 17:13:17 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B4D831E28D for ; Mon, 20 Feb 2023 14:12:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931150; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=AlibHVdyX399Ef3X6uxd5yO7sNGLKio5S4P5CpjNius=; b=gbi18py+W8o6HGjfwtlalYItNlw12hadjQdxqVu4RQAJLuXc3yPGy9AoSn7gnafsd6fKMp 7uz4fIlv3/lsmFLd9RdImbZH2OuWtxUwYzPAD4ybV6s8SmQFhZ62q7r+tMyXB+SbCuda/X 4i73bWSLRDDC4Q6EnOH8Ks1UrxG7EQE= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-399-A6mykgb2Mn-4khnPEarkzQ-1; Mon, 20 Feb 2023 17:12:28 -0500 X-MC-Unique: A6mykgb2Mn-4khnPEarkzQ-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 461B029AA2CE; Mon, 20 Feb 2023 22:12:28 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9FAD4140EBF6; Mon, 20 Feb 2023 22:12:27 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 8/9] platform/x86: x86-android-tablets: Add gpio_keys support to x86_android_tablet_init() Date: Mon, 20 Feb 2023 23:12:11 +0100 Message-Id: <20230220221212.196009-9-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org 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: Hans de Goede --- .../platform/x86/x86-android-tablets/asus.c | 53 ++++--------------- .../platform/x86/x86-android-tablets/core.c | 30 ++++++++++- .../platform/x86/x86-android-tablets/other.c | 37 ++----------- .../x86-android-tablets/x86-android-tablets.h | 4 ++ 4 files changed, 48 insertions(+), 76 deletions(-) diff --git a/drivers/platform/x86/x86-android-tablets/asus.c b/drivers/platform/x86/x86-android-tablets/asus.c index c7d3ca73ebd3..78e5d10eb803 100644 --- a/drivers/platform/x86/x86-android-tablets/asus.c +++ b/drivers/platform/x86/x86-android-tablets/asus.c @@ -8,7 +8,6 @@ * Copyright (C) 2021-2023 Hans de Goede */ -#include #include #include "shared-psy-info.h" @@ -25,7 +24,7 @@ static struct gpiod_lookup_table int3496_gpo2_pin22_gpios = { static struct gpio_keys_button asus_me176c_tf103c_lid = { .code = SW_LID, - /* .gpio gets filled in by asus_me176c_tf103c_init() */ + /* .gpio gets filled in by x86_android_tablet_init() */ .active_low = true, .desc = "lid_sw", .type = EV_SW, @@ -33,40 +32,6 @@ static struct gpio_keys_button asus_me176c_tf103c_lid = { .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, - }, -}; - -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", @@ -200,15 +165,17 @@ 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), .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, + .gpio_keys_button = &asus_me176c_tf103c_lid, + .gpio_keys_gpiochip = "INT33FC:02", + .gpio_keys_pin = 12, }; /* Asus TF103C tablets have an Android factory img with everything hardcoded */ @@ -345,11 +312,13 @@ 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, .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, + .gpio_keys_button = &asus_me176c_tf103c_lid, + .gpio_keys_gpiochip = "INT33FC:02", + .gpio_keys_pin = 12, }; diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c index 5d04e63e1ebc..32819e7d4763 100644 --- a/drivers/platform/x86/x86-android-tablets/core.c +++ b/drivers/platform/x86/x86-android-tablets/core.c @@ -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_keys_button) { + struct gpio_keys_platform_data pdata = { + .buttons = dev_info->gpio_keys_button, + .nbuttons = 1, + }; + struct gpio_desc *gpiod; + + /* Get GPIO for the gpio-button */ + ret = x86_android_tablet_get_gpiod(dev_info->gpio_keys_gpiochip, + dev_info->gpio_keys_pin, &gpiod); + if (ret < 0) { + x86_android_tablet_cleanup(); + return ret; + } + + dev_info->gpio_keys_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; } diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index a0f8c4bb3237..e4b3ad2ce7c1 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -9,7 +9,6 @@ */ #include -#include #include #include "shared-psy-info.h" @@ -95,7 +94,7 @@ const struct x86_dev_info acer_b1_750_info __initconst = { */ static struct gpio_keys_button advantech_mica_071_button = { .code = KEY_PROG1, - /* .gpio gets filled in by advantech_mica_071_init() */ + /* .gpio gets filled in by x86_android_tablet_init() */ .active_low = true, .desc = "prog1_key", .type = EV_KEY, @@ -103,38 +102,10 @@ static struct gpio_keys_button advantech_mica_071_button = { .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), - }, -}; - -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_keys_button = &advantech_mica_071_button, + .gpio_keys_gpiochip = "INT33FC:00", + .gpio_keys_pin = 2, }; /* 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 2023b53e0df2..f93d0fc61b7d 100644 --- a/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h +++ b/drivers/platform/x86/x86-android-tablets/x86-android-tablets.h @@ -10,6 +10,7 @@ #ifndef __X86_ANDROID_TABLETS_H #define __X86_ANDROID_TABLETS_H +#include #include #include #include @@ -67,6 +68,9 @@ struct x86_dev_info { int i2c_client_count; int pdev_count; int serdev_count; + int gpio_keys_pin; + const char *gpio_keys_gpiochip; + struct gpio_keys_button *gpio_keys_button; int (*init)(void); void (*exit)(void); }; From patchwork Mon Feb 20 22:12:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hans de Goede X-Patchwork-Id: 13147170 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 052CEC6379F for ; Mon, 20 Feb 2023 22:13:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232640AbjBTWNW (ORCPT ); Mon, 20 Feb 2023 17:13:22 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33310 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232635AbjBTWNV (ORCPT ); Mon, 20 Feb 2023 17:13:21 -0500 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4493ABBA1 for ; Mon, 20 Feb 2023 14:12:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1676931154; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1wmFjPeBR++Gy2BieIFCcgY1pSkWiBpG6/usJz+hPp8=; b=VKXkEjn0iiWaMnifs+Gh28GjWm8rKe4tNECNlUUG7OuSci6Mb/f40IhhX0DqC3hY+1Kw3d HtsSWGyeZNXWPq4jRMLrDnIEi9LoIYc/AGb5DYhe0uPRibgSa/18m43LZywm9aDdRaKBAq Fu8ZUiyyfeRKDfu2K2VRFWeQwOJCsDA= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-36-UguxO3tiMP-RLXb8-tNuVw-1; Mon, 20 Feb 2023 17:12:29 -0500 X-MC-Unique: UguxO3tiMP-RLXb8-tNuVw-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.rdu2.redhat.com [10.11.54.7]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 19DE0185A794; Mon, 20 Feb 2023 22:12:29 +0000 (UTC) Received: from localhost.localdomain (unknown [10.39.192.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 75AF4140EBF6; Mon, 20 Feb 2023 22:12:28 +0000 (UTC) From: Hans de Goede To: Mark Gross , Andy Shevchenko Cc: Hans de Goede , platform-driver-x86@vger.kernel.org Subject: [PATCH 9/9] platform/x86: x86-android-tablets: Add support for the Dolby button on Peaq C1010 Date: Mon, 20 Feb 2023 23:12:12 +0100 Message-Id: <20230220221212.196009-10-hdegoede@redhat.com> In-Reply-To: <20230220221212.196009-1-hdegoede@redhat.com> References: <20230220221212.196009-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.7 Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org The Peaq C1010 tablet has a special "Dolby" button. This button has a WMI interface, but this is broken in several ways: 1. It only supports polling 2. The value read on polling goes from 0 -> 1 for one poll on both edges of the button, with no way to tell which edge causes the poll to return 1. 3. It uses a non unique GUID (it uses the Microsoft docs WMI example GUID). There currently is a WMI driver for this, but it uses several kludges to work around these issues and is not entirely reliable due to 2. Replace the unreliable WMI driver by using the x86-android-tablets code to instantiate a gpio_keys device for this. Signed-off-by: Hans de Goede --- MAINTAINERS | 6 - drivers/platform/x86/Kconfig | 7 - drivers/platform/x86/Makefile | 1 - drivers/platform/x86/peaq-wmi.c | 128 ------------------ .../platform/x86/x86-android-tablets/dmi.c | 9 ++ .../platform/x86/x86-android-tablets/other.c | 27 ++++ 6 files changed, 36 insertions(+), 142 deletions(-) delete mode 100644 drivers/platform/x86/peaq-wmi.c diff --git a/MAINTAINERS b/MAINTAINERS index 87cc1e6b37c0..3c86814fc3ab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16377,12 +16377,6 @@ S: Maintained F: crypto/pcrypt.c F: include/crypto/pcrypt.h -PEAQ WMI HOTKEYS DRIVER -M: Hans de Goede -L: platform-driver-x86@vger.kernel.org -S: Maintained -F: drivers/platform/x86/peaq-wmi.c - PECI HARDWARE MONITORING DRIVERS M: Iwona Winiarska L: linux-hwmon@vger.kernel.org diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 8b4e03fe5bff..e7166812875a 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig @@ -84,13 +84,6 @@ config MXM_WMI MXM is a standard for laptop graphics cards, the WMI interface is required for switchable nvidia graphics machines -config PEAQ_WMI - tristate "PEAQ 2-in-1 WMI hotkey driver" - depends on ACPI_WMI - depends on INPUT - help - Say Y here if you want to support WMI-based hotkeys on PEAQ 2-in-1s. - config NVIDIA_WMI_EC_BACKLIGHT tristate "EC Backlight Driver for Hybrid Graphics Notebook Systems" depends on ACPI_VIDEO diff --git a/drivers/platform/x86/Makefile b/drivers/platform/x86/Makefile index 0d9cc9af6ba7..12407f36d2be 100644 --- a/drivers/platform/x86/Makefile +++ b/drivers/platform/x86/Makefile @@ -12,7 +12,6 @@ obj-$(CONFIG_WMI_BMOF) += wmi-bmof.o obj-$(CONFIG_HUAWEI_WMI) += huawei-wmi.o obj-$(CONFIG_MXM_WMI) += mxm-wmi.o obj-$(CONFIG_NVIDIA_WMI_EC_BACKLIGHT) += nvidia-wmi-ec-backlight.o -obj-$(CONFIG_PEAQ_WMI) += peaq-wmi.o obj-$(CONFIG_XIAOMI_WMI) += xiaomi-wmi.o obj-$(CONFIG_GIGABYTE_WMI) += gigabyte-wmi.o obj-$(CONFIG_YOGABOOK_WMI) += lenovo-yogabook-wmi.o diff --git a/drivers/platform/x86/peaq-wmi.c b/drivers/platform/x86/peaq-wmi.c deleted file mode 100644 index cf9c44c20a82..000000000000 --- a/drivers/platform/x86/peaq-wmi.c +++ /dev/null @@ -1,128 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * PEAQ 2-in-1 WMI hotkey driver - * Copyright (C) 2017 Hans de Goede - */ - -#include -#include -#include -#include -#include - -#define PEAQ_DOLBY_BUTTON_GUID "ABBC0F6F-8EA1-11D1-00A0-C90629100000" -#define PEAQ_DOLBY_BUTTON_METHOD_ID 5 -#define PEAQ_POLL_INTERVAL_MS 250 -#define PEAQ_POLL_IGNORE_MS 500 -#define PEAQ_POLL_MAX_MS 1000 - -MODULE_ALIAS("wmi:"PEAQ_DOLBY_BUTTON_GUID); - -static struct input_dev *peaq_poll_dev; - -/* - * The Dolby button (yes really a Dolby button) causes an ACPI variable to get - * set on both press and release. The WMI method checks and clears that flag. - * So for a press + release we will get back One from the WMI method either once - * (if polling after the release) or twice (polling between press and release). - * We ignore events for 0.5s after the first event to avoid reporting 2 presses. - */ -static void peaq_wmi_poll(struct input_dev *input_dev) -{ - static unsigned long last_event_time; - static bool had_events; - union acpi_object obj; - acpi_status status; - u32 dummy = 0; - - struct acpi_buffer input = { sizeof(dummy), &dummy }; - struct acpi_buffer output = { sizeof(obj), &obj }; - - status = wmi_evaluate_method(PEAQ_DOLBY_BUTTON_GUID, 0, - PEAQ_DOLBY_BUTTON_METHOD_ID, - &input, &output); - if (ACPI_FAILURE(status)) - return; - - if (obj.type != ACPI_TYPE_INTEGER) { - dev_err(&input_dev->dev, - "Error WMBC did not return an integer\n"); - return; - } - - if (!obj.integer.value) - return; - - if (had_events && time_before(jiffies, last_event_time + - msecs_to_jiffies(PEAQ_POLL_IGNORE_MS))) - return; - - input_event(input_dev, EV_KEY, KEY_SOUND, 1); - input_sync(input_dev); - input_event(input_dev, EV_KEY, KEY_SOUND, 0); - input_sync(input_dev); - - last_event_time = jiffies; - had_events = true; -} - -/* Some other devices (Shuttle XS35) use the same WMI GUID for other purposes */ -static const struct dmi_system_id peaq_dmi_table[] __initconst = { - { - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"), - DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"), - }, - }, - {} -}; - -static int __init peaq_wmi_init(void) -{ - int err; - - /* WMI GUID is not unique, also check for a DMI match */ - if (!dmi_check_system(peaq_dmi_table)) - return -ENODEV; - - if (!wmi_has_guid(PEAQ_DOLBY_BUTTON_GUID)) - return -ENODEV; - - peaq_poll_dev = input_allocate_device(); - if (!peaq_poll_dev) - return -ENOMEM; - - peaq_poll_dev->name = "PEAQ WMI hotkeys"; - peaq_poll_dev->phys = "wmi/input0"; - peaq_poll_dev->id.bustype = BUS_HOST; - input_set_capability(peaq_poll_dev, EV_KEY, KEY_SOUND); - - err = input_setup_polling(peaq_poll_dev, peaq_wmi_poll); - if (err) - goto err_out; - - input_set_poll_interval(peaq_poll_dev, PEAQ_POLL_INTERVAL_MS); - input_set_max_poll_interval(peaq_poll_dev, PEAQ_POLL_MAX_MS); - - err = input_register_device(peaq_poll_dev); - if (err) - goto err_out; - - return 0; - -err_out: - input_free_device(peaq_poll_dev); - return err; -} - -static void __exit peaq_wmi_exit(void) -{ - input_unregister_device(peaq_poll_dev); -} - -module_init(peaq_wmi_init); -module_exit(peaq_wmi_exit); - -MODULE_DESCRIPTION("PEAQ 2-in-1 WMI hotkey driver"); -MODULE_AUTHOR("Hans de Goede "); -MODULE_LICENSE("GPL"); diff --git a/drivers/platform/x86/x86-android-tablets/dmi.c b/drivers/platform/x86/x86-android-tablets/dmi.c index ec7c0af8d73d..9a236bcd9728 100644 --- a/drivers/platform/x86/x86-android-tablets/dmi.c +++ b/drivers/platform/x86/x86-android-tablets/dmi.c @@ -30,6 +30,7 @@ extern struct x86_dev_info lenovo_yoga_tab2_830_1050_info; extern const struct x86_dev_info lenovo_yt3_info; extern const struct x86_dev_info medion_lifetab_s10346_info; extern const struct x86_dev_info nextbook_ares8_info; +extern const struct x86_dev_info peaq_c1010_info; extern const struct x86_dev_info whitelabel_tm800a550l_info; extern const struct x86_dev_info xiaomi_mipad2_info; @@ -143,6 +144,14 @@ const struct dmi_system_id x86_android_tablet_ids[] __initconst = { }, .driver_data = (void *)&nextbook_ares8_info, }, + { + /* Peaq C1010 */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "PEAQ"), + DMI_MATCH(DMI_PRODUCT_NAME, "PEAQ PMM C1010 MD99187"), + }, + .driver_data = (void *)&peaq_c1010_info, + }, { /* Whitelabel (sold as various brands) TM800A550L */ .matches = { diff --git a/drivers/platform/x86/x86-android-tablets/other.c b/drivers/platform/x86/x86-android-tablets/other.c index e4b3ad2ce7c1..e09d3baff677 100644 --- a/drivers/platform/x86/x86-android-tablets/other.c +++ b/drivers/platform/x86/x86-android-tablets/other.c @@ -377,6 +377,33 @@ const struct x86_dev_info nextbook_ares8_info __initconst = { .invalid_aei_gpiochip = "INT33FC:02", }; +/* + * Peaq C1010 + * This is a standard Windows tablet, but it has a special Dolby button. + * 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 struct gpio_keys_button peaq_c1010_button = { + .code = KEY_SOUND, + /* .gpio gets filled in by x86_android_tablet_init() */ + .active_low = true, + .desc = "dolby_key", + .type = EV_KEY, + .wakeup = false, + .debounce_interval = 50, +}; + +const struct x86_dev_info peaq_c1010_info __initconst = { + .gpio_keys_button = &peaq_c1010_button, + .gpio_keys_gpiochip = "INT33FC:00", + .gpio_keys_pin = 3, + /* + * Move the ACPI event handler used by the broken WMI interface out of + * the way. This is the only event handler on INT33FC:00. + */ + .invalid_aei_gpiochip = "INT33FC:00", +}; + /* * Whitelabel (sold as various brands) TM800A550L tablets. * These tablet's DSDT contains a whole bunch of bogus ACPI I2C devices