📄 wm8731power.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: WM8731Power.c 2828 2006-04-06 14:11:45Z ian $
*
* This file contains functionality for controlling power on WM8731 codecs.
*
* Warning:
* This driver is specifically written for Wolfson Codecs. It is not a
* general CODEC device driver.
*
* -----------------------------------------------------------------------------*/
/*
* Include files
*/
#include "WMCommon.h"
#include "WMPower.h"
#include "WM8731Power.h"
#include "WM8731RegisterDefs.h"
#include "WMControlLink.h"
#include "WMGlobals.h"
/*
* Global definitions
*/
/*
* Touch panel masks.
*/
/*
* Private data
*/
/*
* Only provide these if we're supporting WM8731 devices.
*/
#if WM8731_FAMILY
/*
* Function prototypes
*/
static WM_POWERFLAG private_CalcPowered( WM_DEVICE_HANDLE hDevice,
WM_DRIVER_ID driverId,
WM_POWERFLAG powerUp,
WM_POWERFLAG powerDown,
WM_POWERFLAG *pCurrentPower
);
/*-----------------------------------------------------------------------------
* Function: WM8731PowerUp
*
* 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 device ID (e.g. WM_DRIVER_TOUCH)
* powerSections The sections to power up.
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
WMSTATUS WM8731PowerUp( WM_DEVICE_HANDLE hDevice,
WM_DRIVER_ID driverId,
WM_POWERFLAG powerSections
)
{
#if WM_CACHE_POWER_STATE
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
#endif /* WM_CACHE_POWER_STATE */
WM_POWERFLAG newPowered = 0; /* What should be powered when we finish */
WM_POWERFLAG powerUp; /* What should be but isn't yet */
WM_REGVAL powerVal = 0;
WM_POWERFLAG currentPower = 0;
WMSTATUS status = WMS_SUCCESS;
/*
* Work out what we need powered on.
* newPowered is what will be powered on at the end.
* powerUp is what will be powered up which isn't currently.
*
* Note: there are things which need to be done even if the codec is
* powered up, since some codecs start up with everything on. In this
* case we don't need to power anything up, but we still need to do
* other things such as enabling on-board amplifiers (for example).
*/
newPowered = private_CalcPowered( hDevice, driverId, powerSections, 0, ¤tPower );
powerUp = newPowered & ~currentPower;
/*
* Get the current reading if necessary.
*/
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData &&
(pDeviceContext->v_pWMData->flags & WM_POWERREG_VALID)
)
{
powerVal = pDeviceContext->v_pWMData->powerReg[0];
}
else
#endif /* WM_CACHE_POWER_STATE */
{
/*
* Get the current power status of the device.
*/
status = WMRead( hDevice, WM8731_POWERDOWN_CONTROL, &powerVal );
if ( WM_ERROR( status ) )
{
goto error;
}
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData )
{
pDeviceContext->v_pWMData->flags |= WM_POWERREG_VALID;
}
#endif /* WM_CACHE_POWER_STATE */
}
/*
* Enable audio.
*
* Note: we use newPowered in this test (instead of powerUp)
* because there are things we may still need to do if the
* audio starts up powered up.
*/
if ( newPowered & WM_POWER_AUDIO )
{
if ( powerUp & WM_POWER_VREF )
{
powerVal |= WM8731_POWERDOWN_POWEROFF;
}
if ( powerUp & WM_POWER_CLOCK )
{
powerVal |= WM8731_POWERDOWN_OSCILLATOR |
WM8731_POWERDOWN_CLKOUT;
}
if ( powerUp & WM_POWER_INPUTS )
{
powerVal |= WM8731_POWERDOWN_INPUTS;
}
if ( powerUp & WM_POWER_AUDIO_ADC )
{
powerVal |= WM8731_POWERDOWN_ADC;
}
if ( powerUp & WM_POWER_AUDIO_DAC )
{
powerVal |= WM8731_POWERDOWN_DAC;
}
/*
* Now write everything so far - but not the outputs (see WAN0111).
*/
status = WMClearField( hDevice, WM8731_POWERDOWN_CONTROL, powerVal );
if ( WM_ERROR( status ) )
{
goto error;
}
/*
* We do this now to reduce pops.
*/
if ( powerUp & WM_POWER_OUTPUTS )
{
status = WMClearField( hDevice, WM8731_POWERDOWN_CONTROL, WM8731_POWERDOWN_OUTPUTS );
if ( WM_ERROR( status ) )
{
goto error;
}
}
/*
* Turn on the on-board amplifiers if needed.
*
* Note: this needs to happen even if these parts of the
* chip were already powered up - hence why we're using
* newPowered instead of powerUp.
*/
if ( newPowered & ( WM_POWER_VREF | WM_POWER_MIXERS ) )
{
WMPlatformEnableAmplifiers( hDevice );
}
}
/*
* Now remember what we've got on.
*/
#if WM_CACHE_POWER_STATE
if ( pDeviceContext->v_pWMData )
{
pDeviceContext->v_pWMData->WmPower = newPowered;
}
#endif /* WM_CACHE_POWER_STATE */
return WMS_SUCCESS;
error:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WM8731PowerDown
*
* 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 device ID (e.g. WM_DRIVER_TOUCH)
* powerSections The sections to power down.
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
WMSTATUS WM8731PowerDown( WM_DEVICE_HANDLE hDevice,
WM_DRIVER_ID driverId,
WM_POWERFLAG powerSections
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
WM_POWERFLAG newPowered = 0; /* What should be powered up at the end */
WM_POWERFLAG powerDown; /* What is powered that shouldn't be */
WM_REGVAL powerVal = 0;
WM_POWERFLAG currentPower;
WMSTATUS status = WMS_SUCCESS;
WM_ASSERT( hDevice, NULL != pDeviceContext );
/*
* If we're not yet initialised, there's nothing to do.
*/
if ( !pDeviceContext->flags & DEVICE_INITIALISED )
{
goto done;
}
/*
* Work out what we need powered off. We set up a few
* variables here:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -