diff options
Diffstat (limited to 'arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c')
-rw-r--r-- | arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c | 81 |
1 files changed, 56 insertions, 25 deletions
diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c index d897eb9f4ee3..29f52e2d7ae0 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_rtc.c @@ -30,10 +30,20 @@ * */ +#include <linux/time.h> #include "nvodm_pmu_tps6586x_rtc.h" #include "nvodm_pmu_tps6586x_i2c.h" #include "tps6586x_reg.h" +// macro SHIFT_TO_2009 if 1, uses 2009 as reference year instead of 1970 +// This is because RTC in PMU TPS6586x can store duration of 34 years, +// else we cannot retain date beyond 2004 +#define SHIFT_TO_2009 1 +#if SHIFT_TO_2009 +static unsigned long epoch = 2009; +static unsigned long epoch_sec = 0; +#endif + static NvBool bRtcNotInitialized = NV_TRUE; /* Read RTC count register */ @@ -43,12 +53,12 @@ Tps6586xRtcCountRead( NvU32* Count) { NvU32 ReadBuffer[2]; - + // 1) The I2C address pointer must not be left pointing in the range 0xC6 to 0xCA // 2) The maximum time for the address pointer to be in this range is 1ms // 3) Always read RTC_ALARM2 in the following order to prevent the address pointer - // from stopping at 0xC6: RTC_ALARM2_LO, then RTC_ALARM2_HI - + // from stopping at 0xC6: RTC_ALARM2_LO, then RTC_ALARM2_HI + if (Tps6586xRtcWasStartUpFromNoPower(hDevice) && bRtcNotInitialized) { Tps6586xRtcCountWrite(hDevice, 0); @@ -59,55 +69,76 @@ Tps6586xRtcCountRead( // The unit of the RTC count is second!!! 1024 tick = 1s. // Read all 40 bit and right move 10 = Read the hightest 32bit and right move 2 Tps6586xI2cRead32(hDevice, TPS6586x_RC6_RTC_COUNT4, &ReadBuffer[0]); - + Tps6586xI2cRead8(hDevice, TPS6586x_RCA_RTC_COUNT0, &ReadBuffer[1]); - + Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer[1]); - + // return second *Count = ReadBuffer[0]>>2; } - +#if SHIFT_TO_2009 + // calculate epoch_sec once + if (!epoch_sec) + epoch_sec = mktime(epoch,1,1,0,0,0); + *Count += epoch_sec; +#endif + return NV_TRUE; } /* Write RTC count register */ -NvBool +NvBool Tps6586xRtcCountWrite( - NvOdmPmuDeviceHandle hDevice, + NvOdmPmuDeviceHandle hDevice, NvU32 Count) { NvU32 ReadBuffer = 0; - +#if SHIFT_TO_2009 + // calculate epoch_sec once + if (!epoch_sec) + epoch_sec = mktime(epoch,1,1,0,0,0); + if (Count < (NvU32)epoch_sec) + { + // prevent setting date earlier than 'epoch' + pr_warning("\n Date being set cannot be earlier than least year=%d. " + "Setting as least year. ", (int)epoch); + // base year seconds count is 0 + Count = 0; + } + else + Count -= (NvU32)epoch_sec; +#endif + // To enable incrementing of the RTC_COUNT[39:0] from an initial value set by the host, - // the RTC_ENABLE bit should be written to 1 only after the RTC_OUT voltage reaches + // the RTC_ENABLE bit should be written to 1 only after the RTC_OUT voltage reaches // the operating range - + // Clear RTC_ENABLE before writing RTC_COUNT Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer); ReadBuffer = ReadBuffer & 0xDF; Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer); - + Tps6586xI2cWrite32(hDevice, TPS6586x_RC6_RTC_COUNT4, (Count<<2)); - Tps6586xI2cWrite8(hDevice, TPS6586x_RCA_RTC_COUNT0, 0); - + Tps6586xI2cWrite8(hDevice, TPS6586x_RCA_RTC_COUNT0, 0); + // Set RTC_ENABLE after writing RTC_COUNT Tps6586xI2cRead8(hDevice, TPS6586x_RC0_RTC_CTRL, &ReadBuffer); ReadBuffer = ReadBuffer | 0x20; Tps6586xI2cWrite8(hDevice, TPS6586x_RC0_RTC_CTRL, ReadBuffer); - + if (bRtcNotInitialized) bRtcNotInitialized = NV_FALSE; - + return NV_TRUE; } /* Read RTC alarm count register */ -NvBool +NvBool Tps6586xRtcAlarmCountRead( - NvOdmPmuDeviceHandle hDevice, + NvOdmPmuDeviceHandle hDevice, NvU32* Count) { return NV_FALSE; @@ -115,9 +146,9 @@ Tps6586xRtcAlarmCountRead( /* Write RTC alarm count register */ -NvBool +NvBool Tps6586xRtcAlarmCountWrite( - NvOdmPmuDeviceHandle hDevice, + NvOdmPmuDeviceHandle hDevice, NvU32 Count) { return NV_FALSE; @@ -125,7 +156,7 @@ Tps6586xRtcAlarmCountWrite( /* Reads RTC alarm interrupt mask status */ -NvBool +NvBool Tps6586xRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice) { return NV_FALSE; @@ -133,9 +164,9 @@ Tps6586xRtcIsAlarmIntEnabled(NvOdmPmuDeviceHandle hDevice) /* Enables / Disables the RTC alarm interrupt */ -NvBool +NvBool Tps6586xRtcAlarmIntEnable( - NvOdmPmuDeviceHandle hDevice, + NvOdmPmuDeviceHandle hDevice, NvBool Enable) { return NV_FALSE; @@ -143,7 +174,7 @@ Tps6586xRtcAlarmIntEnable( /* Checks if boot was from nopower / powered state */ -NvBool +NvBool Tps6586xRtcWasStartUpFromNoPower(NvOdmPmuDeviceHandle hDevice) { NvU32 Data = 0; |