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