📄 wmpower.c
字号:
/*-----------------------------------------------------------------------------
* Copyright (c) Wolfson Microelectronics plc. All rights reserved.
*
* This software as well as any related documentation is furnished under
* license and may only be used or copied in accordance with the terms of the
* license. The information in this file is furnished for informational use
* only, is subject to change without notice, and should not be construed as
* a commitment by Wolfson Microelectronics plc. Wolfson Microelectronics plc
* assumes no responsibility or liability for any errors or inaccuracies that
* may appear in this document or any software that may be provided in
* association with this document.
*
* Except as permitted by such license, no part of this document may be
* reproduced, stored in a retrieval system, or transmitted in any form or by
* any means without the express written consent of Wolfson Microelectronics plc.
*
* $Id: WMPower.c 2828 2006-04-06 14:11:45Z ian $
*
* This file contains functionality for controlling power.
*
* Warning:
* This driver is specifically written for Wolfson Codecs. It is not a
* general CODEC device driver.
*
* -----------------------------------------------------------------------------*/
/*
* Include files
*/
#include "WMCommon.h"
#include "WMDevice.h"
#include "WMControlLink.h"
#include "WMGlobals.h"
#include "WMPower.h"
/*
* Global definitions
*/
/*
* Touch panel masks.
*/
/*
* Private data
*/
/*
* Function prototypes
*/
/*-----------------------------------------------------------------------------
* Function: WMPowerUp
*
* Called to power up the specific sections of the chip on behalf of this
* driver.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* driverId The driver ID (e.g. WM_DRIVER_TOUCH)
* powerSections The sections to power up.
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
WMSTATUS WMPowerUp( WM_DEVICE_HANDLE hDevice,
WM_DRIVER_ID driverId,
WM_POWERFLAG powerSections
)
{
WMSTATUS status = WMS_UNSUPPORTED;
const WM_CHIPDEF *pChipDef;
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto done;
}
/*
* Can we do power-up?
*/
if ( !pChipDef->vtable.fnPowerUp )
{
status = WMS_UNSUPPORTED;
goto done;
}
/*
* Lock our global data.
*/
if ( !WMLockGlobalData( hDevice ) )
{
status = WMS_LOCK_TIMED_OUT;
goto done;
}
status = pChipDef->vtable.fnPowerUp( hDevice,
driverId,
powerSections
);
/* Let other threads in again */
WMUnlockGlobalData( hDevice );
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMPowerDown
*
* Called to power down the specific sections of the chip on behalf of this
* driver. Note if the driver can tell that the sections are still in use
* by another driver they will not actually be powered down.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* driverId The driver ID (e.g. WM_DRIVER_TOUCH)
* powerSections The sections to power down.
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
WMSTATUS WMPowerDown( WM_DEVICE_HANDLE hDevice,
WM_DRIVER_ID driverId,
WM_POWERFLAG powerSections
)
{
WMSTATUS status = WMS_UNSUPPORTED;
const WM_CHIPDEF *pChipDef;
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto done;
}
/*
* Can we do power-down?
*/
if ( !pChipDef->vtable.fnPowerDown )
{
status = WMS_UNSUPPORTED;
goto done;
}
/*
* Lock our global data.
*/
if ( !WMLockGlobalData( hDevice ) )
{
status = WMS_LOCK_TIMED_OUT;
goto done;
}
status = pChipDef->vtable.fnPowerDown( hDevice,
driverId,
powerSections
);
/* Let other threads in again */
WMUnlockGlobalData( hDevice );
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WMGetCurrentPowerState
*
* Returns the current power state - either cached or by looking at the register.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
*
* Returns: WM_POWERFLAG
* The current power state.
*---------------------------------------------------------------------------*/
WM_POWERFLAG WMGetCurrentPowerState( WM_DEVICE_HANDLE hDevice )
{
WM_POWERFLAG currentPower = 0;
/*
* I2S devices implicitly have the link.
*/
if ( WM_IS_I2S( hDevice ) )
{
currentPower |= WM_POWER_LINK;
}
#if WM_CACHE_POWER_STATE
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
if ( pDeviceContext->v_pWMData )
{
if ( pDeviceContext->v_pWMData->powerStateFlags & WM_ASLEEP )
currentPower = 0;
else
currentPower = pDeviceContext->v_pWMData->WmPower;
}
else
#endif /* WM_CACHE_POWER_STATE */
{
const WM_CHIPDEF *pChipDef;
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
goto done;
}
/*
* Can we get the current power?
*/
if ( !pChipDef->vtable.fnGetPower )
{
goto done;
}
/*
* Make the call.
*/
if ( pChipDef->vtable.fnGetPower )
{
currentPower = pChipDef->vtable.fnGetPower( hDevice );
}
}
done:
return currentPower;
}
/*-----------------------------------------------------------------------------
* Function: calcPowered
*
* Works out what should currently be powered up, based on what all the drivers
* are requesting and the various dependencies.
*
* NB This function only makes sense if we have global data pointer.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* driverId The device ID (e.g. WM_DRIVER_TOUCH)
* powerUp The sections to power up.
* powerDown The sections to power down.
* pCurrentPower A pointer to receive the current power state.
*
* Returns: WM_POWERFLAG
* The bitmask describing the sections which should be powered up.
*---------------------------------------------------------------------------*/
WM_POWERFLAG calcPowered( WM_DEVICE_HANDLE hDevice,
WM_DRIVER_ID driverId,
WM_POWERFLAG powerUp,
WM_POWERFLAG powerDown,
WM_POWERFLAG *pCurrentPower
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
WM_POWERFLAG newPowered = 0;
#if WM_CACHE_POWER_STATE
unsigned int driver = DRIVER_TO_INDEX( driverId );
WM_ASSERT( hDevice, driver < WM_MAX_DRIVERS );
#endif /* WM_CACHE_POWER_STATE */
/*
* Work out what's currently on.
*/
*pCurrentPower = WMGetCurrentPowerState( hDevice );
/*
* If we're entering sleep, we want everything powered off.
*/
if ( pDeviceContext->v_pWMData->powerStateFlags & WM_ENTERING_SLEEP )
{
newPowered = 0;
goto done;
}
/*
* Check whether we've got our globals.
*/
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData )
{
int drv;
/*
* Update our driver settings.
*/
pDeviceContext->v_pWMData->powerRequirements[driver] |= powerUp;
pDeviceContext->v_pWMData->powerRequirements[driver] &= ~powerDown;
/*
* Check what all the drivers are asking for.
*/
for ( drv = 0; drv < WM_MAX_DRIVERS; drv++ )
{
newPowered |= pDeviceContext->v_pWMData->powerRequirements[drv];
}
}
else
#endif /* WM_CACHE_POWER_STATE */
{
newPowered = ( *pCurrentPower | powerUp ) & ~powerDown;
}
#if WM_TOUCH
/*
* If we've had pen down, the link is up and so is the digitiser.
*/
if ( WM_IS_TOUCH_SUPPORTED( hDevice ) &&
( WM_DRIVER_TOUCH == driverId ) )
{
if ( newPowered & WM_POWER_PEN_DETECTED )
{
newPowered |= WM_POWER_AUXADC_DIGITISER | WM_POWER_LINK;
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData )
{
pDeviceContext->v_pWMData->WmPower |=
WM_POWER_AUXADC_DIGITISER | WM_POWER_LINK;
}
#endif /* WM_CACHE_POWER_STATE */
}
else
{
newPowered |= WM_POWER_PEN_DETECT | WM_POWER_LINK;
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData )
{
pDeviceContext->v_pWMData->WmPower |=
WM_POWER_PEN_DETECT | WM_POWER_LINK;
}
#endif /* WM_CACHE_POWER_STATE */
}
}
#endif /* WM_TOUCH */
#if WM_AUXADC
/*
* If we've requested an aux adc reading, the link is up and so is the digitiser.
*/
if ( WM_IS_AUXADC_SUPPORTED( hDevice ) &&
( WM_DRIVER_AUXADC == driverId ) )
{
if ( newPowered & WM_POWER_AUXADC_DIGITISER )
{
newPowered |= WM_POWER_LINK;
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData )
{
pDeviceContext->v_pWMData->WmPower |=
WM_POWER_AUXADC_DIGITISER | WM_POWER_LINK;
}
#endif /* WM_CACHE_POWER_STATE */
}
}
#endif /* WM_AUXADC */
/*
* Now work out dependencies.
*/
/* Anything audio needs audio stuff powered up */
if ( newPowered & ( WM_POWER_AUDIO_DACS
| WM_POWER_OUTPUTS
| WM_POWER_INPUTS )
)
{
newPowered |= WM_POWER_MIXERS | WM_POWER_VREF;
}
/* The ADC just needs the references */
if ( newPowered & WM_POWER_AUDIO_ADCS )
{
newPowered |= WM_POWER_VREF;
}
/* For the digital stuff we need the link and the internal clocks. */
if ( newPowered & ( WM_POWER_AUDIO_ADCS
| WM_POWER_AUDIO_DACS )
)
{
newPowered |= WM_POWER_CLOCK | WM_POWER_LINK;
}
/* The AuxADC requires the references and the link */
if ( newPowered & WM_POWER_AUXADC_DIGITISER )
{
newPowered |= WM_POWER_VREF | WM_POWER_LINK;
}
done:
return newPowered;
}
/*------------------------------ END OF FILE ---------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -