Skip to content

Commit

Permalink
platform/x86: alienware-wmi: Add a state container for LED control fe…
Browse files Browse the repository at this point in the history
…ature

Add a state container for the "alienware-wmi" platform device and
initialize it on the new alienfx_probe(). Migrate all LED control functions
to use this state container to support upcoming file split.

Additionally move the led_classdev registration to the platform driver
probe and make it device managed.

Drop alienware_zone_init() and alienware_zone_exit() because they are no
longer needed and mimic the `quirks->num_zone > 0` check by failing the
platform device probe.

Reviewed-by: Armin Wolf <W_Armin@gmx.de>
Signed-off-by: Kurt Borja <kuurtb@gmail.com>
Link: https://lore.kernel.org/r/20250207154610.13675-2-kuurtb@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
  • Loading branch information
Kurt Borja authored and Ilpo Järvinen committed Feb 10, 2025
1 parent 56f529c commit 4c546de
Showing 1 changed file with 68 additions and 57 deletions.
125 changes: 68 additions & 57 deletions drivers/platform/x86/dell/alienware-wmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,13 +413,18 @@ struct wmax_u32_args {
u8 arg3;
};

struct alienfx_priv {
struct platform_device *pdev;
struct led_classdev global_led;
struct color_platform colors[4];
u8 global_brightness;
u8 lighting_control_state;
};

static struct platform_device *platform_device;
static struct color_platform colors[4];
static enum wmax_thermal_mode supported_thermal_profiles[PLATFORM_PROFILE_LAST];

static u8 interface;
static u8 lighting_control_state;
static u8 global_brightness;

/*
* Helpers used for zone control
Expand Down Expand Up @@ -451,7 +456,7 @@ static int parse_rgb(const char *buf, struct color_platform *colors)
/*
* Individual RGB zone control
*/
static int alienware_update_led(u8 location)
static int alienware_update_led(struct alienfx_priv *priv, u8 location)
{
int method_id;
acpi_status status;
Expand All @@ -461,21 +466,21 @@ static int alienware_update_led(u8 location)
struct wmax_led_args wmax_basic_args;
if (interface == WMAX) {
wmax_basic_args.led_mask = 1 << location;
wmax_basic_args.colors = colors[location];
wmax_basic_args.state = lighting_control_state;
wmax_basic_args.colors = priv->colors[location];
wmax_basic_args.state = priv->lighting_control_state;
guid = WMAX_CONTROL_GUID;
method_id = WMAX_METHOD_ZONE_CONTROL;

input.length = sizeof(wmax_basic_args);
input.pointer = &wmax_basic_args;
} else {
legacy_args.colors = colors[location];
legacy_args.brightness = global_brightness;
legacy_args.colors = priv->colors[location];
legacy_args.brightness = priv->global_brightness;
legacy_args.state = 0;
if (lighting_control_state == LEGACY_BOOTING ||
lighting_control_state == LEGACY_SUSPEND) {
if (priv->lighting_control_state == LEGACY_BOOTING ||
priv->lighting_control_state == LEGACY_SUSPEND) {
guid = LEGACY_POWER_CONTROL_GUID;
legacy_args.state = lighting_control_state;
legacy_args.state = priv->lighting_control_state;
} else
guid = LEGACY_CONTROL_GUID;
method_id = location + 1;
Expand All @@ -494,22 +499,26 @@ static int alienware_update_led(u8 location)
static ssize_t zone_show(struct device *dev, struct device_attribute *attr,
char *buf, u8 location)
{
struct alienfx_priv *priv = dev_get_drvdata(dev);
struct color_platform *colors = &priv->colors[location];

return sprintf(buf, "red: %d, green: %d, blue: %d\n",
colors[location].red, colors[location].green,
colors[location].blue);
colors->red, colors->green, colors->blue);

}

static ssize_t zone_store(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count, u8 location)
{
struct alienfx_priv *priv = dev_get_drvdata(dev);
struct color_platform *colors = &priv->colors[location];
int ret;

ret = parse_rgb(buf, &colors[location]);
ret = parse_rgb(buf, colors);
if (ret)
return ret;

ret = alienware_update_led(location);
ret = alienware_update_led(priv, location);

return ret ? ret : count;
}
Expand Down Expand Up @@ -577,9 +586,11 @@ static ssize_t lighting_control_state_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
if (lighting_control_state == LEGACY_BOOTING)
struct alienfx_priv *priv = dev_get_drvdata(dev);

if (priv->lighting_control_state == LEGACY_BOOTING)
return sysfs_emit(buf, "[booting] running suspend\n");
else if (lighting_control_state == LEGACY_SUSPEND)
else if (priv->lighting_control_state == LEGACY_SUSPEND)
return sysfs_emit(buf, "booting running [suspend]\n");

return sysfs_emit(buf, "booting [running] suspend\n");
Expand All @@ -589,6 +600,7 @@ static ssize_t lighting_control_state_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct alienfx_priv *priv = dev_get_drvdata(dev);
u8 val;

if (strcmp(buf, "booting\n") == 0)
Expand All @@ -600,9 +612,9 @@ static ssize_t lighting_control_state_store(struct device *dev,
else
val = WMAX_RUNNING;

lighting_control_state = val;
priv->lighting_control_state = val;
pr_debug("alienware-wmi: updated control state to %d\n",
lighting_control_state);
priv->lighting_control_state);

return count;
}
Expand Down Expand Up @@ -662,46 +674,26 @@ static int wmax_brightness(int brightness)
static void global_led_set(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
struct alienfx_priv *priv = container_of(led_cdev, struct alienfx_priv,
global_led);
int ret;
global_brightness = brightness;

priv->global_brightness = brightness;

if (interface == WMAX)
ret = wmax_brightness(brightness);
else
ret = alienware_update_led(0);
ret = alienware_update_led(priv, 0);
if (ret)
pr_err("LED brightness update failed\n");
}

static enum led_brightness global_led_get(struct led_classdev *led_cdev)
{
return global_brightness;
}

static struct led_classdev global_led = {
.brightness_set = global_led_set,
.brightness_get = global_led_get,
.name = "alienware::global_brightness",
};
struct alienfx_priv *priv = container_of(led_cdev, struct alienfx_priv,
global_led);

static int alienware_zone_init(struct platform_device *dev)
{
if (interface == WMAX) {
lighting_control_state = WMAX_RUNNING;
} else if (interface == LEGACY) {
lighting_control_state = LEGACY_RUNNING;
}
global_led.max_brightness = 0x0F;
global_brightness = global_led.max_brightness;

return led_classdev_register(&dev->dev, &global_led);
}

static void alienware_zone_exit(struct platform_device *dev)
{
if (!quirks->num_zones)
return;

led_classdev_unregister(&global_led);
return priv->global_brightness;
}

static acpi_status alienware_wmax_command(void *in_args, size_t in_size,
Expand Down Expand Up @@ -1157,6 +1149,33 @@ static int create_thermal_profile(struct platform_device *platform_device)
/*
* Platform Driver
*/
static int alienfx_probe(struct platform_device *pdev)
{
struct alienfx_priv *priv;

if (!quirks->num_zones)
return -ENODEV;

priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

if (interface == WMAX)
priv->lighting_control_state = WMAX_RUNNING;
else
priv->lighting_control_state = LEGACY_RUNNING;

priv->pdev = pdev;
priv->global_led.name = "alienware::global_brightness";
priv->global_led.brightness_set = global_led_set;
priv->global_led.brightness_get = global_led_get;
priv->global_led.max_brightness = 0x0F;
priv->global_brightness = priv->global_led.max_brightness;
platform_set_drvdata(pdev, priv);

return devm_led_classdev_register(&pdev->dev, &priv->global_led);
}

static const struct attribute_group *alienfx_groups[] = {
&zone_attribute_group,
&hdmi_attribute_group,
Expand All @@ -1170,6 +1189,7 @@ static struct platform_driver platform_driver = {
.name = "alienware-wmi",
.dev_groups = alienfx_groups,
},
.probe = alienfx_probe,
};

static int __init alienware_wmi_init(void)
Expand Down Expand Up @@ -1217,16 +1237,8 @@ static int __init alienware_wmi_init(void)
goto fail_prep_thermal_profile;
}

if (quirks->num_zones > 0) {
ret = alienware_zone_init(platform_device);
if (ret)
goto fail_prep_zones;
}

return 0;

fail_prep_zones:
alienware_zone_exit(platform_device);
fail_prep_thermal_profile:
platform_device_del(platform_device);
fail_platform_device2:
Expand All @@ -1241,7 +1253,6 @@ module_init(alienware_wmi_init);

static void __exit alienware_wmi_exit(void)
{
alienware_zone_exit(platform_device);
platform_device_unregister(platform_device);
platform_driver_unregister(&platform_driver);
}
Expand Down

0 comments on commit 4c546de

Please sign in to comment.