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-05 16:43:28

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

Generated by: LCOV version 2.0-1