diff options
-rw-r--r-- | arch/arm/configs/apalis_t30_defconfig | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-apalis_t30-pinmux.c | 28 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-apalis_t30-power.c | 108 | ||||
-rw-r--r-- | arch/arm/mach-tegra/board-apalis_t30.c | 14 |
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); |