drivers: led_strip: Add support for external SPI CS on APA102 LED strips

Some boards may include an APA102 LED on an existing SPI bus. With
additional circuitry, chip select is supported where the APA102
lacks a built in CS pin.

This patch allows CS to be defined in the devicetree (through .dts
files) and utilised in the apa102.c driver if it's available. Preserving
old behaviour if no chip select is defined.

Signed-off-by: Roman Vaughan <nzsmartie@gmail.com>
This commit is contained in:
Roman Vaughan 2020-05-14 14:24:10 +12:00 committed by Anas Nashif
parent 285ffe9727
commit ac6fec45e7

View file

@ -9,10 +9,33 @@
#include <errno.h>
#include <drivers/led_strip.h>
#include <drivers/spi.h>
#include <drivers/gpio.h>
#include <sys/util.h>
/*
* Devicetree helper macros which gets the 'flags' cell from a 'cs_gpios'
* property on the spi bus, or returns 0 if the property has no 'flags' cell.
*
* Hopefully these helpers will be removed once #25827 is resolved.
*/
#define HAS_FLAGS(spi_dev, spi_reg) \
DT_PHA_HAS_CELL_AT_IDX(spi_dev, cs_gpios, spi_reg, flags)
#define INST_SPI_DEV_CS_GPIOS_HAS_FLAGS(node) \
HAS_FLAGS(DT_BUS(node), DT_REG_ADDR(node))
#define FLAGS_OR_ZERO(inst) \
COND_CODE_1( \
INST_SPI_DEV_CS_GPIOS_HAS_FLAGS(DT_DRV_INST(inst)), \
(DT_INST_SPI_DEV_CS_GPIOS_FLAGS(inst)), \
(0x0))
struct apa102_data {
struct device *spi;
struct spi_config cfg;
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
struct spi_cs_control cs_ctl;
#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */
};
static int apa102_update(struct device *dev, void *buf, size_t size)
@ -93,6 +116,21 @@ static int apa102_init(struct device *dev)
data->cfg.operation =
SPI_OP_MODE_MASTER | SPI_TRANSFER_MSB | SPI_WORD_SET(8);
#if DT_INST_SPI_DEV_HAS_CS_GPIOS(0)
data->cs_ctl.gpio_dev =
device_get_binding(DT_INST_SPI_DEV_CS_GPIOS_LABEL(0));
if (!data->cs_ctl.gpio_dev) {
return -ENODEV;
}
data->cs_ctl.gpio_pin = DT_INST_SPI_DEV_CS_GPIOS_PIN(0);
data->cs_ctl.delay = 0;
data->cfg.cs = &data->cs_ctl;
gpio_pin_configure(data->cs_ctl.gpio_dev, data->cs_ctl.gpio_pin,
GPIO_OUTPUT_INACTIVE | FLAGS_OR_ZERO(0));
#endif /* DT_INST_SPI_DEV_HAS_CS_GPIOS(0) */
return 0;
}