diff options
Diffstat (limited to 'klaptopdaemon/smapidev.c')
-rw-r--r-- | klaptopdaemon/smapidev.c | 743 |
1 files changed, 743 insertions, 0 deletions
diff --git a/klaptopdaemon/smapidev.c b/klaptopdaemon/smapidev.c new file mode 100644 index 0000000..3dbcd6d --- /dev/null +++ b/klaptopdaemon/smapidev.c @@ -0,0 +1,743 @@ +#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 <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 |