[UPSTREAM PATCH] glamo_mci_use_regulator_api.patch

Balaji Rao balajirrao at openmoko.org
Wed Oct 29 16:16:33 CET 2008


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);




More information about the openmoko-kernel mailing list