⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wm8753power.c

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/*-----------------------------------------------------------------------------
 * 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: WM8753Power.c 2828 2006-04-06 14:11:45Z ian $
 *
 * This file contains functionality for controlling power on WM8753 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 "WM8753Power.h"
#include "WM8753RegisterDefs.h"
#include "WMControlLink.h"
#include "WMGlobals.h"

/*
 * Global definitions
 */

/*
 * Touch panel masks.
 */

/*
 * Private data
 */

/*
 * Only provide these if we're supporting WM8753 devices.
 */
#if WM8753_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:    WM8753PowerUp
 *
 * 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 WM8753PowerUp( 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[WM8753_MAX_POWER_REGS];
	WM_REGTYPE			powerReg = WM8753_PWR_MGMT_1;
    WM_POWERFLAG        currentPower = 0;
	int					powerLoop;
    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, &currentPower );
    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)
       )
    {
		for ( powerLoop = 0; powerLoop < WM8753_MAX_POWER_REGS; powerLoop++ )
		{
            powerVal[powerLoop] = pDeviceContext->v_pWMData->powerReg[powerLoop];
		}
    }
    else
#endif /* WM_CACHE_POWER_STATE */
    {
		/*
		 * Get the current power status of the device.
		 */
		for ( powerLoop = 0; powerLoop < WM8753_MAX_POWER_REGS; powerLoop++ )
		{
            status = WMRead( hDevice, powerReg++, &powerVal[powerLoop] );
            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[PWR_REG_1] |= ( WM8753_PWR1_VMIDSEL_50KOHM &
                                     WM8753_PWR1_VMIDSEL_MASK ) |
                                     WM8753_PWR1_VREF;
		}

		if ( powerUp & WM_POWER_INPUTS )
		{
            powerVal[PWR_REG_2] |= WM8753_PWR2_MICAMPEN;

		}

		if ( powerUp & WM_POWER_MIXERS )
		{
			powerVal[PWR_REG_2] |= WM8753_PWR2_MIX;

			powerVal[PWR_REG_4] |= WM8753_PWR4_MIX;
		}

		if ( powerUp & WM_POWER_AUDIO_HIFI_ADC )
		{
			powerVal[PWR_REG_2] |= WM8753_PWR2_ADC;	
		}

		if ( powerUp & WM_POWER_AUDIO_HIFI_DAC )
		{
            powerVal[PWR_REG_1] |= WM8753_PWR1_HIFIDAC;
		}

		if ( powerUp & WM_POWER_AUDIO_VOICE_DAC )
		{
            powerVal[PWR_REG_1] |= WM8753_PWR1_VXDAC;
		}
        
        /* We need MCLK for any DAC or ADC */ 
        if ( powerUp & ( WM_POWER_AUDIO_DACS | WM_POWER_AUDIO_ADCS ) )
        {
            /*
             * This is the one bit which is a power *down* bit -
             * i.e. clear to enable.
             */
            powerVal[PWR_REG_1] &= ~WM8753_PWR1_DIGENB;
        }

        if ( powerUp & WM_POWER_CLOCK )
        {
            powerVal[PWR_REG_1] &= ~WM8753_PWR1_DIGENB;
        }

		if ( powerUp & WM_POWER_OUTPUTS	)
		{
            powerVal[PWR_REG_3] |= WM8753_PWR3_OUTPUT;
		}


		/* Set up powerReg so that is starts with the first power register. */
		powerReg = WM8753_PWR_MGMT_1;

		for ( powerLoop = 0; powerLoop < WM8753_MAX_POWER_REGS; powerLoop++ )
		{
			status = WMWrite( hDevice, powerReg++, powerVal[powerLoop] );
			if ( WM_ERROR( status ) )
			{
				goto error;
			}
		}

        /* Let the WM8753 power up and then set VMid to 50KOhm. */
        if ( powerUp & WM_POWER_VREF )
        {
			MilliSleep( hDevice, 1 );

			powerVal[PWR_REG_1] |= ( WM8753_PWR1_VMIDSEL_50KOHM &
                                     WM8753_PWR1_VMIDSEL_MASK ) |
                                     WM8753_PWR1_VREF;


			status = WMWrite( hDevice, WM8753_PWR_MGMT_1, powerVal[PWR_REG_1] );
			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 )
    {
		for ( powerLoop = 0; powerLoop < WM8753_MAX_POWER_REGS; powerLoop++ )
		{
            pDeviceContext->v_pWMData->powerReg[powerLoop] = powerVal[powerLoop];
		}

        pDeviceContext->v_pWMData->WmPower = newPowered;
    }
#endif /* WM_CACHE_POWER_STATE */

    return WMS_SUCCESS;

error:
    return status;
}

/*-----------------------------------------------------------------------------
 * Function:    WM8753PowerDown
 *
 * 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 WM8753PowerDown( 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[WM8753_MAX_POWER_REGS];
    WM_REGTYPE			powerReg = WM8753_PWR_MGMT_1;
	int					powerLoop;
    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:
     *
     *  - newPowered holds what should still be powered up at the
     *    end of the function.
     *  - powerDown holds what needs to be powered down.
     *  - pDeviceContext->v_pWMData->WmPower holds what is currently powered up.
     */
    newPowered = private_CalcPowered( hDevice, driverId, 0, powerSections, &currentPower );

    /* Power down the bits currently powered up which shouldn't be */
    powerDown = currentPower & ~newPowered;

    /*
     * If there's nothing to do, get out now.
     */
    if ( 0 == powerDown )
    {
        goto done;
    }

    /*
     * Get the current reading if necessary.
     */
#if WM_CACHE_POWER_STATE
    if ( pDeviceContext->v_pWMData &&
         (pDeviceContext->v_pWMData->flags & WM_POWERREG_VALID)
       )
    {
		for ( powerLoop = 0; powerLoop < WM8753_MAX_POWER_REGS; powerLoop++ )
		{
            powerVal[powerLoop] = pDeviceContext->v_pWMData->powerReg[powerLoop];
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -