diff options
| author | Armin Wolf <W_Armin@gmx.de> | 2026-06-10 22:34:46 +0200 |
|---|---|---|
| committer | Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> | 2026-06-12 16:01:44 +0300 |
| commit | 1719340487e63da13f2ac25e488c72737a545772 (patch) | |
| tree | 4cad52160c98aeaab4ea015146bdcb23902c9eba /drivers/platform | |
| parent | 0f2d6a308210caaa5e0ebf9c085d87f4a2c06bfa (diff) | |
platform/x86: dell-privacy: Use new buffer-based WMI API
Use the new buffer-based WMI API to also support ACPI firmware
implementations that do not use ACPI buffers for the device state.
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Link: https://patch.msgid.link/20260610203453.816254-3-W_Armin@gmx.de
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Diffstat (limited to 'drivers/platform')
| -rw-r--r-- | drivers/platform/x86/dell/dell-wmi-privacy.c | 77 |
1 files changed, 34 insertions, 43 deletions
diff --git a/drivers/platform/x86/dell/dell-wmi-privacy.c b/drivers/platform/x86/dell/dell-wmi-privacy.c index ed099a431ea4..f9d275b2f900 100644 --- a/drivers/platform/x86/dell/dell-wmi-privacy.c +++ b/drivers/platform/x86/dell/dell-wmi-privacy.c @@ -9,11 +9,14 @@ #include <linux/acpi.h> #include <linux/bitops.h> +#include <linux/cleanup.h> +#include <linux/compiler_attributes.h> #include <linux/input.h> #include <linux/input/sparse-keymap.h> #include <linux/list.h> #include <linux/leds.h> #include <linux/module.h> +#include <linux/types.h> #include <linux/wmi.h> #include "dell-wmi-privacy.h" @@ -26,6 +29,26 @@ #define led_to_priv(c) container_of(c, struct privacy_wmi_data, cdev) /* + * Describes the Device State class exposed by BIOS which can be consumed by + * various applications interested in knowing the Privacy feature capabilities. + * class DeviceState + * { + * [key, read] string InstanceName; + * [read] boolean ReadOnly; + * + * [WmiDataId(1), read] uint32 DevicesSupported; + * 0 - None; 0x1 - Microphone; 0x2 - Camera; 0x4 - ePrivacy Screen + * + * [WmiDataId(2), read] uint32 CurrentState; + * 0 - Off; 1 - On; Bit0 - Microphone; Bit1 - Camera; Bit2 - ePrivacyScreen + * }; + */ +struct device_state { + __le32 devices_supported; + __le32 current_state; +} __packed; + +/* * The wmi_list is used to store the privacy_priv struct with mutex protecting */ static LIST_HEAD(wmi_list); @@ -185,60 +208,28 @@ static struct attribute *privacy_attrs[] = { }; ATTRIBUTE_GROUPS(privacy); -/* - * Describes the Device State class exposed by BIOS which can be consumed by - * various applications interested in knowing the Privacy feature capabilities. - * class DeviceState - * { - * [key, read] string InstanceName; - * [read] boolean ReadOnly; - * - * [WmiDataId(1), read] uint32 DevicesSupported; - * 0 - None; 0x1 - Microphone; 0x2 - Camera; 0x4 - ePrivacy Screen - * - * [WmiDataId(2), read] uint32 CurrentState; - * 0 - Off; 1 - On; Bit0 - Microphone; Bit1 - Camera; Bit2 - ePrivacyScreen - * }; - */ static int get_current_status(struct wmi_device *wdev) { struct privacy_wmi_data *priv = dev_get_drvdata(&wdev->dev); - union acpi_object *obj_present; - u32 *buffer; - int ret = 0; + struct wmi_buffer buffer; + int ret; if (!priv) { dev_err(&wdev->dev, "dell privacy priv is NULL\n"); return -EINVAL; } + /* check privacy support features and device states */ - obj_present = wmidev_block_query(wdev, 0); - if (!obj_present) { - dev_err(&wdev->dev, "failed to read Binary MOF\n"); - return -EIO; - } + ret = wmidev_query_block(wdev, 0, &buffer, sizeof(struct device_state)); + if (ret < 0) + return ret; - if (obj_present->type != ACPI_TYPE_BUFFER) { - dev_err(&wdev->dev, "Binary MOF is not a buffer!\n"); - ret = -EIO; - goto obj_free; - } - /* Although it's not technically a failure, this would lead to - * unexpected behavior - */ - if (obj_present->buffer.length != 8) { - dev_err(&wdev->dev, "Dell privacy buffer has unexpected length (%d)!\n", - obj_present->buffer.length); - ret = -EINVAL; - goto obj_free; - } - buffer = (u32 *)obj_present->buffer.pointer; - priv->features_present = buffer[0]; - priv->last_status = buffer[1]; + struct device_state *state __free(kfree) = buffer.data; -obj_free: - kfree(obj_present); - return ret; + priv->features_present = le32_to_cpu(state->devices_supported); + priv->last_status = le32_to_cpu(state->current_state); + + return 0; } static int dell_privacy_micmute_led_set(struct led_classdev *led_cdev, |
