1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Alienware LEGACY WMI device driver 4 * 5 * Copyright (C) 2025 Kurt Borja <kuurtb@gmail.com> 6 */ 7 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 9 10 #include <linux/wmi.h> 11 #include "alienware-wmi.h" 12 13 struct legacy_led_args { 14 struct color_platform colors; 15 u8 brightness; 16 u8 state; 17 } __packed; 18 19 20 /* 21 * Legacy WMI driver 22 */ 23 static int legacy_wmi_update_led(struct alienfx_priv *priv, 24 struct wmi_device *wdev, u8 location) 25 { 26 struct legacy_led_args legacy_args = { 27 .colors = priv->colors[location], 28 .brightness = priv->global_brightness, 29 .state = 0, 30 }; 31 struct acpi_buffer input; 32 acpi_status status; 33 34 if (legacy_args.state != LEGACY_RUNNING) { 35 legacy_args.state = priv->lighting_control_state; 36 37 input.length = sizeof(legacy_args); 38 input.pointer = &legacy_args; 39 40 status = wmi_evaluate_method(LEGACY_POWER_CONTROL_GUID, 0, 41 location + 1, &input, NULL); 42 if (ACPI_FAILURE(status)) 43 return -EIO; 44 45 return 0; 46 } 47 48 return alienware_wmi_command(wdev, location + 1, &legacy_args, 49 sizeof(legacy_args), NULL); 50 } 51 52 static int legacy_wmi_update_brightness(struct alienfx_priv *priv, 53 struct wmi_device *wdev, u8 brightness) 54 { 55 return legacy_wmi_update_led(priv, wdev, 0); 56 } 57 58 static int legacy_wmi_probe(struct wmi_device *wdev, const void *context) 59 { 60 struct alienfx_platdata pdata = { 61 .wdev = wdev, 62 .ops = { 63 .upd_led = legacy_wmi_update_led, 64 .upd_brightness = legacy_wmi_update_brightness, 65 }, 66 }; 67 68 return alienware_alienfx_setup(&pdata); 69 } 70 71 static const struct wmi_device_id alienware_legacy_device_id_table[] = { 72 { LEGACY_CONTROL_GUID, NULL }, 73 { }, 74 }; 75 MODULE_DEVICE_TABLE(wmi, alienware_legacy_device_id_table); 76 77 static struct wmi_driver alienware_legacy_wmi_driver = { 78 .driver = { 79 .name = "alienware-wmi-alienfx", 80 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 81 }, 82 .id_table = alienware_legacy_device_id_table, 83 .probe = legacy_wmi_probe, 84 .no_singleton = true, 85 }; 86 87 int __init alienware_legacy_wmi_init(void) 88 { 89 return wmi_driver_register(&alienware_legacy_wmi_driver); 90 } 91 92 void __exit alienware_legacy_wmi_exit(void) 93 { 94 wmi_driver_unregister(&alienware_legacy_wmi_driver); 95 } 96