File Index
Files and directories
Sign in
FILE

wmi_util.c

File preview with syntax highlighting.

linux-6.19.14/drivers/platform/x86/tuxedo/nb04/wmi_util.c C
 1// SPDX-License-Identifier: GPL-2.0-or-later
 2/*
 3 * This code gives functions to avoid code duplication while interacting with
 4 * the TUXEDO NB04 wmi interfaces.
 5 *
 6 * Copyright (C) 2024-2025 Werner Sembach <wse@tuxedocomputers.com>
 7 */
 8
 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
10
11#include <linux/cleanup.h>
12#include <linux/wmi.h>
13
14#include "wmi_util.h"
15
16static int __wmi_method_acpi_object_out(struct wmi_device *wdev,
17					u32 wmi_method_id,
18					u8 *in,
19					acpi_size in_len,
20					union acpi_object **out)
21{
22	struct acpi_buffer acpi_buffer_in = { in_len, in };
23	struct acpi_buffer acpi_buffer_out = { ACPI_ALLOCATE_BUFFER, NULL };
24
25	dev_dbg(&wdev->dev, "Evaluate WMI method: %u in:\n", wmi_method_id);
26	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, in, in_len);
27
28	acpi_status status = wmidev_evaluate_method(wdev, 0, wmi_method_id,
29						    &acpi_buffer_in,
30						    &acpi_buffer_out);
31	if (ACPI_FAILURE(status)) {
32		dev_err(&wdev->dev, "Failed to evaluate WMI method.\n");
33		return -EIO;
34	}
35	if (!acpi_buffer_out.pointer) {
36		dev_err(&wdev->dev, "Unexpected empty out buffer.\n");
37		return -ENODATA;
38	}
39
40	*out = acpi_buffer_out.pointer;
41
42	return 0;
43}
44
45static int __wmi_method_buffer_out(struct wmi_device *wdev,
46				   u32 wmi_method_id,
47				   u8 *in,
48				   acpi_size in_len,
49				   u8 *out,
50				   acpi_size out_len)
51{
52	int ret;
53
54	union acpi_object *acpi_object_out __free(kfree) = NULL;
55
56	ret = __wmi_method_acpi_object_out(wdev, wmi_method_id,
57					   in, in_len,
58					   &acpi_object_out);
59	if (ret)
60		return ret;
61
62	if (acpi_object_out->type != ACPI_TYPE_BUFFER) {
63		dev_err(&wdev->dev, "Unexpected out buffer type. Expected: %u Got: %u\n",
64			ACPI_TYPE_BUFFER, acpi_object_out->type);
65		return -EIO;
66	}
67	if (acpi_object_out->buffer.length < out_len) {
68		dev_err(&wdev->dev, "Unexpected out buffer length.\n");
69		return -EIO;
70	}
71
72	memcpy(out, acpi_object_out->buffer.pointer, out_len);
73
74	return 0;
75}
76
77int tux_wmi_xx_8in_80out(struct wmi_device *wdev,
78			 enum tux_wmi_xx_8in_80out_methods method,
79			 union tux_wmi_xx_8in_80out_in_t *in,
80			 union tux_wmi_xx_8in_80out_out_t *out)
81{
82	return __wmi_method_buffer_out(wdev, method, in->raw, 8, out->raw, 80);
83}
84
85int tux_wmi_xx_496in_80out(struct wmi_device *wdev,
86			   enum tux_wmi_xx_496in_80out_methods method,
87			   union tux_wmi_xx_496in_80out_in_t *in,
88			   union tux_wmi_xx_496in_80out_out_t *out)
89{
90	return __wmi_method_buffer_out(wdev, method, in->raw, 496, out->raw, 80);
91}
~/ Read-only file preview.