diff --git a/doc/releases/release-notes-4.1.rst b/doc/releases/release-notes-4.1.rst index 2e734c7f8197b..9b445ed643877 100644 --- a/doc/releases/release-notes-4.1.rst +++ b/doc/releases/release-notes-4.1.rst @@ -119,6 +119,9 @@ Drivers and Sensors * LED * Added a new set of devicetree based LED APIs, see :c:struct:`led_dt_spec`. + * lp5569: added use of auto-increment functionality. + * lp5569: implemented ``write_channels`` api. + * lp5569: demonstrate ``led_write_channels`` in the sample. * LED Strip diff --git a/drivers/led/lp5569.c b/drivers/led/lp5569.c index f7a9758c4ec2c..c87a574900dc1 100644 --- a/drivers/led/lp5569.c +++ b/drivers/led/lp5569.c @@ -31,6 +31,7 @@ LOG_MODULE_REGISTER(lp5569, CONFIG_LED_LOG_LEVEL); #define LP5569_MISC 0x2F #define LP5569_POWERSAVE_EN BIT(5) +#define LP5569_EN_AUTO_INCR BIT(6) #define LP5569_CP_MODE_SHIFT 3 /* PWM base Register for controlling the duty-cycle */ @@ -76,6 +77,23 @@ static inline int lp5569_led_off(const struct device *dev, uint32_t led) return lp5569_led_set_brightness(dev, led, 0); } +static int lp5569_write_channels(const struct device *dev, uint32_t start_channel, + uint32_t num_channels, const uint8_t *buf) +{ + const struct lp5569_config *config = dev->config; + uint32_t i2c_len = num_channels + 1; + uint8_t i2c_msg[LP5569_NUM_LEDS + 1]; + + if ((uint64_t)start_channel + num_channels > LP5569_NUM_LEDS) { + return -EINVAL; + } + + i2c_msg[0] = LP5569_LED0_PWM + start_channel; + memcpy(&i2c_msg[1], buf, num_channels); + + return i2c_write_dt(&config->bus, i2c_msg, i2c_len); +} + static int lp5569_enable(const struct device *dev) { const struct lp5569_config *config = dev->config; @@ -110,7 +128,7 @@ static int lp5569_enable(const struct device *dev) } ret = i2c_reg_write_byte_dt(&config->bus, LP5569_MISC, - LP5569_POWERSAVE_EN | + LP5569_POWERSAVE_EN | LP5569_EN_AUTO_INCR | (config->cp_mode << LP5569_CP_MODE_SHIFT)); if (ret < 0) { LOG_ERR("LED reg update failed"); @@ -169,6 +187,7 @@ static const struct led_driver_api lp5569_led_api = { .set_brightness = lp5569_led_set_brightness, .on = lp5569_led_on, .off = lp5569_led_off, + .write_channels = lp5569_write_channels, }; #define LP5569_DEFINE(id) \ diff --git a/samples/drivers/led/lp5569/README.rst b/samples/drivers/led/lp5569/README.rst index ecb04cf9965cd..f39fcd1678c63 100644 --- a/samples/drivers/led/lp5569/README.rst +++ b/samples/drivers/led/lp5569/README.rst @@ -8,7 +8,10 @@ Overview ******** This sample controls 9 LEDs connected to an LP5569 driver. The sample turns -all LEDs on and switches all LEDs off again within a one second interval. +all LEDs on one by one with a 1 second delay between each. Then it fades all +LEDs until they are off again. Afterwards, it turns them all on at once, waits +a second, and turns them all back off. +This pattern then repeats indefinitely. Building and Running ******************** diff --git a/samples/drivers/led/lp5569/src/main.c b/samples/drivers/led/lp5569/src/main.c index fe18d5ee280aa..bf18ef33b3877 100644 --- a/samples/drivers/led/lp5569/src/main.c +++ b/samples/drivers/led/lp5569/src/main.c @@ -18,6 +18,7 @@ LOG_MODULE_REGISTER(app, CONFIG_LED_LOG_LEVEL); int main(void) { const struct device *const led_dev = DEVICE_DT_GET_ANY(ti_lp5569); + uint8_t ch_buf[9] = {0}; int i, ret; if (!led_dev) { @@ -32,7 +33,8 @@ int main(void) /* * Display a continuous pattern that turns on 9 LEDs at 1 s one by - * one until it reaches the end and turns off LEDs in reverse order. + * one until it reaches the end and fades off all LEDs. + * Afterwards, all LEDs get blinked once at the same time. */ LOG_INF("Testing 9 LEDs .."); @@ -59,6 +61,26 @@ int main(void) k_sleep(DELAY_TIME_BREATHING); } + + k_sleep(DELAY_TIME_ON); + + /* Turn on all LEDs at once to demonstrate write_channels */ + memset(ch_buf, 255, ARRAY_SIZE(ch_buf)); + ret = led_write_channels(led_dev, 0, ARRAY_SIZE(ch_buf), ch_buf); + if (ret) { + return ret; + } + + k_sleep(DELAY_TIME_ON); + + /* Turn off all LEDs at once to demonstrate write_channels */ + memset(ch_buf, 0, ARRAY_SIZE(ch_buf)); + ret = led_write_channels(led_dev, 0, ARRAY_SIZE(ch_buf), ch_buf); + if (ret) { + return ret; + } + + k_sleep(DELAY_TIME_ON); } return 0; }