summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-s3c64xx/setup-sdhci-gpio.c15
-rw-r--r--arch/arm/mach-s5pc100/setup-sdhci-gpio.c22
-rw-r--r--arch/arm/mach-s5pv210/setup-sdhci-gpio.c22
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc.c5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc1.c5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc2.c5
-rw-r--r--arch/arm/plat-samsung/dev-hsmmc3.c5
-rw-r--r--arch/arm/plat-samsung/include/plat/sdhci.h29
8 files changed, 92 insertions, 16 deletions
diff --git a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
index a58c0cc7ba5e..4a42ede99025 100644
--- a/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s3c64xx/setup-sdhci-gpio.c
@@ -19,9 +19,11 @@
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
+#include <plat/sdhci.h>
void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
@@ -33,12 +35,15 @@ void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
- s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(2));
+ }
}
void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
@@ -50,8 +55,10 @@ void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
- s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S3C64XX_GPG(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S3C64XX_GPG(6), S3C_GPIO_SFN(3));
+ }
}
void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
diff --git a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
index 7769c760c9ef..dc7208c639ea 100644
--- a/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pc100/setup-sdhci-gpio.c
@@ -20,9 +20,11 @@
#include <plat/gpio-cfg.h>
#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
unsigned int num;
@@ -47,12 +49,15 @@ void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
}
}
- s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PC100_GPG1(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PC100_GPG1(2), S3C_GPIO_SFN(2));
+ }
}
void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
@@ -64,12 +69,15 @@ void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
- s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PC100_GPG2(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PC100_GPG2(6), S3C_GPIO_SFN(2));
+ }
}
void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
unsigned int end;
@@ -81,6 +89,8 @@ void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
- s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PC100_GPG3(6), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PC100_GPG3(6), S3C_GPIO_SFN(2));
+ }
}
diff --git a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
index fe7d86dad14c..b3ad2439e34b 100644
--- a/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
+++ b/arch/arm/mach-s5pv210/setup-sdhci-gpio.c
@@ -21,9 +21,11 @@
#include <mach/gpio.h>
#include <plat/gpio-cfg.h>
#include <plat/regs-sdhci.h>
+#include <plat/sdhci.h>
void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG0/GPG1 pins to special-function 2 */
@@ -48,12 +50,15 @@ void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *dev, int width)
break;
}
- s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG0(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG0(2), S3C_GPIO_SFN(2));
+ }
}
void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG1[0:1] pins to special-function 2 */
@@ -68,12 +73,15 @@ void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *dev, int width)
s3c_gpio_setpull(gpio, S3C_GPIO_PULL_NONE);
}
- s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG1(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG1(2), S3C_GPIO_SFN(2));
+ }
}
void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
{
+ struct s3c_sdhci_platdata *pdata = dev->dev.platform_data;
unsigned int gpio;
/* Set all the necessary GPG2[0:1] pins to special-function 2 */
@@ -99,6 +107,8 @@ void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *dev, int width)
break;
}
- s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
- s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
+ if (pdata->cd_type == S3C_SDHCI_CD_INTERNAL) {
+ s3c_gpio_setpull(S5PV210_GPG2(2), S3C_GPIO_PULL_UP);
+ s3c_gpio_cfgpin(S5PV210_GPG2(2), S3C_GPIO_SFN(2));
+ }
}
diff --git a/arch/arm/plat-samsung/dev-hsmmc.c b/arch/arm/plat-samsung/dev-hsmmc.c
index 4c05b39810e2..b0f93f11e281 100644
--- a/arch/arm/plat-samsung/dev-hsmmc.c
+++ b/arch/arm/plat-samsung/dev-hsmmc.c
@@ -60,6 +60,11 @@ void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd)
struct s3c_sdhci_platdata *set = &s3c_hsmmc0_def_platdata;
set->max_width = pd->max_width;
+ set->cd_type = pd->cd_type;
+ set->ext_cd_init = pd->ext_cd_init;
+ set->ext_cd_cleanup = pd->ext_cd_cleanup;
+ set->ext_cd_gpio = pd->ext_cd_gpio;
+ set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/dev-hsmmc1.c b/arch/arm/plat-samsung/dev-hsmmc1.c
index e49bc4cd0ee6..1504fd802865 100644
--- a/arch/arm/plat-samsung/dev-hsmmc1.c
+++ b/arch/arm/plat-samsung/dev-hsmmc1.c
@@ -60,6 +60,11 @@ void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd)
struct s3c_sdhci_platdata *set = &s3c_hsmmc1_def_platdata;
set->max_width = pd->max_width;
+ set->cd_type = pd->cd_type;
+ set->ext_cd_init = pd->ext_cd_init;
+ set->ext_cd_cleanup = pd->ext_cd_cleanup;
+ set->ext_cd_gpio = pd->ext_cd_gpio;
+ set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/dev-hsmmc2.c b/arch/arm/plat-samsung/dev-hsmmc2.c
index 824580bc0e06..b28ef173444d 100644
--- a/arch/arm/plat-samsung/dev-hsmmc2.c
+++ b/arch/arm/plat-samsung/dev-hsmmc2.c
@@ -61,6 +61,11 @@ void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd)
struct s3c_sdhci_platdata *set = &s3c_hsmmc2_def_platdata;
set->max_width = pd->max_width;
+ set->cd_type = pd->cd_type;
+ set->ext_cd_init = pd->ext_cd_init;
+ set->ext_cd_cleanup = pd->ext_cd_cleanup;
+ set->ext_cd_gpio = pd->ext_cd_gpio;
+ set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/dev-hsmmc3.c b/arch/arm/plat-samsung/dev-hsmmc3.c
index 57bd394123cd..85aaf0f2842f 100644
--- a/arch/arm/plat-samsung/dev-hsmmc3.c
+++ b/arch/arm/plat-samsung/dev-hsmmc3.c
@@ -64,6 +64,11 @@ void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd)
struct s3c_sdhci_platdata *set = &s3c_hsmmc3_def_platdata;
set->max_width = pd->max_width;
+ set->cd_type = pd->cd_type;
+ set->ext_cd_init = pd->ext_cd_init;
+ set->ext_cd_cleanup = pd->ext_cd_cleanup;
+ set->ext_cd_gpio = pd->ext_cd_gpio;
+ set->ext_cd_gpio_invert = pd->ext_cd_gpio_invert;
if (pd->cfg_gpio)
set->cfg_gpio = pd->cfg_gpio;
diff --git a/arch/arm/plat-samsung/include/plat/sdhci.h b/arch/arm/plat-samsung/include/plat/sdhci.h
index 3994a875473b..3880cc736a98 100644
--- a/arch/arm/plat-samsung/include/plat/sdhci.h
+++ b/arch/arm/plat-samsung/include/plat/sdhci.h
@@ -20,10 +20,31 @@ struct mmc_host;
struct mmc_card;
struct mmc_ios;
+enum cd_types {
+ S3C_SDHCI_CD_INTERNAL, /* use mmc internal CD line */
+ S3C_SDHCI_CD_EXTERNAL, /* use external callback */
+ S3C_SDHCI_CD_GPIO, /* use external gpio pin for CD line */
+ S3C_SDHCI_CD_NONE, /* no CD line, use polling to detect card */
+ S3C_SDHCI_CD_PERMANENT, /* no CD line, card permanently wired to host */
+};
+
/**
* struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
* @max_width: The maximum number of data bits supported.
* @host_caps: Standard MMC host capabilities bit field.
+ * @cd_type: Type of Card Detection method (see cd_types enum above)
+ * @ext_cd_init: Initialize external card detect subsystem. Called on
+ * sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
+ * notify_func argument is a callback to the sdhci-s3c driver
+ * that triggers the card detection event. Callback arguments:
+ * dev is pointer to platform device of the host controller,
+ * state is new state of the card (0 - removed, 1 - inserted).
+ * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on
+ * sdhci-s3c driver remove when cd_type == S3C_SDHCI_CD_EXTERNAL.
+ * notify_func argument is the same callback as for ext_cd_init.
+ * @ext_cd_gpio: gpio pin used for external CD line, valid only if
+ * cd_type == S3C_SDHCI_CD_GPIO
+ * @ext_cd_gpio_invert: invert values for external CD gpio line
* @cfg_gpio: Configure the GPIO for a specific card bit-width
* @cfg_card: Configure the interface for a specific card and speed. This
* is necessary the controllers and/or GPIO blocks require the
@@ -37,9 +58,17 @@ struct mmc_ios;
struct s3c_sdhci_platdata {
unsigned int max_width;
unsigned int host_caps;
+ enum cd_types cd_type;
char **clocks; /* set of clock sources */
+ int ext_cd_gpio;
+ bool ext_cd_gpio_invert;
+ int (*ext_cd_init)(void (*notify_func)(struct platform_device *,
+ int state));
+ int (*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
+ int state));
+
void (*cfg_gpio)(struct platform_device *dev, int width);
void (*cfg_card)(struct platform_device *dev,
void __iomem *regbase,