Small driver to manage the system LED or sys-led peripheral, leveraging
the register field led functions. The sys-led supports only two blinking
intervals, so most users will probably prefer to use a GPIO controlled
LED. To enable blink offloading, the sys-led/GPIO0 mux needs to be
configured to enable sys-led support.

Signed-off-by: Sander Vanheule <san...@svanheule.net>
---
Changes in v3:
- Merge symbol selection updates to ease bisecting
---
 .../files-5.10/drivers/leds/realtek/Kconfig   |   9 ++
 .../files-5.10/drivers/leds/realtek/Makefile  |   1 +
 .../leds/realtek/rtl-switch-sys-leds.c        | 105 ++++++++++++++++++
 target/linux/realtek/rtl838x/config-5.10      |   1 +
 target/linux/realtek/rtl839x/config-5.10      |   1 +
 5 files changed, 117 insertions(+)
 create mode 100644 
target/linux/realtek/files-5.10/drivers/leds/realtek/rtl-switch-sys-leds.c

diff --git a/target/linux/realtek/files-5.10/drivers/leds/realtek/Kconfig 
b/target/linux/realtek/files-5.10/drivers/leds/realtek/Kconfig
index 687be63f739c..fb78d3269dcc 100644
--- a/target/linux/realtek/files-5.10/drivers/leds/realtek/Kconfig
+++ b/target/linux/realtek/files-5.10/drivers/leds/realtek/Kconfig
@@ -7,4 +7,13 @@ menuconfig LEDS_RTL
 
 if LEDS_RTL
 
+config LEDS_RTL_SWITCHCORE_SYSTEM
+       bool "Realtek switch SoC system LED support"
+       default MFD_REALTEK_SWITCHCORE
+       depends on LEDS_CLASS
+       depends on MFD_REALTEK_SWITCHCORE || COMPILE_TEST
+       select MFD_SYSCON
+       help
+         This option enables support for Realtek switch SoC system LEDs.
+
 endif # LED_RTL
diff --git a/target/linux/realtek/files-5.10/drivers/leds/realtek/Makefile 
b/target/linux/realtek/files-5.10/drivers/leds/realtek/Makefile
index 125dc45ff2ce..2aa1607199be 100644
--- a/target/linux/realtek/files-5.10/drivers/leds/realtek/Makefile
+++ b/target/linux/realtek/files-5.10/drivers/leds/realtek/Makefile
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_LEDS_RTL)                         += led-regfield.o
+obj-$(CONFIG_LEDS_RTL_SWITCHCORE_SYSTEM)       += rtl-switch-sys-leds.o
diff --git 
a/target/linux/realtek/files-5.10/drivers/leds/realtek/rtl-switch-sys-leds.c 
b/target/linux/realtek/files-5.10/drivers/leds/realtek/rtl-switch-sys-leds.c
new file mode 100644
index 000000000000..2551d6c0faf6
--- /dev/null
+++ b/target/linux/realtek/files-5.10/drivers/leds/realtek/rtl-switch-sys-leds.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/mfd/syscon.h>
+#include <linux/mod_devicetable.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+
+#include "led-regfield.h"
+
+/*
+ * Realtek hardware system LED
+ *
+ * The switch SoC supports one hardware managed direct LED output
+ * to manage a system LED, with two supported blinking rates.
+ */
+
+#define RTL838X_REG_LED_GLB_CTRL               0xa000
+#define RTL839X_REG_LED_GLB_CTRL               0x00e4
+#define RTL930X_REG_LED_GLB_CTRL               0xcc00
+#define RTL931X_REG_LED_GLB_CTRL               0x0600
+
+static const struct reg_field rtl838x_sys_led_field = 
REG_FIELD(RTL838X_REG_LED_GLB_CTRL, 16, 17);
+static const struct reg_field rtl839x_sys_led_field = 
REG_FIELD(RTL839X_REG_LED_GLB_CTRL, 15, 16);
+static const struct reg_field rtl930x_sys_led_field = 
REG_FIELD(RTL930X_REG_LED_GLB_CTRL, 13, 14);
+static const struct reg_field rtl931x_sys_led_field = 
REG_FIELD(RTL931X_REG_LED_GLB_CTRL, 12, 13);
+
+static const struct regfield_led_modes rtl_sys_led_modes = {
+       .off = 0,
+       .on = 3,
+       .blink = {
+               {64, 1},
+               {1024, 2},
+               { /* sentinel */ }
+       },
+};
+
+static const struct of_device_id of_rtl_sys_led_match[] = {
+       {
+               .compatible = "realtek,maple-sys-led",
+               .data = &rtl838x_sys_led_field,
+       },
+       {
+               .compatible = "realtek,cypress-sys-led",
+               .data = &rtl839x_sys_led_field,
+       },
+       {
+               .compatible = "realtek,longan-sys-led",
+               .data = &rtl930x_sys_led_field,
+       },
+       {
+               .compatible = "realtek,mango-sys-led",
+               .data = &rtl931x_sys_led_field,
+       },
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, of_rtl_sys_led_match);
+
+static int rtl_sys_led_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct led_init_data init_data = {};
+       const struct reg_field *field_data;
+       struct regmap_field *field;
+       struct regfield_led *led;
+       struct regmap *map;
+       int err;
+
+       map = syscon_node_to_regmap(of_get_parent(dev->of_node));
+       if (!map)
+               return dev_err_probe(dev, -ENXIO, "failed to get regmap\n");
+
+       led = devm_kzalloc(dev, sizeof(*led), GFP_KERNEL);
+       if (!led)
+               return -ENOMEM;
+
+       field_data = device_get_match_data(dev);
+       field = devm_regmap_field_alloc(dev, map, *field_data);
+       if (IS_ERR(field))
+               return dev_err_probe(dev, PTR_ERR(field), "register field 
allocation failed\n");
+
+       err = regfield_led_init(led, field, of_fwnode_handle(np), 
&rtl_sys_led_modes);
+       if (err)
+               dev_err_probe(dev, err, "regfield_led initialisation failed\n");
+
+       init_data.fwnode = of_fwnode_handle(np);
+
+       return devm_led_classdev_register_ext(dev, &led->cdev, &init_data);
+}
+
+static struct platform_driver rtl_sys_led_driver = {
+       .probe = rtl_sys_led_probe,
+       .driver = {
+               .name = "realtek-sys-led",
+               .of_match_table = of_rtl_sys_led_match,
+       },
+};
+module_platform_driver(rtl_sys_led_driver);
+
+MODULE_AUTHOR("Sander Vanheule <san...@svanheule.net>");
+MODULE_DESCRIPTION("Realtek switch SoC system LED driver");
+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/realtek/rtl838x/config-5.10 
b/target/linux/realtek/rtl838x/config-5.10
index 574405e05f06..7c440c4a6e69 100644
--- a/target/linux/realtek/rtl838x/config-5.10
+++ b/target/linux/realtek/rtl838x/config-5.10
@@ -117,6 +117,7 @@ CONFIG_IRQ_WORK=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_RTL=y
+CONFIG_LEDS_RTL_SWITCHCORE_SYSTEM=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_LIBFDT=y
diff --git a/target/linux/realtek/rtl839x/config-5.10 
b/target/linux/realtek/rtl839x/config-5.10
index 5bb76371b58e..a071b78a8c04 100644
--- a/target/linux/realtek/rtl839x/config-5.10
+++ b/target/linux/realtek/rtl839x/config-5.10
@@ -110,6 +110,7 @@ CONFIG_IRQ_WORK=y
 CONFIG_JFFS2_ZLIB=y
 CONFIG_LEDS_GPIO=y
 CONFIG_LEDS_RTL=y
+CONFIG_LEDS_RTL_SWITCHCORE_SYSTEM=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
 CONFIG_LIBFDT=y
-- 
2.38.1


_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to