Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1651790 > unrolled thread

[PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch

Started byHao Wei Tee <angelsl@angelsl.xyz>
First post2017-05-27 09:40 +0200
Last post2017-05-30 16:10 +0200
Articles 4 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch Hao Wei Tee <angelsl@angelsl.xyz> - 2017-05-27 09:40 +0200
    Re: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode  switch Hao Wei Tee <angelsl@angelsl.xyz> - 2017-05-28 15:50 +0200
      Re: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch Andy Shevchenko <andy.shevchenko@gmail.com> - 2017-05-30 15:30 +0200
        Re: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode  switch Hao Wei Tee <angelsl@angelsl.xyz> - 2017-05-30 16:10 +0200

#1651790 — [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch

FromHao Wei Tee <angelsl@angelsl.xyz>
Date2017-05-27 09:40 +0200
Subject[PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch
Message-ID<tLEul-cX-1@gated-at.bofh.it>
This exposes the battery conservation mode present on some (?) IdeaPads.
The mode is set by calling ACPI method SBMC with argument 3 (on) or
5 (off). Status is reported in bit 5 of the return value of ACPI method
GBMD.

This patch was written based on an IdeaPad U430p. I'm not sure if the ACPI
methods are the same across all IdeaPads, so it would be great if this got more
testing across other models before it's merged.

Signed-off-by: Hao Wei Tee <angelsl@angelsl.xyz>
---
 drivers/platform/x86/ideapad-laptop.c | 70 +++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
index d48962569364..3798a1ab1604 100644
--- a/drivers/platform/x86/ideapad-laptop.c
+++ b/drivers/platform/x86/ideapad-laptop.c
@@ -42,6 +42,7 @@
 
 #define IDEAPAD_RFKILL_DEV_NUM	(3)
 
+#define GBMD_CONSERVATION_BIT (5)
 #define CFG_BT_BIT	(16)
 #define CFG_3G_BIT	(17)
 #define CFG_WIFI_BIT	(18)
@@ -55,6 +56,8 @@ static const char *const ideapad_wmi_fnesc_events[] = {
 #endif
 
 enum {
+	VPCCMD_CONSERVATION_ON = 3,
+	VPCCMD_CONSERVATION_OFF = 5,
 	VPCCMD_R_VPC1 = 0x10,
 	VPCCMD_R_BL_MAX,
 	VPCCMD_R_BL,
@@ -123,6 +126,27 @@ static int read_method_int(acpi_handle handle, const char *method, int *val)
 	}
 }
 
+static int conservation_mode_status(acpi_handle handle, bool *ret)
+{
+	acpi_status status;
+	unsigned long long result;
+
+	status = acpi_evaluate_integer(handle, "GBMD", NULL, &result);
+	if (ACPI_FAILURE(status))
+		return -1;
+
+	*ret = (result & (1 << GBMD_CONSERVATION_BIT)) != 0;
+	return 0;
+}
+
+static int method_sbmc(acpi_handle handle, int cmd)
+{
+	acpi_status status;
+
+	status = acpi_execute_simple_method(handle, "SBMC", cmd);
+	return ACPI_FAILURE(status) ? -1 : 0;
+}
+
 static int method_vpcr(acpi_handle handle, int cmd, int *ret)
 {
 	acpi_status status;
@@ -218,6 +242,7 @@ static int debugfs_status_show(struct seq_file *s, void *data)
 {
 	struct ideapad_private *priv = s->private;
 	unsigned long value;
+	bool boolval;
 
 	if (!priv)
 		return -EINVAL;
@@ -250,6 +275,12 @@ static int debugfs_status_show(struct seq_file *s, void *data)
 	if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value))
 		seq_printf(s, "Camera status:\t%s(%lu)\n",
 			   value ? "On" : "Off", value);
+	seq_puts(s, "=====================\n");
+
+	if (!conservation_mode_status(priv->adev->handle, &boolval)) {
+		seq_printf(s, "Conservation mode:\t%s(%u)\n",
+			   boolval ? "On" : "Off", boolval);
+	}
 
 	return 0;
 }
@@ -456,10 +487,46 @@ static ssize_t __maybe_unused touchpad_store(struct device *dev,
 
 static DEVICE_ATTR_RO(touchpad);
 
+static ssize_t show_ideapad_conservation(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	bool result;
+	struct ideapad_private *priv = dev_get_drvdata(dev);
+
+	if (conservation_mode_status(priv->adev->handle, &result))
+		return sprintf(buf, "-1\n");
+	return sprintf(buf, "%u\n", result);
+}
+
+static ssize_t store_ideapad_conservation(struct device *dev,
+				 struct device_attribute *attr,
+				 const char *buf, size_t count)
+{
+	int ret;
+	bool state;
+	struct ideapad_private *priv = dev_get_drvdata(dev);
+
+	ret = kstrtobool(buf, &state);
+	if (ret)
+		return ret;
+
+	ret = method_sbmc(priv->adev->handle, state ?
+					      VPCCMD_CONSERVATION_ON :
+					      VPCCMD_CONSERVATION_OFF);
+	if (ret < 0)
+		return -EIO;
+	return count;
+}
+
+static DEVICE_ATTR(conservation_mode, 0644, show_ideapad_conservation,
+					    store_ideapad_conservation);
+
 static struct attribute *ideapad_attributes[] = {
 	&dev_attr_camera_power.attr,
 	&dev_attr_fan_mode.attr,
 	&dev_attr_touchpad.attr,
+	&dev_attr_conservation_mode.attr,
 	NULL
 };
 
@@ -477,6 +544,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
 		unsigned long value;
 		supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
 					  &value);
+	} else if (attr == &dev_attr_conservation_mode.attr) {
+		supported = acpi_has_method(priv->adev->handle, "GBMD") &&
+			    acpi_has_method(priv->adev->handle, "SBMC");
 	} else
 		supported = true;
 
-- 
2.13.0

[toc] | [next] | [standalone]


#1652126 — Re: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch

FromHao Wei Tee <angelsl@angelsl.xyz>
Date2017-05-28 15:50 +0200
SubjectRe: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch
Message-ID<tM6JX-2FP-5@gated-at.bofh.it>
In reply to#1651790
On 5/27/17 3:31 PM, Hao Wei Tee wrote:
> This exposes the battery conservation mode present on some (?) IdeaPads.
> The mode is set by calling ACPI method SBMC with argument 3 (on) or
> 5 (off). Status is reported in bit 5 of the return value of ACPI method
> GBMD.
> 
> This patch was written based on an IdeaPad U430p. I'm not sure if the ACPI
> methods are the same across all IdeaPads, so it would be great if this got more
> testing across other models before it's merged.

I got someone to test on an IdeaPad Y510p. It works on that too.

> Signed-off-by: Hao Wei Tee <angelsl@angelsl.xyz>
> ---
>  drivers/platform/x86/ideapad-laptop.c | 70 +++++++++++++++++++++++++++++++++++
>  1 file changed, 70 insertions(+)
> 
> diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c
> index d48962569364..3798a1ab1604 100644
> --- a/drivers/platform/x86/ideapad-laptop.c
> +++ b/drivers/platform/x86/ideapad-laptop.c
> @@ -42,6 +42,7 @@
>  
>  #define IDEAPAD_RFKILL_DEV_NUM	(3)
>  
> +#define GBMD_CONSERVATION_BIT (5)
>  #define CFG_BT_BIT	(16)
>  #define CFG_3G_BIT	(17)
>  #define CFG_WIFI_BIT	(18)
> @@ -55,6 +56,8 @@ static const char *const ideapad_wmi_fnesc_events[] = {
>  #endif
>  
>  enum {
> +	VPCCMD_CONSERVATION_ON = 3,
> +	VPCCMD_CONSERVATION_OFF = 5,
>  	VPCCMD_R_VPC1 = 0x10,
>  	VPCCMD_R_BL_MAX,
>  	VPCCMD_R_BL,
> @@ -123,6 +126,27 @@ static int read_method_int(acpi_handle handle, const char *method, int *val)
>  	}
>  }
>  
> +static int conservation_mode_status(acpi_handle handle, bool *ret)
> +{
> +	acpi_status status;
> +	unsigned long long result;
> +
> +	status = acpi_evaluate_integer(handle, "GBMD", NULL, &result);
> +	if (ACPI_FAILURE(status))
> +		return -1;
> +
> +	*ret = (result & (1 << GBMD_CONSERVATION_BIT)) != 0;
> +	return 0;
> +}
> +
> +static int method_sbmc(acpi_handle handle, int cmd)
> +{
> +	acpi_status status;
> +
> +	status = acpi_execute_simple_method(handle, "SBMC", cmd);
> +	return ACPI_FAILURE(status) ? -1 : 0;
> +}
> +
>  static int method_vpcr(acpi_handle handle, int cmd, int *ret)
>  {
>  	acpi_status status;
> @@ -218,6 +242,7 @@ static int debugfs_status_show(struct seq_file *s, void *data)
>  {
>  	struct ideapad_private *priv = s->private;
>  	unsigned long value;
> +	bool boolval;
>  
>  	if (!priv)
>  		return -EINVAL;
> @@ -250,6 +275,12 @@ static int debugfs_status_show(struct seq_file *s, void *data)
>  	if (!read_ec_data(priv->adev->handle, VPCCMD_R_CAMERA, &value))
>  		seq_printf(s, "Camera status:\t%s(%lu)\n",
>  			   value ? "On" : "Off", value);
> +	seq_puts(s, "=====================\n");
> +
> +	if (!conservation_mode_status(priv->adev->handle, &boolval)) {
> +		seq_printf(s, "Conservation mode:\t%s(%u)\n",
> +			   boolval ? "On" : "Off", boolval);
> +	}
>  
>  	return 0;
>  }
> @@ -456,10 +487,46 @@ static ssize_t __maybe_unused touchpad_store(struct device *dev,
>  
>  static DEVICE_ATTR_RO(touchpad);
>  
> +static ssize_t show_ideapad_conservation(struct device *dev,
> +				struct device_attribute *attr,
> +				char *buf)
> +{
> +	bool result;
> +	struct ideapad_private *priv = dev_get_drvdata(dev);
> +
> +	if (conservation_mode_status(priv->adev->handle, &result))
> +		return sprintf(buf, "-1\n");
> +	return sprintf(buf, "%u\n", result);
> +}
> +
> +static ssize_t store_ideapad_conservation(struct device *dev,
> +				 struct device_attribute *attr,
> +				 const char *buf, size_t count)
> +{
> +	int ret;
> +	bool state;
> +	struct ideapad_private *priv = dev_get_drvdata(dev);
> +
> +	ret = kstrtobool(buf, &state);
> +	if (ret)
> +		return ret;
> +
> +	ret = method_sbmc(priv->adev->handle, state ?
> +					      VPCCMD_CONSERVATION_ON :
> +					      VPCCMD_CONSERVATION_OFF);
> +	if (ret < 0)
> +		return -EIO;
> +	return count;
> +}
> +
> +static DEVICE_ATTR(conservation_mode, 0644, show_ideapad_conservation,
> +					    store_ideapad_conservation);
> +
>  static struct attribute *ideapad_attributes[] = {
>  	&dev_attr_camera_power.attr,
>  	&dev_attr_fan_mode.attr,
>  	&dev_attr_touchpad.attr,
> +	&dev_attr_conservation_mode.attr,
>  	NULL
>  };
>  
> @@ -477,6 +544,9 @@ static umode_t ideapad_is_visible(struct kobject *kobj,
>  		unsigned long value;
>  		supported = !read_ec_data(priv->adev->handle, VPCCMD_R_FAN,
>  					  &value);
> +	} else if (attr == &dev_attr_conservation_mode.attr) {
> +		supported = acpi_has_method(priv->adev->handle, "GBMD") &&
> +			    acpi_has_method(priv->adev->handle, "SBMC");
>  	} else
>  		supported = true;
>  
> 

[toc] | [prev] | [next] | [standalone]


#1653235

FromAndy Shevchenko <andy.shevchenko@gmail.com>
Date2017-05-30 15:30 +0200
Message-ID<tMPnI-7TL-19@gated-at.bofh.it>
In reply to#1652126
On Sun, May 28, 2017 at 4:47 PM, Hao Wei Tee <angelsl@angelsl.xyz> wrote:
> On 5/27/17 3:31 PM, Hao Wei Tee wrote:
>> This exposes the battery conservation mode present on some (?) IdeaPads.
>> The mode is set by calling ACPI method SBMC with argument 3 (on) or
>> 5 (off). Status is reported in bit 5 of the return value of ACPI method
>> GBMD.
>>
>> This patch was written based on an IdeaPad U430p. I'm not sure if the ACPI
>> methods are the same across all IdeaPads, so it would be great if this got more
>> testing across other models before it's merged.
>
> I got someone to test on an IdeaPad Y510p. It works on that too.

Do we have any other option that expose something via sysfs?

-- 
With Best Regards,
Andy Shevchenko

[toc] | [prev] | [next] | [standalone]


#1653262 — Re: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch

FromHao Wei Tee <angelsl@angelsl.xyz>
Date2017-05-30 16:10 +0200
SubjectRe: [PATCH] platform/x86: ideapad-laptop: Expose conservation mode switch
Message-ID<tMQ0q-8oA-15@gated-at.bofh.it>
In reply to#1653235
On 5/30/17 9:22 PM, Andy Shevchenko wrote:
> On Sun, May 28, 2017 at 4:47 PM, Hao Wei Tee <angelsl@angelsl.xyz> wrote:
>> On 5/27/17 3:31 PM, Hao Wei Tee wrote:
>>> This exposes the battery conservation mode present on some (?) IdeaPads.
>>> The mode is set by calling ACPI method SBMC with argument 3 (on) or
>>> 5 (off). Status is reported in bit 5 of the return value of ACPI method
>>> GBMD.
>>>
>>> This patch was written based on an IdeaPad U430p. I'm not sure if the ACPI
>>> methods are the same across all IdeaPads, so it would be great if this got more
>>> testing across other models before it's merged.
>>
>> I got someone to test on an IdeaPad Y510p. It works on that too.
> 
> Do we have any other option that expose something via sysfs?
> 

Sorry, not sure what you meant.

If you meant

> Do we have any other options than expose something via sysfs?

I'm not sure, maybe an ioctl? That wouldn't be very convenient though.

The tp_smapi module (not in mainline) that exposes the battery threshold
functionality for ThinkPads also uses sysfs.

If you meant

> Do we have any other options that expose something via sysfs?

yes, camera_power, fan_mode, touchpad and conservation_mode.

Hao Wei

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web