summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorJon Mayo <jmayo@nvidia.com>2010-09-09 11:46:18 -0700
committerVarun Colbert <vcolbert@nvidia.com>2010-10-26 15:03:36 -0700
commit35e97aa59eaa0cc7233c100edc0aa3e7b4e1605e (patch)
tree743512854b2ce749bd92eb09c6ae52688b8ff1a8 /arch
parentdc9cea61b3333432d6c1d2003a1bdb9ce055f04a (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')
-rw-r--r--arch/arm/mach-tegra/include/nvodm_pmu.h29
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.c15
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b.h10
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.c100
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_i2c.h9
-rwxr-xr-xarch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_interrupt.c50
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/max8907b/max8907b_rtc.c175
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.c53
-rw-r--r--arch/arm/mach-tegra/odm_kit/adaptations/pmu/pmu_hal.h10
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/whistler/nvodm_query.c2
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]