// SPDX-License-Identifier: GPL-2.0+ /* * Support of SDHCI for Microchip PIC32 SoC. * * Copyright (C) 2015 Microchip Technology Inc. * Andrei Pistirica */ #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; static int pic32_sdhci_get_cd(struct sdhci_host *host) { /* PIC32 SDHCI CD errata: * - set CD_TEST and clear CD_TEST_INS bit */ sdhci_writeb(host, SDHCI_CTRL_CD_TEST, SDHCI_HOST_CONTROL); return 0; } static const struct sdhci_ops pic32_sdhci_ops = { .get_cd = pic32_sdhci_get_cd, }; static int pic32_sdhci_probe(struct udevice *dev) { struct sdhci_host *host = dev_get_priv(dev); const void *fdt = gd->fdt_blob; u32 f_min_max[2]; fdt_addr_t addr; fdt_size_t size; int ret; addr = fdtdec_get_addr_size(fdt, dev_of_offset(dev), "reg", &size); if (addr == FDT_ADDR_T_NONE) return -EINVAL; host->ioaddr = ioremap(addr, size); host->name = dev->name; host->quirks = SDHCI_QUIRK_NO_HISPD_BIT; host->bus_width = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev), "bus-width", 4); host->ops = &pic32_sdhci_ops; ret = fdtdec_get_int_array(gd->fdt_blob, dev_of_offset(dev), "clock-freq-min-max", f_min_max, 2); if (ret) { printf("sdhci: clock-freq-min-max not found\n"); return ret; } host->max_clk = f_min_max[1]; ret = add_sdhci(host, 0, f_min_max[0]); if (ret) return ret; host->mmc->dev = dev; return 0; } static const struct udevice_id pic32_sdhci_ids[] = { { .compatible = "microchip,pic32mzda-sdhci" }, { } }; U_BOOT_DRIVER(pic32_sdhci_drv) = { .name = "pic32_sdhci", .id = UCLASS_MMC, .of_match = pic32_sdhci_ids, .probe = pic32_sdhci_probe, .priv_auto_alloc_size = sizeof(struct sdhci_host), };