From patchwork Wed Jul 31 17:52:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068979 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8954F13B1 for ; Wed, 31 Jul 2019 17:53:34 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7137926B41 for ; Wed, 31 Jul 2019 17:53:34 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 62AAC26E4F; Wed, 31 Jul 2019 17:53:34 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6784D26B41 for ; Wed, 31 Jul 2019 17:53:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729900AbfGaRxX (ORCPT ); Wed, 31 Jul 2019 13:53:23 -0400 Received: from mail-yb1-f193.google.com ([209.85.219.193]:41258 "EHLO mail-yb1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728083AbfGaRxX (ORCPT ); Wed, 31 Jul 2019 13:53:23 -0400 Received: by mail-yb1-f193.google.com with SMTP id x188so2569534yba.8; Wed, 31 Jul 2019 10:53:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=keTu6I6tlBnNCh2Upxogp/wWzBQIcKt48FGiqp4KVvM=; b=NIBbKay4tXfjMx48Zim8dxneOLkbUkQiFnb1ibkq9Oxyeh5nU3efrjM9IzFl4EpG9y n5m9hjP6JhkgajfKO5cAuW7qPYXzVgVOiUxjnCED08R1afcxLF8Akf0ZuAEdS33jI2lR 2EQVyNpKgoLubFqAuM6XampltZWnM648558JUjPdkj3DNPk3a7NJSCmZ0CNa8yXjj7Pq p6aoB8zBDY/7FxXN2zYjOP/z07u4jIWs6JR+rjW7KnAPP6wqVy1QbS0UDVKrOBMOCh+7 wd66bxK/x3rrE+eE4lb9TydmYPEMv+3GAw8J2G1JlLjO2/oEvKxAY73IjszTk883ASCY hqIA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=keTu6I6tlBnNCh2Upxogp/wWzBQIcKt48FGiqp4KVvM=; b=dMa1KKR8188B85vmAlH1r7NpHKfvQVJsr/yYZDxgq5hXbNL9EQOOdKezh/CCt/nOVY Q5GD1iggyZNarsyrgxJ0r7tA2IzDD1DfKCq6Qd1T6SVyv329Qlag5SILGgCqxaY/l81B 8h6nVzj8NnN4v1S1dwqTR9tC45lVRceqn9la9G+j9BXuCnQMBxEZE5sAiPL21jF4Ik3A DAsrnQPOS0Qdga+bZDMQimM7y1zadS+t/vNO+eABYkeajqVS9K4XG/5kv2qJUC8rumGA Za+Dg1b6dVD65xfBHWYbxHiD89a4rDv5qL99DTH4zTAy93yKSrlYfh8asP++knX9FAZJ E8bg== X-Gm-Message-State: APjAAAWe1J98XlpQ8Vk0ND3XpiMtd5q07Cz7tRA54M0nONeS+0IybR1H 5nfhUCvWGBJP+HfwFw4e0A== X-Google-Smtp-Source: APXvYqzSUYsonBNSknu9swcftjZ8WHgXVTVDy/BOoDqPiW+eGU9Zls2sGzI11t7Leycn6iKh7bZ77w== X-Received: by 2002:a25:2a4f:: with SMTP id q76mr75726008ybq.322.1564595602543; Wed, 31 Jul 2019 10:53:22 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.21 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:22 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 2/9] platform/x86: huawei-wmi: Move to platform driver Date: Wed, 31 Jul 2019 13:52:48 -0400 Message-Id: <20190731175255.25676-3-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Move from WMI driver to platform driver. This move is necessary since the driver is no longer a hotkeys driver only. Platform driver makes it easier for users to access sysfs attributes under (i.e. /sys/devices/platform/huawei-wmi) compared to wmi driver. Signed-off-by: Ayman Bagabas --- Do you think we should stick to wmi driver especially after "platform/x86: wmi: add context pointer field to struct wmi_device_id" https://patchwork.kernel.org/patch/10963421/ which is basically was my issue with wmi driver where there wasn't a way to distinguish what wmi device is associated with which guid. I believe that platform driver is more suitable for this since it has grown from just a hotkeys driver and users can access sysfs of this easily with platform driver. What do you think? drivers/platform/x86/huawei-wmi.c | 152 +++++++++++++++++++++--------- 1 file changed, 110 insertions(+), 42 deletions(-) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index a1159850a16c..12cae450fc1f 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -10,6 +10,7 @@ #include #include #include +#include #include /* @@ -23,12 +24,15 @@ struct huawei_wmi_priv { - struct input_dev *idev; + struct input_dev *idev[2]; struct led_classdev cdev; acpi_handle handle; char *acpi_method; + struct platform_device *pdev; }; +struct platform_device *huawei_wmi_pdev; + static const struct key_entry huawei_wmi_keymap[] = { { KE_KEY, 0x281, { KEY_BRIGHTNESSDOWN } }, { KE_KEY, 0x282, { KEY_BRIGHTNESSUP } }, @@ -46,6 +50,8 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_END, 0 } }; +/* LEDs */ + static int huawei_wmi_micmute_led_set(struct led_classdev *led_cdev, enum led_brightness brightness) { @@ -77,9 +83,9 @@ static int huawei_wmi_micmute_led_set(struct led_classdev *led_cdev, return 0; } -static int huawei_wmi_leds_setup(struct wmi_device *wdev) +static int huawei_wmi_leds_setup(struct device *dev) { - struct huawei_wmi_priv *priv = dev_get_drvdata(&wdev->dev); + struct huawei_wmi_priv *priv = dev_get_drvdata(dev); priv->handle = ec_get_handle(); if (!priv->handle) @@ -97,15 +103,16 @@ static int huawei_wmi_leds_setup(struct wmi_device *wdev) priv->cdev.brightness_set_blocking = huawei_wmi_micmute_led_set; priv->cdev.default_trigger = "audio-micmute"; priv->cdev.brightness = ledtrig_audio_get(LED_AUDIO_MICMUTE); - priv->cdev.dev = &wdev->dev; + priv->cdev.dev = dev; priv->cdev.flags = LED_CORE_SUSPENDRESUME; - return devm_led_classdev_register(&wdev->dev, &priv->cdev); + return devm_led_classdev_register(dev, &priv->cdev); } -static void huawei_wmi_process_key(struct wmi_device *wdev, int code) +/* Input */ + +static void huawei_wmi_process_key(struct input_dev *idev, int code) { - struct huawei_wmi_priv *priv = dev_get_drvdata(&wdev->dev); const struct key_entry *key; /* @@ -129,81 +136,142 @@ static void huawei_wmi_process_key(struct wmi_device *wdev, int code) kfree(response.pointer); } - key = sparse_keymap_entry_from_scancode(priv->idev, code); + key = sparse_keymap_entry_from_scancode(idev, code); if (!key) { - dev_info(&wdev->dev, "Unknown key pressed, code: 0x%04x\n", code); + dev_info(&idev->dev, "Unknown key pressed, code: 0x%04x\n", code); return; } - sparse_keymap_report_entry(priv->idev, key, 1, true); + sparse_keymap_report_entry(idev, key, 1, true); } -static void huawei_wmi_notify(struct wmi_device *wdev, - union acpi_object *obj) +static void huawei_wmi_input_notify(u32 value, void *context) { - if (obj->type == ACPI_TYPE_INTEGER) - huawei_wmi_process_key(wdev, obj->integer.value); + struct input_dev *idev = (struct input_dev *)context; + struct acpi_buffer response = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *obj; + acpi_status status; + + status = wmi_get_event_data(value, &response); + if (ACPI_FAILURE(status)) { + dev_err(&idev->dev, "Unable to get event data\n"); + return; + } + + obj = (union acpi_object *)response.pointer; + if (obj && obj->type == ACPI_TYPE_INTEGER) + huawei_wmi_process_key(idev, obj->integer.value); else - dev_info(&wdev->dev, "Bad response type %d\n", obj->type); + dev_err(&idev->dev, "Bad response type\n"); + + kfree(response.pointer); } -static int huawei_wmi_input_setup(struct wmi_device *wdev) +static int huawei_wmi_input_setup(struct device *dev, + struct input_dev **idev) { - struct huawei_wmi_priv *priv = dev_get_drvdata(&wdev->dev); int err; - priv->idev = devm_input_allocate_device(&wdev->dev); - if (!priv->idev) + *idev = devm_input_allocate_device(dev); + if (!*idev) return -ENOMEM; - priv->idev->name = "Huawei WMI hotkeys"; - priv->idev->phys = "wmi/input0"; - priv->idev->id.bustype = BUS_HOST; - priv->idev->dev.parent = &wdev->dev; + (*idev)->name = "Huawei WMI hotkeys"; + (*idev)->phys = "wmi/input0"; + (*idev)->id.bustype = BUS_HOST; + (*idev)->dev.parent = dev; - err = sparse_keymap_setup(priv->idev, huawei_wmi_keymap, NULL); + err = sparse_keymap_setup(*idev, huawei_wmi_keymap, NULL); if (err) return err; - return input_register_device(priv->idev); + return input_register_device(*idev); } -static int huawei_wmi_probe(struct wmi_device *wdev, const void *context) +/* Huawei driver */ + +static int huawei_wmi_probe(struct platform_device *pdev) { struct huawei_wmi_priv *priv; int err; - priv = devm_kzalloc(&wdev->dev, sizeof(struct huawei_wmi_priv), GFP_KERNEL); + priv = devm_kzalloc(&pdev->dev, sizeof(struct huawei_wmi_priv), GFP_KERNEL); if (!priv) return -ENOMEM; - dev_set_drvdata(&wdev->dev, priv); + priv->pdev = pdev; + dev_set_drvdata(&pdev->dev, priv); + + if (wmi_has_guid(WMI0_EVENT_GUID)) { + err = huawei_wmi_input_setup(&pdev->dev, &priv->idev[0]) || + wmi_install_notify_handler(WMI0_EVENT_GUID, + huawei_wmi_input_notify, priv->idev[0]); + if (err) { + dev_err(&pdev->dev, "Failed to setup input device\n"); + return err; + } + } - err = huawei_wmi_input_setup(wdev); - if (err) - return err; + if (wmi_has_guid(HWMI_EVENT_GUID)) { + err = huawei_wmi_input_setup(&pdev->dev, &priv->idev[1]) || + wmi_install_notify_handler(HWMI_EVENT_GUID, + huawei_wmi_input_notify, priv->idev[1]); + if (err) { + dev_err(&pdev->dev, "Failed to setup input device\n"); + return err; + } + } - return huawei_wmi_leds_setup(wdev); + return huawei_wmi_leds_setup(&pdev->dev); } -static const struct wmi_device_id huawei_wmi_id_table[] = { - { .guid_string = WMI0_EVENT_GUID }, - { .guid_string = HWMI_EVENT_GUID }, - { } -}; +static int huawei_wmi_remove(struct platform_device *pdev) +{ + if (wmi_has_guid(WMI0_EVENT_GUID)) + wmi_remove_notify_handler(WMI0_EVENT_GUID); + + if (wmi_has_guid(HWMI_EVENT_GUID)) + wmi_remove_notify_handler(HWMI_EVENT_GUID); -static struct wmi_driver huawei_wmi_driver = { + return 0; +} + +static struct platform_driver huawei_wmi_driver = { .driver = { .name = "huawei-wmi", }, - .id_table = huawei_wmi_id_table, .probe = huawei_wmi_probe, - .notify = huawei_wmi_notify, + .remove = huawei_wmi_remove, }; -module_wmi_driver(huawei_wmi_driver); +static __init int huawei_wmi_init(void) +{ + int err; + + err = platform_driver_register(&huawei_wmi_driver); + if (err) + return err; + + huawei_wmi_pdev = platform_device_register_simple("huawei-wmi", -1, NULL, 0); + if (IS_ERR(huawei_wmi_pdev)) { + platform_driver_unregister(&huawei_wmi_driver); + return PTR_ERR(huawei_wmi_pdev); + } + + return 0; +} + +static __exit void huawei_wmi_exit(void) +{ + platform_device_unregister(huawei_wmi_pdev); + platform_driver_unregister(&huawei_wmi_driver); +} + +module_init(huawei_wmi_init); +module_exit(huawei_wmi_exit); -MODULE_DEVICE_TABLE(wmi, huawei_wmi_id_table); +MODULE_ALIAS("wmi:"WMI0_EVENT_GUID); +MODULE_ALIAS("wmi:"HWMI_EVENT_GUID); MODULE_AUTHOR("Ayman Bagabas "); MODULE_DESCRIPTION("Huawei WMI laptop extras driver"); MODULE_LICENSE("GPL v2"); From patchwork Wed Jul 31 17:52:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068977 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 65A881399 for ; Wed, 31 Jul 2019 17:53:29 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4F6BF26E1A for ; Wed, 31 Jul 2019 17:53:29 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 42F9926E4A; Wed, 31 Jul 2019 17:53:29 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ACCEF26E1A for ; Wed, 31 Jul 2019 17:53:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726469AbfGaRx0 (ORCPT ); Wed, 31 Jul 2019 13:53:26 -0400 Received: from mail-yw1-f68.google.com ([209.85.161.68]:41011 "EHLO mail-yw1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728083AbfGaRxZ (ORCPT ); Wed, 31 Jul 2019 13:53:25 -0400 Received: by mail-yw1-f68.google.com with SMTP id i138so25269678ywg.8; Wed, 31 Jul 2019 10:53:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=kdPbODA0z2TZ5tYy71TYwrIsVN8PGj8ecEakmSP6UzE=; b=vTPOIKUkH6041laPC7baGx/L3DTOzOF/jHi9HXRZA+hCqKelK9HUgyKJQx0Tv0qwo7 4g+K/zvRYtyivGkK5tT8o5eJWaLz266a4GYjAixrnMIFhLz2OeW4fNgPbiEcwvY04yMN oLCdeGejYE0VZ6G/kdnKQg6XO/jIBqbtbtNF40i9+aOL7MdWoKZTOIJWYaEz93+101cV GZ/ADDdV1mn5gxQUUIYrMBG+TCKRXQvOqwBv0FAwf3SvZCPNaggRsRwyreFbv86GEaDD K/rlVFx4SQeOAz7ir0FqnMppfceq62hEQYQKp9Jec5RiB5k2WMaU/0xz1HfgoU11V97Z KQAQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=kdPbODA0z2TZ5tYy71TYwrIsVN8PGj8ecEakmSP6UzE=; b=B1kgj2vt0f580grNiUXf3YV4Gch/tkss8xLl79TF3/+flLPldFJJ0Cf62h5d21o1Rp 60KBScwPDKdxVyLzqCGrusCWQ1HvVC2mIzdk2M9JxyoZ+RcZ9xGj3fyIRv8z8fqiFq1m oWJEwHSbtk/Fvtnog/0ADDIt8rojhwDc/+Tkf509qgZPb8N6uXmuAxikIpVLH5IMd2wC u6KGCxXbIMWTE7zISxWUQvJr8tk6nIu9rizc9MqoWN0G/l2o5bIZnUCnXLKm23zgKp9t fm+XVwiMr4OhHe3lk3eNte+zx5zgkoXnic/FNQCtSlbgYUqg6uL/nP9C9EqvyA1S/VyL 40wA== X-Gm-Message-State: APjAAAWZdSlBlvn6tgXajmaXUYtKZ1B9TN3jfL0OYc/T/q5u/ZDJjtea FTdxEJVgTVMG0QiyayVpZ35irP0= X-Google-Smtp-Source: APXvYqzWs//VXf/O6rc1PgbiaDnArGR2YEtvTtEcwGVVyAIBOoLbgaE6rgwihyNWsO4rqa1oe8mQhg== X-Received: by 2002:a81:230a:: with SMTP id j10mr75078006ywj.259.1564595604273; Wed, 31 Jul 2019 10:53:24 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.23 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:23 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 3/9] platform/x86: huawei-wmi: Implement huawei wmi management interface Date: Wed, 31 Jul 2019 13:52:49 -0400 Message-Id: <20190731175255.25676-4-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Huawei Matebook laptops come with a WMI management interface that can control various aspects of the device. This interface is also found on the old Matebook X released in 2017. Implement basic functionality of this interface along with supported command IDs that are implemented in this series. Signed-off-by: Ayman Bagabas --- drivers/platform/x86/huawei-wmi.c | 130 ++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 12cae450fc1f..27520b0f8956 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -10,24 +10,36 @@ #include #include #include +#include #include #include /* * Huawei WMI GUIDs */ +#define HWMI_METHOD_GUID "ABBC0F5B-8EA1-11D1-A000-C90629100000" #define HWMI_EVENT_GUID "ABBC0F5C-8EA1-11D1-A000-C90629100000" /* Legacy GUIDs */ #define WMI0_EXPENSIVE_GUID "39142400-C6A3-40fa-BADB-8A2652834100" #define WMI0_EVENT_GUID "59142400-C6A3-40fa-BADB-8A2652834100" +/* HWMI commands */ + +enum { + BATTERY_THRESH_GET = 0x00001103, /* \GBTT */ + BATTERY_THRESH_SET = 0x00001003, /* \SBTT */ + FN_LOCK_GET = 0x00000604, /* \GFRS */ + FN_LOCK_SET = 0x00000704, /* \SFRS */ + MICMUTE_LED_SET = 0x00000b04, /* \SMLS */ +}; struct huawei_wmi_priv { struct input_dev *idev[2]; struct led_classdev cdev; acpi_handle handle; char *acpi_method; + struct mutex wmi_lock; struct platform_device *pdev; }; @@ -50,6 +62,116 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_END, 0 } }; +/* Utils */ + +static int huawei_wmi_call(struct device *dev, struct acpi_buffer *in, + struct acpi_buffer *out) +{ + struct huawei_wmi_priv *priv = dev_get_drvdata(dev); + acpi_status status; + + mutex_lock(&priv->wmi_lock); + status = wmi_evaluate_method(HWMI_METHOD_GUID, 0, 1, in, out); + mutex_unlock(&priv->wmi_lock); + if (ACPI_FAILURE(status)) { + dev_err(dev, "Failed to evaluate wmi method\n"); + return -ENODEV; + } + + return 0; +} + +/* HWMI takes a 64 bit input and returns either a package with 2 buffers, one of + * 4 bytes and the other of 256 bytes, or one buffer of size 0x104 (260) bytes. + * The first 4 bytes are ignored, we ignore the first 4 bytes buffer if we got a + * package, or skip the first 4 if a buffer of 0x104 is used. The first byte of + * the remaining 0x100 sized buffer has the return status of every call. In case + * the return status is non-zero, we return -ENODEV but still copy the returned + * buffer to the given buffer parameter (buf). + */ +static int huawei_wmi_cmd(struct device *dev, u64 arg, u8 *buf, size_t buflen) +{ + struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer in; + union acpi_object *obj; + size_t len; + int err, i; + + in.length = sizeof(arg); + in.pointer = &arg; + + /* Some models require calling HWMI twice to execute a command. We evaluate + * HWMI and if we get a non-zero return status we evaluate it again. + */ + for (i = 0; i < 2; i++) { + err = huawei_wmi_call(dev, &in, &out); + if (err) + goto fail_cmd; + + obj = out.pointer; + if (!obj) { + err = -EIO; + goto fail_cmd; + } + + switch (obj->type) { + /* Models that implement both "legacy" and HWMI tend to return a 0x104 + * sized buffer instead of a package of 0x4 and 0x100 buffers. + */ + case ACPI_TYPE_BUFFER: + if (obj->buffer.length == 0x104) { + // Skip the first 4 bytes. + obj->buffer.pointer += 4; + len = 0x100; + } else { + dev_err(dev, "Bad buffer length, got %d\n", obj->buffer.length); + err = -EIO; + goto fail_cmd; + } + + break; + /* HWMI returns a package with 2 buffer elements, one of 4 bytes and the + * other is 256 bytes. + */ + case ACPI_TYPE_PACKAGE: + if (obj->package.count != 2) { + dev_err(dev, "Bad package count, got %d\n", obj->package.count); + err = -EIO; + goto fail_cmd; + } + + obj = &obj->package.elements[1]; + if (obj->type != ACPI_TYPE_BUFFER) { + dev_err(dev, "Bad package element type, got %d\n", obj->type); + err = -EIO; + goto fail_cmd; + } + len = obj->buffer.length; + + break; + /* Shouldn't get here! */ + default: + dev_err(dev, "Unexpected obj type, got: %d\n", obj->type); + err = -EIO; + goto fail_cmd; + } + + if (!*obj->buffer.pointer) + break; + } + + err = (*obj->buffer.pointer) ? -ENODEV : 0; + + if (buf) { + len = min(buflen, len); + memcpy(buf, obj->buffer.pointer, len); + } + +fail_cmd: + kfree(out.pointer); + return err; +} + /* LEDs */ static int huawei_wmi_micmute_led_set(struct led_classdev *led_cdev, @@ -222,6 +344,10 @@ static int huawei_wmi_probe(struct platform_device *pdev) } } + if (wmi_has_guid(HWMI_METHOD_GUID)) { + mutex_init(&priv->wmi_lock); + } + return huawei_wmi_leds_setup(&pdev->dev); } @@ -233,6 +359,9 @@ static int huawei_wmi_remove(struct platform_device *pdev) if (wmi_has_guid(HWMI_EVENT_GUID)) wmi_remove_notify_handler(HWMI_EVENT_GUID); + if (wmi_has_guid(HWMI_METHOD_GUID)) { + } + return 0; } @@ -272,6 +401,7 @@ module_exit(huawei_wmi_exit); MODULE_ALIAS("wmi:"WMI0_EVENT_GUID); MODULE_ALIAS("wmi:"HWMI_EVENT_GUID); +MODULE_ALIAS("wmi:"HWMI_METHOD_GUID); MODULE_AUTHOR("Ayman Bagabas "); MODULE_DESCRIPTION("Huawei WMI laptop extras driver"); MODULE_LICENSE("GPL v2"); From patchwork Wed Jul 31 17:52:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068993 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8DE1B13B1 for ; Wed, 31 Jul 2019 17:53:59 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 77DF826B41 for ; Wed, 31 Jul 2019 17:53:59 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 6BB8226E3A; Wed, 31 Jul 2019 17:53:59 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 078AF26B41 for ; Wed, 31 Jul 2019 17:53:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730003AbfGaRx2 (ORCPT ); Wed, 31 Jul 2019 13:53:28 -0400 Received: from mail-yw1-f65.google.com ([209.85.161.65]:40529 "EHLO mail-yw1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729937AbfGaRx1 (ORCPT ); Wed, 31 Jul 2019 13:53:27 -0400 Received: by mail-yw1-f65.google.com with SMTP id b143so25249370ywb.7; Wed, 31 Jul 2019 10:53:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5j3IO2fR8dGnJJ8Bw7OG2mF2AzsT5n4q6VZYnXcfGiQ=; b=RPLontfBxz6EnXqQjCfVk2e0ngDlCKruYe2/+ozxbIhTq3aQ9Jy4gsi7rAQSTcbYEf HewDWMj8GkkX0Tfno/A7YOZVt52fYEbXvOLLbSUKGQ8JjPGy0KsDyXsY/qhQ7f7OoVHD qSLMInRmoVsthtz+UhfsahggoNidlCUgrq/RBKfaw0dpHyviEdsmie6txSXeRijCMDIk YDXOUPI9XqUbjcCNaxkggykO4lG4L/6aF4wmLtvtlkLoYbfGL2aDBxYpKLSWUJtSVdGW rw7y9jYxY7GrSXCb+PesvDg6hOYT0x9JmKjz2ESAe6jJLHomvRYrYt48CgNcq74PB3tm EMIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5j3IO2fR8dGnJJ8Bw7OG2mF2AzsT5n4q6VZYnXcfGiQ=; b=Ssne8cA+mLhrDf12LKpk4A6/qq7XZmvFy1v5QolLFxyXwMsdgfPl/HZxIWQEedMbsa 3oQP6hivu0WWUxpMI+eyMIgOcQzz0x8r0+PsQEhkCzhvrBFrcm6Ld3s6D95DccQuYmqH w/5aIAqSozIolgt8MaonZbLSSANLgN2AkHBc9et1zZe7BCTlD7VzIMvbIa4mRA9QhT7F n1qiCZxns69+N6G2+2QsLQSWp1qnYbSq7c5eQHFOMm2a4umGivqRRiPSj1tzZgCTUN37 SGPFSYjYswlNwU1+Ofon2M9kyuI5r1tv7jnjMu0rnY+ygtk9xzboCqOdY8BtBK8QxWNn Icmw== X-Gm-Message-State: APjAAAXTBe1kcWS6TeSzB+LviqjBGbIjA90qW1VlgTGrNcnPo4EiB8hf 2cOJXuw8wTYLzOZAKKX7ap4l7FM= X-Google-Smtp-Source: APXvYqxeLfizgBb7E2bUU1iFT8lyaE+xSWDb2ThZKdNcKWX9IM21R09cuJ7nXHYMaijpFtYe4Awx1w== X-Received: by 2002:a81:ad5a:: with SMTP id l26mr78435686ywk.388.1564595606052; Wed, 31 Jul 2019 10:53:26 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.25 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:25 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 4/9] platform/x86: huawei-wmi: Add quirks and module parameters Date: Wed, 31 Jul 2019 13:52:50 -0400 Message-Id: <20190731175255.25676-5-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Introduce quirks and module parameters. 3 quirks are added: 1. Fixes reporting brightness keys twice since it's already handled by acpi-video. 2. Some models need a short delay when setting battery thresholds to prevent a race condition when two processes read/write. 3. Matebook X (2017) handles micmute led through the "legacy" interface which is not currently implemented. Use ACPI EC method to control this led. 2 module parameters are added to enable this short delay and/or report brightness keys through this driver. Signed-off-by: Ayman Bagabas --- drivers/platform/x86/huawei-wmi.c | 71 +++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 27520b0f8956..8f918138053a 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -34,6 +35,14 @@ enum { MICMUTE_LED_SET = 0x00000b04, /* \SMLS */ }; +struct quirk_entry { + bool battery_sleep; + bool ec_micmute; + bool report_brightness; +}; + +static struct quirk_entry *quirks; + struct huawei_wmi_priv { struct input_dev *idev[2]; struct led_classdev cdev; @@ -62,6 +71,58 @@ static const struct key_entry huawei_wmi_keymap[] = { { KE_END, 0 } }; +static bool battery_sleep; +static bool report_brightness; + +module_param(battery_sleep, bool, 0444); +MODULE_PARM_DESC(battery_sleep, + "Delay after setting battery charging thresholds."); +module_param(report_brightness, bool, 0444); +MODULE_PARM_DESC(report_brightness, + "Report brightness keys."); + +/* Quirks */ + +static int __init dmi_matched(const struct dmi_system_id *dmi) +{ + quirks = dmi->driver_data; + return 1; +} + +static struct quirk_entry quirk_unknown = { +}; + +static struct quirk_entry quirk_battery_sleep = { + .battery_sleep = true, +}; + +static struct quirk_entry quirk_matebook_x = { + .ec_micmute = true, + .report_brightness = true, +}; + +static const struct dmi_system_id huawei_quirks[] = { + { + .callback = dmi_matched, + .ident = "Huawei MACH-WX9", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"), + DMI_MATCH(DMI_PRODUCT_NAME, "MACH-WX9"), + }, + .driver_data = &quirk_battery_sleep + }, + { + .callback = dmi_matched, + .ident = "Huawei MateBook X", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "HUAWEI"), + DMI_MATCH(DMI_PRODUCT_NAME, "HUAWEI MateBook X") + }, + .driver_data = &quirk_matebook_x + }, + { } +}; + /* Utils */ static int huawei_wmi_call(struct device *dev, struct acpi_buffer *in, @@ -264,6 +325,11 @@ static void huawei_wmi_process_key(struct input_dev *idev, int code) return; } + if (quirks && !quirks->report_brightness && + (key->sw.code == KEY_BRIGHTNESSDOWN || + key->sw.code == KEY_BRIGHTNESSUP)) + return; + sparse_keymap_report_entry(idev, key, 1, true); } @@ -377,6 +443,11 @@ static __init int huawei_wmi_init(void) { int err; + quirks = &quirk_unknown; + dmi_check_system(huawei_quirks); + quirks->battery_sleep |= battery_sleep; + quirks->report_brightness |= report_brightness; + err = platform_driver_register(&huawei_wmi_driver); if (err) return err; From patchwork Wed Jul 31 17:52:51 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068989 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4F0D413B1 for ; Wed, 31 Jul 2019 17:53:53 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A24C26B41 for ; Wed, 31 Jul 2019 17:53:53 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2E4C126E3A; Wed, 31 Jul 2019 17:53:53 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B6C8826B41 for ; Wed, 31 Jul 2019 17:53:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730051AbfGaRxa (ORCPT ); Wed, 31 Jul 2019 13:53:30 -0400 Received: from mail-yw1-f67.google.com ([209.85.161.67]:44679 "EHLO mail-yw1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729997AbfGaRx3 (ORCPT ); Wed, 31 Jul 2019 13:53:29 -0400 Received: by mail-yw1-f67.google.com with SMTP id l79so25249070ywe.11; Wed, 31 Jul 2019 10:53:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=qZ9bQ4qlIvn0nmi3/fOq2/nuJUUiXRlbGalFjI3uA7I=; b=i6QxSZfkIyq5TKFGaTNeNkQ4cJFz60M1HM+Mz6TdHb57MaE4cAaMuRLApZoOusKCJ1 bfoM1I970P3hEqUe/jhd7iXTZj7hAMJIPEq0EfLXE9CZF+FiRl9wBlSe5v1IObP53muG FU36aHFS9gxYFbiXE/EjZ1X/1lJ7GwGU6b2Z0bnWQZBc+2WUJb41WDqVQjFnww5clYGr 7dVFN7vfidGiH6KdtP3gmdb+n6eR/cje+o1idClYP5Vhwna+oWXxXg7SUKUTWyv1CFS8 MW9Mhpz4n9wmf3e6JWWpn1qtH+7QHkZxLvZLkYHgKGMuDza4zERal0srjHczo2iMAY9i o1Dg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=qZ9bQ4qlIvn0nmi3/fOq2/nuJUUiXRlbGalFjI3uA7I=; b=jkUO0f8ZysP8sITDcmKR7LGf+nlBdcWeWBnbuj52ev2fuQycrgkIeVY757LWoalDZV RLC0eeuEXw4y/vvdCqWtrCH+JiDjD5L2srfJLBSEwsxmbV9nox/TBEuWU0avSDo51lJ+ k3Cy45e3mbxwKfrhenOhtN62sJ5t655tKh9eXFDRND7uQTyA/6KKP96kXuW2gUr43mDY RIRY+Vt94n63+ie1ba01mSF1eXtAb0UyPmjbrskrc7xcuJnYjTftmQNvJA7ilSQ+iVN4 VMbzXGN8ZBCU+Bmbi3fJVVrttn7ILMy5VbG0OIt+Sd5XG1gSULWqNSJOE2TKYN6nSxNn AHYQ== X-Gm-Message-State: APjAAAXkLDFgeFRkkaUvyMgNN5qIeOZafvNBix1W7fMpvoud310PBTo3 SQuNNN7lvhXG5t8TC2fFQg== X-Google-Smtp-Source: APXvYqxZahjTwEiFR8+YnzaToBYJqEk10aFO7u84onDnGBYXIB4RuD4c52wOK3rEV324N7h+8+EmhQ== X-Received: by 2002:a0d:df47:: with SMTP id i68mr78055398ywe.151.1564595607426; Wed, 31 Jul 2019 10:53:27 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.26 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:26 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 5/9] platform/x86: huawei-wmi: Control micmute led through wmi interface Date: Wed, 31 Jul 2019 13:52:51 -0400 Message-Id: <20190731175255.25676-6-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Now that huawei WMI management interface is implemented, micmute LED can be controlled easily through this interface. Exception is the Matebook X (2017) which continue to uses ACPI EC method to control the LED. This model can control the LED through the legacy WMI interface which is not implemented ATM. Signed-off-by: Ayman Bagabas --- drivers/platform/x86/huawei-wmi.c | 86 ++++++++++++++++++------------- 1 file changed, 49 insertions(+), 37 deletions(-) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 8f918138053a..9013a05d2832 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -46,8 +46,6 @@ static struct quirk_entry *quirks; struct huawei_wmi_priv { struct input_dev *idev[2]; struct led_classdev cdev; - acpi_handle handle; - char *acpi_method; struct mutex wmi_lock; struct platform_device *pdev; }; @@ -238,49 +236,57 @@ static int huawei_wmi_cmd(struct device *dev, u64 arg, u8 *buf, size_t buflen) static int huawei_wmi_micmute_led_set(struct led_classdev *led_cdev, enum led_brightness brightness) { - struct huawei_wmi_priv *priv = dev_get_drvdata(led_cdev->dev->parent); - acpi_status status; - union acpi_object args[3]; - struct acpi_object_list arg_list = { - .pointer = args, - .count = ARRAY_SIZE(args), - }; - - args[0].type = args[1].type = args[2].type = ACPI_TYPE_INTEGER; - args[1].integer.value = 0x04; - - if (strcmp(priv->acpi_method, "SPIN") == 0) { - args[0].integer.value = 0; - args[2].integer.value = brightness ? 1 : 0; - } else if (strcmp(priv->acpi_method, "WPIN") == 0) { - args[0].integer.value = 1; - args[2].integer.value = brightness ? 0 : 1; + /* This is a workaround until the "legacy" interface is implemented. */ + if (quirks && quirks->ec_micmute) { + char *acpi_method; + acpi_handle handle; + acpi_status status; + union acpi_object args[3]; + struct acpi_object_list arg_list = { + .pointer = args, + .count = ARRAY_SIZE(args), + }; + + handle = ec_get_handle(); + if (!handle) { + dev_err(led_cdev->dev->parent, "Failed to get EC handle\n"); + return -ENODEV; + } + + args[0].type = args[1].type = args[2].type = ACPI_TYPE_INTEGER; + args[1].integer.value = 0x04; + + if (acpi_has_method(handle, "SPIN")) { + acpi_method = "SPIN"; + args[0].integer.value = 0; + args[2].integer.value = brightness ? 1 : 0; + } else if (acpi_has_method(handle, "WPIN")) { + acpi_method = "WPIN"; + args[0].integer.value = 1; + args[2].integer.value = brightness ? 0 : 1; + } else { + return -ENODEV; + } + + status = acpi_evaluate_object(handle, acpi_method, &arg_list, NULL); + if (ACPI_FAILURE(status)) + return -ENODEV; + + return 0; } else { - return -EINVAL; - } + u8 arg[8]; - status = acpi_evaluate_object(priv->handle, priv->acpi_method, &arg_list, NULL); - if (ACPI_FAILURE(status)) - return -ENXIO; + *(u64 *)arg = MICMUTE_LED_SET; + arg[2] = brightness; - return 0; + return huawei_wmi_cmd(led_cdev->dev->parent, *(u64 *)arg, NULL, NULL); + } } static int huawei_wmi_leds_setup(struct device *dev) { struct huawei_wmi_priv *priv = dev_get_drvdata(dev); - priv->handle = ec_get_handle(); - if (!priv->handle) - return 0; - - if (acpi_has_method(priv->handle, "SPIN")) - priv->acpi_method = "SPIN"; - else if (acpi_has_method(priv->handle, "WPIN")) - priv->acpi_method = "WPIN"; - else - return 0; - priv->cdev.name = "platform::micmute"; priv->cdev.max_brightness = 1; priv->cdev.brightness_set_blocking = huawei_wmi_micmute_led_set; @@ -412,9 +418,15 @@ static int huawei_wmi_probe(struct platform_device *pdev) if (wmi_has_guid(HWMI_METHOD_GUID)) { mutex_init(&priv->wmi_lock); + + err = huawei_wmi_leds_setup(&pdev->dev); + if (err) { + dev_err(&pdev->dev, "Failed to setup leds\n"); + return err; + } } - return huawei_wmi_leds_setup(&pdev->dev); + return 0; } static int huawei_wmi_remove(struct platform_device *pdev) From patchwork Wed Jul 31 17:52:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068991 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 9F50F1399 for ; Wed, 31 Jul 2019 17:53:58 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 88FA626B41 for ; Wed, 31 Jul 2019 17:53:58 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7D43826E3A; Wed, 31 Jul 2019 17:53:58 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 086CC26B41 for ; Wed, 31 Jul 2019 17:53:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726942AbfGaRxx (ORCPT ); Wed, 31 Jul 2019 13:53:53 -0400 Received: from mail-yw1-f68.google.com ([209.85.161.68]:40535 "EHLO mail-yw1-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730042AbfGaRxa (ORCPT ); Wed, 31 Jul 2019 13:53:30 -0400 Received: by mail-yw1-f68.google.com with SMTP id b143so25249430ywb.7; Wed, 31 Jul 2019 10:53:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=4B7kxSwn+Y6/oG1SY2GzSzP2SB2pWwxeXqv90tBjdMY=; b=WPdCfARiuE/+FieBaeEbT9g9k7rBNDO1TEU1Cy2KOqt+f/g/HD+V3Errd+85gJBSBi UKERBgBCWu9KRovzNAuYwBayKOe8Zs4Sf+gza/QxgNuylDnl0gLfLufuEdqA6F5q1zII lHLsxHxKP+/PtcGTTAkwWiTUCalSm8H9yjjFjN9DOwZyvehEEFgHTocaXBc2BC/PWSmP hyHqmuoT6YcpHZ5Z/Pr+5GSIkNJP8rEMSrIp81yZgMXmij26ab+gzIoCiXotMzQIPdFh gf9CrDxECfMn6/xwYKo163IZQjADURPnqkwatET3bpxvT03PppdPCUITp01YU2KsLsK7 U4pQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=4B7kxSwn+Y6/oG1SY2GzSzP2SB2pWwxeXqv90tBjdMY=; b=C0ScOOjhDFvZsKFqNyqrb9Lz9W80WxyGsedEGZcEwlYq5RRmkcQJRBVWZgCTs+z3Ga WvTp8DFk6MBQpJqHHmrK8zkoA0UleLEzrjlWkdBdTOUSXyg1zNTnDXRfwtKOqnj+3AzX sNb640of1I7iPQj/wDNOzWDsue6tldpfFLXR7rxxXtdoRiMUwRe6X4ekHxmm+UaK4Nvg X3Db/5hsOISWM5krf1ILWKcyuwuiS3wGuSkpMg+/qLRO5mTWq0fAVPq+ZbI+YLhIqojp Y31ITQsOj0orntWVj12JKGFvvEUKmr7K3xyoDaqx/pGv/yWK6oYADSwdTmJgb4ucQ6fW KUAQ== X-Gm-Message-State: APjAAAVwwalhT+BTkAbnjfPYHRg+vs+O3n5jAYS8GkZNRb4wtVLuFqok Ilo3PJwg74f/7nS8yDHymw== X-Google-Smtp-Source: APXvYqxQWi9XR3MxBQ8RjOAMiby7njxIJdp2+VJ/SxtuAxUx0hoOPljgoBq9QMoYKiiuk1bWJVcd+w== X-Received: by 2002:a81:7b89:: with SMTP id w131mr76298619ywc.462.1564595609261; Wed, 31 Jul 2019 10:53:29 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.28 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:28 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 6/9] platform/x86: huawei-wmi: Add battery charging thresholds Date: Wed, 31 Jul 2019 13:52:52 -0400 Message-Id: <20190731175255.25676-7-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Implement battery charging thresholds functionality to be used with sysfs interface support that is implemented in this series. Setting battery charging thresholds can introduce a race condition where two are trying to read/write values from/to EC memory. Even though a mutex is used, this doesn't guarantee that these values will make it to EC so a blocking sleep is necessary. This sleep is enforced on the MACH-WX9 model since turning off battery protection using (0,100) doesn't change the values in the EC memory, instead it only disables the protection. So a workaround is to set the thresholds to (0,0) before setting it to (0,100). This will ensure that we update these values in EC memory and then turning it off with (0,100). Thus, the msleep(1000). Signed-off-by: Ayman Bagabas --- In huawei_wmi_battery_get and later in huawei_wmi_fn_lock_get, 256 bytes buffer is allocated dynamically on the stack. Now I know this is discouraged, should it be changed to use kmalloc? drivers/platform/x86/huawei-wmi.c | 54 +++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 9013a05d2832..da3986cd0428 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -46,6 +47,7 @@ static struct quirk_entry *quirks; struct huawei_wmi_priv { struct input_dev *idev[2]; struct led_classdev cdev; + struct mutex battery_lock; struct mutex wmi_lock; struct platform_device *pdev; }; @@ -298,6 +300,57 @@ static int huawei_wmi_leds_setup(struct device *dev) return devm_led_classdev_register(dev, &priv->cdev); } +/* Battery protection */ + +static int huawei_wmi_battery_get(struct device *dev, int *low, int *high) +{ + struct huawei_wmi_priv *priv = dev_get_drvdata(dev); + u8 ret[0x100]; + int err, i; + + mutex_lock(&priv->battery_lock); + err = huawei_wmi_cmd(dev, BATTERY_THRESH_GET, ret, 0x100); + mutex_unlock(&priv->battery_lock); + if (err) + return err; + + /* Find the last two non-zero values. Return status is ignored. */ + i = 0x100; + do { + *low = ret[i-1]; + *high = ret[i]; + } while (i > 2 && !ret[i--]); + + return 0; +} + +static int huawei_wmi_battery_set(struct device *dev, int low, int high) +{ + struct huawei_wmi_priv *priv = dev_get_drvdata(dev); + u8 arg[8]; + int err; + + *(u64 *)arg = BATTERY_THRESH_SET; + arg[2] = low; + arg[3] = high; + + /* This is an edge case were some models turn battery protection + * off without changing their thresholds values. We clear the + * values before turning off protection. Sometimes we need a sleep delay to + * make sure these values make their way to EC memory. + */ + if (low == 0 && high == 100) + huawei_wmi_battery_set(dev, 0, 0); + + mutex_lock(&priv->battery_lock); + err = huawei_wmi_cmd(dev, *(u64 *)arg, NULL, NULL); + if (quirks && quirks->battery_sleep) + msleep(1000); + mutex_unlock(&priv->battery_lock); + + return err; +} + /* Input */ static void huawei_wmi_process_key(struct input_dev *idev, int code) @@ -418,6 +471,7 @@ static int huawei_wmi_probe(struct platform_device *pdev) if (wmi_has_guid(HWMI_METHOD_GUID)) { mutex_init(&priv->wmi_lock); + mutex_init(&priv->battery_lock); err = huawei_wmi_leds_setup(&pdev->dev); if (err) { From patchwork Wed Jul 31 17:52:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068983 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C3B761399 for ; Wed, 31 Jul 2019 17:53:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AE1AC26B41 for ; Wed, 31 Jul 2019 17:53:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A22E926E1A; Wed, 31 Jul 2019 17:53:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DE72226E3A for ; Wed, 31 Jul 2019 17:53:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728961AbfGaRxd (ORCPT ); Wed, 31 Jul 2019 13:53:33 -0400 Received: from mail-yb1-f195.google.com ([209.85.219.195]:36078 "EHLO mail-yb1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729997AbfGaRxb (ORCPT ); Wed, 31 Jul 2019 13:53:31 -0400 Received: by mail-yb1-f195.google.com with SMTP id d9so18318648ybf.3; Wed, 31 Jul 2019 10:53:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YmPyHZ8dDaGq4wOOYUfRrP02saBuikUQohVrtGbVNIQ=; b=hpkAMpmvNOtFxbAzq7Rj86ZGsKpOir3GJ99AJTe6kwi9ybicQC7TSiKRCK45vjVoD9 72iuLSEfmp13a2CFWw1n4h64jiPmynh99wpcTWz1Be/OCoiZmQpgfhH43M5IpbQoaefg ECFfAd9uzU91m4FM+Yc5ayCHtRcmJoc1fIVMz7X3ZJmnWC3CGkUR8n4BfPFDZh+8L6L1 40J8WTvd4/xPAc2mFpD6Bsm8bpZOXk0Mmp5xyEXe6Q/C9eVYYkLST0mLk2Tmz+Hexlif 6uPeLV0yab+SqzsrS7gy/TnnQ9VMc/1vdTT52z2Q72qrwR2rXQZcAKghKMbzwOR/AVbs ntMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YmPyHZ8dDaGq4wOOYUfRrP02saBuikUQohVrtGbVNIQ=; b=rjcdRhnPVQM+lQJ/KMvmcgpuOYFb2/fNp5dTp/m/pGVJiBO6dz3oVP+6LwW2elpYxq yukQyTe/uBxF0qXVIm9fpNp/tdoJs3oOuKtI0l39cID8JN6H7Ahr+oRlCNULSbJsgT14 Gi52c06M5zGrWpV4YXg7FaJ7XB+6hz5c5lV/e628oyHb+z6vnCMNbplfra0blc5MdyU/ rhbDD3L6XflrM5C2jzEM5pIERwxEipvAhdB58WGq/CMRPC8u80J2UJSCWxb43xvzTo6p 1UMptLnUJOg14KBJoEoEx+ndB3HegT+v2NizhCBrXwKPWfU/NC+QL0z/AUKO0cnvECin YDag== X-Gm-Message-State: APjAAAWFJ9LRTewqVRN8KkQv1ADnrqtkczYR0MUQFMtI6wGk+Qzy+zGh EpmzP/cofZ04LkdKaePWKg== X-Google-Smtp-Source: APXvYqzy2iBVuUnEnTQNmQa5OOhb/cHA3x/v/crI+Vm9UD80Qulphe14LMvjoBwoP8RRH23vM5LvBg== X-Received: by 2002:a5b:bc8:: with SMTP id c8mr9338954ybr.152.1564595610754; Wed, 31 Jul 2019 10:53:30 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.30 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:30 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 7/9] platform/x86: huawei-wmi: Add fn-lock support Date: Wed, 31 Jul 2019 13:52:53 -0400 Message-Id: <20190731175255.25676-8-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Huawei Matebook laptops uses Fn key and toggle to access F1-F12 keys. Along with that, there is this feature called fn-lock that inverts the behavior of this Fn key. Implement the basic functionality of this feature to be used later by sysfs interface support introduced in this series. Signed-off-by: Ayman Bagabas --- drivers/platform/x86/huawei-wmi.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index da3986cd0428..4159e10bda26 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -351,6 +351,36 @@ static int huawei_wmi_battery_set(struct device *dev, int low, int high) return err; } +/* Fn lock */ + +static int huawei_wmi_fn_lock_get(struct device *dev, int *on) +{ + u8 ret[0x100] = { 0 }; + int err, i; + + err = huawei_wmi_cmd(dev, FN_LOCK_GET, ret, 0x100); + if (err) + return err; + + /* Find the first non-zero value. Return status is ignored. */ + i = 1; + do { + *on = ret[i] - 1; // -1 undefined, 0 off, 1 on. + } while (i < 0x100 && !ret[i++]); + + return 0; +} + +static int huawei_wmi_fn_lock_set(struct device *dev, int on) +{ + u8 arg[8]; + + *(u64 *)arg = FN_LOCK_SET; + arg[2] = on + 1; // 0 undefined, 1 off, 2 on. + + return huawei_wmi_cmd(dev, *(u64 *)arg, NULL, NULL); +} + /* Input */ static void huawei_wmi_process_key(struct input_dev *idev, int code) From patchwork Wed Jul 31 17:52:54 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068987 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1AEF513B1 for ; Wed, 31 Jul 2019 17:53:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 04F0526B41 for ; Wed, 31 Jul 2019 17:53:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ED76626E3A; Wed, 31 Jul 2019 17:53:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8DBDD26B41 for ; Wed, 31 Jul 2019 17:53:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730148AbfGaRxe (ORCPT ); Wed, 31 Jul 2019 13:53:34 -0400 Received: from mail-yw1-f65.google.com ([209.85.161.65]:40535 "EHLO mail-yw1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730119AbfGaRxd (ORCPT ); Wed, 31 Jul 2019 13:53:33 -0400 Received: by mail-yw1-f65.google.com with SMTP id b143so25249472ywb.7; Wed, 31 Jul 2019 10:53:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tCO4bB5RG1i1zaVkyEc6qftvnA4HN0QLB0O4PI95vVE=; b=Oi9PYp43hhSDGj6Pl+Nbl3ZXdbcKnXBqlsfWNZ53GxMveGmDH/kzGpsdtWkWtzdy0s OzHKylRvNphRRWBOak0gnWmft6TU1IxEYxbTzlu3yUdyFvronv0p0d1yy8OvswIa15Mr emMjC4sRUZCm+sao/hmBcXQRv79fyeTnrM5+5o2KIYWSfgq/YddYg96dge+8hYFnUYX3 hTyj6Dpx06d83Q8j8kiS7rxtgjDWeVsu6B4jo1sESmzeoNYd9wv0cf7DMsKkycjcpqqu bmvKtzk43YeUThy2gD34yRWG2KIbXMOr5MFfetLykQW1JYt2LWUA/VdQHu7aBavmwLT9 jRfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tCO4bB5RG1i1zaVkyEc6qftvnA4HN0QLB0O4PI95vVE=; b=sIVW9w4Il78J7X0w5O0vNCmeETwvUX45k8LSQ87tUtm/Rl3Ia3LVE2HT9Yvagri2d4 zNOBQK9fulR7xIPHwswmn5f5gM1YxzXHsFd9lZhdTi5Gr7BzqOVM4y8iyEQC1J8UeWs6 0HxxhfVMJiQFgNdbKgijvbQ9x7zQSJOmmHugh7ayvmq7r67KTdtOSJbDz7YEDUoclBWm dXTLypK4aiL3XCCTOciHJjHocFm9B8aZt5pgsq4WN3/KHRGWCMe0DRtpb2l1h56Dn0e7 SLHeLTZTaXoEdEhE+uUrCK1MnFQ6xuxrxog5ESBClr3C9+qEO25f55+1IpZC3jRJPHEc 0H/A== X-Gm-Message-State: APjAAAXmU6QKsRESPcUbnRBcDzZhgltqpd6OcSQpeyqEA1Gh3M+FJ3qQ hKKj0GK4npiv5JAKv9119Q== X-Google-Smtp-Source: APXvYqxXQu/KM/sG9siSkXFwxDRnlm4Sap9pwHPuXLupJo0etFZsC1P95pTWUELx9y29+Tzhp6tKHw== X-Received: by 2002:a81:3b4a:: with SMTP id i71mr80000529ywa.395.1564595612224; Wed, 31 Jul 2019 10:53:32 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.31 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:31 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 8/9] platform/x86: huawei-wmi: Add sysfs interface support Date: Wed, 31 Jul 2019 13:52:54 -0400 Message-Id: <20190731175255.25676-9-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add sysfs interface to enable the use of battery charging thresholds and fn-lock support introduced in this series. Signed-off-by: Ayman Bagabas --- drivers/platform/x86/huawei-wmi.c | 82 +++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index 4159e10bda26..f7041fb71026 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -14,6 +14,7 @@ #include #include #include +#include #include /* @@ -381,6 +382,80 @@ static int huawei_wmi_fn_lock_set(struct device *dev, int on) return huawei_wmi_cmd(dev, *(u64 *)arg, NULL, NULL); } +/* sysfs */ + +static ssize_t charge_thresholds_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int err, low, high; + + err = huawei_wmi_battery_get(dev, &low, &high); + if (err) + return err; + + return sprintf(buf, "%d %d\n", low, high); +} + +static ssize_t charge_thresholds_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int low, high, err; + + if (sscanf(buf, "%d %d", &low, &high) != 2 || + low < 0 || high > 100 || + low > high) + return -EINVAL; + + err = huawei_wmi_battery_set(dev, low, high); + if (err) + return err; + + return size; +} + +static ssize_t fn_lock_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int err, on; + + err = huawei_wmi_fn_lock_get(dev, &on); + if (err) + return err; + + return sprintf(buf, "%d\n", on); +} + +static ssize_t fn_lock_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int on, err; + + if (kstrtoint(buf, 10, &on) || + on < 0 || on > 1) + return -EINVAL; + + err = huawei_wmi_fn_lock_set(dev, on); + if (err) + return err; + + return size; +} + +static DEVICE_ATTR_RW(charge_thresholds); +static DEVICE_ATTR_RW(fn_lock_state); + +static struct attribute *huawei_wmi_attrs[] = { + &dev_attr_charge_thresholds.attr, + &dev_attr_fn_lock_state.attr, + NULL +}; + +ATTRIBUTE_GROUPS(huawei_wmi); + /* Input */ static void huawei_wmi_process_key(struct input_dev *idev, int code) @@ -508,6 +583,12 @@ static int huawei_wmi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to setup leds\n"); return err; } + + err = sysfs_create_groups(&pdev->dev.kobj, huawei_wmi_groups); + if (err) { + dev_err(&pdev->dev, "Failed to create sysfs interface\n"); + return err; + } } return 0; @@ -522,6 +603,7 @@ static int huawei_wmi_remove(struct platform_device *pdev) wmi_remove_notify_handler(HWMI_EVENT_GUID); if (wmi_has_guid(HWMI_METHOD_GUID)) { + sysfs_remove_groups(&pdev->dev.kobj, huawei_wmi_groups); } return 0; From patchwork Wed Jul 31 17:52:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ayman Bagabas X-Patchwork-Id: 11068985 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 51A1A1399 for ; Wed, 31 Jul 2019 17:53:48 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3A63D26B41 for ; Wed, 31 Jul 2019 17:53:48 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 2DBBD26E3A; Wed, 31 Jul 2019 17:53:48 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ABE9A26B41 for ; Wed, 31 Jul 2019 17:53:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730179AbfGaRxg (ORCPT ); Wed, 31 Jul 2019 13:53:36 -0400 Received: from mail-yb1-f195.google.com ([209.85.219.195]:33112 "EHLO mail-yb1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729467AbfGaRxf (ORCPT ); Wed, 31 Jul 2019 13:53:35 -0400 Received: by mail-yb1-f195.google.com with SMTP id c202so23393749ybf.0; Wed, 31 Jul 2019 10:53:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xl+sNzEYPOT1ywDx++7Y8OIBlzLDJkDBqJnWrBIwwq4=; b=nyi/izXTpquwaKJYaeTkQLXnq3F/yOfKXje6aOE22OZzp9etnKEXfYR9szqP5gbaQi lqE1RzYgcP+Rk2QbA3e/BdPJCdb8hZhwuXEWV5mddcwzLh0D+xd48SHuwlcZH3dXlgBN 92cS++AAFHW/FoRyq/x02uNJ9jRfpfflwW5D7pSu622/9mtZ8c6gLFfJdviAybK7X1A2 sCCw2P1YUylJ434vKU1rRDoWv9QIk09fxDEApMqM9IKQ3xTQUVGfovQq1JxeFzzB3d1F GTGGx1/Io/rwCN2uLGEt29IIyP5t1qU/fdM7HLP1rrieg1Eq8N8EFLwQO2SrjXCpasub PjTw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xl+sNzEYPOT1ywDx++7Y8OIBlzLDJkDBqJnWrBIwwq4=; b=BV8Ae+I2L0AWSNyggJPSfN3nG3w2ugFJrSZQlJgDV83DtTIDNiMZNE0ieLn6mvJVxe zhEFaADB3N2b26WM7SjpyeiKcKVWzxMEf5uXkJFvQ+mjrOfl4GA2vWN7lvhcmvwXOaC+ QqlWMNxVSo1jc/l1ctcDwIiwCvmx/evmrqzBLrOy8HOOd+HZV+CcBAAYMrb3el+uxHKb b9d2m9MUgc4cSvJGi0DHFhWYoMGKinKOtGZDxDrqJShzdq+VzdMSac13wK+/wpbPs+DB FI4YxgfCPEZ7J/7vYBP5wx6ptvTJmHeS8lSksSOJXk8+OgPT/MAspMIHeYqXdYVNlaf2 MNAg== X-Gm-Message-State: APjAAAUPJ8DpZBwNJx9vSe0+gp8JWDpUGpGtV9ICsbgKbTbO9JVGvhzi sN4LFO5h8dJ4u2sOHOlsEXYbtsI= X-Google-Smtp-Source: APXvYqy8z/OlVkd240XLgbZteZYyKIP+RYC2cR0fhSo0jIhO0cRURLPFWIoNWpPjD0VnzRnKenYtCw== X-Received: by 2002:a25:1806:: with SMTP id 6mr28052653yby.415.1564595613804; Wed, 31 Jul 2019 10:53:33 -0700 (PDT) Received: from localhost.localdomain ([12.156.111.130]) by smtp.gmail.com with ESMTPSA id w193sm10517294ywa.72.2019.07.31.10.53.33 (version=TLS1_3 cipher=AEAD-AES256-GCM-SHA384 bits=256/256); Wed, 31 Jul 2019 10:53:33 -0700 (PDT) From: Ayman Bagabas To: Darren Hart , Andy Shevchenko , platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Ayman Bagabas Subject: [RFC 9/9] platform/x86: huawei-wmi: Add debugfs support Date: Wed, 31 Jul 2019 13:52:55 -0400 Message-Id: <20190731175255.25676-10-ayman.bagabas@gmail.com> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190731175255.25676-1-ayman.bagabas@gmail.com> References: <20190731175255.25676-1-ayman.bagabas@gmail.com> MIME-Version: 1.0 X-Mailer: git-send-email 2.20.1 Sender: platform-driver-x86-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: platform-driver-x86@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a debugfs interface that can be used to call the WMI management interface function. The WMI interface takes a 64 bit integer and returns 256-260 bytes buffer. This debugfs interface creates two files, one stores a 64 bit int and the other calls the WMI interface and dumps out the returned buffer. Signed-off-by: Ayman Bagabas --- drivers/platform/x86/huawei-wmi.c | 98 +++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c index f7041fb71026..bdca8bd76c8c 100644 --- a/drivers/platform/x86/huawei-wmi.c +++ b/drivers/platform/x86/huawei-wmi.c @@ -6,6 +6,7 @@ */ #include +#include #include #include #include @@ -45,7 +46,13 @@ struct quirk_entry { static struct quirk_entry *quirks; +struct huawei_wmi_debug { + struct dentry *root; + u64 arg; +}; + struct huawei_wmi_priv { + struct huawei_wmi_debug debug; struct input_dev *idev[2]; struct led_classdev cdev; struct mutex battery_lock; @@ -456,6 +463,94 @@ static struct attribute *huawei_wmi_attrs[] = { ATTRIBUTE_GROUPS(huawei_wmi); +/* debugfs */ + +static void huawei_wmi_debugfs_call_dump(struct seq_file *m, void *data, + union acpi_object *obj) +{ + struct huawei_wmi_priv *priv = m->private; + int i; + + switch (obj->type) { + case ACPI_TYPE_INTEGER: + seq_printf(m, "0x%llx", obj->integer.value); + break; + case ACPI_TYPE_STRING: + seq_printf(m, "\"%*s\"", obj->string.length, obj->string.pointer); + break; + case ACPI_TYPE_BUFFER: + seq_puts(m, "{"); + for (i = 0; i < obj->buffer.length; i++) { + seq_printf(m, "0x%02x", obj->buffer.pointer[i]); + if (i < obj->buffer.length - 1) + seq_puts(m, ","); + } + seq_puts(m, "}"); + break; + case ACPI_TYPE_PACKAGE: + seq_puts(m, "["); + for (i = 0; i < obj->package.count; i++) { + huawei_wmi_debugfs_call_dump(m, priv, &obj->package.elements[i]); + if (i < obj->package.count - 1) + seq_puts(m, ","); + } + seq_puts(m, "]"); + break; + default: + dev_err(&priv->pdev->dev, "Unexpected obj type, got %d\n", obj->type); + return; + } +} + +static int huawei_wmi_debugfs_call_show(struct seq_file *m, void *data) +{ + struct huawei_wmi_priv *priv = m->private; + struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer in; + union acpi_object *obj; + int err; + + in.length = sizeof(u64); + in.pointer = &priv->debug.arg; + + err = huawei_wmi_call(&priv->pdev->dev, &in, &out); + if (err) + return err; + + obj = out.pointer; + if (!obj) { + err = -EIO; + goto fail_debugfs_call; + } + + huawei_wmi_debugfs_call_dump(m, priv, obj); + +fail_debugfs_call: + kfree(out.pointer); + return err; +} + +DEFINE_SHOW_ATTRIBUTE(huawei_wmi_debugfs_call); + +static void huawei_wmi_debugfs_exit(struct device *dev) +{ + struct huawei_wmi_priv *priv = dev_get_drvdata(dev); + + debugfs_remove_recursive(priv->debug.root); +} + +static void huawei_wmi_debugfs_setup(struct device *dev) +{ + struct huawei_wmi_priv *priv = dev_get_drvdata(dev); + + priv->debug.root = debugfs_create_dir("huawei-wmi", NULL); + + debugfs_create_x64("arg", 0644, priv->debug.root, + &priv->debug.arg); + debugfs_create_file("call", 0400, + priv->debug.root, priv, &huawei_wmi_debugfs_call_fops); +} + /* Input */ static void huawei_wmi_process_key(struct input_dev *idev, int code) @@ -589,6 +684,8 @@ static int huawei_wmi_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Failed to create sysfs interface\n"); return err; } + + huawei_wmi_debugfs_setup(&pdev->dev); } return 0; @@ -603,6 +700,7 @@ static int huawei_wmi_remove(struct platform_device *pdev) wmi_remove_notify_handler(HWMI_EVENT_GUID); if (wmi_has_guid(HWMI_METHOD_GUID)) { + huawei_wmi_debugfs_exit(&pdev->dev); sysfs_remove_groups(&pdev->dev.kobj, huawei_wmi_groups); }