mirror of
https://github.com/torvalds/linux.git
synced 2026-05-27 00:22:00 +02:00
platform/x86: alienware-wmi: Add a state container for LED control feature
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>
This commit is contained in:
parent
56f529ce43
commit
4c546de990
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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");
|
||||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
struct alienfx_priv *priv = container_of(led_cdev, struct alienfx_priv,
|
||||
global_led);
|
||||
|
||||
static struct led_classdev global_led = {
|
||||
.brightness_set = global_led_set,
|
||||
.brightness_get = global_led_get,
|
||||
.name = "alienware::global_brightness",
|
||||
};
|
||||
|
||||
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,
|
||||
|
|
@ -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,
|
||||
|
|
@ -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)
|
||||
|
|
@ -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:
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user