You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
744 lines
21 KiB
744 lines
21 KiB
15 years ago
|
#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
|