Changes the glamo-mci driver to use the regulator API.
---

 arch/arm/mach-s3c2440/mach-gta02.c |   85 ++++++++++++++----------------------
 drivers/mfd/glamo/glamo-core.c     |   28 ++++++------
 drivers/mfd/glamo/glamo-core.h     |    3 -
 drivers/mfd/glamo/glamo-mci.c      |   41 ++++++++++++++++-
 drivers/mfd/glamo/glamo-mci.h      |    3 +
 include/linux/glamofb.h            |    6 ++-
 6 files changed, 92 insertions(+), 74 deletions(-)

diff --git a/arch/arm/mach-s3c2440/mach-gta02.c 
b/arch/arm/mach-s3c2440/mach-gta02.c
index 6a96092..3143d51 100644
--- a/arch/arm/mach-s3c2440/mach-gta02.c
+++ b/arch/arm/mach-s3c2440/mach-gta02.c
@@ -568,6 +568,20 @@ static struct regulator_consumer_supply ldo4_consumers[] = 
{
        },
 };
 
+/*
+ * We need this dummy thing to fill the regulator consumers
+ */
+static struct platform_device gta02_mmc_dev = {
+       /* details filled in by glamo core */
+};
+
+static struct regulator_consumer_supply hcldo_consumers[] = {
+       {
+               .dev = &gta02_mmc_dev.dev,
+               .supply = "SD_3V3",
+       },
+};
+
 struct pcf50633_platform_data gta02_pcf_pdata = {
        .used_features  = PCF50633_FEAT_MBC |
                          PCF50633_FEAT_BBC |
@@ -696,6 +710,15 @@ struct pcf50633_platform_data gta02_pcf_pdata = {
                        .num_consumer_supplies = 1,
                        .consumer_supplies = ldo4_consumers,
                },
+               [PCF50633_REGULATOR_HCLDO] = {
+                       .constraints = {
+                               .min_uV = 2000000,
+                               .max_uV = 3300000,
+                               .valid_modes_mask = REGULATOR_MODE_NORMAL,
+                       },
+                       .num_consumer_supplies = 1,
+                       .consumer_supplies = hcldo_consumers,
+               },
 
        },
 
@@ -1427,61 +1450,18 @@ static int glamo_irq_is_wired(void)
        return -ENODEV;
 }
 
-
-static void
-gta02_glamo_mmc_set_power(unsigned char power_mode, unsigned short vdd)
+static int gta02_glamo_can_set_mmc_power(void)
 {
-       int mv = 1650;
-       int timeout = 500;
-
-       printk(KERN_DEBUG "mmc_set_power(power_mode=%u, vdd=%u)\n",
-              power_mode, vdd);
-
        switch (system_rev) {
-       case GTA02v1_SYSTEM_REV:
-       case GTA02v2_SYSTEM_REV:
-               break;
-       case GTA02v3_SYSTEM_REV:
-       case GTA02v4_SYSTEM_REV:
-       case GTA02v5_SYSTEM_REV:
-       case GTA02v6_SYSTEM_REV:
-               switch (power_mode) {
-               case MMC_POWER_ON:
-               case MMC_POWER_UP:
-                       /* depend on pcf50633 driver init + not suspended */
-                       while (pcf50633_ready(gta02_pcf_pdata.pcf) && 
(timeout--))
-                               msleep(5);
-
-                       if (timeout < 0) {
-                               printk(KERN_ERR"gta02_glamo_mmc_set_power "
-                                            "BAILING on timeout\n");
-                               return;
-                       }
-                       /* select and set the voltage */
-                       if (vdd > 7)
-                               mv += 350 + 100 * (vdd - 8);
-                       printk(KERN_INFO "SD power -> %dmV\n", mv);
-                       pcf50633_voltage_set(gta02_pcf_pdata.pcf,
-                                            PCF50633_REGULATOR_HCLDO, mv);
-                       pcf50633_onoff_set(gta02_pcf_pdata.pcf,
-                                          PCF50633_REGULATOR_HCLDO, 1);
-                       break;
-               case MMC_POWER_OFF:
-                       /* power off happens during suspend, when pcf50633 can
-                        * be already gone and not coming back... just forget
-                        * the action then because pcf50633 suspend already
-                        * dealt with it, otherwise we spin forever
-                        */
-                       if (pcf50633_ready(gta02_pcf_pdata.pcf))
-                               return;
-                       pcf50633_onoff_set(gta02_pcf_pdata.pcf,
-                                          PCF50633_REGULATOR_HCLDO, 0);
-                       break;
-               }
-               break;
+               case GTA02v3_SYSTEM_REV:
+               case GTA02v4_SYSTEM_REV:
+               case GTA02v5_SYSTEM_REV:
+               case GTA02v6_SYSTEM_REV:
+                       return 1;
        }
-}
 
+       return 0;
+}
 
 /* Smedia Glamo 3362 */
 
@@ -1531,7 +1511,8 @@ static struct glamofb_platform_data gta02_glamo_pdata = {
        .spigpio_info   = &glamo_spigpio_cfg,
 
        /* glamo MMC function platform data */
-       .glamo_set_mci_power = gta02_glamo_mmc_set_power,
+       .mmc_dev = &gta02_mmc_dev,
+       .glamo_can_set_mci_power = gta02_glamo_can_set_mmc_power,
        .glamo_mci_use_slow = gta02_glamo_mci_use_slow,
        .glamo_irq_is_wired = glamo_irq_is_wired,
        .glamo_external_reset = gta02_glamo_external_reset
diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
index 140cd98..624703b 100644
--- a/drivers/mfd/glamo/glamo-core.c
+++ b/drivers/mfd/glamo/glamo-core.c
@@ -288,15 +288,9 @@ static struct resource glamo_mmc_resources[] = {
        },
 };
 
-static struct platform_device glamo_mmc_dev = {
-       .name           = "glamo-mci",
-       .resource       = glamo_mmc_resources,
-       .num_resources  = ARRAY_SIZE(glamo_mmc_resources),
-};
-
 struct glamo_mci_pdata glamo_mci_def_pdata = {
        .gpio_detect            = 0,
-       .glamo_set_mci_power    = NULL, /* filled in from MFD platform data */
+       .glamo_can_set_mci_power        = NULL, /* filled in from MFD platform 
data */
        .ocr_avail      = MMC_VDD_20_21 |
                          MMC_VDD_21_22 |
                          MMC_VDD_22_23 |
@@ -1148,6 +1142,7 @@ static int __init glamo_probe(struct platform_device 
*pdev)
 {
        int rc = 0, irq;
        struct glamo_core *glamo;
+       struct platform_device *glamo_mmc_dev;
 
        if (glamo_handle) {
                dev_err(&pdev->dev,
@@ -1242,8 +1237,8 @@ static int __init glamo_probe(struct platform_device 
*pdev)
                 glamo_pll_rate(glamo, GLAMO_PLL2));
 
        /* bring MCI specific stuff over from our MFD platform data */
-       glamo_mci_def_pdata.glamo_set_mci_power =
-                                       glamo->pdata->glamo_set_mci_power;
+       glamo_mci_def_pdata.glamo_can_set_mci_power =
+                                       glamo->pdata->glamo_can_set_mci_power;
        glamo_mci_def_pdata.glamo_mci_use_slow =
                                        glamo->pdata->glamo_mci_use_slow;
        glamo_mci_def_pdata.glamo_irq_is_wired =
@@ -1283,12 +1278,17 @@ static int __init glamo_probe(struct platform_device 
*pdev)
        glamo_spigpio_dev.dev.platform_data = glamo->pdata->spigpio_info;
        platform_device_register(&glamo_spigpio_dev);
 
-       glamo_mmc_dev.dev.parent = &pdev->dev;
+       glamo_mmc_dev = glamo->pdata->mmc_dev;
+       glamo_mmc_dev->name = "glamo-mci";
+       glamo_mmc_dev->dev.parent = &pdev->dev;
+       glamo_mmc_dev->resource = glamo_mmc_resources;
+       glamo_mmc_dev->num_resources = ARRAY_SIZE(glamo_mmc_resources); 
+
        /* we need it later to give to the engine enable and disable */
        glamo_mci_def_pdata.pglamo = glamo;
-       mangle_mem_resources(glamo_mmc_dev.resource,
-                            glamo_mmc_dev.num_resources, glamo->mem);
-       platform_device_register(&glamo_mmc_dev);
+       mangle_mem_resources(glamo_mmc_dev->resource,
+                            glamo_mmc_dev->num_resources, glamo->mem);
+       platform_device_register(glamo_mmc_dev);
 
        /* only request the generic, hostbus and memory controller MMIO */
        glamo->mem = request_mem_region(glamo->mem->start,
@@ -1333,7 +1333,7 @@ static int glamo_remove(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, NULL);
        platform_device_unregister(&glamo_fb_dev);
-       platform_device_unregister(&glamo_mmc_dev);
+       platform_device_unregister(glamo->pdata->mmc_dev);
        iounmap(glamo->base);
        release_mem_region(glamo->mem->start, GLAMO_REGOFS_VIDCAP);
        glamo_handle = NULL;
diff --git a/drivers/mfd/glamo/glamo-core.h b/drivers/mfd/glamo/glamo-core.h
index 0705204..8e09564 100644
--- a/drivers/mfd/glamo/glamo-core.h
+++ b/drivers/mfd/glamo/glamo-core.h
@@ -68,8 +68,7 @@ struct glamo_mci_pdata {
        unsigned int    gpio_detect;
        unsigned int    gpio_wprotect;
        unsigned long   ocr_avail;
-       void            (*glamo_set_mci_power)(unsigned char power_mode,
-                                    unsigned short vdd);
+       int             (*glamo_can_set_mci_power)(void);
        /* glamo-mci asking if it should use the slow clock to card */
        int             (*glamo_mci_use_slow)(void);
        int             (*glamo_irq_is_wired)(void);
diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
index 00e3c5c..5079796 100644
--- a/drivers/mfd/glamo/glamo-mci.c
+++ b/drivers/mfd/glamo/glamo-mci.c
@@ -757,13 +757,24 @@ static void glamo_mci_reset(struct glamo_mci_host *host)
                   glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC);
 }
 #endif
+static inline int glamo_mci_get_mv(int vdd)
+{
+       int mv = 1650;
+
+       if (vdd > 7)
+               mv += 350 + 100 * (vdd - 8);
+
+       return mv;
+}
 
 static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 {
        struct glamo_mci_host *host = mmc_priv(mmc);
+       struct regulator *regulator;
        int n = 0;
        int div;
        int powering = 0;
+       int mv;
 
        if (host->suspending) {
                dev_err(&host->pdev->dev, "IGNORING glamo_mci_set_ios while "
@@ -771,10 +782,18 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, 
struct mmc_ios *ios)
                return;
        }
 
+       regulator = host->regulator;
+
        /* Set power */
        switch(ios->power_mode) {
-       case MMC_POWER_ON:
        case MMC_POWER_UP:
+               if (host->pdata->glamo_can_set_mci_power()) {
+                       mv = glamo_mci_get_mv(ios->vdd);
+                       regulator_set_voltage(regulator, mv * 1000, mv * 1000);
+                       regulator_enable(regulator);
+               }
+               break;
+       case MMC_POWER_ON:
                /*
                 * we should use very slow clock until first bulk
                 * transfer completes OK
@@ -782,8 +801,11 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
                host->force_slow_during_powerup = 1;
 
                if (host->vdd_current != ios->vdd) {
-                       host->pdata->glamo_set_mci_power(ios->power_mode,
-                                                        ios->vdd);
+                       if (host->pdata->glamo_can_set_mci_power()) {
+                               mv = glamo_mci_get_mv(ios->vdd);
+                               regulator_set_voltage(regulator, mv * 1000, mv 
* 1000);
+                               printk(KERN_INFO "SD power -> %dmV\n", mv);
+                       }
                        host->vdd_current = ios->vdd;
                }
                if (host->power_mode_current == MMC_POWER_OFF) {
@@ -802,7 +824,7 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct 
mmc_ios *ios)
 
                glamo_engine_disable(glamo_mci_def_pdata.pglamo,
                                     GLAMO_ENGINE_MMC);
-               host->pdata->glamo_set_mci_power(MMC_POWER_OFF, 0);
+               regulator_disable(regulator);
                host->vdd_current = -1;
                break;
        }
@@ -907,6 +929,12 @@ static int glamo_mci_probe(struct platform_device *pdev)
                goto probe_free_mem_region;
        }
 
+       host->regulator = regulator_get(&pdev->dev, "SD_3V3");
+       if (!host->regulator) {
+               dev_err(&pdev->dev, "Cannot proceed without regulator.\n");
+               return -ENODEV;
+       }
+
        /* set the handler for our bit of the shared chip irq register */
        set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), glamo_mci_irq);
        /* stash host as our handler's private data */
@@ -994,6 +1022,7 @@ static int glamo_mci_remove(struct platform_device *pdev)
 {
        struct mmc_host         *mmc  = platform_get_drvdata(pdev);
        struct glamo_mci_host   *host = mmc_priv(mmc);
+       struct regulator *regulator;
 
        mmc_remove_host(mmc);
        /* stop using our handler, revert it to default */
@@ -1002,6 +1031,10 @@ static int glamo_mci_remove(struct platform_device *pdev)
        iounmap(host->base_data);
        release_mem_region(host->mem->start, RESSIZE(host->mem));
        release_mem_region(host->mem_data->start, RESSIZE(host->mem_data));
+
+       regulator = host->regulator;
+       regulator_put(regulator);
+       
        mmc_free_host(mmc);
 
        glamo_engine_disable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC);
diff --git a/drivers/mfd/glamo/glamo-mci.h b/drivers/mfd/glamo/glamo-mci.h
index 38f6376..bd62e9a 100644
--- a/drivers/mfd/glamo/glamo-mci.h
+++ b/drivers/mfd/glamo/glamo-mci.h
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include <linux/regulator/consumer.h>
 
 enum glamo_mci_waitfor {
        COMPLETION_NONE,
@@ -77,4 +78,6 @@ struct glamo_mci_host {
 
        unsigned int            ccnt, dcnt;
        struct tasklet_struct   pio_tasklet;
+
+       struct regulator        *regulator;
 };
diff --git a/include/linux/glamofb.h b/include/linux/glamofb.h
index a68870d..b787a0c 100644
--- a/include/linux/glamofb.h
+++ b/include/linux/glamofb.h
@@ -27,9 +27,11 @@ struct glamofb_platform_data {
        struct glamo_spigpio_info *spigpio_info;
        struct glamo_core *glamo;
 
+       struct platform_device *mmc_dev;
+
        /* glamo mmc platform specific info */
-       void            (*glamo_set_mci_power)(unsigned char power_mode,
-                                    unsigned short vdd);
+       int             (*glamo_can_set_mci_power)(void);
+       
        /* glamo-mci asking if it should use the slow clock to card */
        int             (*glamo_mci_use_slow)(void);
        int             (*glamo_irq_is_wired)(void);


Reply via email to