summaryrefslogtreecommitdiff
path: root/nuttx/drivers/mmcsd/mmcsd_spi.c
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-06-17 12:31:24 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-06-17 12:31:24 -0600
commit42593d65b9712714bb41326f4b23f6c62cf0b058 (patch)
tree7104b8971397e504e66bbc550de93629a2a5690f /nuttx/drivers/mmcsd/mmcsd_spi.c
parent016924ddbd281ccba7ee72fce682ddd9a1fb40e0 (diff)
downloadpx4-nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.tar.gz
px4-nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.tar.bz2
px4-nuttx-42593d65b9712714bb41326f4b23f6c62cf0b058.zip
MMC/SD driver needs to manage SPI mode and data width as well
Diffstat (limited to 'nuttx/drivers/mmcsd/mmcsd_spi.c')
-rw-r--r--nuttx/drivers/mmcsd/mmcsd_spi.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/nuttx/drivers/mmcsd/mmcsd_spi.c b/nuttx/drivers/mmcsd/mmcsd_spi.c
index 71fe5c625..46d624d3c 100644
--- a/nuttx/drivers/mmcsd/mmcsd_spi.c
+++ b/nuttx/drivers/mmcsd/mmcsd_spi.c
@@ -86,6 +86,10 @@
# define CONFIG_MMCSD_SPICLOCK 20000000
#endif
+#ifndef CONFIG_MMCSD_SPIMODE
+# define CONFIG_MMCSD_SPIMODE SPIDEV_MODE0
+#endif
+
#ifndef CONFIG_MMCSD_SECTOR512
# define CONFIG_MMCSD_SECTOR512 /* Force 512 byte sectors on all cards */
#endif
@@ -348,12 +352,13 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot)
#ifndef CONFIG_SPI_OWNBUS
(void)SPI_LOCK(slot->spi, true);
- /* Set the frequency, as some other driver could have changed it.
- * TODO: Also need to restore mode and number-of-bits. Those can also
- * change from SPI device-to-device.
+ /* Set the frequency, bit width and mode, as some other driver could have
+ * changed those since the last time that we had the SPI bus.
*/
SPI_SETFREQUENCY(slot->spi, slot->spispeed);
+ SPI_SETMODE(slot->sp, CONFIG_MMCSD_SPIMODE);
+ SPI_SETBITS(slot->sp, 8);
#endif
/* Get exclusive access to the MMC/SD device (prossibly un-necessary if
@@ -370,6 +375,10 @@ static void mmcsd_semtake(FAR struct mmcsd_slot_s *slot)
}
}
+/****************************************************************************
+ * Name: mmcsd_semgive
+ ****************************************************************************/
+
static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot)
{
/* Relinquish the lock on the MMC/SD device */
@@ -392,6 +401,27 @@ static void mmcsd_semgive(FAR struct mmcsd_slot_s *slot)
}
/****************************************************************************
+ * Name: mmcsd_spiinit
+ *
+ * Description:
+ * Set SPI mode and data width.
+ *
+ * Assumptions:
+ * MMC/SD card already selected
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_SPI_OWNBUS
+static inline void mmcsd_spiinit(FAR struct mmcsd_slot_s *slot)
+{
+ SPI_SETMODE(slot->spi, CONFIG_MMCSD_SPIMODE);
+ SPI_SETBITS(slot->spi, 8);
+}
+#else
+# define mmcsd_spiinit(slot)
+#endif
+
+/****************************************************************************
* Name: mmcsd_waitready
*
* Description:
@@ -682,7 +712,7 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd)
uint32_t csizemult;
uint32_t csize;
- /* Calculate SPI max clock */
+ /* Calculate the SPI max clock frequency */
maxfrequency =
g_transpeedtu[MMCSD_CSD_TRANSPEED_TIMEVALUE(csd)] *
@@ -696,12 +726,9 @@ static void mmcsd_decodecsd(FAR struct mmcsd_slot_s *slot, uint8_t *csd)
frequency = CONFIG_MMCSD_SPICLOCK;
}
- /* Store the value for future use */
+ /* Set the actual SPI frequency as close as possible to the max frequency */
slot->spispeed = frequency;
-
- /* Set the actual SPI frequency as close as possible to that value */
-
frequency = SPI_SETFREQUENCY(spi, frequency);
/* Now determine the delay to access data */
@@ -1548,6 +1575,7 @@ static int mmcsd_mediainitialize(FAR struct mmcsd_slot_s *slot)
/* Clock Freq. Identification Mode < 400kHz */
+ slot->spispeed = MMCSD_IDMODE_CLOCK;
SPI_SETFREQUENCY(spi, MMCSD_IDMODE_CLOCK);
/* Set the maximum access time out */
@@ -1910,9 +1938,15 @@ int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi)
slot->spi = spi;
slot->spispeed = MMCSD_IDMODE_CLOCK;
- /* Ininitialize for the media in the slot (if any) */
+ /* Get exclusvice access to the SPI bus and make sure that SPI is properly
+ * configured for the MMC/SD card
+ */
mmcsd_semtake(slot);
+ mmcsd_spiinit(slot);
+
+ /* Ininitialize for the media in the slot (if any) */
+
ret = mmcsd_mediainitialize(slot);
mmcsd_semgive(slot);
if (ret == 0)