Lines Matching +full:entry +full:- +full:method
1 // SPDX-License-Identifier: GPL-2.0-or-later
36 #define DRIVER_NAME "dell-wmi-ddv"
40 #define DELL_DDV_GUID "8A42EA14-4F2A-FD45-6422-0087F7A7E608"
131 static int dell_wmi_ddv_query_type(struct wmi_device *wdev, enum dell_ddv_method method, u32 arg, in dell_wmi_ddv_query_type() argument
142 ret = wmidev_evaluate_method(wdev, 0x0, method, &in, &out); in dell_wmi_ddv_query_type()
144 return -EIO; in dell_wmi_ddv_query_type()
148 return -ENODATA; in dell_wmi_ddv_query_type()
150 if (obj->type != type) { in dell_wmi_ddv_query_type()
152 return -ENOMSG; in dell_wmi_ddv_query_type()
160 static int dell_wmi_ddv_query_integer(struct wmi_device *wdev, enum dell_ddv_method method, in dell_wmi_ddv_query_integer() argument
166 ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_INTEGER); in dell_wmi_ddv_query_integer()
170 if (obj->integer.value <= U32_MAX) in dell_wmi_ddv_query_integer()
171 *res = (u32)obj->integer.value; in dell_wmi_ddv_query_integer()
173 ret = -ERANGE; in dell_wmi_ddv_query_integer()
180 static int dell_wmi_ddv_query_buffer(struct wmi_device *wdev, enum dell_ddv_method method, in dell_wmi_ddv_query_buffer() argument
187 ret = dell_wmi_ddv_query_type(wdev, method, arg, &obj, ACPI_TYPE_PACKAGE); in dell_wmi_ddv_query_buffer()
191 if (obj->package.count != 2 || in dell_wmi_ddv_query_buffer()
192 obj->package.elements[0].type != ACPI_TYPE_INTEGER || in dell_wmi_ddv_query_buffer()
193 obj->package.elements[1].type != ACPI_TYPE_BUFFER) { in dell_wmi_ddv_query_buffer()
194 ret = -ENOMSG; in dell_wmi_ddv_query_buffer()
199 buffer_size = obj->package.elements[0].integer.value; in dell_wmi_ddv_query_buffer()
202 ret = -ENODATA; in dell_wmi_ddv_query_buffer()
207 if (buffer_size > obj->package.elements[1].buffer.length) { in dell_wmi_ddv_query_buffer()
208 dev_warn(&wdev->dev, in dell_wmi_ddv_query_buffer()
210 buffer_size, obj->package.elements[1].buffer.length); in dell_wmi_ddv_query_buffer()
211 ret = -EMSGSIZE; in dell_wmi_ddv_query_buffer()
226 static int dell_wmi_ddv_query_string(struct wmi_device *wdev, enum dell_ddv_method method, in dell_wmi_ddv_query_string() argument
229 return dell_wmi_ddv_query_type(wdev, method, arg, result, ACPI_TYPE_STRING); in dell_wmi_ddv_query_string()
235 static int dell_wmi_ddv_update_sensors(struct wmi_device *wdev, enum dell_ddv_method method, in dell_wmi_ddv_update_sensors() argument
243 if (sensors->obj) { in dell_wmi_ddv_update_sensors()
244 if (time_before(jiffies, sensors->timestamp + HZ)) in dell_wmi_ddv_update_sensors()
247 kfree(sensors->obj); in dell_wmi_ddv_update_sensors()
248 sensors->obj = NULL; in dell_wmi_ddv_update_sensors()
251 ret = dell_wmi_ddv_query_buffer(wdev, method, 0, &obj); in dell_wmi_ddv_update_sensors()
256 buffer_size = obj->package.elements[0].integer.value; in dell_wmi_ddv_update_sensors()
257 buffer = obj->package.elements[1].buffer.pointer; in dell_wmi_ddv_update_sensors()
259 if (rem != 1 || buffer[buffer_size - 1] != 0xff) { in dell_wmi_ddv_update_sensors()
260 ret = -ENOMSG; in dell_wmi_ddv_update_sensors()
265 ret = -ENODATA; in dell_wmi_ddv_update_sensors()
269 sensors->obj = obj; in dell_wmi_ddv_update_sensors()
270 sensors->entries = entries; in dell_wmi_ddv_update_sensors()
271 sensors->timestamp = jiffies; in dell_wmi_ddv_update_sensors()
290 struct fan_sensor_entry *entry; in dell_wmi_ddv_fan_read_channel() local
293 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION, in dell_wmi_ddv_fan_read_channel()
294 &data->fans, sizeof(*entry)); in dell_wmi_ddv_fan_read_channel()
298 if (channel >= data->fans.entries) in dell_wmi_ddv_fan_read_channel()
299 return -ENXIO; in dell_wmi_ddv_fan_read_channel()
301 entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer; in dell_wmi_ddv_fan_read_channel()
304 *val = get_unaligned_le16(&entry[channel].rpm); in dell_wmi_ddv_fan_read_channel()
310 return -EOPNOTSUPP; in dell_wmi_ddv_fan_read_channel()
316 struct thermal_sensor_entry *entry; in dell_wmi_ddv_temp_read_channel() local
319 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, in dell_wmi_ddv_temp_read_channel()
320 &data->temps, sizeof(*entry)); in dell_wmi_ddv_temp_read_channel()
324 if (channel >= data->temps.entries) in dell_wmi_ddv_temp_read_channel()
325 return -ENXIO; in dell_wmi_ddv_temp_read_channel()
327 entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer; in dell_wmi_ddv_temp_read_channel()
330 *val = entry[channel].now * 1000; in dell_wmi_ddv_temp_read_channel()
333 *val = entry[channel].min * 1000; in dell_wmi_ddv_temp_read_channel()
336 *val = entry[channel].max * 1000; in dell_wmi_ddv_temp_read_channel()
342 return -EOPNOTSUPP; in dell_wmi_ddv_temp_read_channel()
353 mutex_lock(&data->fans.lock); in dell_wmi_ddv_read()
355 mutex_unlock(&data->fans.lock); in dell_wmi_ddv_read()
358 mutex_lock(&data->temps.lock); in dell_wmi_ddv_read()
360 mutex_unlock(&data->temps.lock); in dell_wmi_ddv_read()
366 return -EOPNOTSUPP; in dell_wmi_ddv_read()
372 struct fan_sensor_entry *entry; in dell_wmi_ddv_fan_read_string() local
376 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_FAN_SENSOR_INFORMATION, in dell_wmi_ddv_fan_read_string()
377 &data->fans, sizeof(*entry)); in dell_wmi_ddv_fan_read_string()
381 if (channel >= data->fans.entries) in dell_wmi_ddv_fan_read_string()
382 return -ENXIO; in dell_wmi_ddv_fan_read_string()
384 entry = (struct fan_sensor_entry *)data->fans.obj->package.elements[1].buffer.pointer; in dell_wmi_ddv_fan_read_string()
385 type = entry[channel].type; in dell_wmi_ddv_fan_read_string()
391 *str = fan_dock_labels[type - 0x11]; in dell_wmi_ddv_fan_read_string()
404 struct thermal_sensor_entry *entry; in dell_wmi_ddv_temp_read_string() local
407 ret = dell_wmi_ddv_update_sensors(data->wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, in dell_wmi_ddv_temp_read_string()
408 &data->temps, sizeof(*entry)); in dell_wmi_ddv_temp_read_string()
412 if (channel >= data->temps.entries) in dell_wmi_ddv_temp_read_string()
413 return -ENXIO; in dell_wmi_ddv_temp_read_string()
415 entry = (struct thermal_sensor_entry *)data->temps.obj->package.elements[1].buffer.pointer; in dell_wmi_ddv_temp_read_string()
416 switch (entry[channel].type) { in dell_wmi_ddv_temp_read_string()
468 mutex_lock(&data->fans.lock); in dell_wmi_ddv_read_string()
470 mutex_unlock(&data->fans.lock); in dell_wmi_ddv_read_string()
479 mutex_lock(&data->temps.lock); in dell_wmi_ddv_read_string()
481 mutex_unlock(&data->temps.lock); in dell_wmi_ddv_read_string()
491 return -EOPNOTSUPP; in dell_wmi_ddv_read_string()
509 return ERR_PTR(-ENOMEM); in dell_wmi_ddv_channel_create()
511 cinfo->info.type = type; in dell_wmi_ddv_channel_create()
512 cinfo->info.config = cinfo->config; in dell_wmi_ddv_channel_create()
515 cinfo->config[i] = config; in dell_wmi_ddv_channel_create()
517 return &cinfo->info; in dell_wmi_ddv_channel_create()
522 if (!sensors->active) in dell_wmi_ddv_hwmon_cache_invalidate()
525 mutex_lock(&sensors->lock); in dell_wmi_ddv_hwmon_cache_invalidate()
526 kfree(sensors->obj); in dell_wmi_ddv_hwmon_cache_invalidate()
527 sensors->obj = NULL; in dell_wmi_ddv_hwmon_cache_invalidate()
528 mutex_unlock(&sensors->lock); in dell_wmi_ddv_hwmon_cache_invalidate()
535 sensors->active = false; in dell_wmi_ddv_hwmon_cache_destroy()
536 mutex_destroy(&sensors->lock); in dell_wmi_ddv_hwmon_cache_destroy()
537 kfree(sensors->obj); in dell_wmi_ddv_hwmon_cache_destroy()
541 enum dell_ddv_method method, in dell_wmi_ddv_channel_init() argument
550 ret = dell_wmi_ddv_update_sensors(wdev, method, sensors, entry_size); in dell_wmi_ddv_channel_init()
554 mutex_init(&sensors->lock); in dell_wmi_ddv_channel_init()
555 sensors->active = true; in dell_wmi_ddv_channel_init()
557 ret = devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors); in dell_wmi_ddv_channel_init()
561 info = dell_wmi_ddv_channel_create(&wdev->dev, sensors->entries, type, config); in dell_wmi_ddv_channel_init()
563 devm_release_action(&wdev->dev, dell_wmi_ddv_hwmon_cache_destroy, sensors); in dell_wmi_ddv_channel_init()
570 struct wmi_device *wdev = data->wdev; in dell_wmi_ddv_hwmon_add()
577 if (!devres_open_group(&wdev->dev, dell_wmi_ddv_hwmon_add, GFP_KERNEL)) in dell_wmi_ddv_hwmon_add()
578 return -ENOMEM; in dell_wmi_ddv_hwmon_add()
580 cinfo = devm_kzalloc(&wdev->dev, struct_size(cinfo, info, 4), GFP_KERNEL); in dell_wmi_ddv_hwmon_add()
582 ret = -ENOMEM; in dell_wmi_ddv_hwmon_add()
587 cinfo->chip.ops = &dell_wmi_ddv_ops; in dell_wmi_ddv_hwmon_add()
588 cinfo->chip.info = cinfo->info; in dell_wmi_ddv_hwmon_add()
590 info = dell_wmi_ddv_channel_create(&wdev->dev, 1, hwmon_chip, HWMON_C_REGISTER_TZ); in dell_wmi_ddv_hwmon_add()
597 cinfo->info[index] = info; in dell_wmi_ddv_hwmon_add()
600 info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_FAN_SENSOR_INFORMATION, &data->fans, in dell_wmi_ddv_hwmon_add()
604 cinfo->info[index] = info; in dell_wmi_ddv_hwmon_add()
608 info = dell_wmi_ddv_channel_init(wdev, DELL_DDV_THERMAL_SENSOR_INFORMATION, &data->temps, in dell_wmi_ddv_hwmon_add()
613 cinfo->info[index] = info; in dell_wmi_ddv_hwmon_add()
624 hdev = devm_hwmon_device_register_with_info(&wdev->dev, "dell_ddv", data, &cinfo->chip, in dell_wmi_ddv_hwmon_add()
632 devres_close_group(&wdev->dev, dell_wmi_ddv_hwmon_add); in dell_wmi_ddv_hwmon_add()
637 devres_release_group(&wdev->dev, dell_wmi_ddv_hwmon_add); in dell_wmi_ddv_hwmon_add()
648 return -ENODEV; in dell_wmi_ddv_battery_index()
660 ret = dell_wmi_ddv_battery_index(to_acpi_device(dev->parent), &index); in eppid_show()
664 ret = dell_wmi_ddv_query_string(data->wdev, DELL_DDV_BATTERY_EPPID, index, &obj); in eppid_show()
668 if (obj->string.length != DELL_EPPID_LENGTH && obj->string.length != DELL_EPPID_EXT_LENGTH) in eppid_show()
669 dev_info_once(&data->wdev->dev, FW_INFO "Suspicious ePPID length (%d)\n", in eppid_show()
670 obj->string.length); in eppid_show()
672 ret = sysfs_emit(buf, "%s\n", obj->string.pointer); in eppid_show()
687 ret = dell_wmi_ddv_battery_index(to_acpi_device(psy->dev.parent), &index); in dell_wmi_ddv_get_property()
693 ret = dell_wmi_ddv_query_integer(data->wdev, DELL_DDV_BATTERY_TEMPERATURE, index, in dell_wmi_ddv_get_property()
701 val->intval = value - 2732; in dell_wmi_ddv_get_property()
704 return -EINVAL; in dell_wmi_ddv_get_property()
726 ret = dell_wmi_ddv_battery_index(to_acpi_device(battery->dev.parent), &index); in dell_wmi_ddv_add_battery()
730 ret = device_create_file(&battery->dev, &data->eppid_attr); in dell_wmi_ddv_add_battery()
734 ret = power_supply_register_extension(battery, &dell_wmi_ddv_extension, &data->wdev->dev, in dell_wmi_ddv_add_battery()
737 device_remove_file(&battery->dev, &data->eppid_attr); in dell_wmi_ddv_add_battery()
749 device_remove_file(&battery->dev, &data->eppid_attr); in dell_wmi_ddv_remove_battery()
757 data->hook.name = "Dell DDV Battery Extension"; in dell_wmi_ddv_battery_add()
758 data->hook.add_battery = dell_wmi_ddv_add_battery; in dell_wmi_ddv_battery_add()
759 data->hook.remove_battery = dell_wmi_ddv_remove_battery; in dell_wmi_ddv_battery_add()
761 sysfs_attr_init(&data->eppid_attr.attr); in dell_wmi_ddv_battery_add()
762 data->eppid_attr.attr.name = "eppid"; in dell_wmi_ddv_battery_add()
763 data->eppid_attr.attr.mode = 0444; in dell_wmi_ddv_battery_add()
764 data->eppid_attr.show = eppid_show; in dell_wmi_ddv_battery_add()
766 return devm_battery_hook_register(&data->wdev->dev, &data->hook); in dell_wmi_ddv_battery_add()
769 static int dell_wmi_ddv_buffer_read(struct seq_file *seq, enum dell_ddv_method method) in dell_wmi_ddv_buffer_read() argument
771 struct device *dev = seq->private; in dell_wmi_ddv_buffer_read()
778 ret = dell_wmi_ddv_query_buffer(data->wdev, method, 0, &obj); in dell_wmi_ddv_buffer_read()
782 size = obj->package.elements[0].integer.value; in dell_wmi_ddv_buffer_read()
783 buf = obj->package.elements[1].buffer.pointer; in dell_wmi_ddv_buffer_read()
802 struct dentry *entry = data; in dell_wmi_ddv_debugfs_remove() local
804 debugfs_remove(entry); in dell_wmi_ddv_debugfs_remove()
809 struct dentry *entry; in dell_wmi_ddv_debugfs_init() local
812 scnprintf(name, ARRAY_SIZE(name), "%s-%s", DRIVER_NAME, dev_name(&wdev->dev)); in dell_wmi_ddv_debugfs_init()
813 entry = debugfs_create_dir(name, NULL); in dell_wmi_ddv_debugfs_init()
815 debugfs_create_devm_seqfile(&wdev->dev, "fan_sensor_information", entry, in dell_wmi_ddv_debugfs_init()
817 debugfs_create_devm_seqfile(&wdev->dev, "thermal_sensor_information", entry, in dell_wmi_ddv_debugfs_init()
820 devm_add_action_or_reset(&wdev->dev, dell_wmi_ddv_debugfs_remove, entry); in dell_wmi_ddv_debugfs_init()
833 dev_dbg(&wdev->dev, "WMI interface version: %d\n", version); in dell_wmi_ddv_probe()
836 return -ENODEV; in dell_wmi_ddv_probe()
838 dev_warn(&wdev->dev, "Loading despite unsupported WMI interface version (%u)\n", in dell_wmi_ddv_probe()
842 data = devm_kzalloc(&wdev->dev, sizeof(*data), GFP_KERNEL); in dell_wmi_ddv_probe()
844 return -ENOMEM; in dell_wmi_ddv_probe()
846 dev_set_drvdata(&wdev->dev, data); in dell_wmi_ddv_probe()
847 data->wdev = wdev; in dell_wmi_ddv_probe()
854 dev_warn(&wdev->dev, "Unable to register ACPI battery hook: %d\n", ret); in dell_wmi_ddv_probe()
860 dev_warn(&wdev->dev, "Unable to register hwmon interface: %d\n", ret); in dell_wmi_ddv_probe()
870 /* Force re-reading of all active sensors */ in dell_wmi_ddv_resume()
871 dell_wmi_ddv_hwmon_cache_invalidate(&data->fans); in dell_wmi_ddv_resume()
872 dell_wmi_ddv_hwmon_cache_invalidate(&data->temps); in dell_wmi_ddv_resume()