summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/pinmux.c
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2011-01-29 05:21:53 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-04-26 15:50:34 -0700
commitd781f9ce1e6a5b23c49ce26eeacb67fc81018700 (patch)
treee284163214840fc9f5eb3307699665f620140b71 /arch/arm/mach-tegra/pinmux.c
parent91e4503567c38078febe3d5ae607c3821c38837f (diff)
arm: tegra: pinmux: Supporting LOCK/OD/IORESET pin configuration.
Supporting the LOCK, OpenDrain (OD), IO_RESET configuration on pinmux register through pinmux apis. Original-Change-Id: I2459723c5fbcadd925331696c9469f64d2ba3b20 Reviewed-on: http://git-master/r/17532 Reviewed-by: Venkata Nageswara Penumarty <vpenumarty@nvidia.com> Tested-by: Venkata Nageswara Penumarty <vpenumarty@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Tested-by: Laxman Dewangan <ldewangan@nvidia.com> Change-Id: Ibd06c9a650ffbacf51530514e58bd52d1f60b4f2
Diffstat (limited to 'arch/arm/mach-tegra/pinmux.c')
-rw-r--r--arch/arm/mach-tegra/pinmux.c164
1 files changed, 164 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
index 7487758a6989..da0210608024 100644
--- a/arch/arm/mach-tegra/pinmux.c
+++ b/arch/arm/mach-tegra/pinmux.c
@@ -214,6 +214,54 @@ static const char *pupd_name(unsigned long val)
}
}
+static const char *lock_name(unsigned long val)
+{
+ switch(val) {
+ case TEGRA_PIN_LOCK_DEFAULT:
+ return "LOCK_DEFUALT";
+
+ case TEGRA_PIN_LOCK_DISABLE:
+ return "LOCK_DISABLE";
+
+ case TEGRA_PIN_LOCK_ENABLE:
+ return "LOCK_ENABLE";
+ default:
+ return "LOCK_DEFAULT";
+ }
+}
+
+static const char *od_name(unsigned long val)
+{
+ switch(val) {
+ case TEGRA_PIN_OD_DEFAULT:
+ return "OD_DEFAULT";
+
+ case TEGRA_PIN_OD_DISABLE:
+ return "OD_DISABLE";
+
+ case TEGRA_PIN_OD_ENABLE:
+ return "OD_ENABLE";
+ default:
+ return "OD_DEFAULT";
+ }
+}
+
+static const char *ioreset_name(unsigned long val)
+{
+ switch(val) {
+ case TEGRA_PIN_IO_RESET_DEFAULT:
+ return "IO_RESET_DEFAULT";
+
+ case TEGRA_PIN_IO_RESET_DISABLE:
+ return "IO_RESET_DISABLE";
+
+ case TEGRA_PIN_IO_RESET_ENABLE:
+ return "IO_RESET_ENABLE";
+ default:
+ return "IO_RESET_DEFAULT";
+ }
+}
+
#if defined(TEGRA_PINMUX_HAS_IO_DIRECTION)
static const char *io_name(unsigned long val)
{
@@ -338,6 +386,94 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
return 0;
}
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+static int tegra_pinmux_set_lock(enum tegra_pingroup pg,
+ enum tegra_pin_lock lock)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if ((lock == TEGRA_PIN_LOCK_DEFAULT) || (pingroups[pg].lock_bit < 0))
+ return 0;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x1 << pingroups[pg].lock_bit);
+ if (lock == TEGRA_PIN_LOCK_ENABLE)
+ reg |= (0x1 << pingroups[pg].lock_bit);
+
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+ return 0;
+}
+
+static int tegra_pinmux_set_od(enum tegra_pingroup pg,
+ enum tegra_pin_od od)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if ((od == TEGRA_PIN_OD_DEFAULT) || (pingroups[pg].od_bit < 0))
+ return 0;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x1 << pingroups[pg].od_bit);
+ if (od == TEGRA_PIN_OD_ENABLE)
+ reg |= 1 << pingroups[pg].od_bit;
+
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+
+static int tegra_pinmux_set_ioreset(enum tegra_pingroup pg,
+ enum tegra_pin_ioreset ioreset)
+{
+ unsigned long reg;
+ unsigned long flags;
+
+ if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
+ return -ERANGE;
+
+ if (pingroups[pg].mux_reg < 0)
+ return -EINVAL;
+
+ if ((ioreset == TEGRA_PIN_IO_RESET_DEFAULT) || (pingroups[pg].ioreset_bit < 0))
+ return 0;
+
+ spin_lock_irqsave(&mux_lock, flags);
+
+ reg = pg_readl(pingroups[pg].mux_reg);
+ reg &= ~(0x1 << pingroups[pg].ioreset_bit);
+ if (ioreset == TEGRA_PIN_IO_RESET_ENABLE)
+ reg |= 1 << pingroups[pg].ioreset_bit;
+
+ pg_writel(reg, pingroups[pg].mux_reg);
+
+ spin_unlock_irqrestore(&mux_lock, flags);
+
+ return 0;
+}
+#endif
+
int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
enum tegra_pullupdown pupd)
{
@@ -374,6 +510,11 @@ static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *con
enum tegra_mux_func func = config->func;
enum tegra_pullupdown pupd = config->pupd;
enum tegra_tristate tristate = config->tristate;
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+ enum tegra_pin_lock lock = config->lock;
+ enum tegra_pin_od od = config->od;
+ enum tegra_pin_ioreset ioreset = config->ioreset;
+#endif
int err;
if (pingroups[pingroup].mux_reg >= 0) {
@@ -396,6 +537,29 @@ static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *con
pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
pingroup_name(pingroup), tri_name(func), err);
}
+
+#if !defined(CONFIG_ARCH_TEGRA_2x_SOC)
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_lock(pingroup, lock);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s lock to %s: %d\n",
+ pingroup_name(pingroup), lock_name(func), err);
+ }
+
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_od(pingroup, od);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s od to %s: %d\n",
+ pingroup_name(pingroup), od_name(func), err);
+ }
+
+ if (pingroups[pingroup].mux_reg >= 0) {
+ err = tegra_pinmux_set_ioreset(pingroup, ioreset);
+ if (err < 0)
+ pr_err("pinmux: can't set pingroup %s ioreset to %s: %d\n",
+ pingroup_name(pingroup), ioreset_name(func), err);
+ }
+#endif
}
void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)