sdhci-npcm.c 2.2 KB

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