#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., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA * ********************************************************************/ #include #include #ifdef __linux__ #include #else #include #endif #include #include #include #ifdef __linux__ #include #else #include #endif #include #include #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