* [PATCH v13 0/2] Introduce Synology Microp driver
@ 2026-05-30 1:17 Markus Probst via B4 Relay
2026-05-30 1:17 ` [PATCH v13 1/2] dt-bindings: embedded-controller: Add synology microp devices Markus Probst via B4 Relay
2026-05-30 1:17 ` [PATCH v13 2/2] platform: Add initial synology microp driver Markus Probst via B4 Relay
0 siblings, 2 replies; 5+ messages in thread
From: Markus Probst via B4 Relay @ 2026-05-30 1:17 UTC (permalink / raw)
To: Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Lee Jones, Pavel Machek, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Greg Kroah-Hartman
Cc: platform-driver-x86, linux-leds, devicetree, linux-kernel,
rust-for-linux, Markus Probst, Krzysztof Kozlowski
Synology uses a microcontroller in their NAS devices connected to a
serial port to control certain LEDs, fan speeds, a beeper, to handle
proper shutdown and restart, buttons and fan failures.
This patch series depends on the rust led abstraction [1] and the rust
serdev abstraction [2].
This is only a initial version of the driver able to control LEDs.
The following rust abstractions would be required, to implement the
remaining features:
- hwmon (include/linux/hwmon.h)
- input (include/linux/input.h)
- sysoff handler (include/linux/reboot.h)
[1] https://lore.kernel.org/rust-for-linux/20260530-rust_leds-v17-0-c0698c4368e2@posteo.de/
[2] https://lore.kernel.org/rust-for-linux/20260530-rust_serdev-v8-0-2a95f1da22a7@posteo.de/
Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
Changes in v13:
- adapted to driver-lifetime v5 patch series.
- set blink = false as initial power led state, as set_blink hasn't been
called yet (even though the led is blinking at startup)
- Link to v12: https://patch.msgid.link/20260429-synology_microp_initial-v12-0-40a05033c620@posteo.de
Changes in v12:
- adapted to driver-lifetime patch series. The driver can't take
advantage of it, until class devices like led also make use of it.
- Link to v11: https://patch.msgid.link/20260427-synology_microp_initial-v11-0-9c1bd5a6f3ed@posteo.de
Changes in v11:
- rebased on top of 7.1-rc1
- add "synology" as devicename to led, like it is done in existing dts
files in the kernel
- fix color for led being orange instead of amber. I personally can't
clearly tell them apart, but apparently its amber.
- replaced MCU with EC in Kconfig help
- Link to v10: https://patch.msgid.link/20260424-synology_microp_initial-v10-0-e852d2f3eba1@posteo.de
Changes in v10:
- resolved issues reported by Sashiko Bot:
- removed unneeded include from device tree
- fix typo in of device table
- fix blink not set to false, if delay_off or delay_on is 0
- Link to v9: https://patch.msgid.link/20260423-synology_microp_initial-v9-0-4a8533f87e07@posteo.de
Changes in v9:
- separate fallback and front compatibles in dt schema
- remove front compatibles from of id table, if all functionality is
by covered by the fallback
- remove TODO file
- add platform-driver-x86@vger.kernel.org to Maintainers file entry
- use `Delta` type in `BLINK_DELAY` const
- Link to v8: https://patch.msgid.link/20260420-synology_microp_initial-v8-0-7946a9124491@posteo.de
Changes in v8:
- removed unnecessary Copy and Clone derive
- added `BLINK_DELAY` constant
- added compatible id fallbacks
- moved dt schema patch before the driver
- added ds411p
- Link to v7: https://lore.kernel.org/r/20260411-synology_microp_initial-v7-0-9a3a094e763a@posteo.de
Changes in v7:
- remove list of compatible ids from commit msg
- explain what makes the different models not compatible in the commit msg
- remove unnecessary examples
- Link to v6: https://lore.kernel.org/r/20260405-synology_microp_initial-v6-0-08fde474b6c9@posteo.de
Changes in v6:
- moved devicetree bindings patch at the end of the set
- remove several patches
- move of id table from model.rs to synology_microp.rs
- remove the model! macro
- use if blocks in devicetree schema to narrow down the
fan-failure-gpios property
- add multiple devicetree examples to test if blocks
- Link to v5: https://lore.kernel.org/r/20260329-synology_microp_initial-v5-0-27cb80bdf591@posteo.de
Changes in v5:
- add esata led support
- use different compatible for each model
- add visibility modifier to of_device_table macro
- fix match data missing when using PRP0001
- Link to v4: https://lore.kernel.org/r/20260320-synology_microp_initial-v4-0-0423ddb83ca4@posteo.de
Changes in v4:
- convert to monolithic driver and moved it into drivers/platform
- removed mfd rust abstraction
- moved dt-bindings to embedded-controller
- Link to v3: https://lore.kernel.org/r/20260313-synology_microp_initial-v3-0-ad6ac463a201@posteo.de
Changes in v3:
- remove `default n` from Kconfig entry, as n is the default already.
- select RUST_SERIAL_DEV_BUS_ABSTRACTIONS in Kconfig
- add mfd rust abstraction
- split core and led parts into their own driver. It should now be considered a
MFD device.
- split led part of dt binding into its own file
- Link to v2: https://lore.kernel.org/r/20260308-synology_microp_initial-v2-0-9389963f31c5@posteo.de
Changes in v2:
- fix missing tabs in MAINTAINERS file
- remove word binding from patch subject
- add missing signed-off-by
- add missing help entry in Kconfig
- add missing spdx license headers
- remove no-check{,-cpu}-fan properties from the dt-bindings and replace
them with the check_fan module parameter
- use patternProperties for leds in dt-bindings
- license dt-binding as GPL-2.0-only OR BSD-2-Clause
- move driver from staging tree into mfd tree and mark it as work in
progress inside Kconfig
- only register alert and usb led if fwnode is present
- Link to v1: https://lore.kernel.org/r/20260306-synology_microp_initial-v1-0-fcffede6448c@posteo.de
---
Markus Probst (2):
dt-bindings: embedded-controller: Add synology microp devices
platform: Add initial synology microp driver
.../synology,ds918p-microp.yaml | 100 +++++++
MAINTAINERS | 7 +
drivers/platform/Kconfig | 2 +
drivers/platform/Makefile | 1 +
drivers/platform/synology_microp/Kconfig | 13 +
drivers/platform/synology_microp/Makefile | 3 +
drivers/platform/synology_microp/command.rs | 54 ++++
drivers/platform/synology_microp/led.rs | 287 +++++++++++++++++++++
drivers/platform/synology_microp/model.rs | 49 ++++
.../platform/synology_microp/synology_microp.rs | 91 +++++++
10 files changed, 607 insertions(+)
---
base-commit: 9e171fc1d7d7ab847a750c03571c87ac3c17bd84
change-id: 20260306-synology_microp_initial-0f7dac7b7496
prerequisite-message-id: 20260505152400.3905096-1-dakr@kernel.org
prerequisite-patch-id: d2aebf69b153c039bbed1d0ed26906708fd22534
prerequisite-patch-id: 84b28da2f5de20fc1785095c647b2ffc35d969a5
prerequisite-patch-id: 67318671a5eed5fb4ad23a450f1cf0e442bf8ca2
prerequisite-message-id: 20260525202921.124698-1-dakr@kernel.org
prerequisite-patch-id: b84db329d4372a175cb8d49e4e88c3eecf7eb228
prerequisite-patch-id: 2c30303f409cc8288cc87e241920219f5ddd8390
prerequisite-patch-id: 4e4f0ad370d763ad00b0f75b91fa216f2cc95953
prerequisite-patch-id: 5bcd6b37f3498feebda275dfef78136eba34004e
prerequisite-patch-id: 872b0982f3e5e7d1698d9df3b325e4cd27b27789
prerequisite-patch-id: 3a3c7749e017d9335f58497404d1350e96caf471
prerequisite-patch-id: 3526c9154f581497a11465b936d83ef61a875454
prerequisite-patch-id: 65d8c757b52475c2acc7d22ddc92cd3f0152b55d
prerequisite-patch-id: 4bd31f1414d5248dc080884caadf5f21684a8427
prerequisite-patch-id: 7beadbb0da3e589ed86d12f512d1c83427dd82b4
prerequisite-patch-id: 12cd0f67ffd27347f90c065db491945908206b7f
prerequisite-patch-id: 4642e31f66331f6c3b579377111ea733dbb3a11c
prerequisite-patch-id: 52d67b40b4396c741e2222d6a5bc7927abcb77aa
prerequisite-patch-id: 74ca82ff26cf9c7a993757c87db8be62006e820f
prerequisite-patch-id: 466fb9fa7febbffd8ef51b311c7d9893c11fc0f0
prerequisite-patch-id: e515cd98b06e26721cbbe6a4fbacd251d0073b63
prerequisite-patch-id: 8dc8e75d9f6499a554ef7e474bbacdbf3660a9f2
prerequisite-patch-id: 5fdb9f71dca2f44dd293760a60db125b770f1f55
prerequisite-patch-id: c766a24c2d5064f5ec09daada0b8e8fba862d3aa
prerequisite-patch-id: b768f6456d35fa7a80c015e34bbdba6082dbd593
prerequisite-patch-id: 6a8b17234f12f7084e6e2ce843a7031b0a891ce4
prerequisite-patch-id: 98b2deb9e60c1f28f90c5ee34fd608aaa9fd9420
prerequisite-patch-id: 774b29be66e641ee50cedb4704cf49d8b9fabf50
prerequisite-patch-id: cf95dc936cfc4b3a7a363435a51a48d9009645b3
prerequisite-change-id: 20251217-rust_serdev-ee5481e9085c:v8
prerequisite-patch-id: 45128665162dd9f51a0764deb3815a338948b291
prerequisite-patch-id: b84db329d4372a175cb8d49e4e88c3eecf7eb228
prerequisite-patch-id: 2c30303f409cc8288cc87e241920219f5ddd8390
prerequisite-patch-id: 4e4f0ad370d763ad00b0f75b91fa216f2cc95953
prerequisite-patch-id: 5bcd6b37f3498feebda275dfef78136eba34004e
prerequisite-patch-id: 872b0982f3e5e7d1698d9df3b325e4cd27b27789
prerequisite-patch-id: 3a3c7749e017d9335f58497404d1350e96caf471
prerequisite-patch-id: 3526c9154f581497a11465b936d83ef61a875454
prerequisite-patch-id: 65d8c757b52475c2acc7d22ddc92cd3f0152b55d
prerequisite-patch-id: 4bd31f1414d5248dc080884caadf5f21684a8427
prerequisite-patch-id: 7beadbb0da3e589ed86d12f512d1c83427dd82b4
prerequisite-patch-id: 12cd0f67ffd27347f90c065db491945908206b7f
prerequisite-patch-id: 4642e31f66331f6c3b579377111ea733dbb3a11c
prerequisite-patch-id: 52d67b40b4396c741e2222d6a5bc7927abcb77aa
prerequisite-patch-id: 74ca82ff26cf9c7a993757c87db8be62006e820f
prerequisite-patch-id: 466fb9fa7febbffd8ef51b311c7d9893c11fc0f0
prerequisite-patch-id: e515cd98b06e26721cbbe6a4fbacd251d0073b63
prerequisite-patch-id: 8dc8e75d9f6499a554ef7e474bbacdbf3660a9f2
prerequisite-patch-id: 5fdb9f71dca2f44dd293760a60db125b770f1f55
prerequisite-patch-id: c766a24c2d5064f5ec09daada0b8e8fba862d3aa
prerequisite-patch-id: b768f6456d35fa7a80c015e34bbdba6082dbd593
prerequisite-patch-id: 6a8b17234f12f7084e6e2ce843a7031b0a891ce4
prerequisite-patch-id: 98b2deb9e60c1f28f90c5ee34fd608aaa9fd9420
prerequisite-patch-id: 774b29be66e641ee50cedb4704cf49d8b9fabf50
prerequisite-patch-id: cf95dc936cfc4b3a7a363435a51a48d9009645b3
prerequisite-patch-id: 52b17274481cc770c257d8f95335293eca32a2c5
prerequisite-patch-id: 6ab09768759461c6bea5d4a0833d50e3e41067f1
prerequisite-patch-id: c8506718a0433ffc4b3c686c1261509159a54d31
prerequisite-patch-id: 19eb53ce0c653c1406f8f192f6ad158fb4bd8d8f
prerequisite-patch-id: 55d6a70baf3be7f4da36b82cf02a5a7d59457520
prerequisite-change-id: 20251114-rust_leds-a959f7c2f7f9:v17
prerequisite-patch-id: 45128665162dd9f51a0764deb3815a338948b291
prerequisite-patch-id: b84db329d4372a175cb8d49e4e88c3eecf7eb228
prerequisite-patch-id: 2c30303f409cc8288cc87e241920219f5ddd8390
prerequisite-patch-id: 4e4f0ad370d763ad00b0f75b91fa216f2cc95953
prerequisite-patch-id: 5bcd6b37f3498feebda275dfef78136eba34004e
prerequisite-patch-id: 872b0982f3e5e7d1698d9df3b325e4cd27b27789
prerequisite-patch-id: 3a3c7749e017d9335f58497404d1350e96caf471
prerequisite-patch-id: 3526c9154f581497a11465b936d83ef61a875454
prerequisite-patch-id: 65d8c757b52475c2acc7d22ddc92cd3f0152b55d
prerequisite-patch-id: 4bd31f1414d5248dc080884caadf5f21684a8427
prerequisite-patch-id: 7beadbb0da3e589ed86d12f512d1c83427dd82b4
prerequisite-patch-id: 12cd0f67ffd27347f90c065db491945908206b7f
prerequisite-patch-id: 4642e31f66331f6c3b579377111ea733dbb3a11c
prerequisite-patch-id: 52d67b40b4396c741e2222d6a5bc7927abcb77aa
prerequisite-patch-id: 74ca82ff26cf9c7a993757c87db8be62006e820f
prerequisite-patch-id: 466fb9fa7febbffd8ef51b311c7d9893c11fc0f0
prerequisite-patch-id: e515cd98b06e26721cbbe6a4fbacd251d0073b63
prerequisite-patch-id: 8dc8e75d9f6499a554ef7e474bbacdbf3660a9f2
prerequisite-patch-id: 5fdb9f71dca2f44dd293760a60db125b770f1f55
prerequisite-patch-id: c766a24c2d5064f5ec09daada0b8e8fba862d3aa
prerequisite-patch-id: b768f6456d35fa7a80c015e34bbdba6082dbd593
prerequisite-patch-id: 6a8b17234f12f7084e6e2ce843a7031b0a891ce4
prerequisite-patch-id: 98b2deb9e60c1f28f90c5ee34fd608aaa9fd9420
prerequisite-patch-id: 774b29be66e641ee50cedb4704cf49d8b9fabf50
prerequisite-patch-id: cf95dc936cfc4b3a7a363435a51a48d9009645b3
prerequisite-patch-id: ea861073f29519d3aa4e6e13b6cdf22e6882c093
prerequisite-patch-id: 72e3f69ddcb244e8871f63086c416d485d807901
prerequisite-patch-id: e8dab3c76da6795163eabb6799188856431134b7
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v13 1/2] dt-bindings: embedded-controller: Add synology microp devices
2026-05-30 1:17 [PATCH v13 0/2] Introduce Synology Microp driver Markus Probst via B4 Relay
@ 2026-05-30 1:17 ` Markus Probst via B4 Relay
2026-05-30 2:14 ` sashiko-bot
2026-05-30 1:17 ` [PATCH v13 2/2] platform: Add initial synology microp driver Markus Probst via B4 Relay
1 sibling, 1 reply; 5+ messages in thread
From: Markus Probst via B4 Relay @ 2026-05-30 1:17 UTC (permalink / raw)
To: Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Lee Jones, Pavel Machek, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Greg Kroah-Hartman
Cc: platform-driver-x86, linux-leds, devicetree, linux-kernel,
rust-for-linux, Markus Probst, Krzysztof Kozlowski
From: Markus Probst <markus.probst@posteo.de>
Add the Synology Microp devicetree bindings. Those devices are
microcontrollers found on Synology NAS devices. They are connected to a
serial port on the host device.
Those devices are used to control certain LEDs, fan speeds, a beeper, to
handle buttons, fan failures and to properly shutdown and reboot the
device.
The device has a different feature set depending on the Synology NAS
model, like having different number of fans, buttons and leds. Depending
on the architecture of the model, they also need a different system
shutdown behaviour.
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
.../synology,ds918p-microp.yaml | 100 +++++++++++++++++++++
1 file changed, 100 insertions(+)
diff --git a/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml b/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
new file mode 100644
index 000000000000..eb1c9d3fac07
--- /dev/null
+++ b/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
@@ -0,0 +1,100 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/embedded-controller/synology,ds918p-microp.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Synology NAS on-board Microcontroller
+
+maintainers:
+ - Markus Probst <markus.probst@posteo.de>
+
+description: |
+ Synology Microp is a microcontroller found in Synology NAS devices.
+ It is connected to a serial port on the host device.
+
+ It is necessary to properly shutdown and reboot the NAS device and
+ provides additional functionality such as led control, fan speed control,
+ a beeper and buttons on the NAS device.
+
+properties:
+ compatible:
+ oneOf:
+ - items:
+ - enum:
+ - synology,ds1221rpp-microp
+ - synology,rs822p-microp
+ - synology,rs422p-microp
+ - const: synology,rs1221p-microp
+
+ - items:
+ - const: synology,ds1825p-microp
+ - const: synology,ds1823xsp-microp
+
+ - items:
+ - enum:
+ - synology,ds725p-microp
+ - synology,ds225p-microp
+ - synology,ds723p-microp
+ - synology,ds710p-microp
+ - const: synology,ds214play-microp
+
+ - items:
+ - enum:
+ - synology,ds425p-microp
+ - synology,ds1525p-microp
+ - synology,ds925p-microp
+ - synology,ds923p-microp
+ - synology,ds1522p-microp
+ - synology,ds1010p-microp
+ - synology,ds411p-microp
+ - const: synology,ds918p-microp
+
+ - items:
+ - enum:
+ - synology,ds124-microp
+ - synology,ds223j-microp
+ - synology,ds223-microp
+ - const: synology,ds118-microp
+
+ - enum:
+ - synology,ds118-microp
+ - synology,ds1823xsp-microp
+ - synology,rs1221p-microp
+ - synology,ds918p-microp
+ - synology,ds214play-microp
+
+ fan-failure-gpios:
+ description: GPIOs needed to determine which fans stopped working on a fan failure event.
+ minItems: 2
+ maxItems: 3
+
+required:
+ - compatible
+
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - synology,ds918p-microp
+ - synology,rs422p-microp
+ then:
+ required:
+ - fan-failure-gpios
+ else:
+ properties:
+ fan-failure-gpios: false
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/gpio/gpio.h>
+
+ embedded-controller {
+ compatible = "synology,ds923p-microp", "synology,ds918p-microp";
+
+ fan-failure-gpios = <&gpio 68 GPIO_ACTIVE_HIGH>, <&gpio 69 GPIO_ACTIVE_HIGH>;
+ };
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v13 2/2] platform: Add initial synology microp driver
2026-05-30 1:17 [PATCH v13 0/2] Introduce Synology Microp driver Markus Probst via B4 Relay
2026-05-30 1:17 ` [PATCH v13 1/2] dt-bindings: embedded-controller: Add synology microp devices Markus Probst via B4 Relay
@ 2026-05-30 1:17 ` Markus Probst via B4 Relay
2026-05-30 3:09 ` sashiko-bot
1 sibling, 1 reply; 5+ messages in thread
From: Markus Probst via B4 Relay @ 2026-05-30 1:17 UTC (permalink / raw)
To: Hans de Goede, Ilpo Järvinen, Bryan O'Donoghue,
Lee Jones, Pavel Machek, Miguel Ojeda, Boqun Feng, Gary Guo,
Björn Roy Baron, Benno Lossin, Andreas Hindborg, Alice Ryhl,
Trevor Gross, Danilo Krummrich, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Greg Kroah-Hartman
Cc: platform-driver-x86, linux-leds, devicetree, linux-kernel,
rust-for-linux, Markus Probst
From: Markus Probst <markus.probst@posteo.de>
Add a initial synology microp driver, written in Rust.
The driver targets a microcontroller found in Synology NAS devices. It
currently only supports controlling of the power led, status led, alert
led and usb led. Other components such as fan control or handling
on-device buttons will be added once the required rust abstractions are
there.
This driver can be used both on arm and x86, thus it goes into the root
directory of drivers/platform.
Tested successfully on a Synology DS923+.
Signed-off-by: Markus Probst <markus.probst@posteo.de>
---
MAINTAINERS | 7 +
drivers/platform/Kconfig | 2 +
drivers/platform/Makefile | 1 +
drivers/platform/synology_microp/Kconfig | 13 +
drivers/platform/synology_microp/Makefile | 3 +
drivers/platform/synology_microp/command.rs | 54 ++++
drivers/platform/synology_microp/led.rs | 287 +++++++++++++++++++++
drivers/platform/synology_microp/model.rs | 49 ++++
.../platform/synology_microp/synology_microp.rs | 91 +++++++
9 files changed, 507 insertions(+)
diff --git a/MAINTAINERS b/MAINTAINERS
index 6e974a518a25..e032b4a1566c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -25838,6 +25838,13 @@ F: drivers/dma-buf/sync_*
F: include/linux/sync_file.h
F: include/uapi/linux/sync_file.h
+SYNOLOGY MICROP DRIVER
+M: Markus Probst <markus.probst@posteo.de>
+L: platform-driver-x86@vger.kernel.org
+S: Maintained
+F: Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
+F: drivers/platform/synology_microp/
+
SYNOPSYS ARC ARCHITECTURE
M: Vineet Gupta <vgupta@kernel.org>
L: linux-snps-arc@lists.infradead.org
diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 312788f249c9..996050566a4a 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -22,3 +22,5 @@ source "drivers/platform/arm64/Kconfig"
source "drivers/platform/raspberrypi/Kconfig"
source "drivers/platform/wmi/Kconfig"
+
+source "drivers/platform/synology_microp/Kconfig"
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index fa322e7f8716..2381872e9133 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -15,3 +15,4 @@ obj-$(CONFIG_SURFACE_PLATFORMS) += surface/
obj-$(CONFIG_ARM64_PLATFORM_DEVICES) += arm64/
obj-$(CONFIG_BCM2835_VCHIQ) += raspberrypi/
obj-$(CONFIG_ACPI_WMI) += wmi/
+obj-$(CONFIG_SYNOLOGY_MICROP) += synology_microp/
diff --git a/drivers/platform/synology_microp/Kconfig b/drivers/platform/synology_microp/Kconfig
new file mode 100644
index 000000000000..8878cfb7bcdd
--- /dev/null
+++ b/drivers/platform/synology_microp/Kconfig
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0
+
+config SYNOLOGY_MICROP
+ tristate "Synology Microp driver"
+ depends on LEDS_CLASS && LEDS_CLASS_MULTICOLOR
+ depends on RUST_SERIAL_DEV_BUS_ABSTRACTIONS
+ help
+ Enable support for the EC found in Synology NAS devices.
+
+ This is needed to properly shutdown and reboot the device, as well as
+ additional functionality like fan and LED control.
+
+ This driver is work in progress and may not be fully functional.
diff --git a/drivers/platform/synology_microp/Makefile b/drivers/platform/synology_microp/Makefile
new file mode 100644
index 000000000000..63585ccf76e4
--- /dev/null
+++ b/drivers/platform/synology_microp/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-y += synology_microp.o
diff --git a/drivers/platform/synology_microp/command.rs b/drivers/platform/synology_microp/command.rs
new file mode 100644
index 000000000000..58cb2f3cb3da
--- /dev/null
+++ b/drivers/platform/synology_microp/command.rs
@@ -0,0 +1,54 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::{
+ device::Bound,
+ error::Result,
+ serdev, //
+};
+
+use crate::led;
+
+#[expect(
+ clippy::enum_variant_names,
+ reason = "future variants will not end with Led"
+)]
+pub(crate) enum Command {
+ PowerLed(led::State),
+ StatusLed(led::StatusLedColor, led::State),
+ AlertLed(led::State),
+ UsbLed(led::State),
+ EsataLed(led::State),
+}
+
+impl Command {
+ pub(crate) fn write(self, dev: &serdev::Device<Bound>) -> Result {
+ dev.write_all(
+ match self {
+ Self::PowerLed(led::State::On) => &[0x34],
+ Self::PowerLed(led::State::Blink) => &[0x35],
+ Self::PowerLed(led::State::Off) => &[0x36],
+
+ Self::StatusLed(_, led::State::Off) => &[0x37],
+ Self::StatusLed(led::StatusLedColor::Green, led::State::On) => &[0x38],
+ Self::StatusLed(led::StatusLedColor::Green, led::State::Blink) => &[0x39],
+ Self::StatusLed(led::StatusLedColor::Amber, led::State::On) => &[0x3A],
+ Self::StatusLed(led::StatusLedColor::Amber, led::State::Blink) => &[0x3B],
+
+ Self::AlertLed(led::State::On) => &[0x4C, 0x41, 0x31],
+ Self::AlertLed(led::State::Blink) => &[0x4C, 0x41, 0x32],
+ Self::AlertLed(led::State::Off) => &[0x4C, 0x41, 0x33],
+
+ Self::UsbLed(led::State::On) => &[0x40],
+ Self::UsbLed(led::State::Blink) => &[0x41],
+ Self::UsbLed(led::State::Off) => &[0x42],
+
+ Self::EsataLed(led::State::On) => &[0x4C, 0x45, 0x31],
+ Self::EsataLed(led::State::Blink) => &[0x4C, 0x45, 0x32],
+ Self::EsataLed(led::State::Off) => &[0x4C, 0x45, 0x33],
+ },
+ serdev::Timeout::Max,
+ )?;
+ dev.wait_until_sent(serdev::Timeout::Max);
+ Ok(())
+ }
+}
diff --git a/drivers/platform/synology_microp/led.rs b/drivers/platform/synology_microp/led.rs
new file mode 100644
index 000000000000..6bc347ea199e
--- /dev/null
+++ b/drivers/platform/synology_microp/led.rs
@@ -0,0 +1,287 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::{
+ device::Bound,
+ devres::{
+ self,
+ Devres, //
+ },
+ led::{
+ self,
+ LedOps,
+ MultiColorSubLed, //
+ },
+ new_mutex,
+ prelude::*,
+ serdev,
+ str::CString,
+ sync::Mutex,
+ time::Delta, //
+};
+use pin_init::pin_init_scope;
+
+use crate::{
+ command::Command,
+ model::Model, //
+};
+
+#[pin_data]
+pub(crate) struct Data {
+ #[pin]
+ status: Devres<led::MultiColorDevice<StatusLedHandler>>,
+ power_name: CString,
+ #[pin]
+ power: Devres<led::Device<LedHandler>>,
+}
+
+impl Data {
+ pub(super) fn register<'a>(
+ dev: &'a serdev::Device<Bound>,
+ model: &'a Model,
+ ) -> impl PinInit<Self, Error> + 'a {
+ pin_init_scope(move || {
+ if let Some(color) = model.led_alert {
+ let name =
+ CString::try_from_fmt(fmt!("synology:{}:alarm", color.as_c_str().to_str()?))?;
+ devres::register(
+ dev.as_ref(),
+ led::DeviceBuilder::new().color(color).name(&name).build(
+ dev,
+ try_pin_init!(LedHandler {
+ blink <- new_mutex!(false),
+ command: Command::AlertLed,
+ }),
+ ),
+ GFP_KERNEL,
+ )?;
+ }
+
+ if model.led_usb_copy {
+ devres::register(
+ dev.as_ref(),
+ led::DeviceBuilder::new()
+ .color(led::Color::Green)
+ .name(c"synology:green:usb")
+ .build(
+ dev,
+ try_pin_init!(LedHandler {
+ blink <- new_mutex!(false),
+ command: Command::UsbLed,
+ }),
+ ),
+ GFP_KERNEL,
+ )?;
+ }
+
+ if model.led_esata {
+ devres::register(
+ dev.as_ref(),
+ led::DeviceBuilder::new()
+ .color(led::Color::Green)
+ .name(c"synology:green:esata")
+ .build(
+ dev,
+ try_pin_init!(LedHandler {
+ blink <- new_mutex!(false),
+ command: Command::EsataLed,
+ }),
+ ),
+ GFP_KERNEL,
+ )?;
+ }
+
+ Ok(try_pin_init!(Self {
+ status <- led::DeviceBuilder::new()
+ .color(led::Color::Multi)
+ .name(c"synology:multicolor:status")
+ .build_multicolor(
+ dev,
+ try_pin_init!(StatusLedHandler {
+ blink <- new_mutex!(false),
+ }),
+ StatusLedHandler::SUBLEDS,
+ ),
+ power_name: CString::try_from_fmt(fmt!(
+ "synology:{}:power",
+ model.led_power.as_c_str().to_str()?
+ ))?,
+ power <- led::DeviceBuilder::new()
+ .color(model.led_power)
+ .name(power_name)
+ .build(
+ dev,
+ try_pin_init!(LedHandler {
+ blink <- new_mutex!(false),
+ command: Command::PowerLed,
+ }),
+ ),
+ }))
+ })
+ }
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum StatusLedColor {
+ Green,
+ Amber,
+}
+
+#[derive(Copy, Clone)]
+pub(crate) enum State {
+ On,
+ Blink,
+ Off,
+}
+
+#[pin_data]
+struct LedHandler {
+ #[pin]
+ blink: Mutex<bool>,
+ command: fn(State) -> Command,
+}
+
+/// Blink delay measured using video recording on DS923+ for Power and Status Led.
+///
+/// We assume it is the same for all other leds and models.
+const BLINK_DELAY: Delta = Delta::from_millis(167);
+
+#[vtable]
+impl LedOps for LedHandler {
+ type Bus = serdev::Device<Bound>;
+ type Mode = led::Normal;
+ const BLOCKING: bool = true;
+ const MAX_BRIGHTNESS: u32 = 1;
+
+ fn brightness_set(
+ &self,
+ dev: &Self::Bus,
+ _classdev: &led::Device<Self>,
+ brightness: u32,
+ ) -> Result<()> {
+ let mut blink = self.blink.lock();
+ (self.command)(if brightness == 0 {
+ *blink = false;
+ State::Off
+ } else if *blink {
+ State::Blink
+ } else {
+ State::On
+ })
+ .write(dev)?;
+
+ Ok(())
+ }
+
+ fn blink_set(
+ &self,
+ dev: &Self::Bus,
+ _classdev: &led::Device<Self>,
+ delay_on: &mut usize,
+ delay_off: &mut usize,
+ ) -> Result<()> {
+ let mut blink = self.blink.lock();
+
+ (self.command)(if *delay_on == 0 && *delay_off != 0 {
+ *blink = false;
+
+ State::Off
+ } else if *delay_on != 0 && *delay_off == 0 {
+ *blink = false;
+
+ State::On
+ } else {
+ *blink = true;
+ *delay_on = BLINK_DELAY.as_millis() as usize;
+ *delay_off = BLINK_DELAY.as_millis() as usize;
+
+ State::Blink
+ })
+ .write(dev)
+ }
+}
+
+#[pin_data]
+struct StatusLedHandler {
+ #[pin]
+ blink: Mutex<bool>,
+}
+
+impl StatusLedHandler {
+ const SUBLEDS: &[MultiColorSubLed] = &[
+ MultiColorSubLed::new(led::Color::Green).initial_intensity(1),
+ MultiColorSubLed::new(led::Color::Amber),
+ ];
+}
+
+#[vtable]
+impl LedOps for StatusLedHandler {
+ type Bus = serdev::Device<Bound>;
+ type Mode = led::MultiColor;
+ const BLOCKING: bool = true;
+ const MAX_BRIGHTNESS: u32 = 1;
+
+ fn brightness_set(
+ &self,
+ dev: &Self::Bus,
+ classdev: &led::MultiColorDevice<Self>,
+ brightness: u32,
+ ) -> Result<()> {
+ let mut blink = self.blink.lock();
+ if brightness == 0 {
+ *blink = false;
+ }
+
+ let (color, subled_brightness) = if classdev.subleds()[1].intensity == 0 {
+ (StatusLedColor::Green, classdev.subleds()[0].brightness)
+ } else {
+ (StatusLedColor::Amber, classdev.subleds()[1].brightness)
+ };
+
+ Command::StatusLed(
+ color,
+ if subled_brightness == 0 {
+ State::Off
+ } else if *blink {
+ State::Blink
+ } else {
+ State::On
+ },
+ )
+ .write(dev)
+ }
+
+ fn blink_set(
+ &self,
+ dev: &Self::Bus,
+ classdev: &led::MultiColorDevice<Self>,
+ delay_on: &mut usize,
+ delay_off: &mut usize,
+ ) -> Result<()> {
+ let mut blink = self.blink.lock();
+ *blink = true;
+
+ let (color, subled_intensity) = if classdev.subleds()[1].intensity == 0 {
+ (StatusLedColor::Green, classdev.subleds()[0].intensity)
+ } else {
+ (StatusLedColor::Amber, classdev.subleds()[1].intensity)
+ };
+ Command::StatusLed(
+ color,
+ if *delay_on == 0 && *delay_off != 0 {
+ *blink = false;
+ State::Off
+ } else if subled_intensity == 0 {
+ State::Off
+ } else if *delay_on != 0 && *delay_off == 0 {
+ *blink = false;
+ State::On
+ } else {
+ *delay_on = BLINK_DELAY.as_millis() as usize;
+ *delay_off = BLINK_DELAY.as_millis() as usize;
+
+ State::Blink
+ },
+ )
+ .write(dev)
+ }
+}
diff --git a/drivers/platform/synology_microp/model.rs b/drivers/platform/synology_microp/model.rs
new file mode 100644
index 000000000000..715d8840f56b
--- /dev/null
+++ b/drivers/platform/synology_microp/model.rs
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+
+use kernel::led::Color;
+
+pub(crate) struct Model {
+ pub(crate) led_power: Color,
+ pub(crate) led_alert: Option<Color>,
+ pub(crate) led_usb_copy: bool,
+ pub(crate) led_esata: bool,
+}
+
+impl Model {
+ pub(super) const fn new() -> Self {
+ Self {
+ led_power: Color::Blue,
+ led_alert: None,
+ led_usb_copy: false,
+ led_esata: false,
+ }
+ }
+
+ pub(super) const fn led_power(self, color: Color) -> Self {
+ Self {
+ led_power: color,
+ ..self
+ }
+ }
+
+ pub(super) const fn led_alert(self, color: Color) -> Self {
+ Self {
+ led_alert: Some(color),
+ ..self
+ }
+ }
+
+ pub(super) const fn led_esata(self) -> Self {
+ Self {
+ led_esata: true,
+ ..self
+ }
+ }
+
+ pub(super) const fn led_usb_copy(self) -> Self {
+ Self {
+ led_usb_copy: true,
+ ..self
+ }
+ }
+}
diff --git a/drivers/platform/synology_microp/synology_microp.rs b/drivers/platform/synology_microp/synology_microp.rs
new file mode 100644
index 000000000000..4fcab3a1678a
--- /dev/null
+++ b/drivers/platform/synology_microp/synology_microp.rs
@@ -0,0 +1,91 @@
+// SPDX-License-Identifier: GPL-2.0
+
+//! Synology Microp driver
+
+use kernel::{
+ device,
+ led::Color,
+ of::{
+ DeviceId,
+ IdTable, //
+ },
+ of_device_table,
+ prelude::*,
+ serdev, //
+};
+use pin_init::pin_init_scope;
+
+use crate::model::Model;
+
+pub(crate) mod command;
+mod led;
+mod model;
+
+kernel::module_serdev_device_driver! {
+ type: SynologyMicropDriver,
+ name: "synology_microp",
+ authors: ["Markus Probst <markus.probst@posteo.de>"],
+ description: "Synology Microp driver",
+ license: "GPL v2",
+}
+
+#[rustfmt::skip]
+of_device_table!(
+ OF_TABLE,
+ MODULE_OF_TABLE,
+ Model,
+ [
+ // apollolake
+ (DeviceId::new(c"synology,ds918p-microp"), Model::new()),
+
+ // evansport
+ (DeviceId::new(c"synology,ds214play-microp"), Model::new()),
+
+ // geminilakenk
+ (DeviceId::new(c"synology,ds225p-microp"), Model::new().led_usb_copy()),
+
+ // pineview
+ (DeviceId::new(c"synology,ds710p-microp"), Model::new().led_esata()),
+ (DeviceId::new(c"synology,ds1010p-microp"), Model::new().led_alert(Color::Amber)),
+
+ // rtd1296
+ (DeviceId::new(c"synology,ds118-microp"), Model::new()),
+
+ // rtd1619b
+ (DeviceId::new(c"synology,ds223-microp"), Model::new().led_usb_copy()),
+
+ // v1000
+ (DeviceId::new(c"synology,ds1823xsp-microp"), Model::new()),
+ (DeviceId::new(c"synology,rs1221p-microp"), Model::new().led_power(Color::Green)),
+ ]
+);
+
+#[pin_data]
+struct SynologyMicropDriver {
+ #[pin]
+ led: led::Data,
+}
+
+#[vtable]
+impl serdev::Driver for SynologyMicropDriver {
+ type IdInfo = Model;
+ type Data<'bound> = Self;
+ const OF_ID_TABLE: Option<IdTable<Self::IdInfo>> = Some(&OF_TABLE);
+
+ fn probe<'bound>(
+ dev: &'bound serdev::Device<device::Core<'_>>,
+ model: Option<&'bound Model>,
+ ) -> impl PinInit<Self, kernel::error::Error> + 'bound {
+ pin_init_scope(move || {
+ let model = model.ok_or(EINVAL)?;
+
+ dev.set_baudrate(9600).map_err(|_| EINVAL)?;
+ dev.set_flow_control(false);
+ dev.set_parity(serdev::Parity::None)?;
+
+ Ok(try_pin_init!(Self {
+ led <- led::Data::register(dev, model),
+ }))
+ })
+ }
+}
--
2.53.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v13 1/2] dt-bindings: embedded-controller: Add synology microp devices
2026-05-30 1:17 ` [PATCH v13 1/2] dt-bindings: embedded-controller: Add synology microp devices Markus Probst via B4 Relay
@ 2026-05-30 2:14 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-05-30 2:14 UTC (permalink / raw)
To: Markus Probst via B4 Relay; +Cc: ojeda, robh, conor+dt, devicetree
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [Medium] Chronological fallback inversions for older models in DT bindings
- [Medium] Model prefix typo (DS vs RS) for `synology,ds1221rpp-microp`
--
commit 420a38b2f09dfb652dcda0d1d821575521540bff
Author: Markus Probst <markus.probst@posteo.de>
dt-bindings: embedded-controller: Add synology microp devices
This commit adds device tree bindings for Synology Microcontrollers (Microp).
These devices manage LEDs, fans, beepers, and handle power events via a
serial connection on Synology NAS devices.
> diff --git a/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml b/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
> new file mode 100644
> index 0000000000000..eb1c9d3fac074
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/embedded-controller/synology,ds918p-microp.yaml
[ ... ]
> +properties:
> + compatible:
> + oneOf:
> + - items:
> + - enum:
> + - synology,ds1221rpp-microp
[Severity: Medium]
Is synology,ds1221rpp-microp a typo? Synology models with redundant power
supplies are typically RackStations (RS) rather than DiskStations (DS), and
this falls back to synology,rs1221p-microp.
Should this be synology,rs1221rpp-microp instead to avoid establishing a typo
in the permanent device tree ABI?
> + - synology,rs822p-microp
> + - synology,rs422p-microp
> + - const: synology,rs1221p-microp
> +
> + - items:
> + - const: synology,ds1825p-microp
> + - const: synology,ds1823xsp-microp
> +
> + - items:
> + - enum:
> + - synology,ds725p-microp
> + - synology,ds225p-microp
> + - synology,ds723p-microp
> + - synology,ds710p-microp
> + - const: synology,ds214play-microp
[Severity: Medium]
Is it correct for the older 2010 model synology,ds710p-microp to fall back to
the newer 2014 model synology,ds214play-microp?
In Device Tree schemas, newer hardware variants typically fall back to older
established base models if they are backward compatible, rather than the
other way around.
> +
> + - items:
> + - enum:
> + - synology,ds425p-microp
> + - synology,ds1525p-microp
> + - synology,ds925p-microp
> + - synology,ds923p-microp
> + - synology,ds1522p-microp
> + - synology,ds1010p-microp
> + - synology,ds411p-microp
> + - const: synology,ds918p-microp
[Severity: Medium]
Does this correctly map the hardware relationships? The 2010 and 2011 models
(synology,ds1010p-microp and synology,ds411p-microp) are configured to fall
back to the 2018 model synology,ds918p-microp.
Since synology,ds918p-microp enforces fan-failure-gpios as a required
property in the conditional block further down in the file, this inverted
fallback forces the older hardware to satisfy constraints defined for newer
hardware. This will cause validation failures for correct older device trees.
Should these older models be listed as their own base models or fall back to
an older base instead?
[ ... ]
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260530-synology_microp_initial-v13-0-aa2bb9c56efc@posteo.de?part=1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v13 2/2] platform: Add initial synology microp driver
2026-05-30 1:17 ` [PATCH v13 2/2] platform: Add initial synology microp driver Markus Probst via B4 Relay
@ 2026-05-30 3:09 ` sashiko-bot
0 siblings, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-05-30 3:09 UTC (permalink / raw)
To: Markus Probst via B4 Relay; +Cc: ojeda, robh, devicetree, conor+dt
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [Critical] The dynamically allocated name for the conditionally registered alert LED is dropped prematurely, leaving a dangling pointer in the LED subsystem.
- [Medium] Concurrent LED operations can interleave serial commands, corrupting the communication protocol with the microcontroller.
- [Medium] Setting an LED's brightness to a non-zero value fails to override and disable hardware blinking.
- [Low] The config SYNOLOGY_MICROP depends on a non-existent symbol RUST_SERIAL_DEV_BUS_ABSTRACTIONS.
--
commit 1779a8eccc4d1fbf66dab42036dc8b8505625855
Author: Markus Probst <markus.probst@posteo.de>
platform: Add initial synology microp driver
Add an initial synology microp driver, written in Rust. The driver targets a
microcontroller found in Synology NAS devices to support controlling of the
power led, status led, alert led and usb led.
> diff --git a/drivers/platform/synology_microp/Kconfig b/drivers/platform/synology_microp/Kconfig
> new file mode 100644
> --- /dev/null
> +++ b/drivers/platform/synology_microp/Kconfig
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +config SYNOLOGY_MICROP
> + tristate "Synology Microp driver"
> + depends on LEDS_CLASS && LEDS_CLASS_MULTICOLOR
> + depends on RUST_SERIAL_DEV_BUS_ABSTRACTIONS
[Severity: Low]
Does RUST_SERIAL_DEV_BUS_ABSTRACTIONS exist in the kernel tree?
Kconfig guidelines state that all dependencies must correspond to a valid
config definition.
Could this missing symbol cause silent build failures by preventing the
driver from ever being enabled?
[ ... ]
> diff --git a/drivers/platform/synology_microp/command.rs b/drivers/platform/synology_microp/command.rs
> new file mode 100644
> --- /dev/null
> +++ b/drivers/platform/synology_microp/command.rs
[ ... ]
> +impl Command {
> + pub(crate) fn write(self, dev: &serdev::Device<Bound>) -> Result {
> + dev.write_all(
> + match self {
[ ... ]
> + Self::EsataLed(led::State::Off) => &[0x4C, 0x45, 0x33],
> + },
> + serdev::Timeout::Max,
> + )?;
> + dev.wait_until_sent(serdev::Timeout::Max);
> + Ok(())
> + }
> +}
[Severity: Medium]
Since multiple LEDs share the same serdev bus, can their operations (like
brightness_set and blink_set) be called concurrently from different sysfs
contexts?
Without a driver-wide lock protecting the dev.write_all() and
dev.wait_until_sent() sequence here, could concurrent calls interleave
bytes in the UART transmit buffer and corrupt the communication protocol
with the microcontroller?
[ ... ]
> diff --git a/drivers/platform/synology_microp/led.rs b/drivers/platform/synology_microp/led.rs
> new file mode 100644
> --- /dev/null
> +++ b/drivers/platform/synology_microp/led.rs
[ ... ]
> +impl Data {
> + pub(super) fn register<'a>(
> + dev: &'a serdev::Device<Bound>,
> + model: &'a Model,
> + ) -> impl PinInit<Self, Error> + 'a {
> + pin_init_scope(move || {
> + if let Some(color) = model.led_alert {
> + let name =
> + CString::try_from_fmt(fmt!("synology:{}:alarm", color.as_c_str().to_str()?))?;
> + devres::register(
> + dev.as_ref(),
> + led::DeviceBuilder::new().color(color).name(&name).build(
[Severity: Critical]
Since the name variable is a local CString scoped to the if let block, won't
it be dropped at the end of the block?
The LED core doesn't copy the string, so could passing the reference &name
leave a dangling pointer that triggers a use-after-free when sysfs,
tracepoints, or triggers access it later?
> + dev,
> + try_pin_init!(LedHandler {
> + blink <- new_mutex!(false),
> + command: Command::AlertLed,
> + }),
> + ),
> + GFP_KERNEL,
> + )?;
> + }
[ ... ]
> + fn brightness_set(
> + &self,
> + dev: &Self::Bus,
> + _classdev: &led::Device<Self>,
> + brightness: u32,
> + ) -> Result<()> {
> + let mut blink = self.blink.lock();
> + (self.command)(if brightness == 0 {
> + *blink = false;
> + State::Off
> + } else if *blink {
> + State::Blink
> + } else {
> + State::On
> + })
[Severity: Medium]
The LED subsystem API semantics normally dictate that writing a non-zero
value to the brightness sysfs file must stop any active hardware blinking
and turn the LED solid on.
By preserving State::Blink here when brightness is greater than 0, does this
force users to explicitly write 0 to brightness to stop the blinking before
they can turn it solid on?
> + .write(dev)?;
> +
> + Ok(())
> + }
[ ... ]
> + fn brightness_set(
> + &self,
> + dev: &Self::Bus,
> + classdev: &led::MultiColorDevice<Self>,
> + brightness: u32,
> + ) -> Result<()> {
[ ... ]
> + Command::StatusLed(
> + color,
> + if subled_brightness == 0 {
> + State::Off
> + } else if *blink {
> + State::Blink
> + } else {
> + State::On
> + },
> + )
[Severity: Medium]
Similarly to the standard LedHandler, does preserving State::Blink here
when setting a non-zero brightness break the LED subsystem expectation
that brightness > 0 overrides and stops blinking?
> + .write(dev)
> + }
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260530-synology_microp_initial-v13-0-aa2bb9c56efc@posteo.de?part=2
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-05-30 3:09 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-30 1:17 [PATCH v13 0/2] Introduce Synology Microp driver Markus Probst via B4 Relay
2026-05-30 1:17 ` [PATCH v13 1/2] dt-bindings: embedded-controller: Add synology microp devices Markus Probst via B4 Relay
2026-05-30 2:14 ` sashiko-bot
2026-05-30 1:17 ` [PATCH v13 2/2] platform: Add initial synology microp driver Markus Probst via B4 Relay
2026-05-30 3:09 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox