LCOV - code coverage report
Current view: top level - zephyr/drivers - sdhc.h Coverage Total Hit
Test: new.info Lines: 83.0 % 94 78
Test Date: 2025-09-25 19:22:35

            Line data    Source code
       1            1 : /*
       2              :  * Copyright 2022 NXP
       3              :  *
       4              :  * SPDX-License-Identifier: Apache-2.0
       5              :  */
       6              : 
       7              : /**
       8              :  * @file
       9              :  * @ingroup sdhc_interface
      10              :  * @brief Main header file for SDHC (Secure Digital Host Controller) driver API.
      11              :  */
      12              : 
      13              : #ifndef ZEPHYR_INCLUDE_DRIVERS_SDHC_H_
      14              : #define ZEPHYR_INCLUDE_DRIVERS_SDHC_H_
      15              : 
      16              : #include <errno.h>
      17              : #include <zephyr/device.h>
      18              : #include <zephyr/sd/sd_spec.h>
      19              : 
      20              : /**
      21              :  * @brief Interfaces for Secure Digital Host Controllers (SDHC).
      22              :  * @defgroup sdhc_interface SDHC
      23              :  * @since 3.1
      24              :  * @version 0.1.0
      25              :  * @ingroup io_interfaces
      26              :  * @{
      27              :  */
      28              : 
      29              : #ifdef __cplusplus
      30              : extern "C" {
      31              : #endif
      32              : 
      33              : 
      34              : /**
      35              :  * @name SD command timeouts
      36              :  * @{
      37              :  */
      38            0 : #define SDHC_TIMEOUT_FOREVER (-1)
      39              : /** @} */
      40              : 
      41              : /**
      42              :  * @brief SD host controller command structure
      43              :  *
      44              :  * This command structure is used to send command requests to an SD
      45              :  * host controller, which will be sent to SD devices.
      46              :  */
      47            1 : struct sdhc_command {
      48            1 :         uint32_t opcode; /*!< SD Host specification CMD index */
      49            1 :         uint32_t arg; /*!< SD host specification argument */
      50            1 :         uint32_t response[4]; /*!< SD card response field */
      51            1 :         uint32_t response_type; /*!< Expected SD response type */
      52            1 :         unsigned int retries; /*!< Max number of retries */
      53            1 :         int timeout_ms; /*!< Command timeout in milliseconds */
      54              : };
      55              : 
      56            0 : #define SDHC_NATIVE_RESPONSE_MASK 0xF
      57            0 : #define SDHC_SPI_RESPONSE_TYPE_MASK 0xF0
      58              : 
      59              : /**
      60              :  * @brief SD host controller data structure
      61              :  *
      62              :  * This command structure is used to send data transfer requests to an SD
      63              :  * host controller, which will be sent to SD devices.
      64              :  */
      65            1 : struct sdhc_data {
      66            1 :         unsigned int block_addr; /*!< Block to start read from */
      67            1 :         unsigned int block_size; /*!< Block size */
      68            1 :         unsigned int blocks; /*!< Number of blocks */
      69            1 :         unsigned int bytes_xfered; /*!< populated with number of bytes sent by SDHC */
      70            1 :         void *data; /*!< Data to transfer or receive */
      71            1 :         int timeout_ms; /*!< data timeout in milliseconds */
      72              : };
      73              : 
      74              : /**
      75              :  * @brief SD bus mode.
      76              :  *
      77              :  * Most controllers will use push/pull, including spi, but
      78              :  * SDHC controllers that implement SD host specification can support open
      79              :  * drain mode
      80              :  */
      81            0 : enum sdhc_bus_mode {
      82              :         SDHC_BUSMODE_OPENDRAIN = 1,
      83              :         SDHC_BUSMODE_PUSHPULL = 2,
      84              : };
      85              : 
      86              : /**
      87              :  * @brief SD host controller power
      88              :  *
      89              :  * Many host controllers can control power to attached SD cards.
      90              :  * This enum allows applications to request the host controller power off
      91              :  * the SD card.
      92              :  */
      93            0 : enum sdhc_power {
      94              :         SDHC_POWER_OFF = 1,
      95              :         SDHC_POWER_ON = 2,
      96              : };
      97              : 
      98              : /**
      99              :  * @brief SD host controller bus width
     100              :  *
     101              :  * Only relevant in SD mode, SPI does not support bus width. UHS cards will
     102              :  * use 4 bit data bus, all cards start in 1 bit mode
     103              :  */
     104            0 : enum sdhc_bus_width {
     105              :         SDHC_BUS_WIDTH1BIT = 1U,
     106              :         SDHC_BUS_WIDTH4BIT = 4U,
     107              :         SDHC_BUS_WIDTH8BIT = 8U,
     108              : };
     109              : 
     110              : /**
     111              :  * @brief SD host controller timing mode
     112              :  *
     113              :  * Used by SD host controller to determine the timing of the cards attached
     114              :  * to the bus. Cards start with legacy timing, but UHS-II cards can go up to
     115              :  * SDR104.
     116              :  */
     117            1 : enum sdhc_timing_mode {
     118              :         SDHC_TIMING_LEGACY = 1U,
     119              :         /*!< Legacy 3.3V Mode */
     120              :         SDHC_TIMING_HS = 2U,
     121              :         /*!< Legacy High speed mode (3.3V) */
     122              :         SDHC_TIMING_SDR12 = 3U,
     123              :         /*!< Identification mode & SDR12 */
     124              :         SDHC_TIMING_SDR25 = 4U,
     125              :         /*!< High speed mode & SDR25 */
     126              :         SDHC_TIMING_SDR50 = 5U,
     127              :         /*!< SDR49 mode*/
     128              :         SDHC_TIMING_SDR104 = 6U,
     129              :         /*!< SDR104 mode */
     130              :         SDHC_TIMING_DDR50 = 7U,
     131              :         /*!< DDR50 mode */
     132              :         SDHC_TIMING_DDR52 = 8U,
     133              :         /*!< DDR52 mode */
     134              :         SDHC_TIMING_HS200 = 9U,
     135              :         /*!< HS200 mode */
     136              :         SDHC_TIMING_HS400 = 10U,
     137              :         /*!< HS400 mode */
     138              : };
     139              : 
     140              : /**
     141              :  * @brief SD voltage
     142              :  *
     143              :  * UHS cards can run with 1.8V signalling for improved power consumption. Legacy
     144              :  * cards may support 3.0V signalling, and all cards start at 3.3V.
     145              :  * Only relevant for SD controllers, not SPI ones.
     146              :  */
     147            1 : enum sd_voltage {
     148              :         SD_VOL_3_3_V = 1U,
     149              :         /*!< card operation voltage around 3.3v */
     150              :         SD_VOL_3_0_V = 2U,
     151              :         /*!< card operation voltage around 3.0v */
     152              :         SD_VOL_1_8_V = 3U,
     153              :         /*!< card operation voltage around 1.8v */
     154              :         SD_VOL_1_2_V = 4U,
     155              :         /*!< card operation voltage around 1.2v */
     156              : };
     157              : 
     158              : /**
     159              :  * @brief SD host controller capabilities
     160              :  *
     161              :  * SD host controller capability flags. These flags should be set by the SDHC
     162              :  * driver, using the @ref sdhc_get_host_props api.
     163              :  */
     164            1 : struct sdhc_host_caps {
     165            1 :         unsigned int timeout_clk_freq: 5;               /**< Timeout clock frequency */
     166              :         unsigned int _rsvd_6: 1;                        /**< Reserved */
     167            1 :         unsigned int timeout_clk_unit: 1;               /**< Timeout clock unit */
     168            1 :         unsigned int sd_base_clk: 8;                    /**< SD base clock frequency */
     169            1 :         unsigned int max_blk_len: 2;                    /**< Max block length */
     170            1 :         unsigned int bus_8_bit_support: 1;              /**< 8-bit Support for embedded device */
     171            1 :         unsigned int bus_4_bit_support: 1;              /**< 4 bit bus support */
     172            1 :         unsigned int adma_2_support: 1;                 /**< ADMA2 support */
     173              :         unsigned int _rsvd_20: 1;                       /**< Reserved */
     174            1 :         unsigned int high_spd_support: 1;               /**< High speed support */
     175            1 :         unsigned int sdma_support: 1;                   /**< SDMA support */
     176            1 :         unsigned int suspend_res_support: 1;            /**< Suspend/Resume support */
     177            1 :         unsigned int vol_330_support: 1;                /**< Voltage support 3.3V */
     178            1 :         unsigned int vol_300_support: 1;                /**< Voltage support 3.0V */
     179            1 :         unsigned int vol_180_support: 1;                /**< Voltage support 1.8V */
     180            1 :         unsigned int address_64_bit_support_v4: 1;      /**< 64-bit system address support for V4 */
     181            1 :         unsigned int address_64_bit_support_v3: 1;      /**< 64-bit system address support for V3 */
     182            1 :         unsigned int sdio_async_interrupt_support: 1;   /**< Asynchronous interrupt support */
     183            1 :         unsigned int slot_type: 2;                      /**< Slot type */
     184            1 :         unsigned int sdr50_support: 1;                  /**< SDR50 support */
     185            1 :         unsigned int sdr104_support: 1;                 /**< SDR104 support */
     186            1 :         unsigned int ddr50_support: 1;                  /**< DDR50 support */
     187            1 :         unsigned int uhs_2_support: 1;                  /**< UHS-II support */
     188            1 :         unsigned int drv_type_a_support: 1;             /**< Driver type A support */
     189            1 :         unsigned int drv_type_c_support: 1;             /**< Driver type C support */
     190            1 :         unsigned int drv_type_d_support: 1;             /**< Driver type D support */
     191              :         unsigned int _rsvd_39: 1;                       /**< Reserved */
     192            1 :         unsigned int retune_timer_count: 4;             /**< Timer count for re-tuning */
     193            1 :         unsigned int sdr50_needs_tuning: 1;             /**< Use tuning for SDR50 */
     194            1 :         unsigned int retuning_mode: 2;                  /**< Re-tuning mode */
     195            1 :         unsigned int clk_multiplier: 8;                 /**< Clock multiplier */
     196              :         unsigned int _rsvd_56: 3;                       /**< Reserved */
     197            1 :         unsigned int adma3_support: 1;                  /**< ADMA3 support */
     198            1 :         unsigned int vdd2_180_support: 1;               /**< 1.8V VDD2 support */
     199              :         unsigned int _rsvd_61: 3;                       /**< Reserved */
     200            1 :         unsigned int hs200_support: 1;                  /**< HS200 support */
     201            1 :         unsigned int hs400_support: 1;                  /**< HS400 support */
     202              : };
     203              : 
     204              : /**
     205              :  * @brief SD host controller I/O control structure
     206              :  *
     207              :  * Controls I/O settings for the SDHC. Note that only a subset of these settings
     208              :  * apply to host controllers in SPI mode. Populate this struct, then call
     209              :  * @ref sdhc_set_io to apply I/O settings
     210              :  */
     211            1 : struct sdhc_io {
     212            1 :         enum sdhc_clock_speed clock; /*!< Clock rate */
     213            1 :         enum sdhc_bus_mode bus_mode; /*!< command output mode */
     214            1 :         enum sdhc_power power_mode; /*!< SD power supply mode */
     215            1 :         enum sdhc_bus_width bus_width; /*!< SD bus width */
     216            1 :         enum sdhc_timing_mode timing; /*!< SD bus timing */
     217            1 :         enum sd_driver_type driver_type; /*!< SD driver type */
     218            1 :         enum sd_voltage signal_voltage; /*!< IO signalling voltage (usually 1.8 or 3.3V) */
     219              : };
     220              : 
     221              : /**
     222              :  * @brief SD host controller properties
     223              :  *
     224              :  * Populated by the host controller using @ref sdhc_get_host_props api.
     225              :  */
     226            1 : struct sdhc_host_props {
     227            1 :         unsigned int f_max; /*!< Max bus frequency */
     228            1 :         unsigned int f_min; /*!< Min bus frequency */
     229            1 :         unsigned int power_delay; /*!< Delay to allow SD to power up or down (in ms) */
     230            1 :         struct sdhc_host_caps host_caps; /*!< Host capability bitfield */
     231            1 :         uint32_t max_current_330; /*!< Max current (in mA) at 3.3V */
     232            1 :         uint32_t max_current_300; /*!< Max current (in mA) at 3.0V */
     233            1 :         uint32_t max_current_180; /*!< Max current (in mA) at 1.8V */
     234            1 :         bool is_spi; /*!< Is the host using SPI mode */
     235              : };
     236              : 
     237              : /**
     238              :  * @brief SD host controller interrupt sources
     239              :  *
     240              :  * Interrupt sources for SD host controller.
     241              :  */
     242            1 : enum sdhc_interrupt_source {
     243              :         SDHC_INT_SDIO = BIT(0), /*!< Card interrupt, used by SDIO cards */
     244              :         SDHC_INT_INSERTED = BIT(1), /*!< Card was inserted into slot */
     245              :         SDHC_INT_REMOVED = BIT(2), /*!< Card was removed from slot */
     246              : };
     247              : 
     248              : /**
     249              :  * @typedef sdhc_interrupt_cb_t
     250              :  * @brief SDHC card interrupt callback prototype
     251              :  *
     252              :  * Function prototype for SDHC card interrupt callback.
     253              :  * @param dev: SDHC device that produced interrupt
     254              :  * @param reason: one of @ref sdhc_interrupt_source values.
     255              :  * @param user_data: User data, set via @ref sdhc_enable_interrupt
     256              :  */
     257            1 : typedef void (*sdhc_interrupt_cb_t)(const struct device *dev, int reason,
     258              :                                     const void *user_data);
     259              : 
     260            0 : __subsystem struct sdhc_driver_api {
     261            0 :         int (*reset)(const struct device *dev);
     262            0 :         int (*request)(const struct device *dev,
     263              :                        struct sdhc_command *cmd,
     264              :                        struct sdhc_data *data);
     265            0 :         int (*set_io)(const struct device *dev, struct sdhc_io *ios);
     266            0 :         int (*get_card_present)(const struct device *dev);
     267            0 :         int (*execute_tuning)(const struct device *dev);
     268            0 :         int (*card_busy)(const struct device *dev);
     269            0 :         int (*get_host_props)(const struct device *dev,
     270              :                               struct sdhc_host_props *props);
     271            0 :         int (*enable_interrupt)(const struct device *dev,
     272              :                                 sdhc_interrupt_cb_t callback,
     273              :                                 int sources, void *user_data);
     274            0 :         int (*disable_interrupt)(const struct device *dev, int sources);
     275              : };
     276              : 
     277              : /**
     278              :  * @brief reset SDHC controller state
     279              :  *
     280              :  * Used when the SDHC has encountered an error. Resetting the SDHC controller
     281              :  * should clear all errors on the SDHC, but does not necessarily reset I/O
     282              :  * settings to boot (this can be done with @ref sdhc_set_io)
     283              :  *
     284              :  * @param dev: SD host controller device
     285              :  * @retval 0 reset succeeded
     286              :  * @retval -ETIMEDOUT: controller reset timed out
     287              :  * @retval -EIO: reset failed
     288              :  */
     289            1 : __syscall int sdhc_hw_reset(const struct device *dev);
     290              : 
     291              : static inline int z_impl_sdhc_hw_reset(const struct device *dev)
     292              : {
     293              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     294              : 
     295              :         if (!api->reset) {
     296              :                 return -ENOSYS;
     297              :         }
     298              : 
     299              :         return api->reset(dev);
     300              : }
     301              : 
     302              : 
     303              : /**
     304              :  * @brief Send command to SDHC
     305              :  *
     306              :  * Sends a command to the SD host controller, which will send this command to
     307              :  * attached SD cards.
     308              :  * @param dev: SDHC device
     309              :  * @param cmd: SDHC command
     310              :  * @param data: SDHC data. Leave NULL to send SD command without data.
     311              :  * @retval 0 command was sent successfully
     312              :  * @retval -ETIMEDOUT command timed out while sending
     313              :  * @retval -ENOTSUP host controller does not support command
     314              :  * @retval -EIO: I/O error
     315              :  */
     316            1 : __syscall int sdhc_request(const struct device *dev, struct sdhc_command *cmd,
     317              :                            struct sdhc_data *data);
     318              : 
     319              : static inline int z_impl_sdhc_request(const struct device *dev,
     320              :                                       struct sdhc_command *cmd,
     321              :                                       struct sdhc_data *data)
     322              : {
     323              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     324              : 
     325              :         if (!api->request) {
     326              :                 return -ENOSYS;
     327              :         }
     328              : 
     329              :         return api->request(dev, cmd, data);
     330              : }
     331              : 
     332              : /**
     333              :  * @brief set I/O properties of SDHC
     334              :  *
     335              :  * I/O properties should be reconfigured when the card has been sent a command
     336              :  * to change its own SD settings. This function can also be used to toggle
     337              :  * power to the SD card.
     338              :  * @param dev: SDHC device
     339              :  * @param io: I/O properties
     340              :  * @return 0 I/O was configured correctly
     341              :  * @return -ENOTSUP controller does not support these I/O settings
     342              :  * @return -EIO controller could not configure I/O settings
     343              :  */
     344            1 : __syscall int sdhc_set_io(const struct device *dev, struct sdhc_io *io);
     345              : 
     346              : static inline int z_impl_sdhc_set_io(const struct device *dev,
     347              :                                      struct sdhc_io *io)
     348              : {
     349              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     350              : 
     351              :         if (!api->set_io) {
     352              :                 return -ENOSYS;
     353              :         }
     354              : 
     355              :         return api->set_io(dev, io);
     356              : }
     357              : 
     358              : /**
     359              :  * @brief check for SDHC card presence
     360              :  *
     361              :  * Checks if card is present on the SD bus. Note that if a controller
     362              :  * requires cards be powered up to detect presence, it should do so in
     363              :  * this function.
     364              :  * @param dev: SDHC device
     365              :  * @retval 1 card is present
     366              :  * @retval 0 card is not present
     367              :  * @retval -EIO I/O error
     368              :  */
     369            1 : __syscall int sdhc_card_present(const struct device *dev);
     370              : 
     371              : static inline int z_impl_sdhc_card_present(const struct device *dev)
     372              : {
     373              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     374              : 
     375              :         if (!api->get_card_present) {
     376              :                 return -ENOSYS;
     377              :         }
     378              : 
     379              :         return api->get_card_present(dev);
     380              : }
     381              : 
     382              : 
     383              : /**
     384              :  * @brief run SDHC tuning
     385              :  *
     386              :  * SD cards require signal tuning for UHS modes SDR104 and SDR50. This function
     387              :  * allows an application to request the SD host controller to tune the card.
     388              :  * @param dev: SDHC device
     389              :  * @retval 0 tuning succeeded, card is ready for commands
     390              :  * @retval -ETIMEDOUT: tuning failed after timeout
     391              :  * @retval -ENOTSUP: controller does not support tuning
     392              :  * @retval -EIO: I/O error while tuning
     393              :  */
     394            1 : __syscall int sdhc_execute_tuning(const struct device *dev);
     395              : 
     396              : static inline int z_impl_sdhc_execute_tuning(const struct device *dev)
     397              : {
     398              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     399              : 
     400              :         if (!api->execute_tuning) {
     401              :                 return -ENOSYS;
     402              :         }
     403              : 
     404              :         return api->execute_tuning(dev);
     405              : }
     406              : 
     407              : /**
     408              :  * @brief check if SD card is busy
     409              :  *
     410              :  * This check should generally be implemented as checking the line level of the
     411              :  * DAT[0:3] lines of the SD bus. No SD commands need to be sent, the controller
     412              :  * simply needs to report the status of the SD bus.
     413              :  * @param dev: SDHC device
     414              :  * @retval 0 card is not busy
     415              :  * @retval 1 card is busy
     416              :  * @retval -EIO I/O error
     417              :  */
     418            1 : __syscall int sdhc_card_busy(const struct device *dev);
     419              : 
     420              : static inline int z_impl_sdhc_card_busy(const struct device *dev)
     421              : {
     422              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     423              : 
     424              :         if (!api->card_busy) {
     425              :                 return -ENOSYS;
     426              :         }
     427              : 
     428              :         return api->card_busy(dev);
     429              : }
     430              : 
     431              : 
     432              : /**
     433              :  * @brief Get SD host controller properties
     434              :  *
     435              :  * Gets host properties from the host controller. Host controller should
     436              :  * initialize all values in the @ref sdhc_host_props structure provided.
     437              :  * @param dev: SDHC device
     438              :  * @param props property structure to be filled by sdhc driver
     439              :  * @retval 0 function succeeded.
     440              :  * @retval -ENOTSUP host controller does not support this call
     441              :  */
     442            1 : __syscall int sdhc_get_host_props(const struct device *dev,
     443              :                                   struct sdhc_host_props *props);
     444              : 
     445              : static inline int z_impl_sdhc_get_host_props(const struct device *dev,
     446              :                                              struct sdhc_host_props *props)
     447              : {
     448              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     449              : 
     450              :         if (!api->get_host_props) {
     451              :                 return -ENOSYS;
     452              :         }
     453              : 
     454              :         return api->get_host_props(dev, props);
     455              : }
     456              : 
     457              : /**
     458              :  * @brief Enable SDHC interrupt sources.
     459              :  *
     460              :  * Enables SDHC interrupt sources. Each subsequent call of this function
     461              :  * should replace the previous callback set, and leave only the interrupts
     462              :  * specified in the "sources" argument enabled.
     463              :  * @param dev: SDHC device
     464              :  * @param callback: Callback called when interrupt occurs
     465              :  * @param sources: bitmask of @ref sdhc_interrupt_source values
     466              :  *        indicating which interrupts should produce a callback
     467              :  * @param user_data: parameter that will be passed to callback function
     468              :  * @retval 0 interrupts were enabled, and callback was installed
     469              :  * @retval -ENOTSUP: controller does not support this function
     470              :  * @retval -EIO: I/O error
     471              :  */
     472            1 : __syscall int sdhc_enable_interrupt(const struct device *dev,
     473              :                                     sdhc_interrupt_cb_t callback,
     474              :                                     int sources, void *user_data);
     475              : 
     476              : static inline int z_impl_sdhc_enable_interrupt(const struct device *dev,
     477              :                                                sdhc_interrupt_cb_t callback,
     478              :                                                int sources, void *user_data)
     479              : {
     480              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     481              : 
     482              :         if (!api->enable_interrupt) {
     483              :                 return -ENOSYS;
     484              :         }
     485              : 
     486              :         return api->enable_interrupt(dev, callback, sources, user_data);
     487              : }
     488              : 
     489              : /**
     490              :  * @brief Disable SDHC interrupt sources
     491              :  *
     492              :  * Disables SDHC interrupt sources. If multiple sources are enabled, only
     493              :  * the ones specified in "sources" will be masked.
     494              :  * @param dev: SDHC device
     495              :  * @param sources: bitmask of @ref sdhc_interrupt_source values
     496              :  *        indicating which interrupts should be disabled.
     497              :  * @retval 0 interrupts were disabled
     498              :  * @retval -ENOTSUP: controller does not support this function
     499              :  * @retval -EIO: I/O error
     500              :  */
     501            1 : __syscall int sdhc_disable_interrupt(const struct device *dev, int sources);
     502              : 
     503              : static inline int z_impl_sdhc_disable_interrupt(const struct device *dev,
     504              :                                                 int sources)
     505              : {
     506              :         const struct sdhc_driver_api *api = (const struct sdhc_driver_api *)dev->api;
     507              : 
     508              :         if (!api->disable_interrupt) {
     509              :                 return -ENOSYS;
     510              :         }
     511              : 
     512              :         return api->disable_interrupt(dev, sources);
     513              : }
     514              : 
     515              : /**
     516              :  * @}
     517              :  */
     518              : 
     519              : #ifdef __cplusplus
     520              : }
     521              : #endif
     522              : 
     523              : #include <zephyr/syscalls/sdhc.h>
     524              : #endif /* ZEPHYR_INCLUDE_DRIVERS_SDHC_H_ */
        

Generated by: LCOV version 2.0-1