summary refs log tree commit diff
path: root/arch/arm/mach-shmobile
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2012-07-11 23:06:57 +0200
committerRafael J. Wysocki <rjw@sisk.pl>2012-07-11 23:06:57 +0200
commitb315ec06e0590ca0aa60a856420d6b698ab896b1 (patch)
treee9529c15860b9cd365418894c21f96b8e94a401b /arch/arm/mach-shmobile
parent8600fb68cfa8f89e23cf872efb87fec641cc747d (diff)
parent6add9691cca71de0eab38e21a1c45812ba204b98 (diff)
downloadlinux-b315ec06e0590ca0aa60a856420d6b698ab896b1.tar.gz
Merge branch 'renesas-ag5evm' into renesas-board
* renesas-ag5evm:
  ARM: mach-shmobile: add fixed voltage regulators to ag5evm
Diffstat (limited to 'arch/arm/mach-shmobile')
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c82
1 files changed, 79 insertions, 3 deletions
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 5a6f22f05e99..d82c010fdfc6 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -27,6 +27,8 @@
 #include <linux/delay.h>
 #include <linux/io.h>
 #include <linux/dma-mapping.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 #include <linux/serial_sci.h>
 #include <linux/smsc911x.h>
 #include <linux/gpio.h>
@@ -52,6 +54,12 @@
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/traps.h>
 
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+	REGULATOR_SUPPLY("vddvario", "smsc911x"),
+	REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
 static struct resource smsc9220_resources[] = {
 	[0] = {
 		.start		= 0x14000000,
@@ -142,6 +150,13 @@ static struct platform_device fsi_device = {
 	.resource	= fsi_resources,
 };
 
+/* Fixed 1.8V regulator to be used by MMCIF */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
+{
+	REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+	REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
 static struct resource sh_mmcif_resources[] = {
 	[0] = {
 		.name	= "MMCIF",
@@ -364,6 +379,13 @@ static struct platform_device mipidsi0_device = {
 	},
 };
 
+/* Fixed 2.8V regulators to be used by SDHI0 */
+static struct regulator_consumer_supply fixed2v8_power_consumers[] =
+{
+	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
 /* SDHI0 */
 static struct sh_mobile_sdhi_info sdhi0_info = {
 	.dma_slave_tx	= SHDMA_SLAVE_SDHI0_TX,
@@ -408,8 +430,57 @@ static struct platform_device sdhi0_device = {
 	},
 };
 
-void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
+/* Fixed 3.3V regulator to be used by SDHI1 */
+static struct regulator_consumer_supply cn4_power_consumers[] =
 {
+	REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+	REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+};
+
+static struct regulator_init_data cn4_power_init_data = {
+	.constraints = {
+		.valid_ops_mask = REGULATOR_CHANGE_STATUS,
+	},
+	.num_consumer_supplies  = ARRAY_SIZE(cn4_power_consumers),
+	.consumer_supplies      = cn4_power_consumers,
+};
+
+static struct fixed_voltage_config cn4_power_info = {
+	.supply_name = "CN4 SD/MMC Vdd",
+	.microvolts = 3300000,
+	.gpio = GPIO_PORT114,
+	.enable_high = 1,
+	.init_data = &cn4_power_init_data,
+};
+
+static struct platform_device cn4_power = {
+	.name = "reg-fixed-voltage",
+	.id   = 2,
+	.dev  = {
+		.platform_data = &cn4_power_info,
+	},
+};
+
+static void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
+{
+	static int power_gpio = -EINVAL;
+
+	if (power_gpio < 0) {
+		int ret = gpio_request(GPIO_PORT114, "sdhi1_power");
+		if (!ret) {
+			power_gpio = GPIO_PORT114;
+			gpio_direction_output(power_gpio, 0);
+		}
+	}
+
+	/*
+	 * If requesting the GPIO above failed, it means, that the regulator got
+	 * probed and grabbed the GPIO, but we don't know, whether the sdhi
+	 * driver already uses the regulator. If it doesn't, we have to toggle
+	 * the GPIO ourselves, even though it is now owned by the fixed
+	 * regulator driver. We have to live with the race in case the driver
+	 * gets unloaded and the GPIO freed between these two steps.
+	 */
 	gpio_set_value(GPIO_PORT114, state);
 }
 
@@ -455,6 +526,7 @@ static struct platform_device sdhi1_device = {
 };
 
 static struct platform_device *ag5evm_devices[] __initdata = {
+	&cn4_power,
 	&eth_device,
 	&keysc_device,
 	&fsi_device,
@@ -468,6 +540,12 @@ static struct platform_device *ag5evm_devices[] __initdata = {
 
 static void __init ag5evm_init(void)
 {
+	regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
+				     ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+	regulator_register_always_on(1, "fixed-2.8V", fixed2v8_power_consumers,
+				     ARRAY_SIZE(fixed2v8_power_consumers), 3300000);
+	regulator_register_fixed(3, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
 	sh73a0_pinmux_init();
 
 	/* enable SCIFA2 */
@@ -562,8 +640,6 @@ static void __init ag5evm_init(void)
 	gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
 	gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
 	gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
-	gpio_request(GPIO_PORT114, "sdhi1_power");
-	gpio_direction_output(GPIO_PORT114, 0);
 
 #ifdef CONFIG_CACHE_L2X0
 	/* Shared attribute override enable, 64K*8way */