Skip to content

Commit 303ecf6

Browse files
Wer-Wolfij-intel
authored andcommitted
platform/x86: dell-ddv: Expose the battery manufacture date to userspace
The manufacture date of a given battery is exposed over the Dell DDV WMI interface using the "BatteryManufactureDate" WMI method. The resulting data contains the manufacture date of the battery encoded inside a 16-bit value as described in the Smart Battery Data Specification. Expose this value to userspace using the power supply extension interface. Tested on a Dell Inspiron 3505. Signed-off-by: Armin Wolf <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Ilpo Järvinen <[email protected]> Signed-off-by: Ilpo Järvinen <[email protected]>
1 parent 058de16 commit 303ecf6

File tree

2 files changed

+56
-3
lines changed

2 files changed

+56
-3
lines changed

Documentation/wmi/devices/dell-wmi-ddv.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,6 @@ The date is encoded in the following manner:
118118
- bits 5 to 8 contain the manufacture month.
119119
- bits 9 to 15 contain the manufacture year biased by 1980.
120120

121-
.. note::
122-
The data format needs to be verified on more machines.
123-
124121
WMI method BatterySerialNumber()
125122
--------------------------------
126123

drivers/platform/x86/dell/dell-wmi-ddv.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define pr_format(fmt) KBUILD_MODNAME ": " fmt
99

1010
#include <linux/acpi.h>
11+
#include <linux/bitfield.h>
1112
#include <linux/debugfs.h>
1213
#include <linux/device.h>
1314
#include <linux/device/driver.h>
@@ -42,6 +43,10 @@
4243
/* Battery indices 1, 2 and 3 */
4344
#define DELL_DDV_NUM_BATTERIES 3
4445

46+
#define SBS_MANUFACTURE_YEAR_MASK GENMASK(15, 9)
47+
#define SBS_MANUFACTURE_MONTH_MASK GENMASK(8, 5)
48+
#define SBS_MANUFACTURE_DAY_MASK GENMASK(4, 0)
49+
4550
#define DELL_EPPID_LENGTH 20
4651
#define DELL_EPPID_EXT_LENGTH 23
4752

@@ -744,6 +749,50 @@ static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, cha
744749
return ret;
745750
}
746751

752+
static int dell_wmi_ddv_get_manufacture_date(struct dell_wmi_ddv_data *data, u32 index,
753+
enum power_supply_property psp,
754+
union power_supply_propval *val)
755+
{
756+
u16 year, month, day;
757+
u32 value;
758+
int ret;
759+
760+
ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_MANUFACTURE_DATE,
761+
index, &value);
762+
if (ret < 0)
763+
return ret;
764+
if (value > U16_MAX)
765+
return -ENXIO;
766+
767+
/*
768+
* Some devices report a invalid manufacture date value
769+
* like 0.0.1980. Because of this we have to check the
770+
* whole value before exposing parts of it to user space.
771+
*/
772+
year = FIELD_GET(SBS_MANUFACTURE_YEAR_MASK, value) + 1980;
773+
month = FIELD_GET(SBS_MANUFACTURE_MONTH_MASK, value);
774+
if (month < 1 || month > 12)
775+
return -ENODATA;
776+
777+
day = FIELD_GET(SBS_MANUFACTURE_DAY_MASK, value);
778+
if (day < 1 || day > 31)
779+
return -ENODATA;
780+
781+
switch (psp) {
782+
case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
783+
val->intval = year;
784+
return 0;
785+
case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
786+
val->intval = month;
787+
return 0;
788+
case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
789+
val->intval = day;
790+
return 0;
791+
default:
792+
return -EINVAL;
793+
}
794+
}
795+
747796
static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct power_supply_ext *ext,
748797
void *drvdata, enum power_supply_property psp,
749798
union power_supply_propval *val)
@@ -768,13 +817,20 @@ static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct powe
768817
*/
769818
val->intval = value - 2732;
770819
return 0;
820+
case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
821+
case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
822+
case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
823+
return dell_wmi_ddv_get_manufacture_date(data, index, psp, val);
771824
default:
772825
return -EINVAL;
773826
}
774827
}
775828

776829
static const enum power_supply_property dell_wmi_ddv_properties[] = {
777830
POWER_SUPPLY_PROP_TEMP,
831+
POWER_SUPPLY_PROP_MANUFACTURE_YEAR,
832+
POWER_SUPPLY_PROP_MANUFACTURE_MONTH,
833+
POWER_SUPPLY_PROP_MANUFACTURE_DAY,
778834
};
779835

780836
static const struct power_supply_ext dell_wmi_ddv_extension = {

0 commit comments

Comments
 (0)