1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Linux driver for WMI sensor information on Dell notebooks.
5 * Copyright (C) 2022 Armin Wolf <W_Armin@gmx.de>
8 #define pr_format(fmt) KBUILD_MODNAME ": " fmt
10 #include <linux/acpi.h>
11 #include <linux/debugfs.h>
12 #include <linux/device.h>
13 #include <linux/device/driver.h>
14 #include <linux/dev_printk.h>
15 #include <linux/errno.h>
16 #include <linux/kconfig.h>
17 #include <linux/kernel.h>
18 #include <linux/hwmon.h>
19 #include <linux/kstrtox.h>
20 #include <linux/math64.h>
21 #include <linux/module.h>
22 #include <linux/mutex.h>
23 #include <linux/limits.h>
25 #include <linux/power_supply.h>
26 #include <linux/printk.h>
27 #include <linux/seq_file.h>
28 #include <linux/sysfs.h>
29 #include <linux/types.h>
30 #include <linux/wmi.h>
32 #include <acpi/battery.h>
34 #include <asm/unaligned.h>
36 #define DRIVER_NAME "dell-wmi-ddv"
38 #define DELL_DDV_SUPPORTED_VERSION_MIN 2
39 #define DELL_DDV_SUPPORTED_VERSION_MAX 3
40 #define DELL_DDV_GUID "8A42EA14-4F2A-FD45-6422-0087F7A7E608"
42 #define DELL_EPPID_LENGTH 20
43 #define DELL_EPPID_EXT_LENGTH 23
46 module_param_unsafe(force, bool, 0);
47 MODULE_PARM_DESC(force, "Force loading without checking for supported WMI interface versions");
49 enum dell_ddv_method {
50 DELL_DDV_BATTERY_DESIGN_CAPACITY = 0x01,
51 DELL_DDV_BATTERY_FULL_CHARGE_CAPACITY = 0x02,
52 DELL_DDV_BATTERY_MANUFACTURE_NAME = 0x03,
53 DELL_DDV_BATTERY_MANUFACTURE_DATE = 0x04,
54 DELL_DDV_BATTERY_SERIAL_NUMBER = 0x05,
55 DELL_DDV_BATTERY_CHEMISTRY_VALUE = 0x06,
56 DELL_DDV_BATTERY_TEMPERATURE = 0x07,
57 DELL_DDV_BATTERY_CURRENT = 0x08,
58 DELL_DDV_BATTERY_VOLTAGE = 0x09,
59 DELL_DDV_BATTERY_MANUFACTURER_ACCESS = 0x0A,
60 DELL_DDV_BATTERY_RELATIVE_CHARGE_STATE = 0x0B,
61 DELL_DDV_BATTERY_CYCLE_COUNT = 0x0C,
62 DELL_DDV_BATTERY_EPPID = 0x0D,
63 DELL_DDV_BATTERY_RAW_ANALYTICS_START = 0x0E,
64 DELL_DDV_BATTERY_RAW_ANALYTICS = 0x0F,
65 DELL_DDV_BATTERY_DESIGN_VOLTAGE = 0x10,
66 DELL_DDV_BATTERY_RAW_ANALYTICS_A_BLOCK = 0x11, /* version 3 */
68 DELL_DDV_INTERFACE_VERSION = 0x12,
70 DELL_DDV_FAN_SENSOR_INFORMATION = 0x20,
71 DELL_DDV_THERMAL_SENSOR_INFORMATION = 0x22,
74 struct fan_sensor_entry {
79 struct thermal_sensor_entry {
87 struct combined_channel_info {
88 struct hwmon_channel_info info;
92 struct combined_chip_info {
93 struct hwmon_chip_info chip;
94 const struct hwmon_channel_info *info[];
97 struct dell_wmi_ddv_sensors {
99 struct mutex lock; /* protect caching */
100 unsigned long timestamp;
101 union acpi_object *obj;
105 struct dell_wmi_ddv_data {
106 struct acpi_battery_hook hook;
107 struct device_attribute temp_attr;
108 struct device_attribute eppid_attr;
109 struct dell_wmi_ddv_sensors fans;
110 struct dell_wmi_ddv_sensors temps;
111 struct wmi_device *wdev;
114 static const char * const fan_labels[] = {
116 "Chassis Motherboard Fan",
125 static const char * const fan_dock_labels[] = {
126 "Docking Chassis/Motherboard Fan",
128 "Docking Power Supply Fan",
129 "Docking Chipset Fan",
132 static int dell_wmi_ddv_query_type(struct wmi_device *wdev, enum dell_ddv_method method, u32 arg,
133 union acpi_object **result, acpi_object_type type)
135 struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
136 const struct acpi_buffer in = {
137 .length = sizeof(arg),
140 union acpi_object *obj;
143 ret = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
144 if (ACPI_FAILURE(ret))
151 if (obj->type != type) {
161 static int dell_wmi_ddv_query_integer(struct wmi_device *wdev, enum dell_ddv_method method,
164 union acpi_object *obj;
167 ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_INTEGER);
171 if (obj->integer.value <= U32_MAX)
172 *res = (u32)obj->integer.value;
181 static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_method method,
182 u32 arg, union acpi_object **result)
184 union acpi_object *obj;
188 ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_PACKAGE);
192 if (obj->package.count != 2 ||
193 obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
194 obj->package.elements[1].type != ACPI_TYPE_BUFFER) {
200 buffer_size = obj->package.elements[0].integer.value;
208 if (buffer_size > obj->package.elements[1].buffer.length) {
210 FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n",
211 buffer_size, obj->package.elements[1].buffer.length);
227 static int dell_wmi_ddv_query_string(struct wmi_device *wdev, enum dell_ddv_method method,
228 u32 arg, union acpi_object **result)
230 return dell_wmi_ddv_query_type(wdev, method, arg, result, ACPI_TYPE_STRING);
234 * Needs to be called with lock held, except during initialization.
236 static int dell_wmi_ddv_update_sensors(struct wmi_device *wdev, enum dell_ddv_method method,
237 struct dell_wmi_ddv_sensors *sensors, size_t entry_size)
239 u64 buffer_size, rem, entries;
240 union acpi_object *obj;
245 if (time_before(jiffies, sensors->timestamp + HZ))
252 ret = dell_wmi_ddv_query_buffer(wdev, method, 0, &obj);
256 /* buffer format sanity check */
257 buffer_size = obj->package.elements[0].integer.value;
258 buffer = obj->package.elements[1].buffer.pointer;
259 entries = div64_u64_rem(buffer_size, entry_size, &rem);
260 if (rem != 1 || buffer[buffer_size - 1] != 0xff) {
271 sensors->entries = entries;
272 sensors->timestamp = jiffies;
282 static umode_t dell_wmi_ddv_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
288 static int dell_wmi_ddv_fan_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
291 struct fan_sensor_entry *entry;
294 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
295 &data->fans, sizeof(*entry));
299 if (channel >= data->fans.entries)
302 entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
304 case hwmon_fan_input:
305 *val = get_unaligned_le16(&entry[channel].rpm);
314 static int dell_wmi_ddv_temp_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
317 struct thermal_sensor_entry *entry;
320 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
321 &data->temps, sizeof(*entry));
325 if (channel >= data->temps.entries)
328 entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
330 case hwmon_temp_input:
331 *val = entry[channel].now * 1000;
334 *val = entry[channel].min * 1000;
337 *val = entry[channel].max * 1000;
346 static int dell_wmi_ddv_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
347 int channel, long *val)
349 struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
354 mutex_lock(&data->fans.lock);
355 ret = dell_wmi_ddv_fan_read_channel(data, attr, channel, val);
356 mutex_unlock(&data->fans.lock);
359 mutex_lock(&data->temps.lock);
360 ret = dell_wmi_ddv_temp_read_channel(data, attr, channel, val);
361 mutex_unlock(&data->temps.lock);
370 static int dell_wmi_ddv_fan_read_string(struct dell_wmi_ddv_data *data, int channel,
373 struct fan_sensor_entry *entry;
377 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
378 &data->fans, sizeof(*entry));
382 if (channel >= data->fans.entries)
385 entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
386 type = entry[channel].type;
389 *str = fan_labels[type];
392 *str = fan_dock_labels[type - 0x11];
395 *str = "Unknown Fan";
402 static int dell_wmi_ddv_temp_read_string(struct dell_wmi_ddv_data *data, int channel,
405 struct thermal_sensor_entry *entry;
408 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
409 &data->temps, sizeof(*entry));
413 if (channel >= data->temps.entries)
416 entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
417 switch (entry[channel].type) {
425 *str = "Memory"; /* sometimes called DIMM */
431 *str = "Ambient"; /* sometimes called SKIN */
459 static int dell_wmi_ddv_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
460 int channel, const char **str)
462 struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
468 case hwmon_fan_label:
469 mutex_lock(&data->fans.lock);
470 ret = dell_wmi_ddv_fan_read_string(data, channel, str);
471 mutex_unlock(&data->fans.lock);
479 case hwmon_temp_label:
480 mutex_lock(&data->temps.lock);
481 ret = dell_wmi_ddv_temp_read_string(data, channel, str);
482 mutex_unlock(&data->temps.lock);
495 static const struct hwmon_ops dell_wmi_ddv_ops = {
496 .is_visible = dell_wmi_ddv_is_visible,
497 .read = dell_wmi_ddv_read,
498 .read_string = dell_wmi_ddv_read_string,
501 static struct hwmon_channel_info *dell_wmi_ddv_channel_create(struct device *dev, u64 count,
502 enum hwmon_sensor_types type,
505 struct combined_channel_info *cinfo;
508 cinfo = devm_kzalloc(dev, struct_size(cinfo, config, count + 1), GFP_KERNEL);
510 return ERR_PTR(-ENOMEM);
512 cinfo->info.type = type;
513 cinfo->info.config = cinfo->config;
515 for (i = 0; i < count; i++)
516 cinfo->config[i] = config;
521 static void dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors *sensors)
523 if (!sensors->active)
526 mutex_lock(&sensors->lock);
529 mutex_unlock(&sensors->lock);
532 static void dell_wmi_ddv_hwmon_cache_destroy(void *data)
534 struct dell_wmi_ddv_sensors *sensors = data;
536 sensors->active = false;
537 mutex_destroy(&sensors->lock);
541 static struct hwmon_channel_info *dell_wmi_ddv_channel_init(struct wmi_device *wdev,
542 enum dell_ddv_method method,
543 struct dell_wmi_ddv_sensors *sensors,
545 enum hwmon_sensor_types type,
548 struct hwmon_channel_info *info;
551 ret = dell_wmi_ddv_update_sensors(wdev, method, sensors, entry_size);
555 mutex_init(&sensors->lock);
556 sensors->active = true;
558 ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
562 info = dell_wmi_ddv_channel_create(&wdev->dev, sensors->entries, type, config);
564 devm_release_action(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
569 static int dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data *data)
571 struct wmi_device *wdev = data->wdev;
572 struct combined_chip_info *cinfo;
573 struct hwmon_channel_info *info;
578 if (!devres_open_group(&wdev->dev, dell_wmi_ddv_hwmon_add, GFP_KERNEL))
581 cinfo = devm_kzalloc(&wdev->dev, struct_size(cinfo, info, 4), GFP_KERNEL);
588 cinfo->chip.ops = &dell_wmi_ddv_ops;
589 cinfo->chip.info = cinfo->info;
591 info = dell_wmi_ddv_channel_create(&wdev->dev, 1, hwmon_chip, HWMON_C_REGISTER_TZ);
598 cinfo->info[index] = info;
601 info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_FAN_SENSOR_INFORMATION, &data->fans,
602 sizeof(struct fan_sensor_entry), hwmon_fan,
603 (HWMON_F_INPUT | HWMON_F_LABEL));
605 cinfo->info[index] = info;
609 info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, &data->temps,
610 sizeof(struct thermal_sensor_entry), hwmon_temp,
611 (HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
614 cinfo->info[index] = info;
624 hdev = devm_hwmon_device_register_with_info(&wdev->dev, "dell_ddv", data, &cinfo->chip,
632 devres_close_group(&wdev->dev, dell_wmi_ddv_hwmon_add);
637 devres_release_group(&wdev->dev, dell_wmi_ddv_hwmon_add);
642 static int dell_wmi_ddv_battery_index(struct acpi_device *acpi_dev, u32 *index)
646 uid_str = acpi_device_uid(acpi_dev);
650 return kstrtou32(uid_str, 10, index);
653 static ssize_t temp_show(struct device *dev, struct device_attribute *attr, char *buf)
655 struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, temp_attr);
659 ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index);
663 ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index, &value);
667 /* Use 2731 instead of 2731.5 to avoid unnecessary rounding */
668 return sysfs_emit(buf, "%d\n", value - 2731);
671 static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
673 struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, eppid_attr);
674 union acpi_object *obj;
678 ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index);
682 ret = dell_wmi_ddv_query_string(data->wdev, DELL_DDV_BATTERY_EPPID, index, &obj);
686 if (obj->string.length != DELL_EPPID_LENGTH && obj->string.length != DELL_EPPID_EXT_LENGTH)
687 dev_info_once(&data->wdev->dev, FW_INFO "Suspicious ePPID length (%d)\n",
690 ret = sysfs_emit(buf, "%s\n", obj->string.pointer);
697 static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
699 struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
703 /* Return 0 instead of error to avoid being unloaded */
704 ret = dell_wmi_ddv_battery_index(to_acpi_device(battery->dev.parent), &index);
708 ret = device_create_file(&battery->dev, &data->temp_attr);
712 ret = device_create_file(&battery->dev, &data->eppid_attr);
714 device_remove_file(&battery->dev, &data->temp_attr);
722 static int dell_wmi_ddv_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
724 struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
726 device_remove_file(&battery->dev, &data->temp_attr);
727 device_remove_file(&battery->dev, &data->eppid_attr);
732 static void dell_wmi_ddv_battery_remove(void *data)
734 struct acpi_battery_hook *hook = data;
736 battery_hook_unregister(hook);
739 static int dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data *data)
741 data->hook.name = "Dell DDV Battery Extension";
742 data->hook.add_battery = dell_wmi_ddv_add_battery;
743 data->hook.remove_battery = dell_wmi_ddv_remove_battery;
745 sysfs_attr_init(&data->temp_attr.attr);
746 data->temp_attr.attr.name = "temp";
747 data->temp_attr.attr.mode = 0444;
748 data->temp_attr.show = temp_show;
750 sysfs_attr_init(&data->eppid_attr.attr);
751 data->eppid_attr.attr.name = "eppid";
752 data->eppid_attr.attr.mode = 0444;
753 data->eppid_attr.show = eppid_show;
755 battery_hook_register(&data->hook);
757 return devm_add_action_or_reset(&data->wdev->dev, dell_wmi_ddv_battery_remove, &data->hook);
760 static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method)
762 struct device *dev = seq->private;
763 struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
764 union acpi_object *obj;
769 ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj);
773 size = obj->package.elements[0].integer.value;
774 buf = obj->package.elements[1].buffer.pointer;
775 ret = seq_write(seq, buf, size);
781 static int dell_wmi_ddv_fan_read(struct seq_file *seq, void *offset)
783 return dell_wmi_ddv_buffer_read(seq, DELL_DDV_FAN_SENSOR_INFORMATION);
786 static int dell_wmi_ddv_temp_read(struct seq_file *seq, void *offset)
788 return dell_wmi_ddv_buffer_read(seq, DELL_DDV_THERMAL_SENSOR_INFORMATION);
791 static void dell_wmi_ddv_debugfs_remove(void *data)
793 struct dentry *entry = data;
795 debugfs_remove(entry);
798 static void dell_wmi_ddv_debugfs_init(struct wmi_device *wdev)
800 struct dentry *entry;
803 scnprintf(name, ARRAY_SIZE(name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));
804 entry = debugfs_create_dir(name, NULL);
806 debugfs_create_devm_seqfile(&wdev->dev, "fan_sensor_information", entry,
807 dell_wmi_ddv_fan_read);
808 debugfs_create_devm_seqfile(&wdev->dev, "thermal_sensor_information", entry,
809 dell_wmi_ddv_temp_read);
811 devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_debugfs_remove, entry);
814 static int dell_wmi_ddv_probe(struct wmi_device *wdev, const void *context)
816 struct dell_wmi_ddv_data *data;
820 ret = dell_wmi_ddv_query_integer(wdev, DELL_DDV_INTERFACE_VERSION, 0, &version);
824 dev_dbg(&wdev->dev, "WMI interface version: %d\n", version);
825 if (version < DELL_DDV_SUPPORTED_VERSION_MIN || version > DELL_DDV_SUPPORTED_VERSION_MAX) {
829 dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u)\n",
833 data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
837 dev_set_drvdata(&wdev->dev, data);
840 dell_wmi_ddv_debugfs_init(wdev);
842 if (IS_REACHABLE(CONFIG_ACPI_BATTERY)) {
843 ret = dell_wmi_ddv_battery_add(data);
844 if (ret < 0 && ret != -ENODEV)
845 dev_warn(&wdev->dev, "Unable to register ACPI battery hook: %d\n", ret);
848 if (IS_REACHABLE(CONFIG_HWMON)) {
849 ret = dell_wmi_ddv_hwmon_add(data);
850 if (ret < 0 && ret != -ENODEV)
851 dev_warn(&wdev->dev, "Unable to register hwmon interface: %d\n", ret);
857 static int dell_wmi_ddv_resume(struct device *dev)
859 struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
861 /* Force re-reading of all active sensors */
862 dell_wmi_ddv_hwmon_cache_invalidate(&data->fans);
863 dell_wmi_ddv_hwmon_cache_invalidate(&data->temps);
868 static DEFINE_SIMPLE_DEV_PM_OPS(dell_wmi_ddv_dev_pm_ops, NULL, dell_wmi_ddv_resume);
870 static const struct wmi_device_id dell_wmi_ddv_id_table[] = {
871 { DELL_DDV_GUID, NULL },
874 MODULE_DEVICE_TABLE(wmi, dell_wmi_ddv_id_table);
876 static struct wmi_driver dell_wmi_ddv_driver = {
879 .probe_type = PROBE_PREFER_ASYNCHRONOUS,
880 .pm = pm_sleep_ptr(&dell_wmi_ddv_dev_pm_ops),
882 .id_table = dell_wmi_ddv_id_table,
883 .probe = dell_wmi_ddv_probe,
885 module_wmi_driver(dell_wmi_ddv_driver);
887 MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
888 MODULE_DESCRIPTION("Dell WMI sensor driver");
889 MODULE_LICENSE("GPL");