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 <daniel.degrasse@nxp.com>
This commit is contained in:
Daniel DeGrasse 2024-03-21 14:22:32 -05:00 committed by Alberto Escolar
parent 8ffefab29f
commit 1c5a66f99c
2 changed files with 39 additions and 1 deletions

View file

@ -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); 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) static int mipi_dbi_spi_init(const struct device *dev)
{ {
const struct mipi_dbi_spi_config *config = dev->config; 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, .reset = mipi_dbi_spi_reset,
.command_write = mipi_dbi_spi_command_write, .command_write = mipi_dbi_spi_command_write,
.write_display = mipi_dbi_spi_write_display, .write_display = mipi_dbi_spi_write_display,
.release = mipi_dbi_spi_release,
#if MIPI_DBI_SPI_READ_REQUIRED #if MIPI_DBI_SPI_READ_REQUIRED
.command_read = mipi_dbi_spi_command_read, .command_read = mipi_dbi_spi_command_read,
#endif #endif

View file

@ -135,6 +135,8 @@ __subsystem struct mipi_dbi_driver_api {
struct display_buffer_descriptor *desc, struct display_buffer_descriptor *desc,
enum display_pixel_format pixfmt); enum display_pixel_format pixfmt);
int (*reset)(const struct device *dev, uint32_t delay); 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. * Writes a command, along with an optional data buffer to the display.
* If data buffer and buffer length are NULL and 0 respectively, then * 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 dev mipi dbi controller
* @param config MIPI DBI configuration * @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); 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 #ifdef __cplusplus
} }
#endif #endif