[ARM] pxa: mmc: add 1st host controller support for pxa3xx
This patchis to add the first mmc controller support for pxa3xx.
It's valid for pxa3[0|1|2]0.
On zylonite, the first controller supports two slots, this patch
only support the first one right now.
Signed-off-by: Bridge Wu <bridge.wu@marvell.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index 75949eb..202d048 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -51,7 +51,7 @@
struct platform_device pxa_device_mci = {
.name = "pxa2xx-mci",
- .id = -1,
+ .id = 0,
.dev = {
.dma_mask = &pxamci_dmamask,
.coherent_dma_mask = 0xffffffff,
diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c
index c0483c3..6271af3 100644
--- a/arch/arm/mach-pxa/pxa3xx.c
+++ b/arch/arm/mach-pxa/pxa3xx.c
@@ -194,6 +194,8 @@
PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev),
PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev),
PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev),
+
+ PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev),
};
void __init pxa3xx_init_irq(void)
diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c
index 743a87b..f72f37f 100644
--- a/arch/arm/mach-pxa/zylonite.c
+++ b/arch/arm/mach-pxa/zylonite.c
@@ -25,9 +25,13 @@
#include <asm/arch/gpio.h>
#include <asm/arch/pxafb.h>
#include <asm/arch/zylonite.h>
+#include <asm/arch/mmc.h>
#include "generic.h"
+#define MAX_SLOTS 2
+struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS];
+
int gpio_backlight;
int gpio_eth_irq;
@@ -156,6 +160,87 @@
static inline void zylonite_init_lcd(void) {}
#endif
+#if defined(CONFIG_MMC)
+static int zylonite_mci_ro(struct device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+
+ return gpio_get_value(zylonite_mmc_slot[pdev->id].gpio_wp);
+}
+
+static int zylonite_mci_init(struct device *dev,
+ irq_handler_t zylonite_detect_int,
+ void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int err, cd_irq, gpio_cd, gpio_wp;
+
+ cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
+ gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
+ gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
+
+ /*
+ * setup GPIO for Zylonite MMC controller
+ */
+ err = gpio_request(gpio_cd, "mmc card detect");
+ if (err)
+ goto err_request_cd;
+ gpio_direction_input(gpio_cd);
+
+ err = gpio_request(gpio_wp, "mmc write protect");
+ if (err)
+ goto err_request_wp;
+ gpio_direction_input(gpio_wp);
+
+ err = request_irq(cd_irq, zylonite_detect_int,
+ IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
+ "MMC card detect", data);
+ if (err) {
+ printk(KERN_ERR "%s: MMC/SD/SDIO: "
+ "can't request card detect IRQ\n", __func__);
+ goto err_request_irq;
+ }
+
+ return 0;
+
+err_request_irq:
+ gpio_free(gpio_wp);
+err_request_wp:
+ gpio_free(gpio_cd);
+err_request_cd:
+ return err;
+}
+
+static void zylonite_mci_exit(struct device *dev, void *data)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ int cd_irq, gpio_cd, gpio_wp;
+
+ cd_irq = gpio_to_irq(zylonite_mmc_slot[pdev->id].gpio_cd);
+ gpio_cd = zylonite_mmc_slot[pdev->id].gpio_cd;
+ gpio_wp = zylonite_mmc_slot[pdev->id].gpio_wp;
+
+ free_irq(cd_irq, data);
+ gpio_free(gpio_cd);
+ gpio_free(gpio_wp);
+}
+
+static struct pxamci_platform_data zylonite_mci_platform_data = {
+ .detect_delay = 20,
+ .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34,
+ .init = zylonite_mci_init,
+ .exit = zylonite_mci_exit,
+ .get_ro = zylonite_mci_ro,
+};
+
+static void __init zylonite_init_mmc(void)
+{
+ pxa_set_mci_info(&zylonite_mci_platform_data);
+}
+#else
+static inline void zylonite_init_mmc(void) {}
+#endif
+
static void __init zylonite_init(void)
{
/* board-processor specific initialization */
@@ -171,6 +256,7 @@
platform_device_register(&smc91x_device);
zylonite_init_lcd();
+ zylonite_init_mmc();
}
MACHINE_START(ZYLONITE, "PXA3xx Platform Development Kit (aka Zylonite)")
diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c
index 1832bc3..cad92d4 100644
--- a/arch/arm/mach-pxa/zylonite_pxa300.c
+++ b/arch/arm/mach-pxa/zylonite_pxa300.c
@@ -88,6 +88,15 @@
GPIO4_2_KP_MKOUT_5,
GPIO5_2_KP_MKOUT_6,
GPIO6_2_KP_MKOUT_7,
+
+ /* MMC1 */
+ GPIO3_MMC1_DAT0,
+ GPIO4_MMC1_DAT1,
+ GPIO5_MMC1_DAT2,
+ GPIO6_MMC1_DAT3,
+ GPIO7_MMC1_CLK,
+ GPIO8_MMC1_CMD, /* CMD0 for slot 0 */
+ GPIO15_GPIO, /* CMD1 default as GPIO for slot 0 */
};
static mfp_cfg_t pxa300_mfp_cfg[] __initdata = {
@@ -174,6 +183,10 @@
/* GPIO pin assignment */
gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20);
+
+ /* MMC card detect & write protect for controller 0 */
+ zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0);
+ zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2);
}
if (cpu_is_pxa300()) {
diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c
index 94c7158..593f7bf 100644
--- a/arch/arm/mach-pxa/zylonite_pxa320.c
+++ b/arch/arm/mach-pxa/zylonite_pxa320.c
@@ -95,6 +95,15 @@
/* Ethernet */
GPIO4_nCS3,
GPIO90_GPIO,
+
+ /* MMC1 */
+ GPIO18_MMC1_DAT0,
+ GPIO19_MMC1_DAT1,
+ GPIO20_MMC1_DAT2,
+ GPIO21_MMC1_DAT3,
+ GPIO22_MMC1_CLK,
+ GPIO23_MMC1_CMD,/* CMD0 for slot 0 */
+ GPIO31_GPIO, /* CMD1 default as GPIO for slot 0 */
};
#define NUM_LCD_DETECT_PINS 7
@@ -169,5 +178,9 @@
/* GPIO pin assignment */
gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14);
gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9);
+
+ /* MMC card detect & write protect for controller 0 */
+ zylonite_mmc_slot[0].gpio_cd = mfp_to_gpio(MFP_PIN_GPIO1);
+ zylonite_mmc_slot[0].gpio_wp = mfp_to_gpio(MFP_PIN_GPIO5);
}
}
diff --git a/drivers/mmc/host/pxamci.h b/drivers/mmc/host/pxamci.h
index 748c770..f6c2e2f 100644
--- a/drivers/mmc/host/pxamci.h
+++ b/drivers/mmc/host/pxamci.h
@@ -68,7 +68,7 @@
#define PRG_DONE (1 << 1)
#define DATA_TRAN_DONE (1 << 0)
-#ifdef CONFIG_PXA27x
+#if defined(CONFIG_PXA27x) || defined(CONFIG_PXA3xx)
#define MMC_I_MASK_ALL 0x00001fff
#else
#define MMC_I_MASK_ALL 0x0000007f
diff --git a/include/asm-arm/arch-pxa/zylonite.h b/include/asm-arm/arch-pxa/zylonite.h
index f58b591..5f717d6 100644
--- a/include/asm-arm/arch-pxa/zylonite.h
+++ b/include/asm-arm/arch-pxa/zylonite.h
@@ -3,9 +3,18 @@
#define ZYLONITE_ETH_PHYS 0x14000000
+#define EXT_GPIO(x) (128 + (x))
+
/* the following variables are processor specific and initialized
* by the corresponding zylonite_pxa3xx_init()
*/
+struct platform_mmc_slot {
+ int gpio_cd;
+ int gpio_wp;
+};
+
+extern struct platform_mmc_slot zylonite_mmc_slot[];
+
extern int gpio_backlight;
extern int gpio_eth_irq;