summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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;
+ }
+
}