aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Rapoport <mike@compulab.co.il>2009-02-02 01:57:51 -0500
committerEric Miao <eric.miao@marvell.com>2009-02-02 04:40:16 -0500
commit6432f46c4ffd0a85cab5313bc989a6db32bc0eb4 (patch)
treee2c72256bc068043d544c764443d1406db4e336a
parent6489c611db095356645ca1a2689e93c63caeb310 (diff)
[ARM] pxa/em-x270: update MMC/SDIO implementation
Signed-off-by: Mike Rapoport <mike@compulab.co.il> Signed-off-by: Eric Miao <eric.miao@marvell.com>
-rw-r--r--arch/arm/mach-pxa/em-x270.c97
1 files changed, 81 insertions, 16 deletions
diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c
index 1aaae97de7d3..05f9e9e1224b 100644
--- a/arch/arm/mach-pxa/em-x270.c
+++ b/arch/arm/mach-pxa/em-x270.c
@@ -43,12 +43,12 @@
43#include <mach/pxa2xx_spi.h> 43#include <mach/pxa2xx_spi.h>
44 44
45#include "generic.h" 45#include "generic.h"
46#include "devices.h"
46 47
47/* GPIO IRQ usage */ 48/* GPIO IRQ usage */
48#define GPIO41_ETHIRQ (41) 49#define GPIO41_ETHIRQ (41)
49#define GPIO13_MMC_CD (13) 50#define GPIO13_MMC_CD (13)
50#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ) 51#define EM_X270_ETHIRQ IRQ_GPIO(GPIO41_ETHIRQ)
51#define EM_X270_MMC_CD IRQ_GPIO(GPIO13_MMC_CD)
52 52
53/* NAND control GPIOs */ 53/* NAND control GPIOs */
54#define GPIO11_NAND_CS (11) 54#define GPIO11_NAND_CS (11)
@@ -56,6 +56,7 @@
56 56
57/* Miscelaneous GPIOs */ 57/* Miscelaneous GPIOs */
58#define GPIO93_CAM_RESET (93) 58#define GPIO93_CAM_RESET (93)
59#define GPIO95_MMC_WP (95)
59 60
60static unsigned long em_x270_pin_config[] = { 61static unsigned long em_x270_pin_config[] = {
61 /* AC'97 */ 62 /* AC'97 */
@@ -163,7 +164,8 @@ static unsigned long em_x270_pin_config[] = {
163 GPIO18_RDY, 164 GPIO18_RDY,
164 165
165 /* GPIO */ 166 /* GPIO */
166 GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, 167 GPIO1_GPIO | WAKEUP_ON_EDGE_BOTH, /* sleep/resume button */
168 GPIO95_GPIO, /* MMC Write protect */
167 169
168 /* power controls */ 170 /* power controls */
169 GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */ 171 GPIO20_GPIO | MFP_LPM_DRIVE_LOW, /* GPRS_PWEN */
@@ -464,47 +466,86 @@ static inline void em_x270_init_ohci(void) {}
464 466
465/* MCI controller setup */ 467/* MCI controller setup */
466#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE) 468#if defined(CONFIG_MMC) || defined(CONFIG_MMC_MODULE)
469static struct regulator *em_x270_sdio_ldo;
470
467static int em_x270_mci_init(struct device *dev, 471static int em_x270_mci_init(struct device *dev,
468 irq_handler_t em_x270_detect_int, 472 irq_handler_t em_x270_detect_int,
469 void *data) 473 void *data)
470{ 474{
471 int err = request_irq(EM_X270_MMC_CD, em_x270_detect_int, 475 int err;
472 IRQF_DISABLED | IRQF_TRIGGER_FALLING, 476
477 em_x270_sdio_ldo = regulator_get(dev, "vcc sdio");
478 if (IS_ERR(em_x270_sdio_ldo)) {
479 dev_err(dev, "can't request SDIO power supply: %ld\n",
480 PTR_ERR(em_x270_sdio_ldo));
481 return PTR_ERR(em_x270_sdio_ldo);
482 }
483
484 err = request_irq(gpio_to_irq(GPIO13_MMC_CD), em_x270_detect_int,
485 IRQF_DISABLED | IRQF_TRIGGER_RISING |
486 IRQF_TRIGGER_FALLING,
473 "MMC card detect", data); 487 "MMC card detect", data);
474 if (err) { 488 if (err) {
475 printk(KERN_ERR "%s: can't request MMC card detect IRQ: %d\n", 489 dev_err(dev, "can't request MMC card detect IRQ: %d\n", err);
476 __func__, err); 490 goto err_irq;
477 return err; 491 }
492
493 err = gpio_request(GPIO95_MMC_WP, "MMC WP");
494 if (err) {
495 dev_err(dev, "can't request MMC write protect: %d\n", err);
496 goto err_gpio_wp;
478 } 497 }
479 498
499 gpio_direction_input(GPIO95_MMC_WP);
500
480 return 0; 501 return 0;
502
503err_gpio_wp:
504 free_irq(gpio_to_irq(GPIO13_MMC_CD), data);
505err_irq:
506 regulator_put(em_x270_sdio_ldo);
507
508 return err;
481} 509}
482 510
483static void em_x270_mci_setpower(struct device *dev, unsigned int vdd) 511static void em_x270_mci_setpower(struct device *dev, unsigned int vdd)
484{ 512{
485 /* 513 struct pxamci_platform_data* p_d = dev->platform_data;
486 FIXME: current hardware implementation does not allow to 514
487 enable/disable MMC power. This will be fixed in next HW releases, 515 if ((1 << vdd) & p_d->ocr_mask) {
488 and we'll need to add implmentation here. 516 int vdd_uV = (2000 + (vdd - __ffs(MMC_VDD_20_21)) * 100) * 1000;
489 */ 517
490 return; 518 regulator_set_voltage(em_x270_sdio_ldo, vdd_uV, vdd_uV);
519 regulator_enable(em_x270_sdio_ldo);
520 } else {
521 regulator_disable(em_x270_sdio_ldo);
522 }
491} 523}
492 524
493static void em_x270_mci_exit(struct device *dev, void *data) 525static void em_x270_mci_exit(struct device *dev, void *data)
494{ 526{
495 int irq = gpio_to_irq(GPIO13_MMC_CD); 527 free_irq(gpio_to_irq(GPIO13_MMC_CD), data);
496 free_irq(irq, data); 528}
529
530static int em_x270_mci_get_ro(struct device *dev)
531{
532 return gpio_get_value(GPIO95_MMC_WP);
497} 533}
498 534
499static struct pxamci_platform_data em_x270_mci_platform_data = { 535static struct pxamci_platform_data em_x270_mci_platform_data = {
500 .ocr_mask = MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31, 536 .ocr_mask = MMC_VDD_20_21|MMC_VDD_21_22|MMC_VDD_22_23|
537 MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
538 MMC_VDD_27_28|MMC_VDD_28_29|MMC_VDD_29_30|
539 MMC_VDD_30_31|MMC_VDD_31_32,
501 .init = em_x270_mci_init, 540 .init = em_x270_mci_init,
502 .setpower = em_x270_mci_setpower, 541 .setpower = em_x270_mci_setpower,
542 .get_ro = em_x270_mci_get_ro,
503 .exit = em_x270_mci_exit, 543 .exit = em_x270_mci_exit,
504}; 544};
505 545
506static void __init em_x270_init_mmc(void) 546static void __init em_x270_init_mmc(void)
507{ 547{
548 em_x270_mci_platform_data.detect_delay = msecs_to_jiffies(250);
508 pxa_set_mci_info(&em_x270_mci_platform_data); 549 pxa_set_mci_info(&em_x270_mci_platform_data);
509} 550}
510#else 551#else
@@ -757,6 +798,13 @@ static struct regulator_consumer_supply ldo5_consumers[] = {
757 }, 798 },
758}; 799};
759 800
801static struct regulator_consumer_supply ldo10_consumers[] = {
802 {
803 .dev = &pxa_device_mci.dev,
804 .supply = "vcc sdio",
805 },
806};
807
760static struct regulator_consumer_supply ldo12_consumers[] = { 808static struct regulator_consumer_supply ldo12_consumers[] = {
761 { 809 {
762 .dev = NULL, 810 .dev = NULL,
@@ -795,6 +843,19 @@ static struct regulator_init_data ldo5_data = {
795 .consumer_supplies = ldo5_consumers, 843 .consumer_supplies = ldo5_consumers,
796}; 844};
797 845
846static struct regulator_init_data ldo10_data = {
847 .constraints = {
848 .min_uV = 2000000,
849 .max_uV = 3200000,
850 .state_mem = {
851 .enabled = 0,
852 },
853 .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_STATUS,
854 },
855 .num_consumer_supplies = ARRAY_SIZE(ldo10_consumers),
856 .consumer_supplies = ldo10_consumers,
857};
858
798static struct regulator_init_data ldo12_data = { 859static struct regulator_init_data ldo12_data = {
799 .constraints = { 860 .constraints = {
800 .min_uV = 3000000, 861 .min_uV = 3000000,
@@ -835,6 +896,10 @@ struct da903x_subdev_info em_x270_da9030_subdevs[] = {
835 .platform_data = &ldo5_data, 896 .platform_data = &ldo5_data,
836 }, { 897 }, {
837 .name = "da903x-regulator", 898 .name = "da903x-regulator",
899 .id = DA9030_ID_LDO10,
900 .platform_data = &ldo10_data,
901 }, {
902 .name = "da903x-regulator",
838 .id = DA9030_ID_LDO12, 903 .id = DA9030_ID_LDO12,
839 .platform_data = &ldo12_data, 904 .platform_data = &ldo12_data,
840 }, { 905 }, {