summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b')
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/Makefile22
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.c193
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/ad5258_dpm.h92
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.c123
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_i2c.h63
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/fan5355_buck_reg.h48
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c2324
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h160
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.c101
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_adc.h63
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.c97
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_batterycharger.h71
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c365
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h82
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c172
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.h58
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_reg.h398
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c260
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.h97
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_supply_info_table.h197
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.c119
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_i2c.h65
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/mic2826_reg.h181
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.c190
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_i2c.h109
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/tca6416_expander_reg.h69
26 files changed, 5719 insertions, 0 deletions
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
+