summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSachin Nikam <snikam@nvidia.com>2010-04-05 15:38:03 +0530
committerGary King <gking@nvidia.com>2010-04-05 20:29:46 -0700
commit6dbb4916287e842f3e8541a980e30ee0cc9479b4 (patch)
treeaf080feed52db654296f1098cc0c7467e6bbbcc0
parent27f64e9323656140b969d0f77cc2b898e8929a75 (diff)
nvec_battery:Handling critical battery condition
1. nvec.h:Correcting enum ordering for NvEcBatterySubtype as per ECI specs. NvEcBatterySubtype_SetRemainingCapacityAlarm and NvEcBatterySubtype_GetRemainingCapacityAlar >> Verified 2. Registering interrupt for LOW_BAT# from T20 pinmux table:- GPIO interrupt for Low battery on port w and pin 3 >> Already verified on Wince. On Android when 0% power is left device is shutdown. Harmony has this setting around 9.3V which is less when the battery is at 0%. 3. Enabling LOW_BAT# as a wakeup source 11 from suspend >> As point no. 2 is wokring this should also work. This is not verfied as in suspend battery discharge is slow. 4. Enabling Low capacity alarm as a wakeup source suspend >> As remaining capacity alarm is working this should also work. This is not verfied as in suspend battery discharge is slow. 5. Setting the 10% of Design capacit as threshold for Remaining capacity alaram event. >> Verified 6. Adding 4 functions which are needed for EC firmware validation NvOdmBatterySetRemCapacityAlarm NvOdmBatteryGetRemCapacityAlarm NvOdmBatterySetConfiguration NvOdmBatteryGetConfiguration >> Verified 7. Calling kernel_power_off() when device is running on only battery and it is ctitically low to gracefully shutdown the system. >> Verified Tested on harmony + eclair + battery Change-Id: I6f4c8a1866ba63c293813b180cc5b74714aa23cd Reviewed-on: http://git-master/r/976 Reviewed-by: Sachin Nikam <snikam@nvidia.com> Tested-by: Sachin Nikam <snikam@nvidia.com> Tested-by: Bharat Nihalani <bnihalani@nvidia.com> Reviewed-by: Gary King <gking@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/include/nvec.h2
-rw-r--r--arch/arm/mach-tegra/include/nvodm_query_gpio.h3
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c411
-rw-r--r--arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h52
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query.c2
-rw-r--r--arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c9
-rw-r--r--drivers/power/nvec_battery.c8
7 files changed, 435 insertions, 52 deletions
diff --git a/arch/arm/mach-tegra/include/nvec.h b/arch/arm/mach-tegra/include/nvec.h
index 4bd934f74a71..72c7b93640b3 100644
--- a/arch/arm/mach-tegra/include/nvec.h
+++ b/arch/arm/mach-tegra/include/nvec.h
@@ -635,8 +635,8 @@ typedef enum
NvEcBatterySubtype_GetManufacturer,
NvEcBatterySubtype_GetModel,
NvEcBatterySubtype_GetType,
- NvEcBatterySubtype_GetRemainingCapacityAlarm,
NvEcBatterySubtype_SetRemainingCapacityAlarm,
+ NvEcBatterySubtype_GetRemainingCapacityAlarm,
NvEcBatterySubtype_SetConfiguration,
NvEcBatterySubtype_GetConfiguration,
NvEcBatterySubtype_ConfigureEventReporting,
diff --git a/arch/arm/mach-tegra/include/nvodm_query_gpio.h b/arch/arm/mach-tegra/include/nvodm_query_gpio.h
index 6e0c449355bd..dd6461a2483d 100644
--- a/arch/arm/mach-tegra/include/nvodm_query_gpio.h
+++ b/arch/arm/mach-tegra/include/nvodm_query_gpio.h
@@ -147,6 +147,9 @@ typedef enum
/// Specifies a group for keys used to resume from EC keyboard.
NvOdmGpioPinGroup_WakeFromECKeyboard,
+ /// Specifies a group for Battery
+ NvOdmGpioPinGroup_Battery,
+
/// Specifies the total number of pin groups.
NvOdmGpioPinGroup_Num,
NvOdmGpioPinGroup_Force32 = 0x7FFFFFFF,
diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c
index b8919573ddeb..9a3d775f5308 100644
--- a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c
+++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery.c
@@ -36,22 +36,6 @@
#include "nvodm_battery.h"
#include "nvec.h"
-/*
- * Macro to disable EC calls for battery operations until EC firware
- * supports it
- */
-#define NVEC_BATTERY_DISABLED 0
-/*
- * Some extra battery info added which is not yet part of the BatteryData
- * structure.
- * Enable it to verify the these extra info with the EC firware
- */
-#define BATTERY_EXTRA_INFO 0
-
-/* Enable to wakeup the AP from suspend */
-#define NVODM_WAKEUP_FROM_BATTERY_EVENT 1
-#define NVODM_WAKEUP_FROM_AC_EVENT 1
-
NvBool NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(
NvOdmBatteryDevice *pBattContext,
NvOdmBatteryInstance BatteryInst,
@@ -103,6 +87,51 @@ NvBool NvOdmBatteryPrivGetCriticalCapacity(
NvOdmBatteryInstance BatteryInst,
NvU32 *pCriticalCapacity);
+NvBool NvOdmBatterySetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 RemCapAlarm);
+
+#if BATTERY_EXTRA_INFO
+NvBool NvOdmBatteryGetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 *RemCapAlarm);
+
+NvBool NvOdmBatterySetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 Configuration);
+
+NvBool NvOdmBatteryGetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *Configuration);
+#endif
+
+#if NVODM_LOWBATTERY_GPIO_INT
+/*
+ * GPIO interrupt handle for battery events
+ */
+static void
+NvOdmBatteryGpioInterruptHandler(void *args)
+{
+ NvOdmBatteryDevice *pBattContext = args;
+
+ NVODMBATTERY_PRINTF(("NvOdmBatteryGpioInterruptHandler:\n"));
+
+ if (pBattContext)
+ {
+ pBattContext->BatteryEvent = NvOdmBatteryEventType_RemainingCapacityAlarm;
+
+ if (pBattContext->hClientBattEventSem)
+ NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem);
+ }
+
+ NvRmGpioInterruptDone(pBattContext->GpioIntrHandle);
+}
+#endif
+
/*
* Gets the EC Firmware version number
*/
@@ -227,6 +256,210 @@ void NvOdmBatteryGetEvent(
}
/**
+ * Sets the battery remaining capacity alarm threshold.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param RemCapAlarm [IN] Capacity Units
+ */
+NvBool NvOdmBatterySetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 RemCapAlarm)
+{
+#if NVEC_BATTERY_DISABLED
+ ;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatterySetRemCapacityAlarm.\n"));
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_SetRemainingCapacityAlarm;
+ EcRequest.NumPayloadBytes = 2;
+ EcRequest.Payload[0] = (RemCapAlarm & 0x00FF);
+ EcRequest.Payload[1] = (RemCapAlarm & 0xFF00) >> 8;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatterySetRemCapacityAlarm\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NVODMBATTERY_PRINTF(("EcResponse.Status failed for NvOdmBatterySetRemCapacityAlarm\n"));
+ return NV_FALSE;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatterySetRemCapacityAlarm.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+#if BATTERY_EXTRA_INFO
+/**
+ * Gets the battery remaining capacity alarm threshold.
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param RemCapAlarm [OUT] Capacity Units
+ */
+NvBool NvOdmBatteryGetRemCapacityAlarm(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU16 *RemCapAlarm)
+{
+#if NVEC_BATTERY_DISABLED
+ *RemCapAlarm = 0;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetRemCapacityAlarm.\n"));
+ *RemCapAlarm = 0;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetRemainingCapacityAlarm;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatteryGetRemCapacityAlarm\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ *RemCapAlarm = EcResponse.Payload[0];
+ *RemCapAlarm |= EcResponse.Payload[1] << 8;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetRemCapacityAlarm.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Sets the battery capacity unit configuration (mAh or 10mWh)
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param Configuration [IN] Capacity Unit
+ */
+NvBool NvOdmBatterySetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 Configuration)
+{
+#if NVEC_BATTERY_DISABLED
+ ;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatterySetConfiguration.\n"));
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_SetConfiguration;
+ EcRequest.NumPayloadBytes = 1;
+ EcRequest.Payload[0] = Configuration;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatterySetConfiguration\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ NVODMBATTERY_PRINTF(("EcResponse.Status failed for NvOdmBatterySetConfiguration\n"));
+ return NV_FALSE;
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatterySetConfiguration.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+
+/**
+ * Gets the battery capacity unit configuration (mAh or 10mWh).
+ *
+ * @param hDevice [IN] A handle to the EC.
+ * @param BatteryInst [IN] The battery type.
+ * @param Configuration [OUT] Capacity Unit
+ */
+NvBool NvOdmBatteryGetConfiguration(
+ NvOdmBatteryDeviceHandle hDevice,
+ NvOdmBatteryInstance BatteryInst,
+ NvU8 *Configuration)
+{
+#if NVEC_BATTERY_DISABLED
+ *Configuration = 0;
+#else
+ NvError NvStatus = NvError_Success;
+ NvEcRequest EcRequest = {0};
+ NvEcResponse EcResponse = {0};
+ NvOdmBatteryDevice *pBattContext = NULL;
+
+ NVODMBATTERY_PRINTF(("[ENTER]NvOdmBatteryGetConfiguration.\n"));
+ *Configuration = 0;
+ pBattContext = (NvOdmBatteryDevice *)hDevice;
+
+ /* Fill up request structure */
+ EcRequest.PacketType = NvEcPacketType_Request;
+ EcRequest.RequestType = NvEcRequestResponseType_Battery;
+ EcRequest.RequestSubtype = NvEcBatterySubtype_GetConfiguration;
+ EcRequest.NumPayloadBytes = 0;
+ EcRequest.Payload[0] = 0;
+
+ /* Request to EC */
+ NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
+ sizeof(EcRequest), sizeof(EcResponse));
+ if (NvSuccess != NvStatus)
+ {
+ NVODMBATTERY_PRINTF(("NvEcSendRequest failed for NvOdmBatteryGetConfiguration\n"));
+ return NV_FALSE;
+ }
+
+ if(EcResponse.Status == NvEcStatus_Success)
+ {
+ *Configuration = EcResponse.Payload[0];
+ }
+
+ NVODMBATTERY_PRINTF(("[EXIT]NvOdmBatteryGetConfiguration.\n"));
+#endif /* end of NVEC_BATTERY_DISABLED */
+ return NV_TRUE;
+}
+#endif
+
+/**
* Gets the battery Current.
*
* @param hDevice [IN] A handle to the EC.
@@ -750,6 +983,8 @@ NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(NvOdmBatteryDevice *pBattContext,
NvEcRequest EcRequest = {0};
NvEcResponse EcResponse = {0};
+ NVODMBATTERY_PRINTF(("NvOdmBatteryPrivGetSlotStatusAndCapacityGuage:Enter"));
+
/* Fill up request structure */
EcRequest.PacketType = NvEcPacketType_Request;
EcRequest.RequestType = NvEcRequestResponseType_Battery;
@@ -789,6 +1024,7 @@ NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(NvOdmBatteryDevice *pBattContext,
return NV_FALSE;
}
+ NVODMBATTERY_PRINTF(("NvOdmBatteryPrivGetSlotStatusAndCapacityGuage:Exit"));
return NV_TRUE;
#endif /* end of NVEC_BATTERY_DISABLED */
}
@@ -926,6 +1162,11 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
NvS32 MajorVersion = 0, MinorVersion = 0;
NvEcRequest EcRequest = {0};
NvEcResponse EcResponse = {0};
+#if NVODM_LOWBATTERY_GPIO_INT
+ NvOsInterruptHandler IntrHandler = {NULL};
+#endif
+ NvU32 BatteryDesignCap = 0;
+ NvU16 RemCapAlarm = 0;
NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryDeviceOpen. \n"));
@@ -956,17 +1197,8 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
goto Cleanup;
}
- /* Minor Version 2 is R01 */
- if (MinorVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01)
- {
- pBattContext->FirmwareVersionR01 = NV_TRUE;
- NVODMBATTERY_PRINTF(("EC Firmware Version is R01\n"));
- }
- else
- {
- pBattContext->FirmwareVersionR01 = NV_FALSE;
- NVODMBATTERY_PRINTF(("EC Firmware Version is beyond R01\n"));
- }
+ pBattContext->ECVersion = MinorVersion;
+ NVODMBATTERY_PRINTF(("EC Firmware Version = 0x%x\n", MinorVersion));
if (hOdmSemaphore != NULL && *hOdmSemaphore != NULL)
{
@@ -988,7 +1220,7 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
goto Cleanup;
}
- if (MinorVersion >= NVODM_BATTERY_EC_FIRMWARE_VER_R04)
+ if (pBattContext->ECVersion >= NVODM_BATTERY_EC_FIRMWARE_VER_R04)
{
#if NVODM_WAKEUP_FROM_BATTERY_EVENT
/* Configure the Batter present event as a wakeup */
@@ -998,7 +1230,11 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
NvEcBatterySubtype_ConfigureWake;
EcRequest.NumPayloadBytes = 2;
EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE;
- EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT;
+ EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT
+#if NVODM_BATTERY_LOW_CAPACITY_ALARM
+ | NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT
+#endif
+ ;
NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse,
sizeof(EcRequest), sizeof(EcResponse));
@@ -1048,6 +1284,13 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
if (EcResponse.Status != NvEcStatus_Success)
goto Cleanup;
+
+ /* Get the design capacity */
+ NvOdmBatteryGetBatteryFullLifeTime(pBattContext, NvOdmBatteryInst_Main,
+ &BatteryDesignCap);
+ /* Set the remaining capacity alarm for 10% of the design capacity */
+ RemCapAlarm = (BatteryDesignCap * 10)/100;
+ NvOdmBatterySetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, RemCapAlarm);
}
/* Register for Battery events */
@@ -1063,6 +1306,62 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice,
{
goto Cleanup;
}
+
+#if NVODM_LOWBATTERY_GPIO_INT
+ NvStatus = NvRmOpen(&pBattContext->hRm, 0);
+ if (NvStatus != NvError_Success)
+ goto Cleanup;
+
+ NvStatus = NvRmGpioOpen(pBattContext->hRm, &pBattContext->hGpio);
+ if (NvStatus != NvError_Success)
+ goto Cleanup;
+
+ pBattContext->pGpioPinInfo = NvOdmQueryGpioPinMap(
+ NvOdmGpioPinGroup_Battery,
+ 0,
+ &pBattContext->PinCount);
+ if (pBattContext->pGpioPinInfo != NULL)
+ {
+
+ IntrHandler = (NvOsInterruptHandler)NvOdmBatteryGpioInterruptHandler;
+
+ if (pBattContext->pGpioPinInfo[0].Port != 0 &&
+ pBattContext->pGpioPinInfo[0].Pin != 0)
+ {
+
+ NvRmGpioAcquirePinHandle(
+ pBattContext->hGpio,
+ pBattContext->pGpioPinInfo[0].Port,
+ pBattContext->pGpioPinInfo[0].Pin,
+ &pBattContext->hPin);
+ if (!pBattContext->hPin)
+ {
+ goto Cleanup;
+ }
+
+ /* Register to receive GPIO events */
+ NvStatus = NvRmGpioInterruptRegister(
+ pBattContext->hGpio,
+ pBattContext->hRm,
+ pBattContext->hPin,
+ IntrHandler,
+ NvRmGpioPinMode_InputInterruptAny,
+ pBattContext,
+ &pBattContext->GpioIntrHandle,
+ 0);
+ if (NvStatus != NvError_Success)
+ {
+ goto Cleanup;
+ }
+
+ NvStatus = NvRmGpioInterruptEnable(pBattContext->GpioIntrHandle);
+ if (NvStatus != NvError_Success)
+ {
+ goto Cleanup;
+ }
+ }
+ }
+#endif
}
*hDevice = pBattContext;
@@ -1088,6 +1387,28 @@ void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice)
pBattContext = (NvOdmBatteryDevice *)hDevice;
+#if NVODM_LOWBATTERY_GPIO_INT
+ if (pBattContext->hGpio)
+ {
+ if (pBattContext->GpioIntrHandle)
+ {
+ NvRmGpioInterruptUnregister(pBattContext->hGpio, pBattContext->hRm,
+ pBattContext->GpioIntrHandle);
+ pBattContext->GpioIntrHandle = NULL;
+ }
+
+ NvRmGpioReleasePinHandles(pBattContext->hGpio, &pBattContext->hPin,
+ pBattContext->PinCount);
+ NvRmGpioClose(pBattContext->hGpio);
+ }
+
+ if (pBattContext->hRm)
+ {
+ NvRmClose(pBattContext->hRm);
+ pBattContext->hRm = NULL;
+ }
+#endif
+
if (pBattContext->hBattEventSem)
{
pBattContext->ExitThread = NV_TRUE;
@@ -1147,7 +1468,7 @@ NvBool NvOdmBatteryGetAcLineStatus(
pBattContext = (NvOdmBatteryDevice *)hDevice;
/* For R01 EC Firware report AC is online as it has not support for this */
- if (pBattContext->FirmwareVersionR01 == NV_TRUE)
+ if (pBattContext->ECVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01)
{
*pStatus = NvOdmBatteryAcLine_Online;
return NV_TRUE;
@@ -1224,12 +1545,12 @@ NvBool NvOdmBatteryGetBatteryStatus(
*pStatus = 0;
/*
- * For R01 firmware Battery support is not present is report
- * Battery is not present.
+ * For R01 firmware Battery support is not present.
*/
- if (pBattContext->FirmwareVersionR01 == NV_TRUE)
+ if (pBattContext->ECVersion == NVODM_BATTERY_EC_FIRMWARE_VER_R01)
{
*pStatus = NVODM_BATTERY_STATUS_UNKNOWN;
+ NVODMBATTERY_PRINTF(("NvOdmBatteryGetBatteryStatus:EC Firmware R01"));
return NV_TRUE;
}
@@ -1237,9 +1558,10 @@ NvBool NvOdmBatteryGetBatteryStatus(
{
if(NvOdmBatteryPrivGetSlotStatusAndCapacityGuage(pBattContext,
NvOdmBatteryInst_Main,
- &BatterySlotStatus, &BatteryCapacityGuage))
+ &BatterySlotStatus,
+ &BatteryCapacityGuage))
{
- BattPresentState = BatterySlotStatus & NVODM_BATTERY_PRESENT_IN_SLOT;
+ BattPresentState = BatterySlotStatus & NVODM_BATTERY_PRESENT_IN_SLOT;
if (BattPresentState == NVODM_BATTERY_PRESENT_IN_SLOT)
{
BattChargingState = BatterySlotStatus >> NVODM_BATTERY_CHARGING_STATE_SHIFT;
@@ -1320,6 +1642,8 @@ NvBool NvOdmBatteryGetBatteryData(
NvU32 BatteryTemp = 0;
NvU32 BattRemCap = 0, BattLastChargeFullCap = 0, BattCriticalCap = 0;
#if BATTERY_EXTRA_INFO
+ NvU16 RemCapAlarm = 0;
+ NvU8 ConfigurationUnit = NVEC_BATTERY_CONFIGURATION_0_CAPACITY_UNITS_MAH;
NvU8 BattManufact[NVEC_MAX_RESPONSE_STRING_SIZE] = {0},
BattModel[NVEC_MAX_RESPONSE_STRING_SIZE] = {0};
#endif
@@ -1360,8 +1684,13 @@ NvBool NvOdmBatteryGetBatteryData(
BatteryData.BatteryLifePercent = BatteryCapacityGuage;
}
- if(NvOdmBatteryPrivGetLifeTime(pBattContext, NvOdmBatteryInst_Main,
- &BatteryLifeTime))
+#if BATTERY_EXTRA_INFO
+ /* ConfigurationUnit = NVEC_BATTERY_CONFIGURATION_0_CAPACITY_UNITS_10MWH; */
+ NvOdmBatterySetConfiguration(pBattContext, NvOdmBatteryInst_Main, ConfigurationUnit);
+ NvOdmBatteryGetConfiguration(pBattContext, NvOdmBatteryInst_Main, &ConfigurationUnit);
+#endif
+
+ if(NvOdmBatteryPrivGetLifeTime(pBattContext, NvOdmBatteryInst_Main, &BatteryLifeTime))
{
BatteryData.BatteryLifeTime = BatteryLifeTime;
}
@@ -1409,8 +1738,12 @@ NvBool NvOdmBatteryGetBatteryData(
}
#if BATTERY_EXTRA_INFO
- NvOdmBatteryGetManufacturer(pBattContext, NvOdmBatteryInst_Main,
- BattManufact);
+ /* RemCapAlarm = 0x0101;*/ /* Some random value */
+ NvOdmBatterySetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, RemCapAlarm);
+ RemCapAlarm = 0;
+ NvOdmBatteryGetRemCapacityAlarm(pBattContext, NvOdmBatteryInst_Main, &RemCapAlarm);
+
+ NvOdmBatteryGetManufacturer(pBattContext, NvOdmBatteryInst_Main, BattManufact);
NvOdmBatteryGetModel(pBattContext, NvOdmBatteryInst_Main, BattModel);
#endif
diff --git a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h
index 39fcb7a8eb3f..3ec7313a0bd4 100644
--- a/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h
+++ b/arch/arm/mach-tegra/odm_kit/platform/battery/nvodm_battery_int.h
@@ -33,6 +33,8 @@
#ifndef INCLUDED_NVODM_BATTERY_INT_H
#define INCLUDED_NVODM_BATTERY_INT_H
+#include "nvodm_query_gpio.h"
+#include "nvrm_gpio.h"
#include "nvodm_services.h"
#include "nvec.h"
@@ -50,6 +52,30 @@ extern "C"
{
#endif
+/****************************************************************************/
+/*
+ * Macro to disable EC calls for battery operations
+ * until EC firware supports it
+ */
+#define NVEC_BATTERY_DISABLED 0
+/*
+ * Some extra battery info added which is not yet part of the
+ * BatteryData struct.
+ * Enable it to verify the these extra info with the EC firware
+ */
+#define BATTERY_EXTRA_INFO 0
+
+/* Enable to wakeup the AP from suspend */
+#define NVODM_WAKEUP_FROM_BATTERY_EVENT 1
+#define NVODM_WAKEUP_FROM_AC_EVENT 1
+
+/* Enable the Low Battery GPIO Interrupt */
+#define NVODM_LOWBATTERY_GPIO_INT 1
+
+/* Enable low capacity alarm wakeup */
+#define NVODM_BATTERY_LOW_CAPACITY_ALARM 1
+/****************************************************************************/
+
#define NVODM_BATTERY_NUM_BATTERY_SLOTS_MASK 0x0F
/* Battery Slot Status and Capacity Gauge Report */
@@ -94,8 +120,8 @@ extern "C"
/* Threshold for battery status.*/
#define NVODM_BATTERY_FULL_VOLTAGE_MV 12600
#define NVODM_BATTERY_HIGH_VOLTAGE_MV 10200
-#define NVODM_BATTERY_LOW_VOLTAGE_MV 9400
-#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 8800
+#define NVODM_BATTERY_LOW_VOLTAGE_MV 10000
+#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 9500
#define NVODM_BATTERY_EC_FIRMWARE_VER_R01 2
#define NVODM_BATTERY_EC_FIRMWARE_VER_R04 8
@@ -129,13 +155,20 @@ typedef struct NvOdmBatteryDeviceRec
{
NvEcHandle hEc;
NvEcEventRegistrationHandle hEcEventReg;
- NvOdmOsSemaphoreHandle hBattEventSem;
- NvOdmOsSemaphoreHandle hClientBattEventSem;
- NvOdmOsThreadHandle hBattEventThread;
- NvU8 BatteryEvent;
- NvU8 NumBatterySlots;
- NvBool FirmwareVersionR01;
- NvBool ExitThread;
+ NvOdmOsSemaphoreHandle hBattEventSem;
+ NvOdmOsSemaphoreHandle hClientBattEventSem;
+ NvOdmOsThreadHandle hBattEventThread;
+#if NVODM_LOWBATTERY_GPIO_INT
+ const NvOdmGpioPinInfo *pGpioPinInfo;
+ NvRmGpioPinHandle hPin;
+ NvRmGpioInterruptHandle GpioIntrHandle;
+ NvU32 PinCount;
+ NvRmDeviceHandle hRm;
+ NvRmGpioHandle hGpio;
+#endif
+ NvU8 BatteryEvent;
+ NvU8 ECVersion;
+ NvBool ExitThread;
} NvOdmBatteryDevice;
#if defined(__cplusplus)
@@ -145,3 +178,4 @@ typedef struct NvOdmBatteryDeviceRec
/** @} */
#endif /* INCLUDED_NVODM_BATTERY_INT_H */
+
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 63116a5d9557..b21a8bd57ed5 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
@@ -305,7 +305,7 @@ static NvOdmWakeupPadInfo s_NvOdmWakeupPadInfo[] =
{NV_FALSE, 8, NvOdmWakeupPadPolarity_AnyEdge}, // Wake Event 8 - gmi_wp_n (MICRO SD_CD)
{NV_FALSE, 9, NvOdmWakeupPadPolarity_High}, // Wake Event 9 - gp3_ps[2] (KB_COL10)
{NV_FALSE, 10, NvOdmWakeupPadPolarity_High}, // Wake Event 10 - gmi_ad21 (Accelerometer_TH/TAP)
- {NV_FALSE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ)
+ {NV_TRUE, 11, NvOdmWakeupPadPolarity_Low}, // Wake Event 11 - spi2_cs2 (PEN_INT, AUDIO-IRQ, LOW_BAT#)
{NV_FALSE, 12, NvOdmWakeupPadPolarity_Low}, // Wake Event 12 - spi2_cs1 (HEADSET_DET, not used)
{NV_FALSE, 13, NvOdmWakeupPadPolarity_Low}, // Wake Event 13 - sdio1_dat1
{NV_FALSE, 14, NvOdmWakeupPadPolarity_High}, // Wake Event 14 - gp3_pv[6] (WLAN_INT)
diff --git a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
index 1868bffa7fd7..8d384db176ee 100644
--- a/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
+++ b/arch/arm/mach-tegra/odm_kit/query/harmony/nvodm_query_gpio.c
@@ -153,6 +153,11 @@ static const NvOdmGpioPinInfo s_WakeFromKeyBoard[] = {
{NVODM_PORT('a'), 0, NvOdmGpioPinActiveState_Low} // EC Keyboard Wakeup
};
+static const NvOdmGpioPinInfo s_Battery[] = {
+ // Low Battery
+ {NVODM_PORT('w'), 3, NvOdmGpioPinActiveState_Low},
+};
+
const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
NvU32 Instance, NvU32 *pCount)
{
@@ -224,6 +229,10 @@ const NvOdmGpioPinInfo *NvOdmQueryGpioPinMap(NvOdmGpioPinGroup Group,
*pCount = NVODM_ARRAY_SIZE(s_WakeFromKeyBoard);
return s_WakeFromKeyBoard;
+ case NvOdmGpioPinGroup_Battery:
+ *pCount = NVODM_ARRAY_SIZE(s_Battery);
+ return s_Battery;
+
default:
*pCount = 0;
return NULL;
diff --git a/drivers/power/nvec_battery.c b/drivers/power/nvec_battery.c
index 42de876b9e63..f9d8c8b41b43 100644
--- a/drivers/power/nvec_battery.c
+++ b/drivers/power/nvec_battery.c
@@ -30,7 +30,7 @@
#include <linux/power_supply.h>
#include <linux/wakelock.h>
#include <linux/tegra_devices.h>
-#include <linux/pm.h>
+#include <linux/reboot.h>
#include "nvcommon.h"
#include "nvos.h"
@@ -186,6 +186,9 @@ void NvBatteryEventHandlerThread(void)
if (batt_dev->exitThread)
break;
+ if (!batt_dev->hOdmBattDev)
+ continue;
+
NvOdmBatteryGetBatteryStatus(batt_dev->hOdmBattDev,
NvOdmBatteryInst_Main,
&BatteryState);
@@ -200,7 +203,8 @@ void NvBatteryEventHandlerThread(void)
if (BatteryState == (NVODM_BATTERY_STATUS_CRITICAL |
NVODM_BATTERY_STATUS_VERY_CRITICAL |
NVODM_BATTERY_STATUS_DISCHARGING)) {
- /* device_power_down(PMSG_HIBERNATE); */
+ pr_info("nvec_battery:calling kernel_power_off...\n");
+ kernel_power_off();
}
} else {
/* Update the battery and power supply info for other events */