From patchwork Wed Jun 16 05:56:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492705 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=H7zKm740; 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 4G4ZG64NNnz9sXL; Wed, 16 Jun 2021 15:57:18 +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 1ltOY7-0005Jt-5W; Wed, 16 Jun 2021 05:57:15 +0000 Received: from mail-pf1-f169.google.com ([209.85.210.169]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOY4-0005Iy-LB for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:12 +0000 Received: by mail-pf1-f169.google.com with SMTP id c12so1309826pfl.3 for ; Tue, 15 Jun 2021 22:57:12 -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=awWEouzUlclYL1k6Cz5jzqKjg4jkEp/oPceeVYrnJp0=; b=H7zKm740kB1mG1sm6BjTrk/PCoTfbSRQVe340SnOVjmAcXE5JQGh5QTYKr/JvHJyDW dS70YIo85RRdslHSFRVo9AmxZ7OI3kd7lKIsVzMDGkHCcc0ZSKt1/0prkP6lED6aWlz3 H6pegrnGN6fi4Zkz7hgREkZbANq2S1coxWlPyJuSRbS4a3WnwW32zKThd07oCQvhXZ8U g7rTRXVpr+QEXvGu8lCX4Kto5DjjU+3fVtA8rUJOAo8TF9eI9BDMSlsj2P2dz2NIwunK HYdSZPkn2CcBEDKmUQBZU4DCxgY9TMrMO1Egrffh7C711MZZrb3qfi/AygoO7R4nKhhM JAvQ== 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=awWEouzUlclYL1k6Cz5jzqKjg4jkEp/oPceeVYrnJp0=; b=YK35dFDrIFU5Kmh0OsmVTtJqO+OToeCrPFwxhnQGkf9T9hjwHestYaf5FIY2GZeqWy IAmLVGd51mZIAMcsQriC7pZSBucR/ue1q/7QwqCOumJ3fL0ZgAmwXNIC0sM36gVZFD6g 68J3vKFChTnE0/iT6/kIkRkzTsWonvdJ74mGFyi7veYNqfEnoqpXChcshezhnZzCk5xC TgM+InStlaAtPi1c/ChtwlknIMmF36MuhBgUeLw/P/SEjfXCJjSn+Pm6nj5fVov8MXOr 8bTguzKhv99Myf6DJIuCLcY5RPtHbPoqJddspwWfyzaJDSONbwWE3DbiOxsi2TEkJRiE Lmdg== X-Gm-Message-State: AOAM5331a0w9xMyv2d8Nq5QtMBVkH3gHlwYKPlSUFzzbMpb8DnznoxWg qHO6Ab4YxXl56j3ST/1hgm35aUYQxrE= X-Google-Smtp-Source: ABdhPJxcyViX85QWNnUrztlVspdMOIW9Q4oOwfBh59nHrXfk05jGYntKEREnNVI8DkGcC9/7ohTawQ== X-Received: by 2002:a62:5c1:0:b029:2a9:7589:dd30 with SMTP id 184-20020a6205c10000b02902a97589dd30mr8024176pff.66.1623823029923; Tue, 15 Jun 2021 22:57:09 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id o3sm889871pfd.41.2021.06.15.22.57.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:09 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 1/6][SRU][G] UBUNTU: ODM: mfd: Add support for IO functions of AAEON devices Date: Wed, 16 Jun 2021 13:56:46 +0800 Message-Id: <20210616055703.124039-2-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.169; envelope-from=acelan@gmail.com; helo=mail-pf1-f169.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 adds the supports for multiple IO functions of the AAEON x86 devices and makes use of the WMI interface to control the these IO devices including: - GPIO - LED - Watchdog - HWMON It also adds the mfd child device drivers to support the above IO functions. Signed-off-by: Kunyang_Fan Review-by: Kai-Heng Feng Review-by: Chia-Lin Kao (AceLan) Signed-off-by: Chia-Lin Kao (AceLan) --- MAINTAINERS | 12 +++++++ drivers/mfd/Kconfig | 12 +++++++ drivers/mfd/Makefile | 1 + drivers/mfd/mfd-aaeon.c | 77 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 drivers/mfd/mfd-aaeon.c diff --git a/MAINTAINERS b/MAINTAINERS index 1c19c1e2c970..49783dd44367 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -257,6 +257,18 @@ W: http://www.adaptec.com/ F: Documentation/scsi/aacraid.rst F: drivers/scsi/aacraid/ +AAEON DEVICE DRIVER WITH WMI INTERFACE +M: Edward Lin +M: Kunyang Fan +M: Frank Hsieh +M: Jacob Wu +S: Supported +F: drivers/gpio/gpio-aaeon.c +F: drivers/hwmon/hwmon-aaeon.c +F: drivers/leds/leds-aaeon.c +F: drivers/mfd/mfd-aaeon.c +F: drivers/watchdog/wdt_aaeon.c + ABI/API L: linux-api@vger.kernel.org F: include/linux/syscalls.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index a37d7d171382..6716ce5f20bb 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -2053,6 +2053,18 @@ config MFD_WCD934X This driver provides common support WCD934x audio codec and its associated Pin Controller, Soundwire Controller and Audio codec. +config MFD_AAEON + tristate "AAEON WMI MFD devices" + depends on ASUS_WMI + depends on UBUNTU_ODM_DRIVERS + help + Say yes here to support mltiple IO devices on Single Board Computers + produced by AAEON. + + This driver leverages the ASUS WMI interface to access device + resources. + + menu "Multimedia Capabilities Port drivers" depends on ARCH_SA1100 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 9367a92f795a..36fff3d0da7e 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -264,3 +264,4 @@ obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_STMFX) += stmfx.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o +obj-$(CONFIG_MFD_AAEON) += mfd-aaeon.o diff --git a/drivers/mfd/mfd-aaeon.c b/drivers/mfd/mfd-aaeon.c new file mode 100644 index 000000000000..9d2efde53cad --- /dev/null +++ b/drivers/mfd/mfd-aaeon.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * UP Board main platform driver and FPGA configuration support + * + * Copyright (c) 2021, AAEON Ltd. + * + * Author: Kunyang_Fan + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define AAEON_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" + +struct aaeon_wmi_priv { + const struct mfd_cell *cells; + size_t ncells; +}; + +static const struct mfd_cell aaeon_mfd_cells[] = { + { .name = "gpio-aaeon" }, + { .name = "hwmon-aaeon"}, + { .name = "leds-aaeon"}, + { .name = "wdt-aaeon"}, +}; + +static const struct aaeon_wmi_priv aaeon_wmi_priv_data = { + .cells = aaeon_mfd_cells, + .ncells = ARRAY_SIZE(aaeon_mfd_cells), +}; + +static int aaeon_wmi_probe(struct wmi_device *wdev, const void *context) +{ + struct aaeon_wmi_priv *priv; + + if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) { + dev_info(&wdev->dev, "AAEON Management GUID not found\n"); + return -ENODEV; + } + + + priv = (struct aaeon_wmi_priv *)context; + dev_set_drvdata(&wdev->dev, priv); + + return devm_mfd_add_devices(&wdev->dev, 0, priv->cells, + priv->ncells, NULL, 0, NULL); +} + +static const struct wmi_device_id aaeon_wmi_id_table[] = { + { AAEON_WMI_MGMT_GUID, (void *)&aaeon_wmi_priv_data }, + {} +}; + +static struct wmi_driver aaeon_wmi_driver = { + .driver = { + .name = "mfd-aaeon", + }, + .id_table = aaeon_wmi_id_table, + .probe = aaeon_wmi_probe, +}; + +module_wmi_driver(aaeon_wmi_driver); + +MODULE_DEVICE_TABLE(wmi, aaeon_wmi_id_table); +MODULE_AUTHOR("Kunyang Fan "); +MODULE_DESCRIPTION("AAEON Board WMI driver"); +MODULE_LICENSE("GPL v2"); From patchwork Wed Jun 16 05:56:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492706 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=UoQarp2B; 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 4G4ZG92vhJz9sX2; Wed, 16 Jun 2021 15:57:21 +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 1ltOYA-0005L8-EU; Wed, 16 Jun 2021 05:57:18 +0000 Received: from mail-pl1-f175.google.com ([209.85.214.175]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOY7-0005Jg-QO for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:15 +0000 Received: by mail-pl1-f175.google.com with SMTP id e7so557917plj.7 for ; Tue, 15 Jun 2021 22:57:15 -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=kVeMYzFeyAFnWKCUrppBC8ofzptOrmNS3V2wvVG53CA=; b=UoQarp2B6PET7jBPnj7SpDjLRMyhP3hbCnDjmYxa0ImU5txvnHYSiWBM6aC75mAhNk 0ml5ALe9Cyka4Nbd0lt8xW/HupfnPHkAeFRY7j4nneJoATES6PTXC4bzI2FZLEhvamOc UlMoqR6sm8tTjWRoBEPv7rGdmkbXyA+nWdxwVMxXRSt84Yz7QT0nBuKu/4GulWKvm0gL C+aORe6rE8ckcmpa1fBlLbCx1lYrSir/o/RvMs4cYRXcCmHylXloxOnsc2Q5CL9SiswF QZp9nGy6m5PpQ1E3t9N+IJjrxsYgCWn4omaZh6po8az5kqIVS53ZiVBZ1X0uR7nPFauR BW7A== 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=kVeMYzFeyAFnWKCUrppBC8ofzptOrmNS3V2wvVG53CA=; b=JSghehOBON90DUlcdEc46dnzTc/jqsHKVz01Bm4HVx6X/bA6MlZlHEieefVGQe/v0X 5ebTFVupDKMCwi1Y9GTT9xee7VzsBuczE3p/BJHO35HmpgRSCE22XqQL7IE4ZDLDDux0 vuBtQgm1L3yaAFJeW9747I1ZlHX3Vr7/KaKTH8m2MKGi6duOF/uEddtdlrMd7rFBkoUQ MlAtVlBCaCbPg4kjom5AvYGLYzjKqGKAI9TuMMNTDWH6qadvaGP+uZJgwtAPfKkdbH6t MpumhSTqjZvB3SJHMbILgti8Dw1nZf344slx+WX6sUw5QtuZBk6/ntCefpkhsOSMsePN zH2Q== X-Gm-Message-State: AOAM531KSKReJH+UOQIpparz1UFkh9WwCAck1stW2nRS3cBk02dXhc45 ZHoTsQxXSWbr4TwKNn2JSWQkc0DRFSM= X-Google-Smtp-Source: ABdhPJxR7D0BamgR1+WCZn0mKJMlKBZszJ7E7PkBCNmJrtXfhIozv817ZRssVWADX853hlpv+ZKitw== X-Received: by 2002:a17:90a:4414:: with SMTP id s20mr3166780pjg.81.1623823032928; Tue, 15 Jun 2021 22:57:12 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id gf10sm974323pjb.35.2021.06.15.22.57.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:12 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 2/6][SRU][G] UBUNTU: ODM: gpio: add driver for AAEON devices Date: Wed, 16 Jun 2021 13:56:47 +0800 Message-Id: <20210616055703.124039-3-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.214.175; envelope-from=acelan@gmail.com; helo=mail-pl1-f175.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 6d2437676a75..0b0a144d769f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -1356,6 +1356,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 1e4894e0bf0f..50682c5c49d3 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"); From patchwork Wed Jun 16 05:56:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492707 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=ZZyCDK5j; 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 4G4ZGG16GKz9sSn; Wed, 16 Jun 2021 15:57:26 +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 1ltOYE-0005OP-Qi; Wed, 16 Jun 2021 05:57:22 +0000 Received: from mail-pl1-f176.google.com ([209.85.214.176]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOYB-0005Kv-LI for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:19 +0000 Received: by mail-pl1-f176.google.com with SMTP id h1so569726plt.1 for ; Tue, 15 Jun 2021 22:57:18 -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=pH253eLy9actG1kMRATmPYo0ip/DUJLkOzp23IyxJHU=; b=ZZyCDK5jKr+VftDOGLyaEhN+YnGw33ceJnyPzKf6RztVebDMXyqe9zif87qvH4ITmw luEhEP+vhmLxBQs8r8iP+3dON1o+KREtQwWNzhPyi5/k6L1/L4J6TQY7Sdcae232/3R8 j2gDR/ccL4yKxbKDL3Ilcu2my+Ikto9Ck2DssvULxI+h/PIkgZav/IP4kqsxuQ2ivtgD woYzhEasVGPW8dfsw8vWCno+q+geugoWKO+Ea7iEYBHaA2iQo5YzHpq4pinrUc/oCe4+ 3yDWZmhWGTytdaHxpe5zOhombExDBCA3uf/D6NZwpk2XA8GBzrZpKs4co8LKQToW9lJy /xvw== 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=pH253eLy9actG1kMRATmPYo0ip/DUJLkOzp23IyxJHU=; b=cL73NsrgNA+l556/OuXInFkSDiPIcTGc4TRvPIHuf5OaXp9biY2Ah3R81poOT33DL7 OHJ6UdssRqbJBhnINmhxnJsJrdoF/zRduGhoghi74LNRY67qwOuxp2JMgV5Xp5SwYJ4o dZ6MsYOd78rfvkOz1QysMeGijGyFAMeoKIgBk7h2ynVUKVfBbs66S5uER2dVbiMSYxLQ vVegi+80O/mAlTUGJkU60RF7HOuHAk5t5gOvjhB9RBQTjojz8A/ZPKmN/QAO/fMJgXKC sUDM/i+XzAVbAMnP9Plf7TK+qDbRWZ9jFkGyuYi3Nl0NooqDXTwL5m7b6U4JL9jmc1UK jvZQ== X-Gm-Message-State: AOAM532gP2aS/0o6G4SVhl4NvYkCv8+0bVjfZn89DPxKa/ASE3rkp1ji Gg8BHYrSvpK6jKCZLQ3yPQoSmRwsDaA= X-Google-Smtp-Source: ABdhPJzzKYhpMjgjuFt75mCjcbCQIC5jGkGlcOfyuMJ6yJGjM4986N7P9WRcMYTHVF9YRp5eb+WJgg== X-Received: by 2002:a17:90a:6bc1:: with SMTP id w59mr3190699pjj.130.1623823036491; Tue, 15 Jun 2021 22:57:16 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id y13sm1017946pgp.16.2021.06.15.22.57.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:15 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 3/6][SRU][G] UBUNTU: ODM: watchdog: add driver for AAEON devices Date: Wed, 16 Jun 2021 13:56:48 +0800 Message-Id: <20210616055703.124039-4-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.214.176; envelope-from=acelan@gmail.com; helo=mail-pl1-f176.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 adds support for the watchdog whose control are transported to BIOS through ASUS WMI interface. This driver imitates the old type SIO watchdog driver to provide the basic control for watchdog functions. Signed-off-by: Kunyang_Fan Review-by: Kai-Heng Feng Review-by: Chia-Lin Kao (AceLan) Signed-off-by: Chia-Lin Kao (AceLan) --- drivers/watchdog/Kconfig | 13 ++ drivers/watchdog/Makefile | 1 + drivers/watchdog/wdt_aaeon.c | 242 +++++++++++++++++++++++++++++++++++ 3 files changed, 256 insertions(+) create mode 100644 drivers/watchdog/wdt_aaeon.c diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 2b2839e89b7b..2f0b93cdfbee 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1623,6 +1623,19 @@ config NIC7018_WDT To compile this driver as a module, choose M here: the module will be called nic7018_wdt. +config AAEON_IWMI_WDT + tristate "AAEON Watchdog Timer" + depends on ASUS_WMI + depends on UBUNTU_ODM_DRIVERS + select MFD_AAEON + help + This is the driver for the hardware watchdog on Single Board + Computers produced by AAEON.Say `Y' here to support its built-in + watchdog timer feature. + + This driver leverages the ASUS WMI interface to access device + resources. + # M68K Architecture config M54xx_WATCHDOG diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 97bed1d3d97c..9d27fec12480 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -145,6 +145,7 @@ obj-$(CONFIG_INTEL_MEI_WDT) += mei_wdt.o obj-$(CONFIG_NI903X_WDT) += ni903x_wdt.o obj-$(CONFIG_NIC7018_WDT) += nic7018_wdt.o obj-$(CONFIG_MLX_WDT) += mlx_wdt.o +obj-$(CONFIG_AAEON_IWMI_WDT) += wdt_aaeon.o # M68K Architecture obj-$(CONFIG_M54xx_WATCHDOG) += m54xx_wdt.o diff --git a/drivers/watchdog/wdt_aaeon.c b/drivers/watchdog/wdt_aaeon.c new file mode 100644 index 000000000000..41c68805cc93 --- /dev/null +++ b/drivers/watchdog/wdt_aaeon.c @@ -0,0 +1,242 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AAEON WDT driver + * + * 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 +#include +#include +#include +#include + +#define AAEON_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" +#define WMI_WDT_GETMAX_METHOD_ID 0x00020000 +#define WMI_WDT_GETVALUE_METHOD_ID 0x00020001 +#define WMI_WDT_SETANDSTOP_METHOD_ID 0x00020002 + +#define WMI_WDT_SUPPORTED_DEVICE_ID \ + 0x12 /* Dev_Id for WDT_WMI supported or not */ +#define WMI_WDT_GETMAX_DEVICE_ID 0x10 /* Dev_Id for WDT_WMI get Max timeout */ +#define WMI_WDT_STOP_DEVICE_ID 0x00 /* Dev_Id for WDT_WMI stop watchdog*/ + +/* Default values */ +#define WATCHDOG_TIMEOUT 60000 /* 1 minute default timeout */ +#define WATCHDOG_MAX_TIMEOUT (60000 * 255) /* WD_TIME is a byte long */ +#define WATCHDOG_PULSE_WIDTH 5000 /* default pulse width for watchdog signal */ + +static const int max_timeout = WATCHDOG_MAX_TIMEOUT; +static int timeout = WATCHDOG_TIMEOUT; /* default timeout in seconds */ +module_param(timeout, int, 0); +MODULE_PARM_DESC(timeout, "Initial watchdog timeout in mini-seconds"); + +static bool nowayout = WATCHDOG_NOWAYOUT; +module_param(nowayout, bool, 0444); +MODULE_PARM_DESC(nowayout, " Disable watchdog shutdown on close"); + +/* Wdog internal data information */ +struct watchdog_data { + unsigned long opened; /* driver open state */ + struct mutex lock; /* concurrency control */ + char expect_close; /* controlled close */ + struct watchdog_info ident; /* wdog information*/ + unsigned short timeout; /* current wdog timeout */ + u8 timer_val; /* content for the WD_TIME register */ + char minutes_mode; + u8 pulse_val; /* pulse width flag */ + char pulse_mode; /* enable pulse output mode? */ + char caused_reboot;/* last reboot was by the watchdog */ +}; + +static long aaeon_watchdog_ioctl(struct file *file, unsigned int cmd, + unsigned long arg); +static int aaeon_watchdog_notify_sys(struct notifier_block *this, + unsigned long code, void *unused); + +static struct watchdog_data watchdog = { + .lock = __MUTEX_INITIALIZER(watchdog.lock), +}; + +/* /dev/watchdog api available options */ +static const struct file_operations watchdog_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = aaeon_watchdog_ioctl, +}; + +static struct miscdevice watchdog_miscdev = { + .minor = WATCHDOG_MINOR, + .name = "watchdog", + .fops = &watchdog_fops, +}; + +static struct notifier_block watchdog_notifier = { + .notifier_call = aaeon_watchdog_notify_sys, +}; + +/* Internal Configuration functions */ +static int aaeon_watchdog_set_timeout(int timeout) +{ + int err = 0; + u32 retval, dev_id = timeout; + + if (timeout <= 0 || timeout > max_timeout) { + pr_debug("watchdog timeout out of range\n"); + return -EINVAL; + } + + mutex_lock(&watchdog.lock); + err = asus_wmi_evaluate_method(WMI_WDT_SETANDSTOP_METHOD_ID, + dev_id, 0, &retval); + mutex_unlock(&watchdog.lock); + + return err; +} + +static int aaeon_watchdog_get_timeout(void) +{ + int err = 0; + u32 retval; + + if (timeout <= 0 || timeout > max_timeout) { + pr_debug("watchdog timeout out of range\n"); + return -EINVAL; + } + mutex_lock(&watchdog.lock); + err = asus_wmi_evaluate_method(WMI_WDT_GETVALUE_METHOD_ID, + 0, 0, &retval); + mutex_unlock(&watchdog.lock); + + return err ? err : retval; +} + +static int aaeon_watchdog_stop(void) +{ + int err = 0; + + mutex_lock(&watchdog.lock); + err = asus_wmi_evaluate_method(WMI_WDT_SETANDSTOP_METHOD_ID, + 0, 0, NULL); + mutex_unlock(&watchdog.lock); + + return err; +} + +static int aaeon_watchdog_get_maxsupport(void) +{ + int err; + u32 retval; + + mutex_lock(&watchdog.lock); + err = asus_wmi_evaluate_method(WMI_WDT_GETMAX_METHOD_ID, + WMI_WDT_GETMAX_DEVICE_ID, + 0, &retval); + mutex_unlock(&watchdog.lock); + + return err ? err : retval; + +} + +static long aaeon_watchdog_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + int new_timeout; + + union { + struct watchdog_info __user *ident; + int __user *i; + } uarg; + + uarg.i = (int __user *) arg; + switch (cmd) { + case WDIOC_SETTIMEOUT: + if (get_user(new_timeout, uarg.i)) + return -EFAULT; + if (aaeon_watchdog_set_timeout(new_timeout)) + return -EINVAL; + return 0; + case WDIOC_GETTIMEOUT: + return aaeon_watchdog_get_timeout(); + case WDIOS_DISABLECARD: + return aaeon_watchdog_stop(); + case WDIOC_GETSUPPORT: + return aaeon_watchdog_get_maxsupport(); + default: + return -ENOTTY; + } +} + +static int aaeon_watchdog_notify_sys(struct notifier_block *this, + unsigned long code, void *unused) +{ + if (code == SYS_DOWN || code == SYS_HALT) + aaeon_watchdog_stop(); + return NOTIFY_DONE; +} + +static int aaeon_wdt_probe(struct platform_device *pdev) +{ + int err = 0; + int retval = 0; + + pr_debug("aaeon watchdog device probe!\n"); + if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) { + pr_debug("AAEON Management GUID not found\n"); + return -ENODEV; + } + err = asus_wmi_evaluate_method(WMI_WDT_GETMAX_METHOD_ID, + WMI_WDT_SUPPORTED_DEVICE_ID, 0, &retval); + if (err) + goto exit; + + /* + * This driver imitates the old type SIO watchdog driver to + * provide the basic control for watchdog functions and only + * access by customized userspace tool + */ + err = misc_register(&watchdog_miscdev); + if (err) { + pr_debug(" cannot register miscdev on minor=%d\n", + watchdog_miscdev.minor); + goto exit; + } + + err = register_reboot_notifier(&watchdog_notifier); + if (err) + goto exit_miscdev; + + if (nowayout) + __module_get(THIS_MODULE); + + return 0; + +exit_miscdev: + misc_deregister(&watchdog_miscdev); +exit: + return err; +} + +static struct platform_driver aaeon_wdt_driver = { + .driver = { + .name = "wdt-aaeon", + }, +}; + +module_platform_driver_probe(aaeon_wdt_driver, aaeon_wdt_probe); + +MODULE_ALIAS("platform:wdt-aaeon"); +MODULE_DESCRIPTION("AAEON WDT Driver"); +MODULE_AUTHOR("Edward Lin "); +MODULE_LICENSE("GPL v2"); From patchwork Wed Jun 16 05:56:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492708 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=ryVB4PUf; 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 4G4ZGK1cCTz9sX2; Wed, 16 Jun 2021 15:57:28 +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 1ltOYH-0005Qi-Op; Wed, 16 Jun 2021 05:57:25 +0000 Received: from mail-pg1-f181.google.com ([209.85.215.181]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOYE-0005NF-7R for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:22 +0000 Received: by mail-pg1-f181.google.com with SMTP id m2so1072866pgk.7 for ; Tue, 15 Jun 2021 22:57:21 -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=s0q6MCbshGriIJpnzVDd3Jq2XybYLkfH9hZzDedKpi0=; b=ryVB4PUfcsHrb3/yLlY4yyY49PB6NGhrzjraw7FnZuxx8IxpDflOUCuIeirjX0TY9b 2PMgY92GOFKc47njyDXD9iUCsraY0DwERJp7HFml+qYjFBf+3FuBL/k+YjBL1SzHw1F8 uFEs+Pk4M7pzcLvjrx4t0clfDILSo2qGjBUUOjHrhtppA/V17Zph1Ik2nS6ashmcMbqc 3JFtiftsITmF3tIKy1zlyyYApwIUukzOic6RowpPs427kI11WtcrZ9fTKVPgprbEh+zR VXZc643WQ0/EQEjr2xgh2F0TvoTNjI+jSZ10MbY1/rkA7b/IMe7/DLi9LHQneQ+48mGr Y0gw== 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=s0q6MCbshGriIJpnzVDd3Jq2XybYLkfH9hZzDedKpi0=; b=jnC9LK9NxG7gM4xgs0/2ifNJ5VVtgwmoplHmUd0jiML7/yS0L9uam2eCB1p4QmrJgk 28B4Vq2I0LfRrm+sJkyvsW306Pm1MLMhO6u1s8dj6TOJQIMNyHHb1jMjk8H1fijf0VnA W5Y0/BfaDqyDoaW6o6eUZ2wnf9vNmRfqO18Ingqs3u2GGQ82jqXns4a+xAPVV+BIz/n6 LQrZ0ZaigaUBfgmMR55Uq8D8lWdeih+FG0wXS3CpUPk+8qYs3Bhepe5alXV6s+DMsc9q pBQ/q+jmVPESSYPhXsZmh0QDB9/exhYLhax6JHNH6iGp5mIYJBAkQr1+kQMNsoIn8MJH TQMA== X-Gm-Message-State: AOAM532MrYdhorEpo1HOM8zJ+oG56DcO+5HY2PKEfRN0OtQAMfzOt7R7 uYNkPsfTpAgiA8vFIQj18Ynq5+nDdjY= X-Google-Smtp-Source: ABdhPJzuYsiG3U4vRof3hpgbpZ8T0KyY5OI8Xeydp9vYCQowwL1GlB3UO72tcaRxoxbdmX3xD89a8w== X-Received: by 2002:aa7:9d92:0:b029:2e9:dcf0:a2ef with SMTP id f18-20020aa79d920000b02902e9dcf0a2efmr7816509pfq.46.1623823039342; Tue, 15 Jun 2021 22:57:19 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id r135sm909767pfc.184.2021.06.15.22.57.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:18 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 4/6][SRU][G] UBUNTU: ODM: hwmon: add driver for AAEON devices Date: Wed, 16 Jun 2021 13:56:49 +0800 Message-Id: <20210616055703.124039-5-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.215.181; envelope-from=acelan@gmail.com; helo=mail-pg1-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 refator patch adds support for the hwmon information which are transported to userspace 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/hwmon/Kconfig | 12 + drivers/hwmon/Makefile | 1 + drivers/hwmon/hwmon-aaeon.c | 568 ++++++++++++++++++++++++++++++++++++ 3 files changed, 581 insertions(+) create mode 100644 drivers/hwmon/hwmon-aaeon.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 288ae9f63588..bb1c83493b9d 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -38,6 +38,18 @@ config HWMON_DEBUG_CHIP comment "Native drivers" +config SENSORS_AAEON + tristate "AAEON hwmon driver" + depends on X86 + depends on UBUNTU_ODM_DRIVERS + select MFD_AAEON + help + This hwmon driver adds support for reporting temperature or fan + speed and voltage on Single Board Computers produced by AAEON. + + This driver leverages the ASUS WMI interface to access device + resources. + config SENSORS_AB8500 tristate "AB8500 thermal monitoring" depends on AB8500_GPADC && AB8500_BM && (IIO = y) diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 3e32c21f5efe..43d8e2fed7b1 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o obj-$(CONFIG_SENSORS_GSC) += gsc-hwmon.o obj-$(CONFIG_SENSORS_GPIO_FAN) += gpio-fan.o obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o +obj-$(CONFIG_SENSORS_AAEON) += hwmon-aaeon.o obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o diff --git a/drivers/hwmon/hwmon-aaeon.c b/drivers/hwmon/hwmon-aaeon.c new file mode 100644 index 000000000000..146da10309bb --- /dev/null +++ b/drivers/hwmon/hwmon-aaeon.c @@ -0,0 +1,568 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AAEON HWMON driver + * Copyright (c) 2021, AAEON Ltd. + * + * Author: Edward Lin + * Author: Kunyang Fan + * + * 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 +#include + +#define DRVNAME "hwmon-aaeon" + +#define AAEON_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" + +#define AAEON_VERSION_METHOD_ID 0x00000000 +#define HWM_INFORMATION_METHOD_ID 0x00030000 +#define HWM_METHOD_ID 0x00030001 + +#define BITMAP_TEMP_ARG 0x12 +#define BITMAP_FAN_ARG 0x13 +#define BITMAP_VOLTAGE_ARG 0x14 + +#define SENSOR_TEMP_NUMBER 0 +#define SENSOR_FAN_NUMBER 1 +#define SENSOR_VOLTAGE_NUMBER 2 +#define SENSOR_MAX_NUMBER 2 + +static ssize_t aaeon_show_sensor(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t aaeon_show_sensor_name(struct device *dev, + struct device_attribute *devattr, + char *buf); +static ssize_t aaeon_show_version(struct device *dev, + struct device_attribute *devattr, char *buf); +static ssize_t name_show(struct device *dev, struct device_attribute *devattr, + char *buf); +static int aaeon_get_version(void); +static int aaeon_hwmon_probe(struct platform_device *pdev); +static int aaeon_hwmon_remove(struct platform_device *pdev); + +static const char * const temp_sensors_name_table[] = { + "CPU_Temp", + "SYS1_Temp", + "SYS2_Temp", +}; + +static const char * const temp_sensors_name_table_V3[] = { + "SYS_Temp", + "CPU_Temp", +}; + +static const char * const fan_sensors_name_table[] = { + "CPU_FAN", + "SYS1_FAN", + "SYS2_FAN", + "Chasis1_FAN", + "Chasis2_FAN", +}; + +static const char * const fan_sensors_name_table_V3[] = { + "Chasis_FAN", + "CPU_FAN", +}; + +static const char * const voltage_sensors_name_table[] = { + "VCORE_Voltage", + "VMEM_Voltage", + "+12_Voltage", + "+5_Voltage", + "+3.3_Voltage", + "+1.8_Voltage", + "5VSB_Voltage", + "3VSB_Voltage", + "VBAT_Voltage", +}; + +static const char * const voltage_sensors_name_table_V3[] = { + "VCORE_Voltage", + "+5_Voltage", + "AVCC_Voltage", + "+3.3_Voltage", + "+12_Voltage", + "VCOREREFIN_Voltage", + "VIN4_Voltage", + "3VSB_Voltage", + "VBAT_Voltage", +}; + +struct aaeon_hwmon_data { + struct device *hwmon_dev; + int bfpi_version; + u32 temp_bitmap; + u32 fan_bitmap; + u32 voltage_bitmap; + unsigned int sensors_number[SENSOR_MAX_NUMBER + 1]; + const char * const *temp_names; + const char * const *fan_names; + const char * const *voltage_names; +}; + +/* Temperature attributes */ +static struct sensor_device_attribute_2 temp_sys_nodes_atts[] = { + SENSOR_ATTR_2(temp1_input, 0444, aaeon_show_sensor, NULL, + SENSOR_TEMP_NUMBER, 0), + SENSOR_ATTR_2(temp1_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_TEMP_NUMBER, 0), + SENSOR_ATTR_2(temp2_input, 0444, aaeon_show_sensor, NULL, + SENSOR_TEMP_NUMBER, 1), + SENSOR_ATTR_2(temp2_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_TEMP_NUMBER, 1), + SENSOR_ATTR_2(temp3_input, 0444, aaeon_show_sensor, NULL, + SENSOR_TEMP_NUMBER, 2), + SENSOR_ATTR_2(temp3_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_TEMP_NUMBER, 2), +}; + +/* Cooler Fan attributes */ +static struct sensor_device_attribute_2 fan_sys_nodes_atts[] = { + SENSOR_ATTR_2(fan1_input, 0444, aaeon_show_sensor, NULL, + SENSOR_FAN_NUMBER, 0), + SENSOR_ATTR_2(fan1_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_FAN_NUMBER, 0), + SENSOR_ATTR_2(fan2_input, 0444, aaeon_show_sensor, NULL, + SENSOR_FAN_NUMBER, 1), + SENSOR_ATTR_2(fan2_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_FAN_NUMBER, 1), + SENSOR_ATTR_2(fan3_input, 0444, aaeon_show_sensor, NULL, + SENSOR_FAN_NUMBER, 2), + SENSOR_ATTR_2(fan3_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_FAN_NUMBER, 2), + SENSOR_ATTR_2(fan4_input, 0444, aaeon_show_sensor, NULL, + SENSOR_FAN_NUMBER, 3), + SENSOR_ATTR_2(fan4_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_FAN_NUMBER, 3), + SENSOR_ATTR_2(fan5_input, 0444, aaeon_show_sensor, NULL, + SENSOR_FAN_NUMBER, 4), + SENSOR_ATTR_2(fan5_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_FAN_NUMBER, 4), +}; + +/* Voltage attributes */ +static struct sensor_device_attribute_2 voltage_sys_nodes_atts[] = { + SENSOR_ATTR_2(in1_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 0), + SENSOR_ATTR_2(in1_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 0), + SENSOR_ATTR_2(in2_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 1), + SENSOR_ATTR_2(in2_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 1), + SENSOR_ATTR_2(in3_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 2), + SENSOR_ATTR_2(in3_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 2), + SENSOR_ATTR_2(in4_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 3), + SENSOR_ATTR_2(in4_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 3), + SENSOR_ATTR_2(in5_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 4), + SENSOR_ATTR_2(in5_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 4), + SENSOR_ATTR_2(in6_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 5), + SENSOR_ATTR_2(in6_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 5), + SENSOR_ATTR_2(in7_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 6), + SENSOR_ATTR_2(in7_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 6), + SENSOR_ATTR_2(in8_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 7), + SENSOR_ATTR_2(in8_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 7), + SENSOR_ATTR_2(in9_input, 0444, aaeon_show_sensor, NULL, + SENSOR_VOLTAGE_NUMBER, 8), + SENSOR_ATTR_2(in9_label, 0444, aaeon_show_sensor_name, NULL, + SENSOR_VOLTAGE_NUMBER, 8), + +}; + +static struct sensor_device_attribute_2 info_sys_nodes_atts[] = { + /* WMI version Information */ + SENSOR_ATTR_2(AAEON_VERSION, 0444, aaeon_show_version, NULL, 0, 0), +}; + +DEVICE_ATTR_RO(name); +static ssize_t name_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf, "%s\n", DRVNAME); +} + +static ssize_t aaeon_show_version(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + struct aaeon_hwmon_data *data = + (struct aaeon_hwmon_data *)dev_get_drvdata(dev); + + return sprintf(buf, "%d\n", data->bfpi_version); +} + +static ssize_t aaeon_show_sensor_name(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + u8 nr = to_sensor_dev_attr_2(devattr)->nr; + u8 index = to_sensor_dev_attr_2(devattr)->index; + struct aaeon_hwmon_data *data = + (struct aaeon_hwmon_data *)dev_get_drvdata(dev); + + if (nr > SENSOR_MAX_NUMBER || index >= data->sensors_number[nr]) { + pr_debug("Can not check the device"); + return -1; + } + + switch (nr) { + case SENSOR_TEMP_NUMBER: + return sprintf(buf, "%s\n", data->temp_names[index]); + case SENSOR_FAN_NUMBER: + return sprintf(buf, "%s\n", data->fan_names[index]); + case SENSOR_VOLTAGE_NUMBER: + return sprintf(buf, "%s\n", data->voltage_names[index]); + default: + break; + } + + return 0; +} + +static ssize_t aaeon_show_sensor(struct device *dev, + struct device_attribute *devattr, char *buf) +{ + u8 nr = to_sensor_dev_attr_2(devattr)->nr; + u8 index = to_sensor_dev_attr_2(devattr)->index; + u32 dev_id; + int retval, err; + struct aaeon_hwmon_data *data = + (struct aaeon_hwmon_data *)dev_get_drvdata(dev); + + if (nr > SENSOR_MAX_NUMBER || index >= data->sensors_number[nr]) { + pr_debug("Can not check the device"); + return -1; + } + + /* For the V3 version, index need offset */ + if (data->bfpi_version == 0x03 && nr != SENSOR_VOLTAGE_NUMBER) + index++; + + dev_id = (index << 12) | (nr << 8); + err = asus_wmi_evaluate_method(HWM_METHOD_ID, dev_id, 0, &retval); + if (err) + return err; + + /* For the V3 version, need to convert the raw value*/ + if (nr == SENSOR_VOLTAGE_NUMBER && data->bfpi_version == 0x03) { + switch (index) { + case 0: /* VCORE */ + retval = retval * 16; + break; + case 1: /* +5V */ + retval = (retval * 2008) / 50; + break; + case 2: /* AVCC */ + retval = retval * 16; + break; + case 3: /* +3.3V */ + retval = retval * 16; + break; + case 4: /* +12V */ + retval = retval * 96; + break; + case 5: /* VCOREREFIN */ + retval = (retval * 552) / 41; + break; + case 6: /* VIN4 */ + retval = retval * 8; + break; + case 7: /* 3VSB */ + retval = retval * 16; + break; + case 8: /* VBAT */ + retval = retval * 16; + break; + default: + break; + } + } else if (nr == SENSOR_TEMP_NUMBER && data->bfpi_version == 0x03) + retval = retval * 1000; + + return sprintf(buf, "%d\n", retval); +} + +static int aaeon_hwmon_create_sub_sysfs_fs(struct platform_device *pdev, + struct sensor_device_attribute_2 *attr, + int sensor_number, + u32 sensor_mask, + int bfpi_version) +{ + int i, err = 0; + + for (i = 0; i < sensor_number; i++) { + if (bfpi_version == 0x03 || sensor_mask & BIT(i)) { + err = device_create_file(&pdev->dev, &attr[2 * i].dev_attr); + if (err) + break; + err = device_create_file(&pdev->dev, &attr[2 * i + 1].dev_attr); + if (err) + break; + } + } + + return err; +} + +static int +aaeon_hwmon_create_sysfs_files(struct platform_device *pdev, struct aaeon_hwmon_data *data) +{ + int err; + + /* register sysfs interface files */ + err = device_create_file(&pdev->dev, &dev_attr_name); + if (err) + return err; + + /* registe sysfs to dump sensors BFPI version */ + err = device_create_file(&pdev->dev, &info_sys_nodes_atts[0].dev_attr); + if (err) + return err; + + /* create temperature name and value node */ + err = aaeon_hwmon_create_sub_sysfs_fs(pdev, temp_sys_nodes_atts, + data->sensors_number[SENSOR_TEMP_NUMBER], + data->temp_bitmap, data->bfpi_version); + if (err) + return err; + + /* create fan name and value node */ + err = aaeon_hwmon_create_sub_sysfs_fs(pdev, fan_sys_nodes_atts, + data->sensors_number[SENSOR_FAN_NUMBER], + data->fan_bitmap, data->bfpi_version); + if (err) + return err; + + /* create voltage name and value node */ + err = aaeon_hwmon_create_sub_sysfs_fs(pdev, voltage_sys_nodes_atts, + data->sensors_number[SENSOR_VOLTAGE_NUMBER], + data->voltage_bitmap, data->bfpi_version); + if (err) + return err; + + return 0; +} + +static void aaeon_hwmon_remove_sub_sysfs_fs(struct platform_device *pdev, + struct sensor_device_attribute_2 *attr, + int sensor_number, + u32 sensor_mask, + int bfpi_version) +{ + int i; + + for (i = 0; i < sensor_number; i++) { + if (bfpi_version == 0x03 || sensor_mask & BIT(i)) { + device_remove_file(&pdev->dev, &attr[2 * i].dev_attr); + device_remove_file(&pdev->dev, &attr[2 * i + 1].dev_attr); + } + } +} + +static void +aaeon_hwmon_remove_sysfs_files(struct platform_device *pdev, + struct aaeon_hwmon_data *data) +{ + /* degister sysfs interface files */ + device_remove_file(&pdev->dev, &dev_attr_name); + + /* degiste sysfs to dump sensors BFPI version */ + device_remove_file(&pdev->dev, &info_sys_nodes_atts[0].dev_attr); + + /* remove temperature name and value node */ + aaeon_hwmon_remove_sub_sysfs_fs(pdev, temp_sys_nodes_atts, + data->sensors_number[SENSOR_TEMP_NUMBER], + data->temp_bitmap, + data->bfpi_version); + + /* remove fan name and value node */ + aaeon_hwmon_remove_sub_sysfs_fs(pdev, fan_sys_nodes_atts, + data->sensors_number[SENSOR_FAN_NUMBER], + data->fan_bitmap, + data->bfpi_version); + + /* remove voltage name and value node */ + aaeon_hwmon_remove_sub_sysfs_fs(pdev, voltage_sys_nodes_atts, + data->sensors_number[SENSOR_VOLTAGE_NUMBER], + data->voltage_bitmap, + data->bfpi_version); +} + +static int aaeon_hwmon_remove(struct platform_device *pdev) +{ + struct aaeon_hwmon_data *data = platform_get_drvdata(pdev); + + if (data->hwmon_dev) + hwmon_device_unregister(data->hwmon_dev); + + aaeon_hwmon_remove_sysfs_files(pdev, data); + + return 0; +} + +static int aaeon_get_version(void) +{ + int err, retval; + u32 dev_id = 0x00; + + err = asus_wmi_evaluate_method(AAEON_VERSION_METHOD_ID, dev_id, 0, + &retval); + if (err) + return err; + + return retval; +} + +static int aaeon_hwmon_init_drv_data(struct aaeon_hwmon_data *data) +{ + int err; + + data->bfpi_version = aaeon_get_version(); + if (data->bfpi_version < 0) { + pr_debug("Error BFPI verion\n"); + return -1; + } + + if (data->bfpi_version == 0x03) { + /* set the number of bits in temp bitmap */ + data->sensors_number[SENSOR_TEMP_NUMBER] = + ARRAY_SIZE(temp_sensors_name_table_V3); + data->temp_names = temp_sensors_name_table_V3; + + /* set the number of bits in fan bitmap */ + data->sensors_number[SENSOR_FAN_NUMBER] = + ARRAY_SIZE(fan_sensors_name_table_V3); + data->fan_names = fan_sensors_name_table_V3; + + /* set the number of bits in voltage bitmap */ + data->sensors_number[SENSOR_VOLTAGE_NUMBER] = + ARRAY_SIZE(voltage_sensors_name_table_V3); + data->voltage_names = voltage_sensors_name_table_V3; + } else { + /* set the number of bits in temp bitmap */ + data->sensors_number[SENSOR_TEMP_NUMBER] = + ARRAY_SIZE(temp_sensors_name_table); + data->temp_names = temp_sensors_name_table; + + /* set the number of bits in fan bitmap */ + data->sensors_number[SENSOR_FAN_NUMBER] = + ARRAY_SIZE(fan_sensors_name_table); + data->fan_names = fan_sensors_name_table; + + /* set the number of bits in voltage bitmap */ + data->sensors_number[SENSOR_VOLTAGE_NUMBER] = + ARRAY_SIZE(voltage_sensors_name_table); + data->voltage_names = voltage_sensors_name_table; + } + + /* get temp supported bitmap */ + err = asus_wmi_evaluate_method(HWM_INFORMATION_METHOD_ID, + BITMAP_TEMP_ARG, 0, &data->temp_bitmap); + if (err) + return err; + + /* get fan supported bitmap */ + err = asus_wmi_evaluate_method(HWM_INFORMATION_METHOD_ID, + BITMAP_FAN_ARG, 0, &data->fan_bitmap); + if (err) + return err; + + /* get voltage supported bitmap */ + err = asus_wmi_evaluate_method(HWM_INFORMATION_METHOD_ID, + BITMAP_VOLTAGE_ARG, 0, &data->voltage_bitmap); + if (err) + return err; + + return 0; +} + +static int aaeon_hwmon_probe(struct platform_device *pdev) +{ + int err; + struct aaeon_hwmon_data *data; + + pr_debug("aaeon hwomon device probe (support V3)!\n"); + if (!wmi_has_guid(AAEON_WMI_MGMT_GUID)) { + pr_info("AAEON Management GUID not found\n"); + return -ENODEV; + } + + data = devm_kzalloc(&pdev->dev, sizeof(struct aaeon_hwmon_data), + GFP_KERNEL); + if (!data) + return -ENOMEM; + + err = aaeon_hwmon_init_drv_data(data); + if (err) { + pr_info("Error to get sensor support bitmap\n"); + goto exit; + } + + if (data->bfpi_version != 0x03 && data->temp_bitmap == 0 && + data->fan_bitmap == 0 && data->voltage_bitmap == 0) { + pr_debug("No sensors found\n"); + err = -ENODEV; + goto exit; + } + + platform_set_drvdata(pdev, data); + err = aaeon_hwmon_create_sysfs_files(pdev, data); + if (err) + goto exit; + + data->hwmon_dev = devm_hwmon_device_register_with_info(&pdev->dev, + "AAEON_HWM", + data, + NULL, + NULL); + if (IS_ERR(data->hwmon_dev)) { + err = PTR_ERR(data->hwmon_dev); + data->hwmon_dev = NULL; + goto exit_unregister_sysfs; + } + + return 0; + +exit_unregister_sysfs: + aaeon_hwmon_remove(pdev); +exit: + return err; +} + +static struct platform_driver aaeon_hwmon_driver = { + .driver = { + .name = DRVNAME, + .owner = THIS_MODULE, + }, + .probe = aaeon_hwmon_probe, + .remove = aaeon_hwmon_remove, +}; + +module_platform_driver_probe(aaeon_hwmon_driver, aaeon_hwmon_probe); + +MODULE_ALIAS("platform:hwmon-aaeon"); +MODULE_DESCRIPTION("AAEON Hardware Monitoring Driver"); +MODULE_AUTHOR("Edward Lin "); +MODULE_AUTHOR("Kunyang Fan "); +MODULE_LICENSE("GPL v2"); From patchwork Wed Jun 16 05:56:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492709 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=LOWR7gFn; 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 4G4ZGP3xpvz9sSn; Wed, 16 Jun 2021 15:57:33 +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 1ltOYM-0005UB-8B; Wed, 16 Jun 2021 05:57:30 +0000 Received: from mail-pg1-f177.google.com ([209.85.215.177]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOYJ-0005PT-Ed for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:27 +0000 Received: by mail-pg1-f177.google.com with SMTP id e33so1091485pgm.3 for ; Tue, 15 Jun 2021 22:57:24 -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=9s1E3LwKXcNhwl2RvqOCLNZJ0zMEBFUDkZ4pFfM9Z68=; b=LOWR7gFn3uyvAbE6rGNooDWqtatO6yC6V24XKww4FXttpiPWaFYZGbN18EO+gvc0bd Q78cv7TpSvmO/oLrs0Str2WD/cCgBwjb+scn2XK4El9j/poLjaMlQLmwIQcNVpxT3wfM FDVn3apHVp/wJH/zPg9WFsAx/+Enyp/vgeg5G6BAq3vZt/lUaSATJmliZ/u0E0TRgRfg Etg2N4+y0uypnWIRxI/mTAesi9SrM4JJbU/h2ar20OxlGL69U4sEa/k1Mv/At2yQ5ut1 fnHHPttQUiHwUG6LuuC4pt5gOyIXdrSfWuRlw88i1n7VrzqYB8Xu0Q4KZXoFMXrnhY4y BoHg== 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=9s1E3LwKXcNhwl2RvqOCLNZJ0zMEBFUDkZ4pFfM9Z68=; b=AiOCJtGEmzzD+xBgNWa/lffOlsgt32pTg5hvvKpnYjPfaweKiQRpKr2d7QTo7G2MMH 66noB2HdrjYpEjZsjG+nIxy8/0hM5VUcaocpS//aoj6bz+mHGJeK8h5qFvw9ILsRe79b 80BFB/tuUYh7T8RrS0Nw8z3FJ44YhLm4e2Od+9WldPgfdmiRkN9Qaz4UMJuQlMaMUkiJ KfVtuhE3bmnTKbS0Swcy6wOXUJyPYxqH87Gx1Ba+1BfZxYuMAODV+T+wuDbkUaNfiIIf Ztu8e2YtrM5DWe7PWqDc1+2sOWwnkhjI/y8zWdkaZDo2Lq4+Y9i6NlREFApINwI9bBC+ 8ApA== X-Gm-Message-State: AOAM532EyMcAsuCQ9Xc9akX0ufurvt1/oifeHm4CqkTpvLiWLxcUBQ8T MCH2e/hYbEkj6OLTuPlOKVmc6jYTDE8= X-Google-Smtp-Source: ABdhPJzajVXiQVnUMByqltZBF2SS37Pi9MdQelunLFbsJyAAOUID31hyvUGROKCQSs+Ry0C1vMKfow== X-Received: by 2002:aa7:83c3:0:b029:2e8:f2ba:3979 with SMTP id j3-20020aa783c30000b02902e8f2ba3979mr7997714pfn.8.1623823042207; Tue, 15 Jun 2021 22:57:22 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id q145sm867580pfc.60.2021.06.15.22.57.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:21 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 5/6][SRU][G] UBUNTU: ODM: leds: add driver for AAEON devices Date: Wed, 16 Jun 2021 13:56:50 +0800 Message-Id: <20210616055703.124039-6-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.215.177; envelope-from=acelan@gmail.com; helo=mail-pg1-f177.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 adds support for the led devices which can be controlled from sysfs 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/leds/Kconfig | 12 ++++ drivers/leds/Makefile | 1 + drivers/leds/leds-aaeon.c | 142 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 drivers/leds/leds-aaeon.c diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index be4536eef1fe..cc795d9762f8 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -49,6 +49,18 @@ config LEDS_88PM860X This option enables support for on-chip LED drivers found on Marvell Semiconductor 88PM8606 PMIC. +config LEDS_AAEON + tristate "AAEON LED driver" + depends on X86 + depends on UBUNTU_ODM_DRIVERS + select MFD_AAEON + help + This led driver adds support for LED brightness control on Single + Board Computers produced by AAEON. + + This driver leverages the ASUS WMI interface to access device + resources. + config LEDS_AAT1290 tristate "LED support for the AAT1290" depends on LEDS_CLASS_FLASH diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index d6b8a792c936..a8a77acc5e11 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_LEDS_TRIGGERS) += led-triggers.o # LED Platform Drivers (keep this sorted, M-| sort) obj-$(CONFIG_LEDS_88PM860X) += leds-88pm860x.o +obj-$(CONFIG_LEDS_AAEON) += leds-aaeon.o obj-$(CONFIG_LEDS_AAT1290) += leds-aat1290.o obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o obj-$(CONFIG_LEDS_AN30259A) += leds-an30259a.o diff --git a/drivers/leds/leds-aaeon.c b/drivers/leds/leds-aaeon.c new file mode 100644 index 000000000000..10090a4bff65 --- /dev/null +++ b/drivers/leds/leds-aaeon.c @@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AAEON LED driver + * + * Copyright (c) 2021, AAEON Ltd. + * + * Author: Kunyang Fan + * + * 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 + +#define DRVNAME "led_aaeon" +#define ASUS_NB_WMI_EVENT_GUID "0B3CBB35-E3C2-45ED-91C2-4C5A6D195D1C" +#define AAEON_WMI_MGMT_GUID "97845ED0-4E6D-11DE-8A39-0800200C9A66" + +#define GET_LED_NUMBER_ID 0x00060000 +#define GET_LED_METHOD_ID 0x00060001 +#define SET_LED_METHOD_ID 0x00060002 +#define GET_LED_NUMBER_METHOD_ID 0x10 + + +struct aaeon_led_data { + int id; + struct led_classdev cdev; +}; + +static int aaeon_led_get_number(void) +{ + int err, retval; + + err = asus_wmi_evaluate_method(GET_LED_NUMBER_ID, + GET_LED_NUMBER_METHOD_ID, + 0, &retval); + if (err) + return err; + + return retval; +} + +static enum led_brightness aaeon_led_brightness_get(struct led_classdev + *cdev) +{ + int err, brightness; + struct aaeon_led_data *led = + container_of(cdev, struct aaeon_led_data, cdev); + u32 arg0; + + arg0 = (u32)(led->id & 0xF); + err = asus_wmi_evaluate_method(GET_LED_METHOD_ID, arg0, 0, &brightness); + if (err) + return err; + + return brightness; +}; + +static void aaeon_led_brightness_set(struct led_classdev *cdev, + enum led_brightness brightness) +{ + int err, retval; + struct aaeon_led_data *led = + container_of(cdev, struct aaeon_led_data, cdev); + u32 arg0; + + arg0 = (u32)(led->id & 0xF); + if (brightness != LED_OFF) + arg0 |= BIT(16); + + err = asus_wmi_evaluate_method(SET_LED_METHOD_ID, arg0, 0, &retval); +}; + +static int __init aaeon_add_led_device(struct platform_device *pdev, + int id) +{ + struct aaeon_led_data *led; + + led = devm_kzalloc(&pdev->dev, sizeof(struct aaeon_led_data), GFP_KERNEL); + if (!led) + return -ENOMEM; + + led->id = id; + led->cdev.brightness_get = aaeon_led_brightness_get; + led->cdev.brightness_set = aaeon_led_brightness_set; + led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "led:%d:", id); + + if (!led->cdev.name) + return -ENOMEM; + + return devm_led_classdev_register(&pdev->dev, &led->cdev); +} + +static int aaeon_led_probe(struct platform_device *pdev) +{ + int err = -ENODEV, i; + int led_number = 0; + + pr_debug("aaeon led device probe!\n"); + /* 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; + } + + /* Query the number of led devices board support */ + led_number = aaeon_led_get_number(); + + /* + * If the number is 0 or can't get the number of leds, + * no need to register any led device node. + */ + if (led_number <= 0) + return -ENODEV; + + for (i = 0; i < led_number; i++) { + err = aaeon_add_led_device(pdev, i); + if (err) + break; + } + + return err; +} + +static struct platform_driver aaeon_led_driver = { + .driver = { + .name = "leds-aaeon", + }, +}; + +module_platform_driver_probe(aaeon_led_driver, aaeon_led_probe); + +MODULE_ALIAS("platform:leds-aaeon"); +MODULE_DESCRIPTION("AAEON LED Driver"); +MODULE_AUTHOR("Kunyang Fan "); +MODULE_LICENSE("GPL v2"); From patchwork Wed Jun 16 05:56:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: AceLan Kao X-Patchwork-Id: 1492710 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=Ki/Ethgu; 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 4G4ZGS73DFz9sX2; Wed, 16 Jun 2021 15:57:36 +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 1ltOYP-0005X0-Cb; Wed, 16 Jun 2021 05:57:33 +0000 Received: from mail-pj1-f52.google.com ([209.85.216.52]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1ltOYK-0005RO-1l for kernel-team@lists.ubuntu.com; Wed, 16 Jun 2021 05:57:28 +0000 Received: by mail-pj1-f52.google.com with SMTP id x21-20020a17090aa395b029016e25313bfcso1103178pjp.2 for ; Tue, 15 Jun 2021 22:57:27 -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=JJ8UIRE4tdSnxSgwyYW3CYPjWhyu67HRMXxXmEqeTx4=; b=Ki/EthguRdxuTD7jsvrjn2T4RQ1oV3THU8fr+qbC6mTQ/RaPNznI4FNzKzu47AqqAG vmRbwkjXDRe4WNVEQU6y9E3ylM1yWUlbq50iM5iUIiTqIxWdqZEya8ss/4xwRSlg7QrT cyCDwzqj5Y5MOQSf+GkvBnl34NjGgZWkNOYJ2P65yiGH7z3z8n9Nlmu+CmCqP1aCJY9M n8lhVwsQdPInT0rAydjB4qJ6UlfXow7iJ9kEXE4WyrtrFpzY3xeXQvQXBcfu/YDANBZf pJkrua5X01NnxzvPPcMQhadunZCMLeDHBxcrTdPKrJcOsc31B6G6xqkO1aW8nnn/Q2gZ GfMA== 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=JJ8UIRE4tdSnxSgwyYW3CYPjWhyu67HRMXxXmEqeTx4=; b=lH74BS0MZ8b5PcJSnACQiWIVQ7O/yXcOZyUaK3sBZkc3xxsnbUhR2vhBUbq2pUKbUN nKOn9Y4cTRX54CqnJKPqqe998QpTcMuZmcIczgC9ZrPPcpLk8mmHAS/I3SS2GML+AJkX tVdD7eEmT1GnuvlYlmQwdkQv2Y6hTr3UADW4sTvWCB5YKtMbAMtsi1COKiR8kRfkJ9zA H2aeiAUSC7xIV0JhcWCY3PogDADifuM+/Ik6gi18S8Do8lpx9zDuOw0iPFBlGvy1xk+N AWQWaAshelBfErhrzc48imGle/rM/JyvWZuLuLi0mC7ENscelxDjG85waTurmhlEU5IY gVPA== X-Gm-Message-State: AOAM533zZHLoPUx6Eqk92HezL2ZgShCVDljGSi6cUKa9lGJ089RNV7lQ +vf1HhBaSgn1kvqgixSANzOR0DO27lc= X-Google-Smtp-Source: ABdhPJwck6VkCisYk8ITARkqG3AZp5SMK0mliwDRFOloZKccxvMgamsYN4lJJQJil7mxAFXAT8KJgg== X-Received: by 2002:a17:90a:6402:: with SMTP id g2mr3219455pjj.82.1623823044868; Tue, 15 Jun 2021 22:57:24 -0700 (PDT) Received: from localhost (61-220-137-34.HINET-IP.hinet.net. [61.220.137.34]) by smtp.gmail.com with ESMTPSA id w23sm876493pfi.220.2021.06.15.22.57.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 15 Jun 2021 22:57:24 -0700 (PDT) From: AceLan Kao To: kernel-team@lists.ubuntu.com, Kunyang_Fan Subject: [RESEND][PATCH 6/6][SRU][G] UBUNTU: ODM: [Config] update config for AAEON devices Date: Wed, 16 Jun 2021 13:56:51 +0800 Message-Id: <20210616055703.124039-7-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.216.52; envelope-from=acelan@gmail.com; helo=mail-pj1-f52.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: "Chia-Lin Kao (AceLan)" BugLink: https://bugs.launchpad.net/bugs/1929504 Signed-off-by: Chia-Lin Kao (AceLan) --- debian.master/config/config.common.ubuntu | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/debian.master/config/config.common.ubuntu b/debian.master/config/config.common.ubuntu index 1cdb812a9d72..9c5dbf1f9a86 100644 --- a/debian.master/config/config.common.ubuntu +++ b/debian.master/config/config.common.ubuntu @@ -33,6 +33,7 @@ CONFIG_9P_FS=m CONFIG_9P_FSCACHE=y CONFIG_9P_FS_POSIX_ACL=y CONFIG_9P_FS_SECURITY=y +CONFIG_AAEON_IWMI_WDT=m CONFIG_AB3100_CORE=y CONFIG_AB3100_OTP=m CONFIG_ABP060MG=m @@ -3703,6 +3704,7 @@ CONFIG_GPIO_104_IDIO_16=m CONFIG_GPIO_104_IDI_48=m CONFIG_GPIO_74X164=m CONFIG_GPIO_74XX_MMIO=m +CONFIG_GPIO_AAEON=m CONFIG_GPIO_ACPI=y CONFIG_GPIO_ADNP=m CONFIG_GPIO_ADP5520=m @@ -5291,6 +5293,7 @@ CONFIG_LDISC_AUTOLOAD=y # CONFIG_LD_HEAD_STUB_CATCH is not set CONFIG_LD_VERSION=235010000 CONFIG_LEDS_88PM860X=m +CONFIG_LEDS_AAEON=m CONFIG_LEDS_AAT1290=m CONFIG_LEDS_ADP5520=m CONFIG_LEDS_AN30259A=m @@ -5718,6 +5721,7 @@ CONFIG_MESON_SM=y CONFIG_MESON_WATCHDOG=m CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4 CONFIG_MFD_88PM860X=y +CONFIG_MFD_AAEON=m CONFIG_MFD_AAT2870_CORE=y # CONFIG_MFD_AC100 is not set CONFIG_MFD_ACT8945A=m @@ -8784,6 +8788,7 @@ CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init" CONFIG_SECURITY_YAMA=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_SENSIRION_SGP30=m +CONFIG_SENSORS_AAEON=m CONFIG_SENSORS_ABITUGURU=m CONFIG_SENSORS_ABITUGURU3=m CONFIG_SENSORS_ACPI_POWER=m