From 4df11ab1bd9ad50e6ed928d1c2f3a8404775837b Mon Sep 17 00:00:00 2001 From: Andrey Smirnov Date: Sun, 27 Feb 2022 12:58:05 -0800 Subject: [PATCH 4/6] leds: steamdeck: Add support for Steam Deck LED (cherry picked from commit 85a86d19aa7022ff0555023d53aef78323a42d0c) Signed-off-by: Cristian Ciocaltea Signed-off-by: Alexandre Frade --- drivers/leds/Kconfig | 7 ++++ drivers/leds/Makefile | 1 + drivers/leds/leds-steamdeck.c | 74 +++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+) create mode 100644 drivers/leds/leds-steamdeck.c --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -959,6 +959,13 @@ config LEDS_ACER_A500 This option enables support for the Power Button LED of Acer Iconia Tab A500. +config LEDS_STEAMDECK + tristate "LED support for Steam Deck" + depends on LEDS_CLASS && MFD_STEAMDECK + help + This option enabled support for the status LED (next to the + power button) on Steam Deck + source "drivers/leds/blink/Kconfig" comment "Flash and Torch LED drivers" --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -81,6 +81,7 @@ obj-$(CONFIG_LEDS_POWERNV) += leds-powe obj-$(CONFIG_LEDS_PWM) += leds-pwm.o obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o obj-$(CONFIG_LEDS_SC27XX_BLTC) += leds-sc27xx-bltc.o +obj-$(CONFIG_LEDS_STEAMDECK) += leds-steamdeck.o obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o obj-$(CONFIG_LEDS_SUNFIRE) += leds-sunfire.o obj-$(CONFIG_LEDS_SYSCON) += leds-syscon.o --- /dev/null +++ b/drivers/leds/leds-steamdeck.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0+ + +/* + * Steam Deck EC MFD LED cell driver + * + * Copyright (C) 2021-2022 Valve Corporation + * + */ + +#include +#include +#include + +struct steamdeck_led { + struct acpi_device *adev; + struct led_classdev cdev; +}; + +static int steamdeck_leds_brightness_set(struct led_classdev *cdev, + enum led_brightness value) +{ + struct steamdeck_led *sd = container_of(cdev, struct steamdeck_led, + cdev); + + if (ACPI_FAILURE(acpi_execute_simple_method(sd->adev->handle, + "CHBV", value))) + return -EIO; + + return 0; +} + +static int steamdeck_leds_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct steamdeck_led *sd; + int ret; + + sd = devm_kzalloc(dev, sizeof(*sd), GFP_KERNEL); + if (!sd) + return -ENOMEM; + + sd->adev = ACPI_COMPANION(dev->parent); + + sd->cdev.name = "status:white"; + sd->cdev.brightness_set_blocking = steamdeck_leds_brightness_set; + sd->cdev.max_brightness = 100; + + ret = devm_led_classdev_register(dev, &sd->cdev); + if (ret) { + dev_err(dev, "Failed to register LEDs device: %d\n", ret); + return ret; + } + + return 0; +} + +static const struct platform_device_id steamdeck_leds_id_table[] = { + { .name = "steamdeck-leds" }, + {} +}; +MODULE_DEVICE_TABLE(platform, steamdeck_leds_id_table); + +static struct platform_driver steamdeck_leds_driver = { + .probe = steamdeck_leds_probe, + .driver = { + .name = "steamdeck-leds", + }, + .id_table = steamdeck_leds_id_table, +}; +module_platform_driver(steamdeck_leds_driver); + +MODULE_AUTHOR("Andrey Smirnov "); +MODULE_DESCRIPTION("Steam Deck LEDs driver"); +MODULE_LICENSE("GPL");