diff options
author | Laxman Dewangan <ldewangan@nvidia.com> | 2010-03-17 14:07:40 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-03-19 18:58:47 -0800 |
commit | 3fd0b4e9712b848d23f2f341ab4e5b472f50932f (patch) | |
tree | 05919b564ce4e4d99557c5c3d40b3d54d289c4de /arch/arm/mach-tegra/gpio.c | |
parent | 57fd96a49d0e279725c215fcc806a9357fd6390c (diff) |
Tegra gpio: Wrapping up nvrm gpio to native gpio.
NvRm Gpio driver will be wrapper on the native gpio driver such that it
will provide the same existing api and implementation will be use the
native gpio driver. In this approach, it does not need to change the
existing gpio client driver.
Tested on whistler with sdcard insert/remove, touch panel and scroll wheel.
Tested on harmony with the suspend/resume.
Change-Id: I2fa98f8f62a111a1463c1e5b1034e145eaae42a3
Reviewed-on: http://git-master/r/851
Tested-by: Ramachandrudu Kandhala <rkandhala@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/gpio.c')
-rw-r--r-- | arch/arm/mach-tegra/gpio.c | 360 |
1 files changed, 357 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c index 9448cad678b7..d40f3345e0af 100644 --- a/arch/arm/mach-tegra/gpio.c +++ b/arch/arm/mach-tegra/gpio.c @@ -21,14 +21,16 @@ * */ +#include "nvrm_pmu.h" +#include "nvos.h" +#include "nvodm_query_discovery.h" + #include <linux/init.h> #include <linux/irq.h> #include <linux/io.h> - #include <asm/io.h> #include <asm/gpio.h> - #define GPIO_BANK(x) ((x) >> 5) #define GPIO_PORT(x) (((x) >> 3) & 0x3) #define GPIO_BIT(x) ((x) & 0x7) @@ -278,7 +280,7 @@ static int __init tegra_gpio_init(void) unsigned long phys; phys = tegra_get_module_inst_base("gpio",0); - add_gpio_base = IO_ADDRESS(phys); + add_gpio_base = (unsigned long)IO_ADDRESS(phys); for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) { for (j = 0; j < 4; j++) { @@ -359,3 +361,355 @@ static int __init tegra_gpio_debuginit(void) } late_initcall(tegra_gpio_debuginit); #endif + +struct gpio_power_rail_info { + /* SoC power rail GUID */ + NvU64 power_rail_guid; + + /* Pmu rail address */ + NvU32 power_rail_address; +}; + +static unsigned int is_gpio_rail_initailized = 0; +static struct gpio_power_rail_info gpio_power_rail_table[] = { + {.power_rail_guid = NV_VDD_SYS_ODM_ID, .power_rail_address = 0}, + {.power_rail_guid = NV_VDD_BB_ODM_ID, .power_rail_address = 0}, + {.power_rail_guid = NV_VDD_VI_ODM_ID, .power_rail_address = 0}, + {.power_rail_guid = NV_VDD_SDIO_ODM_ID, .power_rail_address = 0}, + {.power_rail_guid = NV_VDD_LCD_ODM_ID, .power_rail_address = 0}, + {.power_rail_guid = NV_VDD_UART_ODM_ID, .power_rail_address = 0}, +}; + +/* Initialize power rails for different gpios pins */ +static struct gpio_power_rail_info *gpio_power_rail_map[ARCH_NR_GPIOS] = { + /* Port a */ + &gpio_power_rail_table[3], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + + /* Port b */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + + /* Port c */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[4], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[4], + &gpio_power_rail_table[5], + + /* Port d */ + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + + /* Port e */ + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + + /* Port f */ + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + + /* Port g */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port h */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port i */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port j */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[4], + &gpio_power_rail_table[5], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port k */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port l */ + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + + /* Port m */ + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + + /* Port n */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + + /* Port o */ + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + + /* Port p */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port q */ + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + + /* Port r */ + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + + /* Port s */ + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + &gpio_power_rail_table[0], + + /* Port t */ + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[2], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port u */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port v */ + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[1], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[3], + &gpio_power_rail_table[4], + + /* Port w */ + &gpio_power_rail_table[4], + &gpio_power_rail_table[4], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port x */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port y */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port z */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port AA */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + + /* Port BB */ + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5], + &gpio_power_rail_table[5] +}; + +static void discover_gpio_io_power_rail(NvRmDeviceHandle hRm) +{ + unsigned int i; + const NvOdmPeripheralConnectivity* connectivity = NULL; + + for (i = 0; i < NV_ARRAY_SIZE(gpio_power_rail_table); i++) { + connectivity = NvOdmPeripheralGetGuid( + gpio_power_rail_table[i].power_rail_guid); + if (!connectivity || !connectivity->NumAddress) + continue; + gpio_power_rail_table[i].power_rail_address = + connectivity->AddressList[0].Address; + } +} +NvError tegra_gpio_io_power_config(NvRmDeviceHandle hRm, int port, + int pin, unsigned int enable) +{ + NvRmPmuVddRailCapabilities rail_caps; + NvU32 settling_time; + struct gpio_power_rail_info *gpio_io_power; + int gpio_nr; + + if (!is_gpio_rail_initailized) { + discover_gpio_io_power_rail(hRm); + is_gpio_rail_initailized = 1; + } + + gpio_nr = port * 8 + pin; + gpio_io_power = gpio_power_rail_map[gpio_nr]; + + /* Nothing to be done if there is no pmu rail + * associated with this port */ + if (gpio_io_power->power_rail_address == 0) + return NvSuccess; + + if (enable) { + NvRmPmuGetCapabilities(hRm, gpio_io_power->power_rail_address, + &rail_caps); + NvRmPmuSetVoltage(hRm, gpio_io_power->power_rail_address, + rail_caps.requestMilliVolts, + &settling_time); + } else { + NvRmPmuSetVoltage(hRm, gpio_io_power->power_rail_address, + ODM_VOLTAGE_OFF, &settling_time); + } + if (settling_time) + NvOsWaitUS(settling_time); + + return NvSuccess; +} |