diff options
Diffstat (limited to 'arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b')
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 + |