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