]> git.karo-electronics.de Git - linux-beck.git/commitdiff
ARM: mach-shmobile: add fixed voltage regulators to ag5evm
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>
Fri, 29 Jun 2012 07:32:29 +0000 (09:32 +0200)
committerRafael J. Wysocki <rjw@sisk.pl>
Sat, 30 Jun 2012 20:39:00 +0000 (22:39 +0200)
On ag5evm provide 1.8V, 2.8V, and 3.3V supplies for its SD/MMC-card
interfaces and a dummy regulator for the smsc911x driver.

Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
Acked-by: Magnus Damm <damm@opensource.se>
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
arch/arm/mach-shmobile/board-ag5evm.c

index 5a6f22f05e99bc3a166a92d968f48e3d43c56e5b..d82c010fdfc6f7682f2c4774db3038656a96a3a6 100644 (file)
@@ -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>
 #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 */