diff --git a/Documentation/devicetree/bindings/leds/wirenboard,wbec-led.yaml b/Documentation/devicetree/bindings/leds/wirenboard,wbec-led.yaml new file mode 100644 index 0000000000000..ad6d0e394400b --- /dev/null +++ b/Documentation/devicetree/bindings/leds/wirenboard,wbec-led.yaml @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/leds/wirenboard,wbec-led.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Wiren Board Embedded Controller LED Driver + +maintainers: + - Vitalii Gaponov + +description: | + Enables access to the LED on the Wiren Board Embedded Controller. + +properties: + compatible: + const: wirenboard,wbec-led + + reg: + const: 0 + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + wbec_led: wbec-led@0 { + compatible = "wirenboard,wbec-led"; + reg = <0>; + }; +... diff --git a/Documentation/devicetree/bindings/mfd/wirenboard,wbec.yaml b/Documentation/devicetree/bindings/mfd/wirenboard,wbec.yaml index 1ce8ccb1206c4..cf72b4ab03282 100644 --- a/Documentation/devicetree/bindings/mfd/wirenboard,wbec.yaml +++ b/Documentation/devicetree/bindings/mfd/wirenboard,wbec.yaml @@ -12,7 +12,8 @@ maintainers: description: | Wiren Board Embedded Controller (WB EC, wbec) is an MCU with special firmware installed on Wiren Board Automation Controller since HW revision 7.4. - WB EC is MFD device and provides such function as RTC, WDT, GPIO, ADC, PWRKEY. + WB EC is MFD device and provides such function as RTC, WDT, GPIO, ADC, LED, + PWRKEY. properties: compatible: @@ -79,6 +80,11 @@ examples: #io-channel-cells = <1>; }; + wbec_led: wbec-led@0 { + compatible = "wirenboard,wbec-led"; + reg = <0>; + }; + vin: wbec-power@0 { compatible = "wirenboard,wbec-power"; reg = <0>; diff --git a/Documentation/driver-api/wbec.rst b/Documentation/driver-api/wbec.rst index 3779419a87018..83dca40c54313 100644 --- a/Documentation/driver-api/wbec.rst +++ b/Documentation/driver-api/wbec.rst @@ -23,6 +23,7 @@ sub-drivers for each device connected to WBEC: * rtc-wbec - RTC driver * pwrkey-wbec - Power key driver * wbec-power - Power driver + * leds-wbec - LED driver The wbec driver also provides a set of sysfs attributes for WBEC: diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616-wirenboard84x.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616-wirenboard84x.dtsi index b48d2dd56ef75..e5a4d163e9683 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h616-wirenboard84x.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616-wirenboard84x.dtsi @@ -647,6 +647,11 @@ #io-channel-cells = <1>; }; + wbec_led: wbec-led@0 { + compatible = "wirenboard,wbec-led"; + reg = <0>; + }; + vin: wbec-power@0 { compatible = "wirenboard,wbec-power"; reg = <0>; diff --git a/arch/arm64/configs/wb8.config b/arch/arm64/configs/wb8.config index 9647e810b77ba..d85ef46d6d13d 100644 --- a/arch/arm64/configs/wb8.config +++ b/arch/arm64/configs/wb8.config @@ -117,6 +117,7 @@ CONFIG_WBEC_POWER=y CONFIG_WBEC_WATCHDOG=y CONFIG_RTC_DRV_WBEC=y CONFIG_WBEC_ADC=y +CONFIG_LEDS_WBEC=y # SD3078 RTC (optional on boards without WBEC) CONFIG_RTC_DRV_SD3078=y diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index d721b254e1e45..5d40d9da26377 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig @@ -545,6 +545,15 @@ config LEDS_PCA995X LED driver chips accessed via the I2C bus. Supported devices include PCA9955BTW, PCA9952TW and PCA9955TW. +config LEDS_WBEC + tristate "Wiren Board Embedded Controller LED Driver" + depends on LEDS_CLASS + depends on SPI + depends on MFD_WBEC + help + This option enables support for LED connected to the + Wiren Board Embedded Controller accessed via the SPI bus. + config LEDS_WM831X_STATUS tristate "LED support for status LEDs on WM831x PMICs" depends on LEDS_CLASS diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index ce07dc295ff00..81c64ae214bd0 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_LEDS_TI_LMU_COMMON) += leds-ti-lmu-common.o obj-$(CONFIG_LEDS_TLC591XX) += leds-tlc591xx.o obj-$(CONFIG_LEDS_TPS6105X) += leds-tps6105x.o obj-$(CONFIG_LEDS_TURRIS_OMNIA) += leds-turris-omnia.o +obj-$(CONFIG_LEDS_WBEC) += leds-wbec.o obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o obj-$(CONFIG_LEDS_WRAP) += leds-wrap.o diff --git a/drivers/leds/leds-wbec.c b/drivers/leds/leds-wbec.c new file mode 100644 index 0000000000000..db9288caa8caf --- /dev/null +++ b/drivers/leds/leds-wbec.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * led-wbec.c - Wiren Board Embedded Controller LED driver + * + * Copyright (c) 2024 Wiren Board LLC + * + * Author: Vitalii Gaponov + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +struct wbec_led { + struct led_classdev cdev; + struct regmap *regmap; +}; + +static void wbec_led_set(struct led_classdev *led_cdev, + enum led_brightness value) +{ + struct wbec_led *wbec_led = container_of(led_cdev, struct wbec_led, cdev); + regmap_write(wbec_led->regmap, WBEC_REG_LED_CTRL, value ? WBEC_REG_LED_CTRL_STATE_MSK : 0); +} + +static int wbec_led_probe(struct platform_device *pdev) +{ + struct wbec *wbec = dev_get_drvdata(pdev->dev.parent); + struct wbec_led *wbec_led; + int err; + + if (!pdev->dev.parent) + return -ENODEV; + + wbec_led = devm_kzalloc(&pdev->dev, sizeof(struct wbec_led), GFP_KERNEL); + if (!wbec_led) + return -ENOMEM; + + platform_set_drvdata(pdev, wbec_led); + wbec_led->regmap = wbec->regmap; + wbec_led->cdev.name = "wbec-led"; + wbec_led->cdev.brightness_set = wbec_led_set; + + err = devm_led_classdev_register(&pdev->dev, &wbec_led->cdev); + if (err) { + dev_err(&pdev->dev, "Couldn't register LED: %d", err); + return err; + } + + dev_info(&pdev->dev, "WBEC LED device initialized successfully"); + + return 0; +} + +static const struct of_device_id wbec_led_of_match[] = { + { .compatible = "wirenboard,wbec-led" }, + {} +}; +MODULE_DEVICE_TABLE(of, wbec_led_of_match); + +static struct platform_driver wbec_led_driver = { + .driver = { + .name = "wbec-led", + .of_match_table = wbec_led_of_match, + }, + .probe = wbec_led_probe, +}; +module_platform_driver(wbec_led_driver); + +MODULE_AUTHOR("Vitalii Gaponov "); +MODULE_DESCRIPTION("Wiren Board 7 Embedded Controller LED driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:wbec-led"); diff --git a/drivers/mfd/wbec.c b/drivers/mfd/wbec.c index d44b794a7a270..2b61e9500447e 100644 --- a/drivers/mfd/wbec.c +++ b/drivers/mfd/wbec.c @@ -62,6 +62,11 @@ static const struct mfd_cell wbec_cells[] = { .id = PLATFORM_DEVID_NONE, .of_compatible = "wirenboard,wbec-rtc" }, + { + .name = "wbec-led", + .id = PLATFORM_DEVID_NONE, + .of_compatible = "wirenboard,wbec-led" + }, { .name = "wbec-pwrkey", .id = PLATFORM_DEVID_NONE, diff --git a/include/linux/mfd/wbec.h b/include/linux/mfd/wbec.h index af8ac069a29fe..bae21ebcb9755 100644 --- a/include/linux/mfd/wbec.h +++ b/include/linux/mfd/wbec.h @@ -86,6 +86,8 @@ #define WBEC_REG_PWR_STATUS 0xC0 #define WBEC_REG_PWR_STATUS_POWERED_FROM_WBMZ_MSK BIT(0) +#define WBEC_REG_LED_CTRL 0xD0 + #define WBEC_REG_LED_CTRL_STATE_MSK BIT(0) struct wbec { struct device *dev;