arch/arm/sr/lpc54xx: Add support for power pin to SDMMC driver. Some fixes from initial testing.
This commit is contained in:
parent
31db67cad7
commit
96e6835793
@ -643,20 +643,20 @@ endmenu # EMC Configuration
|
|||||||
menu "SD/MMC Configuration"
|
menu "SD/MMC Configuration"
|
||||||
depends on LPC54_SDMMC
|
depends on LPC54_SDMMC
|
||||||
|
|
||||||
|
config LPC54_SDMMC_PWRCTRL
|
||||||
|
bool "Power-enable pin"
|
||||||
|
default n
|
||||||
|
---help---
|
||||||
|
Select if the board supports a power-enable pin that must be selected
|
||||||
|
to provide power to the SD card.
|
||||||
|
|
||||||
config LPC54_SDMMC_DMA
|
config LPC54_SDMMC_DMA
|
||||||
bool "Support DMA data transfers"
|
bool "Support DMA data transfers"
|
||||||
default y
|
default y
|
||||||
|
select SDIO_DMA
|
||||||
---help---
|
---help---
|
||||||
Support DMA data transfers.
|
Support DMA data transfers.
|
||||||
|
|
||||||
config LPC54_SDMMC_WIDTH_D1_ONLY
|
|
||||||
bool "Use D1 only"
|
|
||||||
default n
|
|
||||||
---help---
|
|
||||||
Select 1-bit transfer mode. This may be selected to force the driver
|
|
||||||
operate with only a single data line (the default is to use all
|
|
||||||
4 SD data lines).Default: 4-bit transfer mode.
|
|
||||||
|
|
||||||
config LPC54_SDMMC_REGDEBUG
|
config LPC54_SDMMC_REGDEBUG
|
||||||
bool "Register level debug"
|
bool "Register level debug"
|
||||||
default n
|
default n
|
||||||
|
@ -92,21 +92,30 @@
|
|||||||
#define MCI_DMADES1_BS1(x) (x)
|
#define MCI_DMADES1_BS1(x) (x)
|
||||||
|
|
||||||
/* Configuration ************************************************************/
|
/* Configuration ************************************************************/
|
||||||
/* Required system configuration options:
|
/* Required system configuration options in the sched/Kconfig:
|
||||||
*
|
*
|
||||||
* CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support.
|
* CONFIG_SCHED_WORKQUEUE -- Callback support requires work queue support.
|
||||||
*
|
*
|
||||||
* Driver-specific configuration options:
|
* Driver-specific configuration options in the drivers/mmcd Kdonfig:
|
||||||
*
|
*
|
||||||
* CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking
|
* CONFIG_SDIO_MUXBUS - Setting this configuration enables some locking
|
||||||
* APIs to manage concurrent accesses on the SD card bus. This is not
|
* APIs to manage concurrent accesses on the SD card bus. This is not
|
||||||
* needed for the simple case of a single SD card, for example.
|
* needed for the simple case of a single SD card slot, for example.
|
||||||
* CONFIG_SDIO_DMA - Enable SD card DMA. This is a marginally optional.
|
* CONFIG_SDIO_WIDTH_D1_ONLY - This may be selected to force the driver
|
||||||
* For most usages, SD accesses will cause data overruns if used without DMA.
|
|
||||||
* NOTE the above system DMA configuration options.
|
|
||||||
* CONFIG_LPC54_SDMMC_WIDTH_D1_ONLY - This may be selected to force the driver
|
|
||||||
* operate with only a single data line (the default is to use all
|
* operate with only a single data line (the default is to use all
|
||||||
* 4 SD data lines).
|
* 4 SD data lines).
|
||||||
|
* CONFIG_MMCSD_HAVE_CARDDETECT - Select if the SD slot supports a card
|
||||||
|
* detect pin.
|
||||||
|
* CONFIG_MMCSD_HAVE_WRITEPROTECT - Select if the SD slots supports a
|
||||||
|
* write protected pin.
|
||||||
|
*
|
||||||
|
* Driver-specific configuration options in the arch/arm/src/lpc54xx/Kconfig
|
||||||
|
*
|
||||||
|
* CONFIG_LPC54_SDMMC_PWRCTRL - Select if the board supports an output
|
||||||
|
* pin to enable power to the SD slot.
|
||||||
|
* CONFIG_LPC54_SDMMC_DMA - Enable SD card DMA. This is a marginally
|
||||||
|
* optional. For most usages, SD accesses will cause data overruns if
|
||||||
|
* used without DMA. This will also select CONFIG_SDIO_DMA.
|
||||||
* CONFIG_LPC54_SDMMC_REGDEBUG - Enables some very low-level debug output
|
* CONFIG_LPC54_SDMMC_REGDEBUG - Enables some very low-level debug output
|
||||||
* This also requires CONFIG_DEBUG_MEMCARD_INFO
|
* This also requires CONFIG_DEBUG_MEMCARD_INFO
|
||||||
*/
|
*/
|
||||||
@ -178,6 +187,15 @@
|
|||||||
#define SDCARD_DMADONE_FLAG (2)
|
#define SDCARD_DMADONE_FLAG (2)
|
||||||
#define SDCARD_ALLDONE (3)
|
#define SDCARD_ALLDONE (3)
|
||||||
|
|
||||||
|
|
||||||
|
/* Card debounce time. Number of host clocks (SD_CLK) used by debounce
|
||||||
|
* filter logic for card detect. typical debounce time is 5-25 ms.
|
||||||
|
*
|
||||||
|
* Eg. Fsd = 44MHz, ticks = 660,000
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEBOUNCE_TICKS (15 * BOARD_SDMMC_FREQUENCY / 1000)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -222,7 +240,7 @@ struct lpc54_dev_s
|
|||||||
/* DMA data transfer support */
|
/* DMA data transfer support */
|
||||||
|
|
||||||
bool widebus; /* Required for DMA support */
|
bool widebus; /* Required for DMA support */
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
bool dmamode; /* true: DMA mode transfer */
|
bool dmamode; /* true: DMA mode transfer */
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@ -252,16 +270,9 @@ static int lpc54_ciu_sendcmd(uint32_t cmd, uint32_t arg);
|
|||||||
static void lpc54_configwaitints(struct lpc54_dev_s *priv, uint32_t waitmask,
|
static void lpc54_configwaitints(struct lpc54_dev_s *priv, uint32_t waitmask,
|
||||||
sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
|
sdio_eventset_t waitevents, sdio_eventset_t wkupevents);
|
||||||
static void lpc54_configxfrints(struct lpc54_dev_s *priv, uint32_t xfrmask);
|
static void lpc54_configxfrints(struct lpc54_dev_s *priv, uint32_t xfrmask);
|
||||||
#if 0 /* Not used */
|
|
||||||
static void lpc54_setpwrctrl(uint32_t pwrctrl);
|
|
||||||
#endif
|
|
||||||
static inline uint32_t lpc54_getpwrctrl(void);
|
|
||||||
|
|
||||||
/* Data Transfer Helpers ****************************************************/
|
/* Data Transfer Helpers ****************************************************/
|
||||||
|
|
||||||
#if 0 /* Not used */
|
|
||||||
static uint8_t lpc54_log2(uint16_t value);
|
|
||||||
#endif
|
|
||||||
static void lpc54_eventtimeout(int argc, uint32_t arg);
|
static void lpc54_eventtimeout(int argc, uint32_t arg);
|
||||||
static void lpc54_endwait(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent);
|
static void lpc54_endwait(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent);
|
||||||
static void lpc54_endtransfer(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent);
|
static void lpc54_endtransfer(struct lpc54_dev_s *priv, sdio_eventset_t wkupevent);
|
||||||
@ -322,7 +333,7 @@ static int lpc54_registercallback(FAR struct sdio_dev_s *dev,
|
|||||||
|
|
||||||
/* DMA */
|
/* DMA */
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev,
|
static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev,
|
||||||
FAR uint8_t *buffer, size_t buflen);
|
FAR uint8_t *buffer, size_t buflen);
|
||||||
static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
|
static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
|
||||||
@ -362,14 +373,14 @@ struct lpc54_dev_s g_scard_dev =
|
|||||||
.eventwait = lpc54_eventwait,
|
.eventwait = lpc54_eventwait,
|
||||||
.callbackenable = lpc54_callbackenable,
|
.callbackenable = lpc54_callbackenable,
|
||||||
.registercallback = lpc54_registercallback,
|
.registercallback = lpc54_registercallback,
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
.dmarecvsetup = lpc54_dmarecvsetup,
|
.dmarecvsetup = lpc54_dmarecvsetup,
|
||||||
.dmasendsetup = lpc54_dmasendsetup,
|
.dmasendsetup = lpc54_dmasendsetup,
|
||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
static struct sdmmc_dma_s g_sdmmc_dmadd[1 + (0x10000 / MCI_DMADES1_MAXTR)];
|
static struct sdmmc_dma_s g_sdmmc_dmadd[1 + (0x10000 / MCI_DMADES1_MAXTR)];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -700,89 +711,6 @@ static void lpc54_configxfrints(struct lpc54_dev_s *priv, uint32_t xfrmask)
|
|||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: lpc54_setpwrctrl
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Change the PWRCTRL field of the SD card POWER register to turn the SD card
|
|
||||||
* ON or OFF
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* clkcr - A new PWRCTRL setting
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#if 0 /* Not used */
|
|
||||||
static void lpc54_setpwrctrl(uint32_t pwrctrl)
|
|
||||||
{
|
|
||||||
mcinfo("pwrctrl=%08lx\n", (unsigned long)pwrctrl);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: lpc54_getpwrctrl
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Return the current value of the the PWRCTRL field of the SD card P
|
|
||||||
* register. This function can be used to see if the SD card is powered ON
|
|
||||||
* or OFF
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* The current value of the the PWRCTRL field of the SD card PWR register.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static inline uint32_t lpc54_getpwrctrl(void)
|
|
||||||
{
|
|
||||||
mcinfo("Returning zero\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Data Transfer Helpers
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: lpc54_log2
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Take (approximate) log base 2 of the provided number (Only works if the
|
|
||||||
* provided number is a power of 2).
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
#if 0 /* Not used */
|
|
||||||
static uint8_t lpc54_log2(uint16_t value)
|
|
||||||
{
|
|
||||||
uint8_t log2 = 0;
|
|
||||||
|
|
||||||
mcinfo("value=%04x\n", value);
|
|
||||||
|
|
||||||
/* 0000 0000 0000 0001 -> return 0,
|
|
||||||
* 0000 0000 0000 001x -> return 1,
|
|
||||||
* 0000 0000 0000 01xx -> return 2,
|
|
||||||
* 0000 0000 0000 1xxx -> return 3,
|
|
||||||
* ...
|
|
||||||
* 1xxx xxxx xxxx xxxx -> return 15,
|
|
||||||
*/
|
|
||||||
|
|
||||||
DEBUGASSERT(value > 0);
|
|
||||||
while (value != 1)
|
|
||||||
{
|
|
||||||
value >>= 1;
|
|
||||||
log2++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return log2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: lpc54_eventtimeout
|
* Name: lpc54_eventtimeout
|
||||||
*
|
*
|
||||||
@ -931,8 +859,12 @@ static int lpc54_interrupt(int irq, void *context, FAR void *arg)
|
|||||||
* bits remaining, then we have work to do here.
|
* bits remaining, then we have work to do here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
while ((enabled = lpc54_getreg(LPC54_SDMMC_RINTSTS) & lpc54_getreg(LPC54_SDMMC_INTMASK)) != 0)
|
while ((enabled = lpc54_getreg(LPC54_SDMMC_MINTSTS)) != 0)
|
||||||
{
|
{
|
||||||
|
/* Clear pending status */
|
||||||
|
|
||||||
|
lpc54_putreg(enabled, LPC54_SDMMC_RINTSTS);
|
||||||
|
|
||||||
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
|
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
|
||||||
/* Handle in card detection events ************************************/
|
/* Handle in card detection events ************************************/
|
||||||
|
|
||||||
@ -943,12 +875,12 @@ static int lpc54_interrupt(int irq, void *context, FAR void *arg)
|
|||||||
/* Update card status */
|
/* Update card status */
|
||||||
|
|
||||||
cdstatus = priv->cdstatus;
|
cdstatus = priv->cdstatus;
|
||||||
if ((getreg32(LPC54_SDMMC_CDETECT) & SDMMC_CDETECT_NOTPRESENT) == 0)
|
if ((lpc54_getreg(LPC54_SDMMC_CDETECT) & SDMMC_CDETECT_NOTPRESENT) == 0)
|
||||||
{
|
{
|
||||||
priv->cdstatus |= SDIO_STATUS_PRESENT;
|
priv->cdstatus |= SDIO_STATUS_PRESENT;
|
||||||
|
|
||||||
#ifdef CONFIG_MMCSD_HAVE_WRITEPROTECT
|
#ifdef CONFIG_MMCSD_HAVE_WRITEPROTECT
|
||||||
if ((getreg32(LPC54_SDMMC_WRTPRT) & SDMMC_WRTPRT_PROTECTED) != 0)
|
if ((lpc54_getreg(LPC54_SDMMC_WRTPRT) & SDMMC_WRTPRT_PROTECTED) != 0)
|
||||||
{
|
{
|
||||||
priv->cdstatus |= SDIO_STATUS_WRPROTECTED;
|
priv->cdstatus |= SDIO_STATUS_WRPROTECTED;
|
||||||
}
|
}
|
||||||
@ -957,10 +889,23 @@ static int lpc54_interrupt(int irq, void *context, FAR void *arg)
|
|||||||
{
|
{
|
||||||
priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED;
|
priv->cdstatus &= ~SDIO_STATUS_WRPROTECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_LPC54_SDMMC_PWRCTRL
|
||||||
|
/* Enable/ power to the SD card */
|
||||||
|
|
||||||
|
lpc54_putreg(SDMMC_PWREN, LPC54_SDMMC_PWREN);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
priv->cdstatus &= ~(SDIO_STATUS_PRESENT | SDIO_STATUS_WRPROTECTED);
|
priv->cdstatus &= ~(SDIO_STATUS_PRESENT | SDIO_STATUS_WRPROTECTED);
|
||||||
|
|
||||||
|
#ifdef CONFIG_LPC54_SDMMC_PWRCTRL
|
||||||
|
/* Disable power to the SD card */
|
||||||
|
|
||||||
|
lpc54_putreg(0, LPC54_SDMMC_PWREN);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
mcinfo("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus);
|
mcinfo("cdstatus OLD: %02x NEW: %02x\n", cdstatus, priv->cdstatus);
|
||||||
@ -1165,7 +1110,7 @@ static void lpc54_reset(FAR struct sdio_dev_s *dev)
|
|||||||
|
|
||||||
regval = 0;
|
regval = 0;
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
priv->dmamode = false; /* true: DMA mode transfer */
|
priv->dmamode = false; /* true: DMA mode transfer */
|
||||||
|
|
||||||
/* Use the Internal DMA */
|
/* Use the Internal DMA */
|
||||||
@ -1182,6 +1127,15 @@ static void lpc54_reset(FAR struct sdio_dev_s *dev)
|
|||||||
|
|
||||||
lpc54_putreg(SDCARD_INT_CDET, LPC54_SDMMC_INTMASK);
|
lpc54_putreg(SDCARD_INT_CDET, LPC54_SDMMC_INTMASK);
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMCSD_HAVE_CARDDETECT
|
||||||
|
/* Set the card debounce time. Number of host clocks (SD_CLK) used by
|
||||||
|
* debounce filter logic for card detect. typical debounce time is 5-25
|
||||||
|
* ms.
|
||||||
|
*/
|
||||||
|
|
||||||
|
lpc54_putreg(DEBOUNCE_TICKS, LPC54_SDMMC_DEBNCE);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Clear to Interrupts */
|
/* Clear to Interrupts */
|
||||||
|
|
||||||
lpc54_putreg(0xffffffff, LPC54_SDMMC_RINTSTS);
|
lpc54_putreg(0xffffffff, LPC54_SDMMC_RINTSTS);
|
||||||
@ -1204,6 +1158,12 @@ static void lpc54_reset(FAR struct sdio_dev_s *dev)
|
|||||||
|
|
||||||
lpc54_putreg(0, LPC54_SDMMC_CLKENA);
|
lpc54_putreg(0, LPC54_SDMMC_CLKENA);
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|
||||||
|
#if defined(CONFIG_LPC54_SDMMC_PWRCTRL) && !defined(CONFIG_MMCSD_HAVE_CARDDETECT)
|
||||||
|
/* Enable power to the SD card */
|
||||||
|
|
||||||
|
lpc54_putreg(enable ? SDMMC_PWREN : 0, LPC54_SDMMC_PWREN);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -1226,10 +1186,10 @@ static sdio_capset_t lpc54_capabilities(FAR struct sdio_dev_s *dev)
|
|||||||
|
|
||||||
caps |= SDIO_CAPS_DMABEFOREWRITE;
|
caps |= SDIO_CAPS_DMABEFOREWRITE;
|
||||||
|
|
||||||
#ifdef CONFIG_LPC54_SDMMC_WIDTH_D1_ONLY
|
#ifdef CONFIG_SDIO_WIDTH_D1_ONLY
|
||||||
caps |= SDIO_CAPS_1BIT_ONLY;
|
caps |= SDIO_CAPS_1BIT_ONLY;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
caps |= SDIO_CAPS_DMASUPPORTED;
|
caps |= SDIO_CAPS_DMASUPPORTED;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1337,7 +1297,7 @@ static void lpc54_clock(FAR struct sdio_dev_s *dev, enum sdio_clock_e rate)
|
|||||||
/* SD normal operation clocking (wide 4-bit mode) */
|
/* SD normal operation clocking (wide 4-bit mode) */
|
||||||
|
|
||||||
case CLOCK_SD_TRANSFER_4BIT:
|
case CLOCK_SD_TRANSFER_4BIT:
|
||||||
#ifndef CONFIG_LPC54_SDMMC_WIDTH_D1_ONLY
|
#ifndef CONFIG_SDIO_WIDTH_D1_ONLY
|
||||||
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_SDWIDEXFR);
|
clkdiv = SDMMC_CLKDIV0(BOARD_CLKDIV_SDWIDEXFR);
|
||||||
ctype = SDCARD_BUS_D4;
|
ctype = SDCARD_BUS_D4;
|
||||||
enabled = true;
|
enabled = true;
|
||||||
@ -1538,7 +1498,7 @@ static int lpc54_recvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
|||||||
|
|
||||||
priv->buffer = (uint32_t *)buffer;
|
priv->buffer = (uint32_t *)buffer;
|
||||||
priv->remaining = nbytes;
|
priv->remaining = nbytes;
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
priv->dmamode = false;
|
priv->dmamode = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1590,7 +1550,7 @@ static int lpc54_sendsetup(FAR struct sdio_dev_s *dev, FAR const uint8_t *buffer
|
|||||||
|
|
||||||
priv->buffer = (uint32_t *)buffer;
|
priv->buffer = (uint32_t *)buffer;
|
||||||
priv->remaining = nbytes;
|
priv->remaining = nbytes;
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
priv->dmamode = false;
|
priv->dmamode = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1637,7 +1597,7 @@ static int lpc54_cancel(FAR struct sdio_dev_s *dev)
|
|||||||
|
|
||||||
/* If this was a DMA transfer, make sure that DMA is stopped */
|
/* If this was a DMA transfer, make sure that DMA is stopped */
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
if (priv->dmamode)
|
if (priv->dmamode)
|
||||||
{
|
{
|
||||||
/* Make sure that the DMA is stopped (it will be stopped automatically
|
/* Make sure that the DMA is stopped (it will be stopped automatically
|
||||||
@ -2218,7 +2178,7 @@ static int lpc54_registercallback(FAR struct sdio_dev_s *dev,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
||||||
size_t buflen)
|
size_t buflen)
|
||||||
{
|
{
|
||||||
@ -2333,15 +2293,13 @@ static int lpc54_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
|||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#ifdef CONFIG_SDIO_DMA
|
#ifdef CONFIG_LPC54_SDMMC_DMA
|
||||||
static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
|
static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
|
||||||
FAR const uint8_t *buffer, size_t buflen)
|
FAR const uint8_t *buffer, size_t buflen)
|
||||||
{
|
{
|
||||||
struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev;
|
struct lpc54_dev_s *priv = (struct lpc54_dev_s *)dev;
|
||||||
uint32_t blocksize;
|
|
||||||
uint32_t bytecnt;
|
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
int ret = OK;
|
int ret = -EPERM;
|
||||||
|
|
||||||
mcinfo("buflen=%lu\n", (unsigned long)buflen);
|
mcinfo("buflen=%lu\n", (unsigned long)buflen);
|
||||||
|
|
||||||
@ -2352,7 +2310,9 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
|
|||||||
|
|
||||||
if (priv->widebus)
|
if (priv->widebus)
|
||||||
{
|
{
|
||||||
/* Save the destination buffer information for use by the interrupt handler */
|
/* Save the destination buffer information for use by the interrupt
|
||||||
|
* handler.
|
||||||
|
*/
|
||||||
|
|
||||||
priv->buffer = (uint32_t *)buffer;
|
priv->buffer = (uint32_t *)buffer;
|
||||||
priv->remaining = buflen;
|
priv->remaining = buflen;
|
||||||
@ -2365,14 +2325,15 @@ static int lpc54_dmasendsetup(FAR struct sdio_dev_s *dev,
|
|||||||
lpc54_putreg(regval, LPC54_SDMMC_CTRL);
|
lpc54_putreg(regval, LPC54_SDMMC_CTRL);
|
||||||
while (lpc54_getreg(LPC54_SDMMC_CTRL) & SDMMC_CTRL_DMARESET);
|
while (lpc54_getreg(LPC54_SDMMC_CTRL) & SDMMC_CTRL_DMARESET);
|
||||||
|
|
||||||
/* Setup DMA list */
|
/* Setup DMA descriptor list */
|
||||||
|
|
||||||
g_sdmmc_dmadd[0].des0 = MCI_DMADES0_OWN | MCI_DMADES0_CH | MCI_DMADES0_LD;
|
g_sdmmc_dmadd[0].des0 = MCI_DMADES0_OWN | MCI_DMADES0_CH | MCI_DMADES0_LD;
|
||||||
g_sdmmc_dmadd[0].des1 = 512;
|
g_sdmmc_dmadd[0].des1 = 512;
|
||||||
g_sdmmc_dmadd[0].des2 = priv->buffer;
|
g_sdmmc_dmadd[0].des2 = (uint32_t)priv->buffer;
|
||||||
g_sdmmc_dmadd[0].des3 = (uint32_t) &g_sdmmc_dmadd[1];
|
g_sdmmc_dmadd[0].des3 = (uint32_t)&g_sdmmc_dmadd[1];
|
||||||
|
|
||||||
lpc54_putreg((uint32_t) &g_sdmmc_dmadd[0], LPC54_SDMMC_DBADDR);
|
lpc54_putreg((uint32_t) &g_sdmmc_dmadd[0], LPC54_SDMMC_DBADDR);
|
||||||
|
ret = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -2428,7 +2389,7 @@ static void lpc54_callback(void *arg)
|
|||||||
{
|
{
|
||||||
/* No... return without performing the callback */
|
/* No... return without performing the callback */
|
||||||
|
|
||||||
mcinfo("Media is not Ejected!\n");
|
mcinfo("Media is not present\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2481,17 +2442,13 @@ static void lpc54_callback(void *arg)
|
|||||||
|
|
||||||
FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
|
FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
|
||||||
{
|
{
|
||||||
|
struct lpc54_dev_s *priv = &g_scard_dev;
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
|
|
||||||
mcinfo("slotno=%d\n", slotno);
|
mcinfo("slotno=%d\n", slotno);
|
||||||
|
|
||||||
flags = enter_critical_section();
|
flags = enter_critical_section();
|
||||||
|
|
||||||
/* There is only one slot */
|
|
||||||
|
|
||||||
struct lpc54_dev_s *priv = &g_scard_dev;
|
|
||||||
|
|
||||||
/* Set the SD/MMMC clock source */
|
/* Set the SD/MMMC clock source */
|
||||||
|
|
||||||
lpc54_putreg(BOARD_SDMMC_CLKSRC, LPC54_SYSCON_SDIOCLKSEL);
|
lpc54_putreg(BOARD_SDMMC_CLKSRC, LPC54_SYSCON_SDIOCLKSEL);
|
||||||
@ -2501,8 +2458,8 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
regval = SYSCON_SDIOCLKDIV_DIV(BOARD_SDMMC_CLKDIV);
|
regval = SYSCON_SDIOCLKDIV_DIV(BOARD_SDMMC_CLKDIV);
|
||||||
lpc54_putreg(regval, LPC54_SYSCON_SDIOCLKSEL);
|
lpc54_putreg(regval, LPC54_SYSCON_SDIOCLKDIV);
|
||||||
lpc54_putreg(regval | SYSCON_SDIOCLKDIV_REQFLAG, LPC54_SYSCON_SDIOCLKSEL);
|
lpc54_putreg(regval | SYSCON_SDIOCLKDIV_REQFLAG, LPC54_SYSCON_SDIOCLKDIV);
|
||||||
|
|
||||||
/* Enable clocking to the SD/MMC peripheral */
|
/* Enable clocking to the SD/MMC peripheral */
|
||||||
|
|
||||||
@ -2525,12 +2482,12 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
|
|||||||
/* Create a watchdog timer */
|
/* Create a watchdog timer */
|
||||||
|
|
||||||
priv->waitwdog = wd_create();
|
priv->waitwdog = wd_create();
|
||||||
DEBUGASSERT(priv->waitwdog);
|
DEBUGASSERT(priv->waitwdog != NULL);
|
||||||
|
|
||||||
/* Configure GPIOs for 4-bit, wide-bus operation */
|
/* Configure GPIOs for 4-bit, wide-bus operation */
|
||||||
|
|
||||||
lpc54_gpio_config(GPIO_SD_D0);
|
lpc54_gpio_config(GPIO_SD_D0);
|
||||||
#ifndef CONFIG_LPC54_SDMMC_WIDTH_D1_ONLY
|
#ifndef CONFIG_SDIO_WIDTH_D1_ONLY
|
||||||
lpc54_gpio_config(GPIO_SD_D1);
|
lpc54_gpio_config(GPIO_SD_D1);
|
||||||
lpc54_gpio_config(GPIO_SD_D2);
|
lpc54_gpio_config(GPIO_SD_D2);
|
||||||
lpc54_gpio_config(GPIO_SD_D3);
|
lpc54_gpio_config(GPIO_SD_D3);
|
||||||
@ -2540,7 +2497,9 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
|
|||||||
#endif
|
#endif
|
||||||
lpc54_gpio_config(GPIO_SD_CLK);
|
lpc54_gpio_config(GPIO_SD_CLK);
|
||||||
lpc54_gpio_config(GPIO_SD_CMD);
|
lpc54_gpio_config(GPIO_SD_CMD);
|
||||||
|
#ifdef CONFIG_LPC54_SDMMC_PWRCTRL
|
||||||
lpc54_gpio_config(GPIO_SD_POW_EN);
|
lpc54_gpio_config(GPIO_SD_POW_EN);
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_MMCSD_HAVE_WRITEPROTECT
|
#ifdef CONFIG_MMCSD_HAVE_WRITEPROTECT
|
||||||
lpc54_gpio_config(GPIO_SD_WR_PRT);
|
lpc54_gpio_config(GPIO_SD_WR_PRT);
|
||||||
#endif
|
#endif
|
||||||
@ -2552,9 +2511,6 @@ FAR struct sdio_dev_s *lpc54_sdmmc_initialize(int slotno)
|
|||||||
lpc54_reset(&priv->dev);
|
lpc54_reset(&priv->dev);
|
||||||
|
|
||||||
leave_critical_section(flags);
|
leave_critical_section(flags);
|
||||||
|
|
||||||
mcinfo("Leaving!\n");
|
|
||||||
|
|
||||||
return &g_scard_dev.dev;
|
return &g_scard_dev.dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user