LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
From: Ayman Bagabas <ayman.bagabas@gmail.com>
To: Darren Hart <dvhart@infradead.org>,
	Andy Shevchenko <andy@infradead.org>,
	platform-driver-x86@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: ayman.bagabas@gmail.com
Subject: [PATCH v2 5/8] platform/x86: huawei-wmi: add battery charging protection support
Date: Wed, 12 Jun 2019 23:04:12 -0400	[thread overview]
Message-ID: <20190613030416.25807-7-ayman.bagabas@gmail.com> (raw)
In-Reply-To: <20190613030416.25807-1-ayman.bagabas@gmail.com>

Some models that implement the new WMI management interface can control
battery charging thresholds where it limits charging the battery once it
reaches certain thresholds. This feature is not present in MateBook X
(2017).

Signed-off-by: Ayman Bagabas <ayman.bagabas@gmail.com>
---
 drivers/platform/x86/huawei-wmi.c | 56 +++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/platform/x86/huawei-wmi.c b/drivers/platform/x86/huawei-wmi.c
index 358d9d168300..06d83e613504 100644
--- a/drivers/platform/x86/huawei-wmi.c
+++ b/drivers/platform/x86/huawei-wmi.c
@@ -6,6 +6,7 @@
  */
 
 #include <linux/acpi.h>
+#include <linux/delay.h>
 #include <linux/dmi.h>
 #include <linux/input.h>
 #include <linux/input/sparse-keymap.h>
@@ -48,6 +49,7 @@ struct huawei_wmi {
 	struct led_classdev cdev;
 	struct input_dev *idev[2];
 	struct mutex wmi_lock;
+	struct mutex battery_lock;
 	struct platform_device *pdev;
 };
 
@@ -302,6 +304,59 @@ static int huawei_wmi_leds_setup(struct device *dev)
 	return devm_led_classdev_register(dev, &huawei->cdev);
 }
 
+/* Battery protection */
+
+static int huawei_wmi_battery_get(struct device *dev, int *low, int *high)
+{
+	struct huawei_wmi *huawei = dev_get_drvdata(dev);
+	u8 ret[0x100];
+	int err, i;
+
+	mutex_lock(&huawei->battery_lock);
+	err = huawei_wmi_cmd(dev, BATTERY_THRESH_GET, ret, 0x100);
+	mutex_unlock(&huawei->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 *huawei = 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(&huawei->battery_lock);
+	err = huawei_wmi_cmd(dev, *(u64 *)arg, NULL, NULL);
+	if (quirks && quirks->battery_sleep)
+		msleep(1000);
+	mutex_unlock(&huawei->battery_lock);
+
+	return err;
+}
+
 /* Input */
 
 static void huawei_wmi_process_key(struct input_dev *idev, int code)
@@ -424,6 +479,7 @@ static int huawei_wmi_probe(struct platform_device *pdev)
 
 	if (wmi_has_guid(HWMI_METHOD_GUID)) {
 		mutex_init(&huawei->wmi_lock);
+		mutex_init(&huawei->battery_lock);
 		err = huawei_wmi_leds_setup(&pdev->dev);
 		if (err)
 			dev_err(&pdev->dev, "Failed to setup leds\n");
-- 
2.20.1


  parent reply	other threads:[~2019-06-13 16:53 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-13  3:04 [PATCH v2 0/8] platform/x86: Huawei WMI laptop extras driver Ayman Bagabas
2019-06-13  3:04 ` [PATCH v2 1/8] platform/x86: huawei-wmi: move to platform driver Ayman Bagabas
2019-06-13  3:04 ` [PATCH v1] platform/x86: Huawei laptop extras driver Ayman Bagabas
2019-06-13  3:04 ` [PATCH v2 2/8] platform/x86: huawei-wmi: implement WMI management interface Ayman Bagabas
2019-06-13  3:04 ` [PATCH v2 3/8] platform/x86: huawei-wmi: use quirks and module parameters Ayman Bagabas
2019-06-13  3:04 ` [PATCH v2 4/8] platform/x86: huawei-wmi: control micmute LED through WMI interface Ayman Bagabas
2019-06-13  3:04 ` Ayman Bagabas [this message]
2019-06-13  3:04 ` [PATCH v2 6/8] platform/x86: huawei-wmi: add fn-lock support Ayman Bagabas
2019-06-13  3:04 ` [PATCH v2 7/8] platform/x86: huawei-wmi: add sysfs interface support Ayman Bagabas
2019-06-13  3:04 ` [PATCH v2 8/8] platform/x86: huawei-wmi: add debugfs files support Ayman Bagabas
2019-06-29 14:27 ` [PATCH v2 0/8] platform/x86: Huawei WMI laptop extras driver Andy Shevchenko
2019-06-30 17:49   ` ayman.bagabas

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190613030416.25807-7-ayman.bagabas@gmail.com \
    --to=ayman.bagabas@gmail.com \
    --cc=andy@infradead.org \
    --cc=dvhart@infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=platform-driver-x86@vger.kernel.org \
    --subject='Re: [PATCH v2 5/8] platform/x86: huawei-wmi: add battery charging protection support' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).