diff options
author | Wilson Chen <wichen@nvidia.com> | 2010-05-27 22:51:56 +0800 |
---|---|---|
committer | Janne Hellsten <jhellsten@nvidia.com> | 2010-06-01 03:13:32 -0700 |
commit | 5645d492c7ddb74c23f10b4daa479b333069516b (patch) | |
tree | 2b09819852417c45fdcc42ca5c9ce625bfa1f3e3 | |
parent | e5fb37702feb532b4e58660d9719c76fa7d8a79a (diff) |
tegra: [RTC Alarm Clock] implement TI pmu tps6586x by PMIC (pwr_int) pin
Bug 631330
Bug 690351
Bug 690993
Tested on Ap20/Harmony.
Change-Id: Id29c5fc8f5078ad4cb3aa1e43d0440c21ddd1a96
Reviewed-on: http://git-master/r/1725
Reviewed-by: Janne Hellsten <jhellsten@nvidia.com>
Tested-by: Janne Hellsten <jhellsten@nvidia.com>
9 files changed, 297 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 197a2c227e1d..781a13d448f8 100755 --- 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 @@ -2030,6 +2030,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 0c1f4fb2b9af..5fdcd563115b 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 @@ -94,6 +94,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 b3ac0b954a4e..f50d120ff386 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,18 +118,25 @@ 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; #if !defined(CONFIG_TEGRA_ODM_HARMONY) @@ -135,13 +146,18 @@ void Tps6586xInterruptHandler_int(NvOdmPmuDeviceHandle hDevice, } /* 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 5040e7004a77..958efb6d4b55 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; diff --git a/drivers/rtc/rtc-tegra-odm.c b/drivers/rtc/rtc-tegra-odm.c index a5ff518c5aa6..becfe334cb4a 100644 --- a/drivers/rtc/rtc-tegra-odm.c +++ b/drivers/rtc/rtc-tegra-odm.c @@ -33,6 +33,8 @@ #include <nvodm_pmu.h> +#define PMU_IOCTL_ENABLE 1 + /* Create a custom rtc structrue and move this to that structure */ static NvOdmPmuDeviceHandle hPmu = NULL; @@ -71,9 +73,96 @@ static int tegra_rtc_set_time(struct device *dev, struct rtc_time *tm) return 0; } +#if (PMU_IOCTL_ENABLE) +static int tegra_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) +{ + void __user *argp = (void __user *)arg; + struct rtc_wkalrm wkalrm; + NvU32 count = 0; + + switch (cmd) { + case RTC_ALM_READ: + NvOdmPmuReadAlarm(hPmu, &count); + wkalrm.time.tm_hour = count / 3600; + wkalrm.time.tm_min = (count - (wkalrm.time.tm_hour * 3600)) / 60; + wkalrm.time.tm_sec = (count - (wkalrm.time.tm_min * 60) - (wkalrm.time.tm_hour * 3600) ); + if (copy_to_user(argp, &count, sizeof(count))) + return -EFAULT; + break; + + case RTC_ALM_SET: + if (copy_from_user(&wkalrm, argp, sizeof(wkalrm))) + return -EFAULT; + count = wkalrm.time.tm_hour * 3600 + wkalrm.time.tm_min * 60 + wkalrm.time.tm_sec; + NvOdmPmuWriteAlarm(hPmu, count); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int tegra_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) +{ + + struct rtc_time *time = &wkalrm->time; + + NvU32 alarm_sec = 0; + NvOdmPmuReadAlarm(hPmu, &alarm_sec); + + rtc_time_to_tm(alarm_sec, time); + + return 0; +} + +static int tegra_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) +{ + struct rtc_time *time = &wkalrm->time; + NvU32 now; + NvU32 alarm_sec; + struct rtc_time now_time; + + pr_debug("wkalrm->enabled = %d\n", wkalrm->enabled); + if (wkalrm->enabled == 0) + return 0; + + if (!NvOdmPmuReadRtc(hPmu, &now)) { + pr_debug("NvOdmPmuReadRtc failed\n"); + return -1; + } + + rtc_time_to_tm(now, &now_time); + pr_debug( "read now_time %02d:%02d:%02d %02d/%02d/%04d\n", + now_time.tm_hour, now_time.tm_min, now_time.tm_sec, + now_time.tm_mon + 1, now_time.tm_mday, now_time.tm_year + 1900); + + pr_debug("write alarm_time %02d:%02d:%02d %02d/%02d/%04d\n", + time->tm_hour, time->tm_min, time->tm_sec, + time->tm_mon+1, time->tm_mday, time->tm_yday+1900); + + alarm_sec = (NvU32)mktime(now_time.tm_year + 1900, time->tm_mon+1, time->tm_mday, + time->tm_hour, time->tm_min, time->tm_sec); + if (alarm_sec < now) + alarm_sec = (NvU32)mktime(now_time.tm_year + 1901, time->tm_mon+1, time->tm_mday, + time->tm_hour, time->tm_min, time->tm_sec); + + pr_debug("alarm_sec = %u\n", alarm_sec); + + NvOdmPmuWriteAlarm(hPmu, alarm_sec-now); + + return 0; +} +#endif + static struct rtc_class_ops tegra_rtc_ops = { .read_time = tegra_rtc_read_time, .set_time = tegra_rtc_set_time, +#if (PMU_IOCTL_ENABLE) + .ioctl = tegra_rtc_ioctl, + .read_alarm = tegra_rtc_read_alarm, + .set_alarm = tegra_rtc_set_alarm, +#endif }; static int __init tegra_rtc_probe(struct platform_device *pdev) |