LCOV - code coverage report
Current view: top level - zephyr/drivers - mipi_dbi.h Coverage Total Hit
Test: new.info Lines: 73.9 % 23 17
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            1 : /*
       2              :  * Copyright 2023 NXP
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @ingroup mipi_dbi_interface
      10              :  * @brief Main header file for MIPI-DBI (Display Bus Interface) driver API.
      11              :  *
      12              :  * MIPI-DBI defines the following 3 interfaces:
      13              :  * - Type A: Motorola 6800 type parallel bus
      14              :  * - Type B: Intel 8080 type parallel bus
      15              :  * - Type C: SPI Type (1 bit bus) with 3 options:
      16              :  *     1. 9 write clocks per byte, final bit is command/data selection bit
      17              :  *     2. Same as above, but 16 write clocks per byte
      18              :  *     3. 8 write clocks per byte. Command/data selected via GPIO pin
      19              :  * The current driver interface does not support type C with 16 write clocks (option 2).
      20              :  */
      21              : 
      22              : #ifndef ZEPHYR_INCLUDE_DRIVERS_MIPI_DBI_H_
      23              : #define ZEPHYR_INCLUDE_DRIVERS_MIPI_DBI_H_
      24              : 
      25              : /**
      26              :  * @brief Interfaces for MIPI-DBI (Display Bus Interface).
      27              :  * @defgroup mipi_dbi_interface MIPI-DBI
      28              :  * @since 3.6
      29              :  * @version 0.8.0
      30              :  * @ingroup display_interface
      31              :  * @{
      32              :  */
      33              : 
      34              : #include <zephyr/device.h>
      35              : #include <zephyr/drivers/display.h>
      36              : #include <zephyr/display/mipi_display.h>
      37              : #include <zephyr/drivers/spi.h>
      38              : #include <zephyr/dt-bindings/mipi_dbi/mipi_dbi.h>
      39              : 
      40              : #ifdef __cplusplus
      41              : extern "C" {
      42              : #endif
      43              : 
      44              : /**
      45              :  * @brief initialize a MIPI DBI SPI configuration struct from devicetree
      46              :  *
      47              :  * This helper allows drivers to initialize a MIPI DBI SPI configuration
      48              :  * structure using devicetree.
      49              :  * @param node_id Devicetree node identifier for the MIPI DBI device whose
      50              :  *                struct spi_config to create an initializer for
      51              :  * @param operation_ the desired operation field in the struct spi_config
      52              :  * @param delay_ the desired delay field in the struct spi_config's
      53              :  *               spi_cs_control, if there is one
      54              :  */
      55            1 : #define MIPI_DBI_SPI_CONFIG_DT(node_id, operation_, delay_)             \
      56              :         {                                                               \
      57              :                 .frequency = DT_PROP(node_id, mipi_max_frequency),      \
      58              :                 .operation = (operation_) |                             \
      59              :                         DT_PROP_OR(node_id, duplex, 0) |                        \
      60              :                         COND_CODE_1(DT_PROP(node_id, mipi_cpol), SPI_MODE_CPOL, (0)) |  \
      61              :                         COND_CODE_1(DT_PROP(node_id, mipi_cpha), SPI_MODE_CPHA, (0)) |  \
      62              :                         COND_CODE_1(DT_PROP(node_id, mipi_hold_cs), SPI_HOLD_ON_CS, (0)),       \
      63              :                 .slave = DT_REG_ADDR(node_id),                          \
      64              :                 .cs = {                                                 \
      65              :                         .gpio = GPIO_DT_SPEC_GET_BY_IDX_OR(DT_PHANDLE(DT_PARENT(node_id), \
      66              :                                                            spi_dev), cs_gpios, \
      67              :                                                            DT_REG_ADDR_RAW(node_id), \
      68              :                                                            {}),         \
      69              :                         .delay = (delay_),                              \
      70              :                 },                                                      \
      71              :         }
      72              : 
      73              : /**
      74              :  * @brief Initialize a MIPI DBI SPI configuration from devicetree instance
      75              :  *
      76              :  * This helper initializes a MIPI DBI SPI configuration from a devicetree
      77              :  * instance. It is equivalent to MIPI_DBI_SPI_CONFIG_DT(DT_DRV_INST(inst))
      78              :  * @param inst Instance number to initialize configuration from
      79              :  * @param operation_ the desired operation field in the struct spi_config
      80              :  * @param delay_ the desired delay field in the struct spi_config's
      81              :  *               spi_cs_control, if there is one
      82              :  */
      83            1 : #define MIPI_DBI_SPI_CONFIG_DT_INST(inst, operation_, delay_)           \
      84              :         MIPI_DBI_SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)
      85              : 
      86              : /**
      87              :  * @brief Initialize a MIPI DBI configuration from devicetree
      88              :  *
      89              :  * This helper allows drivers to initialize a MIPI DBI configuration
      90              :  * structure from devicetree. It sets the MIPI DBI mode, as well
      91              :  * as configuration fields in the SPI configuration structure
      92              :  * @param node_id Devicetree node identifier for the MIPI DBI device to
      93              :  *                initialize
      94              :  * @param operation_ the desired operation field in the struct spi_config
      95              :  * @param delay_ the desired delay field in the struct spi_config's
      96              :  *               spi_cs_control, if there is one
      97              :  */
      98            1 : #define MIPI_DBI_CONFIG_DT(node_id, operation_, delay_)                 \
      99              :         {                                                               \
     100              :                 .mode = DT_STRING_UPPER_TOKEN(node_id, mipi_mode),      \
     101              :                 .config = MIPI_DBI_SPI_CONFIG_DT(node_id, operation_, delay_), \
     102              :         }
     103              : 
     104              : /**
     105              :  * @brief Initialize a MIPI DBI configuration from device instance
     106              :  *
     107              :  * Equivalent to MIPI_DBI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)
     108              :  * @param inst Instance of the device to initialize a MIPI DBI configuration for
     109              :  * @param operation_ the desired operation field in the struct spi_config
     110              :  * @param delay_ the desired delay field in the struct spi_config's
     111              :  *               spi_cs_control, if there is one
     112              :  */
     113            1 : #define MIPI_DBI_CONFIG_DT_INST(inst, operation_, delay_)               \
     114              :         MIPI_DBI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)
     115              : 
     116              : /**
     117              :  * @brief Get the MIPI DBI TE mode from devicetree
     118              :  *
     119              :  * Gets the MIPI DBI TE mode from a devicetree property.
     120              :  * @param node_id Devicetree node identifier for the MIPI DBI device with the
     121              :  *                TE mode property
     122              :  * @param edge_prop Property name for the TE mode that should be read from
     123              :  *                  devicetree
     124              :  */
     125            1 : #define MIPI_DBI_TE_MODE_DT(node_id, edge_prop)                           \
     126              :         DT_STRING_UPPER_TOKEN(node_id, edge_prop)
     127              : 
     128              : /**
     129              :  * @brief Get the MIPI DBI TE mode for device instance
     130              :  *
     131              :  * Gets the MIPI DBI TE mode from a devicetree property. Equivalent to
     132              :  * MIPI_DBI_TE_MODE_DT(DT_DRV_INST(inst), edge_mode).
     133              :  * @param inst Instance of the device to get the TE mode for
     134              :  * @param edge_prop Property name for the TE mode that should be read from
     135              :  *                  devicetree
     136              :  */
     137            1 : #define MIPI_DBI_TE_MODE_DT_INST(inst, edge_prop)                         \
     138              :         DT_STRING_UPPER_TOKEN(DT_DRV_INST(inst), edge_prop)
     139              : 
     140              : /**
     141              :  * @brief MIPI DBI controller configuration
     142              :  *
     143              :  * Configuration for MIPI DBI controller write
     144              :  */
     145            1 : struct mipi_dbi_config {
     146              :         /** MIPI DBI mode */
     147            1 :         uint8_t mode;
     148              :         /** SPI configuration */
     149            1 :         struct spi_config config;
     150              : };
     151              : 
     152              : 
     153              : /** MIPI-DBI host driver API */
     154            1 : __subsystem struct mipi_dbi_driver_api {
     155            0 :         int (*command_write)(const struct device *dev,
     156              :                              const struct mipi_dbi_config *config, uint8_t cmd,
     157              :                              const uint8_t *data, size_t len);
     158            0 :         int (*command_read)(const struct device *dev,
     159              :                             const struct mipi_dbi_config *config, uint8_t *cmds,
     160              :                             size_t num_cmds, uint8_t *response, size_t len);
     161            0 :         int (*write_display)(const struct device *dev,
     162              :                              const struct mipi_dbi_config *config,
     163              :                              const uint8_t *framebuf,
     164              :                              struct display_buffer_descriptor *desc,
     165              :                              enum display_pixel_format pixfmt);
     166            0 :         int (*reset)(const struct device *dev, k_timeout_t delay);
     167            0 :         int (*release)(const struct device *dev,
     168              :                        const struct mipi_dbi_config *config);
     169            0 :         int (*configure_te)(const struct device *dev,
     170              :                             uint8_t edge,
     171              :                             k_timeout_t delay);
     172              : };
     173              : 
     174              : /**
     175              :  * @brief Write a command to the display controller
     176              :  *
     177              :  * Writes a command, along with an optional data buffer to the display.
     178              :  * If data buffer and buffer length are NULL and 0 respectively, then
     179              :  * only a command will be sent. Note that if the SPI configuration passed
     180              :  * to this function locks the SPI bus, it is the caller's responsibility
     181              :  * to release it with mipi_dbi_release()
     182              :  *
     183              :  * @param dev mipi dbi controller
     184              :  * @param config MIPI DBI configuration
     185              :  * @param cmd command to write to display controller
     186              :  * @param data optional data buffer to write after command
     187              :  * @param len size of data buffer in bytes. Set to 0 to skip sending data.
     188              :  * @retval 0 command write succeeded
     189              :  * @retval -EIO I/O error
     190              :  * @retval -ETIMEDOUT transfer timed out
     191              :  * @retval -EBUSY controller is busy
     192              :  * @retval -ENOSYS not implemented
     193              :  */
     194            1 : static inline int mipi_dbi_command_write(const struct device *dev,
     195              :                                          const struct mipi_dbi_config *config,
     196              :                                          uint8_t cmd, const uint8_t *data,
     197              :                                          size_t len)
     198              : {
     199              :         const struct mipi_dbi_driver_api *api =
     200              :                 (const struct mipi_dbi_driver_api *)dev->api;
     201              : 
     202              :         if (api->command_write == NULL) {
     203              :                 return -ENOSYS;
     204              :         }
     205              :         return api->command_write(dev, config, cmd, data, len);
     206              : }
     207              : 
     208              : /**
     209              :  * @brief Read a command response from the display controller
     210              :  *
     211              :  * Reads a command response from the display controller.
     212              :  *
     213              :  * @param dev mipi dbi controller
     214              :  * @param config MIPI DBI configuration
     215              :  * @param cmds array of one byte commands to send to display controller
     216              :  * @param num_cmd number of commands to write to display controller
     217              :  * @param response response buffer, filled with display controller response
     218              :  * @param len size of response buffer in bytes.
     219              :  * @retval 0 command read succeeded
     220              :  * @retval -EIO I/O error
     221              :  * @retval -ETIMEDOUT transfer timed out
     222              :  * @retval -EBUSY controller is busy
     223              :  * @retval -ENOSYS not implemented
     224              :  */
     225            1 : static inline int mipi_dbi_command_read(const struct device *dev,
     226              :                                         const struct mipi_dbi_config *config,
     227              :                                         uint8_t *cmds, size_t num_cmd,
     228              :                                         uint8_t *response, size_t len)
     229              : {
     230              :         const struct mipi_dbi_driver_api *api =
     231              :                 (const struct mipi_dbi_driver_api *)dev->api;
     232              : 
     233              :         if (api->command_read == NULL) {
     234              :                 return -ENOSYS;
     235              :         }
     236              :         return api->command_read(dev, config, cmds, num_cmd, response, len);
     237              : }
     238              : 
     239              : /**
     240              :  * @brief Write a display buffer to the display controller.
     241              :  *
     242              :  * Writes a display buffer to the controller. If the controller requires
     243              :  * a "Write memory" command before writing display data, this should be
     244              :  * sent with @ref mipi_dbi_command_write
     245              :  * @param dev mipi dbi controller
     246              :  * @param config MIPI DBI configuration
     247              :  * @param framebuf: framebuffer to write to display
     248              :  * @param desc: descriptor of framebuffer to write. Note that the pitch must
     249              :  *   be equal to width. "buf_size" field determines how many bytes will be
     250              :  *   written.
     251              :  * @param pixfmt: pixel format of framebuffer data
     252              :  * @retval 0 buffer write succeeded.
     253              :  * @retval -EIO I/O error
     254              :  * @retval -ETIMEDOUT transfer timed out
     255              :  * @retval -EBUSY controller is busy
     256              :  * @retval -ENOSYS not implemented
     257              :  */
     258            1 : static inline int mipi_dbi_write_display(const struct device *dev,
     259              :                                          const struct mipi_dbi_config *config,
     260              :                                          const uint8_t *framebuf,
     261              :                                          struct display_buffer_descriptor *desc,
     262              :                                          enum display_pixel_format pixfmt)
     263              : {
     264              :         const struct mipi_dbi_driver_api *api =
     265              :                 (const struct mipi_dbi_driver_api *)dev->api;
     266              : 
     267              :         if (api->write_display == NULL) {
     268              :                 return -ENOSYS;
     269              :         }
     270              :         return api->write_display(dev, config, framebuf, desc, pixfmt);
     271              : }
     272              : 
     273              : /**
     274              :  * @brief Resets attached display controller
     275              :  *
     276              :  * Resets the attached display controller.
     277              :  * @param dev mipi dbi controller
     278              :  * @param delay_ms duration to set reset signal for, in milliseconds
     279              :  * @retval 0 reset succeeded
     280              :  * @retval -EIO I/O error
     281              :  * @retval -ENOSYS not implemented
     282              :  * @retval -ENOTSUP not supported
     283              :  */
     284            1 : static inline int mipi_dbi_reset(const struct device *dev, uint32_t delay_ms)
     285              : {
     286              :         const struct mipi_dbi_driver_api *api =
     287              :                 (const struct mipi_dbi_driver_api *)dev->api;
     288              : 
     289              :         if (api->reset == NULL) {
     290              :                 return -ENOSYS;
     291              :         }
     292              :         return api->reset(dev, K_MSEC(delay_ms));
     293              : }
     294              : 
     295              : /**
     296              :  * @brief Releases a locked MIPI DBI device.
     297              :  *
     298              :  * Releases a lock on a MIPI DBI device and/or the device's CS line if and
     299              :  * only if the given config parameter was the last one to be used in any
     300              :  * of the above functions, and if it has the SPI_LOCK_ON bit set and/or
     301              :  * the SPI_HOLD_ON_CS bit set into its operation bits field.
     302              :  * This lock functions exactly like the SPI lock, and can be used if the caller
     303              :  * needs to keep CS asserted for multiple transactions, or the MIPI DBI device
     304              :  * locked.
     305              :  * @param dev mipi dbi controller
     306              :  * @param config MIPI DBI configuration
     307              :  * @retval 0 reset succeeded
     308              :  * @retval -EIO I/O error
     309              :  * @retval -ENOSYS not implemented
     310              :  * @retval -ENOTSUP not supported
     311              :  */
     312            1 : static inline int mipi_dbi_release(const struct device *dev,
     313              :                                    const struct mipi_dbi_config *config)
     314              : {
     315              :         const struct mipi_dbi_driver_api *api =
     316              :                 (const struct mipi_dbi_driver_api *)dev->api;
     317              : 
     318              :         if (api->release == NULL) {
     319              :                 return -ENOSYS;
     320              :         }
     321              :         return api->release(dev, config);
     322              : }
     323              : 
     324              : /**
     325              :  * @brief Configures MIPI DBI tearing effect signal
     326              :  *
     327              :  * Many displays provide a tearing effect signal, which can be configured
     328              :  * to pulse at each vsync interval or each hsync interval. This signal can be
     329              :  * used by the MCU to determine when to transmit a new frame so that the
     330              :  * read pointer of the display never overlaps with the write pointer from the
     331              :  * MCU. This function configures the MIPI DBI controller to delay transmitting
     332              :  * display frames until the selected tearing effect signal edge occurs.
     333              :  *
     334              :  * The delay will occur on the on each call to @ref mipi_dbi_write_display
     335              :  * where the ``frame_incomplete`` flag was set within the buffer descriptor
     336              :  * provided with the prior call, as this indicates the buffer being written
     337              :  * in this call is the first buffer of a new frame.
     338              :  *
     339              :  * Note that most display controllers will need to enable the TE signal
     340              :  * using vendor specific commands before the MIPI DBI controller can react
     341              :  * to it.
     342              :  *
     343              :  * @param dev mipi dbi controller
     344              :  * @param edge which edge of the TE signal to start transmitting on
     345              :  * @param delay_us how many microseconds after TE edge to start transmission
     346              :  * @retval -EIO I/O error
     347              :  * @retval -ENOSYS not implemented
     348              :  * @retval -ENOTSUP not supported
     349              :  */
     350            1 : static inline int mipi_dbi_configure_te(const struct device *dev,
     351              :                                         uint8_t edge,
     352              :                                         uint32_t delay_us)
     353              : {
     354              :         const struct mipi_dbi_driver_api *api =
     355              :                 (const struct mipi_dbi_driver_api *)dev->api;
     356              : 
     357              :         if (api->configure_te == NULL) {
     358              :                 return -ENOSYS;
     359              :         }
     360              :         return api->configure_te(dev, edge, K_USEC(delay_us));
     361              : }
     362              : 
     363              : #ifdef __cplusplus
     364              : }
     365              : #endif
     366              : 
     367              : /**
     368              :  * @}
     369              :  */
     370              : 
     371              : #endif /* ZEPHYR_INCLUDE_DRIVERS_MIPI_DBI_H_ */
        

Generated by: LCOV version 2.0-1