]>
Commit | Line | Data |
---|---|---|
3363a73d JL |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Copyright (c) 2022 Nuvoton Technology Corp. | |
4 | */ | |
5 | ||
6 | #include <common.h> | |
7 | #include <dm.h> | |
8 | #include <sdhci.h> | |
9 | #include <clk.h> | |
10 | #include <power/regulator.h> | |
11 | ||
12 | #define NPCM_SDHC_MIN_FREQ 400000 | |
13 | ||
14 | struct npcm_sdhci_plat { | |
15 | struct mmc_config cfg; | |
16 | struct mmc mmc; | |
17 | }; | |
18 | ||
19 | static int npcm_sdhci_probe(struct udevice *dev) | |
20 | { | |
21 | struct npcm_sdhci_plat *plat = dev_get_plat(dev); | |
22 | struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); | |
23 | struct sdhci_host *host = dev_get_priv(dev); | |
24 | struct udevice *vqmmc_supply; | |
25 | int vqmmc_uv, ret; | |
26 | struct clk clk; | |
27 | ||
28 | host->name = dev->name; | |
29 | host->ioaddr = dev_read_addr_ptr(dev); | |
30 | host->max_clk = dev_read_u32_default(dev, "clock-frequency", 0); | |
31 | ||
32 | ret = clk_get_by_index(dev, 0, &clk); | |
33 | if (!ret && host->max_clk) { | |
34 | ret = clk_set_rate(&clk, host->max_clk); | |
35 | if (ret < 0) | |
36 | return ret; | |
37 | } | |
38 | ||
6419dbab | 39 | if (CONFIG_IS_ENABLED(DM_REGULATOR)) { |
3363a73d JL |
40 | device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_supply); |
41 | vqmmc_uv = dev_read_u32_default(dev, "vqmmc-microvolt", 0); | |
42 | /* Set IO voltage */ | |
43 | if (vqmmc_supply && vqmmc_uv) | |
44 | regulator_set_value(vqmmc_supply, vqmmc_uv); | |
45 | } | |
46 | ||
47 | host->index = dev_read_u32_default(dev, "index", 0); | |
48 | ret = mmc_of_parse(dev, &plat->cfg); | |
49 | if (ret) | |
50 | return ret; | |
51 | ||
52 | host->mmc = &plat->mmc; | |
53 | host->mmc->priv = host; | |
54 | host->mmc->dev = dev; | |
55 | upriv->mmc = host->mmc; | |
56 | ||
57 | ret = sdhci_setup_cfg(&plat->cfg, host, 0, NPCM_SDHC_MIN_FREQ); | |
58 | if (ret) | |
59 | return ret; | |
60 | ||
61 | return sdhci_probe(dev); | |
62 | } | |
63 | ||
64 | static int npcm_sdhci_bind(struct udevice *dev) | |
65 | { | |
66 | struct npcm_sdhci_plat *plat = dev_get_plat(dev); | |
67 | ||
68 | return sdhci_bind(dev, &plat->mmc, &plat->cfg); | |
69 | } | |
70 | ||
71 | static const struct udevice_id npcm_mmc_ids[] = { | |
72 | { .compatible = "nuvoton,npcm750-sdhci" }, | |
73 | { .compatible = "nuvoton,npcm845-sdhci" }, | |
74 | { } | |
75 | }; | |
76 | ||
77 | U_BOOT_DRIVER(npcm_sdhci_drv) = { | |
78 | .name = "npcm_sdhci", | |
79 | .id = UCLASS_MMC, | |
80 | .of_match = npcm_mmc_ids, | |
81 | .ops = &sdhci_ops, | |
82 | .bind = npcm_sdhci_bind, | |
83 | .probe = npcm_sdhci_probe, | |
84 | .priv_auto = sizeof(struct sdhci_host), | |
85 | .plat_auto = sizeof(struct npcm_sdhci_plat), | |
86 | }; |