Unverified Commit 4c546de9 authored by Kurt Borja's avatar Kurt Borja Committed by Ilpo Järvinen
Browse files

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: default avatarArmin Wolf <W_Armin@gmx.de>
Signed-off-by: default avatarKurt Borja <kuurtb@gmail.com>
Link: https://lore.kernel.org/r/20250207154610.13675-2-kuurtb@gmail.com


Reviewed-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: default avatarIlpo Järvinen <ilpo.jarvinen@linux.intel.com>
parent 56f529ce
Loading
Loading
Loading
Loading
+68 −57
Original line number Diff line number Diff line
@@ -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;
}

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,
@@ -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);
}