diff options
author | rhsieh <rhsieh@nvidia.com> | 2010-06-28 10:25:03 -0400 |
---|---|---|
committer | Antti Hatala <ahatala@nvidia.com> | 2010-06-29 04:10:01 -0700 |
commit | 7ddeb18acc426474d4f5447eb45ca7f29671aa55 (patch) | |
tree | 432313599f9b69ad9f5ada9a7c56e5f021265649 /arch/arm | |
parent | d563271ec962dcb8ef677c45ff63e6c016cdb25a (diff) |
tegra: [RTC Alarm Clock] Implement TI pmu tps6586x by PMIC (pwr_int) pin
Integrate PMU RTC alarm function from K29 to K32.
Bug 701881
Change-Id: Iee137be5a2e9a369611037da4c39b9f443ce8979
Reviewed-on: http://git-master/r/3265
Reviewed-by: Ching Kuang (Roger) Hsieh <rhsieh@nvidia.com>
Tested-by: Ching Kuang (Roger) Hsieh <rhsieh@nvidia.com>
Reviewed-by: Wilson Chen <wichen@nvidia.com>
Reviewed-by: Antti Hatala <ahatala@nvidia.com>
Diffstat (limited to 'arch/arm')
8 files changed, 208 insertions, 13 deletions
diff --git a/arch/arm/mach-tegra/include/nvodm_pmu.h b/arch/arm/mach-tegra/include/nvodm_pmu.h index 2b768edbe5b4..b20f536ebb82 100644 --- a/arch/arm/mach-tegra/include/nvodm_pmu.h +++ b/arch/arm/mach-tegra/include/nvodm_pmu.h @@ -449,6 +449,30 @@ NvOdmPmuWriteRtc( NvU32 Count); /** + * Gets the alarm count in seconds of the current external RTC (in PMU). + * + * @param hDevice A handle to the PMU. + * @param Count A pointer to where to return the current counter in sec. + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool +NvOdmPmuReadAlarm( + NvOdmPmuDeviceHandle hDevice, + NvU32* Count); + +/** + * Updates alarm count value. + * + * @param hDevice A handle to the PMU. + * @param Count data with which to update the current counter in sec. + * @return NV_TRUE if successful, or NV_FALSE otherwise. + */ +NvBool +NvOdmPmuWriteAlarm( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count); + +/** * Returns whether or not the RTC is initialized. * * @param hDevice A handle to the PMU. 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 ec62ac6c4c17..ffe0b584340d 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 @@ -70,6 +70,8 @@ GetPmuInstance(NvOdmPmuDeviceHandle hDevice) Pmu.pfnInterruptHandler = Tps6586xInterruptHandler; Pmu.pfnReadRtc = Tps6586xReadRtc; Pmu.pfnWriteRtc = Tps6586xWriteRtc; + Pmu.pfnReadAlarm = Tps6586xReadAlarm; + Pmu.pfnWriteAlarm = Tps6586xWriteAlarm; Pmu.pfnIsRtcInitialized = Tps6586xIsRtcInitialized; } else if (NvOdmPeripheralGetGuid(NV_ODM_GUID('p','c','f','_','p','m','u','0'))) @@ -89,6 +91,8 @@ GetPmuInstance(NvOdmPmuDeviceHandle hDevice) Pmu.pfnInterruptHandler = Pcf50626InterruptHandler; Pmu.pfnReadRtc = Pcf50626RtcCountRead; Pmu.pfnWriteRtc = Pcf50626RtcCountWrite; + Pmu.pfnReadAlarm = NULL; + Pmu.pfnWriteAlarm = NULL; Pmu.pfnIsRtcInitialized = Pcf50626IsRtcInitialized; Pmu.pPrivate = NULL; Pmu.Hal = NV_TRUE; @@ -111,6 +115,8 @@ GetPmuInstance(NvOdmPmuDeviceHandle hDevice) Pmu.pfnInterruptHandler = Max8907bInterruptHandler; Pmu.pfnReadRtc = Max8907bRtcCountRead; Pmu.pfnWriteRtc = Max8907bRtcCountWrite; + Pmu.pfnReadAlarm = NULL; + Pmu.pfnWriteAlarm = NULL; Pmu.pfnIsRtcInitialized = Max8907bIsRtcInitialized; Pmu.pPrivate = NULL; Pmu.Hal = NV_TRUE; @@ -341,6 +347,28 @@ NvBool NvOdmPmuWriteRtc( return NV_FALSE; } +NvBool NvOdmPmuReadAlarm( + NvOdmPmuDeviceHandle hDevice, + NvU32 *Count) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnReadAlarm) + return pmu->pfnReadAlarm(pmu, Count); + return NV_FALSE; +} + +NvBool NvOdmPmuWriteAlarm( + NvOdmPmuDeviceHandle hDevice, + NvU32 Count) +{ + NvOdmPmuDevice *pmu = GetPmuInstance(hDevice); + + if (pmu && pmu->pfnWriteAlarm) + return pmu->pfnWriteAlarm(pmu, Count); + return NV_FALSE; +} + NvBool NvOdmPmuIsRtcInitialized(NvOdmPmuDeviceHandle hDevice) { 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 05cdea828a20..23a02f9bf6a9 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 @@ -63,6 +63,8 @@ typedef void (*pfnPmuInterruptHandler)(NvOdmPmuDeviceHandle); typedef NvBool (*pfnPmuReadRtc)(NvOdmPmuDeviceHandle, NvU32*); typedef NvBool (*pfnPmuWriteRtc)(NvOdmPmuDeviceHandle, NvU32); typedef NvBool (*pfnPmuIsRtcInitialized)(NvOdmPmuDeviceHandle); +typedef NvBool (*pfnPmuReadAlarm)(NvOdmPmuDeviceHandle, NvU32*); +typedef NvBool (*pfnPmuWriteAlarm)(NvOdmPmuDeviceHandle, NvU32); typedef struct NvOdmPmuDeviceRec { @@ -80,6 +82,8 @@ typedef struct NvOdmPmuDeviceRec pfnPmuInterruptHandler pfnInterruptHandler; pfnPmuReadRtc pfnReadRtc; pfnPmuWriteRtc pfnWriteRtc; + pfnPmuReadAlarm pfnReadAlarm; + pfnPmuWriteAlarm pfnWriteAlarm; pfnPmuIsRtcInitialized pfnIsRtcInitialized; void *pPrivate; NvBool Hal; diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c index 099422df6e9c..f708f4ad89cd 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.c @@ -1808,6 +1808,17 @@ NvBool Tps6586xWriteRtc( NvOdmPmuDeviceHandle hDevice, NvU32 Count) return (Tps6586xRtcCountWrite(hDevice, Count)); } +NvBool Tps6586xReadAlarm( NvOdmPmuDeviceHandle hDevice, NvU32 *Count) +{ + *Count = 0; + return (Tps6586xRtcAlarmCountRead(hDevice, Count)); +} + +NvBool Tps6586xWriteAlarm( NvOdmPmuDeviceHandle hDevice, NvU32 Count) +{ + return (Tps6586xRtcAlarmCountWrite(hDevice, Count)); +} + NvBool Tps6586xIsRtcInitialized( NvOdmPmuDeviceHandle hDevice) { return ((Tps6586xRtcWasStartUpFromNoPower(hDevice))? NV_FALSE: NV_TRUE); diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h index ee25ecca8684..e1629a54a1f4 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x.h @@ -86,6 +86,8 @@ NvBool Tps6586xSetChargingCurrent( NvOdmPmuDeviceHandle hDevice, NvOdmPmuChargin void Tps6586xInterruptHandler( NvOdmPmuDeviceHandle hDevice); NvBool Tps6586xReadRtc( NvOdmPmuDeviceHandle hDevice, NvU32 *Count); NvBool Tps6586xWriteRtc( NvOdmPmuDeviceHandle hDevice, NvU32 Count); +NvBool Tps6586xReadAlarm( NvOdmPmuDeviceHandle hDevice, NvU32 *Count); +NvBool Tps6586xWriteAlarm( NvOdmPmuDeviceHandle hDevice, NvU32 Count); NvBool Tps6586xIsRtcInitialized( NvOdmPmuDeviceHandle hDevice); #if defined(__cplusplus) diff --git a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c index a9b6e4a89c31..8150fb19d3ce 100644 --- a/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c +++ b/arch/arm/mach-tegra/odm_kit/adaptations/pmu/tps6586x/nvodm_pmu_tps6586x_interrupt.c @@ -37,13 +37,17 @@ #include "nvodm_services.h" #include "nvodm_pmu_tps6586x_batterycharger.h" +/* INT_MASK3 */ #define TPS6586X_INT_BATT_INST 0x01 #define TPS6586X_INT_PACK_COLD_DET 0x02 #define TPS6586X_INT_PACK_HOT_DET 0x04 - -#define TPS6586X_INT_USB_DETECTION 0x04 -#define TPS6586X_INT_AC_DETECTION 0x08 -#define TPS6586X_INT_LOWSYS_DETECTION 0x40 +/* INT_MASK4 */ +#define TPS6586X_INT_ALM2_INST 0x02 +/* INT_MASK5 */ +#define TPS6586X_INT_USB_DETECTION 0x04 +#define TPS6586X_INT_AC_DETECTION 0x08 +#define TPS6586X_INT_ALM1_DETECTION 0x10 +#define TPS6586X_INT_LOWSYS_DETECTION 0x40 NvBool Tps6586xSetupInterrupt(NvOdmPmuDeviceHandle hDevice, TPS6586xStatus *pmuStatus) @@ -114,31 +118,43 @@ void Tps6586xInterruptHandler_int(NvOdmPmuDeviceHandle hDevice, pmuStatus->powerGood |= ((data & 0xFF)<<8); /* INT_ACK3 */ - /* LOW SYS */ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB7_INT_ACK3, &data)) { return; } if (data != 0) { + /* ACK_RTCALM1 */ + if (data&0x01) + { + /* printk("%s ACK_RTC_ALM_1 detect!!!\n", __func__); */ + } + + /* ACK_CHGTEMP */ if (data&0x40) { pmuStatus->highTemp = NV_TRUE; } - if (data&0xc0) + /* ACK_ACDET & ACK_USBDET */ + if (data&0x0C) { pmuStatus->mChgPresent = NV_TRUE; } } /* INT_ACK4 */ - /* CHG TEMP */ if (!Tps6586xI2cRead8(hDevice, TPS6586x_RB8_INT_ACK4, &data)) { return; } if (data != 0) { + /* ACK_RTCALM2 */ + if (data&0x04) + { + /* printk("%s ACK_RTC_ALM_2 detect!!!\n", __func__); */ + } + /* LOW SYS */ if (data&0x02) { pmuStatus->lowBatt = NV_TRUE; 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 889cf2bbc6ff..80942c232c83 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 @@ -41,9 +41,15 @@ #define OFFSET_BASE_YEAR 1 #if OFFSET_BASE_YEAR static unsigned long epoch = 2009; +#define epoch_end 2037L static unsigned long epoch_sec = 0; #endif +#define RTC_LIMITED 1 + +static NvBool rtc_alarm_active = NV_FALSE; /* RTC_ALARM_ACTIVE */ +static NvBool ALARM1_used = NV_FALSE; + static NvBool bRtcNotInitialized = NV_TRUE; /* Read RTC count register */ @@ -61,8 +67,13 @@ Tps6586xRtcCountRead( if (Tps6586xRtcWasStartUpFromNoPower(hDevice) && bRtcNotInitialized) { +#if RTC_LIMITED + Tps6586xRtcCountWrite(hDevice, (NvU32)mktime(epoch,1,1,0,0,0)); + *Count = 0; +#else /* RTC_LIMITED */ Tps6586xRtcCountWrite(hDevice, 0); *Count = 0; +#endif /* RTC_LIMITED */ } else { @@ -81,7 +92,7 @@ Tps6586xRtcCountRead( // calculate epoch_sec once if (!epoch_sec) epoch_sec = mktime(epoch,1,1,0,0,0); - *Count += epoch_sec; + *Count += (NvU32)epoch_sec; #endif return NV_TRUE; @@ -105,11 +116,20 @@ Tps6586xRtcCountWrite( 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 +#if RTC_LIMITED + Count = (NvU32)epoch_sec; //reset RTC count to 2010/01/01 00:00:00 +#else /* RTC_LIMITED */ Count = 0; +#endif /* RTC_LIMITED */ } else Count -= (NvU32)epoch_sec; -#endif +#if RTC_LIMITED + if (Count > (NvU32)mktime(epoch_end,12,31,23,59,59)) + Count = (NvU32)epoch_sec; //reset RTC count to 2010/01/01 00:00:00 +#endif /* RTC_LIMITED */ + +#endif /*OFFSET_BASE_YEAR */ // Switch to 32KHz crystal oscillator // POR_SRC_SEL=1 and OSC_SRC_SEL=1 @@ -147,7 +167,30 @@ Tps6586xRtcAlarmCountRead( NvOdmPmuDeviceHandle hDevice, NvU32* Count) { - return NV_FALSE; + NvU32 Counter; + NvU32 ReadBuffer[3]; + + if ( rtc_alarm_active ) { + + if ( ALARM1_used ) { + Tps6586xI2cRead8(hDevice, TPS6586x_RC3_RTC_ALARM1_LO, &ReadBuffer[2]); + Tps6586xI2cRead8(hDevice, TPS6586x_RC2_RTC_ALARM1_MID, &ReadBuffer[1]); + Tps6586xI2cRead8(hDevice, TPS6586x_RC1_RTC_ALARM1_HI, &ReadBuffer[0]); + Counter = (ReadBuffer[0] << 16) + (ReadBuffer[1] << 8) + ReadBuffer[2]; + *Count = Counter >> 10; + } else { //( ALARM1_used ) + Tps6586xI2cRead8(hDevice, TPS6586x_RC5_RTC_ALARM2_LO, &ReadBuffer[1]); + Tps6586xI2cRead8(hDevice, TPS6586x_RC4_RTC_ALARM2_HI, &ReadBuffer[0]); + Counter = (ReadBuffer[0]<<8) + ReadBuffer[1]; + *Count = Counter << 2; + } //( ALARM1_used ) + + return NV_TRUE; + + } else { // ( rtc_alarm_active ) + return NV_FALSE; + } // ( rtc_alarm_active ) + } /* Write RTC alarm count register */ @@ -157,7 +200,74 @@ Tps6586xRtcAlarmCountWrite( NvOdmPmuDeviceHandle hDevice, NvU32 Count) { - return NV_FALSE; + NvU32 ReadBuffer32; + NvU32 Counter; + NvU32 temp; + + NvU32 alarm1_start_sec; + NvU32 alarm1_end_sec; + NvU32 alarm2_start_sec; + NvU32 alarm2_end_sec; + + alarm1_start_sec = 0; //2^(10-10)-1 = 2^0-1 = 0 + alarm1_end_sec = 16384; //2^(24-10) = 2^14 =16384 sec = 273 min 4 sec = 4 hr 33min 4 sec + + alarm2_start_sec = 3; //2^(12-10)-1 = 2^2-1 = 3 + alarm2_end_sec = 262144; //2^(28-10)= 2^18 = 262144sec = 4369min 4sec = 72hr 49min 4sec = 3day 0hr 49min 4sec + + if ( Count < alarm2_end_sec && Count > alarm1_start_sec ) { + rtc_alarm_active = NV_TRUE; + if ( Count < alarm1_end_sec ) + ALARM1_used = NV_TRUE; + else + ALARM1_used = NV_FALSE; + } + + if ( rtc_alarm_active ) { + + if ( ALARM1_used ) { + + if (Count >= alarm1_end_sec || Count <= alarm1_start_sec) + return NV_FALSE; + + Tps6586xI2cRead32(hDevice, TPS6586x_RC6_RTC_COUNT4, &ReadBuffer32); + Tps6586xI2cRead8(hDevice, TPS6586x_RCA_RTC_COUNT0, &temp); + ReadBuffer32 &= 0x0000ffff; //bit[23:08] + Counter = (ReadBuffer32<<8)+ temp; + Counter += Count << 10; + + Tps6586xI2cWrite8(hDevice, TPS6586x_RC3_RTC_ALARM1_LO, ((Counter >> 0) & 0xFF)); + Tps6586xI2cWrite8(hDevice, TPS6586x_RC2_RTC_ALARM1_MID, ((Counter >> 8) & 0xFF)); + Tps6586xI2cWrite8(hDevice, TPS6586x_RC1_RTC_ALARM1_HI, ((Counter >> 16) & 0xFF)); + //FIXME: + Tps6586xI2cRead8(hDevice, TPS6586x_RB4_INT_MASK5, &temp); + temp = temp & 0xEF; + Tps6586xI2cWrite8(hDevice, TPS6586x_RB4_INT_MASK5, temp); + + } else { //( ALARM1_used ) + + if (Count >= alarm2_end_sec || Count <= alarm2_start_sec) + return NV_FALSE; + + Tps6586xI2cRead32(hDevice, TPS6586x_RC6_RTC_COUNT4, &ReadBuffer32); + Tps6586xI2cRead8(hDevice, TPS6586x_RCA_RTC_COUNT0, &temp); + ReadBuffer32 &= 0x000ffff0; //bit[27:12] + Counter = ReadBuffer32 >> 4; + Counter += Count >>2; //(Count*4sec) + + Tps6586xI2cWrite8(hDevice, TPS6586x_RC5_RTC_ALARM2_LO, ((Counter >> 0) & 0xFF)); + Tps6586xI2cWrite8(hDevice, TPS6586x_RC4_RTC_ALARM2_HI, ((Counter >> 8) & 0xFF)); + //FIXME: + Tps6586xI2cRead8(hDevice, TPS6586x_RB3_INT_MASK4, &temp); + temp = temp & 0xFD; + Tps6586xI2cWrite8(hDevice, TPS6586x_RB3_INT_MASK4, temp); + + } //( ALARM1_used ) + return NV_TRUE; + } else { // ( rtc_alarm_active ) + return NV_FALSE; + } // ( rtc_alarm_active ) + } /* Reads RTC alarm interrupt mask status */ diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c index 3eae7fc4efb7..8afe5ef11ee8 100644 --- a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c +++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c @@ -316,7 +316,7 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] = #else {NV_FALSE, 17, NvOdmWakeupPadPolarity_High}, #endif - {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] @@ -668,7 +668,7 @@ NvOdmQueryPinAttributes(const NvOdmPinAttrib** pPinAttributes) NvBool NvOdmQueryGetPmuProperty(NvOdmPmuProperty* pPmuProperty) { - pPmuProperty->IrqConnected = NV_FALSE; + pPmuProperty->IrqConnected = NV_TRUE; pPmuProperty->PowerGoodCount = 0x7E7E; pPmuProperty->IrqPolarity = NvOdmInterruptPolarity_Low; pPmuProperty->CorePowerReqPolarity = NvOdmCorePowerReqPolarity_Low; |