#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,
.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",
},
};
+/* 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,
},
};
-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);
}
};
static struct platform_device *ag5evm_devices[] __initdata = {
+ &cn4_power,
ð_device,
&keysc_device,
&fsi_device,
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 */
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 */