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-05 20:47:19

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

Generated by: LCOV version 2.0-1