Changeset 406


Ignore:
Timestamp:
Feb 23, 2012, 12:13:33 AM (13 years ago)
Author:
shl
Message:

Add additioned ACPI support for battery and temperature monitoring
Code from David Azarewicz

Location:
branches/branch-1-0
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • branches/branch-1-0/include/helpers/acpih.h

    r325 r406  
    2727#endif
    2828
     29// @@changed V1.0.9 (2012-02-20) [slevine]: sync with current ACPI toolkit, code by David Azarewicz
     30
    2931#ifndef ACPIH_HEADER_INCLUDED
    3032    #define ACPIH_HEADER_INCLUDED
    3133
     34    #pragma pack(4)
     35    #include <acpi.h>
     36    #include <acpiapi.h>
     37    #pragma pack()
    3238    /*
    3339     * Power state values
    3440     */
    35 
    36     #define ACPI_STATE_UNKNOWN              (UCHAR) 0xFF
    37 
    38     #define ACPI_STATE_S0                   (UCHAR) 0
    39     #define ACPI_STATE_S1                   (UCHAR) 1
    40     #define ACPI_STATE_S2                   (UCHAR) 2
    41     #define ACPI_STATE_S3                   (UCHAR) 3
    42     #define ACPI_STATE_S4                   (UCHAR) 4
    43     #define ACPI_STATE_S5                   (UCHAR) 5
    44     #define ACPI_S_STATES_MAX               ACPI_STATE_S5
    45     #define ACPI_S_STATE_COUNT              6
    46 
    47     #pragma pack(1)
    48 
    49     typedef struct _VersionAcpi_
    50     {
    51         ULONG  Major;
    52         ULONG  Minor;
    53     } ACPI_VERSION;
    54 
    55     typedef struct _AcpiApiHandle_
    56     {
    57         HFILE           AcpiDrv;                 // Handle to ACPICA driver
    58         ACPI_VERSION    PSD;                     // Version PSD
    59         ACPI_VERSION    Driver;                  // Version ACPICA driver
    60         ACPI_VERSION    DLL;                     // Version acpi32.dll
    61         ULONG           StartAddrPSD;            // Start address PSD (for testcase)
    62         ULONG           AddrCommApp;             // Address DosCommApp from PSD (which not write IBM)
    63         ULONG           StartAddrDriver;         // Start address ACPICA (for testcase)
    64         ULONG           AddrFindPSD;             // Address function for find PSD (find CommApp)
    65         ULONG           IRQNumber;               // Number use IRQ
    66         void            *Internal;               // For internal DLL use
    67     } ACPI_API_HANDLE, *PACPI_API_HANDLE;
    68 
    69     /* ******************************************************************
    70      *
    71      *   ACPI helper APIs
    72      *
    73      ********************************************************************/
    74 
    75     #pragma pack()
    7641
    7742    APIRET APIENTRY AcpiStartApi(ACPI_API_HANDLE *);
     
    8752    typedef ACPIGOTOSLEEP *PACPIGOTOSLEEP;
    8853
     54    typedef APIRET APIENTRY ACPITKGETOBJECTINFOALLOC(ACPI_HANDLE *, PVOID);
     55    typedef APIRET APIENTRY ACPITKGETHANDLE(ACPI_HANDLE, ACPI_STRING, ACPI_HANDLE *);
     56    typedef APIRET APIENTRY ACPITKOSFREE(PVOID);
     57    typedef APIRET APIENTRY ACPITKWALKNAMESPACE(ACPI_OBJECT_TYPE, ACPI_HANDLE, UINT32,ACPI_WALK_CALLBACK, PVOID, void **);
     58    typedef APIRET APIENTRY ACPITKEVALUATEOBJECT(ACPI_HANDLE, ACPI_STRING, ACPI_OBJECT_LIST *, ACPI_BUFFER *);
     59
    8960    APIRET APIENTRY acpihOpen(ACPI_API_HANDLE *phACPI);
     61    typedef APIRET APIENTRY ACPIHOPEN(ACPI_API_HANDLE *);
     62    typedef ACPIHOPEN *PACPIHOPEN;
    9063
    9164    VOID APIENTRY acpihClose(ACPI_API_HANDLE *phACPI);
     
    9366    APIRET APIENTRY acpihGoToSleep(ACPI_API_HANDLE *phACPI, UCHAR ucState);
    9467
     68    APIRET APIENTRY acpihGetPowerStatus(PAPM, PBOOL);
     69    typedef APIRET APIENTRY ACPIHGETPOWERSTATUS(PAPM, PBOOL);
     70    typedef ACPIHGETPOWERSTATUS *PACPIHGETPOWERSTATUS;
     71
     72    BOOL acpihHasBattery(VOID);
     73
    9574    #define ORD_ACPISTARTAPI    16
    9675    #define ORD_ACPIENDAPI      17
    9776    #define ORD_ACPIGOTOSLEEP   19
     77    #define ORD_ACPITKGETOBJECTINFOALLOC 85
     78    #define ORD_ACPITKGETHANDLE 65
     79    #define ORD_ACPITKOSFREE 66
     80    #define ORD_ACPITKWALKNAMESPACE 56
     81    #define ORD_ACPITKEVALUATEOBJECT 50
    9882
    9983#endif
  • branches/branch-1-0/src/helpers/acpih.c

    r380 r406  
    4040#include "setup.h"                      // code generation and debugging options
    4141
     42#include "helpers\apmh.h"               // @@added V1.0.9 (2012-02-20) [slevine]
    4243#include "helpers\acpih.h"
    4344#include "helpers\standards.h"
     
    5152HMODULE       G_hmodACPI = NULLHANDLE;
    5253ULONG         G_ulCount = 0;
     54// @@added V1.0.9 (2012-02-20) [slevine]: additional ACPI support, code from David Azarewicz
     55ACPI_HANDLE   G_ahAC = 0;
     56#define MAX_BATTERY_COUNT 4
     57ACPI_HANDLE   G_ahBat[MAX_BATTERY_COUNT];
     58ULONG         G_uiBatteryCount = 0;
     59ULONG         G_uiAlreadyWalked = 0;
    5360
    5461ACPISTARTAPI  *pAcpiStartApi = NULL;
     
    5663ACPIGOTOSLEEP *pAcpiGoToSleep = NULL;
    5764
     65ACPITKGETOBJECTINFOALLOC *pAcpiTkGetObjectInfoAlloc = NULL;
     66ACPITKGETHANDLE *pAcpiTkGetHandle = NULL;
     67ACPITKOSFREE *pAcpiTkOsFree = NULL;
     68ACPITKWALKNAMESPACE *pAcpiTkWalkNamespace = NULL;
     69ACPITKEVALUATEOBJECT *pAcpiTkEvaluateObject = NULL;
     70
    5871/*
    5972 *@@category: Helpers\Control program helpers\ACPI
     
    7184
    7285    if (!G_hmodACPI)
     86    {
    7387        if (!(arc = DosLoadModule(NULL,
    7488                                  0,
     
    100114                return(arc);
    101115            }
    102         }
     116
     117            // @@added V1.0.9 (2012-02-20) [slevine]: additional ACPI support, code from David Azarewicz
     118            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKGETOBJECTINFOALLOC, NULL, (PFN *) &pAcpiTkGetObjectInfoAlloc);
     119            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKGETHANDLE, NULL, (PFN *) &pAcpiTkGetHandle);
     120            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKOSFREE, NULL, (PFN *) &pAcpiTkOsFree);
     121            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKWALKNAMESPACE, NULL, (PFN *) &pAcpiTkWalkNamespace);
     122            DosQueryProcAddr(G_hmodACPI, ORD_ACPITKEVALUATEOBJECT, NULL, (PFN *) &pAcpiTkEvaluateObject);
     123        }
     124    }
    103125
    104126    if (arc)
     
    147169}
    148170
     171
     172/**
     173 *@@ AcpiCallbackWidget:
     174 *      ACPI callback helper for battery and power status queries.
     175 *      Code provided by David Azarewicz
     176 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
     177 */
     178
     179#define AE_DEPTH AE_OK
     180
     181ACPI_STATUS AcpiCallbackWidget( ACPI_HANDLE ObjHandle, UINT32 NestingLevel, void *Context, void **ReturnValue )
     182{
     183    ACPI_STATUS Status;
     184    ACPI_DEVICE_INFO *pDevInfo;
     185
     186    pDevInfo = NULL;
     187    Status = pAcpiTkGetObjectInfoAlloc( ObjHandle, &pDevInfo );
     188
     189    if (Status == AE_OK)
     190    {
     191        if (pDevInfo->Type != ACPI_TYPE_DEVICE) return AE_DEPTH;
     192        if (!(pDevInfo->Valid & ACPI_VALID_HID)) return AE_DEPTH;
     193        if (!pDevInfo->HardwareId.String ) return AE_DEPTH;
     194
     195        if (strncmp(pDevInfo->HardwareId.String, "ACPI0003", 8)==0)
     196        { /* AC Power */
     197            Status = pAcpiTkGetHandle(ObjHandle, "_PSR", &G_ahAC);
     198            if (Status) G_ahAC = 0;
     199            return AE_DEPTH;
     200        }
     201
     202        if (strncmp(pDevInfo->HardwareId.String, "PNP0C0A", 7)==0)
     203        { /* Smart battery */
     204            if (G_uiBatteryCount >= MAX_BATTERY_COUNT) return AE_DEPTH;
     205            G_ahBat[G_uiBatteryCount] = ObjHandle;
     206            G_uiBatteryCount++;
     207            return AE_DEPTH;
     208        }
     209    }
     210
     211    if (pDevInfo) pAcpiTkOsFree(pDevInfo);
     212
     213    return AE_OK;
     214}
     215
     216/**
     217 *@@ acpihGetPowerStatus:
     218 *      Returns power and battery status in caller provided buffers.
     219 *      Returns zero if success, non-zero if fail.
     220 *      Code provided by David Azarewicz
     221 *@@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
     222 */
     223APIRET acpihGetPowerStatus(PAPM pApm, PBOOL pfChanged)
     224{
     225    ACPI_STATUS Status;
     226    ACPI_BUFFER Result;
     227    ACPI_OBJECT *Obj, Object[20];
     228    UINT32 uiI;
     229    ULONG ulTmp, BRemaining, LastFull;
     230    BOOL fChanged;
     231
     232    if (pAcpiTkWalkNamespace==NULL) return 1;
     233    if (pApm==NULL) return 1;
     234
     235    if (!G_uiAlreadyWalked)
     236    {
     237        Status = pAcpiTkWalkNamespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, AcpiCallbackWidget, pApm, NULL);
     238        G_uiAlreadyWalked = 1;
     239    }
     240
     241    fChanged = FALSE;
     242
     243    // VAC 3.08 long long compatibility support
     244#   ifdef INCL_LONGLONG // VAC 3.6.5 - compiler supports long long
     245#   define OBJECT_VALUE(index)  (Object[index].Integer.Value)
     246#   else // VAC 3.08 - compiler does not support long long
     247#   define OBJECT_VALUE(index)  (Object[index].Integer.Value.ulLo)
     248#   endif
     249
     250    if (G_ahAC)
     251    {
     252        Result.Length = sizeof(Object);
     253        Result.Pointer = Object;
     254        Status = pAcpiTkEvaluateObject(G_ahAC, NULL, NULL, &Result);
     255        if (Status != AE_OK) ulTmp = 2;
     256        if (Object[0].Type != ACPI_TYPE_INTEGER) ulTmp = 2;
     257
     258        ulTmp = OBJECT_VALUE(0);
     259        if (pApm->fUsingAC != ulTmp)
     260        {
     261            pApm->fUsingAC = ulTmp;
     262            fChanged = TRUE;
     263        }
     264    }
     265
     266    for (uiI=0; uiI<G_uiBatteryCount; uiI++)
     267    {
     268        if (G_ahBat[uiI] == 0) continue;
     269
     270        Result.Length = sizeof(Object);
     271        Result.Pointer = Object;
     272        Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BIF", NULL, &Result);
     273        if (Status != AE_OK)
     274        {
     275            G_ahBat[uiI] = 0;
     276            continue;
     277        }
     278
     279        Obj = Result.Pointer;
     280        Obj = (ACPI_OBJECT *)Obj[0].Package.Elements;
     281        LastFull = (UINT32)OBJECT_VALUE(2);
     282        if (LastFull == 0xffffffff)
     283        {
     284            G_ahBat[uiI] = 0;
     285            continue;
     286        }
     287
     288        Result.Length = sizeof(Object);
     289        Result.Pointer = Object;
     290        Status = pAcpiTkEvaluateObject(G_ahBat[uiI], "_BST", NULL, &Result);
     291        if (Status != AE_OK)
     292        {
     293            G_ahBat[uiI] = 0;
     294            continue;
     295        }
     296
     297        Obj = Result.Pointer;
     298        Obj = (ACPI_OBJECT *)Obj[0].Package.Elements;
     299
     300        if (OBJECT_VALUE(2) != 0xffffffff)
     301        {
     302            BRemaining = (UINT32)OBJECT_VALUE(2);
     303        }
     304
     305        if (OBJECT_VALUE(0) != 0xffffffff)
     306        {
     307            if (BRemaining > (LastFull >> 1)) // > 50% is high. < 50% is low
     308            {
     309                ulTmp = 1; // High
     310            }
     311            else
     312            {
     313                ulTmp = 2; // Low
     314            }
     315
     316            if (OBJECT_VALUE(0) & 4)
     317            {
     318                ulTmp = 2; // Critical
     319            }
     320            // If battery charging - it can't be critical
     321            if (OBJECT_VALUE(0) & 2)
     322            {
     323                ulTmp = 3; // Charging
     324            }
     325            if (pApm->bBatteryStatus != ulTmp)
     326            {
     327                pApm->bBatteryStatus = ulTmp;
     328                fChanged = TRUE;
     329            }
     330        }
     331
     332        ulTmp = (BRemaining*100)/LastFull;
     333        if (ulTmp > 100) ulTmp = 100;
     334        if (pApm->bBatteryLife != ulTmp)
     335        {
     336            pApm->bBatteryLife = ulTmp;
     337            fChanged = TRUE;
     338        }
     339    }
     340
     341    if (pfChanged) *pfChanged = fChanged;
     342    pApm->fAlreadyRead = FALSE;
     343
     344    return 0;
     345
     346#   undef OBJECT_VALUE
     347}
     348
     349/*
     350 *@@ acpihHasBattery:
     351 *      quick'n'dirty helper which returns TRUE only
     352 *      if ACPI is supported on the system and the
     353 *      system actually has a battery (i.e. is a laptop).
     354 *      Code provided by David Azarewicz.
     355 * @@added V1.0.9 (2012-02-20) [slevine]: code from David Azarewicz
     356 */
     357BOOL acpihHasBattery(VOID)
     358{
     359    BOOL brc = FALSE;
     360    ACPI_API_HANDLE hACPI;
     361    APM Apm;
     362
     363    if (!acpihOpen(&hACPI))
     364    {
     365        Apm.bBatteryStatus = 0xff;
     366        if (!acpihGetPowerStatus(&Apm, NULL)) brc = (Apm.bBatteryStatus != 0xFF);
     367        acpihClose(&hACPI);
     368    }
     369
     370    return brc;
     371}
  • branches/branch-1-0/src/helpers/apmh.c

    r184 r406  
    9999    HFILE hfAPMSys = NULLHANDLE;
    100100    ULONG ulAction;
     101    PAPM papm;
    101102
    102103    if (!(arc = DosOpen("\\DEV\\APM$",
     
    121122                              getpowerinfo.usParmLength)))
    122123        {
    123             PAPM papm;
    124             if (!(papm = NEW(APM)))
    125                 arc = ERROR_NOT_ENOUGH_MEMORY;
    126             else
     124            // @@changed V1.0.9 (2012-02-20) [slevine]: reworked to use caller's buffer if passed
     125            // Code from David Azarewicz
     126            if (*ppApm==NULL)
     127            {
     128                if (!(papm = NEW(APM))) arc = ERROR_NOT_ENOUGH_MEMORY;
     129                *ppApm = papm;
     130            }
     131            if (*ppApm)
    127132            {
    128133                ZERO(papm);
Note: See TracChangeset for help on using the changeset viewer.