[U-Boot] [PATCH v1 0/2] Add SDHCI card detection support

This patch series adds card detection support in sdhci framework & added functionality to read card detect dt properties.
Thanks, Michal
T Karthik Reddy (2): mmc: sdhci: Implement SDHCI card detect mmc: sdhci: Read sdhci card detect properties from DT
drivers/mmc/sdhci.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ include/sdhci.h | 7 +++++++ 2 files changed, 54 insertions(+)

From: T Karthik Reddy t.karthik.reddy@xilinx.com
Card detect function implemented for SDHCI framework.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/mmc/sdhci.c | 32 ++++++++++++++++++++++++++++++++ include/sdhci.h | 7 +++++++ 2 files changed, 39 insertions(+)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index e2bb90abbdf3..67ca324c9320 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -12,6 +12,7 @@ #include <malloc.h> #include <mmc.h> #include <sdhci.h> +#include <dm.h>
#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER) void *aligned_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER; @@ -624,9 +625,40 @@ int sdhci_probe(struct udevice *dev) return sdhci_init(mmc); }
+int sdhci_get_cd(struct udevice *dev) +{ + struct mmc *mmc = mmc_get_mmc_dev(dev); + struct sdhci_host *host = mmc->priv; + int value; + + /* If nonremovable, assume that the card is always present. */ + if (host->host_caps & MMC_CAP_NONREMOVABLE) + return 1; + /* If polling, assume that the card is always present. */ + if (host->host_caps & MMC_CAP_NEEDS_POLL) + return 1; + +#if CONFIG_IS_ENABLED(DM_GPIO) + value = dm_gpio_get_value(&host->cd_gpio); + if (value >= 0) { + if (host->host_caps & MMC_CAP_CD_ACTIVE_HIGH) + return !value; + else + return value; + } +#endif + value = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & + SDHCI_CARD_DETECT_PIN_LEVEL); + if (host->host_caps & MMC_CAP_CD_ACTIVE_HIGH) + return !value; + else + return value; +} + const struct dm_mmc_ops sdhci_ops = { .send_cmd = sdhci_send_command, .set_ios = sdhci_set_ios, + .get_cd = sdhci_get_cd, #ifdef MMC_SUPPORTS_TUNING .execute_tuning = sdhci_execute_tuning, #endif diff --git a/include/sdhci.h b/include/sdhci.h index eee493ab5f57..4c944d0867a2 100644 --- a/include/sdhci.h +++ b/include/sdhci.h @@ -228,6 +228,13 @@ #define SDHCI_QUIRK_USE_WIDE8 (1 << 8) #define SDHCI_QUIRK_NO_1_8_V (1 << 9)
+/* + * mmc host capabilities + */ +#define MMC_CAP_NONREMOVABLE BIT(8) +#define MMC_CAP_NEEDS_POLL BIT(9) +#define MMC_CAP_CD_ACTIVE_HIGH BIT(10) + /* to make gcc happy */ struct sdhci_host;

Hi Michal,
On 07/06/19 2:05 PM, Michal Simek wrote:
From: T Karthik Reddy t.karthik.reddy@xilinx.com
Card detect function implemented for SDHCI framework.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com
drivers/mmc/sdhci.c | 32 ++++++++++++++++++++++++++++++++ include/sdhci.h | 7 +++++++ 2 files changed, 39 insertions(+)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index e2bb90abbdf3..67ca324c9320 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -12,6 +12,7 @@ #include <malloc.h> #include <mmc.h> #include <sdhci.h> +#include <dm.h>
#if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER) void *aligned_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER; @@ -624,9 +625,40 @@ int sdhci_probe(struct udevice *dev) return sdhci_init(mmc); }
+int sdhci_get_cd(struct udevice *dev) +{
- struct mmc *mmc = mmc_get_mmc_dev(dev);
- struct sdhci_host *host = mmc->priv;
- int value;
- /* If nonremovable, assume that the card is always present. */
- if (host->host_caps & MMC_CAP_NONREMOVABLE)
return 1;
- /* If polling, assume that the card is always present. */
- if (host->host_caps & MMC_CAP_NEEDS_POLL)
return 1;
+#if CONFIG_IS_ENABLED(DM_GPIO)
- value = dm_gpio_get_value(&host->cd_gpio);
- if (value >= 0) {
if (host->host_caps & MMC_CAP_CD_ACTIVE_HIGH)
return !value;
else
return value;
- }
+#endif
- value = !!(sdhci_readl(host, SDHCI_PRESENT_STATE) &
SDHCI_CARD_DETECT_PIN_LEVEL);
I think you need to use CARD_PRESENT instead of this. According to the spec, "This bit may be valid when Card State Stable is set to 1, but it is not guaranteed because of propagation delay. Use of this bit is limited to testing since it must be debounced by software."
Thanks, Faiz

From: T Karthik Reddy t.karthik.reddy@xilinx.com
This patch reads card detect properties from device tree.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com ---
drivers/mmc/sdhci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 67ca324c9320..a451ccbdf014 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -591,7 +591,22 @@ static int sdhci_set_ios(struct mmc *mmc) static int sdhci_init(struct mmc *mmc) { struct sdhci_host *host = mmc->priv; +#if CONFIG_IS_ENABLED(DM_MMC) + struct udevice *dev = mmc->dev;
+ if (dev_read_bool(dev, "non-removable")) { + host->host_caps |= MMC_CAP_NONREMOVABLE; + } else { + if (dev_read_bool(dev, "cd-inverted")) + host->host_caps |= MMC_CAP_CD_ACTIVE_HIGH; + if (dev_read_bool(dev, "broken-cd")) + host->host_caps |= MMC_CAP_NEEDS_POLL; +#if CONFIG_IS_ENABLED(DM_GPIO) + gpio_request_by_name(dev, "cd-gpio", 0, + &host->cd_gpio, GPIOD_IS_IN); +#endif + } +#endif sdhci_reset(host, SDHCI_RESET_ALL);
if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) {

Hi,
On 07/06/19 2:05 PM, Michal Simek wrote:
From: T Karthik Reddy t.karthik.reddy@xilinx.com
This patch reads card detect properties from device tree.
Signed-off-by: T Karthik Reddy t.karthik.reddy@xilinx.com Signed-off-by: Michal Simek michal.simek@xilinx.com
drivers/mmc/sdhci.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 67ca324c9320..a451ccbdf014 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -591,7 +591,22 @@ static int sdhci_set_ios(struct mmc *mmc) static int sdhci_init(struct mmc *mmc) { struct sdhci_host *host = mmc->priv; +#if CONFIG_IS_ENABLED(DM_MMC)
struct udevice *dev = mmc->dev;
if (dev_read_bool(dev, "non-removable")) {
host->host_caps |= MMC_CAP_NONREMOVABLE;
} else {
if (dev_read_bool(dev, "cd-inverted"))
host->host_caps |= MMC_CAP_CD_ACTIVE_HIGH;
if (dev_read_bool(dev, "broken-cd"))
host->host_caps |= MMC_CAP_NEEDS_POLL;
+#if CONFIG_IS_ENABLED(DM_GPIO)
gpio_request_by_name(dev, "cd-gpio", 0,
&host->cd_gpio, GPIOD_IS_IN);
+#endif
- }
+#endif
All of the above properties are not related to SDHCI. They need to go in generic mmc host code. Add them to mmc_of_parse()
Thanks, Faiz
participants (2)
-
Faiz Abbas
-
Michal Simek