drivers: led_strip: Add length function

Adds a length function which returns the length of the LED strip

Signed-off-by: Jamie McCrae <spam@helper3000.net>
This commit is contained in:
Jamie McCrae 2024-04-17 19:10:22 +01:00 committed by Henrik Brix Andersen
commit 4bea96b68b
11 changed files with 97 additions and 4 deletions

View file

@ -14,6 +14,7 @@
struct apa102_config {
struct spi_dt_spec bus;
size_t length;
};
static int apa102_update(const struct device *dev, void *buf, size_t size)
@ -80,6 +81,13 @@ static int apa102_update_channels(const struct device *dev, uint8_t *channels,
return -EINVAL;
}
static size_t apa102_length(const struct device *dev)
{
const struct apa102_config *config = dev->config;
return config->length;
}
static int apa102_init(const struct device *dev)
{
const struct apa102_config *config = dev->config;
@ -94,6 +102,7 @@ static int apa102_init(const struct device *dev)
static const struct led_strip_driver_api apa102_api = {
.update_rgb = apa102_update_rgb,
.update_channels = apa102_update_channels,
.length = apa102_length,
};
#define APA102_DEVICE(idx) \
@ -102,6 +111,7 @@ static const struct led_strip_driver_api apa102_api = {
idx, \
SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8), \
0), \
.length = DT_INST_PROP(idx, chain_length), \
}; \
\
DEVICE_DT_INST_DEFINE(idx, \

View file

@ -36,6 +36,7 @@ LOG_MODULE_REGISTER(lpd880x);
struct lpd880x_config {
struct spi_dt_spec bus;
size_t length;
};
static int lpd880x_update(const struct device *dev, void *data, size_t size)
@ -125,6 +126,13 @@ static int lpd880x_strip_update_channels(const struct device *dev,
return lpd880x_update(dev, channels, num_channels);
}
static size_t lpd880x_strip_length(const struct device *dev)
{
const struct lpd880x_config *config = dev->config;
return config->length;
}
static int lpd880x_strip_init(const struct device *dev)
{
const struct lpd880x_config *config = dev->config;
@ -138,12 +146,14 @@ static int lpd880x_strip_init(const struct device *dev)
}
static const struct lpd880x_config lpd880x_config = {
.bus = SPI_DT_SPEC_INST_GET(0, LPD880X_SPI_OPERATION, 0)
.bus = SPI_DT_SPEC_INST_GET(0, LPD880X_SPI_OPERATION, 0),
.length = DT_INST_PROP(0, chain_length),
};
static const struct led_strip_driver_api lpd880x_strip_api = {
.update_rgb = lpd880x_strip_update_rgb,
.update_channels = lpd880x_strip_update_channels,
.length = lpd880x_strip_length,
};
DEVICE_DT_INST_DEFINE(0, lpd880x_strip_init, NULL,

View file

@ -269,6 +269,13 @@ static int tlc5971_update_channels(const struct device *dev, uint8_t *channels,
return -ENOTSUP;
}
static size_t tlc5971_length(const struct device *dev)
{
const struct tlc5971_config *cfg = dev->config;
return (size_t)cfg->num_pixels;
}
int tlc5971_set_global_brightness(const struct device *dev, struct led_rgb pixel)
{
const struct tlc5971_config *cfg = dev->config;
@ -334,6 +341,7 @@ static int tlc5971_init(const struct device *dev)
static const struct led_strip_driver_api tlc5971_api = {
.update_rgb = tlc5971_update_rgb,
.update_channels = tlc5971_update_channels,
.length = tlc5971_length,
};
#define TLC5971_DATA_BUFFER_LENGTH(inst) \

View file

@ -28,6 +28,7 @@ struct ws2812_gpio_cfg {
struct gpio_dt_spec gpio;
uint8_t num_colors;
const uint8_t *color_mapping;
size_t length;
};
/*
@ -187,9 +188,17 @@ static int ws2812_gpio_update_channels(const struct device *dev,
return -ENOTSUP;
}
static size_t ws2812_gpio_length(const struct device *dev)
{
const struct ws2812_gpio_cfg *config = dev->config;
return config->length;
}
static const struct led_strip_driver_api ws2812_gpio_api = {
.update_rgb = ws2812_gpio_update_rgb,
.update_channels = ws2812_gpio_update_channels,
.length = ws2812_gpio_length,
};
/*
@ -245,6 +254,7 @@ static const uint8_t ws2812_gpio_##idx##_color_mapping[] = \
.gpio = GPIO_DT_SPEC_INST_GET(idx, gpios), \
.num_colors = WS2812_NUM_COLORS(idx), \
.color_mapping = ws2812_gpio_##idx##_color_mapping, \
.length = DT_INST_PROP(idx, chain_length), \
}; \
\
DEVICE_DT_INST_DEFINE(idx, \

View file

@ -38,6 +38,7 @@ struct ws2812_i2s_cfg {
size_t tx_buf_bytes;
struct k_mem_slab *mem_slab;
uint8_t num_colors;
size_t length;
const uint8_t *color_mapping;
uint16_t reset_words;
uint32_t lrck_period;
@ -170,6 +171,13 @@ static int ws2812_strip_update_channels(const struct device *dev, uint8_t *chann
return -ENOTSUP;
}
static size_t ws2812_strip_length(const struct device *dev)
{
const struct ws2812_i2s_cfg *cfg = dev->config;
return cfg->length;
}
static int ws2812_i2s_init(const struct device *dev)
{
const struct ws2812_i2s_cfg *cfg = dev->config;
@ -218,6 +226,7 @@ static int ws2812_i2s_init(const struct device *dev)
static const struct led_strip_driver_api ws2812_i2s_api = {
.update_rgb = ws2812_strip_update_rgb,
.update_channels = ws2812_strip_update_channels,
.length = ws2812_strip_length,
};
/* Integer division, but always rounds up: e.g. 10/3 = 4 */
@ -250,6 +259,7 @@ static const struct led_strip_driver_api ws2812_i2s_api = {
.tx_buf_bytes = WS2812_I2S_BUFSIZE(idx), \
.mem_slab = &ws2812_i2s_##idx##_slab, \
.num_colors = WS2812_NUM_COLORS(idx), \
.length = DT_INST_PROP(idx, chain_length), \
.color_mapping = ws2812_i2s_##idx##_color_mapping, \
.lrck_period = WS2812_I2S_LRCK_PERIOD_US(idx), \
.extra_wait_time_us = DT_INST_PROP(idx, extra_wait_time), \

View file

@ -24,6 +24,7 @@ struct ws2812_led_strip_config {
const struct device *piodev;
const uint8_t gpio_pin;
uint8_t num_colors;
size_t length;
uint32_t frequency;
const uint8_t *const color_mapping;
uint16_t reset_delay;
@ -115,9 +116,17 @@ static int ws2812_led_strip_update_channels(const struct device *dev, uint8_t *c
return -ENOTSUP;
}
static size_t ws2812_led_strip_length(const struct device *dev)
{
const struct ws2812_led_strip_config *config = dev->config;
return config->length;
}
static const struct led_strip_driver_api ws2812_led_strip_api = {
.update_rgb = ws2812_led_strip_update_rgb,
.update_channels = ws2812_led_strip_update_channels,
.length = ws2812_led_strip_length,
};
/*
@ -190,6 +199,7 @@ static int ws2812_rpi_pico_pio_init(const struct device *dev)
.piodev = DEVICE_DT_GET(DT_PARENT(DT_PARENT(node))), \
.gpio_pin = DT_GPIO_PIN_BY_IDX(node, gpios, 0), \
.num_colors = DT_PROP_LEN(node, color_mapping), \
.length = DT_PROP(node, chain_length), \
.color_mapping = ws2812_led_strip_##node##_color_mapping, \
.reset_delay = DT_PROP(node, reset_delay), \
.frequency = DT_PROP(node, frequency), \

View file

@ -44,6 +44,7 @@ struct ws2812_spi_cfg {
uint8_t zero_frame;
uint8_t num_colors;
const uint8_t *color_mapping;
size_t length;
uint16_t reset_delay;
};
@ -160,6 +161,13 @@ static int ws2812_strip_update_channels(const struct device *dev,
return -ENOTSUP;
}
static size_t ws2812_strip_length(const struct device *dev)
{
const struct ws2812_spi_cfg *cfg = dev_cfg(dev);
return cfg->length;
}
static int ws2812_spi_init(const struct device *dev)
{
const struct ws2812_spi_cfg *cfg = dev_cfg(dev);
@ -191,6 +199,7 @@ static int ws2812_spi_init(const struct device *dev)
static const struct led_strip_driver_api ws2812_spi_api = {
.update_rgb = ws2812_strip_update_rgb,
.update_channels = ws2812_strip_update_channels,
.length = ws2812_strip_length,
};
#define WS2812_SPI_NUM_PIXELS(idx) \
@ -231,6 +240,7 @@ static const struct led_strip_driver_api ws2812_spi_api = {
.zero_frame = WS2812_SPI_ZERO_FRAME(idx), \
.num_colors = WS2812_NUM_COLORS(idx), \
.color_mapping = ws2812_spi_##idx##_color_mapping, \
.length = DT_INST_PROP(idx, chain_length), \
.reset_delay = WS2812_RESET_DELAY(idx), \
}; \
\

View file

@ -2,4 +2,4 @@ description: APA102 SPI LED strip
compatible: "apa,apa102"
include: spi-device.yaml
include: [spi-device.yaml, led-strip.yaml]

View file

@ -5,4 +5,4 @@ description: GreeLed LPD8803 SPI LED strip
compatible: "greeled,lpd8803"
include: spi-device.yaml
include: [spi-device.yaml, led-strip.yaml]

View file

@ -5,4 +5,4 @@ description: GreeLed LPD8806 SPI LED strip
compatible: "greeled,lpd8806"
include: spi-device.yaml
include: [spi-device.yaml, led-strip.yaml]

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2017 Linaro Limited
* Copyright (c) 2024 Jamie McCrae
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -71,6 +72,14 @@ typedef int (*led_api_update_channels)(const struct device *dev,
uint8_t *channels,
size_t num_channels);
/**
* @typedef led_api_length
* @brief Callback API for getting length of an LED strip.
*
* @see led_strip_length() for argument descriptions.
*/
typedef size_t (*led_api_length)(const struct device *dev);
/**
* @brief LED strip driver API
*
@ -79,6 +88,7 @@ typedef int (*led_api_update_channels)(const struct device *dev,
__subsystem struct led_strip_driver_api {
led_api_update_rgb update_rgb;
led_api_update_channels update_channels;
led_api_length length;
};
/**
@ -131,6 +141,21 @@ static inline int led_strip_update_channels(const struct device *dev,
return api->update_channels(dev, channels, num_channels);
}
/**
* @brief Mandatory function to get chain length (in pixels) of an LED strip device.
*
* @param dev LED strip device.
*
* @retval Length of LED strip device.
*/
static inline size_t led_strip_length(const struct device *dev)
{
const struct led_strip_driver_api *api =
(const struct led_strip_driver_api *)dev->api;
return api->length(dev);
}
#ifdef __cplusplus
}
#endif