Add support to funcmux for selecting I2C functions and programming
the pinmux appropriately.

Signed-off-by: Simon Glass <s...@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)
-- 
1.7.3.1

_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to