diff options
author | Sachin Nikam <snikam@nvidia.com> | 2010-03-19 12:39:06 +0530 |
---|---|---|
committer | Gary King <gking@nvidia.com> | 2010-03-29 08:41:34 -0800 |
commit | a3644ba3a01c41f789432bbb75c9dbba004d3664 (patch) | |
tree | 4c7bbb3610e77145157b66f75548d49b71b27598 /arch | |
parent | 5054b24952cdcef10819fe6137de46450d440bbe (diff) |
nvec_battery:registering battery as wakeup source and battery events.
1. Making Battery and AC present as a wakeup source
2. Registering battery events:present, charging, remaining capacity
3. Handling battery odm flags and events in nvec_battery.c
Change-Id: I814960ab5f065e6aaad72ea1c403ad9c8d6a1af8
Reviewed-on: http://git-master/r/907
Reviewed-by: Sachin Nikam <snikam@nvidia.com>
Tested-by: Sachin Nikam <snikam@nvidia.com>
Reviewed-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch')
3 files changed, 221 insertions, 95 deletions
diff --git a/arch/arm/mach-tegra/include/nvodm_battery.h b/arch/arm/mach-tegra/include/nvodm_battery.h index ae4567169b05..4dba0edc1c48 100644 --- a/arch/arm/mach-tegra/include/nvodm_battery.h +++ b/arch/arm/mach-tegra/include/nvodm_battery.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 NVIDIA Corporation. + * Copyright (c) 2009-2010 NVIDIA Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,8 +35,12 @@ * <b>NVIDIA Tegra ODM Kit: * Battery Interface</b> * - * @b Description: Defines the ODM adaptation interface for battery. - * + * @b Description: Defines the ODM adaptation interface for + * Embedded Controller (EC) based battery interface. + * Note that this doesn't use PMU interface. + * EC Interface is used to get battery and power supply + * information and configure for events. + * Battery charging is taken care by EC firmware itself. */ #ifndef INCLUDED_NVODM_BATTERY_H @@ -82,20 +86,27 @@ typedef enum }NvOdmBatteryAcLineStatus; /** - * Defines the Battery events. + * Defines the battery events. */ typedef enum { - /// Specifies Battery Present State. - NvOdmBatteryEventType_Present, + /// Indicates battery present state. + NvOdmBatteryEventType_Present = 0x01, + + /// Indicates idle state. + NvOdmBatteryEventType_Idle = 0x02, + + /// Indicates charging state. + NvOdmBatteryEventType_Charging = 0x04, + + /// Indicates disharging state. + NvOdmBatteryEventType_Disharging = 0x08, - /// Specifies Charging State. - NvOdmBatteryEventType_Charging, + /// Indicates remaining capacity alarm set. + NvOdmBatteryEventType_RemainingCapacityAlarm = 0x10, - /// Specifies Remaining Capacity Alarm. - NvOdmBatteryEventType_RemainingCapacityAlarm, + NvOdmBatteryEventType_Num = 0x20, - NvOdmBatteryEventType_Num, /// Ignore -- Forces compilers to make 32-bit enums. NvOdmBatteryEventType_Force32 = 0x7FFFFFFF }NvOdmBatteryEventType; @@ -107,6 +118,9 @@ typedef enum #define NVODM_BATTERY_STATUS_LOW 0x02 #define NVODM_BATTERY_STATUS_CRITICAL 0x04 #define NVODM_BATTERY_STATUS_CHARGING 0x08 +#define NVODM_BATTERY_STATUS_DISCHARGING 0x10 +#define NVODM_BATTERY_STATUS_IDLE 0x20 +#define NVODM_BATTERY_STATUS_VERY_CRITICAL 0x40 #define NVODM_BATTERY_STATUS_NO_BATTERY 0x80 #define NVODM_BATTERY_STATUS_UNKNOWN 0xFF @@ -162,13 +176,13 @@ typedef struct NvOdmBatteryDataRec /// Specifies battery temperature. NvU32 BatteryTemperature; - /// Specifies battery Remaining Capacity. + /// Specifies battery remaining capacity. NvU32 BatteryRemainingCapacity; - /// Specifies battery Last Charge Full Capacity. + /// Specifies battery last charge full capacity. NvU32 BatteryLastChargeFullCapacity; - /// Specifies battery Critical Capacity. + /// Specifies battery critical capacity. NvU32 BatteryCriticalCapacity; }NvOdmBatteryData; @@ -205,7 +219,7 @@ typedef enum * Opens the handle for battery ODM. * * @param hDevice A pointer to the handle to the battery ODM. - * @param hOdmSemaphore Battery events signals this registered semaphore. + * @param hOdmSemaphore Battery events signal this registered semaphore. * Can Pass NULL if events are not needed by client. * @return NV_TRUE if successful, or NV_FALSE otherwise. */ @@ -296,7 +310,7 @@ void NvOdmBatteryGetBatteryChemistry( * Gets the battery event. * * @param hDevice A handle to the EC. - * @param pBatteryEvent Battery events + * @param pBatteryEvent A pointer to the battery events. * */ void NvOdmBatteryGetEvent( @@ -305,11 +319,11 @@ void NvOdmBatteryGetEvent( /** - * Gets the Battery Manufacturer. + * Gets the battery manufacturer. * * @param hDevice [IN] A handle to the EC. * @param BatteryInst [IN] The battery type. - * @param pBatteryManufacturer [OUT] A pointer to the battery Manufacturer + * @param pBatteryManufacturer [OUT] A pointer to the battery manufacturer. */ NvBool NvOdmBatteryGetManufacturer( NvOdmBatteryDeviceHandle hDevice, @@ -317,11 +331,11 @@ NvBool NvOdmBatteryGetManufacturer( NvU8 *pBatteryManufacturer); /** - * Gets the Battery Model. + * Gets the battery model. * * @param hDevice [IN] A handle to the EC. * @param BatteryInst [IN] The battery type. - * @param pBatteryModel [OUT] A pointer to the battery model + * @param pBatteryModel [OUT] A pointer to the battery model. */ NvBool NvOdmBatteryGetModel( NvOdmBatteryDeviceHandle hDevice, 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 14908b21cf91..b8919573ddeb 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 NVIDIA Corporation. + * Copyright (c) 2009-2010 NVIDIA Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,10 @@ */ #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, @@ -144,13 +148,16 @@ static void NvOdmBatteryEventHandler(void *args) NvOdmBatteryDevice *pBattContext = args; NvError NvStatus = NvError_Success; NvEcEvent EcEvent = {0}; + NvU8 BattEvent = 0, ChargingState = 0; for (;;) { NvOdmOsSemaphoreWait(pBattContext->hBattEventSem); - NVODMBATTERY_PRINTF(("NvOdmBatteryEventHandler:hBattEventSem \ - signaled\n")); + if (pBattContext->ExitThread == NV_TRUE) + break; + + NVODMBATTERY_PRINTF(("NvOdmBatteryEventHandler:hBattEventSem signaled\n")); if (pBattContext->hEcEventReg) { @@ -168,11 +175,33 @@ static void NvOdmBatteryEventHandler(void *args) continue; } - pBattContext->BatteryEvent = EcEvent.Payload[0]; - - /* Signal the Battery Client for arrival of the event */ - if (pBattContext->hClientBattEventSem) - NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem); + /* EcEvent.Payload[0] is Slot number */ + + /* EcEvent.Payload[1] has 4 lsb bits for battery events */ + BattEvent = EcEvent.Payload[1] & NVODM_BATTERY_EVENT_MASK; + + pBattContext->BatteryEvent = 0; + /* Read the Battery Slot status to set the proper event */ + if (BattEvent & NVODM_BATTERY_PRESENT_IN_SLOT) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Present; + + ChargingState = BattEvent >> NVODM_BATTERY_CHARGING_STATE_SHIFT; + ChargingState &= NVODM_BATTERY_CHARGING_STATE_MASK; + if (ChargingState == NVODM_BATTERY_CHARGING_STATE_IDLE) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Idle; + else if (ChargingState == NVODM_BATTERY_CHARGING_STATE_CHARGING) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Charging; + else if (ChargingState == NVODM_BATTERY_CHARGING_STATE_DISCHARGING) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_Disharging; + + ChargingState = BattEvent >> NVODM_BATTERY_REM_CAP_ALARM_SHIFT; + if (ChargingState == NVODM_BATTERY_REM_CAP_ALARM_IS_SET) + pBattContext->BatteryEvent |= NvOdmBatteryEventType_RemainingCapacityAlarm; + + /* Signal the Battery Client for arrival of the valid event */ + if ((pBattContext->hClientBattEventSem != 0) && + (pBattContext->BatteryEvent != 0)) + NvOdmOsSemaphoreSignal(pBattContext->hClientBattEventSem); } } } @@ -895,6 +924,8 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, NvError NvStatus = NvError_Success; NvEcEventType EventTypes[] = {NvEcEventType_Battery}; NvS32 MajorVersion = 0, MinorVersion = 0; + NvEcRequest EcRequest = {0}; + NvEcResponse EcResponse = {0}; NVODMBATTERY_PRINTF(("[ENTER] NvOdmBatteryDeviceOpen. \n")); @@ -903,7 +934,7 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, if (!pBattContext) { NVODMBATTERY_PRINTF(("NvOdmOsAlloc failed to allocate pBattContext.")); - goto Cleanup; + return NV_FALSE; } NvOdmOsMemset(pBattContext, 0, sizeof(NvOdmBatteryDevice)); @@ -916,6 +947,27 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, goto Cleanup; } + /* Get the EC Firmware version */ + NvStatus = NvOdmBatteryPrivEcGetFirmwareVersion(pBattContext, + &MajorVersion, + &MinorVersion); + if (NvStatus != NvError_Success) + { + 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")); + } + if (hOdmSemaphore != NULL && *hOdmSemaphore != NULL) { pBattContext->hClientBattEventSem = *hOdmSemaphore; @@ -927,6 +979,77 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, goto Cleanup; } + /* Thread to handle Battery events */ + pBattContext->hBattEventThread = NvOdmOsThreadCreate( + (NvOdmOsThreadFunction)NvOdmBatteryEventHandler, + (void *)pBattContext); + if (!pBattContext->hBattEventThread) + { + goto Cleanup; + } + + if (MinorVersion >= NVODM_BATTERY_EC_FIRMWARE_VER_R04) + { +#if NVODM_WAKEUP_FROM_BATTERY_EVENT + /* Configure the Batter present event as a wakeup */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcBatterySubtype_ConfigureWake; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE; + EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT; + + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvStatus != NvSuccess) + goto Cleanup; + + if (EcResponse.Status != NvEcStatus_Success) + goto Cleanup; +#endif + +#if NVODM_WAKEUP_FROM_AC_EVENT + /* Configure the AC present event as a wakeup */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_System; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcSystemSubtype_ConfigureWake; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = NVEC_SYSTEM_REPORT_ENABLE_0_ACTION_ENABLE; + EcRequest.Payload[1] = NVEC_SYSTEM_STATE1_0_AC_PRESENT; + + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvStatus != NvSuccess) + goto Cleanup; + + if (EcResponse.Status != NvEcStatus_Success) + goto Cleanup; +#endif + /* Configure the Battery events */ + EcRequest.PacketType = NvEcPacketType_Request; + EcRequest.RequestType = NvEcRequestResponseType_Battery; + EcRequest.RequestSubtype = (NvEcRequestResponseSubtype) + NvEcBatterySubtype_ConfigureEventReporting; + EcRequest.NumPayloadBytes = 2; + EcRequest.Payload[0] = NVEC_BATTERY_REPORT_ENABLE_0_ACTION_ENABLE; + /* Bit 0 = Present State event */ + /* Bit 1 = Charging State event */ + /* Bit 2 = Remaining Capacity Alaram event */ + EcRequest.Payload[1] = NVODM_BATTERY_SET_PRESENT_EVENT | + NVODM_BATTERY_SET_CHARGING_EVENT| + NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT; + + NvStatus = NvEcSendRequest(pBattContext->hEc, &EcRequest, &EcResponse, + sizeof(EcRequest), sizeof(EcResponse)); + if (NvStatus != NvSuccess) + goto Cleanup; + + if (EcResponse.Status != NvEcStatus_Success) + goto Cleanup; + } + /* Register for Battery events */ NvStatus = NvEcRegisterForEvents( pBattContext->hEc, @@ -940,35 +1063,6 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, { goto Cleanup; } - - /* Thread to handle Battery events */ - pBattContext->hBattEventThread = \ - NvOdmOsThreadCreate((NvOdmOsThreadFunction)NvOdmBatteryEventHandler, - (void *)pBattContext); - if (!pBattContext->hBattEventThread) - { - goto Cleanup; - } - } - - /* Get the EC Firmware version */ - NvStatus = NvOdmBatteryPrivEcGetFirmwareVersion(pBattContext, &MajorVersion, - &MinorVersion); - if (NvStatus != NvError_Success) - { - goto Cleanup; - } - - /* Minor Version 2 is R01 */ - if (MinorVersion == 2) - { - 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")); } *hDevice = pBattContext; @@ -976,27 +1070,7 @@ NvBool NvOdmBatteryDeviceOpen(NvOdmBatteryDeviceHandle *hDevice, return NV_TRUE; Cleanup: - - if (pBattContext->hBattEventSem) - { - NvOdmOsSemaphoreDestroy(pBattContext->hBattEventSem); - pBattContext->hBattEventSem = NULL; - } - - if (pBattContext->hEc) - { - if (pBattContext->hEcEventReg) - { - NvEcUnregisterForEvents(pBattContext->hEcEventReg); - pBattContext->hEcEventReg = NULL; - } - - NvEcClose(pBattContext->hEc); - pBattContext->hEc = NULL; - } - - if (pBattContext) - NvOdmOsFree(pBattContext); + NvOdmBatteryDeviceClose(pBattContext); return NV_FALSE; } @@ -1005,7 +1079,7 @@ Cleanup: * Closes the battery device * * @param hDevice [IN] handle to Battery Device. - * + * * @return void. */ void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice) @@ -1016,10 +1090,18 @@ void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice) if (pBattContext->hBattEventSem) { + pBattContext->ExitThread = NV_TRUE; + NvOdmOsSemaphoreSignal(pBattContext->hBattEventSem); NvOdmOsSemaphoreDestroy(pBattContext->hBattEventSem); pBattContext->hBattEventSem = NULL; } + if (pBattContext->hBattEventThread) + { + NvOdmOsThreadJoin(pBattContext->hBattEventThread); + pBattContext->hBattEventThread = NULL; + } + if (pBattContext->hEc) { if (pBattContext->hEcEventReg) @@ -1028,12 +1110,6 @@ void NvOdmBatteryDeviceClose(NvOdmBatteryDeviceHandle hDevice) pBattContext->hEcEventReg = NULL; } - if (pBattContext->hBattEventThread) - { - NvOdmOsThreadJoin(pBattContext->hBattEventThread); - pBattContext->hBattEventThread = NULL; - } - NvEcClose(pBattContext->hEc); pBattContext->hEc = NULL; } @@ -1166,10 +1242,14 @@ NvBool NvOdmBatteryGetBatteryStatus( BattPresentState = BatterySlotStatus & NVODM_BATTERY_PRESENT_IN_SLOT; if (BattPresentState == NVODM_BATTERY_PRESENT_IN_SLOT) { - BattChargingState = \ - BatterySlotStatus >> NVODM_BATTERY_CHARGING_STATE_SHIFT; + BattChargingState = BatterySlotStatus >> NVODM_BATTERY_CHARGING_STATE_SHIFT; + BattChargingState &= NVODM_BATTERY_CHARGING_STATE_MASK; if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_CHARGING) - *pStatus |= NVODM_BATTERY_STATUS_CHARGING; + *pStatus |= NVODM_BATTERY_STATUS_CHARGING; + else if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_DISCHARGING) + *pStatus |= NVODM_BATTERY_STATUS_DISCHARGING; + else if (BattChargingState == NVODM_BATTERY_CHARGING_STATE_IDLE) + *pStatus |= NVODM_BATTERY_STATUS_IDLE; } else { @@ -1192,7 +1272,15 @@ NvBool NvOdmBatteryGetBatteryStatus( else if (BatteryVoltage >= NVODM_BATTERY_LOW_VOLTAGE_MV) *pStatus |= NVODM_BATTERY_STATUS_LOW; else + { *pStatus |= NVODM_BATTERY_STATUS_CRITICAL; + /* + * Additional flag which tells battery is very critical + * and needs system shutdown. + */ + if (BatteryVoltage <= NVODM_BATTERY_CRITICAL_VOLTAGE_MV) + *pStatus |= NVODM_BATTERY_STATUS_VERY_CRITICAL; + } } else { 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 88f7894a1a64..39fcb7a8eb3f 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 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009 NVIDIA Corporation. + * Copyright (c) 2009-2010 NVIDIA Corporation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,11 +69,17 @@ extern "C" #define NVODM_BATTERY_PRESENT_IN_SLOT 0x01 #define NVODM_BATTERY_CHARGING_STATE_SHIFT 1 +#define NVODM_BATTERY_CHARGING_STATE_MASK 0x03 + /* Battery Slot Status : Bits 1-2 = Charging state */ #define NVODM_BATTERY_CHARGING_STATE_IDLE 0x00 #define NVODM_BATTERY_CHARGING_STATE_CHARGING 0x01 -#define NVODM_BATTERY_CHARGING_STATE_DISCHARGING 0x10 -#define NVODM_BATTERY_CHARGING_STATE_RESERVED 0x11 +#define NVODM_BATTERY_CHARGING_STATE_DISCHARGING 0x02 +#define NVODM_BATTERY_CHARGING_STATE_RESERVED 0x03 + +/* Remaining capacity alarm bit is 3rd in slot status */ +#define NVODM_BATTERY_REM_CAP_ALARM_SHIFT 3 +#define NVODM_BATTERY_REM_CAP_ALARM_IS_SET 1 /* Response System Status : Data Byte 3 System State Bits 7-0 */ #define NVODM_BATTERY_SYSTEM_STATE_DATA1 0 @@ -87,9 +93,26 @@ extern "C" /* Threshold for battery status.*/ #define NVODM_BATTERY_FULL_VOLTAGE_MV 12600 -#define NVODM_BATTERY_HIGH_VOLTAGE_MV 10000 -#define NVODM_BATTERY_LOW_VOLTAGE_MV 9000 -#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 8500 +#define NVODM_BATTERY_HIGH_VOLTAGE_MV 10200 +#define NVODM_BATTERY_LOW_VOLTAGE_MV 9400 +#define NVODM_BATTERY_CRITICAL_VOLTAGE_MV 8800 + +#define NVODM_BATTERY_EC_FIRMWARE_VER_R01 2 +#define NVODM_BATTERY_EC_FIRMWARE_VER_R04 8 + +/* Bit 0 = Present State event */ +/* Bit 1 = Charging State event */ +/* Bit 2 = Remaining Capacity Alaram event */ +#define NVODM_BATTERY_SET_PRESENT_EVENT 0x01 +#define NVODM_BATTERY_SET_CHARGING_EVENT 0x02 +#define NVODM_BATTERY_SET_REM_CAP_ALARM_EVENT 0x04 + +/* + * Bit 0 => 0=Not Present, 1=Present + * Bit 1:2 => 00=Idle, 01=Charging,10=Discharging, 11=Reserved + * Bit 3 => 1=Remaining Capacity Alaram set + */ +#define NVODM_BATTERY_EVENT_MASK 0x0F typedef enum { @@ -112,6 +135,7 @@ typedef struct NvOdmBatteryDeviceRec NvU8 BatteryEvent; NvU8 NumBatterySlots; NvBool FirmwareVersionR01; + NvBool ExitThread; } NvOdmBatteryDevice; #if defined(__cplusplus) |