@@ -15,6 +15,8 @@
#ifndef __PLAT_S3C_SDHCI_H
#define __PLAT_S3C_SDHCI_H __FILE__
+#include <plat/devs.h>
+
struct platform_device;
struct mmc_host;
struct mmc_card;
@@ -288,4 +290,21 @@ static inline void s5pv210_default_sdhci3(void) { }
#endif /* CONFIG_S5PV210_SETUP_SDHCI */
+/* re-define device name depending on support. */
+static inline void s3c_hsmmc_setname(char *name)
+{
+#ifdef CONFIG_S3C_DEV_HSMMC
+ s3c_device_hsmmc0.name = name;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC1
+ s3c_device_hsmmc1.name = name;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC2
+ s3c_device_hsmmc2.name = name;
+#endif
+#ifdef CONFIG_S3C_DEV_HSMMC3
+ s3c_device_hsmmc3.name = name;
+#endif
+}
+
#endif /* __PLAT_S3C_SDHCI_H */
@@ -52,6 +52,11 @@ struct sdhci_s3c {
struct clk *clk_bus[MAX_BUS_CLK];
};
+enum soc_type {
+ TYPE_SAMSUNG, /* S5PC1XX, S3C... */
+ TYPE_S5PC210, /* S5PC210 */
+};
+
static inline struct sdhci_s3c *to_s3c(struct sdhci_host *host)
{
return sdhci_priv(host);
@@ -232,6 +237,52 @@ static unsigned int sdhci_s3c_get_min_clock(struct sdhci_host *host)
return min;
}
+/**
+* sdhci_s3c_get_max_clk - callback to get maximum clock frequency.
+*/
+static unsigned int sdhci_s5pc210_get_max_clock(struct sdhci_host *host)
+{
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ unsigned int rate;
+ int ptr = ourhost->cur_clk;
+
+ rate = clk_round_rate(ourhost->clk_bus[ptr], UINT_MAX);
+
+ return rate;
+}
+
+/**
+ * sdhci_s3c_get_min_clock - callback to get minimal supported clock value
+*/
+static unsigned int sdhci_s5pc210_get_min_clock(struct sdhci_host *host)
+{
+ struct sdhci_s3c *ourhost = to_s3c(host);
+ unsigned int rate;
+ int ptr = ourhost->cur_clk;
+
+ rate = clk_round_rate(ourhost->clk_bus[ptr], 400000);
+
+ return rate;
+}
+
+/**
+ * sdhci_s5pc210_set_clock - callback on clock change
+*/
+static void sdhci_s5pc210_set_clock(struct sdhci_host *host,
+ unsigned int clock)
+{
+ struct sdhci_s3c *ourhost = to_s3c(host);
+
+ if (clock == 0)
+ return;
+
+ sdhci_s3c_set_clock(host, clock);
+
+ clk_set_rate(ourhost->clk_bus[ourhost->cur_clk], clock);
+
+ host->clock = clock;
+}
+
static struct sdhci_ops sdhci_s3c_ops = {
.get_max_clock = sdhci_s3c_get_max_clk,
.set_clock = sdhci_s3c_set_clock,
@@ -395,6 +446,12 @@ static int __devinit sdhci_s3c_probe(struct platform_device *pdev)
host->quirks = 0;
host->irq = irq;
+ if (pdev->id_entry->driver_data == TYPE_S5PC210) {
+ sdhci_s3c_ops.set_clock = sdhci_s5pc210_set_clock;
+ sdhci_s3c_ops.get_min_clock = sdhci_s5pc210_get_min_clock;
+ sdhci_s3c_ops.get_max_clock = sdhci_s5pc210_get_max_clock;
+ }
+
/* Setup quirks for the controller */
host->quirks |= SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC;
host->quirks |= SDHCI_QUIRK_NO_HISPD_BIT;
@@ -520,6 +577,16 @@ static int sdhci_s3c_resume(struct platform_device *dev)
#define sdhci_s3c_resume NULL
#endif
+static struct platform_device_id sdhci_driver_ids[] = {
+ {
+ .name = "s3c-sdhci",
+ .driver_data = TYPE_SAMSUNG,
+ }, {
+ .name = "s5pc210-sdhci",
+ .driver_data = TYPE_S5PC210,
+ }, { },
+};
+
static struct platform_driver sdhci_s3c_driver = {
.probe = sdhci_s3c_probe,
.remove = __devexit_p(sdhci_s3c_remove),
@@ -529,6 +596,7 @@ static struct platform_driver sdhci_s3c_driver = {
.owner = THIS_MODULE,
.name = "s3c-sdhci",
},
+ .id_table = sdhci_driver_ids,
};
static int __init sdhci_s3c_init(void)