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

📄 wmpower.c

📁 pxa270平台 windows mobile 5.2 wm9713 触摸屏+音频驱动
💻 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 3998 2006-10-03 13:00:37Z fb $
 *
 * 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:    WMPowerInit
 *
 * Initalise the driver in the correct power state.
 *
 * Parameters:
 *      hDevice             handle to the device (from WMOpenDevice)
 *      driverId            The device ID (e.g. WM_DRIVER_TOUCH)
 *
 * Returns:     WMSTATUS
 *        See WMStatus.h.
 *---------------------------------------------------------------------------*/
WMSTATUS WMPowerInit( WM_DEVICE_HANDLE  hDevice,
                      WM_DRIVER_ID      driverId
                    )
{
    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 intialisation?
     */
    if ( !pChipDef->vtable.fnPowerInit )
    {
        status = WMS_UNSUPPORTED;
        goto done;
    }

    /*
     * Lock our global data.
     */
    if ( !WMLockGlobalData( hDevice ) )
    {
        status = WMS_LOCK_TIMED_OUT;
        goto done;
    }

    status = pChipDef->vtable.fnPowerInit( hDevice, 
                                           driverId
                                         );

    /* Let other threads in again */
    WMUnlockGlobalData( hDevice );

done:
    return status;
}

/*-----------------------------------------------------------------------------
 * 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 + -