From patchwork Wed Jun 16 05:56:53 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492712 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=GNlyWhL6; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4G4ZGd5t10z9sXG; Wed, 16 Jun 2021 15:57:45 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1ltOYX-0005dj-D3; Wed, 16 Jun 2021 05:57:41 +0000 Received: from mail-pf1-f181.google.com ([209.85.210.181]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOYT-0005WI-2M for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:37 +0000 Received: by mail-pf1-f181.google.com with SMTP id z26so1299935pfj.5 for ; Tue, 15 Jun 2021 22:57:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=V2g2NcIpDcPXjfGAxc06oFkY9fQIm2XY0XZBdxgTuj0=; b=GNlyWhL6QYa3Carj/kIen7BPR8EXDrMTNftSn9Iqn7Cnw0vDoG+W2JEEheTmqrZwdY RDqE8P/j/VNRy19H+dnYzNrX0W4tdzrJvUFJFC4HJGIMTj7WgHuxiPKLR8bRcEWS0llP 30WSo/nAw23mmN4cQAil1WKAw1fJv9gvzs0behB8Mt05+U3/qyBb2h+lJEd9Pm8vtcK1 0Yy2SI7p3O4wL2iAbwaGlp3A1hzU5rUQrRSqKyLUgLDN/w5hw3JM0Ijlr1ABqQt6yAGP /y1SRARJqh+ShmP4L0bQp4zNPPMtBlGAinA/56mEfHkfFZJpMSE9cxFIeVvvthLaemsr +aXg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=V2g2NcIpDcPXjfGAxc06oFkY9fQIm2XY0XZBdxgTuj0=; b=lkHxiBm0wquXGtPZemqyuY3nKU5MZr6bZqUqVrhOSNLdo+sd+h4LhXr4ga24MJgztz QDRqBrhT378471dtjx6UPANObYZhL0Cxo5U8wp9iM8qCQ8ql4wCWEXb1rf3ifzV0iZS0 /jsAilt2JRqJqwhkpJ+ggRBn8zHGvo0CjdZIqY4CwmD6qIl7lSIhooKPO3xRer9t4jmC GA9bmcu0VohgGLPqVB9Xaug0C5NypgeAdXtwj/kmMO+UTsJvXDNlG+MYjsL8duEuI+ES rK/LbhHkWjpX/KBEofVUFaS0Ush0EP44MEZ3yRkA171nRWavmrXdMxNz3qPEdOOOqn9l TnKw== X-Gm-Message-State: AOAM533onlGFqHSHiIWztoGuFtNlFW0Q/6nSg+G70MDj8SBI25upSXvZ l/WBdqSlvNpL/0M00YCmt84YeazdMGY= X-Google-Smtp-Source: ABdhPJzmceXrULdNZSCRoCpmSGkdJ+mAwP1jGJX2UcAh7oAYT1OdXp/tdHEDPjyrbBkDGE7yc0w5eg== X-Received: by 2002:a63:e90e:: with SMTP id i14mr2730425pgh.89.1623823050922; Tue, 15 Jun 2021 22:57:30 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id o139sm948248pfd.96.2021.06.15.22.57.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:30 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 2/6][SRU][H] UBUNTU: ODM: gpio: add driver for AAEON devices Date: Wed, 16 Jun 2021 13:56:53 +0800 Message-Id: <20210616055703.124039-9-acelan.kao@canonical.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210616055703.124039-1-acelan.kao@canonical.com> References: <20210616055703.124039-1-acelan.kao@canonical.com> MIME-Version: 1.0 Received-SPF: pass client-ip=209.85.210.181; envelope-from=acelan@gmail.com; helo=mail-pf1-f181.google.com X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Kunyang_Fan BugLink: https://bugs.launchpad.net/bugs/1929504 This patch add support for the GPIO pins whose control are transported to BIOS through ASUS WMI interface. Signed-off-by: Kunyang_Fan Review-by: Kai-Heng Feng Review-by: Chia-Lin Kao (AceLan) Signed-off-by: Chia-Lin Kao (AceLan) --- drivers/gpio/Kconfig | 12 +++ drivers/gpio/Makefile | 1 + drivers/gpio/gpio-aaeon.c | 205 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 218 insertions(+) create mode 100644 drivers/gpio/gpio-aaeon.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index fa225175e68d..e8cb09d75cbb 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1427,6 +1427,18 @@ endmenu menu "PCI GPIO expanders" depends on PCI +config GPIO_AAEON + tristate "AAEON GPIO support" + depends on ASUS_WMI + depends on UBUNTU_ODM_DRIVERS + select MFD_AAEON + help + Say yes here to support GPIO pins on Single Board Computers produced + by AAEON. + + This driver leverages the ASUS WMI interface to access device + resources. + config GPIO_AMD8111 tristate "AMD 8111 GPIO driver" depends on X86 || COMPILE_TEST diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 35e3b6026665..4b6496e174c4 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -23,6 +23,7 @@ obj-$(CONFIG_GPIO_104_IDI_48) += gpio-104-idi-48.o obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o +obj-$(CONFIG_GPIO_AAEON) += gpio-aaeon.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5588) += gpio-adp5588.o diff --git a/drivers/gpio/gpio-aaeon.c b/drivers/gpio/gpio-aaeon.c new file mode 100644 index 000000000000..3183c45dd194 --- /dev/null +++ b/drivers/gpio/gpio-aaeon.c @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AAEON GPIO driver + * Copyright (c) 2021, AAEON Ltd. + * + * Author: Edward Lin + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRVNAME "gpio_aaeon" +#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" +#define AAEON_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" + +#define GET_GPIO_NUMBER_ID 0x00010000 +#define GET_LEVEL_METHOD_ID 0x00010001 +#define SET_LEVEL_METHOD_ID 0x00010002 +#define GET_DIRECTION_METHOD_ID 0x00010003 +#define SET_DIRECTION_METHOD_ID 0x00010004 +#define GET_SIO_NUMBER_METHOD_ID 0xF0010 + +struct aaeon_gpio_bank { + struct gpio_chip chip; + unsigned int regbase; + struct aaeon_gpio_data *data; +}; + +struct aaeon_gpio_data { + int nr_bank; + struct aaeon_gpio_bank *bank; +}; + +static int aaeon_gpio_get_number(void); +static int aaeon_gpio_get_direction(struct gpio_chip *chip, + unsigned int offset); +static int aaeon_gpio_output_set_direction(struct gpio_chip *chip, + unsigned int offset, int value); +static int aaeon_gpio_input_set_direction(struct gpio_chip *chip, + unsigned int offset); +static int aaeon_gpio_get(struct gpio_chip *chip, + unsigned int offset); +static void aaeon_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value); + +#define AAEON_GPIO_BANK(_base, _ngpio, _regbase) \ +{ \ + .chip = { \ + .label = DRVNAME, \ + .owner = THIS_MODULE, \ + .get_direction = aaeon_gpio_get_direction, \ + .direction_input = aaeon_gpio_input_set_direction, \ + .direction_output = aaeon_gpio_output_set_direction, \ + .get = aaeon_gpio_get, \ + .set = aaeon_gpio_set, \ + .base = _base, \ + .ngpio = _ngpio, \ + .can_sleep = true, \ + }, \ + .regbase = _regbase, \ +} + +static struct aaeon_gpio_bank aaeon_gpio_bank[] = { + AAEON_GPIO_BANK(0, 0, 0xF0), +}; + +static int aaeon_gpio_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + int err, retval; + u32 dev_id = 0x0; + + dev_id |= offset; + err = asus_wmi_evaluate_method(GET_DIRECTION_METHOD_ID, dev_id, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_gpio_input_set_direction(struct gpio_chip *chip, + unsigned int offset) +{ + int err, retval; + u32 dev_id; + + dev_id = BIT(16) | offset; + err = asus_wmi_evaluate_method(SET_DIRECTION_METHOD_ID, dev_id, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_gpio_output_set_direction(struct gpio_chip *chip, + unsigned int offset, int value) +{ + int err, retval; + u32 dev_id = 0x0; + + dev_id |= offset; + err = asus_wmi_evaluate_method(SET_DIRECTION_METHOD_ID, dev_id, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_gpio_get(struct gpio_chip *chip, unsigned int offset) +{ + int err, retval; + u32 dev_id = 0x0; + + dev_id |= offset; + err = asus_wmi_evaluate_method(GET_LEVEL_METHOD_ID, dev_id, 0, &retval); + if (err) + return err; + + return retval; +} + +static void aaeon_gpio_set(struct gpio_chip *chip, unsigned int offset, + int value) +{ + int retval; + u32 dev_id = offset; + + if (value) + dev_id = BIT(16) | dev_id; + + asus_wmi_evaluate_method(SET_LEVEL_METHOD_ID, dev_id, 0, &retval); +} + +static int aaeon_gpio_get_number(void) +{ + int err, retval; + + err = asus_wmi_evaluate_method(GET_GPIO_NUMBER_ID, + GET_SIO_NUMBER_METHOD_ID, + 0, &retval); + if (err) + return err; + + return retval; +} + +static int __init aaeon_gpio_probe(struct platform_device *pdev) +{ + int err, i; + int dio_number = 0; + struct aaeon_gpio_data *data; + struct aaeon_gpio_bank *bank; + + /* Prevent other drivers adding this platfom device */ + if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) { + pr_debug("AAEON Management GUID not found\n"); + return -ENODEV; + } + + dio_number = aaeon_gpio_get_number(); + if (dio_number < 0) + return -ENODEV; + + data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->nr_bank = ARRAY_SIZE(aaeon_gpio_bank); + data->bank = aaeon_gpio_bank; + platform_set_drvdata(pdev, data); + bank = &data->bank[0]; + bank->chip.parent = &pdev->dev; + bank->chip.ngpio = dio_number; + bank->data = data; + err = devm_gpiochip_add_data(&pdev->dev, &bank->chip, bank); + if (err) + pr_debug("Failed to register gpiochip %d: %d\n", i, err); + + return err; +} + +static struct platform_driver aaeon_gpio_driver = { + .driver = { + .name = "gpio-aaeon", + }, +}; + +module_platform_driver_probe(aaeon_gpio_driver, aaeon_gpio_probe); + +MODULE_ALIAS("platform:gpio-aaeon"); +MODULE_DESCRIPTION("AAEON GPIO Driver"); +MODULE_AUTHOR("Edward Lin "); +MODULE_LICENSE("GPL v2");