Revert "ARM: tegra: Remove pre-pinctrl pinmux driver"
Dan Willemsen [Fri, 4 Jan 2013 07:51:04 +0000 (23:51 -0800)]
This reverts commit b7449d95b0cbfb06b9ca9de8c322c470fbc2a873.

We haven't switched to pinctrl yet, so we still need this.

Signed-off-by: Dan Willemsen <dwillemsen@nvidia.com>

arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/include/mach/pinmux-tegra20.h [new file with mode: 0644]
arch/arm/mach-tegra/include/mach/pinmux-tegra30.h [new file with mode: 0644]
arch/arm/mach-tegra/include/mach/pinmux.h [new file with mode: 0644]
arch/arm/mach-tegra/pinmux-tegra20-tables.c [new file with mode: 0644]
arch/arm/mach-tegra/pinmux-tegra30-tables.c [new file with mode: 0644]
arch/arm/mach-tegra/pinmux.c [new file with mode: 0644]

index 115d957..aad7fdd 100644 (file)
@@ -7,6 +7,7 @@ obj-y                                   += io.o
 obj-y                                   += irq.o
 obj-y                                   += clock.o
 obj-y                                   += timer.o
+obj-y                                   += pinmux.o
 obj-y                                  += fuse.o
 obj-y                                  += pmc.o
 obj-y                                  += flowctrl.o
@@ -17,6 +18,8 @@ obj-$(CONFIG_CPU_IDLE)                        += sleep.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra20_speedo.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += tegra2_emc.o
 obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += sleep-t20.o
+obj-$(CONFIG_ARCH_TEGRA_2x_SOC)                += pinmux-tegra20-tables.o
+obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += pinmux-tegra30-tables.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += tegra30_speedo.o
 obj-$(CONFIG_ARCH_TEGRA_3x_SOC)                += sleep-t30.o
 obj-$(CONFIG_SMP)                      += platsmp.o headsmp.o
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-tegra20.h b/arch/arm/mach-tegra/include/mach/pinmux-tegra20.h
new file mode 100644 (file)
index 0000000..6a40c1d
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux-tegra20.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PINMUX_TEGRA20_H
+#define __MACH_TEGRA_PINMUX_TEGRA20_H
+
+enum tegra_pingroup {
+       TEGRA_PINGROUP_ATA = 0,
+       TEGRA_PINGROUP_ATB,
+       TEGRA_PINGROUP_ATC,
+       TEGRA_PINGROUP_ATD,
+       TEGRA_PINGROUP_ATE,
+       TEGRA_PINGROUP_CDEV1,
+       TEGRA_PINGROUP_CDEV2,
+       TEGRA_PINGROUP_CRTP,
+       TEGRA_PINGROUP_CSUS,
+       TEGRA_PINGROUP_DAP1,
+       TEGRA_PINGROUP_DAP2,
+       TEGRA_PINGROUP_DAP3,
+       TEGRA_PINGROUP_DAP4,
+       TEGRA_PINGROUP_DDC,
+       TEGRA_PINGROUP_DTA,
+       TEGRA_PINGROUP_DTB,
+       TEGRA_PINGROUP_DTC,
+       TEGRA_PINGROUP_DTD,
+       TEGRA_PINGROUP_DTE,
+       TEGRA_PINGROUP_DTF,
+       TEGRA_PINGROUP_GMA,
+       TEGRA_PINGROUP_GMB,
+       TEGRA_PINGROUP_GMC,
+       TEGRA_PINGROUP_GMD,
+       TEGRA_PINGROUP_GME,
+       TEGRA_PINGROUP_GPU,
+       TEGRA_PINGROUP_GPU7,
+       TEGRA_PINGROUP_GPV,
+       TEGRA_PINGROUP_HDINT,
+       TEGRA_PINGROUP_I2CP,
+       TEGRA_PINGROUP_IRRX,
+       TEGRA_PINGROUP_IRTX,
+       TEGRA_PINGROUP_KBCA,
+       TEGRA_PINGROUP_KBCB,
+       TEGRA_PINGROUP_KBCC,
+       TEGRA_PINGROUP_KBCD,
+       TEGRA_PINGROUP_KBCE,
+       TEGRA_PINGROUP_KBCF,
+       TEGRA_PINGROUP_LCSN,
+       TEGRA_PINGROUP_LD0,
+       TEGRA_PINGROUP_LD1,
+       TEGRA_PINGROUP_LD10,
+       TEGRA_PINGROUP_LD11,
+       TEGRA_PINGROUP_LD12,
+       TEGRA_PINGROUP_LD13,
+       TEGRA_PINGROUP_LD14,
+       TEGRA_PINGROUP_LD15,
+       TEGRA_PINGROUP_LD16,
+       TEGRA_PINGROUP_LD17,
+       TEGRA_PINGROUP_LD2,
+       TEGRA_PINGROUP_LD3,
+       TEGRA_PINGROUP_LD4,
+       TEGRA_PINGROUP_LD5,
+       TEGRA_PINGROUP_LD6,
+       TEGRA_PINGROUP_LD7,
+       TEGRA_PINGROUP_LD8,
+       TEGRA_PINGROUP_LD9,
+       TEGRA_PINGROUP_LDC,
+       TEGRA_PINGROUP_LDI,
+       TEGRA_PINGROUP_LHP0,
+       TEGRA_PINGROUP_LHP1,
+       TEGRA_PINGROUP_LHP2,
+       TEGRA_PINGROUP_LHS,
+       TEGRA_PINGROUP_LM0,
+       TEGRA_PINGROUP_LM1,
+       TEGRA_PINGROUP_LPP,
+       TEGRA_PINGROUP_LPW0,
+       TEGRA_PINGROUP_LPW1,
+       TEGRA_PINGROUP_LPW2,
+       TEGRA_PINGROUP_LSC0,
+       TEGRA_PINGROUP_LSC1,
+       TEGRA_PINGROUP_LSCK,
+       TEGRA_PINGROUP_LSDA,
+       TEGRA_PINGROUP_LSDI,
+       TEGRA_PINGROUP_LSPI,
+       TEGRA_PINGROUP_LVP0,
+       TEGRA_PINGROUP_LVP1,
+       TEGRA_PINGROUP_LVS,
+       TEGRA_PINGROUP_OWC,
+       TEGRA_PINGROUP_PMC,
+       TEGRA_PINGROUP_PTA,
+       TEGRA_PINGROUP_RM,
+       TEGRA_PINGROUP_SDB,
+       TEGRA_PINGROUP_SDC,
+       TEGRA_PINGROUP_SDD,
+       TEGRA_PINGROUP_SDIO1,
+       TEGRA_PINGROUP_SLXA,
+       TEGRA_PINGROUP_SLXC,
+       TEGRA_PINGROUP_SLXD,
+       TEGRA_PINGROUP_SLXK,
+       TEGRA_PINGROUP_SPDI,
+       TEGRA_PINGROUP_SPDO,
+       TEGRA_PINGROUP_SPIA,
+       TEGRA_PINGROUP_SPIB,
+       TEGRA_PINGROUP_SPIC,
+       TEGRA_PINGROUP_SPID,
+       TEGRA_PINGROUP_SPIE,
+       TEGRA_PINGROUP_SPIF,
+       TEGRA_PINGROUP_SPIG,
+       TEGRA_PINGROUP_SPIH,
+       TEGRA_PINGROUP_UAA,
+       TEGRA_PINGROUP_UAB,
+       TEGRA_PINGROUP_UAC,
+       TEGRA_PINGROUP_UAD,
+       TEGRA_PINGROUP_UCA,
+       TEGRA_PINGROUP_UCB,
+       TEGRA_PINGROUP_UDA,
+       /* these pin groups only have pullup and pull down control */
+       TEGRA_PINGROUP_CK32,
+       TEGRA_PINGROUP_DDRC,
+       TEGRA_PINGROUP_PMCA,
+       TEGRA_PINGROUP_PMCB,
+       TEGRA_PINGROUP_PMCC,
+       TEGRA_PINGROUP_PMCD,
+       TEGRA_PINGROUP_PMCE,
+       TEGRA_PINGROUP_XM2C,
+       TEGRA_PINGROUP_XM2D,
+       TEGRA_MAX_PINGROUP,
+};
+
+enum tegra_drive_pingroup {
+       TEGRA_DRIVE_PINGROUP_AO1 = 0,
+       TEGRA_DRIVE_PINGROUP_AO2,
+       TEGRA_DRIVE_PINGROUP_AT1,
+       TEGRA_DRIVE_PINGROUP_AT2,
+       TEGRA_DRIVE_PINGROUP_CDEV1,
+       TEGRA_DRIVE_PINGROUP_CDEV2,
+       TEGRA_DRIVE_PINGROUP_CSUS,
+       TEGRA_DRIVE_PINGROUP_DAP1,
+       TEGRA_DRIVE_PINGROUP_DAP2,
+       TEGRA_DRIVE_PINGROUP_DAP3,
+       TEGRA_DRIVE_PINGROUP_DAP4,
+       TEGRA_DRIVE_PINGROUP_DBG,
+       TEGRA_DRIVE_PINGROUP_LCD1,
+       TEGRA_DRIVE_PINGROUP_LCD2,
+       TEGRA_DRIVE_PINGROUP_SDMMC2,
+       TEGRA_DRIVE_PINGROUP_SDMMC3,
+       TEGRA_DRIVE_PINGROUP_SPI,
+       TEGRA_DRIVE_PINGROUP_UAA,
+       TEGRA_DRIVE_PINGROUP_UAB,
+       TEGRA_DRIVE_PINGROUP_UART2,
+       TEGRA_DRIVE_PINGROUP_UART3,
+       TEGRA_DRIVE_PINGROUP_VI1,
+       TEGRA_DRIVE_PINGROUP_VI2,
+       TEGRA_DRIVE_PINGROUP_XM2A,
+       TEGRA_DRIVE_PINGROUP_XM2C,
+       TEGRA_DRIVE_PINGROUP_XM2D,
+       TEGRA_DRIVE_PINGROUP_XM2CLK,
+       TEGRA_DRIVE_PINGROUP_MEMCOMP,
+       TEGRA_DRIVE_PINGROUP_SDIO1,
+       TEGRA_DRIVE_PINGROUP_CRT,
+       TEGRA_DRIVE_PINGROUP_DDC,
+       TEGRA_DRIVE_PINGROUP_GMA,
+       TEGRA_DRIVE_PINGROUP_GMB,
+       TEGRA_DRIVE_PINGROUP_GMC,
+       TEGRA_DRIVE_PINGROUP_GMD,
+       TEGRA_DRIVE_PINGROUP_GME,
+       TEGRA_DRIVE_PINGROUP_OWR,
+       TEGRA_DRIVE_PINGROUP_UAD,
+       TEGRA_MAX_DRIVE_PINGROUP,
+};
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h b/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h
new file mode 100644 (file)
index 0000000..c1aee3e
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux-tegra30.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010,2011 Nvidia, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PINMUX_TEGRA30_H
+#define __MACH_TEGRA_PINMUX_TEGRA30_H
+
+enum tegra_pingroup {
+       TEGRA_PINGROUP_ULPI_DATA0 = 0,
+       TEGRA_PINGROUP_ULPI_DATA1,
+       TEGRA_PINGROUP_ULPI_DATA2,
+       TEGRA_PINGROUP_ULPI_DATA3,
+       TEGRA_PINGROUP_ULPI_DATA4,
+       TEGRA_PINGROUP_ULPI_DATA5,
+       TEGRA_PINGROUP_ULPI_DATA6,
+       TEGRA_PINGROUP_ULPI_DATA7,
+       TEGRA_PINGROUP_ULPI_CLK,
+       TEGRA_PINGROUP_ULPI_DIR,
+       TEGRA_PINGROUP_ULPI_NXT,
+       TEGRA_PINGROUP_ULPI_STP,
+       TEGRA_PINGROUP_DAP3_FS,
+       TEGRA_PINGROUP_DAP3_DIN,
+       TEGRA_PINGROUP_DAP3_DOUT,
+       TEGRA_PINGROUP_DAP3_SCLK,
+       TEGRA_PINGROUP_GPIO_PV0,
+       TEGRA_PINGROUP_GPIO_PV1,
+       TEGRA_PINGROUP_SDMMC1_CLK,
+       TEGRA_PINGROUP_SDMMC1_CMD,
+       TEGRA_PINGROUP_SDMMC1_DAT3,
+       TEGRA_PINGROUP_SDMMC1_DAT2,
+       TEGRA_PINGROUP_SDMMC1_DAT1,
+       TEGRA_PINGROUP_SDMMC1_DAT0,
+       TEGRA_PINGROUP_GPIO_PV2,
+       TEGRA_PINGROUP_GPIO_PV3,
+       TEGRA_PINGROUP_CLK2_OUT,
+       TEGRA_PINGROUP_CLK2_REQ,
+       TEGRA_PINGROUP_LCD_PWR1,
+       TEGRA_PINGROUP_LCD_PWR2,
+       TEGRA_PINGROUP_LCD_SDIN,
+       TEGRA_PINGROUP_LCD_SDOUT,
+       TEGRA_PINGROUP_LCD_WR_N,
+       TEGRA_PINGROUP_LCD_CS0_N,
+       TEGRA_PINGROUP_LCD_DC0,
+       TEGRA_PINGROUP_LCD_SCK,
+       TEGRA_PINGROUP_LCD_PWR0,
+       TEGRA_PINGROUP_LCD_PCLK,
+       TEGRA_PINGROUP_LCD_DE,
+       TEGRA_PINGROUP_LCD_HSYNC,
+       TEGRA_PINGROUP_LCD_VSYNC,
+       TEGRA_PINGROUP_LCD_D0,
+       TEGRA_PINGROUP_LCD_D1,
+       TEGRA_PINGROUP_LCD_D2,
+       TEGRA_PINGROUP_LCD_D3,
+       TEGRA_PINGROUP_LCD_D4,
+       TEGRA_PINGROUP_LCD_D5,
+       TEGRA_PINGROUP_LCD_D6,
+       TEGRA_PINGROUP_LCD_D7,
+       TEGRA_PINGROUP_LCD_D8,
+       TEGRA_PINGROUP_LCD_D9,
+       TEGRA_PINGROUP_LCD_D10,
+       TEGRA_PINGROUP_LCD_D11,
+       TEGRA_PINGROUP_LCD_D12,
+       TEGRA_PINGROUP_LCD_D13,
+       TEGRA_PINGROUP_LCD_D14,
+       TEGRA_PINGROUP_LCD_D15,
+       TEGRA_PINGROUP_LCD_D16,
+       TEGRA_PINGROUP_LCD_D17,
+       TEGRA_PINGROUP_LCD_D18,
+       TEGRA_PINGROUP_LCD_D19,
+       TEGRA_PINGROUP_LCD_D20,
+       TEGRA_PINGROUP_LCD_D21,
+       TEGRA_PINGROUP_LCD_D22,
+       TEGRA_PINGROUP_LCD_D23,
+       TEGRA_PINGROUP_LCD_CS1_N,
+       TEGRA_PINGROUP_LCD_M1,
+       TEGRA_PINGROUP_LCD_DC1,
+       TEGRA_PINGROUP_HDMI_INT,
+       TEGRA_PINGROUP_DDC_SCL,
+       TEGRA_PINGROUP_DDC_SDA,
+       TEGRA_PINGROUP_CRT_HSYNC,
+       TEGRA_PINGROUP_CRT_VSYNC,
+       TEGRA_PINGROUP_VI_D0,
+       TEGRA_PINGROUP_VI_D1,
+       TEGRA_PINGROUP_VI_D2,
+       TEGRA_PINGROUP_VI_D3,
+       TEGRA_PINGROUP_VI_D4,
+       TEGRA_PINGROUP_VI_D5,
+       TEGRA_PINGROUP_VI_D6,
+       TEGRA_PINGROUP_VI_D7,
+       TEGRA_PINGROUP_VI_D8,
+       TEGRA_PINGROUP_VI_D9,
+       TEGRA_PINGROUP_VI_D10,
+       TEGRA_PINGROUP_VI_D11,
+       TEGRA_PINGROUP_VI_PCLK,
+       TEGRA_PINGROUP_VI_MCLK,
+       TEGRA_PINGROUP_VI_VSYNC,
+       TEGRA_PINGROUP_VI_HSYNC,
+       TEGRA_PINGROUP_UART2_RXD,
+       TEGRA_PINGROUP_UART2_TXD,
+       TEGRA_PINGROUP_UART2_RTS_N,
+       TEGRA_PINGROUP_UART2_CTS_N,
+       TEGRA_PINGROUP_UART3_TXD,
+       TEGRA_PINGROUP_UART3_RXD,
+       TEGRA_PINGROUP_UART3_CTS_N,
+       TEGRA_PINGROUP_UART3_RTS_N,
+       TEGRA_PINGROUP_GPIO_PU0,
+       TEGRA_PINGROUP_GPIO_PU1,
+       TEGRA_PINGROUP_GPIO_PU2,
+       TEGRA_PINGROUP_GPIO_PU3,
+       TEGRA_PINGROUP_GPIO_PU4,
+       TEGRA_PINGROUP_GPIO_PU5,
+       TEGRA_PINGROUP_GPIO_PU6,
+       TEGRA_PINGROUP_GEN1_I2C_SDA,
+       TEGRA_PINGROUP_GEN1_I2C_SCL,
+       TEGRA_PINGROUP_DAP4_FS,
+       TEGRA_PINGROUP_DAP4_DIN,
+       TEGRA_PINGROUP_DAP4_DOUT,
+       TEGRA_PINGROUP_DAP4_SCLK,
+       TEGRA_PINGROUP_CLK3_OUT,
+       TEGRA_PINGROUP_CLK3_REQ,
+       TEGRA_PINGROUP_GMI_WP_N,
+       TEGRA_PINGROUP_GMI_IORDY,
+       TEGRA_PINGROUP_GMI_WAIT,
+       TEGRA_PINGROUP_GMI_ADV_N,
+       TEGRA_PINGROUP_GMI_CLK,
+       TEGRA_PINGROUP_GMI_CS0_N,
+       TEGRA_PINGROUP_GMI_CS1_N,
+       TEGRA_PINGROUP_GMI_CS2_N,
+       TEGRA_PINGROUP_GMI_CS3_N,
+       TEGRA_PINGROUP_GMI_CS4_N,
+       TEGRA_PINGROUP_GMI_CS6_N,
+       TEGRA_PINGROUP_GMI_CS7_N,
+       TEGRA_PINGROUP_GMI_AD0,
+       TEGRA_PINGROUP_GMI_AD1,
+       TEGRA_PINGROUP_GMI_AD2,
+       TEGRA_PINGROUP_GMI_AD3,
+       TEGRA_PINGROUP_GMI_AD4,
+       TEGRA_PINGROUP_GMI_AD5,
+       TEGRA_PINGROUP_GMI_AD6,
+       TEGRA_PINGROUP_GMI_AD7,
+       TEGRA_PINGROUP_GMI_AD8,
+       TEGRA_PINGROUP_GMI_AD9,
+       TEGRA_PINGROUP_GMI_AD10,
+       TEGRA_PINGROUP_GMI_AD11,
+       TEGRA_PINGROUP_GMI_AD12,
+       TEGRA_PINGROUP_GMI_AD13,
+       TEGRA_PINGROUP_GMI_AD14,
+       TEGRA_PINGROUP_GMI_AD15,
+       TEGRA_PINGROUP_GMI_A16,
+       TEGRA_PINGROUP_GMI_A17,
+       TEGRA_PINGROUP_GMI_A18,
+       TEGRA_PINGROUP_GMI_A19,
+       TEGRA_PINGROUP_GMI_WR_N,
+       TEGRA_PINGROUP_GMI_OE_N,
+       TEGRA_PINGROUP_GMI_DQS,
+       TEGRA_PINGROUP_GMI_RST_N,
+       TEGRA_PINGROUP_GEN2_I2C_SCL,
+       TEGRA_PINGROUP_GEN2_I2C_SDA,
+       TEGRA_PINGROUP_SDMMC4_CLK,
+       TEGRA_PINGROUP_SDMMC4_CMD,
+       TEGRA_PINGROUP_SDMMC4_DAT0,
+       TEGRA_PINGROUP_SDMMC4_DAT1,
+       TEGRA_PINGROUP_SDMMC4_DAT2,
+       TEGRA_PINGROUP_SDMMC4_DAT3,
+       TEGRA_PINGROUP_SDMMC4_DAT4,
+       TEGRA_PINGROUP_SDMMC4_DAT5,
+       TEGRA_PINGROUP_SDMMC4_DAT6,
+       TEGRA_PINGROUP_SDMMC4_DAT7,
+       TEGRA_PINGROUP_SDMMC4_RST_N,
+       TEGRA_PINGROUP_CAM_MCLK,
+       TEGRA_PINGROUP_GPIO_PCC1,
+       TEGRA_PINGROUP_GPIO_PBB0,
+       TEGRA_PINGROUP_CAM_I2C_SCL,
+       TEGRA_PINGROUP_CAM_I2C_SDA,
+       TEGRA_PINGROUP_GPIO_PBB3,
+       TEGRA_PINGROUP_GPIO_PBB4,
+       TEGRA_PINGROUP_GPIO_PBB5,
+       TEGRA_PINGROUP_GPIO_PBB6,
+       TEGRA_PINGROUP_GPIO_PBB7,
+       TEGRA_PINGROUP_GPIO_PCC2,
+       TEGRA_PINGROUP_JTAG_RTCK,
+       TEGRA_PINGROUP_PWR_I2C_SCL,
+       TEGRA_PINGROUP_PWR_I2C_SDA,
+       TEGRA_PINGROUP_KB_ROW0,
+       TEGRA_PINGROUP_KB_ROW1,
+       TEGRA_PINGROUP_KB_ROW2,
+       TEGRA_PINGROUP_KB_ROW3,
+       TEGRA_PINGROUP_KB_ROW4,
+       TEGRA_PINGROUP_KB_ROW5,
+       TEGRA_PINGROUP_KB_ROW6,
+       TEGRA_PINGROUP_KB_ROW7,
+       TEGRA_PINGROUP_KB_ROW8,
+       TEGRA_PINGROUP_KB_ROW9,
+       TEGRA_PINGROUP_KB_ROW10,
+       TEGRA_PINGROUP_KB_ROW11,
+       TEGRA_PINGROUP_KB_ROW12,
+       TEGRA_PINGROUP_KB_ROW13,
+       TEGRA_PINGROUP_KB_ROW14,
+       TEGRA_PINGROUP_KB_ROW15,
+       TEGRA_PINGROUP_KB_COL0,
+       TEGRA_PINGROUP_KB_COL1,
+       TEGRA_PINGROUP_KB_COL2,
+       TEGRA_PINGROUP_KB_COL3,
+       TEGRA_PINGROUP_KB_COL4,
+       TEGRA_PINGROUP_KB_COL5,
+       TEGRA_PINGROUP_KB_COL6,
+       TEGRA_PINGROUP_KB_COL7,
+       TEGRA_PINGROUP_CLK_32K_OUT,
+       TEGRA_PINGROUP_SYS_CLK_REQ,
+       TEGRA_PINGROUP_CORE_PWR_REQ,
+       TEGRA_PINGROUP_CPU_PWR_REQ,
+       TEGRA_PINGROUP_PWR_INT_N,
+       TEGRA_PINGROUP_CLK_32K_IN,
+       TEGRA_PINGROUP_OWR,
+       TEGRA_PINGROUP_DAP1_FS,
+       TEGRA_PINGROUP_DAP1_DIN,
+       TEGRA_PINGROUP_DAP1_DOUT,
+       TEGRA_PINGROUP_DAP1_SCLK,
+       TEGRA_PINGROUP_CLK1_REQ,
+       TEGRA_PINGROUP_CLK1_OUT,
+       TEGRA_PINGROUP_SPDIF_IN,
+       TEGRA_PINGROUP_SPDIF_OUT,
+       TEGRA_PINGROUP_DAP2_FS,
+       TEGRA_PINGROUP_DAP2_DIN,
+       TEGRA_PINGROUP_DAP2_DOUT,
+       TEGRA_PINGROUP_DAP2_SCLK,
+       TEGRA_PINGROUP_SPI2_MOSI,
+       TEGRA_PINGROUP_SPI2_MISO,
+       TEGRA_PINGROUP_SPI2_CS0_N,
+       TEGRA_PINGROUP_SPI2_SCK,
+       TEGRA_PINGROUP_SPI1_MOSI,
+       TEGRA_PINGROUP_SPI1_SCK,
+       TEGRA_PINGROUP_SPI1_CS0_N,
+       TEGRA_PINGROUP_SPI1_MISO,
+       TEGRA_PINGROUP_SPI2_CS1_N,
+       TEGRA_PINGROUP_SPI2_CS2_N,
+       TEGRA_PINGROUP_SDMMC3_CLK,
+       TEGRA_PINGROUP_SDMMC3_CMD,
+       TEGRA_PINGROUP_SDMMC3_DAT0,
+       TEGRA_PINGROUP_SDMMC3_DAT1,
+       TEGRA_PINGROUP_SDMMC3_DAT2,
+       TEGRA_PINGROUP_SDMMC3_DAT3,
+       TEGRA_PINGROUP_SDMMC3_DAT4,
+       TEGRA_PINGROUP_SDMMC3_DAT5,
+       TEGRA_PINGROUP_SDMMC3_DAT6,
+       TEGRA_PINGROUP_SDMMC3_DAT7,
+       TEGRA_PINGROUP_PEX_L0_PRSNT_N,
+       TEGRA_PINGROUP_PEX_L0_RST_N,
+       TEGRA_PINGROUP_PEX_L0_CLKREQ_N,
+       TEGRA_PINGROUP_PEX_WAKE_N,
+       TEGRA_PINGROUP_PEX_L1_PRSNT_N,
+       TEGRA_PINGROUP_PEX_L1_RST_N,
+       TEGRA_PINGROUP_PEX_L1_CLKREQ_N,
+       TEGRA_PINGROUP_PEX_L2_PRSNT_N,
+       TEGRA_PINGROUP_PEX_L2_RST_N,
+       TEGRA_PINGROUP_PEX_L2_CLKREQ_N,
+       TEGRA_PINGROUP_HDMI_CEC,
+       TEGRA_MAX_PINGROUP,
+};
+
+enum tegra_drive_pingroup {
+       TEGRA_DRIVE_PINGROUP_AO1 = 0,
+       TEGRA_DRIVE_PINGROUP_AO2,
+       TEGRA_DRIVE_PINGROUP_AT1,
+       TEGRA_DRIVE_PINGROUP_AT2,
+       TEGRA_DRIVE_PINGROUP_AT3,
+       TEGRA_DRIVE_PINGROUP_AT4,
+       TEGRA_DRIVE_PINGROUP_AT5,
+       TEGRA_DRIVE_PINGROUP_CDEV1,
+       TEGRA_DRIVE_PINGROUP_CDEV2,
+       TEGRA_DRIVE_PINGROUP_CSUS,
+       TEGRA_DRIVE_PINGROUP_DAP1,
+       TEGRA_DRIVE_PINGROUP_DAP2,
+       TEGRA_DRIVE_PINGROUP_DAP3,
+       TEGRA_DRIVE_PINGROUP_DAP4,
+       TEGRA_DRIVE_PINGROUP_DBG,
+       TEGRA_DRIVE_PINGROUP_LCD1,
+       TEGRA_DRIVE_PINGROUP_LCD2,
+       TEGRA_DRIVE_PINGROUP_SDIO2,
+       TEGRA_DRIVE_PINGROUP_SDIO3,
+       TEGRA_DRIVE_PINGROUP_SPI,
+       TEGRA_DRIVE_PINGROUP_UAA,
+       TEGRA_DRIVE_PINGROUP_UAB,
+       TEGRA_DRIVE_PINGROUP_UART2,
+       TEGRA_DRIVE_PINGROUP_UART3,
+       TEGRA_DRIVE_PINGROUP_VI1,
+       TEGRA_DRIVE_PINGROUP_SDIO1,
+       TEGRA_DRIVE_PINGROUP_CRT,
+       TEGRA_DRIVE_PINGROUP_DDC,
+       TEGRA_DRIVE_PINGROUP_GMA,
+       TEGRA_DRIVE_PINGROUP_GMB,
+       TEGRA_DRIVE_PINGROUP_GMC,
+       TEGRA_DRIVE_PINGROUP_GMD,
+       TEGRA_DRIVE_PINGROUP_GME,
+       TEGRA_DRIVE_PINGROUP_GMF,
+       TEGRA_DRIVE_PINGROUP_GMG,
+       TEGRA_DRIVE_PINGROUP_GMH,
+       TEGRA_DRIVE_PINGROUP_OWR,
+       TEGRA_DRIVE_PINGROUP_UAD,
+       TEGRA_DRIVE_PINGROUP_GPV,
+       TEGRA_DRIVE_PINGROUP_DEV3,
+       TEGRA_DRIVE_PINGROUP_CEC,
+       TEGRA_MAX_DRIVE_PINGROUP,
+};
+
+#endif
+
diff --git a/arch/arm/mach-tegra/include/mach/pinmux.h b/arch/arm/mach-tegra/include/mach/pinmux.h
new file mode 100644 (file)
index 0000000..055f179
--- /dev/null
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/arm/mach-tegra/include/mach/pinmux.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2010,2011 Nvidia, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifndef __MACH_TEGRA_PINMUX_H
+#define __MACH_TEGRA_PINMUX_H
+
+enum tegra_mux_func {
+       TEGRA_MUX_RSVD = 0x8000,
+       TEGRA_MUX_RSVD1 = 0x8000,
+       TEGRA_MUX_RSVD2 = 0x8001,
+       TEGRA_MUX_RSVD3 = 0x8002,
+       TEGRA_MUX_RSVD4 = 0x8003,
+       TEGRA_MUX_INVALID = 0x4000,
+       TEGRA_MUX_NONE = -1,
+       TEGRA_MUX_AHB_CLK,
+       TEGRA_MUX_APB_CLK,
+       TEGRA_MUX_AUDIO_SYNC,
+       TEGRA_MUX_CRT,
+       TEGRA_MUX_DAP1,
+       TEGRA_MUX_DAP2,
+       TEGRA_MUX_DAP3,
+       TEGRA_MUX_DAP4,
+       TEGRA_MUX_DAP5,
+       TEGRA_MUX_DISPLAYA,
+       TEGRA_MUX_DISPLAYB,
+       TEGRA_MUX_EMC_TEST0_DLL,
+       TEGRA_MUX_EMC_TEST1_DLL,
+       TEGRA_MUX_GMI,
+       TEGRA_MUX_GMI_INT,
+       TEGRA_MUX_HDMI,
+       TEGRA_MUX_I2C,
+       TEGRA_MUX_I2C2,
+       TEGRA_MUX_I2C3,
+       TEGRA_MUX_IDE,
+       TEGRA_MUX_IRDA,
+       TEGRA_MUX_KBC,
+       TEGRA_MUX_MIO,
+       TEGRA_MUX_MIPI_HS,
+       TEGRA_MUX_NAND,
+       TEGRA_MUX_OSC,
+       TEGRA_MUX_OWR,
+       TEGRA_MUX_PCIE,
+       TEGRA_MUX_PLLA_OUT,
+       TEGRA_MUX_PLLC_OUT1,
+       TEGRA_MUX_PLLM_OUT1,
+       TEGRA_MUX_PLLP_OUT2,
+       TEGRA_MUX_PLLP_OUT3,
+       TEGRA_MUX_PLLP_OUT4,
+       TEGRA_MUX_PWM,
+       TEGRA_MUX_PWR_INTR,
+       TEGRA_MUX_PWR_ON,
+       TEGRA_MUX_RTCK,
+       TEGRA_MUX_SDIO1,
+       TEGRA_MUX_SDIO2,
+       TEGRA_MUX_SDIO3,
+       TEGRA_MUX_SDIO4,
+       TEGRA_MUX_SFLASH,
+       TEGRA_MUX_SPDIF,
+       TEGRA_MUX_SPI1,
+       TEGRA_MUX_SPI2,
+       TEGRA_MUX_SPI2_ALT,
+       TEGRA_MUX_SPI3,
+       TEGRA_MUX_SPI4,
+       TEGRA_MUX_TRACE,
+       TEGRA_MUX_TWC,
+       TEGRA_MUX_UARTA,
+       TEGRA_MUX_UARTB,
+       TEGRA_MUX_UARTC,
+       TEGRA_MUX_UARTD,
+       TEGRA_MUX_UARTE,
+       TEGRA_MUX_ULPI,
+       TEGRA_MUX_VI,
+       TEGRA_MUX_VI_SENSOR_CLK,
+       TEGRA_MUX_XIO,
+       TEGRA_MUX_BLINK,
+       TEGRA_MUX_CEC,
+       TEGRA_MUX_CLK12,
+       TEGRA_MUX_DAP,
+       TEGRA_MUX_DAPSDMMC2,
+       TEGRA_MUX_DDR,
+       TEGRA_MUX_DEV3,
+       TEGRA_MUX_DTV,
+       TEGRA_MUX_VI_ALT1,
+       TEGRA_MUX_VI_ALT2,
+       TEGRA_MUX_VI_ALT3,
+       TEGRA_MUX_EMC_DLL,
+       TEGRA_MUX_EXTPERIPH1,
+       TEGRA_MUX_EXTPERIPH2,
+       TEGRA_MUX_EXTPERIPH3,
+       TEGRA_MUX_GMI_ALT,
+       TEGRA_MUX_HDA,
+       TEGRA_MUX_HSI,
+       TEGRA_MUX_I2C4,
+       TEGRA_MUX_I2C5,
+       TEGRA_MUX_I2CPWR,
+       TEGRA_MUX_I2S0,
+       TEGRA_MUX_I2S1,
+       TEGRA_MUX_I2S2,
+       TEGRA_MUX_I2S3,
+       TEGRA_MUX_I2S4,
+       TEGRA_MUX_NAND_ALT,
+       TEGRA_MUX_POPSDIO4,
+       TEGRA_MUX_POPSDMMC4,
+       TEGRA_MUX_PWM0,
+       TEGRA_MUX_PWM1,
+       TEGRA_MUX_PWM2,
+       TEGRA_MUX_PWM3,
+       TEGRA_MUX_SATA,
+       TEGRA_MUX_SPI5,
+       TEGRA_MUX_SPI6,
+       TEGRA_MUX_SYSCLK,
+       TEGRA_MUX_VGP1,
+       TEGRA_MUX_VGP2,
+       TEGRA_MUX_VGP3,
+       TEGRA_MUX_VGP4,
+       TEGRA_MUX_VGP5,
+       TEGRA_MUX_VGP6,
+       TEGRA_MUX_SAFE,
+       TEGRA_MAX_MUX,
+};
+
+enum tegra_pullupdown {
+       TEGRA_PUPD_NORMAL = 0,
+       TEGRA_PUPD_PULL_DOWN,
+       TEGRA_PUPD_PULL_UP,
+};
+
+enum tegra_tristate {
+       TEGRA_TRI_NORMAL = 0,
+       TEGRA_TRI_TRISTATE = 1,
+};
+
+enum tegra_pin_io {
+       TEGRA_PIN_OUTPUT = 0,
+       TEGRA_PIN_INPUT = 1,
+};
+
+enum tegra_vddio {
+       TEGRA_VDDIO_BB = 0,
+       TEGRA_VDDIO_LCD,
+       TEGRA_VDDIO_VI,
+       TEGRA_VDDIO_UART,
+       TEGRA_VDDIO_DDR,
+       TEGRA_VDDIO_NAND,
+       TEGRA_VDDIO_SYS,
+       TEGRA_VDDIO_AUDIO,
+       TEGRA_VDDIO_SD,
+       TEGRA_VDDIO_CAM,
+       TEGRA_VDDIO_GMI,
+       TEGRA_VDDIO_PEXCTL,
+       TEGRA_VDDIO_SDMMC1,
+       TEGRA_VDDIO_SDMMC3,
+       TEGRA_VDDIO_SDMMC4,
+};
+
+struct tegra_pingroup_config {
+       int pingroup;
+       enum tegra_mux_func     func;
+       enum tegra_pullupdown   pupd;
+       enum tegra_tristate     tristate;
+};
+
+enum tegra_slew {
+       TEGRA_SLEW_FASTEST = 0,
+       TEGRA_SLEW_FAST,
+       TEGRA_SLEW_SLOW,
+       TEGRA_SLEW_SLOWEST,
+       TEGRA_MAX_SLEW,
+};
+
+enum tegra_pull_strength {
+       TEGRA_PULL_0 = 0,
+       TEGRA_PULL_1,
+       TEGRA_PULL_2,
+       TEGRA_PULL_3,
+       TEGRA_PULL_4,
+       TEGRA_PULL_5,
+       TEGRA_PULL_6,
+       TEGRA_PULL_7,
+       TEGRA_PULL_8,
+       TEGRA_PULL_9,
+       TEGRA_PULL_10,
+       TEGRA_PULL_11,
+       TEGRA_PULL_12,
+       TEGRA_PULL_13,
+       TEGRA_PULL_14,
+       TEGRA_PULL_15,
+       TEGRA_PULL_16,
+       TEGRA_PULL_17,
+       TEGRA_PULL_18,
+       TEGRA_PULL_19,
+       TEGRA_PULL_20,
+       TEGRA_PULL_21,
+       TEGRA_PULL_22,
+       TEGRA_PULL_23,
+       TEGRA_PULL_24,
+       TEGRA_PULL_25,
+       TEGRA_PULL_26,
+       TEGRA_PULL_27,
+       TEGRA_PULL_28,
+       TEGRA_PULL_29,
+       TEGRA_PULL_30,
+       TEGRA_PULL_31,
+       TEGRA_MAX_PULL,
+};
+
+enum tegra_drive {
+       TEGRA_DRIVE_DIV_8 = 0,
+       TEGRA_DRIVE_DIV_4,
+       TEGRA_DRIVE_DIV_2,
+       TEGRA_DRIVE_DIV_1,
+       TEGRA_MAX_DRIVE,
+};
+
+enum tegra_hsm {
+       TEGRA_HSM_DISABLE = 0,
+       TEGRA_HSM_ENABLE,
+};
+
+enum tegra_schmitt {
+       TEGRA_SCHMITT_DISABLE = 0,
+       TEGRA_SCHMITT_ENABLE,
+};
+
+struct tegra_drive_pingroup_config {
+       int pingroup;
+       enum tegra_hsm hsm;
+       enum tegra_schmitt schmitt;
+       enum tegra_drive drive;
+       enum tegra_pull_strength pull_down;
+       enum tegra_pull_strength pull_up;
+       enum tegra_slew slew_rising;
+       enum tegra_slew slew_falling;
+};
+
+struct tegra_drive_pingroup_desc {
+       const char *name;
+       s16 reg_bank;
+       s16 reg;
+};
+
+struct tegra_pingroup_desc {
+       const char *name;
+       int funcs[4];
+       int func_safe;
+       int vddio;
+       enum tegra_pin_io io_default;
+       s16 tri_bank;   /* Register bank the tri_reg exists within */
+       s16 mux_bank;   /* Register bank the mux_reg exists within */
+       s16 pupd_bank;  /* Register bank the pupd_reg exists within */
+       s16 tri_reg;    /* offset into the TRISTATE_REG_* register bank */
+       s16 mux_reg;    /* offset into the PIN_MUX_CTL_* register bank */
+       s16 pupd_reg;   /* offset into the PULL_UPDOWN_REG_* register bank */
+       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;    /* offset 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 */
+};
+
+typedef void (*pinmux_init) (const struct tegra_pingroup_desc **pg,
+       int *pg_max, const struct tegra_drive_pingroup_desc **pgdrive,
+       int *pgdrive_max);
+
+void tegra20_pinmux_init(const struct tegra_pingroup_desc **pg, int *pg_max,
+       const struct tegra_drive_pingroup_desc **pgdrive, int *pgdrive_max);
+
+void tegra30_pinmux_init(const struct tegra_pingroup_desc **pg, int *pg_max,
+       const struct tegra_drive_pingroup_desc **pgdrive, int *pgdrive_max);
+
+int tegra_pinmux_set_tristate(int pg, enum tegra_tristate tristate);
+int tegra_pinmux_set_pullupdown(int pg, enum tegra_pullupdown pupd);
+
+void tegra_pinmux_config_table(const struct tegra_pingroup_config *config,
+       int len);
+
+void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
+       int len);
+void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
+       int len);
+void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
+       int len);
+void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
+       int len, enum tegra_tristate tristate);
+void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
+       int len, enum tegra_pullupdown pupd);
+#endif
diff --git a/arch/arm/mach-tegra/pinmux-tegra20-tables.c b/arch/arm/mach-tegra/pinmux-tegra20-tables.c
new file mode 100644 (file)
index 0000000..951243d
--- /dev/null
@@ -0,0 +1,244 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux-tegra20-tables.c
+ *
+ * Common pinmux configurations for Tegra20 SoCs
+ *
+ * Copyright (C) 2010 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <mach/pinmux.h>
+#include <mach/pinmux-tegra20.h>
+
+#include "iomap.h"
+
+#define TRISTATE_REG_A         0x14
+#define PIN_MUX_CTL_REG_A      0x80
+#define PULLUPDOWN_REG_A       0xa0
+#define PINGROUP_REG_A         0x868
+
+#define DRIVE_PINGROUP(pg_name, r)                             \
+       [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {                  \
+               .name = #pg_name,                               \
+               .reg_bank = 3,                                  \
+               .reg = ((r) - PINGROUP_REG_A)                   \
+       }
+
+static const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
+       DRIVE_PINGROUP(AO1,             0x868),
+       DRIVE_PINGROUP(AO2,             0x86c),
+       DRIVE_PINGROUP(AT1,             0x870),
+       DRIVE_PINGROUP(AT2,             0x874),
+       DRIVE_PINGROUP(CDEV1,           0x878),
+       DRIVE_PINGROUP(CDEV2,           0x87c),
+       DRIVE_PINGROUP(CSUS,            0x880),
+       DRIVE_PINGROUP(DAP1,            0x884),
+       DRIVE_PINGROUP(DAP2,            0x888),
+       DRIVE_PINGROUP(DAP3,            0x88c),
+       DRIVE_PINGROUP(DAP4,            0x890),
+       DRIVE_PINGROUP(DBG,             0x894),
+       DRIVE_PINGROUP(LCD1,            0x898),
+       DRIVE_PINGROUP(LCD2,            0x89c),
+       DRIVE_PINGROUP(SDMMC2,          0x8a0),
+       DRIVE_PINGROUP(SDMMC3,          0x8a4),
+       DRIVE_PINGROUP(SPI,             0x8a8),
+       DRIVE_PINGROUP(UAA,             0x8ac),
+       DRIVE_PINGROUP(UAB,             0x8b0),
+       DRIVE_PINGROUP(UART2,           0x8b4),
+       DRIVE_PINGROUP(UART3,           0x8b8),
+       DRIVE_PINGROUP(VI1,             0x8bc),
+       DRIVE_PINGROUP(VI2,             0x8c0),
+       DRIVE_PINGROUP(XM2A,            0x8c4),
+       DRIVE_PINGROUP(XM2C,            0x8c8),
+       DRIVE_PINGROUP(XM2D,            0x8cc),
+       DRIVE_PINGROUP(XM2CLK,          0x8d0),
+       DRIVE_PINGROUP(MEMCOMP,         0x8d4),
+       DRIVE_PINGROUP(SDIO1,           0x8e0),
+       DRIVE_PINGROUP(CRT,             0x8ec),
+       DRIVE_PINGROUP(DDC,             0x8f0),
+       DRIVE_PINGROUP(GMA,             0x8f4),
+       DRIVE_PINGROUP(GMB,             0x8f8),
+       DRIVE_PINGROUP(GMC,             0x8fc),
+       DRIVE_PINGROUP(GMD,             0x900),
+       DRIVE_PINGROUP(GME,             0x904),
+       DRIVE_PINGROUP(OWR,             0x908),
+       DRIVE_PINGROUP(UAD,             0x90c),
+};
+
+#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, f_safe,         \
+                tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b)    \
+       [TEGRA_PINGROUP_ ## pg_name] = {                        \
+               .name = #pg_name,                               \
+               .vddio = TEGRA_VDDIO_ ## vdd,                   \
+               .funcs = {                                      \
+                       TEGRA_MUX_ ## f0,                       \
+                       TEGRA_MUX_ ## f1,                       \
+                       TEGRA_MUX_ ## f2,                       \
+                       TEGRA_MUX_ ## f3,                       \
+               },                                              \
+               .func_safe = TEGRA_MUX_ ## f_safe,              \
+               .tri_bank = 0,                                  \
+               .tri_reg = ((tri_r) - TRISTATE_REG_A),          \
+               .tri_bit = tri_b,                               \
+               .mux_bank = 1,                                  \
+               .mux_reg = ((mux_r) - PIN_MUX_CTL_REG_A),       \
+               .mux_bit = mux_b,                               \
+               .pupd_bank = 2,                         \
+               .pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A),      \
+               .pupd_bit = pupd_b,                             \
+               .lock_bit = -1,                                 \
+               .od_bit = -1,                                   \
+               .ioreset_bit = -1,                              \
+               .io_default = -1,                               \
+       }
+
+static const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
+       PINGROUP(ATA,   NAND,  IDE,       NAND,      GMI,       RSVD,          IDE,       0x14, 0,  0x80, 24, 0xA0, 0),
+       PINGROUP(ATB,   NAND,  IDE,       NAND,      GMI,       SDIO4,         IDE,       0x14, 1,  0x80, 16, 0xA0, 2),
+       PINGROUP(ATC,   NAND,  IDE,       NAND,      GMI,       SDIO4,         IDE,       0x14, 2,  0x80, 22, 0xA0, 4),
+       PINGROUP(ATD,   NAND,  IDE,       NAND,      GMI,       SDIO4,         IDE,       0x14, 3,  0x80, 20, 0xA0, 6),
+       PINGROUP(ATE,   NAND,  IDE,       NAND,      GMI,       RSVD,          IDE,       0x18, 25, 0x80, 12, 0xA0, 8),
+       PINGROUP(CDEV1, AUDIO, OSC,       PLLA_OUT,  PLLM_OUT1, AUDIO_SYNC,    OSC,       0x14, 4,  0x88, 2,  0xA8, 0),
+       PINGROUP(CDEV2, AUDIO, OSC,       AHB_CLK,   APB_CLK,   PLLP_OUT4,     OSC,       0x14, 5,  0x88, 4,  0xA8, 2),
+       PINGROUP(CRTP,  LCD,   CRT,       RSVD,      RSVD,      RSVD,          RSVD,      0x20, 14, 0x98, 20, 0xA4, 24),
+       PINGROUP(CSUS,  VI,    PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6,  0x88, 6,  0xAC, 24),
+       PINGROUP(DAP1,  AUDIO, DAP1,      RSVD,      GMI,       SDIO2,         DAP1,      0x14, 7,  0x88, 20, 0xA0, 10),
+       PINGROUP(DAP2,  AUDIO, DAP2,      TWC,       RSVD,      GMI,           DAP2,      0x14, 8,  0x88, 22, 0xA0, 12),
+       PINGROUP(DAP3,  BB,    DAP3,      RSVD,      RSVD,      RSVD,          DAP3,      0x14, 9,  0x88, 24, 0xA0, 14),
+       PINGROUP(DAP4,  UART,  DAP4,      RSVD,      GMI,       RSVD,          DAP4,      0x14, 10, 0x88, 26, 0xA0, 16),
+       PINGROUP(DDC,   LCD,   I2C2,      RSVD,      RSVD,      RSVD,          RSVD4,     0x18, 31, 0x88, 0,  0xB0, 28),
+       PINGROUP(DTA,   VI,    RSVD,      SDIO2,     VI,        RSVD,          RSVD4,     0x14, 11, 0x84, 20, 0xA0, 18),
+       PINGROUP(DTB,   VI,    RSVD,      RSVD,      VI,        SPI1,          RSVD1,     0x14, 12, 0x84, 22, 0xA0, 20),
+       PINGROUP(DTC,   VI,    RSVD,      RSVD,      VI,        RSVD,          RSVD1,     0x14, 13, 0x84, 26, 0xA0, 22),
+       PINGROUP(DTD,   VI,    RSVD,      SDIO2,     VI,        RSVD,          RSVD1,     0x14, 14, 0x84, 28, 0xA0, 24),
+       PINGROUP(DTE,   VI,    RSVD,      RSVD,      VI,        SPI1,          RSVD1,     0x14, 15, 0x84, 30, 0xA0, 26),
+       PINGROUP(DTF,   VI,    I2C3,      RSVD,      VI,        RSVD,          RSVD4,     0x20, 12, 0x98, 30, 0xA0, 28),
+       PINGROUP(GMA,   NAND,  UARTE,     SPI3,      GMI,       SDIO4,         SPI3,      0x14, 28, 0x84, 0,  0xB0, 20),
+       PINGROUP(GMB,   NAND,  IDE,       NAND,      GMI,       GMI_INT,       GMI,       0x18, 29, 0x88, 28, 0xB0, 22),
+       PINGROUP(GMC,   NAND,  UARTD,     SPI4,      GMI,       SFLASH,        SPI4,      0x14, 29, 0x84, 2,  0xB0, 24),
+       PINGROUP(GMD,   NAND,  RSVD,      NAND,      GMI,       SFLASH,        GMI,       0x18, 30, 0x88, 30, 0xB0, 26),
+       PINGROUP(GME,   NAND,  RSVD,      DAP5,      GMI,       SDIO4,         GMI,       0x18, 0,  0x8C, 0,  0xA8, 24),
+       PINGROUP(GPU,   UART,  PWM,       UARTA,     GMI,       RSVD,          RSVD4,     0x14, 16, 0x8C, 4,  0xA4, 20),
+       PINGROUP(GPU7,  SYS,   RTCK,      RSVD,      RSVD,      RSVD,          RTCK,      0x20, 11, 0x98, 28, 0xA4, 6),
+       PINGROUP(GPV,   SD,    PCIE,      RSVD,      RSVD,      RSVD,          PCIE,      0x14, 17, 0x8C, 2,  0xA0, 30),
+       PINGROUP(HDINT, LCD,   HDMI,      RSVD,      RSVD,      RSVD,          HDMI,      0x1C, 23, 0x84, 4,  0xAC, 22),
+       PINGROUP(I2CP,  SYS,   I2C,       RSVD,      RSVD,      RSVD,          RSVD4,     0x14, 18, 0x88, 8,  0xA4, 2),
+       PINGROUP(IRRX,  UART,  UARTA,     UARTB,     GMI,       SPI4,          UARTB,     0x14, 20, 0x88, 18, 0xA8, 22),
+       PINGROUP(IRTX,  UART,  UARTA,     UARTB,     GMI,       SPI4,          UARTB,     0x14, 19, 0x88, 16, 0xA8, 20),
+       PINGROUP(KBCA,  SYS,   KBC,       NAND,      SDIO2,     EMC_TEST0_DLL, KBC,       0x14, 22, 0x88, 10, 0xA4, 8),
+       PINGROUP(KBCB,  SYS,   KBC,       NAND,      SDIO2,     MIO,           KBC,       0x14, 21, 0x88, 12, 0xA4, 10),
+       PINGROUP(KBCC,  SYS,   KBC,       NAND,      TRACE,     EMC_TEST1_DLL, KBC,       0x18, 26, 0x88, 14, 0xA4, 12),
+       PINGROUP(KBCD,  SYS,   KBC,       NAND,      SDIO2,     MIO,           KBC,       0x20, 10, 0x98, 26, 0xA4, 14),
+       PINGROUP(KBCE,  SYS,   KBC,       NAND,      OWR,       RSVD,          KBC,       0x14, 26, 0x80, 28, 0xB0, 2),
+       PINGROUP(KBCF,  SYS,   KBC,       NAND,      TRACE,     MIO,           KBC,       0x14, 27, 0x80, 26, 0xB0, 0),
+       PINGROUP(LCSN,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      RSVD,          RSVD4,     0x1C, 31, 0x90, 12, 0xAC, 20),
+       PINGROUP(LD0,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 0,  0x94, 0,  0xAC, 12),
+       PINGROUP(LD1,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 1,  0x94, 2,  0xAC, 12),
+       PINGROUP(LD10,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 10, 0x94, 20, 0xAC, 12),
+       PINGROUP(LD11,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 11, 0x94, 22, 0xAC, 12),
+       PINGROUP(LD12,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 12, 0x94, 24, 0xAC, 12),
+       PINGROUP(LD13,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 13, 0x94, 26, 0xAC, 12),
+       PINGROUP(LD14,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 14, 0x94, 28, 0xAC, 12),
+       PINGROUP(LD15,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 15, 0x94, 30, 0xAC, 12),
+       PINGROUP(LD16,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 16, 0x98, 0,  0xAC, 12),
+       PINGROUP(LD17,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 17, 0x98, 2,  0xAC, 12),
+       PINGROUP(LD2,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 2,  0x94, 4,  0xAC, 12),
+       PINGROUP(LD3,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 3,  0x94, 6,  0xAC, 12),
+       PINGROUP(LD4,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 4,  0x94, 8,  0xAC, 12),
+       PINGROUP(LD5,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 5,  0x94, 10, 0xAC, 12),
+       PINGROUP(LD6,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 6,  0x94, 12, 0xAC, 12),
+       PINGROUP(LD7,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 7,  0x94, 14, 0xAC, 12),
+       PINGROUP(LD8,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 8,  0x94, 16, 0xAC, 12),
+       PINGROUP(LD9,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 9,  0x94, 18, 0xAC, 12),
+       PINGROUP(LDC,   LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 30, 0x90, 14, 0xAC, 20),
+       PINGROUP(LDI,   LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x20, 6,  0x98, 16, 0xAC, 18),
+       PINGROUP(LHP0,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 18, 0x98, 10, 0xAC, 16),
+       PINGROUP(LHP1,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 19, 0x98, 4,  0xAC, 14),
+       PINGROUP(LHP2,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 20, 0x98, 6,  0xAC, 14),
+       PINGROUP(LHS,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x20, 7,  0x90, 22, 0xAC, 22),
+       PINGROUP(LM0,   LCD,   DISPLAYA,  DISPLAYB,  SPI3,      RSVD,          RSVD4,     0x1C, 24, 0x90, 26, 0xAC, 22),
+       PINGROUP(LM1,   LCD,   DISPLAYA,  DISPLAYB,  RSVD,      CRT,           RSVD3,     0x1C, 25, 0x90, 28, 0xAC, 22),
+       PINGROUP(LPP,   LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x20, 8,  0x98, 14, 0xAC, 18),
+       PINGROUP(LPW0,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x20, 3,  0x90, 0,  0xAC, 20),
+       PINGROUP(LPW1,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x20, 4,  0x90, 2,  0xAC, 20),
+       PINGROUP(LPW2,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x20, 5,  0x90, 4,  0xAC, 20),
+       PINGROUP(LSC0,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 27, 0x90, 18, 0xAC, 22),
+       PINGROUP(LSC1,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x1C, 28, 0x90, 20, 0xAC, 20),
+       PINGROUP(LSCK,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x1C, 29, 0x90, 16, 0xAC, 20),
+       PINGROUP(LSDA,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      HDMI,          DISPLAYA,  0x20, 1,  0x90, 8,  0xAC, 20),
+       PINGROUP(LSDI,  LCD,   DISPLAYA,  DISPLAYB,  SPI3,      RSVD,          DISPLAYA,  0x20, 2,  0x90, 6,  0xAC, 20),
+       PINGROUP(LSPI,  LCD,   DISPLAYA,  DISPLAYB,  XIO,       HDMI,          DISPLAYA,  0x20, 0,  0x90, 10, 0xAC, 22),
+       PINGROUP(LVP0,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 21, 0x90, 30, 0xAC, 22),
+       PINGROUP(LVP1,  LCD,   DISPLAYA,  DISPLAYB,  RSVD,      RSVD,          RSVD4,     0x1C, 22, 0x98, 8,  0xAC, 16),
+       PINGROUP(LVS,   LCD,   DISPLAYA,  DISPLAYB,  XIO,       RSVD,          RSVD4,     0x1C, 26, 0x90, 24, 0xAC, 22),
+       PINGROUP(OWC,   SYS,   OWR,       RSVD,      RSVD,      RSVD,          OWR,       0x14, 31, 0x84, 8,  0xB0, 30),
+       PINGROUP(PMC,   SYS,   PWR_ON,    PWR_INTR,  RSVD,      RSVD,          PWR_ON,    0x14, 23, 0x98, 18, -1,   -1),
+       PINGROUP(PTA,   NAND,  I2C2,      HDMI,      GMI,       RSVD,          RSVD4,     0x14, 24, 0x98, 22, 0xA4, 4),
+       PINGROUP(RM,    UART,  I2C,       RSVD,      RSVD,      RSVD,          RSVD4,     0x14, 25, 0x80, 14, 0xA4, 0),
+       PINGROUP(SDB,   SD,    UARTA,     PWM,       SDIO3,     SPI2,          PWM,       0x20, 15, 0x8C, 10, -1,   -1),
+       PINGROUP(SDC,   SD,    PWM,       TWC,       SDIO3,     SPI3,          TWC,       0x18, 1,  0x8C, 12, 0xAC, 28),
+       PINGROUP(SDD,   SD,    UARTA,     PWM,       SDIO3,     SPI3,          PWM,       0x18, 2,  0x8C, 14, 0xAC, 30),
+       PINGROUP(SDIO1, BB,    SDIO1,     RSVD,      UARTE,     UARTA,         RSVD2,     0x14, 30, 0x80, 30, 0xB0, 18),
+       PINGROUP(SLXA,  SD,    PCIE,      SPI4,      SDIO3,     SPI2,          PCIE,      0x18, 3,  0x84, 6,  0xA4, 22),
+       PINGROUP(SLXC,  SD,    SPDIF,     SPI4,      SDIO3,     SPI2,          SPI4,      0x18, 5,  0x84, 10, 0xA4, 26),
+       PINGROUP(SLXD,  SD,    SPDIF,     SPI4,      SDIO3,     SPI2,          SPI4,      0x18, 6,  0x84, 12, 0xA4, 28),
+       PINGROUP(SLXK,  SD,    PCIE,      SPI4,      SDIO3,     SPI2,          PCIE,      0x18, 7,  0x84, 14, 0xA4, 30),
+       PINGROUP(SPDI,  AUDIO, SPDIF,     RSVD,      I2C,       SDIO2,         RSVD2,     0x18, 8,  0x8C, 8,  0xA4, 16),
+       PINGROUP(SPDO,  AUDIO, SPDIF,     RSVD,      I2C,       SDIO2,         RSVD2,     0x18, 9,  0x8C, 6,  0xA4, 18),
+       PINGROUP(SPIA,  AUDIO, SPI1,      SPI2,      SPI3,      GMI,           GMI,       0x18, 10, 0x8C, 30, 0xA8, 4),
+       PINGROUP(SPIB,  AUDIO, SPI1,      SPI2,      SPI3,      GMI,           GMI,       0x18, 11, 0x8C, 28, 0xA8, 6),
+       PINGROUP(SPIC,  AUDIO, SPI1,      SPI2,      SPI3,      GMI,           GMI,       0x18, 12, 0x8C, 26, 0xA8, 8),
+       PINGROUP(SPID,  AUDIO, SPI2,      SPI1,      SPI2_ALT,  GMI,           GMI,       0x18, 13, 0x8C, 24, 0xA8, 10),
+       PINGROUP(SPIE,  AUDIO, SPI2,      SPI1,      SPI2_ALT,  GMI,           GMI,       0x18, 14, 0x8C, 22, 0xA8, 12),
+       PINGROUP(SPIF,  AUDIO, SPI3,      SPI1,      SPI2,      RSVD,          RSVD4,     0x18, 15, 0x8C, 20, 0xA8, 14),
+       PINGROUP(SPIG,  AUDIO, SPI3,      SPI2,      SPI2_ALT,  I2C,           SPI2_ALT,  0x18, 16, 0x8C, 18, 0xA8, 16),
+       PINGROUP(SPIH,  AUDIO, SPI3,      SPI2,      SPI2_ALT,  I2C,           SPI2_ALT,  0x18, 17, 0x8C, 16, 0xA8, 18),
+       PINGROUP(UAA,   BB,    SPI3,      MIPI_HS,   UARTA,     ULPI,          MIPI_HS,   0x18, 18, 0x80, 0,  0xAC, 0),
+       PINGROUP(UAB,   BB,    SPI2,      MIPI_HS,   UARTA,     ULPI,          MIPI_HS,   0x18, 19, 0x80, 2,  0xAC, 2),
+       PINGROUP(UAC,   BB,    OWR,       RSVD,      RSVD,      RSVD,          RSVD4,     0x18, 20, 0x80, 4,  0xAC, 4),
+       PINGROUP(UAD,   UART,  IRDA,      SPDIF,     UARTA,     SPI4,          SPDIF,     0x18, 21, 0x80, 6,  0xAC, 6),
+       PINGROUP(UCA,   UART,  UARTC,     RSVD,      GMI,       RSVD,          RSVD4,     0x18, 22, 0x84, 16, 0xAC, 8),
+       PINGROUP(UCB,   UART,  UARTC,     PWM,       GMI,       RSVD,          RSVD4,     0x18, 23, 0x84, 18, 0xAC, 10),
+       PINGROUP(UDA,   BB,    SPI1,      RSVD,      UARTD,     ULPI,          RSVD2,     0x20, 13, 0x80, 8,  0xB0, 16),
+       /* these pin groups only have pullup and pull down control */
+       PINGROUP(CK32,  SYS,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xB0, 14),
+       PINGROUP(DDRC,  DDR,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xAC, 26),
+       PINGROUP(PMCA,  SYS,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xB0, 4),
+       PINGROUP(PMCB,  SYS,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xB0, 6),
+       PINGROUP(PMCC,  SYS,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xB0, 8),
+       PINGROUP(PMCD,  SYS,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xB0, 10),
+       PINGROUP(PMCE,  SYS,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xB0, 12),
+       PINGROUP(XM2C,  DDR,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xA8, 30),
+       PINGROUP(XM2D,  DDR,   RSVD,      RSVD,      RSVD,      RSVD,          RSVD,      -1,   -1, -1,   -1, 0xA8, 28),
+};
+
+void tegra20_pinmux_init(const struct tegra_pingroup_desc **pg,
+               int *pg_max, const struct tegra_drive_pingroup_desc **pgdrive,
+               int *pgdrive_max)
+{
+       *pg = tegra_soc_pingroups;
+       *pg_max = TEGRA_MAX_PINGROUP;
+       *pgdrive = tegra_soc_drive_pingroups;
+       *pgdrive_max = TEGRA_MAX_DRIVE_PINGROUP;
+}
+
diff --git a/arch/arm/mach-tegra/pinmux-tegra30-tables.c b/arch/arm/mach-tegra/pinmux-tegra30-tables.c
new file mode 100644 (file)
index 0000000..9b1219c
--- /dev/null
@@ -0,0 +1,376 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux-tegra30-tables.c
+ *
+ * Common pinmux configurations for Tegra30 SoCs
+ *
+ * Copyright (C) 2010,2011 NVIDIA Corporation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <mach/pinmux.h>
+#include <mach/pinmux-tegra30.h>
+
+#include "iomap.h"
+
+#define PINGROUP_REG_A 0x868
+#define MUXCTL_REG_A   0x3000
+
+#define DRIVE_PINGROUP(pg_name, r)             \
+       [TEGRA_DRIVE_PINGROUP_ ## pg_name] = {  \
+               .name = #pg_name,               \
+               .reg_bank = 0,                  \
+               .reg = ((r) - PINGROUP_REG_A)   \
+       }
+
+static const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
+       DRIVE_PINGROUP(AO1,             0x868),
+       DRIVE_PINGROUP(AO2,             0x86c),
+       DRIVE_PINGROUP(AT1,             0x870),
+       DRIVE_PINGROUP(AT2,             0x874),
+       DRIVE_PINGROUP(AT3,             0x878),
+       DRIVE_PINGROUP(AT4,             0x87c),
+       DRIVE_PINGROUP(AT5,             0x880),
+       DRIVE_PINGROUP(CDEV1,           0x884),
+       DRIVE_PINGROUP(CDEV2,           0x888),
+       DRIVE_PINGROUP(CSUS,            0x88c),
+       DRIVE_PINGROUP(DAP1,            0x890),
+       DRIVE_PINGROUP(DAP2,            0x894),
+       DRIVE_PINGROUP(DAP3,            0x898),
+       DRIVE_PINGROUP(DAP4,            0x89c),
+       DRIVE_PINGROUP(DBG,             0x8a0),
+       DRIVE_PINGROUP(LCD1,            0x8a4),
+       DRIVE_PINGROUP(LCD2,            0x8a8),
+       DRIVE_PINGROUP(SDIO2,           0x8ac),
+       DRIVE_PINGROUP(SDIO3,           0x8b0),
+       DRIVE_PINGROUP(SPI,             0x8b4),
+       DRIVE_PINGROUP(UAA,             0x8b8),
+       DRIVE_PINGROUP(UAB,             0x8bc),
+       DRIVE_PINGROUP(UART2,           0x8c0),
+       DRIVE_PINGROUP(UART3,           0x8c4),
+       DRIVE_PINGROUP(VI1,             0x8c8),
+       DRIVE_PINGROUP(SDIO1,           0x8ec),
+       DRIVE_PINGROUP(CRT,             0x8f8),
+       DRIVE_PINGROUP(DDC,             0x8fc),
+       DRIVE_PINGROUP(GMA,             0x900),
+       DRIVE_PINGROUP(GMB,             0x904),
+       DRIVE_PINGROUP(GMC,             0x908),
+       DRIVE_PINGROUP(GMD,             0x90c),
+       DRIVE_PINGROUP(GME,             0x910),
+       DRIVE_PINGROUP(GMF,             0x914),
+       DRIVE_PINGROUP(GMG,             0x918),
+       DRIVE_PINGROUP(GMH,             0x91c),
+       DRIVE_PINGROUP(OWR,             0x920),
+       DRIVE_PINGROUP(UAD,             0x924),
+       DRIVE_PINGROUP(GPV,             0x928),
+       DRIVE_PINGROUP(DEV3,            0x92c),
+       DRIVE_PINGROUP(CEC,             0x938),
+};
+
+#define PINGROUP(pg_name, vdd, f0, f1, f2, f3, fs, iod, reg)   \
+       [TEGRA_PINGROUP_ ## pg_name] = {                        \
+               .name = #pg_name,                               \
+               .vddio = TEGRA_VDDIO_ ## vdd,                   \
+               .funcs = {                                      \
+                       TEGRA_MUX_ ## f0,                       \
+                       TEGRA_MUX_ ## f1,                       \
+                       TEGRA_MUX_ ## f2,                       \
+                       TEGRA_MUX_ ## f3,                       \
+               },                                              \
+               .func_safe = TEGRA_MUX_ ## fs,                  \
+               .tri_bank = 1,                                  \
+               .tri_reg = ((reg) - MUXCTL_REG_A),              \
+               .tri_bit = 4,                                   \
+               .mux_bank = 1,                                  \
+               .mux_reg = ((reg) - MUXCTL_REG_A),              \
+               .mux_bit = 0,                                   \
+               .pupd_bank = 1,                                 \
+               .pupd_reg = ((reg) - MUXCTL_REG_A),             \
+               .pupd_bit = 2,                                  \
+               .io_default = TEGRA_PIN_ ## iod,                \
+               .od_bit = 6,                                    \
+               .lock_bit = 7,                                  \
+               .ioreset_bit = 8,                               \
+       }
+
+static const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
+       /*       NAME             VDD       f0          f1          f2          f3          fSafe       io      reg */
+       PINGROUP(ULPI_DATA0,      BB,       SPI3,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x3000),
+       PINGROUP(ULPI_DATA1,      BB,       SPI3,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x3004),
+       PINGROUP(ULPI_DATA2,      BB,       SPI3,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x3008),
+       PINGROUP(ULPI_DATA3,      BB,       SPI3,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x300c),
+       PINGROUP(ULPI_DATA4,      BB,       SPI2,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x3010),
+       PINGROUP(ULPI_DATA5,      BB,       SPI2,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x3014),
+       PINGROUP(ULPI_DATA6,      BB,       SPI2,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x3018),
+       PINGROUP(ULPI_DATA7,      BB,       SPI2,       HSI,        UARTA,      ULPI,       RSVD,       INPUT,  0x301c),
+       PINGROUP(ULPI_CLK,        BB,       SPI1,       RSVD,       UARTD,      ULPI,       RSVD,       INPUT,  0x3020),
+       PINGROUP(ULPI_DIR,        BB,       SPI1,       RSVD,       UARTD,      ULPI,       RSVD,       INPUT,  0x3024),
+       PINGROUP(ULPI_NXT,        BB,       SPI1,       RSVD,       UARTD,      ULPI,       RSVD,       INPUT,  0x3028),
+       PINGROUP(ULPI_STP,        BB,       SPI1,       RSVD,       UARTD,      ULPI,       RSVD,       INPUT,  0x302c),
+       PINGROUP(DAP3_FS,         BB,       I2S2,       RSVD1,      DISPLAYA,   DISPLAYB,   RSVD,       INPUT,  0x3030),
+       PINGROUP(DAP3_DIN,        BB,       I2S2,       RSVD1,      DISPLAYA,   DISPLAYB,   RSVD,       INPUT,  0x3034),
+       PINGROUP(DAP3_DOUT,       BB,       I2S2,       RSVD1,      DISPLAYA,   DISPLAYB,   RSVD,       INPUT,  0x3038),
+       PINGROUP(DAP3_SCLK,       BB,       I2S2,       RSVD1,      DISPLAYA,   DISPLAYB,   RSVD,       INPUT,  0x303c),
+       PINGROUP(GPIO_PV0,        BB,       RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3040),
+       PINGROUP(GPIO_PV1,        BB,       RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3044),
+       PINGROUP(SDMMC1_CLK,      SDMMC1,   SDIO1,      RSVD1,      RSVD2,      INVALID,    RSVD,       INPUT,  0x3048),
+       PINGROUP(SDMMC1_CMD,      SDMMC1,   SDIO1,      RSVD1,      RSVD2,      INVALID,    RSVD,       INPUT,  0x304c),
+       PINGROUP(SDMMC1_DAT3,     SDMMC1,   SDIO1,      RSVD1,      UARTE,      INVALID,    RSVD,       INPUT,  0x3050),
+       PINGROUP(SDMMC1_DAT2,     SDMMC1,   SDIO1,      RSVD1,      UARTE,      INVALID,    RSVD,       INPUT,  0x3054),
+       PINGROUP(SDMMC1_DAT1,     SDMMC1,   SDIO1,      RSVD1,      UARTE,      INVALID,    RSVD,       INPUT,  0x3058),
+       PINGROUP(SDMMC1_DAT0,     SDMMC1,   SDIO1,      RSVD1,      UARTE,      INVALID,    RSVD,       INPUT,  0x305c),
+       PINGROUP(GPIO_PV2,        SDMMC1,   OWR,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3060),
+       PINGROUP(GPIO_PV3,        SDMMC1,   INVALID,    RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3064),
+       PINGROUP(CLK2_OUT,        SDMMC1,   EXTPERIPH2, RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3068),
+       PINGROUP(CLK2_REQ,        SDMMC1,   DAP,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x306c),
+       PINGROUP(LCD_PWR1,        LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x3070),
+       PINGROUP(LCD_PWR2,        LCD,      DISPLAYA,   DISPLAYB,   SPI5,       INVALID,    RSVD,       OUTPUT, 0x3074),
+       PINGROUP(LCD_SDIN,        LCD,      DISPLAYA,   DISPLAYB,   SPI5,       RSVD,       RSVD,       OUTPUT, 0x3078),
+       PINGROUP(LCD_SDOUT,       LCD,      DISPLAYA,   DISPLAYB,   SPI5,       INVALID,    RSVD,       OUTPUT, 0x307c),
+       PINGROUP(LCD_WR_N,        LCD,      DISPLAYA,   DISPLAYB,   SPI5,       INVALID,    RSVD,       OUTPUT, 0x3080),
+       PINGROUP(LCD_CS0_N,       LCD,      DISPLAYA,   DISPLAYB,   SPI5,       RSVD,       RSVD,       OUTPUT, 0x3084),
+       PINGROUP(LCD_DC0,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x3088),
+       PINGROUP(LCD_SCK,         LCD,      DISPLAYA,   DISPLAYB,   SPI5,       INVALID,    RSVD,       OUTPUT, 0x308c),
+       PINGROUP(LCD_PWR0,        LCD,      DISPLAYA,   DISPLAYB,   SPI5,       INVALID,    RSVD,       OUTPUT, 0x3090),
+       PINGROUP(LCD_PCLK,        LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x3094),
+       PINGROUP(LCD_DE,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x3098),
+       PINGROUP(LCD_HSYNC,       LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x309c),
+       PINGROUP(LCD_VSYNC,       LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30a0),
+       PINGROUP(LCD_D0,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30a4),
+       PINGROUP(LCD_D1,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30a8),
+       PINGROUP(LCD_D2,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30ac),
+       PINGROUP(LCD_D3,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30b0),
+       PINGROUP(LCD_D4,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30b4),
+       PINGROUP(LCD_D5,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30b8),
+       PINGROUP(LCD_D6,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30bc),
+       PINGROUP(LCD_D7,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30c0),
+       PINGROUP(LCD_D8,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30c4),
+       PINGROUP(LCD_D9,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30c8),
+       PINGROUP(LCD_D10,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30cc),
+       PINGROUP(LCD_D11,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30d0),
+       PINGROUP(LCD_D12,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30d4),
+       PINGROUP(LCD_D13,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30d8),
+       PINGROUP(LCD_D14,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30dc),
+       PINGROUP(LCD_D15,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30e0),
+       PINGROUP(LCD_D16,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30e4),
+       PINGROUP(LCD_D17,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30e8),
+       PINGROUP(LCD_D18,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30ec),
+       PINGROUP(LCD_D19,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30f0),
+       PINGROUP(LCD_D20,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30f4),
+       PINGROUP(LCD_D21,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30f8),
+       PINGROUP(LCD_D22,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x30fc),
+       PINGROUP(LCD_D23,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x3100),
+       PINGROUP(LCD_CS1_N,       LCD,      DISPLAYA,   DISPLAYB,   SPI5,       RSVD2,      RSVD,       OUTPUT, 0x3104),
+       PINGROUP(LCD_M1,          LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x3108),
+       PINGROUP(LCD_DC1,         LCD,      DISPLAYA,   DISPLAYB,   RSVD1,      RSVD2,      RSVD,       OUTPUT, 0x310c),
+       PINGROUP(HDMI_INT,        LCD,      RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3110),
+       PINGROUP(DDC_SCL,         LCD,      I2C4,       RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3114),
+       PINGROUP(DDC_SDA,         LCD,      I2C4,       RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3118),
+       PINGROUP(CRT_HSYNC,       LCD,      CRT,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x311c),
+       PINGROUP(CRT_VSYNC,       LCD,      CRT,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3120),
+       PINGROUP(VI_D0,           VI,       INVALID,    RSVD1,      VI,         RSVD2,      RSVD,       INPUT,  0x3124),
+       PINGROUP(VI_D1,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3128),
+       PINGROUP(VI_D2,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x312c),
+       PINGROUP(VI_D3,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3130),
+       PINGROUP(VI_D4,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3134),
+       PINGROUP(VI_D5,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3138),
+       PINGROUP(VI_D6,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x313c),
+       PINGROUP(VI_D7,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3140),
+       PINGROUP(VI_D8,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3144),
+       PINGROUP(VI_D9,           VI,       INVALID,    SDIO2,      VI,         RSVD1,      RSVD,       INPUT,  0x3148),
+       PINGROUP(VI_D10,          VI,       INVALID,    RSVD1,      VI,         RSVD2,      RSVD,       INPUT,  0x314c),
+       PINGROUP(VI_D11,          VI,       INVALID,    RSVD1,      VI,         RSVD2,      RSVD,       INPUT,  0x3150),
+       PINGROUP(VI_PCLK,         VI,       RSVD1,      SDIO2,      VI,         RSVD2,      RSVD,       INPUT,  0x3154),
+       PINGROUP(VI_MCLK,         VI,       VI,         INVALID,    INVALID,    INVALID,    RSVD,       INPUT,  0x3158),
+       PINGROUP(VI_VSYNC,        VI,       INVALID,    RSVD1,      VI,         RSVD2,      RSVD,       INPUT,  0x315c),
+       PINGROUP(VI_HSYNC,        VI,       INVALID,    RSVD1,      VI,         RSVD2,      RSVD,       INPUT,  0x3160),
+       PINGROUP(UART2_RXD,       UART,     IRDA,       SPDIF,      UARTA,      SPI4,       RSVD,       INPUT,  0x3164),
+       PINGROUP(UART2_TXD,       UART,     IRDA,       SPDIF,      UARTA,      SPI4,       RSVD,       INPUT,  0x3168),
+       PINGROUP(UART2_RTS_N,     UART,     UARTA,      UARTB,      GMI,        SPI4,       RSVD,       INPUT,  0x316c),
+       PINGROUP(UART2_CTS_N,     UART,     UARTA,      UARTB,      GMI,        SPI4,       RSVD,       INPUT,  0x3170),
+       PINGROUP(UART3_TXD,       UART,     UARTC,      RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x3174),
+       PINGROUP(UART3_RXD,       UART,     UARTC,      RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x3178),
+       PINGROUP(UART3_CTS_N,     UART,     UARTC,      RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x317c),
+       PINGROUP(UART3_RTS_N,     UART,     UARTC,      PWM0,       GMI,        RSVD2,      RSVD,       INPUT,  0x3180),
+       PINGROUP(GPIO_PU0,        UART,     OWR,        UARTA,      GMI,        RSVD1,      RSVD,       INPUT,  0x3184),
+       PINGROUP(GPIO_PU1,        UART,     RSVD1,      UARTA,      GMI,        RSVD2,      RSVD,       INPUT,  0x3188),
+       PINGROUP(GPIO_PU2,        UART,     RSVD1,      UARTA,      GMI,        RSVD2,      RSVD,       INPUT,  0x318c),
+       PINGROUP(GPIO_PU3,        UART,     PWM0,       UARTA,      GMI,        RSVD1,      RSVD,       INPUT,  0x3190),
+       PINGROUP(GPIO_PU4,        UART,     PWM1,       UARTA,      GMI,        RSVD1,      RSVD,       INPUT,  0x3194),
+       PINGROUP(GPIO_PU5,        UART,     PWM2,       UARTA,      GMI,        RSVD1,      RSVD,       INPUT,  0x3198),
+       PINGROUP(GPIO_PU6,        UART,     PWM3,       UARTA,      GMI,        RSVD1,      RSVD,       INPUT,  0x319c),
+       PINGROUP(GEN1_I2C_SDA,    UART,     I2C,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x31a0),
+       PINGROUP(GEN1_I2C_SCL,    UART,     I2C,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x31a4),
+       PINGROUP(DAP4_FS,         UART,     I2S3,       RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x31a8),
+       PINGROUP(DAP4_DIN,        UART,     I2S3,       RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x31ac),
+       PINGROUP(DAP4_DOUT,       UART,     I2S3,       RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x31b0),
+       PINGROUP(DAP4_SCLK,       UART,     I2S3,       RSVD1,      GMI,        RSVD2,      RSVD,       INPUT,  0x31b4),
+       PINGROUP(CLK3_OUT,        UART,     EXTPERIPH3, RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x31b8),
+       PINGROUP(CLK3_REQ,        UART,     DEV3,       RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x31bc),
+       PINGROUP(GMI_WP_N,        GMI,      RSVD1,      NAND,       GMI,        GMI_ALT,    RSVD,       INPUT,  0x31c0),
+       PINGROUP(GMI_IORDY,       GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31c4),
+       PINGROUP(GMI_WAIT,        GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31c8),
+       PINGROUP(GMI_ADV_N,       GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31cc),
+       PINGROUP(GMI_CLK,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31d0),
+       PINGROUP(GMI_CS0_N,       GMI,      RSVD1,      NAND,       GMI,        INVALID,    RSVD,       INPUT,  0x31d4),
+       PINGROUP(GMI_CS1_N,       GMI,      RSVD1,      NAND,       GMI,        DTV,        RSVD,       INPUT,  0x31d8),
+       PINGROUP(GMI_CS2_N,       GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31dc),
+       PINGROUP(GMI_CS3_N,       GMI,      RSVD1,      NAND,       GMI,        GMI_ALT,    RSVD,       INPUT,  0x31e0),
+       PINGROUP(GMI_CS4_N,       GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31e4),
+       PINGROUP(GMI_CS6_N,       GMI,      NAND,       NAND_ALT,   GMI,        SATA,       RSVD,       INPUT,  0x31e8),
+       PINGROUP(GMI_CS7_N,       GMI,      NAND,       NAND_ALT,   GMI,        GMI_ALT,    RSVD,       INPUT,  0x31ec),
+       PINGROUP(GMI_AD0,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31f0),
+       PINGROUP(GMI_AD1,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31f4),
+       PINGROUP(GMI_AD2,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31f8),
+       PINGROUP(GMI_AD3,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x31fc),
+       PINGROUP(GMI_AD4,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3200),
+       PINGROUP(GMI_AD5,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3204),
+       PINGROUP(GMI_AD6,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3208),
+       PINGROUP(GMI_AD7,         GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x320c),
+       PINGROUP(GMI_AD8,         GMI,      PWM0,       NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3210),
+       PINGROUP(GMI_AD9,         GMI,      PWM1,       NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3214),
+       PINGROUP(GMI_AD10,        GMI,      PWM2,       NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3218),
+       PINGROUP(GMI_AD11,        GMI,      PWM3,       NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x321c),
+       PINGROUP(GMI_AD12,        GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3220),
+       PINGROUP(GMI_AD13,        GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3224),
+       PINGROUP(GMI_AD14,        GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x3228),
+       PINGROUP(GMI_AD15,        GMI,      RSVD1,      NAND,       GMI,        RSVD2,      RSVD,       INPUT,  0x322c),
+       PINGROUP(GMI_A16,         GMI,      UARTD,      SPI4,       GMI,        GMI_ALT,    RSVD,       INPUT,  0x3230),
+       PINGROUP(GMI_A17,         GMI,      UARTD,      SPI4,       GMI,        INVALID,    RSVD,       INPUT,  0x3234),
+       PINGROUP(GMI_A18,         GMI,      UARTD,      SPI4,       GMI,        INVALID,    RSVD,       INPUT,  0x3238),
+       PINGROUP(GMI_A19,         GMI,      UARTD,      SPI4,       GMI,        RSVD3,      RSVD,       INPUT,  0x323c),
+       PINGROUP(GMI_WR_N,        GMI,      RSVD1,      NAND,       GMI,        RSVD3,      RSVD,       INPUT,  0x3240),
+       PINGROUP(GMI_OE_N,        GMI,      RSVD1,      NAND,       GMI,        RSVD3,      RSVD,       INPUT,  0x3244),
+       PINGROUP(GMI_DQS,         GMI,      RSVD1,      NAND,       GMI,        RSVD3,      RSVD,       INPUT,  0x3248),
+       PINGROUP(GMI_RST_N,       GMI,      NAND,       NAND_ALT,   GMI,        RSVD3,      RSVD,       INPUT,  0x324c),
+       PINGROUP(GEN2_I2C_SCL,    GMI,      I2C2,       INVALID,    GMI,        RSVD3,      RSVD,       INPUT,  0x3250),
+       PINGROUP(GEN2_I2C_SDA,    GMI,      I2C2,       INVALID,    GMI,        RSVD3,      RSVD,       INPUT,  0x3254),
+       PINGROUP(SDMMC4_CLK,      SDMMC4,   INVALID,    NAND,       GMI,        SDIO4,      RSVD,       INPUT,  0x3258),
+       PINGROUP(SDMMC4_CMD,      SDMMC4,   I2C3,       NAND,       GMI,        SDIO4,      RSVD,       INPUT,  0x325c),
+       PINGROUP(SDMMC4_DAT0,     SDMMC4,   UARTE,      SPI3,       GMI,        SDIO4,      RSVD,       INPUT,  0x3260),
+       PINGROUP(SDMMC4_DAT1,     SDMMC4,   UARTE,      SPI3,       GMI,        SDIO4,      RSVD,       INPUT,  0x3264),
+       PINGROUP(SDMMC4_DAT2,     SDMMC4,   UARTE,      SPI3,       GMI,        SDIO4,      RSVD,       INPUT,  0x3268),
+       PINGROUP(SDMMC4_DAT3,     SDMMC4,   UARTE,      SPI3,       GMI,        SDIO4,      RSVD,       INPUT,  0x326c),
+       PINGROUP(SDMMC4_DAT4,     SDMMC4,   I2C3,       I2S4,       GMI,        SDIO4,      RSVD,       INPUT,  0x3270),
+       PINGROUP(SDMMC4_DAT5,     SDMMC4,   VGP3,       I2S4,       GMI,        SDIO4,      RSVD,       INPUT,  0x3274),
+       PINGROUP(SDMMC4_DAT6,     SDMMC4,   VGP4,       I2S4,       GMI,        SDIO4,      RSVD,       INPUT,  0x3278),
+       PINGROUP(SDMMC4_DAT7,     SDMMC4,   VGP5,       I2S4,       GMI,        SDIO4,      RSVD,       INPUT,  0x327c),
+       PINGROUP(SDMMC4_RST_N,    SDMMC4,   VGP6,       RSVD1,      RSVD2,      POPSDMMC4,  RSVD,       INPUT,  0x3280),
+       PINGROUP(CAM_MCLK,        CAM,      VI,         INVALID,    VI_ALT2,    POPSDMMC4,  RSVD,       INPUT,  0x3284),
+       PINGROUP(GPIO_PCC1,       CAM,      I2S4,       RSVD1,      RSVD2,      POPSDMMC4,  RSVD,       INPUT,  0x3288),
+       PINGROUP(GPIO_PBB0,       CAM,      I2S4,       RSVD1,      RSVD2,      POPSDMMC4,  RSVD,       INPUT,  0x328c),
+       PINGROUP(CAM_I2C_SCL,     CAM,      INVALID,    I2C3,       RSVD2,      POPSDMMC4,  RSVD,       INPUT,  0x3290),
+       PINGROUP(CAM_I2C_SDA,     CAM,      INVALID,    I2C3,       RSVD2,      POPSDMMC4,  RSVD,       INPUT,  0x3294),
+       PINGROUP(GPIO_PBB3,       CAM,      VGP3,       DISPLAYA,   DISPLAYB,   POPSDMMC4,  RSVD,       INPUT,  0x3298),
+       PINGROUP(GPIO_PBB4,       CAM,      VGP4,       DISPLAYA,   DISPLAYB,   POPSDMMC4,  RSVD,       INPUT,  0x329c),
+       PINGROUP(GPIO_PBB5,       CAM,      VGP5,       DISPLAYA,   DISPLAYB,   POPSDMMC4,  RSVD,       INPUT,  0x32a0),
+       PINGROUP(GPIO_PBB6,       CAM,      VGP6,       DISPLAYA,   DISPLAYB,   POPSDMMC4,  RSVD,       INPUT,  0x32a4),
+       PINGROUP(GPIO_PBB7,       CAM,      I2S4,       RSVD1,      RSVD2,      POPSDMMC4,  RSVD,       INPUT,  0x32a8),
+       PINGROUP(GPIO_PCC2,       CAM,      I2S4,       RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x32ac),
+       PINGROUP(JTAG_RTCK,       SYS,      RTCK,       RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x32b0),
+       PINGROUP(PWR_I2C_SCL,     SYS,      I2CPWR,     RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x32b4),
+       PINGROUP(PWR_I2C_SDA,     SYS,      I2CPWR,     RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x32b8),
+       PINGROUP(KB_ROW0,         SYS,      KBC,        INVALID,    RSVD2,      RSVD3,      RSVD,       INPUT,  0x32bc),
+       PINGROUP(KB_ROW1,         SYS,      KBC,        INVALID,    RSVD2,      RSVD3,      RSVD,       INPUT,  0x32c0),
+       PINGROUP(KB_ROW2,         SYS,      KBC,        INVALID,    RSVD2,      RSVD3,      RSVD,       INPUT,  0x32c4),
+       PINGROUP(KB_ROW3,         SYS,      KBC,        INVALID,    RSVD2,      INVALID,    RSVD,       INPUT,  0x32c8),
+       PINGROUP(KB_ROW4,         SYS,      KBC,        INVALID,    TRACE,      RSVD3,      RSVD,       INPUT,  0x32cc),
+       PINGROUP(KB_ROW5,         SYS,      KBC,        INVALID,    TRACE,      OWR,        RSVD,       INPUT,  0x32d0),
+       PINGROUP(KB_ROW6,         SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32d4),
+       PINGROUP(KB_ROW7,         SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32d8),
+       PINGROUP(KB_ROW8,         SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32dc),
+       PINGROUP(KB_ROW9,         SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32e0),
+       PINGROUP(KB_ROW10,        SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32e4),
+       PINGROUP(KB_ROW11,        SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32e8),
+       PINGROUP(KB_ROW12,        SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32ec),
+       PINGROUP(KB_ROW13,        SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32f0),
+       PINGROUP(KB_ROW14,        SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32f4),
+       PINGROUP(KB_ROW15,        SYS,      KBC,        INVALID,    SDIO2,      INVALID,    RSVD,       INPUT,  0x32f8),
+       PINGROUP(KB_COL0,         SYS,      KBC,        INVALID,    TRACE,      INVALID,    RSVD,       INPUT,  0x32fc),
+       PINGROUP(KB_COL1,         SYS,      KBC,        INVALID,    TRACE,      INVALID,    RSVD,       INPUT,  0x3300),
+       PINGROUP(KB_COL2,         SYS,      KBC,        INVALID,    TRACE,      RSVD,       RSVD,       INPUT,  0x3304),
+       PINGROUP(KB_COL3,         SYS,      KBC,        INVALID,    TRACE,      RSVD,       RSVD,       INPUT,  0x3308),
+       PINGROUP(KB_COL4,         SYS,      KBC,        INVALID,    TRACE,      RSVD,       RSVD,       INPUT,  0x330c),
+       PINGROUP(KB_COL5,         SYS,      KBC,        INVALID,    TRACE,      RSVD,       RSVD,       INPUT,  0x3310),
+       PINGROUP(KB_COL6,         SYS,      KBC,        INVALID,    TRACE,      INVALID,    RSVD,       INPUT,  0x3314),
+       PINGROUP(KB_COL7,         SYS,      KBC,        INVALID,    TRACE,      INVALID,    RSVD,       INPUT,  0x3318),
+       PINGROUP(CLK_32K_OUT,     SYS,      BLINK,      RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x331c),
+       PINGROUP(SYS_CLK_REQ,     SYS,      SYSCLK,     RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x3320),
+       PINGROUP(CORE_PWR_REQ,    SYS,      RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3324),
+       PINGROUP(CPU_PWR_REQ,     SYS,      RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3328),
+       PINGROUP(PWR_INT_N,       SYS,      RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x332c),
+       PINGROUP(CLK_32K_IN,      SYS,      RSVD,       RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3330),
+       PINGROUP(OWR,             SYS,      OWR,        RSVD,       RSVD,       RSVD,       RSVD,       INPUT,  0x3334),
+       PINGROUP(DAP1_FS,         AUDIO,    I2S0,       HDA,        GMI,        SDIO2,      RSVD,       INPUT,  0x3338),
+       PINGROUP(DAP1_DIN,        AUDIO,    I2S0,       HDA,        GMI,        SDIO2,      RSVD,       INPUT,  0x333c),
+       PINGROUP(DAP1_DOUT,       AUDIO,    I2S0,       HDA,        GMI,        SDIO2,      RSVD,       INPUT,  0x3340),
+       PINGROUP(DAP1_SCLK,       AUDIO,    I2S0,       HDA,        GMI,        SDIO2,      RSVD,       INPUT,  0x3344),
+       PINGROUP(CLK1_REQ,        AUDIO,    DAP,        HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x3348),
+       PINGROUP(CLK1_OUT,        AUDIO,    EXTPERIPH1, RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x334c),
+       PINGROUP(SPDIF_IN,        AUDIO,    SPDIF,      HDA,        INVALID,    DAPSDMMC2,  RSVD,       INPUT,  0x3350),
+       PINGROUP(SPDIF_OUT,       AUDIO,    SPDIF,      RSVD1,      INVALID,    DAPSDMMC2,  RSVD,       INPUT,  0x3354),
+       PINGROUP(DAP2_FS,         AUDIO,    I2S1,       HDA,        RSVD2,      GMI,        RSVD,       INPUT,  0x3358),
+       PINGROUP(DAP2_DIN,        AUDIO,    I2S1,       HDA,        RSVD2,      GMI,        RSVD,       INPUT,  0x335c),
+       PINGROUP(DAP2_DOUT,       AUDIO,    I2S1,       HDA,        RSVD2,      GMI,        RSVD,       INPUT,  0x3360),
+       PINGROUP(DAP2_SCLK,       AUDIO,    I2S1,       HDA,        RSVD2,      GMI,        RSVD,       INPUT,  0x3364),
+       PINGROUP(SPI2_MOSI,       AUDIO,    SPI6,       SPI2,       INVALID,    GMI,        RSVD,       INPUT,  0x3368),
+       PINGROUP(SPI2_MISO,       AUDIO,    SPI6,       SPI2,       INVALID,    GMI,        RSVD,       INPUT,  0x336c),
+       PINGROUP(SPI2_CS0_N,      AUDIO,    SPI6,       SPI2,       INVALID,    GMI,        RSVD,       INPUT,  0x3370),
+       PINGROUP(SPI2_SCK,        AUDIO,    SPI6,       SPI2,       INVALID,    GMI,        RSVD,       INPUT,  0x3374),
+       PINGROUP(SPI1_MOSI,       AUDIO,    SPI2,       SPI1,       INVALID,    GMI,        RSVD,       INPUT,  0x3378),
+       PINGROUP(SPI1_SCK,        AUDIO,    SPI2,       SPI1,       INVALID,    GMI,        RSVD,       INPUT,  0x337c),
+       PINGROUP(SPI1_CS0_N,      AUDIO,    SPI2,       SPI1,       INVALID,    GMI,        RSVD,       INPUT,  0x3380),
+       PINGROUP(SPI1_MISO,       AUDIO,    INVALID,    SPI1,       INVALID,    RSVD3,      RSVD,       INPUT,  0x3384),
+       PINGROUP(SPI2_CS1_N,      AUDIO,    INVALID,    SPI2,       INVALID,    INVALID,    RSVD,       INPUT,  0x3388),
+       PINGROUP(SPI2_CS2_N,      AUDIO,    INVALID,    SPI2,       INVALID,    INVALID,    RSVD,       INPUT,  0x338c),
+       PINGROUP(SDMMC3_CLK,      SDMMC3,   UARTA,      PWM2,       SDIO3,      INVALID,    RSVD,       INPUT,  0x3390),
+       PINGROUP(SDMMC3_CMD,      SDMMC3,   UARTA,      PWM3,       SDIO3,      INVALID,    RSVD,       INPUT,  0x3394),
+       PINGROUP(SDMMC3_DAT0,     SDMMC3,   RSVD,       RSVD1,      SDIO3,      INVALID,    RSVD,       INPUT,  0x3398),
+       PINGROUP(SDMMC3_DAT1,     SDMMC3,   RSVD,       RSVD1,      SDIO3,      INVALID,    RSVD,       INPUT,  0x339c),
+       PINGROUP(SDMMC3_DAT2,     SDMMC3,   RSVD,       PWM1,       SDIO3,      INVALID,    RSVD,       INPUT,  0x33a0),
+       PINGROUP(SDMMC3_DAT3,     SDMMC3,   RSVD,       PWM0,       SDIO3,      INVALID,    RSVD,       INPUT,  0x33a4),
+       PINGROUP(SDMMC3_DAT4,     SDMMC3,   PWM1,       INVALID,    SDIO3,      INVALID,    RSVD,       INPUT,  0x33a8),
+       PINGROUP(SDMMC3_DAT5,     SDMMC3,   PWM0,       INVALID,    SDIO3,      INVALID,    RSVD,       INPUT,  0x33ac),
+       PINGROUP(SDMMC3_DAT6,     SDMMC3,   SPDIF,      INVALID,    SDIO3,      INVALID,    RSVD,       INPUT,  0x33b0),
+       PINGROUP(SDMMC3_DAT7,     SDMMC3,   SPDIF,      INVALID,    SDIO3,      INVALID,    RSVD,       INPUT,  0x33b4),
+       PINGROUP(PEX_L0_PRSNT_N,  PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33b8),
+       PINGROUP(PEX_L0_RST_N,    PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33bc),
+       PINGROUP(PEX_L0_CLKREQ_N, PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33c0),
+       PINGROUP(PEX_WAKE_N,      PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33c4),
+       PINGROUP(PEX_L1_PRSNT_N,  PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33c8),
+       PINGROUP(PEX_L1_RST_N,    PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33cc),
+       PINGROUP(PEX_L1_CLKREQ_N, PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33d0),
+       PINGROUP(PEX_L2_PRSNT_N,  PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33d4),
+       PINGROUP(PEX_L2_RST_N,    PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33d8),
+       PINGROUP(PEX_L2_CLKREQ_N, PEXCTL,   PCIE,       HDA,        RSVD2,      RSVD3,      RSVD,       INPUT,  0x33dc),
+       PINGROUP(HDMI_CEC,        SYS,      CEC,        RSVD1,      RSVD2,      RSVD3,      RSVD,       INPUT,  0x33e0),
+};
+
+void tegra30_pinmux_init(const struct tegra_pingroup_desc **pg,
+               int *pg_max, const struct tegra_drive_pingroup_desc **pgdrive,
+               int *pgdrive_max)
+{
+       *pg = tegra_soc_pingroups;
+       *pg_max = TEGRA_MAX_PINGROUP;
+       *pgdrive = tegra_soc_drive_pingroups;
+       *pgdrive_max = TEGRA_MAX_DRIVE_PINGROUP;
+}
+
diff --git a/arch/arm/mach-tegra/pinmux.c b/arch/arm/mach-tegra/pinmux.c
new file mode 100644 (file)
index 0000000..e2593c2
--- /dev/null
@@ -0,0 +1,988 @@
+/*
+ * linux/arch/arm/mach-tegra/pinmux.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/of_device.h>
+
+#include <mach/pinmux.h>
+
+#include "iomap.h"
+
+#define HSM_EN(reg)    (((reg) >> 2) & 0x1)
+#define SCHMT_EN(reg)  (((reg) >> 3) & 0x1)
+#define LPMD(reg)      (((reg) >> 4) & 0x3)
+#define DRVDN(reg)     (((reg) >> 12) & 0x1f)
+#define DRVUP(reg)     (((reg) >> 20) & 0x1f)
+#define SLWR(reg)      (((reg) >> 28) & 0x3)
+#define SLWF(reg)      (((reg) >> 30) & 0x3)
+
+static const struct tegra_pingroup_desc *pingroups;
+static const struct tegra_drive_pingroup_desc *drive_pingroups;
+static int pingroup_max;
+static int drive_max;
+
+static char *tegra_mux_names[TEGRA_MAX_MUX] = {
+       [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
+       [TEGRA_MUX_APB_CLK] = "APB_CLK",
+       [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC",
+       [TEGRA_MUX_CRT] = "CRT",
+       [TEGRA_MUX_DAP1] = "DAP1",
+       [TEGRA_MUX_DAP2] = "DAP2",
+       [TEGRA_MUX_DAP3] = "DAP3",
+       [TEGRA_MUX_DAP4] = "DAP4",
+       [TEGRA_MUX_DAP5] = "DAP5",
+       [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
+       [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
+       [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
+       [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
+       [TEGRA_MUX_GMI] = "GMI",
+       [TEGRA_MUX_GMI_INT] = "GMI_INT",
+       [TEGRA_MUX_HDMI] = "HDMI",
+       [TEGRA_MUX_I2C] = "I2C",
+       [TEGRA_MUX_I2C2] = "I2C2",
+       [TEGRA_MUX_I2C3] = "I2C3",
+       [TEGRA_MUX_IDE] = "IDE",
+       [TEGRA_MUX_IRDA] = "IRDA",
+       [TEGRA_MUX_KBC] = "KBC",
+       [TEGRA_MUX_MIO] = "MIO",
+       [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
+       [TEGRA_MUX_NAND] = "NAND",
+       [TEGRA_MUX_OSC] = "OSC",
+       [TEGRA_MUX_OWR] = "OWR",
+       [TEGRA_MUX_PCIE] = "PCIE",
+       [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
+       [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
+       [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
+       [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
+       [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
+       [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
+       [TEGRA_MUX_PWM] = "PWM",
+       [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
+       [TEGRA_MUX_PWR_ON] = "PWR_ON",
+       [TEGRA_MUX_RTCK] = "RTCK",
+       [TEGRA_MUX_SDIO1] = "SDIO1",
+       [TEGRA_MUX_SDIO2] = "SDIO2",
+       [TEGRA_MUX_SDIO3] = "SDIO3",
+       [TEGRA_MUX_SDIO4] = "SDIO4",
+       [TEGRA_MUX_SFLASH] = "SFLASH",
+       [TEGRA_MUX_SPDIF] = "SPDIF",
+       [TEGRA_MUX_SPI1] = "SPI1",
+       [TEGRA_MUX_SPI2] = "SPI2",
+       [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
+       [TEGRA_MUX_SPI3] = "SPI3",
+       [TEGRA_MUX_SPI4] = "SPI4",
+       [TEGRA_MUX_TRACE] = "TRACE",
+       [TEGRA_MUX_TWC] = "TWC",
+       [TEGRA_MUX_UARTA] = "UARTA",
+       [TEGRA_MUX_UARTB] = "UARTB",
+       [TEGRA_MUX_UARTC] = "UARTC",
+       [TEGRA_MUX_UARTD] = "UARTD",
+       [TEGRA_MUX_UARTE] = "UARTE",
+       [TEGRA_MUX_ULPI] = "ULPI",
+       [TEGRA_MUX_VI] = "VI",
+       [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
+       [TEGRA_MUX_XIO] = "XIO",
+       [TEGRA_MUX_BLINK] = "BLINK",
+       [TEGRA_MUX_CEC] = "CEC",
+       [TEGRA_MUX_CLK12] = "CLK12",
+       [TEGRA_MUX_DAP] = "DAP",
+       [TEGRA_MUX_DAPSDMMC2] = "DAPSDMMC2",
+       [TEGRA_MUX_DDR] = "DDR",
+       [TEGRA_MUX_DEV3] = "DEV3",
+       [TEGRA_MUX_DTV] = "DTV",
+       [TEGRA_MUX_VI_ALT1] = "VI_ALT1",
+       [TEGRA_MUX_VI_ALT2] = "VI_ALT2",
+       [TEGRA_MUX_VI_ALT3] = "VI_ALT3",
+       [TEGRA_MUX_EMC_DLL] = "EMC_DLL",
+       [TEGRA_MUX_EXTPERIPH1] = "EXTPERIPH1",
+       [TEGRA_MUX_EXTPERIPH2] = "EXTPERIPH2",
+       [TEGRA_MUX_EXTPERIPH3] = "EXTPERIPH3",
+       [TEGRA_MUX_GMI_ALT] = "GMI_ALT",
+       [TEGRA_MUX_HDA] = "HDA",
+       [TEGRA_MUX_HSI] = "HSI",
+       [TEGRA_MUX_I2C4] = "I2C4",
+       [TEGRA_MUX_I2C5] = "I2C5",
+       [TEGRA_MUX_I2CPWR] = "I2CPWR",
+       [TEGRA_MUX_I2S0] = "I2S0",
+       [TEGRA_MUX_I2S1] = "I2S1",
+       [TEGRA_MUX_I2S2] = "I2S2",
+       [TEGRA_MUX_I2S3] = "I2S3",
+       [TEGRA_MUX_I2S4] = "I2S4",
+       [TEGRA_MUX_NAND_ALT] = "NAND_ALT",
+       [TEGRA_MUX_POPSDIO4] = "POPSDIO4",
+       [TEGRA_MUX_POPSDMMC4] = "POPSDMMC4",
+       [TEGRA_MUX_PWM0] = "PWM0",
+       [TEGRA_MUX_PWM1] = "PWM2",
+       [TEGRA_MUX_PWM2] = "PWM2",
+       [TEGRA_MUX_PWM3] = "PWM3",
+       [TEGRA_MUX_SATA] = "SATA",
+       [TEGRA_MUX_SPI5] = "SPI5",
+       [TEGRA_MUX_SPI6] = "SPI6",
+       [TEGRA_MUX_SYSCLK] = "SYSCLK",
+       [TEGRA_MUX_VGP1] = "VGP1",
+       [TEGRA_MUX_VGP2] = "VGP2",
+       [TEGRA_MUX_VGP3] = "VGP3",
+       [TEGRA_MUX_VGP4] = "VGP4",
+       [TEGRA_MUX_VGP5] = "VGP5",
+       [TEGRA_MUX_VGP6] = "VGP6",
+       [TEGRA_MUX_SAFE] = "<safe>",
+};
+
+static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
+       [TEGRA_DRIVE_DIV_8] = "DIV_8",
+       [TEGRA_DRIVE_DIV_4] = "DIV_4",
+       [TEGRA_DRIVE_DIV_2] = "DIV_2",
+       [TEGRA_DRIVE_DIV_1] = "DIV_1",
+};
+
+static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
+       [TEGRA_SLEW_FASTEST] = "FASTEST",
+       [TEGRA_SLEW_FAST] = "FAST",
+       [TEGRA_SLEW_SLOW] = "SLOW",
+       [TEGRA_SLEW_SLOWEST] = "SLOWEST",
+};
+
+static DEFINE_SPINLOCK(mux_lock);
+
+static const char *pingroup_name(int pg)
+{
+       if (pg < 0 || pg >=  pingroup_max)
+               return "<UNKNOWN>";
+
+       return pingroups[pg].name;
+}
+
+static const char *func_name(enum tegra_mux_func func)
+{
+       if (func == TEGRA_MUX_RSVD1)
+               return "RSVD1";
+
+       if (func == TEGRA_MUX_RSVD2)
+               return "RSVD2";
+
+       if (func == TEGRA_MUX_RSVD3)
+               return "RSVD3";
+
+       if (func == TEGRA_MUX_RSVD4)
+               return "RSVD4";
+
+       if (func == TEGRA_MUX_NONE)
+               return "NONE";
+
+       if (func < 0 || func >=  TEGRA_MAX_MUX)
+               return "<UNKNOWN>";
+
+       return tegra_mux_names[func];
+}
+
+
+static const char *tri_name(unsigned long val)
+{
+       return val ? "TRISTATE" : "NORMAL";
+}
+
+static const char *pupd_name(unsigned long val)
+{
+       switch (val) {
+       case 0:
+               return "NORMAL";
+
+       case 1:
+               return "PULL_DOWN";
+
+       case 2:
+               return "PULL_UP";
+
+       default:
+               return "RSVD";
+       }
+}
+
+static int nbanks;
+static void __iomem **regs;
+
+static inline u32 pg_readl(u32 bank, u32 reg)
+{
+       return readl(regs[bank] + reg);
+}
+
+static inline void pg_writel(u32 val, u32 bank, u32 reg)
+{
+       writel(val, regs[bank] + reg);
+}
+
+static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
+{
+       int mux = -1;
+       int i;
+       unsigned long reg;
+       unsigned long flags;
+       int pg = config->pingroup;
+       enum tegra_mux_func func = config->func;
+
+       if (pg < 0 || pg >=  pingroup_max)
+               return -ERANGE;
+
+       if (pingroups[pg].mux_reg < 0)
+               return -EINVAL;
+
+       if (func < 0)
+               return -ERANGE;
+
+       if (func == TEGRA_MUX_SAFE)
+               func = pingroups[pg].func_safe;
+
+       if (func & TEGRA_MUX_RSVD) {
+               mux = func & 0x3;
+       } else {
+               for (i = 0; i < 4; i++) {
+                       if (pingroups[pg].funcs[i] == func) {
+                               mux = i;
+                               break;
+                       }
+               }
+       }
+
+       if (mux < 0)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(pingroups[pg].mux_bank, pingroups[pg].mux_reg);
+       reg &= ~(0x3 << pingroups[pg].mux_bit);
+       reg |= mux << pingroups[pg].mux_bit;
+       pg_writel(reg, pingroups[pg].mux_bank, pingroups[pg].mux_reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+int tegra_pinmux_set_tristate(int pg, enum tegra_tristate tristate)
+{
+       unsigned long reg;
+       unsigned long flags;
+
+       if (pg < 0 || pg >=  pingroup_max)
+               return -ERANGE;
+
+       if (pingroups[pg].tri_reg < 0)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(pingroups[pg].tri_bank, pingroups[pg].tri_reg);
+       reg &= ~(0x1 << pingroups[pg].tri_bit);
+       if (tristate)
+               reg |= 1 << pingroups[pg].tri_bit;
+       pg_writel(reg, pingroups[pg].tri_bank, pingroups[pg].tri_reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+int tegra_pinmux_set_pullupdown(int pg, enum tegra_pullupdown pupd)
+{
+       unsigned long reg;
+       unsigned long flags;
+
+       if (pg < 0 || pg >=  pingroup_max)
+               return -ERANGE;
+
+       if (pingroups[pg].pupd_reg < 0)
+               return -EINVAL;
+
+       if (pupd != TEGRA_PUPD_NORMAL &&
+           pupd != TEGRA_PUPD_PULL_DOWN &&
+           pupd != TEGRA_PUPD_PULL_UP)
+               return -EINVAL;
+
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
+       reg &= ~(0x3 << pingroups[pg].pupd_bit);
+       reg |= pupd << pingroups[pg].pupd_bit;
+       pg_writel(reg, pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
+{
+       int pingroup = config->pingroup;
+       enum tegra_mux_func func     = config->func;
+       enum tegra_pullupdown pupd   = config->pupd;
+       enum tegra_tristate tristate = config->tristate;
+       int err;
+
+       if (pingroups[pingroup].mux_reg >= 0) {
+               err = tegra_pinmux_set_func(config);
+               if (err < 0)
+                       pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
+                              pingroup_name(pingroup), func_name(func), err);
+       }
+
+       if (pingroups[pingroup].pupd_reg >= 0) {
+               err = tegra_pinmux_set_pullupdown(pingroup, pupd);
+               if (err < 0)
+                       pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
+                              pingroup_name(pingroup), pupd_name(pupd), err);
+       }
+
+       if (pingroups[pingroup].tri_reg >= 0) {
+               err = tegra_pinmux_set_tristate(pingroup, tristate);
+               if (err < 0)
+                       pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
+                              pingroup_name(pingroup), tri_name(func), err);
+       }
+}
+
+void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               tegra_pinmux_config_pingroup(&config[i]);
+}
+
+static const char *drive_pinmux_name(int pg)
+{
+       if (pg < 0 || pg >=  drive_max)
+               return "<UNKNOWN>";
+
+       return drive_pingroups[pg].name;
+}
+
+static const char *enable_name(unsigned long val)
+{
+       return val ? "ENABLE" : "DISABLE";
+}
+
+static const char *drive_name(unsigned long val)
+{
+       if (val >= TEGRA_MAX_DRIVE)
+               return "<UNKNOWN>";
+
+       return tegra_drive_names[val];
+}
+
+static const char *slew_name(unsigned long val)
+{
+       if (val >= TEGRA_MAX_SLEW)
+               return "<UNKNOWN>";
+
+       return tegra_slew_names[val];
+}
+
+static int tegra_drive_pinmux_set_hsm(int pg, enum tegra_hsm hsm)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       if (hsm == TEGRA_HSM_ENABLE)
+               reg |= (1 << 2);
+       else
+               reg &= ~(1 << 2);
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static int tegra_drive_pinmux_set_schmitt(int pg, enum tegra_schmitt schmitt)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       if (schmitt == TEGRA_SCHMITT_ENABLE)
+               reg |= (1 << 3);
+       else
+               reg &= ~(1 << 3);
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static int tegra_drive_pinmux_set_drive(int pg, enum tegra_drive drive)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       reg &= ~(0x3 << 4);
+       reg |= drive << 4;
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static int tegra_drive_pinmux_set_pull_down(int pg,
+       enum tegra_pull_strength pull_down)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       reg &= ~(0x1f << 12);
+       reg |= pull_down << 12;
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static int tegra_drive_pinmux_set_pull_up(int pg,
+       enum tegra_pull_strength pull_up)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       reg &= ~(0x1f << 12);
+       reg |= pull_up << 12;
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static int tegra_drive_pinmux_set_slew_rising(int pg,
+       enum tegra_slew slew_rising)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       reg &= ~(0x3 << 28);
+       reg |= slew_rising << 28;
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static int tegra_drive_pinmux_set_slew_falling(int pg,
+       enum tegra_slew slew_falling)
+{
+       unsigned long flags;
+       u32 reg;
+       if (pg < 0 || pg >=  drive_max)
+               return -ERANGE;
+
+       if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
+               return -EINVAL;
+
+       spin_lock_irqsave(&mux_lock, flags);
+
+       reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+       reg &= ~(0x3 << 30);
+       reg |= slew_falling << 30;
+       pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
+
+       spin_unlock_irqrestore(&mux_lock, flags);
+
+       return 0;
+}
+
+static void tegra_drive_pinmux_config_pingroup(int pingroup,
+                                         enum tegra_hsm hsm,
+                                         enum tegra_schmitt schmitt,
+                                         enum tegra_drive drive,
+                                         enum tegra_pull_strength pull_down,
+                                         enum tegra_pull_strength pull_up,
+                                         enum tegra_slew slew_rising,
+                                         enum tegra_slew slew_falling)
+{
+       int err;
+
+       err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
+                       drive_pinmux_name(pingroup),
+                       enable_name(hsm), err);
+
+       err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
+                       drive_pinmux_name(pingroup),
+                       enable_name(schmitt), err);
+
+       err = tegra_drive_pinmux_set_drive(pingroup, drive);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
+                       drive_pinmux_name(pingroup),
+                       drive_name(drive), err);
+
+       err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
+                       drive_pinmux_name(pingroup),
+                       pull_down, err);
+
+       err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
+                       drive_pinmux_name(pingroup),
+                       pull_up, err);
+
+       err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
+                       drive_pinmux_name(pingroup),
+                       slew_name(slew_rising), err);
+
+       err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
+       if (err < 0)
+               pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
+                       drive_pinmux_name(pingroup),
+                       slew_name(slew_falling), err);
+}
+
+void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
+       int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++)
+               tegra_drive_pinmux_config_pingroup(config[i].pingroup,
+                                                    config[i].hsm,
+                                                    config[i].schmitt,
+                                                    config[i].drive,
+                                                    config[i].pull_down,
+                                                    config[i].pull_up,
+                                                    config[i].slew_rising,
+                                                    config[i].slew_falling);
+}
+
+void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
+       int len)
+{
+       int i;
+       struct tegra_pingroup_config c;
+
+       for (i = 0; i < len; i++) {
+               int err;
+               c = config[i];
+               if (c.pingroup < 0 || c.pingroup >= pingroup_max) {
+                       WARN_ON(1);
+                       continue;
+               }
+               c.func = pingroups[c.pingroup].func_safe;
+               err = tegra_pinmux_set_func(&c);
+               if (err < 0)
+                       pr_err("%s: tegra_pinmux_set_func returned %d setting "
+                              "%s to %s\n", __func__, err,
+                              pingroup_name(c.pingroup), func_name(c.func));
+       }
+}
+
+void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
+       int len)
+{
+       int i;
+
+       for (i = 0; i < len; i++) {
+               int err;
+               if (config[i].pingroup < 0 ||
+                   config[i].pingroup >= pingroup_max) {
+                       WARN_ON(1);
+                       continue;
+               }
+               err = tegra_pinmux_set_func(&config[i]);
+               if (err < 0)
+                       pr_err("%s: tegra_pinmux_set_func returned %d setting "
+                              "%s to %s\n", __func__, err,
+                              pingroup_name(config[i].pingroup),
+                              func_name(config[i].func));
+       }
+}
+
+void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
+       int len, enum tegra_tristate tristate)
+{
+       int i;
+       int err;
+       int pingroup;
+
+       for (i = 0; i < len; i++) {
+               pingroup = config[i].pingroup;
+               if (pingroups[pingroup].tri_reg >= 0) {
+                       err = tegra_pinmux_set_tristate(pingroup, tristate);
+                       if (err < 0)
+                               pr_err("pinmux: can't set pingroup %s tristate"
+                                       " to %s: %d\n", pingroup_name(pingroup),
+                                       tri_name(tristate), err);
+               }
+       }
+}
+
+void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
+       int len, enum tegra_pullupdown pupd)
+{
+       int i;
+       int err;
+       int pingroup;
+
+       for (i = 0; i < len; i++) {
+               pingroup = config[i].pingroup;
+               if (pingroups[pingroup].pupd_reg >= 0) {
+                       err = tegra_pinmux_set_pullupdown(pingroup, pupd);
+                       if (err < 0)
+                               pr_err("pinmux: can't set pingroup %s pullupdown"
+                                       " to %s: %d\n", pingroup_name(pingroup),
+                                       pupd_name(pupd), err);
+               }
+       }
+}
+
+static struct of_device_id tegra_pinmux_of_match[] = {
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+       { .compatible = "nvidia,tegra20-pinmux-disabled", tegra20_pinmux_init },
+#endif
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+       { .compatible = "nvidia,tegra30-pinmux-disabled", tegra30_pinmux_init },
+#endif
+       { },
+};
+
+static int tegra_pinmux_probe(struct platform_device *pdev)
+{
+       struct resource *res;
+       int i;
+       int config_bad = 0;
+       const struct of_device_id *match;
+
+       match = of_match_device(tegra_pinmux_of_match, &pdev->dev);
+
+       if (match)
+               ((pinmux_init)(match->data))(&pingroups, &pingroup_max,
+                       &drive_pingroups, &drive_max);
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+       else
+               /* no device tree available, so we must be on tegra20 */
+               tegra20_pinmux_init(&pingroups, &pingroup_max,
+                                       &drive_pingroups, &drive_max);
+#else
+       pr_warn("non Tegra20 platform requires pinmux devicetree node\n");
+#endif
+
+       for (i = 0; ; i++) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               if (!res)
+                       break;
+       }
+       nbanks = i;
+
+       for (i = 0; i < pingroup_max; i++) {
+               if (pingroups[i].tri_bank >= nbanks) {
+                       dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i);
+                       config_bad = 1;
+               }
+
+               if (pingroups[i].mux_bank >= nbanks) {
+                       dev_err(&pdev->dev, "pingroup %d: bad mux_bank\n", i);
+                       config_bad = 1;
+               }
+
+               if (pingroups[i].pupd_bank >= nbanks) {
+                       dev_err(&pdev->dev, "pingroup %d: bad pupd_bank\n", i);
+                       config_bad = 1;
+               }
+       }
+
+       for (i = 0; i < drive_max; i++) {
+               if (drive_pingroups[i].reg_bank >= nbanks) {
+                       dev_err(&pdev->dev,
+                               "drive pingroup %d: bad reg_bank\n", i);
+                       config_bad = 1;
+               }
+       }
+
+       if (config_bad)
+               return -ENODEV;
+
+       regs = devm_kzalloc(&pdev->dev, nbanks * sizeof(*regs), GFP_KERNEL);
+       if (!regs) {
+               dev_err(&pdev->dev, "Can't alloc regs pointer\n");
+               return -ENODEV;
+       }
+
+       for (i = 0; i < nbanks; i++) {
+               res = platform_get_resource(pdev, IORESOURCE_MEM, i);
+               if (!res) {
+                       dev_err(&pdev->dev, "Missing MEM resource\n");
+                       return -ENODEV;
+               }
+
+               if (!devm_request_mem_region(&pdev->dev, res->start,
+                                           resource_size(res),
+                                           dev_name(&pdev->dev))) {
+                       dev_err(&pdev->dev,
+                               "Couldn't request MEM resource %d\n", i);
+                       return -ENODEV;
+               }
+
+               regs[i] = devm_ioremap(&pdev->dev, res->start,
+                                       resource_size(res));
+               if (!regs) {
+                       dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i);
+                       return -ENODEV;
+               }
+       }
+
+       return 0;
+}
+
+static struct platform_driver tegra_pinmux_driver = {
+       .driver         = {
+               .name   = "tegra-pinmux-disabled",
+               .owner  = THIS_MODULE,
+               .of_match_table = tegra_pinmux_of_match,
+       },
+       .probe          = tegra_pinmux_probe,
+};
+
+static int __init tegra_pinmux_init(void)
+{
+       return platform_driver_register(&tegra_pinmux_driver);
+}
+postcore_initcall(tegra_pinmux_init);
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+static void dbg_pad_field(struct seq_file *s, int len)
+{
+       seq_putc(s, ',');
+
+       while (len-- > -1)
+               seq_putc(s, ' ');
+}
+
+static int dbg_pinmux_show(struct seq_file *s, void *unused)
+{
+       int i;
+       int len;
+
+       for (i = 0; i < pingroup_max; i++) {
+               unsigned long reg;
+               unsigned long tri;
+               unsigned long mux;
+               unsigned long pupd;
+
+               seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
+               len = strlen(pingroups[i].name);
+               dbg_pad_field(s, 5 - len);
+
+               if (pingroups[i].mux_reg < 0) {
+                       seq_printf(s, "TEGRA_MUX_NONE");
+                       len = strlen("NONE");
+               } else {
+                       reg = pg_readl(pingroups[i].mux_bank,
+                                       pingroups[i].mux_reg);
+                       mux = (reg >> pingroups[i].mux_bit) & 0x3;
+                       if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
+                               seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
+                               len = 5;
+                       } else {
+                               seq_printf(s, "TEGRA_MUX_%s",
+                                          tegra_mux_names[pingroups[i].funcs[mux]]);
+                               len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
+                       }
+               }
+               dbg_pad_field(s, 13-len);
+
+               if (pingroups[i].pupd_reg < 0) {
+                       seq_printf(s, "TEGRA_PUPD_NORMAL");
+                       len = strlen("NORMAL");
+               } else {
+                       reg = pg_readl(pingroups[i].pupd_bank,
+                                       pingroups[i].pupd_reg);
+                       pupd = (reg >> pingroups[i].pupd_bit) & 0x3;
+                       seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
+                       len = strlen(pupd_name(pupd));
+               }
+               dbg_pad_field(s, 9 - len);
+
+               if (pingroups[i].tri_reg < 0) {
+                       seq_printf(s, "TEGRA_TRI_NORMAL");
+               } else {
+                       reg = pg_readl(pingroups[i].tri_bank,
+                                       pingroups[i].tri_reg);
+                       tri = (reg >> pingroups[i].tri_bit) & 0x1;
+
+                       seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
+               }
+               seq_printf(s, "},\n");
+       }
+       return 0;
+}
+
+static int dbg_pinmux_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dbg_pinmux_show, &inode->i_private);
+}
+
+static const struct file_operations debug_fops = {
+       .open           = dbg_pinmux_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
+{
+       int i;
+       int len;
+
+       for (i = 0; i < drive_max; i++) {
+               u32 reg;
+
+               seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
+                       drive_pingroups[i].name);
+               len = strlen(drive_pingroups[i].name);
+               dbg_pad_field(s, 7 - len);
+
+
+               reg = pg_readl(drive_pingroups[i].reg_bank,
+                               drive_pingroups[i].reg);
+               if (HSM_EN(reg)) {
+                       seq_printf(s, "TEGRA_HSM_ENABLE");
+                       len = 16;
+               } else {
+                       seq_printf(s, "TEGRA_HSM_DISABLE");
+                       len = 17;
+               }
+               dbg_pad_field(s, 17 - len);
+
+               if (SCHMT_EN(reg)) {
+                       seq_printf(s, "TEGRA_SCHMITT_ENABLE");
+                       len = 21;
+               } else {
+                       seq_printf(s, "TEGRA_SCHMITT_DISABLE");
+                       len = 22;
+               }
+               dbg_pad_field(s, 22 - len);
+
+               seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
+               len = strlen(drive_name(LPMD(reg)));
+               dbg_pad_field(s, 5 - len);
+
+               seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg));
+               len = DRVDN(reg) < 10 ? 1 : 2;
+               dbg_pad_field(s, 2 - len);
+
+               seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg));
+               len = DRVUP(reg) < 10 ? 1 : 2;
+               dbg_pad_field(s, 2 - len);
+
+               seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg)));
+               len = strlen(slew_name(SLWR(reg)));
+               dbg_pad_field(s, 7 - len);
+
+               seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg)));
+
+               seq_printf(s, "},\n");
+       }
+       return 0;
+}
+
+static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
+}
+
+static const struct file_operations debug_drive_fops = {
+       .open           = dbg_drive_pinmux_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init tegra_pinmux_debuginit(void)
+{
+       (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
+                                       NULL, NULL, &debug_fops);
+       (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
+                                       NULL, NULL, &debug_drive_fops);
+       return 0;
+}
+late_initcall(tegra_pinmux_debuginit);
+#endif