realtek: disable synchronous operation on RTL8231

It may be possible that the bootloader has left an RTL8231 expander
configured for synchronous operation, which requires the user to signal
that the new GPIO/LED states should be latched.

As drivers typically perform one operation at a time for the higher
level kernel framework, this would require a latch on every update,
which is not very useful. Disable synchronous operation to keeps things
simple.

Signed-off-by: Sander Vanheule <sander@svanheule.net>
This commit is contained in:
Sander Vanheule 2026-02-19 21:17:07 +01:00
parent c98289b074
commit 2fffb27c98
6 changed files with 30 additions and 6 deletions

View File

@ -256,7 +256,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/include/linux/mfd/rtl8231.h
@@ -0,0 +1,71 @@
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Register definitions the RTL8231 GPIO and LED expander chip
@ -280,6 +280,8 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+#define RTL8231_FUNC0_SCAN_MODE BIT(0)
+#define RTL8231_FUNC0_SCAN_SINGLE 0
+#define RTL8231_FUNC0_SCAN_BICOLOR BIT(0)
+#define RTL8231_ENABLE_SYNC_LED BIT(14)
+#define RTL8231_ENABLE_SYNC_GPIO BIT(15)
+
+#define RTL8231_REG_FUNC1 0x01
+#define RTL8231_FUNC1_READY_CODE_VALUE 0x37

View File

@ -53,7 +53,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rtl8231.c
@@ -0,0 +1,525 @@
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitfield.h>
@ -432,6 +432,11 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+ unsigned int dir;
+ int err;
+
+ /* Enable immediate GPIO changes, otherwise we need to latch updates */
+ err = regmap_update_bits(map, RTL8231_REG_FUNC0, RTL8231_ENABLE_SYNC_GPIO, 0);
+ if (err)
+ return err;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(pin_fields); i++) {
+ field_data = devm_regmap_field_alloc(dev, map, pin_fields[i].gpio_data);
+ if (IS_ERR(field_data))

View File

@ -50,7 +50,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o
--- /dev/null
+++ b/drivers/leds/leds-rtl8231.c
@@ -0,0 +1,285 @@
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/device.h>
@ -309,6 +309,11 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+ return -EINVAL;
+ }
+
+ /* Enable immediate LED changes, otherwise we need to latch updates */
+ err = regmap_update_bits(map, RTL8231_REG_FUNC0, RTL8231_ENABLE_SYNC_LED, 0);
+ if (err)
+ return err;
+
+ fwnode_for_each_available_child_node(dev->fwnode, child) {
+ err = rtl8231_led_probe_single(dev, map, port_counts, child);
+ if (err)

View File

@ -256,7 +256,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+MODULE_LICENSE("GPL");
--- /dev/null
+++ b/include/linux/mfd/rtl8231.h
@@ -0,0 +1,71 @@
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Register definitions the RTL8231 GPIO and LED expander chip
@ -280,6 +280,8 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+#define RTL8231_FUNC0_SCAN_MODE BIT(0)
+#define RTL8231_FUNC0_SCAN_SINGLE 0
+#define RTL8231_FUNC0_SCAN_BICOLOR BIT(0)
+#define RTL8231_ENABLE_SYNC_LED BIT(14)
+#define RTL8231_ENABLE_SYNC_GPIO BIT(15)
+
+#define RTL8231_REG_FUNC1 0x01
+#define RTL8231_FUNC1_READY_CODE_VALUE 0x37

View File

@ -53,7 +53,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
obj-$(CONFIG_PINCTRL_ST) += pinctrl-st.o
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-rtl8231.c
@@ -0,0 +1,525 @@
@@ -0,0 +1,530 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/bitfield.h>
@ -432,6 +432,11 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+ unsigned int dir;
+ int err;
+
+ /* Enable immediate GPIO changes, otherwise we need to latch updates */
+ err = regmap_update_bits(map, RTL8231_REG_FUNC0, RTL8231_ENABLE_SYNC_GPIO, 0);
+ if (err)
+ return err;
+
+ for (unsigned int i = 0; i < ARRAY_SIZE(pin_fields); i++) {
+ field_data = devm_regmap_field_alloc(dev, map, pin_fields[i].gpio_data);
+ if (IS_ERR(field_data))

View File

@ -50,7 +50,7 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
obj-$(CONFIG_LEDS_SUN50I_A100) += leds-sun50i-a100.o
--- /dev/null
+++ b/drivers/leds/leds-rtl8231.c
@@ -0,0 +1,285 @@
@@ -0,0 +1,290 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/device.h>
@ -309,6 +309,11 @@ Signed-off-by: Sander Vanheule <sander@svanheule.net>
+ return -EINVAL;
+ }
+
+ /* Enable immediate LED changes, otherwise we need to latch updates */
+ err = regmap_update_bits(map, RTL8231_REG_FUNC0, RTL8231_ENABLE_SYNC_LED, 0);
+ if (err)
+ return err;
+
+ fwnode_for_each_available_child_node(dev->fwnode, child) {
+ err = rtl8231_led_probe_single(dev, map, port_counts, child);
+ if (err)