• Marek Behún's avatar
    leds: turris-omnia: Make set_brightness() more efficient · 9f028c9e
    Marek Behún authored
    Implement caching of the LED color and state values that are sent to MCU
    in order to make the set_brightness() operation more efficient by
    avoiding I2C transactions which are not needed.
    
    On Turris Omnia's MCU, which acts as the RGB LED controller, each LED
    has a RGB color, and a ON/OFF state, which are configurable via I2C
    commands CMD_LED_COLOR and CMD_LED_STATE.
    
    The CMD_LED_COLOR command sends 5 bytes and the CMD_LED_STATE command 2
    bytes over the I2C bus, which operates at 100 kHz. With I2C overhead
    this allows ~1670 color changing commands and ~3200 state changing
    commands per second (or around 1000 color + state changes per second).
    This may seem more than enough, but the issue is that the I2C bus is
    shared with another peripheral, the MCU. The MCU exposes an interrupt
    interface, and it can trigger hundreds of interrupts per second. Each
    time, we need to read the interrupt state register over this I2C bus.
    Whenever we are sending a LED color/state changing command, the
    interrupt reading is waiting.
    
    Currently, every time LED brightness or LED multi intensity is changed,
    we send a CMD_LED_STATE command, and if the computed color (brightness
    adjusted multi_intensity) is non-zero, we also send a CMD_LED_COLOR
    command.
    
    Consider for example the situation when we have a netdev trigger enabled
    for a LED. The netdev trigger does not change the LED color, only the
    brightness (either to 0 or to currently configured brightness), and so
    there is no need to send the CMD_LED_COLOR command. But each change of
    brightness to 0 sends one CMD_LED_STATE command, and each change of
    brightness to max_brightness sends one CMD_LED_STATE command and one
    CMD_LED_COLOR command:
        set_brightness(0)   ->  CMD_LED_STATE
        set_brightness(255) ->  CMD_LED_STATE + CMD_LED_COLOR
                                                (unnecessary)
    
    We can avoid the unnecessary I2C transactions if we cache the values of
    state and color that are sent to the controller. If the color does not
    change from the one previously sent, there is no need to do the
    CMD_LED_COLOR I2C transaction, and if the state does not change, there
    is no need to do the CMD_LED_STATE transaction.
    
    Because we need to make sure that our cached values are consistent with
    the controller state, add explicit setting of the LED color to white at
    probe time (this is the default setting when MCU resets, but does not
    necessarily need to be the case, for example if U-Boot played with the
    LED colors).
    Signed-off-by: default avatarMarek Behún <kabel@kernel.org>
    Link: https://lore.kernel.org/r/20230918161104.20860-3-kabel@kernel.orgSigned-off-by: default avatarLee Jones <lee@kernel.org>
    9f028c9e
leds-turris-omnia.c 9.05 KB