diff options
author | Gary King <gking@nvidia.com> | 2010-05-14 10:36:33 -0700 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-05-14 20:04:06 -0700 |
commit | 106de33bf7f410bade659e110a5a7b187b46b8b2 (patch) | |
tree | 4d8231dc38fb3c05b6ccb911ff1e3b840d1d444b /arch/arm/mach-tegra/odm_kit | |
parent | e0426ba3077eae7e326c56487f34719f9638ddb5 (diff) |
[ARM/tegra] add NvRm, ODM services, ODM kit for harmony & whistler
add power rail support to GPIO driver
Change-Id: I45d4c1110a635047d68fb14f3e72a28f99acbe1b
Diffstat (limited to 'arch/arm/mach-tegra/odm_kit')
168 files changed, 36873 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/odm_kit/Kconfig b/arch/arm/mach-tegra/odm_kit/Kconfig new file mode 100644 index 000000000000..dbf829f1b79e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/Kconfig @@ -0,0 +1,16 @@ +if MACH_TEGRA_GENERIC + +choice + prompt "Select ODM kit target board" + +config TEGRA_ODM_HARMONY + bool "NVIDIA Harmony development system" + depends on ARCH_TEGRA_2x_SOC + +config TEGRA_ODM_WHISTLER + bool "NVIDIA Whistler development system" + depends on ARCH_TEGRA_2x_SOC + +endchoice + +endif diff --git a/arch/arm/mach-tegra/odm_kit/Makefile b/arch/arm/mach-tegra/odm_kit/Makefile new file mode 100644 index 000000000000..a0f0c6670f71 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/Makefile @@ -0,0 +1,3 @@ +obj-y += adaptations/ +obj-y += platform/ +obj-y += query/ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/Makefile new file mode 100644 index 000000000000..9b0d46744489 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/Makefile @@ -0,0 +1,4 @@ +obj-y += gpio_ext/ +obj-y += tmon/ +obj-y += pmu/ +obj-y += misc/ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile new file mode 100644 index 000000000000..8500f4a6779a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/Makefile @@ -0,0 +1,12 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-y += gpio_ext_hal.o +obj-y += gpio_ext_null.o +obj-y += gpio_pcf50626.o diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c new file mode 100644 index 000000000000..c53fad2da1cd --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 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 "nvcommon.h" +#include "nvodm_query_discovery.h" +#include "nvodm_gpio_ext.h" +#include "nvodm_services.h" +#include "gpio_ext_hal.h" +#include "gpio_ext_null.h" +#include "gpio_pcf50626.h" + +void +NvOdmExternalGpioWritePins( + NvU32 Port, + NvU32 Pin, + NvU32 PinValue) +{ + static NvBool IsInit = NV_FALSE; + static NvOdmGpioExtDevice GpioExtDevice; + + if (!IsInit) + { + NvOdmOsMemset(&GpioExtDevice, 0, sizeof(GpioExtDevice)); + if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0'))) + { + // fill in HAL function here. + GpioExtDevice.pfnWritePins = GPIO_PCF50626_NvOdmExternalGpioWritePins; + } + else + { + // NULL implementation + GpioExtDevice.pfnWritePins = null_NvOdmExternalGpioWritePins; + } + IsInit = NV_TRUE; + } + GpioExtDevice.pfnWritePins(Port, Pin, PinValue); +} + +NvU32 +NvOdmExternalGpioReadPins( + NvU32 Port, + NvU32 Pin) +{ + static NvBool IsInit = NV_FALSE; + static NvOdmGpioExtDevice GpioExtDevice; + + if (!IsInit) + { + NvOdmOsMemset(&GpioExtDevice, 0, sizeof(GpioExtDevice)); + if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0'))) + { + // fill in HAL function here. + GpioExtDevice.pfnReadPins = GPIO_PCF50626_NvOdmExternalGpioReadPins; + } + else + { + // NULL implementation + GpioExtDevice.pfnReadPins = null_NvOdmExternalGpioReadPins; + } + IsInit = NV_TRUE; + } + return GpioExtDevice.pfnReadPins(Port, Pin); +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h new file mode 100644 index 000000000000..e1ca2c1182f9 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_hal.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Abstraction layer stub for external gpio + * adaptation</b> + */ + +#ifndef INCLUDED_NVODM_GPIO_EXT_ADAPTATION_HAL_H +#define INCLUDED_NVODM_GPIO_EXT_ADAPTATION_HAL_H + +#include "nvodm_gpio_ext.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +// A simple HAL for the External GPIO adaptations. +typedef void (*pfnExternalGpioWritePins)(NvU32, NvU32, NvU32); +typedef NvU32 (*pfnExternalGpioReadPins)(NvU32, NvU32); + +typedef struct NvOdmGpioExtDeviceRec +{ + pfnExternalGpioWritePins pfnWritePins; + pfnExternalGpioReadPins pfnReadPins; + +} NvOdmGpioExtDevice; + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c new file mode 100644 index 000000000000..4957b099484a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.c @@ -0,0 +1,54 @@ +/* + * Copyright (c) 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 "nvodm_gpio_ext.h" +#include "gpio_ext_null.h" + +void +null_NvOdmExternalGpioWritePins( + NvU32 Port, + NvU32 Pin, + NvU32 PinValue) +{ + // NULL implementation that does nothing. + return; +} + +NvU32 +null_NvOdmExternalGpioReadPins( + NvU32 Port, + NvU32 Pin) +{ + // NULL implementation that does nothing. + return 0; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h new file mode 100644 index 000000000000..6e38bb31f121 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_ext_null.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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_GPIO_EXT_NULL_H +#define INCLUDED_GPIO_EXT_NULL_H + +#include "gpio_ext_hal.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +void null_NvOdmExternalGpioWritePins(NvU32, NvU32, NvU32); +NvU32 null_NvOdmExternalGpioReadPins(NvU32, NvU32); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c new file mode 100644 index 000000000000..5f41b8aee053 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 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 "nvodm_services.h" +#include "nvassert.h" +#include "nvodm_gpio_ext.h" +#include "gpio_pcf50626.h" + +#if NV_DEBUG +#define ASSERT_SUCCESS( expr ) \ + do { \ + NvBool b = (expr); \ + NV_ASSERT( b == NV_TRUE ); \ + } while( 0 ) +#else +#define ASSERT_SUCCESS( expr ) \ + do { \ + (void)(expr); \ + } while( 0 ) +#endif + +static NvOdmServicesI2cHandle s_hOdmI2c = NULL; + +#define PCF50626_I2C_SPEED_KHZ 400 +#define PCF50626_DEVICE_ADDR 0xE0 +#define PCF50626_GPO2C1_ADDR 0x55 +#define PCF50626_PWM1S_ADDR 0x2D +#define PCF50626_PWM1D_ADDR 0x2E + +static NvBool GPIO_PCF50626_I2cWrite8(NvU8 Addr, NvU8 Data); + +void +GPIO_PCF50626_NvOdmExternalGpioWritePins( + NvU32 Port, + NvU32 Pin, + NvU32 PinValue) +{ + NvU8 val; + NvBool RetVal = NV_TRUE; + + switch (Port) + { + case NVODM_GPIO_EXT_PORT_2: + if (Pin != 1) // Only Pin 1 is implemented at this time + break; + + if (PinValue) // Enable + { + val = (1UL << 6) // invert polarity + | 0x3; // pwm1 output + RetVal = GPIO_PCF50626_I2cWrite8(PCF50626_GPO2C1_ADDR, val); + } + else // Disable + { + RetVal = GPIO_PCF50626_I2cWrite8(PCF50626_GPO2C1_ADDR, 0x0); + } + break; + } + + if (RetVal == NV_FALSE) + { + NvOdmOsDebugPrintf("ERROR: GPIO_PCF50626_I2cWrite8() failed.\n"); + } + + return; +} + +NvU32 +GPIO_PCF50626_NvOdmExternalGpioReadPins( + NvU32 Port, + NvU32 Pin) +{ + // Implement external GPIO port read routine here. + return 0; +} + +static NvBool GPIO_PCF50626_I2cWrite8( + NvU8 Addr, + NvU8 Data) +{ + NvBool RetVal = NV_TRUE; + NvU8 WriteBuffer[2]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + NvOdmI2cTransactionInfo TransactionInfo; + NvU32 DeviceAddr = (NvU32)PCF50626_DEVICE_ADDR; + + s_hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0); + if (!s_hOdmI2c) + { + RetVal = NV_FALSE; + goto GPIO_PCF50626_I2cWrite8_exit; + } + + WriteBuffer[0] = Addr & 0xFF; // PMU offset + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = DeviceAddr; + TransactionInfo.Buf = WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(s_hOdmI2c, &TransactionInfo, 1, + PCF50626_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + RetVal = NV_TRUE; + else + RetVal = NV_FALSE; + +GPIO_PCF50626_I2cWrite8_exit: + NvOdmI2cClose(s_hOdmI2c); + s_hOdmI2c = NULL; + return RetVal; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h new file mode 100644 index 000000000000..4f78bff05e3f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/gpio_ext/gpio_pcf50626.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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_GPIO_PCF50626_H +#define INCLUDED_GPIO_PCF50626_H + +#include "gpio_ext_hal.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +void +GPIO_PCF50626_NvOdmExternalGpioWritePins( + NvU32 Port, + NvU32 Pin, + NvU32 PinValue); + +NvU32 +GPIO_PCF50626_NvOdmExternalGpioReadPins( + NvU32 Port, + NvU32 Pin); + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile new file mode 100644 index 000000000000..61c287105a48 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_TEGRA_ODM_HARMONY) += harmony/ +obj-$(CONFIG_TEGRA_ODM_WHISTLER) += whistler/ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile new file mode 100644 index 000000000000..12af02178d7f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/Makefile @@ -0,0 +1,14 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc.o +obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc_keymapping.o +obj-y += nvodm_sdio.o +obj-y += nvodm_uart.o +obj-y += nvodm_usbulpi.o diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c new file mode 100644 index 000000000000..3f07a61a66c4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2008-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. + * + */ + +/** + * @file Nvodm_Kbc.c + * @brief <b>KBC odm implementation</b> + * + * @Description : Implementation of the odm KBC API + */ +#include "nvodm_kbc.h" +#include "../../../query/harmony/nvodm_query_kbc_qwerty_def.h" + +NvU32 +NvOdmKbcFilterKeys( + NvU32 *pRows, + NvU32 *pCols, + NvU32 NumOfKeysPressed) +{ + NvBool IsFunctionKeyFound = NV_FALSE; + NvU32 KeyIndex; + + for (KeyIndex = 0; KeyIndex < NumOfKeysPressed; ++KeyIndex) + { + if ((pRows[KeyIndex] == KBC_QWERTY_FUNCTION_KEY_ROW_NUMBER) && + (pCols[KeyIndex] == KBC_QWERTY_FUNCTION_KEY_COLUMN_NUMBER)) + { + IsFunctionKeyFound = NV_TRUE; + break; + } + } + if (!IsFunctionKeyFound) + return NumOfKeysPressed; + + // Add function row base to treat as special case + for (KeyIndex = 0; KeyIndex < NumOfKeysPressed; ++KeyIndex) + pRows[KeyIndex] += KBC_QWERTY_FUNCTION_KEY_ROW_BASE; + + return NumOfKeysPressed; +} + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c new file mode 100644 index 000000000000..1b316bc511e8 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_kbc_keymapping.c @@ -0,0 +1,184 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Keyboard Controller virtual key mapping</b> + * + * @b Description: Implement the ODM keyboard mapping to the platform + * specific. + */ +#include "nvodm_kbc_keymapping.h" +#include <linux/input.h> + + +#define KBC_QWERTY_NORMAL_KEY_CODE_BASE 0x1000 +#define KBC_QWERTY_FUNCTION_KEY_CODE_BASE 0x2000 + +#define KBC_QWERTY_FUNCTION_KEY_ROW_BASE 0x100 +#define KBC_QWERTY_FUNCTION_KEY_ROW_NUMBER 0 +#define KBC_QWERTY_FUNCTION_KEY_COLUMN_NUMBER 7 + +/** + * @brief Scan Code to Virtual Key mappings. + */ + + +/* The total number of soc scan codes will be (first - last) */ +#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST KBC_QWERTY_NORMAL_KEY_CODE_BASE +#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST (KBC_QWERTY_NORMAL_KEY_CODE_BASE +0x7F) + +#define NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_FIRST KBC_QWERTY_FUNCTION_KEY_CODE_BASE +#define NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_LAST (KBC_QWERTY_FUNCTION_KEY_CODE_BASE +0x7F) + +/** + * @brief This is the actual Scan-code-to-VKey mapping table. For new layouts + * this is the only structure which needs to be modified to return the + * proper vkey depending on the scan code. + */ + +#define KEY_UNUSED 0 + +static NvU32 ScanCodeToVKeyTableKbcQwertyNormal[] = +{ + // Row 0-> Unused, Unused, 'W', 'S', 'A', 'Z', Unused, Function, + // Row 1 ->Unused, Unused, Unused, Unused, Unused, unused, Unused, WIN_SPECIAL + // Row 2 ->Unused, Unused, Unused, Unused, Unused, unused, Alt, Alt2 + // Row 3 ->'5', '4', 'R', 'E', 'F', 'D', 'X', Unused, + // Row 4 ->'7', '6', 'T', 'H', 'G', 'V', 'C', SPACEBAR, + // Row 5 ->'9', '8', 'U', 'Y', 'J', 'N', 'B', '|\', + // Row 6 ->Minus, '0', 'O', 'I', 'L', 'K', '<', M, + // Row 7 ->unused, '+', '}]', '#', Unused, Unused, Unused, WinSpecial, + // Row 8 ->Unused, Unused, Unused, Unused, SHIFT, SHIFT, UnUsed, Unused , + // Row 9 ->Unused, Unused, Unused, Unused, unused, Ctrl, UnUsed, Control, + // Row A ->Unused, Unused, Unused, Unused, unused, unused, UnUsed, Unused, + // Row B ->'{[', 'P', '"', ':;', '/?, '>', UnUsed, Unused, + // Row C ->'F10', 'F9', 'BckSpc','3', '2', 'Up, Prntscr,Pause + // Row D ->INS, DEL, Unused, Pgup, PgDn, right, Down, Left, + // Row E ->F11, F12, F8, 'Q', F4, F3, '1', F7, + // Row F ->ESC, '~', F5, TAB, F1, F2, CAPLOCK,F6, + KEY_UNUSED, KEY_UNUSED, KEY_W, KEY_S, + KEY_A, KEY_Z, KEY_UNUSED, KEY_FN, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_MENU, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_LEFTALT, KEY_RIGHTALT, + KEY_5, KEY_4, KEY_R, KEY_E, + KEY_F, KEY_D, KEY_X, KEY_UNUSED, + KEY_7, KEY_6, KEY_T, KEY_H, + KEY_G, KEY_V, KEY_C, KEY_SPACE, + KEY_9, KEY_8, KEY_U, KEY_Y, + KEY_J, KEY_N, KEY_B, KEY_BACKSLASH, + KEY_MINUS, KEY_0, KEY_O, KEY_I, + KEY_L, KEY_K, KEY_COMMA, KEY_M, + KEY_UNUSED, KEY_EQUAL, KEY_RIGHTBRACE, KEY_ENTER, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_MENU, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_LEFTSHIFT, KEY_RIGHTSHIFT, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_LEFTCTRL, KEY_UNUSED, KEY_RIGHTCTRL, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_LEFTBRACE, KEY_P, KEY_APOSTROPHE, KEY_SEMICOLON, + KEY_SLASH, KEY_DOT, KEY_UNUSED, KEY_UNUSED, + KEY_F10, KEY_F9, KEY_BACKSPACE, KEY_3, + KEY_2, KEY_UP, KEY_PRINT, KEY_PAUSE, + KEY_INSERT, KEY_DELETE, KEY_UNUSED, KEY_PAGEUP, + KEY_PAGEDOWN, KEY_RIGHT, KEY_DOWN, KEY_LEFT, + KEY_F11, KEY_F12, KEY_F8, KEY_Q, + KEY_F4, KEY_F3, KEY_1, KEY_F7, + KEY_ESC, KEY_GRAVE, KEY_F5, KEY_TAB, + KEY_F1, KEY_F2, KEY_CAPSLOCK , KEY_F6 +}; + +static NvU32 ScanCodeToVKeyTableKbcQwertyFunction[] = +{ + // Row 0-> Unused, Unused, 'W', 'S', 'A', 'Z', Unused, Function, + // Row 1 ->WINSPECIAL, Unused, Unused, Unused, Unused, unused, Unused, Win_special + // Row 2 ->Unused, Unused, Unused, Unused, Unused, unused, Alt, Alt2 + // Row 3 ->'5', '4', 'R', 'E', 'F', 'D', 'X', Unused, + // Row 4 ->'7', '6', 'T', 'H', 'G', 'V', 'C', SPACEBAR, + // Row 5 ->'9', '8', 'U', 'Y', 'J', 'N', 'B', '|\', + // Row 6 ->Minus, '0', 'O', 'I', 'L', 'K', '<', M, + // Row 7 ->unused, '+', '}]', '#', Unused, Unused, Unused, WinSpecial, + // Row 8 ->Unused, Unused, Unused, Unused, SHIFT, SHIFT, UnUsed, Unused , + // Row 9 ->Unused, Unused, Unused, Unused, unused, Ctrl, UnUsed, Control, + // Row A ->Unused, Unused, Unused, Unused, unused, unused, UnUsed, Unused, + // Row B ->'{[', 'P', '"', ':;', '/?, '>', UnUsed, Unused, + // Row C ->'F10', 'F9', 'BckSpc','3', '2', 'Up, Prntscr,Pause + // Row D ->INS, DEL, Unused, Pgup, PgDn, right, Down, Left, + // Row E ->F11, F12, F8, 'Q', F4, F3, '1', F7, + // Row F ->ESC, '~', F5, TAB, F1, F2, CAPLOCK,F6, + + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_7, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_9, KEY_8, KEY_4, KEY_UNUSED, KEY_1, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_SLASH, KEY_6, KEY_5, KEY_3, KEY_2, KEY_UNUSED, KEY_0, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_KPASTERISK, KEY_UNUSED, KEY_KPMINUS, KEY_KPPLUS, KEY_DOT, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_VOLUMEUP, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_HOME, KEY_END, KEY_BRIGHTNESSUP, KEY_VOLUMEDOWN, KEY_BRIGHTNESSDOWN, + KEY_NUMLOCK, KEY_SCROLLLOCK, KEY_MUTE,KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, + KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_UNUSED, KEY_QUESTION,KEY_UNUSED, KEY_UNUSED, KEY_UNUSED +}; +static struct NvOdmKeyVirtTableDetail s_ScvkQwertyNormalEngUS = +{ + NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST, // scan code start + NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST, // scan code end + ScanCodeToVKeyTableKbcQwertyNormal // Normal Qwerty keyboard +}; + +static struct NvOdmKeyVirtTableDetail s_ScvkQwertyFunctionEngUS = +{ + NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_FIRST, // scan code start + NV_SOC_FUNCTION_KEY_SCAN_CODE_TABLE_LAST, // scan code end + ScanCodeToVKeyTableKbcQwertyFunction // Function Qwerty keyboard +}; + +static const struct NvOdmKeyVirtTableDetail *s_pVirtualKeyTables[] = + {&s_ScvkQwertyNormalEngUS, &s_ScvkQwertyFunctionEngUS}; + + +NvU32 +NvOdmKbcKeyMappingGetVirtualKeyMappingList( + const struct NvOdmKeyVirtTableDetail ***pVirtKeyTableList) +{ + *pVirtKeyTableList = s_pVirtualKeyTables; + return NV_ARRAY_SIZE(s_pVirtualKeyTables); +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c new file mode 100644 index 000000000000..946f4ab9ecc4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_sdio.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2008-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. + * + */ + +/** + * @file Nvodm_Sdio.c + * @brief <b>Sdio odm implementation</b> + * + * @Description : Implementation of the odm sdio API + */ +#include "nvodm_sdio.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvodm_pmu.h" +#include "nvos.h" + +#ifdef NV_DRIVER_DEBUG + #define NV_DRIVER_TRACE(x) NvOdmOsDebugPrintf x +#else + #define NV_DRIVER_TRACE(x) +#endif + +#define WLAN_GUID NV_ODM_GUID('s','d','i','o','w','l','a','n') + +typedef struct NvOdmSdioRec +{ + // NvODM PMU device handle + NvOdmServicesPmuHandle hPmu; + // Gpio Handle + NvOdmServicesGpioHandle hGpio; + // Pin handle to Wlan Reset Gpio pin + NvOdmGpioPinHandle hResetPin; + // Pin handle to Wlan PWR GPIO Pin + NvOdmGpioPinHandle hPwrPin; + NvOdmPeripheralConnectivity *pConnectivity; + // Power state + NvBool PoweredOn; + // Instance + NvU32 Instance; +} NvOdmSdio; + + + +static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, NvBool IsEnable); +static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable); + + +static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable) +{ + if (IsEnable) + { + // Wlan Power On Reset Sequence + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x0); //RST -> Low + NvOdmOsWaitUS(2000); + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x1); //PWD -> High + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x1); //RST -> High + } + else + { + // Power Off sequence + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low + } + + return NV_TRUE; +} + +NvOdmSdioHandle NvOdmSdioOpen(NvU32 Instance) +{ + static NvOdmSdio *pDevice = NULL; + NvOdmServicesGpioHandle hGpioTemp = NULL; + NvOdmPeripheralConnectivity *pConnectivity; + NvU32 NumOfGuids = 1; + NvU64 guid; + NvU32 searchVals[2]; + const NvU32 *pOdmConfigs; + NvU32 NumOdmConfigs; + NvBool Status = NV_TRUE; + const NvOdmPeripheralSearch searchAttrs[] = + { + NvOdmPeripheralSearch_IoModule, + NvOdmPeripheralSearch_Instance, + }; + + searchVals[0] = NvOdmIoModule_Sdio; + searchVals[1] = Instance; + + NvOdmQueryPinMux(NvOdmIoModule_Sdio, &pOdmConfigs, &NumOdmConfigs); + if (Instance >= NumOdmConfigs ) + return NULL; + if( pOdmConfigs[Instance] == 0 ) + return NULL; + + NumOfGuids = NvOdmPeripheralEnumerate( + searchAttrs, + searchVals, + 2, + &guid, + NumOfGuids); + + + // Get the peripheral connectivity information + pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid); + if (pConnectivity == NULL) + return NULL; + + pDevice = NvOdmOsAlloc(sizeof(NvOdmSdio)); + pDevice->hPmu = NULL; + if(pDevice == NULL) + return (pDevice); + + if (pDevice->hPmu == NULL) + { + pDevice->hPmu = NvOdmServicesPmuOpen(); + if(pDevice->hPmu == NULL) + { + NvOdmOsFree(pDevice); + pDevice = NULL; + return (NULL); + } + } + + pDevice->pConnectivity = pConnectivity; + NvOdmSetPowerOnSdio(pDevice, NV_TRUE); + + if (pConnectivity->Guid == WLAN_GUID) + { + // Getting the OdmGpio Handle + hGpioTemp = NvOdmGpioOpen(); + if (hGpioTemp == NULL) + { + NvOdmOsFree(pDevice); + pDevice = NULL; + return (pDevice); + } + + // Search for the Vdd rail and set the proper volage to the rail. + if (pConnectivity->AddressList[1].Interface == NvOdmIoModule_Gpio) + { + // Acquiring Pin Handles for Power Pin + pDevice->hPwrPin= NvOdmGpioAcquirePinHandle(hGpioTemp, + pConnectivity->AddressList[1].Instance, + pConnectivity->AddressList[1].Address); + } + + if (pConnectivity->AddressList[2].Interface == NvOdmIoModule_Gpio) + { + // Acquiring Pin Handles for Reset Pin + pDevice->hResetPin= NvOdmGpioAcquirePinHandle(hGpioTemp, + pConnectivity->AddressList[2].Instance, + pConnectivity->AddressList[2].Address); + } + + // Setting the ON/OFF pin to output mode. + NvOdmGpioConfig(hGpioTemp, pDevice->hPwrPin, NvOdmGpioPinMode_Output); + NvOdmGpioConfig(hGpioTemp, pDevice->hResetPin, NvOdmGpioPinMode_Output); + + // Setting the Output Pin to Low + NvOdmGpioSetState(hGpioTemp, pDevice->hPwrPin, 0x0); + NvOdmGpioSetState(hGpioTemp, pDevice->hResetPin, 0x0); + + pDevice->hGpio = hGpioTemp; + + Status = SdioOdmWlanSetPowerOn(pDevice, NV_TRUE); + if (Status != NV_TRUE) + { + NvOdmOsFree(pDevice); + pDevice = NULL; + return (pDevice); + } + } + pDevice->PoweredOn = NV_TRUE; + pDevice->Instance = Instance; + NV_DRIVER_TRACE(("Open SDIO%d", Instance)); + return pDevice; +} + +void NvOdmSdioClose(NvOdmSdioHandle hOdmSdio) +{ + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + + NV_DRIVER_TRACE(("Close SDIO%d", hOdmSdio->Instance)); + + pConnectivity = hOdmSdio->pConnectivity; + if (pConnectivity->Guid == WLAN_GUID) + { + // Call Turn off power when close is Called + (void)SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE); + + NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hPwrPin); + NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hResetPin); + NvOdmGpioClose(hOdmSdio->hGpio); + } + NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE); + if (hOdmSdio->hPmu != NULL) + { + NvOdmServicesPmuClose(hOdmSdio->hPmu); + } + NvOdmOsFree(hOdmSdio); + hOdmSdio = NULL; +} + +static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, + NvBool IsEnable) +{ + NvU32 Index = 0; + NvOdmServicesPmuVddRailCapabilities RailCaps; + NvU32 SettlingTime = 0; + const NvOdmPeripheralConnectivity *pConnectivity; + + pConnectivity = pDevice->pConnectivity; + if (IsEnable) // Turn on Power + { + // Search for the Vdd rail and set the proper volage to the rail. + for (Index = 0; Index < pConnectivity->NumAddress; ++Index) + { + if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd) + { + NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps); + NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address, + RailCaps.requestMilliVolts, &SettlingTime); + if (SettlingTime) + { + NvOdmOsWaitUS(SettlingTime); + } + } + } + } + else // Shutdown Power + { + // Search for the Vdd rail and power Off the module + for (Index = 0; Index < pConnectivity->NumAddress; ++Index) + { + if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd) + { + NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps); + NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address, + ODM_VOLTAGE_OFF, &SettlingTime); + if (SettlingTime) + { + NvOdmOsWaitUS(SettlingTime); + } + } + } + } +} + +NvBool NvOdmSdioSuspend(NvOdmSdioHandle hOdmSdio) +{ + + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + NvBool Status = NV_TRUE; + + if (!hOdmSdio->PoweredOn) + { + NV_DRIVER_TRACE(("SDIO%d already suspended", hOdmSdio->Instance)); + return NV_TRUE; + } + + NV_DRIVER_TRACE(("Suspend SDIO%d", hOdmSdio->Instance)); + NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE); + + pConnectivity = hOdmSdio->pConnectivity; + if (pConnectivity->Guid == WLAN_GUID) + { + // Turn off power + Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE); + + } + hOdmSdio->PoweredOn = NV_FALSE; + return Status; + +} + +NvBool NvOdmSdioResume(NvOdmSdioHandle hOdmSdio) +{ + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + NvBool Status = NV_TRUE; + + if (hOdmSdio->PoweredOn) + { + NV_DRIVER_TRACE(("SDIO%d already resumed", hOdmSdio->Instance)); + return NV_TRUE; + } + + NvOdmSetPowerOnSdio(hOdmSdio, NV_TRUE); + + pConnectivity = hOdmSdio->pConnectivity; + if (pConnectivity->Guid == WLAN_GUID) + { + // Turn on power + Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_TRUE); + } + NV_DRIVER_TRACE(("Resume SDIO%d", hOdmSdio->Instance)); + hOdmSdio->PoweredOn = NV_TRUE; + return Status; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c new file mode 100644 index 000000000000..a3f09ad89c18 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_uart.c @@ -0,0 +1,138 @@ +/* + * 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. + * + */ + +/** + * @file nvodm_uart.c + * @brief <b>Adaptation for uart </b> + * + * @Description : Implementation of the uart adaptation. + */ +#include "nvodm_uart.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvos.h" +#include "nvodm_pmu.h" + +#ifdef NV_DRIVER_DEBUG + #define NV_DRIVER_TRACE NvOsDebugPrintf +#else + #define NV_DRIVER_TRACE (void) +#endif + +typedef struct NvOdmUartRec +{ + // NvODM PMU device handle + NvOdmServicesPmuHandle hPmu; + // Gpio Handle + NvOdmServicesGpioHandle hGpio; + // Pin handle to Bluetooth Reset Gpio pin + NvOdmGpioPinHandle hResetPin; + NvOdmPeripheralConnectivity *pConnectivity; +} NvOdmUart; + +NvOdmUartHandle NvOdmUartOpen(NvU32 Instance) +{ + NvOdmUart *pDevice = NULL; + NvOdmPeripheralConnectivity *pConnectivity; + NvU32 NumOfGuids = 1; + NvU64 guid; + NvU32 searchVals[2]; + const NvOdmPeripheralSearch searchAttrs[] = + { + NvOdmPeripheralSearch_IoModule, + NvOdmPeripheralSearch_Instance, + }; + + searchVals[0] = NvOdmIoModule_Uart; + searchVals[1] = Instance; + + NumOfGuids = NvOdmPeripheralEnumerate( + searchAttrs, + searchVals, + 2, + &guid, + NumOfGuids); + + pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid); + if (pConnectivity == NULL) + goto ExitUartOdm; + + pDevice = NvOdmOsAlloc(sizeof(NvOdmUart)); + if(pDevice == NULL) + goto ExitUartOdm; + + pDevice->hPmu = NvOdmServicesPmuOpen(); + if(pDevice->hPmu == NULL) + { + goto ExitUartOdm; + } + + // Switch On UART Interface + + pDevice->pConnectivity = pConnectivity; + + return pDevice; + +ExitUartOdm: + NvOdmOsFree(pDevice); + pDevice = NULL; + + return NULL; +} + +void NvOdmUartClose(NvOdmUartHandle hOdmUart) +{ + + if (hOdmUart) + { + // Switch OFF UART Interface + + if (hOdmUart->hPmu != NULL) + { + NvOdmServicesPmuClose(hOdmUart->hPmu); + } + NvOdmOsFree(hOdmUart); + hOdmUart = NULL; + } +} + +NvBool NvOdmUartSuspend(NvOdmUartHandle hOdmUart) +{ + return NV_FALSE; +} + +NvBool NvOdmUartResume(NvOdmUartHandle hOdmUart) +{ + return NV_FALSE; +} + 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 new file mode 100644 index 000000000000..63bdf09a14ae --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/harmony/nvodm_usbulpi.c @@ -0,0 +1,144 @@ +/* + * 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. + * + */ + +/** + * @file nvodm_usbulpi.c + * @brief <b>Adaptation for USB ULPI </b> + * + * @Description : Implementation of the USB ULPI adaptation. + */ +#include "nvodm_usbulpi.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvos.h" + +#define SMSC3317GUID NV_ODM_GUID('s','m','s','c','3','3','1','7') + +#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 + #define NV_DRIVER_TRACE NvOsDebugPrintf +#else + #define NV_DRIVER_TRACE (void) +#endif + +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; + + pDevice = NvOdmOsAlloc(sizeof(NvOdmUsbUlpi)); + if(pDevice == NULL) + return NULL; + + if(!NvOdmExternalClockConfig(SMSC3317GUID, NV_FALSE, ClockInstances, + ClockFrequencies, &NumClocks)) + { + 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) + // config as out put pin + NvOdmGpioConfig(s_hGpio,s_hResetPin, NvOdmGpioPinMode_Output); + // Set low to write high on ULPI_RESETB pin + NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x01); + NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x0); + NvOdmOsSleepMS(5); + NvOdmGpioSetState(s_hGpio, s_hResetPin, 0x01); + + pDevice->CurrentGUID = SMSC3317GUID; + return pDevice; + +ExitUlpiOdm: + NvOdmOsFree(pDevice); + return NULL; +} + +void NvOdmUsbUlpiClose(NvOdmUsbUlpiHandle hOdmUlpi) +{ + if (hOdmUlpi) + { + NvOdmOsFree(hOdmUlpi); + } + if (s_hResetPin) + { + NvOdmGpioReleasePinHandle(s_hGpio, s_hResetPin); + s_hResetPin = NULL; + } + if (s_hGpio) + { + NvOdmGpioClose(s_hGpio); + s_hGpio = NULL; + } + +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile new file mode 100644 index 000000000000..9f3eb8402b6b --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/Makefile @@ -0,0 +1,15 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc.o +obj-$(CONFIG_KEYBOARD_TEGRA) += nvodm_kbc_keymapping.o +obj-y += nvodm_sdio.o +obj-y += nvodm_uart.o +obj-y += nvodm_usbulpi.o + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c new file mode 100644 index 000000000000..70b468d9ff51 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc.c @@ -0,0 +1,145 @@ +/* + * Copyright (c) 2008-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. + * + */ + +/** + * @file Nvodm_Kbc.c + * @brief <b>KBC odm implementation</b> + * + * @Description : Implementation of the odm KBC API + */ +#include "nvodm_kbc.h" + + +#define KEYPAD_HAS_DIODES 1 + +NvU32 +NvOdmKbcFilterKeys( + NvU32 *pRows, + NvU32 *pCols, + NvU32 NumOfKeysPressed) +{ + +#if KEYPAD_HAS_DIODES + return NumOfKeysPressed; +#else + NvU32 i=0; + NvU32 j=0; + NvU32 k=0; + NvU32 FilterKeys[2] = {0}; + NvBool IsFiltered = NV_FALSE; + NvU32 NewKeyPressCount = NumOfKeysPressed; + + if (NumOfKeysPressed <= 3) + { + for (i=0; i<NumOfKeysPressed; i++) + { + for (j=(i+1); j<NumOfKeysPressed; j++) + { + if ((pRows[i]+1==pRows[j])||(pRows[j]+1==pRows[i])) + { + for (k=j; i<(NumOfKeysPressed - 1); i++) + { + pRows[k] = pRows[k+1]; + pCols[k] = pCols[k+1]; + } + NumOfKeysPressed--; + } + if ((pCols[i]+1==pCols[j])||(pCols[j]+1==pCols[i])) + { + for (k=j; i<(NumOfKeysPressed - 1); i++) + { + pRows[k] = pRows[k+1]; + pCols[k] = pCols[k+1]; + } + NumOfKeysPressed--; + } + } + } + return NumOfKeysPressed; + } + + for (i=0; i<NumOfKeysPressed; i++) + { + for (j=(i+1); j<NumOfKeysPressed; j++) + { + if (pRows[i] == pRows[j]) + { + for (k=0; k<NumOfKeysPressed; k++) + { + if (k == i) + continue; + + if(pCols[i] == pCols[k]) + { + FilterKeys[0] = k; + IsFiltered = NV_TRUE; + } + } + for (k=0; k<NumOfKeysPressed; k++) + { + if (k == j) + continue; + + if (pCols[j] == pCols[k]) + { + FilterKeys[1] = k; + IsFiltered = NV_TRUE; + } + } + goto end; + } + } + } + + end: + if (IsFiltered) + { + for (i=FilterKeys[0]; i<(NumOfKeysPressed - 1); i++) + { + pRows[i] = pRows[i+1]; + pCols[i] = pCols[i+1]; + } + NewKeyPressCount--; + for (i=FilterKeys[1]; i<(NumOfKeysPressed - 1); i++) + { + pRows[i] = pRows[i+1]; + pCols[i] = pCols[i+1]; + } + NewKeyPressCount--; + } + NumOfKeysPressed = NewKeyPressCount; + return NewKeyPressCount; +#endif + +} + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c new file mode 100644 index 000000000000..1f2dd7275eae --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_kbc_keymapping.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Keyboard Controller virtual key mapping</b> + * + * @b Description: Implement the ODM keyboard mapping to the platform + * specific. + */ +#include "nvodm_kbc_keymapping.h" +#include <linux/input.h> + +/* The total number of soc scan codes will be (first - last) */ +#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST 0 +#define NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST 3 + +static NvU32 KbcLayOutVirtualKey[] = +{ + KEY_MENU, + 0, + KEY_HOME, + KEY_BACK +}; + +static struct NvOdmKeyVirtTableDetail s_ScvkKeyMap = +{ + NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_FIRST, // scan code start + NV_SOC_NORMAL_KEY_SCAN_CODE_TABLE_LAST, // scan code end + KbcLayOutVirtualKey // Normal Qwerty keyboard +}; + + +static const struct NvOdmKeyVirtTableDetail *s_pVirtualKeyTables[] = + {&s_ScvkKeyMap}; + + +NvU32 +NvOdmKbcKeyMappingGetVirtualKeyMappingList( + const struct NvOdmKeyVirtTableDetail ***pVirtKeyTableList) +{ + *pVirtKeyTableList = s_pVirtualKeyTables; + return NV_ARRAY_SIZE(s_pVirtualKeyTables); +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c new file mode 100644 index 000000000000..d980dfca3b2b --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_sdio.c @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2008-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. + * + */ + +/** + * @file Nvodm_Sdio.c + * @brief <b>Sdio odm implementation</b> + * + * @Description : Implementation of the odm sdio API + */ +#include "nvodm_sdio.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvodm_pmu.h" + +#ifdef NV_DRIVER_DEBUG + #define NV_DRIVER_TRACE(x) NvOdmOsDebugPrintf x +#else + #define NV_DRIVER_TRACE(x) +#endif + +#define WLAN_GUID NV_ODM_GUID('s','d','i','o','w','l','a','n') +// Device Board definitions +#define BOARD_ID_E951 (0x0933) /* Decimal 951. => ((9<<8) | 51)*/ + + +typedef enum +{ + NvOdmSdioDiscoveryAddress_0 = 0, + NvOdmSdioDiscoveryAddress_1, + + NvOdmSdioDiscoveryAddress_Force32 = 0x7FFFFFFF, + +} NvOdmSdioDiscoveryAddress; + +typedef struct NvOdmSdioRec +{ + // NvODM PMU device handle + NvOdmServicesPmuHandle hPmu; + // Gpio Handle + NvOdmServicesGpioHandle hGpio; + // Pin handle to Wlan Reset Gpio pin + NvOdmGpioPinHandle hResetPin; + // Pin handle to Wlan PWR GPIO Pin + NvOdmGpioPinHandle hPwrPin; + NvOdmPeripheralConnectivity *pConnectivity; + // Power state + NvBool PoweredOn; + // Instance + NvU32 Instance; +} NvOdmSdio; + +static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, NvBool IsEnable); +static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable); + + +static NvBool SdioOdmWlanSetPowerOn(NvOdmSdioHandle hOdmSdio, NvBool IsEnable) +{ + if (IsEnable) + { + // Wlan Power On Reset Sequence + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x0); //RST -> Low + NvOdmOsWaitUS(2000); + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x1); //PWD -> High + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hResetPin, 0x1); //RST -> High + } + else + { + // Power Off sequence + NvOdmGpioSetState(hOdmSdio->hGpio, hOdmSdio->hPwrPin, 0x0); //PWD -> Low + } + return NV_TRUE; +} + +NvOdmSdioHandle NvOdmSdioOpen(NvU32 Instance) +{ + static NvOdmSdio *pDevice = NULL; + NvOdmServicesGpioHandle hGpioTemp = NULL; + NvOdmPeripheralConnectivity *pConnectivity; + NvU32 NumOfGuids = 1; + NvU64 guid; + NvU32 searchVals[4]; + const NvU32 *pOdmConfigs; + NvU32 NumOdmConfigs; + NvBool Status = NV_TRUE; + const NvOdmPeripheralSearch searchAttrs[] = + { + NvOdmPeripheralSearch_PeripheralClass, + NvOdmPeripheralSearch_IoModule, + NvOdmPeripheralSearch_Instance, + NvOdmPeripheralSearch_Address, + }; + NvOdmBoardInfo BoardInfo; + NvBool status = NV_FALSE; + + searchVals[0] = NvOdmPeripheralClass_Other; + searchVals[1] = NvOdmIoModule_Sdio; + searchVals[2] = Instance; + + NvOdmQueryPinMux(NvOdmIoModule_Sdio, &pOdmConfigs, &NumOdmConfigs); + if ((Instance == 0) && (pOdmConfigs[0] == NvOdmSdioPinMap_Config1)) + { + // sdio is connected to sdio2 slot. + searchVals[3] = NvOdmSdioDiscoveryAddress_1; + } + else + { + // sdio is connected to wifi module. + searchVals[3] = NvOdmSdioDiscoveryAddress_0; + } + + NumOfGuids = NvOdmPeripheralEnumerate(searchAttrs, + searchVals, + 4, + &guid, + NumOfGuids); + + // Get the peripheral connectivity information + pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid); + if (pConnectivity == NULL) + return NULL; + + pDevice = NvOdmOsAlloc(sizeof(NvOdmSdio)); + if(pDevice == NULL) + return (pDevice); + + pDevice->hPmu = NvOdmServicesPmuOpen(); + if(pDevice->hPmu == NULL) + { + NvOdmOsFree(pDevice); + pDevice = NULL; + return (NULL); + } + + if (pConnectivity->Guid == WLAN_GUID) + { + // WARNING: This function *cannot* be called before RmOpen(). + status = NvOdmPeripheralGetBoardInfo((BOARD_ID_E951), &BoardInfo); + if (NV_TRUE != status) + { + // whistler should have E951 Module, if it is not presnt return NULL Handle. + NvOdmServicesPmuClose(pDevice->hPmu); + NvOdmOsFree(pDevice); + pDevice = NULL; + NvOdmOsDebugPrintf(("No E951 Detected")); + return (pDevice); + } + } + + pDevice->pConnectivity = pConnectivity; + NvOdmSetPowerOnSdio(pDevice, NV_TRUE); + + if (pConnectivity->Guid == WLAN_GUID) + { + // Getting the OdmGpio Handle + hGpioTemp = NvOdmGpioOpen(); + if (hGpioTemp == NULL) + { + NvOdmServicesPmuClose(pDevice->hPmu); + NvOdmOsFree(pDevice); + pDevice = NULL; + return (pDevice); + } + + // Search for the Vdd rail and set the proper volage to the rail. + if (pConnectivity->AddressList[1].Interface == NvOdmIoModule_Gpio) + { + // Acquiring Pin Handles for Power Pin + pDevice->hPwrPin= NvOdmGpioAcquirePinHandle(hGpioTemp, + pConnectivity->AddressList[1].Instance, + pConnectivity->AddressList[1].Address); + } + + if (pConnectivity->AddressList[2].Interface == NvOdmIoModule_Gpio) + { + // Acquiring Pin Handles for Reset Pin + pDevice->hResetPin= NvOdmGpioAcquirePinHandle(hGpioTemp, + pConnectivity->AddressList[2].Instance, + pConnectivity->AddressList[2].Address); + } + + // Setting the ON/OFF pin to output mode. + NvOdmGpioConfig(hGpioTemp, pDevice->hPwrPin, NvOdmGpioPinMode_Output); + NvOdmGpioConfig(hGpioTemp, pDevice->hResetPin, NvOdmGpioPinMode_Output); + + // Setting the Output Pin to Low + NvOdmGpioSetState(hGpioTemp, pDevice->hPwrPin, 0x0); + NvOdmGpioSetState(hGpioTemp, pDevice->hResetPin, 0x0); + + pDevice->hGpio = hGpioTemp; + + Status = SdioOdmWlanSetPowerOn(pDevice, NV_TRUE); + if (Status != NV_TRUE) + { + NvOdmServicesPmuClose(pDevice->hPmu); + NvOdmGpioReleasePinHandle(pDevice->hGpio, pDevice->hPwrPin); + NvOdmGpioReleasePinHandle(pDevice->hGpio, pDevice->hResetPin); + NvOdmGpioClose(pDevice->hGpio); + NvOdmOsFree(pDevice); + pDevice = NULL; + return (pDevice); + } + } + pDevice->PoweredOn = NV_TRUE; + pDevice->Instance = Instance; + NV_DRIVER_TRACE(("Open SDIO%d", Instance)); + return pDevice; +} + +void NvOdmSdioClose(NvOdmSdioHandle hOdmSdio) +{ + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + + NV_DRIVER_TRACE(("Close SDIO%d", hOdmSdio->Instance)); + + pConnectivity = hOdmSdio->pConnectivity; + if (pConnectivity->Guid == WLAN_GUID) + { + // Call Turn off power when close is Called + (void)SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE); + + NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hPwrPin); + NvOdmGpioReleasePinHandle(hOdmSdio->hGpio, hOdmSdio->hResetPin); + NvOdmGpioClose(hOdmSdio->hGpio); + } + NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE); + if (hOdmSdio->hPmu != NULL) + { + NvOdmServicesPmuClose(hOdmSdio->hPmu); + } + NvOdmOsFree(hOdmSdio); + hOdmSdio = NULL; +} + +static void NvOdmSetPowerOnSdio(NvOdmSdioHandle pDevice, NvBool IsEnable) +{ + NvU32 Index = 0; + NvOdmServicesPmuVddRailCapabilities RailCaps; + NvU32 SettlingTime = 0; + const NvOdmPeripheralConnectivity *pConnectivity; + + pConnectivity = pDevice->pConnectivity; + if (IsEnable) // Turn on Power + { + // Search for the Vdd rail and set the proper volage to the rail. + for (Index = 0; Index < pConnectivity->NumAddress; ++Index) + { + if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd) + { + NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps); + NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address, + RailCaps.requestMilliVolts, &SettlingTime); + if (SettlingTime) + { + NvOdmOsWaitUS(SettlingTime); + } + } + } + } + else // Shutdown Power + { + // Search for the Vdd rail and power Off the module + for (Index = 0; Index < pConnectivity->NumAddress; ++Index) + { + if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd) + { + NvOdmServicesPmuGetCapabilities(pDevice->hPmu, pConnectivity->AddressList[Index].Address, &RailCaps); + NvOdmServicesPmuSetVoltage(pDevice->hPmu, pConnectivity->AddressList[Index].Address, + ODM_VOLTAGE_OFF, &SettlingTime); + if (SettlingTime) + { + NvOdmOsWaitUS(SettlingTime); + } + } + } + } +} + +NvBool NvOdmSdioSuspend(NvOdmSdioHandle hOdmSdio) +{ + + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + NvBool Status = NV_TRUE; + + if (!hOdmSdio->PoweredOn) + { + NV_DRIVER_TRACE(("SDIO%d already suspended", hOdmSdio->Instance)); + return NV_TRUE; + } + + NV_DRIVER_TRACE(("Suspend SDIO%d", hOdmSdio->Instance)); + NvOdmSetPowerOnSdio(hOdmSdio, NV_FALSE); + + pConnectivity = hOdmSdio->pConnectivity; + if (pConnectivity->Guid == WLAN_GUID) + { + // Turn off power + Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_FALSE); + + } + hOdmSdio->PoweredOn = NV_FALSE; + return Status; + +} + +NvBool NvOdmSdioResume(NvOdmSdioHandle hOdmSdio) +{ + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + NvBool Status = NV_TRUE; + + if (hOdmSdio->PoweredOn) + { + NV_DRIVER_TRACE(("SDIO%d already resumed", hOdmSdio->Instance)); + return NV_TRUE; + } + + NvOdmSetPowerOnSdio(hOdmSdio, NV_TRUE); + + pConnectivity = hOdmSdio->pConnectivity; + if (pConnectivity->Guid == WLAN_GUID) + { + // Turn on power + Status = SdioOdmWlanSetPowerOn(hOdmSdio, NV_TRUE); + } + NV_DRIVER_TRACE(("Resume SDIO%d", hOdmSdio->Instance)); + hOdmSdio->PoweredOn = NV_TRUE; + return Status; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c new file mode 100644 index 000000000000..a3f09ad89c18 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_uart.c @@ -0,0 +1,138 @@ +/* + * 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. + * + */ + +/** + * @file nvodm_uart.c + * @brief <b>Adaptation for uart </b> + * + * @Description : Implementation of the uart adaptation. + */ +#include "nvodm_uart.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvos.h" +#include "nvodm_pmu.h" + +#ifdef NV_DRIVER_DEBUG + #define NV_DRIVER_TRACE NvOsDebugPrintf +#else + #define NV_DRIVER_TRACE (void) +#endif + +typedef struct NvOdmUartRec +{ + // NvODM PMU device handle + NvOdmServicesPmuHandle hPmu; + // Gpio Handle + NvOdmServicesGpioHandle hGpio; + // Pin handle to Bluetooth Reset Gpio pin + NvOdmGpioPinHandle hResetPin; + NvOdmPeripheralConnectivity *pConnectivity; +} NvOdmUart; + +NvOdmUartHandle NvOdmUartOpen(NvU32 Instance) +{ + NvOdmUart *pDevice = NULL; + NvOdmPeripheralConnectivity *pConnectivity; + NvU32 NumOfGuids = 1; + NvU64 guid; + NvU32 searchVals[2]; + const NvOdmPeripheralSearch searchAttrs[] = + { + NvOdmPeripheralSearch_IoModule, + NvOdmPeripheralSearch_Instance, + }; + + searchVals[0] = NvOdmIoModule_Uart; + searchVals[1] = Instance; + + NumOfGuids = NvOdmPeripheralEnumerate( + searchAttrs, + searchVals, + 2, + &guid, + NumOfGuids); + + pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(guid); + if (pConnectivity == NULL) + goto ExitUartOdm; + + pDevice = NvOdmOsAlloc(sizeof(NvOdmUart)); + if(pDevice == NULL) + goto ExitUartOdm; + + pDevice->hPmu = NvOdmServicesPmuOpen(); + if(pDevice->hPmu == NULL) + { + goto ExitUartOdm; + } + + // Switch On UART Interface + + pDevice->pConnectivity = pConnectivity; + + return pDevice; + +ExitUartOdm: + NvOdmOsFree(pDevice); + pDevice = NULL; + + return NULL; +} + +void NvOdmUartClose(NvOdmUartHandle hOdmUart) +{ + + if (hOdmUart) + { + // Switch OFF UART Interface + + if (hOdmUart->hPmu != NULL) + { + NvOdmServicesPmuClose(hOdmUart->hPmu); + } + NvOdmOsFree(hOdmUart); + hOdmUart = NULL; + } +} + +NvBool NvOdmUartSuspend(NvOdmUartHandle hOdmUart) +{ + return NV_FALSE; +} + +NvBool NvOdmUartResume(NvOdmUartHandle hOdmUart) +{ + return NV_FALSE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c new file mode 100644 index 000000000000..5bd21b2bd51b --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/misc/whistler/nvodm_usbulpi.c @@ -0,0 +1,235 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file nvodm_usbulpi.c + * @brief <b>Adaptation for USB ULPI </b> + * + * @Description : Implementation of the USB ULPI adaptation. + */ +#include "nvodm_usbulpi.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvodm_keylist_reserved.h" +#include "nvrm_drf.h" +#include "nvos.h" + +typedef struct NvOdmUsbUlpiRec { + NvU64 CurrentGUID; +} NvOdmUsbUlpi; + +/* ST-Ericsson U3XX modem power control */ +struct ste_u3xx_info { + NvU32 ste_u3xx_uart_port; + NvU32 ste_u3xx_reset_port; + NvU32 ste_u3xx_reset_pin; + NvU32 ste_u3xx_power_port; + NvU32 ste_u3xx_power_pin; + NvU32 ste_u3xx_awr_port; + NvU32 ste_u3xx_awr_pin; + NvU32 ste_u3xx_cwr_port; + NvU32 ste_u3xx_cwr_pin; + NvU32 ste_u3xx_spi_int_port; + NvU32 ste_u3xx_spi_int_pin; + NvU32 ste_u3xx_slave_select_port; + NvU32 ste_u3xx_slave_select_pin; + NvU32 ste_u3xx_slink_instance; +}; + +/* ST-Ericsson U3XX modem control */ +static struct ste_u3xx_info ste_u3xx_info; +static NvOdmServicesGpioHandle ste_u3xx_gpio; +static NvOdmGpioPinHandle ste_u3xx_reset_gpio_pin; +static NvOdmGpioPinHandle ste_u3xx_power_gpio_pin; +static NvOdmGpioPinHandle ste_u3xx_awr_gpio_pin; +static NvOdmGpioPinHandle ste_u3xx_cwr_gpio_pin; + +static int ste_u3xx_query(struct ste_u3xx_info *info) +{ + NvU64 guid = NV_ODM_GUID('e', 'm', 'p', ' ', 'M', '5', '7', '0'); + NvOdmPeripheralConnectivity *pConnectivity; + + /* query odm kit for modem support */ + pConnectivity = + (NvOdmPeripheralConnectivity *) NvOdmPeripheralGetGuid(guid); + if (pConnectivity == NULL) + return -1; + NV_ASSERT(pConnectivity->NumAddress >= 5); + + /* query for uart port */ + NV_ASSERT(pConnectivity->AddressList[0].Interface == + NvOdmIoModule_Uart); + info->ste_u3xx_uart_port = pConnectivity->AddressList[0].Instance; + + /* query for reset pin */ + NV_ASSERT(pConnectivity->AddressList[1].Interface == + NvOdmIoModule_Gpio); + info->ste_u3xx_reset_port = pConnectivity->AddressList[1].Instance; + info->ste_u3xx_reset_pin = pConnectivity->AddressList[1].Address; + + /* query for power pin */ + NV_ASSERT(pConnectivity->AddressList[2].Interface == + NvOdmIoModule_Gpio); + info->ste_u3xx_power_port = pConnectivity->AddressList[2].Instance; + info->ste_u3xx_power_pin = pConnectivity->AddressList[2].Address; + + /* query for ACPU wakeup request pin */ + NV_ASSERT(pConnectivity->AddressList[3].Interface == + NvOdmIoModule_Gpio); + info->ste_u3xx_awr_port = pConnectivity->AddressList[3].Instance; + info->ste_u3xx_awr_pin = pConnectivity->AddressList[3].Address; + + /* query for CCPU wakeup request pin */ + NV_ASSERT(pConnectivity->AddressList[4].Interface == + NvOdmIoModule_Gpio); + info->ste_u3xx_cwr_port = pConnectivity->AddressList[4].Instance; + info->ste_u3xx_cwr_pin = pConnectivity->AddressList[4].Address; + + return 0; +} + +static void ste_u3xx_turn_on_modem(struct ste_u3xx_info *info) +{ + /* get odm gpio handle */ + ste_u3xx_gpio = NvOdmGpioOpen(); + if (!ste_u3xx_gpio) + return; + + /* acquire pin handle for reset pin */ + ste_u3xx_reset_gpio_pin = + NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_reset_port, + info->ste_u3xx_reset_pin); + if (!ste_u3xx_reset_gpio_pin) { + NvOdmGpioClose(ste_u3xx_gpio); + return; + } + + /* acquire pin handle for power pin */ + ste_u3xx_power_gpio_pin = + NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_power_port, + info->ste_u3xx_power_pin); + if (!ste_u3xx_power_gpio_pin) { + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, + ste_u3xx_reset_gpio_pin); + NvOdmGpioClose(ste_u3xx_gpio); + return; + } + + /* acquire pin handle for ACPU wakeup request pin */ + ste_u3xx_awr_gpio_pin = + NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_awr_port, + info->ste_u3xx_awr_pin); + if (!ste_u3xx_awr_gpio_pin) { + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, + ste_u3xx_power_gpio_pin); + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, + ste_u3xx_reset_gpio_pin); + NvOdmGpioClose(ste_u3xx_gpio); + return; + } + + /* acquire pin handle for CCPU wakeup request pin */ + ste_u3xx_cwr_gpio_pin = + NvOdmGpioAcquirePinHandle(ste_u3xx_gpio, info->ste_u3xx_cwr_port, + info->ste_u3xx_cwr_pin); + if (!ste_u3xx_cwr_gpio_pin) { + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_awr_gpio_pin); + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, + ste_u3xx_power_gpio_pin); + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, + ste_u3xx_reset_gpio_pin); + NvOdmGpioClose(ste_u3xx_gpio); + return; + } + + /* set output levels - start with modem power off, reset deasserted */ + NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, 0); + NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin, 0); + NvOdmGpioConfig(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, + NvOdmGpioPinMode_Output); + NvOdmGpioConfig(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin, + NvOdmGpioPinMode_Output); + NvOdmGpioConfig(ste_u3xx_gpio, ste_u3xx_cwr_gpio_pin, + NvOdmGpioPinMode_InputData); + + NvOdmOsSleepMS(300); + NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin, 1); + + /* pulse modem power on for 300 ms */ + NvOdmOsSleepMS(300); + NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, 1); + NvOdmOsSleepMS(300); + NvOdmGpioSetState(ste_u3xx_gpio, ste_u3xx_power_gpio_pin, 0); + NvOdmOsSleepMS(100); + + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_cwr_gpio_pin); + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_awr_gpio_pin); + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_power_gpio_pin); + NvOdmGpioReleasePinHandle(ste_u3xx_gpio, ste_u3xx_reset_gpio_pin); + NvOdmGpioClose(ste_u3xx_gpio); +} + +NvOdmUsbUlpiHandle NvOdmUsbUlpiOpen(NvU32 Instance) +{ + const NvOdmUsbProperty *pUsbProperty = + NvOdmQueryGetUsbProperty(NvOdmIoModule_Usb, Instance); + NvOdmUsbUlpi *pDevice = NULL; + + pDevice = NvOdmOsAlloc(sizeof(NvOdmUsbUlpi)); + if (pDevice == NULL) + goto ExitUlpiOdm; + + if (pUsbProperty->UsbInterfaceType == + NvOdmUsbInterfaceType_UlpiNullPhy) { + /* query the modem control pins */ + if (ste_u3xx_query(&ste_u3xx_info) < 0) + goto ExitUlpiOdm; + + NvOsDebugPrintf("turn modem on\n"); + ste_u3xx_turn_on_modem(&ste_u3xx_info); + } + return pDevice; + +ExitUlpiOdm: + if (pDevice) + NvOdmOsFree(pDevice); + return NULL; +} + +void NvOdmUsbUlpiClose(NvOdmUsbUlpiHandle hOdmUlpi) +{ + if (hOdmUlpi) { + NvOdmOsFree(hOdmUlpi); + hOdmUlpi = NULL; + } +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile new file mode 100644 index 000000000000..b19449bd3cfa --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/Makefile @@ -0,0 +1,18 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626 +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x + +obj-y += pmu_hal.o +obj-y += max8907b/ +obj-y += pcf50626/ +obj-y += tps6586x/ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile new file mode 100644 index 000000000000..321377d9317f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile @@ -0,0 +1,22 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b + +obj-y += ad5258_dpm.o +obj-y += fan5355_buck_i2c.o +obj-y += max8907b_adc.o +obj-y += max8907b_batterycharger.o +obj-y += max8907b.o +obj-y += max8907b_i2c.o +obj-y += max8907b_interrupt.o +obj-y += max8907b_rtc.o +obj-y += mic2826_i2c.o +obj-y += tca6416_expander_i2c.o diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c new file mode 100644 index 000000000000..7f785f920afc --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 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 "nvodm_pmu.h" +#include "nvodm_services.h" +#include "ad5258_dpm.h" + + +static NvBool +Ad5258I2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU32 i; + NvU8 WriteBuffer[2]; + NvOdmI2cTransactionInfo TransactionInfo; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + + for (i = 0; i < AD5258_I2C_RETRY_CNT; i++) + { + WriteBuffer[0] = Addr & 0xFF; // AD5258 address + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = AD5258_SLAVE_ADDR; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + AD5258_I2C_SPEED_KHZ, AD5258_I2C_TIMEOUT_MS); + if (status == NvOdmI2cStatus_Success) + return NV_TRUE; + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmDpmI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmDpmI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +static NvBool +Ad5258I2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data) +{ + NvU32 i; + NvU8 ReadBuffer = 0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + for (i = 0; i < AD5258_I2C_RETRY_CNT; i++) + { + // The AD5258 register address + ReadBuffer = Addr & 0xFF; + + TransactionInfo[0].Address = AD5258_SLAVE_ADDR; + TransactionInfo[0].Buf = &ReadBuffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + + TransactionInfo[1].Address = (AD5258_SLAVE_ADDR | 0x1);; + TransactionInfo[1].Buf = &ReadBuffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + // Read data from PMU at the specified offset + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2, + AD5258_I2C_SPEED_KHZ, AD5258_I2C_TIMEOUT_MS); + if (status == NvOdmI2cStatus_Success) + { + *Data = ReadBuffer; + return NV_TRUE; + } + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmDpmI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmDpmI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool +Ad5258I2cSetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 MilliVolts) +{ + static NvU32 s_LastMilliVolts = 0; + + NvU8 Data = 0; + NvU8 Addr = AD5258_RDAC_ADDR; + + if (s_LastMilliVolts == 0) + { + if (!Ad5258I2cGetVoltage(hDevice, &s_LastMilliVolts)) + return NV_FALSE; + NV_ASSERT((s_LastMilliVolts >= AD5258_V0) && + (s_LastMilliVolts <= AD5258_VMAX)); + } + + // Change voltage level one maximum allowed step at a time + while (s_LastMilliVolts != MilliVolts) + { + if (MilliVolts > s_LastMilliVolts + AD5258_MAX_STEP_MV) + s_LastMilliVolts += AD5258_MAX_STEP_MV; + else if (MilliVolts + AD5258_MAX_STEP_MV < s_LastMilliVolts) + s_LastMilliVolts -= AD5258_MAX_STEP_MV; + else + s_LastMilliVolts = MilliVolts; + + // D(Vout) = (Vout - V0) * M1 / 2^b + Data = 0; + if (s_LastMilliVolts > AD5258_V0) + { + Data = (NvU8)(((s_LastMilliVolts - AD5258_V0) * AD5258_M1 + + (0x1 << (AD5258_b - 1))) >> AD5258_b); + Data++; // account for load + } + NV_ASSERT(Data <= AD5258_RDAC_MASK); + if (!Ad5258I2cWrite8(hDevice, Addr, Data)) + return NV_FALSE; + NvOdmOsWaitUS(AD5258_MAX_STEP_SETTLE_TIME_US); + } + return NV_TRUE; +} + +NvBool +Ad5258I2cGetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32* pMilliVolts) +{ + NvU8 Data = 0; + NvU8 Addr = AD5258_RDAC_ADDR; + + if (!Ad5258I2cRead8(hDevice, Addr, &Data)) + return NV_FALSE; + + // Vout(D) = V0 + (D * M2) / 2^b + Data &= AD5258_RDAC_MASK; + *pMilliVolts = AD5258_V0 + + (((NvU32)Data * AD5258_M2 + (0x1 << (AD5258_b - 1))) >> AD5258_b); + + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h new file mode 100644 index 000000000000..8bfd23eecf59 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h @@ -0,0 +1,92 @@ +/* + * Copyright (c) 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_AD5258_DPM_I2C_H +#define INCLUDED_AD5258_DPM_I2C_H + +#include "nvodm_pmu.h" +#include "max8907b.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define AD5258_SLAVE_ADDR (0x9C) // (7'h4E) +#define AD5258_I2C_SPEED_KHZ (400) +#define AD5258_I2C_RETRY_CNT (2) +#define AD5258_I2C_TIMEOUT_MS (1000) + +#define AD5258_RDAC_ADDR (0x0) +#define AD5258_RDAC_MASK (0x3F) + +/* + * Linear approximation of digital potentiometer (DPM) scaling ladder: + * D(Vout) = (Vout - V0) * M1 / 2^b + * Vout(D) = V0 + (D * M2) / 2^b + * D - DPM setting, Vout - output voltage in mV, b - fixed point calculation + * precision, approximation parameters V0, M1, M2 are determined for the + * particular schematic combining constant resistors, DPM, and DCDC supply. + */ +// On Whistler: +#define AD5258_V0 (815) +#define AD5258_M1 (229) +#define AD5258_M2 (4571) +#define AD5258_b (10) + +#define AD5258_VMAX (AD5258_V0 + ((AD5258_RDAC_MASK * AD5258_M2 + \ + (0x1 << (AD5258_b - 1))) >> AD5258_b)) + +// Minimum voltage step is determined by DPM resolution, maximum voltage step +// is limited to keep dynamic over/under shoot within +/- 50mV +#define AD5258_MIN_STEP_MV ((AD5258_M2 + (0x1 << AD5258_b) - 1) >> AD5258_b) +#define AD5258_MAX_STEP_MV (50) +#define AD5258_MAX_STEP_SETTLE_TIME_US (20) +#define AD5258_TURN_ON_TIME_US (2000) + +NvBool +Ad5258I2cSetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 MilliVolts); + +NvBool +Ad5258I2cGetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32* pMilliVolts); + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_AD5258_DPM_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c new file mode 100644 index 000000000000..bb00b0bbab1f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 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 "nvodm_pmu.h" +#include "nvodm_services.h" +#include "fan5355_buck_i2c.h" +#include "fan5355_buck_reg.h" + +// Function declaration +NvBool Fan5355I2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cTransactionInfo TransactionInfo; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + + WriteBuffer[0] = Addr & 0xFF; // PMU offset + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = FAN5335_SLAVE_ADDR; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + FAN5335_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool Fan5355I2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data) +{ + NvU8 ReadBuffer = 0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + // Write the PMU offset + ReadBuffer = Addr & 0xFF; + + TransactionInfo[0].Address = FAN5335_SLAVE_ADDR; + TransactionInfo[0].Buf = &ReadBuffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + + TransactionInfo[1].Address = (FAN5335_SLAVE_ADDR | 0x1);; + TransactionInfo[1].Buf = &ReadBuffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + // Read data from PMU at the specified offset + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2, + FAN5335_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = ReadBuffer; + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h new file mode 100644 index 000000000000..7df90a192769 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 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_FAN5355_BUCK_I2C_H +#define INCLUDED_FAN5355_BUCK_I2C_H + +#include "nvodm_pmu.h" +#include "max8907b.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define FAN5335_SLAVE_ADDR 0x94 // (7'h4A) +#define FAN5335_I2C_SPEED_KHZ 400 + +NvBool Fan5355I2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data); + +NvBool Fan5355I2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data); + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_FAN5355_BUCK_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h new file mode 100644 index 000000000000..104be89ac462 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 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_FAN5355_BUCK_REG_HEADER +#define INCLUDED_FAN5355_BUCK_REG_HEADER + +// Registers + +/* field defines for register bit ops */ + +#define FAN5335_VSEL0 0x0 +#define FAN5335_VSEL1 0x1 +#define FAN5335_CONTROL1 0x2 +#define FAN5335_CONTROL2 0x3 + +#define FAN5335_REG_INVALID 0xFF + +#endif //INCLUDED_FAN5355_BUCK_REG_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c new file mode 100644 index 000000000000..285044034f97 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c @@ -0,0 +1,2324 @@ +/* + * Copyright (c) 2007-2010 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 "nvodm_query_discovery.h" +#include "nvodm_query.h" +#include "nvodm_services.h" +#include "max8907b.h" +#include "max8907b_reg.h" +#include "max8907b_adc.h" +#include "max8907b_i2c.h" +#include "max8907b_interrupt.h" +#include "max8907b_batterycharger.h" +#include "max8907b_supply_info_table.h" +#include "fan5355_buck_reg.h" +#include "fan5355_buck_i2c.h" +#include "tca6416_expander_reg.h" +#include "tca6416_expander_i2c.h" +#include "mic2826_reg.h" +#include "mic2826_i2c.h" +#include "ad5258_dpm.h" + +// Private PMU context info +Max8907bPrivData *hMax8907bPmu; + +#define PMUGUID NV_ODM_GUID('m','a','x','8','9','0','7','b') + +#define MAX_CHARGER_LIMIT_MA 1000 + +#define ALWAYS_ONLINE (1) + +/** + * MAX8907B regulators can be enabled/disabled via s/w I2C commands only + * when MAX8907B_SEQSEL_I2CEN_LXX (7) is selected as regulator sequencer. + * Otherwise, regulator is controlled by h/w sequencers: SEQ1 (SYSEN), + * which is always On when PMU is On, or SEQ2 (PWREN) which is always On, + * when system is running (it is Off in LPx mode only). + */ +#define MAX8907B_OUT_VOLTAGE_CONTROL_MASK \ + ((MAX8907B_CTL_SEQ_MASK << MAX8907B_CTL_SEQ_SHIFT) | \ + MAX8907B_OUT_VOLTAGE_ENABLE_BIT) + +#define MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE \ + (MAX8907B_SEQSEL_I2CEN_LXX << MAX8907B_CTL_SEQ_SHIFT) + +// MAX8907B revision that requires s/w WAR to connect PWREN input to +// sequencer 2 because of the bug in the silicon. +#define MAX8907B_II2RR_PWREN_WAR (0x12) + +/** +* The FAN5355 is used to scale the voltage of an external +* DC/DC voltage rail (for PCIE). However, voltage scaling is +* not required for this source, since the 1.05V default +* voltage when enabled is OK. On some boards, the FAN5355 may +* not function properly, as an I2C re-work may be required +* (otherwise, the slave address may not be found). Therefore, +* this feature is disabled by default. +*/ +#undef MAX8907B_USE_FAN5355_VOLTAGE_SCALING + +/*-- Output Voltage tables --*/ + +// V1, V2 (millivolts x 10) +static const NvU32 VoltageTable_SD_A[] = { + 6375, 6500, 6625, 6750, 6875, 7000, 7125, 7250, + 7375, 7500, 7625, 7750, 7875, 8000, 8125, 8250, + 8375, 8500, 8625, 8750, 8875, 9000, 9125, 9250, + 9375, 9500, 9625, 9750, 9875, 10000, 10125, 10250, + 10375, 10500, 10625, 10750, 10875, 11000, 11125, 11250, + 11375, 11500, 11625, 11750, 11875, 12000, 12125, 12250, + 12375, 12500, 12625, 12750, 12875, 13000, 13125, 13250, + 13375, 13500, 13625, 13750, 13875, 14000, 14125, 14250 +}; + +// V3, LDO1, LDO4-LDO16, LDO19-20 (millivolts) +static const NvU32 VoltageTable_SD_B_LDO_B[] = { + 750, 800, 850, 900, 950, 1000, 1050, 1100, + 1150, 1200, 1250, 1300, 1350, 1400, 1450, 1500, + 1550, 1600, 1650, 1700, 1750, 1800, 1850, 1900, + 1950, 2000, 2050, 2100, 2150, 2200, 2250, 2300, + 2350, 2400, 2450, 2500, 2550, 2600, 2650, 2700, + 2750, 2800, 2850, 2900, 2950, 3000, 3050, 3100, + 3150, 3200, 3250, 3300, 3350, 3400, 3450, 3500, + 3550, 3600, 3650, 3700, 3750, 3800, 3850, 3900 +}; + +// LDO2, LDO3, LDO17, LDO18 (millivolts) +static const NvU32 VoltageTable_LDO_A[] = { + 650, 675, 700, 725, 750, 775, 800, 825, + 850, 875, 900, 925, 950, 975, 1000, 1025, + 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1225, + 1250, 1275, 1300, 1325, 1350, 1375, 1400, 1425, + 1450, 1475, 1500, 1525, 1550, 1575, 1600, 1625, + 1650, 1675, 1700, 1725, 1750, 1775, 1800, 1825, + 1850, 1875, 1900, 1925, 1950, 1975, 2000, 2025, + 2050, 2075, 2100, 2125, 2150, 2175, 2200, 2225 +}; + +// FAN5355 VOUT_02 (millivolts x 10) +static const NvU32 VoltageTable_VOUT_02[] = { + 7500, 7625, 7750, 7875, 8000, 8125, 8250, 8375, + 8500, 8625, 8750, 8875, 9000, 9125, 9250, 9375, + 9500, 9625, 9750, 9875, 10000, 10125, 10250, 10375, + 10500, 10625, 10750, 10875, 11000, 11125, 11250, 11375, + 11500, 11625, 11750, 11875, 12000, 12125, 12250, 12375, + 12500, 12625, 12750, 12875, 13000, 13125, 13250, 13375, + 13500, 13625, 13750, 13875, 14000, 14125, 14250, 14375, +}; + +/*-- Sequencer table --*/ + +// Timer period, microseconds (us). +// Specifies the time between each sequencer event. + +// Disable temporarily to keep the compiler happy. +//static const NvU32 SequencerPeriod[] = { 20, 40, 80, 160, 320, 640, 1280, 2560 }; + +/*-- Voltage translation functions --*/ + +// OutVoltageIndex is the lower six bits of the output voltage registers, VO[5:0] +static NvU32 Max8907bPmuVoltageGet_SD_A(const NvU32 OutVoltageIndex); +static NvU32 Max8907bPmuVoltageGet_SD_B_LDO_B(const NvU32 OutVoltageIndex); +static NvU32 Max8907bPmuVoltageGet_LDO_A(const NvU32 OutVoltageIndex); + +static NvU32 Max8907bPmuVoltageSet_SD_A(const NvU32 OutMilliVolts); +static NvU32 Max8907bPmuVoltageSet_SD_B_LDO_B(const NvU32 OutMilliVolts); +static NvU32 Max8907bPmuVoltageSet_LDO_A(const NvU32 OutMilliVolts); + +#define MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX 0x3F +#define FAN5355_MAX_OUTPUT_VOLTAGE_INDEX 0x37 + +static NvU32 Max8907bPmuVoltageGet_SD_A(const NvU32 OutVoltageIndex) +{ + NV_ASSERT(OutVoltageIndex <= MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX); + return VoltageTable_SD_A[OutVoltageIndex]/10; +} + +static NvU32 Max8907bPmuVoltageGet_SD_B_LDO_B(const NvU32 OutVoltageIndex) +{ + NV_ASSERT(OutVoltageIndex <= MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX); + return VoltageTable_SD_B_LDO_B[OutVoltageIndex]; +} + +static NvU32 Max8907bPmuVoltageGet_LDO_A(const NvU32 OutVoltageIndex) +{ + NV_ASSERT(OutVoltageIndex <= MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX); + return VoltageTable_LDO_A[OutVoltageIndex]; +} + +// Secondary PMU MIC2826 API +static NvBool MIC2826ReadVoltageReg(NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, NvU32* pMilliVolts); + +static NvBool MIC2826WriteVoltageReg( NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, NvU32 MilliVolts, NvU32* pSettleMicroSeconds); + +const NvU8 MIC2826_BUCK_Votage_Table[] = +{ + MIC2826_BUCK_OUT_VOLTAGE_0800, + MIC2826_BUCK_OUT_VOLTAGE_0825, + MIC2826_BUCK_OUT_VOLTAGE_0850, + MIC2826_BUCK_OUT_VOLTAGE_0875, + MIC2826_BUCK_OUT_VOLTAGE_0900, + MIC2826_BUCK_OUT_VOLTAGE_0925, + MIC2826_BUCK_OUT_VOLTAGE_0950, + MIC2826_BUCK_OUT_VOLTAGE_0975, + MIC2826_BUCK_OUT_VOLTAGE_1000, + MIC2826_BUCK_OUT_VOLTAGE_1025, + MIC2826_BUCK_OUT_VOLTAGE_1050, + MIC2826_BUCK_OUT_VOLTAGE_1075, + MIC2826_BUCK_OUT_VOLTAGE_1100, + MIC2826_BUCK_OUT_VOLTAGE_1125, + MIC2826_BUCK_OUT_VOLTAGE_1150, + MIC2826_BUCK_OUT_VOLTAGE_1175, + MIC2826_BUCK_OUT_VOLTAGE_1200, + MIC2826_BUCK_OUT_VOLTAGE_1250, + MIC2826_BUCK_OUT_VOLTAGE_1300, + MIC2826_BUCK_OUT_VOLTAGE_1350, + MIC2826_BUCK_OUT_VOLTAGE_1400, + MIC2826_BUCK_OUT_VOLTAGE_1450, + MIC2826_BUCK_OUT_VOLTAGE_1500, + MIC2826_BUCK_OUT_VOLTAGE_1550, + MIC2826_BUCK_OUT_VOLTAGE_1600, + MIC2826_BUCK_OUT_VOLTAGE_1650, + MIC2826_BUCK_OUT_VOLTAGE_1700, + MIC2826_BUCK_OUT_VOLTAGE_1750, + MIC2826_BUCK_OUT_VOLTAGE_1800 +}; + +const NvU8 MIC2826_LDO_Votage_Table[] = +{ + MIC2826_LDO_OUT_VOLTAGE_0800, + MIC2826_LDO_OUT_VOLTAGE_0850, + MIC2826_LDO_OUT_VOLTAGE_0900, + MIC2826_LDO_OUT_VOLTAGE_0950, + MIC2826_LDO_OUT_VOLTAGE_1000, + MIC2826_LDO_OUT_VOLTAGE_1050, + MIC2826_LDO_OUT_VOLTAGE_1100, + MIC2826_LDO_OUT_VOLTAGE_1150, + MIC2826_LDO_OUT_VOLTAGE_1200, + MIC2826_LDO_OUT_VOLTAGE_1250, + MIC2826_LDO_OUT_VOLTAGE_1300, + MIC2826_LDO_OUT_VOLTAGE_1350, + MIC2826_LDO_OUT_VOLTAGE_1400, + MIC2826_LDO_OUT_VOLTAGE_1450, + MIC2826_LDO_OUT_VOLTAGE_1500, + MIC2826_LDO_OUT_VOLTAGE_1550, + MIC2826_LDO_OUT_VOLTAGE_1600, + MIC2826_LDO_OUT_VOLTAGE_1650, + MIC2826_LDO_OUT_VOLTAGE_1700, + MIC2826_LDO_OUT_VOLTAGE_1750, + MIC2826_LDO_OUT_VOLTAGE_1800, + MIC2826_LDO_OUT_VOLTAGE_1850, + MIC2826_LDO_OUT_VOLTAGE_1900, + MIC2826_LDO_OUT_VOLTAGE_1950, + MIC2826_LDO_OUT_VOLTAGE_2000, + MIC2826_LDO_OUT_VOLTAGE_2050, + MIC2826_LDO_OUT_VOLTAGE_2100, + MIC2826_LDO_OUT_VOLTAGE_2150, + MIC2826_LDO_OUT_VOLTAGE_2200, + MIC2826_LDO_OUT_VOLTAGE_2250, + MIC2826_LDO_OUT_VOLTAGE_2300, + MIC2826_LDO_OUT_VOLTAGE_2350, + MIC2826_LDO_OUT_VOLTAGE_2400, + MIC2826_LDO_OUT_VOLTAGE_2450, + MIC2826_LDO_OUT_VOLTAGE_2500, + MIC2826_LDO_OUT_VOLTAGE_2550, + MIC2826_LDO_OUT_VOLTAGE_2600, + MIC2826_LDO_OUT_VOLTAGE_2650, + MIC2826_LDO_OUT_VOLTAGE_2700, + MIC2826_LDO_OUT_VOLTAGE_2750, + MIC2826_LDO_OUT_VOLTAGE_2800, + MIC2826_LDO_OUT_VOLTAGE_2850, + MIC2826_LDO_OUT_VOLTAGE_2900, + MIC2826_LDO_OUT_VOLTAGE_2950, + MIC2826_LDO_OUT_VOLTAGE_3000, + MIC2826_LDO_OUT_VOLTAGE_3050, + MIC2826_LDO_OUT_VOLTAGE_3100, + MIC2826_LDO_OUT_VOLTAGE_3150, + MIC2826_LDO_OUT_VOLTAGE_3200, + MIC2826_LDO_OUT_VOLTAGE_3250, + MIC2826_LDO_OUT_VOLTAGE_3300 +}; + +#define MIC2826_BUCK_Votage_Table_Size NV_ARRAY_SIZE(MIC2826_BUCK_Votage_Table) +#define MIC2826_LDO_Votage_Table_Size NV_ARRAY_SIZE(MIC2826_LDO_Votage_Table) + +#ifndef MIN +#define MIN(a, b) (a) <= (b) ? (a) : (b) +#endif + +#define MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10 6375 // 637.5 mV +#define MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B 750 // 750 mV +#define MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A 650 // 650 mV +#define FAN5355_MIN_OUTPUT_VOLTAGE_x10 7500 // 750.0 mV + +#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10 125 // 12.5 mV +#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B 50 // 50 mV +#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A 25 // 25 mV +#define FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10 125 // 12.5 mV + +#define MAX8907B_MAX_OUTPUT_VOLTAGE_SD_A_x10 14250 // 1,425.0 mV +#define MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B 3900 // 3,900 mV +#define MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A 2225 // 2,225 mV +#define FAN5355_MAX_OUTPUT_VOLTAGE_x10 14375 // 1,437.5 mV + +#define MAX8907B_MIN_OUTPUT_VOLTAGE_RTC 0 // 0 mV +#define MAX8907B_OUTPUT_VOLTAGE_INCREMENT_RTC 1 // Protected; use dummy, non-zero value +//#define MAX8907B_MAX_OUTPUT_VOLTAGE_RTC 3300 // 3,300 mV +// WHISTLER/AP16 - Make this 1.2V for now, since ap15rm_power.c expects it that way. +#define MAX8907B_MAX_OUTPUT_VOLTAGE_RTC 1200 + +static NvU32 Max8907bPmuVoltageSet_SD_A(const NvU32 OutMilliVolts) +{ + if (OutMilliVolts < MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10/10) + return 0; + else + return MIN( \ + (OutMilliVolts*10 - MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10) / \ + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10, \ + MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX); +} + +static NvU32 Max8907bPmuVoltageSet_SD_B_LDO_B(const NvU32 OutMilliVolts) +{ + if (OutMilliVolts < MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B) + return 0; + else + return MIN( \ + (OutMilliVolts - MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B) / \ + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, \ + MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX); +} + +static NvU32 Max8907bPmuVoltageSet_LDO_A(const NvU32 OutMilliVolts) +{ + if (OutMilliVolts < MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A) + return 0; + else + return MIN( \ + (OutMilliVolts - MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A) / \ + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A, \ + MAX8907B_MAX_OUTPUT_VOLTAGE_INDEX); +} + +static NvU32 Fan5355PmuVoltageGet_VOUT_02(const NvU32 OutVoltageIndex) +{ + NV_ASSERT(OutVoltageIndex <= FAN5355_MAX_OUTPUT_VOLTAGE_INDEX); + return VoltageTable_VOUT_02[OutVoltageIndex]/10; +} + +static NvU32 Fan5355PmuVoltageSet_VOUT_02(const NvU32 OutMilliVolts) +{ + if (OutMilliVolts < FAN5355_MIN_OUTPUT_VOLTAGE_x10/10) + return 0; + else + return MIN( \ + (OutMilliVolts*10 - FAN5355_MIN_OUTPUT_VOLTAGE_x10) / \ + FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10, \ + FAN5355_MAX_OUTPUT_VOLTAGE_x10); +} + +// This board-specific table is indexed by Max8907bPmuSupply +const Max8907bPmuSupplyInfo Max8907bSupplyInfoTable[] = +{ + { + Max8907bPmuSupply_Invalid, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + {NV_TRUE, 0, 0, 0, 0}, + }, + + // LX_V1 (V1) + { + Max8907bPmuSupply_LX_V1, + MAX8907B_SDCTL1, + MAX8907B_SDSEQCNT1, + MAX8907B_SDV1, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_A, + Max8907bPmuVoltageSet_SD_A, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10/10, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10/10, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_A_x10/10, + MAX8907B_REQUESTVOLTAGE_LX_V1 + }, + }, + + // LX_V2 (V2) + { + Max8907bPmuSupply_LX_V2, + MAX8907B_SDCTL2, + MAX8907B_SDSEQCNT2, + MAX8907B_SDV2, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_A, + Max8907bPmuVoltageSet_SD_A, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_A_x10/10, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_A_x10/10, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_A_x10/10, + MAX8907B_REQUESTVOLTAGE_LX_V2 + }, + }, + + // LX_V3 (V3) + { + Max8907bPmuSupply_LX_V3, + MAX8907B_SDCTL3, + MAX8907B_SDSEQCNT3, + MAX8907B_SDV3, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LX_V3 + }, + }, + + // VRTC (RTC) + { + Max8907bPmuSupply_VRTC, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + { + NV_TRUE, + MAX8907B_MIN_OUTPUT_VOLTAGE_RTC, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_RTC, + MAX8907B_MAX_OUTPUT_VOLTAGE_RTC, + MAX8907B_MAX_OUTPUT_VOLTAGE_RTC + }, + }, + + // LDO1 (VOUT1) + { + Max8907bPmuSupply_LDO1, + MAX8907B_LDOCTL1, + MAX8907B_LDOSEQCNT1, + MAX8907B_LDO1VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO1 + }, + }, + + // LDO2 (VOUT2) + { + Max8907bPmuSupply_LDO2, + MAX8907B_LDOCTL2, + MAX8907B_LDOSEQCNT2, + MAX8907B_LDO2VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_LDO_A, + Max8907bPmuVoltageSet_LDO_A, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A, + MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_REQUESTVOLTAGE_LDO2 + }, + }, + + // LDO3 (VOUT3) + { + Max8907bPmuSupply_LDO3, + MAX8907B_LDOCTL3, + MAX8907B_LDOSEQCNT3, + MAX8907B_LDO3VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_LDO_A, + Max8907bPmuVoltageSet_LDO_A, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A, + MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_REQUESTVOLTAGE_LDO3 + }, + }, + + // LDO4 (VOUT4) + { + Max8907bPmuSupply_LDO4, + MAX8907B_LDOCTL4, + MAX8907B_LDOSEQCNT4, + MAX8907B_LDO4VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO4 + }, + }, + + // LDO5 (VOUT5) + { + Max8907bPmuSupply_LDO5, + MAX8907B_LDOCTL5, + MAX8907B_LDOSEQCNT5, + MAX8907B_LDO5VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO5 + }, + }, + + // LDO6 (VOUT6) + { + Max8907bPmuSupply_LDO6, + MAX8907B_LDOCTL6, + MAX8907B_LDOSEQCNT6, + MAX8907B_LDO6VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO6 + }, + }, + + // LDO7 (VOUT7) + { + Max8907bPmuSupply_LDO7, + MAX8907B_LDOCTL7, + MAX8907B_LDOSEQCNT7, + MAX8907B_LDO7VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO7 + }, + }, + + // LDO8 (VOUT8) + { + Max8907bPmuSupply_LDO8, + MAX8907B_LDOCTL8, + MAX8907B_LDOSEQCNT8, + MAX8907B_LDO8VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO8 + }, + }, + + // LDO9 (VOUT9) + { + Max8907bPmuSupply_LDO9, + MAX8907B_LDOCTL9, + MAX8907B_LDOSEQCNT9, + MAX8907B_LDO9VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO9 + }, + }, + + // LDO10 (VOUT10) + { + Max8907bPmuSupply_LDO10, + MAX8907B_LDOCTL10, + MAX8907B_LDOSEQCNT10, + MAX8907B_LDO10VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO10 + }, + }, + + // LDO11 (VOUT11) + { + Max8907bPmuSupply_LDO11, + MAX8907B_LDOCTL11, + MAX8907B_LDOSEQCNT11, + MAX8907B_LDO11VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO11 + }, + }, + + // LDO12 (VOUT12) + { + Max8907bPmuSupply_LDO12, + MAX8907B_LDOCTL12, + MAX8907B_LDOSEQCNT12, + MAX8907B_LDO12VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO12 + }, + }, + + // LDO13 (VOUT13) + { + Max8907bPmuSupply_LDO13, + MAX8907B_LDOCTL13, + MAX8907B_LDOSEQCNT13, + MAX8907B_LDO13VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO13 + }, + }, + + // LDO14 (VOUT14) + { + Max8907bPmuSupply_LDO14, + MAX8907B_LDOCTL14, + MAX8907B_LDOSEQCNT14, + MAX8907B_LDO14VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO14 + }, + }, + + // LDO15 (VOUT15) + { + Max8907bPmuSupply_LDO15, + MAX8907B_LDOCTL15, + MAX8907B_LDOSEQCNT15, + MAX8907B_LDO15VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO15 + }, + }, + + // LDO16 (VOUT16) + { + Max8907bPmuSupply_LDO16, + MAX8907B_LDOCTL16, + MAX8907B_LDOSEQCNT16, + MAX8907B_LDO16VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO16 + }, + }, + + // LDO17 (VOUT17) + { + Max8907bPmuSupply_LDO17, + MAX8907B_LDOCTL17, + MAX8907B_LDOSEQCNT17, + MAX8907B_LDO17VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_LDO_A, + Max8907bPmuVoltageSet_LDO_A, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A, + MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_REQUESTVOLTAGE_LDO17 + }, + }, + + // LDO18 (VOUT18) + { + Max8907bPmuSupply_LDO18, + MAX8907B_LDOCTL18, + MAX8907B_LDOSEQCNT18, + MAX8907B_LDO18VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_LDO_A, + Max8907bPmuVoltageSet_LDO_A, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_LDO_A, + MAX8907B_MAX_OUTPUT_VOLTAGE_LDO_A, + MAX8907B_REQUESTVOLTAGE_LDO18 + }, + }, + + // LDO19 (VOUT19) + { + Max8907bPmuSupply_LDO19, + MAX8907B_LDOCTL19, + MAX8907B_LDOSEQCNT19, + MAX8907B_LDO19VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO19 + }, + }, + + // LDO20 (VOUT20) + { + Max8907bPmuSupply_LDO20, + MAX8907B_LDOCTL20, + MAX8907B_LDOSEQCNT20, + MAX8907B_LDO20VOUT, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + Max8907bPmuVoltageGet_SD_B_LDO_B, + Max8907bPmuVoltageSet_SD_B_LDO_B, + { + NV_FALSE, + MAX8907B_MIN_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_OUTPUT_VOLTAGE_INCREMENT_SD_B_LDO_B, + MAX8907B_MAX_OUTPUT_VOLTAGE_SD_B_LDO_B, + MAX8907B_REQUESTVOLTAGE_LDO20 + }, + }, + + // WHITE_LED + { + Max8907bPmuSupply_WHITE_LED, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + {NV_TRUE, 0, 0, 0, 0}, + }, + + // EXT_DC/DC1 (for HDMI, VGA, USB) + // By default, this is hard-wired as "always on" (see schematics) + { + Max8907bPmuSupply_EXT_DCDC_1, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + { + NV_TRUE, + MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1, + 0, + MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1, + MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1 + }, + }, + + // EXT_DC/DC2 (not connected / reserved) + { + Max8907bPmuSupply_EXT_DCDC_2, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + {NV_TRUE, 0, 0, 0, 0}, + }, + + // EXT_DC/DC3 (PCI Express) + { + Max8907bPmuSupply_EXT_DCDC_3, + TCA6416_CONFIG_PORT_0, + MAX8907B_REG_INVALID, + FAN5335_VSEL0, + TCA6416_PORT_0, + TCA6416_PIN_6, + Fan5355PmuVoltageGet_VOUT_02, + Fan5355PmuVoltageSet_VOUT_02, + { + NV_FALSE, + FAN5355_MIN_OUTPUT_VOLTAGE_x10/10, + FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10/10, + FAN5355_MAX_OUTPUT_VOLTAGE_x10/10, + MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3 + }, + }, + + // EXT_DC/DC4 (Backlight-1 Intensity Enable) + // By default, this is hard-wired as "always enabled" (see schematics) + { + Max8907bPmuSupply_EXT_DCDC_4, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + {NV_TRUE, 0, 0, 0, 0}, + }, + + // EXT_DC/DC5 (Backlight-2 Intensity Enable) + // By default, this is hard-wired as "always enabled" (see schematics) + { + Max8907bPmuSupply_EXT_DCDC_5, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + {NV_TRUE, 0, 0, 0, 0}, + }, + + // EXT_DC/DC6 (not connected / reserved) + { + Max8907bPmuSupply_EXT_DCDC_6, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + {NV_TRUE, 0, 0, 0, 0}, + }, + + // USB1 VBUS is wired from with DCDC_3. + { + Max8907bPmuSupply_EXT_DCDC_3_USB1, + TCA6416_CONFIG_PORT_0, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + TCA6416_PORT_0, + TCA6416_PIN_0, + NULL, + NULL, + { + NV_FALSE, + FAN5355_MIN_OUTPUT_VOLTAGE_x10/10, + FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10/10, + FAN5355_MAX_OUTPUT_VOLTAGE_x10/10, + MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3 + }, + }, + + // USB3 VBUS is wired from with DCDC_3. + { + Max8907bPmuSupply_EXT_DCDC_3_USB3, + TCA6416_CONFIG_PORT_0, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + TCA6416_PORT_0, + TCA6416_PIN_1, + NULL, + NULL, + { + NV_FALSE, + FAN5355_MIN_OUTPUT_VOLTAGE_x10/10, + FAN5355_OUTPUT_VOLTAGE_INCREMENT_x10/10, + FAN5355_MAX_OUTPUT_VOLTAGE_x10/10, + MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3 + }, + }, + + // MIC2826 BUCK Regulator(BUCK) + { + MIC2826PmuSupply_BUCK, + MIC2826_REG_ADDR_BUCK, + MIC2826_REG_INVALID, + MIC2826_REG_INVALID, + MIC2826_INVALID_PORT, + MIC2826_INVALID_PORT, + NULL, + NULL, + { + NV_FALSE, + MIC2826_BUCK_VOLTAGE_MIN_MV, + MIC2826_BUCK_VOLTAGE_STEP_MV, + MIC2826_BUCK_VOLTAGE_MAX_MV, + MIC2826_BUCK_REQUESTVOLTAGE_MV + }, + }, + // MIC2826 LDO1 + { + MIC2826PmuSupply_LDO1, + MIC2826_REG_ADDR_LD01, + MIC2826_REG_INVALID, + MIC2826_REG_INVALID, + MIC2826_INVALID_PORT, + MIC2826_INVALID_PORT, + NULL, + NULL, + { + NV_FALSE, + MIC2826_LDO_VOLTAGE_MIN_MV, + MIC2826_LDO_VOLTAGE_STEP_MV, + MIC2826_LDO_VOLTAGE_MAX_MV, + MIC2826_LDO1_REQUESTVOLTAGE_MV + }, + }, + + // MIC2826 LDO2 + { + MIC2826PmuSupply_LDO2, + MIC2826_REG_ADDR_LD02, + MIC2826_REG_INVALID, + MIC2826_REG_INVALID, + MIC2826_INVALID_PORT, + MIC2826_INVALID_PORT, + NULL, + NULL, + { + NV_FALSE, + MIC2826_LDO_VOLTAGE_MIN_MV, + MIC2826_LDO_VOLTAGE_STEP_MV, + MIC2826_LDO_VOLTAGE_MAX_MV, + MIC2826_LDO2_REQUESTVOLTAGE_MV + }, + }, + + // LDO3 + { + MIC2826PmuSupply_LDO3, + MIC2826_REG_ADDR_LD03, + MIC2826_REG_INVALID, + MIC2826_REG_INVALID, + MIC2826_INVALID_PORT, + MIC2826_INVALID_PORT, + NULL, + NULL, + { + NV_FALSE, + MIC2826_LDO_VOLTAGE_MIN_MV, + MIC2826_LDO_VOLTAGE_STEP_MV, + MIC2826_LDO_VOLTAGE_MAX_MV, + MIC2826_LDO3_REQUESTVOLTAGE_MV + }, + }, + + // EXT_DC/DC7 (controlled by LX_V1, scaled by AD5258 DPM) + { + Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7, + AD5258_RDAC_ADDR, + MAX8907B_REG_INVALID, + MAX8907B_REG_INVALID, + TCA6416_INVALID_PORT, + TCA6416_INVALID_PORT, + NULL, + NULL, + { + NV_FALSE, + AD5258_V0, + AD5258_MIN_STEP_MV, + AD5258_VMAX, + MAX8907B_REQUESTVOLTAGE_LX_V1 + }, + } +}; + +static NvBool +Max8907bReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + NvU8 data = 0; + NvU32 milliVolts = 0; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + if (pSupplyInfo->ControlRegAddr != MAX8907B_REG_INVALID) + { + if (!Max8907bI2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data)) + return NV_FALSE; + + if ((data & MAX8907B_OUT_VOLTAGE_CONTROL_MASK) == + MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE) + { + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] = + ODM_VOLTAGE_OFF; + *pMilliVolts = ODM_VOLTAGE_OFF; + return NV_TRUE; + } + } + + if (pSupplyInfo->OutputVoltageRegAddr == MAX8907B_REG_INVALID) + return NV_FALSE; + + if (!Max8907bI2cRead8(hDevice, pSupplyInfo->OutputVoltageRegAddr, &data)) + return NV_FALSE; + + data &= MAX8907B_OUT_VOLTAGE_MASK; + if (!data) //OFF + milliVolts = ODM_VOLTAGE_OFF; + else + milliVolts = pSupplyInfo->GetVoltage(data); + + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] = milliVolts; + *pMilliVolts = milliVolts; + return NV_TRUE; +} + +static NvBool +Max8907bWriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + NvU8 data = 0; + NvU32 SettleUS = 0; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + if (MilliVolts == ODM_VOLTAGE_OFF) + { + // check if the supply can be turned off + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 1) + { + // turn off the supply + NvOdmServicesPmuSetSocRailPowerState( + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE); + + // Disable the output (read-modify-write the control register) + Max8907bI2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data); + data &= (~MAX8907B_OUT_VOLTAGE_CONTROL_MASK); + data |= MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE; + if (!Max8907bI2cWrite8(hDevice, pSupplyInfo->ControlRegAddr, data)) + return NV_FALSE; + + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] = + ODM_VOLTAGE_OFF; + SettleUS = MAX8907B_TURN_OFF_TIME_US; + } + + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] != 0) + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] --; + + if (pSettleMicroSeconds) + *pSettleMicroSeconds = SettleUS; + else + NvOdmOsWaitUS(SettleUS); + + return NV_TRUE; + } + + // Set voltage level + data = pSupplyInfo->SetVoltage(MilliVolts); + if (!Max8907bI2cWrite8(hDevice, pSupplyInfo->OutputVoltageRegAddr, data)) + return NV_FALSE; + if (MilliVolts > + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail]) + { + NvU32 LastMV = + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail]; + SettleUS = (MilliVolts - LastMV) * 1000 / MAX8907B_SCALE_UP_UV_PER_US; + } + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[vddRail] = MilliVolts; + + // turn on supply + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 0) + { + // Enable the output (read-modify-write the control register) + Max8907bI2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data); + + if ((data & MAX8907B_OUT_VOLTAGE_CONTROL_MASK) == + MAX8907B_OUT_VOLTAGE_CONTROL_DISABLE) + { + // Voltage on/change (supply was off, so it must be turned on) + NvOdmServicesPmuSetSocRailPowerState( + ((Max8907bPrivData*)(hDevice->pPrivate))->hOdmPmuSevice, + pSupplyInfo->supply, NV_TRUE); + data |= MAX8907B_OUT_VOLTAGE_ENABLE_BIT; + if (!Max8907bI2cWrite8(hDevice, pSupplyInfo->ControlRegAddr, data)) + return NV_FALSE; + + SettleUS = MAX8907B_TURN_ON_TIME_US; + } + } + + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] ++; + + if (pSettleMicroSeconds) + *pSettleMicroSeconds = SettleUS; + else + NvOdmOsWaitUS(SettleUS); + + return NV_TRUE; +} + +static NvBool +Max8907bOnOffConfigure(NvOdmPmuDeviceHandle hDevice) +{ + NvU8 data = 0; + + if (!Max8907bI2cRead8(hDevice, MAX8907B_SYSENSEL, &data)) + return NV_FALSE; + + // Enable hard reset - power-off after ONKEY press for 5 seconds + // (must be enabled for thermal auto-shutdown) + data |= (MAX8907B_SYSENSEL_HRDSTEN_MASK << + MAX8907B_SYSENSEL_HRDSTEN_SHIFT); + + return Max8907bI2cWrite8(hDevice, MAX8907B_SYSENSEL, data); +} + +static NvBool +Max8907bPwrEnConfigure(NvOdmPmuDeviceHandle hDevice, NvBool Enable) +{ + NvU8 data = 0; + + if (!Max8907bI2cRead8(hDevice, MAX8907B_RESET_CNFG, &data)) + return NV_FALSE; + + // Enable/disable PWREN h/w control mechanism (PWREN signal must be + // inactive = high at this time) + if (Enable) + data |= (MAX8907B_RESET_CNFG_PWREN_EN_MASK << + MAX8907B_RESET_CNFG_PWREN_EN_SHIFT); + else + data &= (~(MAX8907B_RESET_CNFG_PWREN_EN_MASK << + MAX8907B_RESET_CNFG_PWREN_EN_SHIFT)); + if (!Max8907bI2cWrite8(hDevice, MAX8907B_RESET_CNFG, data)) + return NV_FALSE; + + // When enabled, connect PWREN to SEQ2 by clearing SEQ2 configuration + // settings for silicon revision that requires s/w WAR. On other MAX8907B + // revisions PWREN is always connected to SEQ2. + if (Enable) + { + if (!Max8907bI2cRead8(hDevice, MAX8907B_II2RR, &data)) + return NV_FALSE; + + if (data == MAX8907B_II2RR_PWREN_WAR) + { + data = 0x00; + if (!Max8907bI2cWrite8(hDevice, MAX8907B_SEQ2CNFG, data)) + return NV_FALSE; + } + } + return NV_TRUE; +} + +static NvBool +Max8907bPwrEnAttach( + NvOdmPmuDeviceHandle hDevice, + Max8907bPmuSupply Supply, + NvBool Attach) +{ + NvU8 CtlAddr, CtlData, CntAddr, CntData, SeqSel; + + switch (Supply) + { + case Max8907bPmuSupply_LX_V1: // CPU + // No sequencer delay for CPU rail when it is attached + CntData = Attach ? 0x00 : MAX8907B_SEQCNT_DEFAULT_LX_V1; + SeqSel = Attach ? MAX8907B_SEQSEL_PWREN_LXX : + MAX8907B_SEQSEL_DEFAULT_LX_V1; + break; + + case Max8907bPmuSupply_LX_V2: // Core + // Change CPU sequencer delay when core is attached to assure + // order of Core/CPU rails control; clear CPU delay when core + // is detached + CntAddr = Max8907bSupplyInfoTable[ + Max8907bPmuSupply_LX_V1].SequencerCountRegAddr; + CntData = Attach ? MAX8907B_SEQCNT_PWREN_LX_V1 : 0x00; + if (!Max8907bI2cWrite8(hDevice, CntAddr, CntData)) + return NV_FALSE; + + CntData = Attach ? MAX8907B_SEQCNT_PWREN_LX_V2 : + MAX8907B_SEQCNT_DEFAULT_LX_V2; + SeqSel = Attach ? MAX8907B_SEQSEL_PWREN_LXX : + MAX8907B_SEQSEL_DEFAULT_LX_V2; + break; + + default: + NV_ASSERT(!"This supply must not be attached to PWREN"); + return NV_FALSE; + } + CtlAddr = Max8907bSupplyInfoTable[Supply].ControlRegAddr; + CntAddr = Max8907bSupplyInfoTable[Supply].SequencerCountRegAddr; + + // Read control refgister, and select target sequencer + if (!Max8907bI2cRead8(hDevice, CtlAddr, &CtlData)) + return NV_FALSE; + CtlData &= (~(MAX8907B_CTL_SEQ_MASK << MAX8907B_CTL_SEQ_SHIFT )); + CtlData |= ((SeqSel & MAX8907B_CTL_SEQ_MASK) << MAX8907B_CTL_SEQ_SHIFT ); + + // Attach: set count => set control + // Dettach: reset control => reset count + if (Attach) + { + if (!Max8907bI2cWrite8(hDevice, CntAddr, CntData)) + return NV_FALSE; + } + + if (!Max8907bI2cWrite8(hDevice, CtlAddr, CtlData)) + return NV_FALSE; + + if (!Attach) + { + if (!Max8907bI2cWrite8(hDevice, CntAddr, CntData)) + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +Tca6416ConfigPort( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvBool Enable) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + NvU32 PortNo; + NvU32 PinNo; + + // Get port number and pin number + PortNo = pSupplyInfo->OutputPort; + PinNo = pSupplyInfo->PmuGpio; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + if (Enable) + { + // Configure GPIO as output + if (!Tca6416ConfigPortPin(hDevice, PortNo, PinNo, GpioPinMode_Output)) + return NV_FALSE; + + // Set the output port + if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_High)) + return NV_FALSE; + } + else + // check if the supply can be turned off + { + // turn off the supply + NvOdmServicesPmuSetSocRailPowerState( + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE); + + // Configure port pin as output + if (!Tca6416ConfigPortPin(hDevice, PortNo, PinNo, GpioPinMode_Output)) + return NV_FALSE; + + // Set the output port (for disable, data = 0) + if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_Low)) + return NV_FALSE; + } + return NV_TRUE; +} + + +#if defined(MAX8907B_USE_FAN5355_VOLTAGE_SCALING) +static NvBool +Fan5355ReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + NvU8 data = 0; + NvU32 milliVolts = 0; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + if (pSupplyInfo->OutputVoltageRegAddr == FAN5335_REG_INVALID) + return NV_FALSE; + + if (!Fan5355I2cRead8(hDevice, pSupplyInfo->OutputVoltageRegAddr, &data)) + return NV_FALSE; + + if (!data) //OFF + milliVolts = 0; + else + milliVolts = pSupplyInfo->GetVoltage(data); + + *pMilliVolts = milliVolts; + return NV_TRUE; +} +#endif + +static NvBool +Fan5355WriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = NULL; + NvU8 data = 0; + + if ((vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB1) || + (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB3)) + { + vddRail = Max8907bPmuSupply_EXT_DCDC_3; + } + + pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + // TO DO: Account for reference counting + if (MilliVolts == ODM_VOLTAGE_OFF) + { + // check if the supply can be turned off + { + // turn off the supply + NvOdmServicesPmuSetSocRailPowerState( + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE); + + // Disable the output + if (!Tca6416ConfigPort(hDevice, vddRail, NV_FALSE)) + return NV_FALSE; + } + } + else + { + // Voltage on/change + NvOdmServicesPmuSetSocRailPowerState( + ((Max8907bPrivData*)(hDevice->pPrivate))->hOdmPmuSevice, pSupplyInfo->supply, NV_TRUE); + + // Set voltage level + data = pSupplyInfo->SetVoltage(MilliVolts); +#if defined(MAX8907B_USE_FAN5355_VOLTAGE_SCALING) + if (!Fan5355I2cWrite8(hDevice, pSupplyInfo->OutputVoltageRegAddr, data)) + return NV_FALSE; +#endif + + // Enable the output + if (!Tca6416ConfigPort(hDevice, vddRail, NV_TRUE)) + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +Max8907bLxV1Ad5258ReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + const Max8907bPmuSupplyInfo* pSupplyInfo = + &Max8907bSupplyInfoTable[vddRail]; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + // Check if DC/DC has been turned Off (controlled by LxV1 main PMU output) + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[ + pSupplyInfo->supply] == 0) + { + if (!Max8907bReadVoltageReg( + hDevice, Max8907bPmuSupply_LX_V1, pMilliVolts)) + return NV_FALSE; + if (*pMilliVolts == ODM_VOLTAGE_OFF) + return NV_TRUE; + } + + // DC/DC is On - now get DPM-scaled voltage + return Ad5258I2cGetVoltage(hDevice, pMilliVolts); +} + +static NvBool +Max8907bLxV1Ad5258WriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = + &Max8907bSupplyInfoTable[vddRail]; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + if (MilliVolts == ODM_VOLTAGE_OFF) + { + // Check if the supply can be turned off, and if yes - turn off + // LxV1 main PMU output, which controls DC/DC + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[ + pSupplyInfo->supply] == 1) + { + if (!Max8907bWriteVoltageReg(hDevice, Max8907bPmuSupply_LX_V1, + MilliVolts, pSettleMicroSeconds)) + return NV_FALSE; + } + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[ + pSupplyInfo->supply] != 0) + { + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[ + pSupplyInfo->supply] --; + } + return NV_TRUE; + } + + // Set DPM voltage level (includes DPM and DCDC change level settle time) + if (!Ad5258I2cSetVoltage(hDevice, MilliVolts)) + return NV_FALSE; + + // Turn on control LxV1 supply on main PMU if necessary + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[ + pSupplyInfo->supply] == 0) + { + if (!Max8907bWriteVoltageReg(hDevice, Max8907bPmuSupply_LX_V1, + MAX8907B_REQUESTVOLTAGE_LX_V1, pSettleMicroSeconds)) + return NV_FALSE; + + // Add external DCDC turning On settling time + if (pSettleMicroSeconds) + *pSettleMicroSeconds += AD5258_TURN_ON_TIME_US; + else + NvOdmOsWaitUS(AD5258_TURN_ON_TIME_US); + } + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[ + pSupplyInfo->supply] ++; + + return NV_TRUE; +} + +NvBool +Max8907bSetup(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmIoModule I2cModule = NvOdmIoModule_I2c; + NvU32 I2cInstance = 0; + NvU32 I2cAddress = 0; + NvU32 i = 0; + const NvOdmPeripheralConnectivity *pConnectivity = + NvOdmPeripheralGetGuid(PMUGUID); + + NV_ASSERT(hDevice); + + hMax8907bPmu = (Max8907bPrivData*) NvOdmOsAlloc(sizeof(Max8907bPrivData)); + if (hMax8907bPmu == NULL) + { + NVODMPMU_PRINTF(("Error Allocating Max8907bPrivData.\n")); + return NV_FALSE; + } + NvOdmOsMemset(hMax8907bPmu, 0, sizeof(Max8907bPrivData)); + hDevice->pPrivate = hMax8907bPmu; + + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable = + NvOdmOsAlloc(sizeof(NvU32) * Max8907bPmuSupply_Num); + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable == NULL) + { + NVODMPMU_PRINTF(("Error Allocating RefCntTable. \n")); + goto fail; + } + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages = + NvOdmOsAlloc(sizeof(NvU32) * Max8907bPmuSupply_Num); + if (((Max8907bPrivData*)hDevice->pPrivate)->pVoltages == NULL) + { + NVODMPMU_PRINTF(("Error Allocating shadow voltages table. \n")); + goto fail; + } + + // memset + for (i = 0; i < Max8907bPmuSupply_Num; i++) + { + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[i] = 0; + // Setting shadow to 0 would cause spare delay on the 1st scaling of + // always On rail; however the alternative reading of initial settings + // over I2C is even worse. + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages[i] = 0; + } + + if (pConnectivity != NULL) // PMU is in database + { + NvU32 i = 0; + + for (i = 0; i < pConnectivity->NumAddress; i ++) + { + if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu) + { + I2cModule = NvOdmIoModule_I2c_Pmu; + I2cInstance = pConnectivity->AddressList[i].Instance; + I2cAddress = pConnectivity->AddressList[i].Address; + break; + } + } + + NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu); + NV_ASSERT(I2cAddress != 0); + + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance); + if (!((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C) + { + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Error Opening I2C device. \n")); + NVODMPMU_PRINTF(("[NVODM PMU]Please check PMU device I2C settings. \n")); + return NV_FALSE; + } + ((Max8907bPrivData*)hDevice->pPrivate)->DeviceAddr = I2cAddress; + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice = NvOdmServicesPmuOpen(); + } + else + { + // if PMU is not present in the database, then the platform is PMU-less. + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: The system did not doscover PMU from the data base.\n")); + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: If this is not intended, please check the peripheral database for PMU settings.\n")); + return NV_FALSE; + } + + // Configure OnOff options + if (!Max8907bOnOffConfigure(hDevice)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bOnOffConfigure() failed. \n")); + return NV_FALSE; + } + + // Configure PWREN, and attach CPU V1 rail to it. + // TODO: h/w events (power cycle, reset, battery low) auto-disables PWREN. + // Only soft reset (not supported) requires s/w to disable PWREN explicitly + if (!Max8907bPwrEnConfigure(hDevice, NV_TRUE)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bPwrEnConfigure() failed. \n")); + return NV_FALSE; + } + if (!Max8907bPwrEnAttach(hDevice, Max8907bPmuSupply_LX_V1, NV_TRUE)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bPwrEnAttach() failed. \n")); + return NV_FALSE; + } + + //Check battery presence + if (!Max8907bBatteryChargerMainBatt(hDevice,&((Max8907bPrivData*)hDevice->pPrivate)->battPresence)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup: Max8907bBatteryChargerMainBatt() failed. \n")); + return NV_FALSE; + } + + // Power up Whistler thermal monitor (it is reported "not connected" + // if board info ROMs cannot be read when the thermal rail is enabled). + // This has to be done as early as possible because of 100ms+ power up + // delay before interface level shifters are operational. + pConnectivity = + NvOdmPeripheralGetGuid(NV_ODM_GUID('a','d','t','7','4','6','1',' ')); + if (pConnectivity) + { + for (i = 0; i < pConnectivity->NumAddress; i++) + { + if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_Vdd) + { + NvU32 vddRail = pConnectivity->AddressList[i].Address; + NvU32 mv = + Max8907bSupplyInfoTable[vddRail].cap.requestMilliVolts; + if(!Max8907bSetVoltage(hDevice, vddRail, mv, NULL)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Max8907bSetup:" + " Thermal rail setup failed. \n")); + } + } + } + } + + // The interrupt assumes not supported until Max8907bInterruptHandler() is called. + ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_FALSE; + + return NV_TRUE; + +fail: + Max8907bRelease(hDevice); + return NV_FALSE; +} + +void +Max8907bRelease(NvOdmPmuDeviceHandle hDevice) +{ + if (hDevice->pPrivate != NULL) + { + if (((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice != NULL) + { + NvOdmServicesPmuClose(((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice); + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmPmuSevice = NULL; + } + + if (((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C != NULL) + { + NvOdmI2cClose(((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C); + ((Max8907bPrivData*)hDevice->pPrivate)->hOdmI2C = NULL; + } + + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable != NULL) + { + NvOdmOsFree(((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable); + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable = NULL; + } + + if (((Max8907bPrivData*)hDevice->pPrivate)->pVoltages != NULL) + { + NvOdmOsFree(((Max8907bPrivData*)hDevice->pPrivate)->pVoltages); + ((Max8907bPrivData*)hDevice->pPrivate)->pVoltages = NULL; + } + + + NvOdmOsFree(hDevice->pPrivate); + hDevice->pPrivate = NULL; + } +} + +NvBool +Max8907bGetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + NV_ASSERT(hDevice); + NV_ASSERT(pMilliVolts); + NV_ASSERT(vddRail < Max8907bPmuSupply_Num); + + // RTC is a special case, since it's "always on" + if (vddRail == Max8907bPmuSupply_VRTC) + { + // Fixed voltage + *pMilliVolts = MAX8907B_MAX_OUTPUT_VOLTAGE_RTC; + } + else if (vddRail == Max8907bPmuSupply_EXT_DCDC_1) + { + // Fixed voltage + *pMilliVolts = MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1; + } + else if (vddRail == Max8907bPmuSupply_EXT_DCDC_3) + { +#if defined(MAX8907B_USE_FAN5355_VOLTAGE_SCALING) + if (!Fan5355ReadVoltageReg(hDevice, vddRail, pMilliVolts)) + return NV_FALSE; +#else + // Fixed voltage + *pMilliVolts = MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3; +#endif + } + else if((vddRail == MIC2826PmuSupply_BUCK) || + (vddRail == MIC2826PmuSupply_LDO1) || + (vddRail == MIC2826PmuSupply_LDO2) || + (vddRail == MIC2826PmuSupply_LDO3)) + { + // Secondary PMU Case + if(! MIC2826ReadVoltageReg(hDevice, (vddRail), pMilliVolts)) + return NV_FALSE; + } + else if (vddRail == Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7) + { + // External DCDC controlled by LX_V1, and scaled by DPM + if (!Max8907bLxV1Ad5258ReadVoltageReg(hDevice, vddRail, pMilliVolts)) + return NV_FALSE; + } + else + { + if (!Max8907bReadVoltageReg(hDevice, vddRail, pMilliVolts)) + return NV_FALSE; + } + + return NV_TRUE; +} + + +static NvBool +Tca6416UsbVbusControl( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts) +{ + const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + NvU32 PortNo; + NvU32 PinNo; + + // Get port number and pin number + PortNo = pSupplyInfo->OutputPort; + PinNo = pSupplyInfo->PmuGpio; + + // Configure port pin as output + if (!Tca6416ConfigPortPin(hDevice, PortNo, PinNo, GpioPinMode_Output)) + return NV_FALSE; + + if (MilliVolts == ODM_VOLTAGE_OFF) // to disable VBUS + { + // Set Low on pin + if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_Low)) + return NV_FALSE; + } + else // to Enable VBUS + { + // Set high on pin + if (!Tca6416WritePortPin(hDevice, PortNo, PinNo, GpioPinState_High)) + return NV_FALSE; + } + return NV_TRUE; +} + +NvBool +Max8907bSetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + NV_ASSERT(hDevice); + NV_ASSERT(vddRail < Max8907bPmuSupply_Num); + + if ( Max8907bSupplyInfoTable[vddRail].cap.OdmProtected == NV_TRUE) + { + NVODMPMU_PRINTF(("The voltage is protected and cannot be set.\n")); + return NV_TRUE; + } + + if ((MilliVolts == ODM_VOLTAGE_ENABLE_EXT_ONOFF) || + (MilliVolts == ODM_VOLTAGE_DISABLE_EXT_ONOFF)) + { + return Max8907bPwrEnAttach(hDevice, (Max8907bPmuSupply)vddRail, + (MilliVolts == ODM_VOLTAGE_ENABLE_EXT_ONOFF)); + } + + if ((MilliVolts == ODM_VOLTAGE_OFF) || + ((MilliVolts <= Max8907bSupplyInfoTable[vddRail].cap.MaxMilliVolts) && + (MilliVolts >= Max8907bSupplyInfoTable[vddRail].cap.MinMilliVolts))) + { + if ((vddRail == Max8907bPmuSupply_EXT_DCDC_1) || + (vddRail == Max8907bPmuSupply_EXT_DCDC_3) || + (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB1) || + (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB3)) + { + // Use External DC/DC switcher + if (!Fan5355WriteVoltageReg(hDevice, vddRail, MilliVolts)) + return NV_FALSE; + } + else if((vddRail == MIC2826PmuSupply_BUCK) || + (vddRail == MIC2826PmuSupply_LDO1) || + (vddRail == MIC2826PmuSupply_LDO2) || + (vddRail == MIC2826PmuSupply_LDO3)) + { + // Secondary PMU Case + if (!MIC2826WriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds)) + return NV_FALSE; + } + else if (vddRail == Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7) + { + // External DCDC controlled by LX_V1, and scaled by DPM + if (!Max8907bLxV1Ad5258WriteVoltageReg( + hDevice, vddRail, MilliVolts, pSettleMicroSeconds)) + return NV_FALSE; + } + else + { + if (!Max8907bWriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds)) + return NV_FALSE; + } + } + else + { + NVODMPMU_PRINTF(("The requested voltage is not supported.\n")); + return NV_FALSE; + } + + // Check whether need to enable VBUS for any of the USB Instance + if ((vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB1) || + (vddRail == Max8907bPmuSupply_EXT_DCDC_3_USB3)) + { + // Enable VBUS for USB1 or USB3 + if (!Tca6416UsbVbusControl(hDevice, vddRail, MilliVolts)) + return NV_FALSE; + } + return NV_TRUE; +} + +void +Max8907bGetCapabilities( + NvU32 vddRail, + NvOdmPmuVddRailCapabilities* pCapabilities) +{ + NV_ASSERT(pCapabilities); + NV_ASSERT(vddRail < Max8907bPmuSupply_Num); + + *pCapabilities = Max8907bSupplyInfoTable[vddRail].cap; +} + +NvBool +Max8907bGetAcLineStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuAcLineStatus *pStatus) +{ + NvBool acLineStatus = NV_FALSE; + + NV_ASSERT(hDevice); + NV_ASSERT(pStatus); + + // check if battery is present + if (((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_FALSE) + { + *pStatus = NvOdmPmuAcLine_Online; + return NV_TRUE; + } + + if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE ) + { + if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus.mChgPresent == NV_TRUE ) + { + *pStatus = NvOdmPmuAcLine_Online; + acLineStatus = NV_TRUE; + } + else + { + *pStatus = NvOdmPmuAcLine_Offline; + acLineStatus = NV_FALSE; + } + } + else + { + // battery is present, now check if charger present + if (!Max8907bBatteryChargerOK(hDevice, &acLineStatus)) + { + NVODMPMU_PRINTF(("[NVODM PMU] Max8907bGetAcLineStatus: Error in checking main charger presence.\n")); + return NV_FALSE; + } + + if (acLineStatus == NV_TRUE) + *pStatus = NvOdmPmuAcLine_Online; + else + *pStatus = NvOdmPmuAcLine_Offline; + } + +#if ALWAYS_ONLINE + // Currently on Whistler battery is not used, and AC is connected to PMU + // battery input, causing false battery presence detection. Voyager battery + // management is don't care at the moment. Hence, force OnLine status. + *pStatus = NvOdmPmuAcLine_Online; +#endif + + return NV_TRUE; +} + +NvBool +Max8907bGetBatteryStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU8 *pStatus) +{ + NvU8 status = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pStatus); + NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num); + + if (batteryInst == NvOdmPmuBatteryInst_Main) + { + if ( ((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_TRUE ) + { + NvOdmPmuAcLineStatus stat = NvOdmPmuAcLine_Offline; + NvU32 VBatSense = 0; + if (!Max8907bGetAcLineStatus(hDevice, &stat)) + return NV_FALSE; + + if (stat == NvOdmPmuAcLine_Online) + { + if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE ) + { + if ( ((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus.batFull == NV_FALSE ) + status = NVODM_BATTERY_STATUS_CHARGING; + } + else + { + NvBool batFull = NV_FALSE; + if (!Max8907bBatteryChargerMainBattFull(hDevice, &batFull)) + return NV_FALSE; + if (batFull == NV_FALSE) + status = NVODM_BATTERY_STATUS_CHARGING; + } + } + + // Get VBatSense + if (!Max8907bAdcVBatSenseRead(hDevice, &VBatSense)) + return NV_FALSE; + + // TO DO: Update status based on VBatSense + } + else + { + /* Battery is actually not present */ + status = NVODM_BATTERY_STATUS_NO_BATTERY; + } + *pStatus = status; + } + else + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + } + + return NV_TRUE; +} + +NvBool +Max8907bGetBatteryData( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryData *pData) +{ + NvOdmPmuBatteryData batteryData; + + batteryData.batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + + NV_ASSERT(hDevice); + NV_ASSERT(pData); + NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num); + + if (batteryInst == NvOdmPmuBatteryInst_Main) + { + NvU32 VBatSense = 0; + NvU32 VBatTemp = 0; + + if (((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_TRUE) + { + /* retrieve Battery voltage and temperature */ + + // Get VBatSense + if (!Max8907bAdcVBatSenseRead(hDevice, &VBatSense)) + { + NVODMPMU_PRINTF(("Error reading VBATSense. \n")); + return NV_FALSE; + } + + // Get VBatTemp + if (!Max8907bAdcVBatTempRead(hDevice, &VBatTemp)) + { + NVODMPMU_PRINTF(("Error reading VBATSense. \n")); + return NV_FALSE; + } + + batteryData.batteryVoltage = VBatSense; + batteryData.batteryTemperature = Max8907bBatteryTemperature(VBatSense, VBatTemp); + } + + *pData = batteryData; + } + else + { + *pData = batteryData; + } + + return NV_TRUE; +} + +void +Max8907bGetBatteryFullLifeTime( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU32 *pLifeTime) +{ + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; +} + +void +Max8907bGetBatteryChemistry( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryChemistry *pChemistry) +{ + *pChemistry = NvOdmPmuBatteryChemistry_LION; +} + +NvBool +Max8907bSetChargingCurrent( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuChargingPath chargingPath, + NvU32 chargingCurrentLimitMa, + NvOdmUsbChargerType ChargerType) +{ + NvU8 data = 0; + NvU8 fchg = 0; + NV_ASSERT(hDevice); + + // If no battery is connected, then do nothing. + if (((Max8907bPrivData*)hDevice->pPrivate)->battPresence == NV_FALSE) + return NV_TRUE; + + // If requested current is more than supported maximum then limit to supported. + if ( chargingCurrentLimitMa > MAX_CHARGER_LIMIT_MA ) + chargingCurrentLimitMa = MAX_CHARGER_LIMIT_MA; + + // If dedicated charger is connected, request maximum current. + if (chargingPath == NvOdmPmuChargingPath_UsbBus) + { + switch (ChargerType) + { + case NvOdmUsbChargerType_SJ: + case NvOdmUsbChargerType_SK: + case NvOdmUsbChargerType_SE1: + case NvOdmUsbChargerType_SE0: + chargingCurrentLimitMa = MAX_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_UsbHost: + default: + break; + } + } + + // Read the current charger setup. + if ( !Max8907bI2cRead8(hDevice, MAX8907B_CHG_CNTL1, &data) ) + return NV_FALSE; + + // Set charging current to the value no larger than requested. + // If less than 85mA is requested, set to 85mA. + // If larger than 1000mA is requested, set to 1000mA. + if (chargingCurrentLimitMa >= 1000) + fchg = MAX8907B_CHG_CNTL1_FCHG_1000MA; + else if (chargingCurrentLimitMa >= 900) + fchg = MAX8907B_CHG_CNTL1_FCHG_900MA; + else if (chargingCurrentLimitMa >= 800) + fchg = MAX8907B_CHG_CNTL1_FCHG_800MA; + else if (chargingCurrentLimitMa >= 700) + fchg = MAX8907B_CHG_CNTL1_FCHG_700MA; + else if (chargingCurrentLimitMa >= 600) + fchg = MAX8907B_CHG_CNTL1_FCHG_600MA; + else if (chargingCurrentLimitMa >= 460) + fchg = MAX8907B_CHG_CNTL1_FCHG_460MA; + else if (chargingCurrentLimitMa >= 300) + fchg = MAX8907B_CHG_CNTL1_FCHG_300MA; + else + fchg = MAX8907B_CHG_CNTL1_FCHG_85MA; + + data &= ~(MAX8907B_CHG_CNTL1_FCHG_MASK << + MAX8907B_CHG_CNTL1_FCHG_SHIFT); + data |= fchg << MAX8907B_CHG_CNTL1_FCHG_SHIFT; + + // Turn off the charger path if the requested current limit is 0mA. + // Turn on the path otherwise. + if ( chargingCurrentLimitMa == 0 ) + { + // off + data |= (MAX8907B_CHG_CNTL1_NOT_CHGEN_MASK << + MAX8907B_CHG_CNTL1_NOT_CHGEN_SHIFT); + } + else + { + // on + data &= ~(MAX8907B_CHG_CNTL1_NOT_CHGEN_MASK << + MAX8907B_CHG_CNTL1_NOT_CHGEN_SHIFT); + } + + // Update the current charger setup. + if ( !Max8907bI2cWrite8(hDevice, MAX8907B_CHG_CNTL1, data) ) + return NV_FALSE; + + return NV_TRUE; +} + +void Max8907bInterruptHandler( NvOdmPmuDeviceHandle hDevice) +{ + // If the interrupt handle is called, the interrupt is supported. + ((Max8907bPrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_TRUE; + + Max8907bInterruptHandler_int(hDevice, &((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus); +} + +/**************** Secondary PMU MIC2826 Programming */ +static NvBool +MIC2826ReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + NvU32 milliVolts = 0; + NvU32 index = 0; + NvU8 data = 0; + const Max8907bPmuSupplyInfo *pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + if(! MIC2826I2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data)) + return NV_FALSE; + + // convert Data to MilliVolts + if (!data) //OFF + milliVolts = 0; + else + { + // set voltage + if(vddRail == MIC2826PmuSupply_BUCK) + { + for(index=0;index<MIC2826_BUCK_Votage_Table_Size;index++) + { + if(data == MIC2826_BUCK_Votage_Table[index]) + break; + } + if(index < 0x10) + { + milliVolts = index * MIC2826_BUCK_VOLTAGE_STEP_25MV + MIC2826_BUCK_VOLTAGE_OFFSET ; + }else + { + milliVolts = 1200 + ((index - 0x10) * MIC2826_BUCK_VOLTAGE_STEP_50MV) ; + } + } + else if ( (vddRail == MIC2826PmuSupply_LDO1) || + (vddRail == MIC2826PmuSupply_LDO2) || + (vddRail == MIC2826PmuSupply_LDO3)) + { + for(index=0;index<MIC2826_LDO_Votage_Table_Size;index++) + { + if(data == MIC2826_BUCK_Votage_Table[index]) + break; + } + milliVolts = (index * pSupplyInfo->cap.StepMilliVolts) + MIC2826_LDO_VOLTAGE_OFFSET; + } + } + + *pMilliVolts = milliVolts; + + return NV_TRUE; +} + + +static NvBool +MIC2826WriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + NvU8 data = 0; + NvU32 index = 0; + NvU32 settleTime = 0; + const Max8907bPmuSupplyInfo* pSupplyInfo = &Max8907bSupplyInfoTable[vddRail]; + + NV_ASSERT(pSupplyInfo->supply == (Max8907bPmuSupply)vddRail); + + // Require to turn off the supply + if (MilliVolts == ODM_VOLTAGE_OFF) + { + // check if the supply can be turned off + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 1) + { + + // Read the current supply info + if(! MIC2826I2cRead8(hDevice, MIC2826_REG_ADDR_ENABLE, &data)) + return NV_FALSE; + + // turn off the supply of particular rail + if(vddRail == MIC2826PmuSupply_BUCK) + data &= MIC2826_REG_DISABLE_BK; + else if(vddRail == MIC2826PmuSupply_LDO1) + data &= MIC2826_REG_DISABLE_LDO1; + else if(vddRail == MIC2826PmuSupply_LDO2) + data &= MIC2826_REG_DISABLE_LDO2; + else if(vddRail == MIC2826PmuSupply_LDO3) + data &= MIC2826_REG_DISABLE_LDO3; + + if (!MIC2826I2cWrite8(hDevice, MIC2826_REG_ADDR_ENABLE, data)) + return NV_FALSE; + } + + //TODO: check if the supply input can be turned off + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] != 0) + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] --; + + if (pSettleMicroSeconds != NULL) + *pSettleMicroSeconds = settleTime; + else + NvOdmOsWaitUS(settleTime); + + return NV_TRUE; + } + + // turn on supply + if (((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 0) + { + { + // Read the current supply info + if(! MIC2826I2cRead8(hDevice, MIC2826_REG_ADDR_ENABLE, &data)) + return NV_FALSE; + + // turn on the supply of particular rail + if(vddRail == MIC2826PmuSupply_BUCK) + data |= MIC2826_REG_ENABLE_BK; + else if(vddRail == MIC2826PmuSupply_LDO1) + data |= MIC2826_REG_ENABLE_LDO1; + else if(vddRail == MIC2826PmuSupply_LDO2) + data |= MIC2826_REG_ENABLE_LDO2; + else if(vddRail == MIC2826PmuSupply_LDO3) + data |= MIC2826_REG_ENABLE_LDO3; + + if (!MIC2826I2cWrite8(hDevice, MIC2826_REG_ADDR_ENABLE, data)) + return NV_FALSE; + } + } + + // set voltage + if(vddRail == MIC2826PmuSupply_BUCK) + { + if(MilliVolts < 1200) + { + index = (MilliVolts - MIC2826_BUCK_VOLTAGE_OFFSET) / MIC2826_BUCK_VOLTAGE_STEP_25MV ; + }else + { + index = 0x10 + ((MilliVolts - 1200) / MIC2826_BUCK_VOLTAGE_STEP_50MV) ; + } + data = MIC2826_BUCK_Votage_Table[index]; + } + else if ( (vddRail == MIC2826PmuSupply_LDO1) || + (vddRail == MIC2826PmuSupply_LDO2) || + (vddRail == MIC2826PmuSupply_LDO3)) + { + index = (MilliVolts - MIC2826_LDO_VOLTAGE_OFFSET) / pSupplyInfo->cap.StepMilliVolts; + data = MIC2826_LDO_Votage_Table[index]; + } + + // Program the Rail Voltage + if(! MIC2826I2cRead8(hDevice, pSupplyInfo->ControlRegAddr, &data)) + return NV_FALSE; + + ((Max8907bPrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] ++; + + // TODO: turn on supply input if necessary + if (pSettleMicroSeconds != NULL) + *pSettleMicroSeconds = settleTime; + else + NvOdmOsWaitUS(settleTime); + + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h new file mode 100644 index 000000000000..ce66a64c9716 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 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_PMU_MAX8907B_H +#define INCLUDED_PMU_MAX8907B_H + +#include "nvodm_pmu.h" +#include"pmu_hal.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if (NV_DEBUG) +#define NVODMPMU_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODMPMU_PRINTF(x) +#endif + +typedef struct Max8907bStatusRec +{ + /* Low Battery voltage detected by BVM */ + NvBool lowBatt; + + /* PMU high temperature */ + NvBool highTemp; + + /* Main charger Present */ + NvBool mChgPresent; + + /* battery Full */ + NvBool batFull; + +} Max8907bStatus; + +typedef struct +{ + /* The handle to the I2C */ + NvOdmServicesI2cHandle hOdmI2C; + + /* The odm pmu service handle */ + NvOdmServicesPmuHandle hOdmPmuSevice; + + /* the PMU I2C device Address */ + NvU32 DeviceAddr; + + /* the PMU status */ + Max8907bStatus pmuStatus; + + /* battery presence */ + NvBool battPresence; + + /* PMU interrupt support enabled */ + NvBool pmuInterruptSupported; + + /* The ref cnt table of the power supplies */ + NvU32 *supplyRefCntTable; + + /* The pointer to supply voltages shadow */ + NvU32 *pVoltages; + +} Max8907bPrivData; + +NvBool +Max8907bSetup(NvOdmPmuDeviceHandle hDevice); + +void +Max8907bRelease(NvOdmPmuDeviceHandle hDevice); + +NvBool +Max8907bGetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts); + +NvBool +Max8907bSetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds); + +void +Max8907bGetCapabilities( + NvU32 vddRail, + NvOdmPmuVddRailCapabilities* pCapabilities); + +NvBool +Max8907bGetAcLineStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuAcLineStatus *pStatus); + +NvBool +Max8907bGetBatteryStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU8 *pStatus); + +NvBool +Max8907bGetBatteryData( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryData *pData); + +void +Max8907bGetBatteryFullLifeTime( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU32 *pLifeTime); + +void +Max8907bGetBatteryChemistry( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryChemistry *pChemistry); + +NvBool +Max8907bSetChargingCurrent( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuChargingPath chargingPath, + NvU32 chargingCurrentLimitMa, + NvOdmUsbChargerType ChargerType); + +void Max8907bInterruptHandler( NvOdmPmuDeviceHandle hDevice); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_PMU_MAX8907B_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c new file mode 100644 index 000000000000..14d2c0d87a1a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c @@ -0,0 +1,101 @@ +/* + * Copyright (c) 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 "max8907b.h" +#include "max8907b_adc.h" +#include "max8907b_i2c.h" +#include "max8907b_reg.h" + +NvBool +Max8907bAdcVBatSenseRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt) +{ +#if 0 + NvU32 timeout = 0; + NvU8 dataS1 = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(volt); + + // Configure ADC (conversion cycle, resolution, etc...) + + // Start conversion + + // Wait for conversion + + // Make sure conversion is complete (or timeout or error) + + // Get result + *volt = << compute >>; + +#endif + *volt = 0; + return NV_TRUE; +} + +NvBool +Max8907bAdcVBatTempRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt) +{ +#if 0 + NvU32 timeout = 0; + NvU8 dataS1 = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(volt); + + // Setup ADC (resolution, etc..) + + // Start conversion + + // Wait for conversion + + // Make sure conversion is complete (or timeout or error) + + // Get result + *volt = << compute >>; + +#endif + *volt = 0; + return NV_TRUE; +} + +NvU32 +Max8907bBatteryTemperature( + NvU32 VBatSense, + NvU32 VBatTemp) +{ + return 0; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h new file mode 100644 index 000000000000..5c3fb34fbf22 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 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_MAX8907B_ADC_HEADER +#define INCLUDED_MAX8907B_ADC_HEADER + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* read voltage from ... */ +NvBool +Max8907bAdcVBatSenseRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt); + +/* read bat temperature voltage from ADC */ +NvBool +Max8907bAdcVBatTempRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt); + +/* Calculate the battery temperature */ +NvU32 +Max8907bBatteryTemperature( + NvU32 VBatSense, + NvU32 VBatTemp); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_MAX8907B_ADC_HEADER diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c new file mode 100644 index 000000000000..00096508b05a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 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 "max8907b.h" +#include "max8907b_batterycharger.h" +#include "max8907b_reg.h" +#include "max8907b_i2c.h" + +NvBool +Max8907bBatteryChargerMainBatt( + NvOdmPmuDeviceHandle hDevice, + NvBool *status) +{ + NvU8 data = 0; + + if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data)) + return NV_FALSE; + + data = (data >> MAX8907B_CHG_STAT_MBDET_SHIFT) & MAX8907B_CHG_STAT_MBDET_MASK; + *status = (data == 0 ? NV_TRUE : NV_FALSE ); // MBDET low (0) = present + return NV_TRUE; +} + +NvBool +Max8907bBatteryChargerOK( + NvOdmPmuDeviceHandle hDevice, + NvBool *status) +{ + NvU8 data = 0; + + if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data)) + return NV_FALSE; + + data = (data >> MAX8907B_CHG_STAT_VCHG_OK_SHIFT) & MAX8907B_CHG_STAT_VCHG_OK_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +NvBool +Max8907bBatteryChargerEnabled( + NvOdmPmuDeviceHandle hDevice, + NvBool *status) +{ + NvU8 data = 0; + + if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data)) + return NV_FALSE; + + data = (data >> MAX8907B_CHG_STAT_CHG_EN_STAT_SHIFT) & MAX8907B_CHG_STAT_CHG_EN_STAT_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +NvBool +Max8907bBatteryChargerMainBattFull( + NvOdmPmuDeviceHandle hDevice, + NvBool *status) +{ + NvU8 data = 0; + + if(!Max8907bI2cRead8(hDevice, MAX8907B_CHG_STAT, &data)) + return NV_FALSE; + + data = (data >> MAX8907B_CHG_STAT_MBATTLOW_SHIFT) & MAX8907B_CHG_STAT_MBATTLOW_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h new file mode 100644 index 000000000000..ab7d1212a44f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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_MAX8907B_BATTERYCHARGER_HEADER +#define INCLUDED_MAX8907B_BATTERYCHARGER_HEADER + +/* the battery charger functions */ +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* check main battery presence */ +NvBool +Max8907bBatteryChargerMainBatt( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check charger input voltage */ +NvBool +Max8907bBatteryChargerOK( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check charger enable status */ +NvBool +Max8907bBatteryChargerEnabled( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check main battery voltage status */ +NvBool +Max8907bBatteryChargerMainBattFull( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_MAX8907B_BATTERYCHARGER_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c new file mode 100644 index 000000000000..0f7a09446876 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c @@ -0,0 +1,365 @@ +/* + * Copyright (c) 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 "max8907b.h" +#include "max8907b_i2c.h" +#include "max8907b_reg.h" + +#define MAX8907B_I2C_SPEED_KHZ 400 +#define MAX8907B_I2C_RETRY_CNT 2 + +// Maximum i2c transaction count +#define MAX_TRANSACTION_COUNT 5 + +NvBool Max8907bI2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU32 i; + NvU8 WriteBuffer[2]; + NvOdmI2cTransactionInfo TransactionInfo; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + + for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) + { + WriteBuffer[0] = Addr & 0xFF; // PMU offset + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = hPmu->DeviceAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (status == NvOdmI2cStatus_Success) + return NV_TRUE; + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool Max8907bI2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data) +{ + NvU32 i; + NvU8 ReadBuffer = 0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) + { + NvU32 TransactionCount = 0; + // Write the PMU offset + ReadBuffer = Addr & 0xFF; + + TransactionInfo[TransactionCount].Address = hPmu->DeviceAddr; + TransactionInfo[TransactionCount].Buf = &ReadBuffer; + TransactionInfo[TransactionCount].Flags = + NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START; + TransactionInfo[TransactionCount++].NumBytes = 1; + + TransactionInfo[TransactionCount].Address = (hPmu->DeviceAddr | 0x1); + TransactionInfo[TransactionCount].Buf = &ReadBuffer; + TransactionInfo[TransactionCount].Flags = 0; + TransactionInfo[TransactionCount++].NumBytes = 1; + + // Read data from PMU at the specified offset + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], + TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (status == NvOdmI2cStatus_Success) + { + *Data = ReadBuffer; + return NV_TRUE; + } + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool Max8907bI2cWrite32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 Data) +{ + NvU32 i; + NvU8 WriteBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo; + + for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) + { + WriteBuffer[0] = (NvU8)(Addr & 0xFF); + WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF); + WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF); + WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF); + WriteBuffer[4] = (NvU8)(Data & 0xFF); + + TransactionInfo.Address = hPmu->DeviceAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 5; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (status == NvOdmI2cStatus_Success) + return NV_TRUE; + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool Max8907bI2cRead32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 *Data) +{ + NvU32 i; + NvU8 ReadBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) + { + NvU32 TransactionCount = 0; + ReadBuffer[0] = Addr & 0xFF; + + TransactionInfo[TransactionCount].Address = hPmu->DeviceAddr; + TransactionInfo[TransactionCount].Buf = &ReadBuffer[0]; + TransactionInfo[TransactionCount].Flags = + NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START; + TransactionInfo[TransactionCount++].NumBytes = 1; + + TransactionInfo[TransactionCount].Address = (hPmu->DeviceAddr | 0x1); + TransactionInfo[TransactionCount].Buf = &ReadBuffer[0]; + TransactionInfo[TransactionCount].Flags = 0; + TransactionInfo[TransactionCount++].NumBytes = 4; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], + TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (status == NvOdmI2cStatus_Success) + { + *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) | + (ReadBuffer[2] << 8) | ReadBuffer[3]; + + return NV_TRUE; + } + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool Max8907bRtcI2cWriteTime( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 Data) +{ + NvU32 i; + NvU8 WriteBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo; + + NVODMPMU_PRINTF(("\n RTC I2C write: Addr=0x%x, Data=0x%x ", Addr, Data)); + for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) + { + WriteBuffer[0] = (NvU8)(Addr & 0xFF); + WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF); + WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF); + WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF); + WriteBuffer[4] = (NvU8)(Data & 0xFF); + + TransactionInfo.Address = MAX8907B_RTC_SLAVE_ADDR; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 5; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (status == NvOdmI2cStatus_Success) + return NV_TRUE; + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("Max8907bRtcI2cWrite32 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("Max8907bRtcI2cWrite32 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool Max8907bRtcI2cReadTime( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 *Data) +{ + NvU32 i; + NvU8 ReadBuffer[4]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[MAX_TRANSACTION_COUNT]; + + NVODMPMU_PRINTF(("\n RTC I2C read: Addr=0x%x ", Addr)); + for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) + { + NvU32 TransactionCount = 0; + ReadBuffer[0] = Addr & 0xFF; + + TransactionInfo[TransactionCount].Address = MAX8907B_RTC_SLAVE_ADDR; + TransactionInfo[TransactionCount].Buf = &ReadBuffer[0]; + TransactionInfo[TransactionCount].Flags = + NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START; + TransactionInfo[TransactionCount++].NumBytes = 1; + + // Seconds / day + if (TransactionCount >= MAX_TRANSACTION_COUNT) + return NV_FALSE; + TransactionInfo[TransactionCount].Address = + (MAX8907B_RTC_SLAVE_ADDR | 0x1); + TransactionInfo[TransactionCount].Buf = &ReadBuffer[0]; + TransactionInfo[TransactionCount].Flags = 0; + TransactionInfo[TransactionCount++].NumBytes = 1; + + // Minutes / month + if (TransactionCount >= MAX_TRANSACTION_COUNT) + return NV_FALSE; + TransactionInfo[TransactionCount].Address = + (MAX8907B_RTC_SLAVE_ADDR | 0x1); + TransactionInfo[TransactionCount].Buf = &ReadBuffer[1]; + TransactionInfo[TransactionCount].Flags = 0; + TransactionInfo[TransactionCount++].NumBytes = 1; + + // Hours / YY1 + if (TransactionCount >= MAX_TRANSACTION_COUNT) + return NV_FALSE; + TransactionInfo[TransactionCount].Address = + (MAX8907B_RTC_SLAVE_ADDR | 0x1); + TransactionInfo[TransactionCount].Buf = &ReadBuffer[2]; + TransactionInfo[TransactionCount].Flags = 0; + TransactionInfo[TransactionCount++].NumBytes = 1; + + // Weekday / YY2 + if (TransactionCount >= MAX_TRANSACTION_COUNT) + return NV_FALSE; + TransactionInfo[TransactionCount].Address = + (MAX8907B_RTC_SLAVE_ADDR | 0x1); + TransactionInfo[TransactionCount].Buf = &ReadBuffer[3]; + TransactionInfo[TransactionCount].Flags = 0; + TransactionInfo[TransactionCount++].NumBytes = 1; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], + TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) | + (ReadBuffer[2] << 8) | ReadBuffer[3]; + + return NV_TRUE; + } + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("Max8907bRtcI2cRead32 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("Max8907bRtcI2cRead32 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h new file mode 100644 index 000000000000..c4b5c634c4fa --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 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_NVODM_PMU_MAX8907B_I2C_H +#define INCLUDED_NVODM_PMU_MAX8907B_I2C_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// Constant definition +// #define PMU_MAX8907B_DEVADDR TBD +#define PMU_MAX8907B_I2C_SPEED_KHZ 400 + +// Function declaration +NvBool Max8907bI2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data); + +NvBool Max8907bI2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data); + +NvBool Max8907bI2cWrite32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 Data); + +NvBool Max8907bI2cRead32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 *Data); + +NvBool Max8907bRtcI2cWriteTime( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 Data); + +NvBool Max8907bRtcI2cReadTime( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 *Data); + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_PMU_MAX8907B_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c new file mode 100644 index 000000000000..38110f83c5a0 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c @@ -0,0 +1,172 @@ +/* + * Copyright (c) 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 "max8907b.h" +#include "max8907b_interrupt.h" +#include "max8907b_i2c.h" +#include "max8907b_reg.h" +#include "max8907b_batterycharger.h" +#include "nvodm_services.h" + +NvBool +Max8907bSetupInterrupt( + NvOdmPmuDeviceHandle hDevice, + Max8907bStatus *pmuStatus) +{ + NvBool status = NV_FALSE; + NvU8 data = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pmuStatus); + + /* Init Pmu Status */ + pmuStatus->lowBatt = NV_FALSE; + pmuStatus->highTemp = NV_FALSE; + + if (!Max8907bBatteryChargerMainBatt(hDevice, &status)) + return NV_FALSE; + pmuStatus->mChgPresent = status; + + /* Set up Interrupt Mask */ + + // CHG_IRQ1 + data = 0; + if (!Max8907bI2cWrite8(hDevice, MAX8907B_CHG_IRQ1, data)) + return NV_FALSE; + + // CHG_IRQ2 + data = MAX8907B_CHG_IRQ2_CHG_DONE_MASK | + MAX8907B_CHG_IRQ2_MBATTLOW_F_SHIFT | + MAX8907B_CHG_IRQ2_THM_OK_F_MASK | + MAX8907B_CHG_IRQ2_THM_OK_R_MASK ; + if (!Max8907bI2cWrite8(hDevice, MAX8907B_CHG_IRQ2, data)) + return NV_FALSE; + + // ON_OFF_IRQ1 + data = 0; + if (!Max8907bI2cWrite8(hDevice, MAX8907B_ON_OFF_IRQ1, data)) + return NV_FALSE; + + // ON_OFF_IRQ2 + data = 0; + if (!Max8907bI2cWrite8(hDevice, MAX8907B_ON_OFF_IRQ2, data)) + return NV_FALSE; + + // RTC_IRQ + data = 0; + if (!Max8907bI2cWrite8(hDevice, MAX8907B_RTC_IRQ, data)) + return NV_FALSE; + + return NV_TRUE; +} + +void +Max8907bInterruptHandler_int( + NvOdmPmuDeviceHandle hDevice, + Max8907bStatus *pmuStatus) +{ + NvU8 data = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pmuStatus); + + /* Check which interrupt... */ + + // CHG_IRQ1 + if (!Max8907bI2cRead8(hDevice, MAX8907B_CHG_IRQ1, &data)) + { + return; + } + + if (data) + { + // VBUS connect interrupt + if (data & + (MAX8907B_CHG_IRQ1_VCHG_R_MASK << MAX8907B_CHG_IRQ1_VCHG_R_SHIFT)) + { + NvOdmEnableOtgCircuitry(NV_TRUE); + } + // VBUS dis-connect interrupt + else if (data & + (MAX8907B_CHG_IRQ1_VCHG_F_MASK << MAX8907B_CHG_IRQ1_VCHG_F_SHIFT)) + { + NvOdmEnableOtgCircuitry(NV_FALSE); + } + } + + // CHG_IRQ2 + if (!Max8907bI2cRead8(hDevice, MAX8907B_CHG_IRQ2, &data)) + { + return; + } + if (data) + { + if (data & MAX8907B_CHG_IRQ2_CHG_DONE_MASK) + { + pmuStatus->mChgPresent = NV_TRUE; + pmuStatus->batFull = NV_TRUE; + } + if (data & MAX8907B_CHG_IRQ2_MBATTLOW_F_SHIFT) + { + pmuStatus->batFull = NV_FALSE; + } + if (data & MAX8907B_CHG_IRQ2_THM_OK_F_MASK) + { + pmuStatus->highTemp = NV_TRUE; + } + if (data & MAX8907B_CHG_IRQ2_THM_OK_R_MASK) + { + pmuStatus->highTemp = NV_FALSE; + } + } + + // ON_OFF_IRQ1 + if (!Max8907bI2cRead8(hDevice, MAX8907B_ON_OFF_IRQ1, &data)) + { + return; + } + + // ON_OFF_IRQ2 + if (!Max8907bI2cRead8(hDevice, MAX8907B_ON_OFF_IRQ2, &data)) + { + return; + } + + // RTC_IRQ + if (!Max8907bI2cRead8(hDevice, MAX8907B_RTC_IRQ, &data)) + { + return; + } + + return; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h new file mode 100644 index 000000000000..a00cabc17039 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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_MAX8907B_INTERRUPT_HEADER +#define INCLUDED_MAX8907B_INTERRUPT_HEADER + +#include "max8907b.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +NvBool +Max8907bSetupInterrupt( + NvOdmPmuDeviceHandle hDevice, + Max8907bStatus *pmuStatus); + +void +Max8907bInterruptHandler_int( + NvOdmPmuDeviceHandle hDevice, + Max8907bStatus *pmuStatus); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_MAX8907B_INTERRUPT_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h new file mode 100644 index 000000000000..513e2f6a1812 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h @@ -0,0 +1,398 @@ +/* + * Copyright (c) 2009-2010 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_MAX8907B_REG_HEADER +#define INCLUDED_MAX8907B_REG_HEADER + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// -- MAX8907B Addresses (See Table 71 of data sheet) -- + +/* MAX8907B Slave Addresses */ + +#define MAX8907B_PMU_SLAVE_ADDR 0x78 +#define MAX8907B_RTC_SLAVE_ADDR 0xD0 +#define MAX8907B_ADC_SLAVE_ADDR 0x8E + +/* MAX8907B Register Addresses */ + +// Main-Battery Charger +#define MAX8907B_CHG_CNTL1 0x7C +#define MAX8907B_CHG_CNTL2 0x7D +#define MAX8907B_CHG_IRQ1 0x7E +#define MAX8907B_CHG_IRQ2 0x7F +#define MAX8907B_CHG_IRQ1_MASK 0x80 +#define MAX8907B_CHG_IRQ2_MASK 0x81 +#define MAX8907B_CHG_STAT 0x82 + +// Backup-Battery Charger +#define MAX8907B_BBATT_CNFG 0x78 +#define MAX8907B_SDBYSEQCNT 0x13 + +// V1 Step Down Regulator +#define MAX8907B_SDCTL1 0x04 +#define MAX8907B_SDSEQCNT1 0x05 +#define MAX8907B_SDV1 0x06 + +// V2 Step Down Regulator +#define MAX8907B_SDCTL2 0x07 +#define MAX8907B_SDSEQCNT2 0x08 +#define MAX8907B_SDV2 0x09 + +// V3 Step Down Regulator +#define MAX8907B_SDCTL3 0x0A +#define MAX8907B_SDSEQCNT3 0x0B +#define MAX8907B_SDV3 0x0C + +// LDO1 Regulator +#define MAX8907B_LDOCTL1 0x18 +#define MAX8907B_LDOSEQCNT1 0x19 +#define MAX8907B_LDO1VOUT 0x1A + +// LDO2 Regulator +#define MAX8907B_LDOCTL2 0x1C +#define MAX8907B_LDOSEQCNT2 0x1D +#define MAX8907B_LDO2VOUT 0x1E + +// LDO3 Regulator +#define MAX8907B_LDOCTL3 0x20 +#define MAX8907B_LDOSEQCNT3 0x21 +#define MAX8907B_LDO3VOUT 0x22 + +// LDO4 Regulator +#define MAX8907B_LDOCTL4 0x24 +#define MAX8907B_LDOSEQCNT4 0x25 +#define MAX8907B_LDO4VOUT 0x26 + +// LDO5 Regulator +#define MAX8907B_LDOCTL5 0x28 +#define MAX8907B_LDOSEQCNT5 0x29 +#define MAX8907B_LDO5VOUT 0x2A + +// LDO6 Regulator +#define MAX8907B_LDOCTL6 0x2C +#define MAX8907B_LDOSEQCNT6 0x2D +#define MAX8907B_LDO6VOUT 0x2E + +// LDO7 Regulator +#define MAX8907B_LDOCTL7 0x30 +#define MAX8907B_LDOSEQCNT7 0x31 +#define MAX8907B_LDO7VOUT 0x32 + +// LDO8 Regulator +#define MAX8907B_LDOCTL8 0x34 +#define MAX8907B_LDOSEQCNT8 0X35 +#define MAX8907B_LDO8VOUT 0x36 + +// LDO9 Regulator +#define MAX8907B_LDOCTL9 0x38 +#define MAX8907B_LDOSEQCNT9 0x39 +#define MAX8907B_LDO9VOUT 0x3A + +// LDO10 Regulator +#define MAX8907B_LDOCTL10 0x3C +#define MAX8907B_LDOSEQCNT10 0x3D +#define MAX8907B_LDO10VOUT 0x3E + +// LDO11 Regulator +#define MAX8907B_LDOCTL11 0x40 +#define MAX8907B_LDOSEQCNT11 0x41 +#define MAX8907B_LDO11VOUT 0x42 + +// LDO12 Regulator +#define MAX8907B_LDOCTL12 0x44 +#define MAX8907B_LDOSEQCNT12 0x45 +#define MAX8907B_LDO12VOUT 0x46 + +// LDO13 Regulator +#define MAX8907B_LDOCTL13 0x48 +#define MAX8907B_LDOSEQCNT13 0x49 +#define MAX8907B_LDO13VOUT 0x4A + +// LDO14 Regulator +#define MAX8907B_LDOCTL14 0x4C +#define MAX8907B_LDOSEQCNT14 0x4D +#define MAX8907B_LDO14VOUT 0x4E + +// LDO15 Regulator +#define MAX8907B_LDOCTL15 0x50 +#define MAX8907B_LDOSEQCNT15 0x51 +#define MAX8907B_LDO15VOUT 0x52 + +// LDO16 Regulator +#define MAX8907B_LDOCTL16 0x10 +#define MAX8907B_LDOSEQCNT16 0x11 +#define MAX8907B_LDO16VOUT 0x12 + +// LDO17 Regulator +#define MAX8907B_LDOCTL17 0x14 +#define MAX8907B_LDOSEQCNT17 0x15 +#define MAX8907B_LDO17VOUT 0x16 + +// LDO18 Regulator +#define MAX8907B_LDOCTL18 0x72 +#define MAX8907B_LDOSEQCNT18 0x73 +#define MAX8907B_LDO18VOUT 0x74 + +// LDO19 Regulator +#define MAX8907B_LDOCTL19 0x5C +#define MAX8907B_LDOSEQCNT19 0x5D +#define MAX8907B_LDO19VOUT 0x5E + +// LDO20 Regulator +#define MAX8907B_LDOCTL20 0x9C +#define MAX8907B_LDOSEQCNT20 0x9D +#define MAX8907B_LDO20VOUT 0x9E + +// OUT5V Regulator +#define MAX8907B_OUT5VEN 0x54 +#define MAX8907B_OUT5VSEQ 0x55 + +// OUT3.3V Regulator +#define MAX8907B_OUT_3_3VEN 0x58 +#define MAX8907B_OUT_3_3VSEQ 0x59 + +// Main Bias Register +#define MAX8907B_LBCNFG 0x60 + +// ON/OFF Controller +#define MAX8907B_SYSENSEL 0x00 +#define MAX8907B_ON_OFF_IRQ1 0x01 +#define MAX8907B_ON_OFF_IRQ1_MASK 0x02 +#define MAX8907B_ON_OFF_STAT 0x03 +#define MAX8907B_ON_OFF_IRQ2 0x0D +#define MAX8907B_ON_OFF_IRQ2_MASK 0x0E +#define MAX8907B_RESET_CNFG 0x0F + +// Flexible Power Sequencer +#define MAX8907B_SEQ1CNFG 0x64 +#define MAX8907B_SEQ2CNFG 0x65 +#define MAX8907B_SEQ3CNFG 0x66 +#define MAX8907B_SEQ4CNFG 0x67 +#define MAX8907B_SEQ5CNFG 0x68 +#define MAX8907B_SEQ6CNFG 0x69 +#define MAX8907B_SEQ7CNFG 0x6A + +// RTC Registers +#define MAX8907B_RTC_SEC 0x00 +#define MAX8907B_RTC_MIN 0x01 +#define MAX8907B_RTC_HOURS 0x02 +#define MAX8907B_RTC_WEEKDAY 0x03 +#define MAX8907B_RTC_DATE 0x04 +#define MAX8907B_RTC_MONTH 0x05 +#define MAX8907B_RTC_YEAR1 0x06 +#define MAX8907B_RTC_YEAR2 0x07 +#define MAX8907B_ALARM0_SEC 0x08 +#define MAX8907B_ALARM0_MIN 0x09 +#define MAX8907B_ALARM0_HOURS 0x0A +#define MAX8907B_ALARM0_WEEKDAY 0x0B +#define MAX8907B_ALARM0_DATE 0x0C +#define MAX8907B_ALARM0_MONTH 0x0D +#define MAX8907B_ALARM0_YEAR1 0x0E +#define MAX8907B_ALARM0_YEAR2 0x0F +#define MAX8907B_ALARM1_SEC 0x10 +#define MAX8907B_ALARM1_MIN 0x11 +#define MAX8907B_ALARM1_HOURS 0x12 +#define MAX8907B_ALARM1_WEEKDAY 0x13 +#define MAX8907B_ALARM1_DATE 0x14 +#define MAX8907B_ALARM1_MONTH 0x15 +#define MAX8907B_ALARM1_YEAR1 0x16 +#define MAX8907B_ALARM1_YEAR2 0x17 +#define MAX8907B_ALARM0_CNTL 0x18 +#define MAX8907B_ALARM1_CNTL 0x19 +#define MAX8907B_RTC_STATUS 0x1A +#define MAX8907B_RTC_CNTL 0x1B +#define MAX8907B_RTC_IRQ 0x1C +#define MAX8907B_RTC_IRQ_MASK 0x1D +#define MAX8907B_MPL_CNTL 0x1E + +// ADC and Touch Screen Controller +#define MAX8907B_TSC_STA_INT 0x00 +#define MAX8907B_TSC_INT_MASK 0x01 +#define MAX8907B_TSC_CNFG1 0x02 +#define MAX8907B_TSC_CNFG2 0x03 +#define MAX8907B_TSC_CNFG3 0x04 +#define MAX8907B_ADC_RES_CNFG1 0x06 +#define MAX8907B_ADC_AVG_CNFG1 0x07 +#define MAX8907B_ADC_ACQ_CNFG1 0x08 +#define MAX8907B_ADC_ACQ_CNFG2 0x09 +#define MAX8907B_ADC_SCHED 0x10 +#define MAX8907B_X_MSB 0x50 +#define MAX8907B_X_LSB 0x51 +#define MAX8907B_Y_MSB 0x52 +#define MAX8907B_Y_LSB 0x53 +#define MAX8907B_Z1_MSB 0x54 +#define MAX8907B_Z1_LSB 0x55 +#define MAX8907B_Z2_MSB 0x56 +#define MAX8907B_Z2_LSB 0x57 +#define MAX8907B_AUX1_MSB 0x60 +#define MAX8907B_AUX1_LSB 0x61 +#define MAX8907B_AUX2_MSB 0x62 +#define MAX8907B_AUX2_LSB 0x63 +#define MAX8907B_VCHG_MSB 0x64 +#define MAX8907B_VCHG_LSB 0x65 +#define MAX8907B_VBBATT_MSB 0x66 +#define MAX8907B_VBBATT_LSB 0x67 +#define MAX8907B_VMBATT_MSB 0x68 +#define MAX8907B_VMBATT_LSB 0x69 +#define MAX8907B_ISNS_MSB 0x6A +#define MAX8907B_ISNS_LSB 0x6B +#define MAX8907B_THM_MSB 0x6C +#define MAX8907B_THM_LSB 0x6D +#define MAX8907B_TDIE_MSB 0x6E +#define MAX8907B_TDIE_LSB 0x6F + +// WLED Driver +#define MAX8907B_WLED_MODE_CNTL 0x84 +#define MAX8907B_ILED_CNTL 0x85 + +// Chip Identification +#define MAX8907B_II1RR 0x8E +#define MAX8907B_II2RR 0x8F + +#define MAX8907B_REG_INVALID 0xFF + +/* field defines for register bit ops */ +#define MAX8907B_OUT_VOLTAGE_MASK 0x3F +#define MAX8907B_OUT_VOLTAGE_ENABLE_BIT 0x01 +#define MAX8907B_OUT_VOLTAGE_DISABLE_MASK 0x3E + +#define MAX8907B_CTL_SEQ_SHIFT 0x02 +#define MAX8907B_CTL_SEQ_MASK 0x07 + +// CHG_CNTL_1 +#define MAX8907B_CHG_CNTL1_NOT_CHGEN_SHIFT 0x7 +#define MAX8907B_CHG_CNTL1_NOT_CHGEN_MASK 0x1 +#define MAX8907B_CHG_CNTL1_CHG_TOPOFF_SHIFT 0x5 +#define MAX8907B_CHG_CNTL1_CHG_TOPOFF_MASK 0x3 +#define MAX8907B_CHG_CNTL1_CHG_RST_HYS_SHIFT 0x3 +#define MAX8907B_CHG_CNTL1_CHG_RST_HYS_MASK 0x3 +#define MAX8907B_CHG_CNTL1_FCHG_SHIFT 0x0 +#define MAX8907B_CHG_CNTL1_FCHG_MASK 0x7 + +#define MAX8907B_CHG_CNTL1_FCHG_85MA 0 +#define MAX8907B_CHG_CNTL1_FCHG_300MA 1 +#define MAX8907B_CHG_CNTL1_FCHG_460MA 2 +#define MAX8907B_CHG_CNTL1_FCHG_600MA 3 +#define MAX8907B_CHG_CNTL1_FCHG_700MA 4 +#define MAX8907B_CHG_CNTL1_FCHG_800MA 5 +#define MAX8907B_CHG_CNTL1_FCHG_900MA 6 +#define MAX8907B_CHG_CNTL1_FCHG_1000MA 7 + +// CHG_CNTL_1 +#define MAX8907B_CHG_CNTL2_FCHG_TMR_SHIFT 0x4 +#define MAX8907B_CHG_CNTL2_FCHG_TMR_MASK 0x3 +#define MAX8907B_CHG_CNTL2_MBAT_REG_TH_SHIFT 0x3 +#define MAX8907B_CHG_CNTL2_MBAT_REG_TH_MASK 0x1 +#define MAX8907B_CHG_CNTL2_TDIE_THERM_REG_SHIFT 0x0 +#define MAX8907B_CHG_CNTL2_TDIE_THERM_REG_MASK 0x3 + +// Interrupts +#define MAX8907B_CHG_STAT_VCHG_OK_SHIFT 0x7 +#define MAX8907B_CHG_STAT_VCHG_OK_MASK 0x1 +#define MAX8907B_CHG_STAT_CHG_TMR_FLT_SHIFT 0x5 +#define MAX8907B_CHG_STAT_CHG_TMR_FLT_MASK 0x1 +#define MAX8907B_CHG_STAT_CHG_EN_STAT_SHIFT 0x4 +#define MAX8907B_CHG_STAT_CHG_EN_STAT_MASK 0x1 +#define MAX8907B_CHG_STAT_CHG_MODE_SHIFT 0x2 +#define MAX8907B_CHG_STAT_CHG_MODE_MASK 0x3 +#define MAX8907B_CHG_STAT_MBDET_SHIFT 0x1 +#define MAX8907B_CHG_STAT_MBDET_MASK 0x1 +#define MAX8907B_CHG_STAT_MBATTLOW_SHIFT 0x0 +#define MAX8907B_CHG_STAT_MBATTLOW_MASK 0x1 + +#define MAX8907B_CHG_IRQ1_VCHG_R_SHIFT 0x2 +#define MAX8907B_CHG_IRQ1_VCHG_R_MASK 0x1 +#define MAX8907B_CHG_IRQ1_VCHG_F_SHIFT 0x1 +#define MAX8907B_CHG_IRQ1_VCHG_F_MASK 0x1 +#define MAX8907B_CHG_IRQ1_VCHG_OVP_SHIFT 0x0 +#define MAX8907B_CHG_IRQ1_VCHG_OVP_MASK 0x1 + +#define MAX8907B_CHG_IRQ2_CHG_TMR_FAULT_SHIFT 0x7 +#define MAX8907B_CHG_IRQ2_CHG_TMR_FAULT_MASK 0x1 +#define MAX8907B_CHG_IRQ2_CHG_TOPOFF_SHIFT 0x6 +#define MAX8907B_CHG_IRQ2_CHG_TOPOFF_MASK 0x1 +#define MAX8907B_CHG_IRQ2_CHG_DONE_SHIFT 0x5 +#define MAX8907B_CHG_IRQ2_CHG_DONE_MASK 0x1 +#define MAX8907B_CHG_IRQ2_CHG_RST_SHIFT 0x4 +#define MAX8907B_CHG_IRQ2_CHG_RST_MASK 0x1 +#define MAX8907B_CHG_IRQ2_MBATTLOW_R_SHIFT 0x3 +#define MAX8907B_CHG_IRQ2_MBATTLOW_R_MASK 0x1 +#define MAX8907B_CHG_IRQ2_MBATTLOW_F_SHIFT 0x2 +#define MAX8907B_CHG_IRQ2_MBATTLOW_F_MASK 0x1 +#define MAX8907B_CHG_IRQ2_THM_OK_F_SHIFT 0x1 +#define MAX8907B_CHG_IRQ2_THM_OK_F_MASK 0x1 +#define MAX8907B_CHG_IRQ2_THM_OK_R_SHIFT 0x0 +#define MAX8907B_CHG_IRQ2_THM_OK_R_MASK 0x1 + +#define MAX8907B_ON_OFF_IRQ1_SW_R_SHIFT 0x7 +#define MAX8907B_ON_OFF_IRQ1_SW_R_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_SW_F_SHIFT 0x6 +#define MAX8907B_ON_OFF_IRQ1_SW_F_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_SW_1SEC_SHIFT 0x5 +#define MAX8907B_ON_OFF_IRQ1_SW_1SEC_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_EXTON_R_SHIFT 0x4 +#define MAX8907B_ON_OFF_IRQ1_EXTON_R_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_EXTON_F_SHIFT 0x3 +#define MAX8907B_ON_OFF_IRQ1_EXTON_F_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_SW_3SEC_SHIFT 0x2 +#define MAX8907B_ON_OFF_IRQ1_SW_3SEC_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_MPL_EVENT_SHIFT 0x1 +#define MAX8907B_ON_OFF_IRQ1_MPL_EVENT_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ1_RSTIN_F_SHIFT 0x0 +#define MAX8907B_ON_OFF_IRQ1_RSTIN_F_MASK 0x1 + +#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_R_SHIFT 0x1 +#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_R_MASK 0x1 +#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_F_SHIFT 0x0 +#define MAX8907B_ON_OFF_IRQ2_SYSCKEN_F_MASK 0x1 + +#define MAX8907B_RTC_IRQ_ALARM0_R_SHIFT 0x3 +#define MAX8907B_RTC_IRQ_ALARM0_R_MASK 0x1 +#define MAX8907B_RTC_IRQ_ALARM1_R_SHIFT 0x2 +#define MAX8907B_RTC_IRQ_ALARM1_R_MASK 0x1 + +// ON/OFF controller +#define MAX8907B_SYSENSEL_HRDSTEN_SHIFT 0x7 +#define MAX8907B_SYSENSEL_HRDSTEN_MASK 0x1 + +#define MAX8907B_RESET_CNFG_PWREN_EN_SHIFT 0x7 +#define MAX8907B_RESET_CNFG_PWREN_EN_MASK 0x1 + +#if defined(__cplusplus) +} +#endif + +#endif //INCLUDED_MAX8907B_REG_HEADER diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c new file mode 100644 index 000000000000..1c4d61a01a98 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 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 <linux/time.h> +#include <linux/rtc.h> +#include "max8907b.h" +#include "max8907b_rtc.h" +#include "max8907b_i2c.h" +#include "max8907b_reg.h" + +/** +* The Maxim 8907B does not have an RTC that simply counts +* seconds from some time t0 (as defined by the OS API). +* Instead, this RTC contains several BCD (Binary Coded Decimal) +* registers, including: seconds, minutes, hours, days, day of +* week, date, etc... These registers account for leap year and +* the various days of the month as well. +* +* Since the OS interpretation of seconds to a particular +* date/time from some OS-defined t0 is unknown at this level of +* the implementation, it is not possible to translate the given +* seconds into these registers (at least, not without a +* dependency on some OS-specific information). +* +*/ + +#define MAX8907B_SECONDS_PER_DAY (60*60*24) +#define MAX8907B_SECONDS_PER_HOUR (60*60) +#define MAX8907B_SECONDS_PER_MINUTE (60) + +#define LINUX_RTC_BASE_YEAR 1900 + +/* Macro for conversion of BCD number to decimal format */ +#define BCD_TO_DECIMAL(BCD) \ + ((((BCD) & 0xF0) >> 4) * 10 + ((BCD) & 0xF)) +/* Macro for conversion of decimal number to BCD format */ +#define DECIMAL_TO_BCD(DEC) \ + ((((DEC) / 10) << 4) | ((DEC) % 10)) + +static NvBool bRtcNotInitialized = NV_TRUE; + +NvBool +Max8907bRtcCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + NvU32 data = 0; + NvU32 BcdHours, BcdMinutes, BcdSeconds; + NvU32 Hours, Minutes, Seconds; + NvU32 BcdDD, BcdMM, BcdYY1, BcdYY2; + NvU32 DD, MM, YY1, YY2, YYYY; +#if NV_DEBUG + struct rtc_time tm; +#endif + + *Count = 0; + // Read seconds, minute, hour and weekday data from RTC registers + if (Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_SEC, &data)) + { + NVODMPMU_PRINTF(("\n Read time data-sec=0x%x ", data)); + // Extract seconds, minute and hour data from RTC registers read + BcdHours = (data >> 8) & 0xFF; + BcdMinutes = (data >> 16) & 0xFF; + BcdSeconds = (data >> 24) & 0xFF; + + // Convert BCD time into decimal values + Hours = BCD_TO_DECIMAL(BcdHours); + Minutes = BCD_TO_DECIMAL(BcdMinutes); + Seconds = BCD_TO_DECIMAL(BcdSeconds); + + // Read day, month, yy1 and yy2 data from RTC registers + if (Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_DATE, &data)) + { + NVODMPMU_PRINTF(("\n Read time data-year=0x%x ", data)); + // Extract day, month, yy1 and yy2 data from RTC registers read + BcdYY2 = (data & 0xFF); + BcdYY1 = (data >> 8) & 0xFF; + BcdMM = (data >> 16) & 0xFF; + BcdDD = (data >> 24) & 0xFF; + // convert bcd day/month/year data to decimal values + YY2 = BCD_TO_DECIMAL(BcdYY2); + YY1 = BCD_TO_DECIMAL(BcdYY1); + YYYY = (YY2 * 100 + YY1) & 0xFFFF; + MM = BCD_TO_DECIMAL(BcdMM); + DD = BCD_TO_DECIMAL(BcdDD); + // get seconds since reference time value given + // year, month, day, hour, minutes and seconds + // NOTE: Using linux specific API mktime for conversion + *Count = mktime(YYYY, (MM + 1), DD, Hours, Minutes, Seconds); + NVODMPMU_PRINTF(("\n Rtc read count=0x%x ", *Count)); + NVODMPMU_PRINTF(("\n mktime: YYYY=%d MM=%d DD=%d Hr=%d Min=%d " + "Sec=%d, *Count=0x%x ", YYYY, (MM + 1), DD, Hours, Minutes, + Seconds, *Count)); +#if NV_DEBUG + // Call to verify that reverse conversion of seconds matches date + rtc_time_to_tm(*Count, &tm); + // Check if Local_rtc_time_to_tm can return values sent to mktime + NVODMPMU_PRINTF(("\n rtc_time_to_tm: YYYY=%d MM=%d DD=%d Hr=%d " + "Min=%d Sec=%d, *Count=0x%x ", (tm.tm_year + + LINUX_RTC_BASE_YEAR), tm.tm_mon, tm.tm_mday, tm.tm_hour, + tm.tm_min, tm.tm_sec, *Count)); +#endif + } + else + { + NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. ")); + return NV_FALSE; + } + } + else + { + NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. ")); + return NV_FALSE; + } + NVODMPMU_PRINTF(("\n *Count=0x%x ", *Count)); + return NV_TRUE; +} + +NvBool +Max8907bRtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + return NV_FALSE; +} + +NvBool +Max8907bRtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + NvU32 BcdHours, BcdMinutes, BcdSeconds; + NvU32 data = 0; + NvU8 BcdDD, BcdMM, BcdYY1, BcdYY2; + NvU16 YYYY; + struct rtc_time tm; +#if NV_DEBUG + NvU32 data1; +#endif + + NVODMPMU_PRINTF(("\n Rtc write count=0x%x ", Count)); + // convert seconds since reference time into date + // NOTE: using linux specific convert function rtc_time_to_tm + rtc_time_to_tm(Count, &tm); + NVODMPMU_PRINTF(("\n rtc_time_to_tm: YYYY=%d MM=%d DD=%d Hr=%d Min=%d " + "Sec=%d, *Count=0x%x ", (tm.tm_year + LINUX_RTC_BASE_YEAR), + (tm.tm_mon + 1), tm.tm_mday, + tm.tm_hour, tm.tm_min, tm.tm_sec, Count)); + + // Convert time to bcd format + BcdHours = DECIMAL_TO_BCD(tm.tm_hour); + BcdMinutes = DECIMAL_TO_BCD(tm.tm_min); + BcdSeconds = DECIMAL_TO_BCD(tm.tm_sec); + + data = (BcdSeconds << 24) | (BcdMinutes << 16) | (BcdHours << 8); + // write time - seconds, minutes and hours in a day to RTC registers + if (Max8907bRtcI2cWriteTime(hDevice, MAX8907B_RTC_SEC, data)) + { + // set the day, month, year + // Assuming we get the days since 1 Jan 1970 + + // convert date to bcd format + BcdDD = DECIMAL_TO_BCD((NvU8)tm.tm_mday); + BcdMM = DECIMAL_TO_BCD((NvU8)tm.tm_mon); + YYYY = (NvU16)tm.tm_year + LINUX_RTC_BASE_YEAR; + BcdYY1 = DECIMAL_TO_BCD((NvU8)(YYYY % 100)); + BcdYY2 = DECIMAL_TO_BCD((NvU8)(YYYY / 100)); + data = (NvU32)((BcdDD << 24) | (BcdMM << 16) | (BcdYY1 << 8) | BcdYY2); + // write date - day, month, and year to RTC registers + if (!(Max8907bRtcI2cWriteTime(hDevice, MAX8907B_RTC_DATE, data))) + { + NVODMPMU_PRINTF(("\n Max8907bRtcCountWrite() error. ")); + return NV_FALSE; + } +#if NV_DEBUG + // verify that read back values from RTC matches written values + if (!(Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_DATE, &data1))) + { + NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. ")); + return NV_FALSE; + } + if (data1 == data) + { + NVODMPMU_PRINTF(("\n Write read Success. ")); + return NV_TRUE; + } + else + { + // return error when read data does not match written data + NVODMPMU_PRINTF(("\n Error: write data=0x%x, rd data=0x%x. ", data, data1)); + return NV_FALSE; + } +#endif + } + else + { + NVODMPMU_PRINTF(("\n Max8907bRtcCountWrite() error. ")); + return NV_FALSE; + } + + return NV_TRUE; +} + +NvBool +Max8907bRtcAlarmCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + return NV_FALSE; +} + +NvBool +Max8907bRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice) +{ + return NV_FALSE; +} + +NvBool +Max8907bRtcAlarmIntEnable( + NvOdmPmuDeviceHandle hDevice, + NvBool Enable) +{ + return NV_FALSE; +} + +NvBool +Max8907bIsRtcInitialized(NvOdmPmuDeviceHandle hDevice) +{ + return (!bRtcNotInitialized); +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h new file mode 100644 index 000000000000..0baa0de55339 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 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_MAX8907B_RTC_HEADER +#define INCLUDED_MAX8907B_RTC_HEADER + +#include "pmu_hal.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Read RTC count register */ + +NvBool +Max8907bRtcCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/* Read RTC alarm count register */ + +NvBool +Max8907bRtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/* Write RTC count register */ + +NvBool +Max8907bRtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/* Write RTC alarm count register */ + +NvBool +Max8907bRtcAlarmCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/* Reads RTC alarm interrupt mask status */ + +NvBool +Max8907bRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice); + +/* Enables / Disables the RTC alarm interrupt */ + +NvBool +Max8907bRtcAlarmIntEnable( + NvOdmPmuDeviceHandle hDevice, + NvBool Enable); + +/* Checks if boot was from nopower / powered state */ + +NvBool +Max8907bRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice); + +NvBool +Max8907bIsRtcInitialized(NvOdmPmuDeviceHandle hDevice); + + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_MAX8907B_RTC_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h new file mode 100644 index 000000000000..1b362aac43f4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h @@ -0,0 +1,197 @@ +/* + * Copyright (c) 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_MAX8907B_SUPPLY_INFO_HEADER +#define INCLUDED_MAX8907B_SUPPLY_INFO_HEADER + +#include "nvodm_pmu.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// Defines for the requested voltage for each supply (mV). +// This is board specific and ODM should change this based on device. +#define MAX8907B_REQUESTVOLTAGE_LX_V1 1000 +#define MAX8907B_REQUESTVOLTAGE_LX_V2 1200 +#define MAX8907B_REQUESTVOLTAGE_LX_V3 1800 + +#define MAX8907B_REQUESTVOLTAGE_LDO1 3300 +#define MAX8907B_REQUESTVOLTAGE_LDO2 1100 +#define MAX8907B_REQUESTVOLTAGE_LDO3 1800 +#define MAX8907B_REQUESTVOLTAGE_LDO4 3300 +#define MAX8907B_REQUESTVOLTAGE_LDO5 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO6 1800 +#define MAX8907B_REQUESTVOLTAGE_LDO7 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO8 3000 +#define MAX8907B_REQUESTVOLTAGE_LDO9 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO10 3000 +#define MAX8907B_REQUESTVOLTAGE_LDO11 3300 +#define MAX8907B_REQUESTVOLTAGE_LDO12 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO13 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO14 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO15 3300 +#define MAX8907B_REQUESTVOLTAGE_LDO16 1300 +#define MAX8907B_REQUESTVOLTAGE_LDO17 1200 +#define MAX8907B_REQUESTVOLTAGE_LDO18 1800 +#define MAX8907B_REQUESTVOLTAGE_LDO19 2800 +#define MAX8907B_REQUESTVOLTAGE_LDO20 1200 + +#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_1 5000 // Fixed +#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_2 0 // Reserved +#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_3 1050 // Fixed (unless FAN5355 is enabled) +#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_4 0 // VBL1, controlled by display adaptation +#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_5 0 // VBL2, controlled by display adaptation +#define MAX8907B_REQUESTVOLTAGE_EXT_DCDC_6 0 // Reserved + +#define MAX8907B_REQUESTVOLTAGE_SDBY 1100 + +// Defines default sequencer selection +#define MAX8907B_SEQSEL_DEFAULT_LX_V1 0 /* SEQ1 (SYSEN) */ +#define MAX8907B_SEQSEL_DEFAULT_LX_V2 0 /* SEQ1 (SYSEN) */ + +// Defines common for all supplies PWREN sequencer selection +#define MAX8907B_SEQSEL_PWREN_LXX 1 /* SEQ2 (PWREN) */ + +// Defines common for all supplies I2C (s/w) sequencer selection +#define MAX8907B_SEQSEL_I2CEN_LXX 7 /* I2CEN (s/w) */ + +// Defines sequencer count default values +#define MAX8907B_SEQCNT_DEFAULT_LX_V1 0x1C +#define MAX8907B_SEQCNT_DEFAULT_LX_V2 0x1C + +// Defines sequencer count PWREN control values (these settings applied +// togeteher, when both CPU/V1 and CORE/V2 rails are attached to PWREN; +// in case when only CPU/V1 rail is attached no delay is specified) +// B[7:4] - power up delay in 20us taps +// B[3:0] - power down delay in 20us taps +#define MAX8907B_SEQCNT_PWREN_LX_V1 0xC0 /* 240us up delay */ +#define MAX8907B_SEQCNT_PWREN_LX_V2 0x00 /* no delay */ + +// Defines PMU output timing parameters. Scaling up time is dynamically +// calculated based on the slew rate maintained by MAX8907B. Turn On delay +// is fixed at max. Turn Off time is "just in case" placeholder - no need +// for s/w to track when output capacitors are discharged. +#define MAX8907B_SCALE_UP_UV_PER_US (2500) +#define MAX8907B_TURN_ON_TIME_US (3000) +#define MAX8907B_TURN_OFF_TIME_US (20) + +// Output voltages supplied by PMU +typedef enum +{ + Max8907bPmuSupply_Invalid = 0x0, + + /*-- Step-Down DC Regulators --*/ + Max8907bPmuSupply_LX_V1, // LX_V1 (V1), step-down DC regulator + Max8907bPmuSupply_LX_V2, // LX_V2 (V2), step-down DC regulator + Max8907bPmuSupply_LX_V3, // LX_V3 (V3), step-down DC regulator + + /*-- Standby LDO --*/ + Max8907bPmuSupply_VRTC, // VRTC (RTC), always-on supply for RTC + + /*-- Linear Regulator Outputs --*/ + Max8907bPmuSupply_LDO1, // LDO1 (VOUT1), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO2, // LDO2 (VOUT2), linear regulator output (default = 1.2V) + Max8907bPmuSupply_LDO3, // LDO3 (VOUT3), linear regulator output (default = 1.2V) + Max8907bPmuSupply_LDO4, // LDO4 (VOUT4), linear regulator output (default = 3.3V) + Max8907bPmuSupply_LDO5, // LDO5 (VOUT5), linear regulator output (default = 1.8V) + Max8907bPmuSupply_LDO6, // LDO6 (VOUT6), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO7, // LDO7 (VOUT7), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO8, // LDO8 (VOUT8), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO9, // LDO9 (VOUT9), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO10, // LDO10 (VOUT10), linear regulator output (default = 1.8V) + Max8907bPmuSupply_LDO11, // LDO11 (VOUT11), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO12, // LDO12 (VOUT12), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO13, // LDO13 (VOUT13), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO14, // LDO14 (VOUT14), linear regulator output (default = 3.3V) + Max8907bPmuSupply_LDO15, // LDO15 (VOUT15), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO16, // LDO16 (VOUT16), linear regulator output (default = 2.8V) + Max8907bPmuSupply_LDO17, // LDO17 (VOUT17), linear regulator output (default = 1.2V) + Max8907bPmuSupply_LDO18, // LDO18 (VOUT18), linear regulator output (default = 1.2V) + Max8907bPmuSupply_LDO19, // LDO19 (VOUT19), linear regulator output (default = 3.3V) + Max8907bPmuSupply_LDO20, // LDO20 (VOUT20), linear regulator output (default = 1.2V) + + /*-- White LED --*/ + Max8907bPmuSupply_WHITE_LED, // (Boost WLED) + + /*-- External DC/DC switcher --*/ + Max8907bPmuSupply_EXT_DCDC_1, // EXT_DC/DC1 + Max8907bPmuSupply_EXT_DCDC_2, // EXT_DC/DC2 + Max8907bPmuSupply_EXT_DCDC_3, // EXT_DC/DC3 + Max8907bPmuSupply_EXT_DCDC_4, // EXT_DC/DC4 + Max8907bPmuSupply_EXT_DCDC_5, // EXT_DC/DC5 + Max8907bPmuSupply_EXT_DCDC_6, // EXT_DC/DC6 + + /** USB1 & USB3 VBus's are getting 5V from DCDC_3 **/ + Max8907bPmuSupply_EXT_DCDC_3_USB1, //USB1 VBUS + Max8907bPmuSupply_EXT_DCDC_3_USB3, // USB3 VBUS + + /** Secondary PMU MIC2826 Rails **/ + MIC2826PmuSupply_BUCK, + MIC2826PmuSupply_LDO1, + MIC2826PmuSupply_LDO2, + MIC2826PmuSupply_LDO3, + + // External DCDC controlled by LX_V1, and scaled by digital + // potentiometer (DPM) AD5258 + Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7, + + Max8907bPmuSupply_Num, + Max8907bPmuSupply_Force32 = 0x7FFFFFFF +} Max8907bPmuSupply; + +typedef NvU32 (*Max8907bPmuVoltageFunc)(const NvU32 data); + +typedef struct Max8907bPmuSupplyInfoRec +{ + Max8907bPmuSupply supply; + + // I2C Registers + NvU8 ControlRegAddr; + NvU8 SequencerCountRegAddr; + NvU8 OutputVoltageRegAddr; + NvU8 OutputPort; + NvU8 PmuGpio; + + Max8907bPmuVoltageFunc GetVoltage; // Function to convert register bits to real voltage + Max8907bPmuVoltageFunc SetVoltage; // Function to convert real voltage to register bits + + NvOdmPmuVddRailCapabilities cap; +} Max8907bPmuSupplyInfo; + +#if defined(__cplusplus) +} +#endif + +#endif //INCLUDED_MAX8907B_SUPPLY_INFO_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c new file mode 100644 index 000000000000..097f0510d581 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c @@ -0,0 +1,119 @@ +/* + * 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 "nvodm_pmu.h" +#include "nvodm_services.h" +#include "mic2826_i2c.h" +#include "mic2826_reg.h" + +NvBool MIC2826I2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo; + + WriteBuffer[0] = Addr & 0xFF; + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = MIC2826_SLAVE_ADDR; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + MIC2826_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool MIC2826I2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data) +{ + NvU8 ReadBuffer = 0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + ReadBuffer = Addr & 0xFF; + + TransactionInfo[0].Address = MIC2826_SLAVE_ADDR; + TransactionInfo[0].Buf = &ReadBuffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + TransactionInfo[1].Address = (MIC2826_SLAVE_ADDR | 0x1); + TransactionInfo[1].Buf = &ReadBuffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2, + MIC2826_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = ReadBuffer; + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h new file mode 100644 index 000000000000..850ab9907b11 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h @@ -0,0 +1,65 @@ +/* + * 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_NVODM_PMU_MIC2826_I2C_H +#define INCLUDED_NVODM_PMU_MIC2826_I2C_H + +#include "nvodm_pmu.h" +#include "max8907b.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// Constant definition +#define MIC2826_SLAVE_ADDR 0xB4 +#define MIC2826_I2C_SPEED_KHZ 400 + +// Function declaration +NvBool MIC2826I2cWrite8( + NvOdmPmuDeviceHandle hPmu, + NvU8 Addr, + NvU8 Data); + +NvBool MIC2826I2cRead8( + NvOdmPmuDeviceHandle hPmu, + NvU8 Addr, + NvU8 *Data); + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_PMU_MIC2826_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h new file mode 100644 index 000000000000..24b31cfa8824 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 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 MIC2826_REG_HEADER +#define MIC2826_REG_HEADER + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define MIC2826_REG_INVALID ~0x0 +#define MIC2826_REG_ADDR_ENABLE 0x00 +#define MIC2826_REG_ADDR_STATUS 0x01 +#define MIC2826_REG_ADDR_BUCK 0x02 +#define MIC2826_REG_ADDR_LD01 0x03 +#define MIC2826_REG_ADDR_LD02 0x04 +#define MIC2826_REG_ADDR_LD03 0x05 + +#define MIC2826_REG_ENABLE_BK 0x1 +#define MIC2826_REG_ENABLE_LDO1 0x2 +#define MIC2826_REG_ENABLE_LDO2 0x4 +#define MIC2826_REG_ENABLE_LDO3 0x8 +#define MIC2826_REG_ENABLE_SEQCNT ~0x10 +#define MIC2826_REG_ENABLE_POAF ~0x20 + +#define MIC2826_REG_DISABLE_BK ~0x1 +#define MIC2826_REG_DISABLE_LDO1 ~0x2 +#define MIC2826_REG_DISABLE_LDO2 ~0x4 +#define MIC2826_REG_DISABLE_LDO3 ~0x8 +#define MIC2826_REG_DISABLE_SEQCNT 0x10 +#define MIC2826_REG_DISABLE_POAF 0x20 + +#define MIC2826_REG_STATUS_BK 0x1 +#define MIC2826_REG_STATUS_LDO1 0x2 +#define MIC2826_REG_STATUS_LDO2 0x4 +#define MIC2826_REG_STATUS_LDO3 0x8 +#define MIC2826_TSD_STATUS_TSD 0x10 +#define MIC2826_REG_STATUS_UVLO 0x20 +#define MIC2826_REG_STATUS_TSD_NORMAL ~0x10 +#define MIC2826_REG_STATUS_UVLO_NORMAL ~0x20 + +#define MIC2826_REG_STATUS_INT_EN 0x40 +#define MIC2826_REG_STATUS_INT_DIS ~0x40 + +#define MIC2826_BUCK_OUT_VOLTAGE_0800 0x00 //0.800 V +#define MIC2826_BUCK_OUT_VOLTAGE_0825 0x01 //0.825 V +#define MIC2826_BUCK_OUT_VOLTAGE_0850 0x02 //0.850 V +#define MIC2826_BUCK_OUT_VOLTAGE_0875 0x03 //0.875 V +#define MIC2826_BUCK_OUT_VOLTAGE_0900 0x04 //0.900 V +#define MIC2826_BUCK_OUT_VOLTAGE_0925 0x05 //0.925 V +#define MIC2826_BUCK_OUT_VOLTAGE_0950 0x06 //0.950 V +#define MIC2826_BUCK_OUT_VOLTAGE_0975 0x07 //0.975 V +#define MIC2826_BUCK_OUT_VOLTAGE_1000 0x08 //1.000 V +#define MIC2826_BUCK_OUT_VOLTAGE_1025 0x09 //1.025 V +#define MIC2826_BUCK_OUT_VOLTAGE_1050 0x0A //1.050 V +#define MIC2826_BUCK_OUT_VOLTAGE_1075 0x0B //1.075 V +#define MIC2826_BUCK_OUT_VOLTAGE_1100 0x0C //1.100 V +#define MIC2826_BUCK_OUT_VOLTAGE_1125 0x0D //1.125 V +#define MIC2826_BUCK_OUT_VOLTAGE_1150 0x0E //1.150 V +#define MIC2826_BUCK_OUT_VOLTAGE_1175 0x0F //1.175 V +#define MIC2826_BUCK_OUT_VOLTAGE_1200 0x10 //1.200 V +#define MIC2826_BUCK_OUT_VOLTAGE_1250 0x11 //1.250 V +#define MIC2826_BUCK_OUT_VOLTAGE_1300 0x12 //1.300 V +#define MIC2826_BUCK_OUT_VOLTAGE_1350 0x13 //1.350 V +#define MIC2826_BUCK_OUT_VOLTAGE_1400 0x14 //1.400 V +#define MIC2826_BUCK_OUT_VOLTAGE_1450 0x15 //1.450 V +#define MIC2826_BUCK_OUT_VOLTAGE_1500 0x16 //1.500 V +#define MIC2826_BUCK_OUT_VOLTAGE_1550 0x17 //1.550 V +#define MIC2826_BUCK_OUT_VOLTAGE_1600 0x18 //1.600 V +#define MIC2826_BUCK_OUT_VOLTAGE_1650 0x19 //1.650 V +#define MIC2826_BUCK_OUT_VOLTAGE_1700 0x1A //1.700 V +#define MIC2826_BUCK_OUT_VOLTAGE_1750 0x1B //1.750 V +#define MIC2826_BUCK_OUT_VOLTAGE_1800 0x1C //1.800 V + +#define MIC2826_LDO_OUT_VOLTAGE_0800 0x00 //0.800 V +#define MIC2826_LDO_OUT_VOLTAGE_0850 0x0B //0.850 V +#define MIC2826_LDO_OUT_VOLTAGE_0900 0x14 //0.900 V +#define MIC2826_LDO_OUT_VOLTAGE_0950 0x1D //0.950 V +#define MIC2826_LDO_OUT_VOLTAGE_1000 0x25 //1.000 V +#define MIC2826_LDO_OUT_VOLTAGE_1050 0x2E //1.050 V +#define MIC2826_LDO_OUT_VOLTAGE_1100 0x37 //1.100 V +#define MIC2826_LDO_OUT_VOLTAGE_1150 0x3E //1.150 V +#define MIC2826_LDO_OUT_VOLTAGE_1200 0x45 //1.200 V +#define MIC2826_LDO_OUT_VOLTAGE_1250 0x4B //1.250 V +#define MIC2826_LDO_OUT_VOLTAGE_1300 0x51 //1.300 V +#define MIC2826_LDO_OUT_VOLTAGE_1350 0x57 //1.350 V +#define MIC2826_LDO_OUT_VOLTAGE_1400 0x5C //1.400 V +#define MIC2826_LDO_OUT_VOLTAGE_1450 0x60 //1.450 V +#define MIC2826_LDO_OUT_VOLTAGE_1500 0x65 //1.500 V +#define MIC2826_LDO_OUT_VOLTAGE_1550 0x69 //1.550 V +#define MIC2826_LDO_OUT_VOLTAGE_1600 0x6D //1.600 V +#define MIC2826_LDO_OUT_VOLTAGE_1650 0x72 //1.650 V +#define MIC2826_LDO_OUT_VOLTAGE_1700 0x78 //1.700 V +#define MIC2826_LDO_OUT_VOLTAGE_1750 0x75 //1.750 V +#define MIC2826_LDO_OUT_VOLTAGE_1800 0x85 //1.800 V +#define MIC2826_LDO_OUT_VOLTAGE_1850 0x8B //1.850 V +#define MIC2826_LDO_OUT_VOLTAGE_1900 0x90 //1.900 V +#define MIC2826_LDO_OUT_VOLTAGE_1950 0x95 //1.950 V +#define MIC2826_LDO_OUT_VOLTAGE_2000 0x9A //2.000 V +#define MIC2826_LDO_OUT_VOLTAGE_2050 0x9F //2.050 V +#define MIC2826_LDO_OUT_VOLTAGE_2100 0xA3 //2.100 V +#define MIC2826_LDO_OUT_VOLTAGE_2150 0xA7 //2.150 V +#define MIC2826_LDO_OUT_VOLTAGE_2200 0xAB //2.200 V +#define MIC2826_LDO_OUT_VOLTAGE_2250 0xA0 //2.250 V +#define MIC2826_LDO_OUT_VOLTAGE_2300 0xB3 //2.300 V +#define MIC2826_LDO_OUT_VOLTAGE_2350 0xB7 //2.350 V +#define MIC2826_LDO_OUT_VOLTAGE_2400 0xBA //2.400 V +#define MIC2826_LDO_OUT_VOLTAGE_2450 0xBD //2.450 V +#define MIC2826_LDO_OUT_VOLTAGE_2500 0xC1 //2.500 V +#define MIC2826_LDO_OUT_VOLTAGE_2550 0xC3 //2.550 V +#define MIC2826_LDO_OUT_VOLTAGE_2600 0xC6 //2.600 V +#define MIC2826_LDO_OUT_VOLTAGE_2650 0xC9 //2.650 V +#define MIC2826_LDO_OUT_VOLTAGE_2700 0xCB //2.700 V +#define MIC2826_LDO_OUT_VOLTAGE_2750 0xCE //2.750 V +#define MIC2826_LDO_OUT_VOLTAGE_2800 0xD1 //2.800 V +#define MIC2826_LDO_OUT_VOLTAGE_2850 0xD3 //2.850 V +#define MIC2826_LDO_OUT_VOLTAGE_2900 0xD5 //2.900 V +#define MIC2826_LDO_OUT_VOLTAGE_2950 0xD8 //2.950 V +#define MIC2826_LDO_OUT_VOLTAGE_3000 0xDA //3.000 V +#define MIC2826_LDO_OUT_VOLTAGE_3050 0xDC //3.050 V +#define MIC2826_LDO_OUT_VOLTAGE_3100 0xDE //3.100 V +#define MIC2826_LDO_OUT_VOLTAGE_3150 0xE0 //3.150 V +#define MIC2826_LDO_OUT_VOLTAGE_3200 0xE3 //3.200 V +#define MIC2826_LDO_OUT_VOLTAGE_3250 0xE6 //3.250 V +#define MIC2826_LDO_OUT_VOLTAGE_3300 0xE8 //3.300 V + +#define MIC2826_BUCK_VOLTAGE_OFFSET 800 +#define MIC2826_BUCK_VOLTAGE_MIN_MV 800 +#define MIC2826_BUCK_VOLTAGE_STEP_MV 25 +#define MIC2826_BUCK_VOLTAGE_STEP_25MV 25 +#define MIC2826_BUCK_VOLTAGE_STEP_50MV 50 +#define MIC2826_BUCK_VOLTAGE_MAX_MV 1800 +#define MIC2826_BUCK_REQUESTVOLTAGE_MV 1800 + +#define MIC2826_LDO_VOLTAGE_OFFSET 800 +#define MIC2826_LDO_VOLTAGE_MIN_MV 800 +#define MIC2826_LDO_VOLTAGE_STEP_MV 50 +#define MIC2826_LDO_VOLTAGE_MAX_MV 3300 +#define MIC2826_LDO1_REQUESTVOLTAGE_MV 1800 +#define MIC2826_LDO2_REQUESTVOLTAGE_MV 1800 +#define MIC2826_LDO3_REQUESTVOLTAGE_MV 1200 + +#define MIC2826_INVALID_PORT 0xFF + + +#if defined(__cplusplus) +} +#endif + + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c new file mode 100644 index 000000000000..4ca397b9951b --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 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 "nvodm_pmu.h" +#include "nvodm_services.h" +#include "tca6416_expander_i2c.h" +#include "tca6416_expander_reg.h" + + + +#define TCA6416_SLAVE_ADDR 0x40 // (7'h20) +#define TCA6416_I2C_SPEED_KHZ 400 + + +NvBool +Tca6416ConfigPortPin( + NvOdmPmuDeviceHandle hDevice, + NvU32 PortNo, + NvU32 PinNo, + GpioPinMode Mode) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cStatus Error; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + + NvOdmI2cTransactionInfo TransactionInfo; + static NvU8 ConfigPort1Val = 0xFF; // set to default value + static NvU8 ConfigPort2Val = 0xFF; // set to default value + + if (PortNo == TCA6416_PORT_0) + { + WriteBuffer[0] = TCA6416_CONFIG_PORT_0 & 0xFF; + + if (Mode == GpioPinMode_Output) + { + WriteBuffer[1] = ((ConfigPort1Val & (0xFF & (~(1 << PinNo)))) | (0x0 << PinNo)); + } else if (Mode == GpioPinMode_InputData) + { + WriteBuffer[1] = ((ConfigPort1Val & (0xFF & (~(1 << PinNo)))) | (0x1 << PinNo)); + } + ConfigPort1Val = WriteBuffer[1]; + }else if (PortNo == TCA6416_PORT_1) + { + WriteBuffer[0] = TCA6416_CONFIG_PORT_1 & 0xFF; + + if (Mode == GpioPinMode_Output) + { + WriteBuffer[1] = (ConfigPort2Val & (0xFF & (~(1 << PinNo)))); + } else if (Mode == GpioPinMode_InputData) + { + WriteBuffer[1] = ((ConfigPort2Val & (0xFF & (~(1 << PinNo)))) | (0x1 << PinNo)); + } + ConfigPort2Val = WriteBuffer[1]; + } + + TransactionInfo.Address = TCA6416_SLAVE_ADDR; + TransactionInfo.Buf = WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + // write the pmu Offset (from where data gpio need to be set) + Error = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + TCA6416_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (Error == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (Error) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("Tca6416ConfigPortPin Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("Tca6416ConfigPortPin Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + + +NvBool +Tca6416WritePortPin( + NvOdmPmuDeviceHandle hDevice, + NvU32 PortNo, + NvU32 PinNo, + GpioPinState data) +{ + NvOdmI2cTransactionInfo TransactionInfo; + NvOdmI2cStatus Error; + NvU8 WriteBuffer[2]; + Max8907bPrivData *hPmu = (Max8907bPrivData*)hDevice->pPrivate; + + static NvU8 OutPut1Val = 0xFF; // set to default value + static NvU8 OutPut2Val = 0xFF; // set to default value + + + /* set the command byte */ + if (PortNo == TCA6416_PORT_0) + { + WriteBuffer[0] = TCA6416_OUTPUT_PORT_0 & 0xFF; + // Set the data + WriteBuffer[1] = ((OutPut1Val & (0xFF & (~(1 << PinNo)))) | (data << PinNo)); + + OutPut1Val = WriteBuffer[1]; + + } else if (PortNo == TCA6416_PORT_1) + { + WriteBuffer[0] = TCA6416_OUTPUT_PORT_1 & 0xFF; + // Set the data + WriteBuffer[1] = ((OutPut2Val & (0xFF & (~(1 << PinNo)))) | (data << PinNo)); + + OutPut2Val = WriteBuffer[1]; + } + + TransactionInfo.Address = TCA6416_SLAVE_ADDR; + TransactionInfo.Buf = WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + Error = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + TCA6416_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + + if (Error == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (Error) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("Tca6416I2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("Tca6416I2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool +Tca6416ReadPortPin( + NvOdmPmuDeviceHandle hDevice, + NvU32 PortNo, + NvU32 PinNo, + GpioPinState*State) +{ + + // Need to implement + return NV_TRUE; +} + + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h new file mode 100644 index 000000000000..ce14b79df090 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h @@ -0,0 +1,109 @@ +/* + * Copyright (c) 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_TCA6416_EXPANDER_I2C_H +#define INCLUDED_TCA6416_EXPANDER_I2C_H + +#include "nvodm_pmu.h" +#include "max8907b.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + + + +/** + * @brief Defines the possible modes. + */ + +typedef enum +{ + + /** + * Specifies the gpio pin as not in use. + */ + GpioPinMode_Inactive = 0, + + /// Specifies the gpio pin mode as input. + GpioPinMode_InputData, + + /// Specifies the gpio pin mode as output. + GpioPinMode_Output, + + GpioPinMode_Num, + GpioPinMode_Force32 = 0x7FFFFFFF +} GpioPinMode; + + +/** + * @brief Defines the pin state + */ + +typedef enum +{ + // Pin state high + GpioPinState_Low = 0, + // Pin is high + GpioPinState_High, + GpioPinState_Num, + GpioPinState_Force32 = 0x7FFFFFFF +} GpioPinState; + + +NvBool Tca6416ConfigPortPin( + NvOdmPmuDeviceHandle hDevice, + NvU32 portNo, + NvU32 pinNo, + GpioPinMode Mode); + +NvBool Tca6416WritePortPin( + NvOdmPmuDeviceHandle hDevice, + NvU32 portNo, + NvU32 pinNo, + GpioPinState data); + +NvBool Tca6416ReadPortPin( + NvOdmPmuDeviceHandle hDevice, + NvU32 portNo, + NvU32 pinNo, + GpioPinState*State); + + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_TCA6416_EXPANDER_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h new file mode 100644 index 000000000000..588335a804c8 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 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_TCA6416_EXPANDER_REG_HEADER +#define INCLUDED_TCA6416_EXPANDER_REG_HEADER + + +// Ports evailable on TCA6416. it is having 2 ports +#define TCA6416_PORT_0 0 +#define TCA6416_PORT_1 1 + + +// Each port is having 8 pins +#define TCA6416_PIN_0 0 +#define TCA6416_PIN_1 1 +#define TCA6416_PIN_2 2 +#define TCA6416_PIN_3 3 +#define TCA6416_PIN_4 4 +#define TCA6416_PIN_5 5 +#define TCA6416_PIN_6 6 +#define TCA6416_PIN_7 7 + + +// Registers +#define TCA6416_INPUT_PORT_0 0x00 // For ports 00 to 07 +#define TCA6416_INPUT_PORT_1 0x01 // For ports 10 to 17 +#define TCA6416_OUTPUT_PORT_0 0x02 // For ports 00 to 07 +#define TCA6416_OUTPUT_PORT_1 0x03 // For ports 10 to 17 +#define TCA6416_POLARITY_INV_PORT_0 0x04 // For ports 00 to 07 +#define TCA6416_POLARITY_INV_PORT_1 0x05 // For ports 10 to 17 +#define TCA6416_CONFIG_PORT_0 0x06 // For ports 00 to 07 +#define TCA6416_CONFIG_PORT_1 0x07 // For ports 10 to 17 + + + +#define TCA6416_INVALID_PORT 0xFF + +#endif //INCLUDED_TCA6416_EXPANDER_REG_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile new file mode 100644 index 000000000000..9e7fe0bcdb16 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/Makefile @@ -0,0 +1,21 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626 + +obj-y += ds2482_bridge.o +obj-y += ds2482_i2c.o +obj-y += pcf50626_adc.o +obj-y += pcf50626_batterycharger.o +obj-y += pcf50626.o +obj-y += pcf50626_i2c.o +obj-y += pcf50626_interrupt.o +obj-y += pcf50626_rtc.o +obj-y += platform.o diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c new file mode 100644 index 000000000000..ecc09f8e6775 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.c @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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 "ds2482_bridge.h" +#include "pcf50626_i2c.h" +#include "ds2482_i2c.h" +#include "pcf50626_reg.h" +#include "ds2482_reg.h" + +NvBool +Ds2482Setup(NvOdmPmuDeviceHandle hDevice) +{ + NvU8 data = 0; + + // One wire I2C bridge + //Device Reset Status + if (!Ds2482OWI2cRead8(hDevice, DS2482_DEVICE_RESET, &data)) + return NV_FALSE; + //NVODMPMU_PRINTF(("Device Reset reg 0x%02x = 0x%02x\n", DS2482_DEVICE_RESET, data)); + + //1-Wire Reset Status + if (!Ds2482OWI2cRead8(hDevice, DS2482_1WIRE_RESET, &data)) + return NV_FALSE; + //NVODMPMU_PRINTF(("1-Wire Reset reg 0x%02x = 0x%02x\n", DS2482_1WIRE_RESET, data)); + + while(1) + { + if (!Ds2482OWI2cWrite8(hDevice, DS2482_READ_DATA_REG_ADDR, DS2482_DEVICE_RESET)) + return NV_FALSE; + + if (!Ds2482OWI2cRead8(hDevice, DS2482_READ_DATA_REG_ADDR, &data)) + return NV_FALSE; + + if (!(data & 0x01)) + break; + } + + + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h new file mode 100644 index 000000000000..84111f8a7876 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_bridge.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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_DS2482_BRIDGE_H +#define INCLUDED_DS2482_BRIDGE_H + +#include "nvodm_pmu.h" +#include "pcf50626.h" + + +#if defined(__cplusplus) +extern "C" +{ +#endif + +NvBool +Ds2482Setup(NvOdmPmuDeviceHandle hDevice); + +NvBool +Ds2482BatteryPresented( + NvOdmPmuDeviceHandle hDevice, + NvBool *BattPresence); + +#if defined(__cplusplus) +} +#endif + + +#endif // INCLUDED_DS2482_BRIDGE_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c new file mode 100644 index 000000000000..09f1194e2a30 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.c @@ -0,0 +1,119 @@ +/* + * Copyright (c) 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 "ds2482_i2c.h" +#include "nvodm_pmu.h" +#include "nvodm_services.h" +#include "ds2482_reg.h" + +NvBool Ds2482OWI2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo; + + WriteBuffer[0] = Addr & 0xFF; + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = DS2482_SLAVE_ADDR; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + DS2482_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool Ds2482OWI2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data) +{ + NvU8 ReadBuffer = 0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + ReadBuffer = Addr & 0xFF; + + TransactionInfo[0].Address = DS2482_SLAVE_ADDR; + TransactionInfo[0].Buf = &ReadBuffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + TransactionInfo[1].Address = (DS2482_SLAVE_ADDR | 0x1); + TransactionInfo[1].Buf = &ReadBuffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2, + DS2482_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuOWI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = ReadBuffer; + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h new file mode 100644 index 000000000000..af6ea8c9330e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_i2c.h @@ -0,0 +1,64 @@ +/* + * Copyright (c) 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_NVODM_PMU_DS2482_I2C_H +#define INCLUDED_NVODM_PMU_DS2482_I2C_H + +#include "pcf50626.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// Constant definition +#define DS2482_SLAVE_ADDR 0x32 +#define DS2482_I2C_SPEED_KHZ 400 + +// Function declaration +NvBool Ds2482OWI2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data); + +NvBool Ds2482OWI2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data); + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_PMU_DS2482_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h new file mode 100644 index 000000000000..6ce603046918 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/ds2482_reg.h @@ -0,0 +1,44 @@ +/* + * 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 DS2482_REG_HEADER +#define DS2482_REG_HEADER + +#define DS2482_DEVICE_RESET 0xF0 +#define DS2482_1WIRE_RESET 0xB4 +#define DS2482_STATUS_REG_ADDR 0xF0 +#define DS2482_READ_DATA_REG_ADDR 0xE1 +#define DS2482_CONFIGURATION_REG_ADDR 0xC3 + + +#endif //DS2482_REG_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h new file mode 100644 index 000000000000..bf46e600401f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/nvodm_pmu_pcf50626_supply_info.h @@ -0,0 +1,144 @@ +/* + * 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 PCF50626_SUPPLY_INFO_HEADER +#define PCF50626_SUPPLY_INFO_HEADER + +#include "pcf50626.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + + + typedef enum +{ + PCF50626PmuSupply_Invalid = 0x0, + + //DCD1 + PCF50626PmuSupply_DCD1, + + //DCD2 + PCF50626PmuSupply_DCD2, + + //DCUD + PCF50626PmuSupply_DCUD, + + //DCULED + PCF50626PmuSupply_DCULED, + + //RF1REG + PCF50626PmuSupply_RF1REG, + + //RF2REG + PCF50626PmuSupply_RF2REG, + + //RF3REG + PCF50626PmuSupply_RF3REG, + + //RF4REG + PCF50626PmuSupply_RF4REG, + + //D1REG + PCF50626PmuSupply_D1REG, + + //D2REG + PCF50626PmuSupply_D2REG, + + //D3REG + PCF50626PmuSupply_D3REG, + + //D4REG + PCF50626PmuSupply_D4REG, + + //D5REG + PCF50626PmuSupply_D5REG, + + //D6REG + PCF50626PmuSupply_D6REG, + + //D7REG + PCF50626PmuSupply_D7REG, + + //D8REG + PCF50626PmuSupply_D8REG, + + //HCREG + PCF50626PmuSupply_HCREG, + + //IOREG + PCF50626PmuSupply_IOREG, + + //USIMREG + PCF50626PmuSupply_USIMREG, + + //USBREG + PCF50626PmuSupply_USBREG, + + //LCREG + PCF50626PmuSupply_LCREG, + + //VBAT + PCF50626PmuSupply_VBAT, + + PCF50626PmuSupply_Num, + PCF50626PmuSupply_Force32 = 0x7FFFFFFF +} PCF50626PmuSupply; + + +typedef struct PCF50626PmuSupplyInfoRec +{ + PCF50626PmuSupply supply; + PCF50626PmuSupply supplyInput; + NvU8 control1Addr; + NvU8 control2Addr; + NvU8 control3Addr; + NvU8 control4Addr; + + NvU8 dvm1Addr; + NvU8 dvm2Addr; + NvU8 dvm3Addr; + NvU8 dvmTimAddr; + + NvOdmPmuVddRailCapabilities cap; + NvU32 offsetVoltage; + NvU32 turnOnTimeMicroSec; + NvU32 switchTimeMicroSec; +} PCF50626PmuSupplyInfo; + +#if defined(__cplusplus) +} +#endif + +#endif //PCF50626_VOLTAGE_INFO_TABLE_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c new file mode 100644 index 000000000000..9272dbdddbc5 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.c @@ -0,0 +1,938 @@ +/* + * Copyright (c) 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 "nvodm_query_discovery.h" +#include "nvodm_query.h" +#include "nvodm_services.h" +#include "pcf50626_i2c.h" +#include "pcf50626.h" +#include "pcf50626_batterycharger.h" +#include "pcf50626_adc.h" +#include "pcf50626_interrupt.h" +#include "pcf50626_supply_info_table.h" + +#ifndef PMU_MAX +#define PMU_MAX(a,b) ((a)<(b)?(b):(a)) +#endif + +#define BATTEMP_CONTROL (0) + +// Board IDs +#define NVODM_PMU_BOARD_ID_E924 0x0918 +#define NVODM_PMU_BOARD_ID_E934 0x0922 + +// SKUs +#define NVODM_PMU_BOARD_SAMSUNG_26_MHZ_OSC 0x0A00 +#define NVODM_PMU_BOARD_HYNIX_12_MHZ_XTAL 0x0A01 + +// h/w configuration +#define CHARGER_CONSTANT_CURRENT_SET_MA (NvU32)(125000/127) +#define MAX_CHARGER_LIMIT_MA 850 + +// This PMU does not have differnet charger programming +// So setting all types of charger limit to the default charger limit +#define SE0_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA +#define SE1_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA +#define SJ_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA +#define SK_TYPE_CHARGER_LIMIT_MA MAX_CHARGER_LIMIT_MA + + +// threshold for battery status. need to fine tune based on battery/system characterisation +#define NVODM_BATTERY_FULL_VOLTAGE_MV 4150 +#define NVODM_BATTERY_HIGH_VOLTAGE_MV 3900 +#define NVODM_BATTERY_LOW_VOLTAGE_MV 3300 +#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 3100 + +#define NVODM_BATTERY_OVERHEAT_THRESHOLD 70 + + +Pcf50626PrivData *pPrivData; +//Concorde WAR for the USB Host mode +NvBool UsbHostMode; + +#define PMUGUID NV_ODM_GUID('p','c','f','_','p','m','u','0') + + +// Calulate the battery life percentage according to the battery voltage. +static NvU32 +Pcf50626CalulateBatteryLifePercent_int(NvU32 vBatSense); + +#if BATTEMP_CONTROL +// switch off the chargeer if the battery temperature is too high +static NvBool +Pcf50626BatteryTemperatureControl_int( + NvOdmPmuDeviceHandle hDevice, + NvU32 batTemp); +#endif + +// Read the voltage setting from PCF50626 registers +static NvBool +Pcf50626ReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts); + +// Write the voltage setting from PCF50626 registers +static NvBool +Pcf50626WriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds); + + +void +Pcf50626GetCapabilities( + NvU32 vddRail, + NvOdmPmuVddRailCapabilities* pCapabilities) +{ + NvOdmBoardInfo BoardInfo; + NvBool Status = NV_FALSE; + + NV_ASSERT(pCapabilities); + NV_ASSERT(vddRail < PCF50626PmuSupply_Num); + + *pCapabilities = pcf50626SupplyInfoTable[vddRail].cap; + + if (vddRail == PCF50626PmuSupply_DCD2) + { + Status = NvOdmPeripheralGetBoardInfo(NVODM_PMU_BOARD_ID_E924, &BoardInfo); + if (Status == NV_TRUE) + { + if ((BoardInfo.SKU == NVODM_PMU_BOARD_SAMSUNG_26_MHZ_OSC) || + (BoardInfo.SKU == NVODM_PMU_BOARD_HYNIX_12_MHZ_XTAL)) + { + // Use 1.8v DDR (TO DO: Don't use a magic number here; define this.) + pCapabilities->requestMilliVolts = 1800; + } + } + else + { + Status = NvOdmPeripheralGetBoardInfo(NVODM_PMU_BOARD_ID_E934, &BoardInfo); + if (Status == NV_TRUE) + { + if (BoardInfo.SKU == NVODM_PMU_BOARD_HYNIX_12_MHZ_XTAL) + { + // Use 1.8v DDR (TO DO: Don't use a magic number here; define this.) + pCapabilities->requestMilliVolts = 1800; + } + } + else + { + // Use default DDR voltage (1.925v) + ; + } + } + } +} + + +NvBool Pcf50626Setup(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmIoModule I2cModule = NvOdmIoModule_I2c; + NvU32 I2cInstance = 0; + NvU32 I2cAddress = 0; + NvU32 i = 0; + NvBool status = NV_FALSE; + + const NvOdmPeripheralConnectivity *pConnectivity = + NvOdmPeripheralGetGuid(PMUGUID); + + NV_ASSERT(hDevice); + + + pPrivData = (Pcf50626PrivData*) NvOdmOsAlloc(sizeof(Pcf50626PrivData)); + if (pPrivData == NULL) + { + NVODMPMU_PRINTF(("Error Allocating Pcf50626PrivData. \n")); + return NV_FALSE; + } + NvOdmOsMemset(pPrivData, 0, sizeof(Pcf50626PrivData)); + hDevice->pPrivate = pPrivData; + + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable = NvOdmOsAlloc(sizeof(NvU32) * PCF50626PmuSupply_Num); + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable == NULL) + { + NVODMPMU_PRINTF(("Error Allocating RefCntTable. \n")); + goto fail; + } + + // memset + for (i = 0; i < PCF50626PmuSupply_Num; i++) + { + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[i] = 0; + } + + + if (pConnectivity != NULL) // PMU is in database + { + for (i = 0; i < pConnectivity->NumAddress; i ++) + { + if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu) + { + I2cModule = NvOdmIoModule_I2c_Pmu; + I2cInstance = pConnectivity->AddressList[i].Instance; + I2cAddress = pConnectivity->AddressList[i].Address; + break; + } + } + + NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu); + NV_ASSERT(I2cAddress != 0); + + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance); + if (!((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C) + { + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Error Open I2C device. \n")); + NVODMPMU_PRINTF(("[NVODM PMU]Please check PMU device I2C settings. \n")); + goto fail; + } + + ((Pcf50626PrivData*)hDevice->pPrivate)->DeviceAddr = I2cAddress; + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice = NvOdmServicesPmuOpen(); + if (!((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice) + { + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Error Open PMU Odm service. \n")); + goto fail; + } + } + else + { + // if PMU is not presented in the database, then the platform is PMU-less. + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: The system did not doscover PMU fromthe data base. \n")); + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: If this is not intended, please check the peripheral database for PMU settings. \n")); + goto fail; + } + + if (!Pcf50626BatteryChargerSetup(hDevice)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626BatteryChargerSetup() failed. \n")); + goto fail; + } + + //Check battery presence + if (!Pcf50626BatteryChargerCBCMainBatt(hDevice,&((Pcf50626PrivData*)hDevice->pPrivate)->battPresence)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626BatteryChargerCBCMainBatt() failed. \n")); + goto fail; + } + + // The interrupt assumes not supported until pcf50626InterruptHandler() is called. + ((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_FALSE; + + // setup the interrupt any way. + if (!Pcf50626SetupInterrupt(hDevice, &((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626SetupInterrupt() failed. \n")); + goto fail; + } + + // Check battery Fullness + if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_TRUE) + { + if (!Pcf50626BatteryChargerCBCBattFul(hDevice,&status)) + { + NVODMPMU_PRINTF(("[NVODM PMU]Pcf50626Setup: Pcf50626BatteryChargerCBCBattFul() failed. \n")); + goto fail; + } + + ((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.batFull = status; + } + else + { + ((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.batFull = NV_FALSE; + } + + return NV_TRUE; + +fail: + Pcf50626Release(hDevice); + return NV_FALSE; + + +} + +void Pcf50626Release(NvOdmPmuDeviceHandle hDevice) +{ + if (hDevice->pPrivate != NULL) + { + if (((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice != NULL) + { + NvOdmServicesPmuClose(((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice); + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice = NULL; + } + + if (((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C != NULL) + { + NvOdmI2cClose(((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C); + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmI2C = NULL; + } + + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable != NULL) + { + NvOdmOsFree(((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable); + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable = NULL; + } + + NvOdmOsFree(hDevice->pPrivate); + hDevice->pPrivate = NULL; + } +} + + +NvBool +Pcf50626GetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + NV_ASSERT(hDevice); + NV_ASSERT(pMilliVolts); + NV_ASSERT(vddRail < PCF50626PmuSupply_Num); + + if(! Pcf50626ReadVoltageReg(hDevice, vddRail,pMilliVolts)) + return NV_FALSE; + + return NV_TRUE; +} + + +NvBool +Pcf50626SetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + NvU8 data = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(vddRail < PCF50626PmuSupply_Num); + + if (pcf50626SupplyInfoTable[vddRail].cap.OdmProtected == NV_TRUE) + { + NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626SetVoltage Warning: The voltage is protected and can not be set: %d.\n", vddRail)); + return NV_TRUE; + } + + if ((MilliVolts == ODM_VOLTAGE_OFF) || + ((MilliVolts <= pcf50626SupplyInfoTable[vddRail].cap.MaxMilliVolts) + && (MilliVolts >= pcf50626SupplyInfoTable[vddRail].cap.MinMilliVolts))) + { + if (! Pcf50626WriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds)) + return NV_FALSE; + } + else + { + NVODMPMU_PRINTF(("[NVODM OPMU] Pcf50626SetVoltage Error: The required voltage is not supported..\n")); + return NV_FALSE; + } + + if (vddRail == PCF50626PmuSupply_DCUD) + { + // VBUs rail is enabled bydefault, so no need to enable set voltage. + // "Millivolts" field is used as Enable or disable VBUS GPIO + if (MilliVolts == ODM_VOLTAGE_OFF) + { + data = 0x7; // all bits to low fixed 0 + } + else + { + data = 0x0; // default reset value high impedence state + } + if (!Pcf50626I2cWrite8(hDevice,PCF50626_GPIO5C1_ADDR, data)) + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +Pcf50626ReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + NvU32 milliVolts = 0; + NvU8 data = 0; + const PCF50626PmuSupplyInfo *pSupplyInfo = &pcf50626SupplyInfoTable[vddRail]; + + NV_ASSERT(pSupplyInfo->supply == (PCF50626PmuSupply)vddRail); + + if(! Pcf50626I2cRead8(hDevice, pSupplyInfo->control2Addr, &data)) + return NV_FALSE; + + data >>= PCF50626_C2_OPMOD_SHIFT; + if (!data) //OFF + milliVolts = 0; + else + { + if (!Pcf50626I2cRead8(hDevice, pSupplyInfo->control1Addr, &data)) + return NV_FALSE; + + if ( (vddRail == PCF50626PmuSupply_DCD1) + |(vddRail == PCF50626PmuSupply_DCD2) + |(vddRail == PCF50626PmuSupply_DCUD)) + { + milliVolts = pSupplyInfo->offsetVoltage + pSupplyInfo->cap.StepMilliVolts * ((NvU32)(data & 0x7F)); + } + else if (vddRail == PCF50626PmuSupply_LCREG) + { + milliVolts = pSupplyInfo->offsetVoltage + pSupplyInfo->cap.StepMilliVolts * ((NvU32)(data & 0x7F) >> 1); + } + else + { + milliVolts = pSupplyInfo->offsetVoltage + pSupplyInfo->cap.StepMilliVolts * ((NvU32)(data & 0x7F) >> 2); + } + } + + *pMilliVolts = milliVolts; + return NV_TRUE; +} + + +static NvBool +Pcf50626WriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + NvU8 data = 0; + NvU8 reg = 0; + NvU32 settleTime = 0; + + const PCF50626PmuSupplyInfo* pSupplyInfo = &pcf50626SupplyInfoTable[vddRail]; + const PCF50626PmuSupplyInfo* pSupplyInputInfo = &pcf50626SupplyInfoTable[pSupplyInfo->supplyInput]; + + NV_ASSERT(pSupplyInfo->supply == (PCF50626PmuSupply)vddRail); + + // Require to turn off the supply + if (MilliVolts == ODM_VOLTAGE_OFF) + { + // check if the supply can be turned off + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 1) + { + // turn off the supply + data = PCF50626_C2_OPMOD_OFF; + NvOdmServicesPmuSetSocRailPowerState( + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE); + if (!Pcf50626I2cWrite8(hDevice, pSupplyInfo->control2Addr, data)) + return NV_FALSE; + } + + //check if the supply input can be turned off + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] == 1) + { + // turn off the supply input + data = PCF50626_C2_OPMOD_OFF; + NvOdmServicesPmuSetSocRailPowerState( + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInputInfo->supply, NV_FALSE); + if(! Pcf50626I2cWrite8(hDevice, pSupplyInputInfo->control2Addr, data)) + return NV_FALSE; + } + + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] != 0) + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] --; + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] != 0) + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] --; + + settleTime = PMU_MAX (pSupplyInfo->switchTimeMicroSec, pSupplyInputInfo->switchTimeMicroSec); + + if (pSettleMicroSeconds != NULL) + *pSettleMicroSeconds = settleTime; + else + NvOdmOsWaitUS(settleTime); + return NV_TRUE; + } + + // set voltage + if ( (vddRail == PCF50626PmuSupply_HCREG) || + ((vddRail == PCF50626PmuSupply_LCREG) && + (MilliVolts > PCF50626_LCREGOUT_VOLTAGE_RESCHANGE_MV))) + { + data = (NvU8)((MilliVolts - pSupplyInfo->offsetVoltage) / pSupplyInfo->cap.StepMilliVolts); + if (data % 2) + data --; + } + else + { + data = (NvU8)((MilliVolts - pSupplyInfo->offsetVoltage) / pSupplyInfo->cap.StepMilliVolts); + } + + reg = 0; + reg &= ~PCF50626_C1_OUTPUT_MASK; + if ( (pSupplyInfo->supply == PCF50626PmuSupply_DCD1) + |(pSupplyInfo->supply == PCF50626PmuSupply_DCD2) + |(pSupplyInfo->supply == PCF50626PmuSupply_DCUD)) + { + reg |= data; + } + else if (pSupplyInfo->supply == PCF50626PmuSupply_LCREG) + { + reg |= (data << 1); + } + else + { + reg |= (data << 2); + } + + if(! Pcf50626I2cWrite8(hDevice, pSupplyInfo->control1Addr, reg)) + return NV_FALSE; + + settleTime = pSupplyInfo->switchTimeMicroSec; + + // turn on supply + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] == 0) + { + if (! Pcf50626I2cRead8(hDevice, pSupplyInfo->control2Addr, &data)) + return NV_FALSE; + data >>= PCF50626_C2_OPMOD_SHIFT; + if (!data) + { + // Require to turn on the supply + data = PCF50626_C2_OPMOD_ON; + NvOdmServicesPmuSetSocRailPowerState( + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInfo->supply, NV_TRUE); + if(! Pcf50626I2cWrite8(hDevice, pSupplyInfo->control2Addr, data)) + return NV_FALSE; + + settleTime += pSupplyInfo->turnOnTimeMicroSec; + } + } + + // turn on supply input if necessary + if (((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] == 0) + { + if(! Pcf50626I2cRead8(hDevice, pSupplyInputInfo->control2Addr, &data)) + return NV_FALSE; + + data >>= PCF50626_C2_OPMOD_SHIFT; + if (!data) + { + // Require to turn on the supply input + data = PCF50626_C2_OPMOD_ON; + NvOdmServicesPmuSetSocRailPowerState( + ((Pcf50626PrivData*)hDevice->pPrivate)->hOdmPmuSevice, pSupplyInputInfo->supply, NV_TRUE); + if(! Pcf50626I2cWrite8(hDevice,pSupplyInputInfo->control2Addr, data)) + return NV_FALSE; + + settleTime += pSupplyInputInfo->turnOnTimeMicroSec; + } + } + + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInputInfo->supply] ++; + ((Pcf50626PrivData*)hDevice->pPrivate)->supplyRefCntTable[pSupplyInfo->supply] ++; + + + if (pSettleMicroSeconds != NULL) + *pSettleMicroSeconds = settleTime; + else + NvOdmOsWaitUS(settleTime); + + return NV_TRUE; +} + +NvBool +Pcf50626GetAcLineStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuAcLineStatus *pStatus) +{ + NvBool acLineStatus = NV_FALSE; + + NV_ASSERT(hDevice); + NV_ASSERT(pStatus); + + // check if charger presents + if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_FALSE) + { + *pStatus = NvOdmPmuAcLine_Online; + return NV_TRUE; + } + + if (((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE) + { + if (( ((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.mChgPresent == NV_TRUE ) && + (UsbHostMode == NV_FALSE)) + { + *pStatus = NvOdmPmuAcLine_Online; + acLineStatus = NV_TRUE; + } + else + { + *pStatus = NvOdmPmuAcLine_Offline; + acLineStatus = NV_FALSE; + } + } + else + { + // battery is present, now check if charger presents + if (!Pcf50626BatteryChargerMainChgPresent(hDevice, &acLineStatus)) + { + NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetAcLineStatus: Error in checking main charger presence.\n")); + return NV_FALSE; + } + + if ((acLineStatus == NV_TRUE) && (UsbHostMode == NV_FALSE)) + *pStatus = NvOdmPmuAcLine_Online; + else + *pStatus = NvOdmPmuAcLine_Offline; + } + return NV_TRUE; +} + + +NvBool +Pcf50626GetBatteryStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU8 *pStatus) +{ + NvU8 status = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pStatus); + NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num); + + if (batteryInst == NvOdmPmuBatteryInst_Main) + { + if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_TRUE) + { + NvOdmPmuAcLineStatus stat = NvOdmPmuAcLine_Offline; + NvU32 VBatSense = 0; + if (!Pcf50626GetAcLineStatus(hDevice, &stat)) + return NV_FALSE; + + if (stat == NvOdmPmuAcLine_Online) + { + if (((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported == NV_TRUE) + { + if (((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus.batFull == NV_FALSE) + status = NVODM_BATTERY_STATUS_CHARGING; + } + else + { + NvBool batFull = NV_FALSE; + if (!Pcf50626BatteryChargerCBCBattFul(hDevice, &batFull)) + return NV_FALSE; + if (batFull == NV_FALSE) + status = NVODM_BATTERY_STATUS_CHARGING; + } + } + + // Get VBatSense + if (!Pcf50626AdcVBatSenseRead(hDevice, &VBatSense)) + return NV_FALSE; + + if (VBatSense > NVODM_BATTERY_HIGH_VOLTAGE_MV) + status |= NVODM_BATTERY_STATUS_HIGH; + else if ((VBatSense < NVODM_BATTERY_LOW_VOLTAGE_MV)&& + (VBatSense > NVODM_BATTERY_CRITICAL_VOLTAGE_MV)) + status |= NVODM_BATTERY_STATUS_LOW; + else if (VBatSense <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV) + status |= NVODM_BATTERY_STATUS_CRITICAL; + + } + else + { + /* Battery is actually not present */ + status = NVODM_BATTERY_STATUS_NO_BATTERY; + } + + *pStatus = status; + } + + else + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + } + + return NV_TRUE; +} + +NvBool +Pcf50626GetBatteryData( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryData *pData) +{ + NvOdmPmuBatteryData batteryData; + batteryData.batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + + + NV_ASSERT(hDevice); + NV_ASSERT(pData); + NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num); + + + if (batteryInst == NvOdmPmuBatteryInst_Main) + { + NvU32 VBatSense = 0; + NvU32 VBatTemp = 0; + + if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_TRUE) + { + /* retrieve Battery voltage and temperature */ + + // Get VBatSense + if (!Pcf50626AdcVBatSenseRead(hDevice, &VBatSense)) + { + NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetBatteryData: Error reading VBATSense. \n")); + return NV_FALSE; + } + + // Get VBatTemp + if (!Pcf50626AdcVBatTempRead(hDevice, &VBatTemp)) + { + NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetBatteryData: Error reading VBATSense. \n")); + return NV_FALSE; + } + + batteryData.batteryLifePercent = + Pcf50626CalulateBatteryLifePercent_int(VBatSense); + +#if BATTEMP_CONTROL + if (!Pcf50626BatteryTemperatureControl_int(hDevice, VBatTemp)) + { + NVODMPMU_PRINTF(("[NVODM PMU] Pcf50626GetBatteryData: Error in battery ctemperature controls. \n")); + return NV_FALSE; + } +#endif + + batteryData.batteryVoltage = VBatSense; + batteryData.batteryTemperature = Pcf50626BatteryTemperature(VBatSense, + VBatTemp); + } + + *pData = batteryData; + } + else + { + *pData = batteryData; + } + + return NV_TRUE; +} + +void +Pcf50626GetBatteryFullLifeTime( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU32 *pLifeTime) +{ + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; +} + +void +Pcf50626GetBatteryChemistry( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryChemistry *pChemistry) +{ + //return fixed data for now. + *pChemistry = NvOdmPmuBatteryChemistry_LION; +} + +NvBool +Pcf50626SetChargingCurrent( +NvOdmPmuDeviceHandle hDevice, +NvOdmPmuChargingPath chargingPath, +NvU32 chargingCurrentLimitMa, +NvOdmUsbChargerType chargerType) +{ + NvU8 data = 0; + NV_ASSERT(hDevice); + + // if no battery, then do nothing + if (((Pcf50626PrivData*)hDevice->pPrivate)->battPresence == NV_FALSE) + return NV_TRUE; + //Concorde s/w WAR for USB Host mode + if (chargingCurrentLimitMa == NVODM_USB_HOST_MODE_LIMIT) + { + chargingCurrentLimitMa = 0; // turn off the charging path + UsbHostMode = NV_TRUE; + } + else + { + UsbHostMode = NV_FALSE; + } + + // if requested current is more than max supported current then limit to supported + if ( chargingCurrentLimitMa > MAX_CHARGER_LIMIT_MA ) + chargingCurrentLimitMa = MAX_CHARGER_LIMIT_MA; + + if (chargingPath == NvOdmPmuChargingPath_UsbBus) + { + switch (chargerType) + { + case NvOdmUsbChargerType_SJ: + chargingCurrentLimitMa = SJ_TYPE_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_SK: + chargingCurrentLimitMa = SK_TYPE_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_SE1: + chargingCurrentLimitMa = SE1_TYPE_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_SE0: + chargingCurrentLimitMa = SE0_TYPE_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_UsbHost: + default: + // USB Host based charging, nothing to do. Just pass current limit to PMU. + break; + } + } + + data = (NvU8)((( chargingCurrentLimitMa << 8 ) - chargingCurrentLimitMa ) + / CHARGER_CONSTANT_CURRENT_SET_MA ); + + if (!Pcf50626I2cWrite8(hDevice, PCF50626_CBCC3_ADDR, data)) + return NV_FALSE; + + // turn off the charger path if the requested current limit is 0mA. Turn on the path otherwise. + data = 0; + if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data) ) + return NV_FALSE; + + if ( chargingCurrentLimitMa == 0 ) + data &= ~(PCF50626_CBCC1_CHGENA_MASK); //off + else + data |= PCF50626_CBCC1_CHGENA_MASK; //on + + if ( !Pcf50626I2cWrite8(hDevice, PCF50626_CBCC1_ADDR, data) ) + return NV_FALSE; + + + data = 0; + if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC2_ADDR, &data) ) + return NV_FALSE; + if ( chargingCurrentLimitMa == 0 ) + { + //enable USB suspend mode regardless of the SCUSB pin state + data |= (PCF50626_CBCC2_SUSPENA_MASK << PCF50626_CBCC2_SUSPENA_SHIFT); + } + else + { + //disable USB suspend mode regardless of the SCUSB pin state + data &= ~(PCF50626_CBCC2_SUSPENA_MASK << PCF50626_CBCC2_SUSPENA_SHIFT); + } + if ( !Pcf50626I2cWrite8(hDevice, PCF50626_CBCC2_ADDR, data) ) + return NV_FALSE; + + //Dump the register value for debug purpose, can be commented out is undesired.. + NVODMPMU_PRINTF(("NvOdmPmuSetChargingCurrent: \n")); + NVODMPMU_PRINTF((" chargingCurrentLimitMa:%d\n", chargingCurrentLimitMa)); + + if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data) ) + return NV_FALSE; + NVODMPMU_PRINTF((" CBCC1:0x%02x\n", data)); + + if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC2_ADDR, &data) ) + return NV_FALSE; + NVODMPMU_PRINTF((" CBCC2:0x%02x\n", data)); + + if ( !Pcf50626I2cRead8(hDevice, PCF50626_CBCC3_ADDR, &data) ) + return NV_FALSE; + NVODMPMU_PRINTF((" CBCC3:0x%02x\n", data)); + + return NV_TRUE; +} + +void Pcf50626InterruptHandler( NvOdmPmuDeviceHandle hDevice) +{ + // If the interrupt handle is called, the interrupt is supported. + ((Pcf50626PrivData*)hDevice->pPrivate)->pmuInterruptSupported = NV_TRUE; + + Pcf50626InterruptHandler_int(hDevice, &((Pcf50626PrivData*)hDevice->pPrivate)->pmuStatus); +} + + +static NvU32 Pcf50626CalulateBatteryLifePercent_int(NvU32 vBatSense) +{ + NvU32 lifePerc = 0; + NvU32 vbat = vBatSense; + + if (vbat < NVODM_BATTERY_CRITICAL_VOLTAGE_MV) + vbat = NVODM_BATTERY_CRITICAL_VOLTAGE_MV; + + // using the linear mapping between the battery voltage and the life percentage. + lifePerc = ( ( vbat - NVODM_BATTERY_CRITICAL_VOLTAGE_MV ) * 50 + / ( NVODM_BATTERY_FULL_VOLTAGE_MV - NVODM_BATTERY_CRITICAL_VOLTAGE_MV ) ) << 1; + + if (lifePerc > 100) + lifePerc = 100; + + return lifePerc; +} + + +#if BATTEMP_CONTROL +static NvBool Pcf50626BatteryTemperatureControl_int( + NvOdmPmuDeviceHandle hDevice, + NvU32 batTemp) +{ + NvU8 data = 0; + + //turn off the charger if the battery is overheating. + if ( batTemp > NVODM_BATTERY_OVERHEAT_THRESHOLD ) + { + if (!Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data)) + return NV_FALSE; + + data &= 0xFE; + if (!Pcf50626I2cWrite8(hDevice, PCF50626_CBCC1_ADDR, data)) + return NV_FALSE; + } + // turn it on otherwise + else + { + if (!Pcf50626I2cRead8(hDevice, PCF50626_CBCC1_ADDR, &data)) + return NV_FALSE; + + data |= 0x01; + if (!Pcf50626I2cWrite8(hDevice, PCF50626_CBCC1_ADDR, data)) + return NV_FALSE; + } + + return NV_TRUE; +} +#endif + + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h new file mode 100644 index 000000000000..2325fb75a9d2 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626.h @@ -0,0 +1,169 @@ +/* + * Copyright (c) 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_PMU_PCF50626_H +#define INCLUDED_PMU_PCF50626_H + +#include "nvodm_pmu.h" +#include"pmu_hal.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + + +#if (NV_DEBUG) +#define NVODMPMU_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODMPMU_PRINTF(x) +#endif + + +typedef struct Pcf50626StatusRec +{ + /* Low Battery voltage detected by BVM */ + NvBool lowBatt; + + /* PMU high temperature */ + NvBool highTemp; + + /* charger switch from CC mode to CV mode */ + NvBool chgCcToCv; + + /* Main charger Presents */ + NvBool mChgPresent; + + /* battery Full */ + NvBool batFull; + +} Pcf50626Status; + + + +typedef struct +{ + /* The handle to the I2C */ + NvOdmServicesI2cHandle hOdmI2C; + + /* The odm pmu service handle */ + NvOdmServicesPmuHandle hOdmPmuSevice; + + /* the PMU I2C device Address */ + NvU32 DeviceAddr; + + /* the PMU status */ + Pcf50626Status pmuStatus; + + /* battery presence */ + NvBool battPresence; + + /* PMU interrupt support enabled */ + NvBool pmuInterruptSupported; + + + /* The ref cnt table of the power supplies */ + NvU32 *supplyRefCntTable; + +}Pcf50626PrivData; + + +NvBool +Pcf50626Setup(NvOdmPmuDeviceHandle hDevice); + +void +Pcf50626Release(NvOdmPmuDeviceHandle hDevice); + +NvBool +Pcf50626GetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts); + +NvBool +Pcf50626SetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds); + +void +Pcf50626GetCapabilities( + NvU32 vddRail, + NvOdmPmuVddRailCapabilities* pCapabilities); + + +NvBool +Pcf50626GetAcLineStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuAcLineStatus *pStatus); + + +NvBool +Pcf50626GetBatteryStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU8 *pStatus); + +NvBool +Pcf50626GetBatteryData( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryData *pData); + +void +Pcf50626GetBatteryFullLifeTime( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU32 *pLifeTime); + +void +Pcf50626GetBatteryChemistry( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryChemistry *pChemistry); + +NvBool +Pcf50626SetChargingCurrent( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuChargingPath chargingPath, + NvU32 chargingCurrentLimitMa, + NvOdmUsbChargerType ChargerType); + +void Pcf50626InterruptHandler( NvOdmPmuDeviceHandle hDevice); + +#if defined(__cplusplus) +} +#endif + + +#endif // INCLUDED_PMU_PCF50626_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c new file mode 100644 index 000000000000..95347fa42cd7 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.c @@ -0,0 +1,196 @@ +/* + * Copyright (c) 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 "pcf50626_adc.h" +#include "pcf50626_i2c.h" +#include "pcf50626_reg.h" +//#include "pcf50626_supply_info.h" + +#define ADC_CONVERSION_DELAY_USEC 70 +#define ADC_CONVERSION_TIMEOUT_USEC 500 +#define ADC_CONVERSION_VOLTAGE_RANGE 2000 +#define ADC_CONVERSION_DIVIDOR 3 +#define ADC_CONVERSION_PRECISION 10 +#define ADC_CONVERSION_SUB_OFFSET 2250 + + +static NvBool +Pcf50626AdcIn1Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt); + +static NvBool +Pcf50626AdcIn2Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt); + + +/* read voltage from VBATSENSE */ +NvBool +Pcf50626AdcVBatSenseRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt) +{ + return Pcf50626AdcIn1Read(hDevice, volt); +} + +static NvBool +Pcf50626AdcIn1Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt) +{ + + NvU32 timeout = 0; + NvU8 dataS1 = 0; + NvU8 dataS3 = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(volt); + + // Turn off GPIO7 + if(! Pcf50626I2cWrite8(hDevice, PCF50626_GPIO7C1_ADDR, 0x0)) + return NV_FALSE; + + + //ADCC3 - Division sel + if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC3_ADDR, PCF50626_ADCC3_RESET)) + return NV_FALSE; + + + //ADCC1 - Resolustion, Mux Sel, Avg sel + if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x0C)) + return NV_FALSE; + + // Start Converstion + if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x0D)) + return NV_FALSE; + + // Wait for conversion + NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + + // make sure the conversion is completed, or timeout. + while (timeout < ADC_CONVERSION_TIMEOUT_USEC) + { + if(! Pcf50626I2cRead8(hDevice, PCF50626_ADCS3_ADDR, &dataS3)) + return NV_FALSE; + + if (dataS3 & 0x80) + break; + + NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + timeout += ADC_CONVERSION_DELAY_USEC; + } + + if (timeout >= ADC_CONVERSION_TIMEOUT_USEC) + { + NVODMPMU_PRINTF(("ADC conversion timeout.\n")); + return NV_FALSE; + } + + // read the conversion result + if (!Pcf50626I2cRead8(hDevice, PCF50626_ADCS1_ADDR, &dataS1)) + return NV_FALSE; + + // Get result + *volt = (((NvU32)((dataS1 << 2) | (dataS3 & 0x03))) * + ADC_CONVERSION_VOLTAGE_RANGE * ADC_CONVERSION_DIVIDOR) + >> ADC_CONVERSION_PRECISION; + + return NV_TRUE; +} + + + +/* read bat temperature voltage from ADC2 */ +NvBool +Pcf50626AdcVBatTempRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt) +{ + return Pcf50626AdcIn2Read(hDevice, volt); +} + +static NvBool +Pcf50626AdcIn2Read(NvOdmPmuDeviceHandle hDevice, NvU32 *volt) +{ + NvU32 timeout = 0; + NvU8 dataS1 = 0; + NvU8 dataS3 = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(volt); + + // Turn off GPIO7 + if(! Pcf50626I2cWrite8(hDevice, PCF50626_GPIO7C1_ADDR, 0x0)) + return NV_FALSE; + + + //ADCC3 - Division sel + if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC3_ADDR, PCF50626_ADCC3_RESET)) + return NV_FALSE; + + + //ADCC1 - Resolustion, Mux Sel, Avg sel + if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x2C)) + return NV_FALSE; + + // Start Converstion + if(! Pcf50626I2cWrite8(hDevice, PCF50626_ADCC1_ADDR, 0x2D)) + return NV_FALSE; + + // Wait for conversion + NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + + // make sure the conversion is completed, or timeout. + while (timeout < ADC_CONVERSION_TIMEOUT_USEC) + { + if(! Pcf50626I2cRead8(hDevice, PCF50626_ADCS3_ADDR, &dataS3)) + return NV_FALSE; + + if (dataS3 & 0x80) + break; + + NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + timeout += ADC_CONVERSION_DELAY_USEC; + } + + if (timeout >= ADC_CONVERSION_TIMEOUT_USEC) + { + NVODMPMU_PRINTF(("ADC conversion timeout.\n")); + return NV_FALSE; + } + + // read the conversion result + if (!Pcf50626I2cRead8(hDevice, PCF50626_ADCS1_ADDR, &dataS1)) + return NV_FALSE; + + // Get result + *volt = (((NvU32)((dataS1 << 2) | (dataS3 & 0x03))) * + ADC_CONVERSION_VOLTAGE_RANGE * ADC_CONVERSION_DIVIDOR) + >> ADC_CONVERSION_PRECISION; + + return NV_TRUE; +} + + + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h new file mode 100644 index 000000000000..e5022c449289 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_adc.h @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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_PCF50626_ADC_HEADER +#define INCLUDED_PCF50626_ADC_HEADER + + +/* the ADC is used for battery voltage conversion */ +#include "pcf50626.h" + + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* read voltage from VBATSENSE */ + +NvBool +Pcf50626AdcVBatSenseRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt); + + +/* read bat temperature voltage from ADC2 */ +NvBool +Pcf50626AdcVBatTempRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt); + +/* Calculate the battery temperature */ +NvU32 Pcf50626BatteryTemperature( + NvU32 VBatSense, + NvU32 VBatTemp); + + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_PCF50626_ADC_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c new file mode 100644 index 000000000000..814d12319dd5 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.c @@ -0,0 +1,257 @@ +/* + * Copyright (c) 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 "pcf50626_batterycharger.h" +#include "pcf50626_adc.h" +#include "pcf50626_i2c.h" +#include "pcf50626_reg.h" + + +/* Get battery Voltage */ +NvBool +Pcf50626BatteryChargerGetVoltage(NvOdmPmuDeviceHandle hDevice, NvU32 *res) +{ + NvU32 volt = 0; + ///TODO: check on HW to see the relation between adc output and the voltage. for now, assume they are the same. + if(! Pcf50626AdcVBatSenseRead(hDevice,&volt)) + return NV_FALSE; + + *res = volt; + return NV_TRUE; +} + + + +/* check OnKey Level */ +NvBool +Pcf50626BatteryChargerOnKeyStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data)) + return NV_FALSE + ; + data = (data >> PCF50626_OOCS_ONKEY_SHIFT) & PCF50626_OOCS_ONKEY_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + + return NV_TRUE; +} + +/* check OnKey Level */ +NvBool +Pcf50626BatteryChargerRec1Status(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data)) + return NV_FALSE; + data = (data >> PCF50626_OOCS_REC1_SHIFT) & PCF50626_OOCS_REC1_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + + return NV_TRUE; +} + +/* check battery status */ +NvBool +Pcf50626BatteryChargerBattStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data)) + return NV_FALSE; + data = (data >> PCF50626_OOCS_BATOK_SHIFT) & PCF50626_OOCS_BATOK_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + + return NV_TRUE; +} + +/* check main charger status */ +NvBool +Pcf50626BatteryChargerMainChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_OOCS_MCHGOK_SHIFT) & PCF50626_OOCS_MCHGOK_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + + +/* check USB charger status */ +NvBool +Pcf50626BatteryChargerUsbChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_OOCS_UCHGOK_SHIFT) & PCF50626_OOCS_UCHGOK_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + + +/* check temparature status */ +NvBool +Pcf50626BatteryChargerTempStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_OOCS_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_OOCS_TEMPOK_SHIFT) & PCF50626_OOCS_TEMPOK_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +/* check CBC batt_ful status */ +NvBool +Pcf50626BatteryChargerCBCBattFul(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS1_BATTFUL_SHIFT) & PCF50626_CBCS1_BATTFUL_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + + +/* check CBC thermal limit activation status */ +NvBool +Pcf50626BatteryChargerCBCTlimStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS1_TLIMIT_SHIFT) & PCF50626_CBCS1_TLIMIT_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +/* check CBC batt_ful status */ +NvBool +Pcf50626BatteryChargerCBCWdExpired(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS1_WDEXP_SHIFT) & PCF50626_CBCS1_WDEXP_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + + +/* check CBC charger current status */ +NvBool +Pcf50626BatteryChargerCBCChgCurStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS1_ILIMIT_SHIFT) & PCF50626_CBCS1_ILIMIT_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +/* check CBC charger voltage status */ +NvBool +Pcf50626BatteryChargerCBCChgVoltStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS1_VLIMIT_SHIFT) & PCF50626_CBCS1_VLIMIT_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +/* check CBC charger resume status */ +NvBool +Pcf50626BatteryChargerCBCChgResStatus(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS1_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS1_RESSTAT_SHIFT) & PCF50626_CBCS1_RESSTAT_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + + +/* check USB suspend status */ +NvBool +Pcf50626BatteryChargerCBCUsbSuspStat(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS2_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS2_USBSUSPSTAT_SHIFT) & PCF50626_CBCS2_USBSUSPSTAT_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + +/* check charger over-voltage protection status */ +NvBool +Pcf50626BatteryChargerCBCChgOvpStat(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU8 data = 0; + + if(! Pcf50626I2cRead8(hDevice, PCF50626_CBCS2_ADDR, &data)) + return NV_FALSE; + + data = (data >> PCF50626_CBCS2_CHGOVP_SHIFT) & PCF50626_CBCS2_CHGOVP_MASK; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + return NV_TRUE; +} + + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h new file mode 100644 index 000000000000..ad5ebbc9f344 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_batterycharger.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 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_PCF50626_BATTERYCHARGER_HEADER +#define INCLUDED_PCF50626_BATTERYCHARGER_HEADER + + + +#include "pcf50626.h" + +/* the battery charger functions */ +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Initliase all registers that related to battery charger */ +NvBool +Pcf50626BatteryChargerSetup(NvOdmPmuDeviceHandle hDevice); + +/* Get battery Voltage */ +NvBool +Pcf50626BatteryChargerGetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 *res); + + +/* check OnKey level */ +NvBool +Pcf50626BatteryChargerOnKeyStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check rec1 level */ +NvBool +Pcf50626BatteryChargerRec1Status( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check battery status */ +NvBool +Pcf50626BatteryChargerBattStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check main charger status */ +NvBool +Pcf50626BatteryChargerMainChgPresent( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check USB charger status */ +NvBool +Pcf50626BatteryChargerUsbChgPresent( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check temparature status */ +NvBool +Pcf50626BatteryChargerTempStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + + +/* check CBC batt_ful status */ +NvBool +Pcf50626BatteryChargerCBCBattFul( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + + + +/* check CBC thermal limit activation status */ +NvBool +Pcf50626BatteryChargerCBCTlimStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check CBC batt_ful status */ +NvBool +Pcf50626BatteryChargerCBCWdExpired( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + + +/* check CBC charger current status */ +NvBool +Pcf50626BatteryChargerCBCChgCurStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check CBC charger voltage status */ +NvBool +Pcf50626BatteryChargerCBCChgVoltStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check CBC charger resume status */ +NvBool +Pcf50626BatteryChargerCBCChgResStatus( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check CBC main batt presence */ +NvBool +Pcf50626BatteryChargerCBCMainBatt( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check USB suspend status */ +NvBool +Pcf50626BatteryChargerCBCUsbSuspStat( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + +/* check charger over-voltage protection status */ +NvBool +Pcf50626BatteryChargerCBCChgOvpStat( + NvOdmPmuDeviceHandle hDevice, + NvBool *status); + + + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_PCF50626_BATTERYCHARGER_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c new file mode 100644 index 000000000000..38990b3ffada --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 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 "pcf50626_i2c.h" +#include "nvodm_pmu.h" +#include "nvodm_services.h" + + +NvBool Pcf50626I2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cTransactionInfo TransactionInfo; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate; + + WriteBuffer[0] = Addr & 0xFF; // PMU offset + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = hPmu->DeviceAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool Pcf50626I2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data) +{ + NvU8 ReadBuffer = 0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + // Write the PMU offset + ReadBuffer = Addr & 0xFF; + + TransactionInfo[0].Address = hPmu->DeviceAddr; + TransactionInfo[0].Buf = &ReadBuffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + TransactionInfo[1].Address = (hPmu->DeviceAddr | 0x1); + TransactionInfo[1].Buf = &ReadBuffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + // Read data from PMU at the specified offset + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2, + PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = ReadBuffer; + return NV_TRUE; +} + +NvBool Pcf50626I2cWrite32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 Data) +{ + NvU8 WriteBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo; + + WriteBuffer[0] = (NvU8)(Addr & 0xFF); + WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF); + WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF); + WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF); + WriteBuffer[4] = (NvU8)(Data & 0xFF); + + TransactionInfo.Address = hPmu->DeviceAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 5; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo, 1, + PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite32 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + return NV_TRUE; +} + +NvBool Pcf50626I2cRead32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 *Data) +{ + NvU8 ReadBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + Pcf50626PrivData *hPmu = (Pcf50626PrivData*)hDevice->pPrivate; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + + ReadBuffer[0] = Addr & 0xFF; + + TransactionInfo[0].Address = hPmu->DeviceAddr; + TransactionInfo[0].Buf = &ReadBuffer[0]; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + + TransactionInfo[1].Address = (hPmu->DeviceAddr | 0x1); + TransactionInfo[1].Buf = &ReadBuffer[0]; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 4; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], 2, + PCF506226_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead32 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) | + (ReadBuffer[2] << 8) | ReadBuffer[3]; + + return NV_TRUE; +} + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h new file mode 100644 index 000000000000..bc4b5aead9c8 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_i2c.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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_NVODM_PMU_PCF50626_I2C_H +#define INCLUDED_NVODM_PMU_PCF50626_I2C_H + +#include "pcf50626.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// Constant definition +#define PMU_PCF50626_DEVADDR 0xE0 +#define PCF506226_I2C_SPEED_KHZ 400 + +// Function declaration +NvBool Pcf50626I2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data); + +NvBool Pcf50626I2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data); + +NvBool Pcf50626I2cWrite32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 Data); + +NvBool Pcf50626I2cRead32( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU32 *Data); + + + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_PMU_PCF50626_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c new file mode 100644 index 000000000000..da9c4b605976 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.c @@ -0,0 +1,167 @@ +/* + * Copyright (c) 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 "pcf50626_interrupt.h" +#include "pcf50626_batterycharger.h" +#include "pcf50626_i2c.h" +#include "pcf50626_reg.h" +#include "nvodm_services.h" + +NvBool Pcf50626SetupInterrupt(NvOdmPmuDeviceHandle hDevice, + Pcf50626Status *pmuStatus) +{ + NvBool status = NV_FALSE; + NvU8 data = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pmuStatus); + + /* Init Pmu Status */ + pmuStatus->lowBatt = NV_FALSE; + pmuStatus->highTemp = NV_FALSE; + pmuStatus->chgCcToCv = NV_FALSE; + + if (!Pcf50626BatteryChargerMainChgPresent(hDevice,&status)) + return NV_FALSE; + pmuStatus->mChgPresent = status; + + + /* Set up Interrupt Mask */ + data = (NvU8) ~(PCF50626_INT1_LOWBATT | PCF50626_INT1_HIGHTEMP); + if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT1M_ADDR, data )) + return NV_FALSE; + + data = 0; + data = (NvU8) ~PCF50626_INT2_VMAX; + if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT2M_ADDR, data )) + return NV_FALSE; + + data = 0; + data = (NvU8) ~(PCF50626_INT3_MCHGINS | PCF50626_INT3_MCHGRM); + if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT3M_ADDR, data )) + return NV_FALSE; + + data = 0; + data = (NvU8) ~(PCF50626_INT4_BATFUL | PCF50626_INT4_CHGRES); + if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT4M_ADDR, data )) + return NV_FALSE; + + //if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT5M_ADDR, 0xff)) + // return NV_FALSE; + + //if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT6M_ADDR, 0xff)) + // return NV_FALSE; + + //if(! Pcf50626I2cWrite8(hDevice, PCF50626_INT7M_ADDR, 0xff)) + // return NV_FALSE; + + return NV_TRUE; +} + +void Pcf50626InterruptHandler_int(NvOdmPmuDeviceHandle hDevice, + Pcf50626Status *pmuStatus) +{ + + NvU8 data = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pmuStatus); + + // INT1 + if (!Pcf50626I2cRead8(hDevice, PCF50626_INT1_ADDR, &data)) + { + NVODMPMU_PRINTF(("Error reading INT1")); + return; + } + if (data != 0) + { + if (data & PCF50626_INT1_HIGHTEMP) + pmuStatus->highTemp = NV_TRUE; + else + pmuStatus->highTemp = NV_FALSE; + if (data & PCF50626_INT1_LOWBATT) + pmuStatus->lowBatt = NV_TRUE; + else + pmuStatus->lowBatt = NV_FALSE; + } + + // INT2 + if (!Pcf50626I2cRead8(hDevice, PCF50626_INT2_ADDR, &data)) + { + NVODMPMU_PRINTF(("Error reading INT2")); + return; + } + if (data != 0) + { + if (data & PCF50626_INT2_VMAX) + pmuStatus->chgCcToCv = NV_TRUE; + else + pmuStatus->chgCcToCv = NV_FALSE; + } + + // INT3 + if (!Pcf50626I2cRead8(hDevice, PCF50626_INT3_ADDR, &data)) + { + NVODMPMU_PRINTF(("Error reading INT3")); + return; + } + if (data != 0) + { + if (data & PCF50626_INT3_MCHGRM) + pmuStatus->mChgPresent = NV_FALSE; + + if (data & PCF50626_INT3_MCHGINS) + { + pmuStatus->mChgPresent = NV_TRUE; + NvOdmEnableOtgCircuitry(NV_TRUE); + } + } + + // INT4 + if (!Pcf50626I2cRead8(hDevice, PCF50626_INT4_ADDR, &data)) + { + NVODMPMU_PRINTF(("Error reading INT4")); + return; + } + if (data != 0) + { + if (data & PCF50626_INT4_CHGRES) + pmuStatus->batFull = NV_FALSE; + + if (data & PCF50626_INT4_BATFUL) + pmuStatus->batFull = NV_TRUE; + } + +} + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h new file mode 100644 index 000000000000..2cf1b404bc8c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_interrupt.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 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_PCF50626_INTERRUPT_HEADER +#define INCLUDED_PCF50626_INTERRUPT_HEADER + +#include "pcf50626.h" + + +#if defined(__cplusplus) +extern "C" +{ +#endif + + +NvBool +Pcf50626SetupInterrupt( + NvOdmPmuDeviceHandle hDevice, + Pcf50626Status *pmuStatus); + + + +void +Pcf50626InterruptHandler_int( + NvOdmPmuDeviceHandle hDevice, + Pcf50626Status *pmuStatus); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_PCF50626_INTERRUPT_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h new file mode 100644 index 000000000000..2454487149e8 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_reg.h @@ -0,0 +1,491 @@ +/* + * 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 PCF50626_REG_HEADER +#define PCF50626_REG_HEADER + +#if defined(__cplusplus) +extern "C" +{ +#endif + + +// The following are the OTP reset values +#define PCF50626_ID_DEFAULT 0x31 // TBD, may change +#define PCF50626_BVMC_RESET 0x18 + +#define PCF50626_D1REGC1_RESET 0x6C +#define PCF50626_D1REGC2_RESET 0x01 +#define PCF50626_D1REGC3_RESET 0x00 + +#define PCF50626_D2REGC1_RESET 0x6C +#define PCF50626_D2REGC2_RESET 0xE1 +#define PCF50626_D2REGC3_RESET 0x00 + +#define PCF50626_D3REGC1_RESET 0x18 +#define PCF50626_D3REGC2_RESET 0xE1 +#define PCF50626_D3REGC3_RESET 0x80 + +#define PCF50626_D7REGC2_RESET 0x01 +#define PCF50626_D7REGC3_RESET 0x00 + +#define PCF50626_D8REGC2_RESET 0xE1 +#define PCF50626_D8REGC3_RESET 0x40 + +#define PCF50626_RF1REGC1_RESET 0x58 +#define PCF50626_RF1REGC2_RESET 0x01 +#define PCF50626_RF1REGC3_RESET 0x40 + +#define PCF50626_RF2REGC1_RESET 0x58 +#define PCF50626_RF2REGC2_RESET 0x01 +#define PCF50626_RF2REGC3_RESET 0x40 + +#define PCF50626_IOREGC1_RESET 0x30 +#define PCF50626_IOREGC2_RESET 0xE1 +#define PCF50626_IOREGC3_RESET 0x40 + +#define PCF50626_USBREGC1_RESET 0x58 +#define PCF50626_USBREGC2_RESET 0xE1 +#define PCF50626_USBREGC3_RESET 0x40 + +#define PCF50626_LCREGC1_RESET 0x18 +#define PCF50626_LCREGC2_RESET 0xE1 +#define PCF50626_LCREGC3_RESET 0x00 + +#define PCF50626_DCD1C1_RESET 0x18 +#define PCF50626_DCD1C2_RESET 0xE1 +#define PCF50626_DCD1C3_RESET 0x00 +#define PCF50626_DCD1C4_RESET 0x0F + +#define PCF50626_DCD2C1_RESET 0x30 +#define PCF50626_DCD2C2_RESET 0xE1 +#define PCF50626_DCD2C3_RESET 0x80 +#define PCF50626_DCD2C4_RESET 0x0F + +#define PCF50626_DCUDC2_RESET 0xE1 +#define PCF50626_DCUDC3_RESET 0xC0 + +#define PCF50626_ALMCAL_RESET 0x11 +#define PCF50626_ALMCRV1_RESET 0x01 +#define PCF50626_ALMCRV2_RESET 0x28 +#define PCF50626_ALMCRV3_RESET 0x50 +#define PCF50626_ALMCRV4_RESET 0x78 +#define PCF50626_LED1C_RESET 0x4D +#define PCF50626_LEDCC_RESET 0x01 + +#define PCF50626_ADCC1_RESET 0x02 +#define PCF50626_ADCC2_RESET 0x00 +#define PCF50626_ADCC3_RESET 0x00 +#define PCF50626_ADCC4_RESET 0x00 + +#define PCF50626_DCULEDC1_RESET 0x08 +#define PCF50626_DCULEDC2_RESET 0x01 +#define PCF50626_DCULEDC3_RESET 0x00 +#define PCF50626_DCULEDDIMMAN_RESET 0x3F + +#define PCF50626_CBCC1_RESET 0x2B +#define PCF50626_CBCC2_RESET 0x5A +#define PCF50626_CBCC3_RESET 0x12 +#define PCF50626_CBCC4_RESET 0x12 +#define PCF50626_CBCC5_RESET 0x0B +#define PCF50626_CBCC6_RESET 0x02 + +#define PCF50626_BBCC1_RESET 0x00 + + +//Table. 168 +#define PCF50626_ID_ADDR 0x00 +#define PCF50626_INT1_ADDR 0x01 +#define PCF50626_INT2_ADDR 0x02 +#define PCF50626_INT3_ADDR 0x03 +#define PCF50626_INT4_ADDR 0x04 +#define PCF50626_INT5_ADDR 0x05 +#define PCF50626_INT6_ADDR 0x06 +#define PCF50626_INT7_ADDR 0x09 + +#define PCF50626_INT1M_ADDR 0x0A +#define PCF50626_INT2M_ADDR 0x0B +#define PCF50626_INT3M_ADDR 0x0C +#define PCF50626_INT4M_ADDR 0x0D +#define PCF50626_INT5M_ADDR 0x0E +#define PCF50626_INT6M_ADDR 0x0F +#define PCF50626_INT7M_ADDR 0x12 + +#define PCF50626_ERROR_ADDR 0x13 + +#define PCF50626_OOCC1_ADDR 0x14 +#define PCF50626_OOCC2_ADDR 0x15 +#define PCF50626_OOCPH_ADDR 0x16 +#define PCF50626_OOCS_ADDR 0x17 + +#define PCF50626_BVMC_ADDR 0x18 + +#define PCF50626_RECC1_ADDR 0x19 +#define PCF50626_RECC2_ADDR 0x1A +#define PCF50626_RECS_ADDR 0x1B + +#define PCF50626_RTC1_ADDR 0x1C +#define PCF50626_RTC2_ADDR 0x1D +#define PCF50626_RTC3_ADDR 0x1E +#define PCF50626_RTC4_ADDR 0x1F + +#define PCF50626_RTC1A_ADDR 0x20 +#define PCF50626_RTC2A_ADDR 0x21 +#define PCF50626_RTC3A_ADDR 0x22 +#define PCF50626_RTC4A_ADDR 0x23 + +#define PCF50626_CBCC1_ADDR 0x24 +#define PCF50626_CBCC2_ADDR 0x25 +#define PCF50626_CBCC3_ADDR 0x26 +#define PCF50626_CBCC4_ADDR 0x27 +#define PCF50626_CBCC5_ADDR 0x28 +#define PCF50626_CBCC6_ADDR 0x29 + +#define PCF50626_CBCS1_ADDR 0x2A +#define PCF50626_CBCS2_ADDR 0x2B +#define PCF50626_BBCC1_ADDR 0x2C +#define PCF50626_PWM1S_ADDR 0x2D +#define PCF50626_PWM1D_ADDR 0x2E +#define PCF50626_PWM2S_ADDR 0x2F +#define PCF50626_PWM2D_ADDR 0x30 + +#define PCF50626_LED1C_ADDR 0x31 +#define PCF50626_LED2C_ADDR 0x32 +#define PCF50626_LEDCC_ADDR 0x33 + +#define PCF50626_ADCC2_ADDR 0x34 +#define PCF50626_ADCC3_ADDR 0x35 +#define PCF50626_ADCC4_ADDR 0x36 +#define PCF50626_ADCC1_ADDR 0x37 +#define PCF50626_ADCS1_ADDR 0x38 +#define PCF50626_ADCS2_ADDR 0x39 +#define PCF50626_ADCS3_ADDR 0x3A + +#define PCF50626_TSIC2_ADDR 0x3B +#define PCF50626_TSIC1_ADDR 0x3C +#define PCF50626_TSIDAT1_ADDR 0x3D +#define PCF50626_TSIDAT2_ADDR 0x3E +#define PCF50626_TSIDAT3_ADDR 0x3F + +#define PCF50626_GPIO1C1_ADDR 0x40 +#define PCF50626_E1REGC2_ADDR 0x41 +#define PCF50626_E1REGC3_ADDR 0x42 +#define PCF50626_GPIO2C1_ADDR 0x43 +#define PCF50626_E2REGC2_ADDR 0x44 +#define PCF50626_E2REGC3_ADDR 0x45 +#define PCF50626_GPIO3C1_ADDR 0x46 +#define PCF50626_E3REGC2_ADDR 0x47 +#define PCF50626_E3REGC3_ADDR 0x48 +#define PCF50626_GPIO4C1_ADDR 0x49 +#define PCF50626_E4REGC2_ADDR 0x4A +#define PCF50626_E4REGC3_ADDR 0x4B +#define PCF50626_GPIO5C1_ADDR 0x4C +#define PCF50626_E5REGC2_ADDR 0x4D +#define PCF50626_E5REGC3_ADDR 0x4E +#define PCF50626_GPIO6C1_ADDR 0x4F +#define PCF50626_E6REGC2_ADDR 0x50 +#define PCF50626_E6REGC3_ADDR 0x51 + +#define PCF50626_GPO1C1_ADDR 0x52 +#define PCF50626_EO1REGC2_ADDR 0x53 +#define PCF50626_EO1REGC3_ADDR 0x54 +#define PCF50626_GPO2C1_ADDR 0x55 +#define PCF50626_EO2REGC2_ADDR 0x56 +#define PCF50626_EO2REGC3_ADDR 0x57 +#define PCF50626_GPO3C1_ADDR 0x58 +#define PCF50626_EO3REGC2_ADDR 0x59 +#define PCF50626_EO3REGC3_ADDR 0x5A +#define PCF50626_GPO4C1_ADDR 0x5B +#define PCF50626_EO4REGC2_ADDR 0x5C +#define PCF50626_EO4REGC3_ADDR 0x5D + +#define PCF50626_D1REGC1_ADDR 0x5E +#define PCF50626_D1REGC2_ADDR 0x5F +#define PCF50626_D1REGC3_ADDR 0x60 + +#define PCF50626_D2REGC1_ADDR 0x61 +#define PCF50626_D2REGC2_ADDR 0x62 +#define PCF50626_D2REGC3_ADDR 0x63 + +#define PCF50626_D3REGC1_ADDR 0x64 +#define PCF50626_D3REGC2_ADDR 0x65 +#define PCF50626_D3REGC3_ADDR 0x66 + +#define PCF50626_D4REGC1_ADDR 0x67 +#define PCF50626_D4REGC2_ADDR 0x68 +#define PCF50626_D4REGC3_ADDR 0x69 + +#define PCF50626_D5REGC1_ADDR 0x6A +#define PCF50626_D5REGC2_ADDR 0x6B +#define PCF50626_D5REGC3_ADDR 0x6C + +#define PCF50626_D6REGC1_ADDR 0x6D +#define PCF50626_D6REGC2_ADDR 0x6E +#define PCF50626_D6REGC3_ADDR 0x6F + +#define PCF50626_D7REGC1_ADDR 0x70 +#define PCF50626_D7REGC2_ADDR 0x71 +#define PCF50626_D7REGC3_ADDR 0x72 + +#define PCF50626_D8REGC1_ADDR 0x73 +#define PCF50626_D8REGC2_ADDR 0x74 +#define PCF50626_D8REGC3_ADDR 0x75 + +#define PCF50626_RF1REGC1_ADDR 0x76 +#define PCF50626_RF1REGC2_ADDR 0x77 +#define PCF50626_RF1REGC3_ADDR 0x78 + +#define PCF50626_RF2REGC1_ADDR 0x79 +#define PCF50626_RF2REGC2_ADDR 0x7A +#define PCF50626_RF2REGC3_ADDR 0x7B + +#define PCF50626_RF3REGC1_ADDR 0x7C +#define PCF50626_RF3REGC2_ADDR 0x7D +#define PCF50626_RF3REGC3_ADDR 0x7E + +#define PCF50626_RF4REGC1_ADDR 0x7F +#define PCF50626_RF4REGC2_ADDR 0x80 +#define PCF50626_RF4REGC3_ADDR 0x81 + +#define PCF50626_IOREGC1_ADDR 0x82 +#define PCF50626_IOREGC2_ADDR 0x83 +#define PCF50626_IOREGC3_ADDR 0x84 + +#define PCF50626_USBREGC1_ADDR 0x85 +#define PCF50626_USBREGC2_ADDR 0x86 +#define PCF50626_USBREGC3_ADDR 0x87 + +#define PCF50626_USIMREGC1_ADDR 0x88 +#define PCF50626_USIMREGC2_ADDR 0x89 +#define PCF50626_USIMREGC3_ADDR 0x8A + +#define PCF50626_LCREGC1_ADDR 0x8B +#define PCF50626_LCREGC2_ADDR 0x8C +#define PCF50626_LCREGC3_ADDR 0x8D + +#define PCF50626_HCREGC1_ADDR 0x8E +#define PCF50626_HCREGC2_ADDR 0x8F +#define PCF50626_HCREGC3_ADDR 0x90 + +#define PCF50626_DCD1C1_ADDR 0x91 +#define PCF50626_DCD1C2_ADDR 0x92 +#define PCF50626_DCD1C3_ADDR 0x93 +#define PCF50626_DCD1C4_ADDR 0x94 + +#define PCF50626_DCD1DVM1_ADDR 0x95 +#define PCF50626_DCD1DVM2_ADDR 0x96 +#define PCF50626_DCD1DVM3_ADDR 0x97 +#define PCF50626_DCD1DVMTIM_ADDR 0x98 + +#define PCF50626_DCD2C1_ADDR 0x99 +#define PCF50626_DCD2C2_ADDR 0x9A +#define PCF50626_DCD2C3_ADDR 0x9B +#define PCF50626_DCD2C4_ADDR 0x9C + +#define PCF50626_DCD2DVM1_ADDR 0x9D +#define PCF50626_DCD2DVM2_ADDR 0x9E +#define PCF50626_DCD2DVM3_ADDR 0x9F +#define PCF50626_DCD2DVMTIM_ADDR 0xA0 + +#define PCF50626_DCUDC1_ADDR 0xA1 +#define PCF50626_DCUDC2_ADDR 0xA2 +#define PCF50626_DCUDC3_ADDR 0xA3 +#define PCF50626_DCUDC4_ADDR 0xA4 +#define PCF50626_DCUDDVMTIM_ADDR 0xA5 + +#define PCF50626_DCULEDC1_ADDR 0xA6 +#define PCF50626_DCULEDC2_ADDR 0xA7 +#define PCF50626_DCULEDC3_ADDR 0xA8 +#define PCF50626_DCULED_DIMMAN_ADDR 0xA9 + +#define PCF50626_ALMCAL_ADDR 0xAA +#define PCF50626_ALMCALMEA_ADDR 0xAB +#define PCF50626_ALMCRV1_ADDR 0xAC +#define PCF50626_ALMCRV2_ADDR 0xAD +#define PCF50626_ALMCRV3_ADDR 0xAE +#define PCF50626_ALMCRV4_ADDR 0xAF + +#define PCF50626_GPIOS_ADDR 0xB0 +#define PCF50626_DREGS1_ADDR 0xB1 +#define PCF50626_DREGS2_ADDR 0xB2 +#define PCF50626_RFREGS_ADDR 0xB3 +#define PCF50626_GREGS_ADDR 0xB4 + +#define PCF50626_GPIO7C1_ADDR 0xB5 +#define PCF50626_GPIO8C1_ADDR 0xB6 + +#define PCF50626_USIMDETC_ADDR 0xB7 + +#define PCF50626_TSINOI_ADDR 0xFE +#define PCF50626_TSIDAT4_ADDR 0xFF + + +/* field defines for register bit ops */ +#define PCF50626_C2_OPMOD_SHIFT 0x05 +#define PCF50626_C2_OPMOD_ON 0xE1 +#define PCF50626_C2_OPMOD_OFF 0x01 +#define PCF50626_C1_OUTPUT_MASK 0x7F + +#define PCF50626_OOCS_ONKEY_SHIFT 0x00 +#define PCF50626_OOCS_ONKEY_MASK 0x01 +#define PCF50626_OOCS_REC1_SHIFT 0x01 +#define PCF50626_OOCS_REC1_MASK 0x01 +#define PCF50626_OOCS_BATOK_SHIFT 0x02 +#define PCF50626_OOCS_BATOK_MASK 0x01 +#define PCF50626_OOCS_MCHGOK_SHIFT 0x04 +#define PCF50626_OOCS_MCHGOK_MASK 0x01 +#define PCF50626_OOCS_UCHGOK_SHIFT 0x05 +#define PCF50626_OOCS_UCHGOK_MASK 0x01 +#define PCF50626_OOCS_TEMPOK_SHIFT 0x06 +#define PCF50626_OOCS_TEMPOK_MASK 0x01 + +#define PCF50626_CBCS1_BATTFUL_SHIFT 0x00 +#define PCF50626_CBCS1_BATTFUL_MASK 0x01 +#define PCF50626_CBCS1_TLIMIT_SHIFT 0x01 +#define PCF50626_CBCS1_TLIMIT_MASK 0x01 +#define PCF50626_CBCS1_WDEXP_SHIFT 0x02 +#define PCF50626_CBCS1_WDEXP_MASK 0x01 +#define PCF50626_CBCS1_ILIMIT_SHIFT 0x03 +#define PCF50626_CBCS1_ILIMIT_MASK 0x01 +#define PCF50626_CBCS1_VLIMIT_SHIFT 0x04 +#define PCF50626_CBCS1_VLIMIT_MASK 0x01 +#define PCF50626_CBCS1_RESSTAT_SHIFT 0x07 +#define PCF50626_CBCS1_RESSTAT_MASK 0x01 +#define PCF50626_CBCS2_NOBAT_SHIFT 0x00 +#define PCF50626_CBCS2_NOBAT_MASK 0x01 +#define PCF50626_CBCS2_USBSUSPSTAT_SHIFT 0x02 +#define PCF50626_CBCS2_USBSUSPSTAT_MASK 0x01 +#define PCF50626_CBCS2_CHGOVP_SHIFT 0x03 +#define PCF50626_CBCS2_CHGOVP_MASK 0x01 + +#define PCF50626_ADCC1_STARTCMD_SHIFT 0x00 +#define PCF50626_ADCC1_STARTCMD_MASK 0x01 +#define PCF50626_ADCC1_STARTCMD_START 0x01 +#define PCF50626_ADCC1_STARTCMD_STOP 0x00 + +#define PCF50626_ADCS3_ADCRDY_SHIFT 0x07 +#define PCF50626_ADCS3_ADCRDY_MASK 0x01 +#define PCF50626_ADCS3_ADCRDY_READY 0x01 + +#define PCF50626_DCULED_DIMMAN_LEDMAN_MASK 0x3F +#define PCF50626_DCULED_DIMMAN_LEDMAN_SHIFT 0x00 + +#define PCF50626_DCULED_DIMMAN_ALMSEL_MASK 0x01 +#define PCF50626_DCULED_DIMMAN_ALMSEL_SHIFT 0x06 +#define PCF50626_DCULED_DIMMAN_ALMSEL_ALM 0x01 +#define PCF50626_DCULED_DIMMAN_ALMSEL_MAN 0x00 + +#define PCF50626_INT1_LOWBATT 0x01 +#define PCF50626_INT1_HIGHTEMP 0x80 +#define PCF50626_INT2_VMAX 0x40 +#define PCF50626_INT3_MCHGINS 0x40 +#define PCF50626_INT3_MCHGRM 0x80 +#define PCF50626_INT4_CHGRES 0x01 +#define PCF50626_INT4_BATFUL 0x08 + +#define PCF50626_CBCC1_CHGENA_SHIFT 0x00 +#define PCF50626_CBCC1_CHGENA_MASK 0x01 +#define PCF50626_CBCC2_SUSPENA_SHIFT 0x02 +#define PCF50626_CBCC2_SUSPENA_MASK 0x01 + +//rail specs +#define PCF50626_DCDXOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_DCDXOUT_VOLTAGE_MIN_MV 625 +#define PCF50626_DCDXOUT_VOLTAGE_STEP_MV 25 +#define PCF50626_DCDXOUT_VOLTAGE_MAX_MV 2700 +#define PCF50626_DCDXOUT_TURNON_TIME_MICROSEC 365 +#define PCF50626_DCDXOUT_SWITCH_TIME_MICROSEC 20 + +#define PCF50626_DCUDOUT_MODE1_VOLTAGE_OFFSET_MV 2675 +#define PCF50626_DCUDOUT_MODE1_VOLTAGE_MIN_MV 3100 +#define PCF50626_DCUDOUT_MODE1_VOLTAGE_STEP_MV 25 +#define PCF50626_DCUDOUT_MODE1_VOLTAGE_MAX_MV 4975 +#define PCF50626_DCUDOUT_TURNON_TIME_MICROSEC 65 +#define PCF50626_DCUDOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_DXREGOUT_VOLTAGE_MIN_MV 1200 +#define PCF50626_DXREGOUT_VOLTAGE_STEP_MV 100 +#define PCF50626_DXREGOUT_VOLTAGE_MAX_MV 3300 +#define PCF50626_DXREGOUT_TURNON_TIME_MICROSEC 85 +#define PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_RFXREGOUT_VOLTAGE_MIN_MV 1200 +#define PCF50626_RFXREGOUT_VOLTAGE_STEP_MV 100 +#define PCF50626_RFXREGOUT_VOLTAGE_MAX_MV 3000 +#define PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC 285 +#define PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_HCREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_HCREGOUT_VOLTAGE_MIN_MV 1800 +#define PCF50626_HCREGOUT_VOLTAGE_STEP_MV 100 +#define PCF50626_HCREGOUT_VOLTAGE_MAX_MV 3000 +#define PCF50626_HCREGOUT_TURNON_TIME_MICROSEC 85 +#define PCF50626_HCREGOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_IOREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_IOREGOUT_VOLTAGE_MIN_MV 1200 +#define PCF50626_IOREGOUT_VOLTAGE_STEP_MV 100 +#define PCF50626_IOREGOUT_VOLTAGE_MAX_MV 3300 +#define PCF50626_IOREGOUT_TURNON_TIME_MICROSEC 85 +#define PCF50626_IOREGOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_USBREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_USBREGOUT_VOLTAGE_MIN_MV 1200 +#define PCF50626_USBREGOUT_VOLTAGE_STEP_MV 100 +#define PCF50626_USBREGOUT_VOLTAGE_MAX_MV 3300 +#define PCF50626_USBREGOUT_TURNON_TIME_MICROSEC 85 +#define PCF50626_USBREGOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_USIMREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_USIMREGOUT_VOLTAGE_MIN_MV 1800 +#define PCF50626_USIMREGOUT_VOLTAGE_STEP_MV 100 +#define PCF50626_USIMREGOUT_VOLTAGE_MAX_MV 3000 +#define PCF50626_USIMREGOUT_TURNON_TIME_MICROSEC 105 +#define PCF50626_USIMREGOUT_SWITCH_TIME_MICROSEC 0 + +#define PCF50626_LCREGOUT_VOLTAGE_OFFSET_MV 600 +#define PCF50626_LCREGOUT_VOLTAGE_MIN_MV 600 +#define PCF50626_LCREGOUT_VOLTAGE_STEP_MV 50 +#define PCF50626_LCREGOUT_VOLTAGE_MAX_MV 2900 +#define PCF50626_LCREGOUT_VOLTAGE_RESCHANGE_MV 1400 +#define PCF50626_LCREGOUT_TURNON_TIME_MICROSEC 125 +#define PCF50626_LCREGOUT_SWITCH_TIME_MICROSEC 0 + +#if defined(__cplusplus) +} +#endif + + +#endif //PCF50626_VOLTAGE_INFO_TABLE_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c new file mode 100644 index 000000000000..ca35bab03b2d --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 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 "pcf50626_rtc.h" +#include "pcf50626_i2c.h" +#include "pcf50626_reg.h" + +/* Read RTC count register */ + +static NvBool bRtcNotInitialized = NV_TRUE; + +NvBool +Pcf50626RtcCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + if (Pcf50626RtcWasStartUpFromNoPower(hDevice) && bRtcNotInitialized) + { + if (!Pcf50626I2cWrite32 (hDevice, PCF50626_RTC1_ADDR, 0)) + { + return NV_FALSE; + } + bRtcNotInitialized = NV_FALSE; + *Count = 0; + return NV_TRUE; + } else + { + return ( Pcf50626I2cRead32 (hDevice, PCF50626_RTC1_ADDR, Count) ); + } +} + +/* Write RTC count register */ + +NvBool +Pcf50626RtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + NvBool ret; + + ret = Pcf50626I2cWrite32 (hDevice, PCF50626_RTC1_ADDR, Count); + + if (ret && bRtcNotInitialized) + bRtcNotInitialized = NV_FALSE; + + return ret; +} + +/* Read RTC alarm count register */ + +NvBool +Pcf50626RtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + return ( Pcf50626I2cRead32 (hDevice, PCF50626_RTC1A_ADDR, Count) ); +} + +/* Write RTC alarm count register */ + +NvBool +Pcf50626RtcAlarmCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + return ( Pcf50626I2cWrite32 (hDevice, PCF50626_RTC1A_ADDR, Count) ); +} + +/* Reads RTC alarm interrupt mask status */ + +NvBool +Pcf50626RtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice) +{ + NvU8 Mask; + + if(Pcf50626I2cRead8 (hDevice, PCF50626_INT1M_ADDR, &Mask)) + { + return ((Mask & 0x8)? NV_FALSE:NV_TRUE); + } + + return NV_FALSE; +} + +/* Enables / Disables the RTC alarm interrupt */ + +NvBool +Pcf50626RtcAlarmIntEnable( + NvOdmPmuDeviceHandle hDevice, + NvBool Enable) +{ + NvBool Status = NV_FALSE; + NvU8 Mask; + + if ((Status = Pcf50626I2cRead8(hDevice, PCF50626_INT1M_ADDR, &Mask)) == NV_TRUE) + { + (Mask = Enable? (Mask & ~0x8):(Mask|0x8)); + Status = Pcf50626I2cWrite8 (hDevice, PCF50626_INT1M_ADDR, Mask); + } + + return Status; +} + +/* Checks if boot was from nopower / powered state */ + +NvBool +Pcf50626RtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice) +{ + NvU8 Data; + + // Check "nopower" bit of the ERROR status register. + // Make sure the backup battery charger is enabled (bbce and vsaveen bits). This is done by + // the bootloader. If this is not done, the "nopower" bit will remain stuck at 0x1. + if ((Pcf50626I2cRead8(hDevice, PCF50626_ERROR_ADDR, &Data)) == NV_TRUE) + { + return ((Data & 0x20)? NV_TRUE : NV_FALSE); + } + + return NV_FALSE; +} + +NvBool +Pcf50626IsRtcInitialized(NvOdmPmuDeviceHandle hDevice) +{ + return ((Pcf50626RtcWasStartUpFromNoPower(hDevice))? NV_FALSE : NV_TRUE); +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h new file mode 100644 index 000000000000..f5979cf5e52d --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_rtc.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 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_PCF50626_RTC_HEADER +#define INCLUDED_PCF50626_RTC_HEADER + +#include "pmu_hal.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Read RTC count register */ + +NvBool +Pcf50626RtcCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/* Read RTC alarm count register */ + +NvBool +Pcf50626RtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/* Write RTC count register */ + +NvBool +Pcf50626RtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/* Write RTC alarm count register */ + +NvBool +Pcf50626RtcAlarmCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/* Reads RTC alarm interrupt mask status */ + +NvBool +Pcf50626RtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice); + +/* Enables / Disables the RTC alarm interrupt */ + +NvBool +Pcf50626RtcAlarmIntEnable( + NvOdmPmuDeviceHandle hDevice, + NvBool Enable); + +/* Checks if boot was from nopower / powered state */ + +NvBool +Pcf50626RtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice); + +NvBool +Pcf50626IsRtcInitialized(NvOdmPmuDeviceHandle hDevice); + + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_PCF50626_RTC_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h new file mode 100644 index 000000000000..7064cf6e68c7 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/pcf50626_supply_info_table.h @@ -0,0 +1,615 @@ +/* + * Copyright (c) 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 PCF50626_SUPPLY_INFO_TABLE_HEADER +#define PCF50626_SUPPLY_INFO_TABLE_HEADER + +#include "nvodm_pmu_pcf50626_supply_info.h" +#include "pcf50626_reg.h" + + +// defines for the request Voltage. This is board specific and ODM should change this based on +// device. +#define PCF50626_REQUESTVOLTAGE_DCD1_MV 1200 +#define PCF50626_REQUESTVOLTAGE_DCD2_MV 1925 +#define PCF50626_REQUESTVOLTAGE_DCUD_MV 4975 +#define PCF50626_REQUESTVOLTAGE_RF1REG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_RF2REG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_RF3REG_MV 1800 +#define PCF50626_REQUESTVOLTAGE_RF4REG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_D1REG_MV 3300 +#define PCF50626_REQUESTVOLTAGE_D2REG_MV 3300 +#define PCF50626_REQUESTVOLTAGE_D3REG_MV 1200 +#define PCF50626_REQUESTVOLTAGE_D4REG_MV 1200 +#define PCF50626_REQUESTVOLTAGE_D5REG_MV 1800 +#define PCF50626_REQUESTVOLTAGE_D6REG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_D7REG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_D8REG_MV 3100 +#define PCF50626_REQUESTVOLTAGE_HCREG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_IOREG_MV 1800 +#define PCF50626_REQUESTVOLTAGE_USIMREG_MV 3000 +#define PCF50626_REQUESTVOLTAGE_USBREG_MV 2800 +#define PCF50626_REQUESTVOLTAGE_LCREG_MV 1200 + +// defines for the additional load-dependent TurnOn delays. This is board +// specific and ODM should change this based on device. +#define PCF50626_TURNON_DELAY_DCD1_US 0 +#define PCF50626_TURNON_DELAY_DCD2_US 0 +#define PCF50626_TURNON_DELAY_DCUD_US 0 +#define PCF50626_TURNON_DELAY_RF1REG_US 0 +#define PCF50626_TURNON_DELAY_RF2REG_US 0 +#define PCF50626_TURNON_DELAY_RF3REG_US 0 +#define PCF50626_TURNON_DELAY_RF4REG_US 0 +#define PCF50626_TURNON_DELAY_D1REG_US 0 +#define PCF50626_TURNON_DELAY_D2REG_US 0 +#define PCF50626_TURNON_DELAY_D3REG_US 0 +#define PCF50626_TURNON_DELAY_D4REG_US 0 +#define PCF50626_TURNON_DELAY_D5REG_US 2000 +#define PCF50626_TURNON_DELAY_D6REG_US 500 +#define PCF50626_TURNON_DELAY_D7REG_US 0 +#define PCF50626_TURNON_DELAY_D8REG_US 0 +#define PCF50626_TURNON_DELAY_HCREG_US 0 +#define PCF50626_TURNON_DELAY_IOREG_US 0 +#define PCF50626_TURNON_DELAY_USIMREG_US 0 +#define PCF50626_TURNON_DELAY_USBREG_US 0 +#define PCF50626_TURNON_DELAY_LCREG_US 0 + + +const PCF50626PmuSupplyInfo pcf50626SupplyInfoTable[] = +{ + { + PCF50626PmuSupply_Invalid, + PCF50626PmuSupply_Invalid, + 0,0,0,0, + 0,0,0,0, + {NV_TRUE,0,0,0,0}, + 0,0,0 + }, + + // DCD1 + { + PCF50626PmuSupply_DCD1, + PCF50626PmuSupply_VBAT, + + PCF50626_DCD1C1_ADDR, + PCF50626_DCD1C2_ADDR, + PCF50626_DCD1C3_ADDR, + PCF50626_DCD1C4_ADDR, + + PCF50626_DCD1DVM1_ADDR, + PCF50626_DCD1DVM2_ADDR, + PCF50626_DCD1DVM3_ADDR, + PCF50626_DCD1DVMTIM_ADDR, + + { + NV_FALSE, + PCF50626_DCDXOUT_VOLTAGE_MIN_MV, + PCF50626_DCDXOUT_VOLTAGE_STEP_MV, + PCF50626_DCDXOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_DCD1_MV + }, + + PCF50626_DCDXOUT_VOLTAGE_OFFSET_MV, + PCF50626_DCDXOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_DCD1_US, + PCF50626_DCDXOUT_SWITCH_TIME_MICROSEC + }, + + //DCD2 + { + PCF50626PmuSupply_DCD2, + PCF50626PmuSupply_VBAT, + + PCF50626_DCD2C1_ADDR, + PCF50626_DCD2C2_ADDR, + PCF50626_DCD2C3_ADDR, + PCF50626_DCD2C4_ADDR, + + PCF50626_DCD2DVM1_ADDR, + PCF50626_DCD2DVM2_ADDR, + PCF50626_DCD2DVM3_ADDR, + PCF50626_DCD2DVMTIM_ADDR, + + { + NV_FALSE, + PCF50626_DCDXOUT_VOLTAGE_MIN_MV, + PCF50626_DCDXOUT_VOLTAGE_STEP_MV, + PCF50626_DCDXOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_DCD2_MV + }, + + PCF50626_DCDXOUT_VOLTAGE_OFFSET_MV, + PCF50626_DCDXOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_DCD2_US, + PCF50626_DCDXOUT_SWITCH_TIME_MICROSEC + }, + + //DCUD + { + PCF50626PmuSupply_DCUD, + PCF50626PmuSupply_VBAT, + + PCF50626_DCUDC1_ADDR, + PCF50626_DCUDC2_ADDR, + PCF50626_DCUDC3_ADDR, + PCF50626_DCUDC4_ADDR, + 0,0,0, + PCF50626_DCUDDVMTIM_ADDR, + + { + NV_FALSE, + PCF50626_DCUDOUT_MODE1_VOLTAGE_MIN_MV, + PCF50626_DCUDOUT_MODE1_VOLTAGE_STEP_MV, + PCF50626_DCUDOUT_MODE1_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_DCUD_MV + }, + + PCF50626_DCUDOUT_MODE1_VOLTAGE_OFFSET_MV, + PCF50626_DCUDOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_DCUD_US, + PCF50626_DCUDOUT_SWITCH_TIME_MICROSEC + }, + + //DCULED + { + PCF50626PmuSupply_DCULED, + PCF50626PmuSupply_VBAT, + + PCF50626_DCULEDC1_ADDR, + PCF50626_DCULEDC2_ADDR, + PCF50626_DCULEDC3_ADDR, + PCF50626_DCULED_DIMMAN_ADDR, + 0,0,0,0, + {NV_TRUE, 0,0,0, 0}, + 0,87,0 + }, + + //RF1 + { + PCF50626PmuSupply_RF1REG, + PCF50626PmuSupply_VBAT, + + PCF50626_RF1REGC1_ADDR, + PCF50626_RF1REGC2_ADDR, + PCF50626_RF1REGC3_ADDR, + 0, + 0,0,0,0, + { + NV_FALSE, + PCF50626_RFXREGOUT_VOLTAGE_MIN_MV, + PCF50626_RFXREGOUT_VOLTAGE_STEP_MV, + PCF50626_RFXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_RF1REG_MV + }, + + PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF1REG_US, + PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC + }, + + //RF2 + { + PCF50626PmuSupply_RF2REG, + PCF50626PmuSupply_VBAT, + + PCF50626_RF2REGC1_ADDR, + PCF50626_RF2REGC2_ADDR, + PCF50626_RF2REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_RFXREGOUT_VOLTAGE_MIN_MV, + PCF50626_RFXREGOUT_VOLTAGE_STEP_MV, + PCF50626_RFXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_RF2REG_MV + }, + + PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF2REG_US, + PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC + }, + + //RF3 + { + PCF50626PmuSupply_RF3REG, + PCF50626PmuSupply_VBAT, + + PCF50626_RF3REGC1_ADDR, + PCF50626_RF3REGC2_ADDR, + PCF50626_RF3REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_RFXREGOUT_VOLTAGE_MIN_MV, + PCF50626_RFXREGOUT_VOLTAGE_STEP_MV, + PCF50626_RFXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_RF3REG_MV + }, + + PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF3REG_US, + PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC + }, + + //RF4 + { + PCF50626PmuSupply_RF4REG, + PCF50626PmuSupply_VBAT, + + PCF50626_RF4REGC1_ADDR, + PCF50626_RF4REGC2_ADDR, + PCF50626_RF4REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_RFXREGOUT_VOLTAGE_MIN_MV, + PCF50626_RFXREGOUT_VOLTAGE_STEP_MV, + PCF50626_RFXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_RF4REG_MV + }, + + PCF50626_RFXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_RFXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_RF4REG_US, + PCF50626_RFXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D1 + { + PCF50626PmuSupply_D1REG, + PCF50626PmuSupply_DCUD, + + PCF50626_D1REGC1_ADDR, + PCF50626_D1REGC2_ADDR, + PCF50626_D1REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D1REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D1REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D2 + { + PCF50626PmuSupply_D2REG, + PCF50626PmuSupply_DCUD, + PCF50626_D2REGC1_ADDR, + PCF50626_D2REGC2_ADDR, + PCF50626_D2REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D2REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D2REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D3 + { + PCF50626PmuSupply_D3REG, + PCF50626PmuSupply_DCD2, + + PCF50626_D3REGC1_ADDR, + PCF50626_D3REGC2_ADDR, + PCF50626_D3REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D3REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D3REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D4 + { + PCF50626PmuSupply_D4REG, + PCF50626PmuSupply_DCD2, + + PCF50626_D4REGC1_ADDR, + PCF50626_D4REGC2_ADDR, + PCF50626_D4REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D4REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D4REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D5 + { + PCF50626PmuSupply_D5REG, + PCF50626PmuSupply_VBAT, + + PCF50626_D5REGC1_ADDR, + PCF50626_D5REGC2_ADDR, + PCF50626_D5REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D5REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D5REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D6 + { + PCF50626PmuSupply_D6REG, + PCF50626PmuSupply_VBAT, + + PCF50626_D6REGC1_ADDR, + PCF50626_D6REGC2_ADDR, + PCF50626_D6REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D6REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D6REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D7 + { + PCF50626PmuSupply_D7REG, + PCF50626PmuSupply_VBAT, + + PCF50626_D7REGC1_ADDR, + PCF50626_D7REGC2_ADDR, + PCF50626_D7REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D7REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D7REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //D8 + { + PCF50626PmuSupply_D8REG, + PCF50626PmuSupply_VBAT, + + PCF50626_D8REGC1_ADDR, + PCF50626_D8REGC2_ADDR, + PCF50626_D8REGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_DXREGOUT_VOLTAGE_MIN_MV, + PCF50626_DXREGOUT_VOLTAGE_STEP_MV, + PCF50626_DXREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_D8REG_MV + }, + + PCF50626_DXREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_DXREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_D8REG_US, + PCF50626_DXREGOUT_SWITCH_TIME_MICROSEC + }, + + //HCREG + { + PCF50626PmuSupply_HCREG, + PCF50626PmuSupply_VBAT, + + PCF50626_HCREGC1_ADDR, + PCF50626_HCREGC2_ADDR, + PCF50626_HCREGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_HCREGOUT_VOLTAGE_MIN_MV, + PCF50626_HCREGOUT_VOLTAGE_STEP_MV, + PCF50626_HCREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_HCREG_MV + }, + + PCF50626_HCREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_HCREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_HCREG_US, + PCF50626_HCREGOUT_SWITCH_TIME_MICROSEC + }, + + //IO + { + PCF50626PmuSupply_IOREG, + PCF50626PmuSupply_VBAT, + + PCF50626_IOREGC1_ADDR, + PCF50626_IOREGC2_ADDR, + PCF50626_IOREGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_IOREGOUT_VOLTAGE_MIN_MV, + PCF50626_IOREGOUT_VOLTAGE_STEP_MV, + PCF50626_IOREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_IOREG_MV + }, + + PCF50626_IOREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_IOREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_IOREG_US, + PCF50626_IOREGOUT_SWITCH_TIME_MICROSEC + }, + + //USIM + { + PCF50626PmuSupply_USIMREG, + PCF50626PmuSupply_VBAT, + + PCF50626_USIMREGC1_ADDR, + PCF50626_USIMREGC2_ADDR, + PCF50626_USIMREGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_USIMREGOUT_VOLTAGE_MIN_MV, + PCF50626_USIMREGOUT_VOLTAGE_STEP_MV, + PCF50626_USIMREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_USIMREG_MV + }, + + PCF50626_USIMREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_USIMREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_USIMREG_US, + PCF50626_USIMREGOUT_SWITCH_TIME_MICROSEC + }, + + //USB + { + PCF50626PmuSupply_USBREG, + PCF50626PmuSupply_VBAT, + + PCF50626_USBREGC1_ADDR, + PCF50626_USBREGC2_ADDR, + PCF50626_USBREGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_USBREGOUT_VOLTAGE_MIN_MV, + PCF50626_USBREGOUT_VOLTAGE_STEP_MV, + PCF50626_USBREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_USBREG_MV + }, + + PCF50626_USBREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_USBREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_USBREG_US, + PCF50626_USBREGOUT_SWITCH_TIME_MICROSEC + }, + + //LC + { + PCF50626PmuSupply_LCREG, + PCF50626PmuSupply_VBAT, + + PCF50626_LCREGC1_ADDR, + PCF50626_LCREGC2_ADDR, + PCF50626_LCREGC3_ADDR, + 0, + 0,0,0,0, + + { + NV_FALSE, + PCF50626_LCREGOUT_VOLTAGE_MIN_MV, + PCF50626_LCREGOUT_VOLTAGE_STEP_MV, + PCF50626_LCREGOUT_VOLTAGE_MAX_MV, + PCF50626_REQUESTVOLTAGE_LCREG_MV + }, + + PCF50626_LCREGOUT_VOLTAGE_OFFSET_MV, + PCF50626_LCREGOUT_TURNON_TIME_MICROSEC + PCF50626_TURNON_DELAY_LCREG_US, + PCF50626_LCREGOUT_SWITCH_TIME_MICROSEC + }, + + //VBAT + { + PCF50626PmuSupply_VBAT, + PCF50626PmuSupply_Invalid, + + 0,0,0,0, + 0,0,0,0, + + {NV_TRUE,0,0,0,0}, + 0,0,0 + } +}; + +#define PCF50626SUPPLYINFOTABLESIZE NV_ARRAY_SIZE(pcf50626SupplyInfoTable) + +#endif //PCF50626_VOLTAGE_INFO_TABLE_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c new file mode 100644 index 000000000000..dee9641eef7c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pcf50626/platform.c @@ -0,0 +1,148 @@ +/* + * Copyright (c) 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 "pcf50626_batterycharger.h" +#include "pcf50626_adc.h" +#include "pcf50626_i2c.h" +#include "pcf50626_reg.h" +#include "ds2482_bridge.h" +#include "ds2482_i2c.h" +#include "nvodm_query_discovery.h" +#include "nvodm_query.h" + +// implementations of platform related functions. + +#define OWI2CGUID NV_ODM_GUID('o','w','i','2','c','_','d','s') +#define BATTERYGUID NV_ODM_GUID('b','a','t','t','_','m','o','t') + +static NvBool ds2482Presented = NV_FALSE; + +/* Initliase all registers that related to battery charger */ +NvBool +Pcf50626BatteryChargerSetup(NvOdmPmuDeviceHandle hDevice) +{ + + NvOdmIoModule I2cModule = NvOdmIoModule_I2c; + NvU32 I2cInstance = 0; + NvU32 I2cAddress = 0; + const NvOdmPeripheralConnectivity *pConnectivity = + NvOdmPeripheralGetGuid(OWI2CGUID); + NV_ASSERT(hDevice); + + if (pConnectivity != NULL) // OwI2c device is in database + { + NvU32 i = 0; + for (i = 0; i < pConnectivity->NumAddress; i ++) + { + if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu) + { + I2cModule = NvOdmIoModule_I2c_Pmu; + I2cInstance = pConnectivity->AddressList[i].Instance; + I2cAddress = pConnectivity->AddressList[i].Address; + break; + } + } + ds2482Presented = NV_TRUE; + } + else + { + ds2482Presented = NV_FALSE; + } + + if (ds2482Presented == NV_TRUE) + { + // init GPIO8 + if (!Pcf50626I2cWrite8(hDevice, PCF50626_GPIO8C1_ADDR, 0x0)) + return NV_FALSE; + + NvOdmOsWaitUS(50000); + + if (!Ds2482Setup(hDevice)) + return NV_FALSE; + + return NV_TRUE; + } + + //TODO: add battery charger setup implementation here, base on HW. + // by default, simply return TRUE if nothing needed. + return NV_TRUE; +} + + +/* check CBC main batt presence */ +NvBool +Pcf50626BatteryChargerCBCMainBatt(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + const NvOdmPeripheralConnectivity *pConnectivity = + NvOdmPeripheralGetGuid(BATTERYGUID); + + NV_ASSERT(hDevice); + + if (pConnectivity != NULL) // battery is in database + { + ///TODO: retrieve data from the database; + //Nothing needed on Concorde for now + } + + if (ds2482Presented == NV_TRUE) + { + if (!Ds2482BatteryPresented(hDevice, status)) + return NV_FALSE; + } + else + { + //TODO: add battery detection impelentation here. by default always return TRUE. + *status = NV_TRUE; + } + + return NV_TRUE; +} + +/* Calculate the battery temperature */ +NvU32 Pcf50626BatteryTemperature(NvU32 VBatSense, NvU32 VBatTemp) +{ + //TODO: implement the temperature algorithm based on the reading of Vbat sense and VBat temp. + // Pending approval. + return 0; +} + + +NvBool +Ds2482BatteryPresented(NvOdmPmuDeviceHandle hDevice, NvBool *BattPresence) +{ + ///TODO: detect battery via ds2482 based on the battery spec. + ///Pending approval + return NV_TRUE; +} + + + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c new file mode 100644 index 000000000000..ec62ac6c4c17 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c @@ -0,0 +1,354 @@ +/* + * Copyright (c) 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 "nvcommon.h" +#include "nvodm_pmu.h" +#include "nvodm_query_discovery.h" +#include "pmu_hal.h" +#include "nvodm_services.h" +#include "tps6586x/nvodm_pmu_tps6586x.h" +#include "max8907b/max8907b.h" +#include "max8907b/max8907b_rtc.h" +#include "pcf50626/pcf50626.h" +#include "pcf50626/pcf50626_rtc.h" + +static NvOdmPmuDevice* +GetPmuInstance(NvOdmPmuDeviceHandle hDevice) +{ + static NvOdmPmuDevice Pmu; + static NvBool first = NV_TRUE; + + if (first) + { + NvOdmOsMemset(&Pmu, 0, sizeof(Pmu)); + first = NV_FALSE; + + if (NvOdmPeripheralGetGuid(NV_ODM_GUID('t','p','s','6','5','8','6','x'))) + { + // fill in HAL functions here. + Pmu.Hal = NV_TRUE; + Pmu.pfnSetup = Tps6586xSetup; + Pmu.pfnRelease = Tps6586xRelease; + Pmu.pfnGetCaps = Tps6586xGetCapabilities; + Pmu.pfnGetVoltage = Tps6586xGetVoltage; + Pmu.pfnSetVoltage = Tps6586xSetVoltage; + Pmu.pfnGetAcLineStatus = Tps6586xGetAcLineStatus; + Pmu.pfnGetBatteryStatus = Tps6586xGetBatteryStatus; + Pmu.pfnGetBatteryData = Tps6586xGetBatteryData; + Pmu.pfnGetBatteryFullLifeTime = Tps6586xGetBatteryFullLifeTime; + Pmu.pfnGetBatteryChemistry = Tps6586xGetBatteryChemistry; + Pmu.pfnSetChargingCurrent = Tps6586xSetChargingCurrent; + Pmu.pfnInterruptHandler = Tps6586xInterruptHandler; + Pmu.pfnReadRtc = Tps6586xReadRtc; + Pmu.pfnWriteRtc = Tps6586xWriteRtc; + Pmu.pfnIsRtcInitialized = Tps6586xIsRtcInitialized; + } + else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0'))) + { + + Pmu.pfnSetup = Pcf50626Setup; + Pmu.pfnRelease = Pcf50626Release; + Pmu.pfnGetCaps = Pcf50626GetCapabilities; + Pmu.pfnGetVoltage = Pcf50626GetVoltage; + Pmu.pfnSetVoltage = Pcf50626SetVoltage; + Pmu.pfnGetAcLineStatus = Pcf50626GetAcLineStatus; + Pmu.pfnGetBatteryStatus = Pcf50626GetBatteryStatus; + Pmu.pfnGetBatteryData = Pcf50626GetBatteryData; + Pmu.pfnGetBatteryFullLifeTime = Pcf50626GetBatteryFullLifeTime; + Pmu.pfnGetBatteryChemistry = Pcf50626GetBatteryChemistry; + Pmu.pfnSetChargingCurrent = Pcf50626SetChargingCurrent; + Pmu.pfnInterruptHandler = Pcf50626InterruptHandler; + Pmu.pfnReadRtc = Pcf50626RtcCountRead; + Pmu.pfnWriteRtc = Pcf50626RtcCountWrite; + Pmu.pfnIsRtcInitialized = Pcf50626IsRtcInitialized; + Pmu.pPrivate = NULL; + Pmu.Hal = NV_TRUE; + Pmu.Init = NV_FALSE; + } + else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('m','a','x','8','9','0','7','b'))) + { + + Pmu.pfnSetup = Max8907bSetup; + Pmu.pfnRelease = Max8907bRelease; + Pmu.pfnGetCaps = Max8907bGetCapabilities; + Pmu.pfnGetVoltage = Max8907bGetVoltage; + Pmu.pfnSetVoltage = Max8907bSetVoltage; + Pmu.pfnGetAcLineStatus = Max8907bGetAcLineStatus; + Pmu.pfnGetBatteryStatus = Max8907bGetBatteryStatus; + Pmu.pfnGetBatteryData = Max8907bGetBatteryData; + Pmu.pfnGetBatteryFullLifeTime = Max8907bGetBatteryFullLifeTime; + Pmu.pfnGetBatteryChemistry = Max8907bGetBatteryChemistry; + Pmu.pfnSetChargingCurrent = Max8907bSetChargingCurrent; + Pmu.pfnInterruptHandler = Max8907bInterruptHandler; + Pmu.pfnReadRtc = Max8907bRtcCountRead; + Pmu.pfnWriteRtc = Max8907bRtcCountWrite; + Pmu.pfnIsRtcInitialized = Max8907bIsRtcInitialized; + Pmu.pPrivate = NULL; + Pmu.Hal = NV_TRUE; + Pmu.Init = NV_FALSE; + } + } + + if (hDevice && Pmu.Hal) + return &Pmu; + + return NULL; +} + +NvBool +NvOdmPmuDeviceOpen(NvOdmPmuDeviceHandle *hDevice) +{ + NvOdmPmuDevice *pmu = GetPmuInstance((NvOdmPmuDeviceHandle)1); + + *hDevice = (NvOdmPmuDeviceHandle)0; + + if (!pmu || !pmu->pfnSetup) + return NV_FALSE; + + if (pmu->Init) + { + *hDevice = (NvOdmPmuDeviceHandle)1; + return NV_TRUE; + } + + if (pmu->pfnSetup(pmu)) + { + *hDevice = (NvOdmPmuDeviceHandle)1; + pmu->Init = NV_TRUE; + return NV_TRUE; + } + + return NV_FALSE; +} + +void NvOdmPmuDeviceClose(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (!pmu) + return; + + if (pmu->pfnRelease) + pmu->pfnRelease(pmu); + + pmu->Init = NV_FALSE; +} + +void +NvOdmPmuGetCapabilities(NvU32 vddId, + NvOdmPmuVddRailCapabilities* pCapabilities) +{ + // use a manual handle, since this function doesn't takea handle + NvOdmPmuDevice* pmu = GetPmuInstance((NvOdmPmuDeviceHandle)1); + + if (pmu && pmu->pfnGetCaps) + pmu->pfnGetCaps(vddId, pCapabilities); + else if (pCapabilities) + { + NvOdmOsMemset(pCapabilities, 0, sizeof(NvOdmPmuVddRailCapabilities)); + pCapabilities->OdmProtected = NV_TRUE; + } +} + + +NvBool +NvOdmPmuGetVoltage(NvOdmPmuDeviceHandle hDevice, + NvU32 vddId, + NvU32* pMilliVolts) +{ + NvOdmPmuDevice* pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnGetVoltage) + return pmu->pfnGetVoltage(pmu, vddId, pMilliVolts); + + return NV_TRUE; +} + +NvBool +NvOdmPmuSetVoltage(NvOdmPmuDeviceHandle hDevice, + NvU32 VddId, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnSetVoltage) + { + return pmu->pfnSetVoltage(pmu, VddId, MilliVolts, pSettleMicroSeconds); + } + + if (pSettleMicroSeconds) + *pSettleMicroSeconds = 0; + return NV_TRUE; +} + + +NvBool +NvOdmPmuGetAcLineStatus(NvOdmPmuDeviceHandle hDevice, + NvOdmPmuAcLineStatus *pStatus) +{ + NvOdmPmuDevice* pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnGetAcLineStatus) + return pmu->pfnGetAcLineStatus(pmu, pStatus); + + return NV_TRUE; +} + + +NvBool +NvOdmPmuGetBatteryStatus(NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance BatteryInst, + NvU8 *pStatus) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnGetBatteryStatus) + return pmu->pfnGetBatteryStatus(pmu, BatteryInst, pStatus); + + return NV_TRUE; +} + +NvBool +NvOdmPmuGetBatteryData(NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance BatteryInst, + NvOdmPmuBatteryData *pData) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnGetBatteryData) + return pmu->pfnGetBatteryData(pmu, BatteryInst, pData); + + pData->batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN; + pData->batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN; + + return NV_TRUE; +} + + +void +NvOdmPmuGetBatteryFullLifeTime(NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance BatteryInst, + NvU32 *pLifeTime) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnGetBatteryFullLifeTime) + pmu->pfnGetBatteryFullLifeTime(pmu, BatteryInst, pLifeTime); + + else + { + if (pLifeTime) + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + } +} + + +void +NvOdmPmuGetBatteryChemistry(NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance BatteryInst, + NvOdmPmuBatteryChemistry *pChemistry) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnGetBatteryChemistry) + pmu->pfnGetBatteryChemistry(pmu, BatteryInst, pChemistry); + else + { + if (pChemistry) + *pChemistry = NVODM_BATTERY_DATA_UNKNOWN; + } +} + +NvBool +NvOdmPmuSetChargingCurrent(NvOdmPmuDeviceHandle hDevice, + NvOdmPmuChargingPath ChargingPath, + NvU32 ChargingCurrentLimitMa, + NvOdmUsbChargerType ChargerType) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnSetChargingCurrent) + return pmu->pfnSetChargingCurrent(pmu, ChargingPath, ChargingCurrentLimitMa, ChargerType); + + return NV_TRUE; +} + + +void NvOdmPmuInterruptHandler(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnInterruptHandler) + pmu->pfnInterruptHandler(pmu); +} + +NvBool NvOdmPmuReadRtc( + NvOdmPmuDeviceHandle hDevice, + NvU32 *Count) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnReadRtc) + return pmu->pfnReadRtc(pmu, Count); + return NV_FALSE; +} + + +NvBool NvOdmPmuWriteRtc( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnWriteRtc) + return pmu->pfnWriteRtc(pmu, Count); + return NV_FALSE; +} + +NvBool +NvOdmPmuIsRtcInitialized(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnIsRtcInitialized) + return pmu->pfnIsRtcInitialized(pmu); + + return NV_FALSE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h new file mode 100644 index 000000000000..05cdea828a20 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Abstraction layer stub for audio codec adaptations</b> + */ + +#ifndef INCLUDED_NVODM_PMU_ADAPTATION_HAL_H +#define INCLUDED_NVODM_PMU_ADAPTATION_HAL_H + +#include "nvcommon.h" +#include "nvodm_pmu.h" +#include "nvodm_services.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef NvBool (*pfnPmuSetup)(NvOdmPmuDeviceHandle); +typedef void (*pfnPmuRelease)(NvOdmPmuDeviceHandle); +typedef void (*pfnPmuGetCaps)(NvU32, NvOdmPmuVddRailCapabilities*); +typedef NvBool (*pfnPmuGetVoltage)(NvOdmPmuDeviceHandle, NvU32, NvU32*); +typedef NvBool (*pfnPmuSetVoltage)(NvOdmPmuDeviceHandle, NvU32, NvU32, NvU32*); +typedef NvBool (*pfnPmuGetAcLineStatus)(NvOdmPmuDeviceHandle, NvOdmPmuAcLineStatus*); +typedef NvBool (*pfnPmuGetBatteryStatus)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvU8*); +typedef NvBool (*pfnPmuGetBatteryData)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvOdmPmuBatteryData*); +typedef void (*pfnPmuGetBatteryFullLifeTime)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvU32*); +typedef void (*pfnPmuGetBatteryChemistry)(NvOdmPmuDeviceHandle, NvOdmPmuBatteryInstance, NvOdmPmuBatteryChemistry*); +typedef NvBool (*pfnPmuSetChargingCurrent)(NvOdmPmuDeviceHandle, NvOdmPmuChargingPath, NvU32, NvOdmUsbChargerType); +typedef void (*pfnPmuInterruptHandler)(NvOdmPmuDeviceHandle); +typedef NvBool (*pfnPmuReadRtc)(NvOdmPmuDeviceHandle, NvU32*); +typedef NvBool (*pfnPmuWriteRtc)(NvOdmPmuDeviceHandle, NvU32); +typedef NvBool (*pfnPmuIsRtcInitialized)(NvOdmPmuDeviceHandle); + +typedef struct NvOdmPmuDeviceRec +{ + pfnPmuSetup pfnSetup; + pfnPmuRelease pfnRelease; + pfnPmuGetCaps pfnGetCaps; + pfnPmuGetVoltage pfnGetVoltage; + pfnPmuSetVoltage pfnSetVoltage; + pfnPmuGetAcLineStatus pfnGetAcLineStatus; + pfnPmuGetBatteryStatus pfnGetBatteryStatus; + pfnPmuGetBatteryData pfnGetBatteryData; + pfnPmuGetBatteryFullLifeTime pfnGetBatteryFullLifeTime; + pfnPmuGetBatteryChemistry pfnGetBatteryChemistry; + pfnPmuSetChargingCurrent pfnSetChargingCurrent; + pfnPmuInterruptHandler pfnInterruptHandler; + pfnPmuReadRtc pfnReadRtc; + pfnPmuWriteRtc pfnWriteRtc; + pfnPmuIsRtcInitialized pfnIsRtcInitialized; + void *pPrivate; + NvBool Hal; + NvBool Init; +} NvOdmPmuDevice; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile new file mode 100644 index 000000000000..3b4770addf96 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/Makefile @@ -0,0 +1,18 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x + +obj-y += nvodm_pmu_tps6586x.o +obj-y += nvodm_pmu_tps6586x_adc.o +obj-y += nvodm_pmu_tps6586x_batterycharger.o +obj-y += nvodm_pmu_tps6586x_i2c.o +obj-y += nvodm_pmu_tps6586x_interrupt.o +obj-y += nvodm_pmu_tps6586x_rtc.o diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c new file mode 100644 index 000000000000..197a2c227e1d --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c @@ -0,0 +1,2036 @@ + +/* + * Copyright (c) 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 "nvodm_query_discovery.h" +#include "nvodm_query.h" +#include "nvodm_query_gpio.h" +#include "nvodm_pmu_tps6586x_i2c.h" +#include "nvodm_pmu_tps6586x_interrupt.h" +#include "nvodm_pmu_tps6586x_batterycharger.h" +#include "nvodm_pmu_tps6586x_adc.h" +#include "nvodm_pmu_tps6586x_rtc.h" +#include "pmu_hal.h" + +/************************************************************************** + * NOTE: + * + Please search "FIXME" and then change the code according to your tps6586x fuse + * * each LDO's voltage range and default value + * * each SM's voltage range and default value + * * Interrupt Masks + * + Battery settings + **************************************************************************/ + +/************************************************************************** + * TPS6586x has two sets of power supliers: + * + 3 DC/DC converters: DCD0/1/2 + * + 11 Regulators: LDO0-9 and RTC_OUT + * Besides that, TPS6586x has + * + 2 sets drivers for LED or other open drain outputs + * + 1 dedicated driver for keyboard backlight LED + * + 1 dedicated driver for external vibrator motor + * + 1 dedicated driver for white LED(SM3) + **************************************************************************/ + +NvBool pmuPresented; +NvBool battPresence; +NvBool pmuInterruptSupported; +TPS6586xStatus pmuStatus; +NvOdmPmuDeviceTPS *hPmu; + + +// threshold for battery status. need to fine tune based on battery/system characterisation +#define NVODM_BATTERY_FULL_VOLTAGE_MV 4200 +#define NVODM_BATTERY_HIGH_VOLTAGE_MV 3900 +#define NVODM_BATTERY_LOW_VOLTAGE_MV 3300 +#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 3100 + +#define DUMB_CHARGER_LIMIT_MA 250 +#define DEDICATED_CHARGER_LIMIT_MA 1000 // 1000mA for dedicated charger + +#define T_START_TIME 210 +#define K_RAMP 7 + +/* + Only 4 options for charger current; Page36 + According to TPS658x spec, the charge current = scaling factor / R_ISET. + From the schematic, R_ISET shows "1K". So the charge current = scaling factor. + Because the min value of the scaling factor is 0.25 and the R_ISET is fixed, + the min charging current = 0.25 / 1 = 0.25 A = 250 mA. + Thus, it will only support 1000mA, 750mA, 500mA, 250mA. + TODO: In future, we need to change to the actual R_IST value +*/ +#define R_IST 1000 +#define MAX_CHARGING_CURRENT 1000000/R_IST +#define L1_CHARGING_CURRENT 750 +#define L2_CHARGING_CURRENT 500 +#define L3_CHARGING_CURRENT 250 + +/* Valtage tables for LDOs */ +/* FIXME: Modify those tables according to your fuse */ +static const NvU32 VLDOx[] = {1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300}; +static const NvU32 VLDO2[] = { 725, 750, 775, 800, 825, 850, 875, 900, + 925, 950, 975, 1000, 1025, 1050, 1075, 1100, + 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, + 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500}; +/* FIXME tps65860 only */ +static const NvU32 VLDO4[] = {1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875, + 1900, 1925, 1950, 1975, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000, + 2000, 2000, 2000, 2000, 2000, 2000, 2000, 2000}; + +typedef NvU32 (*TPS6586xPmuVoltageFunc)(const NvU32 bits); +typedef NvBool (*TPS6586xPmuRailCtrlFunc)(const NvU32 rail, NvBool enable); + +typedef struct { + NvU8 addr; + NvU8 start; + NvU8 bits; + NvU8 flag; /*!< see each settings */ +} TPS6586xPmuRegisterInfo; + +typedef struct TPS6586xPmuSupplyInfoRec +{ + TPS6586xPmuSupply supply; + + TPS6586xPmuRegisterInfo supplyRegInfo; /*!< Register info to set/get supply voltage */ + TPS6586xPmuRegisterInfo ctrlRegInfo; /*!< Register info to enable/disable supply, flag indicates another addr */ + TPS6586xPmuVoltageFunc getVoltage; /*!< Func to convert register bits to real voltage */ + TPS6586xPmuVoltageFunc setVoltage; /*!< Func to convert real voltage to register bits */ + TPS6586xPmuRailCtrlFunc railControl; /*!< Func to enable/disable output for each rail */ + NvU8 Gpio; /*!< GPIO pin used to enable/disable external supplies */ + + NvOdmPmuVddRailCapabilities cap; + + +} TPS6586xPmuSupplyInfo; + +static NvU32 TPS6586xPmuVoltageGetSM0(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageGetSM1(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageGetSM2(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageGetVLDOx(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageGetVLDO1(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageGetVLDO2(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageGetVLDO4(const NvU32 bits); + +static NvU32 TPS6586xPmuVoltageSetSM0(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageSetSM1(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageSetSM2(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageSetVLDOx(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageSetVLDO1(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageSetVLDO2(const NvU32 bits); +static NvU32 TPS6586xPmuVoltageSetVLDO4(const NvU32 bits); + +/* FIXME: Change getVoltage/setVoltage according to your fuse */ +static const TPS6586xPmuSupplyInfo tps6586xSupplyInfoTable[] = +{ + { + TPS6586xPmuSupply_Invalid, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_TRUE,0,0,0,0}, + }, + + //DCD0 + { + TPS6586xPmuSupply_DCD0, + + {TPS6586x_R26_SM0V1, 0, 5, 0}, + {TPS6586x_R10_SUPPLYENA, 1, 1, TPS6586x_R11_SUPPLYENB}, + TPS6586xPmuVoltageGetSM0, + TPS6586xPmuVoltageSetSM0, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 625, 25, 2700, 1200 +#else + 900, 25, 1200, 1200 +#endif + }, + }, + + //DCD1 + { + TPS6586xPmuSupply_DCD1, + + {TPS6586x_R23_SM1V1, 0, 5, 0}, + {TPS6586x_R10_SUPPLYENA, 0, 1, TPS6586x_R11_SUPPLYENB}, + TPS6586xPmuVoltageGetSM1, + TPS6586xPmuVoltageSetSM1, + NULL, + TPS6586x_RFF_INVALID, + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 625, 25, 2700, 1000 +#else + 1800, 0, 1800, 1800 +#endif + }, + }, + + //DCD2 + { + TPS6586xPmuSupply_DCD2, + + {TPS6586x_R42_SUPPLYV2, 0, 5, 0}, + {TPS6586x_R12_SUPPLYENC, 7, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetSM2, + TPS6586xPmuVoltageSetSM2, + NULL, + TPS6586x_RFF_INVALID, + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 3000, 50, 4550, 3700 +#else + 3000, 50, 4550, 3250 // fixme +#endif + }, + }, + + // LD00 + { + TPS6586xPmuSupply_LDO0, + + {TPS6586x_R41_SUPPLYV1, 5, 3, 0}, + {TPS6586x_R12_SUPPLYENC, 0, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 3300 +#else + 2800, 0, 2800, 2800 +#endif + }, + }, + + // LD01 - V-1V2 + { + TPS6586xPmuSupply_LDO1, + + {TPS6586x_R41_SUPPLYV1, 0, 5, 0}, + {TPS6586x_R12_SUPPLYENC, 1, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDO1, + TPS6586xPmuVoltageSetVLDO1, + NULL, + TPS6586x_RFF_INVALID, + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 725, 25, 1500, 1100 +#else + 1200, 0, 1200, 1200 +#endif + }, + }, + + //LD02 - V-RTC + { + TPS6586xPmuSupply_LDO2, + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + {TPS6586x_R2F_LDO2BV1, 0, 5, 0}, +#else + {TPS6586x_R29_LDO2AV1, 0, 5, 0}, +#endif + {TPS6586x_R10_SUPPLYENA, 2, 2, TPS6586x_R11_SUPPLYENB}, + TPS6586xPmuVoltageGetVLDO2, + TPS6586xPmuVoltageSetVLDO2, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 725, 25, 1500, 1200 +#else + 900, 25, 1200, 1200 +#endif + }, + }, + + //LDO3 + { + TPS6586xPmuSupply_LDO3, + + {TPS6586x_R44_SUPPLYV4, 0, 3, 0}, + {TPS6586x_R12_SUPPLYENC, 2, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 3300 +#else + 1800, 0, 1800, 1800 +#endif + }, + }, + + //LDO4 + { + TPS6586xPmuSupply_LDO4, + + {TPS6586x_R32_LDO4V1, 0, 5, 0}, + {TPS6586x_R12_SUPPLYENC, 3, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDO4, + TPS6586xPmuVoltageSetVLDO4, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1700, 25, 2000, 1800 +#else + 1800, 0, 1800, 1800 +#endif + }, + }, + + //LDO5 + { + TPS6586xPmuSupply_LDO5, + + {TPS6586x_R46_SUPPLYV6, 0, 3, 0}, + {TPS6586x_R14_SUPPLYENE, 6, 1, TPS6586x_RFF_INVALID}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 2850 +#else + 2800, 0, 2800, 2800 +#endif + }, + }, + + //LDO6 - V-3V3 USB + { + TPS6586xPmuSupply_LDO6, + + {TPS6586x_R43_SUPPLYV3, 0, 3, 0}, + {TPS6586x_R12_SUPPLYENC, 4, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 2850 +#else + 3300, 0, 3300, 3300 +#endif + }, + }, + + //LDO7 - V-SDIO + { + TPS6586xPmuSupply_LDO7, + + {TPS6586x_R43_SUPPLYV3, 3, 3, 0}, + {TPS6586x_R12_SUPPLYENC, 5, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 3300 +#else + 2800, 0, 2800, 2800 +#endif + }, + }, + + //LDO8 - V-2V8 + { + TPS6586xPmuSupply_LDO8, + + {TPS6586x_R42_SUPPLYV2, 5, 3, 0}, + {TPS6586x_R12_SUPPLYENC, 6, 1, TPS6586x_R13_SUPPLYEND}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 1800 +#else + 2800, 0, 2800, 2800 +#endif + }, + }, + + //LDO9 + { + TPS6586xPmuSupply_LDO9, + + {TPS6586x_R46_SUPPLYV6, 3, 3, 0}, + {TPS6586x_R14_SUPPLYENE, 7, 1, TPS6586x_RFF_INVALID}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 2850 +#else + 2500, 0, 2500, 2500, +#endif + }, + }, + + //RTC_OUT + { + TPS6586xPmuSupply_RTC_OUT, + + {TPS6586x_R44_SUPPLYV4, 3, 3, 0}, + {TPS6586x_RFF_INVALID, 0, 0, TPS6586x_RFF_INVALID}, + TPS6586xPmuVoltageGetVLDOx, + TPS6586xPmuVoltageSetVLDOx, + NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + 1250, 25, 3350, 3300 +#else + 2500, 0, 2500, 2500 +#endif + }, + }, + + + //RED1 + { + TPS6586xPmuSupply_RED1, + + {TPS6586x_R51_RGB1RED, 0, 5, 0}, + {TPS6586x_R52_RGB1GREEN, 7, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 0, 1, 0x1f, 0 + }, + }, + + //GREEN1 + { + TPS6586xPmuSupply_GREEN1, + + {TPS6586x_R52_RGB1GREEN, 0, 5, 0}, + {TPS6586x_R52_RGB1GREEN, 7, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 0, 1, 0x1f, 0 + }, + }, + + //BLUE1 + { + TPS6586xPmuSupply_BLUE1, + + {TPS6586x_R53_RGB1BLUE, 0, 5, 0}, + {TPS6586x_R52_RGB1GREEN, 7, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 0, 1, 0x1f, 0 + }, + }, + + //RED2 + { + TPS6586xPmuSupply_RED2, + + {TPS6586x_R54_RGB2RED, 0, 5, 0}, + {TPS6586x_R55_RGB2GREEN, 7, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 0, 1, 0x1f, 0 + }, + }, + + //GREEN2 + { + TPS6586xPmuSupply_GREEN2, + + {TPS6586x_R55_RGB2GREEN, 0, 5, 0}, + {TPS6586x_R55_RGB2GREEN, 7, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 0, 1, 0x1f, 0 + }, + }, + + //BLUE2 + { + TPS6586xPmuSupply_BLUE2, + + {TPS6586x_R56_RGB2BLUE, 0, 5, 0}, + {TPS6586x_R55_RGB2GREEN, 7, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 0, 1, 0x1f, 0 + }, + }, + + //LED_PWM + { + TPS6586xPmuSupply_LED_PWM, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, /* FIXME: how to get the output */ + {TPS6586x_RFF_INVALID, 0, 0, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_TRUE, + 0, 0, 0, 0 + }, + }, + + //PWM + { + TPS6586xPmuSupply_PWM, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, /* FIXME: how to get the output */ + {TPS6586x_RFF_INVALID, 0, 0, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_TRUE, + 0, 0, 0, 0 + }, + }, + + //White LED(SM3) + { + TPS6586xPmuSupply_WHITE_LED, + + {TPS6586x_R58_SM3_SET1, 0, 3, 0}, + {TPS6586x_R57_SM3_SET0, 0, 8, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + + { + NV_FALSE, + 25000, 0, 25000, 0 + }, + }, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + { + TPS6586xPmuSupply_SoC, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_R14_SUPPLYENE, 3, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_FALSE,0,0,0,0}, + }, + // External Supplies + + { + Ext_TPS62290PmuSupply_BUCK, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + 3, + {NV_FALSE,0,1050,1050,1050}, + }, + + { + Ext_TPS72012PmuSupply_LDO, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + 2, + {NV_FALSE,0,1200,1200,1200}, + }, + + { + Ext_TPS74201PmuSupply_LDO, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + 1, + {NV_FALSE,0,1500,1500,1500}, + }, + { + Ext_TPS2051BPmuSupply_VDDIO_VID, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_FALSE,0,5000,5000,5000}, + }, + + { + Ext_SWITCHPmuSupply_VDDIO_SD, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_FALSE,0,3300,3300,3300}, + }, + + { + Ext_SWITCHPmuSupply_VDDIO_SDMMC, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_FALSE,0,3300,3300,3300}, + }, + { + Ext_SWITCHPmuSupply_VDD_BL, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_RFF_INVALID, 0, 0, 0}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_FALSE,0,11100,11100,11100}, + }, + + { + Ext_SWITCHPmuSupply_VDD_PNL, + + {TPS6586x_RFF_INVALID, 0, 0, 0}, + {TPS6586x_R14_SUPPLYENE, 3, 1, TPS6586x_RFF_INVALID}, + NULL, NULL, NULL, + TPS6586x_RFF_INVALID, + {NV_FALSE,0,3300,3300,3300}, + } +#endif +}; + +static NvU32 TPS6586xPmuVoltageGetSM0(const NvU32 bits) +{ + NV_ASSERT(bits <= 0x1F); + + return (725 + bits * 25); +} + +static NvU32 TPS6586xPmuVoltageGetSM1(const NvU32 bits) +{ + NV_ASSERT(bits <= 0x1F); + +#if defined (CONFIG_TEGRA_ODM_HARMONY) + return (725 + bits * 25); +#else + return (1450 + bits * 50); +#endif +} + +static NvU32 TPS6586xPmuVoltageGetSM2(const NvU32 bits) +{ + NV_ASSERT(bits <= 0x1F); + + return (3000 + bits * 25); +} + +static NvU32 TPS6586xPmuVoltageGetVLDOx(const NvU32 bits) +{ + NV_ASSERT(bits <= 0x7); + + return VLDOx[bits]; +} + +static NvU32 TPS6586xPmuVoltageGetVLDO1(const NvU32 bits) +{ + /* VLDO1 and VLDO2 use the same table. + * See pp. 64 - 66 of TPS658621 data sheet. + */ + NV_ASSERT(bits <= 0x1F); + + return VLDO2[bits]; +} + +static NvU32 TPS6586xPmuVoltageGetVLDO2(const NvU32 bits) +{ + NV_ASSERT(bits <= 0x1F); + return VLDO2[bits]; +} +static NvU32 TPS6586xPmuVoltageGetVLDO4(const NvU32 bits) +{ + NV_ASSERT(bits <= 0x1F); + return VLDO4[bits]; +} + +#ifndef MIN +#define MIN(a, b) (a) <= (b) ? (a) : (b) +#endif + +static NvU32 TPS6586xPmuVoltageSetSM0(const NvU32 millivolts) +{ + if (millivolts < 725) + return 0; + else + return MIN((millivolts - 725) / 25, 0x1f); +} + +static NvU32 TPS6586xPmuVoltageSetSM1(const NvU32 millivolts) +{ +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if (millivolts < 725) + return 0; + else + return MIN((millivolts - 725) / 25, 0x1f); +#else + if (millivolts < 1450) + return 0; + else + return MIN((millivolts - 1450) / 50, 0x1f); +#endif +} + +static NvU32 TPS6586xPmuVoltageSetSM2(const NvU32 millivolts) +{ + if (millivolts < 3000) + return 0; + else + return MIN((millivolts - 3000) / 25, 0x1f); +} + +#define VOLTAGE_SEARCH(mv, vtbl) \ + const int cnt = sizeof(vtbl)/sizeof(NvU32); \ + int i; \ + for (i=0; i<cnt; i++) \ + { \ + if (mv <= (vtbl)[i]) \ + break; \ + } \ + return MIN(i, cnt-1) + + +static NvU32 TPS6586xPmuVoltageSetVLDOx(const NvU32 millivolts) +{ + VOLTAGE_SEARCH(millivolts, VLDOx); +} + +static NvU32 TPS6586xPmuVoltageSetVLDO1(const NvU32 millivolts) +{ + /* VLDO1 and VLDO2 use the same table. + * See pp. 64 - 66 of TPS658621 data sheet. + */ + VOLTAGE_SEARCH(millivolts, VLDO2); +} + +static NvU32 TPS6586xPmuVoltageSetVLDO2(const NvU32 millivolts) +{ + VOLTAGE_SEARCH(millivolts, VLDO2); +} +static NvU32 TPS6586xPmuVoltageSetVLDO4(const NvU32 millivolts) +{ + VOLTAGE_SEARCH(millivolts, VLDO4); +} + + +void +Tps6586xGetCapabilities( + NvU32 vddRail, + NvOdmPmuVddRailCapabilities* pCapabilities) +{ + NV_ASSERT(pCapabilities); + NV_ASSERT(vddRail < TPS6586xPmuSupply_Num); + + *pCapabilities = tps6586xSupplyInfoTable[vddRail].cap; +} + +#if defined(CONFIG_TEGRA_ODM_HARMONY) +static NvBool g_ExternalSupplyEnabled[TPS6586x_EXTERNAL_SUPPLY_NUM] = { 0 }; + +static NvBool +Tps6586xGetExternalSupply( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + if (g_ExternalSupplyEnabled[vddRail - (NvU32)(Ext_TPS62290PmuSupply_BUCK)] == NV_TRUE) + *pMilliVolts = tps6586xSupplyInfoTable[vddRail].cap.requestMilliVolts; + else + *pMilliVolts = 0; + + return NV_TRUE; +} +#endif + +static NvBool +Tps6586xReadVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + const TPS6586xPmuSupplyInfo *pSupplyInfo = &tps6586xSupplyInfoTable[vddRail]; + NvU32 data = 0; + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + // External supplies are fixed. + if ((vddRail == Ext_TPS62290PmuSupply_BUCK) || + (vddRail == Ext_TPS72012PmuSupply_LDO) || + (vddRail == Ext_TPS74201PmuSupply_LDO) || + (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) || + (vddRail == Ext_SWITCHPmuSupply_VDDIO_SD) || + (vddRail == Ext_SWITCHPmuSupply_VDDIO_SDMMC) || + (vddRail == Ext_SWITCHPmuSupply_VDD_BL) || + (vddRail == Ext_SWITCHPmuSupply_VDD_PNL)) + { + if (!Tps6586xGetExternalSupply(hDevice, vddRail, pMilliVolts)) + return NV_FALSE; + else + return NV_TRUE; + } +#endif + + if (pSupplyInfo->supplyRegInfo.addr == TPS6586x_RFF_INVALID) + { + return NV_FALSE; + } + + if (! Tps6586xI2cRead8(hDevice, pSupplyInfo->supplyRegInfo.addr, &data)) + return NV_FALSE; + + if (pSupplyInfo->getVoltage) + *pMilliVolts = pSupplyInfo->getVoltage((data >> pSupplyInfo->supplyRegInfo.start) & ((1<<pSupplyInfo->supplyRegInfo.bits)-1)); + else + *pMilliVolts = data; + + Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.addr, &data); + data &= (((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start); + if (data == 0) + { + //since Voltage table is {1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300} + //need to fill 0 voltage if needed + *pMilliVolts = data; + } + + + return NV_TRUE; +} + +#if 0 +static NvBool +Tps6586xSupplyCtrl( + const NvU32 vddRail, + NvBool ctrl) +{ + return NV_TRUE; +} +#endif + +#if defined(CONFIG_TEGRA_ODM_HARMONY) +#define NVODM_PORT(x) ((x) - 'a') + +static NvBool +Tps6586xSetExternalSupply( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvBool Enable) +{ + const TPS6586xPmuSupplyInfo* pSupplyInfo = &tps6586xSupplyInfoTable[vddRail]; + NvU32 data = 0; + NvU8 Gpio; + NvU32 GpioPort; + NvU32 GpioPin; + + NV_ASSERT((vddRail > TPS6586xPmuSupply_Invalid) && (vddRail < TPS6586xPmuSupply_Num)); + + // FIXME: Clean this up! This includes embedding more of these settings in + // the supply info table to simplify the code. + + // Switched by PMU GPIO + if ((vddRail == Ext_TPS62290PmuSupply_BUCK)|| + (vddRail == Ext_TPS72012PmuSupply_LDO) || + (vddRail == Ext_TPS74201PmuSupply_LDO)) + { + // Set output mode (TEST: FOR GPIO1 only) + + Gpio = pSupplyInfo->Gpio; + switch (Gpio) + { + case 1: + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5D_GPIOSET1, &data)) + return NV_FALSE; + + // Reset mode field + data &= ~(TPS6586x_R5D_GPIOSET1_GPIO1_MODE_MASK << + TPS6586x_R5D_GPIOSET1_GPIO1_MODE_SHIFT); + // Apply new mode setting (output) + data |= (TPS6586x_R5D_GPIO_MODE_OUTPUT << + TPS6586x_R5D_GPIOSET1_GPIO1_MODE_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data)) + return NV_FALSE; + + if (Enable) + { + // Enable output + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data)) + return NV_FALSE; + + data |= (TPS6586x_R5E_GPIOSET2_GPIO1_OUT_MASK << + TPS6586x_R5E_GPIOSET2_GPIO1_OUT_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; + } + else + { + // Disable output + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data)) + return NV_FALSE; + + data &= ~(TPS6586x_R5E_GPIOSET2_GPIO1_OUT_MASK << + TPS6586x_R5E_GPIOSET2_GPIO1_OUT_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; + } + break; + + case 2: + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5D_GPIOSET1, &data)) + return NV_FALSE; + + // Reset mode field + data &= ~(TPS6586x_R5D_GPIOSET1_GPIO2_MODE_MASK << + TPS6586x_R5D_GPIOSET1_GPIO2_MODE_SHIFT); + // Apply new mode setting (output) + data |= (TPS6586x_R5D_GPIO_MODE_OUTPUT << + TPS6586x_R5D_GPIOSET1_GPIO2_MODE_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data)) + return NV_FALSE; + + if (Enable) + { + // Enable output + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data)) + return NV_FALSE; + + data |= (TPS6586x_R5E_GPIOSET2_GPIO2_OUT_MASK << + TPS6586x_R5E_GPIOSET2_GPIO2_OUT_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; + } + else + { + // Disable output + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data)) + return NV_FALSE; + + data &= ~(TPS6586x_R5E_GPIOSET2_GPIO2_OUT_MASK << + TPS6586x_R5E_GPIOSET2_GPIO2_OUT_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; + } + break; + + case 3: + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5D_GPIOSET1, &data)) + return NV_FALSE; + // Reset mode field + data &= ~(TPS6586x_R5D_GPIOSET1_GPIO3_MODE_MASK << + TPS6586x_R5D_GPIOSET1_GPIO3_MODE_SHIFT); + // Apply new mode setting (output) + data |= (TPS6586x_R5D_GPIO_MODE_OUTPUT << + TPS6586x_R5D_GPIOSET1_GPIO3_MODE_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data)) + return NV_FALSE; + + if (Enable) + { + // Enable output + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data)) + return NV_FALSE; + + data |= (TPS6586x_R5E_GPIOSET2_GPIO3_OUT_MASK << + TPS6586x_R5E_GPIOSET2_GPIO3_OUT_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; + } + else + { + // Disable output + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R5E_GPIOSET2, &data)) + return NV_FALSE; + + data &= ~(TPS6586x_R5E_GPIOSET2_GPIO3_OUT_MASK << + TPS6586x_R5E_GPIOSET2_GPIO3_OUT_SHIFT); + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; + } + break; + + default: + return NV_FALSE; // bad parameter + } + } + // Switched by AP GPIO + else + { + // Open GPIO + if (!hPmu->hGpio) + { + hPmu->hGpio = NvOdmGpioOpen(); + + if (!hPmu->hGpio) + return NV_FALSE; + } + + // Get AP GPIO pin assigned to the respective voltage rail + // FIXME: This should be driven by supply info table. + switch (vddRail) + { + case Ext_TPS2051BPmuSupply_VDDIO_VID: + GpioPort = NVODM_PORT('t'); + GpioPin = 2; + break; + + case Ext_SWITCHPmuSupply_VDDIO_SD: + GpioPort = NVODM_PORT('t'); + GpioPin = 3; + break; + + case Ext_SWITCHPmuSupply_VDDIO_SDMMC: + GpioPort = NVODM_PORT('i'); + GpioPin = 6; + break; + + case Ext_SWITCHPmuSupply_VDD_BL: + GpioPort = NVODM_PORT('w'); + GpioPin = 0; + break; + + case Ext_SWITCHPmuSupply_VDD_PNL: + GpioPort = NVODM_PORT('c'); + GpioPin = 6; + break; + + default: + return NV_FALSE; + } + + NV_ASSERT((NVODM_EXT_AP_GPIO_RAIL(vddRail) >= 0) && + (NVODM_EXT_AP_GPIO_RAIL(vddRail) < TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM)); + + // Acquire Pin Handle + if (!hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)]) + { + hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)] = + NvOdmGpioAcquirePinHandle(hPmu->hGpio, GpioPort, GpioPin); + + if (!hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)]) + return NV_FALSE; + } + + if (Enable) + { + if (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) + { + NvOdmGpioConfig(hPmu->hGpio, + hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)], + NvOdmGpioPinMode_Tristate); + } + else + { + NvOdmGpioSetState(hPmu->hGpio, + hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)], + NvOdmGpioPinActiveState_High); + + NvOdmGpioConfig(hPmu->hGpio, + hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)], + NvOdmGpioPinMode_Output); + } + } + else + { + if (vddRail != Ext_TPS2051BPmuSupply_VDDIO_VID) + { + NvOdmGpioSetState(hPmu->hGpio, + hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)], + NvOdmGpioPinActiveState_Low); + NvOdmGpioConfig(hPmu->hGpio, + hPmu->hPin[NVODM_EXT_AP_GPIO_RAIL(vddRail)], + NvOdmGpioPinMode_Output); + } + } + } + + // This isn't thread safe, but it's highly unlikely that will be an issue for these rails. + if (Enable) + { + g_ExternalSupplyEnabled[vddRail - (NvU32)(Ext_TPS62290PmuSupply_BUCK)] = NV_TRUE; + } + else + { + g_ExternalSupplyEnabled[vddRail - (NvU32)(Ext_TPS62290PmuSupply_BUCK)] = NV_FALSE; + } + return NV_TRUE; +} +#endif + +static NvBool +Tps6586xWriteVoltageReg( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + const TPS6586xPmuSupplyInfo* pSupplyInfo = &tps6586xSupplyInfoTable[vddRail]; + //const TPS6586xPmuSupplyInfo* pSupplyInputInfo = &tps6586xSupplyInfoTable[pSupplyInfo->supplyInput]; + NvBool status = NV_FALSE; + NvU32 settleTime = 0; +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + NvU32 volChange = 0; +#endif + + NV_ASSERT(pSupplyInfo->supply == (TPS6586xPmuSupply)vddRail); + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if ((vddRail != Ext_TPS62290PmuSupply_BUCK) && + (vddRail != Ext_TPS72012PmuSupply_LDO) && + (vddRail != Ext_TPS74201PmuSupply_LDO) && + (vddRail != Ext_TPS2051BPmuSupply_VDDIO_VID) && + (vddRail != Ext_SWITCHPmuSupply_VDDIO_SD) && + (vddRail != Ext_SWITCHPmuSupply_VDDIO_SDMMC) && + (vddRail != Ext_SWITCHPmuSupply_VDD_BL) && + (vddRail != Ext_SWITCHPmuSupply_VDD_PNL)) +#endif + { + if (pSupplyInfo->ctrlRegInfo.addr == TPS6586x_RFF_INVALID) + { + NVODMPMU_PRINTF(("TPS:The required ctrl register address is INVALID...\n")); +#if defined(CONFIG_TEGRA_ODM_HARMONY) + return NV_TRUE; + //return NV_FALSE; +#else + return NV_FALSE; +#endif + } + } + + if (MilliVolts == ODM_VOLTAGE_OFF) + { + NvU32 data = 0; + + // check if the supply can be turned off + //NV_ASSERT(hDevice->supplyRefCntTable[vddRail]); + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + // Disable external supplies + if ((vddRail == Ext_TPS62290PmuSupply_BUCK) || + (vddRail == Ext_TPS72012PmuSupply_LDO) || + (vddRail == Ext_TPS74201PmuSupply_LDO) || + (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) || + (vddRail == Ext_SWITCHPmuSupply_VDDIO_SD) || + (vddRail == Ext_SWITCHPmuSupply_VDDIO_SDMMC) || + (vddRail == Ext_SWITCHPmuSupply_VDD_BL) || + (vddRail == Ext_SWITCHPmuSupply_VDD_PNL)) + { + status = Tps6586xSetExternalSupply(hDevice, vddRail, NV_FALSE); + } + else +#endif + if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail] == 1) + { + /* Disable */ + NvOdmServicesPmuSetSocRailPowerState( + ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->hOdmPmuSevice, pSupplyInfo->supply, NV_FALSE); + Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.addr, &data); +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if (vddRail == TPS6586xPmuSupply_SoC) + { + // SOC Super power rail don't hold the sleep bit + data |= (((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start); + } + else +#endif + { + data &= ~(((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start); + } + status = Tps6586xI2cWrite8(hDevice, pSupplyInfo->ctrlRegInfo.addr, data); +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if (vddRail == TPS6586xPmuSupply_SoC) + { + // Wait 10 secs for PMU to shutdown + NvOdmOsWaitUS(100000000); + } +#endif + + if (status && (pSupplyInfo->ctrlRegInfo.flag != TPS6586x_RFF_INVALID)) + { + status = Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.flag, &data); + if (status) + { + data &= ~(((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start); + status = Tps6586xI2cWrite8(hDevice, pSupplyInfo->ctrlRegInfo.flag, data); + } + } + + /* Reset to voltage to 0th */ + MilliVolts = 0; + +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + // Calcuate this voltage change + volChange = ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail]; + + ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] = 0; + + // DCD0/DCD1/DCD2 + if ((vddRail == TPS6586xPmuSupply_DCD0) || + (vddRail == TPS6586xPmuSupply_DCD1) || + (vddRail == TPS6586xPmuSupply_DCD2)) + { + // delay = Tstart(210) + Voltage change/Kramp + settleTime = T_START_TIME + volChange/K_RAMP; + } + else if ((vddRail == TPS6586xPmuSupply_LDO2) || + (vddRail == TPS6586xPmuSupply_LDO4)) + { + // Voltage change/Kramp + settleTime = volChange/K_RAMP; + } + else + { + settleTime = 0; + } +#endif + } + + if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail] != 0) + { +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if(--((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail] != 0) + { + if (pSettleMicroSeconds) + *pSettleMicroSeconds = 0; + return NV_TRUE; + } +#else + --((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail]; +#endif + } + +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + if (pSettleMicroSeconds != NULL) + *pSettleMicroSeconds = settleTime; + else + NvOdmOsWaitUS(settleTime); + + return NV_TRUE; +#endif + } + else + { + NvU32 data = 0; + + if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->supplyRefCntTable[vddRail]++ == 0) + { + // Enable external supplies +#if defined(CONFIG_TEGRA_ODM_HARMONY) + if ((vddRail == Ext_TPS62290PmuSupply_BUCK) || + (vddRail == Ext_TPS72012PmuSupply_LDO) || + (vddRail == Ext_TPS74201PmuSupply_LDO) || + (vddRail == Ext_TPS2051BPmuSupply_VDDIO_VID) || + (vddRail == Ext_SWITCHPmuSupply_VDDIO_SD) || + (vddRail == Ext_SWITCHPmuSupply_VDDIO_SDMMC) || + (vddRail == Ext_SWITCHPmuSupply_VDD_BL) || + (vddRail == Ext_SWITCHPmuSupply_VDD_PNL)) + { + status = Tps6586xSetExternalSupply(hDevice, vddRail, NV_TRUE); + } + else +#endif + { +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + NvOdmServicesPmuSetSocRailPowerState( + ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->hOdmPmuSevice, pSupplyInfo->supply, NV_TRUE); +#endif + status = Tps6586xI2cRead8(hDevice, pSupplyInfo->ctrlRegInfo.addr, &data); + if (status && ((data >> pSupplyInfo->ctrlRegInfo.start) & 0x1) == 0) + { +#if defined(CONFIG_TEGRA_ODM_HARMONY) + /* Enable */ + NvOdmServicesPmuSetSocRailPowerState( + ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->hOdmPmuSevice, + pSupplyInfo->supply, NV_TRUE); +#endif + data |= (((1<<pSupplyInfo->ctrlRegInfo.bits)-1)<<pSupplyInfo->ctrlRegInfo.start); + if (NV_FALSE == Tps6586xI2cWrite8(hDevice, pSupplyInfo->ctrlRegInfo.addr, data)) +#if defined(CONFIG_TEGRA_ODM_HARMONY) + return NV_TRUE; +#else + return NV_FALSE; +#endif + } + } + } + + /* Disable Flash mode + * FIXME: please check whether you need to disable flash */ + /* + if (vddRail == TPS6586xPmuSupply_RED1 || + vddRail == TPS6586xPmuSupply_GREEN1 || + vddRail == TPS6586xPmuSupply_BLUE1) + { + if (NV_FALSE == Tps6586xI2cWrite8(hDevice, TPS6586x_R50_RGB1FLASH, 0xFF)) + return NV_FALSE; + } + */ + } + + if (pSupplyInfo->supplyRegInfo.addr == TPS6586x_RFF_INVALID) + { +#if defined(CONFIG_TEGRA_ODM_HARMONY) + return NV_TRUE; +#else + return NV_FALSE; +#endif + } + else + { + const int bits = pSupplyInfo->setVoltage ? pSupplyInfo->setVoltage(MilliVolts) : MilliVolts; + NvU32 data = 0; + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + status = Tps6586xI2cRead8(hDevice, pSupplyInfo->supplyRegInfo.addr, &data); + if (NV_FALSE == status) + NVODMPMU_PRINTF(("TPS:Writing to PMU I2C fails 1... supplyaddress: %d\n", pSupplyInfo->supplyRegInfo.addr)); +#else + if ((vddRail == TPS6586xPmuSupply_DCD0) || + (vddRail == TPS6586xPmuSupply_DCD1) || + (vddRail == TPS6586xPmuSupply_LDO4) || + (vddRail == TPS6586xPmuSupply_LDO2)) + { + status = NV_TRUE; + } + else + { + status = Tps6586xI2cRead8(hDevice, pSupplyInfo->supplyRegInfo.addr, &data); + } +#endif + + if (status) + { + data &= ~(((1<<pSupplyInfo->supplyRegInfo.bits)-1)<<pSupplyInfo->supplyRegInfo.start); + data |= (bits << pSupplyInfo->supplyRegInfo.start); + status = Tps6586xI2cWrite8(hDevice, pSupplyInfo->supplyRegInfo.addr, data); + + /* Trigger a voltage change for SM0/SM1/LDO2/LDO4 */ + if ((vddRail == TPS6586xPmuSupply_DCD0) || + (vddRail == TPS6586xPmuSupply_DCD1) || + (vddRail == TPS6586xPmuSupply_LDO4) || + (vddRail == TPS6586xPmuSupply_LDO2)) + { + data = 0; + switch (vddRail) + { + case TPS6586xPmuSupply_LDO2: + data |= (1<<4); + data &= ~(1<<5); + break; + + case TPS6586xPmuSupply_LDO4: + data |= (1<<6); + data &= ~(1<<7); + break; + + case TPS6586xPmuSupply_DCD0: + data |= (1<<2); + data &= ~(1<<3); + break; + + case TPS6586xPmuSupply_DCD1: + data |= (1<<0); + data &= ~(1<<1); + break; + } + status = Tps6586xI2cWrite8(hDevice, TPS6586x_R20_VCC1, data); + } + +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + // Calcuate this voltage change + if (((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] < MilliVolts) + volChange = MilliVolts - ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail]; + else + volChange = ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] - MilliVolts; + + ((NvOdmPmuDeviceTPS *)(hDevice->pPrivate))->curVoltageTable[vddRail] = MilliVolts; + + // DCD0/DCD1/DCD2 + if ((vddRail == TPS6586xPmuSupply_DCD0) || + (vddRail == TPS6586xPmuSupply_DCD1) || + (vddRail == TPS6586xPmuSupply_DCD2)) + { + // delay = Tstart(210) + Voltage change/Kramp + settleTime = T_START_TIME + volChange/K_RAMP; + } + else if ((vddRail == TPS6586xPmuSupply_LDO2) || + (vddRail == TPS6586xPmuSupply_LDO4)) + { + // Voltage change/Kramp + settleTime = volChange/K_RAMP; + } + else + { + settleTime = 0; + } +#else + settleTime = 250; +#endif + + if (pSettleMicroSeconds) + *pSettleMicroSeconds = settleTime; + else + NvOdmOsWaitUS(settleTime); + return status; + } + } + + if (pSupplyInfo->supplyRegInfo.addr == TPS6586x_RFF_INVALID) + { +#if defined(CONFIG_TEGRA_ODM_HARMONY) + return NV_TRUE; +#else + return NV_FALSE; +#endif + } + + if (pSettleMicroSeconds) +#if defined(CONFIG_TEGRA_ODM_HARMONY) + *pSettleMicroSeconds = 250; + else + NvOdmOsWaitUS(250); +#else + *pSettleMicroSeconds = 0; +#endif + + return NV_TRUE; +} + +NvBool +Tps6586xGetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32* pMilliVolts) +{ + NV_ASSERT(hDevice); + NV_ASSERT(pMilliVolts); + NV_ASSERT(vddRail < TPS6586xPmuSupply_Num); + + if(! Tps6586xReadVoltageReg(hDevice, vddRail,pMilliVolts)) + return NV_FALSE; + + return NV_TRUE; +} + +NvBool +Tps6586xSetVoltage( + NvOdmPmuDeviceHandle hDevice, + NvU32 vddRail, + NvU32 MilliVolts, + NvU32* pSettleMicroSeconds) +{ + NV_ASSERT(hDevice); + NV_ASSERT(vddRail < TPS6586xPmuSupply_Num); + + if (pSettleMicroSeconds) + *pSettleMicroSeconds = 0; + + if (tps6586xSupplyInfoTable[vddRail].cap.OdmProtected == NV_TRUE) + { + NVODMPMU_PRINTF(("The voltage is protected and can not be set.\n")); + return NV_TRUE; + } + + if ((MilliVolts == ODM_VOLTAGE_OFF) || + ((MilliVolts <= tps6586xSupplyInfoTable[vddRail].cap.MaxMilliVolts) && + (MilliVolts >= tps6586xSupplyInfoTable[vddRail].cap.MinMilliVolts))) + { + if (! Tps6586xWriteVoltageReg(hDevice, vddRail, MilliVolts, pSettleMicroSeconds)) + return NV_FALSE; + } + else + { + NVODMPMU_PRINTF(("The required voltage is not supported..\n")); +#if defined(CONFIG_TEGRA_ODM_HARMONY) + return NV_TRUE; + //return NV_FALSE; +#else + return NV_FALSE; +#endif + } + + return NV_TRUE; +} + +#if 0 +void DumpTps6586x(NvOdmPmuDeviceHandle hDevice) +{ + int i; + NvU32 data; + for (i=0; i<0xFF; i++) + { + data = 0; + Tps6586xI2cRead8(hDevice, i, &data); + NVODMPMU_PRINTF(("Register 0x%x = 0x%x\n", i, data)); + } +} +#endif + +NvBool Tps6586xSetup(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmIoModule I2cModule = NvOdmIoModule_I2c; + NvU32 I2cInstance = 0; + NvU32 I2cAddress = 0; + NvBool status = NV_FALSE; + NvU32 data = 0; +// static TPS6586xDevice s_tps6586x = {0}; + + const NvOdmPeripheralConnectivity *pConnectivity = + NvOdmPeripheralGetGuid(PMUGUID); + + NV_ASSERT(hDevice); + + hPmu = (NvOdmPmuDeviceTPS *)NvOdmOsAlloc(sizeof(NvOdmPmuDeviceTPS)); + if (hPmu == NULL) + { + NVODMPMU_PRINTF(("Error Allocating NvOdmPmuDeviceTPS. \n")); + return NV_FALSE; + } + NvOdmOsMemset(hPmu, 0, sizeof(NvOdmPmuDeviceTPS)); + + hDevice->pPrivate = hPmu; + + if (pConnectivity != NULL) // PMU is in database + { + NvU32 i = 0; + pmuPresented = NV_TRUE; + + for (i = 0; i < pConnectivity->NumAddress; i ++) + { + if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_I2c_Pmu) + { + I2cModule = NvOdmIoModule_I2c_Pmu; + I2cInstance = pConnectivity->AddressList[i].Instance; + I2cAddress = pConnectivity->AddressList[i].Address; + break; + } + } + + NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu); + NV_ASSERT(I2cAddress != 0); + + hPmu->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance); + if (!hPmu->hOdmI2C) + { + NVODMPMU_PRINTF(("[NVODM PMU]Tps6586xSetup: Error Open I2C device. \n")); + NVODMPMU_PRINTF(("[NVODM PMU]Please check PMU device I2C settings. \n")); + goto OPEN_FAILED; + } + hPmu->DeviceAddr = I2cAddress; + hPmu->hOdmPmuSevice = NvOdmServicesPmuOpen(); +#if defined(CONFIG_TEGRA_ODM_HARMONY) + //if (NV_FALSE == Tps6586xWriteVoltageReg(hDevice, TPS6586xPmuSupply_LDO5, 3300, NULL)) + if (NV_FALSE == Tps6586xWriteVoltageReg(hDevice, TPS6586xPmuSupply_LDO5, 2850, NULL)) + NVODMPMU_PRINTF(("TPS: Fail to set the NVDDIO_NAND to 2.85V\n")); + else + NVODMPMU_PRINTF(("TPS: set the NVDDIO_NAND to 2.85V\n")); +#endif + } + else + { + // if PMU is not presented in the database, then the platform is PMU-less. + NVODMPMU_PRINTF(("[NVODM PMU]Tps6586xSetup: The system did not doscover PMU fromthe data base. \n")); + NVODMPMU_PRINTF(("[NVODM PMU]Tps6586xSetup: If this is not intended, please check the peripheral database for PMU settings. \n")); + + //uncomment below line if you really need to run pmu adaptation on pmu-less system. + // the system will run in pmu-less mode. + //pmuPresented = NV_FALSE; + + goto OPEN_FAILED; + } + + //hDevice->priv = &s_tps6586x; + + /* Check Chip Device ID to verify it */ +#if 0 + I2cInstance = 0; + if (!Tps6586xI2cRead8(hDevice, TPS6586x_RCD_VERSIONID, &I2cInstance) || I2cInstance != 0x60) + { + NV_ASSERT(!"did not find TSP6586x"); + goto OPEN_FAILED; + } +#endif + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + /* Initialize the refcont of the rails which are ON by default */ + hPmu->supplyRefCntTable[TPS6586xPmuSupply_SoC] = 1; +#endif + +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + // If your project doesn't use this GPIO, please delete them! + // Enable GPIO3 to HIGH + // Set GPIO Configure to output + data = 0x10; + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5D_GPIOSET1, data)) + return NV_FALSE; + + // Set GPIO to HI, NON-Inverting + data = 0x04; + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R5E_GPIOSET2, data)) + return NV_FALSE; +#endif + + //NvOdmOsMemset(&s_tps6586x, 0, sizeof(s_tps6586x)); + //s_tps6586x.pmuPresented = NV_TRUE; + pmuPresented = NV_TRUE; + +#if NV_DEBUG + //DumpTps6586x(hDevice); +#endif + + if (!Tps6586xBatteryChargerSetup(hDevice)) + return NV_FALSE; + + // The interrupt assumes not supported until tps6586xInterruptHandler() is called. + pmuInterruptSupported = NV_FALSE; + + // setup the interrupt any way. + if (!Tps6586xSetupInterrupt(hDevice, &pmuStatus)) + return NV_FALSE; + + //Check battery presence + if (!Tps6586xBatteryChargerCBCMainBatt(hDevice, &battPresence)) + return NV_FALSE; + + // Check battery Fullness + if (battPresence == NV_TRUE) + { + if (!Tps6586xBatteryChargerCBCBattFul(hDevice, &status)) + return NV_FALSE; + pmuStatus.batFull = status; + } + else + { + pmuStatus.batFull = NV_FALSE; + } + + return NV_TRUE; + +OPEN_FAILED: + Tps6586xRelease(hDevice); + return NV_FALSE; +} + +void Tps6586xRelease(NvOdmPmuDeviceHandle hDevice) +{ +#if defined(CONFIG_TEGRA_ODM_HARMONY) + NvU32 i; +#endif + if (hDevice != NULL && hPmu->hOdmI2C) + { + NvOdmServicesPmuClose(hPmu->hOdmPmuSevice); + hPmu->hOdmPmuSevice = NULL; + NvOdmI2cClose(hPmu->hOdmI2C); + hPmu->hOdmI2C = NULL; + NvOdmOsFree(hPmu); + hPmu = NULL; + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + + // Release & Close the GPIOs + for (i=0; i<(TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM); i++) + { + NvOdmGpioReleasePinHandle(hPmu->hGpio, hPmu->hPin[i]); + } + NvOdmGpioClose(hPmu->hGpio); +#endif + } +} + +NvBool +Tps6586xGetAcLineStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuAcLineStatus *pStatus) +{ + NvBool acLineStatus = NV_FALSE; + + NV_ASSERT(hDevice); + NV_ASSERT(pStatus); + + // check if charger presents + if (battPresence == NV_FALSE) + { + *pStatus = NvOdmPmuAcLine_Online; + return NV_TRUE; + } + + if (pmuInterruptSupported == NV_TRUE) + { + if ( pmuStatus.mChgPresent == NV_TRUE ) + { + *pStatus = NvOdmPmuAcLine_Online; + acLineStatus = NV_TRUE; + } + else + { + *pStatus = NvOdmPmuAcLine_Offline; + acLineStatus = NV_FALSE; + } + } + else + { + // battery is present, now check if charger presents + if (!Tps6586xBatteryChargerMainChgPresent(hDevice, &acLineStatus)) + { + NVODMPMU_PRINTF(("Error in checking main charger presence.\n")); + return NV_FALSE; + } + + if (acLineStatus == NV_TRUE) + *pStatus = NvOdmPmuAcLine_Online; + else + *pStatus = NvOdmPmuAcLine_Offline; + } + return NV_TRUE; +} + +NvBool +Tps6586xGetBatteryStatus( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU8 *pStatus) +{ + NvU8 status = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pStatus); + NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num); + + if (batteryInst == NvOdmPmuBatteryInst_Main) + { + if (battPresence == NV_TRUE) + { + NvOdmPmuAcLineStatus stat = NvOdmPmuAcLine_Offline; + NvU32 VBatSense = 0; + if (!Tps6586xGetAcLineStatus(hDevice, &stat)) + return NV_FALSE; + + if (stat == NvOdmPmuAcLine_Online) + { + if (pmuInterruptSupported == NV_TRUE) + { + if (pmuStatus.batFull == NV_FALSE) + status = NVODM_BATTERY_STATUS_CHARGING; + } + else + { + NvBool batFull = NV_FALSE; + if (!Tps6586xBatteryChargerCBCBattFul(hDevice, &batFull)) + return NV_FALSE; + if (batFull == NV_FALSE) + status = NVODM_BATTERY_STATUS_CHARGING; + } + } + + // Get VBatSense + if (!Tps6586xAdcVBatSenseRead(hDevice, &VBatSense)) + return NV_FALSE; + + if (VBatSense > NVODM_BATTERY_HIGH_VOLTAGE_MV) // maybe modify these parameters + status |= NVODM_BATTERY_STATUS_HIGH; + else if ((VBatSense < NVODM_BATTERY_LOW_VOLTAGE_MV)&& + (VBatSense > NVODM_BATTERY_CRITICAL_VOLTAGE_MV)) + status |= NVODM_BATTERY_STATUS_LOW; + else if (VBatSense <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV) + status |= NVODM_BATTERY_STATUS_CRITICAL; + + } + else + { + /* Battery is actually not present */ + status = NVODM_BATTERY_STATUS_NO_BATTERY; + } + + *pStatus = status; + } + else + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + } + + return NV_TRUE; +} + +NvBool +Tps6586xGetBatteryData( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryData *pData) +{ + NvOdmPmuBatteryData batteryData; + + batteryData.batteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryCurrent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryTemperature = NVODM_BATTERY_DATA_UNKNOWN; + batteryData.batteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + + NV_ASSERT(hDevice); + NV_ASSERT(pData); + NV_ASSERT(batteryInst <= NvOdmPmuBatteryInst_Num); + + if (batteryInst == NvOdmPmuBatteryInst_Main) + { + NvU32 VBatSense = 0; + NvU32 VBatTemp = 0; + + if (battPresence == NV_TRUE) + { + /* retrieve Battery voltage and temperature */ + + // Get VBatSense + if (!Tps6586xAdcVBatSenseRead(hDevice, &VBatSense)) + { + NVODMPMU_PRINTF(("Error reading VBATSense. \n")); + return NV_FALSE; + } + + // Get VBatTemp + if (!Tps6586xAdcVBatTempRead(hDevice, &VBatTemp)) + { + NVODMPMU_PRINTF(("Error reading VBATSense. \n")); + return NV_FALSE; + } + + batteryData.batteryVoltage = VBatSense; + batteryData.batteryTemperature = Tps6586xBatteryTemperature(VBatSense, VBatTemp); + } + + *pData = batteryData; + } + else + { + *pData = batteryData; + } + + return NV_TRUE; +} + +void +Tps6586xGetBatteryFullLifeTime( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvU32 *pLifeTime) +{ + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; +} + +void +Tps6586xGetBatteryChemistry( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuBatteryInstance batteryInst, + NvOdmPmuBatteryChemistry *pChemistry) +{ + *pChemistry = NvOdmPmuBatteryChemistry_LION; +} + + +NvBool +Tps6586xSetChargingCurrent( + NvOdmPmuDeviceHandle hDevice, + NvOdmPmuChargingPath chargingPath, + NvU32 chargingCurrentLimitMa, + NvOdmUsbChargerType ChargerType) +{ + NvU32 data = 0; + NV_ASSERT(hDevice); + + // if no battery, then do nothing + if (battPresence == NV_FALSE) + return NV_TRUE; + + if (chargingCurrentLimitMa > DEDICATED_CHARGER_LIMIT_MA) + chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA; + + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R49_CHG1, &data)) + return NV_FALSE; + + if (chargingPath == NvOdmPmuChargingPath_UsbBus) + { + switch (ChargerType) + { + case NvOdmUsbChargerType_SJ: + chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_SK: + chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_SE1: + chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_SE0: + chargingCurrentLimitMa = DEDICATED_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_Dummy: + chargingCurrentLimitMa = DUMB_CHARGER_LIMIT_MA; + break; + case NvOdmUsbChargerType_UsbHost: + default: + // USB Host based charging, nothing to do. Just pass current limit to PMU. + break; + } + } + + if (chargingCurrentLimitMa >= MAX_CHARGING_CURRENT) + { + data = data & 0xf3; + data = data | 0xC; + } + else if (chargingCurrentLimitMa >= L2_CHARGING_CURRENT) + { + data = data & 0xf3; + data = data | 0x4; + } + else if (chargingCurrentLimitMa >= L3_CHARGING_CURRENT) + { + data = data & 0xf3; + data = data | 0x0; + } + // 0 mA + else + { + chargingCurrentLimitMa = 0; + } + + //data = (NvU8)((( chargingCurrentLimitMa << 8 ) - chargingCurrentLimitMa ) + // / CHARGER_CONSTANT_CURRENT_SET_MA ); + + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R49_CHG1, data)) + return NV_FALSE; + + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R4A_CHG2, &data)) + return NV_FALSE; + + if (chargingCurrentLimitMa == 0) + { + data = data & 0xfd; // Disable charging! + } + else + { + data = data | 0x02; // Enable Charging! + } + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4A_CHG2, data)) + return NV_FALSE; + + return NV_TRUE; +} + +void Tps6586xInterruptHandler( NvOdmPmuDeviceHandle hDevice) +{ + //TPS6586xHandle tps6586x = hDevice->priv; + //tps6586x->pmuStatus.batFull = NV_FALSE; + + // If the interrupt handle is called, the interrupt is supported. + pmuInterruptSupported = NV_TRUE; + + Tps6586xInterruptHandler_int(hDevice, &pmuStatus); +} + +NvBool Tps6586xReadRtc( NvOdmPmuDeviceHandle hDevice, NvU32 *Count) +{ + *Count = 0; + return (Tps6586xRtcCountRead(hDevice, Count)); +} + +NvBool Tps6586xWriteRtc( NvOdmPmuDeviceHandle hDevice, NvU32 Count) +{ + return (Tps6586xRtcCountWrite(hDevice, Count)); +} + +NvBool Tps6586xIsRtcInitialized( NvOdmPmuDeviceHandle hDevice) +{ + return ((Tps6586xRtcWasStartUpFromNoPower(hDevice))? NV_FALSE: NV_TRUE); +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h new file mode 100644 index 000000000000..0c1f4fb2b9af --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 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 NVODM_PMU_TPS6586X_H_HH +#define NVODM_PMU_TPS6586X_H_HH + +#include "nvodm_pmu.h" +#include "nvodm_services.h" +#include "nvodm_pmu_tps6586x_supply_info_table.h" +#include "tps6586x_reg.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#if (NV_DEBUG) +#define NVODMPMU_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODMPMU_PRINTF(x) +#endif + +typedef struct NvOdmPmuDeviceTPSRec +{ + /* The handle to the I2C */ + NvOdmServicesI2cHandle hOdmI2C; + + /* The odm pmu service handle */ + NvOdmServicesPmuHandle hOdmPmuSevice; + /* the PMU I2C device Address */ + NvU32 DeviceAddr; + + /* Device's private data */ + void *priv; + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + /* Gpio Handles (for external supplies) */ + NvOdmServicesGpioHandle hGpio; + NvOdmGpioPinHandle hPin[TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM]; +#else + /* The current voltage */ + NvU32 curVoltageTable[VRAILCOUNT]; +#endif + + /* The ref cnt table of the power supplies */ +#if defined(CONFIG_TEGRA_ODM_HARMONY) + NvU32 supplyRefCntTable[TPS6586xPmuSupply_Num]; +#else + NvU32 supplyRefCntTable[VRAILCOUNT]; +#endif + +} NvOdmPmuDeviceTPS; + +void Tps6586xGetCapabilities( NvU32 vddRail, NvOdmPmuVddRailCapabilities* pCapabilities); +NvBool Tps6586xGetVoltage( NvOdmPmuDeviceHandle hDevice, NvU32 vddRail, NvU32* pMilliVolts); +NvBool Tps6586xSetVoltage( NvOdmPmuDeviceHandle hDevice, NvU32 vddRail, NvU32 MilliVolts, NvU32* pSettleMicroSeconds); +NvBool Tps6586xSetup(NvOdmPmuDeviceHandle hDevice); +void Tps6586xRelease(NvOdmPmuDeviceHandle hDevice); +NvBool Tps6586xGetAcLineStatus( NvOdmPmuDeviceHandle hDevice, NvOdmPmuAcLineStatus *pStatus); +NvBool Tps6586xGetBatteryStatus( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvU8 *pStatus); +NvBool Tps6586xGetBatteryData( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvOdmPmuBatteryData *pData); +void Tps6586xGetBatteryFullLifeTime( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvU32 *pLifeTime); +void Tps6586xGetBatteryChemistry( NvOdmPmuDeviceHandle hDevice, NvOdmPmuBatteryInstance batteryInst, NvOdmPmuBatteryChemistry *pChemistry); +NvBool Tps6586xSetChargingCurrent( NvOdmPmuDeviceHandle hDevice, NvOdmPmuChargingPath chargingPath, NvU32 chargingCurrentLimitMa, NvOdmUsbChargerType ChargerType); +void Tps6586xInterruptHandler( NvOdmPmuDeviceHandle hDevice); +NvBool Tps6586xReadRtc( NvOdmPmuDeviceHandle hDevice, NvU32 *Count); +NvBool Tps6586xWriteRtc( NvOdmPmuDeviceHandle hDevice, NvU32 Count); +NvBool Tps6586xIsRtcInitialized( NvOdmPmuDeviceHandle hDevice); + +#if defined(__cplusplus) +} +#endif + +#endif /* NVODM_PMU_TPS6586X_H_HH */ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c new file mode 100644 index 000000000000..7f2fcb0dd54c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.c @@ -0,0 +1,200 @@ +/* + * Copyright (c) 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 "nvodm_pmu_tps6586x_adc.h" +#include "nvodm_pmu_tps6586x_i2c.h" +#include "tps6586x_reg.h" +#include "nvodm_pmu_tps6586x_supply_info_table.h" + +#define ADC_CONVERSION_DELAY_USEC 70 +#define ADC_CONVERSION_TIMEOUT_USEC 500 +#define ADC_CONVERSION_VOLTAGE_RANGE 2000 +#define ADC_CONVERSION_DIVIDOR 3 +#define ADC_CONVERSION_PRECISION 10 +#define ADC_CONVERSION_SUB_OFFSET 2250 +#define ADC_FULL_SCALE_READING_MV_BAT 4622 +#define ADC_FULL_SCALE_READING_MV_TS 2600 +#define ADC_CONVERSION_PREWAIT_MS 26 + +/* read voltage from ADC CH10(battery) */ +NvBool +Tps6586xAdcVBatSenseRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt) +{ + NvU32 timeout = 0; + NvU32 dataS1 = 0; + NvU32 dataH = 0; + NvU32 dataL = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(volt); + + *volt = 0; // Default is 0mV. + // Configuring the adc conversion cycle + // ADC0_WAIT register(0x62) + // Reset all ADC engines and return them to the idle state; ADC0_RESET: 1 + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x80)) + return NV_FALSE; + + // ADC0_SET register(0x61) + // ADC0_EN: 0(Don't start conversion); Number of Readings: 16; CHANNEL: CH10(battery) + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x19)) + return NV_FALSE; + + // ADC0_WAIT register(0x62) + // REF_EN: 0; AUTO_REF: 1; Wait time: 0.062ms + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x21)) + return NV_FALSE; + + // Start conversion!! + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x99)) + return NV_FALSE; + + // Wait for conversion + //NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + NvOdmOsSleepMS(ADC_CONVERSION_PREWAIT_MS); + + // Make sure the conversion is completed - check for ADC error. + while (1) + { + // Read ADC status register + if(! Tps6586xI2cRead8(hDevice, TPS6586x_R9A_ADC0_INT, &dataS1)) + return NV_FALSE; + + // Conversion is done! + if (dataS1 & 0x80) + break; + + // ADC error! + if (dataS1 & 0x40) + { + NVODMPMU_PRINTF(("ADC conversion error.\n")); + return NV_FALSE; + } + + NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + timeout += ADC_CONVERSION_DELAY_USEC; + if (timeout >= ADC_CONVERSION_TIMEOUT_USEC) + return NV_FALSE; + } + + // Read the ADC conversion Average (SUM). + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R94_ADC0_SUM2, &dataH)) + return NV_FALSE; + + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R95_ADC0_SUM1, &dataL)) + return NV_FALSE; + + // Get a result value with mV. + *volt = (((dataH << 8) | dataL) * ADC_FULL_SCALE_READING_MV_BAT) / 1023 / 16; + + return NV_TRUE; +} + +/* read voltage from ADC CH5(temperature) */ +NvBool +Tps6586xAdcVBatTempRead(NvOdmPmuDeviceHandle hDevice, NvU32 *volt) +{ + NvU32 timeout = 0; + NvU32 dataS1 = 0; + NvU32 dataH = 0; + NvU32 dataL = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(volt); + + *volt = 0; // Default is 0'C. + + // Configuring the adc conversion cycle + // ADC0_WAIT register(0x62) + // Reset all ADC engines and return them to the idle state; ADC0_RESET: 1 + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x80)) + return NV_FALSE; + // ADC0_SET register(0x61) + // ADC0_EN: 0(Don't start conversion); Number of Readings: 16; CHANNEL: CH5(temperature) + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x14)) + return NV_FALSE; + + // ADC0_WAIT register(0x62) + // REF_EN: 0; AUTO_REF: 1; Wait time: 0.062ms + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R62_ADC0_WAIT, 0x21)) + return NV_FALSE; + + // Start conversion!! + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_R61_ADC0_SET, 0x94)) + return NV_FALSE; + + // Wait for conversion + // NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + NvOdmOsSleepMS(ADC_CONVERSION_PREWAIT_MS); + + // make sure the conversion is completed, or adc error. + while (1) + { + // Read ADC status register + if(! Tps6586xI2cRead8(hDevice, TPS6586x_R9A_ADC0_INT, &dataS1)) + return NV_FALSE; + + // Conversion is done! + if (dataS1 & 0x80) + break; + + // ADC error! + if (dataS1 & 0x40) + { + NVODMPMU_PRINTF(("ADC conversion error.\n")); + return NV_FALSE; + } + + NvOdmOsWaitUS(ADC_CONVERSION_DELAY_USEC); + timeout += ADC_CONVERSION_DELAY_USEC; + if (timeout >= ADC_CONVERSION_TIMEOUT_USEC) + return NV_FALSE; + } + + // Read the ADC conversion Average (SUM). + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R94_ADC0_SUM2, &dataH)) + return NV_FALSE; + + if (!Tps6586xI2cRead8(hDevice, TPS6586x_R95_ADC0_SUM1, &dataL)) + return NV_FALSE; + + // Get a result value with mV. + *volt = (((dataH << 8) | dataL) * ADC_FULL_SCALE_READING_MV_TS) / 1023 / 16; + + return NV_TRUE; +} + +/* Calculate the battery temperature */ +NvU32 Tps6586xBatteryTemperature(NvU32 VBatSense, NvU32 VBatTemp) +{ + return 0; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h new file mode 100644 index 000000000000..803a62856a9b --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_adc.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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_TPS6586X_ADC_HEADER +#define INCLUDED_TPS6586X_ADC_HEADER + +/* the ADC is used for battery voltage conversion */ +#include "nvodm_pmu_tps6586x.h" + + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* read voltage from adc */ +NvBool +Tps6586xAdcVBatSenseRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt); + +/* read bat temperature voltage from ADC */ +NvBool +Tps6586xAdcVBatTempRead( + NvOdmPmuDeviceHandle hDevice, + NvU32 *volt); + +/* Calculate the battery temperature */ +NvU32 +Tps6586xBatteryTemperature( + NvU32 VBatSense, + NvU32 VBatTemp); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_TPS6586X_ADC_HEADER diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c new file mode 100644 index 000000000000..8a4573922adf --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.c @@ -0,0 +1,109 @@ +/* + * Copyright (c) 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 "nvodm_pmu_tps6586x_i2c.h" +#include "nvodm_pmu_tps6586x_batterycharger.h" + +NvBool Tps6586xBatteryChargerSetup(NvOdmPmuDeviceHandle hDevice) +{ + NvU32 data = 0; + // Configure CHARGER RAM registers + // CHG1: Charge safety timer value is 4 Hrs; Charge current scaling facotr: 1.0; + data = 0x0c; + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R49_CHG1, data)) + return NV_FALSE; + + // CHG2: CHARGE SAFETY TIMER: ON; CHARGE VOLTAGE: 4.2V; CHARGER: ON; + data = 0x1a; + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4A_CHG2, data)) + return NV_FALSE; + + // CHG3: + data = 0x0; + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4B_CHG3, data)) + return NV_FALSE; + + // RAM Control BITS: CHARGE VOLTAGE RANGE: 3.95 - 4.2; USB Input current limit: 500mA; + // Auto mode enabled; AC input current limit: 2A + data = 0x05; + if (!Tps6586xI2cWrite8(hDevice, TPS6586x_R4C_PPATH2, data)) + return NV_FALSE; + + return NV_TRUE; +} + +/* check CBC main batt presence */ +NvBool +Tps6586xBatteryChargerCBCMainBatt(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU32 data = 0; + + if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB9_STAT1, &data)) + return NV_FALSE; + + // bit 0 show if battery exists or not + data = data & 0x01; + + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + + return NV_TRUE; +} + +/* check batt_ful status */ +NvBool +Tps6586xBatteryChargerCBCBattFul(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU32 data = 0; + + if(! Tps6586xI2cRead8(hDevice, TPS6586x_RBA_STAT2, &data)) + return NV_FALSE; + + data = data & 0x2; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + + return NV_TRUE; +} + +/* check main charger status */ +NvBool +Tps6586xBatteryChargerMainChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status) +{ + NvU32 data = 0; + + if(! Tps6586xI2cRead8(hDevice, TPS6586x_RBB_STAT3, &data)) + return NV_FALSE; + + data = data & 0xc; + *status = (data == 0 ? NV_FALSE : NV_TRUE ); + + return NV_TRUE; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h new file mode 100644 index 000000000000..83b538792334 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_batterycharger.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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_TPS6586X_BATTERYCHARGER_HEADER +#define INCLUDED_TPS6586X_BATTERYCHARGER_HEADER + + + +#include "nvodm_pmu_tps6586x.h" + +/* the battery charger functions */ +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Initliase all registers that related to battery charger */ +NvBool +Tps6586xBatteryChargerSetup(NvOdmPmuDeviceHandle hDevice); + +/* check CBC main batt presence */ +NvBool +Tps6586xBatteryChargerCBCMainBatt(NvOdmPmuDeviceHandle hDevice, NvBool *status); + +/* check batt_ful status */ +NvBool +Tps6586xBatteryChargerCBCBattFul(NvOdmPmuDeviceHandle hDevice, NvBool *status); + +/* check main charger status */ +NvBool +Tps6586xBatteryChargerMainChgPresent(NvOdmPmuDeviceHandle hDevice, NvBool *status); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_TPS6586X_BATTERYCHARGER_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c new file mode 100644 index 000000000000..94e806101b10 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.c @@ -0,0 +1,207 @@ +/* + * Copyright (c) 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 "nvodm_pmu_tps6586x_i2c.h" +#include "nvodm_pmu_tps6586x.h" +#include "pmu_hal.h" + +NvBool +Tps6586xI2cWrite8( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 Data) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + NvOdmI2cTransactionInfo TransactionInfo = {0}; + + WriteBuffer[0] = Addr & 0xFF; // PMU offset + WriteBuffer[1] = Data & 0xFF; // written data + + TransactionInfo.Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo, 1, + TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool +Tps6586xI2cRead8( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 *Data) +{ + NvU8 ReadBuffer=0; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + // Write the PMU offset + ReadBuffer = Addr & 0xFF; + + TransactionInfo[0].Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr; + TransactionInfo[0].Buf = &ReadBuffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + TransactionInfo[1].Address = (((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr | 0x1); + TransactionInfo[1].Buf = &ReadBuffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + // Read data from PMU at the specified offset + status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo[0], 2, + TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = ReadBuffer; + return NV_TRUE; +} + +NvBool Tps6586xI2cWrite32( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 Data) +{ + NvU8 WriteBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + NvOdmI2cTransactionInfo TransactionInfo = {0}; + + WriteBuffer[0] = (NvU8)(Addr & 0xFF); + WriteBuffer[1] = (NvU8)((Data >> 24) & 0xFF); + WriteBuffer[2] = (NvU8)((Data >> 16) & 0xFF); + WriteBuffer[3] = (NvU8)((Data >> 8) & 0xFF); + WriteBuffer[4] = (NvU8)(Data & 0xFF); + + TransactionInfo.Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 5; + + status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo, 1, + TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + return NV_TRUE; + } + else + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } +} + +NvBool Tps6586xI2cRead32( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 *Data) +{ + NvU8 ReadBuffer[5]; + NvOdmI2cStatus status = NvOdmI2cStatus_Success; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + // Write the PMU offset + ReadBuffer[0] = Addr & 0xFF; + + TransactionInfo[0].Address = ((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr; + TransactionInfo[0].Buf = &ReadBuffer[0]; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + + TransactionInfo[1].Address = (((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->DeviceAddr | 0x1); + TransactionInfo[1].Buf = &ReadBuffer[0]; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 4; + + // Read data from PMU at the specified offset + status = NvOdmI2cTransaction(((NvOdmPmuDeviceTPS *)(hPmu->pPrivate))->hOdmI2C, &TransactionInfo[0], 2, + TPS6586x_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status != NvOdmI2cStatus_Success) + { + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("NvOdmPmuI2cRead8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; + } + + *Data = (ReadBuffer[0] << 24) | (ReadBuffer[1] << 16) | + (ReadBuffer[2] << 8) | ReadBuffer[3]; + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h new file mode 100644 index 000000000000..df17ff6c2cf0 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_i2c.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 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_NVODM_PMU_TPS6856X_I2C_H +#define INCLUDED_NVODM_PMU_TPS6856X_I2C_H + +#include "nvodm_pmu_tps6586x.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// Constant definition +#define TPS6586x_I2C_SPEED_KHZ 100 + +// Function declaration +NvBool Tps6586xI2cWrite8( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 Data); + +NvBool Tps6586xI2cRead8( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 *Data); + +NvBool Tps6586xI2cWrite32( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 Data); + +NvBool Tps6586xI2cRead32( + NvOdmPmuDeviceHandle hPmu, + NvU32 Addr, + NvU32 *Data); + + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_PMU_TPS6856X_I2C_H diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c new file mode 100644 index 000000000000..b3ac0b954a4e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 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 "nvodm_pmu_tps6586x_interrupt.h" +#include "nvodm_pmu_tps6586x_i2c.h" +#include "nvodm_pmu_tps6586x_supply_info_table.h" +#include "nvodm_services.h" +#include "nvodm_pmu_tps6586x_batterycharger.h" + +#define TPS6586X_INT_BATT_INST 0x01 +#define TPS6586X_INT_PACK_COLD_DET 0x02 +#define TPS6586X_INT_PACK_HOT_DET 0x04 + +#define TPS6586X_INT_USB_DETECTION 0x04 +#define TPS6586X_INT_AC_DETECTION 0x08 +#define TPS6586X_INT_LOWSYS_DETECTION 0x40 + +NvBool Tps6586xSetupInterrupt(NvOdmPmuDeviceHandle hDevice, + TPS6586xStatus *pmuStatus) +{ + NvBool status = NV_FALSE; + NvU32 data = 0; + + NV_ASSERT(hDevice); + NV_ASSERT(pmuStatus); + + /* Init Pmu Status */ + pmuStatus->lowBatt = NV_FALSE; + pmuStatus->highTemp = NV_FALSE; + + if (!Tps6586xBatteryChargerMainChgPresent(hDevice,&status)) + return NV_FALSE; + pmuStatus->mChgPresent = status; + + /* Set up Interrupt Mask */ + /* Mask1 */ + data = 0xFF; + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB0_INT_MASK1, data )) + return NV_FALSE; + + /* Mask2 */ + data = 0xFF; + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB1_INT_MASK2, data )) + return NV_FALSE; + + /* Mask3: Battery detction, etc */ + data = 0; + data = (NvU32)~(TPS6586X_INT_BATT_INST|TPS6586X_INT_PACK_COLD_DET|TPS6586X_INT_PACK_HOT_DET); + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB2_INT_MASK3, data )) + return NV_FALSE; + + /* Mask4 */ + data = 0xFF; + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB3_INT_MASK4, data )) + return NV_FALSE; + + /* Mask5: USB Detection; AC Detection; Low System detection; */ + data = 0; + data = (NvU32) ~(TPS6586X_INT_USB_DETECTION|TPS6586X_INT_AC_DETECTION|TPS6586X_INT_LOWSYS_DETECTION); + if(! Tps6586xI2cWrite8(hDevice, TPS6586x_RB4_INT_MASK5, data )) + return NV_FALSE; + + return NV_TRUE; +} + +void Tps6586xInterruptHandler_int(NvOdmPmuDeviceHandle hDevice, + TPS6586xStatus *pmuStatus) +{ + NvU32 data = 0; + + /* INT_ACK1 */ + if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB5_INT_ACK1, &data)) + { + return; + } + pmuStatus->powerGood = (data & 0xFF); + + + /* INT_ACK2 */ + if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB6_INT_ACK2, &data)) + { + return; + } + pmuStatus->powerGood |= ((data & 0xFF)<<8); + + /* INT_ACK3 */ + /* LOW SYS */ + if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB7_INT_ACK3, &data)) + { + return; + } + if (data != 0) + { + if (data&0x40) + { + pmuStatus->highTemp = NV_TRUE; + } + if (data&0xc0) + { + pmuStatus->mChgPresent = NV_TRUE; +#if !defined(CONFIG_TEGRA_ODM_HARMONY) + NvOdmEnableOtgCircuitry(NV_TRUE); +#endif + } + } + + /* INT_ACK4 */ + /* CHG TEMP */ + if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB8_INT_ACK4, &data)) + { + return; + } + if (data != 0) + { + if (data&0x02) + { + pmuStatus->lowBatt = NV_TRUE; + } + } +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h new file mode 100644 index 000000000000..8e9ff0464135 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 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_TPS6586X_INTERRUPT_HEADER +#define INCLUDED_TPS6586X_INTERRUPT_HEADER + +#include "nvodm_pmu_tps6586x.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef struct TPS6586xStatusRef +{ + /* Low Battery voltage detected by BVM */ + NvBool lowBatt; + + /* PMU high temperature */ + NvBool highTemp; + + /* Main charger Presents */ + NvBool mChgPresent; + + /* battery Full */ + NvBool batFull; + + /* Porwer In type*/ + NvU32 powerType; /* Bit meanings: + 0: AC_DET, + 1: USB_DET, + 2: BAT_DET */ + NvU32 powerGood; /* Bit meanings: + 0-7: LDO0 to LDO7 + 10-11: LDO8 and LDO9, + 12-15: SMO0 to SM11 */ +}TPS6586xStatus; + +#if 0 +typedef struct { + NvBool pmuInterruptSupported; + NvBool pmuPresented; + NvBool battPresence; + TPS6586xStatus pmuStatus; +} TPS6586xDevice, *TPS6586xHandle; +#endif + +NvBool +Tps6586xSetupInterrupt( + NvOdmPmuDeviceHandle hDevice, + TPS6586xStatus *pmuStatus); + + + +void +Tps6586xInterruptHandler_int( + NvOdmPmuDeviceHandle hDevice, + TPS6586xStatus *pmuStatus); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_TPS6586X_INTERRUPT_HEADER diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c new file mode 100644 index 000000000000..889cf2bbc6ff --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c @@ -0,0 +1,193 @@ +/* + * Copyright (c) 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 <linux/time.h> +#include "nvodm_pmu_tps6586x_rtc.h" +#include "nvodm_pmu_tps6586x_i2c.h" +#include "tps6586x_reg.h" + +// macro OFFSET_BASE_YEAR if 1, uses epoch as reference year instead of 1970 +// This is because RTC in PMU TPS6586x can store duration of 34 years, +// else we cannot retain date beyond 2004 +#define OFFSET_BASE_YEAR 1 +#if OFFSET_BASE_YEAR +static unsigned long epoch = 2009; +static unsigned long epoch_sec = 0; +#endif + +static NvBool bRtcNotInitialized = NV_TRUE; + +/* Read RTC count register */ +NvBool +Tps6586xRtcCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + NvU32 ReadBuffer[2]; + + // 1) The I2C address pointer must not be left pointing in the range 0xC6 to 0xCA + // 2) The maximum time for the address pointer to be in this range is 1ms + // 3) Always read RTC_ALARM2 in the following order to prevent the address pointer + // from stopping at 0xC6: RTC_ALARM2_LO, then RTC_ALARM2_HI + + if (Tps6586xRtcWasStartUpFromNoPower(hDevice) && bRtcNotInitialized) + { + Tps6586xRtcCountWrite(hDevice, 0); + *Count = 0; + } + else + { + // The unit of the RTC count is second!!! 1024 tick = 1s. + // Read all 40 bit and right move 10 = Read the hightest 32bit and right move 2 + Tps6586xI2cRead32(hDevice, TPS6586x_RC6_RTC_COUNT4, &ReadBuffer[0]); + + Tps6586xI2cRead8(hDevice, TPS6586x_RCA_RTC_COUNT0, &ReadBuffer[1]); + + Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer[1]); + + // return second + *Count = ReadBuffer[0]>>2; + } +#if OFFSET_BASE_YEAR + // calculate epoch_sec once + if (!epoch_sec) + epoch_sec = mktime(epoch,1,1,0,0,0); + *Count += epoch_sec; +#endif + + return NV_TRUE; +} + +/* Write RTC count register */ + +NvBool +Tps6586xRtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + NvU32 ReadBuffer = 0; +#if OFFSET_BASE_YEAR + // calculate epoch_sec once + if (!epoch_sec) + epoch_sec = mktime(epoch,1,1,0,0,0); + if (Count < (NvU32)epoch_sec) + { + // prevent setting date earlier than 'epoch' + pr_warning("\n Date being set cannot be earlier than least " + "year=%d. Setting as least year. ", (int)epoch); + // base year seconds count is 0 + Count = 0; + } + else + Count -= (NvU32)epoch_sec; +#endif + + // Switch to 32KHz crystal oscillator + // POR_SRC_SEL=1 and OSC_SRC_SEL=1 + Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer); + ReadBuffer = ReadBuffer | 0xC0; + Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer); + + // To enable incrementing of the RTC_COUNT[39:0] from an initial value set by the host, + // the RTC_ENABLE bit should be written to 1 only after the RTC_OUT voltage reaches + // the operating range + + // Clear RTC_ENABLE before writing RTC_COUNT + Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer); + ReadBuffer = ReadBuffer & 0xDF; + Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer); + + Tps6586xI2cWrite32(hDevice, TPS6586x_RC6_RTC_COUNT4, (Count<<2)); + Tps6586xI2cWrite8(hDevice, TPS6586x_RCA_RTC_COUNT0, 0); + + // Set RTC_ENABLE after writing RTC_COUNT + Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer); + ReadBuffer = ReadBuffer | 0x20; + Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer); + + if (bRtcNotInitialized) + bRtcNotInitialized = NV_FALSE; + + return NV_TRUE; +} + +/* Read RTC alarm count register */ + +NvBool +Tps6586xRtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + return NV_FALSE; +} + +/* Write RTC alarm count register */ + +NvBool +Tps6586xRtcAlarmCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + return NV_FALSE; +} + +/* Reads RTC alarm interrupt mask status */ + +NvBool +Tps6586xRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice) +{ + return NV_FALSE; +} + +/* Enables / Disables the RTC alarm interrupt */ + +NvBool +Tps6586xRtcAlarmIntEnable( + NvOdmPmuDeviceHandle hDevice, + NvBool Enable) +{ + return NV_FALSE; +} + +/* Checks if boot was from nopower / powered state */ + +NvBool +Tps6586xRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice) +{ + NvU32 Data = 0; + + if ((Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &Data)) == NV_TRUE) + { + return ((Data & 0x20)? NV_FALSE : NV_TRUE); + } + return NV_FALSE; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h new file mode 100644 index 000000000000..8137c95e1702 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 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_TPS6586X_RTC_HEADER +#define INCLUDED_TPS6586X_RTC_HEADER + +#include "nvodm_pmu_tps6586x.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/* Read RTC count register */ + +NvBool +Tps6586xRtcCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/* Read RTC alarm count register */ + +NvBool +Tps6586xRtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/* Write RTC count register */ + +NvBool +Tps6586xRtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/* Write RTC alarm count register */ + +NvBool +Tps6586xRtcAlarmCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/* Reads RTC alarm interrupt mask status */ + +NvBool +Tps6586xRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice); + +/* Enables / Disables the RTC alarm interrupt */ + +NvBool +Tps6586xRtcAlarmIntEnable( + NvOdmPmuDeviceHandle hDevice, + NvBool Enable); + +/* Checks if boot was from nopower / powered state */ + +NvBool +Tps6586xRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice); + +#if defined(__cplusplus) +} +#endif + +#endif // INCLUDED_TPS6586X_RTC_HEADER + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h new file mode 100644 index 000000000000..fe34d3a02ca1 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 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 TPS6586x_SUPPLY_INFO_TABLE_H_ +#define TPS6586x_SUPPLY_INFO_TABLE_H_ + +#if defined(__cplusplus) +extern "C" +{ +#endif + +#define PMUGUID NV_ODM_GUID('t','p','s','6','5','8','6','x') + +#if defined(CONFIG_TEGRA_ODM_HARMONY) + +/// The total number of external supplies (which use both AP and PMU GPIOs) +#define TPS6586x_EXTERNAL_SUPPLY_NUM \ + (NvU32)(TPS6586xPmuSupply_Num - Ext_TPS62290PmuSupply_BUCK) + +/// Macro for converting a vddRail to AP GPIO pin index. +#define NVODM_EXT_AP_GPIO_RAIL(x) ((x) - Ext_TPS2051BPmuSupply_VDDIO_VID) + +/// The total number of external supplies which use AP GPIO pins for enable +#define TPS6586x_EXTERNAL_SUPPLY_AP_GPIO_NUM \ + (NvU32)NVODM_EXT_AP_GPIO_RAIL(TPS6586xPmuSupply_Num) + +#else + +/* FIXME: modify this table according to your schematics */ +#define V_CORE TPS6586xPmuSupply_DCD0 +#define V_1V8 TPS6586xPmuSupply_DCD1 +#define LCD_2V8 TPS6586xPmuSupply_LDO0 +#define V_1V2 TPS6586xPmuSupply_LDO1 +#define V_RTC TPS6586xPmuSupply_LDO2 +#define V_CAM_1V8 TPS6586xPmuSupply_LDO3 +#define V_CODEC_1V8 TPS6586xPmuSupply_LDO4 +#define V_CAM_2V8 TPS6586xPmuSupply_LDO5 +#define V_3V3 TPS6586xPmuSupply_LDO6 +#define V_SDIO TPS6586xPmuSupply_LDO7 +#define V_2V8 TPS6586xPmuSupply_LDO8 +#define V_2V5 TPS6586xPmuSupply_LDO9 +#define V_25V TPS6586xPmuSupply_WHITE_LED +#define V_CHARGE TPS6586xPmuSupply_DCD2 +#define V_MODEM V_1V8 /* Alias for V_1V8 */ +#define V_GND TPS6586xPmuSupply_Invalid +#define V_INVALID TPS6586xPmuSupply_Invalid +#define VRAILCOUNT TPS6586xPmuSupply_Num +#endif + +typedef enum +{ + TPS6586xPmuSupply_Invalid = 0x0, + + //DCD0 + TPS6586xPmuSupply_DCD0, + + //DCD1 + TPS6586xPmuSupply_DCD1, + + //DCD2 + TPS6586xPmuSupply_DCD2, + + + //LDO0 + TPS6586xPmuSupply_LDO0, + + //LDO1 + TPS6586xPmuSupply_LDO1, + + //LDO2 + TPS6586xPmuSupply_LDO2, + + //LDO3 + TPS6586xPmuSupply_LDO3, + + //LDO4 + TPS6586xPmuSupply_LDO4, + + //LDO5 + TPS6586xPmuSupply_LDO5, + + //LDO6 + TPS6586xPmuSupply_LDO6, + + //LDO7 + TPS6586xPmuSupply_LDO7, + + //LDO8 + TPS6586xPmuSupply_LDO8, + + //LDO9 + TPS6586xPmuSupply_LDO9, + + //RTC_OUT + TPS6586xPmuSupply_RTC_OUT, + + //RED1 + TPS6586xPmuSupply_RED1, + + //GREEN1 + TPS6586xPmuSupply_GREEN1, + + //BLUE1 + TPS6586xPmuSupply_BLUE1, + + //RED2 + TPS6586xPmuSupply_RED2, + + //GREEN2 + TPS6586xPmuSupply_GREEN2, + + //BLUE2 + TPS6586xPmuSupply_BLUE2, + + //LED_PWM + TPS6586xPmuSupply_LED_PWM, + + //PWM + TPS6586xPmuSupply_PWM, + + //White LED(SW3) + TPS6586xPmuSupply_WHITE_LED, +#if defined(CONFIG_TEGRA_ODM_HARMONY) + //SOC + TPS6586xPmuSupply_SoC, + + /*--- Secondary/External PMU Rails ---*/ + + // PMU GPIO-3: VDD_1V05 + Ext_TPS62290PmuSupply_BUCK, + + // PMU GPIO-2: VDD_1V2 + Ext_TPS72012PmuSupply_LDO, + + // PMU GPIO-1: VDD_1V5 + Ext_TPS74201PmuSupply_LDO, + + // AP GPIO(T,2): VDDIO_HDMI, VDDIO_VGA (5V @ 500ma) + Ext_TPS2051BPmuSupply_VDDIO_VID, + + // AP GPIO(T,3): VDDIO_SD + Ext_SWITCHPmuSupply_VDDIO_SD, + + // AP GPIO(I,6): VDDIO_SDMMC + Ext_SWITCHPmuSupply_VDDIO_SDMMC, + + // AP GPIO(W,0): VDD_BL + // FIXME: This is already supplied by nvodm_query_gpio in the display GPIO settings. + Ext_SWITCHPmuSupply_VDD_BL, + + // AP GPIO(C,6): VDD_PNL + // FIXME: This is already supplied by nvodm_query_gpio in the display GPIO settings. + Ext_SWITCHPmuSupply_VDD_PNL, +#endif + + TPS6586xPmuSupply_Num, + TPS6586xPmuSupply_Force32 = 0x7FFFFFFF +} TPS6586xPmuSupply; + +#if defined(__cplusplus) +} +#endif + +#endif /* TPS6586x_SUPPLY_INFO_TABLE_H_ */ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h new file mode 100644 index 000000000000..c22cc43854ae --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/tps6586x_reg.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 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 TPS6586X_REG_HEADER +#define TPS6586X_REG_HEADER + +#if defined(__cplusplus) +extern "C" +{ +#endif + + + +/* TPS6586x registers */ + +/* Supply Control and Voltage Settings */ +#define TPS6586x_R10_SUPPLYENA 0x10 +#define TPS6586x_R11_SUPPLYENB 0x11 +#define TPS6586x_R12_SUPPLYENC 0x12 +#define TPS6586x_R13_SUPPLYEND 0x13 +#define TPS6586x_R14_SUPPLYENE 0x14 +#define TPS6586x_R20_VCC1 0x20 +#define TPS6586x_R21_VCC2 0x21 +#define TPS6586x_R23_SM1V1 0x23 +#define TPS6586x_R24_SM1V2 0x24 +#define TPS6586x_R25_SM1SL 0x25 +#define TPS6586x_R26_SM0V1 0x26 +#define TPS6586x_R27_SM0V2 0x27 +#define TPS6586x_R28_SM0SL 0x28 +#define TPS6586x_R29_LDO2AV1 0x29 +#define TPS6586x_R2A_LDO2AV2 0x2A +#define TPS6586x_R2F_LDO2BV1 0x2F +#define TPS6586x_R30_LDO2BV2 0x30 +#define TPS6586x_R32_LDO4V1 0x32 +#define TPS6586x_R33_LDO4V2 0x33 + +/* Converter Settings */ +#define TPS6586x_R41_SUPPLYV1 0x41 +#define TPS6586x_R42_SUPPLYV2 0x42 +#define TPS6586x_R43_SUPPLYV3 0x43 +#define TPS6586x_R44_SUPPLYV4 0x44 +#define TPS6586x_R45_SUPPLYV5 0x45 +#define TPS6586x_R46_SUPPLYV6 0x46 +#define TPS6586x_R47_SMODE1 0x47 +#define TPS6586x_R48_SMODE2 0x48 + +/* Charger Setup */ +#define TPS6586x_R49_CHG1 0x49 +#define TPS6586x_R4A_CHG2 0x4A +#define TPS6586x_R4B_CHG3 0x4B + +/* Power Path Setup */ +#define TPS6586x_R4C_PPATH2 0x4C + +/* Sequencing */ +#define TPS6586x_R4D_PGFLTMSK1 0x4D +#define TPS6586x_R4E_PGFLTMSK2 0x4E + +/* Peripheral Control */ +#define TPS6586x_R50_RGB1FLASH 0x50 +#define TPS6586x_R51_RGB1RED 0x51 +#define TPS6586x_R52_RGB1GREEN 0x52 +#define TPS6586x_R53_RGB1BLUE 0x53 +#define TPS6586x_R54_RGB2RED 0x54 +#define TPS6586x_R55_RGB2GREEN 0x55 +#define TPS6586x_R56_RGB2BLUE 0x56 +#define TPS6586x_R57_SM3_SET0 0x57 +#define TPS6586x_R58_SM3_SET1 0x58 +#define TPS6586x_R59_LED_PWM 0x59 +#define TPS6586x_R5A_DIG_PWM 0x5A +#define TPS6586x_R5B_PWM 0x5B +#define TPS6586x_R5C_DIG_PWM1 0x5C +#define TPS6586x_R5D_GPIOSET1 0x5D +#define TPS6586x_R5E_GPIOSET2 0x5E + +#if defined(CONFIG_TEGRA_ODM_HARMONY) +/*-- GPIO Register Bit Shifts/Masks --*/ +// GPIO1 +#define TPS6586x_R5D_GPIOSET1_GPIO1_MODE_SHIFT 0x0 +#define TPS6586x_R5D_GPIOSET1_GPIO1_MODE_MASK 0x3 +#define TPS6586x_R5E_GPIOSET2_GPIO1_OUT_SHIFT 0x0 +#define TPS6586x_R5E_GPIOSET2_GPIO1_OUT_MASK 0x1 +#define TPS6586x_R5E_GPIOSET2_GPIO1_INV_SHIFT 0x4 +#define TPS6586x_R5E_GPIOSET2_GPIO1_INV_MASK 0x1 + +// GPIO2 +#define TPS6586x_R5D_GPIOSET1_GPIO2_MODE_SHIFT 0x2 +#define TPS6586x_R5D_GPIOSET1_GPIO2_MODE_MASK 0x3 +#define TPS6586x_R5E_GPIOSET2_GPIO2_OUT_SHIFT 0x1 +#define TPS6586x_R5E_GPIOSET2_GPIO2_OUT_MASK 0x1 +#define TPS6586x_R5E_GPIOSET2_GPIO2_INV_SHIFT 0x5 +#define TPS6586x_R5E_GPIOSET2_GPIO2_INV_MASK 0x1 + +// GPIO3 +#define TPS6586x_R5D_GPIOSET1_GPIO3_MODE_SHIFT 0x4 +#define TPS6586x_R5D_GPIOSET1_GPIO3_MODE_MASK 0x3 +#define TPS6586x_R5E_GPIOSET2_GPIO3_OUT_SHIFT 0x2 +#define TPS6586x_R5E_GPIOSET2_GPIO3_OUT_MASK 0x1 +#define TPS6586x_R5E_GPIOSET2_GPIO3_INV_SHIFT 0x6 +#define TPS6586x_R5E_GPIOSET2_GPIO3_INV_MASK 0x1 + +// GPIO4 +#define TPS6586x_R5D_GPIOSET1_GPIO4_MODE_SHIFT 0x6 +#define TPS6586x_R5D_GPIOSET1_GPIO4_MODE_MASK 0x3 +#define TPS6586x_R5E_GPIOSET2_GPIO4_OUT_SHIFT 0x3 +#define TPS6586x_R5E_GPIOSET2_GPIO4_OUT_MASK 0x1 +#define TPS6586x_R5E_GPIOSET2_GPIO4_INV_SHIFT 0x7 +#define TPS6586x_R5E_GPIOSET2_GPIO4_INV_MASK 0x1 + +#define TPS6586x_R5D_GPIO_MODE_NOT_CONFIG 0x0 +#define TPS6586x_R5D_GPIO_MODE_OUTPUT 0x1 +#define TPS6586x_R5D_GPIO_MODE_INPUT_ADC 0x2 +#define TPS6586x_R5D_GPIO_MODE_INPUT_LDO 0x3 +#endif + +/* ADC0 Engine Setup */ +#define TPS6586x_R60_ADCANLG 0x60 + /* Not finish yet */ + +/* ADC0 Engine Data */ +#define TPS6586x_R61_ADC0_SET 0x61 +#define TPS6586x_R62_ADC0_WAIT 0x62 +#define TPS6586x_R94_ADC0_SUM2 0x94 +#define TPS6586x_R95_ADC0_SUM1 0x95 +#define TPS6586x_R9A_ADC0_INT 0x9A + +/* Interrupt Control */ +#define TPS6586x_RB0_INT_MASK1 0xB0 +#define TPS6586x_RB1_INT_MASK2 0xB1 +#define TPS6586x_RB2_INT_MASK3 0xB2 +#define TPS6586x_RB3_INT_MASK4 0xB3 +#define TPS6586x_RB4_INT_MASK5 0xB4 +#define TPS6586x_RB5_INT_ACK1 0xB5 +#define TPS6586x_RB6_INT_ACK2 0xB6 +#define TPS6586x_RB7_INT_ACK3 0xB7 +#define TPS6586x_RB8_INT_ACK4 0xB8 + +/* System Status */ +#define TPS6586x_RB9_STAT1 0xB9 +#define TPS6586x_RBA_STAT2 0xBA +#define TPS6586x_RBB_STAT3 0xBB +#define TPS6586x_RBC_STAT4 0xBC + +/* RTC */ +#define TPS6586x_RC0_RTC_CTRL 0xC0 +#define TPS6586x_RC1_RTC_ALARM1_HI 0xC1 +#define TPS6586x_RC2_RTC_ALARM1_MID 0xC2 +#define TPS6586x_RC3_RTC_ALARM1_LO 0xC3 +#define TPS6586x_RC4_RTC_ALARM2_HI 0xC4 +#define TPS6586x_RC5_RTC_ALARM2_LO 0xC5 +#define TPS6586x_RC6_RTC_COUNT4 0xC6 +#define TPS6586x_RC7_RTC_COUNT3 0xC7 +#define TPS6586x_RC8_RTC_COUNT2 0xC8 +#define TPS6586x_RC9_RTC_COUNT1 0xC9 +#define TPS6586x_RCA_RTC_COUNT0 0xCA + +/* Device ID */ +#define TPS6586x_RCD_VERSIONID 0xCD + +#define TPS6586x_RFF_INVALID 0xFF + +/* RTC */ + /* Not finish yet */ + + +#if defined(__cplusplus) +} +#endif + + +#endif //TPS6586X_REG_HEADER diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile new file mode 100644 index 000000000000..d2245a6505fa --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/Makefile @@ -0,0 +1,11 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-y += tmon_hal.o +obj-y += adt7461/ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile new file mode 100644 index 000000000000..03f222cbeee4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/Makefile @@ -0,0 +1,13 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/tmon +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461 + +obj-y += nvodm_tmon_adt7461.o diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c new file mode 100644 index 000000000000..dc76869f6dec --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.c @@ -0,0 +1,934 @@ +/* + * Copyright (c) 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 "nvodm_tmon_adt7461.h" +#include "tmon_hal.h" + +// TODO: Always Disable before check-in +// Always debug module: 0=disable, 1=enable +#define NV_ADT7461_DEBUG (0) + +#if (NV_DEBUG || NV_ADT7461_DEBUG) +#define NVODM_ADT7461_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODM_ADT7461_PRINTF(x) +#endif + +#define ADT7461_ALERT_DEBOUNCE (1) + +// ADT7461 Descrriptor +static const ADT7461Info s_Adt7461Info = +{ + // TMON device conversion channels + { + // Invalid channel + {0}, + + // Local channel + { + ADT7461ChannelID_Local, + { + ADT7461_ODM_LOCAL_RATE_PROTECTED, + ADT7461_ODM_LOCAL_INTR_LIMITS_PROTECTED, + ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_PROTECTED + }, + { + ADT7461_LOCAL_INTR_LIMIT_HIGH_RD_ADDR, + ADT7461_LOCAL_INTR_LIMIT_HIGH_WR_ADDR, + }, + { + ADT7461_LOCAL_INTR_LIMIT_LOW_RD_ADDR, + ADT7461_LOCAL_INTR_LIMIT_LOW_WR_ADDR, + }, + { + ADT7461_LOCAL_COMPARATOR_LIMIT_ADDR, + ADT7461_LOCAL_COMPARATOR_LIMIT_ADDR, + }, + { + ADT7461_INVALID_ADDR, // Local offset does not exist + ADT7461_INVALID_ADDR, + }, + { + ADT7461_LOCAL_TDATA_RD_ADDR, + ADT7461_INVALID_ADDR, + }, + }, + + // Remote channel + { + ADT7461ChannelID_Remote, + { + ADT7461_ODM_REMOTE_RATE_PROTECTED, + ADT7461_ODM_REMOTE_INTR_LIMITS_PROTECTED, + ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_PROTECTED + }, + { + ADT7461_REMOTE_INTR_LIMIT_HIGH_RD_ADDR, + ADT7461_REMOTE_INTR_LIMIT_HIGH_WR_ADDR, + }, + { + ADT7461_REMOTE_INTR_LIMIT_LOW_RD_ADDR, + ADT7461_REMOTE_INTR_LIMIT_LOW_WR_ADDR, + }, + { + ADT7461_REMOTE_COMPARATOR_LIMIT_ADDR, + ADT7461_REMOTE_COMPARATOR_LIMIT_ADDR, + }, + { + ADT7461_REMOTE_TOFFSET_ADDR, + ADT7461_REMOTE_TOFFSET_ADDR, + }, + { + ADT7461_REMOTE_TDATA_RD_ADDR, + ADT7461_INVALID_ADDR, + }, + } + }, + + // TMON device common status/control registers + { + ADT7461_STATUS_RD_ADDR, + ADT7461_INVALID_ADDR, + }, + { + ADT7461_CONFIG_RD_ADDR, + ADT7461_CONFIG_WR_ADDR, + }, + { + ADT7461_RATE_RD_ADDR, + ADT7461_RATE_WR_ADDR, + }, + { + ADT7461_INVALID_ADDR, + ADT7461_ONE_SHOT_WR_ADDR, + }, + { + ADT7461_COMPARATOR_HYSTERESIS_ADDR, + ADT7461_COMPARATOR_HYSTERESIS_ADDR, + }, + { + ADT7461_INTR_CNT_DELAY_ADDR, + ADT7461_INTR_CNT_DELAY_ADDR, + }, +}; + +// ADT7461 sample intervals +static const NvS32 s_Adt7461SampleIntervalsMS[] = +{ + ADT7461_SAMPLE_INTERVALS_MS +}; + +// ADT7461 converison times +static const NvS32 s_Adt7461ConversionTimesMS[] = +{ + ADT7461_CONVERSION_TIME_MS +}; + +NV_CT_ASSERT(NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS) == + NV_ARRAY_SIZE(s_Adt7461ConversionTimesMS)); + +/*****************************************************************************/ + +#define ADT7461_T_DATA_TO_VALUE(ExtRange, data) \ + ( (ExtRange) ? \ + ((NvS32)((NvU32)(data) - ADT7461_RANGE_EXTENDED_DATA_OFFSET)) : \ + ((NvS32)((NvS8)data)) \ + ) + +#define ADT7461_T_VALUE_TO_DATA(ExtRange, val) \ + ( (ExtRange) ? \ + ((NvU8)((NvU32)(val) + ADT7461_RANGE_EXTENDED_DATA_OFFSET)) : \ + ((NvU8)(val)) \ + ) + +#define ADT7461_T_RANGE_LIMIT_HIGH(ExtRange) \ + ( (ExtRange) ? \ + ADT7461_RANGE_EXTENDED_LIMIT_HIGH : \ + ADT7461_RANGE_STANDARD_LIMIT_HIGH \ + ) + +#define ADT7461_T_RANGE_LIMIT_LOW(ExtRange) \ + ( (ExtRange) ? \ + ADT7461_RANGE_EXTENDED_LIMIT_LOW : \ + ADT7461_RANGE_STANDARD_LIMIT_LOW \ + ) + +/*****************************************************************************/ + +static NvBool +Adt7461WriteReg( + ADT7461PrivData* pPrivData, + const ADT7461RegisterInfo* pReg, + NvU8 Data) +{ + NvU32 i; + NvU8 WriteBuffer[2]; + NvOdmI2cStatus status; + NvOdmI2cTransactionInfo TransactionInfo; + + NV_ASSERT(pPrivData && pReg); + NV_ASSERT(pReg->WrAddr != ADT7461_INVALID_ADDR); + + for (i = 0; i < ADT7461_I2C_RETRY_CNT; i++) + { + WriteBuffer[0] = pReg->WrAddr; + WriteBuffer[1] = Data; + + TransactionInfo.Address = pPrivData->DeviceI2cAddr; + TransactionInfo.Buf = &WriteBuffer[0]; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + status = NvOdmI2cTransaction(pPrivData->hOdmI2C, &TransactionInfo, 1, + ADT7461_I2C_SPEED_KHZ, ADT7461_I2C_TIMEOUT_MS); + if (status == NvOdmI2cStatus_Success) + break; + } + + switch (status) + { + case NvOdmI2cStatus_Success: + pPrivData->ShadowRegPtr = pReg->WrAddr; + return NV_TRUE; + + case NvOdmI2cStatus_Timeout: + NVODM_ADT7461_PRINTF(("ADT7461: WriteReg Timeout\n")); + return NV_FALSE; + + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODM_ADT7461_PRINTF(("ADT7461: WriteReg SlaveNotFound\n")); + return NV_FALSE; + } +} + +static NvBool +Adt7461ReadReg( + ADT7461PrivData* pPrivData, + const ADT7461RegisterInfo* pReg, + NvU8* pData) +{ + NvU32 i; + NvU8 Buffer = 0; + NvOdmI2cStatus status; + NvOdmI2cTransactionInfo TransactionInfo[2]; + + NV_ASSERT(pPrivData && pReg && pData); + NV_ASSERT(pReg->RdAddr != ADT7461_INVALID_ADDR); + + // TODO: possible optimization - is shadow pointer matches register + // address, just send one read transaction (can be done only if Read/Wr + // Reg routines are serialized). + + for (i = 0; i < ADT7461_I2C_RETRY_CNT; i++) + { + Buffer = pReg->RdAddr; + + TransactionInfo[0].Address = pPrivData->DeviceI2cAddr; + TransactionInfo[0].Buf = &Buffer; + TransactionInfo[0].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[0].NumBytes = 1; + + TransactionInfo[1].Address = (pPrivData->DeviceI2cAddr | 0x1); + TransactionInfo[1].Buf = &Buffer; + TransactionInfo[1].Flags = 0; + TransactionInfo[1].NumBytes = 1; + + status = NvOdmI2cTransaction(pPrivData->hOdmI2C, &TransactionInfo[0], 2, + ADT7461_I2C_SPEED_KHZ, ADT7461_I2C_TIMEOUT_MS); + if (status == NvOdmI2cStatus_Success) + break; + } + + switch (status) + { + case NvOdmI2cStatus_Success: + pPrivData->ShadowRegPtr = pReg->RdAddr; + *pData = Buffer; + return NV_TRUE; + + case NvOdmI2cStatus_Timeout: + NVODM_ADT7461_PRINTF(("ADT7461: ReadReg Timeout\n")); + return NV_FALSE; + + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODM_ADT7461_PRINTF(("ADT7461: ReadReg SlaveNotFound\n")); + return NV_FALSE; + } +} + +static void Adt7461ReadAra(ADT7461PrivData* pPrivData) +{ + NvU32 i; + NvU8 Buffer = 0; + NvOdmI2cStatus status; + NvOdmI2cTransactionInfo TransactionInfo; + + NV_ASSERT(pPrivData); + + for (i = 0; i < ADT7461_ARA_RETRY_CNT; i++) + { + TransactionInfo.Address = (ADT7461_ARA | 0x1); + TransactionInfo.Buf = &Buffer; + TransactionInfo.Flags = 0; + TransactionInfo.NumBytes = 1; + + status = NvOdmI2cTransaction(pPrivData->hOdmI2C, &TransactionInfo, 1, + ADT7461_I2C_SPEED_KHZ, ADT7461_I2C_TIMEOUT_MS); + if ((status == NvOdmI2cStatus_SlaveNotFound) || // False alarm + ((status == NvOdmI2cStatus_Success) && + ((Buffer & 0xFE) == (NvU8)pPrivData->DeviceI2cAddr)) // Cleared ARA + ) + break; + } +} + +static NvBool +Adt7461ConfigureSampleInterval( + ADT7461PrivData* pPrivData, + NvBool OdmProtected, + NvS32* pTargetMs) +{ + NvU8 i; + NvS32 Delta; + const ADT7461RegisterInfo* pReg = &pPrivData->pDeviceInfo->Rate; + + if (OdmProtected || + ((*pTargetMs) == ODM_TMON_PARAMETER_UNSPECIFIED)) + { + // Read ADT7461 rate register (fail the call if returned data + // does not make sense) + if(!Adt7461ReadReg(pPrivData, pReg, &i)) + return NV_FALSE; + if (i >= NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS)) + return NV_FALSE; + } + else + { + // Find and set the best floor approximation of the target sample + // interval. Note the descending order of sample intervals array. + for (i = 0; i < NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS); i++) + { + Delta = (*pTargetMs) - s_Adt7461SampleIntervalsMS[i]; + if(Delta >= 0) + break; + } + if (i == NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS)) + i--; // min interval is the best we can do + + if(!Adt7461WriteReg(pPrivData, pReg, i)) + return NV_FALSE; + pPrivData->ShadowRate = i; + } + *pTargetMs = s_Adt7461SampleIntervalsMS[i]; + return NV_TRUE; +} + +/*****************************************************************************/ + +static void Adt7461Isr(void* arg) +{ + NvU8 Data; + ADT7461PrivData* pPrivData = (ADT7461PrivData*)arg; + NvOdmInterruptHandler volatile Callback = pPrivData->Callback; + void* volatile CallbackArg = pPrivData->CallbackArg; + const ADT7461RegisterInfo* pReg = NULL; + + if (Callback && CallbackArg) + { + Callback(CallbackArg); + } +#if ADT7461_ALERT_DEBOUNCE + // New range limits set by callback are not guaranteed to take effect + // before the next temperature conversion is completed, and interrupt + // can not be cleared until then. Hence, the debounce delay below. + NvOdmOsSleepMS(s_Adt7461SampleIntervalsMS[pPrivData->ShadowRate] + + s_Adt7461ConversionTimesMS[pPrivData->ShadowRate] + 1); +#endif + // Read status and ARA to finish clearing interrupt after callback + pReg = &pPrivData->pDeviceInfo->Status; + (void)Adt7461ReadReg(pPrivData, pReg, &Data); + Adt7461ReadAra(pPrivData); + + // Re-enable interrupt + if (pPrivData->hGpioIntr) + NvOdmGpioInterruptDone(pPrivData->hGpioIntr); +} + +static void Adt7461FreePrivData(ADT7461PrivData* pPrivData) +{ + if (pPrivData) + { + if (pPrivData->hGpioIntr) + { + NvOdmGpioInterruptUnregister( + pPrivData->hGpio, pPrivData->hGpioPin, pPrivData->hGpioIntr); + } + NvOdmI2cClose(pPrivData->hOdmI2C); + NvOdmGpioReleasePinHandle(pPrivData->hGpio, pPrivData->hGpioPin); + NvOdmGpioClose(pPrivData->hGpio); + NvOdmServicesPmuClose(pPrivData->hOdmPmuSevice); + NvOdmOsFree(pPrivData); + } +} + +/*****************************************************************************/ + +NvBool Adt7461Init(NvOdmTmonDeviceHandle hTmon) +{ + NvU8 Data; + NvBool ExtRange; + NvU32 i = 0; + NvU32 I2cInstance = 0; + NvOdmIoModule I2cModule = NvOdmIoModule_Num; // Inavlid module + const ADT7461RegisterInfo* pReg = NULL; + ADT7461PrivData* pPrivData = NULL; + + NV_ASSERT(hTmon && hTmon->pConn && hTmon->pConn->AddressList); + + // Allocate and clear priavte data + pPrivData = (ADT7461PrivData*) NvOdmOsAlloc(sizeof(ADT7461PrivData)); + if (pPrivData == NULL) + { + NVODM_ADT7461_PRINTF(("ADT7461: Error Allocating PrivData. \n")); + return NV_FALSE; + } + NvOdmOsMemset(pPrivData, 0, sizeof(ADT7461PrivData)); + hTmon->pPrivate = pPrivData; + + // Register for PMU services + pPrivData->hOdmPmuSevice = NvOdmServicesPmuOpen(); + if (pPrivData->hOdmPmuSevice == NULL) + { + NVODM_ADT7461_PRINTF(("ADT7461: Error Open PMU service. \n")); + goto fail; + } + + // Register for GPIO services + pPrivData->hGpio = NvOdmGpioOpen(); + if (pPrivData->hOdmPmuSevice == NULL) + { + NVODM_ADT7461_PRINTF(("ADT7461: Error Open GPIO service. \n")); + goto fail; + } + + /* + * Parse connectivity data: turn On power to the device, acquire I2C + * interface and GPIO interrupt (optional); map device channels to + * thermal zones + */ + for (i = 0; i < hTmon->pConn->NumAddress; i ++) + { + const NvOdmIoAddress* pIoAddress = &hTmon->pConn->AddressList[i]; + if (pIoAddress->Interface == NvOdmIoModule_I2c_Pmu) + { + I2cModule = NvOdmIoModule_I2c_Pmu; + I2cInstance = pIoAddress->Instance; + NV_ASSERT(pIoAddress->Address != 0); + pPrivData->DeviceI2cAddr = pIoAddress->Address; + } + else if (pIoAddress->Interface == NvOdmIoModule_Tsense) + { + NV_ASSERT(pIoAddress->Instance < NvOdmTmonZoneID_Num); + NV_ASSERT(pIoAddress->Address < ADT7461ChannelID_Num); + pPrivData->ConnectivityMap[pIoAddress->Instance] = + pIoAddress->Address; + } + else if (pIoAddress->Interface == NvOdmIoModule_Vdd) + { + NvU32 usec = 0; + NvU32 RailAddress = pIoAddress->Address; + NvOdmServicesPmuVddRailCapabilities RailCapabilities = {0}; + NvOdmServicesPmuGetCapabilities( + pPrivData->hOdmPmuSevice, RailAddress, &RailCapabilities); + NvOdmServicesPmuSetVoltage(pPrivData->hOdmPmuSevice, RailAddress, + RailCapabilities.requestMilliVolts, &usec); + NvOdmOsWaitUS(usec + (ADT7461_POWERUP_DELAY_MS * 1000)); + } + else if (pIoAddress->Interface == NvOdmIoModule_Gpio) + { + NvU32 port = pIoAddress->Instance; + NvU32 pin = pIoAddress->Address; + pPrivData->hGpioPin = NvOdmGpioAcquirePinHandle( + pPrivData->hGpio, port, pin); + } + + } + NV_ASSERT(I2cModule == NvOdmIoModule_I2c_Pmu); + pPrivData->hOdmI2C = NvOdmI2cOpen(I2cModule, I2cInstance); + if (pPrivData->hOdmI2C == NULL) + { + NVODM_ADT7461_PRINTF(("ADT7461: Error Open I2C device. \n")); + goto fail; + } + + /* + * Initialize device info and configuration. Force standby mode to avoid + * glitch on shutdown comparator output when temperature range and/or + * comparator limit is changing during initialization. The Adt7461Run() + * call from the hal that follows initialization will switch device to + * run mode and re-start temperature monitoring (note that out of limit + * interrupt is always masked during and after initialization) + */ + pPrivData->pDeviceInfo = &s_Adt7461Info; + pPrivData->ShadowRegPtr = ADT7461_INVALID_ADDR; + + pReg = &pPrivData->pDeviceInfo->Config; + if (!Adt7461ReadReg(pPrivData, pReg, &Data)) + goto fail; + if ((Data & ADT7461ConfigBits_ExtendedRange) != + (ADT7461_INITIAL_CONFIG & ADT7461ConfigBits_ExtendedRange)) + { + // Only switch from standard to extended range is supported + NV_ASSERT((Data & ADT7461ConfigBits_ExtendedRange) == 0); + Data |= ADT7461ConfigBits_Standby; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + } + Data = ADT7461_INITIAL_CONFIG | ADT7461ConfigBits_Standby; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + pPrivData->ShadowConfig = Data; + ExtRange = ((Data & ADT7461ConfigBits_ExtendedRange) != 0); + + // Program shutdown comparators settings + Data = ADT7461_T_VALUE_TO_DATA( + ExtRange, ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_VALUE); + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Local].ComparatorLimit; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + + Data = ADT7461_T_VALUE_TO_DATA( + ExtRange, ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_VALUE); + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Remote].ComparatorLimit; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + + // Set interrupt limits to the range boundaries to prevent out of limit + // interrupt + Data = ADT7461_T_VALUE_TO_DATA( + ExtRange, ADT7461_T_RANGE_LIMIT_HIGH(ExtRange)); + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Local].IntrLimitHigh; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Remote].IntrLimitHigh; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + + Data = ADT7461_T_VALUE_TO_DATA( + ExtRange, ADT7461_T_RANGE_LIMIT_LOW(ExtRange)); + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Local].IntrLimitLow; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Remote].IntrLimitLow; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + + // Set initial rate + Data = ADT7461_INITIAL_RATE_SETTING; + pReg = &pPrivData->pDeviceInfo->Rate; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + pPrivData->ShadowRate = Data; + + // Set remote channel offset (8-bit 2's complement value for any range) + Data = ((NvU8)ADT7461_ODM_REMOTE_OFFSET_VALUE); + pReg = &pPrivData->pDeviceInfo->Channels[ + ADT7461ChannelID_Remote].Toffset; + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + goto fail; + + // Read ADT7461 status and ARA (clear pending Alert interrupt, if any) + pReg = &pPrivData->pDeviceInfo->Status; + if (!Adt7461ReadReg(pPrivData, pReg, &Data)) + goto fail; + // TODO: check open remote circuit error + + Adt7461ReadAra(pPrivData); + return NV_TRUE; + +fail: + Adt7461FreePrivData(pPrivData); + hTmon->pPrivate = NULL; + return NV_FALSE; +} + +void Adt7461Deinit(NvOdmTmonDeviceHandle hTmon) +{ + if (hTmon && hTmon->pPrivate) + { + ADT7461PrivData* pPrivData = hTmon->pPrivate; + (void)Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, + ADT7461_INITIAL_CONFIG); //leave device in default configuration + // with power rail ON (forever) + Adt7461FreePrivData(pPrivData); + hTmon->pPrivate = NULL; + } +} + +/*****************************************************************************/ + +NvBool Adt7461Run(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId) +{ + NvU8 Data; + NvBool IsRunning; + ADT7461PrivData* pPrivData; + + NV_ASSERT(hTmon && hTmon->pPrivate); + pPrivData = hTmon->pPrivate; + IsRunning = (pPrivData->ShadowConfig & ADT7461ConfigBits_Standby) == 0; + + if (!IsRunning) + { + Data = pPrivData->ShadowConfig & (~ADT7461ConfigBits_Standby); + if(!Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data)) + return NV_FALSE; + pPrivData->ShadowConfig = Data; + } + pPrivData->RunRefCount++; + return NV_TRUE; +} + +NvBool Adt7461Stop(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId) +{ + NvU8 Data; + NvBool IsRunning; + ADT7461PrivData* pPrivData; + + NV_ASSERT(hTmon && hTmon->pPrivate); + pPrivData = hTmon->pPrivate; + IsRunning = (pPrivData->ShadowConfig & ADT7461ConfigBits_Standby) == 0; + + if (ADT7461_ODM_STANDBY_ENABLED && + IsRunning && (pPrivData->RunRefCount == 1)) + { + Data = pPrivData->ShadowConfig | ADT7461ConfigBits_Standby; + if(!Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data)) + return NV_FALSE; + pPrivData->ShadowConfig = Data; + } + if (pPrivData->RunRefCount != 0) + { + pPrivData->RunRefCount--; + return NV_TRUE; + } + NV_ASSERT(!"RunRefCount balance failed"); + NVODM_ADT7461_PRINTF(("ADT7461: RunRefCount balance failed. \n")); + return NV_FALSE; +} + +/*****************************************************************************/ +// ADT7461 aborts and restarts conversion cycle when temperature is read +// (actually on any I2C access for that matter, but other accesses are rare). +// TODO: add time stamps and implement refresh policy to make sure that +// frequent temperature reads would not stall the conversion forever. + +NvBool +Adt7461TemperatureGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvS32* pDegreesC) +{ + NvU8 Data; + NvBool ExtRange; + ADT7461ChannelID ChannelId; + ADT7461PrivData* pPrivData; + const ADT7461RegisterInfo* pReg; + + NV_ASSERT(hTmon && hTmon->pPrivate && pDegreesC); + pPrivData = hTmon->pPrivate; + ExtRange = ((pPrivData->ShadowConfig & + ADT7461ConfigBits_ExtendedRange) != 0); + ChannelId = pPrivData->ConnectivityMap[ZoneId]; + pReg = &pPrivData->pDeviceInfo->Channels[ChannelId].Tdata; + + if(!Adt7461ReadReg(pPrivData, pReg, &Data)) + return NV_FALSE; + + *pDegreesC = ADT7461_T_DATA_TO_VALUE(ExtRange, Data); + return NV_TRUE; +} + +/*****************************************************************************/ + +void +Adt7461CapabilitiesGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonCapabilities* pCaps) +{ + NvBool ExtRange; + ADT7461PrivData* pPrivData; + + NV_ASSERT(hTmon && hTmon->pPrivate && pCaps); + pPrivData = hTmon->pPrivate; + ExtRange = ((pPrivData->ShadowConfig & + ADT7461ConfigBits_ExtendedRange) != 0); + + pCaps->Tmax = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); + pCaps->Tmin = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); + pCaps->IntrSupported = NV_TRUE; + pCaps->HwCriticalSupported = NV_TRUE; + pCaps->HwCoolingSupported = NV_FALSE; +} + +void +Adt7461ParameterCapsGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonConfigParam ParamId, + NvOdmTmonParameterCaps* pCaps) +{ + NvBool ExtRange; + ADT7461PrivData* pPrivData; + const ADT7461ChannelInfo* pChannel; + + NV_ASSERT(hTmon && hTmon->pPrivate && pCaps); + pPrivData = hTmon->pPrivate; + ExtRange = ((pPrivData->ShadowConfig & + ADT7461ConfigBits_ExtendedRange) != 0); + pChannel = &pPrivData->pDeviceInfo->Channels[( + pPrivData->ConnectivityMap[ZoneId])]; + + switch (ParamId) + { + case NvOdmTmonConfigParam_IntrLimitHigh: + case NvOdmTmonConfigParam_IntrLimitLow: + pCaps->OdmProtected = + pChannel->ChannelPolicy.IntrLimitsOdmProtected; + break; + + case NvOdmTmonConfigParam_HwLimitCrit: + pCaps->OdmProtected = + pChannel->ChannelPolicy.HwLimitCritOdmProtected; + break; + + case NvOdmTmonConfigParam_SampleMs: + // smaple intervals in descending order + pCaps->MaxValue = s_Adt7461SampleIntervalsMS[0]; + pCaps->MinValue = s_Adt7461SampleIntervalsMS[( + NV_ARRAY_SIZE(s_Adt7461SampleIntervalsMS) - 1)]; + pCaps->OdmProtected = pChannel->ChannelPolicy.RateOdmProtected; + return; + + default: // unsupported parameter + pCaps->MaxValue = ODM_TMON_PARAMETER_UNSPECIFIED; + pCaps->MinValue = ODM_TMON_PARAMETER_UNSPECIFIED; + pCaps->OdmProtected = NV_TRUE; + return; + } + + // Common range for limits + pCaps->MaxValue = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); + pCaps->MinValue = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); +} + +NvBool +Adt7461ParameterConfig( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonConfigParam ParamId, + NvS32* pSetting) +{ + NvU8 Data; + NvBool ExtRange, OdmProtected; + ADT7461PrivData* pPrivData; + const ADT7461RegisterInfo* pReg; + const ADT7461ChannelInfo* pChannel; + + NV_ASSERT(hTmon && hTmon->pPrivate && pSetting); + pPrivData = hTmon->pPrivate; + ExtRange = ((pPrivData->ShadowConfig & + ADT7461ConfigBits_ExtendedRange) != 0); + pChannel = &pPrivData->pDeviceInfo->Channels[( + pPrivData->ConnectivityMap[ZoneId])]; + + switch (ParamId) + { + case NvOdmTmonConfigParam_IntrLimitHigh: + pReg = &pChannel->IntrLimitHigh; + OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected; + break; + + case NvOdmTmonConfigParam_IntrLimitLow: + pReg = &pChannel->IntrLimitLow; + OdmProtected = pChannel->ChannelPolicy.IntrLimitsOdmProtected; + break; + + case NvOdmTmonConfigParam_HwLimitCrit: + pReg = &pChannel->ComparatorLimit; + OdmProtected = pChannel->ChannelPolicy.HwLimitCritOdmProtected; + break; + + case NvOdmTmonConfigParam_SampleMs: + OdmProtected = pChannel->ChannelPolicy.RateOdmProtected; + return Adt7461ConfigureSampleInterval( + pPrivData, OdmProtected, pSetting); + + default: // unsupported parameter + *pSetting = ODM_TMON_PARAMETER_UNSPECIFIED; + return NV_TRUE; + } + + // Common processing for temperature limits configuration + if ((OdmProtected) || + ((*pSetting) == ODM_TMON_PARAMETER_UNSPECIFIED)) + { + // Read ADT7461 register and convert data to current parameter value + if(!Adt7461ReadReg(pPrivData, pReg, &Data)) + return NV_FALSE; + + *pSetting = ADT7461_T_DATA_TO_VALUE(ExtRange, Data); + } + else + { + // Clip target setting to temperature range + if ((*pSetting) > ADT7461_T_RANGE_LIMIT_HIGH(ExtRange)) + *pSetting = ADT7461_T_RANGE_LIMIT_HIGH(ExtRange); + else if ((*pSetting) < ADT7461_T_RANGE_LIMIT_LOW(ExtRange)) + *pSetting = ADT7461_T_RANGE_LIMIT_LOW(ExtRange); + + // Convert new configuration setting and write to ADT7461 register + Data = ADT7461_T_VALUE_TO_DATA(ExtRange, *pSetting); + if(!Adt7461WriteReg(pPrivData, pReg, Data)) + return NV_FALSE; + } + return NV_TRUE; +} + +/*****************************************************************************/ + +NvOdmTmonIntrHandle +Adt7461IntrRegister( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmInterruptHandler Callback, + void* CallbackArg) +{ + NvU8 Data; + ADT7461PrivData* pPrivData; + const ADT7461ChannelInfo* pChannel; + NvOdmServicesGpioIntrHandle hGpioIntr = NULL; + + NV_ASSERT(hTmon && hTmon->pPrivate && Callback && CallbackArg); + pPrivData = hTmon->pPrivate; + + // No registration, if no GPIO pin available or interrupt already registred + if (!pPrivData->hGpioPin || pPrivData->hGpioIntr) + return NULL; + + // No registration for other than remote channel + pChannel = &pPrivData->pDeviceInfo->Channels[( + pPrivData->ConnectivityMap[ZoneId])]; + if (pChannel->ChannelId != ADT7461ChannelID_Remote) + return NULL; + + // Register GPIO interrupt (will be enabled at SoC IC, but still disabled + // at ADT7461 device) + pPrivData->Callback = Callback; + pPrivData->CallbackArg = CallbackArg; + if (!NvOdmGpioInterruptRegister( + pPrivData->hGpio, &hGpioIntr, pPrivData->hGpioPin, + ADT7461_ODM_INTR_POLARITY, Adt7461Isr, (void *)pPrivData, 0)) + { + pPrivData->Callback = NULL; + pPrivData->CallbackArg = NULL; + return NULL; + } + NV_ASSERT(hGpioIntr); + pPrivData->hGpioIntr = hGpioIntr; + + // Finally enable ADT7461 device interrupt output (interrupt may or may + // not be generated depending on temperature and limt settings). + Data = pPrivData->ShadowConfig & (~ADT7461ConfigBits_IntrDisabled); + if(!Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data)) + { + NvOdmGpioInterruptUnregister( + pPrivData->hGpio, pPrivData->hGpioPin, hGpioIntr); + pPrivData->Callback = NULL; + pPrivData->CallbackArg = NULL; + pPrivData->hGpioIntr = NULL; + return NULL; + } + pPrivData->ShadowConfig = Data; + + return (NvOdmTmonIntrHandle)hGpioIntr; +} + +void +Adt7461IntrUnregister( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonIntrHandle hIntr) +{ + NvU8 Data; + ADT7461PrivData* pPrivData; + const ADT7461ChannelInfo* pChannel; + + // Ignore invalid handles + if(!hIntr || !hTmon || !hTmon->pPrivate) + return; + + pPrivData = hTmon->pPrivate; + if (hIntr != ((NvOdmTmonIntrHandle)pPrivData->hGpioIntr)) + return; + + // Ignore any channel other than remote + pChannel = &pPrivData->pDeviceInfo->Channels[( + pPrivData->ConnectivityMap[ZoneId])]; + if (pChannel->ChannelId != ADT7461ChannelID_Remote) + return; + + // Disable ADT7461 interrupt output + Data = pPrivData->ShadowConfig | ADT7461ConfigBits_IntrDisabled; + if(Adt7461WriteReg(pPrivData, &pPrivData->pDeviceInfo->Config, Data)) + pPrivData->ShadowConfig = Data; + + // Unregister GPIO interrupt, clear callbacks and handle + NvOdmGpioInterruptUnregister( + pPrivData->hGpio, pPrivData->hGpioPin, pPrivData->hGpioIntr); + + pPrivData->Callback = NULL; + pPrivData->CallbackArg = NULL; + pPrivData->hGpioIntr = NULL; +} + +/*****************************************************************************/ + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h new file mode 100644 index 000000000000..ffe4bf15dbec --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 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_NVODM_TMON_ADT7461_H +#define INCLUDED_NVODM_TMON_ADT7461_H + +#include "nvodm_tmon.h" +#include "nvodm_tmon_adt7461_reg.h" +#include "nvodm_tmon_adt7461_channel.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef struct ADT7461RegisterInfoRec +{ + NvU8 RdAddr; // Invalid if WO + NvU8 WrAddr; // Invalid if RO +} ADT7461RegisterInfo; + +typedef struct ADT7461ChannelOdmPolicyRec +{ + NvBool RateOdmProtected; + NvBool IntrLimitsOdmProtected; + NvBool HwLimitCritOdmProtected; +} ADT7461ChannelOdmPolicy; + +typedef struct ADT7461ChannelInfoRec +{ + // TMON device conversion channel ID + ADT7461ChannelID ChannelId; + + // ODM channel policy + ADT7461ChannelOdmPolicy ChannelPolicy; + + // Alert Interrupt limits registers + ADT7461RegisterInfo IntrLimitHigh; + ADT7461RegisterInfo IntrLimitLow; + + // Thermal comparator limit register + ADT7461RegisterInfo ComparatorLimit; + + // Temperature measurement offset + ADT7461RegisterInfo Toffset; + + // Temperature Data register + ADT7461RegisterInfo Tdata; +} ADT7461ChannelInfo; + +typedef struct ADT7461InfoRec +{ + // TMON device conversion channels + ADT7461ChannelInfo Channels[ADT7461ChannelID_Num]; + + // Chip status register + ADT7461RegisterInfo Status; + + // Common configration controls + ADT7461RegisterInfo Config; + + // Common conversion rate + ADT7461RegisterInfo Rate; + + // One-shot trigger register + ADT7461RegisterInfo OneShot; + + // Common comparator hysteresis + ADT7461RegisterInfo ComparatorHysteresis; + + // Number of consecutive limit violation before + // interrupt is generated + ADT7461RegisterInfo IntrCntDelay; +} ADT7461Info; + +typedef struct ADT7461PrivDataRec +{ + // ADT7461 device registers descriptors + const ADT7461Info* pDeviceInfo; + + // ADT7461 I2C device Address + NvU32 DeviceI2cAddr; + + // The handle to the I2C controller + NvOdmServicesI2cHandle hOdmI2C; + + // The odm pmu service handle + NvOdmServicesPmuHandle hOdmPmuSevice; + + // Zone => Channel map + ADT7461ChannelID ConnectivityMap[NvOdmTmonZoneID_Num]; + + // ADR7461 run mode reference count + NvU32 RunRefCount; + + // Shadow of ADT7461 internal configuration register + NvU8 ShadowConfig; + + // Shadow of ADT7461 internal rate settings + NvU8 ShadowRate; + + // Shadow of ADT7461 internal address pointer + NvU8 ShadowRegPtr; + + // The odm GPIO service handle + NvOdmServicesGpioHandle hGpio; + + // SoC GPIO dedicated for ADT7461 out of limit interrupt + NvOdmGpioPinHandle hGpioPin; + + // The ADT7461 interrupt handle + NvOdmServicesGpioIntrHandle hGpioIntr; + + // The ADT7461 interrupt callback + NvOdmInterruptHandler Callback; + + // The ADT7461 interrupt callback context + void* CallbackArg; +} ADT7461PrivData; + +NvBool Adt7461Init(NvOdmTmonDeviceHandle hTmon); +void Adt7461Deinit(NvOdmTmonDeviceHandle hTmon); +NvBool Adt7461Run(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId); +NvBool Adt7461Stop(NvOdmTmonDeviceHandle hTmon, NvOdmTmonZoneID ZoneId); + +NvBool +Adt7461TemperatureGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvS32* pDegreesC); + +void +Adt7461CapabilitiesGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonCapabilities* pCaps); + +void +Adt7461ParameterCapsGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonConfigParam ParamId, + NvOdmTmonParameterCaps* pCaps); + +NvBool +Adt7461ParameterConfig( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonConfigParam ParamId, + NvS32* pSetting); + +NvOdmTmonIntrHandle +Adt7461IntrRegister( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmInterruptHandler Callback, + void* arg); + +void +Adt7461IntrUnregister( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonZoneID ZoneId, + NvOdmTmonIntrHandle hIntr); + +#if defined(__cplusplus) +} +#endif + +#endif //INCLUDED_NVODM_TMON_ADT7461_H + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h new file mode 100644 index 000000000000..8d9f9bb22d95 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_channel.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 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_NVODM_TMON_ADT7461_CHANNEL_H +#define INCLUDED_NVODM_TMON_ADT7461_CHANNEL_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef enum +{ + // Local sensor + ADT7461ChannelID_Local = 1, + + // Remote sensor + ADT7461ChannelID_Remote, + + ADT7461ChannelID_Num, + ADT7461ChannelID_Force32 = 0x7FFFFFFFUL +} ADT7461ChannelID; + +#if defined(__cplusplus) +} +#endif + +#endif //INCLUDED_NVODM_TMON_ADT7461_CHANNEL_H + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h new file mode 100644 index 000000000000..e0e930e79fe7 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/adt7461/nvodm_tmon_adt7461_reg.h @@ -0,0 +1,203 @@ +/* + * Copyright (c) 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_NVODM_TMON_ADT7461_REG_H +#define INCLUDED_NVODM_TMON_ADT7461_REG_H + +#include "nvodm_tmon_adt7461.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +// ODM policy: use ADT7461 extended=1 (standard=0) range +#define ADT7461_ODM_EXTENDED_RANGE (1) + +// ODM policy: enable=1 (disable=0) ADT7461 standby mode +#define ADT7461_ODM_STANDBY_ENABLED (0) + +// ODM policy: protect=1 (not=0) thermal limits from being overwritten by API +#define ADT7461_ODM_LOCAL_INTR_LIMITS_PROTECTED (1) +#define ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_PROTECTED (1) + +#define ADT7461_ODM_REMOTE_INTR_LIMITS_PROTECTED (0) +#define ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_PROTECTED (1) + +// ODM policy: protect=1 (not=0) sample rate from being overwritten by API +#define ADT7461_ODM_LOCAL_RATE_PROTECTED (1) +#define ADT7461_ODM_REMOTE_RATE_PROTECTED (0) + +// ODM policy: comparator limit values for critical shutdown (in degrees C) +#define ADT7461_ODM_LOCAL_COMPARATOR_LIMIT_VALUE (120L) +#define ADT7461_ODM_REMOTE_COMPARATOR_LIMIT_VALUE (115L) + +// ODM ADT7461 remote channel measurement offset +#define ADT7461_ODM_REMOTE_OFFSET_VALUE (6L) + +// ODM ADT7461 interrupt polarity +#define ADT7461_ODM_INTR_POLARITY (NvOdmGpioPinMode_InputInterruptLow) + +// ADT7461 Register POR settings +#define ADT7461_LOCAL_TDATA_POR (0x00) +#define ADT7461_REMOTE_TDATA_POR (0x00) +// #define ADT7461_STATUS_POR unknown +#define ADT7461_CONFIG_POR (0x00) +#define ADT7461_RATE_POR (0x08) +#define ADT7461_LOCAL_INTR_LIMIT_HIGH_POR (0x55) +#define ADT7461_LOCAL_INTR_LIMIT_LOW_POR (0x00) +#define ADT7461_REMOTE_INTR_LIMIT_HIGH_POR (0x55) +#define ADT7461_REMOTE_INTR_LIMIT_LOW_POR (0x00) +// #define ADT7461_ONE_SHOT_POR unknown +#define ADT7461_REMOTE_TDATA_FRACTION_POR (0x00) +#define ADT7461_REMOTE_TOFFSET_POR (0x00) +#define ADT7461_REMOTE_TOFFSET_FRACTION_POR (0x00) +#define ADT7461_REMOTE_INTR_LIMIT_HIGH_FRACTION_POR (0x00) +#define ADT7461_REMOTE_INTR_LIMIT_LOW_FRACTION_POR (0x00) +#define ADT7461_REMOTE_COMPARATOR_LIMIT_POR (0x55) +#define ADT7461_LOCAL_COMPARATOR_LIMIT_POR (0x55) +#define ADT7461_COMPARATOR_HYSTERESIS_POR (0x0A) +#define ADT7461_INTR_CNT_DELAY_POR (0x01) +#define ADT7461_CHIP_ID_POR (0x41) +#define ADT7461_CHIP_REV_POR (0x51) + + +// ADT7461 Register Addresses +#define ADT7461_LOCAL_TDATA_RD_ADDR (0x00) +#define ADT7461_REMOTE_TDATA_RD_ADDR (0x01) + +#define ADT7461_STATUS_RD_ADDR (0x02) +#define ADT7461_CONFIG_RD_ADDR (0x03) +#define ADT7461_CONFIG_WR_ADDR (0x09) +#define ADT7461_RATE_RD_ADDR (0x04) +#define ADT7461_RATE_WR_ADDR (0x0A) + +#define ADT7461_LOCAL_INTR_LIMIT_HIGH_RD_ADDR (0x05) +#define ADT7461_LOCAL_INTR_LIMIT_HIGH_WR_ADDR (0x0B) +#define ADT7461_LOCAL_INTR_LIMIT_LOW_RD_ADDR (0x06) +#define ADT7461_LOCAL_INTR_LIMIT_LOW_WR_ADDR (0x0C) + +#define ADT7461_REMOTE_INTR_LIMIT_HIGH_RD_ADDR (0x07) +#define ADT7461_REMOTE_INTR_LIMIT_HIGH_WR_ADDR (0x0D) +#define ADT7461_REMOTE_INTR_LIMIT_LOW_RD_ADDR (0x08) +#define ADT7461_REMOTE_INTR_LIMIT_LOW_WR_ADDR (0x0E) + +#define ADT7461_ONE_SHOT_WR_ADDR (0x0F) + +#define ADT7461_REMOTE_TDATA_FRACTION_RD_ADDR (0x10) +#define ADT7461_REMOTE_TOFFSET_ADDR (0x11) +#define ADT7461_REMOTE_TOFFSET_FRACTION_ADDR (0x12) +#define ADT7461_REMOTE_INTR_LIMIT_HIGH_FRACTION_ADDR (0x13) +#define ADT7461_REMOTE_INTR_LIMIT_LOW_FRACTION_ADDR (0x14) + +#define ADT7461_REMOTE_COMPARATOR_LIMIT_ADDR (0x19) +#define ADT7461_LOCAL_COMPARATOR_LIMIT_ADDR (0x20) +#define ADT7461_COMPARATOR_HYSTERESIS_ADDR (0x21) + +#define ADT7461_INTR_CNT_DELAY_ADDR (0x22) +#define ADT7461_CHIP_ID_RD_ADDR (0xFE) +#define ADT7461_CHIP_REV_RD_ADDR (0xFF) + +#define ADT7461_INVALID_ADDR (0xF0) + + +// ADT7461 conversion range (signed values) +#define ADT7461_RANGE_STANDARD_LIMIT_HIGH (127L) +#define ADT7461_RANGE_STANDARD_LIMIT_LOW (0L) +#define ADT7461_RANGE_EXTENDED_LIMIT_HIGH (150L) +#define ADT7461_RANGE_EXTENDED_LIMIT_LOW (-64L) + +// ADT7461 data reading offsets (unsigned data) +#define ADT7461_RANGE_STANDARD_DATA_OFFSET (0UL) +#define ADT7461_RANGE_EXTENDED_DATA_OFFSET (64UL) + + +// ADT7461 Configuration Register bitfields +typedef enum +{ + // If set - extended temperature range (-55C to 150C); data offset 64C + // If cleared - stnadard temperature range (0C to 127C); data offset 0 + ADT7461ConfigBits_ExtendedRange = (0x1 << 2), + + // If set - interrupt output works as second auto cleared comparator + // If cleared - interrupt output works as level out of limit interrupt, + // cleared by (a) reading status and (b) alert response protocol over I2C + ADT7461ConfigBits_IntrAutoClear = (0x1 << 5), + + // If set - put device in stanby mode + // If cleared - put device in running mode + ADT7461ConfigBits_Standby = (0x1 << 6), + + // If set - interrupt from device is disabled + // If cleared - interrupt from device is enabled + ADT7461ConfigBits_IntrDisabled = (0x1 << 7), +} ADT7461ConfigBits; + +// ADT7461 initial configuration set by adaptation: +// ADT7461 THERM1 output is dedicated for critical h/w shutdown, and ADT7461 +// ALERT/THERM2 output is always configured as out of limit ALERT interrupt. +// Monitor is in running mode, in the range selected per ODM policy. +#define ADT7461_INITIAL_CONFIG \ + ((ADT7461ConfigBits_IntrDisabled) | \ + (ADT7461_ODM_EXTENDED_RANGE ? ADT7461ConfigBits_ExtendedRange : 0)) + + +// ADT7461 sample intervals and conversion time limits rounded to the nearest +// milliseconds, in descending order indexed by rate register DATA settings + +// RATE: 1/16 1/8 1/4 1/2 1 2 4 8 16 32 64 (1/s) +// DATA: 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 0x09 0x0A +#define ADT7461_SAMPLE_INTERVALS_MS \ + 16000, 8000, 4000, 2000, 1000, 500, 250, 125, 63, 31, 16 +#define ADT7461_CONVERSION_TIME_MS \ + 115, 115, 115, 115, 115, 115, 115, 115, 13, 13, 13 + +#define ADT7461_INITIAL_RATE_SETTING (0x0A) + + +// ADT7461 I2C (SMBus) clock speed, bus timeout, retries, and fixed +// Alert Response Address (ARA). +#define ADT7461_I2C_SPEED_KHZ (400) +#define ADT7461_I2C_TIMEOUT_MS (500) +#define ADT7461_I2C_RETRY_CNT (2) +#define ADT7461_ARA_RETRY_CNT (4) +#define ADT7461_ARA (0x18) + +// ADT7461 power up delay (TODO: get spec for delay from vendor) +#define ADT7461_POWERUP_DELAY_MS (5) + +#if defined(__cplusplus) +} +#endif + +#endif //INCLUDED_NVODM_TMON_ADT7461_REG_H + diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c new file mode 100644 index 000000000000..acabf8492c35 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.c @@ -0,0 +1,304 @@ +/* + * Copyright (c) 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 "tmon_hal.h" +#include "adt7461/nvodm_tmon_adt7461.h" + +/* + * TMON adaptation is a singleton linked directly with NVRM only. + * Thread safety for TMON APIs is provided by NVRM as well. + */ + + +// Temperature Monitors suported under hal +#define TMON_ADT7461_ID (NV_ODM_GUID('a','d','t','7','4','6','1',' ')) + +#define TMON_ZONE_PSEUDOHANDLE(h, z) \ + ( (NvOdmTmonDeviceHandle)((((NvU32)(h)) << 16) | (z)) ) +#define TMON_PSEUDOHANDLE_ZONE(h) ( ((NvU32)(h)) & 0xFFFF ) + +/*****************************************************************************/ + +static NvOdmTmonDevice* +TmonGetInstance(NvOdmTmonZoneID ZoneId) +{ + static NvOdmTmonDevice s_TmonArray[NvOdmTmonZoneID_Num]; + static NvOdmTmonDevice* s_TmonMap[NvOdmTmonZoneID_Num]; + static NvBool s_Initialized = NV_FALSE; + + NvU32 i, j; + NvOdmTmonDevice* pTmon = NULL; + const NvOdmPeripheralConnectivity* pConn = NULL; + + // Check for invalid zone + if (ZoneId == 0) + return NULL; + + if (!s_Initialized) + { + NvOdmOsMemset(s_TmonArray, 0, sizeof(s_TmonArray)); + NvOdmOsMemset(s_TmonMap, 0, sizeof(s_TmonMap)); + s_Initialized = NV_TRUE; + i = 0; // allocation index + + pConn = NvOdmPeripheralGetGuid(TMON_ADT7461_ID); + if (pConn) + { + pTmon = &s_TmonArray[i++]; + pTmon->pfnInit = Adt7461Init; + pTmon->pfnDeinit = Adt7461Deinit; + pTmon->pfnTemperatureGet = Adt7461TemperatureGet; + pTmon->pfnCapabilitiesGet = Adt7461CapabilitiesGet; + pTmon->pfnParameterCapsGet = Adt7461ParameterCapsGet; + pTmon->pfnParameterConfig = Adt7461ParameterConfig; + pTmon->pfnRun = Adt7461Run; + pTmon->pfnStop = Adt7461Stop; + pTmon->pfnIntrRegister = Adt7461IntrRegister; + pTmon->pfnIntrUnregister = Adt7461IntrUnregister; + pTmon->pConn = pConn; + pTmon->RefCount = 0; + pTmon->pPrivate = NULL; + + // Fill in Zones => TMON devices map + NV_ASSERT(pConn->AddressList); + for (j = 0; j < pConn->NumAddress; j++) + { + if (pConn->AddressList[j].Interface == NvOdmIoModule_Tsense) + s_TmonMap[pConn->AddressList[j].Instance] = pTmon; + } + } + } + // Find TMON instance for the given zone + if(ZoneId < NvOdmTmonZoneID_Num) + { + pTmon = s_TmonMap[ZoneId]; + if (pTmon && pTmon->pConn) + return pTmon; + } + return NULL; +} + +/*****************************************************************************/ + +NvOdmTmonDeviceHandle +NvOdmTmonDeviceOpen(NvOdmTmonZoneID ZoneId) +{ + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon) + { + NV_ASSERT(pTmon->pfnInit && pTmon->pfnRun); + // Init TMON device on the 1st open + if (pTmon->RefCount == 0) + { + if (!pTmon->pfnInit(pTmon)) + return NULL; + } + // Make sure targeted zone is monitored + if (pTmon->pfnRun(pTmon, ZoneId)) + { + pTmon->RefCount++; + return TMON_ZONE_PSEUDOHANDLE(pTmon, ZoneId); + } + } + return NULL; +} + +void NvOdmTmonDeviceClose(NvOdmTmonDeviceHandle hTmon) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon) + { + NV_ASSERT(pTmon->pfnDeinit && pTmon->pfnStop); + (void)pTmon->pfnStop(pTmon, ZoneId); + if (pTmon->RefCount == 1) + pTmon->pfnDeinit(pTmon); + + if (pTmon->RefCount) + { + pTmon->RefCount--; + return; + } + NV_ASSERT(!"RefCount balance failed"); + } +} + +NvBool NvOdmTmonSuspend(NvOdmTmonDeviceHandle hTmon) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnStop); + if (pTmon->pfnStop(pTmon, ZoneId)) + return NV_TRUE; + } + return NV_FALSE; +} + +NvBool NvOdmTmonResume(NvOdmTmonDeviceHandle hTmon) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnRun); + if (pTmon->pfnRun(pTmon, ZoneId)) + return NV_TRUE; + } + return NV_FALSE; +} + +/*****************************************************************************/ + +NvBool +NvOdmTmonTemperatureGet( + NvOdmTmonDeviceHandle hTmon, + NvS32* pDegreesC) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnTemperatureGet); + if (pTmon->pfnTemperatureGet(pTmon, ZoneId, pDegreesC)) + return NV_TRUE; + } + return NV_FALSE; +} + +/*****************************************************************************/ + +void +NvOdmTmonCapabilitiesGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonCapabilities* pCaps) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnCapabilitiesGet); + pTmon->pfnCapabilitiesGet(pTmon, ZoneId, pCaps); + } + else if (pCaps) + { + NvOdmOsMemset(pCaps, 0, sizeof(NvOdmTmonCapabilities)); + pCaps->Tmax = ODM_TMON_PARAMETER_UNSPECIFIED; + pCaps->Tmin = ODM_TMON_PARAMETER_UNSPECIFIED; + } +} + +void +NvOdmTmonParameterCapsGet( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonConfigParam ParamId, + NvOdmTmonParameterCaps* pCaps) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnParameterCapsGet); + pTmon->pfnParameterCapsGet(pTmon, ZoneId, ParamId, pCaps); + } + else if (pCaps) + { + NvOdmOsMemset(pCaps, 0, sizeof(NvOdmTmonParameterCaps)); + pCaps->MaxValue = ODM_TMON_PARAMETER_UNSPECIFIED; + pCaps->MinValue = ODM_TMON_PARAMETER_UNSPECIFIED; + pCaps->OdmProtected = NV_TRUE; + } +} + +NvBool +NvOdmTmonParameterConfig( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonConfigParam ParamId, + NvS32* pSetting) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnParameterConfig); + if (pTmon->pfnParameterConfig(pTmon, ZoneId, ParamId, pSetting)) + return NV_TRUE; + } + return NV_FALSE; +} + +/*****************************************************************************/ + +NvOdmTmonIntrHandle +NvOdmTmonIntrRegister( + NvOdmTmonDeviceHandle hTmon, + NvOdmInterruptHandler Callback, + void* CallbackArg) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + NvOdmTmonIntrHandle hIntr = NULL; + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnIntrRegister); + hIntr = pTmon->pfnIntrRegister( + pTmon, ZoneId, Callback, CallbackArg); + } + return hIntr; +} + +void +NvOdmTmonIntrUnregister( + NvOdmTmonDeviceHandle hTmon, + NvOdmTmonIntrHandle hIntr) +{ + NvOdmTmonZoneID ZoneId = TMON_PSEUDOHANDLE_ZONE(hTmon); + NvOdmTmonDevice* pTmon = TmonGetInstance(ZoneId); + + if (pTmon && pTmon->RefCount) + { + NV_ASSERT(pTmon->pfnIntrUnregister); + pTmon->pfnIntrUnregister(pTmon, ZoneId, hIntr); + } +} + +/*****************************************************************************/ diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h new file mode 100644 index 000000000000..5e5e1141c584 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/adaptations/tmon/tmon_hal.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Abstraction layer stub for Temperature Monitor adaptations</b> + */ + +#ifndef INCLUDED_NVODM_TMON_ADAPTATION_HAL_H +#define INCLUDED_NVODM_TMON_ADAPTATION_HAL_H + +#include "nvcommon.h" +#include "nvodm_tmon.h" +#include "nvodm_query_discovery.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +typedef NvBool (*pfnTmonInit)(NvOdmTmonDeviceHandle); +typedef void (*pfnTmonDeinit)(NvOdmTmonDeviceHandle); +typedef NvBool (*pfnTmonTemperatureGet)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvS32*); +typedef void (*pfnTmonCapabilitiesGet)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonCapabilities*); +typedef void (*pfnTmonParameterCapsGet) + (NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonConfigParam, NvOdmTmonParameterCaps*); +typedef NvBool (*pfnTmonParameterConfig)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonConfigParam, NvS32*); +typedef NvBool (*pfnTmonRun)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID); +typedef NvBool (*pfnTmonStop)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID); +typedef NvOdmTmonIntrHandle + (*pfnTmonIntrRegister)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmInterruptHandler, void*); +typedef void (*pfnTmonIntrUnregister)(NvOdmTmonDeviceHandle, NvOdmTmonZoneID, NvOdmTmonIntrHandle); + +typedef struct NvOdmTmonDeviceRec +{ + pfnTmonInit pfnInit; + pfnTmonDeinit pfnDeinit; + pfnTmonTemperatureGet pfnTemperatureGet; + pfnTmonCapabilitiesGet pfnCapabilitiesGet; + pfnTmonParameterCapsGet pfnParameterCapsGet; + pfnTmonParameterConfig pfnParameterConfig; + pfnTmonRun pfnRun; + pfnTmonStop pfnStop; + pfnTmonIntrRegister pfnIntrRegister; + pfnTmonIntrUnregister pfnIntrUnregister; + + const NvOdmPeripheralConnectivity* pConn; + NvU32 RefCount; + void *pPrivate; +} NvOdmTmonDevice; + +#ifdef __cplusplus +} +#endif + +#endif //INCLUDED_NVODM_TMON_ADAPTATION_HAL_H diff --git a/arch/arm/mach-tegra/odm_kit/platform/Makefile b/arch/arm/mach-tegra/odm_kit/platform/Makefile new file mode 100644 index 000000000000..8cf34fa4b7f6 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/Makefile @@ -0,0 +1,8 @@ +obj-$(CONFIG_INPUT_TEGRA_ODM_ACCEL) += accelerometer/ +obj-$(CONFIG_INPUT_TEGRA_ODM_SCROLL) += scrollwheel/ +obj-$(CONFIG_KEYBOARD_TEGRA_NVEC) += keyboard/ +obj-$(CONFIG_TOUCHSCREEN_TEGRA_ODM) += touch/ +obj-$(CONFIG_TEGRA_ODM_VIBRATE) += vibrate/ +obj-$(CONFIG_MOUSE_TEGRA_NVEC) += mouse/ +obj-$(CONFIG_TEGRA_BATTERY_NVEC) += battery/ +obj-$(CONFIG_BATTERY_TEGRA_ODM) += battery/ diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile new file mode 100644 index 000000000000..0ec8a6b4ea03 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile @@ -0,0 +1,12 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_accelerometer_adi340.o +obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_accelerometer_bma150.o +obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_accelerometer_adi340.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c new file mode 100644 index 000000000000..9a6ae96a3b52 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.c @@ -0,0 +1,1204 @@ +/* + * 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. + * + */ + +/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the + * WinCE Accelerometer Driver + */ + + +#include "nvodm_accelerometer_adi340.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvos.h" + +#define NV_ACCELEROMETER_REGISTER_RANGE 8 +// When acc is put in horizontal, the max value from acc. +#define NV_ADI340_ACCELEROMETER_NORMAL_THRESHOLD 30 +#define NV_ADI340_ACCELEROMETER_TAP_THRESHOLD 40 +#define NV_ADI340_LOW_POWER_SAMPLERATE 3 +#define NV_ADI340_FULL_RUN_SAMPLERATE 100 +#define NV_ADI340_FORCE_FACTOR 1000 +#define NV_ADI340_MAX_FORCE_IN_REG 128 // It indicates force register length. +#define NV_DEBOUNCE_TIME_MS 0 +//static NvU32 g_thresholdG_shadow = 70; + +// For interrupt handle, set GPIO when an interrupt happens. +static void GpioInterruptHandler(void *arg); +NvBool NvAccelerometerI2COpen(NvOdmServicesI2cHandle* hI2CDevice, NvU32 id); +void NvAccelerometerI2CClose(NvOdmServicesI2cHandle hI2CDevice); +NvBool NvAccelerometerI2CSetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len); +NvBool NvAccelerometerI2CGetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len); +NvBool NvAccelerometerConnectSemaphore(NvOdmAccelHandle hDevice); +void NvAccelerometerSetPowerRail(NvOdmServicesPmuHandle hPMUDevice, NvU32 Id, NvBool IsEnable); +void NvAccelerometerGetInterruptSouce(NvOdmAccelHandle hDevice, + NvOdmAccelIntType *IntType, + NvOdmAccelAxisType *IntMotionAxis, + NvOdmAccelAxisType *IntTapAxis); + +/* + * Set accelerometer registers. + * [in] attrib: The register flag. + * [out] info: The value to be set into the register of accelerometer. + * Returns NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmAccelerometerSetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32 info) +{ + // Because there are only 8 bits for one accelerometer register. + NvU8 LocalInfo = 0; + LocalInfo = (NvU8)(info); + // Due to the register length, we only accept the lowest 8 bits. + NvOdmOsMemcpy(&LocalInfo, &info, sizeof(NvU8)); + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerSetParameter +++\n"); + switch (attrib) + { + case XLR_CTL: + //NvOdmOsDebugPrintf("set XLR_CTL = 0x%x\n", LocalInfo); + hDevice->RegsWrite( hDevice, XLR_CTL, &LocalInfo, 1); + break; + case XLR_INTCONTROL: + //NvOdmOsDebugPrintf("set XLR_INTCONTROL = 0x%x\n", LocalInfo); + hDevice->RegsWrite( hDevice, XLR_INTCONTROL, &LocalInfo, 1); + break; + case XLR_INTCONTROL2: + //NvOdmOsDebugPrintf("set XLR_INTCONTROL2 = 0x%x\n", LocalInfo); + hDevice->RegsWrite( hDevice, XLR_INTCONTROL2, &LocalInfo, 1); + break; + case XLR_THRESHG: + //NVODMACCELEROMETER_PRINTF("set XLR_THRESHG = 0x%x\n", LocalInfo); + hDevice->RegsWrite( hDevice, XLR_THRESHG, &LocalInfo, 1); + break; + case XLR_THRESHC: + hDevice->RegsWrite( hDevice, XLR_THRESHC, &LocalInfo, 1); + break; + case XLR_OFSX: + hDevice->RegsWrite( hDevice, XLR_OFSX, &LocalInfo, 1); + break; + case XLR_OFSY: + hDevice->RegsWrite( hDevice, XLR_OFSY, &LocalInfo, 1); + break; + case XLR_OFSZ: + hDevice->RegsWrite( hDevice, XLR_OFSZ, &LocalInfo, 1); + break; + case XLR_DUR: + hDevice->RegsWrite( hDevice, XLR_DUR, &LocalInfo, 1); + break; + case XLR_LATENT: + hDevice->RegsWrite( hDevice, XLR_LATENT, &LocalInfo, 1); + break; + case XLR_INTVL: + hDevice->RegsWrite( hDevice, XLR_INTVL, &LocalInfo, 1); + break; + default: + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerSetParameter DONT SUPPORT SUCH ATTRIBUTE ---\n"); + return NV_FALSE; + } + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerSetParameter ---\n"); + return NV_TRUE; +} + + + +/* + * Get acceleromter registers. + * [in] attrib: The regsiter flag. + * [out] info: The value from register of accelerometer. + * Returns NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmAccelerometerGetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32* info) +{ + NvU8 LocalInfo = 0; + NvS32 temp; + + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter +++\n"); + switch (attrib) + { + case XLR_DEVID: + hDevice->RegsRead( hDevice, XLR_DEVID, &LocalInfo, 1); + break; + case XLR_WHOAMI: + hDevice->RegsRead( hDevice, XLR_WHOAMI, &LocalInfo, 1); + break; + case XLR_STATUS: + hDevice->RegsRead( hDevice, XLR_STATUS, &LocalInfo, 1); + break; + case XLR_INTSOURCE: + hDevice->RegsRead( hDevice, XLR_INTSOURCE, &LocalInfo, 1); + break; + case XLR_CTL: + hDevice->RegsRead( hDevice, XLR_CTL, &LocalInfo, 1); + break; + case XLR_INTCONTROL: + hDevice->RegsRead( hDevice, XLR_INTCONTROL, &LocalInfo, 1); + break; + case XLR_INTCONTROL2: + hDevice->RegsRead( hDevice, XLR_INTCONTROL2, &LocalInfo, 1); + break; + case XLR_DATAX: + // Because it is a signed char. + hDevice->RegsRead( hDevice, XLR_DATAX, &LocalInfo, 1); + temp = (LocalInfo<128)?LocalInfo:(LocalInfo-256); + NvOdmOsMemcpy(info, &temp, sizeof(NvU32)); + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n"); + return NV_TRUE; + case XLR_DATAY: + // Because it is a signed char. + hDevice->RegsRead( hDevice, XLR_DATAY, &LocalInfo, 1); + temp = (LocalInfo<128)?LocalInfo:(LocalInfo-256); + NvOdmOsMemcpy(info, &temp, sizeof(NvU32)); + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n"); + return NV_TRUE; + case XLR_DATAZ: + // Because it is a signed char. + hDevice->RegsRead( hDevice, XLR_DATAZ, &LocalInfo, 1); + temp = (LocalInfo<128)?LocalInfo:(LocalInfo-256); + NvOdmOsMemcpy(info, &temp, sizeof(NvU32)); + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n"); + return NV_TRUE; + case XLR_MOREINFO: + hDevice->RegsRead( hDevice, XLR_MOREINFO, &LocalInfo, 1); + break; + case XLR_THRESHG: + hDevice->RegsRead( hDevice, XLR_THRESHG, &LocalInfo, 1); + break; + case XLR_THRESHC: + hDevice->RegsRead( hDevice, XLR_THRESHC, &LocalInfo, 1); + break; + case XLR_OFSX: + hDevice->RegsRead( hDevice, XLR_OFSX, &LocalInfo, 1); + break; + case XLR_OFSY: + hDevice->RegsRead( hDevice, XLR_OFSY, &LocalInfo, 1); + break; + case XLR_OFSZ: + hDevice->RegsRead( hDevice, XLR_OFSZ, &LocalInfo, 1); + break; + case XLR_DUR: + hDevice->RegsRead( hDevice, XLR_DUR, &LocalInfo, 1); + break; + case XLR_LATENT: + hDevice->RegsRead( hDevice, XLR_LATENT, &LocalInfo, 1); + break; + case XLR_INTVL: + hDevice->RegsRead( hDevice, XLR_INTVL, &LocalInfo, 1); + break; + case XLR_SCALE: + hDevice->RegsRead( hDevice, XLR_CTL, &LocalInfo, 1); + if ((LocalInfo&(0x01)) == 0) + { + LocalInfo = 2; + } + else + { + LocalInfo = 8; + } + break; + case XLR_ROTATE: + *info = 1; + break; + case XLR_GYRO: + *info = 0; + break; + default: + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter DONT SUPPORT SUCH ATTRIBUTE ---\n"); + return NV_FALSE; + } + *info = LocalInfo; + //NVODMACCELEROMETER_PRINTF("NV ODM ACCELEROMETER NvOdmAccelerometerGetParameter ---\n"); + return NV_TRUE; +} + +void NvAccelerometerSetPowerRail(NvOdmServicesPmuHandle hPMUDevice, NvU32 Id, NvBool IsEnable) +{ + NvOdmServicesPmuVddRailCapabilities vddrailcap; + NvU32 settletime; + + if (hPMUDevice) + { + NvOdmServicesPmuGetCapabilities(hPMUDevice, Id, &vddrailcap); + if (IsEnable) + { + NvOdmServicesPmuSetVoltage(hPMUDevice, Id, vddrailcap.requestMilliVolts, &settletime); + } + else + { + NvOdmServicesPmuSetVoltage(hPMUDevice, Id, vddrailcap.MinMilliVolts, &settletime); + } + NvOdmOsWaitUS(settletime); // wait to settle power + } +} + + +/* + * Get interrupt type and source. + */ +void NvAccelerometerGetInterruptSouce(NvOdmAccelHandle hDevice, + NvOdmAccelIntType *IntType, + NvOdmAccelAxisType *IntMotionAxis, + NvOdmAccelAxisType *IntTapAxis) +{ + NvU32 reg_val; + + NV_ASSERT(hDevice != 0); + NV_ASSERT(IntType != 0); + NV_ASSERT(IntMotionAxis != 0); + NV_ASSERT(IntTapAxis != 0); + + *IntType = NvOdmAccelInt_None; + *IntMotionAxis = NvOdmAccelAxis_None; + *IntTapAxis = NvOdmAccelAxis_None; + + if(NULL != hDevice) + { + NvOdmAccelerometerGetParameter(hDevice, XLR_INTSOURCE, ®_val); + if(reg_val & XLR_INTSOURCE_X_COM_MASK) + { + *IntType |= NvOdmAccelInt_MotionThreshold; + *IntMotionAxis |= NvOdmAccelAxis_X; + } + if(reg_val & XLR_INTSOURCE_Y_COM_MASK) + { + *IntType |= NvOdmAccelInt_MotionThreshold; + *IntMotionAxis |= NvOdmAccelAxis_Y; + } + if(reg_val & XLR_INTSOURCE_Z_COM_MASK) + { + *IntType |= NvOdmAccelInt_MotionThreshold; + *IntMotionAxis |= NvOdmAccelAxis_Z; + } + if(reg_val & XLR_INTSOURCE_X_TAP_MASK) + { + *IntType |= NvOdmAccelInt_TapThreshold; + *IntTapAxis |= NvOdmAccelAxis_X; + } + if(reg_val & XLR_INTSOURCE_Y_TAP_MASK) + { + *IntType |= NvOdmAccelInt_TapThreshold; + *IntTapAxis |= NvOdmAccelAxis_Y; + } + if(reg_val & XLR_INTSOURCE_Z_TAP_MASK) + { + *IntType |= NvOdmAccelInt_TapThreshold; + *IntTapAxis |= NvOdmAccelAxis_Z; + } + } + //NvOdmOsDebugPrintf("IntType =%d, IntAxis = %d\n", *IntType, *IntAxis); +} + + +static void +GpioInterruptHandler(void *arg) +{ + NvOdmGpioPinMode mode; + + NvU32 pinValue; + NvOdmAccelHandle hDevice = (NvOdmAccelHandle)arg; + //NvOdmOsSemaphoreHandle s = (NvOdmOsSemaphoreHandle)arg; + + NvOdmGpioGetState(hDevice->hGpioINT, hDevice->hPinINT, &pinValue); + if (pinValue == 1) + { + mode = NvOdmGpioPinMode_InputInterruptLow; + } + else + { + mode = NvOdmGpioPinMode_InputInterruptHigh; + } + + NvOdmGpioConfig(hDevice->hGpioINT, hDevice->hPinINT, mode); + + if (pinValue == 1) + { + NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); + } + NvOdmGpioInterruptDone(hDevice->hGpioInterrupt); + return; +} + +/* + * Connect semaphore with interrupt pins according to your configuration. + */ +NvBool NvAccelerometerConnectSemaphore(NvOdmAccelHandle hDevice) +{ + NvOdmGpioPinMode mode; + NvOdmInterruptHandler callback = (NvOdmInterruptHandler)GpioInterruptHandler; + + hDevice->hGpioINT = (NvOdmServicesGpioHandle)NvOdmGpioOpen(); + if(!(hDevice->hGpioINT)) + { + //NVODMACCELEROMETER_PRINTF("NvOdm Accelerometer : NvOdmGpioOpen Error \n"); + return NV_FALSE; + } + + hDevice->hPinINT = NvOdmGpioAcquirePinHandle(hDevice->hGpioINT, + hDevice->GPIOPortINT, + hDevice->GPIOPinINT); + + hDevice->SemaphoreForINT = NvOdmOsSemaphoreCreate(0); + + if(!(hDevice->SemaphoreForINT)) + { + //NVODMACCELEROMETER_PRINTF("NvOdm Accelerometer : NvOdmOsSemaphoreCreate Error \n"); + NvOdmGpioClose(hDevice->hGpioINT); + return NV_FALSE; + } + + mode = NvOdmGpioPinMode_InputInterruptHigh; + + if (NvOdmGpioInterruptRegister(hDevice->hGpioINT, &hDevice->hGpioInterrupt, + hDevice->hPinINT, mode, callback, hDevice, NV_DEBOUNCE_TIME_MS) == NV_FALSE) + { + return NV_FALSE; + } + + if(!(hDevice->hGpioInterrupt)) + { + //NVODMACCELEROMETER_PRINTF("NvOdm Accelerometer : NvOdmGpioInterruptRegister Error \n"); + NvOdmGpioClose(hDevice->hGpioINT); + NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); + return NV_FALSE; + } + + return NV_TRUE; +} + +/* + * Initialize I2C for accelerometer. + */ +NvBool NvAccelerometerI2COpen(NvOdmServicesI2cHandle* hI2CDevice, NvU32 id) +{ + // Open I2C handle. + *hI2CDevice = NvOdmI2cOpen(NvOdmIoModule_I2c, id); + if (*hI2CDevice == NULL) + { + return NV_FALSE; + } + return NV_TRUE; +} + + +/* + * De-initialize I2C for accelerometer. + */ +void NvAccelerometerI2CClose(NvOdmServicesI2cHandle hI2CDevice) +{ + // Close I2C handle. + if(NULL != hI2CDevice) + { + NvOdmI2cClose(hI2CDevice); + } +} + + +/* + * Write I2C register function. + * offset[Input]: I2C register offset of accelerometer. + * value[Input]: register value you will write. + * len[Input]: requested bytes. + * Returns NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvAccelerometerI2CSetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len) +{ + NvOdmI2cTransactionInfo TransactionInfo; + + if( (NULL == hDevice) || (NULL == value) || (len > I2C_ACCELRATOR_PACKET_SIZE-1 )) + { + //NVODMACCELEROMETER_PRINTF("NvOdmI2c Set Regs Failed, max size is %d bytes\n", I2C_ACCELRATOR_PACKET_SIZE-1); + return NV_FALSE; + } + + NvOdmOsMemset(s_WriteBuffer, 0, sizeof(s_WriteBuffer)); + s_WriteBuffer[0] = offset; + NvOdmOsMemcpy(&s_WriteBuffer[1], value, len); + + TransactionInfo.Address = hDevice->nDevAddr; + TransactionInfo.Buf = s_WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = len+1; + + // Write the accelerator offset (from where data is to be read). + if(NvOdmI2cStatus_Success != NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, I2C_ACCELRATOR_TRANSACTION_TIMEOUT)) + { + return NV_FALSE; + }; + + return NV_TRUE; +} + +/* + * Read I2C register function. + * offset[Input]: I2C register offset of accelerometer. + * value[Output]: Fegister value you get. + * len[Input]: Requested bytes. + * Returns NV_TRUE if successful, or NV_FALSE otherwise. + */ + +NvBool NvAccelerometerI2CGetRegs(NvOdmAccelHandle hDevice, NvU8 offset, NvU8* value, NvU32 len) +{ + NvOdmI2cTransactionInfo TransactionInfo; + + if( (NULL == hDevice) || (NULL == value) || (len > I2C_ACCELRATOR_PACKET_SIZE-1 )) + { + //NVODMACCELEROMETER_PRINTF("NvOdmI2c Get Regs Failed, max size is %d bytes\n", I2C_ACCELRATOR_PACKET_SIZE-1); + return NV_FALSE; + } + + NvOdmOsMemset(s_WriteBuffer, 0, sizeof(s_WriteBuffer)); + s_WriteBuffer[0] = offset; + + TransactionInfo.Address = hDevice->nDevAddr; + TransactionInfo.Buf = s_WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 1; + + // Write the accelerometor offset (from where data is to be read). + if(NvOdmI2cStatus_Success != NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, I2C_ACCELRATOR_TRANSACTION_TIMEOUT)) + { + return NV_FALSE; + }; + + NvOdmOsMemset(s_ReadBuffer, 0, sizeof(s_ReadBuffer)); + s_ReadBuffer[0] = 0; + + TransactionInfo.Address = (hDevice->nDevAddr| 0x1); + TransactionInfo.Buf = s_ReadBuffer; + TransactionInfo.Flags = 0; + TransactionInfo.NumBytes = len; + + //Read the data from the eeprom at the specified offset + if(NvOdmI2cStatus_Success != NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, I2C_ACCELRATOR_TRANSACTION_TIMEOUT)) + { + return NV_FALSE; + }; + + NvOdmOsMemcpy(value, &s_ReadBuffer[0], len); + + return NV_TRUE; +} + +//----------------------------------------------------------------- +//--------------------------------New API-------------------------- +//----------------------------------------------------------------- +NvBool +NvOdmAccelOpen(NvOdmAccelHandle* hDevice) +{ + NvU32 test_val; + NvU32 i; + NvBool foundGpio = NV_FALSE, foundI2cModule = NV_FALSE; + const NvOdmPeripheralConnectivity *pConnectivity; + NvOdmAccelHandle hAccel; + + hAccel = NvOdmOsAlloc(sizeof(NvOdmAccel)); + if (hAccel == NULL) + { + //NVODMACCELEROMETER_PRINTF("Error Allocating NvOdmAccel. \n"); + return NV_FALSE; + } + NvOdmOsMemset(hAccel, 0, sizeof(NvOdmAccel)); + + hAccel->hPmu = NULL; + hAccel->hOdmI2C = NULL; + hAccel->nBusType = NV_ACCELEROMETER_BUS_I2C; + + // Chip init cfg info here, here just a sample for common interrupt now! + // This part will move to a configuration table later. + // Start here. + // Only enable common interrupt + // Enable common and single tap at the same time. + hAccel->CtrlRegsList[0].RegAddr = XLR_CTL; //0x12 + hAccel->CtrlRegsList[0].RegValue = 0x20; + hAccel->CtrlRegsList[1].RegAddr = XLR_INTCONTROL; //0x13 + hAccel->CtrlRegsList[1].RegValue = 0xF3; // modify so that sw is compatible + hAccel->CtrlRegsList[2].RegAddr = XLR_INTCONTROL2; //0x14 + hAccel->CtrlRegsList[2].RegValue = 0xe0; + hAccel->CtrlRegsList[3].RegAddr = XLR_THRESHG; //0x1C + hAccel->CtrlRegsList[3].RegValue = NV_ADI340_ACCELEROMETER_NORMAL_THRESHOLD; + hAccel->CtrlRegsList[4].RegAddr = XLR_OFSX; //0x1E + hAccel->CtrlRegsList[4].RegValue = 0; + hAccel->CtrlRegsList[5].RegAddr = XLR_OFSY; //0x1F + hAccel->CtrlRegsList[5].RegValue = 0; + hAccel->CtrlRegsList[6].RegAddr = XLR_OFSZ; //0x20 + hAccel->CtrlRegsList[6].RegValue = 0; + hAccel->CtrlRegsList[7].RegAddr = XLR_THRESHC; //0x1D + hAccel->CtrlRegsList[7].RegValue = NV_ADI340_ACCELEROMETER_TAP_THRESHOLD; + hAccel->CtrlRegsList[8].RegAddr = XLR_DUR; //0x21 + hAccel->CtrlRegsList[8].RegValue = 0x40; + hAccel->CtrlRegsList[9].RegAddr = XLR_LATENT; //0x22 + hAccel->CtrlRegsList[9].RegValue = 0xff; + hAccel->CtrlRegsList[10].RegAddr = XLR_INTVL; //0x23 + hAccel->CtrlRegsList[10].RegValue = 0; + hAccel->CtrlRegsList[11].RegAddr = XLR_INTCONTROL2; //0x14 + hAccel->CtrlRegsList[11].RegValue = 0xe1; + hAccel->CtrlRegsList[12].RegAddr = XLR_INTCONTROL2; //0x14 + hAccel->CtrlRegsList[12].RegValue = 0xe0; + hAccel->nLength = 13; + // Stop here. + // Info of accelerometer with current setting. + hAccel->Caption.MaxForceInGs = 2000; + hAccel->Caption.MaxTapTimeDeltaInUs = 255; + hAccel->Caption.NumMotionThresholds = 1; + hAccel->Caption.SupportsFreefallInt = 0; + hAccel->Caption.MaxSampleRate = 100; + hAccel->Caption.MinSampleRate = 3; + hAccel->PowerState = NvOdmAccelPower_Fullrun; + hAccel->AxisXMapping = NvOdmAccelAxis_X; + hAccel->AxisXDirection = 1; + hAccel->AxisYMapping = NvOdmAccelAxis_Y; + hAccel->AxisYDirection = 1; + hAccel->AxisZMapping = NvOdmAccelAxis_Z; + hAccel->AxisZDirection = -1; + + hAccel->hPmu = NvOdmServicesPmuOpen(); + if (!hAccel->hPmu) + { + //NVODMACCELEROMETER_PRINTF("NvOdmServicesPmuOpen Error \n"); + goto error; + } + + pConnectivity = (NvOdmPeripheralConnectivity*)NvOdmPeripheralGetGuid(NV_ODM_GUID('a','c','c','e','l','e','r','o')); + if (!pConnectivity) + { + NvOdmOsDebugPrintf("NvOdmPeripheralGetGuid doesn't detect accelerometer device\n"); + goto error; + } + + if(pConnectivity->Class != NvOdmPeripheralClass_Other) + { + goto error; + } + + for( i = 0; i < pConnectivity->NumAddress; i++) + { + switch(pConnectivity->AddressList[i].Interface) + { + case NvOdmIoModule_I2c: + hAccel->I2CChannelId = pConnectivity->AddressList[i].Instance; + hAccel->nDevAddr = (NvU8)pConnectivity->AddressList[i].Address; + foundI2cModule = NV_TRUE; + break; + case NvOdmIoModule_Gpio: + hAccel->GPIOPortINT = pConnectivity->AddressList[i].Instance; + hAccel->GPIOPinINT = pConnectivity->AddressList[i].Address; + foundGpio = NV_TRUE; + break; + case NvOdmIoModule_Vdd: + hAccel->VddId = pConnectivity->AddressList[i].Address; + // Power on accelerometer according to Vddid + NvAccelerometerSetPowerRail(hAccel->hPmu, hAccel->VddId, NV_TRUE); + break; + default: + break; + } + } + + if(foundGpio != NV_TRUE || foundI2cModule != NV_TRUE) + { + //NVODMACCELEROMETER_PRINTF("Accelerometer : didn't find any periperal in discovery query for touch device Error \n"); + goto error; + } + + + // Set up I2C bus. + if(NV_FALSE == NvAccelerometerI2COpen(&hAccel->hOdmI2C, hAccel->I2CChannelId)) + { + goto error; + }; + hAccel->RegsRead = NvAccelerometerI2CGetRegs; + hAccel->RegsWrite = NvAccelerometerI2CSetRegs; + + NvOdmAccelerometerGetParameter(hAccel, XLR_WHOAMI, &test_val); + if(XLR_IDNUM != test_val) + { + goto error; + } + + NvOdmAccelerometerGetParameter(hAccel, XLR_DEVID, &test_val); + if (test_val == XLR_NEWCHIPID) + { + // This chip is ADXL345 + //NvOdmOsDebugPrintf("This chip is ADXL345!!!\n"); + hAccel->CtrlRegsList[4].RegValue = 0x0A; // offset X + hAccel->CtrlRegsList[5].RegValue = 0x0B; // offset Y + hAccel->CtrlRegsList[6].RegValue = 0x14; // offset Z + } + //NVODMACCELEROMETER_PRINTF("ID is 0x%x\n", test_val); + + /* We don't know the reset state of the accelerometer. So, program the + * accelerometer to disable generation of interrupts. + * + * Write to INTCONTROL register to disable genetration of the interrupts. + * Write to INTCONTROL2 to clear the already latched interrupts. + */ + NvOdmAccelerometerSetParameter(hAccel, XLR_ATTR_INTCONTROL, 0x0); + NvOdmAccelerometerSetParameter(hAccel, XLR_ATTR_INTCONTROL2, 0x1); + if(NV_FALSE == NvAccelerometerConnectSemaphore(hAccel)) + { + goto error; + } + + //init accelerometer + for(i=0; i<hAccel->nLength; i++) + { + NvOdmAccelerometerSetParameter(hAccel, + hAccel->CtrlRegsList[i].RegAddr, + hAccel->CtrlRegsList[i].RegValue); + } + // Set up event. + + //NvOdmAccelerometerGetParameter(XLR_SCALE, hAccel); + *hDevice = hAccel; + return NV_TRUE; + error: + // Release all of resources requested. + if(NULL != hAccel) + { + NvAccelerometerSetPowerRail(hAccel->hPmu, hAccel->VddId, NV_FALSE); + NvOdmServicesPmuClose(hAccel->hPmu); + hAccel->hPmu = NULL; + NvAccelerometerI2CClose(hAccel->hOdmI2C); + hAccel->hOdmI2C = NULL; + NvOdmOsFree(hAccel); + *hDevice = NULL; + } + return NV_FALSE; +} + +void +NvOdmAccelClose(NvOdmAccelHandle hDevice) +{ + if(NULL != hDevice) + { + if(NULL != hDevice->SemaphoreForINT && + NULL != hDevice->hGpioINT && + NULL != hDevice->hPinINT && + NULL != hDevice->hGpioInterrupt) + { + NvOdmGpioInterruptUnregister(hDevice->hGpioINT, + hDevice->hPinINT, + hDevice->hGpioInterrupt); + NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); + NvOdmGpioReleasePinHandle(hDevice->hGpioINT, hDevice->hPinINT); + NvOdmGpioClose(hDevice->hGpioINT); + } + NvAccelerometerI2CClose(hDevice->hOdmI2C); + + // Power off accelermeter + NvAccelerometerSetPowerRail(hDevice->hPmu, hDevice->VddId, NV_FALSE); + if (hDevice->hPmu) + { + //NvAccelerometerSetPowerOn(0); + NvOdmServicesPmuClose(hDevice->hPmu); + } + + return; + } +} + +/* + * After setting the force threshold, we should remove all of interrupt flag + * that may be left from the last threshold. + */ +NvBool +NvOdmAccelSetIntForceThreshold(NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + // At first, we need to translate the threshold to register value for acc. + // The first step is get current work range. + NvU32 uMaxThreshold; + NvU32 uThresholdToRegister; + NvU32 temp; + + + NV_ASSERT(NULL != hDevice); + uMaxThreshold = hDevice->Caption.MaxForceInGs; + if(Threshold > uMaxThreshold) + { + //NVODMACCELEROMETER_PRINTF("Current accelerometer supprt max threshold is %d g\n", uMaxThreshold); + Threshold = uMaxThreshold; + } + + uThresholdToRegister = (NvU8)(Threshold*((1<<(NV_ACCELEROMETER_REGISTER_RANGE-1))-1)/uMaxThreshold); + + // ADI345 can't receive interrupt while threshold = 0 + if (uThresholdToRegister == 0) + uThresholdToRegister = 1; + + // We only enable 2 interrupt pins, INT2 for Motion, INT1 for single tap. + switch(IntType) + { + case NvOdmAccelInt_MotionThreshold: + //NvOdmOsDebugPrintf("Current motion setting threshold is %d \n", uThresholdToRegister); + //NvOdmOsDebugPrintf("the motion threshold program into reg is %d \n", uThresholdToRegister); + NvOdmAccelerometerSetParameter(hDevice, XLR_THRESHG, uThresholdToRegister); + break; + case NvOdmAccelInt_TapThreshold: + //NvOdmOsDebugPrintf("Current tap setting threshold is %d \n", uThresholdToRegister); + //NvOdmOsDebugPrintf("the tap threshold program into reg is %d \n", uThresholdToRegister); + NvOdmAccelerometerSetParameter(hDevice, XLR_THRESHC, uThresholdToRegister); + break; + default: + //NVODMACCELEROMETER_PRINTF("Do not support such Interrupt!\n"); + return NV_FALSE; + } + + // Clear interrupt flag. + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &temp); + temp |= XLR_INTCONTROL2_CLR_INT; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp); + temp &= XLR_INTCONTROL2_CLR_INT_MASK; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp); + return NV_TRUE; +} + +/* + * After setting the time threshold, we should remove all of interrupt flag + * that may be left from the last threshold. + */ +NvBool +NvOdmAccelSetIntTimeThreshold(NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + NvU32 temp; + NV_ASSERT(NULL != hDevice); + //its due adi340 limitation. + if(Threshold > 0xff) + { + //NVODMACCELEROMETER_PRINTF("The max threshold support is 255 ms for adi340\n"); + return NV_FALSE; + } + //NvOdmOsDebugPrintf("The threshold is %d\n", Threshold); + switch(IntType) + { + case NvOdmAccelInt_TapThreshold: + NvOdmAccelerometerSetParameter(hDevice, XLR_DUR, Threshold); + NvOdmAccelerometerSetParameter(hDevice, XLR_INTVL, 0); + NvOdmAccelerometerSetParameter(hDevice, XLR_LATENT, 0); + break; + default: + //NVODMACCELEROMETER_PRINTF("Do not need set time threshold for such Interrupt!\n"); + return NV_FALSE; + } + + // Clear interrupt flag. + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &temp); + temp |= XLR_INTCONTROL2_CLR_INT; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp); + temp &= XLR_INTCONTROL2_CLR_INT_MASK; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp); + return NV_TRUE; +} + +/* + * After enable/disable threshold, we should remove all of interrupt flag + * that may be left from that last threshold. + */ +NvBool +NvOdmAccelSetIntEnable(NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvOdmAccelAxisType IntAxis, + NvU32 IntNum, + NvBool Toggle) +{ + NvU32 uTemp = 0; + NV_ASSERT(NULL != hDevice); + + switch(IntType) + { + case NvOdmAccelInt_MotionThreshold: + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL, &uTemp); + //NvOdmOsDebugPrintf("INTCONTROL is 0x%x g\n", uTemp); + uTemp |= XLR_INTCONTROL_COM_INT_ENABLE; + switch(IntAxis) + { + case NvOdmAccelAxis_X: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL_COM_SRC_X; + } + else + { + uTemp &= XLR_INTCONTROL_COM_SRC_X_MASK; + } + break; + } + case NvOdmAccelAxis_Y: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL_COM_SRC_Y; + } + else + { + uTemp &= XLR_INTCONTROL_COM_SRC_Y_MASK; + } + break; + } + case NvOdmAccelAxis_Z: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL_COM_SRC_Z; + } + else + { + uTemp &= XLR_INTCONTROL_COM_SRC_Z_MASK; + } + break; + } + case NvOdmAccelAxis_All: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL_COM_SRC_X; + uTemp |= XLR_INTCONTROL_COM_SRC_Y; + uTemp |= XLR_INTCONTROL_COM_SRC_Z; + } + else + { + uTemp &= XLR_INTCONTROL_COM_SRC_X_MASK; + uTemp &= XLR_INTCONTROL_COM_SRC_Y_MASK; + uTemp &= XLR_INTCONTROL_COM_SRC_Z_MASK; + } + break; + } + default: + return NV_FALSE; + } + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL, uTemp); + break; + case NvOdmAccelInt_TapThreshold: + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL, &uTemp); + //NvOdmOsDebugPrintf("INTCONTROL is 0x%x \n", uTemp); + uTemp |= XLR_INTCONTROL_TAP_INT_ENABLE; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL, uTemp); + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &uTemp); + //NvOdmOsDebugPrintf("INTCONTROL2 is 0x%x \n", uTemp); + switch(IntAxis) + { + case NvOdmAccelAxis_X: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL2_TAP_SRC_X; + } + else + { + uTemp &= XLR_INTCONTROL2_TAP_SRC_X_MASK; + } + break; + } + case NvOdmAccelAxis_Y: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL2_TAP_SRC_Y; + } + else + { + uTemp &= XLR_INTCONTROL2_TAP_SRC_Y_MASK; + } + break; + } + case NvOdmAccelAxis_Z: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL2_TAP_SRC_Z; + } + else + { + uTemp &= XLR_INTCONTROL2_TAP_SRC_Z_MASK; + } + break; + } + case NvOdmAccelAxis_All: + { + if(Toggle == NV_TRUE) + { + uTemp |= XLR_INTCONTROL2_TAP_SRC_X; + uTemp |= XLR_INTCONTROL2_TAP_SRC_Y; + uTemp |= XLR_INTCONTROL2_TAP_SRC_Z; + } + else + { + uTemp &= XLR_INTCONTROL2_TAP_SRC_X_MASK; + uTemp &= XLR_INTCONTROL2_TAP_SRC_Y_MASK; + uTemp &= XLR_INTCONTROL2_TAP_SRC_Z_MASK; + } + break; + } + default: + return NV_FALSE; + } + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, uTemp); + break; + default: + //NVODMACCELEROMETER_PRINTF("Do not support such Interrupt!\n"); + return NV_FALSE; + } + + // Clear interrupt flag. + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &uTemp); + uTemp |= XLR_INTCONTROL2_CLR_INT; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, uTemp); + uTemp &= XLR_INTCONTROL2_CLR_INT_MASK; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, uTemp); + return NV_TRUE; +} + + +void +NvOdmAccelWaitInt(NvOdmAccelHandle hDevice, + NvOdmAccelIntType *IntType, + NvOdmAccelAxisType *IntMotionAxis, + NvOdmAccelAxisType *IntTapAxis) +{ + NvU32 temp; + NV_ASSERT(NULL != hDevice); + NV_ASSERT(NULL != IntType); + NV_ASSERT(NULL != IntMotionAxis); + NV_ASSERT(NULL != IntTapAxis); + + NvOdmOsSemaphoreWait( hDevice->SemaphoreForINT); + + NvAccelerometerGetInterruptSouce( hDevice , IntType, IntMotionAxis, IntTapAxis); + //NvOdmOsDebugPrintf("Captured interrupt!!!\n"); + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL2, &temp); + temp |= XLR_INTCONTROL2_CLR_INT; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp); + temp &= XLR_INTCONTROL2_CLR_INT_MASK; + NvOdmAccelerometerSetParameter(hDevice, XLR_INTCONTROL2, temp); + + //This is a WAR for ADI340 to prevent I2C register from unstable state + NvOdmAccelerometerGetParameter(hDevice, XLR_INTCONTROL, &temp); + //NvOdmOsDebugPrintf("XLR_INTCONTROL is 0x%x\n", temp); + NvOdmAccelerometerGetParameter(hDevice, XLR_THRESHG, &temp); + //NvOdmOsDebugPrintf("XLR_THRESHG is 0x%x\n", temp); + NvOdmAccelerometerGetParameter(hDevice, XLR_INTSOURCE, &temp); + //NvOdmOsDebugPrintf("XLR_INTSOURCE is 0x%x\n", temp); + return ; +} + + +void NvOdmAccelSignal(NvOdmAccelHandle hDevice) +{ + NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); +} + +NvBool +NvOdmAccelGetAcceleration(NvOdmAccelHandle hDevice, + NvS32 *AccelX, + NvS32 *AccelY, + NvS32 *AccelZ) +{ + NvS32 data = 0; + NV_ASSERT(NULL != hDevice); + NV_ASSERT(NULL != AccelX); + NV_ASSERT(NULL != AccelY); + NV_ASSERT(NULL != AccelZ); + + //fix error for adi340 i2c bug. XLR_OFSZ will be set to 0xA0 randomly. + NvOdmAccelerometerSetParameter(hDevice, XLR_OFSZ, 0); + + NvOdmAccelerometerGetParameter(hDevice, XLR_DATAX, (NvU32*)&data); + //NvOdmOsDebugPrintf("DATAX is %d , after normalization is ", data); + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*data+(NvS32)(NV_ADI340_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_ADI340_MAX_FORCE_IN_REG; + switch(hDevice->AxisXMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + //NvOdmOsDebugPrintf("%d \n", data); + NvOdmAccelerometerGetParameter(hDevice, XLR_DATAY, (NvU32*)&data); + //NvOdmOsDebugPrintf("DATAY is %d , after normalization is ", data); + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*data+(NvS32)(NV_ADI340_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_ADI340_MAX_FORCE_IN_REG; + switch(hDevice->AxisYMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + //NvOdmOsDebugPrintf("%d \n", data); + NvOdmAccelerometerGetParameter(hDevice, XLR_DATAZ, (NvU32*)&data); + //NvOdmOsDebugPrintf("DATAZ is %d , after normalization is ", data); + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*data+(NvS32)(NV_ADI340_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_ADI340_MAX_FORCE_IN_REG; + switch(hDevice->AxisZMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + //NvOdmOsDebugPrintf("%d \n", data); + return NV_TRUE; +} + +NvOdmAccelerometerCaps +NvOdmAccelGetCaps(NvOdmAccelHandle hDevice) +{ + NV_ASSERT(NULL != hDevice); + + return hDevice->Caption; +} + +NvBool +NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate) +{ + NvU32 PowerFlag = 0; + NV_ASSERT(NULL != hDevice); + NvOdmAccelerometerGetParameter(hDevice, XLR_CTL, &PowerFlag); + if(SampleRate > NV_ADI340_LOW_POWER_SAMPLERATE)////3 is the info get from datasheet + { + //if(NvOdmAccelPower_Fullrun != hDevice->PowerState) + { + PowerFlag &= XLR_CTL_POWER_MASK; + PowerFlag |= XLR_CTL_FULL_RUN; + PowerFlag &= XLR_CTL_MODE_MASK; + PowerFlag |= XLR_CTL_MEASURE_MODE; + NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag); + hDevice->PowerState = NvOdmAccelPower_Fullrun; + } + } + else + { + //if(NvOdmAccelPower_Low != hDevice->PowerState) + { + PowerFlag &= XLR_CTL_POWER_MASK; + PowerFlag |= XLR_CTL_LOW_POWER; + PowerFlag &= XLR_CTL_MODE_MASK; + PowerFlag |= XLR_CTL_MEASURE_MODE; + NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag); + hDevice->PowerState = NvOdmAccelPower_Low; + } + } + return NV_TRUE; +} + +NvBool +NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate) +{ + NvU32 SampleFlag = 0; + NV_ASSERT(NULL != hDevice); + NvOdmAccelerometerGetParameter(hDevice, XLR_CTL, &SampleFlag); + + if((SampleFlag&XLR_CTL_LOW_POWER)) + { + *pSampleRate = NV_ADI340_LOW_POWER_SAMPLERATE; + } + else + { + *pSampleRate = NV_ADI340_FULL_RUN_SAMPLERATE; + } + return NV_TRUE; +} + +NvBool +NvOdmAccelSetPowerState(NvOdmAccelHandle hDevice, NvOdmAccelPowerType PowerState) +{ + NvU32 PowerFlag = 0; + NV_ASSERT(NULL != hDevice); + NvOdmAccelerometerGetParameter(hDevice, XLR_CTL, &PowerFlag); + switch(PowerState) + { + case NvOdmAccelPower_Fullrun: + if(NvOdmAccelPower_Fullrun != hDevice->PowerState) + { + PowerFlag &= XLR_CTL_POWER_MASK; + PowerFlag |= XLR_CTL_FULL_RUN; + PowerFlag &= XLR_CTL_MODE_MASK; + PowerFlag |= XLR_CTL_MEASURE_MODE; + NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag); + hDevice->PowerState = NvOdmAccelPower_Fullrun; + } + break; + case NvOdmAccelPower_Low: + if(NvOdmAccelPower_Low != hDevice->PowerState) + { + PowerFlag &= XLR_CTL_POWER_MASK; + PowerFlag |= XLR_CTL_LOW_POWER; + PowerFlag &= XLR_CTL_MODE_MASK; + PowerFlag |= XLR_CTL_MEASURE_MODE; + NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag); + hDevice->PowerState = NvOdmAccelPower_Low; + } + break; + case NvOdmAccelPower_Standby: + if(NvOdmAccelPower_Standby != hDevice->PowerState) + { + PowerFlag &= XLR_CTL_MODE_MASK; + PowerFlag |= XLR_CTL_STANDBY_MODE; + NvOdmAccelerometerSetParameter(hDevice, XLR_CTL, PowerFlag); + hDevice->PowerState = NvOdmAccelPower_Standby; + } + break; + case NvOdmAccelPower_Off: + //the implementation should consider real board connection + //sometimes we need use acc's interrupt to resum the whole + //system, so the power are alway supplied. + return NV_FALSE; + default: + return NV_FALSE; + } + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h new file mode 100644 index 000000000000..3febae3b1f40 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_adi340.h @@ -0,0 +1,321 @@ +/* + * 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. + * + */ + +/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the + * WinCE Accelerometer Driver + */ + +#ifndef INCLUDED_NVODM_ACCELEROMETER_ADI340_H +#define INCLUDED_NVODM_ACCELEROMETER_ADI340_H + +#if defined(_cplusplus) +extern "C" +{ +#endif + +#include "nvodm_services.h" +#include "nvodm_accelerometer.h" + + /* Will keep some attributes from customer in the future */ + #define XLR_ATTR_CTL 0 + #define XLR_ATTR_INTCONTROL 1 + #define XLR_ATTR_INTCONTROL2 2 + #define XLR_ATTR_THRESHG 3 + #define XLR_ATTR_THRESHC 4 + #define XLR_ATTR_OFSX 5 + #define XLR_ATTR_OFSY 6 + #define XLR_ATTR_OFSZ 7 + #define XLR_ATTR_DUR 8 + #define XLR_ATTR_LATENT 9 + #define XLR_ATTR_INTVL 10 + #define XLR_ATTR_WHOAMI 11 + #define XLR_ATTR_STATUS 12 + #define XLR_ATTR_INTSOURCE 13 + #define XLR_ATTR_DATAX 14 + #define XLR_ATTR_DATAY 15 + #define XLR_ATTR_DATAZ 16 + #define XLR_ATTR_MOREINFO 17 + #define XLR_ATTR_SCALE 18 + #define XLR_ATTR_ROTATE 19 + #define XLR_ATTR_GYRO 20 + +// AD22345 register definitions +#define XLR_DEVID 0x00 + +// AD22340 register definitions +#define XLR_WHOAMI 0x0f // RO - device identification +#define XLR_STATUS 0x10 // RO - device status bits +#define XLR_STATUS_DATA_READY 0x80 //0b10000000 indicate that data in XLR_DATAX,Y,Z can be read. +#define XLR_STATUS_DATA_OVERRUN 0x02 //0b00000010 indicate that the old data in XLR_DATAX,Y,Z have not be read +#define XLR_STATUS_INTRRUPT_PENDING 0x01 //0b00000001 indicate that interrupt is active. + +#define XLR_INTSOURCE 0x11 // RO - interrupt source +#define XLR_INTSOURCE_X_TAP_MASK 0x80 //0b10000000 tap interrupt is from x-axis +#define XLR_INTSOURCE_Y_TAP_MASK 0x40 //0b01000000 tap interrupt is from y-axis +#define XLR_INTSOURCE_Z_TAP_MASK 0x20 //0b00100000 tap interrupt is from z-axis +#define XLR_INTSOURCE_X_COM_MASK 0x10 //0b00010000 comm interrupt is from x-axis +#define XLR_INTSOURCE_Y_COM_MASK 0x8 //0b00001000 comm interrupt is from y-axis +#define XLR_INTSOURCE_Z_COM_MASK 0x4 //0b00000100 comm interrupt is from z-axis +#define XLR_INTSOURCE_SINGLE_TAP_MASK 0x2 //0b00000010 single tap mask +#define XLR_INTSOURCE_DOUBLE_TAP_MASK 0x1 //0b00000001 double tap mask + +#define XLR_CTL 0x12 // RW - device control reg +#define XLR_CTL_POWER_MASK 0xbf //0b10111111 +#define XLR_CTL_LOW_POWER 0x40 //0b01000000 low power mode +#define XLR_CTL_FULL_RUN 0x00 //0b00000000 full run mode +#define XLR_CTL_MODE_MASK 0xdf //0b11011111 +#define XLR_CTL_STANDBY_MODE 0x0 //0b00000000 standby mode +#define XLR_CTL_MEASURE_MODE 0x20 //0b00100000 measure mode +#define XLR_CTL_SPI_3_BUS 0x0 //0b00000000 3 wires SPI mode +#define XLR_CTL_SPI_4_BUS 0x10 //0b00010000 4 wires SPI mode +#define XLR_CTL_SELF_TEST_MODE 0x4 //0b00000100 self test mode +#define XLR_CTL_INT1_FUNC_MASK 0xfd //0b11111101 range mask +#define XLR_CTL_INT1_DATA_READY_MODE 0x2 //0b00000010 INT1 pin is data ready flag +#define XLR_CTL_INT1_INTRUPT_MODE 0x0 //0b00000000 INT1 pin is interrupt flag +#define XLR_CTL_RANGE_MASK 0xfe //0b11111110 range mask +#define XLR_CTL_8G_RANGE 0x1 //0b00000001 range is 8g +#define XLR_CTL_2G_RANGE 0x0 //0b00000000 range is 2g + +#define XLR_INTCONTROL 0x13 // RW - interrupt control/config reg +#define XLR_INTCONTROL_COM_SRC_X_MASK 0x7f //0b01111111 +#define XLR_INTCONTROL_COM_SRC_X 0x80 //0b10000000 x participate common interrupt +#define XLR_INTCONTROL_COM_SRC_Y_MASK 0xbf //0b10111111 +#define XLR_INTCONTROL_COM_SRC_Y 0x40 //0b01000000 y participate common interrupt +#define XLR_INTCONTROL_COM_SRC_Z_MASK 0xdf //0b11011111 +#define XLR_INTCONTROL_COM_SRC_Z 0x20 //0b00100000 z participate common interrupt +#define XLR_INTCONTROL_SINGLE_DOUBLE_MASK 0xef //0b11101111 +#define XLR_INTCONTROL_SINGLE_TAP 0x10 //0b00010000 detect single tap +#define XLR_INTCONTROL_DOUBLE_TAP 0x0 //0b00000000 detect double tap +#define XLR_INTCONTROL_INTERRUPT_MAP_MASK 0xfb //0b11111011 +#define XLR_INTCONTROL_INTERRUPT_MAP1 0x4 //0b00000100 common interrupt map to INT2, tap interrupt map to INT1 +#define XLR_INTCONTROL_INTERRUPT_MAP2 0x0 //0b00000000 common interrupt map to INT1, tap interrupt map to INT2 +#define XLR_INTCONTROL_TAP_INT_MASK 0xfd //0b11111101 +#define XLR_INTCONTROL_TAP_INT_ENABLE 0x2 //0b00000010 enable the tap interrupt. +#define XLR_INTCONTROL_COM_INT_MASK 0xfe //0b11111110 +#define XLR_INTCONTROL_COM_INT_ENABLE 0x1 //0b00000001 enable the common interrupt. + +#define XLR_INTCONTROL2 0x14 // RW - interrupt control/config reg 2 +#define XLR_INTCONTROL2_TAP_SRC_X_MASK 0x7f //0b01111111 +#define XLR_INTCONTROL2_TAP_SRC_X 0x80 //0b10000000 x participate tap interrupt +#define XLR_INTCONTROL2_TAP_SRC_Y_MASK 0xbf //0b10111111 +#define XLR_INTCONTROL2_TAP_SRC_Y 0x40 //0b01000000 y participate tap interrupt +#define XLR_INTCONTROL2_TAP_SRC_Z_MASK 0xdf //0b11011111 +#define XLR_INTCONTROL2_TAP_SRC_Z 0x20 //0b00100000 z participate tap interrupt +#define XLR_INTCONTROL2_CLR_INT_MASK 0xfe //0b11111110 +#define XLR_INTCONTROL2_CLR_INT 0x1 //0b00000001 clear interrupt bit and pin + +#define XLR_DATAX 0x15 // RO - data from X axis +#define XLR_DATAY 0x16 // RO - data from Y axis +#define XLR_DATAZ 0x17 // RO - data from Z axis +#define XLR_MOREINFO 0x1b // RO - additional device info + +#define XLR_THRESHG 0x1c // RW - common interrupt threshold reg +#define XLR_THRESHC 0x1d // RW - click threshold reg + +#define XLR_OFSX 0x1e // RW - x axis offset reg +#define XLR_OFSY 0x1f // RW - y axis offset reg +#define XLR_OFSZ 0x20 // RW - z axis offset reg +#define XLR_DUR 0x21 // RW - click duration reg +#define XLR_LATENT 0x22 // RW - click latency reg +#define XLR_INTVL 0x23 // RW - click interval reg + +//virtual register which should translated in driver. +#define XLR_SCALE 0x24 +#define XLR_ROTATE 0x25 +#define XLR_GYRO 0x26 + +/* + * Defines the threshold source for the accelerometer. + */ +typedef enum +{ + /// Indicates the accelerometer generated interrupt by exceeding the x threshold. + NvOdmAccelerometerThresholdSource_X = 0, + + /// Indicates the accelerometer generated interrupt by exceeding the y threshold. + NvOdmAccelerometerThresholdSource_Y, + + /// Indicates the accelerometer generated interrupt by exceeding the z threshold. + NvOdmAccelerometerThresholdSource_Z, + + NvOdmAccelerometerThresholdSource_Force32 = 0x7FFFFFFF +} NvOdmAccelerometerThresholdSource; + +// I2C device address from accelerator. +enum { I2C_ACCELRATOR_ADDRESS = 0x3A}; +// Timeout for I2C transaction. +enum { I2C_ACCELRATOR_TRANSACTION_TIMEOUT = 1000 }; +// Maximum number of packetsize supported by the I2C controller. +enum { I2C_ACCELRATOR_PACKET_SIZE = 8}; +static NvU8 s_ReadBuffer[I2C_ACCELRATOR_PACKET_SIZE]; +static NvU8 s_WriteBuffer[I2C_ACCELRATOR_PACKET_SIZE]; + +// Fixed device identification code. +#define XLR_IDNUM 0x4A + +#define XLR_NEWCHIPID 0xE5 + +#define INT_EVENT_TIMEOUT 100 +#define NV_ACCELEROMETER_BUS_I2C 0 +#define NV_ACCELEROMETER_BUS_SPI_3 1 +#define NV_ACCELEROMETER_BUS_SPI_4 2 +/* +// All of interrupt pins from accelerometer are connected to one interrupt pin of ap15. +#define NV_ACCELEROMETER_INTERRUPT_GPIO_PORT 'C'-'A' +#define NV_ACCELEROMETER_INTERRUPT_GPIO_PIN 7 +// only work for ap10 hw connection +#define NV_ACCELEROMETER_INTERRUPT1_GPIO_PORT 'C'-'A' +#define NV_ACCELEROMETER_INTERRUPT1_GPIO_PIN 7 +#define NV_ACCELEROMETER_INTERRUPT2_GPIO_PORT 'C'-'A' +#define NV_ACCELEROMETER_INTERRUPT2_GPIO_PIN 1 +*/ +/*g value under 8g*/ +#define NVODM_ACCELEROMETER_G_UNDER_8G 16 +/*g value under 2g*/ +#define NVODM_ACCELEROMETER_G_UNDER_2G 64 + +// Module debug: 0=disable, 1=enable +#define NVODMACCELEROMETER_ENABLE_PRINTF (0) + +#if NVODMACCELEROMETER_ENABLE_PRINTF + #define NVODMACCELEROMETER_PRINTF NvOdmOsDebugPrintf +#else + #define NVODMACCELEROMETER_PRINTF (void) +#endif +/* + * Defines the way to read accelerometer registers. + */ +typedef NvBool (*AccelerometerRegsRead)(NvOdmAccelHandle hDevice, NvU8 nRegOffset, NvU8* nData, NvU32 nLen); +/* + * Defines the way to write accelerometer registers. + */ +typedef NvBool (*AccelerometerRegsWrite)(NvOdmAccelHandle hDevice, NvU8 nRegOffset, NvU8* nData, NvU32 nLen); +/* + * Holds register address and value pairs. + */ +typedef struct NvDevCtrlRegRec { + /// Holds the register offset. + NvU8 RegAddr; + /// Holds the value programmed into the upper address. + NvU8 RegValue; +} NvDevCtrlReg; +/* + * Max accelerometer registers number. + */ +#define ACCELEROMETER_CONTROL_REGS_MAX_LENGHT 100 +/* + * Max accelerometer callback functions number. + */ +#define ACCELEROMETER_CALLBACK_ARRAY_LENGTH 5 + +/* + * Gets parameters relating to the accelerometer. + * attrib: Specifies the attributes to get. + * - XLR_ATTR_DATAX--gets data from x-axis. + * - XLR_ATTR_DATAY--gets data from y-axis. + * - XLR_ATTR_DATAZ--gets data from z-axis. + * - XLR_ATTR_OFSX--gets the x-axis offset. + * - XLR_ATTR_OFSY--gets the y-axis offset. + * - XLR_ATTR_OFSZ--gets the z-axis offset. + * + * info: A pointer to the returned parameters. + * Returns NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool +NvOdmAccelerometerGetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32* info); + +/* + * Sets parameters relating to the accelerometer, + * according to the caller's requirements. + * attrib: Specifies the attributes to set. + * - XLR_ATTR_OFSX--sets the x-axis offset. + * - XLR_ATTR_OFSY--sets the y-axis offset. + * - XLR_ATTR_OFSZ--sets the z-axis offset. + * info: Specifies the parameter information to set. + * Returns NV_TRUE if successful, or NV_FALSE otherwise. + */ + +NvBool +NvOdmAccelerometerSetParameter(NvOdmAccelHandle hDevice, NvU8 attrib, NvU32 info); + +//----------------------------------------------------------------- +//--------------------------New API-------------------------------- +//----------------------------------------------------------------- + +typedef struct NvOdmAccelRec +{ + // Specifies use I2C or SPI to configure accelerometer registers. + NvU8 nBusType; + // Specifies accelerometer device address, for example, I2C write address. + NvU8 nDevAddr; + // Specifies the initial value that make accelerometer work, ACCELEROMETER_CONTROL_REGS_MAX_LENGHT is always 100. + NvDevCtrlReg CtrlRegsList[ACCELEROMETER_CONTROL_REGS_MAX_LENGHT]; + // Specifies the initial CtrlRegsList length. + NvU8 nLength; + // Specifies accelerometer chip ID. + NvU8 nChipID; + // Specifies the way to get accelerometer register information. + AccelerometerRegsRead RegsRead; + // Specifies the way to set accelerometer register information. + AccelerometerRegsWrite RegsWrite; + // Specifies I2C handle from the system. + NvOdmServicesI2cHandle hOdmI2C; + // Interrupt pin to ap15. + NvOdmServicesGpioHandle hGpioINT; + NvOdmGpioPinHandle hPinINT; + NvU32 GPIOPortINT; + NvU32 GPIOPinINT; + NvOdmOsSemaphoreHandle SemaphoreForINT; + NvOdmServicesGpioIntrHandle hGpioInterrupt; + NvOdmAccelIntType Data; + NvOdmServicesPmuHandle hPmu; + NvU32 VddId; + NvU32 I2CChannelId; + NvOdmAccelerometerCaps Caption; + NvOdmAccelPowerType PowerState; + // In real case, when the board put in frontispiece, the value from z axis + // should be g, but due to physical connect on different board, the axis + // should be remapped to the correct one. + NvOdmAccelAxisType AxisXMapping; + // If the physical direct is the same with our expection, the value + // should be set to 1, or else the value should be -1. + NvS32 AxisXDirection; + NvOdmAccelAxisType AxisYMapping; + NvS32 AxisYDirection; + NvOdmAccelAxisType AxisZMapping; + NvS32 AxisZDirection; +} NvOdmAccel; + +#if defined(__cplusplus) +} +#endif +#endif diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c new file mode 100644 index 000000000000..aedf87c837a9 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2010 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. + * + */ + +/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the + * WinCE Accelerometer Driver + */ + +#include "nvodm_accelerometer_bma150.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvos.h" + +#define NVODMACCELEROMETER_ENABLE_PRINTF 0 + +#if NVODMACCELEROMETER_ENABLE_PRINTF + #define NVODMACCELEROMETER_PRINTF(x) \ + do { \ + NvOdmOsPrintf x; \ + } while (0) +#else + #define NVODMACCELEROMETER_PRINTF(x) +#endif + +#define NV_BMA150_MAX_FORCE_IN_REG 512 // It indicates force register length. +#define NV_DEBOUNCE_TIME_MS 0 + +#define ENABLE_XYZ_POLLING 0 + +//FIXME: protect this variable using spinlock. +static volatile int g_WaitCounter = 0; +static void BMA150_ResetInterrupt(NvOdmAccelHandle hDevice); + +static void +SetPowerRail( + NvOdmServicesPmuHandle hPMUDevice, + NvU32 Id, + NvBool IsEnable) +{ + NvOdmServicesPmuVddRailCapabilities vddrailcap; + NvU32 settletime; + + if (hPMUDevice && Id) + { + NvOdmServicesPmuGetCapabilities(hPMUDevice, Id, &vddrailcap); + if (IsEnable) + { + NvOdmServicesPmuSetVoltage(hPMUDevice, Id, + vddrailcap.requestMilliVolts, &settletime); + } + else + { + NvOdmServicesPmuSetVoltage(hPMUDevice, Id, + vddrailcap.MinMilliVolts, &settletime); + } + NvOdmOsWaitUS(settletime); + } +} + +static void GpioInterruptHandler(void *arg) +{ + NvU32 pinValue; + NvOdmAccelHandle hDevice = (NvOdmAccelHandle)arg; + + NvOdmGpioGetState(hDevice->hGpioINT, hDevice->hPinINT, &pinValue); + if (pinValue == 1) + { + NVODMACCELEROMETER_PRINTF(("\r\nBMA150 Interrupt")); + g_WaitCounter = 10; + BMA150_ResetInterrupt(hDevice); + } else + NVODMACCELEROMETER_PRINTF(("\r\nBMA150 non-Interrupt")); + + if (pinValue == 1) + { + NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); + } + NvOdmGpioInterruptDone(hDevice->hGpioInterrupt); + return; +} + +static NvBool ConnectSemaphore(NvOdmAccelHandle hDevice) +{ + NvOdmGpioPinMode mode; + NvOdmInterruptHandler callback = + (NvOdmInterruptHandler)GpioInterruptHandler; + + hDevice->hGpioINT = (NvOdmServicesGpioHandle)NvOdmGpioOpen(); + if (!(hDevice->hGpioINT)) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdm Accelerometer : NvOdmGpioOpen Error \n")); + return NV_FALSE; + } + + hDevice->hPinINT = NvOdmGpioAcquirePinHandle(hDevice->hGpioINT, + hDevice->GPIOPortINT, + hDevice->GPIOPinINT); + hDevice->SemaphoreForINT = NvOdmOsSemaphoreCreate(0); + + if (!(hDevice->SemaphoreForINT)) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdm Accelerometer : NvOdmOsSemaphoreCreate Error \n")); + NvOdmGpioClose(hDevice->hGpioINT); + return NV_FALSE; + } + + mode = NvOdmGpioPinMode_InputInterruptHigh; + if (NvOdmGpioInterruptRegister(hDevice->hGpioINT, + &hDevice->hGpioInterrupt, hDevice->hPinINT, mode, callback, + hDevice, NV_DEBOUNCE_TIME_MS) == NV_FALSE) + { + return NV_FALSE; + } + + if (!(hDevice->hGpioInterrupt)) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdm Accelerometer : NvOdmGpioInterruptRegister Error \n")); + NvOdmGpioClose(hDevice->hGpioINT); + NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +WriteReg( + NvOdmAccelHandle hDevice, + NvU8 RegAddr, + NvU8* value, + NvU32 len) +{ + NvOdmI2cTransactionInfo TransactionInfo; + + if ( (NULL == hDevice) || (NULL == value) || + (len > I2C_ACCELRATOR_PACKET_SIZE-1 ) ) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdmI2c Set Regs Failed, max size is %d bytes\n", + I2C_ACCELRATOR_PACKET_SIZE-1)); + return NV_FALSE; + } + + s_WriteBuffer[0] = RegAddr; + NvOdmOsMemcpy(&s_WriteBuffer[1], value, len); + + TransactionInfo.Address = hDevice->nDevAddr; + TransactionInfo.Buf = s_WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = len+1; + + // Write the accelerator RegAddr (from where data is to be read). + if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, + I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) + return NV_FALSE; + + return NV_TRUE; +} + +static NvBool +ReadReg( + NvOdmAccelHandle hDevice, + NvU8 RegAddr, + NvU8* value, + NvU32 len) +{ + NvOdmI2cTransactionInfo TransactionInfo; + + if ( (NULL == hDevice) || (NULL == value) || + (len > I2C_ACCELRATOR_PACKET_SIZE-1 ) ) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdmI2c Get Regs Failed, max size is %d bytes\n", + I2C_ACCELRATOR_PACKET_SIZE-1)); + return NV_FALSE; + } + + s_WriteBuffer[0] = RegAddr; + TransactionInfo.Address = hDevice->nDevAddr; + TransactionInfo.Buf = s_WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 1; + + // Write the accelerometor RegAddr (from where data is to be read). + if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, + I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) + return NV_FALSE; + + s_ReadBuffer[0] = 0; + TransactionInfo.Address = (hDevice->nDevAddr| 0x1); + TransactionInfo.Buf = s_ReadBuffer; + TransactionInfo.Flags = 0; + TransactionInfo.NumBytes = len; + + //Read the data from the eeprom at the specified RegAddr + if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, 400, + I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) + return NV_FALSE; + + NvOdmOsMemcpy(value, &s_ReadBuffer[0], len); + return NV_TRUE; +} + +static NvBool BMA150_Init(NvOdmAccelHandle hAccel) +{ + NvU8 TestVal; + + ReadReg(hAccel, CHIP_ID_REG, &TestVal, 1); + if (TestVal != BMA150_CHIP_ID) + { + NVODMACCELEROMETER_PRINTF(("Unknown BMA150 ID = 0x%x\n", TestVal)); + goto error; + } + NVODMACCELEROMETER_PRINTF(("BMA150 ID is 0x%x\n", TestVal)); + + // Init Hw + if (!ReadReg(hAccel, RANGE_BWIDTH_REG, &TestVal, 1)) + goto error; + TestVal &= 0xE0; + TestVal |= 0x04; //Set bandwidth to 375hz + if (!WriteReg(hAccel, RANGE_BWIDTH_REG, &TestVal, 1)) + goto error; + + if (!ReadReg(hAccel, SMB150_CONF2_REG, &TestVal, 1)) + goto error; + // Enable Advanced interrupt(6), latch int(4) + TestVal |= (0 << 3) | (1 << 6) | (1 << 4); + if (!WriteReg(hAccel, SMB150_CONF2_REG, &TestVal, 1)) + goto error; + // Init Hw end + // Set mode + if (!ReadReg(hAccel, SMB150_CTRL_REG, &TestVal, 1)) + goto error; + TestVal &= 0xFE; + if (!WriteReg(hAccel, SMB150_CTRL_REG, &TestVal, 1)) + goto error; + // Set mode end + + // Set motion thres + if (!ReadReg(hAccel, MOTION_THRS_REG, &TestVal, 1)) + goto error; + TestVal = 0x0A; + if (!WriteReg(hAccel, MOTION_THRS_REG, &TestVal, 1)) + goto error; + // Set motion thres end + + // Set any motion int + if (!ReadReg(hAccel, SMB150_CONF1_REG, &TestVal, 1)) + goto error; + TestVal &= 0xFC; + TestVal |= (1 << 6) | (1 << 1) | (1 << 0); + if (!WriteReg(hAccel, SMB150_CONF1_REG, &TestVal, 1)) + goto error; + // Set any motion int end + NVODMACCELEROMETER_PRINTF(("\n BMA150_Init passed")); + return NV_TRUE; +error: + NVODMACCELEROMETER_PRINTF(("\n BMA150_Init failed")); + return NV_FALSE; +} + +static NvBool +BMA150_ReadXYZ( + NvOdmAccelHandle hDevice, + NvS32* X, + NvS32* Y, + NvS32* Z) +{ + NvU8 Data[6]; + NvBool NewData = 0; + + if (!ReadReg(hDevice, X_AXIS_LSB_REG, &Data[0], 6)) + return NV_FALSE; + NewData = ( (Data[0] & 0x1) || (Data[2] & 0x1) || (Data[4] & 0x1) ) ? 1 : 0; + + *X = ((Data[1] << 2) | (Data[0] >> 6)); + *Y = ((Data[3] << 2) | (Data[2] >> 6)); + *Z = ((Data[5] << 2) | (Data[4] >> 6)); + + // Preserve sign bits. + *X = *X << ((sizeof(*X)*8) - 10); + *X = *X >> ((sizeof(*X)*8) - 10); + *Y = *Y << ((sizeof(*Y)*8) - 10); + *Y = *Y >> ((sizeof(*Y)*8) - 10); + *Z = *Z << ((sizeof(*Z)*8) - 10); + *Z = *Z >> ((sizeof(*Z)*8) - 10); + return NewData; +} + +static void BMA150_ResetInterrupt(NvOdmAccelHandle hDevice) +{ + NvU8 Data = (1 << 6); + + WriteReg(hDevice, SMB150_CTRL_REG, &Data, 1); +} + +NvBool NvOdmAccelOpen(NvOdmAccelHandle* hDevice) +{ + NvU32 i; + NvOdmAccelHandle hAccel; + NvOdmIoModule IoModule = NvOdmIoModule_I2c; + const NvOdmPeripheralConnectivity *pConnectivity; + NvBool FoundGpio = NV_FALSE, FoundI2cModule = NV_FALSE; + + hAccel = NvOdmOsAlloc(sizeof(NvOdmAccel)); + if (hAccel == NULL) + { + NVODMACCELEROMETER_PRINTF(("Error Allocating NvOdmAccel. \n")); + return NV_FALSE; + } + NvOdmOsMemset(hAccel, 0, sizeof(NvOdmAccel)); + hAccel->nBusType = NV_ACCELEROMETER_BUS_I2C; + + // Info of accelerometer with current setting. + hAccel->Caption.MaxForceInGs = 2000; + hAccel->Caption.MaxTapTimeDeltaInUs = 255; + hAccel->Caption.NumMotionThresholds = 1; + hAccel->Caption.SupportsFreefallInt = 0; + hAccel->Caption.MaxSampleRate = 100; + hAccel->Caption.MinSampleRate = 3; + hAccel->PowerState = NvOdmAccelPower_Fullrun; + hAccel->AxisXMapping = NvOdmAccelAxis_Y; + hAccel->AxisXDirection = -1; + hAccel->AxisYMapping = NvOdmAccelAxis_X; + hAccel->AxisYDirection = 1; + hAccel->AxisZMapping = NvOdmAccelAxis_Z; + hAccel->AxisZDirection = -1; + + hAccel->hPmu = NvOdmServicesPmuOpen(); + if (!hAccel->hPmu) + { + NVODMACCELEROMETER_PRINTF(("NvOdmServicesPmuOpen Error \n")); + goto error; + } + + pConnectivity = (NvOdmPeripheralConnectivity*)NvOdmPeripheralGetGuid( + NV_ODM_GUID('b','m','a','1','5','0','a','c')); + if (!pConnectivity) + { + NvOdmOsDebugPrintf(("NvOdmPeripheralGetGuid doesn't detect\ + BMA150 accelerometer device\n")); + goto error; + } + + if (pConnectivity->Class != NvOdmPeripheralClass_Other) + goto error; + + for( i = 0; i < pConnectivity->NumAddress; i++) + { + switch(pConnectivity->AddressList[i].Interface) + { + case NvOdmIoModule_I2c: + case NvOdmIoModule_I2c_Pmu: + hAccel->I2CChannelId = pConnectivity->AddressList[i].Instance; + hAccel->nDevAddr = (NvU8)pConnectivity->AddressList[i].Address; + FoundI2cModule = NV_TRUE; + IoModule = pConnectivity->AddressList[i].Interface; + break; + case NvOdmIoModule_Gpio: + hAccel->GPIOPortINT = pConnectivity->AddressList[i].Instance; + hAccel->GPIOPinINT = pConnectivity->AddressList[i].Address; + FoundGpio = NV_TRUE; + break; + case NvOdmIoModule_Vdd: + hAccel->VddId = pConnectivity->AddressList[i].Address; + // Power on accelerometer according to Vddid + SetPowerRail(hAccel->hPmu, hAccel->VddId, NV_TRUE); + break; + default: + break; + } + } + + if (!FoundGpio || !FoundI2cModule) + { + NVODMACCELEROMETER_PRINTF(("Accelerometer : didn't find any periperal\ + in discovery query for touch device Error \n")); + goto error; + } + + // Open I2C handle. + hAccel->hOdmI2C = NvOdmI2cOpen(IoModule, hAccel->I2CChannelId); + if (!hAccel->hOdmI2C) + goto error; + + hAccel->RegsRead = ReadReg; + hAccel->RegsWrite = WriteReg; + + if (!BMA150_Init(hAccel)) + goto error; + if (!ConnectSemaphore(hAccel)) + goto error; + + *hDevice = hAccel; + return NV_TRUE; + error: + NVODMACCELEROMETER_PRINTF(("Error during BMA150 NvOdmAccelOpen\n")); + // Release all of resources requested. + if (hAccel) + { + SetPowerRail(hAccel->hPmu, hAccel->VddId, NV_FALSE); + NvOdmServicesPmuClose(hAccel->hPmu); + hAccel->hPmu = NULL; + NvOdmI2cClose(hAccel->hOdmI2C); + hAccel->hOdmI2C = NULL; + NvOdmOsFree(hAccel); + *hDevice = NULL; + } + return NV_FALSE; +} + +void NvOdmAccelClose(NvOdmAccelHandle hDevice) +{ + if (hDevice) + { + if (hDevice->SemaphoreForINT && hDevice->hGpioINT && + hDevice->hPinINT && hDevice->hGpioInterrupt) + { + NvOdmGpioInterruptUnregister(hDevice->hGpioINT, + hDevice->hPinINT, hDevice->hGpioInterrupt); + NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); + NvOdmGpioReleasePinHandle(hDevice->hGpioINT, hDevice->hPinINT); + NvOdmGpioClose(hDevice->hGpioINT); + } + NvOdmI2cClose(hDevice->hOdmI2C); + + // Power off accelermeter + SetPowerRail(hDevice->hPmu, hDevice->VddId, NV_FALSE); + if (hDevice->hPmu) + { + //NvAccelerometerSetPowerOn(0); + NvOdmServicesPmuClose(hDevice->hPmu); + } + } +} + +NvBool +NvOdmAccelSetIntForceThreshold( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + return NV_TRUE; +} + +NvBool +NvOdmAccelSetIntTimeThreshold( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + return NV_TRUE; +} + +NvBool +NvOdmAccelSetIntEnable( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvOdmAccelAxisType IntAxis, + NvU32 IntNum, + NvBool Toggle) +{ + return NV_TRUE; +} + +void +NvOdmAccelWaitInt( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType *IntType, + NvOdmAccelAxisType *IntMotionAxis, + NvOdmAccelAxisType *IntTapAxis) +{ + NV_ASSERT(hDevice); + NV_ASSERT(IntType); + NV_ASSERT(IntMotionAxis); + NV_ASSERT(IntTapAxis); + + if ((g_WaitCounter > 0) || ENABLE_XYZ_POLLING) + { + NvOdmOsSemaphoreWaitTimeout( hDevice->SemaphoreForINT, 300); + g_WaitCounter--; + } + else + NvOdmOsSemaphoreWait( hDevice->SemaphoreForINT); +} + +void NvOdmAccelSignal(NvOdmAccelHandle hDevice) +{ + NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); +} + +NvBool +NvOdmAccelGetAcceleration( + NvOdmAccelHandle hDevice, + NvS32 *AccelX, + NvS32 *AccelY, + NvS32 *AccelZ) +{ + NvS32 data; + NvBool NewData = 0; + NvS32 TempAccelX = 0; + NvS32 TempAccelY = 0; + NvS32 TempAccelZ = 0; + + NV_ASSERT(NULL != hDevice); + NV_ASSERT(NULL != AccelX); + NV_ASSERT(NULL != AccelY); + NV_ASSERT(NULL != AccelZ); + NewData = BMA150_ReadXYZ(hDevice, &TempAccelX, &TempAccelY, &TempAccelZ); + + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelX+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_BMA150_MAX_FORCE_IN_REG; + switch(hDevice->AxisXMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelY+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_BMA150_MAX_FORCE_IN_REG; + switch(hDevice->AxisYMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelZ+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_BMA150_MAX_FORCE_IN_REG; + switch(hDevice->AxisZMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + + NVODMACCELEROMETER_PRINTF(("\naccel output, x=%d,y=%d,z=%d, NewData=%d", + *AccelX, *AccelY, *AccelZ, NewData)); + return NewData; +} + +NvOdmAccelerometerCaps NvOdmAccelGetCaps(NvOdmAccelHandle hDevice) +{ + NV_ASSERT(NULL != hDevice); + return hDevice->Caption; +} + +NvBool NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate) +{ + return NV_TRUE; +} + +NvBool NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate) +{ + return NV_TRUE; +} + +NvBool +NvOdmAccelSetPowerState( + NvOdmAccelHandle hDevice, + NvOdmAccelPowerType PowerState) +{ + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h new file mode 100644 index 000000000000..1b8efb12ad0c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2010 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. + * + */ + +/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the + * WinCE Accelerometer Driver + */ + +#ifndef INCLUDED_NVODM_ACCELEROMETER_BMA150_H +#define INCLUDED_NVODM_ACCELEROMETER_BMA150_H + +#if defined(_cplusplus) +extern "C" +{ +#endif + +#include "nvodm_services.h" +#include "nvodm_accelerometer.h" + +/* BMA150 register address */ +#define CHIP_ID_REG 0x00 +#define VERSION_REG 0x01 +#define X_AXIS_LSB_REG 0x02 +#define X_AXIS_MSB_REG 0x03 +#define Y_AXIS_LSB_REG 0x04 +#define Y_AXIS_MSB_REG 0x05 +#define Z_AXIS_LSB_REG 0x06 +#define Z_AXIS_MSB_REG 0x07 +#define TEMP_RD_REG 0x08 +#define SMB150_STATUS_REG 0x09 +#define SMB150_CTRL_REG 0x0a +#define SMB150_CONF1_REG 0x0b +#define LG_THRESHOLD_REG 0x0c +#define LG_DURATION_REG 0x0d +#define HG_THRESHOLD_REG 0x0e +#define HG_DURATION_REG 0x0f +#define MOTION_THRS_REG 0x10 +#define HYSTERESIS_REG 0x11 +#define CUSTOMER1_REG 0x12 +#define CUSTOMER2_REG 0x13 +#define RANGE_BWIDTH_REG 0x14 +#define SMB150_CONF2_REG 0x15 + +#define OFFS_GAIN_X_REG 0x16 +#define OFFS_GAIN_Y_REG 0x17 +#define OFFS_GAIN_Z_REG 0x18 +#define OFFS_GAIN_T_REG 0x19 +#define OFFSET_X_REG 0x1a +#define OFFSET_Y_REG 0x1b +#define OFFSET_Z_REG 0x1c +#define OFFSET_T_REG 0x1d + +/* range and bandwidth */ +#define BMA_RANGE_2G 0 +#define BMA_RANGE_4G 1 +#define BMA_RANGE_8G 2 + +#define BMA_BW_25HZ 0 +#define BMA_BW_50HZ 1 +#define BMA_BW_100HZ 2 +#define BMA_BW_190HZ 3 +#define BMA_BW_375HZ 4 +#define BMA_BW_750HZ 5 +#define BMA_BW_1500HZ 6 + +/* mode settings */ +#define BMA_MODE_NORMAL 0 +#define BMA_MODE_SLEEP 1 + +#define BMA150_CHIP_ID 0x02 // RO - device identification +/* + * Defines the threshold source for the accelerometer. + */ +typedef enum +{ + /// Indicates the accelerometer generated interrupt by exceeding the x threshold. + NvOdmAccelerometerThresholdSource_X = 0, + + /// Indicates the accelerometer generated interrupt by exceeding the y threshold. + NvOdmAccelerometerThresholdSource_Y, + + /// Indicates the accelerometer generated interrupt by exceeding the z threshold. + NvOdmAccelerometerThresholdSource_Z, + + NvOdmAccelerometerThresholdSource_Force32 = 0x7FFFFFFF +} NvOdmAccelerometerThresholdSource; + +// Timeout for I2C transaction. +enum { I2C_ACCELRATOR_TRANSACTION_TIMEOUT = 1000 }; +// Maximum number of packetsize supported by the I2C controller. +enum { I2C_ACCELRATOR_PACKET_SIZE = 8}; +static NvU8 s_ReadBuffer[I2C_ACCELRATOR_PACKET_SIZE]; +static NvU8 s_WriteBuffer[I2C_ACCELRATOR_PACKET_SIZE]; + +#define INT_EVENT_TIMEOUT 100 +#define NV_ACCELEROMETER_BUS_I2C 0 +#define NV_ACCELEROMETER_BUS_SPI_3 1 +#define NV_ACCELEROMETER_BUS_SPI_4 2 + +/* + * Defines the way to read accelerometer registers. + */ +typedef NvBool +(*AccelerometerRegsRead)( + NvOdmAccelHandle hDevice, + NvU8 nRegOffset, + NvU8* nData, + NvU32 nLen); +/* + * Defines the way to write accelerometer registers. + */ +typedef NvBool +(*AccelerometerRegsWrite)( + NvOdmAccelHandle hDevice, + NvU8 nRegOffset, + NvU8* nData, + NvU32 nLen); +/* + * Holds register address and value pairs. + */ +typedef struct NvDevCtrlRegRec { + /// Holds the register offset. + NvU8 RegAddr; + /// Holds the value programmed into the upper address. + NvU8 RegValue; +} NvDevCtrlReg; +/* + * Max accelerometer registers number. + */ +#define ACCELEROMETER_CONTROL_REGS_MAX_LENGHT 100 +/* + * Max accelerometer callback functions number. + */ +#define ACCELEROMETER_CALLBACK_ARRAY_LENGTH 5 + +typedef struct NvOdmAccelRec +{ + // Specifies use I2C or SPI to configure accelerometer registers. + NvU8 nBusType; + // Specifies accelerometer device address, for example, I2C write address. + NvU8 nDevAddr; + // Specifies the initial value that make accelerometer work, + // ACCELEROMETER_CONTROL_REGS_MAX_LENGHT is always 100. + NvDevCtrlReg CtrlRegsList[ACCELEROMETER_CONTROL_REGS_MAX_LENGHT]; + // Specifies the initial CtrlRegsList length. + NvU8 nLength; + // Specifies accelerometer chip ID. + NvU8 nChipID; + // Specifies the way to get accelerometer register information. + AccelerometerRegsRead RegsRead; + // Specifies the way to set accelerometer register information. + AccelerometerRegsWrite RegsWrite; + // Specifies I2C handle from the system. + NvOdmServicesI2cHandle hOdmI2C; + // Interrupt pin to ap15. + NvOdmServicesGpioHandle hGpioINT; + NvOdmGpioPinHandle hPinINT; + NvU32 GPIOPortINT; + NvU32 GPIOPinINT; + NvOdmOsSemaphoreHandle SemaphoreForINT; + NvOdmServicesGpioIntrHandle hGpioInterrupt; + NvOdmAccelIntType Data; + NvOdmServicesPmuHandle hPmu; + NvU32 VddId; + NvU32 I2CChannelId; + NvOdmAccelerometerCaps Caption; + NvOdmAccelPowerType PowerState; + // In real case, when the board put in frontispiece, the value from z axis + // should be g, but due to physical connect on different board, the axis + // should be remapped to the correct one. + NvOdmAccelAxisType AxisXMapping; + // If the physical direct is the same with our expection, the value + // should be set to 1, or else the value should be -1. + NvS32 AxisXDirection; + NvOdmAccelAxisType AxisYMapping; + NvS32 AxisYDirection; + NvOdmAccelAxisType AxisZMapping; + NvS32 AxisZDirection; +} NvOdmAccel; + +#if defined(__cplusplus) +} +#endif +#endif diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c new file mode 100644 index 000000000000..b10e15f84754 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_stub.c @@ -0,0 +1,150 @@ +/* + * 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. + * + */ + +/** + * @file NvAccelerometer.c + * @brief <b>Device Driver for Accelerometer</b> + * + * @Description : Implementation of the WinCE Accelerometer driver + */ + +#include "nvodm_accelerometer.h" + + +NvBool +NvOdmAccelOpen(NvOdmAccelHandle* hDevice) +{ + *hDevice = NULL; + return NV_FALSE; +} + + +void +NvOdmAccelClose(NvOdmAccelHandle hDevice) +{ +} + + +/** + * After setting the force threshold, we should remove all of interrupt flag + * Which may be left from last threshold + */ +NvBool +NvOdmAccelSetIntForceThreshold(NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + return NV_FALSE; +} + +/** + * After setting the time threshold, we should remove all of interrupt flag + * Which may be left from last threshold + */ +NvBool +NvOdmAccelSetIntTimeThreshold(NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + return NV_FALSE; +} + + +/** + * After enable/disable threshold, we should remove all of interrupt flag + * Which may be left from last threshold + */ +NvBool +NvOdmAccelSetIntEnable(NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvOdmAccelAxisType IntAxis, + NvU32 IntNum, + NvBool Toggle) +{ + return NV_FALSE; +} + + +void +NvOdmAccelWaitInt(NvOdmAccelHandle hDevice, + NvOdmAccelIntType *IntType, + NvOdmAccelAxisType *IntMotionAxis, + NvOdmAccelAxisType *IntTapAxis) +{ +} + + +void NvOdmAccelSignal(NvOdmAccelHandle hDevice) +{ +} + +NvBool +NvOdmAccelGetAcceleration(NvOdmAccelHandle hDevice, + NvS32 *AccelX, + NvS32 *AccelY, + NvS32 *AccelZ) +{ + return NV_FALSE; +} + + +NvOdmAccelerometerCaps +NvOdmAccelGetCaps(NvOdmAccelHandle hDevice) +{ + NvOdmAccelerometerCaps caps; + NvOdmOsMemset(&caps, 0, sizeof(NvOdmAccelerometerCaps)); + + return caps; +} + + +NvBool +NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate) +{ + return NV_FALSE; +} + + +NvBool +NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate) +{ + return NV_FALSE; +} + +NvBool +NvOdmAccelSetPowerState(NvOdmAccelHandle hDevice, NvOdmAccelPowerType PowerState) +{ + return NV_FALSE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/Makefile b/arch/arm/mach-tegra/odm_kit/platform/battery/Makefile new file mode 100644 index 000000000000..9c1a4b43b4ab --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/battery/Makefile @@ -0,0 +1,11 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_battery.o +obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_battery_stub.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c new file mode 100644 index 000000000000..9a3d775f5308 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c @@ -0,0 +1,1896 @@ +/* + * Copyright (c) 2009-2010 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 "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvodm_battery_int.h" +#include "nvodm_battery.h" +#include "nvec.h" + +NvBool NvOdmBatteryPrivGetSlotStatusAndCapacityGuage( + NvOdmBatteryDevice *pBattContext, + NvOdmBatteryInstance BatteryInst, + NvU8 *BatterySlotStatus, + NvU8 *BatteryCapacityGuage); + +NvBool NvOdmBatteryPrivGetLifeTime( + NvOdmBatteryDevice *pBattContext, + NvOdmBatteryInstance BatteryInst, + NvU32 *BatteryLifeTime); + +NvBool NvOdmPrivBattGetBatteryVoltage( + NvOdmBatteryDevice *pBattContext, + NvOdmBatteryInstance BatteryInst, + NvU32 *BatteryVoltage); + +NvBool NvOdmBatteryPrivGetCurrent( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvS32 *pCurrent); + +NvBool NvOdmBatteryPrivGetAverageCurrent( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvS32 *pAverageCurrent); + +NvBool NvOdmBatteryPrivGetAverageTimeInterval( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pAverageTimeInterval); + +NvBool NvOdmBatteryPrivGetTemperature( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pBatteryTemp); + +NvBool NvOdmBatteryPrivGetRemainingCapacity( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pRemCapacity); + +NvBool NvOdmBatteryPrivGetLastFullChargeCapacity( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pLastFullChargeCapacity); + +NvBool NvOdmBatteryPrivGetCriticalCapacity( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pCriticalCapacity); + +NvBool NvOdmBatterySetRemCapacityAlarm( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU16 RemCapAlarm); + +#if BATTERY_EXTRA_INFO +NvBool NvOdmBatteryGetRemCapacityAlarm( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU16 *RemCapAlarm); + +NvBool NvOdmBatterySetConfiguration( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 Configuration); + +NvBool NvOdmBatteryGetConfiguration( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 *Configuration); +#endif + +#if NVODM_LOWBATTERY_GPIO_INT +/* + * GPIO interrupt handle for battery events + */ +static void +NvOdmBatteryGpioInterruptHandler(void *args) +{ + NvOdmBatteryDevice *pBattContext = args; + + NVODMBATTERY_PRINTF(("NvOdmBatteryGpioInterruptHandler:\n")); + + if (pBattContext) + { + pBattContext->BatteryEvent = NvOdmBatteryEventType_RemainingCapacityAlarm; + + if (pBattContext->hClientBattEventSem) + NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem); + } + + NvRmGpioInterruptDone(pBattContext->GpioIntrHandle); +} +#endif + +/* + * Gets the EC Firmware version number + */ +static NvError NvOdmBatteryPrivEcGetFirmwareVersion( + NvOdmBatteryDevice *pBattContext, + NvS32 *MajorVersion, + NvS32 *MinorVersion) +{ + NvEcControlGetFirmwareVersionResponsePayload FirmwareVersion; + NvError RetVal = NvSuccess; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvS32 Version = 0; + + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Control; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcControlSubtype_GetFirmwareVersion; + EcRequest.NumPayloadBytes = 0; + RetVal = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (RetVal != NvSuccess) + return RetVal; + + if (EcResponse.Status != NvEcStatus_Success) + return NvError_BadValue; + + NvOdmOsMemcpy(&FirmwareVersion, EcResponse.Payload, + EcResponse.NumPayloadBytes); + + Version = (FirmwareVersion.VersionMajor[1] << 24) | + (FirmwareVersion.VersionMajor[0] << 16) | + (FirmwareVersion.VersionMinor[1] << 8) | + (FirmwareVersion.VersionMinor[0] << 0); + + *MajorVersion = Version & 0xFF00; + *MinorVersion = Version & 0xFF; + return NvSuccess; +} + +static void NvOdmBatteryEventHandler(void *args) +{ + NvOdmBatteryDevice *pBattContext = args; + NvError NvStatus = NvError_Success; + NvEcEvent EcEvent = {0}; + NvU8 BattEvent = 0, ChargingState = 0; + + for (;;) + { + NvOdmOsSemaphoreWait(pBattContext->hBattEventSem); + + if (pBattContext->ExitThread == NV_TRUE) + break; + + NVODMBATTERY_PRINTF(("NvOdmBatteryEventHandler:hBattEventSem signaled\n")); + + if (pBattContext->hEcEventReg) + { + NvStatus = NvEcGetEvent(pBattContext->hEcEventReg, + &EcEvent, sizeof(NvEcEvent)); + if (NvStatus != NvError_Success) + { + NV_ASSERT(!"Could not receive EC event\n"); + continue; + } + + if (EcEvent.NumPayloadBytes == 0) + { + NV_ASSERT(!"Received Battery event with no data\n"); + continue; + } + + /* EcEvent.Payload[0] is Slot number */ + + /* EcEvent.Payload[1] has 4 lsb bits for battery events */ + BattEvent = EcEvent.Payload[1] & NVODM_BATTERY_EVENT_MASK; + + pBattContext->BatteryEvent = 0; + /* Read the Battery Slot status to set the proper event */ + if (BattEvent & NVODM_BATTERY_PRESENT_IN_SLOT) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Present; + + ChargingState = BattEvent >> NVODM_BATTERY_CHARGING_STATE_SHIFT; + ChargingState &= NVODM_BATTERY_CHARGING_STATE_MASK; + if (ChargingState == NVODM_BATTERY_CHARGING_STATE_IDLE) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Idle; + else if (ChargingState == NVODM_BATTERY_CHARGING_STATE_CHARGING) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Charging; + else if (ChargingState == NVODM_BATTERY_CHARGING_STATE_DISCHARGING) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Disharging; + + ChargingState = BattEvent >> NVODM_BATTERY_REM_CAP_ALARM_SHIFT; + if (ChargingState == NVODM_BATTERY_REM_CAP_ALARM_IS_SET) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_RemainingCapacityAlarm; + + /* Signal the Battery Client for arrival of the valid event */ + if ((pBattContext->hClientBattEventSem != 0) && + (pBattContext->BatteryEvent != 0)) + NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem); + } + } +} + +/** + * Gets the battery event. + * + * @param hDevice A handle to the EC. + * @param pBatteryEvent Battery events + * + */ +void NvOdmBatteryGetEvent( + NvOdmBatteryDeviceHandle hDevice, + NvU8 *pBatteryEvent) +{ + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetEvent.\n")); + + pBattContext = (NvOdmBatteryDevice *)hDevice; + + *pBatteryEvent = pBattContext->BatteryEvent; +} + +/** + * Sets the battery remaining capacity alarm threshold. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param RemCapAlarm [IN] Capacity Units + */ +NvBool NvOdmBatterySetRemCapacityAlarm( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU16 RemCapAlarm) +{ +#if NVEC_BATTERY_DISABLED + ; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatterySetRemCapacityAlarm.\n")); + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_SetRemainingCapacityAlarm; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = (RemCapAlarm & 0x00FF); + EcRequest.Payload[1] = (RemCapAlarm & 0xFF00) >> 8; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatterySetRemCapacityAlarm\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NVODMBATTERY_PRINTF(("EcResponse.Status failed for NvOdmBatterySetRemCapacityAlarm\n")); + return NV_FALSE; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatterySetRemCapacityAlarm.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +#if BATTERY_EXTRA_INFO +/** + * Gets the battery remaining capacity alarm threshold. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param RemCapAlarm [OUT] Capacity Units + */ +NvBool NvOdmBatteryGetRemCapacityAlarm( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU16 *RemCapAlarm) +{ +#if NVEC_BATTERY_DISABLED + *RemCapAlarm = 0; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetRemCapacityAlarm.\n")); + *RemCapAlarm = 0; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetRemainingCapacityAlarm; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatteryGetRemCapacityAlarm\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + *RemCapAlarm = EcResponse.Payload[0]; + *RemCapAlarm |= EcResponse.Payload[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetRemCapacityAlarm.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Sets the battery capacity unit configuration (mAh or 10mWh) + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param Configuration [IN] Capacity Unit + */ +NvBool NvOdmBatterySetConfiguration( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 Configuration) +{ +#if NVEC_BATTERY_DISABLED + ; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatterySetConfiguration.\n")); + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_SetConfiguration; + EcRequest.NumPayloadBytes = 1; + EcRequest.Payload[0] = Configuration; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatterySetConfiguration\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NVODMBATTERY_PRINTF(("EcResponse.Status failed for NvOdmBatterySetConfiguration\n")); + return NV_FALSE; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatterySetConfiguration.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the battery capacity unit configuration (mAh or 10mWh). + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param Configuration [OUT] Capacity Unit + */ +NvBool NvOdmBatteryGetConfiguration( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 *Configuration) +{ +#if NVEC_BATTERY_DISABLED + *Configuration = 0; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetConfiguration.\n")); + *Configuration = 0; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetConfiguration; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatteryGetConfiguration\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + *Configuration = EcResponse.Payload[0]; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetConfiguration.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} +#endif + +/** + * Gets the battery Current. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pCurrent [OUT] A pointer to the battery current + */ +NvBool NvOdmBatteryPrivGetCurrent( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvS32 *pCurrent) +{ +#if NVEC_BATTERY_DISABLED + *pCurrent = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetCurrentResponsePayload BatteryCurrent; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetCurrent.\n")); + *pCurrent = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetCurrent; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetCurrent\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryCurrent, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pCurrent = BatteryCurrent.PresentCurrent[0]; + *pCurrent |= BatteryCurrent.PresentCurrent[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetCurrent.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery Average Current. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pAverageCurrent [OUT] A pointer to the battery average current + */ +NvBool NvOdmBatteryPrivGetAverageCurrent( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvS32 *pAverageCurrent) +{ +#if NVEC_BATTERY_DISABLED + *pAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetAverageCurrentResponsePayload BatteryAverageCurrent; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetAverageCurrent.\n")); + *pAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetAverageCurrent; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetAverageCurrent\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryAverageCurrent, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pAverageCurrent = BatteryAverageCurrent.AverageCurrent[0]; + *pAverageCurrent |= BatteryAverageCurrent.AverageCurrent[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetAverageCurrent.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery Average time interval. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pAverageTimeInterval [OUT] A pointer to the battery average + * time interval + */ +NvBool NvOdmBatteryPrivGetAverageTimeInterval( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pAverageTimeInterval) +{ +#if NVEC_BATTERY_DISABLED + *pAverageTimeInterval = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetAveragingTimeIntervalResponsePayload \ + BatteryAverageTimeInterval; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetAverageTimeInterval.\n")); + *pAverageTimeInterval = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetAveragingTimeInterval; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetAverageTimeInterval\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryAverageTimeInterval, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pAverageTimeInterval = BatteryAverageTimeInterval.TimeInterval[0]; + *pAverageTimeInterval |= \ + BatteryAverageTimeInterval.TimeInterval[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetAverageTimeInterval.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery Temperature. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pBatteryTemp [OUT] A pointer to the battery Temperature + */ +NvBool NvOdmBatteryPrivGetTemperature( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pBatteryTemp) +{ +#if NVEC_BATTERY_DISABLED + *pBatteryTemp = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetTemperatureResponsePayload BatteryTemperature; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetTemperature.\n")); + *pBatteryTemp = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetTemperature; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetTemperature\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryTemperature, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pBatteryTemp = BatteryTemperature.Temperature[0]; + *pBatteryTemp |= BatteryTemperature.Temperature[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetTemperature.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery Manufacturer. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pBatteryManufacturer [OUT] A pointer to the battery Manufacturer + */ +NvBool NvOdmBatteryGetManufacturer( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 *pBatteryManufacturer) +{ +#if NVEC_BATTERY_DISABLED + *pBatteryManufacturer = '\0'; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetManufacturerResponsePayload BatteryManufacturer; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetManufacturer.\n")); + *pBatteryManufacturer = '\0'; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetManufacturer; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryGetManufacturer\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryManufacturer, EcResponse.Payload, + EcResponse.NumPayloadBytes); + NvOdmOsMemcpy(pBatteryManufacturer, BatteryManufacturer.Manufacturer, + EcResponse.NumPayloadBytes); + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetManufacturer.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery Model. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pBatteryModel [OUT] A pointer to the battery model + */ +NvBool NvOdmBatteryGetModel( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 *pBatteryModel) +{ +#if NVEC_BATTERY_DISABLED + *pBatteryModel = '\0'; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetModelResponsePayload BatteryModel; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetModel.\n")); + *pBatteryModel = '\0'; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetModel; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryGetModel\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryModel, EcResponse.Payload, + EcResponse.NumPayloadBytes); + NvOdmOsMemcpy(pBatteryModel, BatteryModel.Model, + EcResponse.NumPayloadBytes); + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetModel.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} +/** + * Gets the Battery Remaining Capacity. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pRemCapacity [OUT] A pointer to the battery remaining capacity + */ +NvBool NvOdmBatteryPrivGetRemainingCapacity( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pRemCapacity) +{ +#if NVEC_BATTERY_DISABLED + *pRemCapacity = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetCapacityRemainingResponsePayload BatteryRemCap; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetRemainingCapacity.\n")); + *pRemCapacity = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetCapacityRemaining; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetRemainingCapacity\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryRemCap, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pRemCapacity = BatteryRemCap.CapacityRemaining[0]; + *pRemCapacity |= BatteryRemCap.CapacityRemaining[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetRemainingCapacity.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery Last FullCharge Capacity + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pLastFullChargeCapacity [OUT] A pointer to the battery + * last fullcharge capacity + */ +NvBool NvOdmBatteryPrivGetLastFullChargeCapacity( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pLastFullChargeCapacity) +{ +#if NVEC_BATTERY_DISABLED + *pLastFullChargeCapacity = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetLastFullChargeCapacityResponsePayload \ + BatteryLastFullChargeCap; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("+NvOdmBatteryPrivGetLastFullChargeCapacity.\n")); + *pLastFullChargeCapacity = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetLastFullChargeCapacity; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetLastFullChargeCapacity\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryLastFullChargeCap, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pLastFullChargeCapacity = \ + BatteryLastFullChargeCap.LastFullChargeCapacity[0]; + *pLastFullChargeCapacity |= \ + BatteryLastFullChargeCap.LastFullChargeCapacity[1] << 8; + } + + NVODMBATTERY_PRINTF(("-NvOdmBatteryPrivGetLastFullChargeCapacity.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the Battery critical capacity + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pCriticalCapacity [OUT] A pointer to the battery critical capacity + */ +NvBool NvOdmBatteryPrivGetCriticalCapacity( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pCriticalCapacity) +{ +#if NVEC_BATTERY_DISABLED + *pCriticalCapacity = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetCriticalCapacityResponsePayload BatteryCriticalCap; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryPrivGetCriticalCapacity.\n")); + *pCriticalCapacity = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetCriticalCapacity; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetCriticalCapacity\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryCriticalCap, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pCriticalCapacity = BatteryCriticalCap.CriticalCapacity[0]; + *pCriticalCapacity |= BatteryCriticalCap.CriticalCapacity[1] << 8; + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryPrivGetCriticalCapacity.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets Battery Slot status and Capacity Guage. + * + * @param pBattContext [IN] Handle to the Battery Context. + * @param BatteryInst [IN] battery type. + * @param BatterySlotStatus [OUT] gives battery presence and charging status + * @param BatteryCapacityGuage [OUT] Battery's relative remaining capacity in % + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool +NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(NvOdmBatteryDevice *pBattContext, + NvOdmBatteryInstance BatteryInst, + NvU8 *BatterySlotStatus, + NvU8 *BatteryCapacityGuage) +{ +#if NVEC_BATTERY_DISABLED + return NV_FALSE; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + + NVODMBATTERY_PRINTF(("NvOdmBatteryPrivGetSlotStatusAndCapacityGuage:Enter")); + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetSlotStatus; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetSlotStatusAndCapacityGuage\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + *BatterySlotStatus = \ + EcResponse.Payload[NVODM_BATTERY_SLOT_STATUS_DATA]; + *BatteryCapacityGuage = \ + EcResponse.Payload[NVODM_BATTERY_CAPACITY_GUAGE_DATA]; + } + else + { + *BatterySlotStatus = 0; + *BatteryCapacityGuage = 0; + /* + * if the response status is unavailable (0x03) that means + * HW is unavailable + * in that case return TRUE to tell that Battery is not present. + */ + if (EcResponse.Status == NvEcStatus_Unavailable) + return NV_TRUE; + + return NV_FALSE; + } + + NVODMBATTERY_PRINTF(("NvOdmBatteryPrivGetSlotStatusAndCapacityGuage:Exit")); + return NV_TRUE; +#endif /* end of NVEC_BATTERY_DISABLED */ +} + +/** + * Gets Battery's Life time + * + * @param pBattContext [IN] Handle to the Battery Context. + * @param BatteryInst [IN] battery type. + * @param BatteryLifeTime [OUT] Estimated remaining time to empty + * for discharging. + * battery at present rate (in [min]) + * Report 0FFFFh if battery is not discharging + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryPrivGetLifeTime(NvOdmBatteryDevice *pBattContext, + NvOdmBatteryInstance BatteryInst, + NvU32 *BatteryLifeTime) +{ +#if NVEC_BATTERY_DISABLED + return NV_FALSE; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetTimeRemainingResponsePayload BattTimeRemain; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetTimeRemaining; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryPrivGetLifeTime\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BattTimeRemain, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *BatteryLifeTime = BattTimeRemain.TimeRemaining[0]; + *BatteryLifeTime |= BattTimeRemain.TimeRemaining[1] << 8; + } + else + { + NVODMBATTERY_PRINTF(("EcResponse.Status failed for \ + NvOdmBatteryPrivGetLifeTime\n")); + *BatteryLifeTime = 0; + return NV_FALSE; + } + + return NV_TRUE; +#endif /* end of NVEC_BATTERY_DISABLED */ +} + +/** + * Gets Battery's Present voltage + * + * @param pBattContext [IN] Handle to the Battery Context. + * @param BatteryInst [IN] battery type. + * @param BatteryVoltage [OUT] Battery's present voltage + * (16-bit unsigned value, in [mV]) + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmPrivBattGetBatteryVoltage(NvOdmBatteryDevice *pBattContext, + NvOdmBatteryInstance BatteryInst, + NvU32 *BatteryVoltage) +{ +#if NVEC_BATTERY_DISABLED + return NV_FALSE; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetVoltageResponsePayload BattVoltage; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetVoltage; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed \ + NvOdmPrivBattGetBatteryVoltage\n")); + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BattVoltage, EcResponse.Payload, + EcResponse.NumPayloadBytes); + NvOdmOsMemcpy(BatteryVoltage, BattVoltage.PresentVoltage, + sizeof(BattVoltage.PresentVoltage)); + } + else + { + NVODMBATTERY_PRINTF(("EcResponse.Status failed in \ + NvOdmPrivBattGetBatteryVoltage\n")); + *BatteryVoltage = 0; + return NV_FALSE; + } + + return NV_TRUE; +#endif /* end of NVEC_BATTERY_DISABLED */ +} + +/** + * Openes the battery device handle + * + * @param hDevice [OUT] handle to Battery Device. + * + * @return NV_TRUE on success. + */ +NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, + NvOdmOsSemaphoreHandle *hOdmSemaphore) +{ + NvOdmBatteryDevice *pBattContext = NULL; + NvError NvStatus = NvError_Success; + NvEcEventType EventTypes[] = {NvEcEventType_Battery}; + NvS32 MajorVersion = 0, MinorVersion = 0; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; +#if NVODM_LOWBATTERY_GPIO_INT + NvOsInterruptHandler IntrHandler = {NULL}; +#endif + NvU32 BatteryDesignCap = 0; + NvU16 RemCapAlarm = 0; + + NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryDeviceOpen. \n")); + + /* Allocate the context */ + pBattContext = NvOdmOsAlloc(sizeof(NvOdmBatteryDevice)); + if (!pBattContext) + { + NVODMBATTERY_PRINTF(("NvOdmOsAlloc failed to allocate pBattContext.")); + return NV_FALSE; + } + + NvOdmOsMemset(pBattContext, 0, sizeof(NvOdmBatteryDevice)); + + /* Get nvec handle */ + NvStatus = NvEcOpen(&pBattContext->hEc, 0 /* instance */); + if (NvStatus != NvError_Success) + { + NVODMBATTERY_PRINTF(("NvEcOpen failed for NvOdmBatteryDeviceOpen.\n")); + goto Cleanup; + } + + /* Get the EC Firmware version */ + NvStatus = NvOdmBatteryPrivEcGetFirmwareVersion(pBattContext, + &MajorVersion, + &MinorVersion); + if (NvStatus != NvError_Success) + { + goto Cleanup; + } + + pBattContext->ECVersion = MinorVersion; + NVODMBATTERY_PRINTF(("EC Firmware Version = 0x%x\n", MinorVersion)); + + if (hOdmSemaphore != NULL && *hOdmSemaphore != NULL) + { + pBattContext->hClientBattEventSem = *hOdmSemaphore; + + /* Semaphore to receive Battery events from EC */ + pBattContext->hBattEventSem = NvOdmOsSemaphoreCreate(0); + if (!pBattContext->hBattEventSem) + { + goto Cleanup; + } + + /* Thread to handle Battery events */ + pBattContext->hBattEventThread = NvOdmOsThreadCreate( + (NvOdmOsThreadFunction)NvOdmBatteryEventHandler, + (void *)pBattContext); + if (!pBattContext->hBattEventThread) + { + goto Cleanup; + } + + if (pBattContext->ECVersion >= NVODM_BATTERY_EC_FIRMWARE_VER_R04) + { +#if NVODM_WAKEUP_FROM_BATTERY_EVENT + /* Configure the Batter present event as a wakeup */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcBatterySubtype_ConfigureWake; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE; + EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT +#if NVODM_BATTERY_LOW_CAPACITY_ALARM + | NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT +#endif + ; + + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvStatus != NvSuccess) + goto Cleanup; + + if (EcResponse.Status != NvEcStatus_Success) + goto Cleanup; +#endif + +#if NVODM_WAKEUP_FROM_AC_EVENT + /* Configure the AC present event as a wakeup */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_System; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcSystemSubtype_ConfigureWake; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = NVEC_SYSTEM_REPORT_ENABLE_0_ACTION_ENABLE; + EcRequest.Payload[1] = NVEC_SYSTEM_STATE1_0_AC_PRESENT; + + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvStatus != NvSuccess) + goto Cleanup; + + if (EcResponse.Status != NvEcStatus_Success) + goto Cleanup; +#endif + /* Configure the Battery events */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcBatterySubtype_ConfigureEventReporting; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE; + /* Bit 0 = Present State event */ + /* Bit 1 = Charging State event */ + /* Bit 2 = Remaining Capacity Alaram event */ + EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT | + NVODM_BATTERY_SET_CHARGING_EVENT| + NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT; + + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvStatus != NvSuccess) + goto Cleanup; + + if (EcResponse.Status != NvEcStatus_Success) + goto Cleanup; + + /* Get the design capacity */ + NvOdmBatteryGetBatteryFullLifeTime(pBattContext, NvOdmBatteryInst_Main, + &BatteryDesignCap); + /* Set the remaining capacity alarm for 10% of the design capacity */ + RemCapAlarm = (BatteryDesignCap * 10)/100; + NvOdmBatterySetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, RemCapAlarm); + } + + /* Register for Battery events */ + NvStatus = NvEcRegisterForEvents( + pBattContext->hEc, + &pBattContext->hEcEventReg, + (NvOsSemaphoreHandle)pBattContext->hBattEventSem, + sizeof(EventTypes)/sizeof(NvEcEventType), + EventTypes, + 1, + sizeof(NvEcEvent)); + if (NvStatus != NvError_Success) + { + goto Cleanup; + } + +#if NVODM_LOWBATTERY_GPIO_INT + NvStatus = NvRmOpen(&pBattContext->hRm, 0); + if (NvStatus != NvError_Success) + goto Cleanup; + + NvStatus = NvRmGpioOpen(pBattContext->hRm, &pBattContext->hGpio); + if (NvStatus != NvError_Success) + goto Cleanup; + + pBattContext->pGpioPinInfo = NvOdmQueryGpioPinMap( + NvOdmGpioPinGroup_Battery, + 0, + &pBattContext->PinCount); + if (pBattContext->pGpioPinInfo != NULL) + { + + IntrHandler = (NvOsInterruptHandler)NvOdmBatteryGpioInterruptHandler; + + if (pBattContext->pGpioPinInfo[0].Port != 0 && + pBattContext->pGpioPinInfo[0].Pin != 0) + { + + NvRmGpioAcquirePinHandle( + pBattContext->hGpio, + pBattContext->pGpioPinInfo[0].Port, + pBattContext->pGpioPinInfo[0].Pin, + &pBattContext->hPin); + if (!pBattContext->hPin) + { + goto Cleanup; + } + + /* Register to receive GPIO events */ + NvStatus = NvRmGpioInterruptRegister( + pBattContext->hGpio, + pBattContext->hRm, + pBattContext->hPin, + IntrHandler, + NvRmGpioPinMode_InputInterruptAny, + pBattContext, + &pBattContext->GpioIntrHandle, + 0); + if (NvStatus != NvError_Success) + { + goto Cleanup; + } + + NvStatus = NvRmGpioInterruptEnable(pBattContext->GpioIntrHandle); + if (NvStatus != NvError_Success) + { + goto Cleanup; + } + } + } +#endif + } + + *hDevice = pBattContext; + NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryDeviceOpen.\n")); + return NV_TRUE; + +Cleanup: + NvOdmBatteryDeviceClose(pBattContext); + + return NV_FALSE; +} + +/** + * Closes the battery device + * + * @param hDevice [IN] handle to Battery Device. + * + * @return void. + */ +void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice) +{ + NvOdmBatteryDevice *pBattContext = NULL; + + pBattContext = (NvOdmBatteryDevice *)hDevice; + +#if NVODM_LOWBATTERY_GPIO_INT + if (pBattContext->hGpio) + { + if (pBattContext->GpioIntrHandle) + { + NvRmGpioInterruptUnregister(pBattContext->hGpio, pBattContext->hRm, + pBattContext->GpioIntrHandle); + pBattContext->GpioIntrHandle = NULL; + } + + NvRmGpioReleasePinHandles(pBattContext->hGpio, &pBattContext->hPin, + pBattContext->PinCount); + NvRmGpioClose(pBattContext->hGpio); + } + + if (pBattContext->hRm) + { + NvRmClose(pBattContext->hRm); + pBattContext->hRm = NULL; + } +#endif + + if (pBattContext->hBattEventSem) + { + pBattContext->ExitThread = NV_TRUE; + NvOdmOsSemaphoreSignal(pBattContext->hBattEventSem); + NvOdmOsSemaphoreDestroy(pBattContext->hBattEventSem); + pBattContext->hBattEventSem = NULL; + } + + if (pBattContext->hBattEventThread) + { + NvOdmOsThreadJoin(pBattContext->hBattEventThread); + pBattContext->hBattEventThread = NULL; + } + + if (pBattContext->hEc) + { + if (pBattContext->hEcEventReg) + { + NvEcUnregisterForEvents(pBattContext->hEcEventReg); + pBattContext->hEcEventReg = NULL; + } + + NvEcClose(pBattContext->hEc); + pBattContext->hEc = NULL; + } + + if (pBattContext) + NvOdmOsFree(pBattContext); +} + +/** + * Gets the AC line status. + * + * @param hDevice [IN] A handle to the EC. + * @param pStatus [OUT] A pointer to the AC line + * status returned by the ODM. + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryGetAcLineStatus( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryAcLineStatus *pStatus) +{ +#if NVEC_BATTERY_DISABLED + *pStatus = NvOdmBatteryAcLine_Online; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvU8 ACStatus = 0; + NvEcSystemGetStateResponsePayload SysQueryState; + + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetAcLineStatus.\n")); + + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* For R01 EC Firware report AC is online as it has not support for this */ + if (pBattContext->ECVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01) + { + *pStatus = NvOdmBatteryAcLine_Online; + return NV_TRUE; + } + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_System; + EcRequest.RequestSubtype = NvEcSystemSubtype_GetStatus; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryGetAcLineStatus\n")); + *pStatus = NvOdmBatteryAcLine_Num; + return NV_FALSE; + } + + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&SysQueryState, EcResponse.Payload, + EcResponse.NumPayloadBytes); + + ACStatus = SysQueryState.State[NVODM_BATTERY_SYSTEM_STATE_DATA1]; + + /* AC is present or not */ + if (ACStatus & NVODM_BATTERY_SYSTEM_STATE_AC_PRESENT) + { + *pStatus = NvOdmBatteryAcLine_Online; + } + else + { + *pStatus = NvOdmBatteryAcLine_Offline; + } + } + + NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetAcLineStatus.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the battery status. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pStatus [OUT] A pointer to the battery + * status returned by the ODM. + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryGetBatteryStatus( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU8 *pStatus) +{ +#if NVEC_BATTERY_DISABLED + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; +#else + NvU8 BatterySlotStatus = 0, BatteryCapacityGuage = 0, + BattPresentState = 0, BattChargingState = 0; + NvU32 BatteryVoltage = 0; /* in mV */ + NvOdmBatteryDevice *pBattContext = NULL; + + pBattContext = (NvOdmBatteryDevice *)hDevice; + + NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetBatteryStatus.\n")); + + *pStatus = 0; + + /* + * For R01 firmware Battery support is not present. + */ + if (pBattContext->ECVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01) + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + NVODMBATTERY_PRINTF(("NvOdmBatteryGetBatteryStatus:EC Firmware R01")); + return NV_TRUE; + } + + if (BatteryInst == NvOdmBatteryInst_Main) + { + if(NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(pBattContext, + NvOdmBatteryInst_Main, + &BatterySlotStatus, + &BatteryCapacityGuage)) + { + BattPresentState = BatterySlotStatus & NVODM_BATTERY_PRESENT_IN_SLOT; + if (BattPresentState == NVODM_BATTERY_PRESENT_IN_SLOT) + { + BattChargingState = BatterySlotStatus >> NVODM_BATTERY_CHARGING_STATE_SHIFT; + BattChargingState &= NVODM_BATTERY_CHARGING_STATE_MASK; + if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_CHARGING) + *pStatus |= NVODM_BATTERY_STATUS_CHARGING; + else if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_DISCHARGING) + *pStatus |= NVODM_BATTERY_STATUS_DISCHARGING; + else if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_IDLE) + *pStatus |= NVODM_BATTERY_STATUS_IDLE; + } + else + { + *pStatus = NVODM_BATTERY_STATUS_NO_BATTERY; + return NV_TRUE; + } + } + else + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + return NV_TRUE; + } + + /* Get the battery voltage to detetmine the Battery Flag */ + if (NvOdmPrivBattGetBatteryVoltage(pBattContext, NvOdmBatteryInst_Main, + &BatteryVoltage)) + { + if (BatteryVoltage >= NVODM_BATTERY_HIGH_VOLTAGE_MV) + *pStatus |= NVODM_BATTERY_STATUS_HIGH; + else if (BatteryVoltage >= NVODM_BATTERY_LOW_VOLTAGE_MV) + *pStatus |= NVODM_BATTERY_STATUS_LOW; + else + { + *pStatus |= NVODM_BATTERY_STATUS_CRITICAL; + /* + * Additional flag which tells battery is very critical + * and needs system shutdown. + */ + if (BatteryVoltage <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV) + *pStatus |= NVODM_BATTERY_STATUS_VERY_CRITICAL; + } + } + else + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + return NV_TRUE; + } + } + else + { + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + } + + NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetBatteryStatus.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ + return NV_TRUE; +} + +/** + * Gets the battery data. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pData [OUT] A pointer to the battery + * data returned by the ODM. + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryGetBatteryData( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvOdmBatteryData *pData) +{ + NvOdmBatteryData BatteryData; + NvU32 BatteryVoltage = 0, BatteryLifeTime = 0; + NvS32 BatteryCurrent = 0, BatteryAvgCurrent = 0; + NvU32 BatteryAvgTimeInterval = 0; + NvU32 BatteryTemp = 0; + NvU32 BattRemCap = 0, BattLastChargeFullCap = 0, BattCriticalCap = 0; +#if BATTERY_EXTRA_INFO + NvU16 RemCapAlarm = 0; + NvU8 ConfigurationUnit = NVEC_BATTERY_CONFIGURATION_0_CAPACITY_UNITS_MAH; + NvU8 BattManufact[NVEC_MAX_RESPONSE_STRING_SIZE] = {0}, + BattModel[NVEC_MAX_RESPONSE_STRING_SIZE] = {0}; +#endif + NvOdmBatteryDevice *pBattContext = NULL; + NvU8 BatterySlotStatus = 0, BatteryCapacityGuage = 0; + + NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetBatteryData.\n")); + + pBattContext = (NvOdmBatteryDevice *)hDevice; + + BatteryData.BatteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryCurrent = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryTemperature = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryRemainingCapacity = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryLastChargeFullCapacity = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryCriticalCapacity = NVODM_BATTERY_DATA_UNKNOWN; + + NV_ASSERT(hDevice); + NV_ASSERT(pData); + NV_ASSERT(BatteryInst <= NvOdmBatteryInst_Num); + + if (BatteryInst == NvOdmBatteryInst_Main) + { + if (NvOdmPrivBattGetBatteryVoltage(pBattContext, NvOdmBatteryInst_Main, + &BatteryVoltage)) + { + BatteryData.BatteryVoltage = BatteryVoltage; + } + + if(NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(pBattContext, + NvOdmBatteryInst_Main, &BatterySlotStatus, &BatteryCapacityGuage)) + { + BatteryData.BatteryLifePercent = BatteryCapacityGuage; + } + +#if BATTERY_EXTRA_INFO + /* ConfigurationUnit = NVEC_BATTERY_CONFIGURATION_0_CAPACITY_UNITS_10MWH; */ + NvOdmBatterySetConfiguration(pBattContext, NvOdmBatteryInst_Main, ConfigurationUnit); + NvOdmBatteryGetConfiguration(pBattContext, NvOdmBatteryInst_Main, &ConfigurationUnit); +#endif + + if(NvOdmBatteryPrivGetLifeTime(pBattContext, NvOdmBatteryInst_Main, &BatteryLifeTime)) + { + BatteryData.BatteryLifeTime = BatteryLifeTime; + } + + if(NvOdmBatteryPrivGetCurrent(pBattContext, NvOdmBatteryInst_Main, + &BatteryCurrent)) + { + BatteryData.BatteryCurrent = BatteryCurrent; + } + + if(NvOdmBatteryPrivGetAverageCurrent(pBattContext, + NvOdmBatteryInst_Main, &BatteryAvgCurrent)) + { + BatteryData.BatteryAverageCurrent = BatteryAvgCurrent; + } + + if(NvOdmBatteryPrivGetAverageTimeInterval(pBattContext, + NvOdmBatteryInst_Main, &BatteryAvgTimeInterval)) + { + BatteryData.BatteryAverageInterval = BatteryAvgTimeInterval; + } + + if(NvOdmBatteryPrivGetTemperature(pBattContext, NvOdmBatteryInst_Main, + &BatteryTemp)) + { + BatteryData.BatteryTemperature = BatteryTemp; + } + + if(NvOdmBatteryPrivGetRemainingCapacity(pBattContext, + NvOdmBatteryInst_Main, &BattRemCap)) + { + BatteryData.BatteryRemainingCapacity = BattRemCap; + } + + if(NvOdmBatteryPrivGetLastFullChargeCapacity(pBattContext, + NvOdmBatteryInst_Main, &BattLastChargeFullCap)) + { + BatteryData.BatteryLastChargeFullCapacity = BattLastChargeFullCap; + } + + if(NvOdmBatteryPrivGetCriticalCapacity(pBattContext, + NvOdmBatteryInst_Main, &BattCriticalCap)) + { + BatteryData.BatteryCriticalCapacity = BattCriticalCap; + } + +#if BATTERY_EXTRA_INFO + /* RemCapAlarm = 0x0101;*/ /* Some random value */ + NvOdmBatterySetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, RemCapAlarm); + RemCapAlarm = 0; + NvOdmBatteryGetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, &RemCapAlarm); + + NvOdmBatteryGetManufacturer(pBattContext, NvOdmBatteryInst_Main, BattManufact); + NvOdmBatteryGetModel(pBattContext, NvOdmBatteryInst_Main, BattModel); +#endif + + *pData = BatteryData; + } + else + { + *pData = BatteryData; + } + + NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetBatteryData.\n")); +#if NVEC_BATTERY_DISABLED + *pData = BatteryData; +#endif + return NV_TRUE; +} + +/** + * Gets the battery full life time. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pLifeTime [OUT] A pointer to the battery + * full life time returned by the ODM. + * + */ +void NvOdmBatteryGetBatteryFullLifeTime( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvU32 *pLifeTime) +{ +#if NVEC_BATTERY_DISABLED + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetDesignCapacityResponsePayload BatteryCapacity; + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetBatteryFullLifeTime.\n")); + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetDesignCapacity; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryGetBatteryFullLifeTime\n")); + } + else + { + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryCapacity, EcResponse.Payload, + EcResponse.NumPayloadBytes); + *pLifeTime = BatteryCapacity.DesignCapacity[0]; + *pLifeTime |= BatteryCapacity.DesignCapacity[1] << 8; + } + } + + NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetBatteryFullLifeTime.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ +} + + +/** + * Gets the battery chemistry. + * + * @param hDevice [IN] A handle to the EC. + * @param BatteryInst [IN] The battery type. + * @param pChemistry [OUT] A pointer to the battery + * chemistry returned by the ODM. + * + */ +void NvOdmBatteryGetBatteryChemistry( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance BatteryInst, + NvOdmBatteryChemistry *pChemistry) +{ +#if NVEC_BATTERY_DISABLED + *pChemistry = NVODM_BATTERY_DATA_UNKNOWN; +#else + NvError NvStatus = NvError_Success; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; + NvEcBatteryGetTypeResponsePayload BatteryType; + + NvOdmBatteryDevice *pBattContext = NULL; + + NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryGetBatteryChemistry.\n")); + *pChemistry = NVODM_BATTERY_DATA_UNKNOWN; + + pBattContext = (NvOdmBatteryDevice *)hDevice; + + /* Fill up request structure */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = NvEcBatterySubtype_GetType; + EcRequest.NumPayloadBytes = 0; + EcRequest.Payload[0] = 0; + + /* Request to EC */ + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvSuccess != NvStatus) + { + NVODMBATTERY_PRINTF(("NvEcSendRequest failed for \ + NvOdmBatteryGetBatteryChemistry\n")); +} + else + { + if(EcResponse.Status == NvEcStatus_Success) + { + NvOdmOsMemcpy(&BatteryType, EcResponse.Payload, + EcResponse.NumPayloadBytes); + + if(!NvOsStrncmp(BatteryType.Type, "LION", + EcResponse.NumPayloadBytes)) + *pChemistry = NvOdmBatteryChemistry_LION; + else if(!NvOsStrncmp(BatteryType.Type, "Alkaline", + EcResponse.NumPayloadBytes)) + *pChemistry = NvOdmBatteryChemistry_Alkaline; + else if(!NvOsStrncmp(BatteryType.Type, "NICD", + EcResponse.NumPayloadBytes)) + *pChemistry = NvOdmBatteryChemistry_NICD; + else if(!NvOsStrncmp(BatteryType.Type, "NIMH", + EcResponse.NumPayloadBytes)) + *pChemistry = NvOdmBatteryChemistry_NIMH; + else if(!NvOsStrncmp(BatteryType.Type, "LIPOLY", + EcResponse.NumPayloadBytes)) + *pChemistry = NvOdmBatteryChemistry_LIPOLY; + else if(!NvOsStrncmp(BatteryType.Type, "XINCAIR", + EcResponse.NumPayloadBytes)) + *pChemistry = NvOdmBatteryChemistry_XINCAIR; + } + } + + NVODMBATTERY_PRINTF(("[EXIT] NvOdmBatteryGetBatteryChemistry.\n")); +#endif /* end of NVEC_BATTERY_DISABLED */ +} diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h new file mode 100644 index 000000000000..3ec7313a0bd4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h @@ -0,0 +1,181 @@ +/* + * Copyright (c) 2009-2010 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_NVODM_BATTERY_INT_H +#define INCLUDED_NVODM_BATTERY_INT_H + +#include "nvodm_query_gpio.h" +#include "nvrm_gpio.h" +#include "nvodm_services.h" +#include "nvec.h" + +/* Module debug msg: 0=disable, 1=enable */ +#define NVODMBATTERY_ENABLE_PRINTF (0) + +#if (NVODMBATTERY_ENABLE_PRINTF) +#define NVODMBATTERY_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODMBATTERY_PRINTF(x) +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +/****************************************************************************/ +/* + * Macro to disable EC calls for battery operations + * until EC firware supports it + */ +#define NVEC_BATTERY_DISABLED 0 +/* + * Some extra battery info added which is not yet part of the + * BatteryData struct. + * Enable it to verify the these extra info with the EC firware + */ +#define BATTERY_EXTRA_INFO 0 + +/* Enable to wakeup the AP from suspend */ +#define NVODM_WAKEUP_FROM_BATTERY_EVENT 1 +#define NVODM_WAKEUP_FROM_AC_EVENT 1 + +/* Enable the Low Battery GPIO Interrupt */ +#define NVODM_LOWBATTERY_GPIO_INT 1 + +/* Enable low capacity alarm wakeup */ +#define NVODM_BATTERY_LOW_CAPACITY_ALARM 1 +/****************************************************************************/ + +#define NVODM_BATTERY_NUM_BATTERY_SLOTS_MASK 0x0F + +/* Battery Slot Status and Capacity Gauge Report */ +/* Data Byte 3 : Battery Slot Status */ +#define NVODM_BATTERY_SLOT_STATUS_DATA 0 +/* + * Data Byte 4 : Battery Capacity Gauge : + * Battery's relative remaining capacity in % + */ +#define NVODM_BATTERY_CAPACITY_GUAGE_DATA 1 + +/* + * Battery Slot Status : + * Bit 0 = Present State: + * 1 = Battery is present in the respective slot + */ +#define NVODM_BATTERY_PRESENT_IN_SLOT 0x01 + +#define NVODM_BATTERY_CHARGING_STATE_SHIFT 1 +#define NVODM_BATTERY_CHARGING_STATE_MASK 0x03 + +/* Battery Slot Status : Bits 1-2 = Charging state */ +#define NVODM_BATTERY_CHARGING_STATE_IDLE 0x00 +#define NVODM_BATTERY_CHARGING_STATE_CHARGING 0x01 +#define NVODM_BATTERY_CHARGING_STATE_DISCHARGING 0x02 +#define NVODM_BATTERY_CHARGING_STATE_RESERVED 0x03 + +/* Remaining capacity alarm bit is 3rd in slot status */ +#define NVODM_BATTERY_REM_CAP_ALARM_SHIFT 3 +#define NVODM_BATTERY_REM_CAP_ALARM_IS_SET 1 + +/* Response System Status : Data Byte 3 System State Bits 7-0 */ +#define NVODM_BATTERY_SYSTEM_STATE_DATA1 0 +/* Response System Status : Data Byte 4 System State Bits 15-8 */ +#define NVODM_BATTERY_SYSTEM_STATE_DATA2 1 +/* System State Flags : AC Present : System State Bit 0 */ +#define NVODM_BATTERY_SYSTEM_STATE_AC_PRESENT 0x01 + +#define NVODM_BATTERY_CHARGING_RATE_DATA_BYTES 3 +#define NVODM_BATTERY_CHARGING_RATE_UNIT 3 + +/* Threshold for battery status.*/ +#define NVODM_BATTERY_FULL_VOLTAGE_MV 12600 +#define NVODM_BATTERY_HIGH_VOLTAGE_MV 10200 +#define NVODM_BATTERY_LOW_VOLTAGE_MV 10000 +#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 9500 + +#define NVODM_BATTERY_EC_FIRMWARE_VER_R01 2 +#define NVODM_BATTERY_EC_FIRMWARE_VER_R04 8 + +/* Bit 0 = Present State event */ +/* Bit 1 = Charging State event */ +/* Bit 2 = Remaining Capacity Alaram event */ +#define NVODM_BATTERY_SET_PRESENT_EVENT 0x01 +#define NVODM_BATTERY_SET_CHARGING_EVENT 0x02 +#define NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT 0x04 + +/* + * Bit 0 => 0=Not Present, 1=Present + * Bit 1:2 => 00=Idle, 01=Charging,10=Discharging, 11=Reserved + * Bit 3 => 1=Remaining Capacity Alaram set + */ +#define NVODM_BATTERY_EVENT_MASK 0x0F + +typedef enum +{ + NvOdmBattCharingUnit_mW, /* Milli Watt */ + NvOdmBattCharingUnit_mA, /* Milli Amps */ + NvOdmBattCharingUnit_10mW, /* Milli Watt * 10 */ + + NvOdmBattCharingUnit_Num, + NvOdmBattCharingUnit_Max = 0x7fffffff + +} NvOdmBattCharingUnit; + +typedef struct NvOdmBatteryDeviceRec +{ + NvEcHandle hEc; + NvEcEventRegistrationHandle hEcEventReg; + NvOdmOsSemaphoreHandle hBattEventSem; + NvOdmOsSemaphoreHandle hClientBattEventSem; + NvOdmOsThreadHandle hBattEventThread; +#if NVODM_LOWBATTERY_GPIO_INT + const NvOdmGpioPinInfo *pGpioPinInfo; + NvRmGpioPinHandle hPin; + NvRmGpioInterruptHandle GpioIntrHandle; + NvU32 PinCount; + NvRmDeviceHandle hRm; + NvRmGpioHandle hGpio; +#endif + NvU8 BatteryEvent; + NvU8 ECVersion; + NvBool ExitThread; +} NvOdmBatteryDevice; + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif /* INCLUDED_NVODM_BATTERY_INT_H */ + diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c new file mode 100644 index 000000000000..63f51d9bdbd2 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_stub.c @@ -0,0 +1,174 @@ +/* + * Copyright (c) 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 "nvcommon.h" +#include "nvodm_battery.h" + +typedef struct NvOdmBatteryDeviceRec +{ + NvBool bBattPresent; + NvBool bBattFull; +} NvOdmBatteryDevice; + +/** + * Gets the battery event. + * + * @param hDevice A handle to the EC. + * @param pBatteryEvent Battery events + * + */ +void NvOdmBatteryGetEvent( + NvOdmBatteryDeviceHandle hDevice, + NvU8 *pBatteryEvent) +{ + NvOdmBatteryDevice *pBattContext = NULL; + + pBattContext = (NvOdmBatteryDevice *)hDevice; + + *pBatteryEvent = 0; +} + +NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, + NvOdmOsSemaphoreHandle *hOdmSemaphore) +{ + *hDevice = NULL; + return NV_FALSE; +} + +void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice) +{ +} + +/** + * Gets the AC line status. + * + * @param hDevice A handle to the EC. + * @param pStatus A pointer to the AC line + * status returned by the ODM. + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryGetAcLineStatus( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryAcLineStatus *pStatus) +{ + *pStatus = NvOdmBatteryAcLine_Offline; + return NV_FALSE; +} + + +/** + * Gets the battery status. + * + * @param hDevice A handle to the EC. + * @param batteryInst The battery type. + * @param pStatus A pointer to the battery + * status returned by the ODM. + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryGetBatteryStatus( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance batteryInst, + NvU8 *pStatus) +{ + *pStatus = NVODM_BATTERY_STATUS_UNKNOWN; + return NV_FALSE; +} + +/** + * Gets the battery data. + * + * @param hDevice A handle to the EC. + * @param batteryInst The battery type. + * @param pData A pointer to the battery + * data returned by the ODM. + * + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool NvOdmBatteryGetBatteryData( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance batteryInst, + NvOdmBatteryData *pData) +{ + NvOdmBatteryData BatteryData; + + BatteryData.BatteryAverageCurrent = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryAverageInterval = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryCurrent = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryLifePercent = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryLifeTime = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryMahConsumed = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryTemperature = NVODM_BATTERY_DATA_UNKNOWN; + BatteryData.BatteryVoltage = NVODM_BATTERY_DATA_UNKNOWN; + + *pData = BatteryData; + return NV_FALSE; +} + +/** + * Gets the battery full life time. + * + * @param hDevice A handle to the EC. + * @param batteryInst The battery type. + * @param pLifeTime A pointer to the battery + * full life time returned by the ODM. + * + */ +void NvOdmBatteryGetBatteryFullLifeTime( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance batteryInst, + NvU32 *pLifeTime) +{ + *pLifeTime = NVODM_BATTERY_DATA_UNKNOWN; +} + + +/** + * Gets the battery chemistry. + * + * @param hDevice A handle to the EC. + * @param batteryInst The battery type. + * @param pChemistry A pointer to the battery + * chemistry returned by the ODM. + * + */ +void NvOdmBatteryGetBatteryChemistry( + NvOdmBatteryDeviceHandle hDevice, + NvOdmBatteryInstance batteryInst, + NvOdmBatteryChemistry *pChemistry) +{ + *pChemistry = NVODM_BATTERY_DATA_UNKNOWN; +} + + + diff --git a/arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile b/arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile new file mode 100644 index 000000000000..8f6e46d214c6 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/keyboard/Makefile @@ -0,0 +1,12 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_keyboard.o +obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_keyboard_stub.o +obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_keyboard_stub.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c new file mode 100644 index 000000000000..86ba9cbc6083 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard.c @@ -0,0 +1,485 @@ +/* + * 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 "mach/nvrm_linux.h" // for s_hRmGlobal +#include "nvodm_keyboard.h" +#include "nvodm_query_discovery.h" +#include "nvodm_services.h" +#include "nvodm_query_gpio.h" +#include "nvrm_gpio.h" +#include "nvec.h" + +// Module debug: 0=disable, 1=enable +#define NVODM_ENABLE_PRINTF 0 + +#if NVODM_ENABLE_PRINTF +#define NVODM_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODM_PRINTF(x) +#endif + +// wake from keyboard disabled for now +#define WAKE_FROM_KEYBOARD 1 + +/* command main category */ +#define EC_KBC_COMMAND 0x5 + +/* number of LEDS on the keyboard */ +enum {NUM_OF_LEDS = 3}; + +/* Keyboard specific sub-commands */ +#define KBD_RESET_COMMAND 0xFF + +/* Special Scan Code set 1 codes */ +#define SC1_LSHIFT (0x2A) +#define SC1_RSHIFT (0x36) +#define SC1_SCROLL (0x46) +#define SC1_PREFIX_E0 (0xE0) +#define SC1_PREFIX_E1 (0xE1) + +/* Scan Code Set 1 break mask */ +#define SC1_BREAK_MASK (0x80) + +static NvEcHandle s_NvEcHandle = NULL; // nvec handle +NvEcEventType EventTypes[] = {NvEcEventType_Keyboard}; // get only keyboard events from EC +NvEcEvent KbdEvent = {0}; +static NvOdmOsSemaphoreHandle s_hKbcKeyScanRecvSema = NULL; +static NvEcEventRegistrationHandle s_hEcEventRegistration = NULL; +static NvBool s_KeyboardDeinit = NV_FALSE; + +#if WAKE_FROM_KEYBOARD +extern NvRmGpioHandle s_hGpioGlobal; +#define DEBOUNCE_TIME_MS 5 /* GPIO debounce time in ms */ +typedef struct NvOdmKbdContextRec +{ + const NvOdmGpioPinInfo *GpioPinInfo; + NvRmGpioPinHandle hPin; + NvRmGpioInterruptHandle GpioIntrHandle; + NvU32 PinCount; +} NvOdmKbdContext; +NvOdmKbdContext *hOdm; + +static void GpioInterruptHandler(void *args) +{ + NvOdmKbdContext *Odm = (NvOdmKbdContext *)args; + + if (Odm) + { + NvRmGpioInterruptDone(Odm->GpioIntrHandle); + } +} + +#endif + +// Shadow LED state +NvU8 s_LedState = 0; + +NvBool NvOdmKeyboardInit(void) +{ + NvError NvStatus = NvError_Success; + NvEcRequest Request = {0}; + NvEcResponse Response = {0}; + + /* get nvec handle */ + NvStatus = NvEcOpen(&s_NvEcHandle, 0 /* instance */); + if (NvStatus != NvError_Success) + { + goto fail; + } + + /* reset the EC to start the keyboard scanning */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_Keyboard; + Request.RequestSubtype = (NvEcRequestResponseSubtype) NvEcKeyboardSubtype_Enable; + Request.NumPayloadBytes = 0; + + NvStatus = NvEcSendRequest(s_NvEcHandle, &Request, &Response, sizeof(Request), sizeof(Response)); + if (NvStatus != NvError_Success) + { + goto cleanup; + } + + /* check if command passed */ + if (Response.Status != NvEcStatus_Success) + { + goto cleanup; + } + +#if WAKE_FROM_KEYBOARD + hOdm = NvOdmOsAlloc(sizeof(NvOdmKbdContext)); + if (!hOdm) { + goto cleanup; + } + + /* Check the supported GPIOs */ + hOdm->GpioPinInfo = NvOdmQueryGpioPinMap(NvOdmGpioPinGroup_WakeFromECKeyboard, + 0, + &hOdm->PinCount); + + NvRmGpioAcquirePinHandle(s_hGpioGlobal, + hOdm->GpioPinInfo->Port, + hOdm->GpioPinInfo->Pin, + &hOdm->hPin); + if (!hOdm->hPin) { + goto cleanup; + } + + /* register to receive GPIO events */ + NvStatus = NvRmGpioInterruptRegister(s_hGpioGlobal, + s_hRmGlobal, + hOdm->hPin, + (NvOsInterruptHandler)GpioInterruptHandler, + NvRmGpioPinMode_InputData, + hOdm, + &hOdm->GpioIntrHandle, + DEBOUNCE_TIME_MS); + if (NvStatus != NvError_Success) { + goto cleanup; + } + + NvStatus = NvRmGpioInterruptEnable(hOdm->GpioIntrHandle); + if (NvStatus != NvError_Success) { + goto cleanup; + } + + /* enable keyboard as wake up source */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_Keyboard; + Request.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcKeyboardSubtype_ConfigureWake; + Request.NumPayloadBytes = 2; + Request.Payload[0] = NVEC_KEYBOARD_WAKE_ENABLE_0_ACTION_ENABLE; + Request.Payload[1] = NVEC_KEYBOARD_EVENT_TYPE_0_ANY_KEY_PRESS_ENABLE; + + NvStatus = NvEcSendRequest(s_NvEcHandle, + &Request, + &Response, + sizeof(Request), + sizeof(Response)); + if (NvStatus != NvError_Success) { + goto cleanup; + } + + if (Response.Status != NvEcStatus_Success) { + goto cleanup; + } + + /* enable key reporting on wake up */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_Keyboard; + Request.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcKeyboardSubtype_ConfigureWakeKeyReport; + Request.NumPayloadBytes = 1; + Request.Payload[0] = NVEC_KEYBOARD_REPORT_WAKE_KEY_0_ACTION_ENABLE; + + NvStatus = NvEcSendRequest(s_NvEcHandle, + &Request, + &Response, + sizeof(Request), + sizeof(Response)); + if (NvStatus != NvError_Success) { + goto cleanup; + } + + if (Response.Status != NvEcStatus_Success) { + goto cleanup; + } +#endif + + /* create semaphore which can be used to send scan codes to the clients */ + s_hKbcKeyScanRecvSema = NvOdmOsSemaphoreCreate(0); + if (!s_hKbcKeyScanRecvSema) + { + goto cleanup; + } + + /* register for keyboard events */ + NvStatus = NvEcRegisterForEvents( + s_NvEcHandle, // nvec handle + &s_hEcEventRegistration, + (NvOsSemaphoreHandle)s_hKbcKeyScanRecvSema, + sizeof(EventTypes)/sizeof(NvEcEventType), + EventTypes, // receive keyboard scan codes + 1, // currently buffer only 1 packet from ECI at a time + sizeof(NvEcEvent)); + if (NvStatus != NvError_Success) + { + goto cleanup; + } + + /* success */ + return NV_TRUE; + +cleanup: +#if WAKE_FROM_KEYBOARD + NvRmGpioInterruptUnregister(s_hGpioGlobal, s_hRmGlobal, hOdm->GpioIntrHandle); + hOdm->GpioIntrHandle = NULL; + NvRmGpioReleasePinHandles(s_hGpioGlobal, &hOdm->hPin, hOdm->PinCount); + NvOdmOsFree(hOdm); + hOdm = NULL; +#endif + (void)NvEcUnregisterForEvents(s_hEcEventRegistration); + s_hEcEventRegistration = NULL; + + NvOdmOsSemaphoreDestroy(s_hKbcKeyScanRecvSema); + s_hKbcKeyScanRecvSema = NULL; + + NvEcClose(s_NvEcHandle); +fail: + s_NvEcHandle = NULL; + + return NV_FALSE; +} + +void NvOdmKeyboardDeInit(void) +{ +#if WAKE_FROM_KEYBOARD + NvRmGpioInterruptUnregister(s_hGpioGlobal, s_hRmGlobal, hOdm->GpioIntrHandle); + hOdm->GpioIntrHandle = NULL; + NvRmGpioReleasePinHandles(s_hGpioGlobal, &hOdm->hPin, hOdm->PinCount); + hOdm->PinCount = 0; + NvOdmOsFree(hOdm); + hOdm = NULL; +#endif + + (void)NvEcUnregisterForEvents(s_hEcEventRegistration); + s_hEcEventRegistration = NULL; + + s_KeyboardDeinit = NV_TRUE; + NvOdmOsSemaphoreSignal(s_hKbcKeyScanRecvSema); + NvOdmOsSemaphoreDestroy(s_hKbcKeyScanRecvSema); + s_hKbcKeyScanRecvSema = NULL; + + NvEcClose(s_NvEcHandle); + s_NvEcHandle = NULL; +} + +/* Gets the actual scan code for a key press */ +NvBool NvOdmKeyboardGetKeyData(NvU32 *pKeyScanCode, NvU8 *pScanCodeFlags, NvU32 Timeout) +{ + NvError NvStatus = NvError_Success; + NvU32 OutCode, OutCodeBytes, i; + NvU8 ScanCodeFlags; + + if (!pKeyScanCode || !pScanCodeFlags || s_KeyboardDeinit) + { + return NV_FALSE; + } + + if (Timeout != 0) + { + /* Use the timeout value */ + if (!NvOdmOsSemaphoreWaitTimeout(s_hKbcKeyScanRecvSema, Timeout)) + return NV_FALSE; // timed out + } + else + { + /* wait till we receive a scan code from the EC */ + NvOdmOsSemaphoreWait(s_hKbcKeyScanRecvSema); + } + + // stop scanning + if (s_KeyboardDeinit) + return NV_FALSE; + + if (s_hEcEventRegistration) + { + NvStatus = NvEcGetEvent(s_hEcEventRegistration, &KbdEvent, sizeof(NvEcEvent)); + if (NvStatus != NvError_Success) + { + NV_ASSERT(!"Could not receive scan code"); + return NV_FALSE; + } + if (KbdEvent.NumPayloadBytes == 0) + { + NV_ASSERT(!"Received keyboard event with no scan codes"); + return NV_FALSE; + } + + // Pack scan code bytes from payload buffer into 32-bit dword + OutCode = (NvU32)KbdEvent.Payload[0]; + OutCodeBytes = 1; + ScanCodeFlags = 0; + + if (KbdEvent.NumPayloadBytes == 1) + NVODM_PRINTF(("EC Payload = 0x%x", KbdEvent.Payload[0])); + else + { + for (i = 0; i < KbdEvent.NumPayloadBytes; i++) + NVODM_PRINTF(("EC Payload = 0x%x", KbdEvent.Payload[i])); + } + + for (i = 1; i < KbdEvent.NumPayloadBytes; i++) + { + if (KbdEvent.Payload[i-1] == SC1_PREFIX_E0) + { + // Temporary clear break flag just to check for extended shifts. + // If detected, remove the entire extended shift sequence, as + // it has no effect on SC1-to-VK translation + NvU8 sc = KbdEvent.Payload[i] & (~SC1_BREAK_MASK); + if ((sc == SC1_LSHIFT) || (sc == SC1_RSHIFT)) + { + OutCode = OutCode >> 8; + OutCodeBytes--; + continue; + } + else if (KbdEvent.Payload[i] == SC1_SCROLL) + { + // If extended ScrollLock = Ctrl+Break, detected store it, + // set both make/break flags, and abort buffer packing, as + // the following bytes are just the break part of sequence + OutCode = (OutCode << 8) | ((NvU32)KbdEvent.Payload[i]); + OutCodeBytes++; + ScanCodeFlags = NV_ODM_SCAN_CODE_FLAG_MAKE | + NV_ODM_SCAN_CODE_FLAG_BREAK; + break; + } + } + if (KbdEvent.Payload[i] == SC1_PREFIX_E1) + { + // If 2nd half of Pause key is detected, set both make/break + // flags, and abort buffer packing, as the following bytes + // are just the break part of sequence + ScanCodeFlags = NV_ODM_SCAN_CODE_FLAG_MAKE | + NV_ODM_SCAN_CODE_FLAG_BREAK; + break; + } + // If not intercepted by special cases, pack scan code byte into + // the output dword + OutCode = (OutCode << 8) | ((NvU32)KbdEvent.Payload[i]); + OutCodeBytes++; + } + + // After above packing all SC1 sequences are shrinked to 1-3 byte + // scan codes; 3-byte scan code always has both make/break flags + // already set; 2- and 1- byte scan code have break flag in low byte + // of low word + if (!ScanCodeFlags) + { + switch (OutCodeBytes) + { + case 2: + case 1: + ScanCodeFlags = (OutCode & ((NvU32)SC1_BREAK_MASK)) ? + NV_ODM_SCAN_CODE_FLAG_BREAK : + NV_ODM_SCAN_CODE_FLAG_MAKE; + OutCode &= ~((NvU32)SC1_BREAK_MASK); + break; + + case 0: + // Dummy sequence, no actual keystrokes (FIXME - assert ?) + return NV_FALSE; + + default: + NV_ASSERT(!"Not an SC1 payload - failed to pack"); + return NV_FALSE; + } + } + *pScanCodeFlags = ScanCodeFlags; + *pKeyScanCode = OutCode; + return NV_TRUE; + } + + return NV_FALSE; +} + +NvBool NvOdmKeyboardToggleLights(NvU32 LedId) +{ + NvError NvStatus = NvError_Success; + NvEcRequest Request = {0}; + NvEcResponse Response = {0}; + NvU8 NewLedState[NUM_OF_LEDS] = {0}, i = 0; + + /* return if EC handle is not available */ + if (!s_NvEcHandle) + return NV_FALSE; + + /* get the current state for each LED and toggle it */ + for (i = 0; i < NUM_OF_LEDS; i++) + { + NewLedState[i] = s_LedState & (LedId & (1 << i)); + + if (LedId & (1 << i)) + { + NewLedState[i] = (~NewLedState[i]) & 0x1; + } + } + + /* update the new LED states to be programmed */ + s_LedState = 0; + for (i = 0; i < NUM_OF_LEDS; i++) + { + s_LedState |= (NewLedState[i] << i); + } + + NVODM_PRINTF(("NvOdmKeyboardToggleLights: LED State = 0x%x", s_LedState)); + + /* issue the Set LED command */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_Keyboard; + Request.RequestSubtype = (NvEcRequestResponseSubtype) NvEcKeyboardSubtype_SetLeds; + Request.NumPayloadBytes = 1; + Request.Payload[0] = (NvU8)s_LedState; + + NvStatus = NvEcSendRequest(s_NvEcHandle, &Request, &Response, sizeof(Request), sizeof(Response)); + if (NvStatus != NvError_Success) + { + NVODM_PRINTF(("NvOdmKeyboardToggleLights: NvEcSendRequest time out")); + return NV_FALSE; + } + + /* check if command passed */ + if (Response.Status != NvEcStatus_Success) + { + return NV_FALSE; + } + + return NV_TRUE; +} + +NvBool NvOdmKeyboardPowerHandler(NvBool PowerDown) +{ + return NV_TRUE; +} + +/* -----------Stub Implemetation for Hold Switch Adaptation, since we do not need these-------*/ + +NvBool NvOdmHoldSwitchInit(void) +{ + // firefly should not concerned about the "hold" key + return NV_FALSE; +} + +void NvOdmHoldSwitchDeInit(void) +{ + // do nothing +} diff --git a/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c new file mode 100644 index 000000000000..7779766c97ba --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/keyboard/nvodm_keyboard_stub.c @@ -0,0 +1,70 @@ +/* + * 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 "nvodm_keyboard.h" + + +NvBool NvOdmKeyboardInit(void) +{ + return NV_FALSE; +} + +void NvOdmKeyboardDeInit(void) +{ +} + +NvBool NvOdmKeyboardGetKeyData(NvU32 *KeyScanCode, NvBool *IsKeyUp, NvU32 Timeout) +{ + return NV_FALSE; +} + +NvBool NvOdmKeyboardToggleLights(NvU32 LedId) +{ + return NV_FALSE; +} + +NvBool NvOdmKeyboardPowerHandler(NvBool PowerDown) +{ + return NV_FALSE; +} + +/* -----------Implemetation for Hold Switch Adaptation starts here-------*/ + +NvBool NvOdmHoldSwitchInit(void) +{ + return NV_FALSE; +} + +void NvOdmHoldSwitchDeInit(void) +{ +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile b/arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile new file mode 100644 index 000000000000..a8897024bf2c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/mouse/Makefile @@ -0,0 +1,10 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_mouse.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c new file mode 100644 index 000000000000..a527ea540d55 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse.c @@ -0,0 +1,586 @@ +/* + * Copyright (c) 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 "nvodm_mouse.h" +#include "nvodm_mouse_int.h" +#include "nvrm_drf.h" + +// Module debug: 0=disable, 1=enable +#define NVODM_ENABLE_PRINTF 0 + +#if NVODM_ENABLE_PRINTF +#define NVODM_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODM_PRINTF(x) +#endif + +// wake from mouse disabled for now +#define WAKE_FROM_MOUSE 1 + +/** + * streaming data from mouse can be compressed if (uncompressed) packet size is + * 3 bytes (as it is for all legacy ps2 mice). Compression works by not sending + * the first byte of the packet when it hasn't change. + */ + +#define ENABLE_COMPRESSION 1 + +#define ECI_MOUSE_DISABLE_SUPPORTED 1 + +#define MAX_PAYLOAD_BYTES 32 + +/** + * specify the ps2 port where the mouse is connected + */ +#define MOUSE_PS2_PORT_ID_0 NVEC_SUBTYPE_0_AUX_PORT_ID_0 +#define MOUSE_PS2_PORT_ID_1 NVEC_SUBTYPE_0_AUX_PORT_ID_1 + +/** Implementation for the NvOdm Mouse */ + +NvBool +NvOdmMouseDeviceOpen( + NvOdmMouseDeviceHandle *hDevice) +{ + NvOdmMouseDevice *hMouseDev = NULL; + NvBool ret = NV_FALSE; + NvU32 InstanceId = 0, count = 0, MousePort = 0, i = 0; +#if WAKE_FROM_MOUSE + NvError err = NvError_Success; + NvEcRequest Request = {0}; + NvEcResponse Response = {0}; +#endif + + // Allocate memory for request type structure + hMouseDev = (NvOdmMouseDevice *)NvOdmOsAlloc(sizeof(NvOdmMouseDevice)); + if (!hMouseDev) + { + ret = NV_FALSE; + NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate hMouseDev!!")); + goto fail_safe; + } + NvOdmOsMemset(hMouseDev, 0, sizeof(NvOdmMouseDevice)); + + // open channel to the EC + if ((NvEcOpen(&hMouseDev->hEc, InstanceId)) != NvSuccess) + { + ret = NV_FALSE; + NVODMMOUSE_PRINTF(("NvEcOpen failed !!")); + goto fail_safe; + } + + hMouseDev->pRequest = NULL; + hMouseDev->pResponse = NULL; + hMouseDev->pEvent = NULL; + hMouseDev->CompressionEnabled = NV_FALSE; + hMouseDev->CompressionState = 0x0; + + do + { + hMouseDev->ValidMousePorts[count] = INVALID_MOUSE_PORT_ID; + count++; + } while (count <= MAX_NUM_MOUSE_PORTS); + + // Allocate memory for request type structure + hMouseDev->pRequest = NvOdmOsAlloc(sizeof(NvEcRequest)); + if (!hMouseDev->pRequest) + { + ret = NV_FALSE; + NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate pRequest!!")); + goto fail_safe; + } + NvOdmOsMemset(hMouseDev->pRequest, 0, sizeof(NvEcRequest)); + + // Allocate memory for response type structure + hMouseDev->pResponse = NvOdmOsAlloc(sizeof(NvEcResponse)); + if (!hMouseDev->pResponse) + { + ret = NV_FALSE; + NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate pResponse!!")); + goto fail_safe; + } + NvOdmOsMemset(hMouseDev->pResponse, 0, sizeof(NvEcResponse)); + + // Allocate memory for event type structure + hMouseDev->pEvent = NvOdmOsAlloc(sizeof(NvEcEvent)); + if (!hMouseDev->pEvent) + { + ret = NV_FALSE; + NVODMMOUSE_PRINTF(("NvOdmOsAlloc failed to allocate pEvent!!")); + goto fail_safe; + } + NvOdmOsMemset(hMouseDev->pEvent, 0, sizeof(NvEcEvent)); + + MousePort = MOUSE_PS2_PORT_ID_0; + count = CMD_MAX_RETRIES + 1; i = 0; + while (count--) + { + // fill up request structure + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_AuxDevice; + Request.RequestSubtype = + ((NvEcRequestResponseSubtype) + (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,MousePort))) | + ((NvEcRequestResponseSubtype) + NvEcAuxDeviceSubtype_SendCommand); + Request.NumPayloadBytes = 2; + Request.Payload[0] = 0xFF; // set the reset command + Request.Payload[1] = 3; + + // Request to EC + err = NvEcSendRequest(hMouseDev->hEc, &Request, &Response, sizeof(Request), + sizeof(Response)); + + if (NvSuccess != err) + { + NVODMMOUSE_PRINTF(("NvEcSendRequest failed !!")); + break; + } + + // mouse not found + if (NvEcStatus_Success != Response.Status) + { + NVODMMOUSE_PRINTF(("EC response failed !!")); + if (MousePort != MOUSE_PS2_PORT_ID_1) + { + count = CMD_MAX_RETRIES + 1; + MousePort = MOUSE_PS2_PORT_ID_1; + continue; + } + break; + } + + if (Response.NumPayloadBytes != 3) + continue; + + // success + if (Response.Payload[0] == 0xFA) + { + hMouseDev->ValidMousePorts[i] = MousePort; + if (MousePort != MOUSE_PS2_PORT_ID_1) + { + count = CMD_MAX_RETRIES + 1; + MousePort = MOUSE_PS2_PORT_ID_1; + i++; + continue; + } + break; + } + } + +#if WAKE_FROM_MOUSE + i = 0; + do + { + /* enable mouse as wake up source */ + Request.PacketType = NvEcPacketType_Request; + Request.RequestType = NvEcRequestResponseType_AuxDevice; + Request.RequestSubtype = ((NvEcRequestResponseSubtype) + (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hMouseDev->ValidMousePorts[i]))) | + (NvEcRequestResponseSubtype) + NvEcAuxDeviceSubtype_ConfigureWake; + Request.NumPayloadBytes = 2; + Request.Payload[0] = NVEC_AUX_DEVICE_WAKE_ENABLE_0_ACTION_ENABLE; + Request.Payload[1] = NVEC_AUX_DEVICE_EVENT_TYPE_0_ANY_EVENT_ENABLE; + + err = NvEcSendRequest( + hMouseDev->hEc, + &Request, + &Response, + sizeof(Request), + sizeof(Response)); + if (err != NvError_Success) + { + ret = NV_FALSE; + goto fail_safe; + } + + if (Response.Status != NvEcStatus_Success) + { + ret = NV_FALSE; + goto fail_safe; + } + } while (hMouseDev->ValidMousePorts[++i] != INVALID_MOUSE_PORT_ID); +#endif + + *hDevice = (NvOdmMouseDeviceHandle)hMouseDev; + ret = NV_TRUE; + return ret; + +fail_safe: + NvOdmMouseDeviceClose((NvOdmMouseDeviceHandle)hMouseDev); + hMouseDev = NULL; + return ret; +} + +void +NvOdmMouseDeviceClose( + NvOdmMouseDeviceHandle hDevice) +{ + if (hDevice) + { + // close channel to the EC + NvEcClose(hDevice->hEc); + hDevice->hEc = NULL; + // Free the request/response structure objects + NvOdmOsFree(hDevice->pRequest); + hDevice->pRequest = NULL; + NvOdmOsFree(hDevice->pResponse); + hDevice->pResponse = NULL; + NvOdmOsFree(hDevice->pEvent); + hDevice->pEvent = NULL; + NvOdmOsFree(hDevice); + hDevice = NULL; + } +} + +NvBool NvOdmMouseEnableInterrupt( + NvOdmMouseDeviceHandle hDevice, + NvOdmOsSemaphoreHandle hInterruptSemaphore) +{ + NvError Status = NvSuccess; + NvEcEventType EventTypes[] = { + (NvEcEventType) (NvEcEventType_AuxDevice0 + MOUSE_PS2_PORT_ID_0), + (NvEcEventType) (NvEcEventType_AuxDevice0 + MOUSE_PS2_PORT_ID_1) + }; + + Status = NvEcRegisterForEvents( + hDevice->hEc, + &hDevice->hEcEventRegister, + (NvOsSemaphoreHandle)hInterruptSemaphore, + NV_ARRAY_SIZE(EventTypes), // number of EventType's + EventTypes, // Auxillary 0 event + 1, // One event packet is expected + // event packet size = packet overhead + size of the mouse sample; + // max sample size is 4 bytes (for an Intellimouse 5-button mouse) + NVEC_MIN_EVENT_SIZE+4); + + if (Status != NvSuccess) + return NV_FALSE; + + return NV_TRUE; +} + +NvBool +NvOdmMouseDisableInterrupt( + NvOdmMouseDeviceHandle hDevice) +{ + NvError Status = NvSuccess; + + // Un-register the events + Status = NvEcUnregisterForEvents(hDevice->hEcEventRegister); + if (Status != NvSuccess) + return NV_FALSE; + + return NV_TRUE; +} + +NvBool NvOdmMouseGetEventInfo( + NvOdmMouseDeviceHandle hDevice, + NvU32 *NumPayLoad, + NvU8 *PayLoadBuf) +{ + NvError Status = NvSuccess; + + // Retrive the event info + Status = NvEcGetEvent(hDevice->hEcEventRegister, + hDevice->pEvent, + sizeof(NvEcEvent)); + + if (Status != NvSuccess) + return NV_FALSE; + + /** + * if compression is enabled, latch the first data byte whenever a full-size + * packet is received; then insert the latched data whenever a compressed + * packet is seen. + */ + if (hDevice->CompressionEnabled && hDevice->pEvent->NumPayloadBytes == 3) + { + hDevice->CompressionState = hDevice->pEvent->Payload[0]; + } + + /** + * fill in the payload and number of bytes + */ + if (hDevice->CompressionEnabled && hDevice->pEvent->NumPayloadBytes == 2) + { + // compressed packet, so insert latched data at beginning + *NumPayLoad = 3; + PayLoadBuf[0] = hDevice->CompressionState; + PayLoadBuf[1] = hDevice->pEvent->Payload[0]; + PayLoadBuf[2] = hDevice->pEvent->Payload[1]; + } + else + { + *NumPayLoad = hDevice->pEvent->NumPayloadBytes; + NvOdmOsMemcpy(PayLoadBuf, hDevice->pEvent->Payload, *NumPayLoad); + } + + return NV_TRUE; +} + +NvBool +NvOdmMouseSendRequest( + NvOdmMouseDeviceHandle hDevice, + NvU32 cmd, + NvU32 ExpectedResponseSize, + NvU32 *NumPayLoad, + NvU8 *PayLoadBuf) +{ + NvError e; + NvEcRequest *pRequest = hDevice->pRequest; + NvEcResponse *pResponse = hDevice->pResponse; + NvU32 Index = 0; + + do + { + // fill up request structure + pRequest->PacketType = NvEcPacketType_Request; + pRequest->RequestType = NvEcRequestResponseType_AuxDevice; + pRequest->RequestSubtype = + ((NvEcRequestResponseSubtype) + (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) | + ((NvEcRequestResponseSubtype) + NvEcAuxDeviceSubtype_SendCommand); + pRequest->NumPayloadBytes = 2; + pRequest->Payload[0] = cmd; // set the command + pRequest->Payload[1] = ExpectedResponseSize; + + // Request to EC + e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest), + sizeof(*pResponse)); + + if (NvSuccess != e) + { + NVODMMOUSE_PRINTF(("NvEcSendRequest failed !!")); + return NV_FALSE; + } + + if (NvEcStatus_Success != pResponse->Status) + { + NVODMMOUSE_PRINTF(("EC response failed !!")); + return NV_FALSE; + } + + // store/process the Mouse response and return to the client driver + *NumPayLoad = pResponse->NumPayloadBytes; + NvOdmOsMemcpy(PayLoadBuf, &pResponse->Payload, *NumPayLoad); + } while (hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID); + + return NV_TRUE; +} + +NvBool +NvOdmMouseStartStreaming( + NvOdmMouseDeviceHandle hDevice, + NvU32 NumBytesPerSample) +{ + NvError e; + NvEcRequest *pRequest = hDevice->pRequest; + NvEcResponse *pResponse = hDevice->pResponse; + NvU32 Index = 0; + + if (!hDevice) + return NV_FALSE; + + hDevice->NumBytesPerSample = NumBytesPerSample; + +#if ENABLE_COMPRESSION + /** + * automatically enable compression if sample size is 3 bytes + * + * compression is supported only for 3-byte data packets (which is the + * common case for ps/2 mice and mouses + * + * compression reduces communication bandwidth by eliminating the first data + * byte of the packet when it hasn't changed relative to the previous + * packet. Whenever a full-sized packet is sent, the first payload byte is + * latched so that it can be inserted into an n y following compressed packets. + */ + + if (NumBytesPerSample == 3) + { + do + { + // prepare Aux Device request for Set Compression + pRequest->PacketType = NvEcPacketType_Request; + pRequest->RequestType = NvEcRequestResponseType_AuxDevice; + pRequest->RequestSubtype = + ((NvEcRequestResponseSubtype) + (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) | + ((NvEcRequestResponseSubtype) + NvEcAuxDeviceSubtype_SetCompression); + pRequest->NumPayloadBytes = 1; + pRequest->Payload[0] = 1; // enable compression + + // send request to EC + e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest), + sizeof(*pResponse)); + + if (NvSuccess != e) + { + NVODMMOUSE_PRINTF(("NvEcSendRequest (compression) failed !!")); + return NV_FALSE; + } + + // check status reported by EC + if (NvEcStatus_Success != pResponse->Status) + { + NVODMMOUSE_PRINTF(("EC response (compression) failed !!")); + return NV_FALSE; + } + } while(hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID); + + hDevice->CompressionEnabled = NV_TRUE; + hDevice->CompressionState = 0x0; + } + else + { + // compression not supported due to packet size (!= 3 bytes) + hDevice->CompressionEnabled = NV_FALSE; + } +#else // ENABLE_COMPRESSION + // disable compression + hDevice->CompressionEnabled = NV_FALSE; +#endif // ENABLE_COMPRESSION + + // prepare Aux Device request for Auto-Receive N Bytes + Index = 0; + do + { + pRequest->PacketType = NvEcPacketType_Request; + pRequest->RequestType = NvEcRequestResponseType_AuxDevice; + pRequest->RequestSubtype = + ((NvEcRequestResponseSubtype) + (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) | + ((NvEcRequestResponseSubtype) + NvEcAuxDeviceSubtype_AutoReceiveBytes); + pRequest->NumPayloadBytes = 1; + pRequest->Payload[0] = NumBytesPerSample; + + // send request to EC + e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest), + sizeof(*pResponse)); + + if (NvSuccess != e) + { + NVODMMOUSE_PRINTF(("NvEcSendRequest (auto-receive) failed !!")); + return NV_FALSE; + } + + // check status reported by EC + if (NvEcStatus_Success != pResponse->Status) + { + NVODMMOUSE_PRINTF(("EC response (auto-receive) failed !!")); + return NV_FALSE; + } + } while(hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID); + + return NV_TRUE; +} + +/** + * Power suspend for mouse. + * + */ +NvBool NvOdmMousePowerSuspend(NvOdmMouseDeviceHandle hDevice) +{ +#if ECI_MOUSE_DISABLE_SUPPORTED + NvError e; + NvEcRequest *pRequest = hDevice->pRequest; + NvEcResponse *pResponse = hDevice->pResponse; + NvU32 Index = 0; + + if (!hDevice || !pRequest || !pResponse) + return NV_FALSE; + + NV_ASSERT(hDevice->hEc); + NV_ASSERT(hDevice->pRequest); + NV_ASSERT(hDevice->pResponse); + + // cancel auto-receive (disables event reporting) + + NVODM_PRINTF(("NvOdmMousePowerSuspend: Cancel Auto Receive\n")); + + do + { + // fill up request structure + pRequest->PacketType = NvEcPacketType_Request; + pRequest->RequestType = NvEcRequestResponseType_AuxDevice; + pRequest->RequestSubtype = + ((NvEcRequestResponseSubtype) + (NV_DRF_NUM(NVEC,SUBTYPE,AUX_PORT_ID,hDevice->ValidMousePorts[Index]))) | + ((NvEcRequestResponseSubtype) + NvEcAuxDeviceSubtype_CancelAutoReceive); + pRequest->NumPayloadBytes = 0; + + // Request to EC + e = NvEcSendRequest(hDevice->hEc, pRequest, pResponse, sizeof(*pRequest), + sizeof(*pResponse)); + + if (NvSuccess != e) + { + NVODMMOUSE_PRINTF(("NvOdmMousePowerSuspend: NvEcSendRequest failed !!")); + return NV_FALSE; + } + + if (NvEcStatus_Success != pResponse->Status) + { + NVODMMOUSE_PRINTF(("NvOdmMousePowerSuspend: EC response failed !!")); + return NV_FALSE; + } + } while(hDevice->ValidMousePorts[++Index] != INVALID_MOUSE_PORT_ID); +#endif + NVODM_PRINTF(("NvOdmMousePowerSuspend: Exit success\n")); + + return NV_TRUE; +} + +/** + * Power resume for mouse. + * + */ +NvBool NvOdmMousePowerResume(NvOdmMouseDeviceHandle hDevice) +{ +#if ECI_MOUSE_DISABLE_SUPPORTED + if (!hDevice) + return NV_FALSE; + + NVODM_PRINTF(("NvOdmMousePowerResume: Start Streaming\n")); + + if (!NvOdmMouseStartStreaming(hDevice, hDevice->NumBytesPerSample)) + return NV_FALSE; +#endif + NVODM_PRINTF(("NvOdmMousePowerResume: Exit success\n")); + + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h new file mode 100644 index 000000000000..2e3a6cc8b71a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/mouse/nvodm_mouse_int.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 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_NVODM_MOUSE_INT_H +#define INCLUDED_NVODM_MOUSE_INT_H + +#include "nvodm_services.h" +#include "nvodm_touch.h" +#include "nvec.h" + +// Module debug: 0=disable, 1=enable +#define NVODMMOUSE_ENABLE_PRINTF (0) + +#define MAX_NUM_MOUSE_PORTS 4 +#define INVALID_MOUSE_PORT_ID 0xF +#define CMD_MAX_RETRIES 3 + +#if (NVODMMOUSE_ENABLE_PRINTF) +#define NVODMMOUSE_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODMMOUSE_PRINTF(x) +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef struct NvOdmMouseDeviceRec +{ + NvEcHandle hEc; + NvEcRequest *pRequest; + NvEcResponse *pResponse; + NvEcEvent *pEvent; + NvEcEventRegistrationHandle hEcEventRegister; + NvBool CompressionEnabled; + NvU8 CompressionState; + NvU32 NumBytesPerSample; + NvU32 ValidMousePorts[MAX_NUM_MOUSE_PORTS + 1]; +} NvOdmMouseDevice; + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_MOUSE_INT_H + diff --git a/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile new file mode 100644 index 000000000000..071c1f60cc28 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/Makefile @@ -0,0 +1,12 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_scrollwheel_stub.o +obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_scrollwheel.o +obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_scrollwheel.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c new file mode 100644 index 000000000000..392ff053ae1f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel.c @@ -0,0 +1,396 @@ +/* + * Copyright (c) 2006-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 "nvodm_scrollwheel.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_query.h" + +#define SCROLL_WHEEL_GUID NV_ODM_GUID('s', 'c', 'r', 'o', 'l', 'w', 'h', 'l') +#define DEBOUNCE_TIME_MS 0 + +typedef struct NvOdmScrollWheelRec +{ + // Gpio Handle + NvOdmServicesGpioHandle hGpio; + // Pin handles to all the 4 Gpio pins + NvOdmGpioPinHandle hInputPin1; + NvOdmGpioPinHandle hInputPin2; + NvOdmGpioPinHandle hSelectPin; + NvOdmGpioPinHandle hOnOffPin; + // Stores the key events the client had registered for. + NvOdmScrollWheelEvent RegisterEvents; + NvOdmOsSemaphoreHandle EventSema; + NvOdmServicesGpioIntrHandle IntrHandle[2]; + NvOdmScrollWheelEvent Event; + NvU32 LastPin1Val; + NvOdmOsMutexHandle hKeyEventMutex; + NvOdmOsThreadHandle hDebounceRotThread; + NvOdmOsSemaphoreHandle hDebounceRotSema; + NvOdmOsSemaphoreHandle hDummySema; + volatile NvU32 shutdown; + volatile NvBool Debouncing; +} NvOdmScrollWheel; + +static NvU32 +GetReliablePinValue(NvOdmServicesGpioHandle hGpio, + NvOdmGpioPinHandle hPin) +{ + NvU32 data = (NvU32)-1; + const int sampleCount = 10; + int i = 0; + + while (i < sampleCount) + { + NvU32 currData; + NvOdmGpioGetState(hGpio, hPin, &currData); + if (currData == data) + { + i++; + } + else + { + data = currData; + i = 0; + } + } + + return data; +} + +static void +ScrollWheelDebounceRotThread(void *arg) +{ + NvOdmScrollWheelHandle hOdmScrollWheel = (NvOdmScrollWheelHandle)arg; + const NvU32 debounceTimeMS = 2; + + while (!hOdmScrollWheel->shutdown) + { + // If a scroll wheel event is detected, wait <debounceTime> milliseconds + // and then read the Terminal 1 pin to determine the current level + NvOdmOsSemaphoreWait(hOdmScrollWheel->hDebounceRotSema); + // The dummy semaphore never gets signalled so it will always timeout + NvOdmOsSemaphoreWaitTimeout(hOdmScrollWheel->hDummySema, debounceTimeMS); + //NvOdmGpioGetState(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin1, &hOdmScrollWheel->LastPin1Val); + hOdmScrollWheel->LastPin1Val = GetReliablePinValue(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin1); + NvOdmGpioConfig(hOdmScrollWheel->hGpio, + hOdmScrollWheel->hInputPin1, + hOdmScrollWheel->LastPin1Val ? + NvOdmGpioPinMode_InputInterruptFallingEdge : + NvOdmGpioPinMode_InputInterruptRisingEdge); + hOdmScrollWheel->Debouncing = NV_FALSE; + } +} + +static void RotGpioInterruptHandler(void *arg) +{ + NvOdmScrollWheelHandle hOdmScrollWheel = (NvOdmScrollWheelHandle)arg; + NvU32 InPinValue2; + NvOdmScrollWheelEvent Event = NvOdmScrollWheelEvent_None; + + /* if still debouncing, ignore interrupt */ + if (hOdmScrollWheel->Debouncing) + { + NvOdmGpioInterruptDone(hOdmScrollWheel->IntrHandle[1]); + return; + } + NvOdmGpioGetState(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin2, &InPinValue2); + + if (InPinValue2 == hOdmScrollWheel->LastPin1Val) + { + Event = NvOdmScrollWheelEvent_RotateAntiClockWise; + } + else + { + Event = NvOdmScrollWheelEvent_RotateClockWise; + } + + Event &= hOdmScrollWheel->RegisterEvents; + if (Event) + { + NvOdmOsMutexLock(hOdmScrollWheel->hKeyEventMutex); + hOdmScrollWheel->Event &= ~(NvOdmScrollWheelEvent_RotateClockWise | + NvOdmScrollWheelEvent_RotateAntiClockWise); + hOdmScrollWheel->Event |= Event; + NvOdmOsMutexUnlock(hOdmScrollWheel->hKeyEventMutex); + NvOdmOsSemaphoreSignal(hOdmScrollWheel->EventSema); + } + /* start debounce */ + hOdmScrollWheel->Debouncing = NV_TRUE; + NvOdmOsSemaphoreSignal(hOdmScrollWheel->hDebounceRotSema); + + NvOdmGpioInterruptDone(hOdmScrollWheel->IntrHandle[1]); +} + +static void SelectGpioInterruptHandler(void *arg) +{ + NvOdmScrollWheelHandle hOdmScrollWheel = (NvOdmScrollWheelHandle)arg; + NvU32 CurrSelectPinState; + NvOdmScrollWheelEvent Event = NvOdmScrollWheelEvent_None; + + NvOdmGpioGetState(hOdmScrollWheel->hGpio, hOdmScrollWheel->hSelectPin, &CurrSelectPinState); + Event = (CurrSelectPinState) ? NvOdmScrollWheelEvent_Release : NvOdmScrollWheelEvent_Press; + Event &= hOdmScrollWheel->RegisterEvents; + + if (Event) + { + NvOdmOsMutexLock(hOdmScrollWheel->hKeyEventMutex); + hOdmScrollWheel->Event &= ~(NvOdmScrollWheelEvent_Press | NvOdmScrollWheelEvent_Release); + hOdmScrollWheel->Event |= Event; + NvOdmOsMutexUnlock(hOdmScrollWheel->hKeyEventMutex); + NvOdmOsSemaphoreSignal(hOdmScrollWheel->EventSema); + } + + NvOdmGpioInterruptDone(hOdmScrollWheel->IntrHandle[0]); +} + +NvOdmScrollWheelHandle +NvOdmScrollWheelOpen( + NvOdmOsSemaphoreHandle hNotifySema, + NvOdmScrollWheelEvent RegisterEvents) +{ + NvOdmScrollWheelHandle hOdmScroll = NULL; + NvOdmPeripheralConnectivity *pConnectivity; + NvU32 i; + NvOdmInterruptHandler RotIntrHandler = (NvOdmInterruptHandler)RotGpioInterruptHandler; + NvOdmInterruptHandler SelectIntrHandler = (NvOdmInterruptHandler)SelectGpioInterruptHandler; + NvU32 GpioInstance[4]; + NvU32 GpioPin[4]; + NvU32 GpioIndex; + + pConnectivity = (NvOdmPeripheralConnectivity *)NvOdmPeripheralGetGuid(SCROLL_WHEEL_GUID); + + if (pConnectivity == NULL) + return NULL; + + // Should be IO class device + if (pConnectivity->Class != NvOdmPeripheralClass_HCI) + return NULL; + + // Minimum 4 entry for the 4 line of GPIO + if (pConnectivity->NumAddress < 4) + return NULL; + + GpioIndex = 0; + for (i=0; i<pConnectivity->NumAddress; i++) + { + if (pConnectivity->AddressList[i].Interface == NvOdmIoModule_Gpio) + { + GpioInstance[GpioIndex] = pConnectivity->AddressList[i].Instance; + GpioPin[GpioIndex++] = pConnectivity->AddressList[i].Address; + } + } + + // 4 GPIO entry for the scroll wheel + if (GpioIndex != 4) + return NULL; + + hOdmScroll = NvOdmOsAlloc(sizeof(NvOdmScrollWheel)); + + if(!hOdmScroll) + { + return NULL; + } + + NvOdmOsMemset(hOdmScroll, 0, sizeof(NvOdmScrollWheel)); + + hOdmScroll->EventSema = hNotifySema; + hOdmScroll->RegisterEvents = RegisterEvents; + hOdmScroll->Event = NvOdmScrollWheelEvent_None; + + hOdmScroll->hKeyEventMutex = NvOdmOsMutexCreate(); + hOdmScroll->hDebounceRotSema = NvOdmOsSemaphoreCreate(0); + hOdmScroll->hDummySema = NvOdmOsSemaphoreCreate(0); + + if (!hOdmScroll->hKeyEventMutex || + !hOdmScroll->hDebounceRotSema || + !hOdmScroll->hDummySema) + { + goto ErrorExit; + } + + // Getting the OdmGpio Handle + hOdmScroll->hGpio = NvOdmGpioOpen(); + if (!hOdmScroll->hGpio) + { + goto ErrorExit; + } + + hOdmScroll->hDebounceRotThread = + NvOdmOsThreadCreate((NvOdmOsThreadFunction)ScrollWheelDebounceRotThread, + (void*)hOdmScroll); + if (!hOdmScroll->hDebounceRotThread) + { + goto ErrorExit; + } + + // Acquiring Pin Handles for all the four Gpio Pins + // First entry is Input GPIO1 + // Second entry should be Input GPIO2 + // Third entry should be Select + // 4 th entry should be OnOff pin + hOdmScroll->hInputPin1= NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio, + GpioInstance[3], GpioPin[3]); + + hOdmScroll->hInputPin2 = NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio, + GpioInstance[0], GpioPin[0]); + + hOdmScroll->hSelectPin= NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio, + GpioInstance[2], GpioPin[2]); + + hOdmScroll->hOnOffPin= NvOdmGpioAcquirePinHandle(hOdmScroll ->hGpio, + GpioInstance[1], GpioPin[1]); + + if (!hOdmScroll->hInputPin1 || !hOdmScroll->hInputPin2 || + !hOdmScroll->hSelectPin || !hOdmScroll->hOnOffPin) + { + goto ErrorExit; + } + + // Setting the ON/OFF pin to output mode and setting to Low. + NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hOnOffPin, NvOdmGpioPinMode_Output); + NvOdmGpioSetState(hOdmScroll->hGpio, hOdmScroll->hOnOffPin, 0); + + // Configuring the other pins as input + // NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hSelectPin, NvOdmGpioPinMode_InputData); + NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hInputPin1, NvOdmGpioPinMode_InputData); + NvOdmGpioConfig(hOdmScroll->hGpio, hOdmScroll->hInputPin2, NvOdmGpioPinMode_InputData); + + if (NvOdmGpioInterruptRegister(hOdmScroll->hGpio, &hOdmScroll->IntrHandle[0], + hOdmScroll->hSelectPin, NvOdmGpioPinMode_InputInterruptAny, + SelectIntrHandler, (void *)(hOdmScroll), DEBOUNCE_TIME_MS) == NV_FALSE) + { + goto ErrorExit; + } + + hOdmScroll->LastPin1Val = GetReliablePinValue(hOdmScroll->hGpio, hOdmScroll->hInputPin1); + + if (NvOdmGpioInterruptRegister(hOdmScroll->hGpio, &hOdmScroll->IntrHandle[1], + hOdmScroll->hInputPin1, hOdmScroll->LastPin1Val ? + NvOdmGpioPinMode_InputInterruptFallingEdge : + NvOdmGpioPinMode_InputInterruptRisingEdge, + RotIntrHandler, (void *)(hOdmScroll), DEBOUNCE_TIME_MS) == NV_FALSE) + { + goto ErrorExit; + } + + if (!hOdmScroll->IntrHandle[0] || !hOdmScroll->IntrHandle[1]) + { + goto ErrorExit; + } + + hOdmScroll->Debouncing = NV_FALSE; + + return hOdmScroll; + + ErrorExit: + NvOdmScrollWheelClose(hOdmScroll); + return NULL; +} + +void NvOdmScrollWheelClose(NvOdmScrollWheelHandle hOdmScrollWheel) +{ + if (hOdmScrollWheel) + { + hOdmScrollWheel->shutdown = 1; + + if (hOdmScrollWheel->hDebounceRotThread) + { + if (hOdmScrollWheel->hDebounceRotSema) + NvOdmOsSemaphoreSignal(hOdmScrollWheel->hDebounceRotSema); + NvOdmOsThreadJoin(hOdmScrollWheel->hDebounceRotThread); + } + + if (hOdmScrollWheel->hGpio) + { + if (hOdmScrollWheel->IntrHandle[0]) + { + NvOdmGpioInterruptUnregister(hOdmScrollWheel->hGpio, + hOdmScrollWheel->hSelectPin, + hOdmScrollWheel->IntrHandle[0]); + } + if (hOdmScrollWheel->IntrHandle[1]) + { + NvOdmGpioInterruptUnregister(hOdmScrollWheel->hGpio, + hOdmScrollWheel->hInputPin1, + hOdmScrollWheel->IntrHandle[1]); + } + + if (hOdmScrollWheel->hOnOffPin) + { + NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hOnOffPin); + } + + if (hOdmScrollWheel->hInputPin1) + { + NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin1); + } + if (hOdmScrollWheel->hInputPin2) + { + NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hInputPin2); + } + + if (hOdmScrollWheel->hSelectPin) + { + NvOdmGpioReleasePinHandle(hOdmScrollWheel->hGpio, hOdmScrollWheel->hSelectPin); + } + + NvOdmGpioClose(hOdmScrollWheel->hGpio); + } + + if (hOdmScrollWheel->hDummySema) + { + NvOdmOsSemaphoreDestroy(hOdmScrollWheel->hDummySema); + } + if (hOdmScrollWheel->hDebounceRotSema) + { + NvOdmOsSemaphoreDestroy(hOdmScrollWheel->hDebounceRotSema); + } + if (hOdmScrollWheel->hKeyEventMutex) + { + NvOdmOsMutexDestroy(hOdmScrollWheel->hKeyEventMutex); + } + + NvOdmOsFree(hOdmScrollWheel); + } +} + +NvOdmScrollWheelEvent NvOdmScrollWheelGetEvent(NvOdmScrollWheelHandle hOdmScrollWheel) +{ + NvOdmScrollWheelEvent Event; + NvOdmOsMutexLock(hOdmScrollWheel->hKeyEventMutex); + Event = hOdmScrollWheel->Event; + hOdmScrollWheel->Event = NvOdmScrollWheelEvent_None; + NvOdmOsMutexUnlock(hOdmScrollWheel->hKeyEventMutex); + return Event; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c new file mode 100644 index 000000000000..cba93b0b9d2d --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/scrollwheel/nvodm_scrollwheel_stub.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2006-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 "nvodm_scrollwheel.h" + + +NvOdmScrollWheelHandle +NvOdmScrollWheelOpen( + NvOdmOsSemaphoreHandle hNotifySema, + NvOdmScrollWheelEvent RegisterEvents) +{ + return NULL; +} + +void NvOdmScrollWheelClose(NvOdmScrollWheelHandle hOdmScrollWheel) +{ +} + +NvOdmScrollWheelEvent NvOdmScrollWheelGetEvent(NvOdmScrollWheelHandle hOdmScrollWheel) +{ + return NvOdmScrollWheelEvent_None; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/Makefile b/arch/arm/mach-tegra/odm_kit/platform/touch/Makefile new file mode 100644 index 000000000000..457bacd20c8c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/Makefile @@ -0,0 +1,27 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ifeq ($(CONFIG_TEGRA_ODM_CONCORDE),y) + is_tpk_touch := y +endif + +ifeq ($(CONFIG_TEGRA_ODM_WHISTLER),y) + is_tpk_touch := y +endif + +ifeq ($(CONFIG_TEGRA_ODM_HARMONY),y) + is_panjit_touch := y +endif + +ccflags-$(is_tpk_touch) += -DNV_TOUCH_TPK +ccflags-$(is_panjit_touch) += -DNV_TOUCH_PANJIT + +obj-y += nvodm_touch.o +obj-$(is_tpk_touch) += nvodm_touch_tpk.o +obj-$(is_panjit_touch) += nvodm_touch_panjit.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c new file mode 100644 index 000000000000..bf7d3eaa3049 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2006-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 "nvodm_touch.h" +#include "nvodm_touch_int.h" + +#if defined(NV_TOUCH_TPK) +#include "nvodm_touch_tpk.h" +#endif +#if defined(NV_TOUCH_PANJIT) +#include "nvodm_touch_panjit.h" +#endif + +/** Implementation for the NvOdm TouchPad */ + +NvBool +NvOdmTouchDeviceOpen( NvOdmTouchDeviceHandle *hDevice ) +{ + NvBool ret = NV_TRUE; + +#if defined(NV_TOUCH_TPK) + ret = TPK_Open(hDevice); +#endif +#if defined(NV_TOUCH_PANJIT) + ret = PANJIT_Open(hDevice); +#endif + + return ret; +} + + +void +NvOdmTouchDeviceGetCapabilities(NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities) +{ + hDevice->GetCapabilities(hDevice, pCapabilities); +} + + +NvBool +NvOdmTouchReadCoordinate( NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo *coord) +{ + return hDevice->ReadCoordinate(hDevice, coord); +} + +NvBool +NvOdmTouchGetSampleRate(NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate) +{ + return hDevice->GetSampleRate(hDevice, pTouchSampleRate); +} + +void NvOdmTouchDeviceClose(NvOdmTouchDeviceHandle hDevice) +{ + hDevice->Close(hDevice); +} + +NvBool NvOdmTouchEnableInterrupt(NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hInterruptSemaphore) +{ + return hDevice->EnableInterrupt(hDevice, hInterruptSemaphore); +} + +NvBool NvOdmTouchHandleInterrupt(NvOdmTouchDeviceHandle hDevice) +{ + return hDevice->HandleInterrupt(hDevice); +} + +NvBool +NvOdmTouchSetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 SampleRate) +{ + return hDevice->SetSampleRate(hDevice, SampleRate); +} + + +NvBool +NvOdmTouchPowerControl(NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode) +{ + return hDevice->PowerControl(hDevice, mode); +} + +void +NvOdmTouchPowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff) +{ + hDevice->PowerOnOff(hDevice, OnOff); +} + + +NvBool +NvOdmTouchOutputDebugMessage(NvOdmTouchDeviceHandle hDevice) +{ + return hDevice->OutputDebugMessage; +} + +NvBool +NvOdmTouchGetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer) +{ + return hDevice->GetCalibrationData(hDevice, NumOfCalibrationData, pRawCoordBuffer); +} diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h new file mode 100644 index 000000000000..d980c99b5c3e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_int.h @@ -0,0 +1,78 @@ +/* + * 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_NVODM_TOUCH_INT_H +#define INCLUDED_NVODM_TOUCH_INT_H + +#include "nvodm_services.h" +#include "nvodm_touch.h" + + +// Module debug: 0=disable, 1=enable +#define NVODMTOUCH_ENABLE_PRINTF (0) + +#if (NV_DEBUG && NVODMTOUCH_ENABLE_PRINTF) +#define NVODMTOUCH_PRINTF(x) NvOdmOsDebugPrintf x +#else +#define NVODMTOUCH_PRINTF(x) +#endif + +#if defined(__cplusplus) +extern "C" +{ +#endif + +typedef struct NvOdmTouchDeviceRec{ + NvBool (*ReadCoordinate) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo *coord); + NvBool (*EnableInterrupt) (NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hInterruptSemaphore); + NvBool (*HandleInterrupt) (NvOdmTouchDeviceHandle hDevice); + NvBool (*GetSampleRate) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate); + NvBool (*SetSampleRate) (NvOdmTouchDeviceHandle hDevice, NvU32 rate); + NvBool (*PowerControl) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode); + NvBool (*PowerOnOff) (NvOdmTouchDeviceHandle hDevice, NvBool OnOff); + void (*GetCapabilities) (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities); + NvBool (*GetCalibrationData)(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer); + void (*Close) (NvOdmTouchDeviceHandle hDevice); + NvU16 CurrentSampleRate; + NvBool OutputDebugMessage; +} NvOdmTouchDevice; + + + +#if defined(__cplusplus) +} +#endif + +/** @} */ + +#endif // INCLUDED_NVODM_TOUCH_INT_H + diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c new file mode 100644 index 000000000000..6516ccbce839 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.c @@ -0,0 +1,603 @@ +/*
+ * Copyright (c) 2010 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 "nvodm_touch_panjit.h"
+#include "nvodm_query_discovery.h"
+#include "nvos.h"
+
+#define PANJIT_BENCHMARK_SAMPLE 0
+#define PANJIT_TOUCH_DEVICE_GUID NV_ODM_GUID('p','a','n','j','i','t','_','0')
+#define PANJIT_READ(dev, reg, buffer, len) \
+ PANJIT_ReadRegister(dev, reg, buffer, len)
+#define PANJIT_I2C_SPEED_KHZ 400
+#define SAMPLES_PER_SECOND 80
+
+#define SLEEP_MODE_NORMAL 0x00
+#define SLEEP_MODE_SENSOR_SLEEP 0x01
+
+#define X_MIN 0x00
+#define Y_MIN 0x00
+#define X_MAX 4095
+#define Y_MAX 4095
+#define PANJIT_I2C_TIMEOUT 1000
+#define PANJIT_DEBOUNCE_TIME_MS 1
+#define TP_DATA_LENGTH 12
+#define TP_TOUCH_STATE_BYTE 0
+#define TP_FINGER_ONE_MASK 0x01
+#define TP_FINGER_TWO_MASK 0x02
+#define TP_SPECIAL_FUNCTION_BYTE 9
+
+static const
+NvOdmTouchCapabilities PANJIT_Capabilities =
+{
+ 1, // IsMultiTouchSupported
+ 2, // MaxNumberOfFingerCoordReported;
+ 0, // IsRelativeDataSupported
+ 0, // MaxNumberOfRelativeCoordReported
+ 0, // MaxNumberOfWidthReported
+ 0, // MaxNumberOfPressureReported
+ (NvU32)NvOdmTouchGesture_Not_Supported, // Gesture
+ 0, // IsWidthSupported
+ 0, // IsPressureSupported
+ 1, // IsFingersSupported
+ X_MIN, // XMinPosition
+ Y_MIN, // YMinPosition
+ X_MAX, // XMaxPosition
+ Y_MAX, // YMaxPosition
+ 0
+};
+
+#define INT_PIN_ACTIVE_STATE 0
+
+static NvBool
+PANJIT_ReadRegister(
+ PANJIT_TouchDevice* hTouch,
+ NvU8 reg,
+ NvU8* buffer,
+ NvU32 len)
+{
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ TransactionInfo.Address = (hTouch->DeviceAddr | 0x1);
+ TransactionInfo.Buf = buffer;
+ TransactionInfo.Flags = 0;
+ TransactionInfo.NumBytes = len;
+
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ &TransactionInfo,
+ 1,
+ hTouch->I2cClockSpeedKHz,
+ PANJIT_I2C_TIMEOUT);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ NVODMTOUCH_PRINTF(("I2C Read Failure = %d (addr=0x%x, reg=0x%x)\r\n", Error,
+ hTouch->DeviceAddr, reg));
+ return NV_FALSE;
+ }
+
+ return NV_TRUE;
+}
+
+static NvBool
+PANJIT_WriteRegister(
+ PANJIT_TouchDevice* hTouch,
+ NvU8 reg,
+ NvU8* buffer,
+ NvU32 len)
+{
+ NvOdmI2cStatus Error;
+ NvOdmI2cTransactionInfo TransactionInfo;
+
+ TransactionInfo.Address = hTouch->DeviceAddr;
+ TransactionInfo.Buf = buffer;
+ TransactionInfo.Flags = NVODM_I2C_IS_WRITE;
+ TransactionInfo.NumBytes = len;
+
+ Error = NvOdmI2cTransaction(hTouch->hOdmI2c,
+ &TransactionInfo,
+ 1,
+ hTouch->I2cClockSpeedKHz,
+ PANJIT_I2C_TIMEOUT);
+
+ if (Error != NvOdmI2cStatus_Success)
+ {
+ NVODMTOUCH_PRINTF(("I2C Write Failure = %d (addr=0x%x, reg=0x%x)\r\n",
+ Error, hTouch->DeviceAddr, reg));
+ return NV_FALSE;
+ }
+ return NV_TRUE;
+}
+
+static void PANJIT_EnableScanMode(PANJIT_TouchDevice* hTouch)
+{
+ NvU8 buff[4];
+
+ // Enable Scan Mode.
+ buff[0] = 0;
+ buff[1] = 8;
+ PANJIT_WriteRegister(hTouch, 0, buff, 2);
+}
+
+static void PANJIT_ClearInterrupt(PANJIT_TouchDevice* hTouch)
+{
+ NvU8 buff[4];
+
+ // Clear Interrupt.
+ buff[0] = 1;
+ buff[1] = 0;
+ PANJIT_WriteRegister(hTouch, 0, buff, 2);
+}
+
+static NvBool PANJIT_Configure(PANJIT_TouchDevice* hTouch)
+{
+
+ NVODMTOUCH_PRINTF(("PANJIT_Configure\r\n"));
+
+ hTouch->SleepMode = SLEEP_MODE_NORMAL;
+ hTouch->SampleRate = SAMPLES_PER_SECOND;
+
+ // Enable Scan Mode.
+ PANJIT_EnableScanMode(hTouch);
+ // Clear Interrupt.
+ PANJIT_ClearInterrupt(hTouch);
+ return NV_TRUE;
+}
+
+static NvBool
+PANJIT_GetSample(
+ PANJIT_TouchDevice* hTouch,
+ NvOdmTouchCoordinateInfo* coord)
+{
+ NvU8 TouchData[TP_DATA_LENGTH] = {0};
+
+ NVODMTOUCH_PRINTF(("PANJIT_GetSample+\r\n"));
+
+ if (!hTouch || !coord)
+ return NV_FALSE;
+
+ if (!PANJIT_READ(hTouch, 0, &TouchData[0], TP_DATA_LENGTH))
+ return NV_FALSE;
+
+ NVODMTOUCH_PRINTF(("TouchData=0x%x %x %x %x %x %x %x %x %x %x %x %x\r\n",
+ TouchData[0], TouchData[1], TouchData[2], TouchData[3], TouchData[4],
+ TouchData[5], TouchData[6], TouchData[7],TouchData[8], TouchData[9],
+ TouchData[10], TouchData[11]));
+
+ /* Ignore No finger */
+ coord->fingerstate = (TouchData[10] & (TP_FINGER_ONE_MASK | TP_FINGER_TWO_MASK)) ?
+ NvOdmTouchSampleValidFlag : NvOdmTouchSampleIgnore;
+
+ if (coord->fingerstate == NvOdmTouchSampleIgnore)
+ {
+ if (hTouch->PrevFingers == 0)
+ {
+ NVODMTOUCH_PRINTF(("NvOdmTouchSampleIgnore\r\n"));
+ return NV_TRUE;
+ }
+ coord->fingerstate = NvOdmTouchSampleValidFlag;
+ }
+
+ // get the finger count
+ coord->additionalInfo.Fingers = TouchData[10];
+ if (coord->additionalInfo.Fingers > hTouch->Caps.MaxNumberOfFingerCoordReported)
+ coord->additionalInfo.Fingers = hTouch->Caps.MaxNumberOfFingerCoordReported;
+
+ NVODMTOUCH_PRINTF(("coord->additionalInfo.Fingers = %d\r\n",
+ coord->additionalInfo.Fingers));
+
+ if (coord->additionalInfo.Fingers)
+ {
+ coord->fingerstate |= NvOdmTouchSampleDownFlag;
+ coord->xcoord = TouchData[2];
+ coord->xcoord = ((coord->xcoord<<8)|(TouchData[3]));
+ coord->ycoord = TouchData[4];
+ coord->ycoord = ((coord->ycoord<<8)|(TouchData[5]));
+ coord->additionalInfo.multi_XYCoords[0][0] = coord->xcoord;
+ coord->additionalInfo.multi_XYCoords[0][1] = coord->ycoord;
+ coord->additionalInfo.multi_XYCoords[1][0] = (TouchData[6]<<8) | (TouchData[7]);
+ coord->additionalInfo.multi_XYCoords[1][1] = (TouchData[8]<<8) | (TouchData[9]);
+ }
+ hTouch->PrevFingers = coord->additionalInfo.Fingers;
+ NVODMTOUCH_PRINTF(("(%d,%d)\r\n", coord->xcoord, coord->ycoord));
+ return NV_TRUE;
+}
+
+static void PANJIT_GpioIsr(void *arg)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)arg;
+
+ /* Signal the touch thread to read the sample. After it is done reading the
+ * sample it should re-enable the interrupt. */
+ NvOdmOsSemaphoreSignal(hTouch->hIntSema);
+}
+
+NvBool
+PANJIT_ReadCoordinate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCoordinateInfo* coord)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+ NvBool status = NV_FALSE;
+ static NvU32 prevSamleTime;
+ NvU32 CurrentSampleTime;
+#if PANJIT_BENCHMARK_SAMPLE
+ NvU32 time;
+#endif
+ NvU32 pinValue;
+
+ NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &pinValue);
+ if (pinValue != INT_PIN_ACTIVE_STATE)
+ return NV_FALSE;
+
+ CurrentSampleTime = NvOdmOsGetTimeMS();
+ if (prevSamleTime)
+ {
+ if ((1000/hTouch->SampleRate) > (CurrentSampleTime - prevSamleTime))
+ {
+ NvOsSleepMS((1000/hTouch->SampleRate) - (CurrentSampleTime - prevSamleTime));
+ }
+ }
+ prevSamleTime = CurrentSampleTime;
+
+#if PANJIT_BENCHMARK_SAMPLE
+ time = CurrentSampleTime;
+#endif
+
+ status = PANJIT_GetSample(hTouch, coord);
+
+#if PANJIT_BENCHMARK_SAMPLE
+ NvOdmOsDebugPrintf("Touch sample time %d\r\n", NvOdmOsGetTimeMS() - time);
+#endif
+ return status;
+}
+
+void
+PANJIT_GetCapabilities(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCapabilities* pCapabilities)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ if (hTouch && pCapabilities)
+ *pCapabilities = hTouch->Caps;
+}
+
+void PANJIT_Close (NvOdmTouchDeviceHandle hDevice)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ if (hTouch)
+ {
+ if (hTouch->hGpio)
+ {
+ if (hTouch->hGpioIntr)
+ {
+ NvOdmGpioInterruptUnregister(hTouch->hGpio,
+ hTouch->hPin, hTouch->hGpioIntr);
+ hTouch->hGpioIntr = NULL;
+ }
+
+ if (hTouch->hPin)
+ {
+ NvOdmGpioReleasePinHandle(hTouch->hGpio, hTouch->hPin);
+ hTouch->hPin = NULL;
+ }
+
+ NvOdmGpioClose(hTouch->hGpio);
+ hTouch->hGpio = NULL;
+ }
+
+ if (hTouch->hOdmI2c)
+ {
+ NvOdmI2cClose(hTouch->hOdmI2c);
+ hTouch->hOdmI2c = NULL;
+ }
+
+ NvOdmOsFree(hTouch);
+ hTouch = NULL;
+ }
+}
+
+static void InitOdmTouch (NvOdmTouchDevice *pDev)
+{
+ if (pDev)
+ {
+ pDev->Close = PANJIT_Close;
+ pDev->GetCapabilities = PANJIT_GetCapabilities;
+ pDev->ReadCoordinate = PANJIT_ReadCoordinate;
+ pDev->EnableInterrupt = PANJIT_EnableInterrupt;
+ pDev->HandleInterrupt = PANJIT_HandleInterrupt;
+ pDev->GetSampleRate = PANJIT_GetSampleRate;
+ pDev->SetSampleRate = PANJIT_SetSampleRate;
+ pDev->PowerControl = PANJIT_PowerControl;
+ pDev->PowerOnOff = PANJIT_PowerOnOff;
+ pDev->GetCalibrationData = PANJIT_GetCalibrationData;
+ pDev->OutputDebugMessage = NV_TRUE;
+ }
+}
+
+NvBool PANJIT_Open(NvOdmTouchDeviceHandle *hDevice)
+{
+ PANJIT_TouchDevice *hTouch = NULL;
+ NvU32 i = 0;
+ NvU32 found = 0;
+ NvU32 GpioPort = 0;
+ NvU32 GpioPin = 0;
+ NvU32 I2cInstance = 0;
+ NvOdmIoModule IoModule = NvOdmIoModule_I2c;
+ const NvOdmPeripheralConnectivity *pConnectivity = NULL;
+
+ NVODMTOUCH_PRINTF(("NvOdm Touch : PANJIT_Open() \r\n"));
+
+ // allocate memory to be used for the handle
+ hTouch = NvOdmOsAlloc(sizeof(PANJIT_TouchDevice));
+ if (!hTouch)
+ return NV_FALSE;
+
+ NvOdmOsMemset(hTouch, 0, sizeof(PANJIT_TouchDevice));
+
+ /* set function pointers */
+ InitOdmTouch(&hTouch->OdmTouch);
+
+ // read the query database
+ pConnectivity = NvOdmPeripheralGetGuid(PANJIT_TOUCH_DEVICE_GUID);
+ if (!pConnectivity)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : pConnectivity is NULL Error \r\n"));
+ goto fail;
+ }
+
+ if (pConnectivity->Class != NvOdmPeripheralClass_HCI)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : didn't find any periperal\
+ in discovery query for touch device Error \r\n"));
+ goto fail;
+ }
+
+ for (i = 0; i < pConnectivity->NumAddress; i++)
+ {
+ switch (pConnectivity->AddressList[i].Interface)
+ {
+ case NvOdmIoModule_I2c:
+ case NvOdmIoModule_I2c_Pmu:
+ hTouch->DeviceAddr = pConnectivity->AddressList[i].Address;
+ I2cInstance = pConnectivity->AddressList[i].Instance;
+ found |= 1;
+ IoModule = pConnectivity->AddressList[i].Interface;
+ break;
+
+ case NvOdmIoModule_Gpio:
+ GpioPort = pConnectivity->AddressList[i].Instance;
+ GpioPin = pConnectivity->AddressList[i].Address;
+ found |= 2;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ // see if we found the bus and GPIO used by the hardware
+ if ((found & 3) != 3)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch:peripheral connectivity problem \r\n"));
+ goto fail;
+ }
+
+ // allocate I2C instance
+ hTouch->hOdmI2c = NvOdmI2cOpen(IoModule, I2cInstance);
+ if (!hTouch->hOdmI2c)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmI2cOpen Error \r\n"));
+ goto fail;
+ }
+
+ // get the handle to the pin used as pen down interrupt
+ hTouch->hGpio = (NvOdmServicesGpioHandle)NvOdmGpioOpen();
+ if (!hTouch->hGpio)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmGpioOpen Error \r\n"));
+ goto fail;
+ }
+
+ hTouch->hPin = NvOdmGpioAcquirePinHandle(hTouch->hGpio, GpioPort, GpioPin);
+ if (!hTouch->hPin)
+ {
+ NVODMTOUCH_PRINTF(("NvOdm Touch : Couldn't get GPIO pin \r\n"));
+ goto fail;
+ }
+
+ NvOdmGpioConfig(hTouch->hGpio, hTouch->hPin, NvOdmGpioPinMode_InputData);
+
+ /* set default capabilities */
+ NvOdmOsMemcpy(&hTouch->Caps, &PANJIT_Capabilities,
+ sizeof(NvOdmTouchCapabilities));
+
+ /* set default I2C speed */
+ hTouch->I2cClockSpeedKHz = PANJIT_I2C_SPEED_KHZ;
+
+ /* set max positions */
+ hTouch->Caps.XMaxPosition = X_MAX;
+ hTouch->Caps.YMaxPosition = Y_MAX;
+
+ PANJIT_Configure(hTouch);
+
+ *hDevice = (NvOdmTouchDeviceHandle)hTouch;
+ return NV_TRUE;
+
+ fail:
+ PANJIT_Close((NvOdmTouchDeviceHandle)hTouch);
+ hTouch = NULL;
+ return NV_FALSE;
+}
+
+NvBool
+PANJIT_EnableInterrupt(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmOsSemaphoreHandle hIntSema)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ NV_ASSERT(hIntSema);
+
+ /* can only be initialized once */
+ if (hTouch->hGpioIntr || hTouch->hIntSema)
+ return NV_FALSE;
+
+ hTouch->hIntSema = hIntSema;
+
+ if (NvOdmGpioInterruptRegister(
+ hTouch->hGpio,
+ &hTouch->hGpioIntr,
+ hTouch->hPin,
+ NvOdmGpioPinMode_InputInterruptLow,
+ PANJIT_GpioIsr,
+ (void*)hTouch,
+ PANJIT_DEBOUNCE_TIME_MS) == NV_FALSE)
+ {
+ return NV_FALSE;
+ }
+
+ if (!hTouch->hGpioIntr)
+ return NV_FALSE;
+ return NV_TRUE;
+}
+
+NvBool PANJIT_HandleInterrupt(NvOdmTouchDeviceHandle hDevice)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+ NvU32 pinValue;
+
+ if (hTouch)
+ {
+ NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &pinValue);
+ if (pinValue == INT_PIN_ACTIVE_STATE)
+ {
+ // Clear Interrupt.
+ PANJIT_ClearInterrupt(hTouch);
+ NvOdmGpioInterruptDone(hTouch->hGpioIntr);
+ return NV_TRUE;
+ }
+ }
+ return NV_FALSE;
+}
+
+NvBool
+PANJIT_GetSampleRate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchSampleRate* pTouchSampleRate)
+{
+ if (pTouchSampleRate)
+ {
+ pTouchSampleRate->NvOdmTouchSampleRateHigh = SAMPLES_PER_SECOND;
+ pTouchSampleRate->NvOdmTouchSampleRateLow = SAMPLES_PER_SECOND;
+ pTouchSampleRate->NvOdmTouchCurrentSampleRate = 0; // 0 = low , 1 = high
+ }
+ return NV_TRUE;
+}
+
+NvBool PANJIT_SetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 rate)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+
+ if (hTouch)
+ {
+ if (rate > SAMPLES_PER_SECOND)
+ hTouch->SampleRate = SAMPLES_PER_SECOND;
+ else
+ hTouch->SampleRate = rate;
+ }
+ return NV_TRUE;
+}
+
+NvBool
+PANJIT_PowerControl(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchPowerModeType mode)
+{
+ PANJIT_TouchDevice *hTouch = (PANJIT_TouchDevice *)hDevice;
+ NvU8 SleepMode;
+
+ switch(mode)
+ {
+ case NvOdmTouch_PowerMode_0:
+ SleepMode = SLEEP_MODE_NORMAL;
+ break;
+ case NvOdmTouch_PowerMode_1:
+ case NvOdmTouch_PowerMode_2:
+ case NvOdmTouch_PowerMode_3:
+ SleepMode = SLEEP_MODE_SENSOR_SLEEP;
+ break;
+ default:
+ return NV_FALSE;
+ }
+
+ if (hTouch->SleepMode == SleepMode)
+ return NV_TRUE;
+ hTouch->SleepMode = SleepMode;
+ return NV_TRUE;
+}
+
+NvBool
+PANJIT_GetCalibrationData(
+ NvOdmTouchDeviceHandle hDevice,
+ NvU32 NumOfCalibrationData,
+ NvS32* pRawCoordBuffer)
+{
+ static NvS32 RawCoordBuffer[] = {2048,2048,840,840,840,3330,3280,3330,3280,840};
+
+ if (!pRawCoordBuffer)
+ return NV_FALSE;
+
+ if (NumOfCalibrationData * 2 != (sizeof(RawCoordBuffer) / sizeof(NvS32)))
+ {
+ NVODMTOUCH_PRINTF(("WARNING: number of calibration data isn't matched\r\n"));
+ return NV_FALSE;
+ }
+
+ NvOdmOsMemcpy(pRawCoordBuffer, RawCoordBuffer, sizeof(RawCoordBuffer));
+ return NV_TRUE;
+}
+
+NvBool PANJIT_PowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff)
+{
+ if (!hDevice)
+ return NV_FALSE;
+
+ if (OnOff)
+ return PANJIT_PowerControl(hDevice, NvOdmTouch_PowerMode_0); // power ON
+ else
+ return PANJIT_PowerControl(hDevice, NvOdmTouch_PowerMode_3); // power OFF
+}
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h new file mode 100644 index 000000000000..bfff86fe21ce --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_panjit.h @@ -0,0 +1,188 @@ +/*
+ * Copyright (c) 2010 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_NVODM_TOUCH_PANJIT_H
+#define INCLUDED_NVODM_TOUCH_PANJIT_H
+
+#include "nvodm_touch_int.h"
+#include "nvodm_services.h"
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+typedef struct PANJIT_TouchDevice_Rec
+{
+ NvOdmTouchDevice OdmTouch;
+ NvOdmTouchCapabilities Caps;
+ NvOdmServicesI2cHandle hOdmI2c;
+ NvOdmServicesGpioHandle hGpio;
+ NvOdmServicesPmuHandle hPmu;
+ NvOdmGpioPinHandle hPin;
+ NvOdmServicesGpioIntrHandle hGpioIntr;
+ NvOdmOsSemaphoreHandle hIntSema;
+ NvU32 PrevFingers;
+ NvU32 DeviceAddr;
+ NvU32 SampleRate;
+ NvU32 SleepMode;
+ NvBool PowerOn;
+ NvU32 I2cClockSpeedKHz;
+} PANJIT_TouchDevice;
+
+/**
+ * Gets a handle to the touch pad in the system.
+ *
+ * @param hDevice A pointer to the handle of the touch pad.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool PANJIT_Open(NvOdmTouchDeviceHandle *hDevice);
+
+/**
+ * Releases the touch pad handle.
+ *
+ * @param hDevice The touch pad handle to be released. If
+ * NULL, this API has no effect.
+ */
+void PANJIT_Close(NvOdmTouchDeviceHandle hDevice);
+
+/**
+ * Gets capabilities for the specified touch device.
+ *
+ * @param hDevice The handle of the touch pad.
+ * @param pCapabilities A pointer to the targeted
+ * capabilities returned by the ODM.
+ */
+void
+PANJIT_GetCapabilities(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCapabilities* pCapabilities);
+
+/**
+ * Gets coordinate info from the touch device.
+ *
+ * @param hDevice The handle to the touch pad.
+ * @param coord A pointer to the structure holding coordinate info.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool
+PANJIT_ReadCoordinate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchCoordinateInfo *pCoord);
+
+/**
+ * Hooks up the interrupt handle to the GPIO interrupt and enables the interrupt.
+ *
+ * @param hDevice The handle to the touch pad.
+ * @param hInterruptSemaphore A handle to hook up the interrupt.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool
+PANJIT_EnableInterrupt(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmOsSemaphoreHandle hInterruptSemaphore);
+
+/**
+ * Prepares the next interrupt to get notified from the touch device.
+ *
+ * @param hDevice A handle to the touch pad.
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+ */
+NvBool PANJIT_HandleInterrupt(NvOdmTouchDeviceHandle hDevice);
+
+/**
+ * Gets the touch ADC sample rate.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param pTouchSampleRate A pointer to the NvOdmTouchSampleRate stucture.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+*/
+NvBool
+PANJIT_GetSampleRate(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchSampleRate* pTouchSampleRate);
+
+/**
+ * Sets the touch ADC sample rate.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param SampleRate 1 indicates high frequency, 0 indicates low frequency.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+*/
+NvBool PANJIT_SetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 rate);
+
+/**
+ * Sets the touch panel power mode.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param mode The mode, ranging from full power to power off.
+ *
+ * @return NV_TRUE if successful, or NV_FALSE otherwise.
+*/
+NvBool
+PANJIT_PowerControl(
+ NvOdmTouchDeviceHandle hDevice,
+ NvOdmTouchPowerModeType mode);
+
+/**
+ * Gets the touch panel calibration data.
+ * This is optional as calibration may perform after the OS is up.
+ * This is not required to bring up the touch panel.
+ *
+ * @param hDevice A handle to the touch panel.
+ * @param NumOfCalibrationData Indicates the number of calibration points.
+ * @param pRawCoordBuffer The collection of X/Y coordinate data.
+ *
+ * @return NV_TRUE if preset calibration data is required, or NV_FALSE otherwise.
+ */
+NvBool
+PANJIT_GetCalibrationData(
+ NvOdmTouchDeviceHandle hDevice,
+ NvU32 NumOfCalibrationData,
+ NvS32* pRawCoordBuffer);
+
+/**
+ * Powers the touch device on or off.
+ *
+ * @param hDevice A handle to the touch ADC.
+ * @param OnOff Specify 1 to power ON, 0 to power OFF.
+*/
+NvBool PANJIT_PowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // INCLUDED_NVODM_TOUCH_PANJIT_H
+
diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c new file mode 100644 index 000000000000..c57663299cc8 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.c @@ -0,0 +1,861 @@ +/* + * 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 "nvodm_touch_int.h" +#include "nvodm_services.h" +#include "nvodm_touch_tpk.h" +#include "nvodm_query_discovery.h" +#include "tpk_reg.h" + +#define TPK_I2C_SPEED_KHZ 40 +#define TPK_I2C_TIMEOUT 500 +#define TPK_LOW_SAMPLE_RATE 0 //40 reports per-second +#define TPK_HIGH_SAMPLE_RATE 1 //80 reports per-second +#define TPK_MAX_READ_BYTES 16 +#define TPK_MAX_PACKET_SIZE 8 +#define TPK_CHECK_ERRORS 0 +#define TPK_BENCHMARK_SAMPLE 0 +#define TPK_REPORT_WAR_SUCCESS 0 +#define TPK_REPORT_2ND_FINGER_DATA 0 +#define TPK_DUMP_REGISTER 0 +#define TPK_SCREEN_ANGLE 0 //0=Landscape, 1=Portrait +#define TPK_QUERY_SENSOR_RESOLUTION 0 //units per millimeter +#define TPK_SET_MAX_POSITION 0 +#define TPK_PAGE_CHANGE_DELAY 0 //This should be unnecessary +#define TPK_POR_DELAY 100 //Dealy after Power-On Reset + //500ms(Max) is suggested + //by RMI Interface Guide + //(511-000099-01 Rev.B) + +#define TPK_ADL340_WAR 0 +/* WAR for spurious zero reports from panel: verify zero + fingers sample data by waiting one refresh interval and + retrying reading data */ +#define TPK_SPURIOUS_ZERO_WAR 1 + +#define TPK_TOUCH_DEVICE_GUID NV_ODM_GUID('t','p','k','t','o','u','c','h') + +#define TPK_WRITE(dev, reg, byte) TPK_WriteRegister(dev, reg, byte) +#define TPK_READ(dev, reg, buffer, len) TPK_ReadRegisterSafe(dev, reg, buffer, len) +#define TPK_DEBOUNCE_TIME_MS 0 + +typedef struct TPK_TouchDeviceRec +{ + NvOdmTouchDevice OdmTouch; + NvOdmTouchCapabilities Caps; + NvOdmServicesI2cHandle hOdmI2c; + NvOdmServicesGpioHandle hGpio; + NvOdmServicesPmuHandle hPmu; + NvOdmGpioPinHandle hPin; + NvOdmServicesGpioIntrHandle hGpioIntr; + NvOdmOsSemaphoreHandle hIntSema; + NvBool PrevFingers; + NvU32 DeviceAddr; + NvU32 SampleRate; + NvU32 SleepMode; + NvBool PowerOn; + NvU32 VddId; + NvU32 ChipRevisionId; //Id=0x01:TPK chip on Concorde1 + //id=0x02:TPK chip with updated firmware on Concorde2 + NvU32 I2cClockSpeedKHz; +} TPK_TouchDevice; + + +static const NvOdmTouchCapabilities TPK_Capabilities = +{ + 1, //IsMultiTouchSupported + 2, //MaxNumberOfFingerCoordReported; + 0, //IsRelativeDataSupported + 1, //MaxNumberOfRelativeCoordReported + 15, //MaxNumberOfWidthReported + 255, //MaxNumberOfPressureReported + (NvU32)NvOdmTouchGesture_Not_Supported, //Gesture + 1, //IsWidthSupported + 1, //IsPressureSupported + 1, //IsFingersSupported + 0, //XMinPosition + 0, //YMinPosition + 0, //XMaxPosition + 0, //YMaxPosition +#if TPK_SCREEN_ANGLE + (NvU32)NvOdmTouchOrientation_H_FLIP // Orientation 4 inch tpk panel +#else + (NvU32)(NvOdmTouchOrientation_XY_SWAP | NvOdmTouchOrientation_H_FLIP | NvOdmTouchOrientation_V_FLIP) +#endif +}; + +#if TPK_ADL340_WAR +// Dummy write accelerometer in order to workaround a HW bug of ADL340 +// Will Remove it once we use new accelerometer +static NvBool NvAccDummyI2CSetRegs(TPK_TouchDevice* hTouch) +{ + NvOdmI2cTransactionInfo TransactionInfo; + NvU8 arr[2]; + NvOdmI2cStatus Error; + + arr[0] = 0x0; + arr[1] = 0x0; + + TransactionInfo.Address = 0x3A; + TransactionInfo.Buf = arr; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + // Write dummy data to accelerometer + + do + { + Error = NvOdmI2cTransaction(hTouch->hOdmI2c, + &TransactionInfo, + 1, + hTouch->I2cClockSpeedKHz, + TPK_I2C_TIMEOUT); + } while (Error == NvOdmI2cStatus_Timeout); + + if (Error != NvOdmI2cStatus_Success) + { + //NvOdmOsDebugPrintf("error!\r\n"); + return NV_FALSE; + } + //NvOdmOsDebugPrintf("dummy!\r\n"); + return NV_TRUE; +} +#endif + +static NvBool TPK_WriteRegister (TPK_TouchDevice* hTouch, NvU8 reg, NvU8 val) +{ + NvOdmI2cStatus Error; + NvOdmI2cTransactionInfo TransactionInfo; + NvU8 arr[2]; +#if TPK_ADL340_WAR + // dummy write + Error = NvAccDummyI2CSetRegs(hTouch); +#endif + arr[0] = reg; + arr[1] = val; + + TransactionInfo.Address = hTouch->DeviceAddr; + TransactionInfo.Buf = arr; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + do + { + Error = NvOdmI2cTransaction(hTouch->hOdmI2c, + &TransactionInfo, + 1, + hTouch->I2cClockSpeedKHz, + TPK_I2C_TIMEOUT); + } while (Error == NvOdmI2cStatus_Timeout); + + if (Error != NvOdmI2cStatus_Success) + { + NVODMTOUCH_PRINTF(("I2C Write Failure = %d (addr=0x%x, reg=0x%x, val=0x%0x)\n", Error, + hTouch->DeviceAddr, reg, val)); + return NV_FALSE; + } + return NV_TRUE; +} + +#define TPK_MAX_READS (((TPK_MAX_READ_BYTES+(TPK_MAX_PACKET_SIZE-1))/TPK_MAX_PACKET_SIZE)) + +static NvBool TPK_ReadRegisterOnce (TPK_TouchDevice* hTouch, NvU8 reg, NvU8* buffer, NvU32 len) +{ + NvOdmI2cStatus Error; + NvOdmI2cTransactionInfo TransactionInfo[2 * TPK_MAX_READS]; + int reads = (len+(TPK_MAX_PACKET_SIZE-1))/TPK_MAX_PACKET_SIZE; + int left = len; + int i; + + NV_ASSERT(len <= TPK_MAX_READ_BYTES); +#if TPK_ADL340_WAR + // dummy write + Error = NvAccDummyI2CSetRegs(hTouch); +#endif + //////////////////////////////////////////////////////////////////////////// + // For multi-byte reads, the TPK panel supports just sending the first + // address and then keep reading registers (non-standard SMBus operation). + // The limit for I2C packets is 8 bytes, so we read up to 8 bytes per + // multi-byte read transaction. + //////////////////////////////////////////////////////////////////////////// + + for (i = 0; i < reads; i++) + { + int ind = i*2; + + TransactionInfo[ind].Address = hTouch->DeviceAddr; + TransactionInfo[ind].Buf = ® + TransactionInfo[ind].Flags = NVODM_I2C_IS_WRITE; + TransactionInfo[ind].NumBytes = 1; + + ind++; + + TransactionInfo[ind].Address = hTouch->DeviceAddr | 0x1; + TransactionInfo[ind].Buf = buffer + i*TPK_MAX_PACKET_SIZE; + TransactionInfo[ind].Flags = 0; + TransactionInfo[ind].NumBytes = + left > TPK_MAX_PACKET_SIZE ? TPK_MAX_PACKET_SIZE : left; + + left -= TPK_MAX_PACKET_SIZE; + } + + do + { + Error = NvOdmI2cTransaction(hTouch->hOdmI2c, + TransactionInfo, + reads * 2, + hTouch->I2cClockSpeedKHz, + TPK_I2C_TIMEOUT); + } while (Error == NvOdmI2cStatus_Timeout); + + if (Error != NvOdmI2cStatus_Success) + { + NVODMTOUCH_PRINTF(("I2C Read Failure = %d (addr=0x%x, reg=0x%x)\n", Error, + hTouch->DeviceAddr, reg)); + return NV_FALSE; + } + + return NV_TRUE; +} + +static NvBool TPK_ReadRegisterSafe (TPK_TouchDevice* hTouch, NvU8 reg, NvU8* buffer, NvU32 len) +{ + + if (!TPK_ReadRegisterOnce(hTouch, reg, buffer, len)) + return NV_FALSE; + + + return NV_TRUE; +} + +static NvBool TPK_SetPage (TPK_TouchDevice* hTouch, NvU8 page) +{ +#if TPK_PAGE_CHANGE_DELAY + NvU32 SetPageDelayMs = 100; //Wait for 100 millisecond after change page +#endif + + if (!TPK_WRITE(hTouch, TPK_PAGE_SELECT, page)) return NV_FALSE; + +#if TPK_PAGE_CHANGE_DELAY + NvOdmOsSleepMS(SetPageDelayMs); +#endif + + return NV_TRUE; +} + +#if TPK_CHECK_ERRORS +static void TPK_CheckError (TPK_TouchDevice* hTouch) +{ + NvU8 status; + TPK_READ(hTouch, TPK_DEVICE_STATUS, &status, 1); + if (status & 0x80) + { + NvU8 error; + TPK_READ(hTouch, TPK_ERROR_STATUE, &error, 1); + NvOdmOsDebugPrintf("Panel error %x %x\n", status, error); + } +#if TPK_DUMP_REGISTER + TPK_READ(hTouch, TPK_DEVICE_STATUS, &status, 1); + NvOdmOsDebugPrintf("DeviceStatus(0x%x)=0x%x\n", TPK_DEVICE_STATUS, status); + + TPK_READ(hTouch, TPK_DEVICE_CONTROL, &status, 1); + NvOdmOsDebugPrintf("DeviceControl(0x%x)=0x%x\n", TPK_DEVICE_CONTROL, status); + + TPK_READ(hTouch, TPK_INTR_ENABLE, &status, 1); + NvOdmOsDebugPrintf("InterruptEnable(0x%x)=0x%x\n", TPK_INTR_ENABLE, status); + + TPK_READ(hTouch, TPK_ERROR_STATUE, &status, 1); + NvOdmOsDebugPrintf("TPK_ERROR_STATUE(0x%x)=0x%x\n", TPK_ERROR_STATUE, status); + + TPK_READ(hTouch, TPK_INTR_STATUS, &status, 1); + NvOdmOsDebugPrintf("InterruptStatus(0x%x)=0x%x\n", TPK_INTR_STATUS, status); + + TPK_READ(hTouch, TPK_DEVICE_COMMAND, &status, 1); + NvOdmOsDebugPrintf("DeviceCommand(0x%x)=0x%x\n", TPK_DEVICE_COMMAND, status); +#endif +} +#endif + +static NvBool TPK_Configure (TPK_TouchDevice* hTouch) +{ + hTouch->SleepMode = 0x0; + hTouch->SampleRate = 0; /* this forces register write */ + return TPK_SetSampleRate(&hTouch->OdmTouch, TPK_HIGH_SAMPLE_RATE); +} + +static NvBool TPK_GetSample (TPK_TouchDevice* hTouch, NvOdmTouchCoordinateInfo* coord) +{ + NvU8 Finger0[6] = {0}; + NvU8 Finger1[6] = {0}; + NvU8 Relative[2] = {0}; + int status = 0; + + NVODMTOUCH_PRINTF(("TPK_GetSample+\n")); + coord->fingerstate = NvOdmTouchSampleIgnore; + + if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0, Finger0, 6)) + return NV_FALSE; + else + status = (Finger0[0] & 0x7); + + if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0+6, Finger1, 6)) + return NV_FALSE; + + if (!TPK_ReadRegisterOnce(hTouch, TPK_DATA_0+12, Relative, 2)) + return NV_FALSE; + + /* tell windows to ignore transitional finger count samples */ + coord->fingerstate = (status > 2) ? NvOdmTouchSampleIgnore : NvOdmTouchSampleValidFlag; + coord->additionalInfo.Fingers = status; + + if (Finger0[0] & 0x8) + // Bit 3 of status indicates a tap. Driver still doesn't expose + // gesture capabilities. This is added more for testing of the support + // in the hardware for gesture support. + { + coord->additionalInfo.Gesture = NvOdmTouchGesture_Tap; + // NvOdmOsDebugPrintf("Detected the Tap gesture\n"); + } + + if (status) + { + /* always read first finger data, even if transitional */ + coord->fingerstate |= NvOdmTouchSampleDownFlag; + + coord->xcoord = + coord->additionalInfo.multi_XYCoords[0][0] = + (((NvU16)Finger0[2] & 0x1f) << 8) | (NvU16)Finger0[3]; + + coord->ycoord = + coord->additionalInfo.multi_XYCoords[0][1] = + (((NvU16)Finger0[4] & 0x1f) << 8) | (NvU16)Finger0[5]; + + coord->additionalInfo.width[0] = Finger0[0] >> 4; + coord->additionalInfo.Pressure[0] = Finger0[1]; + + /* only read second finger data if reported */ + if (status == 2) + { + coord->additionalInfo.multi_XYCoords[1][0] = + (((NvU16)Finger1[2] & 0x1f) << 8) | (NvU16)Finger1[3]; + + coord->additionalInfo.multi_XYCoords[1][1] = + (((NvU16)Finger1[4] & 0x1f) << 8) | (NvU16)Finger1[5]; + + /* these are not supported, zero out just in case */ + coord->additionalInfo.width[1] = 0; + coord->additionalInfo.Pressure[1] = 0; + if ( coord->additionalInfo.multi_XYCoords[1][0] <= 0 || + coord->additionalInfo.multi_XYCoords[1][0] >= hTouch->Caps.XMaxPosition || + coord->additionalInfo.multi_XYCoords[1][1] <= 0 || + coord->additionalInfo.multi_XYCoords[1][1] >= hTouch->Caps.YMaxPosition) + coord->fingerstate = NvOdmTouchSampleIgnore; +#if TPK_REPORT_2ND_FINGER_DATA + else + NvOdmOsDebugPrintf("catch 2 fingers width=0x%x, X=%d, Y=%d, DeltaX=%d, DeltaY=%d\n", + coord->additionalInfo.width[0], + coord->additionalInfo.multi_XYCoords[1][0], + coord->additionalInfo.multi_XYCoords[1][1], + Relative[0], Relative[1]); +#endif + } + } + else if (!hTouch->PrevFingers) + { + /* two successive 0 finger samples */ + coord->fingerstate = NvOdmTouchSampleIgnore; + } + + hTouch->PrevFingers = status; + + NVODMTOUCH_PRINTF(("TPK_GetSample-\n")); + return NV_TRUE; +} + +static void InitOdmTouch (NvOdmTouchDevice* Dev) +{ + Dev->Close = TPK_Close; + Dev->GetCapabilities = TPK_GetCapabilities; + Dev->ReadCoordinate = TPK_ReadCoordinate; + Dev->EnableInterrupt = TPK_EnableInterrupt; + Dev->HandleInterrupt = TPK_HandleInterrupt; + Dev->GetSampleRate = TPK_GetSampleRate; + Dev->SetSampleRate = TPK_SetSampleRate; + Dev->PowerControl = TPK_PowerControl; + Dev->PowerOnOff = TPK_PowerOnOff; + Dev->GetCalibrationData = TPK_GetCalibrationData; + Dev->OutputDebugMessage = NV_FALSE; +} + +static void TPK_GpioIsr(void *arg) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)arg; + + /* Signal the touch thread to read the sample. After it is done reading the + * sample it should re-enable the interrupt. */ + NvOdmOsSemaphoreSignal(hTouch->hIntSema); +} + +NvBool TPK_ReadCoordinate (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo* coord) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + +#if TPK_BENCHMARK_SAMPLE + NvU32 time = NvOdmOsGetTimeMS(); +#endif + NVODMTOUCH_PRINTF(("GpioIst+\n")); + +#if TPK_CHECK_ERRORS + TPK_CheckError(hTouch); +#endif + + for (;;) + { + if (TPK_GetSample(hTouch, coord)) + { + break; + } + + /* If reading the data failed, the panel may be resetting itself. + Poll device status register to find when panel is back up + and reconfigure */ + for (;;) + { + NvU8 status; + + while (!TPK_READ(hTouch, TPK_DEVICE_STATUS, &status, 1)) + { + NvOdmOsSleepMS(10); + } + + /* if we have a panel error, force reset and wait for status again */ + if (status & 0x80) + { + TPK_WRITE(hTouch, TPK_DEVICE_COMMAND, 0x1); + continue; + } + + /* reconfigure panel, if failed start again */ + if (!TPK_Configure(hTouch)) + continue; + + /* re-enable interrupts for absolute data only */ + if (!TPK_WRITE(hTouch, TPK_INTR_ENABLE, 0x3)) + continue; + + break; + } + } + +#if TPK_BENCHMARK_SAMPLE + NvOdmOsDebugPrintf("Touch sample time %d\n", NvOdmOsGetTimeMS() - time); +#endif + + return NV_TRUE; +} + +void TPK_GetCapabilities (NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + *pCapabilities = hTouch->Caps; +} + +NvBool TPK_PowerOnOff (NvOdmTouchDeviceHandle hDevice, NvBool OnOff) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + + hTouch->hPmu = NvOdmServicesPmuOpen(); + + if (!hTouch->hPmu) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmServicesPmuOpen Error \n")); + return NV_FALSE; + } + + if (OnOff != hTouch->PowerOn) + { + NvOdmServicesPmuVddRailCapabilities vddrailcap; + NvU32 settletime; + + NvOdmServicesPmuGetCapabilities( hTouch->hPmu, hTouch->VddId, &vddrailcap); + + if(OnOff) + NvOdmServicesPmuSetVoltage( hTouch->hPmu, hTouch->VddId, vddrailcap.requestMilliVolts, &settletime); + else + NvOdmServicesPmuSetVoltage( hTouch->hPmu, hTouch->VddId, NVODM_VOLTAGE_OFF, &settletime); + + if (settletime) + NvOdmOsWaitUS(settletime); // wait to settle power + + hTouch->PowerOn = OnOff; + + if(OnOff) + NvOdmOsSleepMS(TPK_POR_DELAY); + } + + NvOdmServicesPmuClose(hTouch->hPmu); + + return NV_TRUE; +} + +NvBool TPK_Open (NvOdmTouchDeviceHandle* hDevice) +{ + TPK_TouchDevice* hTouch; + NvU32 i; + NvU32 found = 0; + NvU32 GpioPort = 0; + NvU32 GpioPin = 0; + NvU32 I2cInstance = 0; + NvU8 Buf[4]; +#if TPK_QUERY_SENSOR_RESOLUTION + NvU8 sensorresolution = 0; //units per millimeter +#endif +#if TPK_SET_MAX_POSITION + NvU32 SET_MAX_POSITION = 8191; //Max Position range from 0x0002 to 0x1fff + NvU32 SENSOR_MAX_POSITION = 0; +#endif + NvU8 TPKChipRevID; + + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + + hTouch = NvOdmOsAlloc(sizeof(TPK_TouchDevice)); + if (!hTouch) return NV_FALSE; + + NvOdmOsMemset(hTouch, 0, sizeof(TPK_TouchDevice)); + + /* set function pointers */ + InitOdmTouch(&hTouch->OdmTouch); + + pConnectivity = NvOdmPeripheralGetGuid(TPK_TOUCH_DEVICE_GUID); + if (!pConnectivity) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : pConnectivity is NULL Error \n")); + goto fail; + } + + if (pConnectivity->Class != NvOdmPeripheralClass_HCI) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : didn't find any periperal in discovery query for touch device Error \n")); + goto fail; + } + + for (i = 0; i < pConnectivity->NumAddress; i++) + { + switch (pConnectivity->AddressList[i].Interface) + { + case NvOdmIoModule_I2c: + hTouch->DeviceAddr = (pConnectivity->AddressList[i].Address << 1); + I2cInstance = pConnectivity->AddressList[i].Instance; + found |= 1; + break; + case NvOdmIoModule_Gpio: + GpioPort = pConnectivity->AddressList[i].Instance; + GpioPin = pConnectivity->AddressList[i].Address; + found |= 2; + break; + case NvOdmIoModule_Vdd: + hTouch->VddId = pConnectivity->AddressList[i].Address; + found |= 4; + break; + default: + break; + } + } + + if ((found & 3) != 3) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : peripheral connectivity problem \n")); + goto fail; + } + + if ((found & 4) != 0) + { + if (NV_FALSE == TPK_PowerOnOff(&hTouch->OdmTouch, 1)) + goto fail; + } + else + { + hTouch->VddId = 0xFF; + } + + hTouch->hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c, I2cInstance); + if (!hTouch->hOdmI2c) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmI2cOpen Error \n")); + goto fail; + } + + hTouch->hGpio = NvOdmGpioOpen(); + + if (!hTouch->hGpio) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : NvOdmGpioOpen Error \n")); + goto fail; + } + + hTouch->hPin = NvOdmGpioAcquirePinHandle(hTouch->hGpio, GpioPort, GpioPin); + if (!hTouch->hPin) + { + NVODMTOUCH_PRINTF(("NvOdm Touch : Couldn't get GPIO pin \n")); + goto fail; + } + + NvOdmGpioConfig(hTouch->hGpio, + hTouch->hPin, + NvOdmGpioPinMode_InputData); + + /* set default capabilities */ + NvOdmOsMemcpy(&hTouch->Caps, &TPK_Capabilities, sizeof(NvOdmTouchCapabilities)); + + /* set default I2C speed */ + hTouch->I2cClockSpeedKHz = TPK_I2C_SPEED_KHZ; + + /* disable interrupts */ + if (!TPK_WRITE(hTouch, TPK_INTR_ENABLE, 0)) + goto fail; + +#if TPK_SET_MAX_POSITION + if (!TPK_READ(hTouch, TPK_SENSOR_MAXPOSITION_0, Buf, 2)) goto fail; + SENSOR_MAX_POSITION = ((NvU32)Buf[0] << 8) | (NvU32)Buf[1]; + NVODMTOUCH_PRINTF(("Touch Max Postion = %d\n", SENSOR_MAX_POSITION)); + + if (!TPK_WRITE(hTouch, TPK_SENSOR_MAXPOSITION_0, (NvU8)((SET_MAX_POSITION & 0x1fff) >> 8))) goto fail; + if (!TPK_WRITE(hTouch, TPK_SENSOR_MAXPOSITION_1, (NvU8)(SET_MAX_POSITION & 0xff))) goto fail; + + if (!TPK_READ(hTouch, TPK_SENSOR_MAXPOSITION_0, Buf, 2)) goto fail; + SENSOR_MAX_POSITION = ((NvU32)Buf[0] << 8) | (NvU32)Buf[1]; + NVODMTOUCH_PRINTF(("Touch Max Postion = %d\n", SENSOR_MAX_POSITION)); +#endif + + /* get max positions */ + /* There is no SMBus Aliased Address to query max position, change page to 0x10 */ + if (!TPK_SetPage(hTouch, ((TPK_RMI_SENSOR_X_MAX_POSITION_0 >> 8) & 0xFF))) goto fail; + + if (!TPK_READ(hTouch, 0x04, Buf, 4)) goto fail; + + hTouch->Caps.XMaxPosition = ((NvU32)Buf[0] << 8) | (NvU32)Buf[1]; + hTouch->Caps.YMaxPosition = ((NvU32)Buf[2] << 8) | (NvU32)Buf[3]; + +#if TPK_QUERY_SENSOR_RESOLUTION + /* get sensor resulution */ + /* There is no SMBus Aliased Address to query sensor resolution, change page to 0x10 */ + if (!TPK_SetPage(hTouch, ((TPK_RMI_SENSOR_RESOLUTION >> 8) & 0xFF))) goto fail; + + if (!TPK_READ(hTouch, TPK_RMI_SENSOR_RESOLUTION, &sensorresolution, 1)) goto fail; + NVODMTOUCH_PRINTF(("Touch Sensor Resolution = %d\n", sensorresolution)); +#endif + /* change page back to 0x04 */ + if (!TPK_SetPage(hTouch, ((TPK_RMI_DATA_0 >> 8) & 0xFF))) goto fail; + + /* get chip revision id */ + if (!TPK_READ(hTouch, TPK_PRODUCT_INFO_QUERY_1, &TPKChipRevID, 1)) goto fail; + + hTouch->ChipRevisionId = (NvU32)TPKChipRevID; + NVODMTOUCH_PRINTF(("Touch controller Revision ID = %d\n", hTouch->ChipRevisionId)); + + /* boost I2c spped to 100Khz when it is new tpk chip */ + if (hTouch->ChipRevisionId == 0x02) + hTouch->I2cClockSpeedKHz = 100; + + /* configure panel */ + if (!TPK_Configure(hTouch)) goto fail; + + *hDevice = &hTouch->OdmTouch; + return NV_TRUE; + + fail: + TPK_Close(&hTouch->OdmTouch); + return NV_FALSE; +} + +NvBool TPK_EnableInterrupt (NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hIntSema) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + NvOdmTouchCoordinateInfo coord; + + NV_ASSERT(hIntSema); + + /* can only be initialized once */ + if (hTouch->hGpioIntr || hTouch->hIntSema) + return NV_FALSE; + + /* zero intr status */ + (void)TPK_GetSample(hTouch, &coord); + + hTouch->hIntSema = hIntSema; + + if (NvOdmGpioInterruptRegister(hTouch->hGpio, &hTouch->hGpioIntr, + hTouch->hPin, NvOdmGpioPinMode_InputInterruptLow, TPK_GpioIsr, + (void*)hTouch, TPK_DEBOUNCE_TIME_MS) == NV_FALSE) + { + return NV_FALSE; + } + + if (!hTouch->hGpioIntr) + return NV_FALSE; + + /* enable interrupts -- only for absolute data */ + if (!TPK_WRITE(hTouch, TPK_INTR_ENABLE, 0x3)) + { + NvOdmGpioInterruptUnregister(hTouch->hGpio, hTouch->hPin, hTouch->hGpioIntr); + hTouch->hGpioIntr = NULL; + return NV_FALSE; + } + + return NV_TRUE; +} + +NvBool TPK_HandleInterrupt(NvOdmTouchDeviceHandle hDevice) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + NvU32 pinValue; + + NvOdmGpioGetState(hTouch->hGpio, hTouch->hPin, &pinValue); + if (!pinValue) + { + //interrupt pin is still LOW, read data until interrupt pin is released. + return NV_FALSE; + } + else + NvOdmGpioInterruptDone(hTouch->hGpioIntr); + + return NV_TRUE; +} + +NvBool TPK_GetSampleRate (NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + pTouchSampleRate->NvOdmTouchSampleRateHigh = 80; + pTouchSampleRate->NvOdmTouchSampleRateLow = 40; + pTouchSampleRate->NvOdmTouchCurrentSampleRate = (hTouch->SampleRate >> 1); + return NV_TRUE; +} + +NvBool TPK_SetSampleRate (NvOdmTouchDeviceHandle hDevice, NvU32 rate) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + + if (rate != 0 && rate != 1) + return NV_FALSE; + + rate = 1 << rate; + + if (hTouch->SampleRate == rate) + return NV_TRUE; + + if (!TPK_WRITE(hTouch, TPK_DEVICE_CONTROL, (NvU8)((rate << 6) | hTouch->SleepMode))) + return NV_FALSE; + + hTouch->SampleRate = rate; + return NV_TRUE; +} + + +NvBool TPK_PowerControl (NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + NvU32 SleepMode; + + NV_ASSERT(hTouch->VddId != 0xFF); + + switch(mode) + { + case NvOdmTouch_PowerMode_0: + SleepMode = 0x0; + break; + case NvOdmTouch_PowerMode_1: + case NvOdmTouch_PowerMode_2: + case NvOdmTouch_PowerMode_3: + SleepMode = 0x03; + break; + default: + return NV_FALSE; + } + + if (hTouch->SleepMode == SleepMode) + return NV_TRUE; + + if (!TPK_WRITE(hTouch, TPK_DEVICE_CONTROL, (NvU8)((hTouch->SampleRate << 6) | SleepMode))) + return NV_FALSE; + + hTouch->SleepMode = SleepMode; + return NV_TRUE; +} + +NvBool TPK_GetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer) +{ +#if TPK_SCREEN_ANGLE + //Portrait + static const NvS32 RawCoordBuffer[] = {2054, 3624, 3937, 809, 3832, 6546, 453, 6528, 231, 890}; +#else + //Landscape + static NvS32 RawCoordBuffer[] = {2054, 3624, 3832, 6546, 453, 6528, 231, 890, 3937, 809}; +#endif + + if (NumOfCalibrationData*2 != (sizeof(RawCoordBuffer)/sizeof(NvS32))) + { + NVODMTOUCH_PRINTF(("WARNING: number of calibration data isn't matched\n")); + return NV_FALSE; + } + + NvOdmOsMemcpy(pRawCoordBuffer, RawCoordBuffer, sizeof(RawCoordBuffer)); + + return NV_TRUE; +} + + +void TPK_Close (NvOdmTouchDeviceHandle hDevice) +{ + TPK_TouchDevice* hTouch = (TPK_TouchDevice*)hDevice; + + if (!hTouch) return; + + if (hTouch->hGpio) + { + if (hTouch->hPin) + { + if (hTouch->hGpioIntr) + NvOdmGpioInterruptUnregister(hTouch->hGpio, hTouch->hPin, hTouch->hGpioIntr); + + NvOdmGpioReleasePinHandle(hTouch->hGpio, hTouch->hPin); + } + + NvOdmGpioClose(hTouch->hGpio); + } + + if (hTouch->hOdmI2c) + NvOdmI2cClose(hTouch->hOdmI2c); + + NvOdmOsFree(hTouch); +} + + diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h new file mode 100644 index 000000000000..6cab3eb66ed1 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/nvodm_touch_tpk.h @@ -0,0 +1,72 @@ +/* + * 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_NVODM_TOUCH_TPK_H +#define INCLUDED_NVODM_TOUCH_TPK_H + +#include "nvodm_touch_int.h" +#include "nvodm_services.h" + +#if defined(__cplusplus) +extern "C" +{ +#endif + +NvBool TPK_Open( NvOdmTouchDeviceHandle *hDevice); + +void TPK_GetCapabilities(NvOdmTouchDeviceHandle hDevice, NvOdmTouchCapabilities* pCapabilities); + +NvBool TPK_ReadCoordinate( NvOdmTouchDeviceHandle hDevice, NvOdmTouchCoordinateInfo *coord); + +NvBool TPK_EnableInterrupt(NvOdmTouchDeviceHandle hDevice, NvOdmOsSemaphoreHandle hInterruptSemaphore); + +NvBool TPK_HandleInterrupt(NvOdmTouchDeviceHandle hDevice); + +NvBool TPK_GetSampleRate(NvOdmTouchDeviceHandle hDevice, NvOdmTouchSampleRate* pTouchSampleRate); + +NvBool TPK_SetSampleRate(NvOdmTouchDeviceHandle hDevice, NvU32 rate); + +NvBool TPK_PowerControl(NvOdmTouchDeviceHandle hDevice, NvOdmTouchPowerModeType mode); + +NvBool TPK_GetCalibrationData(NvOdmTouchDeviceHandle hDevice, NvU32 NumOfCalibrationData, NvS32* pRawCoordBuffer); + +NvBool TPK_PowerOnOff(NvOdmTouchDeviceHandle hDevice, NvBool OnOff); + +void TPK_Close( NvOdmTouchDeviceHandle hDevice); + + +#if defined(__cplusplus) +} +#endif + + +#endif // INCLUDED_NVODM_TOUCH_TPK_H diff --git a/arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h b/arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h new file mode 100644 index 000000000000..141a522bb944 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/touch/tpk_reg.h @@ -0,0 +1,165 @@ +/* + * 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 TPK_REG_HEADER +#define TPK_REG_HEADER + +#if defined(__cplusplus) +extern "C" +{ +#endif + + +// SMBus Aliased Address +/* To make most efficient use of the SMBus paged addressing scheme, Synaptics + * RMI-on-SMBus devices define that for all commonly used RMI device registers, + * there will be a duplicate aliased register located at a new RMI address. + * The entire set of aliased register addresses are grouped into a single page + * of the RMI address space. This will enable user software to access all commonly + * used RMI registers without ever having to rewrite the Page Select register. + * + * The aliased addresses occupy page $04xx in the general RMI address map. At reset, + * all RMI-on-SMBus devices initialize their Page Select register to the value $04. + * This means that by default, all SMBus register accesses will access the RMI + * Aliased Address space. + * + * ---------------------------------------------------------------------------- + * | Aliased Address | General RMI Address | Register Group | + * ---------------------------------------------------------------------------- + * | $0400-$041F | $0400-$041F | RMI Data Register and | + * | | | Device Status Reg | + * ---------------------------------------------------------------------------- + * | $04E0-$04E7 | $0200-$0207 | RMI Product ID queries | + * ---------------------------------------------------------------------------- + * | $04F0-$04F4 | $0000-$0004 | RMI control, command, and | + * | | | general status registers | + * ---------------------------------------------------------------------------- + * | $04FF | $xxFF | Page Select Register | + * ---------------------------------------------------------------------------- + +*/ +#define TPK_DATA_0 0x00 //Data Reg 0 - Finger #0 +#define TPK_DATA_1 0x01 //Data Reg 1 - Finger #0 +#define TPK_DATA_2 0x02 //Data Reg 2 - Finger #0 +#define TPK_DATA_3 0x03 //Data Reg 3 - Finger #0 +#define TPK_DATA_4 0x04 //Data Reg 4 - Finger #0 +#define TPK_DATA_5 0x05 //Data Reg 5 - Finger #0 +#define TPK_DATA_6 0x06 //Data Reg 6 - Finger #1 +#define TPK_DATA_7 0x07 //Data Reg 7 - Finger #1 +#define TPK_DATA_8 0x08 //Data Reg 8 - Finger #1 +#define TPK_DATA_9 0x09 //Data Reg 9 - Finger #1 +#define TPK_DATA_A 0x0A //Data Reg 10 - Finger #1 +#define TPK_DATA_B 0x0B //Data Reg 11 - Finger #1 +#define TPK_RELATIVE_DATA_X 0x0C //Relative Horizontal Motion - Finger #0 +#define TPK_RELATIVE_DATA_Y 0x0D //Relative Vertical Motion - Finger #0 +#define TPK_DEVICE_STATUS 0x0E //Device Status Register +#define TPK_2D_CONTROL 0x21 //Func10: General 2D Control Reg +#define TPK_2D_RELATIVE_SPEED 0x22 //Func10: General 2D Relative Speed Reg +#define TPK_2D_ACCLELERATION 0x23 //Func10: General 2D Relative Acceleration Reg +#define TPK_SENSOR_SENSITIVITY 0x24 //Func10: Sensor Sensitivity +#define TPK_SENSOR_MAXPOSITION_0 0x26 //Func10: Sensor Max Position (bit 12:8) +#define TPK_SENSOR_MAXPOSITION_1 0x27 //Func10: Sensor Max Position (bit 7:0) +#define TPK_RMI_PROTOCOL_VERSION 0xE0 //RMI Protocol Version +#define TPK_MANUFACTURER_ID 0xE1 //Manufacturer ID +#define TPK_PHYSICAL_INTERFACE_VERSION 0xE2 //Physical Interface Version +#define TPK_PRODUCT_QUERY 0xE3 //Product Property +#define TPK_PRODUCT_INFO_QUERY_0 0xE4 //Product Info 0 +#define TPK_PRODUCT_INFO_QUERY_1 0xE5 //Product Info 1 (REVISION_ID) +#define TPK_PRODUCT_INFO_QUERY_2 0xE6 //Product Info 2 +#define TPK_PRODUCT_INFO_QUERY_3 0xE7 //Product Info 3 +#define TPK_DEVICE_CONTROL 0xF0 //Device Control Register +#define TPK_INTR_ENABLE 0xF1 //Interrupt Enable Register +#define TPK_ERROR_STATUE 0xF2 //Error Status Register +#define TPK_INTR_STATUS 0xF3 //Interrupt Request Status Register +#define TPK_DEVICE_COMMAND 0xF4 //Device Command Register +#define TPK_PAGE_SELECT 0xFF //Page Select Register + +// RMI Address Space +// Data registers +#define TPK_RMI_DATA_0 0x0400 //Data Reg 0 - Finger #0 +#define TPK_RMI_DATA_1 0x0401 //Data Reg 1 - Finger #0 +#define TPK_RMI_DATA_2 0x0402 //Data Reg 2 - Finger #0 +#define TPK_RMI_DATA_3 0x0403 //Data Reg 3 - Finger #0 +#define TPK_RMI_DATA_4 0x0404 //Data Reg 4 - Finger #0 +#define TPK_RMI_DATA_5 0x0405 //Data Reg 5 - Finger #0 +#define TPK_RMI_DATA_6 0x0406 //Data Reg 6 - Finger #1 +#define TPK_RMI_DATA_7 0x0407 //Data Reg 7 - Finger #1 +#define TPK_RMI_DATA_8 0x0408 //Data Reg 8 - Finger #1 +#define TPK_RMI_DATA_9 0x0409 //Data Reg 9 - Finger #1 +#define TPK_RMI_DATA_A 0x040A //Data Reg 10 - Finger #1 +#define TPK_RMI_DATA_B 0x040B //Data Reg 11 - Finger #1 +#define TPK_RMI_RELATIVE_DATA_X 0x040C //Relative Horizontal Motion - Finger #0 +#define TPK_RMI_RELATIVE_DATA_Y 0x040D //Relative Vertical Motion - Finger #0 +#define TPK_RMI_DEVICE_STATUS 0x040E //Device Status Register + +// Function $10 register pages +#define TPK_RMI_FUNCTION_VERSION 0x1000 //Func10: Function Version query +#define TPK_RMI_2D_PROPERTIES 0x1001 //Func10: General 2D Properties query +#define TPK_RMI_SENSOR_PROPERTIES_0 0x1002 //Func10: Sensor Properties +#define TPK_RMI_SENSOR_PROPERTIES_1 0x1003 //Func10: Sensor Properties +#define TPK_RMI_SENSOR_X_MAX_POSITION_0 0x1004 //Func10: Sensor X Max Position (bits 12:8) +#define TPK_RMI_SENSOR_X_MAX_POSITION_1 0x1005 //Func10: Sensor X Max Position (bits 7:0) +#define TPK_RMI_SENSOR_Y_MAX_POSITION_0 0x1006 //Func10: Sensor Y Max Position (bits 12:8) +#define TPK_RMI_SENSOR_Y_MAX_POSITION_1 0x1007 //Func10: Sensor Y Max Position (bits 7:0) +#define TPK_RMI_SENSOR_RESOLUTION 0x1008 //Func10: Sensor Resolution +#define TPK_RMI_2D_CONTROL 0x1041 //Func10: General 2D Control Reg +#define TPK_RMI_2D_RELATIVE_SPEED 0x1042 //Func10: General 2D Relative Speed Reg +#define TPK_RMI_2D_ACCLELERATION 0x1043 //Func10: General 2D Relative Acceleration Reg +#define TPK_RMI_SENSOR_SENSITIVITY 0x1044 //Func10: Sensor Sensitivity +#define TPK_RMI_SENSOR_MAXPOSITION_0 0x1046 //Func10: Sensor Max Position (bit 12:8) +#define TPK_RMI_SENSOR_MAXPOSITION_1 0x1047 //Func10: Sensor Max Position (bit 7:0) + +// General product information and version queries +#define TPK_RMI_RMI_PROTOCOL_VERSION 0x2000 //RMI Protocol Version +#define TPK_RMI_MANUFACTURER_ID 0x2001 //Manufacturer ID +#define TPK_RMI_PHYSICAL_INTERFACE_VERSION 0x2002 //Physical Interface Version +#define TPK_RMI_PRODUCT_QUERY 0x2003 //Product Property +#define TPK_RMI_PRODUCT_INFO_QUERY_0 0x2004 //Product Info 0 +#define TPK_RMI_PRODUCT_INFO_QUERY_1 0x2005 //Product Info 1 (REVISION_ID) +#define TPK_RMI_PRODUCT_INFO_QUERY_2 0x2006 //Product Info 2 +#define TPK_RMI_PRODUCT_INFO_QUERY_3 0x2007 //Product Info 3 + +// Standard RMI control, command, and status registers +#define TPK_RMI_DEVICE_CONTROL 0x0000 //Device Control Register +#define TPK_RMI_INTR_ENABLE 0x0001 //Interrupt Enable Register +#define TPK_RMI_ERROR_STATUE 0x0002 //Error Status Register +#define TPK_RMI_INTR_STATUS 0x0003 //Interrupt Request Status Register +#define TPK_RMI_DEVICE_COMMAND 0x0004 //Device Command Register + +#if defined(__cplusplus) +} +#endif + + +#endif //TPK_REG_HEADER + + diff --git a/arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile b/arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile new file mode 100644 index 000000000000..d8807f63e73a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/vibrate/Makefile @@ -0,0 +1,10 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +obj-y += nvodm_vibrate.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c b/arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c new file mode 100644 index 000000000000..43cc3cbf5ee4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/vibrate/nvodm_vibrate.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2006-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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Vibrate Interface</b> + * + * @b Description: Defines the ODM interface for Vibrate devices. + * + */ + +#include "nvodm_vibrate.h" +#include "nvos.h" +#include "nvassert.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvodm_pmu.h" + +#define VIBRATE_DEVICE_GUID NV_ODM_GUID('v','i','b','r','a','t','o','r') + +/** + * @brief Used to enable/disable debug print messages. + */ +#define NV_ODM_DEBUG 0 + +#if NV_ODM_DEBUG + #define NV_ODM_TRACE NvOdmOsDebugPrintf +#else + #define NV_ODM_TRACE (void) +#endif + +typedef struct NvOdmVibDeviceRec +{ + /* The handle to the Pmu device */ + NvOdmServicesPmuHandle hOdmServicePmuDevice; + + /*Pmu Vdd Rail capabilities*/ + NvOdmServicesPmuVddRailCapabilities RailCaps; + + /* Pmu Rail ID*/ + NvU32 VddId; + +} NvOdmVibDevice; + + +/** + * @brief Allocates a handle to the device. Configures the PWM + * control to the Vibro motor with default values. To change + * the amplitude and frequency use NvOdmVibrateSetParameter API. + * @param hOdmVibrate [IN] Opaque handle to the device. + * @return NV_TRUE on success and NV_FALSE on error + */ +NvBool +NvOdmVibOpen(NvOdmVibDeviceHandle *hOdmVibrate) +{ + const NvOdmPeripheralConnectivity *pConnectivity = NULL; + NvU32 Index = 0; + + NV_ASSERT(hOdmVibrate); + + /* Allocate the handle */ + (*hOdmVibrate) = (NvOdmVibDeviceHandle)NvOdmOsAlloc(sizeof(NvOdmVibDevice)); + if (*hOdmVibrate == NULL) + { + NV_ODM_TRACE(("Error Allocating NvOdmPmuDevice. \n")); + return NV_FALSE; + } + NvOsMemset((*hOdmVibrate), 0, sizeof(NvOdmVibDevice)); + + /* Get the PMU handle */ + (*hOdmVibrate)->hOdmServicePmuDevice = NvOdmServicesPmuOpen(); + if (!(*hOdmVibrate)->hOdmServicePmuDevice) + { + NV_ODM_TRACE(("Error Opening Pmu device. \n")); + NvOdmOsFree(*hOdmVibrate); + *hOdmVibrate = NULL; + return NV_FALSE; + } + + // Get the peripheral connectivity information + pConnectivity = NvOdmPeripheralGetGuid(VIBRATE_DEVICE_GUID); + if (pConnectivity == NULL) + return NV_FALSE; + + // Search for the Vdd rail and set the proper volage to the rail. + for (Index = 0; Index < pConnectivity->NumAddress; ++Index) + { + if (pConnectivity->AddressList[Index].Interface == NvOdmIoModule_Vdd) + { + (*hOdmVibrate)->VddId = pConnectivity->AddressList[Index].Address; + NvOdmServicesPmuGetCapabilities((*hOdmVibrate)->hOdmServicePmuDevice, (*hOdmVibrate)->VddId, &((*hOdmVibrate)->RailCaps)); + break; + } + } + + return NV_TRUE; +} + +/** + * @brief Closes the ODM device and destroys all allocated resources. + * @param hOdmVibrate [IN] Opaque handle to the device. + * @return None. + */ +void NvOdmVibClose(NvOdmVibDeviceHandle hOdmVibrate) +{ + if (hOdmVibrate != NULL) + { + NvOdmServicesPmuClose(hOdmVibrate->hOdmServicePmuDevice); + hOdmVibrate->hOdmServicePmuDevice = NULL; + + hOdmVibrate->VddId = 0; + + NvOsMemset(&hOdmVibrate->RailCaps, 0, sizeof(NvOdmServicesPmuVddRailCapabilities)); + + NvOdmOsFree(hOdmVibrate); + hOdmVibrate = NULL; + } +} + + +/** + * @brief Gets capabilities of the Vibrate device. + * @param hOdmVibrate [IN] Opaque handle to the device. + * @param RequestedCaps [IN] Specifies the capability to get. + * @param pCapsValue [OUT] A pointer to the returned value. + * @return NV_TRUE on success and NV_FALSE on error + */ +NvBool +NvOdmVibGetCaps( + NvOdmVibDeviceHandle hOdmVibrate, + NvOdmVibCaps RequestedCaps, + NvU32 *pCapsValue) +{ + NV_ASSERT(hOdmVibrate); + NV_ASSERT(pCapsValue); + + if (!hOdmVibrate || !pCapsValue) + { + return NV_FALSE; + } + + return NV_TRUE; +} + +/** + * @brief The frequency to the Vibro motor can be set + * using this function. A frequency less than zero will be + * clamped to zero and a frequency value beyond the max supported value + * will be clamped to the max supported value. + * @param hOdmVibrate [IN] Opaque handle to the device. + * @param Freq [IN] Frequency in Hz + * @return NV_TRUE on success and NV_FALSE on error + */ +NvBool +NvOdmVibSetFrequency(NvOdmVibDeviceHandle hOdmVibrate, NvS32 Freq) +{ + //AP20 Vibrator does'nt support setting Frequency + return NV_TRUE; +} + +/** + * @brief The dutycycle of the PWM driving the Vibro motor can be set + * using this function. A dutycycle less than zero will be + * clamped to zero and value beyond the max supported value + * will be clamped to the max supported value. + * @param hOdmVibrate [IN] Opaque handle to the device. + * @param DCycle [IN] Duty Cycle value in percentage (0%-100%) + * @return NV_TRUE on success and NV_FALSE on error + */ +NvBool +NvOdmVibSetDutyCycle(NvOdmVibDeviceHandle hOdmVibrate, NvS32 DCycle) +{ + //AP20 Vibrator does'nt support setting DutyCycle + return NV_TRUE; +} + +/** + * @brief Starts the Vibro with the frequency and duty-cycle set using the + * Set API. + * @param hOdmVibrate [IN] Opaque handle to the device. + * @return NV_TRUE on success and NV_FALSE on error + */ +NvBool +NvOdmVibStart(NvOdmVibDeviceHandle hOdmVibrate) +{ + NvU32 SettlingTime = 0; + + NV_ASSERT(hOdmVibrate); + + if (!hOdmVibrate) + { + return NV_FALSE; + } + + if (hOdmVibrate->hOdmServicePmuDevice != NULL) + { + // Search for the Vdd rail and power Off the module + if (hOdmVibrate->VddId) + { + NvOdmServicesPmuSetVoltage(hOdmVibrate->hOdmServicePmuDevice, + hOdmVibrate->VddId, hOdmVibrate->RailCaps.requestMilliVolts, &SettlingTime); + + if (SettlingTime) + NvOdmOsWaitUS(SettlingTime); + } + } + + return NV_TRUE; +} + +/** + * @brief Stops the Vibro motor + * @param hOdmVibrate [IN] Opaque handle to the device. + * @return NV_TRUE on success and NV_FALSE on error + */ +NvBool +NvOdmVibStop(NvOdmVibDeviceHandle hOdmVibrate) +{ + NvU32 SettlingTime; + + NV_ASSERT(hOdmVibrate); + + if (!hOdmVibrate) + { + return NV_FALSE; + } + + if (hOdmVibrate->hOdmServicePmuDevice != NULL) + { + // Search for the Vdd rail and power Off the module + if (hOdmVibrate->VddId) + { + NvOdmServicesPmuSetVoltage(hOdmVibrate->hOdmServicePmuDevice, + hOdmVibrate->VddId, NVODM_VOLTAGE_OFF, &SettlingTime); + + if (SettlingTime) + NvOdmOsWaitUS(SettlingTime); + } + } + + return NV_TRUE; +} diff --git a/arch/arm/mach-tegra/odm_kit/query/Makefile b/arch/arm/mach-tegra/odm_kit/query/Makefile new file mode 100644 index 000000000000..ef54c3faed47 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/Makefile @@ -0,0 +1,3 @@ +obj-$(CONFIG_TEGRA_ODM_HARMONY) += harmony/ +obj-$(CONFIG_TEGRA_ODM_WHISTLER) += whistler/ + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/Makefile b/arch/arm/mach-tegra/odm_kit/query/harmony/Makefile new file mode 100644 index 000000000000..bdc7cbfee77f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/Makefile @@ -0,0 +1,19 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations + +obj-y += nvodm_query.o +obj-y += nvodm_query_discovery.o +obj-y += nvodm_query_nand.o +obj-y += nvodm_query_gpio.o +obj-y += nvodm_query_pinmux.o +obj-y += nvodm_query_kbc.o + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c new file mode 100644 index 000000000000..62243eded55d --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c @@ -0,0 +1,869 @@ +/* + * 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit: + * Implementation of the ODM Query API</b> + * + * @b Description: Implements the query functions for ODMs that may be + * accessed at boot-time, runtime, or anywhere in between. + */ + +#include "nvodm_query.h" +#include "nvodm_query_gpio.h" +#include "nvodm_query_memc.h" +#include "nvodm_query_discovery.h" +#include "nvodm_query_pins.h" +#include "nvodm_query_pins_ap20.h" +#include "tegra_devkit_custopt.h" +#include "nvodm_keylist_reserved.h" +#include "nvrm_drf.h" + +#if !defined(NV_OAL) +#define NV_OAL (0) +#endif + +#define BOARD_ID_HARMONY 0x0B3E +#define HARMONY_HYS5C1GB_SKU 0x3829 + +#define NVODM_ENABLE_EMC_DVFS (1) + +// Although AP16 Concorde2 and AP16 Vail boards can support PMU +// interrupt, keep it disabled for now because of PMU VBUS input +// latch problem +#define NVODM_PMU_INT_ENABLED (0) + +static const NvU8 +s_NvOdmQueryDeviceNamePrefixValue[] = {'T','e','g','r','a',0}; + +static const NvU8 +s_NvOdmQueryManufacturerSetting[] = {'N','V','I','D','I','A',0}; + +static const NvU8 +s_NvOdmQueryModelSetting[] = {'A','P','2','0',0}; + +static const NvU8 +s_NvOdmQueryPlatformSetting[] = {'H','a','r','m','o','n','y',0}; + +static const NvU8 +s_NvOdmQueryProjectNameSetting[] = {'O','D','M',' ','K','i','t',0}; + +static const NvOdmDownloadTransport +s_NvOdmQueryDownloadTransportSetting = NvOdmDownloadTransport_None; + +static const NvOdmQuerySdioInterfaceProperty s_NvOdmQuerySdioInterfaceProperty[4] = +{ + { NV_FALSE, 10, NV_TRUE, 0x8, NvOdmQuerySdioSlotUsage_wlan }, + { NV_TRUE, 0, NV_FALSE, 0x5, NvOdmQuerySdioSlotUsage_Media }, + { NV_TRUE, 0, NV_FALSE, 0x6, NvOdmQuerySdioSlotUsage_unused }, + { NV_TRUE, 0, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Media } +}; + +static const NvOdmQuerySpiDeviceInfo s_NvOdmQuerySpiDeviceInfoTable [] = +{ + {NvOdmQuerySpiSignalMode_0, NV_TRUE} // Spi1_Devices_0 (chip sel 0) +}; + +// Spi idle signal state +static const NvOdmQuerySpiIdleSignalState s_NvOdmQuerySpiIdleSignalStateLevel[] = +{ + {NV_FALSE, NvOdmQuerySpiSignalMode_0, NV_FALSE} // Spi 1 +}; +// We can have two I2s Instances +static const NvOdmQueryI2sInterfaceProperty s_NvOdmQueryI2sInterfacePropertySetting[] = +{ + { + NvOdmQueryI2sMode_Master, // Mode + NvOdmQueryI2sLRLineControl_LeftOnLow, // I2sLRLineControl + NvOdmQueryI2sDataCommFormat_I2S, // I2sDataCommunicationFormat + NV_FALSE, // IsFixedMCLK + 0 // FixedMCLKFrequency + }, + { + NvOdmQueryI2sMode_Master, // Mode + NvOdmQueryI2sLRLineControl_LeftOnLow, // I2sLRLineControl + NvOdmQueryI2sDataCommFormat_I2S, // I2sDataCommunicationFormat + NV_FALSE, // IsFixedMCLK + 0 // FixedMCLKFrequency + } +}; + + +static const NvOdmQuerySpdifInterfaceProperty s_NvOdmQuerySpdifInterfacePropertySetting = +{ + NvOdmQuerySpdifDataCaptureControl_FromLeft +}; + +static const NvOdmQueryAc97InterfaceProperty s_NvOdmQueryAc97InterfacePropertySetting = +{ + NV_FALSE, + NV_FALSE, + NV_FALSE, + NV_FALSE, + NV_TRUE +}; + +// Add support for the Codec Formats +// It must the order (dapIndex) how the codec is connected to the Dap port +static const NvOdmQueryI2sACodecInterfaceProp s_NvOdmQueryI2sACodecInterfacePropSetting[] = +{ + { + NV_FALSE, // IsCodecMaster + 0, // DapPortIndex + 0x36, // DevAddress + NV_FALSE, // IsUsbmode + NvOdmQueryI2sLRLineControl_LeftOnLow, // I2sCodecLRLineControl + NvOdmQueryI2sDataCommFormat_I2S // I2sCodecDataCommFormat + } +}; + +static const NvOdmQueryDapPortConnection s_NvOdmQueryDapPortConnectionTable[] = +{ + // the Default Music Path + { NvOdmDapConnectionIndex_Music_Path, 2, + { {NvOdmDapPort_I2s1, NvOdmDapPort_Dap1, NV_TRUE}, + {NvOdmDapPort_Dap1, NvOdmDapPort_I2s1, NV_FALSE} + }}, + + // Bluetooth to Codec + { NvOdmDapConnectionIndex_BlueTooth_Codec, 3, + { {NvOdmDapPort_Dap4, NvOdmDapPort_I2s1, NV_TRUE}, + {NvOdmDapPort_I2s1, NvOdmDapPort_Dap4, NV_FALSE}, + {NvOdmDapPort_I2s2, NvOdmDapPort_Dap1, NV_FALSE} + }} +}; + + +// Ap20 support 5 dap ports +// For port is connected to DAC(I2s) then PortMode is not valid- as Dac would be driving it +static const NvOdmQueryDapPortProperty s_NvOdmQueryDapPortInfoTable[] = +{ + {NvOdmDapPort_None, NvOdmDapPort_None , {0, 0, 0, 0} }, // Reserved + // I2S1 (DAC1) <-> DAP1 <-> HIFICODEC + {NvOdmDapPort_I2s1, NvOdmDapPort_HifiCodecType, + {2, 16, 44100, NvOdmQueryI2sDataCommFormat_I2S}}, // Dap1 + {NvOdmDapPort_None, NvOdmDapPort_None , {0, 0, 0, 0} }, // Dap2 + {NvOdmDapPort_None, NvOdmDapPort_None , {0, 0, 0, 0} }, // Dap3 + // I2S2 (DAC2) <-> DAP4 <-> BLUETOOTH + {NvOdmDapPort_I2s2, NvOdmDapPort_BlueTooth, + {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S}} // Dap4 +}; + +static const NvOdmSdramControllerConfigAdv s_NvOdmHyS5c1GbEmcConfigTable[] = +{ + { + 0x20, /* Rev 2.0 */ + 166500, /* SDRAM frquency */ + 950, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x0000000A, /* RC */ + 0x00000016, /* RFC */ + 0x00000008, /* RAS */ + 0x00000003, /* RP */ + 0x00000004, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000C, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000001, /* REXT */ + 0x00000004, /* WDV */ + 0x00000005, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000009, /* QSAFE */ + 0x0000000D, /* RDV */ + 0x000004DF, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000A, /* RW2PDEN */ + 0x000000C8, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000006, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x00000000, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000002, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000083, /* FBIO_CFG5 */ + 0xE03B0323, /* CFG_DIG_DLL */ + 0x007FC010, /* DLL_XFORM_DQS */ + 0x00008010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000000, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 333000, /* SDRAM frquency */ + 1200, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000014, /* RC */ + 0x0000002B, /* RFC */ + 0x0000000F, /* RAS */ + 0x00000005, /* RP */ + 0x00000004, /* R2W */ + 0x00000005, /* W2R */ + 0x00000003, /* R2P */ + 0x0000000C, /* W2P */ + 0x00000005, /* RD_RCD */ + 0x00000005, /* WR_RCD */ + 0x00000003, /* RRD */ + 0x00000001, /* REXT */ + 0x00000004, /* WDV */ + 0x00000005, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000009, /* QSAFE */ + 0x0000000D, /* RDV */ + 0x000009FF, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000005, /* PCHG2PDEN */ + 0x00000005, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000F, /* RW2PDEN */ + 0x000000C8, /* TXSR */ + 0x00000003, /* TCKE */ + 0x0000000C, /* TFAW */ + 0x00000006, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x00000000, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000002, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000083, /* FBIO_CFG5 */ + 0xF0320303, /* CFG_DIG_DLL */ + 0x007FC010, /* DLL_XFORM_DQS */ + 0x00008010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000000, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + } +}; + +// Wake Events +static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] = +{ + {NV_FALSE, 0, NvOdmWakeupPadPolarity_Low}, // Wake Event 0 - ulpi_data4 (UART_RI) + {NV_FALSE, 1, NvOdmWakeupPadPolarity_High}, // Wake Event 1 - gp3_pv[3] (BB_MOD, MODEM_RESET_OUT) + {NV_FALSE, 2, NvOdmWakeupPadPolarity_High}, // Wake Event 2 - dvi_d3 + {NV_FALSE, 3, NvOdmWakeupPadPolarity_Low}, // Wake Event 3 - sdio3_dat1 + {NV_FALSE, 4, NvOdmWakeupPadPolarity_High}, // Wake Event 4 - hdmi_int (HDMI_HPD) + {NV_TRUE, 5, NvOdmWakeupPadPolarity_Low}, // Wake Event 5 - vgp[6] (VI_GP6, Flash_EN2) + {NV_FALSE, 6, NvOdmWakeupPadPolarity_High}, // Wake Event 6 - gp3_pu[5] (GPS_ON_OFF, GPS_IRQ) + {NV_FALSE, 7, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 7 - gp3_pu[6] (GPS_INT, BT_IRQ) + {NV_FALSE, 8, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 8 - gmi_wp_n (MICRO SD_CD) + {NV_FALSE, 9, NvOdmWakeupPadPolarity_High}, // Wake Event 9 - gp3_ps[2] (KB_COL10) + {NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP) + {NV_TRUE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ, LOW_BAT#) + {NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used) + {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1 + {NV_FALSE, 14, NvOdmWakeupPadPolarity_High}, // Wake Event 14 - gp3_pv[6] (WLAN_INT) + {NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1) + {NV_TRUE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq +#ifdef CONFIG_KEYBOARD_TEGRA + {NV_TRUE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt +#else + {NV_FALSE, 17, NvOdmWakeupPadPolarity_High}, +#endif + {NV_FALSE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT) + {NV_FALSE, 19, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 19 - usb_vbus_wakeup[0] + {NV_FALSE, 20, NvOdmWakeupPadPolarity_High}, // Wake Event 20 - usb_vbus_wakeup[1] + {NV_FALSE, 21, NvOdmWakeupPadPolarity_Low}, // Wake Event 21 - usb_iddig[0] + {NV_FALSE, 22, NvOdmWakeupPadPolarity_Low}, // Wake Event 22 - usb_iddig[1] + {NV_TRUE, 23, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 23 - gmi_iordy (HSMMC_CLK) + {NV_FALSE, 24, NvOdmWakeupPadPolarity_High}, // Wake Event 24 - gp3_pv[2] (BB_MOD, MODEM WAKEUP_AP15, SPI-SS) + {NV_FALSE, 25, NvOdmWakeupPadPolarity_High}, // Wake Event 25 - gp3_ps[4] (KB_COL12) + {NV_FALSE, 26, NvOdmWakeupPadPolarity_High}, // Wake Event 26 - gp3_ps[5] (KB_COL10) + {NV_FALSE, 27, NvOdmWakeupPadPolarity_High}, // Wake Event 27 - gp3_ps[0] (KB_COL8) + {NV_FALSE, 28, NvOdmWakeupPadPolarity_Low}, // Wake Event 28 - gp3_pq[6] (KB_ROW6) + {NV_FALSE, 29, NvOdmWakeupPadPolarity_Low}, // Wake Event 29 - gp3_pq[7] (KB_ROW6) + {NV_FALSE, 30, NvOdmWakeupPadPolarity_High} // Wake Event 30 - dap1_dout (DAP1_DOUT) +}; + +/* --- Function Implementations ---*/ +static NvU32 +GetBctKeyValue(void) +{ + NvOdmServicesKeyListHandle hKeyList = NULL; + NvU32 BctCustOpt = 0; + + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + BctCustOpt = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + } + + return BctCustOpt; +} + +NvOdmDebugConsole +NvOdmQueryDebugConsole(void) +{ + NvU32 CustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC: + return NvOdmDebugConsole_Dcc; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE: + return NvOdmDebugConsole_None; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART: + return NvOdmDebugConsole_UartA + + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE_OPTION, CustOpt); + default: + return NvOdmDebugConsole_None; + } +} + +NvOdmDownloadTransport +NvOdmQueryDownloadTransport(void) +{ + NvU32 CustOpt = GetBctKeyValue(); + + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, TRANSPORT, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE: + return NvOdmDownloadTransport_None; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB: + return NvOdmDownloadTransport_Usb; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET: + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, ETHERNET_OPTION, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT: + default: + return NvOdmDownloadTransport_SpiEthernet; + } + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART: + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, UART_OPTION, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B: + return NvOdmDownloadTransport_UartB; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C: + return NvOdmDownloadTransport_UartC; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A: + default: + return NvOdmDownloadTransport_UartA; + } + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT: + default: + return s_NvOdmQueryDownloadTransportSetting; + } +} + +const NvU8* +NvOdmQueryDeviceNamePrefix(void) +{ + return s_NvOdmQueryDeviceNamePrefixValue; +} + +const NvOdmQuerySpiDeviceInfo * +NvOdmQuerySpiGetDeviceInfo( + NvOdmIoModule OdmIoModule, + NvU32 ControllerId, + NvU32 ChipSelect) +{ + if (OdmIoModule == NvOdmIoModule_Spi) + { + switch (ControllerId) + { + case 0: + if (ChipSelect == 0) + return &s_NvOdmQuerySpiDeviceInfoTable[0]; + break; + + default: + break; + } + return NULL; + } + return NULL; +} + +const NvOdmQuerySpiIdleSignalState * +NvOdmQuerySpiGetIdleSignalState( + NvOdmIoModule OdmIoModule, + NvU32 ControllerId) +{ + if (OdmIoModule == NvOdmIoModule_Spi) + { + if (ControllerId == 0) + return &s_NvOdmQuerySpiIdleSignalStateLevel[0]; + } + return NULL; +} + +const NvOdmQueryI2sInterfaceProperty * +NvOdmQueryI2sGetInterfaceProperty( + NvU32 I2sInstanceId) +{ + if ((I2sInstanceId == 0) || (I2sInstanceId == 1)) + return &s_NvOdmQueryI2sInterfacePropertySetting[I2sInstanceId]; + + return NULL; +} + +const NvOdmQueryDapPortProperty * +NvOdmQueryDapPortGetProperty( + NvU32 DapPortId) +{ + if (DapPortId > 0 && DapPortId < NV_ARRAY_SIZE(s_NvOdmQueryDapPortInfoTable) ) + return &s_NvOdmQueryDapPortInfoTable[DapPortId]; + + return NULL; +} + +const NvOdmQueryDapPortConnection* +NvOdmQueryDapPortGetConnectionTable( + NvU32 ConnectionIndex) +{ + NvU32 TableIndex = 0; + for( TableIndex = 0; + TableIndex < NV_ARRAY_SIZE(s_NvOdmQueryDapPortConnectionTable); + TableIndex++) + { + if (s_NvOdmQueryDapPortConnectionTable[TableIndex].UseIndex + == ConnectionIndex) + return &s_NvOdmQueryDapPortConnectionTable[TableIndex]; + } + return NULL; +} + +const NvOdmQuerySpdifInterfaceProperty * +NvOdmQuerySpdifGetInterfaceProperty( + NvU32 SpdifInstanceId) +{ + if (SpdifInstanceId == 0) + return &s_NvOdmQuerySpdifInterfacePropertySetting; + + return NULL; +} + +const NvOdmQueryAc97InterfaceProperty * +NvOdmQueryAc97GetInterfaceProperty( + NvU32 Ac97InstanceId) +{ + if (Ac97InstanceId == 0) + return &s_NvOdmQueryAc97InterfacePropertySetting; + + return NULL; +} + +const NvOdmQueryI2sACodecInterfaceProp * +NvOdmQueryGetI2sACodecInterfaceProperty( + NvU32 AudioCodecId) +{ + NvU32 NumInstance = sizeof(s_NvOdmQueryI2sACodecInterfacePropSetting)/ + sizeof(s_NvOdmQueryI2sACodecInterfacePropSetting[0]); + if (AudioCodecId < NumInstance) + return &s_NvOdmQueryI2sACodecInterfacePropSetting[AudioCodecId]; + + return NULL; +} + +/** + * This function is called from early boot process. + * Therefore, it cannot use global variables. + */ +NvBool NvOdmQueryAsynchMemConfig( + NvU32 ChipSelect, + NvOdmAsynchMemConfig *pMemConfig) +{ + return NV_FALSE; +} + +const void* +NvOdmQuerySdramControllerConfigGet(NvU32 *pEntries, NvU32 *pRevision) +{ +#if NVODM_ENABLE_EMC_DVFS + NvOdmBoardInfo BoardInfo; + + if (NvOdmPeripheralGetBoardInfo(BOARD_ID_HARMONY, &BoardInfo)) + { + if (BoardInfo.SKU == HARMONY_HYS5C1GB_SKU) + { + if (pRevision) + *pRevision = s_NvOdmHyS5c1GbEmcConfigTable[0].Revision; + if (pEntries) + *pEntries = NV_ARRAY_SIZE(s_NvOdmHyS5c1GbEmcConfigTable); + return (const void*)s_NvOdmHyS5c1GbEmcConfigTable; + } + } +#endif + if (pEntries) + *pEntries = 0; + return NULL; +} + +NvOdmQueryOscillator NvOdmQueryGetOscillatorSource(void) +{ + return NvOdmQueryOscillator_Xtal; +} + +NvU32 NvOdmQueryGetOscillatorDriveStrength(void) +{ + /// Oscillator drive strength range is 0 to 0x3F + return 0x04; +} + +const NvOdmWakeupPadInfo *NvOdmQueryGetWakeupPadTable(NvU32 *pSize) +{ + if (pSize) + *pSize = NV_ARRAY_SIZE(s_NvOdmWakeupPadInfo); + + return (const NvOdmWakeupPadInfo *) s_NvOdmWakeupPadInfo; +} + +const NvU8* NvOdmQueryManufacturer(void) +{ + return s_NvOdmQueryManufacturerSetting; +} + +const NvU8* NvOdmQueryModel(void) +{ + return s_NvOdmQueryModelSetting; +} + +const NvU8* NvOdmQueryPlatform(void) +{ + return s_NvOdmQueryPlatformSetting; +} + +const NvU8* NvOdmQueryProjectName(void) +{ + return s_NvOdmQueryProjectNameSetting; +} + +#define EXT 0 // external pull-up/down resistor +#define INT_PU 1 // internal pull-up +#define INT_PD 2 // internal pull-down + +#define HIGHSPEED 1 +#define SCHMITT 1 +#define VREF 1 +#define OHM_50 3 +#define OHM_100 2 +#define OHM_200 1 +#define OHM_400 0 + + // Pin attributes +static const NvOdmPinAttrib pin_config[] = { + // Pull ups for the kbc pins + { NvOdmPinRegister_Ap20_PullUpDown_B, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_B(0x0, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) }, + + // Pull ups for the kbc pins + { NvOdmPinRegister_Ap20_PullUpDown_E, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_E(0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x2, 0x2) }, + + // Set pad control for the sdio2 - - AOCFG1 and AOCFG2 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_AOCFG1PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_AOCFG2PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for the sdio3 - SDIO2 and SDIO3 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_SDIO2CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_SDIO3CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for I2C1 pins + { NvOdmPinRegister_Ap20_PadCtrl_DBGCFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_VICFG1PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_VICFG2PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for I2C2 (DDC) pins + { NvOdmPinRegister_Ap20_PadCtrl_DDCCFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for the sdio1 - SDIO1 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_SDIO1CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // WiFi Pins (DTA, DTD) need to be pulled up + { NvOdmPinRegister_Ap20_PullUpDown_A, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_A(0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0) }, + + // Set pad control for the sdio4- ATCCFG1 and ATCCFG2 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_ATCFG1PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_ATCFG2PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) } +}; + +NvU32 +NvOdmQueryPinAttributes(const NvOdmPinAttrib** pPinAttributes) +{ + if (pPinAttributes) + { + *pPinAttributes = &pin_config[0]; + return NV_ARRAY_SIZE(pin_config); + } + return 0; +} + +NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty) +{ + pPmuProperty->IrqConnected = NV_FALSE; + pPmuProperty->PowerGoodCount = 0x7E; + pPmuProperty->IrqPolarity = NvOdmInterruptPolarity_Low; + pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_Low; + pPmuProperty->SysClockReqPolarity = NvOdmSysClockReqPolarity_High; + pPmuProperty->CombinedPowerReq = NV_FALSE; + pPmuProperty->CpuPowerGoodUs = 2000; + pPmuProperty->AccuracyPercent = 3; + pPmuProperty->VCpuOTPOnWakeup = NV_FALSE; + return NV_TRUE; +} + +/** + * Gets the lowest soc power state supported by the hardware + * + * @returns information about the SocPowerState + */ +const NvOdmSocPowerStateInfo* NvOdmQueryLowestSocPowerState(void) +{ + + static NvOdmSocPowerStateInfo PowerStateInfo; + const static NvOdmSocPowerStateInfo* pPowerStateInfo = NULL; + NvOdmServicesKeyListHandle hKeyList; + NvU32 LPStateSelection = 0; + if (pPowerStateInfo == NULL) + { + + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + LPStateSelection = NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + LPStateSelection = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, LPSTATE, LPStateSelection); + } + // Lowest power state controlled by the flashed custom option. + PowerStateInfo.LowestPowerState = ((LPStateSelection != TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1)? + NvOdmSocPowerState_Suspend : NvOdmSocPowerState_DeepSleep); + pPowerStateInfo = (const NvOdmSocPowerStateInfo*) &PowerStateInfo; + } + return (pPowerStateInfo); +} + +const NvOdmUsbProperty* +NvOdmQueryGetUsbProperty(NvOdmIoModule OdmIoModule, + NvU32 Instance) +{ + static const NvOdmUsbProperty Usb1Property = + { + NvOdmUsbInterfaceType_Utmi, + (NvOdmUsbChargerType_SE0 | NvOdmUsbChargerType_SE1 | NvOdmUsbChargerType_SK), + 20, + NV_TRUE, + NvOdmUsbModeType_Device, + NvOdmUsbIdPinType_CableId, + NvOdmUsbConnectorsMuxType_None, + NV_TRUE + }; + + static const NvOdmUsbProperty Usb2Property = + { + NvOdmUsbInterfaceType_UlpiExternalPhy, + NvOdmUsbChargerType_UsbHost, + 20, + NV_TRUE, + NvOdmUsbModeType_Host, + NvOdmUsbIdPinType_None, + NvOdmUsbConnectorsMuxType_None, + NV_TRUE + }; + + static const NvOdmUsbProperty Usb3Property = + { + NvOdmUsbInterfaceType_Utmi, + NvOdmUsbChargerType_UsbHost, + 20, + NV_TRUE, + NvOdmUsbModeType_Host, + NvOdmUsbIdPinType_None, + NvOdmUsbConnectorsMuxType_None, + NV_TRUE + }; + + if (OdmIoModule == NvOdmIoModule_Usb && Instance == 0) + return &(Usb1Property); + + if (OdmIoModule == NvOdmIoModule_Usb && Instance == 1) + return &(Usb2Property); + + if (OdmIoModule == NvOdmIoModule_Usb && Instance == 2) + return &(Usb3Property); + + return (const NvOdmUsbProperty *)NULL; +} + +const NvOdmQuerySdioInterfaceProperty* NvOdmQueryGetSdioInterfaceProperty(NvU32 Instance) +{ + return &s_NvOdmQuerySdioInterfaceProperty[Instance]; +} + +const NvOdmQueryHsmmcInterfaceProperty* NvOdmQueryGetHsmmcInterfaceProperty(NvU32 Instance) +{ + return NULL; +} + +NvU32 +NvOdmQueryGetBlockDeviceSectorSize(NvOdmIoModule OdmIoModule) +{ + return 0; +} + +const NvOdmQueryOwrDeviceInfo* NvOdmQueryGetOwrDeviceInfo(NvU32 Instance) +{ + return NULL; +} + +const NvOdmGpioWakeupSource *NvOdmQueryGetWakeupSources(NvU32 *pCount) +{ + *pCount = 0; + return NULL; +} + +/** + * This function is called from early boot process. + * Therefore, it cannot use global variables. + */ +NvU32 NvOdmQueryMemSize(NvOdmMemoryType MemType) +{ + NvOdmOsOsInfo Info; + NvU32 MemBctCustOpt = GetBctKeyValue(); + + switch (MemType) + { + // NOTE: + // For Windows CE/WM operating systems the total size of SDRAM may + // need to be reduced due to limitations in the virtual address map. + // Under the legacy physical memory manager, Windows OSs have a + // maximum 512MB statically mapped virtual address space. Under the + // new physical memory manager, Windows OSs have a maximum 1GB + // statically mapped virtual address space. Out of that virtual + // address space, the upper 32 or 36 MB (depending upon the SOC) + // of the virtual address space is reserved for SOC register + // apertures. + // + // Refer to virtual_tables_apxx.arm for the reserved aperture list. + // If the cumulative size of the reserved apertures changes, the + // maximum size of SDRAM will also change. + case NvOdmMemoryType_Sdram: + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_SYSTEM, MEMORY, MemBctCustOpt)) + { + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_256: + if ( NvOdmOsGetOsInformation(&Info) && + ((Info.OsType!=NvOdmOsOs_Windows) || + (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) ) + return 0x10000000; + else + return 0x0DD00000; // Legacy Physical Memory Manager: 256 MB - 35 MB + + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1024: + if ( NvOdmOsGetOsInformation(&Info) && + ((Info.OsType!=NvOdmOsOs_Windows) || + (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) ) + return 0x40000000; + else + // Earlier versions of WinCE only support 512MB max memory size + return 0x1E000000; // Legacy Physical Memory Manager: 512 MB - 32 MB + + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_512: + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT: + default: + if ( NvOdmOsGetOsInformation(&Info) && + ((Info.OsType!=NvOdmOsOs_Windows) || + (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) ) + return 0x20000000; + else + return 0x1E000000; // Legacy Physical Memory Manager: 512 MB - 32 MB + } + + case NvOdmMemoryType_Nor: + return 0x00400000; // 4 MB + + case NvOdmMemoryType_Nand: + case NvOdmMemoryType_I2CEeprom: + case NvOdmMemoryType_Hsmmc: + case NvOdmMemoryType_Mio: + default: + return 0; + } +} + +NvU32 NvOdmQueryCarveoutSize(void) +{ + return 0x04000000; // 64 MB +} + +NvU32 NvOdmQuerySecureRegionSize(void) +{ + return 0x00800000;// 8 MB +} diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c new file mode 100644 index 000000000000..6b0b896d0cf3 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_discovery.c @@ -0,0 +1,770 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: The peripheral connectivity database implementation. + */ + +#include "nvcommon.h" +#include "nvodm_query_gpio.h" +#include "nvodm_modules.h" +#include "nvodm_query_discovery.h" +#include "nvodm_keylist_reserved.h" +#include "tegra_devkit_custopt.h" +#include "nvodm_query.h" +#include "nvrm_drf.h" + +#include "subboards/nvodm_query_discovery_e1162_addresses.h" + +static NvOdmPeripheralConnectivity s_Peripherals_Default[] = +{ +#include "subboards/nvodm_query_discovery_e1162_peripherals.h" +}; + +#define NVODM_QUERY_BOARD_ID_UNKNOWN 0xFFFF + +#define NVODM_QUERY_MAX_PERIPHERALS 0x400 +#define NVODM_QUERY_MAX_IO_ADDRESSES 0x400 + +#define NVODM_QUERY_MAX_EEPROMS 8 // Maximum number of EEPROMs per bus segment + +#define NVODM_QUERY_ERASED_EEPROM_VALUE 0xFF + +#define PROCESSOR_BOARD_ID_I2C_ADDRESS ((0x56)<<1) +#define PROCESSOR_BOARD_ID_I2C_SEGMENT (0x00) + +// The following are used to store entries read from EEPROMs at runtime. +static NvOdmPeripheralConnectivity s_Peripherals[NVODM_QUERY_MAX_PERIPHERALS]; +static NvOdmIoAddress s_Peripheral_IoAddresses[NVODM_QUERY_MAX_IO_ADDRESSES]; +static NvOdmBoardInfo s_BoardModuleTable[NVODM_QUERY_MAX_EEPROMS]; + +#define NVODM_QUERY_I2C_CLOCK_SPEED 100 // kHz + +#define NVODM_QUERY_ENTRY_HEADER_SIZE 0x30 // Size of EERPOM "Entry Header" +#define NVODM_QUERY_BOARD_HEADER_START 0x04 // Offset to Part Number in EERPOM + +#define NVODM_QUERY_I2C_EEPROM_ADDRESS 0xA0 // I2C device base address for EEPROM (7'h50) + +#define NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED 10 // See EEPROM_format.txt +#define NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED 2 // See EEPROM_format.txt + + +static NvOdmI2cStatus +NvOdmPeripheralI2cRead8( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 I2cAddr, + NvU8 Offset, + NvU8 *pData) +{ + NvU8 ReadBuffer[1]; + NvOdmI2cStatus Error; + NvOdmI2cTransactionInfo TransactionInfo; + + ReadBuffer[0] = Offset; + + TransactionInfo.Address = I2cAddr; + TransactionInfo.Buf = ReadBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 1; + + Error = NvOdmI2cTransaction( + hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); + if (Error != NvOdmI2cStatus_Success) + { + return Error; + } + + NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer)); + + TransactionInfo.Address = (I2cAddr | 0x1); + TransactionInfo.Buf = ReadBuffer; + TransactionInfo.Flags = 0; + TransactionInfo.NumBytes = 1; + + // Read data from ROM at the specified offset + Error = NvOdmI2cTransaction( + hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); + if (Error != NvOdmI2cStatus_Success) + { + return Error; + } + *pData = ReadBuffer[0]; + return Error; +} + +static NvBool +NvOdmPeripheralReadNumPeripherals( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvU8 *pNumModulePeripherals) +{ + NvOdmI2cStatus Error; + NvU8 I2cAddr, Offset; + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + /** + * Offset to numPeripherals in NvOdmPeripheralConnectivity Structure. + * It's the first parameter after the "Entry Header." + */ + Offset = NVODM_QUERY_ENTRY_HEADER_SIZE; + + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, Offset, pNumModulePeripherals); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadPeripheral( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvU8 Peripheral, + NvU64 *pGuid, + NvU8 *pEepromAddressListOffset, + NvU32 *pNumAddress, + NvOdmPeripheralClass *pClass) +{ + NvOdmI2cStatus Error; + NvU32 i; + NvU8 ConnMemberIndex=0; // Offset to members in NvOdmPeripheralConnectivity + NvU8 I2cAddr, Offset; + NvU8 ReadBuffer[NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED]; + NvU8 NumAddrAndClass; + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + /** + * Calculate offset to pGuid in NvOdmPeripheralConnectivity Structure + * + * Offset = sizeof(eeprom Entry Header) + + * sizeof(NvOdmPeripheralConnectivity)*peripheral + + * pGuid offset <-- First field, so this is 0 + */ + Offset = NVODM_QUERY_ENTRY_HEADER_SIZE + + sizeof(NvOdmPeripheralConnectivity)*Peripheral; + + for (i=0; i<NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED; i++) + { + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, Offset, (NvU8 *)&ReadBuffer[i]); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + } + // Save pGuid entry + NvOdmOsMemcpy(pGuid, &ReadBuffer[0], sizeof(NvU64)); + + // Save EEPROM offset + ConnMemberIndex += sizeof(NvU64); // Increment to next member + *pEepromAddressListOffset = ReadBuffer[ConnMemberIndex]; + + // Save pNumAddress & Class + ConnMemberIndex += sizeof(NvU8); // Increment to next member + NumAddrAndClass = ReadBuffer[ConnMemberIndex]; + *pNumAddress = (NvU32)((NumAddrAndClass >> 3) & 0x0000001F); + *pClass = (NvOdmPeripheralClass)(NumAddrAndClass & 0x00000007); + + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadIoAddressData( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvU8 EepromAddressListOffset, + NvOdmIoAddress *pIoAddressEntry) +{ + NvOdmI2cStatus Error; + NvU32 i; + NvU8 I2cAddr; + NvU8 ReadBuffer[NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED]; + NvU16 CompressedIoAddressEntry; + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + for (i=0; i<NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED; i++) + { + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, EepromAddressListOffset, (NvU8 *)&ReadBuffer[i]); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + } + // Save pIoAddressEntry: interface, instance, address + CompressedIoAddressEntry = ((((NvU16)ReadBuffer[1]) << 8) & 0xFF00) | ReadBuffer[0]; + + pIoAddressEntry->Interface = (NvOdmIoModule)((CompressedIoAddressEntry >> 11) & 0x1F); + + if (pIoAddressEntry->Interface != NvOdmIoModule_Gpio) + { + pIoAddressEntry->Instance = (NvU32)((CompressedIoAddressEntry >> 7) & 0xF); + pIoAddressEntry->Address = (NvU32)(CompressedIoAddressEntry & 0x7F); + } + else + { + pIoAddressEntry->Address = (NvU32)((CompressedIoAddressEntry >> 6) & 0x3F); + pIoAddressEntry->Instance = (NvU32)(CompressedIoAddressEntry & 0x3F); + } + + return NV_TRUE; +} + +static NvBool NvOdmPeripheralGetEntries(NvU32 *pNum) +{ + NvBool RetVal; + NvBool IsMatch = NV_FALSE; + NvOdmServicesI2cHandle hOdmI2c = NULL; + NvU8 EepromInst; + + // Peripheral counters + NvU8 NumPeripherals = 0; + NvU8 CurrentPeripheral = 0; + NvU32 TotalPeripherals = 0; + NvU32 StaticPeripherals; + + NvU32 CurrentIoAddressNum = 0; + NvU32 TotalIoAddressEntries = 0; + + NvU32 i,j; + NvU8 EepromAddressListOffset; + + if (!pNum) { + return NV_FALSE; + } + + // Auto-detect -- Read I2C-EEPROMs on each sub-board + + hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0); + if (!hOdmI2c) + return NV_FALSE; + + for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++) + { + RetVal = NvOdmPeripheralReadNumPeripherals( + hOdmI2c, EepromInst, &NumPeripherals); + + if ( (RetVal == NV_TRUE) && + (NumPeripherals != NVODM_QUERY_ERASED_EEPROM_VALUE) ) + { + if (NumPeripherals > 0) + { + if ((NumPeripherals + TotalPeripherals) > NVODM_QUERY_MAX_PERIPHERALS) + { + NV_ASSERT( !"ERROR: s_Peripherals[] is too small to accommodate entries!" ); + + // Break out of loop and use static/default configuration + break; + } + + for (CurrentPeripheral=0; \ + CurrentPeripheral < NumPeripherals; \ + CurrentPeripheral++) + { + RetVal = NvOdmPeripheralReadPeripheral( + hOdmI2c, + EepromInst, + CurrentPeripheral, + &s_Peripherals[TotalPeripherals+CurrentPeripheral].Guid, + &EepromAddressListOffset, + &s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress, + &s_Peripherals[TotalPeripherals+CurrentPeripheral].Class); + + if (RetVal == NV_FALSE) + { + NV_ASSERT(!"Unable to read EEPROM peripheral entry!"); + break; // Go to next EEPROM + } + else // Process peripheral entry + { + /** + * Process NvOdmIoAddress arrays -- + * + * These are separate data structures. The addressList value + * read from the EEPROM (EepromAddressListOffset) represents + * an offset address within the I2C-EEPROM. This offset value + * identifies where to find the first instance of the + * NvOdmIoAddress data. + * + * The total number of NvOdmIoAddress entries is identified + * by the numAddress variable following the addressList entry + * in EEPROM. + * + * Once the offset and number of entries are determined (from + * above NvOdmPeripheralReadPeripheral function call), a loop + * fills in entries within the fixed storage area + * (e.g., s_Peripheral_IoAddresses) and the actual + * addressList pointer is assigned a value that corresponds + * to the first entry of the current class within this array. + * In other words, there might be prior entries in the + * s_Peripheral_IoAddresses array, but the first entry + * corresponding to the current class might be the third + * element in this array. Therefore, the actual addressList + * pointer for the current NvOdmPeripheralConnectivity.addressList + * parameter would be the address of the third entry, which is + * &s_Peripheral_IoAddresses[2] in this example. + */ + + // Read all of the entries and save them in s_Peripheral_IoAddresses + for (CurrentIoAddressNum=0; \ + CurrentIoAddressNum < s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress; \ + CurrentIoAddressNum++) + { + if (TotalIoAddressEntries > NVODM_QUERY_MAX_IO_ADDRESSES) + { + NV_ASSERT( !"ERROR: s_Peripheral_IoAddresses[] is too small to accommodate entries!" ); + + // Cannot recover from this error. + NvOdmI2cClose(hOdmI2c); + return NV_FALSE; + } + + RetVal = NvOdmPeripheralReadIoAddressData( + hOdmI2c, + EepromInst, + EepromAddressListOffset, + &s_Peripheral_IoAddresses[TotalIoAddressEntries+CurrentIoAddressNum]); + + if (RetVal == NV_FALSE) + { + NV_ASSERT(!"Unable to read EEPROM (IoAddresses)!"); + + // Cannot recover from this error. + NvOdmI2cClose(hOdmI2c); + return NV_FALSE; + } + else // Process IoAddresses entry + { + /** + * Save the addressList pointer. This points to the first + * IoAddresses entry of this class. Then update the overall + * IoAddresses array counter (TotalIoAddressEntries). + */ + s_Peripherals[TotalPeripherals+CurrentPeripheral].AddressList = + &s_Peripheral_IoAddresses[TotalIoAddressEntries]; + + TotalIoAddressEntries += CurrentIoAddressNum; + + // >-- End of NvOdmIoAddress array processing --< + } + } + } + } + } + TotalPeripherals += NumPeripherals; + } + } + + // Done reading I2C-EEPROM; close it. + NvOdmI2cClose(hOdmI2c); + + /** + * Append static peripheral entries (if any) to dynamic list + * read from EEPROMs (this list may also be empty), except for + * duplicate GUIDs. The dynamic list takes precedence when + * duplicate entries are found in the static list. + */ + StaticPeripherals = NV_ARRAY_SIZE(s_Peripherals_Default); + for (i=0; i<StaticPeripherals; i++) + { + for (j=0; j<TotalPeripherals; j++) + { + if (s_Peripherals_Default[i].Guid == s_Peripherals[j].Guid) + { + IsMatch = NV_TRUE; + break; // Ignore duplicate entry from static list. + } + } + if (IsMatch != NV_TRUE) + { + // Append unique entry to dynamic list + + s_Peripherals[TotalPeripherals].Guid = + s_Peripherals_Default[i].Guid; + + s_Peripherals[TotalPeripherals].AddressList = + s_Peripherals_Default[i].AddressList; + + s_Peripherals[TotalPeripherals].NumAddress = + s_Peripherals_Default[i].NumAddress; + + s_Peripherals[TotalPeripherals].Class = + s_Peripherals_Default[i].Class; + + TotalPeripherals++; + } + } + *pNum = TotalPeripherals; + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadPartNumber( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvOdmBoardInfo *pBoardInfo) +{ + NvOdmI2cStatus Error; + NvU32 i; + NvU8 I2cAddr, Offset; + NvU8 ReadBuffer[sizeof(NvOdmBoardInfo)]; + + NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer)); + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + /** + * Offset to the board number entry in EEPROM. + */ + Offset = NVODM_QUERY_BOARD_HEADER_START; + + for (i=0; i<sizeof(NvOdmBoardInfo); i++) + { + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, Offset+i, (NvU8 *)&ReadBuffer[i]); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + } + NvOdmOsMemcpy(pBoardInfo, &ReadBuffer[0], sizeof(NvOdmBoardInfo)); + return NV_TRUE; +} + +NvBool +NvOdmPeripheralGetBoardInfo( + NvU16 BoardId, + NvOdmBoardInfo *pBoardInfo) +{ + NvBool RetVal = NV_FALSE; + NvOdmServicesI2cHandle hOdmI2c = NULL; + NvU8 EepromInst, CurrentBoard; + static NvU8 NumBoards = 0; + static NvBool s_ReadBoardInfoDone = NV_FALSE; + + if (!s_ReadBoardInfoDone) + { + s_ReadBoardInfoDone = NV_TRUE; + hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0); + if (!hOdmI2c) + { + // Exit + pBoardInfo = NULL; + return NV_FALSE; + } + + for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++) + { + RetVal = NvOdmPeripheralReadPartNumber( + hOdmI2c, EepromInst, &s_BoardModuleTable[NumBoards]); + if (RetVal == NV_TRUE) + NumBoards++; + } + NvOdmI2cClose(hOdmI2c); + } + + if (NumBoards) + { + // Linear search for given BoardId; if found, return entry + for (CurrentBoard=0; CurrentBoard < NumBoards; CurrentBoard++) + { + if (s_BoardModuleTable[CurrentBoard].BoardID == BoardId) + { + // Match found + pBoardInfo->BoardID = s_BoardModuleTable[CurrentBoard].BoardID; + pBoardInfo->SKU = s_BoardModuleTable[CurrentBoard].SKU; + pBoardInfo->Fab = s_BoardModuleTable[CurrentBoard].Fab; + pBoardInfo->Revision = s_BoardModuleTable[CurrentBoard].Revision; + pBoardInfo->MinorRevision = s_BoardModuleTable[CurrentBoard].MinorRevision; + return NV_TRUE; + } + } + } + + // Match not found + pBoardInfo = NULL; + return NV_FALSE; +} + +// This will compare the peripheral GUID against a list of known-bad GUIDs +// for certain development kit personalities, and return NV_TRUE if it is +// known to be unsupported (filtered) on the current configuration +static NvBool +NvIsFilteredPeripheral(const NvOdmPeripheralConnectivity* pConnectivity) +{ + NvOdmServicesKeyListHandle hKeyList; + NvU32 Personality = 0; + NvU32 opt = 0; + NvOdmIoModule OdmModule; + const NvU32 *OdmConfigs=NULL; + NvU32 NumOdmConfigs = 0; + const NvOdmPeripheralConnectivity* pFilteredPeriph = pConnectivity; + + if((!pConnectivity) || (!pConnectivity->NumAddress)) + return NV_TRUE; + + hKeyList = NvOdmServicesKeyListOpen(); + + if (hKeyList) + { + Personality = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + Personality = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, Personality); + opt = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, DISPLAY_OPTION, opt); + } + + if (!Personality) + Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY; + + OdmModule = pFilteredPeriph->AddressList[0].Interface; + + if(OdmModule != NvOdmIoModule_Gpio) + NvOdmQueryPinMux(OdmModule, &OdmConfigs, &NumOdmConfigs); + + switch (OdmModule) + { + case NvOdmIoModule_Gpio: + // Filter scroll wheel when trace is enabled + if ( (pConnectivity->Guid == NV_ODM_GUID('s','c','r','o','l','w','h','l')) && + ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) ) + return NV_TRUE; + else + return NV_FALSE; + + default: + return NV_FALSE; + } +} + +static const NvOdmPeripheralConnectivity* +NvApGetAllPeripherals (NvU32 *pNum) +{ + static NvBool s_AutoDetectDone = NV_FALSE; + NvBool RetVal = NV_TRUE; + static NvU32 s_TotalPeripherals; + NvOdmBoardInfo BoardInfo; + + if (!pNum) + return NULL; + + if (!s_AutoDetectDone) + { + /** + * Read & cache the board ID info from the I2C-EEPROMs. This + * is necessary because once Whistler's thermal power rail is + * enabled, the ID ROMs cannot be read. NvApGetAllPeripherals() + * is called before that rail is enabled. + */ + NvOdmPeripheralGetBoardInfo(NVODM_QUERY_BOARD_ID_UNKNOWN, &BoardInfo); + + RetVal = NvOdmPeripheralGetEntries(&s_TotalPeripherals); + if (RetVal == NV_FALSE) + { + *pNum = 0; + return NULL; + } + s_AutoDetectDone = NV_TRUE; + } + + *pNum = s_TotalPeripherals; + return (const NvOdmPeripheralConnectivity *)s_Peripherals; +} + +// This implements a simple linear search across the entire set of currently- +// connected peripherals to find the set of GUIDs that Match the search +// criteria. More clever implementations are possible, but given the +// relatively small search space (max dozens of peripherals) and the relative +// infrequency of enumerating peripherals, this is the easiest implementation. +const NvOdmPeripheralConnectivity * +NvOdmPeripheralGetGuid(NvU64 SearchGuid) +{ + const NvOdmPeripheralConnectivity *pAllPeripherals; + NvU32 NumPeripherals; + NvU32 i; + + pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals); + + if (!pAllPeripherals || !NumPeripherals) + return NULL; + + for (i=0; i<NumPeripherals; i++) + { + if (SearchGuid == pAllPeripherals[i].Guid) + { + if (NvIsFilteredPeripheral(&pAllPeripherals[i])) + return NULL; + return &pAllPeripherals[i]; + } + } + + return NULL; +} + +static NvBool +IsBusMatch( + const NvOdmPeripheralConnectivity *pPeriph, + const NvOdmPeripheralSearch *pSearchAttrs, + const NvU32 *pSearchVals, + NvU32 offset, + NvU32 NumAttrs) +{ + NvU32 i, j; + NvBool IsMatch = NV_FALSE; + + for (i=0; i<pPeriph->NumAddress; i++) + { + j = offset; + do + { + switch (pSearchAttrs[j]) + { + case NvOdmPeripheralSearch_IoModule: + IsMatch = (pSearchVals[j] == + (NvU32)(pPeriph->AddressList[i].Interface)); + break; + case NvOdmPeripheralSearch_Address: + IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Address); + break; + case NvOdmPeripheralSearch_Instance: + IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Instance); + break; + case NvOdmPeripheralSearch_PeripheralClass: + default: + NV_ASSERT(!"Bad Query!"); + break; + } + j++; + } while (IsMatch && j<NumAttrs && + pSearchAttrs[j]!=NvOdmPeripheralSearch_IoModule); + + if (IsMatch) + { + return NV_TRUE; + } + } + return NV_FALSE; +} + +static NvBool +IsPeripheralMatch( + const NvOdmPeripheralConnectivity *pPeriph, + const NvOdmPeripheralSearch *pSearchAttrs, + const NvU32 *pSearchVals, + NvU32 NumAttrs) +{ + NvU32 i; + NvBool IsMatch = NV_TRUE; + + for (i=0; i<NumAttrs && IsMatch; i++) + { + switch (pSearchAttrs[i]) + { + case NvOdmPeripheralSearch_PeripheralClass: + IsMatch = (pSearchVals[i] == (NvU32)(pPeriph->Class)); + break; + case NvOdmPeripheralSearch_IoModule: + IsMatch = IsBusMatch(pPeriph, pSearchAttrs, pSearchVals, i, NumAttrs); + break; + case NvOdmPeripheralSearch_Address: + case NvOdmPeripheralSearch_Instance: + // In correctly-formed searches, these parameters will be parsed by + // IsBusMatch, so we ignore them here. + break; + default: + NV_ASSERT(!"Bad search attribute!"); + break; + } + } + return IsMatch; +} + +NvU32 +NvOdmPeripheralEnumerate( + const NvOdmPeripheralSearch *pSearchAttrs, + const NvU32 *pSearchVals, + NvU32 NumAttrs, + NvU64 *pGuidList, + NvU32 NumGuids) +{ + const NvOdmPeripheralConnectivity *pAllPeripherals; + NvU32 NumPeripherals; + NvU32 Matches; + NvU32 i; + + pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals); + + if (!pAllPeripherals || !NumPeripherals) + { + return 0; + } + + if (!pSearchAttrs || !pSearchVals) + { + NumAttrs = 0; + } + for (i=0, Matches=0; i<NumPeripherals && + (Matches < NumGuids || !pGuidList); i++) + { + if ( !NumAttrs || IsPeripheralMatch(&pAllPeripherals[i], + pSearchAttrs, pSearchVals, + NumAttrs) ) + { + if (NvIsFilteredPeripheral(&pAllPeripherals[i])) + continue; + + if (pGuidList) + pGuidList[Matches] = pAllPeripherals[i].Guid; + Matches++; + } + } + return Matches; +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c new file mode 100644 index 000000000000..8d384db176ee --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c @@ -0,0 +1,240 @@ +/* + * 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 "nvodm_query_gpio.h" +#include "nvodm_services.h" +#include "nvrm_drf.h" + +#define NVODM_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define NVODM_PORT(x) ((x) - 'a') + +static const NvOdmGpioPinInfo s_vi[] = { + {NVODM_PORT('t'), 3, NvOdmGpioPinActiveState_High}, // EN_VDDIO_SD +}; + +static const NvOdmGpioPinInfo s_display[] = { + + // TO DO: Verify these settings for harmony. + + /* Panel 0 -- sony vga */ + { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('j'), 3, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('j'), 4, NvOdmGpioPinActiveState_Low }, + // this pin is not needed for ap15 + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + + /* Panel 1 -- samtek */ + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + + /* Panel 2 -- sharp wvga */ + { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low }, + + /* Panel 3 -- sharp qvga */ + { NVODM_PORT('n'), 6, NvOdmGpioPinActiveState_High }, // LCD_DC0 + { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low }, // LCD_CS0 + { NVODM_PORT('b'), 3, NvOdmGpioPinActiveState_Low }, // LCD_PCLK + { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low }, // LCD_PWR0 + { NVODM_PORT('e'), 0, NvOdmGpioPinActiveState_High }, // LCD_D0 + { NVODM_PORT('e'), 1, NvOdmGpioPinActiveState_High }, // LCD_D1 + { NVODM_PORT('e'), 2, NvOdmGpioPinActiveState_High }, // LCD_D2 + { NVODM_PORT('e'), 3, NvOdmGpioPinActiveState_High }, // LCD_D3 + { NVODM_PORT('e'), 4, NvOdmGpioPinActiveState_High }, // LCD_D4 + { NVODM_PORT('e'), 5, NvOdmGpioPinActiveState_High }, // LCD_D5 + { NVODM_PORT('e'), 6, NvOdmGpioPinActiveState_High }, // LCD_D6 + { NVODM_PORT('e'), 7, NvOdmGpioPinActiveState_High }, // LCD_D7 + { NVODM_PORT('f'), 0, NvOdmGpioPinActiveState_High }, // LCD_D8 + { NVODM_PORT('f'), 1, NvOdmGpioPinActiveState_High }, // LCD_D9 + { NVODM_PORT('f'), 2, NvOdmGpioPinActiveState_High }, // LCD_D10 + { NVODM_PORT('f'), 3, NvOdmGpioPinActiveState_High }, // LCD_D11 + { NVODM_PORT('f'), 4, NvOdmGpioPinActiveState_High }, // LCD_D12 + { NVODM_PORT('f'), 5, NvOdmGpioPinActiveState_High }, // LCD_D13 + { NVODM_PORT('f'), 6, NvOdmGpioPinActiveState_High }, // LCD_D14 + { NVODM_PORT('f'), 7, NvOdmGpioPinActiveState_High }, // LCD_D15 + { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_High }, // LCD_D19 + + /* Panel 4 -- auo */ + { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low }, + + /* Panel 5 -- firefly p1138 lvds interface */ + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, NvOdmGpioPinActiveState_Low}, + { NVODM_PORT('b'), 4, NvOdmGpioPinActiveState_High }, // LCD_BL_PWM + { NVODM_PORT('b'), 5, NvOdmGpioPinActiveState_High }, // LCD_BL_EN + { NVODM_PORT('c'), 6, NvOdmGpioPinActiveState_High }, // EN_VDD_PNL +}; + +static const NvOdmGpioPinInfo s_hdmi[] = +{ + /* hdmi hot-plug interrupt pin */ + { NVODM_PORT('n'), 7, NvOdmGpioPinActiveState_High }, // HDMI HPD +}; + +static const NvOdmGpioPinInfo s_crt[] = +{ + /* crt hot-plug interrupt pin */ + { NVODM_PORT('x'), 2, NvOdmGpioPinActiveState_Low }, // VGA_DET# +}; + +static const NvOdmGpioPinInfo s_sdio[] = { + {NVODM_PORT('i'), 5, NvOdmGpioPinActiveState_Low}, // Card Detect for SDIO instance 2 + /* High for WP and low for read/write */ + {NVODM_PORT('h'), 1, NvOdmGpioPinActiveState_High}, // Write Protect for SDIO instance 2 +}; + +static const NvOdmGpioPinInfo s_sdio3[] = { + {NVODM_PORT('h'), 2, NvOdmGpioPinActiveState_Low}, // Card Detect for SDIO instance 3 + /* High for WP and low for read/write */ + {NVODM_PORT('h'), 3, NvOdmGpioPinActiveState_High}, // Write Protect for SDIO instance 3 +}; + +static const NvOdmGpioPinInfo s_NandFlash[] = { + {NVODM_PORT('c'), 7, NvOdmGpioPinActiveState_High}, // Raw NAND WP_N +}; + +static const NvOdmGpioPinInfo s_spi_ethernet[] = { + {NVODM_PORT('c'), 1, NvOdmGpioPinActiveState_Low} // DBG_IRQ +}; + +static const NvOdmGpioPinInfo s_Bluetooth[] = { + {NVODM_PORT('u'), 0, NvOdmGpioPinActiveState_Low} // BT_RST# +}; + +static const NvOdmGpioPinInfo s_Wlan[] = { + {NVODM_PORT('k'), 5, NvOdmGpioPinActiveState_Low}, // WF_PWDN# + {NVODM_PORT('k'), 6, NvOdmGpioPinActiveState_Low} // WF_RST# +}; + +static const NvOdmGpioPinInfo s_Power[] = { + // lid open/close, High = Lid Closed + {NVODM_PORT('u'), 5, NvOdmGpioPinActiveState_High}, + // power button + {NVODM_PORT('v'), 2, NvOdmGpioPinActiveState_Low} +}; + +static const NvOdmGpioPinInfo s_WakeFromKeyBoard[] = { + {NVODM_PORT('a'), 0, NvOdmGpioPinActiveState_Low} // EC Keyboard Wakeup +}; + +static const NvOdmGpioPinInfo s_Battery[] = { + // Low Battery + {NVODM_PORT('w'), 3, NvOdmGpioPinActiveState_Low}, +}; + +const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group, + NvU32 Instance, NvU32 *pCount) +{ + switch (Group) + { + case NvOdmGpioPinGroup_Display: + *pCount = NVODM_ARRAY_SIZE(s_display); + return s_display; + + case NvOdmGpioPinGroup_Hdmi: + *pCount = NVODM_ARRAY_SIZE(s_hdmi); + return s_hdmi; + + case NvOdmGpioPinGroup_Crt: + *pCount = NVODM_ARRAY_SIZE(s_crt); + return s_crt; + + case NvOdmGpioPinGroup_Sdio: + if (Instance == 1) + { + *pCount = NVODM_ARRAY_SIZE(s_sdio); + return s_sdio; + } + else if (Instance == 3) + { + *pCount = NVODM_ARRAY_SIZE(s_sdio3); + return s_sdio3; + } + else + { + *pCount = 0; + return NULL; + } + + case NvOdmGpioPinGroup_NandFlash: + *pCount = NVODM_ARRAY_SIZE(s_NandFlash); + return s_NandFlash; + + case NvOdmGpioPinGroup_Bluetooth: + *pCount = NVODM_ARRAY_SIZE(s_Bluetooth); + return s_Bluetooth; + + case NvOdmGpioPinGroup_Wlan: + *pCount = NVODM_ARRAY_SIZE(s_Wlan); + return s_Wlan; + + case NvOdmGpioPinGroup_SpiEthernet: + if (NvOdmQueryDownloadTransport() == + NvOdmDownloadTransport_SpiEthernet) + { + *pCount = NVODM_ARRAY_SIZE(s_spi_ethernet); + return s_spi_ethernet; + } + else + { + *pCount = 0; + return NULL; + } + + case NvOdmGpioPinGroup_Vi: + *pCount = NVODM_ARRAY_SIZE(s_vi); + return s_vi; + + case NvOdmGpioPinGroup_Power: + *pCount = NVODM_ARRAY_SIZE(s_Power); + return s_Power; + + case NvOdmGpioPinGroup_WakeFromECKeyboard: + *pCount = NVODM_ARRAY_SIZE(s_WakeFromKeyBoard); + return s_WakeFromKeyBoard; + + case NvOdmGpioPinGroup_Battery: + *pCount = NVODM_ARRAY_SIZE(s_Battery); + return s_Battery; + + default: + *pCount = 0; + return NULL; + } +} diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c new file mode 100644 index 000000000000..951fc9730f41 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc.c @@ -0,0 +1,100 @@ +/* + * 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. + * + */ + +/** + * @file + * @brief <b>NVIDIA Driver Development Kit: + * ODM Kbc interface</b> + * + */ + +#include "nvodm_query_kbc.h" +#include "nvodm_query_kbc_gpio_def.h" +#include "nvodm_query_kbc_qwerty_def.h" + +static NvU32 RowNumbers[] = {1, 15}; +static NvU32 ColNumbers[] = {7, 0}; + +void +NvOdmKbcGetParameter( + NvOdmKbcParameter Param, + NvU32 SizeOfValue, + void * pValue) +{ + NvU32 *pTempVar; + switch (Param) + { + case NvOdmKbcParameter_DebounceTime: + pTempVar = (NvU32 *)pValue; + *pTempVar = 2; + break; + case NvOdmKbcParameter_RepeatCycleTime: + pTempVar = (NvU32 *)pValue; + *pTempVar = 5; + break; + default: + break; + } +} + +NvU32 +NvOdmKbcGetKeyCode( + NvU32 Row, + NvU32 Column, + NvU32 RowCount, + NvU32 ColumnCount) +{ + NvU32 CodeData; + if (Row < KBC_QWERTY_FUNCTION_KEY_ROW_BASE) + { + CodeData = KBC_QWERTY_NORMAL_KEY_CODE_BASE + ((Row * ColumnCount) + Column); + } + else + { + CodeData = KBC_QWERTY_FUNCTION_KEY_CODE_BASE + + (((Row - KBC_QWERTY_FUNCTION_KEY_ROW_BASE) * ColumnCount) + Column); + } + return CodeData; +} + +NvBool +NvOdmKbcIsSelectKeysWkUpEnabled( + NvU32 **pRowNumber, + NvU32 **pColNumber, + NvU32 *NumOfKeys) +{ + *pRowNumber = &RowNumbers[0]; + *pColNumber = &ColNumbers[0]; + *NumOfKeys = 2; + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h new file mode 100644 index 000000000000..2e625eb6217d --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_gpio_def.h @@ -0,0 +1,75 @@ +/* + * 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * The KBC GPIO pin definitions</b> + * + * @b Description: Define the KBC GPIO pins in row and column numbers. + */ + +#ifndef NVODM_QUERY_KBC_GPIO_DEF_H +#define NVODM_QUERY_KBC_GPIO_DEF_H + +typedef enum +{ + NvOdmKbcGpioPin_KBRow0 = 0, + NvOdmKbcGpioPin_KBRow1, + NvOdmKbcGpioPin_KBRow2, + NvOdmKbcGpioPin_KBRow3, + NvOdmKbcGpioPin_KBRow4, + NvOdmKbcGpioPin_KBRow5, + NvOdmKbcGpioPin_KBRow6, + NvOdmKbcGpioPin_KBRow7, + NvOdmKbcGpioPin_KBRow8, + NvOdmKbcGpioPin_KBRow9, + NvOdmKbcGpioPin_KBRow10, + NvOdmKbcGpioPin_KBRow11, + NvOdmKbcGpioPin_KBRow12, + NvOdmKbcGpioPin_KBRow13, + NvOdmKbcGpioPin_KBRow14, + NvOdmKbcGpioPin_KBRow15, + NvOdmKbcGpioPin_KBCol0, + NvOdmKbcGpioPin_KBCol1, + NvOdmKbcGpioPin_KBCol2, + NvOdmKbcGpioPin_KBCol3, + NvOdmKbcGpioPin_KBCol4, + NvOdmKbcGpioPin_KBCol5, + NvOdmKbcGpioPin_KBCol6, + NvOdmKbcGpioPin_KBCol7, + NvOdmKbcGpioPin_Num, + NvOdmKbcGpioPin_Force32 = 0x7FFFFFFF +}NvOdmKbcGpioPin; + +#endif // NVODM_QUERY_KBC_GPIO_DEF_H + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h new file mode 100644 index 000000000000..c5c82bb5df35 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_kbc_qwerty_def.h @@ -0,0 +1,54 @@ +/* + * 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * The KBC qwerty property definitions</b> + * + * @b Description: Define the qwerty keyboard support definitions which is used + * by multiple functions. + */ + +#ifndef NVODM_QUERY_KBC_QWERTY_DEF_H +#define NVODM_QUERY_KBC_QWERTY_DEF_H + +#define KBC_QWERTY_NORMAL_KEY_CODE_BASE 0x1000 +#define KBC_QWERTY_FUNCTION_KEY_CODE_BASE 0x2000 + +#define KBC_QWERTY_FUNCTION_KEY_ROW_BASE 0x100 +#define KBC_QWERTY_FUNCTION_KEY_ROW_NUMBER 0 +#define KBC_QWERTY_FUNCTION_KEY_COLUMN_NUMBER 7 + + +#endif // NVODM_QUERY_KBC_QWERTY_DEF_H + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c new file mode 100644 index 000000000000..18a2c903cbb4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_nand.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * @brief <b>NVIDIA Driver Development Kit: + * ODM Uart interface</b> + * + * @b Description: Implements the ODM for the Uart communication. + * + */ + +#include "nvodm_query_nand.h" +#include "nvcommon.h" + +// fill params for all required nand flashes here. +// this list will end when vendor id and chipd id will be zero. +// hence, all supported chips should be listed before that. +NvOdmNandFlashParams g_Params[] = +{ + /* + { + VendorId, DeviceId, NandType, IsCopyBackCommandSupported, IsCacheWriteSupported, CapacityInMB, ZonesPerDevice, + BlocksPerZone, OperationSuccessStatus, InterleaveCapability, EccAlgorithm, + ErrorsCorrectable, SkippedSpareBytes, + TRP, TRH (TREH), TWP, TWH, TCS, TWHR, TWB, TREA, TADL, + TCLS, TCLH, TCH, TALS, TALH, TRC, TWC, TCR(TCLR), TAR, TRR, NandDeviceType, ReadIdFourthByte + } + Note : + TADL values for flashes K9F1G08Q0M, K9F1G08U0M, TH58NVG4D4CTG00, + TH58NVG3D4BTG00, TH58NVG2S3BFT00 is not available from their data sheets. + Hence TADL is computed as + tADL = (tALH + tALS + tWP). + */ + // filling odm parameter structure for Samsung K9K8G08U0M + { + 0xEC, 0xD3, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 1024, 4, + 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 20, 60, 100, 26, 70, + 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x95 + }, + // filling odm parameter structure for Samsung K9GAG08U0D + { + 0xEC, 0xD5, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 2048, 2, + 2048, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Eight, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 20, 60, 100, 20, 100, + 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type2, 0x29 + }, + // filling odm parameter structure for Samsung K9W8G08U1M + { + 0xEC, 0xDC, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 1024, 2, + 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 15, 60, 100, 18, 100, + 10, 5, 5, 10, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, + // filling odm parameter structure for Samsung K9F1G08Q0M + { + 0xEC, 0xA1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1, + 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 60, 20, 60, 20, 0, 60, 100, 60, 70, + 0, 10, 10, 0, 10, 80, 80, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, + // filling odm parameter structure for Samsung K9F1G08U0M + { + 0xEC, 0xF1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 15, 25, 15, 0, 60, 100, 30, 35, + 0, 10, 10, 0, 10, 50, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, + // filling odm parameter structure for Samsung K9L8G08U0M + { + 0xEC, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 1024, 4, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 20, 60, 100, 20, 35, + 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Samsung K9G4G08U0M + { + 0xEC, 0xDC, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 512, 2, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 15, 15, 60, 100, 18, 50, + 10, 5, 5, 10, 5, 30, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Samsung K5E2G1GACM + { + 0xEC, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 2, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 21, 15, 21, 15, 31, 60, 100, 30, 100, + 21, 5, 5, 21, 5, 42, 42, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, +/* + // filling odm parameter structure for Toshiba TH58NVG4D4CTG00 + { + 0x98, 0xD5, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 2048, 1, + 8192, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 41, 15, 15, 10, 0, 30, 20, 200, 41, 21, + 0, 6, 6, 0, 6, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Toshiba TH58NVG3D4BTG00 + { + 0x98, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_TRUE, 1024, 1, + 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 41, 15, 15, 10, 0, 30, 20, 200, 41, 35, + 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Toshiba TH58NVG2S3BFT00 + { + 0x98, 0xDC, NvOdmNandFlashType_Slc, NV_FALSE, NV_FALSE, 512, 1, + 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 41, 15, 15, 10, 0, 30, 20, 200, 41, 35, + 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25 + }, +*/ + // filling odm parameter structure for Samsung K9LBG08U0M + { + 0xEC, 0xD7, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 4096, 4, 2048, + 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Six, NvOdmNandSkipSpareBytes_4, + 12, 10, 12, 10, 20, 60, 100, 20, 100, + 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0xB6 + }, + //Hynix H8BES0UQ0MCP + { + 0xAD, 0xBC, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 512, 2, 2048, + 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 10, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x55 + }, + //Hynix H8BCS0SJ0MCP + { + 0xAD, 0xBA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048, + 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 15, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x55 + }, + + //Hynix H8BCS0RJ0MCP + { + 0xAD, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048, + 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 10, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15 + }, + /*Numonyx MCP - NAND02GR3B2D*/ + { + 0x20, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, + 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 15, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15 + }, + // Hynix HY27UF084G2B (readid 4th byte 0x95) + { + 0xAD, 0xDC, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 512, 2, + 2048, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 12, 10, 12, 10, 20, 80, 100, 20, 70, + 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x95 + }, + /* "This is the end of device list please do not modify this. To add support for more flash parts, + add device category for those parts before this element"*/ + { + 0, 0, NvOdmNandFlashType_UnKnown, NV_FALSE, NV_FALSE, 0, 0, + 0, 0, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NvOdmNandDeviceType_Type1, 0 + } +}; + +NvOdmNandFlashParams *NvOdmNandGetFlashInfo (NvU32 ReadID) +{ + NvU8 TempValue; + NvU8 VendorId = 0; + NvU8 DeviceId = 0; + NvU8 ReadIdFourthByte = 0; + NvOdmNandFlashType NandType; + NvU8 i = 0; + // To extract Vendor Id + VendorId = (NvU8) (ReadID & 0xFF); + // To extract Device Id + DeviceId = (NvU8) ((ReadID >> DEVICE_SHIFT) & 0xFF); + // To extract Fourth ID byte of Read ID - for checking if the flash is 42nm. + ReadIdFourthByte = (NvU8) ((ReadID >> FOURTH_ID_SHIFT) & 0xFF); + // To extract device Type Mask + TempValue = (NvU8) ((ReadID >> FLASH_TYPE_SHIFT) & 0xC); + if (TempValue) + { + NandType = NvOdmNandFlashType_Mlc; + } + else + { + NandType = NvOdmNandFlashType_Slc; + } + // following ORing is done to check if we reached the end of the list. + while ((g_Params[i].VendorId) | (g_Params[i].DeviceId)) + { + if ((g_Params[i].VendorId == VendorId) && + (g_Params[i].DeviceId == DeviceId) && + (g_Params[i].ReadIdFourthByte == ReadIdFourthByte) && + (g_Params[i].NandType == NandType)) + { + return &g_Params[i]; + } + else + i++; + } + // This condition will be reached if "g_Params" is not having Parameters of the flash used. + // Hence add the parameters required in the table. + return NULL; +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c new file mode 100644 index 000000000000..e8ec4b70b3dc --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_pinmux.c @@ -0,0 +1,305 @@ +/* + * Copyright (c) 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. + * + */ + +/* + * This file implements the pin-mux configuration tables for each I/O module. + */ + +// THESE SETTINGS ARE PLATFORM-SPECIFIC (not SOC-specific). +// PLATFORM = Harmony + +#include "nvodm_query_pinmux.h" +#include "nvassert.h" +#include "nvodm_query.h" +#include "nvodm_services.h" + +#define NVODM_PINMUX_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +static const NvU32 s_NvOdmPinMuxConfig_Uart[] = { + NvOdmUartPinMap_Config4, // UART1, 2 lines + NvOdmUartPinMap_Config2, // UART2, 2 lines + NvOdmUartPinMap_Config1, // UART3, 4 lines + NvOdmUartPinMap_Config2, // UART4, 4 lines + 0 // UART5 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Spi[] = { + NvOdmSpiPinMap_Config4, + 0, + 0, + 0, + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Twc[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_I2c[] = { + NvOdmI2cPinMap_Config1, + NvOdmI2cPinMap_Config1, + NvOdmI2cPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_I2cPmu[] = { + NvOdmI2cPmuPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Ulpi[] = { + NvOdmUlpiPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Sdio[] = { + NvOdmSdioPinMap_Config1, + NvOdmSdioPinMap_Config5, + 0, + NvOdmSdioPinMap_Config2 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Spdif[] = { + NvOdmSpdifPinMap_Config2 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Hsi[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Hdcp[] = { + NvOdmHdcpPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Hdmi[] = { + NvOdmHdmiPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Pwm[] = { + NvOdmPwmPinMap_Config6 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Ata[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Nand[] = { + NvOdmNandPinMap_Config4, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Dap[] = { + NvOdmDapPinMap_Config1, + NvOdmDapPinMap_Config1, + 0, + NvOdmDapPinMap_Config1, + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Kbd[] = { + NvOdmKbdPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_SyncNor[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Mio[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_ExternalClock[] = { + NvOdmExternalClockPinMap_Config2, + NvOdmExternalClockPinMap_Config3, + NvOdmExternalClockPinMap_Config1 +}; + +static const NvU32 s_NvOdmPinMuxConfig_VideoInput[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Display[] = { + NvOdmDisplayPinMap_Config1, + 0 // Only 1 display is connected to the LCD pins +}; + +static const NvU32 s_NvOdmPinMuxConfig_BacklightPwm[] = { + 0, + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_Crt[] = { + NvOdmCrtPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Tvo[] = { + NvOdmTvoPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_OneWire[] = { + 0 +}; + +static const NvU32 s_NvOdmPinMuxConfig_PciExpress[] = { + NvOdmPciExpressPinMap_Config1, +}; + +void +NvOdmQueryPinMux( + NvOdmIoModule IoModule, + const NvU32 **pPinMuxConfigTable, + NvU32 *pCount) +{ + switch (IoModule) + { + case NvOdmIoModule_Display: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Display; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Display); + break; + + case NvOdmIoModule_Dap: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Dap; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Dap); + break; + + case NvOdmIoModule_Hdcp: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdcp; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdcp); + break; + + case NvOdmIoModule_Hdmi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdmi; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdmi); + break; + + case NvOdmIoModule_I2c: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2c; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2c); + break; + + case NvOdmIoModule_I2c_Pmu: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2cPmu; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2cPmu); + break; + + case NvOdmIoModule_Nand: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Nand; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Nand); + break; + + case NvOdmIoModule_Sdio: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Sdio; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Sdio); + break; + + case NvOdmIoModule_Spi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spi; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spi); + break; + + case NvOdmIoModule_Uart: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Uart; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Uart); + break; + + case NvOdmIoModule_ExternalClock: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_ExternalClock; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_ExternalClock); + break; + + case NvOdmIoModule_Crt: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Crt; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Crt); + break; + + case NvOdmIoModule_PciExpress: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_PciExpress; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_PciExpress); + break; + + case NvOdmIoModule_Tvo: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Tvo; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Tvo); + break; + case NvOdmIoModule_BacklightPwm: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_BacklightPwm; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_BacklightPwm); + break; + + case NvOdmIoModule_Pwm: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Pwm; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Pwm); + break; + + case NvOdmIoModule_Ulpi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ulpi; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ulpi); + break; + + case NvOdmIoModule_Spdif: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spdif; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spdif); + break; + + case NvOdmIoModule_Kbd: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Kbd; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmPinMuxConfig_Kbd); + break; + + case NvOdmIoModule_Twc: + case NvOdmIoModule_Hsi: + case NvOdmIoModule_Ata: + case NvOdmIoModule_SyncNor: + case NvOdmIoModule_Mio: + case NvOdmIoModule_VideoInput: + case NvOdmIoModule_OneWire: + *pPinMuxConfigTable = NULL; + *pCount = 0; + break; + + default: + *pCount = 0; + break; + } +} + +void +NvOdmQueryClockLimits( + NvOdmIoModule IoModule, + const NvU32 **pClockSpeedLimits, + NvU32 *pCount) +{ + switch (IoModule) + { + default: + *pClockSpeedLimits = NULL; + *pCount = 0; + break; + } +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h new file mode 100644 index 000000000000..000fd861577e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_addresses.h @@ -0,0 +1,428 @@ +/* + * 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity database NvOdmIoAddress entries + * for the peripherals on E1162 module. + */ + +#include "pmu/tps6586x/nvodm_pmu_tps6586x_supply_info_table.h" +#include "tmon/adt7461/nvodm_tmon_adt7461_channel.h" +#include "nvodm_tmon.h" +#include "../nvodm_query_kbc_gpio_def.h" + + +// RTC voltage rail +static const NvOdmIoAddress s_RtcAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO2 } /* VDD_RTC -> LD02 */ +}; + +// Core voltage rail +static const NvOdmIoAddress s_CoreAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_DCD0 } /* VDD_CORE -> SM0 */ +}; + +// CPU voltage rail +static const NvOdmIoAddress s_ffaCpuAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_DCD1 } /* VDD_CPU -> SM1 */ +}; + +// PLLA voltage rail +static const NvOdmIoAddress s_PllAAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */ +}; + +// PLLM voltage rail +static const NvOdmIoAddress s_PllMAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */ +}; + +// PLLP voltage rail +static const NvOdmIoAddress s_PllPAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */ +}; + +// PLLC voltage rail +static const NvOdmIoAddress s_PllCAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX_1V2 -> LDO1 */ +}; + +// PLLE voltage rail +static const NvOdmIoAddress s_PllEAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Ext_TPS62290PmuSupply_BUCK } /* AVDD_PLLE -> VDD_1V05 */ +}; + +// PLLU voltage rail +static const NvOdmIoAddress s_PllUAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDD_PLLU -> LDO1 */ +}; + +// PLLU1 voltage rail +static const NvOdmIoAddress s_ffaPllU1Addresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDD_PLLU -> LDO1 */ +}; + +// PLLS voltage rail +static const NvOdmIoAddress s_PllSAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* PLL_S -> LDO1 */ +}; + +// PLLHD voltage rail +static const NvOdmIoAddress s_PllHdmiAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO8 } /* AVDD_HDMI_PLL -> LDO8 */ +}; + +// OSC voltage rail +static const NvOdmIoAddress s_VddOscAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* AVDD_OSC -> LDO4 */ +}; + +// PLLX voltage rail +static const NvOdmIoAddress s_PllXAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO1 } /* AVDDPLLX -> LDO1 */ +}; + +// PLL_USB voltage rail +static const NvOdmIoAddress s_PllUsbAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* AVDD_USB_PLL -> derived from LDO3 (VDD_3V3) */ +}; + +// SYS IO voltage rail +static const NvOdmIoAddress s_VddSysAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_SYS -> LDO4 */ +}; + +// USB voltage rail +static const NvOdmIoAddress s_VddUsbAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* AVDD_USB -> derived from LDO3 (VDD_3V3) */ +}; + +// HDMI voltage rail +static const NvOdmIoAddress s_VddHdmiAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO7 } /* AVDD_HDMI -> LDO7 */ +}; + +// MIPI voltage rail (DSI_CSI) +static const NvOdmIoAddress s_VddMipiAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Ext_TPS72012PmuSupply_LDO } /* AVDD_DSI_CSI -> VDD_1V2 */ +}; + +// LCD voltage rail +static const NvOdmIoAddress s_VddLcdAddresses[] = +{ + // This is in the AON domain + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_LCD -> (LDO4PG) */ +}; + +// Audio voltage rail +static const NvOdmIoAddress s_VddAudAddresses[] = +{ + // This is in the AON domain + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_AUDIO -> (LDO4PG) */ +}; + +// DDR voltage rail +static const NvOdmIoAddress s_VddDdrAddresses[] = +{ + // This is in the AON domain + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_DDR -> (LDO4PG) */ +}; + +// DDR_RX voltage rail +static const NvOdmIoAddress s_VddDdrRxAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO9 } /* VDDIO_RX_DDR(2.7-3.3) -> LDO9 */ +}; + +// NAND voltage rail +static const NvOdmIoAddress s_VddNandAddresses[] = +{ + // This is in the AON domain + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_NAND_3V3 -> derived from LDO3 (VDD_3V3) */ +}; + +// UART voltage rail +static const NvOdmIoAddress s_VddUartAddresses[] = +{ + // This is in the AON domain + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_UART -> (LDO4PG) */ +}; + +// SDIO voltage rail +static const NvOdmIoAddress s_VddSdioAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_SDIO -> derived from LDO3 (VDD_3V3) */ +}; + +// VDAC voltage rail +static const NvOdmIoAddress s_VddVdacAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO6 } /* AVDD_VDAC -> LDO6 */ +}; + +// VI voltage rail +static const NvOdmIoAddress s_VddViAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_VI -> derived from LDO3 (VDD_3V3) */ +}; + +// BB voltage rail +static const NvOdmIoAddress s_VddBbAddresses[] = +{ + // This is in the AON domain + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDIO_BB -> (LDO4PG) */ +}; + +// Super power voltage rail for the SOC +static const NvOdmIoAddress s_VddSocAddresses[]= +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_SoC } /* VDD SOC */ +}; + +// PEX_CLK voltage rail +static const NvOdmIoAddress s_VddPexClkAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO0 }, /* VDDIO_PEX_CLK -> LDO0 */ + { NvOdmIoModule_Vdd, 0x00, Ext_TPS62290PmuSupply_BUCK }, /* AVDD_PLLE -> VDD_1V05 */ + { NvOdmIoModule_Vdd, 0x00, Ext_TPS74201PmuSupply_LDO }, /* PMU_GPIO-1 -> VDD_1V5 */ +}; + +// PMU0 +static const NvOdmIoAddress s_Pmu0Addresses[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x68 }, +}; + +// SPI1 for Spi Ethernet Kitl only +static const NvOdmIoAddress s_SpiEthernetAddresses[] = +{ + { NvOdmIoModule_Spi, 0, 0 }, + { NvOdmIoModule_Gpio, (NvU32)'c'-'a', 1 }, // DBQ_IRQ, Port C, Pin 1 +}; + +// P1160 ULPI USB +static const NvOdmIoAddress s_UlpiUsbAddresses[] = +{ + { NvOdmIoModule_ExternalClock, 1, 0 }, /* ULPI PHY Clock -> DAP_MCLK2 */ +}; + +// LVDS LCD Display +static const NvOdmIoAddress s_LvdsDisplayAddresses[] = +{ + { NvOdmIoModule_Display, 0, 0 }, + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4}, /* VDDIO_LCD (AON:VDD_1V8) */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 }, /* VDD_LVDS (VDD_3V3) */ +}; + +// HDMI addresses based on Concorde 2 design +static const NvOdmIoAddress s_HdmiAddresses[] = +{ + { NvOdmIoModule_Hdmi, 0, 0 }, + + // Display Data Channel (DDC) for Extended Display Identification + // Data (EDID) + { NvOdmIoModule_I2c, 0x01, 0xA0 }, + + // HDCP ROM + { NvOdmIoModule_I2c, 0x01, 0x74 }, + + /* AVDD_HDMI */ + { NvOdmIoModule_Vdd, 0x00, Ext_TPS2051BPmuSupply_VDDIO_VID }, // VDDIO_HDMI + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO8 }, // AVDD_HDMI_PLL + + /* lcd i/o rail (for hot plug pin) */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 }, // VDDIO_LCD (VDD_1V8) +}; + +// CRT address based on Concorde 2 design +static const NvOdmIoAddress s_CrtAddresses[] = +{ + { NvOdmIoModule_Crt, 0, 0 }, + + // Display Data Channel (DDC) for Extended Display Identification + // Data (EDID) + // FIXME: Disable this for now since it causes some TV not display. + { NvOdmIoModule_I2c, 0x01, 0xA0 }, + + /* tvdac rail */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO6 }, // VDDIO_VDAC + + /* lcd rail (required for crt out) */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 }, // VDDIO_LCD (VDD_1V8) + { NvOdmIoModule_Vdd, 0x00, Ext_TPS2051BPmuSupply_VDDIO_VID }, // VDDIO_VGA +}; + +static const NvOdmIoAddress s_ffaVideoDacAddresses[] = +{ + { NvOdmIoModule_Tvo, 0x00, 0x00 }, + /* tvdac rail */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO6 }, // AVDD_VDAC +}; + +// Sdio +static const NvOdmIoAddress s_SdioAddresses[] = +{ + { NvOdmIoModule_Sdio, 0x1, 0x0 }, /* SD Memory on SD Bus */ + { NvOdmIoModule_Sdio, 0x3, 0x0 }, /* SD Memory on SD Bus */ + { NvOdmIoModule_Vdd, 0x00, Ext_SWITCHPmuSupply_VDDIO_SD }, /* EN_VDDIO_SD */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 } /* VDDIO_SDIO -> derived from LDO3 (VDD_3V3) */ +}; + +static const NvOdmIoAddress s_I2cSmbusAddresses[] = +{ + { NvOdmIoModule_I2c, 2, 0x8A }, + { NvOdmIoModule_Gpio, 27, 1} //Port BB:01 is used on harmony. +}; + +static const NvOdmIoAddress s_UsbMuxAddress[] = +{ + {NvOdmIoModule_Usb, 1, 0} +}; + +static const NvOdmIoAddress s_QwertyKeyPad16x8Addresses[] = +{ + // instance = 1 indicates Column info. + // instance = 0 indicates Row info. + // address holds KBC pin number used for row/column. + + // All Row info has to be defined contiguously from 0 to max. + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow0}, // Row 0 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow1}, // Row 1 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow2}, // Row 2 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow3}, // Row 3 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow4}, // Row 4 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow5}, // Row 5 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow6}, // Row 6 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow7}, // Row 7 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow8}, // Row 8 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow9}, // Row 9 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow10}, // Row 10 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow11}, // Row 11 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow12}, // Row 12 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow13}, // Row 13 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow14}, // Row 14 + { NvOdmIoModule_Kbd, 0x00, NvOdmKbcGpioPin_KBRow15}, // Row 15 + + // All Column info has to be defined contiguously from 0 to max. + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol0}, // Column 0 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol1}, // Column 1 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol2}, // Column 2 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol3}, // Column 3 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol4}, // Column 4 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol5}, // Column 5 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol6}, // Column 6 + { NvOdmIoModule_Kbd, 0x01, NvOdmKbcGpioPin_KBCol7}, // Column 7 +}; + + +static const NvOdmIoAddress s_Tmon0Addresses[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x98 }, /* I2C bus */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO3 }, /* TMON pwer rail -> LDO3 (VDD_3V3) */ + { NvOdmIoModule_Gpio, (NvU32)'n'-'a', 6 }, /* GPIO Port N and Pin 6 */ + + /* Temperature zone mapping */ + { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Core, ADT7461ChannelID_Remote }, /* TSENSOR */ + { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Ambient, ADT7461ChannelID_Local }, /* TSENSOR */ +}; + +// Bluetooth +static const NvOdmIoAddress s_p1162BluetoothAddresses[] = +{ + { NvOdmIoModule_Uart, 0x2, 0x0 }, // FIXME: Is this used? + { NvOdmIoModule_Gpio, (NvU32)'u'-'a', 0 }, /* BT_RST#: GPIO Port U and Pin 0 */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 } /* VDDHOSTIF_BT -> LDO4 (AON:VDD_1V8) */ +}; + +// Wlan +static const NvOdmIoAddress s_WlanAddresses[] = +{ + { NvOdmIoModule_Sdio, 0x0, 0x0 }, /* WLAN is on SD Bus */ + { NvOdmIoModule_Gpio, 0xa, 0x5 }, /* GPIO Port K and Pin 5 - WIFI_PWR*/ + { NvOdmIoModule_Gpio, 0xa, 0x6 }, /* GPIO Port K and Pin 6 - WIFI_RST */ + { NvOdmIoModule_Vdd, 0x00, TPS6586xPmuSupply_LDO4 }, /* VDDIO_WLAN (AON:VDD_1V8) */ + { NvOdmIoModule_Vdd, 0x00, Ext_TPS72012PmuSupply_LDO } /* VCORE_WIFI (VDD_1V2) */ +}; + +// Audio Codec +static const NvOdmIoAddress s_AudioCodecAddresses[] = +{ + { NvOdmIoModule_ExternalClock, 0, 0 }, /* Codec MCLK -> APxx DAP_MCLK1 */ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x34 }, /* Codec I2C -> APxx PMU I2C, segment 0 */ + /* Codec I2C address is 0x34 */ +}; + +// Audio Codec on GEN1_I2C (I2C_1) +static const NvOdmIoAddress s_AudioCodecAddressesI2C_1[] = +{ + { NvOdmIoModule_ExternalClock, 0, 0 }, /* Codec MCLK -> APxx DAP_MCLK1 */ + { NvOdmIoModule_I2c, 0x00, 0x34 }, /* Codec I2C -> APxx PMU I2C, segment 0 */ + /* Codec I2C address is 0x34 */ +}; + +// TouchPanel +static const NvOdmIoAddress s_TouchPanelAddresses[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x06 }, /* I2C address (7-bit) 0x03<<1=0x06(8-bit) */ + { NvOdmIoModule_Gpio, (NvU32)'d'-'a', 0x02 }, /* GPIO Port D and Pin 2 */ +}; + +static const NvOdmIoAddress s_AcceleroAddresses[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x70 }, /* I2C address (7-bit) 0x38<<1 = 0x70(8-bit) */ + { NvOdmIoModule_Gpio, (NvU32)'c'-'a', 0x03 }, /* Gpio port C and Pin 3 */ +}; + + diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h new file mode 100644 index 000000000000..df91cc1e6d22 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/subboards/nvodm_query_discovery_e1162_peripherals.h @@ -0,0 +1,453 @@ +/* + * 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity database Peripheral entries + * for the peripherals on P1162 module. + */ +// AP20 doesn't have PLL_D rail. +// PLLD (NV reserved) / Use PLL_U +{ + NV_VDD_PLLD_ODM_ID, + s_PllUAddresses, + NV_ARRAY_SIZE(s_PllUAddresses), + NvOdmPeripheralClass_Other +}, + +// RTC (NV reserved) +{ + NV_VDD_RTC_ODM_ID, + s_RtcAddresses, + NV_ARRAY_SIZE(s_RtcAddresses), + NvOdmPeripheralClass_Other +}, + +// CORE (NV reserved) +{ + NV_VDD_CORE_ODM_ID, + s_CoreAddresses, + NV_ARRAY_SIZE(s_CoreAddresses), + NvOdmPeripheralClass_Other +}, + +// CPU (NV reserved) +{ + NV_VDD_CPU_ODM_ID, + s_ffaCpuAddresses, + NV_ARRAY_SIZE(s_ffaCpuAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLA (NV reserved) +{ + NV_VDD_PLLA_ODM_ID, + s_PllAAddresses, + NV_ARRAY_SIZE(s_PllAAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLM (NV reserved) +{ + NV_VDD_PLLM_ODM_ID, + s_PllMAddresses, + NV_ARRAY_SIZE(s_PllMAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLP (NV reserved) +{ + NV_VDD_PLLP_ODM_ID, + s_PllPAddresses, + NV_ARRAY_SIZE(s_PllPAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLC (NV reserved) +{ + NV_VDD_PLLC_ODM_ID, + s_PllCAddresses, + NV_ARRAY_SIZE(s_PllCAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLE (NV reserved) +{ + NV_VDD_PLLE_ODM_ID, + s_PllEAddresses, + NV_ARRAY_SIZE(s_PllEAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLU (NV reserved) +{ + NV_VDD_PLLU_ODM_ID, + s_PllUAddresses, + NV_ARRAY_SIZE(s_PllUAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLU1 (NV reserved) +{ + NV_VDD_PLLU1_ODM_ID, + s_ffaPllU1Addresses, + NV_ARRAY_SIZE(s_ffaPllU1Addresses), + NvOdmPeripheralClass_Other +}, + +// PLLS (NV reserved) +{ + NV_VDD_PLLS_ODM_ID, + s_PllSAddresses, + NV_ARRAY_SIZE(s_PllSAddresses), + NvOdmPeripheralClass_Other +}, + +// HDMI PLL (NV reserved) +{ + NV_VDD_PLLHDMI_ODM_ID, + s_PllHdmiAddresses, + NV_ARRAY_SIZE(s_PllHdmiAddresses), + NvOdmPeripheralClass_Other +}, + +// OSC VDD (NV reserved) +{ + NV_VDD_OSC_ODM_ID, + s_VddOscAddresses, + NV_ARRAY_SIZE(s_VddOscAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLX (NV reserved) +{ + NV_VDD_PLLX_ODM_ID, + s_PllXAddresses, + NV_ARRAY_SIZE(s_PllXAddresses), + NvOdmPeripheralClass_Other +}, + +// PLL_USB (NV reserved) +{ + NV_VDD_PLL_USB_ODM_ID, + s_PllUsbAddresses, + NV_ARRAY_SIZE(s_PllUsbAddresses), + NvOdmPeripheralClass_Other +}, + +// System IO VDD (NV reserved) +{ + NV_VDD_SYS_ODM_ID, + s_VddSysAddresses, + NV_ARRAY_SIZE(s_VddSysAddresses), + NvOdmPeripheralClass_Other +}, + +// USB VDD (NV reserved) +{ + NV_VDD_USB_ODM_ID, + s_VddUsbAddresses, + NV_ARRAY_SIZE(s_VddUsbAddresses), + NvOdmPeripheralClass_Other +}, + +// HDMI VDD (NV reserved) +{ + NV_VDD_HDMI_ODM_ID, + s_VddHdmiAddresses, + NV_ARRAY_SIZE(s_VddHdmiAddresses), + NvOdmPeripheralClass_Other +}, + +// MIPI VDD (NV reserved) / AVDD_DSI_CSI +{ + NV_VDD_MIPI_ODM_ID, + s_VddMipiAddresses, + NV_ARRAY_SIZE(s_VddMipiAddresses), + NvOdmPeripheralClass_Other +}, + +// LCD VDD (NV reserved) +{ + NV_VDD_LCD_ODM_ID, + s_VddLcdAddresses, + NV_ARRAY_SIZE(s_VddLcdAddresses), + NvOdmPeripheralClass_Other +}, + +// AUDIO VDD (NV reserved) +{ + NV_VDD_AUD_ODM_ID, + s_VddAudAddresses, + NV_ARRAY_SIZE(s_VddAudAddresses), + NvOdmPeripheralClass_Other +}, + +// DDR VDD (NV reserved) +{ + NV_VDD_DDR_ODM_ID, + s_VddDdrAddresses, + NV_ARRAY_SIZE(s_VddDdrAddresses), + NvOdmPeripheralClass_Other +}, + +// DDR_RX (NV reserved) +{ + NV_VDD_DDR_RX_ODM_ID, + s_VddDdrRxAddresses, + NV_ARRAY_SIZE(s_VddDdrRxAddresses), + NvOdmPeripheralClass_Other +}, + +// NAND VDD (NV reserved) +{ + NV_VDD_NAND_ODM_ID, + s_VddNandAddresses, + NV_ARRAY_SIZE(s_VddNandAddresses), + NvOdmPeripheralClass_Other +}, + +// UART VDD (NV reserved) +{ + NV_VDD_UART_ODM_ID, + s_VddUartAddresses, + NV_ARRAY_SIZE(s_VddUartAddresses), + NvOdmPeripheralClass_Other +}, + +// SDIO VDD (NV reserved) +{ + NV_VDD_SDIO_ODM_ID, + s_VddSdioAddresses, + NV_ARRAY_SIZE(s_VddSdioAddresses), + NvOdmPeripheralClass_Other +}, + +// VDAC VDD (NV reserved) +{ + NV_VDD_VDAC_ODM_ID, + s_VddVdacAddresses, + NV_ARRAY_SIZE(s_VddVdacAddresses), + NvOdmPeripheralClass_Other +}, + +// VI VDD (NV reserved) +{ + NV_VDD_VI_ODM_ID, + s_VddViAddresses, + NV_ARRAY_SIZE(s_VddViAddresses), + NvOdmPeripheralClass_Other +}, + +// BB VDD (NV reserved) +{ + NV_VDD_BB_ODM_ID, + s_VddBbAddresses, + NV_ARRAY_SIZE(s_VddBbAddresses), + NvOdmPeripheralClass_Other +}, + +// PEX_CLK (NV reserved) +{ + NV_VDD_PEX_CLK_ODM_ID, + s_VddPexClkAddresses, + NV_ARRAY_SIZE(s_VddPexClkAddresses), + NvOdmPeripheralClass_Other +}, + +#if 0 +// VBUS +{ + NV_VDD_VBUS_ODM_ID, + s_VddVBusAddresses, + NV_ARRAY_SIZE(s_VddVBusAddresses), + NvOdmPeripheralClass_Other +}, +#endif + +//SOC +{ + NV_VDD_SoC_ODM_ID, + s_VddSocAddresses, + NV_ARRAY_SIZE(s_VddSocAddresses), + NvOdmPeripheralClass_Other +}, + +// PMU0 +{ + NV_ODM_GUID('t','p','s','6','5','8','6','x'), + s_Pmu0Addresses, + NV_ARRAY_SIZE(s_Pmu0Addresses), + NvOdmPeripheralClass_Other +}, + +// ENC28J60 SPI Ethernet module +{ + NV_ODM_GUID('e','n','c','2','8','j','6','0'), + s_SpiEthernetAddresses, + NV_ARRAY_SIZE(s_SpiEthernetAddresses), + NvOdmPeripheralClass_Other +}, + +// SMSC3317 ULPI USB PHY +{ + NV_ODM_GUID('s','m','s','c','3','3','1','7'), + s_UlpiUsbAddresses, + NV_ARRAY_SIZE(s_UlpiUsbAddresses), + NvOdmPeripheralClass_Other +}, + +// LVDS LCD Display +{ + NV_ODM_GUID('L','V','D','S','W','S','V','G'), // LVDS WSVGA panel + s_LvdsDisplayAddresses, + NV_ARRAY_SIZE(s_LvdsDisplayAddresses), + NvOdmPeripheralClass_Display +}, + +// HDMI (based on Concorde 2 design) +{ + NV_ODM_GUID('f','f','a','2','h','d','m','i'), + s_HdmiAddresses, + NV_ARRAY_SIZE(s_HdmiAddresses), + NvOdmPeripheralClass_Display +}, + +// CRT (based on Concorde 2 design) +{ + NV_ODM_GUID('f','f','a','_','_','c','r','t'), + s_CrtAddresses, + NV_ARRAY_SIZE(s_CrtAddresses), + NvOdmPeripheralClass_Display +}, + +// TV Out Video Dac +{ + NV_ODM_GUID('f','f','a','t','v','o','u','t'), + s_ffaVideoDacAddresses, + NV_ARRAY_SIZE(s_ffaVideoDacAddresses), + NvOdmPeripheralClass_Display +}, + +// Sdio +{ + NV_ODM_GUID('s','d','i','o','_','m','e','m'), + s_SdioAddresses, + NV_ARRAY_SIZE(s_SdioAddresses), + NvOdmPeripheralClass_Other +}, + +// I2c SmBus transport. +{ + NV_ODM_GUID('I','2','c','S','m','B','u','s'), + s_I2cSmbusAddresses, + NV_ARRAY_SIZE(s_I2cSmbusAddresses), + NvOdmPeripheralClass_Other +}, + +// USB Mux J7A1 and J6A1 +{ + NV_ODM_GUID('u','s','b','m','x','J','7','6'), + s_UsbMuxAddress, + NV_ARRAY_SIZE(s_UsbMuxAddress), + NvOdmPeripheralClass_Other + +}, + +// Qwerty key baord for 16x8 +{ + NV_ODM_GUID('q','w','e','r','t','y',' ',' '), + s_QwertyKeyPad16x8Addresses, + NV_ARRAY_SIZE(s_QwertyKeyPad16x8Addresses), + NvOdmPeripheralClass_HCI +}, + +// Temperature Monitor (TMON) +{ + NV_ODM_GUID('a','d','t','7','4','6','1',' '), + s_Tmon0Addresses, + NV_ARRAY_SIZE(s_Tmon0Addresses), + NvOdmPeripheralClass_Other +}, + +// Bluetooth +{ + NV_ODM_GUID('b','l','u','t','o','o','t','h'), + s_p1162BluetoothAddresses, + NV_ARRAY_SIZE(s_p1162BluetoothAddresses), + NvOdmPeripheralClass_Other +}, + +// Sdio wlan on COMMs Module +{ + NV_ODM_GUID('s','d','i','o','w','l','a','n'), + s_WlanAddresses, + NV_ARRAY_SIZE(s_WlanAddresses), + NvOdmPeripheralClass_Other +}, + +// Audio codec (I2C_PMU edition) +{ + NV_ODM_GUID('w','o','l','f','8','9','0','3'), + s_AudioCodecAddresses, + NV_ARRAY_SIZE(s_AudioCodecAddresses), + NvOdmPeripheralClass_Other +}, + +// Audio codec (I2C_1 edition) +{ + NV_ODM_GUID('w','o','8','9','0','3','_','1'), + s_AudioCodecAddressesI2C_1, + NV_ARRAY_SIZE(s_AudioCodecAddressesI2C_1), + NvOdmPeripheralClass_Other +}, + +// Touch panel +{ + NV_ODM_GUID('p','a','n','j','i','t','_','0'), + s_TouchPanelAddresses, + NV_ARRAY_SIZE(s_TouchPanelAddresses), + NvOdmPeripheralClass_HCI +}, + +// Accelerometer Module +{ + NV_ODM_GUID('b','m','a','1','5','0','a','c'), + s_AcceleroAddresses, + NV_ARRAY_SIZE(s_AcceleroAddresses), + NvOdmPeripheralClass_Other, +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h b/arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h new file mode 100644 index 000000000000..1ec701091145 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/tegra_devkit_custopt.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Definition of bitfields inside the BCT customer option</b> + * + * @b Description: Defines the board-specific bitfields of the + * BCT customer option parameter, for NVIDIA + * Tegra development platforms. + * + * This file pertains to Whistler and Voyager. + */ + +#ifndef NVIDIA_TEGRA_DEVKIT_CUSTOPT_H +#define NVIDIA_TEGRA_DEVKIT_CUSTOPT_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +//---------- BOARD PERSONALITIES (BEGIN) ----------// +// On the Whistler boards, be sure to match the following +// switches with the personality setting you choose. +// +// SW2 = bits 3:0 (low nibble) +// SW3 = bits 7:4 (high nibble) + +#define TEGRA_DEVKIT_DEFAULT_PERSONALITY \ + TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_RANGE 7:0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_DEFAULT 0x0UL + +// VOYAGER, eMMC, NO TRACE (10x8 keypad) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_01 0x01UL // ULPI = baseband +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05 0x05UL // ULPI = UART1 + +// VOYAGER, eMMC, with TRACE (7x1 keypad) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11 0x11UL // ULPI = baseband +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15 0x15UL // ULPI = UART1 + +// VOYAGER, NAND, NO TRACE (10x8 keypad) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 0x75UL // Voyager, NAND + +// WHISTLER, stand-alone +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1 0xC1UL // KB = 13x1, TRACE, GMI = A/D NOR +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C3 0xC3UL // KB = 16x8, NO TRACE, GMI = NAND + +// VOYAGER, USB2-ULPI (No UART1) +// Personality 71 is similar to the 75, except ULPI is enabled instead of UART1. +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_71 0x71UL + + +//---------- BOARD PERSONALITIES (END) ----------// + +/// Download transport +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_RANGE 10:8 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE 0x1UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART 0x2UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB 0x3UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET 0x4UL + +/// Transport option (bus selector), for UART and Ethernet transport +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_RANGE 12:11 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A 0x1UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B 0x2UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C 0x3UL + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_RANGE 12:11 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI 0x1UL + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_RANGE 17:15 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_DEFAULT 0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTA 0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTB 1 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTC 2 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTD 3 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTE 4 + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_RANGE 19:18 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT 0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE 1 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC 2 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART 3 + +// display options +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_RANGE 22:20 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_DEFAULT 0x0UL +// embedded panel (lvds, dsi, etc) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_EMBEDDED 0x0UL +// no panels (external or embedded) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_NULL 0x1UL +// use hdmi as the primary +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_HDMI 0x2UL +// use crt as the primary +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_CRT 0x3UL + +// Enable DHCP +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_RANGE 23:23 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_ENABLE 0x1UL + +/// Total RAM +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_RANGE 30:28 +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT 0x0UL // 512 MB +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_256 0x1UL // 256 MB +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_512 0x2UL // 512 MB +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1024 0x3UL // 1024 MB (1 GB) + +/// Soc low power state +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_RANGE 31:31 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP0 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1 0x1UL +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/Makefile b/arch/arm/mach-tegra/odm_kit/query/whistler/Makefile new file mode 100644 index 000000000000..cd3c24b7f540 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/Makefile @@ -0,0 +1,18 @@ +ccflags-y += -DNV_IS_AVP=0 +ccflags-y += -DNV_OAL=0 +ccflags-y += -DNV_USE_FUSE_CLOCK_ENABLE=0 +ifeq ($(CONFIG_MACH_TEGRA_GENERIC_DEBUG),y) +ccflags-y += -DNV_DEBUG=1 +else +ccflags-y += -DNV_DEBUG=0 +endif + +ccflags-y += -Iarch/arm/mach-tegra/odm_kit/adaptations + +obj-y += nvodm_query.o +obj-y += nvodm_query_discovery.o +obj-y += nvodm_query_nand.o +obj-y += nvodm_query_gpio.o +obj-y += nvodm_query_pinmux.o +obj-y += nvodm_query_kbc.o + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h b/arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h new file mode 100644 index 000000000000..869aedf1eb67 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/include/nvodm_imager_guids.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 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 NVODM_IMAGER_GUIDS_H +#define NVODM_IMAGER_GUIDS_H + +#include "nvodm_query_discovery.h" + +// E912-A02 and Concorde2 Sensors +#define OV5630_GUID NV_ODM_GUID('s','_','O','V','5','6','3','0') + +// E911 Sensors +#define MI5130_GUID NV_ODM_GUID('s','_','M','I','5','1','3','0') +#define SEMCOVGA_GUID NV_ODM_GUID('S','E','M','C','O','V','G','A') + +// E911 Focusers +// focuser for MI5130 +#define DW9710_GUID NV_ODM_GUID('f','_','D','W','9','7','1','0') + +/// focuser for OV5630 +#define AD5820_GUID NV_ODM_GUID('f','_','A','D','5','8','2','0') + +// E911 Flash +#define LTC3216_GUID NV_ODM_GUID('l','_','L','T','3','2','1','6') + +// io addresses common to all imagers (clock) +#define COMMONIMAGER_GUID NV_ODM_GUID('s', '_', 'c', 'o', 'm', 'm', 'o', 'n') + +// Pin Use Codes: +// VI/CSI Parallel and Serial Pins and GPIO Pins + +// More than one device may be retrieved thru the query +#define NVODM_CAMERA_DEVICE_IS_DEFAULT (1) + +// The imager devices can connect to the parallel bus or the serial bus +// Parallel connections use pins VD0 thru VD9. +// Serial connections use the mipi pins (ex: CSI_D1AN/CSI_D1AP) +#define NVODM_CAMERA_DATA_PIN_SHIFT (1) +#define NVODM_CAMERA_DATA_PIN_MASK 0x0F +#define NVODM_CAMERA_PARALLEL_VD0_TO_VD9 (1 << NVODM_CAMERA_DATA_PIN_SHIFT) +#define NVODM_CAMERA_PARALLEL_VD0_TO_VD7 (2 << NVODM_CAMERA_DATA_PIN_SHIFT) +#define NVODM_CAMERA_SERIAL_CSI_D1A (4 << NVODM_CAMERA_DATA_PIN_SHIFT) +#define NVODM_CAMERA_SERIAL_CSI_D2A (5 << NVODM_CAMERA_DATA_PIN_SHIFT) +#define NVODM_CAMERA_SERIAL_CSI_D1A_D2A (6 << NVODM_CAMERA_DATA_PIN_SHIFT) +#define NVODM_CAMERA_SERIAL_CSI_D1B (7 << NVODM_CAMERA_DATA_PIN_SHIFT) + +// Switching the encoding from the VideoInput module address to use with +// each GPIO module address. +// NVODM_IMAGER_GPIO will tell the nvodm imager how to use each gpio +// A gpio can be used for powerdown (lo, hi) or !powerdown (hi, lo) +// used for reset (hi, lo, hi) or for !reset (lo, hi, lo) +// Or, for mclk or pwm (unimplemented yet) +// We have moved the flash to its own, so it is not needed here +#define NVODM_IMAGER_GPIO_PIN_SHIFT (24) +#define NVODM_IMAGER_UNUSED (0x0) +#define NVODM_IMAGER_RESET (0x1 << NVODM_IMAGER_GPIO_PIN_SHIFT) +#define NVODM_IMAGER_RESET_AL (0x2 << NVODM_IMAGER_GPIO_PIN_SHIFT) +#define NVODM_IMAGER_POWERDOWN (0x3 << NVODM_IMAGER_GPIO_PIN_SHIFT) +#define NVODM_IMAGER_POWERDOWN_AL (0x4 << NVODM_IMAGER_GPIO_PIN_SHIFT) +// only on VGP0 +#define NVODM_IMAGER_MCLK (0x8 << NVODM_IMAGER_GPIO_PIN_SHIFT) +// only on VGP6 +#define NVODM_IMAGER_PWM (0x9 << NVODM_IMAGER_GPIO_PIN_SHIFT) +// If flash code wants the gpio's labelled +// use for any purpose, or not at all +#define NVODM_IMAGER_FLASH0 (0x5 << NVODM_IMAGER_GPIO_PIN_SHIFT) +#define NVODM_IMAGER_FLASH1 (0x6 << NVODM_IMAGER_GPIO_PIN_SHIFT) +#define NVODM_IMAGER_FLASH2 (0x7 << NVODM_IMAGER_GPIO_PIN_SHIFT) +// Shutter control +#define NVOSM_IMAGER_SHUTTER (0xA << NVODM_IMAGER_GPIO_PIN_SHIFT) +// + +#define NVODM_IMAGER_MASK (0xF << NVODM_IMAGER_GPIO_PIN_SHIFT) +#define NVODM_IMAGER_CLEAR(_s) ((_s) & ~(NVODM_IMAGER_MASK)) +#define NVODM_IMAGER_IS_SET(_s) (((_s) & (NVODM_IMAGER_MASK)) != 0) +#define NVODM_IMAGER_FIELD(_s) ((_s) >> NVODM_IMAGER_GPIO_PIN_SHIFT) + +// The imager devices can connect to the vi gpio (VGP) pins +// for various reasons: flash, powerdown, reset, pwm, mclk. +// Only certain pins can be used for certain activities. +// These flags should be OR'd together to form the proper 'address' +// in the NvOdmIoAddress for VideoInput. +// VGP1 & VGP2 are used for i2c +// _AL means 'active low', otherwise active high is assumed + +#define NVODM_CAMERA_GPIO_PIN_SHIFT (8) +#define NVODM_CAMERA_GPIO_PIN_MASK (0x7) +#define NVODM_CAMERA_GPIO_PIN_WIDTH 3 +#define NVODM_CAMERA_GPIO_PIN_COUNT 7 + +#define NVODM_CAMERA_UNUSED (0x0) +#define NVODM_CAMERA_RESET(_s) (0x1 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +#define NVODM_CAMERA_RESET_AL(_s) (0x2 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +#define NVODM_CAMERA_POWERDOWN(_s) (0x3 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +#define NVODM_CAMERA_POWERDOWN_AL(_s) (0x4 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +#define NVODM_CAMERA_FLASH_LOW(_s) (0x5 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +#define NVODM_CAMERA_FLASH_HIGH(_s) (0x6 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +// only on VGP0 +#define NVODM_CAMERA_MCLK(_s) (0x7 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) +// only on VGP6 +#define NVODM_CAMERA_PWM(_s) (0x7 << (_s+NVODM_CAMERA_GPIO_PIN_SHIFT)) + +#define NVODM_VGP0_SHIFT 0 +#define NVODM_VD10_SHIFT (1*NVODM_CAMERA_GPIO_PIN_WIDTH) +#define NVODM_VD11_SHIFT (2*NVODM_CAMERA_GPIO_PIN_WIDTH) +#define NVODM_VGP3_SHIFT (3*NVODM_CAMERA_GPIO_PIN_WIDTH) +#define NVODM_VGP4_SHIFT (4*NVODM_CAMERA_GPIO_PIN_WIDTH) +#define NVODM_VGP5_SHIFT (5*NVODM_CAMERA_GPIO_PIN_WIDTH) +#define NVODM_VGP6_SHIFT (6*NVODM_CAMERA_GPIO_PIN_WIDTH) + +// VGP0 +#define NVODM_CAMERA_VGP0_RESET NVODM_CAMERA_RESET(NVODM_VGP0_SHIFT) +#define NVODM_CAMERA_VGP0_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP0_SHIFT) +#define NVODM_CAMERA_VGP0_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP0_SHIFT) +#define NVODM_CAMERA_VGP0_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP0_SHIFT) +#define NVODM_CAMERA_VGP0_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP0_SHIFT) +#define NVODM_CAMERA_VGP0_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP0_SHIFT) +#define NVODM_CAMERA_VGP0_MCLK NVODM_CAMERA_MCLK(NVODM_VGP0_SHIFT) +// VD10 +#define NVODM_CAMERA_VD10_RESET NVODM_CAMERA_RESET(NVODM_VD10_SHIFT) +#define NVODM_CAMERA_VD10_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VD10_SHIFT) +#define NVODM_CAMERA_VD10_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VD10_SHIFT) +#define NVODM_CAMERA_VD10_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VD10_SHIFT) +#define NVODM_CAMERA_VD10_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VD10_SHIFT) +#define NVODM_CAMERA_VD10_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VD10_SHIFT) +// VD11 +#define NVODM_CAMERA_VD11_RESET NVODM_CAMERA_RESET(NVODM_VD11_SHIFT) +#define NVODM_CAMERA_VD11_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VD11_SHIFT) +#define NVODM_CAMERA_VD11_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VD11_SHIFT) +#define NVODM_CAMERA_VD11_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VD11_SHIFT) +#define NVODM_CAMERA_VD11_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VD11_SHIFT) +#define NVODM_CAMERA_VD11_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VD11_SHIFT) +// VGP3 +#define NVODM_CAMERA_VGP3_RESET NVODM_CAMERA_RESET(NVODM_VGP3_SHIFT) +#define NVODM_CAMERA_VGP3_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP3_SHIFT) +#define NVODM_CAMERA_VGP3_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP3_SHIFT) +#define NVODM_CAMERA_VGP3_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP3_SHIFT) +#define NVODM_CAMERA_VGP3_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP3_SHIFT) +#define NVODM_CAMERA_VGP3_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP3_SHIFT) +// VGP4 +#define NVODM_CAMERA_VGP4_RESET NVODM_CAMERA_RESET(NVODM_VGP4_SHIFT) +#define NVODM_CAMERA_VGP4_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP4_SHIFT) +#define NVODM_CAMERA_VGP4_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP4_SHIFT) +#define NVODM_CAMERA_VGP4_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP4_SHIFT) +#define NVODM_CAMERA_VGP4_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP4_SHIFT) +#define NVODM_CAMERA_VGP4_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP4_SHIFT) +// VGP5 +#define NVODM_CAMERA_VGP5_RESET NVODM_CAMERA_RESET(NVODM_VGP5_SHIFT) +#define NVODM_CAMERA_VGP5_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP5_SHIFT) +#define NVODM_CAMERA_VGP5_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP5_SHIFT) +#define NVODM_CAMERA_VGP5_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP5_SHIFT) +#define NVODM_CAMERA_VGP5_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP5_SHIFT) +#define NVODM_CAMERA_VGP5_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP5_SHIFT) +// VGP6 +#define NVODM_CAMERA_VGP6_RESET NVODM_CAMERA_RESET(NVODM_VGP6_SHIFT) +#define NVODM_CAMERA_VGP6_RESET_AL NVODM_CAMERA_RESET_AL(NVODM_VGP6_SHIFT) +#define NVODM_CAMERA_VGP6_POWERDOWN NVODM_CAMERA_POWERDOWN(NVODM_VGP6_SHIFT) +#define NVODM_CAMERA_VGP6_POWERDOWN_AL NVODM_CAMERA_POWERDOWN_AL(NVODM_VGP6_SHIFT) +#define NVODM_CAMERA_VGP6_FLASH_LOW NVODM_CAMERA_FLASH_LOW(NVODM_VGP6_SHIFT) +#define NVODM_CAMERA_VGP6_FLASH_HIGH NVODM_CAMERA_FLASH_HIGH(NVODM_VGP6_SHIFT) +#define NVODM_CAMERA_VGP6_PWM NVODM_CAMERA_PWM(NVODM_VGP6_SHIFT) + +#endif diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c new file mode 100644 index 000000000000..d17f12b59559 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c @@ -0,0 +1,1490 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit: + * Implementation of the ODM Query API</b> + * + * @b Description: Implements the query functions for ODMs that may be + * accessed at boot-time, runtime, or anywhere in between. + */ + +#include "nvodm_query.h" +#include "nvodm_query_gpio.h" +#include "nvodm_query_memc.h" +#include "nvodm_query_discovery.h" +#include "nvodm_query_pins.h" +#include "nvodm_query_pins_ap20.h" +#include "tegra_devkit_custopt.h" +#include "nvodm_keylist_reserved.h" +#include "nvrm_drf.h" + +#define BOARD_ID_WHISTLER_E1108 0x0B08 +#define BOARD_ID_WHISTLER_E1109 0x0B09 +#define BOARD_ID_WHISTLER_PMU_E1116 0x0B10 +#define BOARD_ID_WHISTLER_MOTHERBOARD_E1120 0xB14 +#define BOARD_ID_VOYAGER_MAINBOARD_E1215 0xC0F +#define BOARD_REV_ALL ((NvU8)0xFF) + +#define NVODM_ENABLE_EMC_DVFS (1) + +// Function to auto-detect boards with external CPU power supply +NvBool NvOdmIsCpuExtSupply(void); + +static const NvU8 +s_NvOdmQueryDeviceNamePrefixValue[] = { 'T','e','g','r','a',0}; + +static const NvU8 +s_NvOdmQueryManufacturerSetting[] = {'N','V','I','D','I','A',0}; + +static const NvU8 +s_NvOdmQueryModelSetting[] = {'A','P','2','0',0}; + +static const NvU8 +s_NvOdmQueryPlatformSetting[] = {'W','h','i','s','t','l','e','r',0}; + +static const NvU8 +s_NvOdmQueryProjectNameSetting[] = {'O','D','M',' ','K','i','t',0}; + +static const NvOdmDownloadTransport +s_NvOdmQueryDownloadTransportSetting = NvOdmDownloadTransport_None; + +static NvOdmQuerySdioInterfaceProperty s_NvOdmQuerySdioInterfaceProperty_Whistler[4] = +{ + { NV_FALSE, 10, NV_FALSE, 0x6, NvOdmQuerySdioSlotUsage_unused }, + { NV_TRUE, 10, NV_TRUE, 0xF, NvOdmQuerySdioSlotUsage_wlan }, + { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Media }, + { NV_TRUE, 10, NV_TRUE, 0x6, NvOdmQuerySdioSlotUsage_Boot }, +}; + +static NvOdmQuerySdioInterfaceProperty s_NvOdmQuerySdioInterfaceProperty_Voyager[4] = +{ + { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_unused }, + { NV_TRUE, 10, NV_TRUE, 0x4, NvOdmQuerySdioSlotUsage_wlan }, + { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Media }, + { NV_FALSE, 10, NV_FALSE, 0x4, NvOdmQuerySdioSlotUsage_Boot }, +}; + +static const NvOdmQueryOwrDeviceInfo s_NvOdmQueryOwrInfo = { + NV_FALSE, + 0x1, /* Tsu */ + 0xF, /* TRelease */ + 0xF, /* TRdv */ + 0X3C, /* TLow0 */ + 0x1, /* TLow1 */ + 0x77, /* TSlot */ + + 0x78, /* TPdl */ + 0x1E, /* TPdh */ + 0x1DF, /* TRstl */ + 0x1DF, /* TRsth */ + + 0x1E0, /* Tpp */ + 0x5, /* Tfp */ + 0x5, /* Trp */ + 0x5, /* Tdv */ + 0x5, /* Tpd */ + + 0x7, /* Read data sample clk */ + 0x50, /* Presence sample clk */ + 2, /* Memory address size */ + 0x80 /* Memory size*/ +}; + +static const NvOdmSdramControllerConfigAdv s_NvOdmE1109EmcConfigTable[] = +{ + { + 0x20, /* Rev 2.0 */ + 166500, /* SDRAM frquency */ + 1000, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x0000000A, /* RC */ + 0x00000016, /* RFC */ + 0x00000008, /* RAS */ + 0x00000003, /* RP */ + 0x00000004, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000F, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000001, /* REXT */ + 0x00000005, /* WDV */ + 0x00000006, /* QUSE */ + 0x00000005, /* QRST */ + 0x00000009, /* QSAFE */ + 0x0000000E, /* RDV */ + 0x000004DF, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000004, /* PDEX2WR */ + 0x00000004, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000B, /* RW2PDEN */ + 0x000000C8, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000008, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x0000000B, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x00000000, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000002, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000083, /* FBIO_CFG5 */ + 0x00400006, /* CFG_DIG_DLL */ + 0x007FD010, /* DLL_XFORM_DQS */ + 0x00001010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000000, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 333000, /* SDRAM frquency */ + 1200, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000014, /* RC */ + 0x0000002B, /* RFC */ + 0x0000000F, /* RAS */ + 0x00000005, /* RP */ + 0x00000004, /* R2W */ + 0x00000005, /* W2R */ + 0x00000003, /* R2P */ + 0x0000000F, /* W2P */ + 0x00000005, /* RD_RCD */ + 0x00000005, /* WR_RCD */ + 0x00000004, /* RRD */ + 0x00000001, /* REXT */ + 0x00000005, /* WDV */ + 0x00000006, /* QUSE */ + 0x00000005, /* QRST */ + 0x00000009, /* QSAFE */ + 0x0000000E, /* RDV */ + 0x000009FF, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000004, /* PDEX2WR */ + 0x00000004, /* PDEX2RD */ + 0x00000005, /* PCHG2PDEN */ + 0x00000005, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x00000010, /* RW2PDEN */ + 0x000000C8, /* TXSR */ + 0x00000003, /* TCKE */ + 0x0000000F, /* TFAW */ + 0x00000006, /* TRPAB */ + 0x0000000B, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x00000000, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000002, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000083, /* FBIO_CFG5 */ + 0x002C0006, /* CFG_DIG_DLL */ + 0x007FD010, /* DLL_XFORM_DQS */ + 0x00001010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000000, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + } +}; + +static const NvOdmSdramControllerConfigAdv s_NvOdmE1108HynixEmcConfigTable[] = +{ + { + 0x20, /* Rev 2.0 */ + 18000, /* SDRAM frquency */ + 950, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000002, /* RC */ + 0x00000006, /* RFC */ + 0x00000003, /* RAS */ + 0x00000003, /* RP */ + 0x00000006, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000B, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000002, /* REXT */ + 0x00000003, /* WDV */ + 0x00000005, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000008, /* QSAFE */ + 0x0000000C, /* RDV */ + 0x00000070, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000B, /* RW2PDEN */ + 0x00000003, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000008, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x0000004B, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000003, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000082, /* FBIO_CFG5 */ + 0x00780006, /* CFG_DIG_DLL */ + 0x00000010, /* DLL_XFORM_DQS */ + 0x00000008, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000002, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 27000, /* SDRAM frquency */ + 950, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000002, /* RC */ + 0x00000006, /* RFC */ + 0x00000003, /* RAS */ + 0x00000003, /* RP */ + 0x00000006, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000B, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000002, /* REXT */ + 0x00000003, /* WDV */ + 0x00000005, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000008, /* QSAFE */ + 0x0000000C, /* RDV */ + 0x000000A8, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000B, /* RW2PDEN */ + 0x00000004, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000008, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x00000071, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000003, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000082, /* FBIO_CFG5 */ + 0x00780006, /* CFG_DIG_DLL */ + 0x00000010, /* DLL_XFORM_DQS */ + 0x00000008, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000003, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 54000, /* SDRAM frquency */ + 1000, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000004, /* RC */ + 0x00000008, /* RFC */ + 0x00000003, /* RAS */ + 0x00000003, /* RP */ + 0x00000006, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000B, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000002, /* REXT */ + 0x00000003, /* WDV */ + 0x00000006, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000008, /* QSAFE */ + 0x0000000C, /* RDV */ + 0x0000017F, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000B, /* RW2PDEN */ + 0x00000008, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000008, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x000000E1, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000000, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000082, /* FBIO_CFG5 */ + 0x00780006, /* CFG_DIG_DLL */ + 0x00000010, /* DLL_XFORM_DQS */ + 0x00000008, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x00000005, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 108000, /* SDRAM frquency */ + 1000, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000007, /* RC */ + 0x0000000F, /* RFC */ + 0x00000005, /* RAS */ + 0x00000003, /* RP */ + 0x00000006, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000B, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000002, /* REXT */ + 0x00000003, /* WDV */ + 0x00000006, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000008, /* QSAFE */ + 0x0000000C, /* RDV */ + 0x0000031F, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000B, /* RW2PDEN */ + 0x00000010, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000008, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x000001C2, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000000, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000082, /* FBIO_CFG5 */ + 0xD0780323, /* CFG_DIG_DLL */ + 0x007FD010, /* DLL_XFORM_DQS */ + 0x00000010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x0000000A, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 150000, /* SDRAM frquency */ + 1000, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000009, /* RC */ + 0x00000014, /* RFC */ + 0x00000007, /* RAS */ + 0x00000003, /* RP */ + 0x00000006, /* R2W */ + 0x00000004, /* W2R */ + 0x00000002, /* R2P */ + 0x0000000B, /* W2P */ + 0x00000003, /* RD_RCD */ + 0x00000003, /* WR_RCD */ + 0x00000002, /* RRD */ + 0x00000002, /* REXT */ + 0x00000003, /* WDV */ + 0x00000006, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000008, /* QSAFE */ + 0x0000000C, /* RDV */ + 0x0000045F, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000003, /* PDEX2WR */ + 0x00000003, /* PDEX2RD */ + 0x00000003, /* PCHG2PDEN */ + 0x00000003, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000B, /* RW2PDEN */ + 0x00000015, /* TXSR */ + 0x00000003, /* TCKE */ + 0x00000008, /* TFAW */ + 0x00000004, /* TRPAB */ + 0x00000008, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x00000270, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000001, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000082, /* FBIO_CFG5 */ + 0xD05E0323, /* CFG_DIG_DLL */ + 0x007FD010, /* DLL_XFORM_DQS */ + 0x00000010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x0000000E, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + }, + { + 0x20, /* Rev 2.0 */ + 300000, /* SDRAM frquency */ + 1100, /* EMC core voltage */ + 46, /* Number of EMC parameters below */ + { + 0x00000012, /* RC */ + 0x00000027, /* RFC */ + 0x0000000D, /* RAS */ + 0x00000006, /* RP */ + 0x00000007, /* R2W */ + 0x00000005, /* W2R */ + 0x00000003, /* R2P */ + 0x0000000B, /* W2P */ + 0x00000006, /* RD_RCD */ + 0x00000006, /* WR_RCD */ + 0x00000003, /* RRD */ + 0x00000003, /* REXT */ + 0x00000003, /* WDV */ + 0x00000006, /* QUSE */ + 0x00000004, /* QRST */ + 0x00000009, /* QSAFE */ + 0x0000000D, /* RDV */ + 0x000008FF, /* REFRESH */ + 0x00000000, /* BURST_REFRESH_NUM */ + 0x00000004, /* PDEX2WR */ + 0x00000004, /* PDEX2RD */ + 0x00000006, /* PCHG2PDEN */ + 0x00000006, /* ACT2PDEN */ + 0x00000001, /* AR2PDEN */ + 0x0000000F, /* RW2PDEN */ + 0x0000002A, /* TXSR */ + 0x00000003, /* TCKE */ + 0x0000000F, /* TFAW */ + 0x00000007, /* TRPAB */ + 0x00000007, /* TCLKSTABLE */ + 0x00000002, /* TCLKSTOP */ + 0x000004E0, /* TREFBW */ + 0x00000000, /* QUSE_EXTRA */ + 0x00000002, /* FBIO_CFG6 */ + 0x00000000, /* ODT_WRITE */ + 0x00000000, /* ODT_READ */ + 0x00000282, /* FBIO_CFG5 */ + 0xE03A0303, /* CFG_DIG_DLL */ + 0x007FD010, /* DLL_XFORM_DQS */ + 0x00000010, /* DLL_XFORM_QUSE */ + 0x00000000, /* ZCAL_REF_CNT */ + 0x0000001B, /* ZCAL_WAIT_CNT */ + 0x00000000, /* AUTO_CAL_INTERVAL */ + 0x00000000, /* CFG_CLKTRIM_0 */ + 0x00000000, /* CFG_CLKTRIM_1 */ + 0x00000000, /* CFG_CLKTRIM_2 */ + } + } +}; + + +// Wake Events +static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] = +{ + {NV_FALSE, 0, NvOdmWakeupPadPolarity_Low}, // Wake Event 0 - ulpi_data4 (UART_RI) + {NV_FALSE, 1, NvOdmWakeupPadPolarity_High}, // Wake Event 1 - gp3_pv[3] (BB_MOD, MODEM_RESET_OUT) + {NV_FALSE, 2, NvOdmWakeupPadPolarity_High}, // Wake Event 2 - dvi_d3 + {NV_FALSE, 3, NvOdmWakeupPadPolarity_Low}, // Wake Event 3 - sdio3_dat1 + {NV_FALSE, 4, NvOdmWakeupPadPolarity_High}, // Wake Event 4 - hdmi_int (HDMI_HPD) + {NV_FALSE, 5, NvOdmWakeupPadPolarity_High}, // Wake Event 5 - vgp[6] (VI_GP6, Flash_EN2) + {NV_FALSE, 6, NvOdmWakeupPadPolarity_High}, // Wake Event 6 - gp3_pu[5] (GPS_ON_OFF, GPS_IRQ) + {NV_FALSE, 7, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 7 - gp3_pu[6] (GPS_INT, BT_IRQ) + {NV_FALSE, 8, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 8 - gmi_wp_n (MICRO SD_CD) + {NV_FALSE, 9, NvOdmWakeupPadPolarity_High}, // Wake Event 9 - gp3_ps[2] (KB_COL10) + {NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP) + {NV_FALSE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ) + {NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used) + {NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1 + {NV_FALSE, 14, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 14 - gp3_pv[6] (WLAN_INT) + {NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1) + {NV_FALSE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq + {NV_TRUE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt + {NV_FALSE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT) + {NV_FALSE, 19, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 19 - usb_vbus_wakeup[0] + {NV_FALSE, 20, NvOdmWakeupPadPolarity_High}, // Wake Event 20 - usb_vbus_wakeup[1] + {NV_FALSE, 21, NvOdmWakeupPadPolarity_Low}, // Wake Event 21 - usb_iddig[0] + {NV_FALSE, 22, NvOdmWakeupPadPolarity_Low}, // Wake Event 22 - usb_iddig[1] + {NV_FALSE, 23, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 23 - gmi_iordy (HSMMC_CLK) + {NV_FALSE, 24, NvOdmWakeupPadPolarity_High}, // Wake Event 24 - gp3_pv[2] (BB_MOD, MODEM WAKEUP_AP15, SPI-SS) + {NV_FALSE, 25, NvOdmWakeupPadPolarity_High}, // Wake Event 25 - gp3_ps[4] (KB_COL12) + {NV_FALSE, 26, NvOdmWakeupPadPolarity_High}, // Wake Event 26 - gp3_ps[5] (KB_COL10) + {NV_FALSE, 27, NvOdmWakeupPadPolarity_High}, // Wake Event 27 - gp3_ps[0] (KB_COL8) + {NV_FALSE, 28, NvOdmWakeupPadPolarity_Low}, // Wake Event 28 - gp3_pq[6] (KB_ROW6) + {NV_FALSE, 29, NvOdmWakeupPadPolarity_Low}, // Wake Event 29 - gp3_pq[7] (KB_ROW6) + {NV_FALSE, 30, NvOdmWakeupPadPolarity_High} // Wake Event 30 - dap1_dout (DAP1_DOUT) +}; + +/* --- Function Implementations ---*/ + +static NvBool +NvOdmIsBoardPresent( + const NvOdmBoardInfo* pBoardList, + NvU32 ListSize) +{ + NvU32 i; + NvOdmBoardInfo BoardInfo; + + // Scan for presence of any board in the list + // ID/SKU/FAB fields must match, revision may be masked + if (pBoardList) + { + for (i=0; i < ListSize; i++) + { + if (NvOdmPeripheralGetBoardInfo( + pBoardList[i].BoardID, &BoardInfo)) + { + if ((pBoardList[i].Fab == BoardInfo.Fab) && + (pBoardList[i].SKU == BoardInfo.SKU) && + ((pBoardList[i].Revision == BOARD_REV_ALL) || + (pBoardList[i].Revision == BoardInfo.Revision)) && + ((pBoardList[i].MinorRevision == BOARD_REV_ALL) || + (pBoardList[i].MinorRevision == BoardInfo.MinorRevision))) + { + return NV_TRUE; // Board found + } + } + } + } + return NV_FALSE; +} + +#if NVODM_ENABLE_EMC_DVFS +static NvBool NvOdmIsE1108Hynix(void) +{ + // A list of Whistler E1108 processor boards with Hynix LPDDR2 + // charcterized by s_NvOdmE1108HynixEmcConfigTable (fill in + // ID/SKU/FAB fields, revision fields are ignored) + static const NvOdmBoardInfo s_WhistlerE1108Hynix[] = + { + // ID SKU FAB Rev Minor Rev + { BOARD_ID_WHISTLER_E1108, 0x0A14, 0x01, BOARD_REV_ALL, BOARD_REV_ALL}, + { BOARD_ID_WHISTLER_E1108, 0x0A1E, 0x01, BOARD_REV_ALL, BOARD_REV_ALL}, + { BOARD_ID_WHISTLER_E1108, 0x0A00, 0x02, BOARD_REV_ALL, BOARD_REV_ALL}, + { BOARD_ID_WHISTLER_E1108, 0x0A0A, 0x02, BOARD_REV_ALL, BOARD_REV_ALL} + }; + return NvOdmIsBoardPresent(s_WhistlerE1108Hynix, + NV_ARRAY_SIZE(s_WhistlerE1108Hynix)); +} +#endif + +static NvBool NvOdmIsCpuRailPreserved(void) +{ + // A list of Whistler PMU boards that preserves CPU voltage across LP2/LP1 + static const NvOdmBoardInfo s_WhistlerCpuPreservedBoards[] = + { + // ID SKU FAB Rev Minor Rev + { BOARD_ID_WHISTLER_PMU_E1116, 0x0A0A, 0x01, BOARD_REV_ALL, BOARD_REV_ALL}, + }; + return NvOdmIsBoardPresent(s_WhistlerCpuPreservedBoards, + NV_ARRAY_SIZE(s_WhistlerCpuPreservedBoards)); +} + +NvBool NvOdmIsCpuExtSupply(void) +{ + // A list of Whistler processor boards that use external DCDC as CPU + // power supply (fill in ID/SKU/FAB fields, revision fields are ignored) + static const NvOdmBoardInfo s_WhistlerCpuExtSupplyBoards[] = + { + // ID SKU FAB Rev Minor Rev + { BOARD_ID_WHISTLER_E1108, 0x0A14, 0x01, BOARD_REV_ALL, BOARD_REV_ALL}, + { BOARD_ID_WHISTLER_E1108, 0x0A00, 0x02, BOARD_REV_ALL, BOARD_REV_ALL} + }; + return NvOdmIsBoardPresent(s_WhistlerCpuExtSupplyBoards, + NV_ARRAY_SIZE(s_WhistlerCpuExtSupplyBoards)); +} + +static NvU32 +GetBctKeyValue(void) +{ + NvOdmServicesKeyListHandle hKeyList = NULL; + NvU32 BctCustOpt = 0; + + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + BctCustOpt = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + } + + return BctCustOpt; +} + +NvOdmDebugConsole +NvOdmQueryDebugConsole(void) +{ + NvU32 CustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC: + return NvOdmDebugConsole_Dcc; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE: + return NvOdmDebugConsole_None; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART: + return NvOdmDebugConsole_UartA + + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, CONSOLE_OPTION, CustOpt); + default: + return NvOdmDebugConsole_None; + } +} + +NvOdmDownloadTransport +NvOdmQueryDownloadTransport(void) +{ + NvU32 CustOpt = GetBctKeyValue(); + + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, TRANSPORT, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE: + return NvOdmDownloadTransport_None; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB: + return NvOdmDownloadTransport_Usb; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET: + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, ETHERNET_OPTION, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT: + default: + return NvOdmDownloadTransport_SpiEthernet; + } + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART: + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, UART_OPTION, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B: + return NvOdmDownloadTransport_UartB; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C: + return NvOdmDownloadTransport_UartC; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A: + default: + return NvOdmDownloadTransport_UartA; + } + case TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT: + default: + return s_NvOdmQueryDownloadTransportSetting; + } +} + +const NvU8* +NvOdmQueryDeviceNamePrefix(void) +{ + return s_NvOdmQueryDeviceNamePrefixValue; +} + +static const NvOdmQuerySpdifInterfaceProperty s_NvOdmQuerySpdifInterfacePropertySetting = +{ + NvOdmQuerySpdifDataCaptureControl_FromLeft +}; + +const NvOdmQuerySpiDeviceInfo * + +NvOdmQuerySpiGetDeviceInfo( + NvOdmIoModule OdmIoModule, + NvU32 ControllerId, + NvU32 ChipSelect) +{ + static const NvOdmQuerySpiDeviceInfo s_Spi1Cs0Info_EmpRil = + {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_TRUE}; + + static const NvOdmQuerySpiDeviceInfo s_Spi1Cs0Info_IfxRil = + {NvOdmQuerySpiSignalMode_1, NV_TRUE, NV_FALSE}; + + static const NvOdmQuerySpiDeviceInfo s_Spi1Cs0Info = + {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_FALSE}; + + static const NvOdmQuerySpiDeviceInfo s_Spi2Cs1Info = + {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_FALSE}; + + static const NvOdmQuerySpiDeviceInfo s_Spi3Cs1Info = + {NvOdmQuerySpiSignalMode_0, NV_TRUE, NV_FALSE}; + + NvU32 CustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW: + if ((OdmIoModule == NvOdmIoModule_Spi) && + (ControllerId == 0 ) && (ChipSelect == 0)) + return &s_Spi1Cs0Info_EmpRil; + break; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX: + if ((OdmIoModule == NvOdmIoModule_Spi) && + (ControllerId == 0 ) && (ChipSelect == 0)) + return &s_Spi1Cs0Info_IfxRil; + break; + } + + if ((OdmIoModule == NvOdmIoModule_Spi) && + (ControllerId == 1 || ControllerId == 0) && (ChipSelect == 0)) + return &s_Spi1Cs0Info; + + if ((OdmIoModule == NvOdmIoModule_Spi) && + (ControllerId == 1 ) && ((ChipSelect == 1)|| (ChipSelect == 3))) + return &s_Spi2Cs1Info; + + if ((OdmIoModule == NvOdmIoModule_Spi) && + (ControllerId == 2 ) && (ChipSelect == 1)) + return &s_Spi3Cs1Info; + + if ((OdmIoModule == NvOdmIoModule_Spi) && + (ControllerId == 2 ) && (ChipSelect == 2)) + return &s_Spi3Cs1Info; + + return NULL; +} + + +const NvOdmQuerySpiIdleSignalState * +NvOdmQuerySpiGetIdleSignalState( + NvOdmIoModule OdmIoModule, + NvU32 ControllerId) +{ + return NULL; +} + +const NvOdmQueryI2sInterfaceProperty * +NvOdmQueryI2sGetInterfaceProperty( + NvU32 I2sInstanceId) +{ + static const NvOdmQueryI2sInterfaceProperty s_Property = + { + NvOdmQueryI2sMode_Slave, + NvOdmQueryI2sLRLineControl_LeftOnLow, + NvOdmQueryI2sDataCommFormat_I2S, + NV_FALSE, + 0 + }; + + if ((!I2sInstanceId) || (I2sInstanceId == 1)) + return &s_Property; + + return NULL; +} + +const NvOdmQueryDapPortProperty * +NvOdmQueryDapPortGetProperty( + NvU32 DapPortId) +{ + static const NvOdmQueryDapPortProperty s_Property[] = + { + { NvOdmDapPort_None, NvOdmDapPort_None, { 0, 0, 0, 0 } }, + // I2S1 (DAC1) <-> DAP1 <-> HIFICODEC + { NvOdmDapPort_I2s1, NvOdmDapPort_HifiCodecType, + { 2, 16, 44100, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap1 + // I2S2 (DAC2) <-> DAP2 <-> VOICECODEC + {NvOdmDapPort_I2s2, NvOdmDapPort_VoiceCodecType, + {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap2 + }; + static const NvOdmQueryDapPortProperty s_Property_Ril_Emp_Rainbow[] = + { + { NvOdmDapPort_None, NvOdmDapPort_None, { 0, 0, 0, 0 } }, + // I2S1 (DAC1) <-> DAP1 <-> HIFICODEC + { NvOdmDapPort_I2s1, NvOdmDapPort_HifiCodecType, + { 2, 16, 44100, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap1 + // I2S2 (DAC2) <-> DAP2 <-> VOICECODEC + {NvOdmDapPort_I2s2, NvOdmDapPort_VoiceCodecType, + {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap2 + // I2S2 (DAC2) <-> DAP3 <-> BASEBAND + {NvOdmDapPort_I2s2, NvOdmDapPort_BaseBand, + {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap3 + // I2S2 (DAC2) <-> DAP4 <-> BLUETOOTH + {NvOdmDapPort_I2s2, NvOdmDapPort_BlueTooth, + {2, 16, 8000, NvOdmQueryI2sDataCommFormat_I2S } }, // Dap4 + }; + NvU32 CustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX: + if (DapPortId && DapPortId<NV_ARRAY_SIZE(s_Property_Ril_Emp_Rainbow)) + return &s_Property_Ril_Emp_Rainbow[DapPortId]; + break; + default: + if (DapPortId && DapPortId<NV_ARRAY_SIZE(s_Property)) + return &s_Property[DapPortId]; + break; + } + return NULL; +} + +const NvOdmQueryDapPortConnection* +NvOdmQueryDapPortGetConnectionTable( + NvU32 ConnectionIndex) +{ + static const NvOdmQueryDapPortConnection s_Property[] = + { + { NvOdmDapConnectionIndex_Music_Path, + 2, { {NvOdmDapPort_I2s1, NvOdmDapPort_Dap1, NV_FALSE}, + {NvOdmDapPort_Dap1, NvOdmDapPort_I2s1, NV_TRUE} } }, + }; + static const NvOdmQueryDapPortConnection s_Property_Ril_Emp_Rainbow[] = + { + { NvOdmDapConnectionIndex_Music_Path, + 2, { {NvOdmDapPort_I2s1, NvOdmDapPort_Dap1, NV_FALSE}, + {NvOdmDapPort_Dap1, NvOdmDapPort_I2s1, NV_TRUE} } }, + + // Voicecall without Bluetooth + { NvOdmDapConnectionIndex_VoiceCall_NoBlueTooth, + 3, { {NvOdmDapPort_Dap3, NvOdmDapPort_Dap2, NV_FALSE}, + {NvOdmDapPort_Dap2, NvOdmDapPort_Dap3, NV_TRUE}, + {NvOdmDapPort_Dap2, NvOdmDapPort_I2s2, NV_TRUE} } }, + + // Voicecall with Bluetooth + { NvOdmDapConnectionIndex_VoiceCall_WithBlueTooth, + 2, { {NvOdmDapPort_Dap4, NvOdmDapPort_Dap3, NV_TRUE}, + {NvOdmDapPort_Dap3, NvOdmDapPort_Dap4, NV_FALSE} + }}, + + }; + NvU32 TableIndex = 0; + NvU32 CustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW: + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX: + { + for( TableIndex = 0; + TableIndex < NV_ARRAY_SIZE(s_Property_Ril_Emp_Rainbow); TableIndex++) + { + if (s_Property_Ril_Emp_Rainbow[TableIndex].UseIndex == ConnectionIndex) + return &s_Property_Ril_Emp_Rainbow[TableIndex]; + } + } + break; + default: + { + for( TableIndex = 0; TableIndex < NV_ARRAY_SIZE(s_Property); TableIndex++) + { + if (s_Property[TableIndex].UseIndex == ConnectionIndex) + return &s_Property[TableIndex]; + } + } + break; + } + return NULL; +} + +const NvOdmQuerySpdifInterfaceProperty * +NvOdmQuerySpdifGetInterfaceProperty( + NvU32 SpdifInstanceId) +{ + if (SpdifInstanceId == 0) + return &s_NvOdmQuerySpdifInterfacePropertySetting; + + return NULL; +} + +const NvOdmQueryAc97InterfaceProperty * +NvOdmQueryAc97GetInterfaceProperty( + NvU32 Ac97InstanceId) +{ + return NULL; +} + +const NvOdmQueryI2sACodecInterfaceProp * +NvOdmQueryGetI2sACodecInterfaceProperty( + NvU32 AudioCodecId) +{ + static const NvOdmQueryI2sACodecInterfaceProp s_Property = + { + NV_TRUE, + 0, + 0x34, + NV_FALSE, + NvOdmQueryI2sLRLineControl_LeftOnLow, + NvOdmQueryI2sDataCommFormat_I2S + }; + if (!AudioCodecId) + return &s_Property; + return NULL; +} + +NvBool NvOdmQueryAsynchMemConfig( + NvU32 ChipSelect, + NvOdmAsynchMemConfig *pMemConfig) +{ + return NV_FALSE; +} + +const void* +NvOdmQuerySdramControllerConfigGet(NvU32 *pEntries, NvU32 *pRevision) +{ +#if NVODM_ENABLE_EMC_DVFS + NvOdmBoardInfo BoardInfo; + + if (NvOdmPeripheralGetBoardInfo(BOARD_ID_WHISTLER_E1109, &BoardInfo)) + { + if (pRevision) + *pRevision = s_NvOdmE1109EmcConfigTable[0].Revision; + if (pEntries) + *pEntries = NV_ARRAY_SIZE(s_NvOdmE1109EmcConfigTable); + return (const void*)s_NvOdmE1109EmcConfigTable; + } + else if (NvOdmIsE1108Hynix()) + { + if (pRevision) + *pRevision = s_NvOdmE1108HynixEmcConfigTable[0].Revision; + if (pEntries) + *pEntries = NV_ARRAY_SIZE(s_NvOdmE1108HynixEmcConfigTable); + return (const void*)s_NvOdmE1108HynixEmcConfigTable; + } +#endif + if (pEntries) + *pEntries = 0; + return NULL; +} + +NvOdmQueryOscillator NvOdmQueryGetOscillatorSource(void) +{ + return NvOdmQueryOscillator_Xtal; +} + +NvU32 NvOdmQueryGetOscillatorDriveStrength(void) +{ + return 0x04; +} + +const NvOdmWakeupPadInfo *NvOdmQueryGetWakeupPadTable(NvU32 *pSize) +{ + NvU32 CustOpt; + if (pSize) + *pSize = NV_ARRAY_SIZE(s_NvOdmWakeupPadInfo); + + CustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt)) + { + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW: + s_NvOdmWakeupPadInfo[24].enable = NV_TRUE; + break; + case TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX: + s_NvOdmWakeupPadInfo[13].enable = NV_TRUE; + break; + default: + break; + } + + return (const NvOdmWakeupPadInfo *) s_NvOdmWakeupPadInfo; +} + + +const NvU8* NvOdmQueryManufacturer(void) +{ + return s_NvOdmQueryManufacturerSetting; +} + +const NvU8* NvOdmQueryModel(void) +{ + return s_NvOdmQueryModelSetting; +} + +const NvU8* NvOdmQueryPlatform(void) +{ + return s_NvOdmQueryPlatformSetting; +} + +const NvU8* NvOdmQueryProjectName(void) +{ + return s_NvOdmQueryProjectNameSetting; +} + + +#define EXT 0 // external pull-up/down resistor +#define INT_PU 1 // internal pull-up +#define INT_PD 2 // internal pull-down + +#define HIGHSPEED 1 +#define SCHMITT 1 +#define VREF 1 +#define OHM_50 3 +#define OHM_100 2 +#define OHM_200 1 +#define OHM_400 0 + + // Pin attributes + static const NvOdmPinAttrib s_pin_config_attributes[] = { + + { NvOdmPinRegister_Ap20_PullUpDown_A, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_A(0x2, 0x2, 0x2, 0x0, 0x0, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x0, 0x1, 0x0) }, + // Pull ups for the kbc pins + { NvOdmPinRegister_Ap20_PullUpDown_B, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_B(0x0, 0x0, 0x2, 0x0, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0) }, + + { NvOdmPinRegister_Ap20_PullUpDown_C, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_C(0x1, 0x1, 0x1, 0x1, 0x2, 0x1, 0x2, 0x1, 0x2, 0x2, 0x2, 0x2, 0x2, 0x0, 0x0) }, + + // Pull ups for the kbc pins + { NvOdmPinRegister_Ap20_PullUpDown_E, + NVODM_QUERY_PIN_AP20_PULLUPDOWN_E(0x2, 0x2, 0x0, 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x0, 0x0, 0x2, 0x2, 0x2, 0x2, 0x2) }, + + // Set pad control for the sdio2 - - AOCFG1 and AOCFG2 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_AOCFG1PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_AOCFG2PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for the sdio1 - SDIO1 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_SDIO1CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for the sdio3 - SDIO2 and SDIO3 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_SDIO2CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_SDIO3CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for the sdio4- ATCCFG1 and ATCCFG2 pad control register + { NvOdmPinRegister_Ap20_PadCtrl_ATCFG1PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_ATCFG2PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for I2C1 pins + { NvOdmPinRegister_Ap20_PadCtrl_DBGCFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_VICFG1PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + { NvOdmPinRegister_Ap20_PadCtrl_VICFG2PADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for I2C2 (DDC) pins + { NvOdmPinRegister_Ap20_PadCtrl_DDCCFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_50, 31, 31, 3, 3) }, + + // Set pad control for Dap pins 1 - 4 + { NvOdmPinRegister_Ap20_PadCtrl_DAP1CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) }, + + { NvOdmPinRegister_Ap20_PadCtrl_DAP2CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) }, + + { NvOdmPinRegister_Ap20_PadCtrl_DAP3CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) }, + + { NvOdmPinRegister_Ap20_PadCtrl_DAP3CFGPADCTRL, + NVODM_QUERY_PIN_AP20_PADCTRL_AOCFG1PADCTRL(!HIGHSPEED, SCHMITT, OHM_400, 0, 0, 0, 0) }, + }; + + +NvU32 +NvOdmQueryPinAttributes(const NvOdmPinAttrib** pPinAttributes) +{ + *pPinAttributes = &s_pin_config_attributes[0]; + return NV_ARRAY_SIZE(s_pin_config_attributes); +} + +NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty) +{ +#ifdef CONFIG_TEGRA_USB_VBUS_DETECT_BY_PMU + pPmuProperty->IrqConnected = NV_TRUE; +#else + pPmuProperty->IrqConnected = NV_FALSE; +#endif + pPmuProperty->PowerGoodCount = 0x7E; + pPmuProperty->IrqPolarity = NvOdmInterruptPolarity_Low; + + // Not there yet, add it later ... + //pPmuProperty->CpuPowerReqPolarity = ; + + pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_High; + pPmuProperty->SysClockReqPolarity = NvOdmSysClockReqPolarity_High; + pPmuProperty->CombinedPowerReq = NV_TRUE; + pPmuProperty->CpuPowerGoodUs = 2000; + pPmuProperty->AccuracyPercent = 3; + + if (NvOdmIsCpuExtSupply() || + NvOdmIsCpuRailPreserved()) + pPmuProperty->VCpuOTPOnWakeup = NV_FALSE; + else + pPmuProperty->VCpuOTPOnWakeup = NV_TRUE; + + return NV_TRUE; +} + +/** + * Gets the lowest soc power state supported by the hardware + * + * @returns information about the SocPowerState + */ +const NvOdmSocPowerStateInfo* NvOdmQueryLowestSocPowerState(void) +{ + + static NvOdmSocPowerStateInfo PowerStateInfo; + const static NvOdmSocPowerStateInfo* pPowerStateInfo = NULL; + NvOdmServicesKeyListHandle hKeyList; + NvU32 LPStateSelection = 0; + if (pPowerStateInfo == NULL) + { + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + LPStateSelection = NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + LPStateSelection = NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, LPSTATE, LPStateSelection); + } + // Lowest power state controlled by the flashed custom option. + PowerStateInfo.LowestPowerState = ((LPStateSelection != TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1)? + NvOdmSocPowerState_Suspend : NvOdmSocPowerState_DeepSleep); + pPowerStateInfo = (const NvOdmSocPowerStateInfo*) &PowerStateInfo; + } + return (pPowerStateInfo); +} + +const NvOdmUsbProperty* +NvOdmQueryGetUsbProperty(NvOdmIoModule OdmIoModule, + NvU32 Instance) +{ +#ifdef CONFIG_TEGRA_USB_VBUS_DETECT_BY_PMU +#define NVODM_USE_INTERNAL_PHY_VBUS_DETECTION NV_FALSE +#else +#define NVODM_USE_INTERNAL_PHY_VBUS_DETECTION NV_TRUE +#endif + static const NvOdmUsbProperty Usb1Property = + { + NvOdmUsbInterfaceType_Utmi, + (NvOdmUsbChargerType_SE0 | NvOdmUsbChargerType_SE1 | NvOdmUsbChargerType_SK), + 20, + NVODM_USE_INTERNAL_PHY_VBUS_DETECTION, +#ifdef CONFIG_USB_TEGRA_OTG + NvOdmUsbModeType_OTG, +#else + NvOdmUsbModeType_Device, +#endif + NvOdmUsbIdPinType_CableId, + NvOdmUsbConnectorsMuxType_None, + NV_FALSE + }; + + static const NvOdmUsbProperty Usb2Property = + { + NvOdmUsbInterfaceType_UlpiExternalPhy, + NvOdmUsbChargerType_UsbHost, + 20, + NVODM_USE_INTERNAL_PHY_VBUS_DETECTION, + NvOdmUsbModeType_None, + NvOdmUsbIdPinType_None, + NvOdmUsbConnectorsMuxType_None, + NV_FALSE + }; + + static const NvOdmUsbProperty Usb2NullPhyProperty = + { + NvOdmUsbInterfaceType_UlpiNullPhy, + NvOdmUsbChargerType_UsbHost, + 20, + NVODM_USE_INTERNAL_PHY_VBUS_DETECTION, + NvOdmUsbModeType_Host, + NvOdmUsbIdPinType_None, + NvOdmUsbConnectorsMuxType_None, + NV_FALSE, + {10, 1, 1, 1} + }; + + static const NvOdmUsbProperty Usb3Property = + { + NvOdmUsbInterfaceType_Utmi, + NvOdmUsbChargerType_UsbHost, + 20, + NVODM_USE_INTERNAL_PHY_VBUS_DETECTION, + NvOdmUsbModeType_Host, + NvOdmUsbIdPinType_CableId, + NvOdmUsbConnectorsMuxType_None, + NV_FALSE + }; + + /* E1108 has no ID pin for USB3, so disable USB3 Host */ + static const NvOdmUsbProperty Usb3Property_E1108 = + { + NvOdmUsbInterfaceType_Utmi, + NvOdmUsbChargerType_UsbHost, + 20, + NVODM_USE_INTERNAL_PHY_VBUS_DETECTION, + NvOdmUsbModeType_None, + NvOdmUsbIdPinType_None, + NvOdmUsbConnectorsMuxType_None, + NV_FALSE + }; + + if (OdmIoModule == NvOdmIoModule_Usb && Instance == 0) + return &(Usb1Property); + + if (OdmIoModule == NvOdmIoModule_Usb && Instance == 1) + { + NvU32 CustOpt = GetBctKeyValue(); + + if (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt) == + TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI) + return &(Usb2NullPhyProperty); + else + return &(Usb2Property); + } + + if (OdmIoModule == NvOdmIoModule_Usb && Instance == 2) + { + NvOdmBoardInfo BoardInfo; + if (NvOdmPeripheralGetBoardInfo(BOARD_ID_WHISTLER_E1108, &BoardInfo)) + { + return &(Usb3Property_E1108); + } + else + { + return &(Usb3Property); + } + } + + return (const NvOdmUsbProperty *)NULL; +} + +const NvOdmQuerySdioInterfaceProperty* NvOdmQueryGetSdioInterfaceProperty(NvU32 Instance) +{ + NvU32 CustomerOption = 0; + NvU32 Personality = 0; + NvOdmServicesKeyListHandle hKeyList; + static NvBool s_IsVoyagerBoard = NV_FALSE; + NvOdmBoardInfo BoardInfo; + static NvBool s_IsBoardInfoDone = NV_FALSE; + + // Detect whether the board is voyager or not + if (!s_IsBoardInfoDone) + { + s_IsVoyagerBoard = NvOdmPeripheralGetBoardInfo( + BOARD_ID_VOYAGER_MAINBOARD_E1215, &BoardInfo); + s_IsBoardInfoDone = NV_TRUE; + } + + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + CustomerOption = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + Personality = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustomerOption); + } + + if (!Personality) + Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY; + + if (s_IsVoyagerBoard) + return &s_NvOdmQuerySdioInterfaceProperty_Voyager[Instance]; + + if (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 || + Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15 || + Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05 || + Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C3) + s_NvOdmQuerySdioInterfaceProperty_Whistler[2].IsCardRemovable = NV_TRUE; + + return &s_NvOdmQuerySdioInterfaceProperty_Whistler[Instance]; +} + +const NvOdmQueryHsmmcInterfaceProperty* NvOdmQueryGetHsmmcInterfaceProperty(NvU32 Instance) +{ + return NULL; +} + +NvU32 +NvOdmQueryGetBlockDeviceSectorSize(NvOdmIoModule OdmIoModule) +{ + return 0; +} + +const NvOdmQueryOwrDeviceInfo* NvOdmQueryGetOwrDeviceInfo(NvU32 Instance) +{ + return &s_NvOdmQueryOwrInfo; +} + +const NvOdmGpioWakeupSource *NvOdmQueryGetWakeupSources(NvU32 *pCount) +{ + *pCount = 0; + return NULL; +} + +/** + * This function is called from early boot process. + * Therefore, it cannot use global variables. + */ +NvU32 NvOdmQueryMemSize(NvOdmMemoryType MemType) +{ + NvOdmOsOsInfo Info; + NvU32 SdramSize; + NvU32 SdramBctCustOpt; + + switch (MemType) + { + // NOTE: + // For Windows CE/WM operating systems the total size of SDRAM may + // need to be reduced due to limitations in the virtual address map. + // Under the legacy physical memory manager, Windows OSs have a + // maximum 512MB statically mapped virtual address space. Under the + // new physical memory manager, Windows OSs have a maximum 1GB + // statically mapped virtual address space. Out of that virtual + // address space, the upper 32 or 36 MB (depending upon the SOC) + // of the virtual address space is reserved for SOC register + // apertures. + // + // Refer to virtual_tables_apxx.arm for the reserved aperture list. + // If the cumulative size of the reserved apertures changes, the + // maximum size of SDRAM will also change. + case NvOdmMemoryType_Sdram: + { + SdramBctCustOpt = GetBctKeyValue(); + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_SYSTEM, MEMORY, SdramBctCustOpt)) + { + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1: + SdramSize = 0x10000000; //256 MB + break; + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_3: + SdramSize = 0x40000000; //1GB + break; + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_2: + case TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT: + default: + SdramSize = 0x20000000; //512 MB + break; + } + + if ( NvOdmOsGetOsInformation(&Info) && + ((Info.OsType!=NvOdmOsOs_Windows) || + (Info.OsType==NvOdmOsOs_Windows && Info.MajorVersion>=7)) ) + return SdramSize; + + // Legacy Physical Memory Manager: SdramSize MB - Carveout MB + return (SdramSize - NvOdmQueryCarveoutSize()); + } + + case NvOdmMemoryType_Nor: + return 0x00400000; // 4 MB + + case NvOdmMemoryType_Nand: + case NvOdmMemoryType_I2CEeprom: + case NvOdmMemoryType_Hsmmc: + case NvOdmMemoryType_Mio: + default: + return 0; + } +} + +NvU32 NvOdmQueryCarveoutSize(void) +{ + NvU32 CarveBctCustOpt = GetBctKeyValue(); + + switch (NV_DRF_VAL(TEGRA_DEVKIT, BCT_CARVEOUT, MEMORY, CarveBctCustOpt)) + { + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_1: + return 0x00400000;// 4MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_2: + return 0x00800000;// 8MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_3: + return 0x00C00000;// 12MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_4: + return 0x01000000;// 16MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_5: + return 0x01400000;// 20MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_6: + return 0x01800000;// 24MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_7: + return 0x01C00000;// 28MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_8: + return 0x02000000; // 32 MB + case TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_DEFAULT: + default: + return 0x04000000; // 64 MB + } +} + +NvU32 NvOdmQuerySecureRegionSize(void) +{ + return 0x00800000;// 8 MB +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c new file mode 100644 index 000000000000..9cf5ddf199a2 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_discovery.c @@ -0,0 +1,997 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: The peripheral connectivity database implementation. + */ + +#include "nvcommon.h" +#include "nvodm_query_gpio.h" +#include "nvodm_modules.h" +#include "nvodm_query_discovery.h" +#include "nvodm_keylist_reserved.h" +#include "tegra_devkit_custopt.h" +#include "nvodm_query.h" +#include "nvrm_drf.h" + +#include "subboards/nvodm_query_discovery_e888_addresses.h" +#include "subboards/nvodm_query_discovery_e906_addresses.h" +#include "subboards/nvodm_query_discovery_e911_addresses.h" +#include "subboards/nvodm_query_discovery_e936_addresses.h" +#include "subboards/nvodm_query_discovery_e951_addresses.h" +#include "subboards/nvodm_query_discovery_e1109_addresses.h" +#include "subboards/nvodm_query_discovery_e1116_addresses.h" +#include "subboards/nvodm_query_discovery_e1120_addresses.h" +#include "subboards/nvodm_query_discovery_e1129_addresses.h" +//#include "subboards/nvodm_query_discovery_e1215_addresses.h" // enable with accelerometer bring-up (Voyager) + +static NvOdmPeripheralConnectivity s_Peripherals_Default[] = +{ +#include "subboards/nvodm_query_discovery_e888_peripherals.h" +#include "subboards/nvodm_query_discovery_e906_peripherals.h" +#include "subboards/nvodm_query_discovery_e911_peripherals.h" +#include "subboards/nvodm_query_discovery_e936_peripherals.h" +#include "subboards/nvodm_query_discovery_e951_peripherals.h" +#include "subboards/nvodm_query_discovery_e1109_peripherals.h" +#include "subboards/nvodm_query_discovery_e1116_peripherals.h" +#include "subboards/nvodm_query_discovery_e1120_peripherals.h" +#include "subboards/nvodm_query_discovery_e1129_peripherals.h" +//#include "subboards/nvodm_query_discovery_e1215_peripherals.h" // enable with accelerometer bring-up (Voyager) +}; + +// Function to auto-detect boards with external CPU power supply +// defined in nvodm_query.c +extern NvBool NvOdmIsCpuExtSupply(void); + +#define NVODM_QUERY_BOARD_ID_UNKNOWN 0xFFFF + +#define NVODM_QUERY_MAX_PERIPHERALS 0x400 +#define NVODM_QUERY_MAX_IO_ADDRESSES 0x400 + +#define NVODM_QUERY_MAX_BUS_SEGMENTS 4 // # of Bus Segments defined by I2C extender +#define NVODM_QUERY_MAX_EEPROMS 8 // Maximum number of EEPROMs per bus segment + +#define NVODM_QUERY_ERASED_EEPROM_VALUE 0xFF + +#define PROCESSOR_BOARD_ID_I2C_ADDRESS ((0x56)<<1) +#define PROCESSOR_BOARD_ID_I2C_SEGMENT (0x00) + +// The following are used to store entries read from EEPROMs at runtime. +static NvOdmPeripheralConnectivity s_Peripherals[NVODM_QUERY_MAX_PERIPHERALS]; +static NvOdmIoAddress s_Peripheral_IoAddresses[NVODM_QUERY_MAX_IO_ADDRESSES]; +static NvOdmBoardInfo s_BoardModuleTable[NVODM_QUERY_MAX_BUS_SEGMENTS * NVODM_QUERY_MAX_EEPROMS]; + +#define NVODM_QUERY_I2C_CLOCK_SPEED 100 // kHz + +#define NVODM_QUERY_ENTRY_HEADER_SIZE 0x30 // Size of EERPOM "Entry Header" +#define NVODM_QUERY_BOARD_HEADER_START 0x04 // Offset to Part Number in EERPOM + +#define NVODM_QUERY_I2C_EEPROM_ADDRESS 0xA0 // I2C device base address for EEPROM (7'h50) +#define NVODM_QUERY_I2C_EXTENDER_ADDRESS 0x42 // I2C bus extender address (7'h21) + +#define NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED 10 // See EEPROM_format.txt +#define NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED 2 // See EEPROM_format.txt + +// The following board IDs are used to auto-configure the thermal rail (VOUT15) +#define BOARD_ID_E1107 0x0B07 +#define BOARD_ID_E1108 0x0B08 +#define BOARD_ID_E1109 0x0B09 +#define BOARD_ID_E1117 0x0B11 +#define BOARD_ID_E951 0x0933 + +#define PROCESSOR_MODULE_REV_A 0 + +// A list of the Whistler processor boards +static NvU32 gs_WhistlerProcessorBoards[] = { + BOARD_ID_E1107, + BOARD_ID_E1108, + BOARD_ID_E1109 +}; + +// A list of Whistler DDR2 processor boards +static NvU32 s_WhistlerDDR2Boards[] = { + BOARD_ID_E1107, + BOARD_ID_E1109, + BOARD_ID_E1117 +}; + + +static NvOdmI2cStatus +NvOdmPeripheralI2cRead8( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 I2cAddr, + NvU8 Offset, + NvU8 *pData) +{ + NvU8 ReadBuffer[1]; + NvOdmI2cStatus Error; + NvOdmI2cTransactionInfo TransactionInfo; + + ReadBuffer[0] = Offset; + + TransactionInfo.Address = I2cAddr; + TransactionInfo.Buf = ReadBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 1; + + Error = NvOdmI2cTransaction( + hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); + if (Error != NvOdmI2cStatus_Success) + { + return Error; + } + + NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer)); + + TransactionInfo.Address = (I2cAddr | 0x1); + TransactionInfo.Buf = ReadBuffer; + TransactionInfo.Flags = 0; + TransactionInfo.NumBytes = 1; + + // Read data from ROM at the specified offset + Error = NvOdmI2cTransaction( + hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); + if (Error != NvOdmI2cStatus_Success) + { + return Error; + } + *pData = ReadBuffer[0]; + return Error; +} + +static NvBool +NvOdmPeripheralSetBusSegment( + NvOdmServicesI2cHandle hOdmI2c, + NvU16 BusSegment) +{ + NvU8 WriteBuffer[2]; + NvOdmI2cStatus Error; + NvOdmI2cTransactionInfo TransactionInfo; + NvU8 Data; + + Data = (NvU8)(BusSegment & 0xF); + + WriteBuffer[0] = 0x03; // Register (0x03) + WriteBuffer[1] = 0x00; // Data + + TransactionInfo.Address = NVODM_QUERY_I2C_EXTENDER_ADDRESS; + TransactionInfo.Buf = WriteBuffer; + TransactionInfo.Flags = NVODM_I2C_IS_WRITE; + TransactionInfo.NumBytes = 2; + + Error = NvOdmI2cTransaction( + hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + + WriteBuffer[0] = 0x01; // Register (0x01) + WriteBuffer[1] = Data; // Data (bus segment 0 thru 3) + + Error = NvOdmI2cTransaction( + hOdmI2c, &TransactionInfo, 1, NVODM_QUERY_I2C_CLOCK_SPEED, NV_WAIT_INFINITE); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadNumPeripherals( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvU8 *pNumModulePeripherals) +{ + NvOdmI2cStatus Error; + NvU8 I2cAddr, Offset; + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + /** + * Offset to numPeripherals in NvOdmPeripheralConnectivity Structure. + * It's the first parameter after the "Entry Header." + */ + Offset = NVODM_QUERY_ENTRY_HEADER_SIZE; + + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, Offset, pNumModulePeripherals); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadPeripheral( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvU8 Peripheral, + NvU64 *pGuid, + NvU8 *pEepromAddressListOffset, + NvU32 *pNumAddress, + NvOdmPeripheralClass *pClass) +{ + NvOdmI2cStatus Error; + NvU32 i; + NvU8 ConnMemberIndex=0; // Offset to members in NvOdmPeripheralConnectivity + NvU8 I2cAddr, Offset; + NvU8 ReadBuffer[NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED]; + NvU8 NumAddrAndClass; + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + /** + * Calculate offset to pGuid in NvOdmPeripheralConnectivity Structure + * + * Offset = sizeof(eeprom Entry Header) + + * sizeof(NvOdmPeripheralConnectivity)*peripheral + + * pGuid offset <-- First field, so this is 0 + */ + Offset = NVODM_QUERY_ENTRY_HEADER_SIZE + + sizeof(NvOdmPeripheralConnectivity)*Peripheral; + + for (i=0; i<NVODM_QUERY_PERIPH_CONN_STRUCT_COMPRESSED; i++) + { + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, Offset, (NvU8 *)&ReadBuffer[i]); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + } + // Save pGuid entry + NvOdmOsMemcpy(pGuid, &ReadBuffer[0], sizeof(NvU64)); + + // Save EEPROM offset + ConnMemberIndex += sizeof(NvU64); // Increment to next member + *pEepromAddressListOffset = ReadBuffer[ConnMemberIndex]; + + // Save pNumAddress & Class + ConnMemberIndex += sizeof(NvU8); // Increment to next member + NumAddrAndClass = ReadBuffer[ConnMemberIndex]; + *pNumAddress = (NvU32)((NumAddrAndClass >> 3) & 0x0000001F); + *pClass = (NvOdmPeripheralClass)(NumAddrAndClass & 0x00000007); + + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadIoAddressData( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvU8 EepromAddressListOffset, + NvOdmIoAddress *pIoAddressEntry) +{ + NvOdmI2cStatus Error; + NvU32 i; + NvU8 I2cAddr; + NvU8 ReadBuffer[NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED]; + NvU16 CompressedIoAddressEntry; + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + for (i=0; i<NVODM_PERIPH_IO_ADDR_STRUCT_SZ_COMPRESSED; i++) + { + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, EepromAddressListOffset, (NvU8 *)&ReadBuffer[i]); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + } + // Save pIoAddressEntry: interface, instance, address + CompressedIoAddressEntry = ((((NvU16)ReadBuffer[1]) << 8) & 0xFF00) | ReadBuffer[0]; + + pIoAddressEntry->Interface = (NvOdmIoModule)((CompressedIoAddressEntry >> 11) & 0x1F); + + if (pIoAddressEntry->Interface != NvOdmIoModule_Gpio) + { + pIoAddressEntry->Instance = (NvU32)((CompressedIoAddressEntry >> 7) & 0xF); + pIoAddressEntry->Address = (NvU32)(CompressedIoAddressEntry & 0x7F); + } + else + { + pIoAddressEntry->Address = (NvU32)((CompressedIoAddressEntry >> 6) & 0x3F); + pIoAddressEntry->Instance = (NvU32)(CompressedIoAddressEntry & 0x3F); + } + + return NV_TRUE; +} + +static NvBool NvOdmPeripheralGetEntries(NvU32 *pNum) +{ + NvBool RetVal; + NvBool IsMatch = NV_FALSE; + NvOdmServicesI2cHandle hOdmI2c = NULL; + NvU8 BusSegment, EepromInst; + + // Peripheral counters + NvU8 NumPeripherals = 0; + NvU8 CurrentPeripheral = 0; + NvU32 TotalPeripherals = 0; + NvU32 StaticPeripherals; + + NvU32 CurrentIoAddressNum = 0; + NvU32 TotalIoAddressEntries = 0; + + NvU32 i,j; + NvU8 EepromAddressListOffset; + + if (!pNum) { + return NV_FALSE; + } + + // Auto-detect -- Read I2C-EEPROMs on each sub-board + + hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0); + if (!hOdmI2c) + return NV_FALSE; + + for (BusSegment=0; BusSegment < NVODM_QUERY_MAX_BUS_SEGMENTS; BusSegment++) + { + RetVal = NvOdmPeripheralSetBusSegment(hOdmI2c, BusSegment); + if (RetVal == NV_FALSE) + { + /** + * Bus segment not found. Set BusSegment to MAX and try reading + * any ID EEPROMS which might be available without the bus + * expander. + */ + BusSegment = NVODM_QUERY_MAX_BUS_SEGMENTS; + } + + for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++) + { + RetVal = NvOdmPeripheralReadNumPeripherals( + hOdmI2c, EepromInst, &NumPeripherals); + + if ( (RetVal == NV_TRUE) && + (NumPeripherals != NVODM_QUERY_ERASED_EEPROM_VALUE) ) + { + if (NumPeripherals > 0) + { + if ((NumPeripherals + TotalPeripherals) > NVODM_QUERY_MAX_PERIPHERALS) + { + NV_ASSERT( !"ERROR: s_Peripherals[] is too small to accommodate entries!" ); + + // Break out of loop and use static/default configuration + break; + } + + for (CurrentPeripheral=0; \ + CurrentPeripheral < NumPeripherals; \ + CurrentPeripheral++) + { + RetVal = NvOdmPeripheralReadPeripheral( + hOdmI2c, + EepromInst, + CurrentPeripheral, + &s_Peripherals[TotalPeripherals+CurrentPeripheral].Guid, + &EepromAddressListOffset, + &s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress, + &s_Peripherals[TotalPeripherals+CurrentPeripheral].Class); + + if (RetVal == NV_FALSE) + { + NV_ASSERT(!"Unable to read EEPROM peripheral entry!"); + break; // Go to next EEPROM + } + else // Process peripheral entry + { + /** + * Process NvOdmIoAddress arrays -- + * + * These are separate data structures. The addressList value + * read from the EEPROM (EepromAddressListOffset) represents + * an offset address within the I2C-EEPROM. This offset value + * identifies where to find the first instance of the + * NvOdmIoAddress data. + * + * The total number of NvOdmIoAddress entries is identified + * by the numAddress variable following the addressList entry + * in EEPROM. + * + * Once the offset and number of entries are determined (from + * above NvOdmPeripheralReadPeripheral function call), a loop + * fills in entries within the fixed storage area + * (e.g., s_Peripheral_IoAddresses) and the actual + * addressList pointer is assigned a value that corresponds + * to the first entry of the current class within this array. + * In other words, there might be prior entries in the + * s_Peripheral_IoAddresses array, but the first entry + * corresponding to the current class might be the third + * element in this array. Therefore, the actual addressList + * pointer for the current NvOdmPeripheralConnectivity.addressList + * parameter would be the address of the third entry, which is + * &s_Peripheral_IoAddresses[2] in this example. + */ + + // Read all of the entries and save them in s_Peripheral_IoAddresses + for (CurrentIoAddressNum=0; \ + CurrentIoAddressNum < s_Peripherals[TotalPeripherals+CurrentPeripheral].NumAddress; \ + CurrentIoAddressNum++) + { + if (TotalIoAddressEntries > NVODM_QUERY_MAX_IO_ADDRESSES) + { + NV_ASSERT( !"ERROR: s_Peripheral_IoAddresses[] is too small to accommodate entries!" ); + + // Cannot recover from this error. + NvOdmI2cClose(hOdmI2c); + return NV_FALSE; + } + + RetVal = NvOdmPeripheralReadIoAddressData( + hOdmI2c, + EepromInst, + EepromAddressListOffset, + &s_Peripheral_IoAddresses[TotalIoAddressEntries+CurrentIoAddressNum]); + + if (RetVal == NV_FALSE) + { + NV_ASSERT(!"Unable to read EEPROM (IoAddresses)!"); + + // Cannot recover from this error. + NvOdmI2cClose(hOdmI2c); + return NV_FALSE; + } + else // Process IoAddresses entry + { + /** + * Save the addressList pointer. This points to the first + * IoAddresses entry of this class. Then update the overall + * IoAddresses array counter (TotalIoAddressEntries). + */ + s_Peripherals[TotalPeripherals+CurrentPeripheral].AddressList = + &s_Peripheral_IoAddresses[TotalIoAddressEntries]; + + TotalIoAddressEntries += CurrentIoAddressNum; + + // >-- End of NvOdmIoAddress array processing --< + } + } + } + } + } + TotalPeripherals += NumPeripherals; + } + } + } + + // Done reading I2C-EEPROM; close it. + NvOdmI2cClose(hOdmI2c); + + /** + * Append static peripheral entries (if any) to dynamic list + * read from EEPROMs (this list may also be empty), except for + * duplicate GUIDs. The dynamic list takes precedence when + * duplicate entries are found in the static list. + */ + StaticPeripherals = NV_ARRAY_SIZE(s_Peripherals_Default); + for (i=0; i<StaticPeripherals; i++) + { + for (j=0; j<TotalPeripherals; j++) + { + if (s_Peripherals_Default[i].Guid == s_Peripherals[j].Guid) + { + IsMatch = NV_TRUE; + break; // Ignore duplicate entry from static list. + } + } + if (IsMatch != NV_TRUE) + { + // Append unique entry to dynamic list + + s_Peripherals[TotalPeripherals].Guid = + s_Peripherals_Default[i].Guid; + + s_Peripherals[TotalPeripherals].AddressList = + s_Peripherals_Default[i].AddressList; + + s_Peripherals[TotalPeripherals].NumAddress = + s_Peripherals_Default[i].NumAddress; + + s_Peripherals[TotalPeripherals].Class = + s_Peripherals_Default[i].Class; + + // Overwrite DDR IO rail address list for DDR2 board + if (s_Peripherals_Default[i].Guid == NV_VDD_DDR_ODM_ID) + { + NvU32 k; + NvOdmBoardInfo BoardInfo; + for (k = 0; k < NV_ARRAY_SIZE(s_WhistlerDDR2Boards); k++) + { + if (NvOdmPeripheralGetBoardInfo( + s_WhistlerDDR2Boards[k], &BoardInfo)) + { + s_Peripherals[TotalPeripherals].AddressList = + s_ffaVddDdr2Addresses; + break; + } + } + } + + // Overwrite CPU rail address list for board with external DCDC + if (s_Peripherals_Default[i].Guid == NV_VDD_CPU_ODM_ID) + { + if (NvOdmIsCpuExtSupply()) + { + s_Peripherals[TotalPeripherals].AddressList = + s_ffaCpuExtSupplyAddresses; + NV_ASSERT(s_Peripherals[TotalPeripherals].NumAddress == + NV_ARRAY_SIZE(s_ffaCpuExtSupplyAddresses)); + } + } + TotalPeripherals++; + } + } + *pNum = TotalPeripherals; + return NV_TRUE; +} + +static NvBool +NvOdmPeripheralReadPartNumber( + NvOdmServicesI2cHandle hOdmI2c, + NvU8 EepromInst, + NvOdmBoardInfo *pBoardInfo) +{ + NvOdmI2cStatus Error; + NvU32 i; + NvU8 I2cAddr, Offset; + NvU8 ReadBuffer[sizeof(NvOdmBoardInfo)]; + + NvOdmOsMemset(ReadBuffer, 0, sizeof(ReadBuffer)); + + // EepromInst*2, since 7-bit addressing + I2cAddr = NVODM_QUERY_I2C_EEPROM_ADDRESS + (EepromInst << 1); + + /** + * Offset to the board number entry in EEPROM. + */ + Offset = NVODM_QUERY_BOARD_HEADER_START; + + for (i=0; i<sizeof(NvOdmBoardInfo); i++) + { + Error = NvOdmPeripheralI2cRead8( + hOdmI2c, I2cAddr, Offset+i, (NvU8 *)&ReadBuffer[i]); + if (Error != NvOdmI2cStatus_Success) + { + return NV_FALSE; + } + } + NvOdmOsMemcpy(pBoardInfo, &ReadBuffer[0], sizeof(NvOdmBoardInfo)); + return NV_TRUE; +} + +NvBool +NvOdmPeripheralGetBoardInfo( + NvU16 BoardId, + NvOdmBoardInfo *pBoardInfo) +{ + NvBool RetVal = NV_FALSE; + NvOdmServicesI2cHandle hOdmI2c = NULL; + NvU8 BusSegment, EepromInst, CurrentBoard; + static NvU8 NumBoards = 0; + static NvBool s_ReadBoardInfoDone = NV_FALSE; + + if (!s_ReadBoardInfoDone) + { + s_ReadBoardInfoDone = NV_TRUE; + hOdmI2c = NvOdmI2cOpen(NvOdmIoModule_I2c_Pmu, 0); + if (!hOdmI2c) + { + // Exit + pBoardInfo = NULL; + return NV_FALSE; + } + + for (BusSegment=0; BusSegment < NVODM_QUERY_MAX_BUS_SEGMENTS; BusSegment++) + { + RetVal = NvOdmPeripheralSetBusSegment(hOdmI2c, BusSegment); + if (RetVal == NV_FALSE) + { + /** + * Bus segment not found. Set BusSegment to MAX and try reading + * any ID EEPROMS which might be available without the bus + * expander. + */ + BusSegment = NVODM_QUERY_MAX_BUS_SEGMENTS; + } + + for (EepromInst=0; EepromInst < NVODM_QUERY_MAX_EEPROMS; EepromInst++) + { + RetVal = NvOdmPeripheralReadPartNumber( + hOdmI2c, EepromInst, &s_BoardModuleTable[NumBoards]); + if (RetVal == NV_TRUE) + NumBoards++; + } + } + NvOdmI2cClose(hOdmI2c); + } + + if (NumBoards) + { + // Linear search for given BoardId; if found, return entry + for (CurrentBoard=0; CurrentBoard < NumBoards; CurrentBoard++) + { + if (s_BoardModuleTable[CurrentBoard].BoardID == BoardId) + { + // Match found + pBoardInfo->BoardID = s_BoardModuleTable[CurrentBoard].BoardID; + pBoardInfo->SKU = s_BoardModuleTable[CurrentBoard].SKU; + pBoardInfo->Fab = s_BoardModuleTable[CurrentBoard].Fab; + pBoardInfo->Revision = s_BoardModuleTable[CurrentBoard].Revision; + return NV_TRUE; + } + } + } + + // Match not found + pBoardInfo = NULL; + return NV_FALSE; +} + +// This will compare the peripheral GUID against a list of known-bad GUIDs +// for certain development kit personalities, and return NV_TRUE if it is +// known to be unsupported (filtered) on the current configuration +static NvBool +NvIsFilteredPeripheral(const NvOdmPeripheralConnectivity* pConnectivity) +{ + NvOdmServicesKeyListHandle hKeyList; + NvU32 CustOpt = 0; + NvU32 Personality = 0; + NvU32 opt = 0; + NvU32 ril = 0; + NvOdmIoModule OdmModule; + const NvU32 *OdmConfigs=NULL; + NvU32 NumOdmConfigs = 0; + const NvOdmPeripheralConnectivity* pFilteredPeriph = pConnectivity; + NvOdmBoardInfo BoardInfo; + NvU32 i, TotalBoards; + NvBool status = NV_FALSE; + + if((!pConnectivity) || (!pConnectivity->NumAddress)) + return NV_TRUE; + + if (pConnectivity->Guid == NV_ODM_GUID('a','d','t','7','4','6','1',' ')) + { + /** + * The following board detection is used to keep thermal rail + * (VOUT15) disabled for certain board SKUs where the board ID + * ROMs cannot be read when the thermal rail is enabled. + */ + TotalBoards = NV_ARRAY_SIZE(gs_WhistlerProcessorBoards); + + // Scan for processor boards + for (i=0; i<TotalBoards; i++) + { + if ( NvOdmPeripheralGetBoardInfo(gs_WhistlerProcessorBoards[i], &BoardInfo) ) + { + // Found the processor module + if (BoardInfo.Fab == PROCESSOR_MODULE_REV_A) + { + // Filter out this peripheral for REV_A processor modules + return NV_TRUE; + } + } + } + } + + if (pConnectivity->Guid == NV_ODM_GUID('b','l','u','t','o','o','t','h')) + { + /** + * The following board detection is used to detect presence of Bluetooth Chip. + * In case of whistler only ossibility is having E951 board. + */ + status = NvOdmPeripheralGetBoardInfo((BOARD_ID_E951), &BoardInfo); + if(NV_TRUE == status) + { + return NV_FALSE; // BT module found; don't filter it. + }else + { + return NV_TRUE; // BT module not found; filter the BT peripheral. + } + } + + hKeyList = NvOdmServicesKeyListOpen(); + + if (hKeyList) + { + CustOpt = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + Personality = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustOpt); + opt = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, DISPLAY_OPTION, CustOpt); + ril = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustOpt); + } + + if (pConnectivity->Guid == NV_ODM_GUID('e','m','p',' ','_','m','d','m')) + { + if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW) + { + return NV_FALSE; // EMP RAINBOW supported - don't filter it + } + else + { + return NV_TRUE; // EMP RAINBOW not supported - filter it + } + } + + if (pConnectivity->Guid == NV_ODM_GUID('e','m','p',' ','M','5','7','0')) + { + if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI) + { + return NV_FALSE; // EMP RAINBOW ULPI supported - don't filter it + } + else + { + return NV_TRUE; // EMP RAINBOW ULPI not supported - filter it + } + } + + if (pConnectivity->Guid == NV_ODM_GUID('s','p','i',' ','_','i','p','c')) + { + if (ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX) + { + return NV_FALSE; // IFX supported - don't filter it + } + else + { + return NV_TRUE; // IFX not supported - filter it + } + } + + + if (!Personality) + Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY; + + OdmModule = pFilteredPeriph->AddressList[0].Interface; + + if(OdmModule != NvOdmIoModule_Gpio) + NvOdmQueryPinMux(OdmModule, &OdmConfigs, &NumOdmConfigs); + + switch (OdmModule) + { + case NvOdmIoModule_Gpio: + // Filter scroll wheel when trace is enabled + if ( (pConnectivity->Guid == NV_ODM_GUID('s','c','r','o','l','w','h','l')) && + ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) ) + return NV_TRUE; + else + return NV_FALSE; + + default: + return NV_FALSE; + } +} + +static const NvOdmPeripheralConnectivity* +NvApGetAllPeripherals (NvU32 *pNum) +{ + static NvBool s_AutoDetectDone = NV_FALSE; + NvBool RetVal = NV_TRUE; + static NvU32 s_TotalPeripherals; + NvOdmBoardInfo BoardInfo; + + if (!pNum) + return NULL; + + if (!s_AutoDetectDone) + { + /** + * Read & cache the board ID info from the I2C-EEPROMs. This + * is necessary because once Whistler's thermal power rail is + * enabled, the ID ROMs cannot be read. NvApGetAllPeripherals() + * is called before that rail is enabled. + */ + NvOdmPeripheralGetBoardInfo(NVODM_QUERY_BOARD_ID_UNKNOWN, &BoardInfo); + + RetVal = NvOdmPeripheralGetEntries(&s_TotalPeripherals); + if (RetVal == NV_FALSE) + { + *pNum = 0; + return NULL; + } + s_AutoDetectDone = NV_TRUE; + } + + *pNum = s_TotalPeripherals; + return (const NvOdmPeripheralConnectivity *)s_Peripherals; +} + +// This implements a simple linear search across the entire set of currently- +// connected peripherals to find the set of GUIDs that Match the search +// criteria. More clever implementations are possible, but given the +// relatively small search space (max dozens of peripherals) and the relative +// infrequency of enumerating peripherals, this is the easiest implementation. +const NvOdmPeripheralConnectivity * +NvOdmPeripheralGetGuid(NvU64 SearchGuid) +{ + const NvOdmPeripheralConnectivity *pAllPeripherals; + NvU32 NumPeripherals; + NvU32 i; + + pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals); + + if (!pAllPeripherals || !NumPeripherals) + return NULL; + + for (i=0; i<NumPeripherals; i++) + { + if (SearchGuid == pAllPeripherals[i].Guid) + { + if (NvIsFilteredPeripheral(&pAllPeripherals[i])) + return NULL; + return &pAllPeripherals[i]; + } + } + + return NULL; +} + +static NvBool +IsBusMatch( + const NvOdmPeripheralConnectivity *pPeriph, + const NvOdmPeripheralSearch *pSearchAttrs, + const NvU32 *pSearchVals, + NvU32 offset, + NvU32 NumAttrs) +{ + NvU32 i, j; + NvBool IsMatch = NV_FALSE; + + for (i=0; i<pPeriph->NumAddress; i++) + { + j = offset; + do + { + switch (pSearchAttrs[j]) + { + case NvOdmPeripheralSearch_IoModule: + IsMatch = (pSearchVals[j] == + (NvU32)(pPeriph->AddressList[i].Interface)); + break; + case NvOdmPeripheralSearch_Address: + IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Address); + break; + case NvOdmPeripheralSearch_Instance: + IsMatch = (pSearchVals[j] == pPeriph->AddressList[i].Instance); + break; + case NvOdmPeripheralSearch_PeripheralClass: + default: + NV_ASSERT(!"Bad Query!"); + break; + } + j++; + } while (IsMatch && j<NumAttrs && + pSearchAttrs[j]!=NvOdmPeripheralSearch_IoModule); + + if (IsMatch) + { + return NV_TRUE; + } + } + return NV_FALSE; +} + +static NvBool +IsPeripheralMatch( + const NvOdmPeripheralConnectivity *pPeriph, + const NvOdmPeripheralSearch *pSearchAttrs, + const NvU32 *pSearchVals, + NvU32 NumAttrs) +{ + NvU32 i; + NvBool IsMatch = NV_TRUE; + + for (i=0; i<NumAttrs && IsMatch; i++) + { + switch (pSearchAttrs[i]) + { + case NvOdmPeripheralSearch_PeripheralClass: + IsMatch = (pSearchVals[i] == (NvU32)(pPeriph->Class)); + break; + case NvOdmPeripheralSearch_IoModule: + IsMatch = IsBusMatch(pPeriph, pSearchAttrs, pSearchVals, i, NumAttrs); + break; + case NvOdmPeripheralSearch_Address: + case NvOdmPeripheralSearch_Instance: + // In correctly-formed searches, these parameters will be parsed by + // IsBusMatch, so we ignore them here. + break; + default: + NV_ASSERT(!"Bad search attribute!"); + break; + } + } + return IsMatch; +} + +NvU32 +NvOdmPeripheralEnumerate( + const NvOdmPeripheralSearch *pSearchAttrs, + const NvU32 *pSearchVals, + NvU32 NumAttrs, + NvU64 *pGuidList, + NvU32 NumGuids) +{ + const NvOdmPeripheralConnectivity *pAllPeripherals; + NvU32 NumPeripherals; + NvU32 Matches; + NvU32 i; + + pAllPeripherals = NvApGetAllPeripherals(&NumPeripherals); + + if (!pAllPeripherals || !NumPeripherals) + { + return 0; + } + + if (!pSearchAttrs || !pSearchVals) + { + NumAttrs = 0; + } + + for (i=0, Matches=0; i<NumPeripherals && + (Matches < NumGuids || !pGuidList); i++) + { + if ( !NumAttrs || IsPeripheralMatch(&pAllPeripherals[i], + pSearchAttrs, pSearchVals, + NumAttrs) ) + { + if (NvIsFilteredPeripheral(&pAllPeripherals[i])) + continue; + + if (pGuidList) + pGuidList[Matches] = pAllPeripherals[i].Guid; + Matches++; + } + } + return Matches; +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c new file mode 100644 index 000000000000..eea1843af763 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_gpio.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 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 "nvodm_query_gpio.h" +#include "nvodm_services.h" +#include "tegra_devkit_custopt.h" +#include "nvodm_keylist_reserved.h" +#include "nvrm_drf.h" + +#define NVODM_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#define NVODM_PORT(x) ((x) - 'a') + +static const NvOdmGpioPinInfo s_vi[] = { + {NVODM_PORT('t'), 3, NvOdmGpioPinActiveState_High}, +}; + +static const NvOdmGpioPinInfo s_display[] = { + /* Panel 0 -- sony vga */ + { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('j'), 3, NvOdmGpioPinActiveState_Low }, + { NVODM_PORT('j'), 4, NvOdmGpioPinActiveState_Low }, + // this pin is not needed for ap15 + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + + /* Panel 1 -- samtek */ + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + {NVODM_GPIO_INVALID_PORT, NVODM_GPIO_INVALID_PIN, + NvOdmGpioPinActiveState_Low}, + + /* Panel 2 -- sharp wvga */ + { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low }, + + /* Panel 3 -- sharp qvga */ + { NVODM_PORT('n'), 6, NvOdmGpioPinActiveState_High }, // LCD_DC0 + { NVODM_PORT('n'), 4, NvOdmGpioPinActiveState_Low }, // LCD_CS0 + { NVODM_PORT('b'), 3, NvOdmGpioPinActiveState_Low }, // LCD_PCLK + { NVODM_PORT('b'), 2, NvOdmGpioPinActiveState_Low }, // LCD_PWR0 + { NVODM_PORT('e'), 0, NvOdmGpioPinActiveState_High }, // LCD_D0 + { NVODM_PORT('e'), 1, NvOdmGpioPinActiveState_High }, // LCD_D1 + { NVODM_PORT('e'), 2, NvOdmGpioPinActiveState_High }, // LCD_D2 + { NVODM_PORT('e'), 3, NvOdmGpioPinActiveState_High }, // LCD_D3 + { NVODM_PORT('e'), 4, NvOdmGpioPinActiveState_High }, // LCD_D4 + { NVODM_PORT('e'), 5, NvOdmGpioPinActiveState_High }, // LCD_D5 + { NVODM_PORT('e'), 6, NvOdmGpioPinActiveState_High }, // LCD_D6 + { NVODM_PORT('e'), 7, NvOdmGpioPinActiveState_High }, // LCD_D7 + { NVODM_PORT('f'), 0, NvOdmGpioPinActiveState_High }, // LCD_D8 + { NVODM_PORT('f'), 1, NvOdmGpioPinActiveState_High }, // LCD_D9 + { NVODM_PORT('f'), 2, NvOdmGpioPinActiveState_High }, // LCD_D10 + { NVODM_PORT('f'), 3, NvOdmGpioPinActiveState_High }, // LCD_D11 + { NVODM_PORT('f'), 4, NvOdmGpioPinActiveState_High }, // LCD_D12 + { NVODM_PORT('f'), 5, NvOdmGpioPinActiveState_High }, // LCD_D13 + { NVODM_PORT('f'), 6, NvOdmGpioPinActiveState_High }, // LCD_D14 + { NVODM_PORT('f'), 7, NvOdmGpioPinActiveState_High }, // LCD_D15 + { NVODM_PORT('m'), 3, NvOdmGpioPinActiveState_High }, // LCD_D19 + + /* Panel 4 -- auo */ + { NVODM_PORT('v'), 7, NvOdmGpioPinActiveState_Low }, +}; + +static const NvOdmGpioPinInfo s_Sdio2[] = { + {NVODM_PORT('i'), 5, NvOdmGpioPinActiveState_Low}, // Card Detect for SDIO instance 2 + /* High for WP and low for read/write */ + {NVODM_PORT('v'), 5, NvOdmGpioPinActiveState_High}, // Write Protect for SDIO instance 2 +}; + +static const NvOdmGpioPinInfo s_NandFlash[] = { + {NVODM_PORT('c'), 7, NvOdmGpioPinActiveState_High}, // MICRO SD_CD# +}; + +static const NvOdmGpioPinInfo s_spi_ethernet[] = { + {NVODM_PORT('c'), 1, NvOdmGpioPinActiveState_Low} // SPI_ENET_IRQ (EMC_INT) +}; + +static const NvOdmGpioPinInfo s_ScrollWheel[] = { + {NVODM_PORT('q'), 4, NvOdmGpioPinActiveState_Low}, // Scroll wheel -QP1 (terminal 1) + {NVODM_PORT('r'), 3, NvOdmGpioPinActiveState_Low}, // Scroll wheel_ONOFF + {NVODM_PORT('q'), 5, NvOdmGpioPinActiveState_Low}, // Scroll wheel -SELECT (terminal 3) + {NVODM_PORT('q'), 3, NvOdmGpioPinActiveState_Low}, // Scroll wheel -QP2 (terminal 4) +}; + +static const NvOdmGpioPinInfo s_ScrollWheel_TraceMode[] = { + {NVODM_PORT('r'), 3, NvOdmGpioPinActiveState_Low}, // Scroll wheel_ONOFF +}; + +static const NvOdmGpioPinInfo s_Bluetooth[] = { + {NVODM_PORT('u'), 0, NvOdmGpioPinActiveState_Low}, // Bluetooth Controls: BT_RST +}; + +static const NvOdmGpioPinInfo s_Wlan[] = { + {NVODM_PORT('k'), 5, NvOdmGpioPinActiveState_Low}, // WLAN-OFF + {NVODM_PORT('k'), 6, NvOdmGpioPinActiveState_Low}, // WLAN-RESET +}; + +static const NvOdmGpioPinInfo s_hdmi[] = +{ + /* hdmi hot-plug interrupt pin */ + { NVODM_PORT('n'), 7, NvOdmGpioPinActiveState_High}, +}; + +const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group, + NvU32 Instance, NvU32 *pCount) +{ + NvU32 CustomerOption = 0; + NvU32 Personality = 0; + NvOdmServicesKeyListHandle hKeyList; + + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + CustomerOption = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + Personality = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustomerOption); + } + + if (!Personality) + Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY; + + switch (Group) + { + case NvOdmGpioPinGroup_Display: + *pCount = NVODM_ARRAY_SIZE(s_display); + return s_display; + + case NvOdmGpioPinGroup_Sdio: + if (Instance == 2) + { + *pCount = NVODM_ARRAY_SIZE(s_Sdio2); + return s_Sdio2; + } + else + { + *pCount = 0; + return NULL; + } + + case NvOdmGpioPinGroup_ScrollWheel: + if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) + { + *pCount = NVODM_ARRAY_SIZE(s_ScrollWheel_TraceMode); + return s_ScrollWheel_TraceMode; + } + else + { + *pCount = NVODM_ARRAY_SIZE(s_ScrollWheel); + return s_ScrollWheel; + } + + case NvOdmGpioPinGroup_NandFlash: + *pCount = NVODM_ARRAY_SIZE(s_NandFlash); + return s_NandFlash; + + case NvOdmGpioPinGroup_Bluetooth: + *pCount = NVODM_ARRAY_SIZE(s_Bluetooth); + return s_Bluetooth; + + case NvOdmGpioPinGroup_Wlan: + *pCount = NVODM_ARRAY_SIZE(s_Wlan); + return s_Wlan; + + case NvOdmGpioPinGroup_SpiEthernet: + *pCount = NVODM_ARRAY_SIZE(s_spi_ethernet); + return s_spi_ethernet; + case NvOdmGpioPinGroup_Vi: + *pCount = NVODM_ARRAY_SIZE(s_vi); + return s_vi; + case NvOdmGpioPinGroup_Hdmi: + *pCount = NVODM_ARRAY_SIZE(s_hdmi); + return s_hdmi; + + default: + *pCount = 0; + return NULL; + } +} diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c new file mode 100644 index 000000000000..1781b6f0ed99 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc.c @@ -0,0 +1,88 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * @brief <b>NVIDIA Driver Development Kit: + * ODM Kbc interface</b> + * + */ + +#include "nvodm_query_kbc.h" + +static NvU32 *RowNumbers = NULL; +static NvU32 *ColNumbers = NULL; + +void +NvOdmKbcGetParameter( + NvOdmKbcParameter Param, + NvU32 SizeOfValue, + void * pValue) +{ + NvU32 *pTempVar; + switch (Param) + { + case NvOdmKbcParameter_DebounceTime: + pTempVar = (NvU32 *)pValue; + *pTempVar = 10; + break; + case NvOdmKbcParameter_RepeatCycleTime: + pTempVar = (NvU32 *)pValue; + *pTempVar = 32; + break; + default: + break; + } +} + +NvU32 +NvOdmKbcGetKeyCode( + NvU32 Row, + NvU32 Column, + NvU32 RowCount, + NvU32 ColumnCount) +{ + return ((Row * ColumnCount) + Column); +} + +NvBool +NvOdmKbcIsSelectKeysWkUpEnabled( + NvU32 **pRowNumber, + NvU32 **pColNumber, + NvU32 *NumOfKeys) +{ + *pRowNumber = RowNumbers; + *pColNumber = ColNumbers; + *NumOfKeys = 0; + return NV_FALSE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h new file mode 100644 index 000000000000..40b0664eeee1 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_kbc_gpio_def.h @@ -0,0 +1,74 @@ +/* + * 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * The KBC GPIO pin definitions</b> + * + * @b Description: Define the KBC GPIO pins in row and column numbers. + */ + +#ifndef NVODM_QUERY_KBC_GPIO_DEF_H +#define NVODM_QUERY_KBC_GPIO_DEF_H + +typedef enum +{ + NvOdmKbcGpioPin_KBRow0 = 0, + NvOdmKbcGpioPin_KBRow1, + NvOdmKbcGpioPin_KBRow2, + NvOdmKbcGpioPin_KBRow3, + NvOdmKbcGpioPin_KBRow4, + NvOdmKbcGpioPin_KBRow5, + NvOdmKbcGpioPin_KBRow6, + NvOdmKbcGpioPin_KBRow7, + NvOdmKbcGpioPin_KBRow8, + NvOdmKbcGpioPin_KBRow9, + NvOdmKbcGpioPin_KBRow10, + NvOdmKbcGpioPin_KBRow11, + NvOdmKbcGpioPin_KBRow12, + NvOdmKbcGpioPin_KBRow13, + NvOdmKbcGpioPin_KBRow14, + NvOdmKbcGpioPin_KBRow15, + NvOdmKbcGpioPin_KBCol0, + NvOdmKbcGpioPin_KBCol1, + NvOdmKbcGpioPin_KBCol2, + NvOdmKbcGpioPin_KBCol3, + NvOdmKbcGpioPin_KBCol4, + NvOdmKbcGpioPin_KBCol5, + NvOdmKbcGpioPin_KBCol6, + NvOdmKbcGpioPin_KBCol7, + NvOdmKbcGpioPin_Num, + NvOdmKbcGpioPin_Force32 = 0x7FFFFFFF +}NvOdmKbcGpioPin; + +#endif // NVODM_QUERY_KBC_GPIO_DEF_H diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c new file mode 100644 index 000000000000..1b7519c77434 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_nand.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * @brief <b>NVIDIA Driver Development Kit: + * ODM Uart interface</b> + * + * @b Description: Implements the ODM for the Uart communication. + * + */ + +#include "nvodm_query_nand.h" +#include "nvcommon.h" + +// fill params for all required nand flashes here. +// this list will end when vendor id and chipd id will be zero. +// hence, all supported chips should be listed before that. +NvOdmNandFlashParams g_Params[] = +{ + /* + { + VendorId, DeviceId, NandType, IsCopyBackCommandSupported, IsCacheWriteSupported, CapacityInMB, ZonesPerDevice, + BlocksPerZone, OperationSuccessStatus, InterleaveCapability, EccAlgorithm, + ErrorsCorrectable, SkippedSpareBytes, + TRP, TRH (TREH), TWP, TWH, TCS, TWHR, TWB, TREA, TADL, + TCLS, TCLH, TCH, TALS, TALH, TRC, TWC, TCR(TCLR), TAR, TRR, NandDeviceType, ReadIdFourthByte + } + Note : + TADL values for flashes K9F1G08Q0M, K9F1G08U0M, TH58NVG4D4CTG00, + TH58NVG3D4BTG00, TH58NVG2S3BFT00 is not available from their data sheets. + Hence TADL is computed as + tADL = (tALH + tALS + tWP). + */ + // filling odm parameter structure for Samsung K9K8G08U0M + { + 0xEC, 0xD3, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 1024, 4, + 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 20, 60, 100, 26, 70, + 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x95 + }, + // filling odm parameter structure for Samsung K9W8G08U1M + { + 0xEC, 0xDC, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 1024, 2, + 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 15, 60, 100, 18, 100, + 10, 5, 5, 10, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, + // filling odm parameter structure for Samsung K9F1G08Q0M + { + 0xEC, 0xA1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1, + 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 60, 20, 60, 20, 0, 60, 100, 60, 70, + 0, 10, 10, 0, 10, 80, 80, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, + // filling odm parameter structure for Samsung K9F1G08U0M + { + 0xEC, 0xF1, NvOdmNandFlashType_Slc, NV_TRUE, NV_TRUE, 128, 1, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 15, 25, 15, 0, 60, 100, 30, 35, + 0, 10, 10, 0, 10, 50, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, + // filling odm parameter structure for Samsung K9L8G08U0M + { + 0xEC, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 1024, 4, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 20, 60, 100, 20, 35, + 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Samsung K9G4G08U0M + { + 0xEC, 0xDC, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 512, 2, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 15, 15, 60, 100, 18, 50, + 10, 5, 5, 10, 5, 30, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Samsung K5E2G1GACM + { + 0xEC, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 2, + 1024, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 21, 15, 21, 15, 31, 60, 100, 30, 100, + 21, 5, 5, 21, 5, 42, 42, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x15 + }, +/* + // filling odm parameter structure for Toshiba TH58NVG4D4CTG00 + { + 0x98, 0xD5, NvOdmNandFlashType_Mlc, NV_FALSE, NV_FALSE, 2048, 1, + 8192, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 41, 15, 15, 10, 0, 30, 20, 200, 41, 21, + 0, 6, 6, 0, 6, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Toshiba TH58NVG3D4BTG00 + { + 0x98, 0xD3, NvOdmNandFlashType_Mlc, NV_FALSE, NV_TRUE, 1024, 1, + 4096, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 41, 15, 15, 10, 0, 30, 20, 200, 41, 35, + 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25 + }, + // filling odm parameter structure for Toshiba TH58NVG2S3BFT00 + { + 0x98, 0xDC, NvOdmNandFlashType_Slc, NV_FALSE, NV_FALSE, 512, 1, + 1024, 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 41, 15, 15, 10, 0, 30, 20, 200, 41, 35, + 0, 10, 10, 0, 10, NvOdmNandDeviceType_Type1, 0x25 + }, +*/ + // filling odm parameter structure for Samsung K9LBG08U0M + { + 0xEC, 0xD7, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 4096, 4, 2048, + 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 12, 10, 12, 10, 20, 60, 100, 20, 100, + 12, 5, 5, 12, 5, 25, 25, 10, 10, 20, NvOdmNandDeviceType_Type1, 0xB6 + }, + // filling odm parameter structure for Samsung K9LBG08U0D - 42 nm Nand + { + 0xEC, 0xD7, NvOdmNandFlashType_Mlc, NV_TRUE, NV_FALSE, 4096, 4, 2048, + 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Eight, NvOdmNandSkipSpareBytes_4, + 15, 10, 15, 10, 20, 60, 100, 20, 100, + 15, 5, 5, 15, 5, 30, 30, 10, 10, 20, NvOdmNandDeviceType_Type2, 0x29 + }, + //Hynix H8BES0UQ0MCR + { + 0xAD, 0xBC, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 512, 2, 2048, + 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 10, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x55 + }, + //Hynix H8BCS0SJ0MCP + { + 0xAD, 0xBA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048, + 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 15, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x55 + }, + //Hynix H8BCS0RJ0MCP + { + 0xAD, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, 2048, + 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 10, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15 + }, + /*Numonyx MCP - NAND02GR3B2D*/ + { + 0x20, 0xAA, NvOdmNandFlashType_Slc, NV_TRUE, NV_FALSE, 256, 1, + 2048, 0x40, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 25, 15, 25, 15, 35, 60, 100, 30, 100, + 25, 10, 10, 25, 10, 45, 45, 10, 10, 25, NvOdmNandDeviceType_Type1, 0x15 + }, + // Micron ONFI 16 Bit Nand MT29F2G16ABD + { + 0x2C, 0xBA, NvOdmNandFlashType_Slc, NV_FALSE, NV_FALSE, 256, 1, 2048, + 0x60, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 12, 10, 17, 15, 24, 60, 100, 20, 100, + 15, 5, 4, 15, 4, 25, 35, 10, 10, 20, NvOdmNandDeviceType_Type1, 0x55 + }, + /* "This is the end of device list please do not modify this. To add support for more flash parts, + add device category for those parts before this element"*/ + { + 0, 0, NvOdmNandFlashType_UnKnown, NV_FALSE, NV_FALSE, 0, 0, + 0, 0, SINGLE_PLANE, NvOdmNandECCAlgorithm_ReedSolomon, + NvOdmNandNumberOfCorrectableSymbolErrors_Four, NvOdmNandSkipSpareBytes_4, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NvOdmNandDeviceType_Type1, 0 + } +}; + +NvOdmNandFlashParams *NvOdmNandGetFlashInfo (NvU32 ReadID) +{ + NvU8 TempValue; + NvU8 VendorId = 0; + NvU8 DeviceId = 0; + NvU8 ReadIdFourthByte = 0; + NvOdmNandFlashType NandType; + NvU8 i = 0; + // To extract Vendor Id + VendorId = (NvU8) (ReadID & 0xFF); + // To extract Device Id + DeviceId = (NvU8) ((ReadID >> DEVICE_SHIFT) & 0xFF); + // To extract Fourth ID byte of Read ID - for checking if the flash is 42nm. + ReadIdFourthByte = (NvU8) ((ReadID >> FOURTH_ID_SHIFT) & 0xFF); + // To extract device Type Mask + TempValue = (NvU8) ((ReadID >> FLASH_TYPE_SHIFT) & 0xC); + if (TempValue) + { + NandType = NvOdmNandFlashType_Mlc; + } + else + { + NandType = NvOdmNandFlashType_Slc; + } + // following ORing is done to check if we reached the end of the list. + while ((g_Params[i].VendorId) | (g_Params[i].DeviceId)) + { + if ((g_Params[i].VendorId == VendorId) && + (g_Params[i].DeviceId == DeviceId) && + (g_Params[i].ReadIdFourthByte == ReadIdFourthByte) && + (g_Params[i].NandType == NandType)) + { + return &g_Params[i]; + } + else + i++; + } + // This condition will be reached if "g_Params" is not having Parameters of the flash used. + // Hence add the parameters required in the table. + return NULL; +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c new file mode 100644 index 000000000000..1e9aeef4e584 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query_pinmux.c @@ -0,0 +1,482 @@ +/* + * Copyright (c) 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. + * + */ + +/* + * This file implements the pin-mux configuration tables for each I/O module. + */ + +// THESE SETTINGS ARE PLATFORM-SPECIFIC (not SOC-specific). +// PLATFORM = AP20 Whistler/Voyager + +#include "nvodm_query_pinmux.h" +#include "nvassert.h" +#include "nvodm_services.h" +#include "tegra_devkit_custopt.h" +#include "nvodm_keylist_reserved.h" +#include "nvrm_drf.h" + +#define NVODM_PINMUX_ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + + +static const NvU32 s_NvOdmPinMuxConfig_Uart_Hsi_Ulpi[] = { + NvOdmUartPinMap_Config7, // Instance 0: UART-A is mapped to SDIO1 pins when ULPI is used + NvOdmUartPinMap_Config1, // Instance 1: UART-B + NvOdmUartPinMap_Config1, // Instance 2: UART-C + 0, // UART-D function disabled: pins used by BB (SPI1) + 0, // UART-E function disabled: pins used by WiFi (SDIO1) +}; + + +static const NvU32 s_NvOdmPinMuxConfig_Uart[] = { + NvOdmUartPinMap_Config1, + NvOdmUartPinMap_Config1, + NvOdmUartPinMap_Config1, + 0, // UART-D function disabled: pins used by BB (SPI1) + 0, // UART-E function disabled: pins used by WiFi (SDIO1) +}; + +static const NvU32 s_NvOdmPinMuxConfig_Spi[] = { + NvOdmSpiPinMap_Config1, + NvOdmSpiPinMap_Config3, + NvOdmSpiPinMap_Multiplexed, + 0, + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Twc[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_I2c[] = { + NvOdmI2cPinMap_Config1, + NvOdmI2cPinMap_Config1, + NvOdmI2cPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_I2c_Pmu[] = { + NvOdmI2cPmuPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Ulpi[] = { + NvOdmUlpiPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Sdio[] = { + 0, + NvOdmSdioPinMap_Config1, /* Wifi */ + NvOdmSdioPinMap_Config1, + NvOdmSdioPinMap_Config2, // NAND enabled +}; + +static const NvU32 s_NvOdmPinMuxConfig_Sdio_05[] = { + 0, + NvOdmSdioPinMap_Config1, /* Wifi */ + NvOdmSdioPinMap_Config1, + NvOdmSdioPinMap_Config1, // Personality 5 uses SDIO (disables NAND) +}; + +static const NvU32 s_NvOdmPinMuxConfig_Spdif[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Hsi[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Hdmi[] = { + NvOdmHdmiPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Pwm[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Ata[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Nand[] = { + NvOdmNandPinMap_Config2, // disable sdio4 pinmux for enabling nand +}; + +static const NvU32 s_NvOdmPinMuxConfig_Nand_05[] = { + 0, // Personality 5 disables NAND +}; + +static const NvU32 s_NvOdmPinMuxConfig_Dsi[] = { + NvOdmDapPinMap_Config1, // fake one, otherwise, ddk display will assert. +}; + +static const NvU32 s_NvOdmPinMuxConfig_Dap[] = { + NvOdmDapPinMap_Config1, + NvOdmDapPinMap_Config1, + NvOdmDapPinMap_Config1, + NvOdmDapPinMap_Config1, + NvOdmDapPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Kbd[] = { + NvOdmKbdPinMap_Config4, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Hdcp[] = { + NvOdmHdcpPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_SyncNor[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Mio[] = { + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_ExternalClock[] = { + NvOdmExternalClockPinMap_Config2, + NvOdmExternalClockPinMap_Config2, + NvOdmExternalClockPinMap_Config1, // CSUS -> VI_Sensor_CLK +}; + +static const NvU32 s_NvOdmPinMuxConfig_VideoInput[] = { + NvOdmVideoInputPinMap_Config2, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Display[] = { + NvOdmDisplayPinMap_Config1, + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_BacklightPwm[] = { + 0, + NvOdmBacklightPwmPinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Crt[] = { + NvOdmDisplayPinMap_Config1, + 0, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Tvo[] = { + NvOdmTvoPinMap_Config1, // FIXME: is this the correct config? +}; + +static const NvU32 s_NvOdmPinMuxConfig_OneWire[] = { + NvOdmOneWirePinMap_Config1, +}; + +static const NvU32 s_NvOdmPinMuxConfig_PciExpress[] = { + 0, // To enable Pcie, set pinmux config for SDIO3 to 0 +}; + +static const NvU32 s_NvOdmClockLimit_Sdio[] = { + 50000, + 32000, + 50000, + 50000, +}; + +static const NvU32 s_NvOdmPinMuxConfig_Ptm[] = { + NvOdmPtmPinMap_Config1, +}; + +void +NvOdmQueryPinMux( + NvOdmIoModule IoModule, + const NvU32 **pPinMuxConfigTable, + NvU32 *pCount) +{ + NvU32 CustomerOption = 0; + NvU32 Personality = 0; + NvU32 Ril = 0; + NvOdmServicesKeyListHandle hKeyList; + + hKeyList = NvOdmServicesKeyListOpen(); + if (hKeyList) + { + CustomerOption = + NvOdmServicesGetKeyValue(hKeyList, + NvOdmKeyListId_ReservedBctCustomerOption); + NvOdmServicesKeyListClose(hKeyList); + Personality = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, PERSONALITY, CustomerOption); + Ril = + NV_DRF_VAL(TEGRA_DEVKIT, BCT_CUSTOPT, RIL, CustomerOption); + } + + if (!Personality) + Personality = TEGRA_DEVKIT_DEFAULT_PERSONALITY; + + if (!Ril) + Ril = TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_DEFAULT; + + switch (IoModule) + { + case NvOdmIoModule_Display: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Display; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Display); + break; + + case NvOdmIoModule_Dap: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Dap; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Dap); + break; + + case NvOdmIoModule_Hdcp: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdcp; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdcp); + break; + + case NvOdmIoModule_Hdmi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hdmi; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hdmi); + break; + + case NvOdmIoModule_I2c: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2c; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2c); + break; + + case NvOdmIoModule_I2c_Pmu: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_I2c_Pmu; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_I2c_Pmu); + break; + + case NvOdmIoModule_Kbd: + if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) + { + // Disable KBD pin-mux when PTM trace enabled (shares kbcc pin-group) + *pPinMuxConfigTable = NULL; + *pCount = 0; + } + else + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Kbd; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Kbd); + } + break; + + case NvOdmIoModule_Mio: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Mio; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Mio); + break; + + case NvOdmIoModule_Nand: + if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15)) + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Nand_05; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Nand_05); + } + else + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Nand; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Nand); + } + break; + + case NvOdmIoModule_Sdio: + if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C4)) + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Sdio_05; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Sdio_05); + } + else + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Sdio; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Sdio); + } + break; + + case NvOdmIoModule_Spdif: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spdif; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spdif); + break; + + case NvOdmIoModule_Spi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Spi; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Spi); + break; + + case NvOdmIoModule_Uart: + if (Ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI) + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Uart_Hsi_Ulpi; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Uart_Hsi_Ulpi); + } + else + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Uart; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Uart); + } + break; + + case NvOdmIoModule_ExternalClock: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_ExternalClock; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_ExternalClock); + break; + + case NvOdmIoModule_VideoInput: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_VideoInput; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_VideoInput); + break; + + case NvOdmIoModule_Crt: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Crt; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Crt); + break; + + case NvOdmIoModule_Tvo: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Tvo; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Tvo); + break; + + case NvOdmIoModule_Ata: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ata; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ata); + break; + + case NvOdmIoModule_Pwm: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Pwm; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Pwm); + break; + + case NvOdmIoModule_Dsi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Dsi; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Dsi); + break; + + case NvOdmIoModule_Hsi: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Hsi; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Hsi); + break; + + case NvOdmIoModule_Twc: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Twc; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Twc); + break; + + case NvOdmIoModule_Ulpi: + if (Ril == TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI) + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ulpi; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ulpi); + } + else + { + *pPinMuxConfigTable = NULL; + *pCount = 0; + } + break; + + case NvOdmIoModule_OneWire: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_OneWire; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_OneWire); + break; + + case NvOdmIoModule_SyncNor: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_SyncNor; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_SyncNor); + break; + + case NvOdmIoModule_PciExpress: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_PciExpress; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_PciExpress); + break; + + case NvOdmIoModule_Trace: + if ((Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15) || + (Personality == TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1)) + { + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_Ptm; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_Ptm); + } + else + { + *pCount = 0; + } + break; + + case NvOdmIoModule_BacklightPwm: + *pPinMuxConfigTable = s_NvOdmPinMuxConfig_BacklightPwm; + *pCount = NV_ARRAY_SIZE(s_NvOdmPinMuxConfig_BacklightPwm); + break; + + case NvOdmIoModule_Hsmmc: + case NvOdmIoModule_Csi: + case NvOdmIoModule_Sflash: + case NvOdmIoModule_Slink: + case NvOdmIoModule_Gpio: + case NvOdmIoModule_I2s: + case NvOdmIoModule_Usb: + case NvOdmIoModule_Vdd: + case NvOdmIoModule_Xio: + case NvOdmIoModule_Tsense: + *pCount = 0; + break; + + default: + NV_ASSERT(!"Bad Parameter!"); + *pCount = 0; + break; + } +} + +void +NvOdmQueryClockLimits( + NvOdmIoModule IoModule, + const NvU32 **pClockSpeedLimits, + NvU32 *pCount) +{ + switch (IoModule) + { + case NvOdmIoModule_Hsmmc: + *pCount = 0; + break; + + case NvOdmIoModule_Sdio: + *pClockSpeedLimits = s_NvOdmClockLimit_Sdio; + *pCount = NVODM_PINMUX_ARRAY_SIZE(s_NvOdmClockLimit_Sdio); + break; + + + default: + *pClockSpeedLimits = NULL; + *pCount = 0; + break; + } +} + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h new file mode 100644 index 000000000000..4752fca7b93e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_addresses.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E1109 + * Processor Module. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" +#include "tmon/adt7461/nvodm_tmon_adt7461_channel.h" +#include "nvodm_tmon.h" + +static const NvOdmIoAddress s_ffaHdmiAddresses[] = +{ + { NvOdmIoModule_Hdmi, 0, 0 }, + + /* Display Data Channel (DDC) for Extended Display Identification + * Data (EDID) + */ + { NvOdmIoModule_I2c, 0x01, 0xA0 }, + + /* HDCP downstream */ + { NvOdmIoModule_I2c, 0x01, 0x74 }, + + /* AVDD_HDMI -> D1REG */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 }, + + /* MIPI PLL */ + { NvOdmIoModule_Vdd, 0, Max8907bPmuSupply_LDO6 }, + + /* lcd i/o rail (for hot plug pin) */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, +}; + +static const NvOdmIoAddress s_ffaCrtAddresses[] = +{ + { NvOdmIoModule_Crt, 0, 0 }, + + /* Display Data Channel (DDC) for Extended Display Identification + * Data (EDID) + */ + { NvOdmIoModule_I2c, 0x01, 0xA0 }, + + /* tvdac rail (required) */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO14 }, + + /* lcd i/o rail (for hot plug pin) */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, +}; + +static const NvOdmIoAddress s_ffaVideoDacAddresses[] = +{ + { NvOdmIoModule_Tvo, 0x00, 0x00 }, + /* tvdac rail */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO14 }, +}; + +static const NvOdmIoAddress s_Tmon0Addresses[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x98 }, /* I2C bus */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO15 }, /* TMON pwer rail -> D4REG */ + { NvOdmIoModule_Gpio, 0x08, 0x02 }, /* GPIO Port I and Pin 2 */ + + /* Temperature zone mapping */ + { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Core, ADT7461ChannelID_Remote }, /* TSENSOR */ + { NvOdmIoModule_Tsense, NvOdmTmonZoneID_Ambient, ADT7461ChannelID_Local }, /* TSENSOR */ +}; + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h new file mode 100644 index 000000000000..9f213e0c35ab --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1109_peripherals.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database Peripheral entries for the E91109 + * Processor Module. + */ + +// HDMI +{ + NV_ODM_GUID('f','f','a','_','h','d','m','i'), + s_ffaHdmiAddresses, + NV_ARRAY_SIZE(s_ffaHdmiAddresses), + NvOdmPeripheralClass_Display +}, + +// CRT +{ + NV_ODM_GUID('f','f','a','_','-','c','r','t'), + s_ffaCrtAddresses, + NV_ARRAY_SIZE(s_ffaCrtAddresses), + NvOdmPeripheralClass_Display +}, + +// TV Out Video Dac +{ + NV_ODM_GUID('f','f','a','t','v','o','u','t'), + s_ffaVideoDacAddresses, + NV_ARRAY_SIZE(s_ffaVideoDacAddresses), + NvOdmPeripheralClass_Display +}, + +// Temperature Monitor (TMON) +{ + NV_ODM_GUID('a','d','t','7','4','6','1',' '), + s_Tmon0Addresses, + NV_ARRAY_SIZE(s_Tmon0Addresses), + NvOdmPeripheralClass_Other +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h new file mode 100644 index 000000000000..2b5ca7f8bacd --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_addresses.h @@ -0,0 +1,270 @@ +/* + * Copyright (c) 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. + * + */ + + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E1116 + * Power module. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" + +// Persistent voltage rail (ie, for RTC, Standby, etc...) +static const NvOdmIoAddress s_ffaRtcAddresses[] = +{ + // On Maxim 8907B, the standby rail automatically follows V2 + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V2 } /* VDD_RTC -> RTC */ +}; + +// Core voltage rail +static const NvOdmIoAddress s_ffaCoreAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V2 } /* VDD_CORE -> V2 */ +}; + +// PMU CPU voltage rail +static const NvOdmIoAddress s_ffaCpuAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V1 } /* VDD_CPU_PMU -> V1 */ +}; + +// External CPU DCDC voltage rail +static const NvOdmIoAddress s_ffaCpuExtSupplyAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bLxV1_Ad5258_DPM_EXT_DCDC_7 } /* VDD_CPU_PMU -> DCDC7 */ +}; + +// PLLA voltage rail +static const NvOdmIoAddress s_ffaPllAAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */ +}; + +// PLLM voltage rail +static const NvOdmIoAddress s_ffaPllMAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLM -> VOUT2 */ +}; + +// PLLP voltage rail +static const NvOdmIoAddress s_ffaPllPAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */ +}; + +// PLLC voltage rail +static const NvOdmIoAddress s_ffaPllCAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */ +}; + +// PLLE voltage rail +static const NvOdmIoAddress s_ffaPllEAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLL_E -> VOUT2 */ +}; + +// PLLU1 voltage rail +static const NvOdmIoAddress s_ffaPllU1Addresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLU -> VOUT2 */ +}; + +// PLLS voltage rail +static const NvOdmIoAddress s_ffaPllSAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLA_P_C_S -> VOUT2 */ +}; + +// PLLHD voltage rail +static const NvOdmIoAddress s_ffaPllHdmiAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO6 } /* AVDD_HDMI_PLL -> VOUT6 */ +}; + +// OSC voltage rail +static const NvOdmIoAddress s_ffaVddOscAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* AVDD_OSC -> V3 */ +}; + +// PLLX voltage rail +static const NvOdmIoAddress s_ffaPllXAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO2 } /* AVDD_PLLX -> VOUT2 */ +}; + +// PLL_USB voltage rail +static const NvOdmIoAddress s_ffaPllUsbAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO4 } /* AVDD_USB_PLL -> VOUT4 */ +}; + +// SYS IO voltage rail +static const NvOdmIoAddress s_ffaVddSysAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_SYS -> V3 */ +}; + +// USB voltage rail +static const NvOdmIoAddress s_ffaVddUsbAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO4 } /* AVDD_USB -> VOUT4 */ +}; + +// HDMI voltage rail +static const NvOdmIoAddress s_ffaVddHdmiAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 } /* AVDD_HDMI -> VOUT11 */ +}; + +// MIPI voltage rail +static const NvOdmIoAddress s_ffaVddMipiAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO17 } /* VDDIO_MIPI -> VOUT17 */ +}; + +// LCD voltage rail +static const NvOdmIoAddress s_ffaVddLcdAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_LCD_PMU -> V3 */ +}; + +// Audio voltage rail +static const NvOdmIoAddress s_ffaVddAudAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_AUDIO -> V3 */ +}; + +// LPDDR2 voltage rail (default) +static const NvOdmIoAddress s_ffaVddDdrAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO20 } /* VDDIO_DDR_1V2 -> VOUT20 */ +}; + +// DDR2 voltage rail (on E1109 board ext 1.8V DCDC is controlled by LDO5) +static const NvOdmIoAddress s_ffaVddDdr2Addresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 } /* VDDIO_DDR_1V8 -> VOUT05 */ +}; + +// DDR_RX voltage rail +static const NvOdmIoAddress s_ffaVddDdrRxAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO1 } /* VDDIO_RX_DDR(2.7-3.3) -> VOUT1 */ +}; + +// NAND voltage rail +static const NvOdmIoAddress s_ffaVddNandAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_NAND_PMU -> V3 */ +}; + +// UART voltage rail +static const NvOdmIoAddress s_ffaVddUartAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_UART -> V3 */ +}; + +// SDIO voltage rail +static const NvOdmIoAddress s_ffaVddSdioAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO12 } /* VDDIO_SDIO -> VOUT12 */ +}; + +// VDAC voltage rail +static const NvOdmIoAddress s_ffaVddVdacAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO14 } /* AVDD_VDAC -> VOUT14 */ +}; + +// VI voltage rail +static const NvOdmIoAddress s_ffaVddViAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18 } /* VDDIO_VI -> VOUT18 */ +}; + +// BB voltage rail +static const NvOdmIoAddress s_ffaVddBbAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* VDDIO_BB -> V3 */ +}; + +// HSIC voltage rail +static const NvOdmIoAddress s_ffaVddHsicAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO20 } /* VDDIO_HSIC -> VOUT20 */ +}; + +// USB_IC voltage rail +static const NvOdmIoAddress s_ffaVddUsbIcAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 } /* AVDD_USB_IC -> V3 */ +}; + +// PEX_CLK voltage rail +static const NvOdmIoAddress s_ffaVddPexClkAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 }, /* VDDIO_PEX_CLK -> VOUT11 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO12 }, /* VDDIO_PEX_CLK -> VOUT12 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_EXT_DCDC_3 } +}; + +// PMU0 +static const NvOdmIoAddress s_Pmu0Addresses[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x78 }, +}; + +// I2C IO Expander +static const NvOdmIoAddress s_I2cioexpanderAddress[] = +{ + { NvOdmIoModule_I2c_Pmu, 0x00, 0x40 }, +}; + +// USB1 VBus voltage rail +static const NvOdmIoAddress s_ffaVddUsb1VBusAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_EXT_DCDC_3_USB1 }, +}; + +// USB3 VBus voltage rail +static const NvOdmIoAddress s_ffaVddUsb3VBusAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_EXT_DCDC_3_USB3 }, +}; + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h new file mode 100644 index 000000000000..5145bf5b0711 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1116_peripherals.h @@ -0,0 +1,349 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database Peripheral entries for the E1116 + * power module. + */ + +/* All of the reserved values, for SOC voltage domains. + */ + +// WHISTLER_AP16_ONLY - AP20 doesn't have PLL_D rail. +// PLLD (NV reserved) / Use PLL_U +{ + NV_VDD_PLLD_ODM_ID, + s_ffaPllU1Addresses, + NV_ARRAY_SIZE(s_ffaPllU1Addresses), + NvOdmPeripheralClass_Other +}, +// -------- END WHISTLER_AP16_ONLY -------- + + +// RTC (NV reserved) +{ + NV_VDD_RTC_ODM_ID, + s_ffaRtcAddresses, + NV_ARRAY_SIZE(s_ffaRtcAddresses), + NvOdmPeripheralClass_Other +}, + +// CORE (NV reserved) +{ + NV_VDD_CORE_ODM_ID, + s_ffaCoreAddresses, + NV_ARRAY_SIZE(s_ffaCoreAddresses), + NvOdmPeripheralClass_Other +}, + +// CPU (NV reserved) +{ + NV_VDD_CPU_ODM_ID, + s_ffaCpuAddresses, + NV_ARRAY_SIZE(s_ffaCpuAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLA (NV reserved) +{ + NV_VDD_PLLA_ODM_ID, + s_ffaPllAAddresses, + NV_ARRAY_SIZE(s_ffaPllAAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLM (NV reserved) +{ + NV_VDD_PLLM_ODM_ID, + s_ffaPllMAddresses, + NV_ARRAY_SIZE(s_ffaPllMAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLP (NV reserved) +{ + NV_VDD_PLLP_ODM_ID, + s_ffaPllPAddresses, + NV_ARRAY_SIZE(s_ffaPllPAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLC (NV reserved) +{ + NV_VDD_PLLC_ODM_ID, + s_ffaPllCAddresses, + NV_ARRAY_SIZE(s_ffaPllCAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLE (NV reserved) +{ + NV_VDD_PLLE_ODM_ID, + s_ffaPllEAddresses, + NV_ARRAY_SIZE(s_ffaPllEAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLU (NV reserved) +{ + NV_VDD_PLLU_ODM_ID, + s_ffaPllUsbAddresses, + NV_ARRAY_SIZE(s_ffaPllUsbAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLU1 (NV reserved) +{ + NV_VDD_PLLU1_ODM_ID, + s_ffaPllU1Addresses, + NV_ARRAY_SIZE(s_ffaPllU1Addresses), + NvOdmPeripheralClass_Other +}, + +// PLLS (NV reserved) +{ + NV_VDD_PLLS_ODM_ID, + s_ffaPllSAddresses, + NV_ARRAY_SIZE(s_ffaPllSAddresses), + NvOdmPeripheralClass_Other +}, + +// HDMI PLL (NV reserved) +{ + NV_VDD_PLLHDMI_ODM_ID, + s_ffaPllHdmiAddresses, + NV_ARRAY_SIZE(s_ffaPllHdmiAddresses), + NvOdmPeripheralClass_Other +}, + +// OSC VDD (NV reserved) +{ + NV_VDD_OSC_ODM_ID, + s_ffaVddOscAddresses, + NV_ARRAY_SIZE(s_ffaVddOscAddresses), + NvOdmPeripheralClass_Other +}, + +// PLLX (NV reserved) +{ + NV_VDD_PLLX_ODM_ID, + s_ffaPllXAddresses, + NV_ARRAY_SIZE(s_ffaPllXAddresses), + NvOdmPeripheralClass_Other +}, + +// PLL_USB (NV reserved) +{ + NV_VDD_PLL_USB_ODM_ID, + s_ffaPllUsbAddresses, + NV_ARRAY_SIZE(s_ffaPllUsbAddresses), + NvOdmPeripheralClass_Other +}, + +// (TBD) PLL_PEX (NV reserved) + +// System IO VDD (NV reserved) +{ + NV_VDD_SYS_ODM_ID, + s_ffaVddSysAddresses, + NV_ARRAY_SIZE(s_ffaVddSysAddresses), + NvOdmPeripheralClass_Other +}, + +// USB VDD (NV reserved) +{ + NV_VDD_USB_ODM_ID, + s_ffaVddUsbAddresses, + NV_ARRAY_SIZE(s_ffaVddUsbAddresses), + NvOdmPeripheralClass_Other +}, + +// VBUS for USB1 +{ + NV_VDD_VBUS_ODM_ID, + s_ffaVddUsb1VBusAddresses, + NV_ARRAY_SIZE(s_ffaVddUsb1VBusAddresses), + NvOdmPeripheralClass_Other +}, + +// VBUS for USB3 +{ + NV_VDD_USB3_VBUS_ODM_ID, + s_ffaVddUsb3VBusAddresses, + NV_ARRAY_SIZE(s_ffaVddUsb3VBusAddresses), + NvOdmPeripheralClass_Other +}, + + +// HDMI VDD (NV reserved) +{ + NV_VDD_HDMI_ODM_ID, + s_ffaVddHdmiAddresses, + NV_ARRAY_SIZE(s_ffaVddHdmiAddresses), + NvOdmPeripheralClass_Other +}, + +// MIPI VDD (NV reserved) +{ + NV_VDD_MIPI_ODM_ID, + s_ffaVddMipiAddresses, + NV_ARRAY_SIZE(s_ffaVddMipiAddresses), + NvOdmPeripheralClass_Other +}, + +// LCD VDD (NV reserved) +{ + NV_VDD_LCD_ODM_ID, + s_ffaVddLcdAddresses, + NV_ARRAY_SIZE(s_ffaVddLcdAddresses), + NvOdmPeripheralClass_Other +}, + +// AUDIO VDD (NV reserved) +{ + NV_VDD_AUD_ODM_ID, + s_ffaVddAudAddresses, + NV_ARRAY_SIZE(s_ffaVddAudAddresses), + NvOdmPeripheralClass_Other +}, + +// DDR VDD (NV reserved) +{ + NV_VDD_DDR_ODM_ID, + s_ffaVddDdrAddresses, + NV_ARRAY_SIZE(s_ffaVddDdrAddresses), + NvOdmPeripheralClass_Other +}, + +// DDR_RX (NV reserved) +{ + NV_VDD_DDR_RX_ODM_ID, + s_ffaVddDdrRxAddresses, + NV_ARRAY_SIZE(s_ffaVddDdrRxAddresses), + NvOdmPeripheralClass_Other +}, + +// NAND VDD (NV reserved) +{ + NV_VDD_NAND_ODM_ID, + s_ffaVddNandAddresses, + NV_ARRAY_SIZE(s_ffaVddNandAddresses), + NvOdmPeripheralClass_Other +}, + +// UART VDD (NV reserved) +{ + NV_VDD_UART_ODM_ID, + s_ffaVddUartAddresses, + NV_ARRAY_SIZE(s_ffaVddUartAddresses), + NvOdmPeripheralClass_Other +}, + +// SDIO VDD (NV reserved) +{ + NV_VDD_SDIO_ODM_ID, + s_ffaVddSdioAddresses, + NV_ARRAY_SIZE(s_ffaVddSdioAddresses), + NvOdmPeripheralClass_Other +}, + +// VDAC VDD (NV reserved) +{ + NV_VDD_VDAC_ODM_ID, + s_ffaVddVdacAddresses, + NV_ARRAY_SIZE(s_ffaVddVdacAddresses), + NvOdmPeripheralClass_Other +}, + +// VI VDD (NV reserved) +{ + NV_VDD_VI_ODM_ID, + s_ffaVddViAddresses, + NV_ARRAY_SIZE(s_ffaVddViAddresses), + NvOdmPeripheralClass_Other +}, + +// BB VDD (NV reserved) +{ + NV_VDD_BB_ODM_ID, + s_ffaVddBbAddresses, + NV_ARRAY_SIZE(s_ffaVddBbAddresses), + NvOdmPeripheralClass_Other +}, + +// HSIC (NV reserved) +{ + NV_VDD_HSIC_ODM_ID, + s_ffaVddHsicAddresses, + NV_ARRAY_SIZE(s_ffaVddHsicAddresses), + NvOdmPeripheralClass_Other +}, + +// USB_IC (NV reserved) +{ + NV_VDD_USB_IC_ODM_ID, + s_ffaVddUsbIcAddresses, + NV_ARRAY_SIZE(s_ffaVddUsbIcAddresses), + NvOdmPeripheralClass_Other +}, + +// (TBD) PEX (NV reserved) + +// PEX_CLK (NV reserved) +{ + NV_VDD_PEX_CLK_ODM_ID, + s_ffaVddPexClkAddresses, + NV_ARRAY_SIZE(s_ffaVddPexClkAddresses), + NvOdmPeripheralClass_Other +}, + +// PMU0 +{ + NV_ODM_GUID('m','a','x','8','9','0','7','b'), + s_Pmu0Addresses, + NV_ARRAY_SIZE(s_Pmu0Addresses), + NvOdmPeripheralClass_Other +}, +// I2C IO expander +{ + NV_ODM_GUID('t','c','a','_','6','4','1','6'), + s_I2cioexpanderAddress, + NV_ARRAY_SIZE(s_I2cioexpanderAddress), + NvOdmPeripheralClass_Other +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h new file mode 100644 index 000000000000..7085868e5374 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_addresses.h @@ -0,0 +1,74 @@ + + +/* + * Copyright (c) 2010 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E1120 + * AP20 Development System Motherboard. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" + +static const NvOdmIoAddress s_enc28j60EthernetAddresses[] = +{ + { NvOdmIoModule_Spi, 1, 1 }, + { NvOdmIoModule_Gpio, (NvU32)'c'-'a', 1 } +}; + +static const NvOdmIoAddress s_SdioAddresses[] = +{ + { NvOdmIoModule_Sdio, 0x0, 0x0 }, + { NvOdmIoModule_Sdio, 0x2, 0x0 }, + { NvOdmIoModule_Sdio, 0x3, 0x0 }, + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO12 }, /* VDDIO_SDIO -> VOUT12 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 } /* VCORE_MMC -> VOUT05 */ +}; + +static const NvOdmIoAddress s_VibAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x0, Max8907bPmuSupply_LDO16}, +}; + +static const NvOdmIoAddress s_AcceleroAddresses[] = +{ + { NvOdmIoModule_I2c, 0x0, 0x3A }, /* I2C address (7-bit) 0x1D < 1 = 0x3A (8-bit) */ + { NvOdmIoModule_Gpio, 0x1A, 0x1 }, /* Gpio port AA[1] = (A=0, Z=25) thus AA = 26 = 0x1A */ + { NvOdmIoModule_Vdd, 0x0, Max8907bPmuSupply_LX_V3 }, /* VDDIO_UART = V3 */ + { NvOdmIoModule_Vdd, 0x0, Max8907bPmuSupply_LDO1 }, /* VCORE_ACC = VOUT1 = 2.8v */ +}; + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h new file mode 100644 index 000000000000..90d038ba2ab2 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1120_peripherals.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity database Peripheral + * entries for the E1120 AP20 Development System + * Motherboard. + */ + +// Ethernet module +{ + NV_ODM_GUID('e','n','c','2','8','j','6','0'), + s_enc28j60EthernetAddresses, + NV_ARRAY_SIZE(s_enc28j60EthernetAddresses), + NvOdmPeripheralClass_Other +}, + +// Sdio module +{ + NV_ODM_GUID('s','d','i','o','_','m','e','m'), + s_SdioAddresses, + NV_ARRAY_SIZE(s_SdioAddresses), + NvOdmPeripheralClass_Other, +}, + +//..Vibrate Module +{ + NV_ODM_GUID('v','i','b','r','a','t','o','r'), + s_VibAddresses, + NV_ARRAY_SIZE(s_VibAddresses), + NvOdmPeripheralClass_Other, +}, + +// Accelerometer Module +{ + NV_ODM_GUID('a','c','c','e','l','e','r','o'), + s_AcceleroAddresses, + NV_ARRAY_SIZE(s_AcceleroAddresses), + NvOdmPeripheralClass_Other, +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h new file mode 100644 index 000000000000..bedebff4a8e4 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_addresses.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E1129 + * keypad module. + */ +#include "../nvodm_query_kbc_gpio_def.h" + +// Key Pad +static const NvOdmIoAddress s_KeyPadAddresses[] = +{ + // instance = 1 indicates Column info. + // instance = 0 indicates Row info. + // address holds KBC pin number used for row/column. + + // All Row info has to be defined contiguously from 0 to max. + { NvOdmIoModule_Kbd,0x00, NvOdmKbcGpioPin_KBRow0}, // Row 0 + { NvOdmIoModule_Kbd,0x00, NvOdmKbcGpioPin_KBRow1}, // Row 1 + { NvOdmIoModule_Kbd,0x00 ,NvOdmKbcGpioPin_KBRow2}, // Row 2 + + // All Column info has to be defined contiguously from 0 to max. + { NvOdmIoModule_Kbd,0x01, NvOdmKbcGpioPin_KBCol0}, // Column 0 + { NvOdmIoModule_Kbd,0x01, NvOdmKbcGpioPin_KBCol1}, // Column 1 +}; + +// s_ffa ScrollWheel... only supported for personality 1 +static const NvOdmIoAddress s_ffaScrollWheelAddresses[] = +{ + { NvOdmIoModule_Gpio, 0x10, 0x3 }, // GPIO Port q - Pin3 + { NvOdmIoModule_Gpio, 0x11, 0x3 }, // GpIO Port r - Pin 3 + { NvOdmIoModule_Gpio, 0x10, 0x5 }, // GPIO Port q - Pin 5 + { NvOdmIoModule_Gpio, 0x10, 0x4 }, // GPIO Port q - Pin 4 +}; + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h new file mode 100644 index 000000000000..3df1481a6894 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e1129_peripherals.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database Peripheral entries for the E1129 + * keypad module. + */ + +// Key Pad +{ + NV_ODM_GUID('k','e','y','b','o','a','r','d'), + s_KeyPadAddresses, + NV_ARRAY_SIZE(s_KeyPadAddresses), + NvOdmPeripheralClass_HCI +}, + +// Scroll Wheel +{ + NV_ODM_GUID('s','c','r','o','l','w','h','l'), + s_ffaScrollWheelAddresses, + NV_ARRAY_SIZE(s_ffaScrollWheelAddresses), + NvOdmPeripheralClass_HCI +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h new file mode 100644 index 000000000000..8946a5cb3056 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_addresses.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E888 + * audio module. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" + +// Audio Codec +static const NvOdmIoAddress s_AudioCodecAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO7}, /* AUDIO_PLL etc -> DCD2 */ + { NvOdmIoModule_ExternalClock, 0, 0 }, // connected to CDEV1 +#if 1 + { NvOdmIoModule_Spi, 2, 1 }, /* FFA Audio codec on SP3- CS1*/ +#else + { NvOdmIoModule_I2c_Pmu, 0, 0x34}, /* FFA Audio codec on DVC*/ + +#endif + { NvOdmIoModule_Dap, 0, 0 }, /* Dap port Index 0 is used for codec*/ +}; diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h new file mode 100644 index 000000000000..939ae49f8175 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e888_peripherals.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database Peripheral entries for the E888 + * audio module. + */ + +// audio codec +{ + NV_ODM_GUID('w','o','l','f','8','7','5','3'), + s_AudioCodecAddresses, + NV_ARRAY_SIZE(s_AudioCodecAddresses), + NvOdmPeripheralClass_Other +}, +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h new file mode 100644 index 000000000000..09f3197447ea --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_addresses.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E906 + * LCD Module. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" + +// Main LCD +static const NvOdmIoAddress s_ffaMainDisplayAddresses[] = +{ + { NvOdmIoModule_Display, 0, 0 }, + { NvOdmIoModule_Spi, 0x2, 0x2 }, // TBD (this is a guess) + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, /* VDDIO_LCD -> V3 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 }, /* AVDD_LCD_1 -> VOUT5 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO19 }, /* AVDD_LCD_2 -> VOUT19 */ +}; + +// DSI LCD +// WARNING: Whistler's board personality needs to be set to 077 for the +// reset gpio pin to work +static const NvOdmIoAddress s_DsiAddresses[] = +{ + { NvOdmIoModule_Display, 0, 0 }, + + { NvOdmIoModule_Gpio, (NvU32)('c' - 'a'), 1 }, + + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, /* VDDIO_LCD -> V3 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO5 }, /* AVDD_LCD_1 -> VOUT5 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO19 }, /* AVDD_LCD_2 -> VOUT19 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO17 }, /* MIPI DSI 1.2V */ +}; + +// TouchPanel +static const NvOdmIoAddress s_ffaTouchPanelAddresses[] = +{ + { NvOdmIoModule_I2c, 0x00, 0x20 },/* I2C device address is 0x20 */ + { NvOdmIoModule_Gpio, 'c' - 'a', 6}, /* GPIO Port V and Pin 3 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO19 } +}; diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h new file mode 100644 index 000000000000..44f7a967ff40 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e906_peripherals.h @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database Peripheral entries for the E906 LCD + * Module. + */ + +// LCD module +{ + NV_ODM_GUID('S','H','P','_','A','P','2','0'), // Sharp WVGA panel with AP20 backlight control + s_ffaMainDisplayAddresses, + NV_ARRAY_SIZE(s_ffaMainDisplayAddresses), + NvOdmPeripheralClass_Display, +}, + +// DSI module +{ + NV_ODM_GUID('s','h','a','r','p','d','s','i'), + s_DsiAddresses, + NV_ARRAY_SIZE(s_DsiAddresses), + NvOdmPeripheralClass_Display, +}, + +// Touch Panel +{ + NV_ODM_GUID('t','p','k','t','o','u','c','h'), + s_ffaTouchPanelAddresses, + NV_ARRAY_SIZE(s_ffaTouchPanelAddresses), + NvOdmPeripheralClass_HCI +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h new file mode 100644 index 000000000000..fe193db73d5e --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_addresses.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity database NvOdmIoAddress entries + * for the E911 5MP + 1.3MP + VGA VI Camera module. + */ +#include "nvodm_query_gpio.h" +#include "../include/nvodm_imager_guids.h" +#include "pmu/max8907b/max8907b_supply_info_table.h" + +#define NVODM_PORT(x) ((x) - 'a') +/* VGP5 is apparently inverted on some boards. + * For E912- A01, you may need to change the VGP5_RESET_AL line to: + * NVODM_CAMERA_VGP5_RESET + * If you find other boards for which it needs to be inverted, please + * add your information to this comment. + */ +#define OV5630_PINS (NVODM_CAMERA_SERIAL_CSI_D1A | \ + NVODM_CAMERA_DEVICE_IS_DEFAULT) +static const NvOdmIoAddress s_ffaImagerOV5630Addresses[] = +{ + { NvOdmIoModule_I2c, 0x02, 0x6C }, + { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 5 | NVODM_IMAGER_RESET_AL }, + { NvOdmIoModule_Gpio, NVODM_PORT('t'), 3 | NVODM_IMAGER_POWERDOWN }, + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18 }, //VDDIO_VI + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO9 }, //AVDD_CAM1 + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO13 }, //VDDIO_AF + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO17 }, //VDDIO_MIPI + { NvOdmIoModule_VideoInput, 0x00, OV5630_PINS }, + { NvOdmIoModule_ExternalClock, 2, 0 } // CSUS +}; + +// OV5630 focuser +static const NvOdmIoAddress s_ffaImagerAD5820Addresses[] = +{ + { NvOdmIoModule_I2c, 0x02, 0x18 }, // focuser i2c +}; + +// OV5630 flash +static const NvOdmIoAddress s_ffaFlashLTC3216Addresses[] = +{ + { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 3 | NVODM_IMAGER_FLASH0 }, // Flash 200mA + { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 6 | NVODM_IMAGER_FLASH1 } // Flash 600mA +}; + +// For SEMCO VGA +#define SOC380_PINS (NVODM_CAMERA_PARALLEL_VD0_TO_VD7) +static const NvOdmIoAddress s_ffaImagerSOC380Addresses[] = +{ + { NvOdmIoModule_I2c, 0x02, 0x78 }, + { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 4 | NVODM_IMAGER_POWERDOWN_AL }, + { NvOdmIoModule_Gpio, NVODM_GPIO_CAMERA_PORT, 0 | NVODM_IMAGER_RESET_AL }, + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18}, //VDDIO_VI + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO9 }, //AVDD_CAM2 + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO13}, //VDDIO_AF + { NvOdmIoModule_VideoInput, 0x00, SOC380_PINS }, + { NvOdmIoModule_ExternalClock, 2, 0 } // CSUS +}; + +static const NvOdmIoAddress s_CommonImagerAddresses[] = +{ + { NvOdmIoModule_ExternalClock, 2, 0 } // CSUS +}; + + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h new file mode 100644 index 000000000000..c6fc1fb9f564 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e911_peripherals.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity database Peripheral entries + * for the E911 5MP + 1.3MP + VGA VI Camera module. + */ +#include "../include/nvodm_imager_guids.h" + +// !!! DON'T MOVE THINGS AROUND !!! +// Position 0 is used as default primary for E912 +// Position 1 is used as default secondary for E912 and E911 +// Position 2 is used as default primary for E911 + +// Imager - Primary +// E912 A01 and Whistler Imager +{ + OV5630_GUID, + s_ffaImagerOV5630Addresses, + NV_ARRAY_SIZE(s_ffaImagerOV5630Addresses), + NvOdmPeripheralClass_Imager +}, +// Imager - Secondary +// sensor for SEMCO VGA +{ + // Aptina (Micron) SOC380 + SEMCOVGA_GUID, + s_ffaImagerSOC380Addresses, + NV_ARRAY_SIZE(s_ffaImagerSOC380Addresses), + NvOdmPeripheralClass_Imager +}, + +// Dummy Entry for Whistler +{ + MI5130_GUID, + s_ffaImagerOV5630Addresses, + NV_ARRAY_SIZE(s_ffaImagerOV5630Addresses), + NvOdmPeripheralClass_Imager +}, + +// focuser for OV5630 module +{ + // VCM driver IC AD5820 Analog Devices + AD5820_GUID, + s_ffaImagerAD5820Addresses, + NV_ARRAY_SIZE(s_ffaImagerAD5820Addresses), + NvOdmPeripheralClass_Other +}, + +// flash device +{ + LTC3216_GUID, + s_ffaFlashLTC3216Addresses, + NV_ARRAY_SIZE(s_ffaFlashLTC3216Addresses), + NvOdmPeripheralClass_Other +}, + +{ + COMMONIMAGER_GUID, + s_CommonImagerAddresses, + NV_ARRAY_SIZE(s_CommonImagerAddresses), + NvOdmPeripheralClass_Other +}, diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h new file mode 100644 index 000000000000..327edf62901a --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_addresses.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E936 + * ISDB-T module. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" + +// VIP raw bitstream addresses +static const NvOdmIoAddress s_ffaVIPBitstreamAddresses[] = +{ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LX_V3 }, + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO9 }, + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO18 }, + // Reset. vgp0 and vgp5: + { NvOdmIoModule_Gpio, 27, 1 }, // vgp[0] - Port BB(27), Pin 1 + { NvOdmIoModule_Gpio, 'd'-'a', 2 }, // vgp[5] - Port D, Pin 2 +}; + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h new file mode 100644 index 000000000000..c2733b11531c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e936_peripherals.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity database Peripheral + * entries for the E936 ISDB-T module. + */ + +// Murata tuner source +{ + NV_ODM_GUID('m','u','r','a','t','a','5','7'), + s_ffaVIPBitstreamAddresses, + NV_ARRAY_SIZE(s_ffaVIPBitstreamAddresses), + NvOdmPeripheralClass_Other +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h new file mode 100644 index 000000000000..70f20af74044 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_addresses.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database NvOdmIoAddress entries for the E951 + * COMMS module. + */ + +#include "pmu/max8907b/max8907b_supply_info_table.h" +// Bluetooth +static const NvOdmIoAddress ffaBluetoothAddresses[] = +{ + { NvOdmIoModule_Uart, 0x2, 0x0 }, + { NvOdmIoModule_Gpio, 0x14, 0x0 }, /* GPIO Port U and Pin 0 */ + { NvOdmIoModule_Vdd, 0x00, MIC2826PmuSupply_LDO3 } /* VDD -> MIC2826 LDO3 */ +}; + + +// Wlan +static const NvOdmIoAddress s_ffaWlanAddresses[] = +{ + { NvOdmIoModule_Sdio, 0x01, 0x0 }, /* WLAN is on SD Bus */ + { NvOdmIoModule_Gpio, 0x0a, 0x5 }, /* GPIO Port K and Pin 5 */ + { NvOdmIoModule_Gpio, 0x0a, 0x6 }, /* GPIO Port K and Pin 6 */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO8 }, /* VDD -> LDO8 (VOUT8) */ + { NvOdmIoModule_Vdd, 0x00, Max8907bPmuSupply_LDO11 }, /* VDD -> LDO11 (VOUT11) */ + { NvOdmIoModule_Vdd, 0x00, MIC2826PmuSupply_LDO3 } /* VDD -> MIC2826 LDO3 */ +}; + +// EMP Rainbow module +static const NvOdmIoAddress s_ffaEmpAddresses[] = +{ + { NvOdmIoModule_Uart, 0x0, 0x0 }, /* UART 0 */ + { NvOdmIoModule_Gpio, 0x15, 0x0 }, /* GPIO Port V and Pin 0 Reset */ + { NvOdmIoModule_Gpio, 0x15, 0x1 }, /* GPIO Port V and Pin 1 Power */ + { NvOdmIoModule_Gpio, 0x19, 0x0 }, /* GPIO Port Z and Pin 0 AWR */ + { NvOdmIoModule_Gpio, 0x18, 0x6 }, /* GPIO Port Y and Pin 6 CWR */ + { NvOdmIoModule_Gpio, 0x0e, 0x6 }, /* GPIO Port O and Pin 6 SpiInt */ + { NvOdmIoModule_Gpio, 0x15, 0x2 }, /* GPIO Port V and Pin 2 SpiSlaveSelect */ + { NvOdmIoModule_Slink, 0x0, 0x0 } /* Slink 0 */ +}; + +// EMP M570 module +static const NvOdmIoAddress s_ffaEmpM570Addresses[] = +{ + { NvOdmIoModule_Uart, 0x0, 0x0 }, /* UART 0 */ + { NvOdmIoModule_Gpio, 0x15, 0x0 }, /* GPIO Port V and Pin 0 Reset */ + { NvOdmIoModule_Gpio, 0x15, 0x1 }, /* GPIO Port V and Pin 1 Power */ + { NvOdmIoModule_Gpio, 0x19, 0x0 }, /* GPIO Port Z and Pin 0 AWR */ + { NvOdmIoModule_Gpio, 0x18, 0x6 }, /* GPIO Port Y and Pin 6 CWR */ +}; + +// IFX Modem module +static const NvOdmIoAddress s_ffaInfnAddresses[] = +{ + { NvOdmIoModule_Spi, 0x0, 0x0 }, /* Spi Controller 0 and Chip Select 0 */ + { NvOdmIoModule_Gpio, 0x18, 0x6 }, /* GPIO Port Y and Pin 6 SRDY */ + { NvOdmIoModule_Gpio, 0x19, 0x0 }, /* GPIO Port Z and Pin 0 MRDY */ + { NvOdmIoModule_Gpio, 0x15, 0x0 }, /* GPIO Port V and Pin 0 Reset */ + { NvOdmIoModule_Gpio, 0x15, 0x1 } /* GPIO Port V and Pin 1 Power */ +}; + diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h new file mode 100644 index 000000000000..69b364f11689 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/subboards/nvodm_query_discovery_e951_peripherals.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA APX ODM Kit:: + * Implementation of the ODM Peripheral Discovery API</b> + * + * @b Description: Specifies the peripheral connectivity + * database Peripheral entries for the E951 + * COMMS module. + */ +// Bluetooth on COMMs Module +{ + NV_ODM_GUID('b','l','u','t','o','o','t','h'), + ffaBluetoothAddresses, + NV_ARRAY_SIZE(ffaBluetoothAddresses), + NvOdmPeripheralClass_Other +}, + +// Sdio wlan on COMMs Module +{ + NV_ODM_GUID('s','d','i','o','w','l','a','n'), + s_ffaWlanAddresses, + NV_ARRAY_SIZE(s_ffaWlanAddresses), + NvOdmPeripheralClass_Other +}, + +// EMP Modem on COMMs Module +{ + NV_ODM_GUID('e','m','p',' ','_','m','d','m'), + s_ffaEmpAddresses, + NV_ARRAY_SIZE(s_ffaEmpAddresses), + NvOdmPeripheralClass_Other +}, + +// EMP M570 Modem on COMMs Module +{ + NV_ODM_GUID('e','m','p',' ','M','5','7','0'), + s_ffaEmpM570Addresses, + NV_ARRAY_SIZE(s_ffaEmpM570Addresses), + NvOdmPeripheralClass_Other +}, + +// IFX Modem on COMMs Module +{ + NV_ODM_GUID('s','p','i',' ','_','i','p','c'), + s_ffaInfnAddresses, + NV_ARRAY_SIZE(s_ffaInfnAddresses), + NvOdmPeripheralClass_Other +}, + +// NOTE: This list *must* end with a trailing comma. diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h b/arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h new file mode 100644 index 000000000000..bfbedb35945f --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/tegra_devkit_custopt.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 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. + * + */ + +/** + * @file + * <b>NVIDIA Tegra ODM Kit: + * Definition of bitfields inside the BCT customer option</b> + * + * @b Description: Defines the board-specific bitfields of the + * BCT customer option parameter, for NVIDIA + * Tegra development platforms. + * + * This file pertains to Whistler and Voyager. + */ + +#ifndef NVIDIA_TEGRA_DEVKIT_CUSTOPT_H +#define NVIDIA_TEGRA_DEVKIT_CUSTOPT_H + +#if defined(__cplusplus) +extern "C" +{ +#endif + +//---------- BOARD PERSONALITIES (BEGIN) ----------// +// On the Whistler boards, be sure to match the following +// switches with the personality setting you choose. +// +// SW2 = bits 3:0 (low nibble) +// SW3 = bits 7:4 (high nibble) + +#define TEGRA_DEVKIT_DEFAULT_PERSONALITY \ + TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_RANGE 7:0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_DEFAULT 0x0UL + +// VOYAGER, eMMC, NO TRACE (10x8 keypad) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_01 0x01UL // ULPI = baseband +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_05 0x05UL // ULPI = UART1 + +// VOYAGER, eMMC, with TRACE (7x1 keypad) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_11 0x11UL // ULPI = baseband +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_15 0x15UL // ULPI = UART1 + +// VOYAGER, NAND, NO TRACE (10x8 keypad) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_75 0x75UL // Voyager, NAND + +// WHISTLER, stand-alone +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C1 0xC1UL // KB = 13x1, TRACE, GMI = A/D NOR +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C3 0xC3UL // KB = 16x8, NO TRACE, GMI = NAND +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_C4 0xC4UL + + +// VOYAGER, USB2-ULPI (No UART1) +// Personality 71 is similar to the 75, except ULPI is enabled instead of UART1. +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_PERSONALITY_71 0x71UL + + +//---------- BOARD PERSONALITIES (END) ----------// + +/// Download transport +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_RANGE 10:8 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_NONE 0x1UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_UART 0x2UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_USB 0x3UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_TRANSPORT_ETHERNET 0x4UL + +/// Transport option (bus selector), for UART and Ethernet transport +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_RANGE 12:11 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_A 0x1UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_B 0x2UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_UART_OPTION_C 0x3UL + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_RANGE 12:11 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_ETHERNET_OPTION_SPI 0x1UL + +/// RIL selection +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_RANGE 14:13 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW 0x1UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_EMP_RAINBOW_ULPI 0x2UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_RIL_IFX 0x3UL + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_RANGE 17:15 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_DEFAULT 0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTA 0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTB 1 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTC 2 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTD 3 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_OPTION_UARTE 4 + +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_RANGE 19:18 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DEFAULT 0 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_NONE 1 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_DCC 2 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_CONSOLE_UART 3 + +// display options +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_RANGE 22:20 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_DEFAULT 0x0UL +// embedded panel (lvds, dsi, etc) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_EMBEDDED 0x0UL +// no panels (external or embedded) +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_NULL 0x1UL +// use hdmi as the primary +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_HDMI 0x2UL +// use crt as the primary +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DISPLAY_OPTION_CRT 0x3UL + + +// Enable DHCP +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_RANGE 23:23 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_DHCP_ENABLE 0x1UL + +/// Carveout RAM +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_RANGE 27:24 +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_1 0x1UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_2 0x2UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_3 0x3UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_4 0x4UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_5 0x5UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_6 0x6UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_7 0x7UL +#define TEGRA_DEVKIT_BCT_CARVEOUT_0_MEMORY_8 0x8UL //32 MB + + +/// Total RAM +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_RANGE 30:28 +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_DEFAULT 0x0UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_1 0x1UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_2 0x2UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_3 0x3UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_4 0x4UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_5 0x5UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_6 0x6UL +#define TEGRA_DEVKIT_BCT_SYSTEM_0_MEMORY_7 0x7UL +/// Soc low power state +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_RANGE 31:31 +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP0 0x0UL +#define TEGRA_DEVKIT_BCT_CUSTOPT_0_LPSTATE_LP1 0x1UL + +#if defined(__cplusplus) +} +#endif + +#endif |