summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/configs/apalis_t30_defconfig1
-rw-r--r--arch/arm/mach-tegra/board-apalis_t30-pinmux.c28
-rw-r--r--arch/arm/mach-tegra/board-apalis_t30-power.c108
-rw-r--r--arch/arm/mach-tegra/board-apalis_t30.c14
4 files changed, 127 insertions, 24 deletions
diff --git a/arch/arm/configs/apalis_t30_defconfig b/arch/arm/configs/apalis_t30_defconfig
index 3e22166f9230..6f9194dad295 100644
--- a/arch/arm/configs/apalis_t30_defconfig
+++ b/arch/arm/configs/apalis_t30_defconfig
@@ -245,6 +245,7 @@ CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
CONFIG_REGULATOR_VIRTUAL_CONSUMER=y
CONFIG_REGULATOR_USERSPACE_CONSUMER=y
+CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_TPS65910=y
CONFIG_REGULATOR_TPS62360=y
CONFIG_REGULATOR_TPS6591X=y
diff --git a/arch/arm/mach-tegra/board-apalis_t30-pinmux.c b/arch/arm/mach-tegra/board-apalis_t30-pinmux.c
index a04a15587129..0f0b5b0ab77c 100644
--- a/arch/arm/mach-tegra/board-apalis_t30-pinmux.c
+++ b/arch/arm/mach-tegra/board-apalis_t30-pinmux.c
@@ -144,7 +144,7 @@ static __initdata struct tegra_pingroup_config apalis_t30_pinmux[] = {
DEFAULT_PINMUX(CLK3_OUT, RSVD1, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
DEFAULT_PINMUX(CLK3_REQ, RSVD1, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
- DEFAULT_PINMUX(CLK_32K_OUT, RSVD1, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
+ DEFAULT_PINMUX(CLK_32K_OUT, RSVD1, PULL_DOWN, TRISTATE, OUTPUT),/* NC */
DEFAULT_PINMUX(CRT_HSYNC, CRT, NORMAL, NORMAL, OUTPUT),
DEFAULT_PINMUX(CRT_VSYNC, CRT, NORMAL, NORMAL, OUTPUT),
@@ -323,7 +323,7 @@ static __initdata struct tegra_pingroup_config apalis_t30_pinmux[] = {
DEFAULT_PINMUX(LCD_PCLK, DISPLAYA, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(LCD_PWR0, DISPLAYB, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
+ DEFAULT_PINMUX(LCD_PWR0, DISPLAYB, PULL_DOWN, TRISTATE, OUTPUT),/* NC */
DEFAULT_PINMUX(LCD_PWR1, RSVD1, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
DEFAULT_PINMUX(LCD_PWR2, RSVD, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
@@ -351,7 +351,7 @@ static __initdata struct tegra_pingroup_config apalis_t30_pinmux[] = {
DEFAULT_PINMUX(PEX_L2_RST_N, PCIE, NORMAL, NORMAL, OUTPUT),
DEFAULT_PINMUX(PEX_WAKE_N, PCIE, NORMAL, NORMAL, INPUT),
-/* Power I2C pinmux */
+ /* Power I2C pinmux */
I2C_PINMUX(PWR_I2C_SCL, I2CPWR, NORMAL, NORMAL, INPUT, DEFAULT, ENABLE),
I2C_PINMUX(PWR_I2C_SDA, I2CPWR, NORMAL, NORMAL, INPUT, DEFAULT, ENABLE),
@@ -363,15 +363,15 @@ static __initdata struct tegra_pingroup_config apalis_t30_pinmux[] = {
DEFAULT_PINMUX(SDMMC1_DAT3, SDMMC1, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(SDMMC3_CLK, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT6, SDMMC3, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(SDMMC3_DAT7, SDMMC3, NORMAL, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_CMD, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT0, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT1, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT2, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT3, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT4, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT5, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT6, SDMMC3, PULL_UP, NORMAL, INPUT),
+ DEFAULT_PINMUX(SDMMC3_DAT7, SDMMC3, PULL_UP, NORMAL, INPUT),
DEFAULT_PINMUX(SDMMC4_CLK, SDMMC4, NORMAL, NORMAL, INPUT),
DEFAULT_PINMUX(SDMMC4_CMD, SDMMC4, PULL_UP, NORMAL, INPUT),
@@ -402,7 +402,9 @@ static __initdata struct tegra_pingroup_config apalis_t30_pinmux[] = {
DEFAULT_PINMUX(SYS_CLK_REQ, SYSCLK, NORMAL, NORMAL, INPUT),
- DEFAULT_PINMUX(UART2_CTS_N, GMI, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
+ /* EN_+3.3_SDMMC3 */
+ DEFAULT_PINMUX(UART2_CTS_N, GMI, NORMAL, NORMAL, OUTPUT),
+
DEFAULT_PINMUX(UART2_RTS_N, GMI, PULL_DOWN, TRISTATE, OUTPUT), /* NC */
DEFAULT_PINMUX(UART2_RXD, IRDA, NORMAL, NORMAL, INPUT),
diff --git a/arch/arm/mach-tegra/board-apalis_t30-power.c b/arch/arm/mach-tegra/board-apalis_t30-power.c
index 064c438b4b64..eda6d9820847 100644
--- a/arch/arm/mach-tegra/board-apalis_t30-power.c
+++ b/arch/arm/mach-tegra/board-apalis_t30-power.c
@@ -25,7 +25,9 @@
#include <linux/io.h>
#include <linux/mfd/tps6591x.h>
#include <linux/platform_device.h>
+#include <linux/regulator/driver.h>
#include <linux/regulator/fixed.h>
+#include <linux/regulator/gpio-regulator.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/tps62360.h>
#include <linux/regulator/tps6591x-regulator.h>
@@ -91,9 +93,9 @@ static struct regulator_consumer_supply tps6591x_vio_supply_0[] = {
REGULATOR_SUPPLY("avdd_ic_usb", NULL),
};
-/* unused */
+/* 1.8 volt VDDIO_SDMMC3 in case EN_+3.3_SDMMC3 is off */
static struct regulator_consumer_supply tps6591x_ldo1_supply_0[] = {
- REGULATOR_SUPPLY("unused_rail_ldo1", NULL),
+ REGULATOR_SUPPLY("vddio_sdmmc_1v8", NULL),
};
/* EN_+V3.3 switching via FET: +V3.3_AUDIO_AVDD_S, +V3.3 and +V1.8_VDD_LAN
@@ -178,7 +180,7 @@ TPS_PDATA_INIT(vdd2, 0, 1050, 1050, 0, 1, 1, 1, -1, 0, 0, EXT_CTRL_SLEEP
TPS_PDATA_INIT(vddctrl, 0, 800, 1300, 0, 1, 1, 0, -1, 0, 0, EXT_CTRL_EN1, 0);
TPS_PDATA_INIT(vio, 0, 1800, 1800, 0, 1, 1, 0, -1, 0, 0, 0, 0);
-TPS_PDATA_INIT(ldo1, 0, 1000, 3300, tps6591x_rails(VIO), 0, 0, 0, -1, 0, 1, 0, 0);
+TPS_PDATA_INIT(ldo1, 0, 1800, 1800, tps6591x_rails(VIO), 1, 1, 1, -1, 0, 1, 0, 0);
/* Make sure EN_+V3.3 is always on! */
TPS_PDATA_INIT(ldo2, 0, 1200, 1200, tps6591x_rails(VIO), 1, 1, 1, -1, 0, 1, 0, 0);
@@ -373,7 +375,7 @@ VDDIO_GMI_3
VDDIO_UART
VDDIO_SDMMC1
AVDD_USB
-VDDIO_SDMMC3
+VDDIO_SDMMC3 in case EN_+3.3_SDMMC3 is on
74AVCAH164245
VDDIO_PEX_CTL
TPS65911 VDDIO
@@ -386,6 +388,7 @@ static struct regulator_consumer_supply fixed_reg_v3_3_supply[] = {
REGULATOR_SUPPLY("avdd_audio", NULL),
REGULATOR_SUPPLY("avdd_usb", NULL),
REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.1"),
+ REGULATOR_SUPPLY("vddio_sd_slot", "sdhci-tegra.2"),
REGULATOR_SUPPLY("vddio_sys", NULL),
REGULATOR_SUPPLY("vddio_uart", NULL),
REGULATOR_SUPPLY("pwrdet_uart", NULL),
@@ -397,12 +400,13 @@ static struct regulator_consumer_supply fixed_reg_v3_3_supply[] = {
REGULATOR_SUPPLY("pwrdet_lcd", NULL),
REGULATOR_SUPPLY("vddio_cam", NULL),
REGULATOR_SUPPLY("pwrdet_cam", NULL),
- /* if this supply is defined, the sdhci driver tries
- * to set it to 1.8V */
-// REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.1"),
+ REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.1"),
+ REGULATOR_SUPPLY("vddio_sdmmc_3v3", NULL),
REGULATOR_SUPPLY("pwrdet_sdmmc2", NULL),
REGULATOR_SUPPLY("pwrdet_sdmmc1", NULL),
- REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
+ /* if this supply is defined, somehow magically LDO1 gets
+ * set to 3.3V resulting in some squeezed out 3.0V */
+// REGULATOR_SUPPLY("pwrdet_sdmmc3", NULL),
REGULATOR_SUPPLY("pwrdet_pex_ctl", NULL),
REGULATOR_SUPPLY("pwrdet_nand", NULL),
@@ -422,6 +426,81 @@ static struct platform_device *fixed_reg_devs_apalis_t30[] = {
ADD_FIXED_REG(v3_3),
};
+/* 1.8 volt resp. 3.3 volt VDDIO_SDMMC3 depending on EN_+3.3_SDMMC3 GPIO */
+static struct regulator_consumer_supply gpio_reg_sdmmc3_vdd_sel_supply[] = {
+ REGULATOR_SUPPLY("vddio_sdmmc_1v8_3v3", NULL),
+ REGULATOR_SUPPLY("vddio_sdmmc", "sdhci-tegra.2"),
+};
+
+static struct gpio_regulator_state gpio_reg_sdmmc3_vdd_sel_states[] = {
+ {
+ .gpios = 0,
+ .value = 1800000,
+ },
+ {
+ .gpios = 1,
+ .value = 3300000,
+ },
+};
+
+static struct gpio gpio_reg_sdmmc3_vdd_sel_gpios[] = {
+ {
+ .gpio = TEGRA_GPIO_PJ5,
+ .flags = 0,
+ .label = "EN_+3.3_SDMMC3",
+ },
+};
+
+/* Macro for defining gpio regulator device data */
+#define GPIO_REG(_id, _name, _input_supply, _active_high, \
+ _boot_state, _delay_us, _minmv, _maxmv) \
+ static struct regulator_init_data ri_data_##_name = \
+ { \
+ .supply_regulator = _input_supply, \
+ .num_consumer_supplies = \
+ ARRAY_SIZE(gpio_reg_##_name##_supply), \
+ .consumer_supplies = gpio_reg_##_name##_supply, \
+ .constraints = { \
+ .name = "gpio_reg_"#_name, \
+ .min_uV = (_minmv)*1000, \
+ .max_uV = (_maxmv)*1000, \
+ .valid_modes_mask = (REGULATOR_MODE_NORMAL | \
+ REGULATOR_MODE_STANDBY), \
+ .valid_ops_mask = (REGULATOR_CHANGE_MODE | \
+ REGULATOR_CHANGE_STATUS | \
+ REGULATOR_CHANGE_VOLTAGE), \
+ }, \
+ }; \
+ static struct gpio_regulator_config gpio_reg_##_name##_pdata = \
+ { \
+ .supply_name = _input_supply, \
+ .enable_gpio = -EINVAL, \
+ .enable_high = _active_high, \
+ .enabled_at_boot = _boot_state, \
+ .startup_delay = _delay_us, \
+ .gpios = gpio_reg_##_name##_gpios, \
+ .nr_gpios = ARRAY_SIZE(gpio_reg_##_name##_gpios), \
+ .states = gpio_reg_##_name##_states, \
+ .nr_states = ARRAY_SIZE(gpio_reg_##_name##_states), \
+ .type = REGULATOR_VOLTAGE, \
+ .init_data = &ri_data_##_name, \
+ }; \
+ static struct platform_device gpio_reg_##_name##_dev = { \
+ .name = "gpio-regulator", \
+ .id = _id, \
+ .dev = { \
+ .platform_data = &gpio_reg_##_name##_pdata, \
+ }, \
+ }
+
+GPIO_REG(4, sdmmc3_vdd_sel, FIXED_SUPPLY(v3_3),
+ true, false, 0, 1800, 3300);
+
+#define ADD_GPIO_REG(_name) (&gpio_reg_##_name##_dev)
+static struct platform_device *gpio_regs_devices[] = {
+ ADD_GPIO_REG(sdmmc3_vdd_sel),
+};
+
#ifdef FORCE_OFF_GPIO
static void apalis_t30_power_off(void)
{
@@ -464,11 +543,18 @@ int __init apalis_t30_regulator_init(void)
return 0;
}
-int __init apalis_t30_fixed_regulator_init(void)
+int __init apalis_t30_fixed_and_gpio_regulator_init(void)
{
- return platform_add_devices(fixed_reg_devs_apalis_t30, ARRAY_SIZE(fixed_reg_devs_apalis_t30));
+ int ret;
+
+ ret = platform_add_devices(fixed_reg_devs_apalis_t30,
+ ARRAY_SIZE(fixed_reg_devs_apalis_t30));
+ if (!ret) ret = platform_add_devices(gpio_regs_devices,
+ ARRAY_SIZE(gpio_regs_devices));
+
+ return ret;
}
-subsys_initcall_sync(apalis_t30_fixed_regulator_init);
+subsys_initcall_sync(apalis_t30_fixed_and_gpio_regulator_init);
static void apalis_t30_board_suspend(int lp_state, enum suspend_stage stg)
{
diff --git a/arch/arm/mach-tegra/board-apalis_t30.c b/arch/arm/mach-tegra/board-apalis_t30.c
index d01f420f33c5..ef709c872d17 100644
--- a/arch/arm/mach-tegra/board-apalis_t30.c
+++ b/arch/arm/mach-tegra/board-apalis_t30.c
@@ -622,6 +622,18 @@ static struct platform_device apalis_t30_keys_device = {
/* MMC/SD */
+/* To limit the 8-bit MMC slot to 3.3 volt only operation (e.g. no UHS) */
+int g_sdmmc3_uhs = 0;
+
+static int __init enable_mmc_uhs(char *s)
+{
+ if (!(*s) || !strcmp(s, "1"))
+ g_sdmmc3_uhs = 1;
+
+ return 0;
+}
+__setup("mmc_uhs=", enable_mmc_uhs);
+
static struct tegra_sdhci_platform_data apalis_t30_emmc_platform_data = {
.cd_gpio = -1,
.ddr_clk_limit = 52000000,
@@ -661,6 +673,8 @@ static void __init apalis_t30_sdhci_init(void)
&apalis_t30_emmc_platform_data;
platform_device_register(&tegra_sdhci_device4);
+ if (g_sdmmc3_uhs)
+ apalis_t30_mmccard_platform_data.no_1v8 = 0;
tegra_sdhci_device3.dev.platform_data =
&apalis_t30_mmccard_platform_data;
platform_device_register(&tegra_sdhci_device3);