Logo Search packages:      
Sourcecode: kdeutils version File versions

smapidev.c

#if defined(__linux__) || defined(__FreeBSD__)
/*********************************************************************
 *                
 * Filename:      smapidev.c
 * Description:   IBM SMAPI (System Management API) interface functions
 * Author:        Bill Mair, Thomas Hood
 * Created:       19 July 1999
 *
 * Please report bugs to the author ASAP.
 * 
 *     Copyright (c) 1999 J.D. Thomas Hood and Bill Mair,
 *         All rights reserved
 *     
 *     This program is free software; you can redistribute it and/or 
 *     modify it under the terms of the GNU General Public License as 
 *     published by the Free Software Foundation; either version 2 of 
 *     the License, or (at your option) any later version.
 * 
 *     This program is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 *     GNU General Public License for more details.
 * 
 *     To receive a copy of the GNU General Public License, please write
 *     to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 *     Boston, MA 02111-1307 USA
 *     
 ********************************************************************/

#include <fcntl.h>
#include <stdlib.h>
#ifdef __linux__
#include <linux/unistd.h>
#else
#include <unistd.h>
#endif
#include <getopt.h>
#include <sys/ioctl.h>
#include <errno.h>
#ifdef __linux__
#include <linux/types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <string.h>

#ifndef __linux__
typedef uint8_t __u8 ;
typedef uint16_t __u16 ;
typedef uint32_t __u32 ;
#endif

#include "thinkpad_common.h"
/*#include "thinkpad.h" */
#include "smapi.h"
#include "smapidev.h"

/****** defines ******/

#define SZ_SMAPIDEV_VERSION "2.0"

#define SZ_SMAPIDEV_NAME "smapidev"

/*
 * The structures may need to be extended if more
 * functionality is added to the SMAPI by IBM.
 *
 * To cover this, future releases can check the size
 * defined in sizeStruct, and reduce the amount of
 * information put into the structure accordingly.
 */

#define SIZE_BIOSINFO_V1           ((size_t)24)
#define SIZE_CPUINFO_V1            ((size_t)16)
#define SIZE_DISPLAYINFO_V1        ((size_t) 8)
#define SIZE_DOCKINGINFO_V1        ((size_t)12)
#define SIZE_ULTRABAYINFO_V1       ((size_t) 8)
#define SIZE_SLAVEINFO_V1          ((size_t)12)
#define SIZE_SENSORINFO_V1         ((size_t) 8)
#define SIZE_SCREENREFRESHINFO_V1  ((size_t)12)
#define SIZE_DISPLAYCAP_V1         ((size_t)12)


/****** variables ******/

char szSmapidevName[] = SZ_SMAPIDEV_NAME;


/****** utility functions ******/

/*
 * This function returns the binary value of a two-digit bcd number
 * If the bcd8 value is 0xFF, as it may be if a location has never been
 * initialized in the ThinkPad CMOS RAM, then 0xFF is returned as the
 * binary equivalent.
 */
byte byte_of_bcd8( bcd8_t bcd8The )
{
      byte bTens, bUnits;

      /* catch uninitialized values: simply return them */
      if ( bcd8The == 0xFF ) return 0xFF;

      bUnits = (byte)bcd8The & 0xF;
      bTens = (byte)(bcd8The & 0xF0) >> 4;

      if ( bUnits > 9 || bTens > 9 ) {
            printf( "%s: Warning: value 0x%x which is supposed to be in BCD format is not; not converting.\n", szSmapidevName, bcd8The );
            return (byte)bcd8The;
      }

      return bUnits + (bTens * 10);
}


bcd8_t bcd8_of_byte( byte bThe )
{
      byte bTens, bUnits;

      if ( bThe > 99 ) {
            printf( "%s: the value %d being converted to BCD format will be limited to 99.\n", szSmapidevName, bThe );
            bThe = 99;
      }

      bTens = bThe / (byte)10;
      bUnits = bThe - (bTens * (byte)10);

      return (bTens << 4) | bUnits;
}

/*
 * This function returns the SMAPI BIOS error code if there is one,
 * otherwise the ioctl errno as a negative number
 */
int ioctl_smapi( int intFiledesc, smapi_ioparm_t *pioparmThe )
{
      int intRtn;

      intRtn = ioctl( intFiledesc, IOCTL_SMAPI_REQUEST, pioparmThe );
      if ( intRtn && errno == ETHINKPAD_SUBDRIVER ) return pioparmThe->out.bRc;
      if ( intRtn ) return -errno;
      return 0;
}


/****** functions ******/

int smapidev_GetInfo( smapidev_info_t *pinfoThe )
{

      strncpy( pinfoThe->szVersion, SZ_SMAPIDEV_VERSION, LEN_VERSION_MAX );

      /*** Make sure that the returned string is terminated ***/
      pinfoThe->szVersion[LEN_VERSION_MAX] = '\0';

      return 0;
}


/*** smapi-module-access functions ***/


/*
 * The Technical Reference fails to mention that the returned 
 * BIOS revision values are in BCD format
 */
int smapidev_GetBiosInfo(
      int intFiledesc,
      smapidev_biosinfo_t *pbiosinfoThe
) {
      bcd8_t bcd8SysHigh, bcd8SysLow;
      bcd8_t bcd8SysMgmtHigh, bcd8SysMgmtLow;
      bcd8_t bcd8SMAPIIfaceHigh, bcd8SMAPIIfaceLow;
      bcd8_t bcd8VideoHigh, bcd8VideoLow;
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pbiosinfoThe->sizeStruct != SIZE_BIOSINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetBiosInfo\n" , pbiosinfoThe->sizeStruct, SIZE_BIOSINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );

      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 0;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pbiosinfoThe->wSysId               = ioparmThe.out.wParm1;
      pbiosinfoThe->wCountryCode         = ioparmThe.out.wParm2;

      bcd8SysHigh =     (bcd8_t)( ioparmThe.out.wParm3 >> 8          );
      bcd8SysLow =      (bcd8_t)( ioparmThe.out.wParm3        & 0xFF );
      pbiosinfoThe->wSysBiosRevMajor     = (word) byte_of_bcd8( bcd8SysHigh );
      pbiosinfoThe->wSysBiosRevMinor     = (word) byte_of_bcd8( bcd8SysLow );

      bcd8SysMgmtHigh = (bcd8_t)( (ioparmThe.out.dwParm4 >> 8) & 0xFF );
      bcd8SysMgmtLow =  (bcd8_t)(  ioparmThe.out.dwParm4       & 0xFF );
      pbiosinfoThe->wSysMgmtBiosRevMajor = (word) byte_of_bcd8( bcd8SysMgmtHigh );
      pbiosinfoThe->wSysMgmtBiosRevMinor = (word) byte_of_bcd8( bcd8SysMgmtLow );

      bcd8SMAPIIfaceHigh =   (bcd8_t)( (ioparmThe.out.dwParm5 >> 8) & 0xFF );
      bcd8SMAPIIfaceLow =    (bcd8_t)(  ioparmThe.out.dwParm5       & 0xFF );
      pbiosinfoThe->wSmapiBiosIfaceRevMajor = (word) byte_of_bcd8( bcd8SMAPIIfaceHigh );
      pbiosinfoThe->wSmapiBiosIfaceRevMinor = (word) byte_of_bcd8( bcd8SMAPIIfaceLow );

      /*** Video BIOS info ***/
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 8;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      bcd8VideoHigh =   (bcd8_t)( (ioparmThe.out.wParm1 >> 8)        );
      bcd8VideoLow =    (bcd8_t)(  ioparmThe.out.wParm1       & 0xFF );

      pbiosinfoThe->wVideoBiosRevMajor = (word) byte_of_bcd8( bcd8VideoHigh );
      pbiosinfoThe->wVideoBiosRevMinor = (word) byte_of_bcd8( bcd8VideoLow );

      return 0;
}


int smapidev_GetCpuInfo(
      int intFiledesc,
      smapidev_cpuinfo_t *pcpuinfoThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pcpuinfoThe->sizeStruct != SIZE_CPUINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetCpuInfo\n" , pcpuinfoThe->sizeStruct, SIZE_CPUINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 1;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pcpuinfoThe->wManufacturer = (word)( 0xFF &  ioparmThe.out.wParm1 );
      pcpuinfoThe->wType         = (word)( 0xFF & (ioparmThe.out.wParm2 >> 8) );
      pcpuinfoThe->wStepping     = (word)( 0xFF &  ioparmThe.out.wParm2 );

      pcpuinfoThe->wClock        = (word)( 0xFF & (ioparmThe.out.wParm3 >> 8) );

      if ( pcpuinfoThe->wClock == 0xfe )
            pcpuinfoThe->wClock = (word) ioparmThe.out.dwParm4;

      pcpuinfoThe->wInternalClock = (word)( 0xFF & ioparmThe.out.wParm3 );
      if ( pcpuinfoThe->wInternalClock == 0xfe )
            pcpuinfoThe->wInternalClock = (word) ioparmThe.out.dwParm5;

      return 0;
}


int smapidev_GetDisplayInfo(
      int intFiledesc,
      smapidev_displayinfo_t *pdisplayinfoThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pdisplayinfoThe->sizeStruct != SIZE_DISPLAYINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetDisplayInfo\n" , pdisplayinfoThe->sizeStruct, SIZE_DISPLAYINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc    = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 2;
      ioparmThe.in.wParm1   = (word) 0x300;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pdisplayinfoThe->bPanelType   = (byte)(ioparmThe.out.wParm1 >> 8);
      pdisplayinfoThe->bPanelDim    = (byte)(ioparmThe.out.wParm1 & 0xFF);
      pdisplayinfoThe->bCrtType     = (byte)(ioparmThe.out.wParm2 >> 8);
      pdisplayinfoThe->bCrtFeatures = (byte)(ioparmThe.out.wParm2 & 0xFF);

      return 0;
}


int smapidev_GetDockingInfo(
      int intFiledesc,
      smapidev_dockinginfo_t *pdockinginfoThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pdockinginfoThe->sizeStruct != SIZE_DOCKINGINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetDockingInfo\n" , pdockinginfoThe->sizeStruct, SIZE_DOCKINGINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 3;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pdockinginfoThe->wID           =           ioparmThe.out.wParm1;  
      pdockinginfoThe->fDocked       = (flag_t)( ioparmThe.out.bSubRc       & 1);
      pdockinginfoThe->fKeyUnlocked  = (flag_t)((ioparmThe.out.bSubRc >> 6) & 1);
      pdockinginfoThe->fBusConnected = (flag_t)((ioparmThe.out.bSubRc >> 7) & 1);

      return 0;
}


int smapidev_GetUltrabayInfo(
      int intFiledesc,
      smapidev_ultrabayinfo_t *pultrabayinfoThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pultrabayinfoThe->sizeStruct != SIZE_ULTRABAYINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetUltrabayInfo\n" , pultrabayinfoThe->sizeStruct, SIZE_ULTRABAYINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 4;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pultrabayinfoThe->bType = (byte)(ioparmThe.out.wParm2 >> 8);
      pultrabayinfoThe->bID   = (byte)(ioparmThe.out.wParm2 & 0xFF);

      return 0;
}


/*
 * The ThinkPad 560Z Technical Reference describes function 0:6 as
 * "Get Power Management Module Information" while the ThinkPad 600
 * describes it as "Get Slave Micro Control Unit Information"
 */
int smapidev_GetSlaveControllerInfo(
      int intFiledesc,
      smapidev_slaveinfo_t *pslaveinfoThe
) {
      smapi_ioparm_t ioparmThe;
      bcd8_t bcd8High = 0, bcd8Low = 0;
      flag_t fInvalidID;
      int intRtn;

      /* Check structure size */
      if( pslaveinfoThe->sizeStruct != SIZE_SLAVEINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetSlaveControllerInfo\n" , pslaveinfoThe->sizeStruct, SIZE_SLAVEINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 6;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      if ( ioparmThe.out.wParm2 == 0xFFFF ) {
            fInvalidID = 1;
      } else {
            fInvalidID = 0;
            bcd8High = (bcd8_t)( ioparmThe.out.wParm2 >> 8 );
            bcd8Low  = (bcd8_t)( ioparmThe.out.wParm2 & 0xFF );
      }

      pslaveinfoThe->fAscii  = (ioparmThe.out.bSubRc == 0);
      if ( fInvalidID ) {
            pslaveinfoThe->wIDMajor = 0xFFFF;
            pslaveinfoThe->wIDMinor = 0xFFFF;
      } else {
            pslaveinfoThe->wIDMajor = byte_of_bcd8( bcd8High );
            pslaveinfoThe->wIDMinor = byte_of_bcd8( bcd8Low );
      }
      pslaveinfoThe->szID[0] = (char)(0xFF&(ioparmThe.out.wParm2>>8));
      pslaveinfoThe->szID[1] = (char)(0xFF&ioparmThe.out.wParm2);
      pslaveinfoThe->szID[2] = '\0'; /* Add zero termination */

      return 0;
}


int smapidev_GetSensorInfo(
      int intFiledesc,
      smapidev_sensorinfo_t *psensorinfoThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( psensorinfoThe->sizeStruct != SIZE_SENSORINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetSensorInfo\n" , psensorinfoThe->sizeStruct, SIZE_SENSORINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 7;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      psensorinfoThe->fLidClosed         = (ioparmThe.out.wParm2 >>  8) & 1;
      psensorinfoThe->fKeyboardOpen      = (ioparmThe.out.wParm2 >>  9) & 1;
      psensorinfoThe->fACAdapterAttached = (ioparmThe.out.wParm2 >> 10) & 1;

      return 0;
}

int smapidev_GetScreenRefreshInfo(
      int intFiledesc,
      word wMode,
      smapidev_screenrefreshinfo_t *pscreenrefreshinfoThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pscreenrefreshinfoThe->sizeStruct != SIZE_SCREENREFRESHINFO_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetScreenRefreshInfo\n" , pscreenrefreshinfoThe->sizeStruct, SIZE_SCREENREFRESHINFO_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0;
      ioparmThe.in.bSubFunc = (byte) 9;
      ioparmThe.in.wParm1 = wMode;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pscreenrefreshinfoThe->f43i = (ioparmThe.out.wParm2 >> 3) & 1;
      pscreenrefreshinfoThe->f48i = (ioparmThe.out.wParm2 >> 7) & 1;
      pscreenrefreshinfoThe->f56  = (ioparmThe.out.wParm2 >> 4) & 1;
      pscreenrefreshinfoThe->f60  =  ioparmThe.out.wParm2 & 1;
      pscreenrefreshinfoThe->f70  = (ioparmThe.out.wParm2 >> 5) & 1;
      pscreenrefreshinfoThe->f72  = (ioparmThe.out.wParm2 >> 1) & 1;
      pscreenrefreshinfoThe->f75  = (ioparmThe.out.wParm2 >> 2) & 1;
      pscreenrefreshinfoThe->f85  = (ioparmThe.out.wParm2 >> 6) & 1;

      return 0;
}


int smapidev_GetDisplayCapability(
      int intFiledesc,
      smapidev_stateplace_t stateplace,
      smapidev_displaycap_t *pdisplaycapThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      /* Check structure size */
      if( pdisplaycapThe->sizeStruct != SIZE_DISPLAYCAP_V1 ) {
#           if DEBUG_STRUCT_SIZES
            printf( "Declared size %d does not match expected size %d in GetDisplayCapability\n" , pdisplaycapThe->sizeStruct, SIZE_DISPLAYCAP_V1 );
#           endif
            return ERR_SMAPIDEV_STRUCTURE_SIZE_INVALID;
      }

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0x10;
      ioparmThe.in.bSubFunc = (byte) 0;
      switch ( stateplace ) {
            case SMAPIDEV_STATEPLACE_CMOS: ioparmThe.in.wParm1 = (word) 1; break;
            case SMAPIDEV_STATEPLACE_CURR: ioparmThe.in.wParm1 = (word) 0; break;
            case SMAPIDEV_STATEPLACE_CMOS_AND_CURR:
            default: return ERR_SMAPIDEV_PARM_INVALID;
      }

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      pdisplaycapThe->fSupported = (flag_t)(ioparmThe.out.wParm2 & 1);
      switch ( ioparmThe.out.wParm2 & 0xFF ) {
            case 0:
                  pdisplaycapThe->tv = SMAPIDEV_DISPLAYCAPTV_NONE;
            break;
            case 1:
                  pdisplaycapThe->tv = SMAPIDEV_DISPLAYCAPTV_NONSIMULTANEOUS;
            break;
            default:
                  pdisplaycapThe->tv = SMAPIDEV_DISPLAYCAPTV_OTHER;
                  return ERR_SMAPIDEV_SMAPI_RESULT_NOT_UNDERSTOOD;
      }

      return 0;
}


int smapidev_GetDisplayState(
      int intFiledesc,
      smapidev_stateplace_t stateplace,
      smapidev_dispmode_t dispmodeThe,
      smapidev_ablestate_t *pablestateThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0x10;
      ioparmThe.in.bSubFunc = (byte) 0;
      switch ( stateplace ) {
            case SMAPIDEV_STATEPLACE_CMOS: ioparmThe.in.wParm1 = (word) 1; break;
            case SMAPIDEV_STATEPLACE_CURR: ioparmThe.in.wParm1 = (word) 0; break;
            case SMAPIDEV_STATEPLACE_CMOS_AND_CURR:
            default: return ERR_SMAPIDEV_PARM_INVALID;
      }

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      switch( dispmodeThe )
      {
            case SMAPIDEV_DISPMODE_INTERNAL :
                  *pablestateThe = ( ioparmThe.out.wParm2 & 0x100 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
            break;

            case SMAPIDEV_DISPMODE_CRT :
                  *pablestateThe = ( ioparmThe.out.wParm2 & 0x200 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
            break;

            case SMAPIDEV_DISPMODE_TV :
                  *pablestateThe = ( ioparmThe.out.wParm2 & 0x400 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
            break;

            case SMAPIDEV_DISPMODE_CRT_DETECTION_IGNORE :
                  *pablestateThe = ( ioparmThe.out.wParm2 & 0x4000 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
            break;

            case SMAPIDEV_DISPMODE_DUAL :
                  *pablestateThe = ( ioparmThe.out.wParm2 & 0x8000 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
            break;

            case SMAPIDEV_DISPMODE_SELECT_TV :
                  *pablestateThe = ( ioparmThe.out.dwParm4 & 1 ) ? SMAPIDEV_ABLESTATE_ENABLED : SMAPIDEV_ABLESTATE_DISABLED ;
            break;

            default:
                  return ERR_SMAPIDEV_PARM_INVALID;
      }

      return 0;
}


int smapidev_SetDisplayState(
      int intFiledesc,
      smapidev_stateplace_t stateplace,
      smapidev_dispmode_t dispmodeThe,
      smapidev_ablestate_t ablestateThe
) {
      smapi_ioparm_t ioparmGet;
      smapi_ioparm_t ioparmSet;
      int intRtn;

      /* We can only update CMOS and current state together */
      if ( stateplace != SMAPIDEV_STATEPLACE_CMOS_AND_CURR ) 
            return ERR_SMAPIDEV_PARM_INVALID;
      
      /* No SMAPIDEV_STATE_AUTO or other invalid values are allowed here */
      if( ablestateThe != SMAPIDEV_ABLESTATE_DISABLED && ablestateThe != SMAPIDEV_ABLESTATE_ENABLED )
      {
            return ERR_SMAPIDEV_PARM_INVALID;
      }

      /* Get the current CMOS state */
      memset( &ioparmGet, 0, sizeof( ioparmGet ) );
      ioparmGet.in.bFunc     = (byte)  0x10;
      ioparmGet.in.bSubFunc  = (byte)  0;
      ioparmGet.in.wParm1    = (word) 1; 

      intRtn = ioctl_smapi( intFiledesc, &ioparmGet );
      if ( intRtn ) return intRtn;

      memset( &ioparmSet, 0, sizeof( ioparmSet ) );
      ioparmSet.in.bFunc     = (byte) 0x10;
      ioparmSet.in.bSubFunc  = (byte) 1;
      ioparmSet.in.wParm1    = ioparmGet.out.wParm2 & 0xC700;
      ioparmSet.in.dwParm4   = ioparmGet.out.dwParm4 & 0x0001;

      switch( dispmodeThe )
      {

            case SMAPIDEV_DISPMODE_INTERNAL :
                  if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
                        ioparmSet.in.wParm1 |=  0x100;
                  else
                        ioparmSet.in.wParm1 &= ~0x100;
            break;

            case SMAPIDEV_DISPMODE_CRT :
                  if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
                        ioparmSet.in.wParm1 |=  0x200;
                  else
                        ioparmSet.in.wParm1 &= ~0x200;
            break;

            case SMAPIDEV_DISPMODE_TV :
                  if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
                        ioparmSet.in.wParm1 |=  0x400;
                  else
                        ioparmSet.in.wParm1 &= ~0x400;
            break;

            case SMAPIDEV_DISPMODE_CRT_DETECTION_IGNORE :
                  if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
                        ioparmSet.in.wParm1 |=  0x4000;
                  else
                        ioparmSet.in.wParm1 &= ~0x4000;
            break;

            case SMAPIDEV_DISPMODE_DUAL :
                  if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
                        ioparmSet.in.wParm1 |=  0x8000;
                  else
                        ioparmSet.in.wParm1 &= ~0x8000;
            break;

            case SMAPIDEV_DISPMODE_SELECT_TV :
                  if( ablestateThe == SMAPIDEV_ABLESTATE_ENABLED )
                        ioparmSet.in.dwParm4 |=  0x1;
                  else
                        ioparmSet.in.dwParm4 &= ~0x1;
            break;

            default:
                  return ERR_SMAPIDEV_PARM_INVALID;
      }

      return ioctl_smapi( intFiledesc, &ioparmSet );
}


int smapidev_GetPowerExpenditureMode(
      int intFiledesc,
      smapidev_powersrc_t powersrcThe,
      smapidev_powermode_t *ppowermodeThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;
      byte bModeAC, bModeBat, bModeSelected;

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0x22;
      ioparmThe.in.bSubFunc = (byte) 0;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      bModeAC = (byte)(ioparmThe.out.wParm2 & 0xFF);
      bModeBat = (byte)(ioparmThe.out.wParm2 >> 8);
      bModeSelected = (powersrcThe == SMAPIDEV_POWERSRC_AC) ? bModeAC : bModeBat;

      switch ( bModeSelected ) {
            case 0: *ppowermodeThe = SMAPIDEV_POWERMODE_HIGH; break;
            case 1: *ppowermodeThe = SMAPIDEV_POWERMODE_AUTO; break;
            case 2: *ppowermodeThe = SMAPIDEV_POWERMODE_MANUAL; break;
            default:
            case 3: *ppowermodeThe = SMAPIDEV_POWERMODE_UNRECOGNIZED; break;
      }

      return 0;
}



int smapidev_SetPowerExpenditureMode(
      int intFiledesc,
      smapidev_powersrc_t powersrcThe,
      smapidev_powermode_t powermodeThe
) {
      smapi_ioparm_t ioparmThe;
      int intRtn;
      byte bMode;

      bMode =
            (powermodeThe == SMAPIDEV_POWERMODE_HIGH) ? 0 :
            (powermodeThe == SMAPIDEV_POWERMODE_AUTO) ? 1 :
            2
      ;

      memset( &ioparmThe, 0, sizeof( ioparmThe ) );
      ioparmThe.in.bFunc = (byte) 0x22;
      ioparmThe.in.bSubFunc = (byte) 0;

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      ioparmThe.in.bFunc = (byte) 0x22;
      ioparmThe.in.bSubFunc = (byte) 1;
      ioparmThe.in.wParm1 = ioparmThe.out.wParm2;
      if ( powersrcThe == SMAPIDEV_POWERSRC_AC ) {
            ioparmThe.in.wParm1 &= 0xff00;
            ioparmThe.in.wParm1 |= bMode;
      } else { /* powersrcThe == SMAPIDEV_POWERSRC_BATTERY */
            ioparmThe.in.wParm1 &= 0x00ff;
            ioparmThe.in.wParm1 |= ((word)bMode) << 8;
      }

      intRtn = ioctl_smapi( intFiledesc, &ioparmThe );
      if ( intRtn ) return intRtn;

      return 0;
}
#else
int smapi_dummy(){}
#endif

Generated by  Doxygen 1.6.0   Back to index