diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2011-01-29 05:21:53 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:42:17 -0800 |
commit | e22447a52e3f053a0f57ef955acf8bed9ba379f8 (patch) | |
tree | 3fe9fb5c1e43013605892193cfa66dd51e2bb419 /arch/arm | |
parent | d75820e970dc1bf4787aee6ed174a2dd977f5713 (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>
Original-Change-Id: Ibd06c9a650ffbacf51530514e58bd52d1f60b4f2
Rebase-Id: R8e593a0b1e27db641d2e0c7b57a2946d97819f25
Diffstat (limited to 'arch/arm')
-rw-r--r-- | arch/arm/mach-tegra/include/mach/pinmux.h | 24 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pinmux-t2-tables.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pinmux-t3-tables.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-tegra/pinmux.c | 164 |
4 files changed, 194 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h index 47056ace13ca..cb14802be2c6 100644 --- a/arch/arm/mach-tegra/include/mach/pinmux.h +++ b/arch/arm/mach-tegra/include/mach/pinmux.h @@ -163,6 +163,24 @@ enum tegra_pin_io { TEGRA_PIN_INPUT = 1, }; +enum tegra_pin_lock { + TEGRA_PIN_LOCK_DEFAULT = 0, + TEGRA_PIN_LOCK_DISABLE, + TEGRA_PIN_LOCK_ENABLE, +}; + +enum tegra_pin_od { + TEGRA_PIN_OD_DEFAULT = 0, + TEGRA_PIN_OD_DISABLE, + TEGRA_PIN_OD_ENABLE, +}; + +enum tegra_pin_ioreset { + TEGRA_PIN_IO_RESET_DEFAULT = 0, + TEGRA_PIN_IO_RESET_DISABLE, + TEGRA_PIN_IO_RESET_ENABLE, +}; + enum tegra_vddio { TEGRA_VDDIO_BB = 0, TEGRA_VDDIO_LCD, @@ -189,6 +207,9 @@ struct tegra_pingroup_config { enum tegra_pullupdown pupd; enum tegra_tristate tristate; enum tegra_pin_io io; + enum tegra_pin_lock lock; + enum tegra_pin_od od; + enum tegra_pin_ioreset ioreset; }; enum tegra_slew { @@ -280,6 +301,9 @@ struct tegra_pingroup_desc { s8 tri_bit; /* offset into the TRISTATE_REG_* register bit */ s8 mux_bit; /* offset into the PIN_MUX_CTL_* register bit */ s8 pupd_bit; /* offset into the PULL_UPDOWN_REG_* register bit */ + s8 lock_bit; /* offser of the LOCK bit into mux register bit */ + s8 od_bit; /* offset of the OD bit into mux register bit */ + s8 ioreset_bit; /* offset of the IO_RESET bit into mux register bit */ s8 io_default; }; diff --git a/arch/arm/mach-tegra/pinmux-t2-tables.c b/arch/arm/mach-tegra/pinmux-t2-tables.c index a6fcd6c62e98..a5dcd107f6d0 100644 --- a/arch/arm/mach-tegra/pinmux-t2-tables.c +++ b/arch/arm/mach-tegra/pinmux-t2-tables.c @@ -97,6 +97,9 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE .pupd_reg = pupd_r, \ .pupd_bit = pupd_b, \ .io_default = 0, \ + .od_bit = -1, \ + .lock_bit = -1, \ + .ioreset_bit = -1, \ } const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = { diff --git a/arch/arm/mach-tegra/pinmux-t3-tables.c b/arch/arm/mach-tegra/pinmux-t3-tables.c index 798986ba1837..f49af0443cf2 100644 --- a/arch/arm/mach-tegra/pinmux-t3-tables.c +++ b/arch/arm/mach-tegra/pinmux-t3-tables.c @@ -99,6 +99,9 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE .pupd_reg = reg, \ .pupd_bit = 2, \ .io_default = TEGRA_PIN_ ## iod, \ + .od_bit = 6, \ + .lock_bit = 7, \ + .ioreset_bit = 8, \ } /* !!!FIXME!!! FILL IN fSafe COLUMN IN TABLE ....... */ diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c index 2b6b69428588..02895a49a0d2 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) |