Subject: [@num@/@total@] ezx: SD / MMC support Preparing pin configuration and voltage settings for the SD / MMC controller. Signed-off-by: Daniel Ribeiro PATCH FOLLOWS KernelVersion: 2.6-arm-git pxa branch Index: linux-2.6-arm/arch/arm/mach-pxa/ezx.c =================================================================== --- linux-2.6-arm.orig/arch/arm/mach-pxa/ezx.c +++ linux-2.6-arm/arch/arm/mach-pxa/ezx.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -27,6 +28,7 @@ #include #include #include +#include #include #include @@ -126,6 +128,78 @@ }, }; +/* MMC */ +static int ezx_mci_init(struct device *dev, + irqreturn_t (*detect_int)(int, void *), void *data) +{ + int err = 0; + + /* A1200 slot is not hot-plug */ + if (!machine_is_ezx_a1200()) { + err = request_irq(gpio_to_irq(11), detect_int, + IRQF_DISABLED | IRQF_SAMPLE_RANDOM | + IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + "MMC card detect", data); + } + + return err; +} + +static int ezx_pcap_mmcsd_voltage(unsigned int vdd) +{ + /* 7 is the active bit in MMC_VDD_165_195 */ + int val = (vdd == 7) ? 6 : (vdd + 1) / 2 + 3; + + if (machine_is_ezx_e680() || machine_is_ezx_e6() || + machine_is_ezx_e2()) + return ezx_pcap_set_vaux(VAUX2, VAUX_VAL, 3); + else if (machine_is_ezx_a780() || machine_is_ezx_a1200() || + machine_is_ezx_a910()) + return ezx_pcap_set_vaux(VAUX3, VAUX_VAL, val); + else + return -ENODEV; +} + +static int ezx_pcap_mmcsd_power(int on) +{ + if (machine_is_ezx_e680() || machine_is_ezx_e6() || + machine_is_ezx_e2()) + return ezx_pcap_set_vaux(VAUX2, VAUX_EN, on); + else if (machine_is_ezx_a780() || machine_is_ezx_a1200() || + machine_is_ezx_a910()) + return ezx_pcap_set_vaux(VAUX3, VAUX_EN, on); + else + return -ENODEV; +} + +static void ezx_mci_setpower(struct device *dev, unsigned int vdd) +{ + struct pxamci_platform_data *pdata = dev->platform_data; + + ezx_pcap_mmcsd_voltage(vdd); + ezx_pcap_mmcsd_power(1); +} + +static void ezx_mci_exit(struct device *dev, void *data) +{ + ezx_pcap_mmcsd_power(0); + if (!machine_is_ezx_a1200()) + free_irq(gpio_to_irq(11), data); +} + +static struct pxamci_platform_data ezx_mci_platform_data = { + .ocr_mask = MMC_VDD_165_195|MMC_VDD_20_21|MMC_VDD_21_22 + |MMC_VDD_22_23|MMC_VDD_23_24|MMC_VDD_24_25 + |MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 + |MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31 + |MMC_VDD_31_32|MMC_VDD_32_33|MMC_VDD_33_34 + |MMC_VDD_34_35|MMC_VDD_35_36, + .init = ezx_mci_init, + .setpower = ezx_mci_setpower, + .exit = ezx_mci_exit, + .detect_delay = 150 / (1000 / HZ), +}; + static struct platform_device *devices[] __initdata = { &ezx_pcap_device, &ezx_backlight_device, @@ -150,6 +224,14 @@ GPIO25_SSP1_TXD, GPIO26_SSP1_RXD, + /* MMC */ + GPIO32_MMC_CLK, + GPIO92_MMC_DAT_0, + GPIO109_MMC_DAT_1, + GPIO110_MMC_DAT_2, + GPIO111_MMC_DAT_3, + GPIO112_MMC_CMD, + /* For A780 support (connected with Neptune GSM chip) */ GPIO30_USB_P3_2, /* ICL_TXENB */ GPIO31_USB_P3_6, /* ICL_VPOUT */ @@ -170,6 +252,7 @@ } else { set_pxa_fb_info(&ezx_fb_info_2); } + pxa_set_mci_info(&ezx_mci_platform_data); platform_add_devices(devices, ARRAY_SIZE(devices)); }