123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /*
- * Copyright (c) 2006-2024 RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2024-08-16 zhujiale first version
- */
- #include "sdhci-platform.h"
- static const struct rt_sdhci_ops sdhci_pltfm_ops = {
- .set_clock = rt_sdhci_set_clock,
- .set_bus_width = rt_sdhci_set_bus_width,
- .reset = rt_sdhci_reset,
- .set_uhs_signaling = rt_sdhci_set_uhs,
- };
- void rt_sdhci_get_property(struct rt_platform_device *pdev)
- {
- struct rt_device *dev = &pdev->parent;
- struct rt_sdhci_host *host = pdev->priv;
- struct rt_sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
- rt_uint32_t bus_width;
- if (rt_dm_dev_prop_read_bool(dev, "sdhci,auto-cmd12"))
- host->quirks |= RT_SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12;
- if (rt_dm_dev_prop_read_bool(dev, "sdhci,1-bit-only") || (rt_dm_dev_prop_read_u32(dev, "bus-width", &bus_width) == 0 && bus_width == 1))
- host->quirks |= RT_SDHCI_QUIRK_FORCE_1_BIT_DATA;
- if (rt_dm_dev_prop_read_bool(dev, "broken-cd"))
- host->quirks |= RT_SDHCI_QUIRK_BROKEN_CARD_DETECTION;
- if (rt_dm_dev_prop_read_bool(dev, "no-1-8-v"))
- host->quirks2 |= RT_SDHCI_QUIRK2_NO_1_8_V;
- rt_dm_dev_prop_read_u32(dev, "clock-frequency", &pltfm_host->clock);
- if (rt_dm_dev_prop_read_bool(dev, "keep-power-in-suspend"))
- host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
- if (rt_dm_dev_prop_read_bool(dev, "wakeup-source") || rt_dm_dev_prop_read_bool(dev, "enable-sdio-wakeup")) /* legacy */
- host->mmc->pm_caps |= MMC_PM_WAKE_SDIO_IRQ;
- }
- struct rt_sdhci_host *rt_sdhci_pltfm_init(struct rt_platform_device *pdev,
- const struct rt_sdhci_pltfm_data *pdata,
- size_t priv_size)
- {
- struct rt_sdhci_host *host;
- struct rt_device *dev = &pdev->parent;
- void *ioaddr;
- int irq;
- ioaddr = rt_dm_dev_iomap(dev, 0);
- if (!ioaddr)
- {
- return RT_NULL;
- }
- irq = rt_dm_dev_get_irq(dev, 0);
- if (irq < 0)
- {
- return RT_NULL;
- }
- host = rt_sdhci_alloc_host(dev,sizeof(struct rt_sdhci_pltfm_host) + priv_size);
- if (!host)
- {
- return RT_NULL;
- }
- host->irq = irq;
- host->ioaddr = ioaddr;
- host->hw_name = rt_dm_dev_get_name(dev);
- if (pdata && pdata->ops)
- host->ops = pdata->ops;
- else
- host->ops = &sdhci_pltfm_ops;
- if (pdata)
- {
- host->quirks = pdata->quirks;
- host->quirks2 = pdata->quirks2;
- }
- pdev->priv = host;
- return host;
- }
- int rt_sdhci_pltfm_init_and_add_host(struct rt_platform_device *pdev,
- const struct rt_sdhci_pltfm_data *pdata,
- size_t priv_size)
- {
- struct rt_sdhci_host *host;
- int ret = 0;
- host = rt_sdhci_pltfm_init(pdev, pdata, priv_size);
- if (!host)
- return -RT_ERROR;
- rt_sdhci_get_property(pdev);
- ret = rt_sdhci_init_host(host);
- if (ret)
- rt_sdhci_pltfm_free(pdev);
- return ret;
- }
- void rt_sdhci_pltfm_free(struct rt_platform_device *pdev)
- {
- struct rt_sdhci_host *host = pdev->priv;
- rt_sdhci_free_host(host);
- }
- void rt_sdhci_pltfm_remove(struct rt_platform_device *pdev)
- {
- struct rt_sdhci_host *host = pdev->priv;
- int dead = (readl(host->ioaddr + RT_SDHCI_INT_STATUS) == 0xffffffff);
- rt_sdhci_uninit_host(host, dead);
- rt_sdhci_pltfm_free(pdev);
- }
|