// SPDX-License-Identifier: GPL-2.0-or-later /* * This code gives functions to avoid code duplication while interacting with * the TUXEDO NB04 wmi interfaces. * * Copyright (C) 2024-2025 Werner Sembach */ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include #include "wmi_util.h" static int __wmi_method_acpi_object_out(struct wmi_device *wdev, u32 wmi_method_id, u8 *in, acpi_size in_len, union acpi_object **out) { struct acpi_buffer acpi_buffer_in = { in_len, in }; struct acpi_buffer acpi_buffer_out = { ACPI_ALLOCATE_BUFFER, NULL }; dev_dbg(&wdev->dev, "Evaluate WMI method: %u in:\n", wmi_method_id); print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, in, in_len); acpi_status status = wmidev_evaluate_method(wdev, 0, wmi_method_id, &acpi_buffer_in, &acpi_buffer_out); if (ACPI_FAILURE(status)) { dev_err(&wdev->dev, "Failed to evaluate WMI method.\n"); return -EIO; } if (!acpi_buffer_out.pointer) { dev_err(&wdev->dev, "Unexpected empty out buffer.\n"); return -ENODATA; } *out = acpi_buffer_out.pointer; return 0; } static int __wmi_method_buffer_out(struct wmi_device *wdev, u32 wmi_method_id, u8 *in, acpi_size in_len, u8 *out, acpi_size out_len) { int ret; union acpi_object *acpi_object_out __free(kfree) = NULL; ret = __wmi_method_acpi_object_out(wdev, wmi_method_id, in, in_len, &acpi_object_out); if (ret) return ret; if (acpi_object_out->type != ACPI_TYPE_BUFFER) { dev_err(&wdev->dev, "Unexpected out buffer type. Expected: %u Got: %u\n", ACPI_TYPE_BUFFER, acpi_object_out->type); return -EIO; } if (acpi_object_out->buffer.length < out_len) { dev_err(&wdev->dev, "Unexpected out buffer length.\n"); return -EIO; } memcpy(out, acpi_object_out->buffer.pointer, out_len); return 0; } int tux_wmi_xx_8in_80out(struct wmi_device *wdev, enum tux_wmi_xx_8in_80out_methods method, union tux_wmi_xx_8in_80out_in_t *in, union tux_wmi_xx_8in_80out_out_t *out) { return __wmi_method_buffer_out(wdev, method, in->raw, 8, out->raw, 80); } int tux_wmi_xx_496in_80out(struct wmi_device *wdev, enum tux_wmi_xx_496in_80out_methods method, union tux_wmi_xx_496in_80out_in_t *in, union tux_wmi_xx_496in_80out_out_t *out) { return __wmi_method_buffer_out(wdev, method, in->raw, 496, out->raw, 80); }