drivers: USDHC: Enable detection using DAT3 pulldown
Enable USDHC host to detect inserted SD card via DAT3 line pulldown. Signed-off-by: Daniel DeGrasse <daniel.degrasse@nxp.com>
This commit is contained in:
parent
4712913872
commit
57f35bbf5a
7 changed files with 125 additions and 2 deletions
|
@ -41,6 +41,10 @@ config SDMMC_USDHC
|
|||
File system on a SDHC card accessed over
|
||||
NXP USDHC.
|
||||
|
||||
if SDMMC_USDHC
|
||||
source "drivers/disk/Kconfig.usdhc"
|
||||
endif
|
||||
|
||||
config SDMMC_STM32
|
||||
bool "STM32 SDMMC driver"
|
||||
depends on HAS_STM32CUBE
|
||||
|
|
18
drivers/disk/Kconfig.usdhc
Normal file
18
drivers/disk/Kconfig.usdhc
Normal file
|
@ -0,0 +1,18 @@
|
|||
# Copyright (c) 2021 NXP
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
# USDHC peripheral require the SD card to power cycle after DAT3 is
|
||||
# pulled low
|
||||
config SDMMC_USDHC_DAT3_PWR_TOGGLE
|
||||
bool
|
||||
help
|
||||
USDHC peripheral requires the SD card power to be cycled after DAT3 is
|
||||
pulled high, before the USDHC peripheral can detect the SD card via DAT3
|
||||
pull
|
||||
|
||||
config SDMMC_USDHC_DAT3_PWR_DELAY
|
||||
int
|
||||
default 0
|
||||
help
|
||||
Period in milliseconds to delay between powering off the SD card and
|
||||
applying power again, whenever the SD card power will be cycled.
|
|
@ -388,6 +388,8 @@ struct usdhc_config {
|
|||
uint8_t detect_pin;
|
||||
gpio_dt_flags_t detect_flags;
|
||||
|
||||
bool detect_dat3;
|
||||
|
||||
bool no_1_8_v;
|
||||
|
||||
uint32_t data_timeout;
|
||||
|
@ -515,6 +517,9 @@ enum usdhc_xfer_data_type {
|
|||
#define CARD_BUS_STRENGTH_6 (6U)
|
||||
#define CARD_BUS_STRENGTH_7 (7U)
|
||||
|
||||
#define USDHC_DAT3_PULL_DOWN 0U /*!< Data 3 pull down */
|
||||
#define USDHC_DAT3_PULL_UP 1U /*!< Data 3 pull up */
|
||||
|
||||
enum usdhc_adma_flag {
|
||||
USDHC_ADMA_SINGLE_FLAG = 0U,
|
||||
USDHC_ADMA_MUTI_FLAG = 1U,
|
||||
|
@ -2604,6 +2609,33 @@ APP_SEND_OP_COND_AGAIN:
|
|||
|
||||
static K_MUTEX_DEFINE(z_usdhc_init_lock);
|
||||
|
||||
|
||||
static int usdhc_dat3_pull(bool pullup, struct usdhc_priv *priv)
|
||||
{
|
||||
int ret = 0U;
|
||||
|
||||
/* Call board specific function to pull down DAT3 */
|
||||
imxrt_usdhc_dat3_pull(pullup);
|
||||
#ifdef CONFIG_SDMMC_USDHC_DAT3_PWR_TOGGLE
|
||||
if (!pullup) {
|
||||
/* Power off the card to clear DAT3 legacy status */
|
||||
if (priv->pwr_gpio) {
|
||||
ret = gpio_pin_set(priv->pwr_gpio, priv->config->pwr_pin, 0);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
/* Delay for card power off to complete */
|
||||
usdhc_millsec_delay(CONFIG_SDMMC_USDHC_DAT3_PWR_DELAY);
|
||||
ret = gpio_pin_set(priv->pwr_gpio, priv->config->pwr_pin, 1);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int usdhc_board_access_init(struct usdhc_priv *priv)
|
||||
{
|
||||
const struct usdhc_config *config = priv->config;
|
||||
|
@ -2626,6 +2658,11 @@ static int usdhc_board_access_init(struct usdhc_priv *priv)
|
|||
}
|
||||
}
|
||||
|
||||
if (config->detect_dat3) {
|
||||
priv->detect_type = SD_DETECT_HOST_DATA3;
|
||||
}
|
||||
|
||||
|
||||
if (priv->pwr_gpio) {
|
||||
ret = gpio_pin_configure(priv->pwr_gpio,
|
||||
config->pwr_pin,
|
||||
|
@ -2643,10 +2680,21 @@ static int usdhc_board_access_init(struct usdhc_priv *priv)
|
|||
|
||||
if (!priv->detect_gpio) {
|
||||
LOG_INF("USDHC detection other than GPIO");
|
||||
/* DATA3 does not monitor card insertion */
|
||||
base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
|
||||
if (config->detect_dat3) {
|
||||
base->PROT_CTRL |= USDHC_PROT_CTRL_D3CD_MASK;
|
||||
/* Pull down DAT3 */
|
||||
usdhc_dat3_pull(USDHC_DAT3_PULL_DOWN, priv);
|
||||
} else {
|
||||
/* DATA3 does not monitor card insertion */
|
||||
base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
|
||||
}
|
||||
if ((base->PRES_STATE & USDHC_PRES_STATE_CINST_MASK) != 0) {
|
||||
priv->inserted = true;
|
||||
if (config->detect_dat3) {
|
||||
usdhc_dat3_pull(USDHC_DAT3_PULL_UP, priv);
|
||||
/* Disable DAT3 detect function */
|
||||
base->PROT_CTRL &= ~USDHC_PROT_CTRL_D3CD_MASK;
|
||||
}
|
||||
} else {
|
||||
priv->inserted = false;
|
||||
return -ENODEV;
|
||||
|
@ -2853,6 +2901,7 @@ static int disk_usdhc_init(const struct device *dev)
|
|||
DISK_ACCESS_USDHC_INIT_PWR(n) \
|
||||
DISK_ACCESS_USDHC_INIT_CD(n) \
|
||||
.no_1_8_v = DT_INST_PROP(n, no_1_8_v), \
|
||||
.detect_dat3 = DT_INST_PROP(n, detect_dat3), \
|
||||
.data_timeout = USDHC_DATA_TIMEOUT, \
|
||||
.endian = USDHC_LITTLE_ENDIAN, \
|
||||
.read_watermark = USDHC_READ_WATERMARK_LEVEL, \
|
||||
|
|
|
@ -36,5 +36,13 @@ properties:
|
|||
When the external SD card circuit does not support 1.8V, add this
|
||||
property to disable 1.8v card voltage of SD card controller.
|
||||
|
||||
detect-dat3:
|
||||
type: boolean
|
||||
required: false
|
||||
description: |
|
||||
Enable the host to detect an SD card via the DAT3 line of the SD card
|
||||
connection. Requires the board to define a function to pull DAT3 low or
|
||||
high using pullup/pulldown resistors.
|
||||
|
||||
label:
|
||||
required: true
|
||||
|
|
|
@ -32,6 +32,12 @@ void imxrt_usdhc_pinmux(uint16_t nusdhc,
|
|||
|
||||
void imxrt_usdhc_pinmux_cb_register(usdhc_pin_cfg_cb cb);
|
||||
|
||||
typedef void (*usdhc_dat3_cfg_cb)(bool pullup);
|
||||
|
||||
void imxrt_usdhc_dat3_cb_register(usdhc_dat3_cfg_cb cb);
|
||||
|
||||
void imxrt_usdhc_dat3_pull(bool pullup);
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -261,6 +261,25 @@ void imxrt_usdhc_pinmux(uint16_t nusdhc, bool init,
|
|||
g_usdhc_pin_cfg_cb(nusdhc, init,
|
||||
speed, strength);
|
||||
}
|
||||
|
||||
/* Usdhc driver needs to reconfigure the dat3 line to a pullup in order to
|
||||
* detect an SD card on the bus. Expose a callback to do that here. The board
|
||||
* must register this callback in its init function.
|
||||
*/
|
||||
static usdhc_dat3_cfg_cb g_usdhc_dat3_cfg_cb;
|
||||
|
||||
void imxrt_usdhc_dat3_cb_register(usdhc_dat3_cfg_cb cb)
|
||||
{
|
||||
g_usdhc_dat3_cfg_cb = cb;
|
||||
}
|
||||
|
||||
void imxrt_usdhc_dat3_pull(bool pullup)
|
||||
{
|
||||
if (g_usdhc_dat3_cfg_cb) {
|
||||
g_usdhc_dat3_cfg_cb(pullup);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
|
@ -426,6 +426,25 @@ void imxrt_usdhc_pinmux(uint16_t nusdhc, bool init,
|
|||
g_usdhc_pin_cfg_cb(nusdhc, init,
|
||||
speed, strength);
|
||||
}
|
||||
|
||||
/* Usdhc driver needs to reconfigure the dat3 line to a pullup in order to
|
||||
* detect an SD card on the bus. Expose a callback to do that here. The board
|
||||
* must register this callback in its init function.
|
||||
*/
|
||||
static usdhc_dat3_cfg_cb g_usdhc_dat3_cfg_cb;
|
||||
|
||||
void imxrt_usdhc_dat3_cb_register(usdhc_dat3_cfg_cb cb)
|
||||
{
|
||||
g_usdhc_dat3_cfg_cb = cb;
|
||||
}
|
||||
|
||||
void imxrt_usdhc_dat3_pull(bool pullup)
|
||||
{
|
||||
if (g_usdhc_dat3_cfg_cb) {
|
||||
g_usdhc_dat3_cfg_cb(pullup);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue