drivers: sdhc: imx_usdhc: enable MMIO mapping

Enable MMIO mapping in the driver.

Signed-off-by: Jiafei Pan <Jiafei.Pan@nxp.com>
This commit is contained in:
Jiafei Pan 2025-03-21 15:30:38 +08:00 committed by Benjamin Cabé
commit 51e0fcf80c

View file

@ -43,6 +43,9 @@ enum transfer_callback_status {
/* Default transfer timeout in ms for tuning */
#define IMX_USDHC_DEFAULT_TIMEOUT (5000U)
#define DEV_CFG(_dev) ((const struct usdhc_config *)(_dev)->config)
#define DEV_DATA(_dev) ((struct usdhc_data *)(_dev)->data)
struct usdhc_host_transfer {
usdhc_transfer_t *transfer;
k_timeout_t command_timeout;
@ -50,7 +53,8 @@ struct usdhc_host_transfer {
};
struct usdhc_config {
USDHC_Type *base;
DEVICE_MMIO_NAMED_ROM(usdhc_mmio);
const struct device *clock_dev;
clock_control_subsys_t clock_subsys;
uint8_t nusdhc;
@ -75,6 +79,8 @@ struct usdhc_config {
};
struct usdhc_data {
DEVICE_MMIO_NAMED_RAM(usdhc_mmio);
const struct device *dev;
struct sdhc_host_props props;
bool card_present;
@ -93,6 +99,11 @@ struct usdhc_data {
#endif
};
static USDHC_Type *get_base(const struct device *dev)
{
return (USDHC_Type *)DEVICE_MMIO_NAMED_GET(dev, usdhc_mmio);
}
static void transfer_complete_cb(USDHC_Type *usdhc, usdhc_handle_t *handle, status_t status,
void *user_data)
{
@ -200,17 +211,17 @@ static int imx_usdhc_dat3_pull(const struct usdhc_config *cfg, bool pullup)
*/
static void imx_usdhc_error_recovery(const struct device *dev)
{
const struct usdhc_config *cfg = dev->config;
uint32_t status = USDHC_GetPresentStatusFlags(cfg->base);
USDHC_Type *base = get_base(dev);
uint32_t status = USDHC_GetPresentStatusFlags(base);
if (status & kUSDHC_CommandInhibitFlag) {
/* Reset command line */
USDHC_Reset(cfg->base, kUSDHC_ResetCommand, 100U);
USDHC_Reset(base, kUSDHC_ResetCommand, 100U);
}
if (((status & (uint32_t)kUSDHC_DataInhibitFlag) != 0U) ||
(USDHC_GetAdmaErrorStatusFlags(cfg->base) != 0U)) {
(USDHC_GetAdmaErrorStatusFlags(base) != 0U)) {
/* Reset data line */
USDHC_Reset(cfg->base, kUSDHC_DataInhibitFlag, 100U);
USDHC_Reset(base, kUSDHC_DataInhibitFlag, 100U);
}
}
@ -223,6 +234,7 @@ static void imx_usdhc_init_host_props(const struct device *dev)
struct usdhc_data *data = dev->data;
usdhc_capability_t caps;
struct sdhc_host_props *props = &data->props;
USDHC_Type *base = get_base(dev);
memset(props, 0, sizeof(struct sdhc_host_props));
props->f_max = cfg->max_bus_freq;
@ -231,7 +243,7 @@ static void imx_usdhc_init_host_props(const struct device *dev)
props->max_current_180 = cfg->max_current_180;
props->power_delay = cfg->power_delay_ms;
/* Read host capabilities */
USDHC_GetCapability(cfg->base, &caps);
USDHC_GetCapability(base, &caps);
if (cfg->no_180_vol) {
props->host_caps.vol_180_support = false;
} else {
@ -258,24 +270,25 @@ static void imx_usdhc_init_host_props(const struct device *dev)
*/
static int imx_usdhc_reset(const struct device *dev)
{
const struct usdhc_config *cfg = dev->config;
USDHC_Type *base = get_base(dev);
/* Switch to default I/O voltage of 3.3V */
imx_usdhc_select_1_8v(cfg->base, false);
USDHC_EnableDDRMode(cfg->base, false, 0U);
imx_usdhc_select_1_8v(base, false);
USDHC_EnableDDRMode(base, false, 0U);
#if defined(FSL_FEATURE_USDHC_HAS_SDR50_MODE) && (FSL_FEATURE_USDHC_HAS_SDR50_MODE)
USDHC_EnableStandardTuning(cfg->base, 0, 0, false);
USDHC_EnableAutoTuning(cfg->base, false);
USDHC_EnableStandardTuning(base, 0, 0, false);
USDHC_EnableAutoTuning(base, false);
#endif
#if FSL_FEATURE_USDHC_HAS_HS400_MODE
/* Disable HS400 mode */
USDHC_EnableHS400Mode(cfg->base, false);
USDHC_EnableHS400Mode(base, false);
/* Disable DLL */
USDHC_EnableStrobeDLL(cfg->base, false);
USDHC_EnableStrobeDLL(base, false);
#endif
/* Reset data/command/tuning circuit */
return USDHC_Reset(cfg->base, kUSDHC_ResetAll, 1000U) == true ? 0 : -ETIMEDOUT;
return USDHC_Reset(base, kUSDHC_ResetAll, 1000U) == true ? 0 : -ETIMEDOUT;
}
/*
@ -287,6 +300,7 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
struct usdhc_data *data = dev->data;
uint32_t src_clk_hz, bus_clk;
struct sdhc_io *host_io = &data->host_io;
USDHC_Type *base = get_base(dev);
LOG_DBG("SDHC I/O: bus width %d, clock %dHz, card power %s, voltage %s", ios->bus_width,
ios->clock, ios->power_mode == SDHC_POWER_ON ? "ON" : "OFF",
@ -304,7 +318,7 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
if (host_io->clock != ios->clock) {
if (ios->clock != 0) {
/* Enable the clock output */
bus_clk = USDHC_SetSdClock(cfg->base, src_clk_hz, ios->clock);
bus_clk = USDHC_SetSdClock(base, src_clk_hz, ios->clock);
LOG_DBG("BUS CLOCK: %d", bus_clk);
if (bus_clk == 0) {
return -ENOTSUP;
@ -317,13 +331,13 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
if (host_io->bus_width != ios->bus_width) {
switch (ios->bus_width) {
case SDHC_BUS_WIDTH1BIT:
USDHC_SetDataBusWidth(cfg->base, kUSDHC_DataBusWidth1Bit);
USDHC_SetDataBusWidth(base, kUSDHC_DataBusWidth1Bit);
break;
case SDHC_BUS_WIDTH4BIT:
USDHC_SetDataBusWidth(cfg->base, kUSDHC_DataBusWidth4Bit);
USDHC_SetDataBusWidth(base, kUSDHC_DataBusWidth4Bit);
break;
case SDHC_BUS_WIDTH8BIT:
USDHC_SetDataBusWidth(cfg->base, kUSDHC_DataBusWidth8Bit);
USDHC_SetDataBusWidth(base, kUSDHC_DataBusWidth8Bit);
break;
default:
return -ENOTSUP;
@ -336,7 +350,7 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
switch (ios->signal_voltage) {
case SD_VOL_3_3_V:
case SD_VOL_3_0_V:
imx_usdhc_select_1_8v(cfg->base, false);
imx_usdhc_select_1_8v(base, false);
break;
case SD_VOL_1_8_V:
/**
@ -350,15 +364,15 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
* 10 ms, then allow it to be gated again.
*/
/* Switch to 1.8V */
imx_usdhc_select_1_8v(cfg->base, true);
imx_usdhc_select_1_8v(base, true);
/* Wait 10 ms- clock will be gated during this period */
k_msleep(10);
/* Force the clock on */
USDHC_ForceClockOn(cfg->base, true);
USDHC_ForceClockOn(base, true);
/* Keep the clock on for a moment, so SD will recognize it */
k_msleep(10);
/* Stop forcing clock on */
USDHC_ForceClockOn(cfg->base, false);
USDHC_ForceClockOn(base, false);
break;
default:
return -ENOTSUP;
@ -386,7 +400,7 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
case SDHC_TIMING_DDR50:
case SDHC_TIMING_DDR52:
/* Enable DDR mode */
USDHC_EnableDDRMode(cfg->base, true, 0);
USDHC_EnableDDRMode(base, true, 0);
__fallthrough;
case SDHC_TIMING_SDR12:
case SDHC_TIMING_SDR25:
@ -397,10 +411,10 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
break;
case SDHC_TIMING_HS400:
#if FSL_FEATURE_USDHC_HAS_HS400_MODE
USDHC_EnableHS400Mode(cfg->base, true);
USDHC_EnableDDRMode(cfg->base, true, 0U);
USDHC_ConfigStrobeDLL(cfg->base, 7U, 4U);
USDHC_EnableStrobeDLL(cfg->base, true);
USDHC_EnableHS400Mode(base, true);
USDHC_EnableDDRMode(base, true, 0U);
USDHC_ConfigStrobeDLL(base, 7U, 4U);
USDHC_EnableStrobeDLL(base, true);
#else
LOG_ERR("HS400 not supported for this device");
return -ENOTSUP;
@ -423,9 +437,9 @@ static int imx_usdhc_set_io(const struct device *dev, struct sdhc_io *ios)
*/
static int imx_usdhc_transfer(const struct device *dev, struct usdhc_host_transfer *request)
{
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *dev_data = dev->data;
status_t error;
USDHC_Type *base = get_base(dev);
#ifdef CONFIG_IMX_USDHC_DMA_SUPPORT
usdhc_adma_config_t dma_config = {0};
@ -443,10 +457,10 @@ static int imx_usdhc_transfer(const struct device *dev, struct usdhc_host_transf
/* Reset semaphore */
k_sem_reset(&dev_data->transfer_sem);
#ifdef CONFIG_IMX_USDHC_DMA_SUPPORT
error = USDHC_TransferNonBlocking(cfg->base, &dev_data->transfer_handle, &dma_config,
error = USDHC_TransferNonBlocking(base, &dev_data->transfer_handle, &dma_config,
request->transfer);
#else
error = USDHC_TransferNonBlocking(cfg->base, &dev_data->transfer_handle, NULL,
error = USDHC_TransferNonBlocking(base, &dev_data->transfer_handle, NULL,
request->transfer);
#endif
if (error == kStatus_USDHC_ReTuningRequest) {
@ -504,9 +518,9 @@ static void imx_usdhc_stop_transmission(const struct device *dev)
*/
static int imx_usdhc_card_busy(const struct device *dev)
{
const struct usdhc_config *cfg = dev->config;
USDHC_Type *base = get_base(dev);
return (USDHC_GetPresentStatusFlags(cfg->base) &
return (USDHC_GetPresentStatusFlags(base) &
(kUSDHC_Data0LineLevelFlag | kUSDHC_Data1LineLevelFlag | kUSDHC_Data2LineLevelFlag |
kUSDHC_Data3LineLevelFlag))
? 0
@ -518,7 +532,6 @@ static int imx_usdhc_card_busy(const struct device *dev)
*/
static int imx_usdhc_execute_tuning(const struct device *dev)
{
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *dev_data = dev->data;
usdhc_command_t cmd = {0};
usdhc_data_t data = {0};
@ -526,6 +539,7 @@ static int imx_usdhc_execute_tuning(const struct device *dev)
usdhc_transfer_t transfer;
int ret;
bool retry_tuning = true;
USDHC_Type *base = get_base(dev);
if ((dev_data->host_io.timing == SDHC_TIMING_HS200) ||
(dev_data->host_io.timing == SDHC_TIMING_HS400)) {
@ -550,20 +564,20 @@ static int imx_usdhc_execute_tuning(const struct device *dev)
transfer.data = &data;
/* Reset tuning circuit */
USDHC_Reset(cfg->base, kUSDHC_ResetTuning, 100U);
USDHC_Reset(base, kUSDHC_ResetTuning, 100U);
/* Disable standard tuning */
USDHC_EnableStandardTuning(cfg->base, IMX_USDHC_STANDARD_TUNING_START,
IMX_USDHC_TUNING_STEP, false);
USDHC_ForceClockOn(cfg->base, true);
USDHC_EnableStandardTuning(base, IMX_USDHC_STANDARD_TUNING_START, IMX_USDHC_TUNING_STEP,
false);
USDHC_ForceClockOn(base, true);
/*
* Tuning fail found on some SOCs is caused by the different of delay
* cell, so we need to increase the tuning counter to cover the
* adjustable tuning window
*/
USDHC_SetStandardTuningCounter(cfg->base, IMX_USDHC_STANDARD_TUNING_COUNTER);
USDHC_SetStandardTuningCounter(base, IMX_USDHC_STANDARD_TUNING_COUNTER);
/* Reenable standard tuning */
USDHC_EnableStandardTuning(cfg->base, IMX_USDHC_STANDARD_TUNING_START,
IMX_USDHC_TUNING_STEP, true);
USDHC_EnableStandardTuning(base, IMX_USDHC_STANDARD_TUNING_START, IMX_USDHC_TUNING_STEP,
true);
request.command_timeout = K_MSEC(IMX_USDHC_DEFAULT_TIMEOUT);
request.data_timeout = K_MSEC(IMX_USDHC_DEFAULT_TIMEOUT);
@ -578,29 +592,29 @@ static int imx_usdhc_execute_tuning(const struct device *dev)
k_busy_wait(1000);
/* Wait for execute tuning bit to clear */
if (USDHC_GetExecuteStdTuningStatus(cfg->base) != 0) {
if (USDHC_GetExecuteStdTuningStatus(base) != 0) {
continue;
}
/* If tuning had error, retry tuning */
if ((USDHC_CheckTuningError(cfg->base) != 0U) && retry_tuning) {
if ((USDHC_CheckTuningError(base) != 0U) && retry_tuning) {
retry_tuning = false;
/* Enable standard tuning */
USDHC_EnableStandardTuning(cfg->base, IMX_USDHC_STANDARD_TUNING_START,
USDHC_EnableStandardTuning(base, IMX_USDHC_STANDARD_TUNING_START,
IMX_USDHC_TUNING_STEP, true);
USDHC_SetTuningDelay(cfg->base, IMX_USDHC_STANDARD_TUNING_START, 0U, 0U);
USDHC_SetTuningDelay(base, IMX_USDHC_STANDARD_TUNING_START, 0U, 0U);
} else {
break;
}
}
/* Check tuning result */
if (USDHC_CheckStdTuningResult(cfg->base) == 0) {
if (USDHC_CheckStdTuningResult(base) == 0) {
return -EIO;
}
USDHC_ForceClockOn(cfg->base, false);
USDHC_ForceClockOn(base, false);
/* Enable auto tuning */
USDHC_EnableAutoTuning(cfg->base, true);
USDHC_EnableAutoTuning(base, true);
return 0;
}
@ -610,7 +624,6 @@ static int imx_usdhc_execute_tuning(const struct device *dev)
static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd,
struct sdhc_data *data)
{
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *dev_data = dev->data;
usdhc_command_t host_cmd = {0};
usdhc_data_t host_data = {0};
@ -619,9 +632,10 @@ static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd,
int busy_timeout = IMX_USDHC_DEFAULT_TIMEOUT;
int ret = 0;
int retries = (int)cmd->retries;
USDHC_Type *base = get_base(dev);
if (cmd->opcode == SD_GO_IDLE_STATE) {
USDHC_SetCardActive(cfg->base, 0xFFFF);
USDHC_SetCardActive(base, 0xFFFF);
}
host_cmd.index = cmd->opcode;
@ -714,12 +728,10 @@ static int imx_usdhc_request(const struct device *dev, struct sdhc_command *cmd,
* the USDHC driver expects data to be present in the
* current transmission, but CMD12 does not contain data
*/
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CommandFlag |
kUSDHC_DataFlag |
kUSDHC_DataDMAFlag);
USDHC_ClearInterruptStatusFlags(cfg->base, kUSDHC_CommandFlag |
kUSDHC_DataFlag |
kUSDHC_DataDMAFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CommandFlag | kUSDHC_DataFlag |
kUSDHC_DataDMAFlag);
USDHC_ClearInterruptStatusFlags(base, kUSDHC_CommandFlag | kUSDHC_DataFlag |
kUSDHC_DataDMAFlag);
/* Stop transmission with CMD12 in case of data error */
imx_usdhc_stop_transmission(dev);
/* Wait for card to go idle */
@ -779,6 +791,7 @@ static int imx_usdhc_get_card_present(const struct device *dev)
{
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *data = dev->data;
USDHC_Type *base = get_base(dev);
if (cfg->detect_dat3) {
/*
@ -788,20 +801,20 @@ static int imx_usdhc_get_card_present(const struct device *dev)
if (!data->card_present) {
/* Detect card presence with DAT3 line pull */
imx_usdhc_dat3_pull(cfg, false);
USDHC_CardDetectByData3(cfg->base, true);
USDHC_CardDetectByData3(base, true);
/* Delay to ensure host has time to detect card */
k_busy_wait(1000);
data->card_present = USDHC_DetectCardInsert(cfg->base);
data->card_present = USDHC_DetectCardInsert(base);
/* Clear card detection and pull */
imx_usdhc_dat3_pull(cfg, true);
USDHC_CardDetectByData3(cfg->base, false);
USDHC_CardDetectByData3(base, false);
}
} else if (cfg->detect_cd) {
/*
* Detect the card via the USDHC_CD signal internal to
* the peripheral
*/
data->card_present = USDHC_DetectCardInsert(cfg->base);
data->card_present = USDHC_DetectCardInsert(base);
} else if (cfg->detect_gpio.port) {
data->card_present = gpio_pin_get_dt(&cfg->detect_gpio) > 0;
} else {
@ -831,6 +844,7 @@ static int imx_usdhc_enable_interrupt(const struct device *dev, sdhc_interrupt_c
{
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *data = dev->data;
USDHC_Type *base = get_base(dev);
int ret;
/* Record SDIO callback parameters */
@ -838,24 +852,24 @@ static int imx_usdhc_enable_interrupt(const struct device *dev, sdhc_interrupt_c
data->sdhc_cb_user_data = user_data;
/* Disable interrupts, then enable what the user requested */
USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag);
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag);
USDHC_DisableInterruptStatus(base, kUSDHC_CardInterruptFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CardInterruptFlag);
if (cfg->detect_gpio.port) {
ret = gpio_pin_interrupt_configure_dt(&cfg->detect_gpio, GPIO_INT_DISABLE);
if (ret) {
return ret;
}
} else {
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardRemovalFlag);
USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardRemovalFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptStatus(base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CardRemovalFlag);
USDHC_DisableInterruptStatus(base, kUSDHC_CardRemovalFlag);
}
if (sources & SDHC_INT_SDIO) {
/* Enable SDIO card interrupt */
USDHC_EnableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag);
USDHC_EnableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag);
USDHC_EnableInterruptStatus(base, kUSDHC_CardInterruptFlag);
USDHC_EnableInterruptSignal(base, kUSDHC_CardInterruptFlag);
}
if (sources & SDHC_INT_INSERTED) {
if (cfg->detect_gpio.port) {
@ -867,8 +881,8 @@ static int imx_usdhc_enable_interrupt(const struct device *dev, sdhc_interrupt_c
}
} else {
/* Enable card insertion interrupt */
USDHC_EnableInterruptStatus(cfg->base, kUSDHC_CardInsertionFlag);
USDHC_EnableInterruptSignal(cfg->base, kUSDHC_CardInsertionFlag);
USDHC_EnableInterruptStatus(base, kUSDHC_CardInsertionFlag);
USDHC_EnableInterruptSignal(base, kUSDHC_CardInsertionFlag);
}
}
if (sources & SDHC_INT_REMOVED) {
@ -881,8 +895,8 @@ static int imx_usdhc_enable_interrupt(const struct device *dev, sdhc_interrupt_c
}
} else {
/* Enable card removal interrupt */
USDHC_EnableInterruptStatus(cfg->base, kUSDHC_CardRemovalFlag);
USDHC_EnableInterruptSignal(cfg->base, kUSDHC_CardRemovalFlag);
USDHC_EnableInterruptStatus(base, kUSDHC_CardRemovalFlag);
USDHC_EnableInterruptSignal(base, kUSDHC_CardRemovalFlag);
}
}
@ -893,12 +907,13 @@ static int imx_usdhc_disable_interrupt(const struct device *dev, int sources)
{
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *data = dev->data;
USDHC_Type *base = get_base(dev);
int ret;
if (sources & SDHC_INT_SDIO) {
/* Disable SDIO card interrupt */
USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInterruptFlag);
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInterruptFlag);
USDHC_DisableInterruptStatus(base, kUSDHC_CardInterruptFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CardInterruptFlag);
}
if (sources & SDHC_INT_INSERTED) {
if (cfg->detect_gpio.port) {
@ -908,8 +923,8 @@ static int imx_usdhc_disable_interrupt(const struct device *dev, int sources)
}
} else {
/* Disable card insertion interrupt */
USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptStatus(base, kUSDHC_CardInsertionFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CardInsertionFlag);
}
}
if (sources & SDHC_INT_REMOVED) {
@ -920,13 +935,13 @@ static int imx_usdhc_disable_interrupt(const struct device *dev, int sources)
}
} else {
/* Disable card removal interrupt */
USDHC_DisableInterruptStatus(cfg->base, kUSDHC_CardRemovalFlag);
USDHC_DisableInterruptSignal(cfg->base, kUSDHC_CardRemovalFlag);
USDHC_DisableInterruptStatus(base, kUSDHC_CardRemovalFlag);
USDHC_DisableInterruptSignal(base, kUSDHC_CardRemovalFlag);
}
}
/* If all interrupt flags are disabled, remove callback */
if ((USDHC_GetEnabledInterruptStatusFlags(cfg->base) &
if ((USDHC_GetEnabledInterruptStatusFlags(base) &
(kUSDHC_CardInterruptFlag | kUSDHC_CardInsertionFlag | kUSDHC_CardRemovalFlag)) == 0) {
data->sdhc_cb = NULL;
data->sdhc_cb_user_data = NULL;
@ -937,10 +952,10 @@ static int imx_usdhc_disable_interrupt(const struct device *dev, int sources)
static int imx_usdhc_isr(const struct device *dev)
{
const struct usdhc_config *cfg = dev->config;
USDHC_Type *base = get_base(dev);
struct usdhc_data *data = dev->data;
USDHC_TransferHandleIRQ(cfg->base, &data->transfer_handle);
USDHC_TransferHandleIRQ(base, &data->transfer_handle);
return 0;
}
@ -952,6 +967,7 @@ static int imx_usdhc_init(const struct device *dev)
const struct usdhc_config *cfg = dev->config;
struct usdhc_data *data = dev->data;
usdhc_config_t host_config = {0};
USDHC_Type *base;
int ret;
const usdhc_transfer_callback_t callbacks = {
.TransferComplete = transfer_complete_cb,
@ -960,6 +976,8 @@ static int imx_usdhc_init(const struct device *dev)
.CardRemoved = card_removed_cb,
};
DEVICE_MMIO_NAMED_MAP(dev, usdhc_mmio, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP);
if (!device_is_ready(cfg->clock_dev)) {
LOG_ERR("clock control device not ready");
return -ENODEV;
@ -969,14 +987,15 @@ static int imx_usdhc_init(const struct device *dev)
if (ret) {
return ret;
}
USDHC_TransferCreateHandle(cfg->base, &data->transfer_handle, &callbacks, (void *)dev);
base = get_base(dev);
USDHC_TransferCreateHandle(base, &data->transfer_handle, &callbacks, (void *)dev);
cfg->irq_config_func(dev);
host_config.dataTimeout = cfg->data_timeout;
host_config.endianMode = kUSDHC_EndianModeLittle;
host_config.readWatermarkLevel = cfg->read_watermark;
host_config.writeWatermarkLevel = cfg->write_watermark;
USDHC_Init(cfg->base, &host_config);
USDHC_Init(base, &host_config);
/* Read host controller properties */
imx_usdhc_init_host_props(dev);
/* Set power GPIO low, so card starts powered off */
@ -1056,7 +1075,7 @@ static DEVICE_API(sdhc, usdhc_api) = {
PINCTRL_DT_INST_DEFINE(n); \
\
static const struct usdhc_config usdhc_##n##_config = { \
.base = (USDHC_Type *)DT_INST_REG_ADDR(n), \
DEVICE_MMIO_NAMED_ROM_INIT(usdhc_mmio, DT_DRV_INST(n)), \
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \
.nusdhc = n, \