From 1c5a66f99ce597372ac6f554a8e52b27426ebc9f Mon Sep 17 00:00:00 2001 From: Daniel DeGrasse Date: Thu, 21 Mar 2024 14:22:32 -0500 Subject: [PATCH] drivers: mipi_dbi: add mipi_dbi_release API Some SPI based displays expect the ability to lock the SPI bus after a transaction completes, or to hold CS low. In order to accommodate this within the MIPI DBI layer, add the mipi_dbi_release API, which allows SPI displays to hold then release the SPI bus used by the MIPI abstraction layer. Signed-off-by: Daniel DeGrasse --- drivers/mipi_dbi/mipi_dbi_spi.c | 9 +++++++++ include/zephyr/drivers/mipi_dbi.h | 31 ++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/mipi_dbi/mipi_dbi_spi.c b/drivers/mipi_dbi/mipi_dbi_spi.c index 846158efee..0314fe5c31 100644 --- a/drivers/mipi_dbi/mipi_dbi_spi.c +++ b/drivers/mipi_dbi/mipi_dbi_spi.c @@ -266,6 +266,14 @@ static int mipi_dbi_spi_reset(const struct device *dev, uint32_t delay) return gpio_pin_set_dt(&config->reset, 0); } +static int mipi_dbi_spi_release(const struct device *dev, + const struct mipi_dbi_config *dbi_config) +{ + const struct mipi_dbi_spi_config *config = dev->config; + + return spi_release(config->spi_dev, &dbi_config->config); +} + static int mipi_dbi_spi_init(const struct device *dev) { const struct mipi_dbi_spi_config *config = dev->config; @@ -308,6 +316,7 @@ static struct mipi_dbi_driver_api mipi_dbi_spi_driver_api = { .reset = mipi_dbi_spi_reset, .command_write = mipi_dbi_spi_command_write, .write_display = mipi_dbi_spi_write_display, + .release = mipi_dbi_spi_release, #if MIPI_DBI_SPI_READ_REQUIRED .command_read = mipi_dbi_spi_command_read, #endif diff --git a/include/zephyr/drivers/mipi_dbi.h b/include/zephyr/drivers/mipi_dbi.h index d0a75e1805..aeaeb57799 100644 --- a/include/zephyr/drivers/mipi_dbi.h +++ b/include/zephyr/drivers/mipi_dbi.h @@ -135,6 +135,8 @@ __subsystem struct mipi_dbi_driver_api { struct display_buffer_descriptor *desc, enum display_pixel_format pixfmt); int (*reset)(const struct device *dev, uint32_t delay); + int (*release)(const struct device *dev, + const struct mipi_dbi_config *config); }; /** @@ -142,7 +144,9 @@ __subsystem struct mipi_dbi_driver_api { * * Writes a command, along with an optional data buffer to the display. * If data buffer and buffer length are NULL and 0 respectively, then - * only a command will be sent. + * only a command will be sent. Note that if the SPI configuration passed + * to this function locks the SPI bus, it is the caller's responsibility + * to release it with mipi_dbi_release() * * @param dev mipi dbi controller * @param config MIPI DBI configuration @@ -256,6 +260,31 @@ static inline int mipi_dbi_reset(const struct device *dev, uint32_t delay) return api->reset(dev, delay); } +/** + * @brief Releases a locked MIPI DBI device. + * + * Releases a lock on a MIPI DBI device and/or the device's CS line if and + * only if the given config parameter was the last one to be used in any + * of the above functions, and if it has the SPI_LOCK_ON bit set and/or + * the SPI_HOLD_ON_CS bit set into its operation bits field. + * This lock functions exactly like the SPI lock, and can be used if the caller + * needs to keep CS asserted for multiple transactions, or the MIPI DBI device + * locked. + * @param dev mipi dbi controller + * @param config MIPI DBI configuration + */ +static inline int mipi_dbi_release(const struct device *dev, + const struct mipi_dbi_config *config) +{ + const struct mipi_dbi_driver_api *api = + (const struct mipi_dbi_driver_api *)dev->api; + + if (api->release == NULL) { + return -ENOSYS; + } + return api->release(dev, config); +} + #ifdef __cplusplus } #endif