The MCA LED controller implements a 9-channel LED driver with independent brightness and blink control. Each channel includes:

  • Brightness control (20 levels).

  • Blink control (configurable on/off periods).

  • Low-power operation with control of the LED state (on/off/blink).

The MCA LED controller is implemented on standard MCA IOs that can only drive up to 25 mA. For LEDs that require higher current, connect an external transistor driver.

Kernel configuration

You can manage the MCA LED driver support through the following kernel configuration option:

  • MCA LED controller support (CONFIG_LEDS_MCA)

This option is enabled as built-in on the default ConnectCore 8X kernel configuration file.

Kernel driver

File Description

drivers/leds/leds-mca.c

MCA LED controller driver

Device tree bindings and customization

The MCA LED controller device tree binding is documented at Documentation/devicetree/bindings/leds/leds-mca.txt.

LED controller inside the MCA

ConnectCore 8X device tree
mca_cc8x: mca@63 {

	...

	mca_led: led {
		compatible = "digi,mca-led";
		status = "disabled";
	};
};

Since the ConnectCore 8X SOM does not contain an LED, the MCA LED controller is disabled by default in the device tree.

LEDs on the ConnectCore 8X SBC Pro

Power LED

ConnectCore 8X SBC Pro device tree
/* Power LED on MCA_IO13 */
&mca_led {
	#address-cells = <1>;
	#size-cells = <0>;
	status = "okay";

	led@0 {
		reg = <0>;
		label = "power:green";
		io = <13>;
		linux,default-trigger = "default-on";
		retain-state-suspended;
	};
};

The ConnectCore 8X SBC Pro device tree assigns LED controller channel (0) to the power LED on the carrier board. The initial configuration for the power LED is "default-on", which turns it solid-on while the device is in run mode. When the system enters suspend state, the power LED is reconfigured to blink with a pattern. When the system resumes operation, the power LED is configured back to its default-on state. This is managed by the following entries on /lib/systemd/system-sleep/standby-actions.

/lib/systemd/system-sleep/standby-actions
if [ "${1}" == "pre" ]; then
	...
        # Configure power LED for blinking in standby
        if [ -d "/sys/class/leds/power:green" ]; then
                # Configure LED for blinking
                echo timer > /sys/class/leds/power\:green/trigger
                # Turn LED on at max brightness
                echo 19 > /sys/class/leds/power\:green/brightness
                # Configure blink timing
                echo 100 > /sys/class/leds/power\:green/delay_on
                echo 1000 > /sys/class/leds/power\:green/delay_off
        fi
elif [ "${1}" == "post" ]; then
	...
        # Configure power LED solid on after resume
        if [ -d "/sys/class/leds/power:green" ]; then
                # Reset LED settings by writing 0 to brightness descriptor
                echo 0 > /sys/class/leds/power\:green/brightness
                # Turn LED on at max brightness
                echo 19 > /sys/class/leds/power\:green/brightness
        fi
fi
The power LED on the ConnectCore 8X SBC Pro is fed from 3V3_EXT (reg_3v3_ext regulator on the device tree). The default ConnectCore 8X device tree configures its parent regulator (vcc_3v3_reg regulator on the device tree) to disable on suspend, for max power saving, so you won’t see the power LED blink on suspend even though the MCA is toggling it. To configure the ConnectCore 8X SBC Pro power LED to blink on suspend, see Power management.

User LEDs

The two user LEDs on the ConnectCore 8X SBC Pro are connected to MCA IOs and can be driven by the MCA LED driver.

The BSP contains an example device tree overlay called _ov_board_user-leds_ccimx8x-sbc-pro.dts that drives the two user LEDs with the MCA LED controller and configures them for blinking at different rates.

MCA LED controller device tree overlay example
	/* Enable USER_LED0 and USER_LED1 as mca-led */
	fragment@1 {
		target = <&mca_led>;
		__overlay__ {
			#address-cells = <1>;
			#size-cells = <0>;
			status = "okay";

			led@1 {
				reg = <1>;
				label = "USER_LED0:orange";
				io = <18>;
				/* Configure LED to blink at boot */
				linux,default-trigger = "timer";
				led-pattern = <100>, <1000>;
				retain-state-suspended;
			};

			led@2 {
				reg = <2>;
				label = "USER_LED1:green";
				io = <10>;
				/* Configure LED to blink at boot */
				linux,default-trigger = "timer";
				led-pattern = <5000>, <5000>;
				retain-state-suspended;
			};
		};
	};
MCA IOs that are managed by the MCA LED driver cannot be used by other drivers. The example user LEDs overlay conflicts with other functionality that tries to control the user LEDs, such as the apix-gpio-example.
The user LEDs on the ConnectCore 8X SBC Pro are fed from 3V3_EXT (reg_3v3_ext regulator on the device tree). The default ConnectCore 8X SBC Pro device tree configures this regulator to disable on suspend, for max power saving, so you won’t see the user LEDs blink on suspend even though the MCA is toggling them. From a hardware perspective, the best approach is to feed the LEDs from a power rail that doesn’t disconnect on suspend, such as VCC_MCA. To see the user LEDs blink on suspend on the ConnectCore 8X SBC Pro, see Power management.

See Device tree files and overlays for information on enabling a device tree overlay.

Using the LED controller

The Linux driver registers the MCA LED controller as a standard controller that can be accessed from the sysfs.

Sysfs access

The LED controller driver creates an entry in the /sys/class/led sysfs directory for each enabled channel:

# ls /sys/class/leds/
USER_LED0:orange  USER_LED1:green   power:green
User LED entries only appear if you load the corresponding device tree overlay.

You can use the sysfs entries associated with each LED label to configure that label:

# ls /sys/class/leds/power\:green
brightness    consumers         delay_off    delay_on
device        max_brightness    power        subsystem
suppliers     trigger           uevent

Examples

The following examples demonstrate different use cases of the LED controller:

Turn LED OFF by writing 0 to brightness descriptor
# echo 0 > /sys/class/leds/power\:green/brightness
Turn LED ON at max brightness (19)
# echo 19 > /sys/class/leds/power\:green/brightness
Sample script that changes LED brightness from 0 to max at 100mS intervals
# cat brightness.sh
#!/bin/sh
counter=0

while true; do
    echo $counter > /sys/class/leds/power\:green/brightness
    sleep 0.1
    let counter++
    if [[ "$counter" -gt 19 ]]; then
        counter=0
    fi
done
Configure LED to blink
# echo timer > /sys/class/leds/power\:green/trigger     # Configure LED for blinking
# echo 19 > /sys/class/leds/power\:green/brightness     # Turn LED on at max brightness
# echo 100 > /sys/class/leds/power\:green/delay_on      # Configure time on
# echo 1000 > /sys/class/leds/power\:green/delay_off    # Configure time off

Power management

The retain-state-suspended device tree entry configures the MCA LED channel to retain configuration while in suspend state.

The retain-state-suspended device tree entry only applies to solid-on and blinking LEDs. Brightness control is not possible in standby state.

If the retain-state-suspended device tree entry is not present, the Linux LED class driver sends a '0' to the brightness descriptor just before entering standby state. This resets the LED settings, and they are not restored upon waking.

MCA standby power consumption will increase slightly if LEDs are configured to blink while in standby. This is because the MCA will wake periodically (microseconds) to handle the LED states.

The power and user LEDs on the ConnectCore 8X SBC Pro are fed from 3V3_EXT (reg_3v3_ext regulator on the device tree). The default ConnectCore 8X device tree configures its parent regulator (vcc_3v3_reg regulator on the device tree) to disable on suspend, for max power saving, so you won’t see the user LEDs blink on suspend even though the MCA is toggling it. From a hardware perspective, the best approach is to feed the power LED from a power rail that doesn’t disconnect on suspend, such as VCC_MCA.

To see the LEDs blink on suspend, you can keep vcc_3v3 on during suspend by adding the following lines to your device tree:

--- a/arch/arm64/boot/dts/digi/ccimx8x.dtsi
+++ b/arch/arm64/boot/dts/digi/ccimx8x.dtsi
@@ -220,21 +220,21 @@
                        regulator-boot-on;
                        regulator-always-on;
                };

                vcc_3v3_reg: SW7 {
                        regulator-min-microvolt = <3300000>;
                        regulator-max-microvolt = <3300000>;
                        regulator-boot-on;
                        regulator-always-on;
                        regulator-state-mem {
-                               regulator-off-in-suspend;
+                               regulator-on-in-suspend;
                        };
                };

                vcc_scu_1v8_reg: LDO1 {
                        regulator-min-microvolt = <1800000>;
                        regulator-max-microvolt = <1800000>;
                        regulator-boot-on;
                        regulator-always-on;
                };