1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * NPCM SDHC MMC host controller driver. 4 * 5 * Copyright (c) 2023 Nuvoton Technology corporation. 6 */ 7 8 #include <linux/clk.h> 9 #include <linux/err.h> 10 #include <linux/io.h> 11 #include <linux/mmc/host.h> 12 #include <linux/mmc/mmc.h> 13 #include <linux/mod_devicetable.h> 14 #include <linux/module.h> 15 #include <linux/of.h> 16 17 #include "sdhci-pltfm.h" 18 19 static const struct sdhci_pltfm_data npcm7xx_sdhci_pdata = { 20 .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER, 21 .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC | 22 SDHCI_QUIRK2_NO_1_8_V, 23 }; 24 25 static const struct sdhci_pltfm_data npcm8xx_sdhci_pdata = { 26 .quirks = SDHCI_QUIRK_DELAY_AFTER_POWER, 27 .quirks2 = SDHCI_QUIRK2_STOP_WITH_TC, 28 }; 29 30 static int npcm_sdhci_probe(struct platform_device *pdev) 31 { 32 const struct sdhci_pltfm_data *data; 33 struct sdhci_pltfm_host *pltfm_host; 34 struct device *dev = &pdev->dev; 35 struct sdhci_host *host; 36 u32 caps; 37 int ret; 38 39 data = of_device_get_match_data(dev); 40 if (!data) 41 return -EINVAL; 42 43 host = sdhci_pltfm_init(pdev, data, 0); 44 if (IS_ERR(host)) 45 return PTR_ERR(host); 46 47 pltfm_host = sdhci_priv(host); 48 49 pltfm_host->clk = devm_clk_get_optional_enabled(dev, NULL); 50 if (IS_ERR(pltfm_host->clk)) { 51 ret = PTR_ERR(pltfm_host->clk); 52 goto err_sdhci; 53 } 54 55 caps = sdhci_readl(host, SDHCI_CAPABILITIES); 56 if (caps & SDHCI_CAN_DO_8BIT) 57 host->mmc->caps |= MMC_CAP_8_BIT_DATA; 58 59 ret = mmc_of_parse(host->mmc); 60 if (ret) 61 goto err_sdhci; 62 63 ret = sdhci_add_host(host); 64 if (ret) 65 goto err_sdhci; 66 67 return 0; 68 69 err_sdhci: 70 sdhci_pltfm_free(pdev); 71 return ret; 72 } 73 74 static const struct of_device_id npcm_sdhci_of_match[] = { 75 { .compatible = "nuvoton,npcm750-sdhci", .data = &npcm7xx_sdhci_pdata }, 76 { .compatible = "nuvoton,npcm845-sdhci", .data = &npcm8xx_sdhci_pdata }, 77 { } 78 }; 79 MODULE_DEVICE_TABLE(of, npcm_sdhci_of_match); 80 81 static struct platform_driver npcm_sdhci_driver = { 82 .driver = { 83 .name = "npcm-sdhci", 84 .of_match_table = npcm_sdhci_of_match, 85 .pm = &sdhci_pltfm_pmops, 86 }, 87 .probe = npcm_sdhci_probe, 88 .remove = sdhci_pltfm_remove, 89 }; 90 module_platform_driver(npcm_sdhci_driver); 91 92 MODULE_DESCRIPTION("NPCM Secure Digital Host Controller Interface driver"); 93 MODULE_AUTHOR("Tomer Maimon <tomer.maimon@nuvoton.com>"); 94 MODULE_LICENSE("GPL"); 95