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/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>
24 #include <linux/pm.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>
31 
32 #include <acpi/battery.h>
33 
34 #include <linux/unaligned.h>
35 
36 #define DRIVER_NAME	"dell-wmi-ddv"
37 
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"
41 
42 #define DELL_EPPID_LENGTH	20
43 #define DELL_EPPID_EXT_LENGTH	23
44 
45 static bool force;
46 module_param_unsafe(force, bool, 0);
47 MODULE_PARM_DESC(force, "Force loading without checking for supported WMI interface versions");
48 
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 */
67 
68 	DELL_DDV_INTERFACE_VERSION		= 0x12,
69 
70 	DELL_DDV_FAN_SENSOR_INFORMATION		= 0x20,
71 	DELL_DDV_THERMAL_SENSOR_INFORMATION	= 0x22,
72 };
73 
74 struct fan_sensor_entry {
75 	u8 type;
76 	__le16 rpm;
77 } __packed;
78 
79 struct thermal_sensor_entry {
80 	u8 type;
81 	s8 now;
82 	s8 min;
83 	s8 max;
84 	u8 unknown;
85 } __packed;
86 
87 struct combined_channel_info {
88 	struct hwmon_channel_info info;
89 	u32 config[];
90 };
91 
92 struct combined_chip_info {
93 	struct hwmon_chip_info chip;
94 	const struct hwmon_channel_info *info[];
95 };
96 
97 struct dell_wmi_ddv_sensors {
98 	bool active;
99 	struct mutex lock;	/* protect caching */
100 	unsigned long timestamp;
101 	union acpi_object *obj;
102 	u64 entries;
103 };
104 
105 struct dell_wmi_ddv_data {
106 	struct acpi_battery_hook hook;
107 	struct device_attribute eppid_attr;
108 	struct dell_wmi_ddv_sensors fans;
109 	struct dell_wmi_ddv_sensors temps;
110 	struct wmi_device *wdev;
111 };
112 
113 static const char * const fan_labels[] = {
114 	"CPU Fan",
115 	"Chassis Motherboard Fan",
116 	"Video Fan",
117 	"Power Supply Fan",
118 	"Chipset Fan",
119 	"Memory Fan",
120 	"PCI Fan",
121 	"HDD Fan",
122 };
123 
124 static const char * const fan_dock_labels[] = {
125 	"Docking Chassis/Motherboard Fan",
126 	"Docking Video Fan",
127 	"Docking Power Supply Fan",
128 	"Docking Chipset Fan",
129 };
130 
dell_wmi_ddv_query_type(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,union acpi_object ** result,acpi_object_type type)131 static int dell_wmi_ddv_query_type(struct wmi_device *wdev, enum dell_ddv_method method, u32 arg,
132 				   union acpi_object **result, acpi_object_type type)
133 {
134 	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
135 	const struct acpi_buffer in = {
136 		.length = sizeof(arg),
137 		.pointer = &arg,
138 	};
139 	union acpi_object *obj;
140 	acpi_status ret;
141 
142 	ret = wmidev_evaluate_method(wdev, 0x0, method, &in, &out);
143 	if (ACPI_FAILURE(ret))
144 		return -EIO;
145 
146 	obj = out.pointer;
147 	if (!obj)
148 		return -ENODATA;
149 
150 	if (obj->type != type) {
151 		kfree(obj);
152 		return -ENOMSG;
153 	}
154 
155 	*result = obj;
156 
157 	return 0;
158 }
159 
dell_wmi_ddv_query_integer(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,u32 * res)160 static int dell_wmi_ddv_query_integer(struct wmi_device *wdev, enum dell_ddv_method method,
161 				      u32 arg, u32 *res)
162 {
163 	union acpi_object *obj;
164 	int ret;
165 
166 	ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_INTEGER);
167 	if (ret < 0)
168 		return ret;
169 
170 	if (obj->integer.value <= U32_MAX)
171 		*res = (u32)obj->integer.value;
172 	else
173 		ret = -ERANGE;
174 
175 	kfree(obj);
176 
177 	return ret;
178 }
179 
dell_wmi_ddv_query_buffer(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,union acpi_object ** result)180 static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_method method,
181 				     u32 arg, union acpi_object **result)
182 {
183 	union acpi_object *obj;
184 	u64 buffer_size;
185 	int ret;
186 
187 	ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_PACKAGE);
188 	if (ret < 0)
189 		return ret;
190 
191 	if (obj->package.count != 2 ||
192 	    obj->package.elements[0].type != ACPI_TYPE_INTEGER ||
193 	    obj->package.elements[1].type != ACPI_TYPE_BUFFER) {
194 		ret = -ENOMSG;
195 
196 		goto err_free;
197 	}
198 
199 	buffer_size = obj->package.elements[0].integer.value;
200 
201 	if (!buffer_size) {
202 		ret = -ENODATA;
203 
204 		goto err_free;
205 	}
206 
207 	if (buffer_size > obj->package.elements[1].buffer.length) {
208 		dev_warn(&wdev->dev,
209 			 FW_WARN "WMI buffer size (%llu) exceeds ACPI buffer size (%d)\n",
210 			 buffer_size, obj->package.elements[1].buffer.length);
211 		ret = -EMSGSIZE;
212 
213 		goto err_free;
214 	}
215 
216 	*result = obj;
217 
218 	return 0;
219 
220 err_free:
221 	kfree(obj);
222 
223 	return ret;
224 }
225 
dell_wmi_ddv_query_string(struct wmi_device * wdev,enum dell_ddv_method method,u32 arg,union acpi_object ** result)226 static int dell_wmi_ddv_query_string(struct wmi_device *wdev, enum dell_ddv_method method,
227 				     u32 arg, union acpi_object **result)
228 {
229 	return dell_wmi_ddv_query_type(wdev, method, arg, result, ACPI_TYPE_STRING);
230 }
231 
232 /*
233  * Needs to be called with lock held, except during initialization.
234  */
dell_wmi_ddv_update_sensors(struct wmi_device * wdev,enum dell_ddv_method method,struct dell_wmi_ddv_sensors * sensors,size_t entry_size)235 static int dell_wmi_ddv_update_sensors(struct wmi_device *wdev, enum dell_ddv_method method,
236 				       struct dell_wmi_ddv_sensors *sensors, size_t entry_size)
237 {
238 	u64 buffer_size, rem, entries;
239 	union acpi_object *obj;
240 	u8 *buffer;
241 	int ret;
242 
243 	if (sensors->obj) {
244 		if (time_before(jiffies, sensors->timestamp + HZ))
245 			return 0;
246 
247 		kfree(sensors->obj);
248 		sensors->obj = NULL;
249 	}
250 
251 	ret = dell_wmi_ddv_query_buffer(wdev, method, 0, &obj);
252 	if (ret < 0)
253 		return ret;
254 
255 	/* buffer format sanity check */
256 	buffer_size = obj->package.elements[0].integer.value;
257 	buffer = obj->package.elements[1].buffer.pointer;
258 	entries = div64_u64_rem(buffer_size, entry_size, &rem);
259 	if (rem != 1 || buffer[buffer_size - 1] != 0xff) {
260 		ret = -ENOMSG;
261 		goto err_free;
262 	}
263 
264 	if (!entries) {
265 		ret = -ENODATA;
266 		goto err_free;
267 	}
268 
269 	sensors->obj = obj;
270 	sensors->entries = entries;
271 	sensors->timestamp = jiffies;
272 
273 	return 0;
274 
275 err_free:
276 	kfree(obj);
277 
278 	return ret;
279 }
280 
dell_wmi_ddv_is_visible(const void * drvdata,enum hwmon_sensor_types type,u32 attr,int channel)281 static umode_t dell_wmi_ddv_is_visible(const void *drvdata, enum hwmon_sensor_types type, u32 attr,
282 				       int channel)
283 {
284 	return 0444;
285 }
286 
dell_wmi_ddv_fan_read_channel(struct dell_wmi_ddv_data * data,u32 attr,int channel,long * val)287 static int dell_wmi_ddv_fan_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
288 					 long *val)
289 {
290 	struct fan_sensor_entry *entry;
291 	int ret;
292 
293 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
294 					  &data->fans, sizeof(*entry));
295 	if (ret < 0)
296 		return ret;
297 
298 	if (channel >= data->fans.entries)
299 		return -ENXIO;
300 
301 	entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
302 	switch (attr) {
303 	case hwmon_fan_input:
304 		*val = get_unaligned_le16(&entry[channel].rpm);
305 		return 0;
306 	default:
307 		break;
308 	}
309 
310 	return -EOPNOTSUPP;
311 }
312 
dell_wmi_ddv_temp_read_channel(struct dell_wmi_ddv_data * data,u32 attr,int channel,long * val)313 static int dell_wmi_ddv_temp_read_channel(struct dell_wmi_ddv_data *data, u32 attr, int channel,
314 					  long *val)
315 {
316 	struct thermal_sensor_entry *entry;
317 	int ret;
318 
319 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
320 					  &data->temps, sizeof(*entry));
321 	if (ret < 0)
322 		return ret;
323 
324 	if (channel >= data->temps.entries)
325 		return -ENXIO;
326 
327 	entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
328 	switch (attr) {
329 	case hwmon_temp_input:
330 		*val = entry[channel].now * 1000;
331 		return 0;
332 	case hwmon_temp_min:
333 		*val = entry[channel].min * 1000;
334 		return 0;
335 	case hwmon_temp_max:
336 		*val = entry[channel].max * 1000;
337 		return 0;
338 	default:
339 		break;
340 	}
341 
342 	return -EOPNOTSUPP;
343 }
344 
dell_wmi_ddv_read(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,long * val)345 static int dell_wmi_ddv_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
346 			     int channel, long *val)
347 {
348 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
349 	int ret;
350 
351 	switch (type) {
352 	case hwmon_fan:
353 		mutex_lock(&data->fans.lock);
354 		ret = dell_wmi_ddv_fan_read_channel(data, attr, channel, val);
355 		mutex_unlock(&data->fans.lock);
356 		return ret;
357 	case hwmon_temp:
358 		mutex_lock(&data->temps.lock);
359 		ret = dell_wmi_ddv_temp_read_channel(data, attr, channel, val);
360 		mutex_unlock(&data->temps.lock);
361 		return ret;
362 	default:
363 		break;
364 	}
365 
366 	return -EOPNOTSUPP;
367 }
368 
dell_wmi_ddv_fan_read_string(struct dell_wmi_ddv_data * data,int channel,const char ** str)369 static int dell_wmi_ddv_fan_read_string(struct dell_wmi_ddv_data *data, int channel,
370 					const char **str)
371 {
372 	struct fan_sensor_entry *entry;
373 	int ret;
374 	u8 type;
375 
376 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION,
377 					  &data->fans, sizeof(*entry));
378 	if (ret < 0)
379 		return ret;
380 
381 	if (channel >= data->fans.entries)
382 		return -ENXIO;
383 
384 	entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer;
385 	type = entry[channel].type;
386 	switch (type) {
387 	case 0x00 ... 0x07:
388 		*str = fan_labels[type];
389 		break;
390 	case 0x11 ... 0x14:
391 		*str = fan_dock_labels[type - 0x11];
392 		break;
393 	default:
394 		*str = "Unknown Fan";
395 		break;
396 	}
397 
398 	return 0;
399 }
400 
dell_wmi_ddv_temp_read_string(struct dell_wmi_ddv_data * data,int channel,const char ** str)401 static int dell_wmi_ddv_temp_read_string(struct dell_wmi_ddv_data *data, int channel,
402 					 const char **str)
403 {
404 	struct thermal_sensor_entry *entry;
405 	int ret;
406 
407 	ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION,
408 					  &data->temps, sizeof(*entry));
409 	if (ret < 0)
410 		return ret;
411 
412 	if (channel >= data->temps.entries)
413 		return -ENXIO;
414 
415 	entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer;
416 	switch (entry[channel].type) {
417 	case 0x00:
418 		*str = "CPU";
419 		break;
420 	case 0x11:
421 		*str = "Video";
422 		break;
423 	case 0x22:
424 		*str = "Memory"; /* sometimes called DIMM */
425 		break;
426 	case 0x33:
427 		*str = "Other";
428 		break;
429 	case 0x44:
430 		*str = "Ambient"; /* sometimes called SKIN */
431 		break;
432 	case 0x52:
433 		*str = "SODIMM";
434 		break;
435 	case 0x55:
436 		*str = "HDD";
437 		break;
438 	case 0x62:
439 		*str = "SODIMM 2";
440 		break;
441 	case 0x73:
442 		*str = "NB";
443 		break;
444 	case 0x83:
445 		*str = "Charger";
446 		break;
447 	case 0xbb:
448 		*str = "Memory 3";
449 		break;
450 	default:
451 		*str = "Unknown";
452 		break;
453 	}
454 
455 	return 0;
456 }
457 
dell_wmi_ddv_read_string(struct device * dev,enum hwmon_sensor_types type,u32 attr,int channel,const char ** str)458 static int dell_wmi_ddv_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr,
459 				    int channel, const char **str)
460 {
461 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
462 	int ret;
463 
464 	switch (type) {
465 	case hwmon_fan:
466 		switch (attr) {
467 		case hwmon_fan_label:
468 			mutex_lock(&data->fans.lock);
469 			ret = dell_wmi_ddv_fan_read_string(data, channel, str);
470 			mutex_unlock(&data->fans.lock);
471 			return ret;
472 		default:
473 			break;
474 		}
475 		break;
476 	case hwmon_temp:
477 		switch (attr) {
478 		case hwmon_temp_label:
479 			mutex_lock(&data->temps.lock);
480 			ret = dell_wmi_ddv_temp_read_string(data, channel, str);
481 			mutex_unlock(&data->temps.lock);
482 			return ret;
483 		default:
484 			break;
485 		}
486 		break;
487 	default:
488 		break;
489 	}
490 
491 	return -EOPNOTSUPP;
492 }
493 
494 static const struct hwmon_ops dell_wmi_ddv_ops = {
495 	.is_visible = dell_wmi_ddv_is_visible,
496 	.read = dell_wmi_ddv_read,
497 	.read_string = dell_wmi_ddv_read_string,
498 };
499 
dell_wmi_ddv_channel_create(struct device * dev,u64 count,enum hwmon_sensor_types type,u32 config)500 static struct hwmon_channel_info *dell_wmi_ddv_channel_create(struct device *dev, u64 count,
501 							      enum hwmon_sensor_types type,
502 							      u32 config)
503 {
504 	struct combined_channel_info *cinfo;
505 	int i;
506 
507 	cinfo = devm_kzalloc(dev, struct_size(cinfo, config, count + 1), GFP_KERNEL);
508 	if (!cinfo)
509 		return ERR_PTR(-ENOMEM);
510 
511 	cinfo->info.type = type;
512 	cinfo->info.config = cinfo->config;
513 
514 	for (i = 0; i < count; i++)
515 		cinfo->config[i] = config;
516 
517 	return &cinfo->info;
518 }
519 
dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors * sensors)520 static void dell_wmi_ddv_hwmon_cache_invalidate(struct dell_wmi_ddv_sensors *sensors)
521 {
522 	if (!sensors->active)
523 		return;
524 
525 	mutex_lock(&sensors->lock);
526 	kfree(sensors->obj);
527 	sensors->obj = NULL;
528 	mutex_unlock(&sensors->lock);
529 }
530 
dell_wmi_ddv_hwmon_cache_destroy(void * data)531 static void dell_wmi_ddv_hwmon_cache_destroy(void *data)
532 {
533 	struct dell_wmi_ddv_sensors *sensors = data;
534 
535 	sensors->active = false;
536 	mutex_destroy(&sensors->lock);
537 	kfree(sensors->obj);
538 }
539 
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)540 static struct hwmon_channel_info *dell_wmi_ddv_channel_init(struct wmi_device *wdev,
541 							    enum dell_ddv_method method,
542 							    struct dell_wmi_ddv_sensors *sensors,
543 							    size_t entry_size,
544 							    enum hwmon_sensor_types type,
545 							    u32 config)
546 {
547 	struct hwmon_channel_info *info;
548 	int ret;
549 
550 	ret = dell_wmi_ddv_update_sensors(wdev, method, sensors, entry_size);
551 	if (ret < 0)
552 		return ERR_PTR(ret);
553 
554 	mutex_init(&sensors->lock);
555 	sensors->active = true;
556 
557 	ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
558 	if (ret < 0)
559 		return ERR_PTR(ret);
560 
561 	info = dell_wmi_ddv_channel_create(&wdev->dev, sensors->entries, type, config);
562 	if (IS_ERR(info))
563 		devm_release_action(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors);
564 
565 	return info;
566 }
567 
dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data * data)568 static int dell_wmi_ddv_hwmon_add(struct dell_wmi_ddv_data *data)
569 {
570 	struct wmi_device *wdev = data->wdev;
571 	struct combined_chip_info *cinfo;
572 	struct hwmon_channel_info *info;
573 	struct device *hdev;
574 	int index = 0;
575 	int ret;
576 
577 	if (!devres_open_group(&wdev->dev, dell_wmi_ddv_hwmon_add, GFP_KERNEL))
578 		return -ENOMEM;
579 
580 	cinfo = devm_kzalloc(&wdev->dev, struct_size(cinfo, info, 4), GFP_KERNEL);
581 	if (!cinfo) {
582 		ret = -ENOMEM;
583 
584 		goto err_release;
585 	}
586 
587 	cinfo->chip.ops = &dell_wmi_ddv_ops;
588 	cinfo->chip.info = cinfo->info;
589 
590 	info = dell_wmi_ddv_channel_create(&wdev->dev, 1, hwmon_chip, HWMON_C_REGISTER_TZ);
591 	if (IS_ERR(info)) {
592 		ret = PTR_ERR(info);
593 
594 		goto err_release;
595 	}
596 
597 	cinfo->info[index] = info;
598 	index++;
599 
600 	info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_FAN_SENSOR_INFORMATION, &data->fans,
601 					 sizeof(struct fan_sensor_entry), hwmon_fan,
602 					 (HWMON_F_INPUT | HWMON_F_LABEL));
603 	if (!IS_ERR(info)) {
604 		cinfo->info[index] = info;
605 		index++;
606 	}
607 
608 	info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, &data->temps,
609 					 sizeof(struct thermal_sensor_entry), hwmon_temp,
610 					 (HWMON_T_INPUT | HWMON_T_MIN | HWMON_T_MAX |
611 					 HWMON_T_LABEL));
612 	if (!IS_ERR(info)) {
613 		cinfo->info[index] = info;
614 		index++;
615 	}
616 
617 	if (index < 2) {
618 		/* Finding no available sensors is not an error */
619 		ret = 0;
620 
621 		goto err_release;
622 	}
623 
624 	hdev = devm_hwmon_device_register_with_info(&wdev->dev, "dell_ddv", data, &cinfo->chip,
625 						    NULL);
626 	if (IS_ERR(hdev)) {
627 		ret = PTR_ERR(hdev);
628 
629 		goto err_release;
630 	}
631 
632 	devres_close_group(&wdev->dev, dell_wmi_ddv_hwmon_add);
633 
634 	return 0;
635 
636 err_release:
637 	devres_release_group(&wdev->dev, dell_wmi_ddv_hwmon_add);
638 
639 	return ret;
640 }
641 
dell_wmi_ddv_battery_index(struct acpi_device * acpi_dev,u32 * index)642 static int dell_wmi_ddv_battery_index(struct acpi_device *acpi_dev, u32 *index)
643 {
644 	const char *uid_str;
645 
646 	uid_str = acpi_device_uid(acpi_dev);
647 	if (!uid_str)
648 		return -ENODEV;
649 
650 	return kstrtou32(uid_str, 10, index);
651 }
652 
eppid_show(struct device * dev,struct device_attribute * attr,char * buf)653 static ssize_t eppid_show(struct device *dev, struct device_attribute *attr, char *buf)
654 {
655 	struct dell_wmi_ddv_data *data = container_of(attr, struct dell_wmi_ddv_data, eppid_attr);
656 	union acpi_object *obj;
657 	u32 index;
658 	int ret;
659 
660 	ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index);
661 	if (ret < 0)
662 		return ret;
663 
664 	ret = dell_wmi_ddv_query_string(data->wdev, DELL_DDV_BATTERY_EPPID, index, &obj);
665 	if (ret < 0)
666 		return ret;
667 
668 	if (obj->string.length != DELL_EPPID_LENGTH && obj->string.length != DELL_EPPID_EXT_LENGTH)
669 		dev_info_once(&data->wdev->dev, FW_INFO "Suspicious ePPID length (%d)\n",
670 			      obj->string.length);
671 
672 	ret = sysfs_emit(buf, "%s\n", obj->string.pointer);
673 
674 	kfree(obj);
675 
676 	return ret;
677 }
678 
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)679 static int dell_wmi_ddv_get_property(struct power_supply *psy, const struct power_supply_ext *ext,
680 				     void *drvdata, enum power_supply_property psp,
681 				     union power_supply_propval *val)
682 {
683 	struct dell_wmi_ddv_data *data = drvdata;
684 	u32 index, value;
685 	int ret;
686 
687 	ret = dell_wmi_ddv_battery_index(to_acpi_device(psy->dev.parent), &index);
688 	if (ret < 0)
689 		return ret;
690 
691 	switch (psp) {
692 	case POWER_SUPPLY_PROP_TEMP:
693 		ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index,
694 						 &value);
695 		if (ret < 0)
696 			return ret;
697 
698 		/* Use 2732 instead of 2731.5 to avoid unnecessary rounding and to emulate
699 		 * the behaviour of the OEM application which seems to round down the result.
700 		 */
701 		val->intval = value - 2732;
702 		return 0;
703 	default:
704 		return -EINVAL;
705 	}
706 }
707 
708 static const enum power_supply_property dell_wmi_ddv_properties[] = {
709 	POWER_SUPPLY_PROP_TEMP,
710 };
711 
712 static const struct power_supply_ext dell_wmi_ddv_extension = {
713 	.name = DRIVER_NAME,
714 	.properties = dell_wmi_ddv_properties,
715 	.num_properties = ARRAY_SIZE(dell_wmi_ddv_properties),
716 	.get_property = dell_wmi_ddv_get_property,
717 };
718 
dell_wmi_ddv_add_battery(struct power_supply * battery,struct acpi_battery_hook * hook)719 static int dell_wmi_ddv_add_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
720 {
721 	struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
722 	u32 index;
723 	int ret;
724 
725 	/* Return 0 instead of error to avoid being unloaded */
726 	ret = dell_wmi_ddv_battery_index(to_acpi_device(battery->dev.parent), &index);
727 	if (ret < 0)
728 		return 0;
729 
730 	ret = device_create_file(&battery->dev, &data->eppid_attr);
731 	if (ret < 0)
732 		return ret;
733 
734 	ret = power_supply_register_extension(battery, &dell_wmi_ddv_extension, &data->wdev->dev,
735 					      data);
736 	if (ret < 0) {
737 		device_remove_file(&battery->dev, &data->eppid_attr);
738 
739 		return ret;
740 	}
741 
742 	return 0;
743 }
744 
dell_wmi_ddv_remove_battery(struct power_supply * battery,struct acpi_battery_hook * hook)745 static int dell_wmi_ddv_remove_battery(struct power_supply *battery, struct acpi_battery_hook *hook)
746 {
747 	struct dell_wmi_ddv_data *data = container_of(hook, struct dell_wmi_ddv_data, hook);
748 
749 	device_remove_file(&battery->dev, &data->eppid_attr);
750 	power_supply_unregister_extension(battery, &dell_wmi_ddv_extension);
751 
752 	return 0;
753 }
754 
dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data * data)755 static int dell_wmi_ddv_battery_add(struct dell_wmi_ddv_data *data)
756 {
757 	data->hook.name = "Dell DDV Battery Extension";
758 	data->hook.add_battery = dell_wmi_ddv_add_battery;
759 	data->hook.remove_battery = dell_wmi_ddv_remove_battery;
760 
761 	sysfs_attr_init(&data->eppid_attr.attr);
762 	data->eppid_attr.attr.name = "eppid";
763 	data->eppid_attr.attr.mode = 0444;
764 	data->eppid_attr.show = eppid_show;
765 
766 	return devm_battery_hook_register(&data->wdev->dev, &data->hook);
767 }
768 
dell_wmi_ddv_buffer_read(struct seq_file * seq,enum dell_ddv_method method)769 static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method)
770 {
771 	struct device *dev = seq->private;
772 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
773 	union acpi_object *obj;
774 	u64 size;
775 	u8 *buf;
776 	int ret;
777 
778 	ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj);
779 	if (ret < 0)
780 		return ret;
781 
782 	size = obj->package.elements[0].integer.value;
783 	buf = obj->package.elements[1].buffer.pointer;
784 	ret = seq_write(seq, buf, size);
785 	kfree(obj);
786 
787 	return ret;
788 }
789 
dell_wmi_ddv_fan_read(struct seq_file * seq,void * offset)790 static int dell_wmi_ddv_fan_read(struct seq_file *seq, void *offset)
791 {
792 	return dell_wmi_ddv_buffer_read(seq, DELL_DDV_FAN_SENSOR_INFORMATION);
793 }
794 
dell_wmi_ddv_temp_read(struct seq_file * seq,void * offset)795 static int dell_wmi_ddv_temp_read(struct seq_file *seq, void *offset)
796 {
797 	return dell_wmi_ddv_buffer_read(seq, DELL_DDV_THERMAL_SENSOR_INFORMATION);
798 }
799 
dell_wmi_ddv_debugfs_remove(void * data)800 static void dell_wmi_ddv_debugfs_remove(void *data)
801 {
802 	struct dentry *entry = data;
803 
804 	debugfs_remove(entry);
805 }
806 
dell_wmi_ddv_debugfs_init(struct wmi_device * wdev)807 static void dell_wmi_ddv_debugfs_init(struct wmi_device *wdev)
808 {
809 	struct dentry *entry;
810 	char name[64];
811 
812 	scnprintf(name, ARRAY_SIZE(name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev));
813 	entry = debugfs_create_dir(name, NULL);
814 
815 	debugfs_create_devm_seqfile(&wdev->dev, "fan_sensor_information", entry,
816 				    dell_wmi_ddv_fan_read);
817 	debugfs_create_devm_seqfile(&wdev->dev, "thermal_sensor_information", entry,
818 				    dell_wmi_ddv_temp_read);
819 
820 	devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_debugfs_remove, entry);
821 }
822 
dell_wmi_ddv_probe(struct wmi_device * wdev,const void * context)823 static int dell_wmi_ddv_probe(struct wmi_device *wdev, const void *context)
824 {
825 	struct dell_wmi_ddv_data *data;
826 	u32 version;
827 	int ret;
828 
829 	ret = dell_wmi_ddv_query_integer(wdev, DELL_DDV_INTERFACE_VERSION, 0, &version);
830 	if (ret < 0)
831 		return ret;
832 
833 	dev_dbg(&wdev->dev, "WMI interface version: %d\n", version);
834 	if (version < DELL_DDV_SUPPORTED_VERSION_MIN || version > DELL_DDV_SUPPORTED_VERSION_MAX) {
835 		if (!force)
836 			return -ENODEV;
837 
838 		dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u)\n",
839 			 version);
840 	}
841 
842 	data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL);
843 	if (!data)
844 		return -ENOMEM;
845 
846 	dev_set_drvdata(&wdev->dev, data);
847 	data->wdev = wdev;
848 
849 	dell_wmi_ddv_debugfs_init(wdev);
850 
851 	if (IS_REACHABLE(CONFIG_ACPI_BATTERY)) {
852 		ret = dell_wmi_ddv_battery_add(data);
853 		if (ret < 0)
854 			dev_warn(&wdev->dev, "Unable to register ACPI battery hook: %d\n", ret);
855 	}
856 
857 	if (IS_REACHABLE(CONFIG_HWMON)) {
858 		ret = dell_wmi_ddv_hwmon_add(data);
859 		if (ret < 0)
860 			dev_warn(&wdev->dev, "Unable to register hwmon interface: %d\n", ret);
861 	}
862 
863 	return 0;
864 }
865 
dell_wmi_ddv_resume(struct device * dev)866 static int dell_wmi_ddv_resume(struct device *dev)
867 {
868 	struct dell_wmi_ddv_data *data = dev_get_drvdata(dev);
869 
870 	/* Force re-reading of all active sensors */
871 	dell_wmi_ddv_hwmon_cache_invalidate(&data->fans);
872 	dell_wmi_ddv_hwmon_cache_invalidate(&data->temps);
873 
874 	return 0;
875 }
876 
877 static DEFINE_SIMPLE_DEV_PM_OPS(dell_wmi_ddv_dev_pm_ops, NULL, dell_wmi_ddv_resume);
878 
879 static const struct wmi_device_id dell_wmi_ddv_id_table[] = {
880 	{ DELL_DDV_GUID, NULL },
881 	{ }
882 };
883 MODULE_DEVICE_TABLE(wmi, dell_wmi_ddv_id_table);
884 
885 static struct wmi_driver dell_wmi_ddv_driver = {
886 	.driver = {
887 		.name = DRIVER_NAME,
888 		.probe_type = PROBE_PREFER_ASYNCHRONOUS,
889 		.pm = pm_sleep_ptr(&dell_wmi_ddv_dev_pm_ops),
890 	},
891 	.id_table = dell_wmi_ddv_id_table,
892 	.probe = dell_wmi_ddv_probe,
893 	.no_singleton = true,
894 };
895 module_wmi_driver(dell_wmi_ddv_driver);
896 
897 MODULE_AUTHOR("Armin Wolf <W_Armin@gmx.de>");
898 MODULE_DESCRIPTION("Dell WMI sensor driver");
899 MODULE_LICENSE("GPL");
900