
Add support to funcmux for selecting I2C functions and programming the pinmux appropriately.
Signed-off-by: Simon Glass sjg@chromium.org --- arch/arm/cpu/armv7/tegra2/funcmux.c | 75 +++++++++++++++++++++++----- arch/arm/include/asm/arch-tegra2/funcmux.h | 3 + 2 files changed, 65 insertions(+), 13 deletions(-)
diff --git a/arch/arm/cpu/armv7/tegra2/funcmux.c b/arch/arm/cpu/armv7/tegra2/funcmux.c index 0878f51..82d994a 100644 --- a/arch/arm/cpu/armv7/tegra2/funcmux.c +++ b/arch/arm/cpu/armv7/tegra2/funcmux.c @@ -26,27 +26,70 @@
int funcmux_select(enum periph_id id, int config) { - if (config != 0) { - debug("%s: invalid config %d for periph_id %d", __func__, - config, id); - return -1; - } + int bad_config = config != 0; + switch (id) { case PERIPH_ID_UART1: - pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA); - pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA); - pinmux_tristate_disable(PINGRP_IRRX); - pinmux_tristate_disable(PINGRP_IRTX); + if (config == 0) { + pinmux_set_func(PINGRP_IRRX, PMUX_FUNC_UARTA); + pinmux_set_func(PINGRP_IRTX, PMUX_FUNC_UARTA); + pinmux_tristate_disable(PINGRP_IRRX); + pinmux_tristate_disable(PINGRP_IRTX); + } break;
case PERIPH_ID_UART2: - pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); - pinmux_tristate_disable(PINGRP_UAD); + if (config == 0) { + pinmux_set_func(PINGRP_UAD, PMUX_FUNC_IRDA); + pinmux_tristate_disable(PINGRP_UAD); + } break;
case PERIPH_ID_UART4: - pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD); - pinmux_tristate_disable(PINGRP_GMC); + if (config == 0) { + pinmux_set_func(PINGRP_GMC, PMUX_FUNC_UARTD); + pinmux_tristate_disable(PINGRP_GMC); + } + break; + + case PERIPH_ID_DVC_I2C: + /* there is only one selection, pinmux_config is ignored */ + if (config == 0) { + pinmux_set_func(PINGRP_I2CP, PMUX_FUNC_I2C); + pinmux_tristate_disable(PINGRP_I2CP); + } + break; + + case PERIPH_ID_I2C1: + /* support pinmux_config of 0 for now, */ + if (config == 0) { + pinmux_set_func(PINGRP_RM, PMUX_FUNC_I2C); + pinmux_tristate_disable(PINGRP_RM); + } + break; + case PERIPH_ID_I2C2: /* I2C2 */ + switch (config) { + case 0: /* DDC pin group, select I2C2 */ + pinmux_set_func(PINGRP_DDC, PMUX_FUNC_I2C2); + /* PTA to HDMI */ + pinmux_set_func(PINGRP_PTA, PMUX_FUNC_HDMI); + pinmux_tristate_disable(PINGRP_DDC); + break; + case 1: /* PTA pin group, select I2C2 */ + pinmux_set_func(PINGRP_PTA, PMUX_FUNC_I2C2); + /* set DDC_SEL to RSVDx (RSVD2 works for now) */ + pinmux_set_func(PINGRP_DDC, PMUX_FUNC_RSVD2); + pinmux_tristate_disable(PINGRP_PTA); + bad_config = 0; + break; + } + break; + case PERIPH_ID_I2C3: /* I2C3 */ + /* support pinmux_config of 0 for now */ + if (config == 0) { + pinmux_set_func(PINGRP_DTF, PMUX_FUNC_I2C3); + pinmux_tristate_disable(PINGRP_DTF); + } break;
default: @@ -54,5 +97,11 @@ int funcmux_select(enum periph_id id, int config) return -1; }
+ if (bad_config) { + debug("%s: invalid config %d for periph_id %d", __func__, + config, id); + return -1; + } + return 0; } diff --git a/arch/arm/include/asm/arch-tegra2/funcmux.h b/arch/arm/include/asm/arch-tegra2/funcmux.h index 2d724a2..d4f9cfb 100644 --- a/arch/arm/include/asm/arch-tegra2/funcmux.h +++ b/arch/arm/include/asm/arch-tegra2/funcmux.h @@ -32,6 +32,9 @@ * The basic config is 0, and higher numbers indicate different * pinmux settings to bring the peripheral out on other pins, * + * This function also disables tristate for the function's pins, + * so that they operate in normal mode. + * * @param id Peripheral id * @param config Configuration to use (generally 0) * @return 0 if ok, -1 on error (e.g. incorrect id or config)