diff options
author | Jon Mayo <jmayo@nvidia.com> | 2010-09-09 11:46:18 -0700 |
---|---|---|
committer | Varun Colbert <vcolbert@nvidia.com> | 2010-10-26 15:03:36 -0700 |
commit | 35e97aa59eaa0cc7233c100edc0aa3e7b4e1605e (patch) | |
tree | 743512854b2ce749bd92eb09c6ae52688b8ff1a8 /arch | |
parent | dc9cea61b3333432d6c1d2003a1bdb9ce055f04a (diff) |
[arm/tegra] support RTC alarm interrupt in odm_kit
New API added to odm_kit to register a callback to use on RTC interrupt.
Supported added for RTC alarms in the max8907b PMU.
Bug 717253
Bug 734529
Change-Id: I34abebd7dd3caf4ef8923fcf651c50f6d245f6b4
Reviewed-on: http://git-master/r/7328
Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
Tested-by: Jonathan Mayo <jmayo@nvidia.com>
Reviewed-by: Aleksandr Frid <afrid@nvidia.com>
Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Diffstat (limited to 'arch')
10 files changed, 380 insertions, 73 deletions
diff --git a/arch/arm/mach-tegra/include/nvodm_pmu.h b/arch/arm/mach-tegra/include/nvodm_pmu.h index b20f536ebb82..00e94168d1ef 100644 --- a/arch/arm/mach-tegra/include/nvodm_pmu.h +++ b/arch/arm/mach-tegra/include/nvodm_pmu.h @@ -482,6 +482,35 @@ NvBool NvOdmPmuIsRtcInitialized( NvOdmPmuDeviceHandle hDevice); +/** + * Registers a callback function for PMU RTC Alarm. + * + * @param hDevice A handle to the PMU. + * @param func Callback function to call on alarm interrupt. + * @return NV_TRUE if successfully registered, or NV_FALSE on failure. + */ +NvBool +NvOdmPmuAlarmHandlerSet( + NvOdmPmuDeviceHandle hDevice, + NvBool (*func)(NvOdmPmuDeviceHandle)); + +/** + * Prep PMU for suspend. + * @param hDevice A handle to the PMU. + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool +NvOdmPmuSuspendRtc( + NvOdmPmuDeviceHandle hDevice); + +/** + * Restore PMU from suspend. + * @param hDevice A handle to the PMU. + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool +NvOdmPmuResumeRtc( + NvOdmPmuDeviceHandle hDevice); #if defined(__cplusplus) } 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 index d7f38d091b29..e8836ba6401c 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c @@ -39,6 +39,7 @@ #include "max8907b_i2c.h" #include "max8907b_interrupt.h" #include "max8907b_batterycharger.h" +#include "max8907b_rtc.h" #include "max8907b_supply_info_table.h" #include "fan5355_buck_reg.h" #include "fan5355_buck_i2c.h" @@ -2250,6 +2251,20 @@ void Max8907bInterruptHandler( NvOdmPmuDeviceHandle hDevice) Max8907bInterruptHandler_int(hDevice, &((Max8907bPrivData*)hDevice->pPrivate)->pmuStatus); } +NvBool +Max8907bRtcSuspend( + NvOdmPmuDeviceHandle hDevice) +{ + return Max8907bRtcAlarmIntEnable(hDevice, 1); +} + +NvBool +Max8907bRtcResume( + NvOdmPmuDeviceHandle hDevice) +{ + return Max8907bRtcAlarmIntEnable(hDevice, 0); +} + /**************** Secondary PMU MIC2826 Programming */ static NvBool MIC2826ReadVoltageReg( 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 index ce66a64c9716..10fb83f59eb6 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h @@ -149,7 +149,15 @@ Max8907bSetChargingCurrent( NvOdmPmuDeviceHandle hDevice, NvOdmPmuChargingPath chargingPath, NvU32 chargingCurrentLimitMa, - NvOdmUsbChargerType ChargerType); + NvOdmUsbChargerType ChargerType); + +NvBool +Max8907bRtcSuspend( + NvOdmPmuDeviceHandle hDevice); + +NvBool +Max8907bRtcResume( + NvOdmPmuDeviceHandle hDevice); void Max8907bInterruptHandler( NvOdmPmuDeviceHandle hDevice); 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 index 0f7a09446876..cb4e6d71d2ed 100644 --- 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 @@ -29,7 +29,6 @@ * POSSIBILITY OF SUCH DAMAGE. * */ - #include "max8907b.h" #include "max8907b_i2c.h" #include "max8907b_reg.h" @@ -294,7 +293,7 @@ NvBool Max8907bRtcI2cReadTime( for (i = 0; i < MAX8907B_I2C_RETRY_CNT; i++) { NvU32 TransactionCount = 0; - ReadBuffer[0] = Addr & 0xFF; + ReadBuffer[0] = Addr; TransactionInfo[TransactionCount].Address = MAX8907B_RTC_SLAVE_ADDR; TransactionInfo[TransactionCount].Buf = &ReadBuffer[0]; @@ -363,3 +362,100 @@ NvBool Max8907bRtcI2cReadTime( return NV_FALSE; } + +NvBool Max8907bRtcI2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data) +{ + NvU32 i; + NvU8 WriteBuffer[2]; + 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] = Addr; + WriteBuffer[1] = Data; + + TransactionInfo.Address = MAX8907B_RTC_SLAVE_ADDR; + 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(("Max8907bRtcI2cWrite8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("Max8907bRtcI2cWrite8 Failed: SlaveNotFound\n")); + break; + } + return NV_FALSE; +} + +NvBool Max8907bRtcI2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *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; + 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; + + 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; + + status = NvOdmI2cTransaction(hPmu->hOdmI2C, &TransactionInfo[0], + TransactionCount, MAX8907B_I2C_SPEED_KHZ, NV_WAIT_INFINITE); + if (status == NvOdmI2cStatus_Success) + { + *Data = ReadBuffer[0]; + return NV_TRUE; + } + } + + // Transaction Error + switch (status) + { + case NvOdmI2cStatus_Timeout: + NVODMPMU_PRINTF(("Max8907bRtcI2cRead8 Failed: Timeout\n")); + break; + case NvOdmI2cStatus_SlaveNotFound: + default: + NVODMPMU_PRINTF(("Max8907bRtcI2cRead8 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 index c4b5c634c4fa..579068ebc03b 100644 --- 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 @@ -73,6 +73,15 @@ NvBool Max8907bRtcI2cReadTime( NvU8 Addr, NvU32 *Data); +NvBool Max8907bRtcI2cWrite8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 Data); + +NvBool Max8907bRtcI2cRead8( + NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, + NvU8 *Data); #if defined(__cplusplus) } #endif 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 index 38110f83c5a0..cc3ab9859fa4 100755 --- 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 @@ -34,20 +34,21 @@ #include "max8907b_interrupt.h" #include "max8907b_i2c.h" #include "max8907b_reg.h" +#include "max8907b_rtc.h" #include "max8907b_batterycharger.h" #include "nvodm_services.h" -NvBool +NvBool Max8907bSetupInterrupt( NvOdmPmuDeviceHandle hDevice, Max8907bStatus *pmuStatus) { NvBool status = NV_FALSE; - NvU8 data = 0; + NvU8 data = 0; NV_ASSERT(hDevice); NV_ASSERT(pmuStatus); - + /* Init Pmu Status */ pmuStatus->lowBatt = NV_FALSE; pmuStatus->highTemp = NV_FALSE; @@ -81,15 +82,31 @@ Max8907bSetupInterrupt( if (!Max8907bI2cWrite8(hDevice, MAX8907B_ON_OFF_IRQ2, data)) return NV_FALSE; - // RTC_IRQ + // disable ALARM0 + data = 0; + if (!Max8907bRtcI2cWrite8(hDevice, MAX8907B_ALARM0_CNTL, data)) + return NV_FALSE; + + // disable ALARM1 data = 0; - if (!Max8907bI2cWrite8(hDevice, MAX8907B_RTC_IRQ, data)) + if (!Max8907bRtcI2cWrite8(hDevice, MAX8907B_ALARM1_CNTL, data)) + return NV_FALSE; + + // clear RTC_IRQ + if (!Max8907bRtcI2cRead8(hDevice, MAX8907B_RTC_IRQ, &data)) + return NV_FALSE; + + // RTC_IRQ_MASK - disable ALARM0 and ALARM1 + data = + ( MAX8907B_RTC_IRQ_ALARM0_R_MASK << MAX8907B_RTC_IRQ_ALARM0_R_SHIFT ) | + ( MAX8907B_RTC_IRQ_ALARM1_R_MASK << MAX8907B_RTC_IRQ_ALARM1_R_SHIFT ); + if (!Max8907bRtcI2cWrite8(hDevice, MAX8907B_RTC_IRQ_MASK, data)) return NV_FALSE; return NV_TRUE; } -void +void Max8907bInterruptHandler_int( NvOdmPmuDeviceHandle hDevice, Max8907bStatus *pmuStatus) @@ -161,12 +178,29 @@ Max8907bInterruptHandler_int( return; } + + // RTC_STATUS + if (!Max8907bRtcI2cRead8(hDevice, MAX8907B_RTC_STATUS, &data)) + { + return; + } + // RTC_IRQ - if (!Max8907bI2cRead8(hDevice, MAX8907B_RTC_IRQ, &data)) + if (!Max8907bRtcI2cRead8(hDevice, MAX8907B_RTC_IRQ, &data)) { return; } + if (data) + { + if (data & + (MAX8907B_RTC_IRQ_ALARM1_R_MASK << MAX8907B_RTC_IRQ_ALARM1_R_SHIFT)) + { + /* disable further alarms from this source. */ + Max8907bRtcAlarmIntEnable(hDevice, 0); + if(hDevice->pfnAlarmInterrupt) + hDevice->pfnAlarmInterrupt(hDevice); + } + } return; } - 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 index 1c4d61a01a98..f2b301eb842c 100644 --- 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 @@ -68,10 +68,11 @@ static NvBool bRtcNotInitialized = NV_TRUE; -NvBool -Max8907bRtcCountRead( +static NvBool +Max8907bRtcTimeRead( NvOdmPmuDeviceHandle hDevice, - NvU32* Count) + NvU8 Addr, + NvU32 *Count) { NvU32 data = 0; NvU32 BcdHours, BcdMinutes, BcdSeconds; @@ -84,7 +85,7 @@ Max8907bRtcCountRead( *Count = 0; // Read seconds, minute, hour and weekday data from RTC registers - if (Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_SEC, &data)) + if (Max8907bRtcI2cReadTime(hDevice, Addr, &data)) { NVODMPMU_PRINTF(("\n Read time data-sec=0x%x ", data)); // Extract seconds, minute and hour data from RTC registers read @@ -98,7 +99,7 @@ Max8907bRtcCountRead( Seconds = BCD_TO_DECIMAL(BcdSeconds); // Read day, month, yy1 and yy2 data from RTC registers - if (Max8907bRtcI2cReadTime(hDevice, MAX8907B_RTC_DATE, &data)) + if (Max8907bRtcI2cReadTime(hDevice, Addr + 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 @@ -132,13 +133,13 @@ Max8907bRtcCountRead( } else { - NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. ")); + NVODMPMU_PRINTF(("\n Max8907bRtcTimeRead() error. ")); return NV_FALSE; } } else { - NVODMPMU_PRINTF(("\n Max8907bRtcCountRead() error. ")); + NVODMPMU_PRINTF(("\n Max8907bRtcTimeRead() error. ")); return NV_FALSE; } NVODMPMU_PRINTF(("\n *Count=0x%x ", *Count)); @@ -146,16 +147,28 @@ Max8907bRtcCountRead( } NvBool -Max8907bRtcAlarmCountRead( +Max8907bRtcCountRead( NvOdmPmuDeviceHandle hDevice, NvU32* Count) { - return NV_FALSE; + return Max8907bRtcTimeRead(hDevice, MAX8907B_RTC_SEC, Count); } NvBool -Max8907bRtcCountWrite( +Max8907bRtcAlarmCountRead( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count) +{ + if (!Max8907bRtcTimeRead(hDevice, MAX8907B_ALARM1_SEC, Count)) + return NV_FALSE; + return NV_TRUE; +} + +/* write time and date in a BCD format */ +static NvBool +Max8907bRtcTimeWrite( NvOdmPmuDeviceHandle hDevice, + NvU8 Addr, NvU32 Count) { NvU32 BcdHours, BcdMinutes, BcdSeconds; @@ -167,7 +180,7 @@ Max8907bRtcCountWrite( NvU32 data1; #endif - NVODMPMU_PRINTF(("\n Rtc write count=0x%x ", Count)); + NVODMPMU_PRINTF(("\n Rtc write count=0x%x to addr=0x%x", Count, Addr)); // convert seconds since reference time into date // NOTE: using linux specific convert function rtc_time_to_tm rtc_time_to_tm(Count, &tm); @@ -176,6 +189,22 @@ Max8907bRtcCountWrite( (tm.tm_mon + 1), tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, Count)); + // set the day, month, year + + // 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, Addr + MAX8907B_RTC_DATE, data))) + { + NVODMPMU_PRINTF(("\n Max8907bRtcTimeWrite() error. ")); + return NV_FALSE; + } + // Convert time to bcd format BcdHours = DECIMAL_TO_BCD(tm.tm_hour); BcdMinutes = DECIMAL_TO_BCD(tm.tm_min); @@ -183,64 +212,67 @@ Max8907bRtcCountWrite( 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 + if (!Max8907bRtcI2cWriteTime(hDevice, Addr, data)) { - NVODMPMU_PRINTF(("\n Max8907bRtcCountWrite() error. ")); + NVODMPMU_PRINTF(("\n Max8907bRtcTimeWrite() error. ")); return NV_FALSE; } return NV_TRUE; } + +NvBool +Max8907bRtcCountWrite( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + return Max8907bRtcTimeWrite(hDevice, MAX8907B_RTC_SEC, Count); +} + +/** + * Set the RTC alarm. + * @param hDevice handle to the PMU. + * @param Count seconds in the future, treat 0 as disable. + * @return NV_TRUE if successful, or NV_FALSE on failure. + */ NvBool Max8907bRtcAlarmCountWrite( NvOdmPmuDeviceHandle hDevice, NvU32 Count) { - return NV_FALSE; + NvBool alarm_int; + + /* disable alarms while setting */ + if (!Max8907bRtcAlarmIntEnable(hDevice, 0)) + return NV_FALSE; + + if (!Max8907bRtcTimeWrite(hDevice, MAX8907B_ALARM1_SEC, Count)) + return NV_FALSE; + + /* enable alarms if Count is non-zero. */ + if (!Max8907bRtcAlarmIntEnable(hDevice, Count != 0)) + return NV_FALSE; + +#if NV_DEBUG + NVODMPMU_PRINTF(("\n Max8907bRtcAlarmCountWrite() wrote count=0x%x. ", Count)); + if (!Max8907bRtcTimeRead(hDevice, MAX8907B_ALARM1_SEC, &Count)) + return NV_FALSE; + NVODMPMU_PRINTF(("\n Max8907bRtcAlarmCountWrite() read back count=0x%x. ", Count)); +#endif + return NV_TRUE; } NvBool Max8907bRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice) { + NvU8 data; + if (Max8907bRtcI2cRead8(hDevice, MAX8907B_RTC_IRQ_MASK, &data)) + if ((data >> MAX8907B_RTC_IRQ_ALARM1_R_SHIFT) + & MAX8907B_RTC_IRQ_ALARM1_R_MASK) + { + return NV_TRUE; + } return NV_FALSE; } @@ -249,7 +281,44 @@ Max8907bRtcAlarmIntEnable( NvOdmPmuDeviceHandle hDevice, NvBool Enable) { - return NV_FALSE; + NvU8 cntl_data, mask_data; + NvU8 tmp; + + if (Enable) + { + /* Alarm check of HOUR, MIN, SEC, YEAR, MONTH, DATE */ + cntl_data = 0x77; + /* mask everything except ALARM1. */ + mask_data = ~(MAX8907B_RTC_IRQ_ALARM1_R_MASK << MAX8907B_RTC_IRQ_ALARM1_R_SHIFT); + } + else + { + /* disable alarm comparisons. */ + cntl_data = 0; + /* mask everything, including ALARM1 */ + mask_data = ~0; + } + + if (!Max8907bRtcI2cWrite8(hDevice, MAX8907B_RTC_IRQ_MASK, mask_data)) + { + NVODMPMU_PRINTF(("\n Max8907bRtcAlarmIntEnable() error. ")); + return NV_FALSE; + } + + if (!Max8907bRtcI2cWrite8(hDevice, MAX8907B_ALARM1_CNTL, cntl_data)) + { + NVODMPMU_PRINTF(("\n Max8907bRtcAlarmIntEnable() error. ")); + return NV_FALSE; + } + + /* always force ALARM0 off */ + if (!Max8907bRtcI2cWrite8(hDevice, MAX8907B_ALARM0_CNTL, 0)) + { + NVODMPMU_PRINTF(("\n Max8907bRtcAlarmIntEnable() error. ")); + return NV_FALSE; + } + + return NV_TRUE; } NvBool diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c index ffe0b584340d..95075edf30c0 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c @@ -72,11 +72,15 @@ GetPmuInstance(NvOdmPmuDeviceHandle hDevice) Pmu.pfnWriteRtc = Tps6586xWriteRtc; Pmu.pfnReadAlarm = Tps6586xReadAlarm; Pmu.pfnWriteAlarm = Tps6586xWriteAlarm; + Pmu.pfnAlarmInterrupt = NULL; + Pmu.pfnEnableRtcInt = NULL; + Pmu.pfnSuspendRtc = NULL; + Pmu.pfnResumeRtc = NULL; Pmu.pfnIsRtcInitialized = Tps6586xIsRtcInitialized; } else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0'))) { - + Pmu.pfnSetup = Pcf50626Setup; Pmu.pfnRelease = Pcf50626Release; Pmu.pfnGetCaps = Pcf50626GetCapabilities; @@ -93,9 +97,13 @@ GetPmuInstance(NvOdmPmuDeviceHandle hDevice) Pmu.pfnWriteRtc = Pcf50626RtcCountWrite; Pmu.pfnReadAlarm = NULL; Pmu.pfnWriteAlarm = NULL; + Pmu.pfnAlarmInterrupt = NULL; + Pmu.pfnEnableRtcInt = NULL; + Pmu.pfnSuspendRtc = NULL; + Pmu.pfnResumeRtc = NULL; Pmu.pfnIsRtcInitialized = Pcf50626IsRtcInitialized; - Pmu.pPrivate = NULL; - Pmu.Hal = NV_TRUE; + Pmu.pPrivate = NULL; + Pmu.Hal = NV_TRUE; Pmu.Init = NV_FALSE; } else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('m','a','x','8','9','0','7','b'))) @@ -115,11 +123,15 @@ GetPmuInstance(NvOdmPmuDeviceHandle hDevice) Pmu.pfnInterruptHandler = Max8907bInterruptHandler; Pmu.pfnReadRtc = Max8907bRtcCountRead; Pmu.pfnWriteRtc = Max8907bRtcCountWrite; - Pmu.pfnReadAlarm = NULL; - Pmu.pfnWriteAlarm = NULL; + Pmu.pfnReadAlarm = Max8907bRtcAlarmCountRead; + Pmu.pfnWriteAlarm = Max8907bRtcAlarmCountWrite; + Pmu.pfnAlarmInterrupt = NULL; + Pmu.pfnEnableRtcInt = Max8907bRtcAlarmIntEnable; + Pmu.pfnSuspendRtc = Max8907bRtcSuspend; + Pmu.pfnResumeRtc = Max8907bRtcResume; Pmu.pfnIsRtcInitialized = Max8907bIsRtcInitialized; Pmu.pPrivate = NULL; - Pmu.Hal = NV_TRUE; + Pmu.Hal = NV_TRUE; Pmu.Init = NV_FALSE; } } @@ -376,7 +388,34 @@ NvOdmPmuIsRtcInitialized(NvOdmPmuDeviceHandle hDevice) if (pmu && pmu->pfnIsRtcInitialized) return pmu->pfnIsRtcInitialized(pmu); - + return NV_FALSE; } +NvBool +NvOdmPmuAlarmHandlerSet(NvOdmPmuDeviceHandle hDevice, pfnPmuAlarmInterrupt func) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + if (!pmu) + return NV_FALSE; + pmu->pfnAlarmInterrupt = func; + return NV_TRUE; +} + +NvBool +NvOdmPmuSuspendRtc(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + if (pmu && pmu->pfnSuspendRtc) + return pmu->pfnSuspendRtc(pmu); + return NV_FALSE; +} + +NvBool +NvOdmPmuResumeRtc(NvOdmPmuDeviceHandle hDevice) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + if (pmu && pmu->pfnResumeRtc) + return pmu->pfnResumeRtc(pmu); + return NV_FALSE; +} diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h index 23a02f9bf6a9..ef99ed9363f4 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h @@ -65,9 +65,13 @@ typedef NvBool (*pfnPmuWriteRtc)(NvOdmPmuDeviceHandle, NvU32); typedef NvBool (*pfnPmuIsRtcInitialized)(NvOdmPmuDeviceHandle); typedef NvBool (*pfnPmuReadAlarm)(NvOdmPmuDeviceHandle, NvU32*); typedef NvBool (*pfnPmuWriteAlarm)(NvOdmPmuDeviceHandle, NvU32); +typedef NvBool (*pfnPmuAlarmInterrupt)(NvOdmPmuDeviceHandle); +typedef NvBool (*pfnPmuEnableRtcInt)(NvOdmPmuDeviceHandle, NvBool); +typedef NvBool (*pfnPmuSuspendRtc)(NvOdmPmuDeviceHandle); +typedef NvBool (*pfnPmuResumeRtc)(NvOdmPmuDeviceHandle); typedef struct NvOdmPmuDeviceRec -{ +{ pfnPmuSetup pfnSetup; pfnPmuRelease pfnRelease; pfnPmuGetCaps pfnGetCaps; @@ -84,6 +88,10 @@ typedef struct NvOdmPmuDeviceRec pfnPmuWriteRtc pfnWriteRtc; pfnPmuReadAlarm pfnReadAlarm; pfnPmuWriteAlarm pfnWriteAlarm; + pfnPmuAlarmInterrupt pfnAlarmInterrupt; + pfnPmuEnableRtcInt pfnEnableRtcInt; + pfnPmuSuspendRtc pfnSuspendRtc; + pfnPmuResumeRtc pfnResumeRtc; pfnPmuIsRtcInitialized pfnIsRtcInitialized; void *pPrivate; NvBool Hal; diff --git a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c index 9e22d67dc84e..84da33aa6215 100644 --- a/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c +++ b/arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c @@ -1568,7 +1568,7 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] = {NV_FALSE, 15, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 15 - gmi_ad16 (SPI3_DOUT, DTV_SPI4_CS1) {NV_TRUE, 16, NvOdmWakeupPadPolarity_High}, // Wake Event 16 - rtc_irq {NV_TRUE, 17, NvOdmWakeupPadPolarity_High}, // Wake Event 17 - kbc_interrupt - {NV_FALSE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT) + {NV_TRUE, 18, NvOdmWakeupPadPolarity_Low}, // Wake Event 18 - pwr_int (PMIC_INT) {NV_FALSE, 19, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 19 - usb_vbus_wakeup[0] {NV_FALSE, 20, NvOdmWakeupPadPolarity_High}, // Wake Event 20 - usb_vbus_wakeup[1] {NV_FALSE, 21, NvOdmWakeupPadPolarity_Low}, // Wake Event 21 - usb_iddig[0] |