/*
 * linux/arch/arm/mach-tegra/include/mach/pinmux.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_H
#define __MACH_TEGRA_PINMUX_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_mux_func {
	TEGRA_MUX_RSVD = 0x8000,
	TEGRA_MUX_RSVD1 = 0x8000,
	TEGRA_MUX_RSVD2 = 0x8001,
	TEGRA_MUX_RSVD3 = 0x8002,
	TEGRA_MUX_RSVD4 = 0x8003,
	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_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,
};

struct tegra_pingroup_config {
	enum tegra_pingroup	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_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_MAX_DRIVE_PINGROUP,
};

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 {
	enum tegra_drive_pingroup 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 tegra_pinmux_set_func(enum tegra_pingroup pg, enum tegra_mux_func func);
int tegra_pinmux_set_tristate(enum tegra_pingroup pg, enum tegra_tristate tristate);
int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg, enum tegra_pullupdown pupd);

void tegra_pinmux_config_pingroup(enum tegra_pingroup pingroup,
	enum tegra_mux_func func, enum tegra_pullupdown pupd,
	enum tegra_tristate tristate);

void tegra_pinmux_config_table(struct tegra_pingroup_config *config, int len);

void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
	int len);

#endif

