xref: /linux/drivers/platform/x86/dell/dell-wmi-ddv.c (revision 964ebc07c546c76b78aea5b6dff0d02c602d4793)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Linux driver for WMI sensor information on Dell notebooks.
4  *
5  * Copyright (C) 2022 Armin Wolf <W_Armin@gmx.de>
6  */
7 
8 #define pr_format(fmt) KBUILD_MODNAME ": " fmt
9 
10 #include <linux/acpi.h>
11 #include <linux/bitfield.h>
12 #include <linux/debugfs.h>
13 #include <linux/device.h>
14 #include <linux/device/driver.h>
15 #include <linux/dev_printk.h>
16 #include <linux/errno.h>
17 #include <linux/kconfig.h>
18 #include <linux/kernel.h>
19 #include <linux/hwmon.h>
20 #include <linux/kstrtox.h>
21 #include <linux/math64.h>
22 #include <linux/module.h>
23 #include <linux/mutex.h>
24 #include <linux/limits.h>
25 #include <linux/pm.h>
26 #include <linux/power_supply.h>
27 #include <linux/printk.h>
28 #include <linux/seq_file.h>
29 #include <linux/sysfs.h>
30 #include <linux/types.h>
31 #include <linux/wmi.h>
32 
33 #include <acpi/battery.h>
34 
35 #include <linux/unaligned.h>
36 
37 #define DRIVER_NAME	"dell-wmi-ddv"
38 
39 #define DELL_DDV_SUPPORTED_VERSION_MIN	2
40 #define DELL_DDV_SUPPORTED_VERSION_MAX	3
41 #define DELL_DDV_GUID	"8A42EA14-4F2A-FD45-6422-0087F7A7E608"
42 
43 /* Battery indices 1, 2 and 3 */
44 #define DELL_DDV_NUM_BATTERIES		3
45 
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 
50 #define MA_FAILURE_MODE_MASK			GENMASK(11, 8)
51 #define MA_FAILURE_MODE_PERMANENT		0x9
52 #define MA_FAILURE_MODE_OVERHEAT		0xA
53 #define MA_FAILURE_MODE_OVERCURRENT		0xB
54 
55 #define MA_PERMANENT_FAILURE_CODE_MASK		GENMASK(13, 12)
56 #define MA_PERMANENT_FAILURE_FUSE_BLOWN		0x0
57 #define MA_PERMANENT_FAILURE_CELL_IMBALANCE	0x1
58 #define MA_PERMANENT_FAILURE_OVERVOLTAGE	0x2
59 #define MA_PERMANENT_FAILURE_FET_FAILURE	0x3
60 
61 #define MA_OVERHEAT_FAILURE_CODE_MASK		GENMASK(15, 12)
62 #define MA_OVERHEAT_FAILURE_START		0x5
63 #define MA_OVERHEAT_FAILURE_CHARGING		0x7
64 #define MA_OVERHEAT_FAILURE_DISCHARGING		0x8
65 
66 #define MA_OVERCURRENT_FAILURE_CODE_MASK	GENMASK(15, 12)
67 #define MA_OVERCURRENT_FAILURE_CHARGING		0x6
68 #define MA_OVERCURRENT_FAILURE_DISCHARGING	0xB
69 
70 #define DELL_EPPID_LENGTH	20
71 #define DELL_EPPID_EXT_LENGTH	23
72 
73 static bool force;
74 module_param_unsafe(force, bool, 0);
75 MODULE_PARM_DESC(force, "Force loading without checking for supported WMI interface versions");
76 
77 enum dell_ddv_method {
78 	DELL_DDV_BATTERY_DESIGN_CAPACITY	= 0x01,
79 	DELL_DDV_BATTERY_FULL_CHARGE_CAPACITY	= 0x02,
80 	DELL_DDV_BATTERY_MANUFACTURE_NAME	= 0x03,
81 	DELL_DDV_BATTERY_MANUFACTURE_DATE	= 0x04,
82 	DELL_DDV_BATTERY_SERIAL_NUMBER		= 0x05,
83 	DELL_DDV_BATTERY_CHEMISTRY_VALUE	= 0x06,
84 	DELL_DDV_BATTERY_TEMPERATURE		= 0x07,
85 	DELL_DDV_BATTERY_CURRENT		= 0x08,
86 	DELL_DDV_BATTERY_VOLTAGE		= 0x09,
87 	DELL_DDV_BATTERY_MANUFACTURER_ACCESS	= 0x0A,
88 	DELL_DDV_BATTERY_RELATIVE_CHARGE_STATE	= 0x0B,
89 	DELL_DDV_BATTERY_CYCLE_COUNT		= 0x0C,
90 	DELL_DDV_BATTERY_EPPID			= 0x0D,
91 	DELL_DDV_BATTERY_RAW_ANALYTICS_START	= 0x0E,
92 	DELL_DDV_BATTERY_RAW_ANALYTICS		= 0x0F,
93 	DELL_DDV_BATTERY_DESIGN_VOLTAGE		= 0x10,
94 	DELL_DDV_BATTERY_RAW_ANALYTICS_A_BLOCK	= 0x11, /* version 3 */
95 
96 	DELL_DDV_INTERFACE_VERSION		= 0x12,
97 
98 	DELL_DDV_FAN_SENSOR_INFORMATION		= 0x20,
99 	DELL_DDV_THERMAL_SENSOR_INFORMATION	= 0x22,
100 };
101 
102 struct fan_sensor_entry {
103 	u8 type;
104 	__le16 rpm;
105 } __packed;
106 
107 struct thermal_sensor_entry {
108 	u8 type;
109 	s8 now;
110 	s8 min;
111 	s8 max;
112 	u8 unknown;
113 } __packed;
114 
115 struct combined_channel_info {
116 	struct hwmon_channel_info info;
117 	u32 config[];
118 };
119 
120 struct combined_chip_info {
121 	struct hwmon_chip_info chip;
122 	const struct hwmon_channel_info *info[];
123 };
124 
125 struct dell_wmi_ddv_sensors {
126 	bool active;
127 	struct mutex lock;	/* protect caching */
128 	unsigned long timestamp;
129 	union acpi_object *obj;
130 	u64 entries;
131 };
132 
133 struct dell_wmi_ddv_data {
134 	struct acpi_battery_hook hook;
135 	struct device_attribute eppid_attr;
136 	struct mutex translation_cache_lock;	/* Protects the translation cache */
137 	struct power_supply *translation_cache[DELL_DDV_NUM_BATTERIES];
138 	struct dell_wmi_ddv_sensors fans;
139 	struct dell_wmi_ddv_sensors temps;
140 	struct wmi_device *wdev;
141 };
142 
143 static const char * const fan_labels[] = {
144 	"CPU Fan",
145 	"Chassis Motherboard Fan",
146 	"Video Fan",
147 	"Power Supply Fan",
148 	"Chipset Fan",
149 	"Memory Fan",
150 	"PCI Fan",
151 	"HDD Fan",
152 };
153 
154 static const char * const fan_dock_labels[] = {
155 	"Docking Chassis/Motherboard Fan",
156 	"Docking Video Fan",
157 	"Docking Power Supply Fan",
158 	"Docking Chipset Fan",
159 };
160 
dell_wmi_ddv_query_type(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,union acpi_object ** result,acpi_object_type type)161 static int dell_wmi_ddv_query_type(struct wmi_device *wdev, enum dell_ddv_method method, u32 arg,
162 				   union acpi_object **result, acpi_object_type type)
163 {
164 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
165 	const struct acpi_buffer in = {
166 		.length = sizeof(arg),
167 		.pointer = &arg,
168 	};
169 	union acpi_object *obj;
170 	acpi_status ret;
171 
172 	ret = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
173 	if (ACPI_FAILURE(ret))
174 		return -EIO;
175 
176 	obj = out.pointer;
177 	if (!obj)
178 		return -ENODATA;
179 
180 	if (obj->type != type) {
181 		kfree(obj);
182 		return -ENOMSG;
183 	}
184 
185 	*result = obj;
186 
187 	return 0;
188 }
189 
dell_wmi_ddv_query_integer(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,u32 * res)190 static int dell_wmi_ddv_query_integer(struct wmi_device *wdev, enum dell_ddv_method method,
191 				      u32 arg, u32 *res)
192 {
193 	union acpi_object *obj;
194 	int ret;
195 
196 	ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_INTEGER);
197 	if (ret < 0)
198 		return ret;
199 
200 	if (obj->integer.value <= U32_MAX)
201 		*res = (u32)obj->integer.value;
202 	else
203 		ret = -ERANGE;
204 
205 	kfree(obj);
206 
207 	return ret;
208 }
209 
dell_wmi_ddv_query_buffer(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,union acpi_object ** result)210 static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_method method,
211 				     u32 arg, union acpi_object **result)
212 {
213 	union acpi_object *obj;
214 	u64 buffer_size;
215 	int ret;
216 
217 	ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_PACKAGE);
218 	if (ret < 0)
219 		return ret;
220 
221 	if (obj->package.count != 2 ||
222 	    obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
223 	    obj->package.elements[1].type != ACPI_TYPE_BUFFER) {
224 		ret = -ENOMSG;
225 
226 		goto err_free;
227 	}
228 
229 	buffer_size = obj->package.elements[0].integer.value;
230 
231 	if (!buffer_size) {
232 		ret = -ENODATA;
233 
234 		goto err_free;
235 	}
236 
237 	if (buffer_size > obj->package.elements[1].buffer.length) {
238 		dev_warn(&wdev->dev,
239 			 FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n",
240 			 buffer_size, obj->package.elements[1].buffer.length);
241 		ret = -EMSGSIZE;
242 
243 		goto err_free;
244 	}
245 
246 	*result = obj;
247 
248 	return 0;
249 
250 err_free:
251 	kfree(obj);
252 
253 	return ret;
254 }
255 
dell_wmi_ddv_query_string(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,union acpi_object ** result)256 static int dell_wmi_ddv_query_string(struct wmi_device *wdev, enum dell_ddv_method method,
257 				     u32 arg, union acpi_object **result)
258 {
259 	return dell_wmi_ddv_query_type(wdev, method, arg, result, ACPI_TYPE_STRING);
260 }
261 
262 /*
263  * Needs to be called with lock held, except during initialization.
264  */
dell_wmi_ddv_update_sensors(struct wmi_device * wdev,enum dell_ddv_method method,struct dell_wmi_ddv_sensors * sensors,size_t entry_size)265 static int dell_wmi_ddv_update_sensors(struct wmi_device *wdev, enum dell_ddv_method method,
266 				       struct dell_wmi_ddv_sensors *sensors, size_t entry_size)
267 {
268 	u64 buffer_size, rem, entries;
269 	union acpi_object *obj;
270 	u8 *buffer;
271 	int ret;
272 
273 	if (sensors->obj) {
274 		if (time_before(jiffies, sensors->timestamp + HZ))
275 			return 0;
276 
277 		kfree(sensors->obj);
278 		sensors->obj = NULL;
279 	}
280 
281 	ret = dell_wmi_ddv_query_buffer(wdev, method, 0, &obj);
282 	if (ret < 0)
283 		return ret;
284 
285 	/* buffer format sanity check */
286 	buffer_size = obj->package.elements[0].integer.value;
287 	buffer = obj->package.elements[1].buffer.pointer;
288 	entries = div64_u64_rem(buffer_size, entry_size, &rem);
289 	if (rem != 1 || buffer[buffer_size - 1] != 0xff) {
290 		ret = -ENOMSG;
291 		goto err_free;
292 	}
293 
294 	if (!entries) {
295 		ret = -ENODATA;
296 		goto err_free;
297 	}
298 
299 	sensors->obj = obj;
300 	sensors->entries = entries;
301 	sensors->timestamp = jiffies;
302 
303 	return 0;
304 
305 err_free:
306 	kfree(obj);
307 
308 	return ret;
309 }
310 
dell_wmi_ddv_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)311 static umode_t dell_wmi_ddv_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
312 				       int channel)
313 {
314 	return 0444;
315 }
316 
dell_wmi_ddv_fan_read_channel(struct dell_wmi_ddv_data * data,u32 attr,int channel,long * val)317 static int dell_wmi_ddv_fan_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
318 					 long *val)
319 {
320 	struct fan_sensor_entry *entry;
321 	int ret;
322 
323 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
324 					  &data->fans, sizeof(*entry));
325 	if (ret < 0)
326 		return ret;
327 
328 	if (channel >= data->fans.entries)
329 		return -ENXIO;
330 
331 	entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
332 	switch (attr) {
333 	case hwmon_fan_input:
334 		*val = get_unaligned_le16(&entry[channel].rpm);
335 		return 0;
336 	default:
337 		break;
338 	}
339 
340 	return -EOPNOTSUPP;
341 }
342 
dell_wmi_ddv_temp_read_channel(struct dell_wmi_ddv_data * data,u32 attr,int channel,long * val)343 static int dell_wmi_ddv_temp_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
344 					  long *val)
345 {
346 	struct thermal_sensor_entry *entry;
347 	int ret;
348 
349 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
350 					  &data->temps, sizeof(*entry));
351 	if (ret < 0)
352 		return ret;
353 
354 	if (channel >= data->temps.entries)
355 		return -ENXIO;
356 
357 	entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
358 	switch (attr) {
359 	case hwmon_temp_input:
360 		*val = entry[channel].now * 1000;
361 		return 0;
362 	case hwmon_temp_min:
363 		*val = entry[channel].min * 1000;
364 		return 0;
365 	case hwmon_temp_max:
366 		*val = entry[channel].max * 1000;
367 		return 0;
368 	default:
369 		break;
370 	}
371 
372 	return -EOPNOTSUPP;
373 }
374 
dell_wmi_ddv_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)375 static int dell_wmi_ddv_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
376 			     int channel, long *val)
377 {
378 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
379 	int ret;
380 
381 	switch (type) {
382 	case hwmon_fan:
383 		mutex_lock(&data->fans.lock);
384 		ret = dell_wmi_ddv_fan_read_channel(data, attr, channel, val);
385 		mutex_unlock(&data->fans.lock);
386 		return ret;
387 	case hwmon_temp:
388 		mutex_lock(&data->temps.lock);
389 		ret = dell_wmi_ddv_temp_read_channel(data, attr, channel, val);
390 		mutex_unlock(&data->temps.lock);
391 		return ret;
392 	default:
393 		break;
394 	}
395 
396 	return -EOPNOTSUPP;
397 }
398 
dell_wmi_ddv_fan_read_string(struct dell_wmi_ddv_data * data,int channel,const char ** str)399 static int dell_wmi_ddv_fan_read_string(struct dell_wmi_ddv_data *data, int channel,
400 					const char **str)
401 {
402 	struct fan_sensor_entry *entry;
403 	int ret;
404 	u8 type;
405 
406 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
407 					  &data->fans, sizeof(*entry));
408 	if (ret < 0)
409 		return ret;
410 
411 	if (channel >= data->fans.entries)
412 		return -ENXIO;
413 
414 	entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
415 	type = entry[channel].type;
416 	switch (type) {
417 	case 0x00 ... 0x07:
418 		*str = fan_labels[type];
419 		break;
420 	case 0x11 ... 0x14:
421 		*str = fan_dock_labels[type - 0x11];
422 		break;
423 	default:
424 		*str = "Unknown Fan";
425 		break;
426 	}
427 
428 	return 0;
429 }
430 
dell_wmi_ddv_temp_read_string(struct dell_wmi_ddv_data * data,int channel,const char ** str)431 static int dell_wmi_ddv_temp_read_string(struct dell_wmi_ddv_data *data, int channel,
432 					 const char **str)
433 {
434 	struct thermal_sensor_entry *entry;
435 	int ret;
436 
437 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
438 					  &data->temps, sizeof(*entry));
439 	if (ret < 0)
440 		return ret;
441 
442 	if (channel >= data->temps.entries)
443 		return -ENXIO;
444 
445 	entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
446 	switch (entry[channel].type) {
447 	case 0x00:
448 		*str = "CPU";
449 		break;
450 	case 0x11:
451 		*str = "Video";
452 		break;
453 	case 0x22:
454 		*str = "Memory"; /* sometimes called DIMM */
455 		break;
456 	case 0x33:
457 		*str = "Other";
458 		break;
459 	case 0x44:
460 		*str = "Ambient"; /* sometimes called SKIN */
461 		break;
462 	case 0x52:
463 		*str = "SODIMM";
464 		break;
465 	case 0x55:
466 		*str = "HDD";
467 		break;
468 	case 0x62:
469 		*str = "SODIMM 2";
470 		break;
471 	case 0x73:
472 		*str = "NB";
473 		break;
474 	case 0x83:
475 		*str = "Charger";
476 		break;
477 	case 0xbb:
478 		*str = "Memory 3";
479 		break;
480 	default:
481 		*str = "Unknown";
482 		break;
483 	}
484 
485 	return 0;
486 }
487 
dell_wmi_ddv_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** str)488 static int dell_wmi_ddv_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
489 				    int channel, const char **str)
490 {
491 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
492 	int ret;
493 
494 	switch (type) {
495 	case hwmon_fan:
496 		switch (attr) {
497 		case hwmon_fan_label:
498 			mutex_lock(&data->fans.lock);
499 			ret = dell_wmi_ddv_fan_read_string(data, channel, str);
500 			mutex_unlock(&data->fans.lock);
501 			return ret;
502 		default:
503 			break;
504 		}
505 		break;
506 	case hwmon_temp:
507 		switch (attr) {
508 		case hwmon_temp_label:
509 			mutex_lock(&data->temps.lock);
510 			ret = dell_wmi_ddv_temp_read_string(data, channel, str);
511 			mutex_unlock(&data->temps.lock);
512 			return ret;
513 		default:
514 			break;
515 		}
516 		break;
517 	default:
518 		break;
519 	}
520 
521 	return -EOPNOTSUPP;
522 }
523 
524 static const struct hwmon_ops dell_wmi_ddv_ops = {
525 	.is_visible = dell_wmi_ddv_is_visible,
526 	.read = dell_wmi_ddv_read,
527 	.read_string = dell_wmi_ddv_read_string,
528 };
529 
dell_wmi_ddv_channel_create(struct device * dev,u64 count,enum hwmon_sensor_types type,u32 config)530 static struct hwmon_channel_info *dell_wmi_ddv_channel_create(struct device *dev, u64 count,
531 							      enum hwmon_sensor_types type,
532 							      u32 config)
533 {
534 	struct combined_channel_info *cinfo;
535 	int i;
536 
537 	cinfo = devm_kzalloc(dev, struct_size(cinfo, config, count + 1), GFP_KERNEL);
538 	if (!cinfo)
539 		return ERR_PTR(-ENOMEM);
540 
541 	cinfo->info.type = type;
542 	cinfo->info.config = cinfo->config;
543 
544 	for (i = 0; i < count; i++)
545 		cinfo->config[i] = config;
546 
547 	return &cinfo->info;
548 }
549 
dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors * sensors)550 static void dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors *sensors)
551 {
552 	if (!sensors->active)
553 		return;
554 
555 	mutex_lock(&sensors->lock);
556 	kfree(sensors->obj);
557 	sensors->obj = NULL;
558 	mutex_unlock(&sensors->lock);
559 }
560 
dell_wmi_ddv_hwmon_cache_destroy(void * data)561 static void dell_wmi_ddv_hwmon_cache_destroy(void *data)
562 {
563 	struct dell_wmi_ddv_sensors *sensors = data;
564 
565 	sensors->active = false;
566 	mutex_destroy(&sensors->lock);
567 	kfree(sensors->obj);
568 }
569 
dell_wmi_ddv_channel_init(struct wmi_device * wdev,enum dell_ddv_method method,struct dell_wmi_ddv_sensors * sensors,size_t entry_size,enum hwmon_sensor_types type,u32 config)570 static struct hwmon_channel_info *dell_wmi_ddv_channel_init(struct wmi_device *wdev,
571 							    enum dell_ddv_method method,
572 							    struct dell_wmi_ddv_sensors *sensors,
573 							    size_t entry_size,
574 							    enum hwmon_sensor_types type,
575 							    u32 config)
576 {
577 	struct hwmon_channel_info *info;
578 	int ret;
579 
580 	ret = dell_wmi_ddv_update_sensors(wdev, method, sensors, entry_size);
581 	if (ret < 0)
582 		return ERR_PTR(ret);
583 
584 	mutex_init(&sensors->lock);
585 	sensors->active = true;
586 
587 	ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
588 	if (ret < 0)
589 		return ERR_PTR(ret);
590 
591 	info = dell_wmi_ddv_channel_create(&wdev->dev, sensors->entries, type, config);
592 	if (IS_ERR(info))
593 		devm_release_action(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
594 
595 	return info;
596 }
597 
dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data * data)598 static int dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data *data)
599 {
600 	struct wmi_device *wdev = data->wdev;
601 	struct combined_chip_info *cinfo;
602 	struct hwmon_channel_info *info;
603 	struct device *hdev;
604 	int index = 0;
605 	int ret;
606 
607 	if (!devres_open_group(&wdev->dev, dell_wmi_ddv_hwmon_add, GFP_KERNEL))
608 		return -ENOMEM;
609 
610 	cinfo = devm_kzalloc(&wdev->dev, struct_size(cinfo, info, 4), GFP_KERNEL);
611 	if (!cinfo) {
612 		ret = -ENOMEM;
613 
614 		goto err_release;
615 	}
616 
617 	cinfo->chip.ops = &dell_wmi_ddv_ops;
618 	cinfo->chip.info = cinfo->info;
619 
620 	info = dell_wmi_ddv_channel_create(&wdev->dev, 1, hwmon_chip, HWMON_C_REGISTER_TZ);
621 	if (IS_ERR(info)) {
622 		ret = PTR_ERR(info);
623 
624 		goto err_release;
625 	}
626 
627 	cinfo->info[index] = info;
628 	index++;
629 
630 	info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_FAN_SENSOR_INFORMATION, &data->fans,
631 					 sizeof(struct fan_sensor_entry), hwmon_fan,
632 					 (HWMON_F_INPUT | HWMON_F_LABEL));
633 	if (!IS_ERR(info)) {
634 		cinfo->info[index] = info;
635 		index++;
636 	}
637 
638 	info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, &data->temps,
639 					 sizeof(struct thermal_sensor_entry), hwmon_temp,
640 					 (HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
641 					 HWMON_T_LABEL));
642 	if (!IS_ERR(info)) {
643 		cinfo->info[index] = info;
644 		index++;
645 	}
646 
647 	if (index < 2) {
648 		/* Finding no available sensors is not an error */
649 		ret = 0;
650 
651 		goto err_release;
652 	}
653 
654 	hdev = devm_hwmon_device_register_with_info(&wdev->dev, "dell_ddv", data, &cinfo->chip,
655 						    NULL);
656 	if (IS_ERR(hdev)) {
657 		ret = PTR_ERR(hdev);
658 
659 		goto err_release;
660 	}
661 
662 	devres_close_group(&wdev->dev, dell_wmi_ddv_hwmon_add);
663 
664 	return 0;
665 
666 err_release:
667 	devres_release_group(&wdev->dev, dell_wmi_ddv_hwmon_add);
668 
669 	return ret;
670 }
671 
dell_wmi_ddv_battery_translate(struct dell_wmi_ddv_data * data,struct power_supply * battery,u32 * index)672 static int dell_wmi_ddv_battery_translate(struct dell_wmi_ddv_data *data,
673 					  struct power_supply *battery, u32 *index)
674 {
675 	u32 serial_dec, serial_hex, serial;
676 	union power_supply_propval val;
677 	int ret;
678 
679 	guard(mutex)(&data->translation_cache_lock);
680 
681 	for (int i = 0; i < ARRAY_SIZE(data->translation_cache); i++) {
682 		if (data->translation_cache[i] == battery) {
683 			dev_dbg(&data->wdev->dev, "Translation cache hit for battery index %u\n",
684 				i + 1);
685 			*index = i + 1;
686 			return 0;
687 		}
688 	}
689 
690 	dev_dbg(&data->wdev->dev, "Translation cache miss\n");
691 
692 	/*
693 	 * Perform a translation between a ACPI battery and a battery index.
694 	 * We have to use power_supply_get_property_direct() here because this
695 	 * function will also get called from the callbacks of the power supply
696 	 * extension.
697 	 */
698 	ret = power_supply_get_property_direct(battery, POWER_SUPPLY_PROP_SERIAL_NUMBER, &val);
699 	if (ret < 0)
700 		return ret;
701 
702 	/*
703 	 * Some devices display the serial number of the ACPI battery (string!) as a decimal
704 	 * number while other devices display it as a hexadecimal number. Because of this we
705 	 * have to check both cases.
706 	 */
707 	ret = kstrtou32(val.strval, 16, &serial_hex);
708 	if (ret < 0)
709 		return ret;	/* Should never fail */
710 
711 	ret = kstrtou32(val.strval, 10, &serial_dec);
712 	if (ret < 0)
713 		serial_dec = 0; /* Can fail, thus we only mark serial_dec as invalid */
714 
715 	for (int i = 0; i < ARRAY_SIZE(data->translation_cache); i++) {
716 		ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_SERIAL_NUMBER, i + 1,
717 						 &serial);
718 		if (ret < 0)
719 			return ret;
720 
721 		/* A serial number of 0 signals that this index is not associated with a battery */
722 		if (!serial)
723 			continue;
724 
725 		if (serial == serial_dec || serial == serial_hex) {
726 			dev_dbg(&data->wdev->dev, "Translation cache update for battery index %u\n",
727 				i + 1);
728 			data->translation_cache[i] = battery;
729 			*index = i + 1;
730 			return 0;
731 		}
732 	}
733 
734 	return -ENODEV;
735 }
736 
dell_wmi_battery_invalidate(struct dell_wmi_ddv_data * data,struct power_supply * battery)737 static void dell_wmi_battery_invalidate(struct dell_wmi_ddv_data *data,
738 					struct power_supply *battery)
739 {
740 	guard(mutex)(&data->translation_cache_lock);
741 
742 	for (int i = 0; i < ARRAY_SIZE(data->translation_cache); i++) {
743 		if (data->translation_cache[i] == battery) {
744 			data->translation_cache[i] = NULL;
745 			return;
746 		}
747 	}
748 }
749 
eppid_show(struct device * dev,struct device_attribute * attr,char * buf)750 static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
751 {
752 	struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, eppid_attr);
753 	union acpi_object *obj;
754 	u32 index;
755 	int ret;
756 
757 	ret = dell_wmi_ddv_battery_translate(data, to_power_supply(dev), &index);
758 	if (ret < 0)
759 		return ret;
760 
761 	ret = dell_wmi_ddv_query_string(data->wdev, DELL_DDV_BATTERY_EPPID, index, &obj);
762 	if (ret < 0)
763 		return ret;
764 
765 	if (obj->string.length != DELL_EPPID_LENGTH && obj->string.length != DELL_EPPID_EXT_LENGTH)
766 		dev_info_once(&data->wdev->dev, FW_INFO "Suspicious ePPID length (%d)\n",
767 			      obj->string.length);
768 
769 	ret = sysfs_emit(buf, "%s\n", obj->string.pointer);
770 
771 	kfree(obj);
772 
773 	return ret;
774 }
775 
dell_wmi_ddv_get_health(struct dell_wmi_ddv_data * data,u32 index,union power_supply_propval * val)776 static int dell_wmi_ddv_get_health(struct dell_wmi_ddv_data *data, u32 index,
777 				   union power_supply_propval *val)
778 {
779 	u32 value, code;
780 	int ret;
781 
782 	ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_MANUFACTURER_ACCESS, index,
783 					 &value);
784 	if (ret < 0)
785 		return ret;
786 
787 	switch (FIELD_GET(MA_FAILURE_MODE_MASK, value)) {
788 	case MA_FAILURE_MODE_PERMANENT:
789 		code = FIELD_GET(MA_PERMANENT_FAILURE_CODE_MASK, value);
790 		switch (code) {
791 		case MA_PERMANENT_FAILURE_FUSE_BLOWN:
792 			val->intval = POWER_SUPPLY_HEALTH_BLOWN_FUSE;
793 			return 0;
794 		case MA_PERMANENT_FAILURE_CELL_IMBALANCE:
795 			val->intval = POWER_SUPPLY_HEALTH_CELL_IMBALANCE;
796 			return 0;
797 		case MA_PERMANENT_FAILURE_OVERVOLTAGE:
798 			val->intval = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
799 			return 0;
800 		case MA_PERMANENT_FAILURE_FET_FAILURE:
801 			val->intval = POWER_SUPPLY_HEALTH_DEAD;
802 			return 0;
803 		default:
804 			dev_notice_once(&data->wdev->dev, "Unknown permanent failure code %u\n",
805 					code);
806 			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
807 			return 0;
808 		}
809 	case MA_FAILURE_MODE_OVERHEAT:
810 		code = FIELD_GET(MA_OVERHEAT_FAILURE_CODE_MASK, value);
811 		switch (code) {
812 		case MA_OVERHEAT_FAILURE_START:
813 		case MA_OVERHEAT_FAILURE_CHARGING:
814 		case MA_OVERHEAT_FAILURE_DISCHARGING:
815 			val->intval = POWER_SUPPLY_HEALTH_OVERHEAT;
816 			return 0;
817 		default:
818 			dev_notice_once(&data->wdev->dev, "Unknown overheat failure code %u\n",
819 					code);
820 			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
821 			return 0;
822 		}
823 	case MA_FAILURE_MODE_OVERCURRENT:
824 		code = FIELD_GET(MA_OVERCURRENT_FAILURE_CODE_MASK, value);
825 		switch (code) {
826 		case MA_OVERCURRENT_FAILURE_CHARGING:
827 		case MA_OVERCURRENT_FAILURE_DISCHARGING:
828 			val->intval = POWER_SUPPLY_HEALTH_OVERCURRENT;
829 			return 0;
830 		default:
831 			dev_notice_once(&data->wdev->dev, "Unknown overcurrent failure code %u\n",
832 					code);
833 			val->intval = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
834 			return 0;
835 		}
836 	default:
837 		val->intval = POWER_SUPPLY_HEALTH_GOOD;
838 		return 0;
839 	}
840 }
841 
dell_wmi_ddv_get_manufacture_date(struct dell_wmi_ddv_data * data,u32 index,enum power_supply_property psp,union power_supply_propval * val)842 static int dell_wmi_ddv_get_manufacture_date(struct dell_wmi_ddv_data *data, u32 index,
843 					     enum power_supply_property psp,
844 					     union power_supply_propval *val)
845 {
846 	u16 year, month, day;
847 	u32 value;
848 	int ret;
849 
850 	ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_MANUFACTURE_DATE,
851 					 index, &value);
852 	if (ret < 0)
853 		return ret;
854 	if (value > U16_MAX)
855 		return -ENXIO;
856 
857 	/*
858 	 * Some devices report a invalid manufacture date value
859 	 * like 0.0.1980. Because of this we have to check the
860 	 * whole value before exposing parts of it to user space.
861 	 */
862 	year = FIELD_GET(SBS_MANUFACTURE_YEAR_MASK, value) + 1980;
863 	month = FIELD_GET(SBS_MANUFACTURE_MONTH_MASK, value);
864 	if (month < 1 || month > 12)
865 		return -ENODATA;
866 
867 	day = FIELD_GET(SBS_MANUFACTURE_DAY_MASK, value);
868 	if (day < 1 || day > 31)
869 		return -ENODATA;
870 
871 	switch (psp) {
872 	case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
873 		val->intval = year;
874 		return 0;
875 	case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
876 		val->intval = month;
877 		return 0;
878 	case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
879 		val->intval = day;
880 		return 0;
881 	default:
882 		return -EINVAL;
883 	}
884 }
885 
dell_wmi_ddv_get_property(struct power_supply * psy,const struct power_supply_ext * ext,void * drvdata,enum power_supply_property psp,union power_supply_propval * val)886 static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct power_supply_ext *ext,
887 				     void *drvdata, enum power_supply_property psp,
888 				     union power_supply_propval *val)
889 {
890 	struct dell_wmi_ddv_data *data = drvdata;
891 	u32 index, value;
892 	int ret;
893 
894 	ret = dell_wmi_ddv_battery_translate(data, psy, &index);
895 	if (ret < 0)
896 		return ret;
897 
898 	switch (psp) {
899 	case POWER_SUPPLY_PROP_HEALTH:
900 		return dell_wmi_ddv_get_health(data, index, val);
901 	case POWER_SUPPLY_PROP_TEMP:
902 		ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index,
903 						 &value);
904 		if (ret < 0)
905 			return ret;
906 
907 		/* Use 2732 instead of 2731.5 to avoid unnecessary rounding and to emulate
908 		 * the behaviour of the OEM application which seems to round down the result.
909 		 */
910 		val->intval = value - 2732;
911 		return 0;
912 	case POWER_SUPPLY_PROP_MANUFACTURE_YEAR:
913 	case POWER_SUPPLY_PROP_MANUFACTURE_MONTH:
914 	case POWER_SUPPLY_PROP_MANUFACTURE_DAY:
915 		return dell_wmi_ddv_get_manufacture_date(data, index, psp, val);
916 	default:
917 		return -EINVAL;
918 	}
919 }
920 
921 static const enum power_supply_property dell_wmi_ddv_properties[] = {
922 	POWER_SUPPLY_PROP_HEALTH,
923 	POWER_SUPPLY_PROP_TEMP,
924 	POWER_SUPPLY_PROP_MANUFACTURE_YEAR,
925 	POWER_SUPPLY_PROP_MANUFACTURE_MONTH,
926 	POWER_SUPPLY_PROP_MANUFACTURE_DAY,
927 };
928 
929 static const struct power_supply_ext dell_wmi_ddv_extension = {
930 	.name = DRIVER_NAME,
931 	.properties = dell_wmi_ddv_properties,
932 	.num_properties = ARRAY_SIZE(dell_wmi_ddv_properties),
933 	.get_property = dell_wmi_ddv_get_property,
934 };
935 
dell_wmi_ddv_add_battery(struct power_supply * battery,struct acpi_battery_hook * hook)936 static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
937 {
938 	struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
939 	int ret;
940 
941 	/*
942 	 * We cannot do the battery matching here since the battery might be absent, preventing
943 	 * us from reading the serial number.
944 	 */
945 
946 	ret = device_create_file(&battery->dev, &data->eppid_attr);
947 	if (ret < 0)
948 		return ret;
949 
950 	ret = power_supply_register_extension(battery, &dell_wmi_ddv_extension, &data->wdev->dev,
951 					      data);
952 	if (ret < 0) {
953 		device_remove_file(&battery->dev, &data->eppid_attr);
954 
955 		return ret;
956 	}
957 
958 	return 0;
959 }
960 
dell_wmi_ddv_remove_battery(struct power_supply * battery,struct acpi_battery_hook * hook)961 static int dell_wmi_ddv_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
962 {
963 	struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
964 
965 	device_remove_file(&battery->dev, &data->eppid_attr);
966 	power_supply_unregister_extension(battery, &dell_wmi_ddv_extension);
967 
968 	dell_wmi_battery_invalidate(data, battery);
969 
970 	return 0;
971 }
972 
dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data * data)973 static int dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data *data)
974 {
975 	int ret;
976 
977 	ret = devm_mutex_init(&data->wdev->dev, &data->translation_cache_lock);
978 	if (ret < 0)
979 		return ret;
980 
981 	data->hook.name = "Dell DDV Battery Extension";
982 	data->hook.add_battery = dell_wmi_ddv_add_battery;
983 	data->hook.remove_battery = dell_wmi_ddv_remove_battery;
984 
985 	sysfs_attr_init(&data->eppid_attr.attr);
986 	data->eppid_attr.attr.name = "eppid";
987 	data->eppid_attr.attr.mode = 0444;
988 	data->eppid_attr.show = eppid_show;
989 
990 	return devm_battery_hook_register(&data->wdev->dev, &data->hook);
991 }
992 
dell_wmi_ddv_buffer_read(struct seq_file * seq,enum dell_ddv_method method)993 static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method)
994 {
995 	struct device *dev = seq->private;
996 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
997 	union acpi_object *obj;
998 	u64 size;
999 	u8 *buf;
1000 	int ret;
1001 
1002 	ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj);
1003 	if (ret < 0)
1004 		return ret;
1005 
1006 	size = obj->package.elements[0].integer.value;
1007 	buf = obj->package.elements[1].buffer.pointer;
1008 	ret = seq_write(seq, buf, size);
1009 	kfree(obj);
1010 
1011 	return ret;
1012 }
1013 
dell_wmi_ddv_fan_read(struct seq_file * seq,void * offset)1014 static int dell_wmi_ddv_fan_read(struct seq_file *seq, void *offset)
1015 {
1016 	return dell_wmi_ddv_buffer_read(seq, DELL_DDV_FAN_SENSOR_INFORMATION);
1017 }
1018 
dell_wmi_ddv_temp_read(struct seq_file * seq,void * offset)1019 static int dell_wmi_ddv_temp_read(struct seq_file *seq, void *offset)
1020 {
1021 	return dell_wmi_ddv_buffer_read(seq, DELL_DDV_THERMAL_SENSOR_INFORMATION);
1022 }
1023 
dell_wmi_ddv_debugfs_remove(void * data)1024 static void dell_wmi_ddv_debugfs_remove(void *data)
1025 {
1026 	struct dentry *entry = data;
1027 
1028 	debugfs_remove(entry);
1029 }
1030 
dell_wmi_ddv_debugfs_init(struct wmi_device * wdev)1031 static void dell_wmi_ddv_debugfs_init(struct wmi_device *wdev)
1032 {
1033 	struct dentry *entry;
1034 	char name[64];
1035 
1036 	scnprintf(name, ARRAY_SIZE(name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));
1037 	entry = debugfs_create_dir(name, NULL);
1038 
1039 	debugfs_create_devm_seqfile(&wdev->dev, "fan_sensor_information", entry,
1040 				    dell_wmi_ddv_fan_read);
1041 	debugfs_create_devm_seqfile(&wdev->dev, "thermal_sensor_information", entry,
1042 				    dell_wmi_ddv_temp_read);
1043 
1044 	devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_debugfs_remove, entry);
1045 }
1046 
dell_wmi_ddv_probe(struct wmi_device * wdev,const void * context)1047 static int dell_wmi_ddv_probe(struct wmi_device *wdev, const void *context)
1048 {
1049 	struct dell_wmi_ddv_data *data;
1050 	u32 version;
1051 	int ret;
1052 
1053 	ret = dell_wmi_ddv_query_integer(wdev, DELL_DDV_INTERFACE_VERSION, 0, &version);
1054 	if (ret < 0)
1055 		return ret;
1056 
1057 	dev_dbg(&wdev->dev, "WMI interface version: %d\n", version);
1058 	if (version < DELL_DDV_SUPPORTED_VERSION_MIN || version > DELL_DDV_SUPPORTED_VERSION_MAX) {
1059 		if (!force)
1060 			return -ENODEV;
1061 
1062 		dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u)\n",
1063 			 version);
1064 	}
1065 
1066 	data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
1067 	if (!data)
1068 		return -ENOMEM;
1069 
1070 	dev_set_drvdata(&wdev->dev, data);
1071 	data->wdev = wdev;
1072 
1073 	dell_wmi_ddv_debugfs_init(wdev);
1074 
1075 	if (IS_REACHABLE(CONFIG_ACPI_BATTERY)) {
1076 		ret = dell_wmi_ddv_battery_add(data);
1077 		if (ret < 0)
1078 			dev_warn(&wdev->dev, "Unable to register ACPI battery hook: %d\n", ret);
1079 	}
1080 
1081 	if (IS_REACHABLE(CONFIG_HWMON)) {
1082 		ret = dell_wmi_ddv_hwmon_add(data);
1083 		if (ret < 0)
1084 			dev_warn(&wdev->dev, "Unable to register hwmon interface: %d\n", ret);
1085 	}
1086 
1087 	return 0;
1088 }
1089 
dell_wmi_ddv_resume(struct device * dev)1090 static int dell_wmi_ddv_resume(struct device *dev)
1091 {
1092 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
1093 
1094 	/* Force re-reading of all active sensors */
1095 	dell_wmi_ddv_hwmon_cache_invalidate(&data->fans);
1096 	dell_wmi_ddv_hwmon_cache_invalidate(&data->temps);
1097 
1098 	return 0;
1099 }
1100 
1101 static DEFINE_SIMPLE_DEV_PM_OPS(dell_wmi_ddv_dev_pm_ops, NULL, dell_wmi_ddv_resume);
1102 
1103 static const struct wmi_device_id dell_wmi_ddv_id_table[] = {
1104 	{ DELL_DDV_GUID, NULL },
1105 	{ }
1106 };
1107 MODULE_DEVICE_TABLE(wmi, dell_wmi_ddv_id_table);
1108 
1109 static struct wmi_driver dell_wmi_ddv_driver = {
1110 	.driver = {
1111 		.name = DRIVER_NAME,
1112 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
1113 		.pm = pm_sleep_ptr(&dell_wmi_ddv_dev_pm_ops),
1114 	},
1115 	.id_table = dell_wmi_ddv_id_table,
1116 	.probe = dell_wmi_ddv_probe,
1117 	.no_singleton = true,
1118 };
1119 module_wmi_driver(dell_wmi_ddv_driver);
1120 
1121 MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
1122 MODULE_DESCRIPTION("Dell WMI sensor driver");
1123 MODULE_LICENSE("GPL");
1124