summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaxman Dewangan <ldewangan@nvidia.com>2010-03-17 14:07:40 +0530
committerGary King <gking@nvidia.com>2010-03-19 18:58:47 -0800
commit3fd0b4e9712b848d23f2f341ab4e5b472f50932f (patch)
tree05919b564ce4e4d99557c5c3d40b3d54d289c4de
parent57fd96a49d0e279725c215fcc806a9357fd6390c (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>
-rw-r--r--arch/arm/mach-tegra/gpio.c360
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/Makefile1
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_gpio_vi.c10
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio.c950
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.c186
-rw-r--r--arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.h129
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c63
7 files changed, 850 insertions, 849 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;
+}
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/Makefile b/arch/arm/mach-tegra/nvrm/io/ap15/Makefile
index 3148c14ba4d7..656d900e32ad 100644
--- a/arch/arm/mach-tegra/nvrm/io/ap15/Makefile
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/Makefile
@@ -22,7 +22,6 @@ obj-y += ap15rm_pwm.o
obj-y += ap15rm_gpio_vi.o
obj-y += nvrm_dma.o
obj-y += nvrm_gpio.o
-obj-y += nvrm_gpio_private.o
obj-y += nvrm_gpio_stub_helper.o
obj-y += ap15rm_dma_intr.o
obj-y += rm_spi_hw_private.o
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_gpio_vi.c b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_gpio_vi.c
index dfad64c856c0..ac6fc966d44f 100644
--- a/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_gpio_vi.c
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/ap15rm_gpio_vi.c
@@ -29,14 +29,16 @@
* POSSIBILITY OF SUCH DAMAGE.
*
*/
-
#include "ap15/ap15rm_gpio_vi.h"
-#include "nvrm_gpio_private.h"
-#include "nvassert.h"
+#include "nvrm_pmu.h"
+#include "nvrm_gpio.h"
#include "nvos.h"
+#include "ap15/ap15rm_private.h"
#include "ap15/arvi.h"
+#include "nvrm_structure.h"
+#include "nvrm_hwintf.h"
#include "nvodm_query_discovery.h"
-#include "nvrm_pmu.h"
+#include "nvassert.h"
#define NV_ENABLE_VI_POWER_RAIL 1
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio.c b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio.c
index c558baf1b5cd..905179934d33 100644
--- a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio.c
+++ b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio.c
@@ -30,562 +30,492 @@
*
*/
-#include "ap15/ap15rm_gpio_vi.h"
-#include "nvrm_gpio_private.h"
-#include "nvassert.h"
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <mach/gpio.h>
+
+#include "nvrm_gpio.h"
#include "nvos.h"
+#include "nvrm_structure.h"
+#include "nvrm_pmu.h"
#include "nvrm_pinmux_utils.h"
-#include "ap15/arapbpm.h"
+#include "ap15/ap15rm_private.h"
+#include "ap15/ap15rm_gpio_vi.h"
#include "nvodm_gpio_ext.h"
+#include "nvodm_query_discovery.h"
+#include "nvrm_hwintf.h"
+#include "nvassert.h"
-// Treats GPIO pin handle releases like the pin is completely invalidated:
-// returned to SFIO state and tristated. See the FIXME comment below
-// to see why this isn't enabled currently...
+/* Treats GPIO pin handle releases like the pin is completely invalidated:
+ * returned to SFIO state and tristated. */
#define RELEASE_IS_INVALIDATE 1
#define NV_ENABLE_GPIO_POWER_RAIL 1
+#define TOTAL_GPIO_BANK 7
+#define GPIO_PORT_PER_BANK 4
+#define GPIO_PIN_PER_PORT 8
+#define GPIO_PORT_ID(bank, port) ((((bank)&0xFF) << 2) | (((port) & 0x3)))
+#define GPIO_PIN_ID(bank, port, pin) ((((bank)&0xFF) << 5) | \
+ (((port) & 0x3) <<3) | ((pin) & 0x7))
+
+#define GET_PIN(h) ((((NvU32)(h))) & 0xFF)
+#define GET_PORT(h) ((((NvU32)(h)) >> 8) & 0xFF)
+#define GET_BANK(h) ((((NvU32)(h)) >> 16) & 0xFF)
+
+#define NVRM_GPIO_CAP_FEAT_EDGE_INTR 0x000000001
+#define GPIO_ARCH_FEATURE (NVRM_GPIO_CAP_FEAT_EDGE_INTR)
+
+extern NvError tegra_gpio_io_power_config(NvRmDeviceHandle hRm, int port,
+ int pin, unsigned int enable);
+
typedef struct NvRmGpioPinInfoRec {
- NvBool used;
- NvU32 port;
- NvU32 inst;
- NvU32 pin;
- NvRmGpioPinMode mode;
- /* Sets up a chain of pins associated by one semaphore. Usefull to parse the
- * pins when an interrupt is received. */
- NvU32 nextPin;
- NvU16 irqNumber;
+ NvBool used;
+ NvU32 port;
+ NvU32 inst;
+ NvU32 pin;
+ NvRmGpioPinMode mode;
+ /* Sets up a chain of pins associated by one semaphore.
+ * Usefull to parse the pins when an interrupt is received. */
+ NvU32 nextPin;
+ NvU16 irqNumber;
} NvRmGpioPinInfo;
-typedef struct NvRmGpioRec
-{
- NvU32 RefCount;
- NvRmDeviceHandle hRm;
- NvRmGpioPinInfo *pPinInfo;
- NvRmGpioCaps *caps;
- NvU32 *pIvlReg;
+typedef struct NvRmGpioRec {
+ NvU32 RefCount;
+ NvRmDeviceHandle hRm;
+ NvRmGpioPinInfo *pPinInfo;
} NvRmGpio;
-
static NvRmGpioHandle s_hGpio = NULL;
-
static NvOsMutexHandle s_GpioMutex = NULL;
-NvError
-NvRmGpioOpen(
- NvRmDeviceHandle hRm,
- NvRmGpioHandle* phGpio)
+NvError NvRmGpioOpen(NvRmDeviceHandle hRm, NvRmGpioHandle * phGpio)
{
- NvError err = NvSuccess;
- NvU32 total_pins;
- NvU32 i;
- NvU32 gpioShadowSize;
- NvU32 gpioShadowPhysical;
-
- NV_ASSERT(hRm);
- NV_ASSERT(phGpio);
-
- if (!s_GpioMutex)
- {
- err = NvOsMutexCreate(&s_GpioMutex);
- if (err != NvSuccess)
- {
- goto fail;
- }
- }
-
- NvOsMutexLock(s_GpioMutex);
- if (s_hGpio)
- {
- s_hGpio->RefCount++;
- goto exit;
- }
-
- s_hGpio = (NvRmGpio *)NvOsAlloc(sizeof(NvRmGpio));
- if (!s_hGpio)
- {
- err = NvError_InsufficientMemory;
- goto exit;
- }
- NvOsMemset(s_hGpio, 0, sizeof(NvRmGpio));
- s_hGpio->hRm = hRm;
-
- err = NvRmGpioGetCapabilities(hRm, (void **)&(s_hGpio->caps));
- if (err)
- {
- // Was a default supplied?
- if (s_hGpio->caps == NULL)
- {
- goto fail;
- }
- }
-
- total_pins = s_hGpio->caps->Instances * s_hGpio->caps->PortsPerInstances *
- s_hGpio->caps->PinsPerPort;
-
- s_hGpio->pPinInfo = NvOsAlloc(sizeof(NvRmGpioPinInfo) * total_pins);
- if (s_hGpio->pPinInfo == NULL)
- {
- NvOsFree(s_hGpio);
- goto exit;
- }
- NvOsMemset(s_hGpio->pPinInfo, 0, sizeof(NvRmGpioPinInfo) * total_pins);
- for (i=0; i<total_pins; i++)
- {
- s_hGpio->pPinInfo[i].irqNumber = NVRM_IRQ_INVALID;
- }
- s_hGpio->RefCount++;
-
- gpioShadowSize = sizeof(NvU32) * (NvU8)s_hGpio->caps->PortsPerInstances * (NvU8)s_hGpio->caps->Instances;
- gpioShadowPhysical = NV_REGR(hRm, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH19_0);
- /* Hack. There is no need for shadow on AP20 */
- if (hRm->ChipId.Id >= 0x20 || !gpioShadowPhysical)
- {
- s_hGpio->pIvlReg = NvOsAlloc(gpioShadowSize);
- NvOsMemset(s_hGpio->pIvlReg, 0, gpioShadowSize);
- }
- else
- {
- /* Map the shadow region that the OAL is using by reading the physical
- * address stored in PMC scratch register */
- err = NvOsPhysicalMemMap(gpioShadowPhysical, gpioShadowSize,
- NvOsMemAttribute_Uncached,
- NVOS_MEM_READ_WRITE,
- (void **)&(s_hGpio->pIvlReg));
- if (err != NvSuccess)
- {
- goto fail;
- }
- }
+ NvError err = NvSuccess;
+ NvU32 total_pins;
+ NvU32 i;
+
+ NV_ASSERT(hRm);
+ NV_ASSERT(phGpio);
+
+ if (!s_GpioMutex) {
+ err = NvOsMutexCreate(&s_GpioMutex);
+ if (err != NvSuccess)
+ goto fail;
+ }
+
+ NvOsMutexLock(s_GpioMutex);
+ if (s_hGpio) {
+ s_hGpio->RefCount++;
+ goto exit;
+ }
+
+ s_hGpio = (NvRmGpio *) NvOsAlloc(sizeof(NvRmGpio));
+ if (!s_hGpio) {
+ err = NvError_InsufficientMemory;
+ goto exit;
+ }
+ NvOsMemset(s_hGpio, 0, sizeof(NvRmGpio));
+ s_hGpio->hRm = hRm;
+
+ total_pins = TOTAL_GPIO_BANK * GPIO_PORT_PER_BANK * GPIO_PIN_PER_PORT;
+ s_hGpio->pPinInfo = NvOsAlloc(sizeof(NvRmGpioPinInfo) * total_pins);
+ if (s_hGpio->pPinInfo == NULL) {
+ NvOsFree(s_hGpio);
+ err = NvError_InsufficientMemory;
+ s_hGpio = NULL;
+ goto exit;
+ }
+ NvOsMemset(s_hGpio->pPinInfo, 0, sizeof(NvRmGpioPinInfo) * total_pins);
+ for (i = 0; i < total_pins; i++)
+ s_hGpio->pPinInfo[i].irqNumber = NVRM_IRQ_INVALID;
+ s_hGpio->RefCount++;
+
exit:
- *phGpio = s_hGpio;
- NvOsMutexUnlock(s_GpioMutex);
+ *phGpio = s_hGpio;
+ NvOsMutexUnlock(s_GpioMutex);
fail:
- return err;
+ return err;
}
void NvRmGpioClose(NvRmGpioHandle hGpio)
{
- if (!hGpio)
- return;
-
- NV_ASSERT(hGpio->RefCount);
-
- NvOsMutexLock(s_GpioMutex);
- hGpio->RefCount--;
- if (hGpio->RefCount == 0)
- {
- NvU32 gpioShadowSize;
- NvU32 gpioShadowPhysical;
-
- NvOsFree(s_hGpio->pPinInfo);
- gpioShadowSize = sizeof(NvU32) * s_hGpio->caps->PortsPerInstances * s_hGpio->caps->Instances;
- gpioShadowPhysical = NV_REGR(hGpio->hRm, NvRmModuleID_Pmif, 0, APBDEV_PMC_SCRATCH19_0);
- if (hGpio->hRm->ChipId.Id >= 0x20 || !gpioShadowPhysical)
- {
- NvOsFree(s_hGpio->pIvlReg);
- }
- else
- {
- NvOsPhysicalMemUnmap(s_hGpio->pIvlReg, gpioShadowSize);
- }
- NvOsFree(s_hGpio);
- s_hGpio = NULL;
- }
- NvOsMutexUnlock(s_GpioMutex);
+ if (!hGpio)
+ return;
+
+ NV_ASSERT(hGpio->RefCount);
+
+ NvOsMutexLock(s_GpioMutex);
+ hGpio->RefCount--;
+ if (hGpio->RefCount == 0) {
+ NvOsFree(s_hGpio->pPinInfo);
+ NvOsFree(s_hGpio);
+ s_hGpio = NULL;
+ }
+ NvOsMutexUnlock(s_GpioMutex);
}
-
NvError
-NvRmGpioAcquirePinHandle(
- NvRmGpioHandle hGpio,
- NvU32 port,
- NvU32 pinNumber,
- NvRmGpioPinHandle *phPin)
+NvRmGpioAcquirePinHandle(NvRmGpioHandle hGpio,
+ NvU32 port, NvU32 pinNumber, NvRmGpioPinHandle * phPin)
{
- NvU32 MaxPorts;
-
- NV_ASSERT(hGpio != NULL);
-
- NvOsMutexLock(s_GpioMutex);
- if (port == NVRM_GPIO_CAMERA_PORT)
- {
- // The Camera has dedicated gpio pins that must be controlled
- // through a non-standard gpio port control.
- NvRmPrivGpioViAcquirePinHandle(hGpio->hRm, pinNumber);
- *phPin = GPIO_MAKE_PIN_HANDLE(NVRM_GPIO_CAMERA_INST, port, pinNumber);
- }
- else if ((port >= NVODM_GPIO_EXT_PORT_0) &&
- (port <= NVODM_GPIO_EXT_PORT_F))
- {
- // Create a pin handle for GPIOs that are
- // sourced by external (off-chip) peripherals
- *phPin = GPIO_MAKE_PIN_HANDLE((port & 0xFF), port, pinNumber);
- }
- else
- {
- NV_ASSERT(4 == hGpio->caps->PortsPerInstances);
- MaxPorts = hGpio->caps->Instances * 4;
-
- if ((port > MaxPorts) || (pinNumber > hGpio->caps->PinsPerPort))
- {
- NV_ASSERT(!" Illegal port or pin number. ");
- }
-
- *phPin = GPIO_MAKE_PIN_HANDLE(port >> 2, port & 0x3, pinNumber);
- }
- NvOsMutexUnlock(s_GpioMutex);
- return NvSuccess;
+ int gpio_nr;
+ int ret_status;
+
+ NV_ASSERT(hGpio != NULL);
+
+ if (port == NVRM_GPIO_CAMERA_PORT) {
+ NvOsMutexLock(s_GpioMutex);
+ /* The Camera has dedicated gpio pins that must be controlled
+ * through a non-standard gpio port control. */
+ NvRmPrivGpioViAcquirePinHandle(hGpio->hRm, pinNumber);
+ *phPin = GPIO_MAKE_PIN_HANDLE(NVRM_GPIO_CAMERA_INST, port,
+ pinNumber);
+ NvOsMutexUnlock(s_GpioMutex);
+ } else if ((port >= NVODM_GPIO_EXT_PORT_0) &&
+ (port <= NVODM_GPIO_EXT_PORT_F)) {
+ /* Create a pin handle for GPIOs that are
+ * sourced by external (off-chip) peripherals */
+ *phPin = GPIO_MAKE_PIN_HANDLE((port & 0xFF), port, pinNumber);
+ } else {
+ gpio_nr = GPIO_PIN_ID((port >> 2), (port & 0x3), pinNumber);
+ if ((gpio_nr >= ARCH_NR_GPIOS) ||
+ (pinNumber >= GPIO_PIN_PER_PORT)) {
+ printk(KERN_ERR "Requested port %d or pin %d number "
+ " is not supported", port, pinNumber);
+ return NvError_NotSupported;
+ }
+ ret_status = gpio_request(gpio_nr, "nvrm_gpio");
+ if (unlikely(ret_status != 0)) {
+ return NvError_AlreadyAllocated;
+ }
+ *phPin = GPIO_MAKE_PIN_HANDLE((port >> 2), (port & 0x3),
+ pinNumber);
+ }
+ return NvSuccess;
}
-void NvRmGpioReleasePinHandles(
- NvRmGpioHandle hGpio,
- NvRmGpioPinHandle *hPin,
- NvU32 pinCount)
+void NvRmGpioReleasePinHandles(NvRmGpioHandle hGpio,
+ NvRmGpioPinHandle * hPin, NvU32 pinCount)
{
- NvU32 i;
- NvU32 port;
- NvU32 pin;
- NvU32 instance;
-
- if (hPin == NULL) return;
-
- for (i=0; i<pinCount; i++)
- {
- instance = GET_INSTANCE(hPin[i]);
- port = GET_PORT(hPin[i]);
- pin = GET_PIN(hPin[i]);
-
- NvOsMutexLock(s_GpioMutex);
- if (port == NVRM_GPIO_CAMERA_PORT)
- {
- NvRmPrivGpioViReleasePinHandles(hGpio->hRm, pin);
- }
- else if ((port >= NVODM_GPIO_EXT_PORT_0) &&
- (port <= NVODM_GPIO_EXT_PORT_F))
- {
- // Do nothing for now...
- }
- else
- {
- NvU32 alphaPort;
-
- alphaPort = instance * s_hGpio->caps->PortsPerInstances + port;
- if (s_hGpio->pPinInfo[pin + alphaPort * s_hGpio->caps->PinsPerPort].used)
- {
- NV_DEBUG_PRINTF(("Warning: Releasing in-use GPIO pin handle GPIO_P%c.%02u (%c=%u)\n",
- 'A'+alphaPort,pin,'A'+alphaPort, alphaPort));
+ NvU32 i;
+ NvU32 port;
+ NvU32 pin;
+ NvU32 bank;
+ int gpio_nr;
+ NvU32 alphaPort;
+
+ if (hPin == NULL)
+ return;
+
+ for (i = 0; i < pinCount; i++) {
+ bank = GET_BANK(hPin[i]);
+ port = GET_PORT(hPin[i]);
+ pin = GET_PIN(hPin[i]);
+ NvOsMutexLock(s_GpioMutex);
+ if (port == NVRM_GPIO_CAMERA_PORT) {
+ NvRmPrivGpioViReleasePinHandles(hGpio->hRm, pin);
+ } else if ((port >= NVODM_GPIO_EXT_PORT_0) &&
+ (port <= NVODM_GPIO_EXT_PORT_F)) {
+ /* Do nothing for now... */
+ } else {
+ gpio_nr = GPIO_PIN_ID(bank, port & 0x3, pin);
+ if (gpio_nr >= ARCH_NR_GPIOS) {
+ printk(KERN_ERR "Illegal pin handle at place "
+ " %u of the list\n",i);
+ NvOsMutexUnlock(s_GpioMutex);
+ continue;
+ }
+ gpio_free(gpio_nr);
+ alphaPort = (NvU32) GPIO_PORT_ID(bank, port);
+ if (s_hGpio->pPinInfo[gpio_nr].used) {
+ NV_DEBUG_PRINTF(("Warning: Releasing in-use "
+ "GPIO pin handle GPIO_P%c.%02u "
+ "(%c=%u)\n", 'A' + alphaPort, pin,
+ 'A' + alphaPort, alphaPort));
#if RELEASE_IS_INVALIDATE
- GPIO_MASKED_WRITE(hGpio->hRm, instance, port, CNF, pin, 0);
- NvRmSetGpioTristate(hGpio->hRm, alphaPort, pin, NV_TRUE);
- s_hGpio->pPinInfo[pin + alphaPort*s_hGpio->caps->PinsPerPort].used = NV_FALSE;
+ tegra_gpio_disable(gpio_nr);
+ NvRmSetGpioTristate(hGpio->hRm,
+ alphaPort, pin, NV_TRUE);
+ s_hGpio->pPinInfo[gpio_nr].used = NV_FALSE;
#endif
- }
- }
- NvOsMutexUnlock(s_GpioMutex);
- }
-
- return;
+ }
+ }
+ NvOsMutexUnlock(s_GpioMutex);
+ }
+ return;
}
-
-void NvRmGpioReadPins(
- NvRmGpioHandle hGpio,
- NvRmGpioPinHandle *hPin,
- NvRmGpioPinState *pPinState,
- NvU32 pinCount )
+void NvRmGpioReadPins(NvRmGpioHandle hGpio,
+ NvRmGpioPinHandle * hPin,
+ NvRmGpioPinState * pPinState, NvU32 pinCount)
{
- NvU32 inst;
- NvU32 port;
- NvU32 pin;
- NvU32 RegValue;
- NvU32 i;
-
- NV_ASSERT(hPin != NULL);
- NV_ASSERT(hGpio != NULL);
- NV_ASSERT(hGpio->caps != NULL);
-
- for (i=0; i<pinCount; i++)
- {
- port = GET_PORT(hPin[i]);
- pin = GET_PIN(hPin[i]);
- inst = GET_INSTANCE(hPin[i]);
-
- if (port == NVRM_GPIO_CAMERA_PORT)
- {
- pPinState[i] = NvRmPrivGpioViReadPins(hGpio->hRm, pin);
- }
- else if ((port >= (NvU32)NVODM_GPIO_EXT_PORT_0) &&
- (port <= (NvU32)NVODM_GPIO_EXT_PORT_F))
- {
- pPinState[i] = NvOdmExternalGpioReadPins(port, pin);
- }
- else
- {
- GPIO_REGR(hGpio->hRm, inst, port, OE, RegValue);
- if (RegValue & (1<<pin))
- {
- GPIO_REGR(hGpio->hRm, inst, port, OUT, RegValue);
- } else
- {
- GPIO_REGR(hGpio->hRm, inst, port, IN, RegValue);
- }
- pPinState[i] = (RegValue >> pin) & 0x1;
- }
- }
+ NvU32 bank;
+ NvU32 port;
+ NvU32 pin;
+ NvU32 i;
+ int gpio_nr;
+
+ NV_ASSERT(hPin != NULL);
+ NV_ASSERT(hGpio != NULL);
+
+ for (i = 0; i < pinCount; i++) {
+ port = GET_PORT(hPin[i]);
+ pin = GET_PIN(hPin[i]);
+ bank = GET_BANK(hPin[i]);
+
+ if (port == NVRM_GPIO_CAMERA_PORT) {
+ pPinState[i] = NvRmPrivGpioViReadPins(hGpio->hRm, pin);
+ } else if ((port >= (NvU32) NVODM_GPIO_EXT_PORT_0) &&
+ (port <= (NvU32) NVODM_GPIO_EXT_PORT_F)) {
+ pPinState[i] = NvOdmExternalGpioReadPins(port, pin);
+ } else {
+ gpio_nr = GPIO_PIN_ID(bank, port, pin);
+ if (gpio_nr >= ARCH_NR_GPIOS) {
+ printk(KERN_ERR "Illegal pin handle at place "
+ " %u of the list\n",i);
+ continue;
+ }
+ pPinState[i] = gpio_get_value(gpio_nr) & 0x1;
+ }
+ }
}
-void NvRmGpioWritePins(
- NvRmGpioHandle hGpio,
- NvRmGpioPinHandle *hPin,
- NvRmGpioPinState *pPinState,
- NvU32 pinCount )
+void NvRmGpioWritePins(NvRmGpioHandle hGpio,
+ NvRmGpioPinHandle * hPin,
+ NvRmGpioPinState * pPinState, NvU32 pinCount)
{
- NvU32 inst;
- NvU32 port;
- NvU32 pin;
- NvU32 i;
-
- NV_ASSERT(hPin != NULL);
- NV_ASSERT(hGpio != NULL);
- NV_ASSERT(hGpio->caps != NULL);
-
- for (i=0; i<pinCount; i++)
- {
- inst = GET_INSTANCE(hPin[i]);
- port = GET_PORT(hPin[i]);
- pin = GET_PIN(hPin[i]);
-
- if (port == NVRM_GPIO_CAMERA_PORT)
- {
- NvRmPrivGpioViWritePins(hGpio->hRm, pin, pPinState[i]);
- }
- else if ((port >= (NvU32)NVODM_GPIO_EXT_PORT_0) &&
- (port <= (NvU32)NVODM_GPIO_EXT_PORT_F))
- {
- NvOdmExternalGpioWritePins(port, pin, pPinState[i]);
- }
- else
- {
- // When updating a contiguous set of pins that are
- // all located in the same port, merge the register
- // write into a single atomic update.
- NvU32 updateVec = 0;
- updateVec = (1<<(pin + GPIO_PINS_PER_PORT));
- updateVec |= ((pPinState[i] & 0x1)<<pin);
- while ((i+1<pinCount) &&
- GET_INSTANCE(hPin[i+1])==inst &&
- GET_PORT(hPin[i+1]==port))
- {
- pin = GET_PIN(hPin[i+1]);
- updateVec |= (1<<(pin + GPIO_PINS_PER_PORT));
- updateVec |= ((pPinState[i+1]&0x1)<<pin);
- i++;
- }
- NV_REGW(hGpio->hRm, NvRmPrivModuleID_Gpio, inst,
- (port*NV_GPIO_PORT_REG_SIZE)+GPIO_MSK_CNF_0+GPIO_OUT_0,
- updateVec);
- }
- }
-
- return;
+ NvU32 port;
+ NvU32 pin;
+ NvU32 bank;
+ NvU32 i;
+ int gpio_nr;
+
+ NV_ASSERT(hPin != NULL);
+ NV_ASSERT(hGpio != NULL);
+
+ for (i = 0; i < pinCount; i++) {
+ port = GET_PORT(hPin[i]);
+ pin = GET_PIN(hPin[i]);
+ bank = GET_BANK(hPin[i]);
+
+ if (port == NVRM_GPIO_CAMERA_PORT) {
+ NvRmPrivGpioViWritePins(hGpio->hRm, pin, pPinState[i]);
+ } else if ((port >= (NvU32) NVODM_GPIO_EXT_PORT_0) &&
+ (port <= (NvU32) NVODM_GPIO_EXT_PORT_F)) {
+ NvOdmExternalGpioWritePins(port, pin, pPinState[i]);
+ } else {
+ gpio_nr = GPIO_PIN_ID(bank, port, pin);
+ if (gpio_nr >= ARCH_NR_GPIOS) {
+ printk(KERN_ERR "Illegal pin handle at place "
+ " %u of the list\n",i);
+ continue;
+ }
+ gpio_set_value(gpio_nr, pPinState[i] & 0x1);
+ }
+ }
+
+ return;
}
-
-NvError NvRmGpioConfigPins(
- NvRmGpioHandle hGpio,
- NvRmGpioPinHandle *hPin,
- NvU32 pinCount,
- NvRmGpioPinMode Mode)
+NvError NvRmGpioConfigPins(NvRmGpioHandle hGpio,
+ NvRmGpioPinHandle * hPin,
+ NvU32 pinCount, NvRmGpioPinMode Mode)
{
- NvError err = NvSuccess;
- NvU32 i;
- NvU32 inst;
- NvU32 port;
- NvU32 pin;
- NvU32 pinNumber;
- NvU32 Reg;
- NvU32 alphaPort;
-
- NvOsMutexLock(s_GpioMutex);
-
- for (i=0; i< pinCount; i++)
- {
- inst = GET_INSTANCE(hPin[i]);
- port = GET_PORT(hPin[i]);
- pin = GET_PIN(hPin[i]);
-
- if (port == NVRM_GPIO_CAMERA_PORT)
- {
- // If they are trying to do the wrong thing, assert.
- // If they are trying to do the only allowed thing,
- // quietly skip it, as nothing needs to be done.
- if (Mode != NvOdmGpioPinMode_Output)
- {
- NV_ASSERT(!"Only output is supported for camera gpio.\n");
- }
- continue;
- }
-
- /* Absolute pin number to index into pPinInfo array and the alphabetic port names. */
- alphaPort = inst * s_hGpio->caps->PortsPerInstances + port;
- pinNumber = pin + alphaPort * s_hGpio->caps->PinsPerPort;
-
- s_hGpio->pPinInfo[pinNumber].mode = Mode;
- s_hGpio->pPinInfo[pinNumber].inst = inst;
- s_hGpio->pPinInfo[pinNumber].port = port;
- s_hGpio->pPinInfo[pinNumber].pin = pin;
-
- /* Don't try to colapse this swtich as the ordering of the register
- * writes matter. */
- switch (Mode)
- {
- case NvRmGpioPinMode_Output:
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 1);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
-
- break;
-
- case NvRmGpioPinMode_InputData:
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
-
- break;
-
- case NvRmGpioPinMode_InputInterruptLow:
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
-
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, INT_LVL, pin, 0);
- break;
-
- case NvRmGpioPinMode_InputInterruptHigh:
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
-
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, INT_LVL, pin, 1);
- break;
-
- case NvRmGpioPinMode_InputInterruptAny:
- if(hGpio->caps->Features & NVRM_GPIO_CAP_FEAT_EDGE_INTR)
- {
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
-
- GPIO_REGR(hGpio->hRm, inst, port, INT_LVL, Reg);
- // see the # Bug ID: 359459
- Reg = (Reg & GPIO_INT_LVL_UNSHADOWED_MASK) |
- (s_hGpio->pIvlReg[alphaPort] & GPIO_INT_LVL_SHADOWED_MASK);
- Reg |= (GPIO_INT_LVL_0_EDGE_0_FIELD << pin);
- Reg |= (GPIO_INT_LVL_0_DELTA_0_FIELD << pin);
- s_hGpio->pIvlReg[alphaPort] = Reg;
- GPIO_REGW(hGpio->hRm, inst, port, INT_LVL, Reg);
- }
- else
- {
- NV_ASSERT(!"Not supported");
- }
-
- break;
-
- case NvRmGpioPinMode_Function:
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 0);
- break;
- case NvRmGpioPinMode_Inactive:
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, INT_ENB, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 0);
- break;
- case NvRmGpioPinMode_InputInterruptRisingEdge:
- if(hGpio->caps->Features & NVRM_GPIO_CAP_FEAT_EDGE_INTR)
- {
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
- GPIO_REGW(hGpio->hRm, inst, port, INT_CLR, (1 << pin));
- GPIO_REGR(hGpio->hRm, inst, port, INT_LVL, Reg);
- // see the # Bug ID: 359459
- Reg = (Reg & GPIO_INT_LVL_UNSHADOWED_MASK) | (s_hGpio->pIvlReg[alphaPort] & GPIO_INT_LVL_SHADOWED_MASK);
- Reg |= (GPIO_INT_LVL_0_BIT_0_FIELD << pin);
- Reg |= (GPIO_INT_LVL_0_EDGE_0_FIELD << pin);
- Reg &= ~(GPIO_INT_LVL_0_DELTA_0_FIELD << pin);
- s_hGpio->pIvlReg[alphaPort] = Reg;
- GPIO_REGW(hGpio->hRm, inst, port, INT_LVL, Reg);
- }
- else
- {
- NV_ASSERT(!"Not supported");
- }
- break;
- case NvRmGpioPinMode_InputInterruptFallingEdge:
- if(hGpio->caps->Features & NVRM_GPIO_CAP_FEAT_EDGE_INTR)
- {
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, OE, pin, 0);
- GPIO_MASKED_WRITE(hGpio->hRm, inst, port, CNF, pin, 1);
- GPIO_REGW(hGpio->hRm, inst, port, INT_CLR, (1 << pin));
- GPIO_REGR(hGpio->hRm, inst, port, INT_LVL, Reg);
- // see the # Bug ID: 359459
- Reg = (Reg & GPIO_INT_LVL_UNSHADOWED_MASK) |(s_hGpio->pIvlReg[alphaPort] & GPIO_INT_LVL_SHADOWED_MASK);
- Reg &= ~(GPIO_INT_LVL_0_BIT_0_FIELD << pin);
- Reg |= (GPIO_INT_LVL_0_EDGE_0_FIELD << pin);
- Reg &= ~(GPIO_INT_LVL_0_DELTA_0_FIELD << pin);
- s_hGpio->pIvlReg[alphaPort] = Reg;
- GPIO_REGW(hGpio->hRm, inst, port, INT_LVL, Reg);
- }
- else
- {
- NV_ASSERT(!"Not supported");
- }
- break;
- default:
- NV_ASSERT(!"Invalid gpio mode");
- break;
- }
-
- /* Pad group global tristates are only modified when the pin transitions
- * from an inactive state to an active one. Active-to-active and
- * inactive-to-inactive transitions are ignored */
- if ((!s_hGpio->pPinInfo[pinNumber].used) && (Mode!=NvRmGpioPinMode_Inactive))
- {
+ NvError err = NvSuccess;
+ NvU32 i;
+ NvU32 bank;
+ NvU32 port;
+ NvU32 pin;
+ NvU32 alphaPort;
+ int ret_status;
+ int gpio_nr;
+ struct irq_chip *chip;
+ int gpio_irq;
+
+ NvOsMutexLock(s_GpioMutex);
+
+ for (i = 0; i < pinCount; i++) {
+ bank = GET_BANK(hPin[i]);
+ port = GET_PORT(hPin[i]);
+ pin = GET_PIN(hPin[i]);
+
+ if (port == NVRM_GPIO_CAMERA_PORT) {
+ /* If they are trying to do the wrong thing, assert.
+ * If they are trying to do the only allowed thing,
+ * quietly skip it, as nothing needs to be done. */
+ if (Mode != NvOdmGpioPinMode_Output) {
+ NV_ASSERT(!"Only output is supported for "
+ "camera gpio.\n");
+ }
+ continue;
+ }
+
+ /* Absolute pin number to index into pPinInfo array and
+ * the alphabetic port names. */
+ gpio_nr = GPIO_PIN_ID(bank, port, pin);
+ gpio_irq = gpio_to_irq(gpio_nr);
+ if (gpio_nr >= ARCH_NR_GPIOS) {
+ printk(KERN_ERR "Illegal pin handle at place "
+ " %u of the list\n",i);
+ continue;
+ }
+
+ alphaPort = GPIO_PORT_ID(bank, port);
+
+ s_hGpio->pPinInfo[gpio_nr].mode = Mode;
+ s_hGpio->pPinInfo[gpio_nr].inst = bank;
+ s_hGpio->pPinInfo[gpio_nr].port = port;
+ s_hGpio->pPinInfo[gpio_nr].pin = pin;
+
+ /* Don't try to colapse this swtich as the ordering of
+ * the register writes matter. */
+ switch (Mode) {
+ case NvRmGpioPinMode_Output:
+ tegra_gpio_enable(gpio_nr);
+ ret_status = gpio_direction_output(gpio_nr, 0);
+ if (unlikely(ret_status != 0)) {
+ NV_ASSERT(!"Not initialized");
+ return NvError_NotInitialized;
+ }
+ break;
+
+ case NvRmGpioPinMode_InputData:
+ tegra_gpio_enable(gpio_nr);
+ ret_status = gpio_direction_input(gpio_nr);
+ if (unlikely(ret_status != 0)) {
+ NV_ASSERT(!"Not initialized");
+ return NvError_NotInitialized;
+ }
+ break;
+
+ case NvRmGpioPinMode_InputInterruptLow:
+ gpio_direction_input(gpio_nr);
+ tegra_gpio_enable(gpio_nr);
+ chip = get_irq_chip(gpio_irq);
+ if ((chip) && (chip->set_type))
+ chip->set_type(gpio_irq, IRQ_TYPE_LEVEL_LOW);
+ break;
+
+ case NvRmGpioPinMode_InputInterruptHigh:
+ gpio_direction_input(gpio_nr);
+ tegra_gpio_enable(gpio_nr);
+ chip = get_irq_chip(gpio_irq);
+ if ((chip) && (chip->set_type))
+ chip->set_type(gpio_irq, IRQ_TYPE_LEVEL_HIGH);
+ break;
+
+ case NvRmGpioPinMode_InputInterruptAny:
+ if (GPIO_ARCH_FEATURE & NVRM_GPIO_CAP_FEAT_EDGE_INTR) {
+ gpio_direction_input(gpio_nr);
+ tegra_gpio_enable(gpio_nr);
+ chip = get_irq_chip(gpio_irq);
+ if ((chip) && (chip->set_type))
+ chip->set_type(gpio_irq,
+ IRQ_TYPE_EDGE_BOTH);
+ } else {
+ NV_ASSERT(!"Not supported");
+ }
+ break;
+
+ case NvRmGpioPinMode_Function:
+ tegra_gpio_disable(gpio_nr);
+ break;
+
+ case NvRmGpioPinMode_Inactive:
+ chip = get_irq_chip(gpio_irq);
+ if ((chip) && (chip->set_type))
+ chip->mask(gpio_irq);
+ tegra_gpio_disable(gpio_nr);
+ break;
+
+ case NvRmGpioPinMode_InputInterruptRisingEdge:
+ if (GPIO_ARCH_FEATURE & NVRM_GPIO_CAP_FEAT_EDGE_INTR) {
+ gpio_direction_input(gpio_nr);
+ tegra_gpio_enable(gpio_nr);
+
+ chip = get_irq_chip(gpio_irq);
+ if ((chip) && (chip->set_type))
+ chip->set_type(gpio_irq,
+ IRQ_TYPE_EDGE_RISING);
+ } else {
+ NV_ASSERT(!"Not supported");
+ }
+ break;
+
+ case NvRmGpioPinMode_InputInterruptFallingEdge:
+ if (GPIO_ARCH_FEATURE & NVRM_GPIO_CAP_FEAT_EDGE_INTR) {
+ gpio_direction_input(gpio_nr);
+ tegra_gpio_enable(gpio_nr);
+ chip = get_irq_chip(gpio_irq);
+ if ((chip) && (chip->set_type))
+ chip->set_type(gpio_irq,
+ IRQ_TYPE_EDGE_FALLING);
+ } else {
+ NV_ASSERT(!"Not supported");
+ }
+ break;
+
+ default:
+ NV_ASSERT(!"Invalid gpio mode");
+ break;
+ }
+
+ /* Pad group global tristates are only modified when
+ * the pin transitions from an inactive state to an
+ * active one. Active-to-active and inactive-to-inactive
+ * transitions are ignored */
+ if ((!s_hGpio->pPinInfo[gpio_nr].used)
+ && (Mode != NvRmGpioPinMode_Inactive)) {
#if NV_ENABLE_GPIO_POWER_RAIL
- err = NvRmGpioIoPowerConfig(hGpio->hRm, alphaPort, pin, NV_TRUE);
+ err = tegra_gpio_io_power_config(hGpio->hRm,
+ alphaPort, pin, true);
#endif
- NvRmSetGpioTristate(hGpio->hRm, alphaPort, pin, NV_FALSE);
- }
- else if ((s_hGpio->pPinInfo[pinNumber].used) && (Mode==NvRmGpioPinMode_Inactive))
- {
+ NvRmSetGpioTristate(hGpio->hRm,
+ alphaPort, pin, NV_FALSE);
+ } else if ((s_hGpio->pPinInfo[gpio_nr].used)
+ && (Mode == NvRmGpioPinMode_Inactive)) {
#if NV_ENABLE_GPIO_POWER_RAIL
- err = NvRmGpioIoPowerConfig(hGpio->hRm, alphaPort, pin, NV_FALSE);
+ err = tegra_gpio_io_power_config(hGpio->hRm,
+ alphaPort, pin, false);
#endif
- NvRmSetGpioTristate(hGpio->hRm, alphaPort, pin, NV_TRUE);
- }
- if (Mode != NvRmGpioPinMode_Inactive)
- s_hGpio->pPinInfo[pinNumber].used = NV_TRUE;
- else
- s_hGpio->pPinInfo[pinNumber].used = NV_FALSE;
- }
-
- NvOsMutexUnlock(s_GpioMutex);
- return err;
+ NvRmSetGpioTristate(hGpio->hRm,
+ alphaPort, pin, NV_TRUE);
+ }
+ if (Mode != NvRmGpioPinMode_Inactive)
+ s_hGpio->pPinInfo[gpio_nr].used = NV_TRUE;
+ else
+ s_hGpio->pPinInfo[gpio_nr].used = NV_FALSE;
+ }
+
+ NvOsMutexUnlock(s_GpioMutex);
+ return err;
}
-NvError NvRmGpioGetIrqs(
- NvRmDeviceHandle hRmDevice,
- NvRmGpioPinHandle * hPin,
- NvU32 * Irq,
- NvU32 pinCount )
+NvError NvRmGpioGetIrqs(NvRmDeviceHandle hRmDevice,
+ NvRmGpioPinHandle * hPin, NvU32 * Irq, NvU32 pinCount)
{
- NvU32 i;
- for (i=0; i< pinCount; i++)
- {
- NvU32 port, pin, inst;
-
- port = GET_PORT(hPin[i]);
- pin = GET_PIN(hPin[i]);
- inst = GET_INSTANCE(hPin[i]);
-
- Irq[i] = NvRmGetIrqForLogicalInterrupt(hRmDevice,
- NVRM_MODULE_ID(NvRmPrivModuleID_Gpio, inst),
- pin + port * GPIO_PINS_PER_PORT);
- }
- return NvSuccess;
+ NvU32 i;
+ int irq_base;
+ NvU32 bank;
+ NvU32 port;
+ NvU32 pin;
+ int gpio_nr;
+
+ irq_base = gpio_to_irq(0);
+ for (i = 0; i < pinCount; i++) {
+ bank = GET_BANK(hPin[i]);
+ port = GET_PORT(hPin[i]);
+ pin = GET_PIN(hPin[i]);
+ gpio_nr = GPIO_PIN_ID(bank, port, pin);
+ if (gpio_nr >= ARCH_NR_GPIOS) {
+ printk(KERN_ERR "Illegal pin handle at place "
+ " %u of the list\n",i);
+ continue;
+ }
+ Irq[i] = irq_base + gpio_nr;
+ }
+ return NvSuccess;
}
-
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.c b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.c
deleted file mode 100644
index 361413dec1a1..000000000000
--- a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.c
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (c) 2007-2009 NVIDIA Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NVIDIA Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "nvrm_gpio_private.h"
-#include "nvassert.h"
-#include "nvos.h"
-
-static NvRmGpioCaps s_ap15_caps = {6, 4, GPIO_PINS_PER_PORT, NVRM_GPIO_CAP_FEAT_EDGE_INTR /* (SEE BUG# 366493) */};
-
-static NvRmModuleCapability s_capsArray[] = {
- /* Major, minor, eco and caps structure */
- { 2, 0, 0, &s_ap15_caps },
-};
-
-static NvBool s_GpioIoPowerInitialized = NV_FALSE;
-
-static NvRmGpioIoPowerInfo s_GpioIoPowerTable[] =
-{
- {NV_VDD_SYS_ODM_ID, 0},
- {NV_VDD_BB_ODM_ID, 0},
- {NV_VDD_VI_ODM_ID, 0},
- {NV_VDD_SDIO_ODM_ID, 0},
- {NV_VDD_LCD_ODM_ID, 0},
- {NV_VDD_UART_ODM_ID, 0}
-};
-
-NvError
-NvRmGpioGetCapabilities(
- NvRmDeviceHandle hRm,
- void **Capability )
-{
- NvError err = NvSuccess;
-
- NV_ASSERT(hRm);
-
- err = NvRmModuleGetCapabilities(hRm, NvRmPrivModuleID_Gpio, s_capsArray,
- NV_ARRAY_SIZE(s_capsArray), Capability);
- if (err)
- {
- /* Default to AP15 caps.
- FIXME: findout why the RM API is returning failure. */
- NV_ASSERT(0);
- *Capability = (void*)&s_ap15_caps;
- }
-
- ((NvRmGpioCaps *)*Capability)->Instances =
- NvRmModuleGetNumInstances(hRm, NvRmPrivModuleID_Gpio);
-
- return err;
-}
-
-static NvError NvRmGpioIoPowerDiscover(
- NvRmDeviceHandle hRm)
-{
- NvU32 i;
- const NvOdmPeripheralConnectivity* pCon = NULL;
-
- for (i = 0; i < NV_ARRAY_SIZE(s_GpioIoPowerTable); i++)
- {
- pCon = NvOdmPeripheralGetGuid(s_GpioIoPowerTable[i].PowerRailId);
- if (!pCon || !pCon->NumAddress)
- return NvError_NotSupported;
- s_GpioIoPowerTable[i].PmuRailAddress = pCon->AddressList[0].Address;
- }
- return NvSuccess;
-}
-
-NvError NvRmGpioIoPowerConfig(
- NvRmDeviceHandle hRm,
- NvU32 port,
- NvU32 pinNumber,
- NvBool Enable)
-{
- NvRmPmuVddRailCapabilities RailCaps;
- NvU32 SettlingTime;
- NvRmGpioIoPowerInfo *pGpioIoPower;
-
- if (!s_GpioIoPowerInitialized)
- {
- NvError err = NvRmGpioIoPowerDiscover(hRm);
- if (err)
- return err;
- s_GpioIoPowerInitialized = NV_TRUE;
- }
-
- if ((port == GPIO_PORT('s')) ||
- (port == GPIO_PORT('q')) ||
- (port == GPIO_PORT('r')))
- {
- /* NV_VDD_SYS_ODM_ID */
- pGpioIoPower = &s_GpioIoPowerTable[0];
- }
- else if ((port == GPIO_PORT('o')) ||
- ((port == GPIO_PORT('v')) && (pinNumber < 4)))
- {
- /* NV_VDD_BB_ODM_ID */
- pGpioIoPower = &s_GpioIoPowerTable[1];
- }
- else if ((port == GPIO_PORT('l')) ||
- ((port == GPIO_PORT('d')) && (pinNumber > 4)) ||
- ((port == GPIO_PORT('t')) && (pinNumber < 5)))
- {
- /* NV_VDD_VI_ODM_ID */
- pGpioIoPower = &s_GpioIoPowerTable[2];
- }
- else if (((port == GPIO_PORT('d')) && (pinNumber < 5)) ||
- ((port == GPIO_PORT('b')) && (pinNumber > 3)) ||
- ((port == GPIO_PORT('v')) && ((pinNumber > 3) &&
- (pinNumber < 7))) ||
- ((port == GPIO_PORT('a')) && ((pinNumber > 5) ||
- (pinNumber == 0))))
- {
- /* NV_VDD_SDIO_ODM_ID */
- pGpioIoPower = &s_GpioIoPowerTable[3];
- }
- else if ((port == GPIO_PORT('e')) ||
- (port == GPIO_PORT('f')) ||
- (port == GPIO_PORT('m')) ||
- ((port == GPIO_PORT('c')) && ((pinNumber == 1) ||
- (pinNumber == 6))) ||
- ((port == GPIO_PORT('w')) && (pinNumber < 2)) ||
- ((port == GPIO_PORT('j')) && ((pinNumber == 1) ||
- (pinNumber == 3) || (pinNumber == 4))) ||
- ((port == GPIO_PORT('v')) && (pinNumber == 7)) ||
- ((port == GPIO_PORT('n')) && (pinNumber > 3)) ||
- ((port == GPIO_PORT('b')) && ((pinNumber == 2) ||
- (pinNumber == 3))))
- {
- /* NV_VDD_LCD_ODM_ID */
- pGpioIoPower = &s_GpioIoPowerTable[4];
- }
- else
- {
- /* NV_VDD_UART_ODM_ID */
- pGpioIoPower = &s_GpioIoPowerTable[5];
- }
-
- if (Enable)
- {
- NvRmPmuGetCapabilities(hRm,
- pGpioIoPower->PmuRailAddress, &RailCaps);
- NvRmPmuSetVoltage(hRm,
- pGpioIoPower->PmuRailAddress,
- RailCaps.requestMilliVolts, &SettlingTime);
- }
- else
- {
- NvRmPmuSetVoltage(hRm,
- pGpioIoPower->PmuRailAddress,
- ODM_VOLTAGE_OFF, &SettlingTime);
- }
- if (SettlingTime)
- NvOsWaitUS(SettlingTime);
-
- return NvSuccess;
-}
-
diff --git a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.h b/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.h
deleted file mode 100644
index deb48f2d97f5..000000000000
--- a/arch/arm/mach-tegra/nvrm/io/ap15/nvrm_gpio_private.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2007-2009 NVIDIA Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * Neither the name of the NVIDIA Corporation nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef INCLUDED_NVRM_GPIO_PRIVATE_H
-#define INCLUDED_NVRM_GPIO_PRIVATE_H
-
-#include "nvrm_gpio.h"
-#include "ap15/argpio.h"
-#include "nvrm_structure.h"
-#include "ap15/ap15rm_private.h"
-#include "nvrm_hwintf.h"
-#include "nvodm_query_discovery.h"
-#include "nvrm_pmu.h"
-
-#define GPIO_INTR_MAX 32
-#define GPIO_PORT(x) ((x) - 'a')
-#define GET_PIN(h) ((((NvU32)(h))) & 0xFF)
-#define GET_PORT(h) ((((NvU32)(h)) >> 8) & 0xFF)
-#define GET_INSTANCE(h) ((((NvU32)(h)) >> 16) & 0xFF)
-
-// Size of a port register.
-#define NV_GPIO_PORT_REG_SIZE (GPIO_CNF_1 - GPIO_CNF_0)
-#define GPIO_INT_LVL_UNSHADOWED_MASK \
- (GPIO_INT_LVL_0_BIT_7_FIELD | GPIO_INT_LVL_0_BIT_6_FIELD | \
- GPIO_INT_LVL_0_BIT_5_FIELD | GPIO_INT_LVL_0_BIT_4_FIELD | \
- GPIO_INT_LVL_0_BIT_3_FIELD | GPIO_INT_LVL_0_BIT_2_FIELD | \
- GPIO_INT_LVL_0_BIT_1_FIELD | GPIO_INT_LVL_0_BIT_0_FIELD)
-
-#define GPIO_INT_LVL_SHADOWED_MASK (~GPIO_INT_LVL_UNSHADOWED_MASK)
-
-// Gpio register read/write macros
-
-#define GPIO_PINS_PER_PORT 8
-
-#define GPIO_MASKED_WRITE(rm, Instance, Port, Reg, Pin, value) \
- do \
- { \
- NV_REGW((rm), NvRmPrivModuleID_Gpio, (Instance), ((Port) * NV_GPIO_PORT_REG_SIZE) + GPIO_MSK_CNF_0 + \
- (GPIO_##Reg##_0), (((1<<((Pin)+ GPIO_PINS_PER_PORT)) | ((value) << (Pin))))); \
- } while (0)
-
-
-// Gpio register read/write macros
-#define GPIO_REGR( rm, Instance, Port, Reg, ReadData) \
- do \
- { \
- ReadData = NV_REGR((rm), NvRmPrivModuleID_Gpio, (Instance), ((Port) * NV_GPIO_PORT_REG_SIZE) + \
- (GPIO_##Reg##_0)); \
- } while (0)
-
-#define GPIO_REGW( rm, Instance, Port, Reg, Data2Write ) \
- do \
- { \
- NV_REGW((rm), NvRmPrivModuleID_Gpio, (Instance), ((Port) * NV_GPIO_PORT_REG_SIZE) + \
- (GPIO_##Reg##_0), (Data2Write)); \
- } while (0)
-
-/* Bit mask of hardware features present in GPIO controller. */
-typedef enum {
- NVRM_GPIO_CAP_FEAT_NONE = 0,
- NVRM_GPIO_CAP_FEAT_EDGE_INTR = 0x000000001
-} NvRmGpioCapFeatures;
-
-
-typedef struct NvRmGpioCapsRec {
- NvU32 Instances;
- NvU32 PortsPerInstances;
- NvU32 PinsPerPort;
- NvU32 Features;
-} NvRmGpioCaps;
-
-typedef struct NvRmGpioIoPowerInfoRec
-{
- // SoC Power rail GUID
- NvU64 PowerRailId;
-
- // PMU Rail Address
- NvU32 PmuRailAddress;
-
-} NvRmGpioIoPowerInfo;
-
-/**
- * GPIO wrapper for NvRmModuleGetCapabilities().
- *
- * @param hRm The RM device handle
- * @param Capability Out parameter: the cap that maches the current hardware
- */
-NvError
-NvRmGpioGetCapabilities(
- NvRmDeviceHandle hRm,
- void **Capability );
-
-NvError NvRmGpioIoPowerConfig(
- NvRmDeviceHandle hRm,
- NvU32 port,
- NvU32 pinNumber,
- NvBool Enable);
-
-#endif // INCLUDED_NVRM_GPIO_PRIVATE_H
-
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c
index 113879b3afdd..63bdf09a14ae 100644
--- a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c
+++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c
@@ -47,6 +47,8 @@
#define MAX_CLOCKS 3
#define NVODM_PORT(x) ((x) - 'a')
+#define ULPI_RESET_PORT NVODM_PORT('v')
+#define ULPI_RESET_PIN 1
#ifdef NV_DRIVER_DEBUG
@@ -60,45 +62,64 @@ typedef struct NvOdmUsbUlpiRec
NvU64 CurrentGUID;
} NvOdmUsbUlpi;
+static NvOdmServicesGpioHandle s_hGpio = NULL;
+static NvOdmGpioPinHandle s_hResetPin = NULL;
+
NvOdmUsbUlpiHandle NvOdmUsbUlpiOpen(NvU32 Instance)
{
NvOdmUsbUlpi*pDevice = NULL;
NvU32 ClockInstances[MAX_CLOCKS];
NvU32 ClockFrequencies[MAX_CLOCKS];
NvU32 NumClocks;
- NvOdmServicesGpioHandle hGpio;
- NvOdmGpioPinHandle hResetPin;
- NvU32 Port = NVODM_PORT('v');
- NvU32 Pin = 1;
pDevice = NvOdmOsAlloc(sizeof(NvOdmUsbUlpi));
if(pDevice == NULL)
- goto ExitUlpiOdm;
+ return NULL;
- if(!NvOdmExternalClockConfig(SMSC3317GUID, NV_FALSE, ClockInstances, ClockFrequencies, &NumClocks))
+ if(!NvOdmExternalClockConfig(SMSC3317GUID, NV_FALSE, ClockInstances,
+ ClockFrequencies, &NumClocks))
{
- NV_DRIVER_TRACE (("ERROR NvOdmUsbUlpiOpen: NvOdmExternalClockConfig fail\n"));
+ NV_DRIVER_TRACE (("ERROR NvOdmUsbUlpiOpen: "
+ "NvOdmExternalClockConfig fail\n"));
goto ExitUlpiOdm;
}
NvOdmOsSleepMS(10);
+
+ if (!s_hGpio)
+ s_hGpio = NvOdmGpioOpen();
+ if (!s_hGpio)
+ {
+ NV_DRIVER_TRACE (("ERROR NvOdmUsbUlpiOpen: "
+ "Not able to open gpio handle\n"));
+ goto ExitUlpiOdm;
+ }
+
+ if (!s_hResetPin)
+ s_hResetPin = NvOdmGpioAcquirePinHandle(s_hGpio, ULPI_RESET_PORT,
+ ULPI_RESET_PIN);
+ if (!s_hResetPin)
+ {
+ NvOdmGpioClose(s_hGpio);
+ s_hGpio = NULL;
+ NV_DRIVER_TRACE (("ERROR NvOdmGpioAcquirePinHandle: "
+ "Not able to Acq pinhandle\n"));
+ goto ExitUlpiOdm;
+ }
+
// Pull high on RESETB ( 22nd pin of smsc3315)
- hGpio = NvOdmGpioOpen();
- hResetPin = NvOdmGpioAcquirePinHandle(hGpio, Port, Pin);
// config as out put pin
- NvOdmGpioConfig(hGpio,hResetPin, NvOdmGpioPinMode_Output);
+ NvOdmGpioConfig(s_hGpio,s_hResetPin, NvOdmGpioPinMode_Output);
// Set low to write high on ULPI_RESETB pin
- NvOdmGpioSetState(hGpio, hResetPin, 0x01);
- NvOdmGpioSetState(hGpio, hResetPin, 0x0);
+ NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x01);
+ NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x0);
NvOdmOsSleepMS(5);
- NvOdmGpioSetState(hGpio, hResetPin, 0x01);
+ NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x01);
pDevice->CurrentGUID = SMSC3317GUID;
return pDevice;
ExitUlpiOdm:
NvOdmOsFree(pDevice);
- pDevice = NULL;
-
return NULL;
}
@@ -107,7 +128,17 @@ void NvOdmUsbUlpiClose(NvOdmUsbUlpiHandle hOdmUlpi)
if (hOdmUlpi)
{
NvOdmOsFree(hOdmUlpi);
- hOdmUlpi = NULL;
}
+ if (s_hResetPin)
+ {
+ NvOdmGpioReleasePinHandle(s_hGpio, s_hResetPin);
+ s_hResetPin = NULL;
+ }
+ if (s_hGpio)
+ {
+ NvOdmGpioClose(s_hGpio);
+ s_hGpio = NULL;
+ }
+
}