📄 wmcontrollink.c
字号:
{
status = WMS_NO_SUPPORTED_DEVICE;
goto done;
}
/*
* Check to make sure that the global registers are available to use.
*/
v_pWMData = pDeviceContext->v_pWMData;
if ( !v_pWMData )
{
status = WMS_RESOURCE_NULL;
goto done;
}
/*
* Make sure non-shadowed registers are initialised to unset.
*/
for ( shadow = 0; shadow < WM_MAX_SHADOW_REGS; shadow++ )
{
v_pWMData->shadowRegisters[ shadow ] = WM_REGISTER_UNSET;
}
/*
* Run through the registers.
*/
for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
{
/* Set the default value in the shadow register */
WM_REGTYPE reg = pChipDef->pShadowedRegisters[ shadow ].reg;
WM_REGTYPE regNum;
unsigned short regOffset;
/*
* Work out our array index.
*/
regOffset = pChipDef->regOffset;
regNum = reg / regOffset;
WM_ASSERT( hDevice, regNum < WM_MAX_SHADOW_REGS );
v_pWMData->shadowRegisters[ regNum ] =
pChipDef->pShadowedRegisters[ shadow ].defaultValue;
}
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_WriteShadowRegister
*
* Writes the value to the given shadow register.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* reg register to write to
* value value to write
*
* Returns: WMSTATUS
* WMS_RETURN_TRUE if value to write is the same as
* the value that was previously shadowed.
* WMS_RETURN_FALSE if value to write is _not_ the
* same as the value that was previously shadowed.
* See WMStatus.h for all other return values.
*---------------------------------------------------------------------------*/
static WMSTATUS private_WriteShadowRegister( WM_DEVICE_HANDLE hDevice,
WM_REGTYPE reg,
WM_REGVAL value
)
{
unsigned int shadow;
const WM_CHIPDEF *pChipDef = NULL;
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
volatile WM_SHARED_DATA *v_pWMData;
WMSTATUS status = WMS_UNABLE_TO_SHADOW;
unsigned short regOffset;
WM_REGTYPE regNum;
WM_ASSERT( hDevice, NULL != pDeviceContext );
WM_ASSERT( hDevice, NULL != pDeviceContext->v_pWMData );
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto done;
}
/*
* Check to make sure that the global registers are available to use.
*/
v_pWMData = pDeviceContext->v_pWMData;
if ( !v_pWMData )
{
status = WMS_RESOURCE_NULL;
goto done;
}
/*
* Work out our array index.
*/
regOffset = pChipDef->regOffset;
regNum = reg / regOffset;
if ( regNum >= WM_MAX_SHADOW_REGS )
{
status = WMS_REG_NOT_PRESENT;
goto done;
}
/*
* Run through the registers.
*/
for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
{
/* Try and find a match for the register */
if ( pChipDef->pShadowedRegisters[ shadow ].reg == reg )
{
/*
* Assume we didn't need to change the value.
*/
status = WMS_RETURN_TRUE;
/*
* The WM8731 family have the concept of "BOTH", which writes
* the same value to both channels, so we need to do some
* special handling to make sure our shadow values are correct.
*/
if ( WM_HAS_BOTH( hDevice ) )
{
WM_REGTYPE signalRegNum;
#if WM_BOTH_QUICK_AND_DIRTY
WM_ASSERT( hDevice, IS_WM8731_FAMILY( hDevice ) );
if ( value & WM8731_VOLUME_BOTH )
{
switch ( reg )
{
case WM8731_LEFT_INPUT_VOLUME:
signalRegNum = WM8731_RIGHT_INPUT_VOLUME;
break;
case WM8731_RIGHT_INPUT_VOLUME:
signalRegNum = WM8731_LEFT_INPUT_VOLUME;
break;
case WM8731_LEFT_HEADPHONE_VOLUME:
signalRegNum = WM8731_RIGHT_HEADPHONE_VOLUME;
break;
case WM8731_RIGHT_HEADPHONE_VOLUME:
signalRegNum = WM8731_LEFT_HEADPHONE_VOLUME;
break;
default:
signalRegNum = WM_REG_INVALID;
}
if ( WM_REG_INVALID != signalRegNum )
{
value &= ~WM8731_VOLUME_BOTH;
/*
* Check to see if the previous shadowed value is the
* same as the value we have been given. If not, update
* it and remember we need to do the write to the device.
*/
if ( v_pWMData->shadowRegisters[ signalRegNum ] != value )
{
v_pWMData->shadowRegisters[ signalRegNum ] = value;
status = WMS_RETURN_FALSE;
WM_REG_TRACE( hDevice, (
"==> WMWrite: R%02Xh := 0x%04X (updated via BOTH)",
signalRegNum,
value
));
}
}
}
#else /* WM_BOTH_QUICK_AND_DIRTY */
unsigned int nSignal;
WM_AUDIO_SIGNAL signal = WM_AUDIO_SIGNAL_UNKNOWN;
/* Check for a signal with this register */
for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
{
const WM_SIGNAL_DETAILS *pSignalDetails;
pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
if ( pSignalDetails->reg == reg &&
pSignalDetails->flags & WM_SIG_HAS_BOTH &&
value & pSignalDetails->specialFlag
)
{
signal = pSignalDetails->signal;
value &= ~pSignalDetails->specialFlag;
break;
}
}
/*
* If there was a match, run through the signals again,
* looking for matching registers and update them too.
*/
if ( WM_AUDIO_SIGNAL_UNKNOWN != signal )
{
for ( nSignal = 0; nSignal < pChipDef->signalCount; nSignal++ )
{
const WM_SIGNAL_DETAILS *pSignalDetails;
pSignalDetails = &pChipDef->pSignalDetails[ nSignal ];
if ( pSignalDetails->signal == signal &&
pSignalDetails->reg != reg
)
{
/*
* Check to see if the previous shadowed value is the
* same as the value we have been given. If not, update
* it and remember we need to do the write to the device.
*/
signalRegNum = pSignalDetails->reg / regOffset;
if ( v_pWMData->shadowRegisters[ signalRegNum ] != value )
{
v_pWMData->shadowRegisters[ signalRegNum ] = value;
status = WMS_RETURN_FALSE;
WM_REG_TRACE( hDevice, (
"==> WMWrite: R%02Xh := 0x%04X (updated via BOTH)",
pSignalDetails->reg,
value
));
}
}
}
}
#endif /* WM_BOTH_QUICK_AND_DIRTY*/
}
/*
* Check to see if the previous shadowed value is the
* same as the value we have been given. If not, update
* it and remember we need to do the write to the device.
*/
if ( v_pWMData->shadowRegisters[ regNum ] != value )
{
/* Write the new value to the shadow register */
v_pWMData->shadowRegisters[ regNum ] = value;
status = WMS_RETURN_FALSE;
}
goto done;
}
}
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_ReadShadowRegister
*
* Reads the value from the given shadow register.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* reg register to read from
* pValue variable to receive value
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
static WMSTATUS private_ReadShadowRegister( WM_DEVICE_HANDLE hDevice,
WM_REGTYPE reg,
WM_REGVAL *pValue
)
{
unsigned int shadow;
const WM_CHIPDEF *pChipDef = NULL;
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
volatile WM_SHARED_DATA *v_pWMData = pDeviceContext->v_pWMData;
WMSTATUS status = WMS_UNABLE_TO_SHADOW;
WM_REGTYPE regNum;
unsigned short regOffset;
WM_ASSERT( hDevice, NULL != pDeviceContext );
WM_ASSERT( hDevice, NULL != pDeviceContext->v_pWMData );
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto done;
}
/*
* Check to make sure that the global registers are available to use.
*/
if ( !v_pWMData )
{
status = WMS_RESOURCE_NULL;
goto done;
}
/*
* Work out our array index.
*/
regOffset = pChipDef->regOffset;
regNum = reg / regOffset;
if ( regNum >= WM_MAX_SHADOW_REGS )
{
status = WMS_REG_NOT_PRESENT;
goto done;
}
/*
* Run through the registers.
*/
for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
{
/* Try and find a match for the register */
if ( pChipDef->pShadowedRegisters[ shadow ].reg == reg )
{
/* Read the value from the shadow register */
*pValue = v_pWMData->shadowRegisters[ regNum ];
/*
* If I2S device does not have a default value
* for this register report the error
*/
if ( WM_IS_I2S( hDevice ) && (WM_REGISTER_UNSET == *pValue) )
{
status = WMS_SHADOW_UNINTIALISED;
}
else
{
status = WMS_SUCCESS;
}
goto done;
}
}
done:
return status;
}
/*-----------------------------------------------------------------------------
* Function: private_ReadDefaulyShadowRegister
*
* Reads the default value from the given shadow register.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* reg register to read from
* pValue variable to receive value
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
static WMSTATUS private_ReadDefaultShadowRegister( WM_DEVICE_HANDLE hDevice,
WM_REGTYPE reg,
WM_REGVAL *pValue
)
{
unsigned int shadow;
const WM_CHIPDEF *pChipDef = NULL;
WMSTATUS status = WMS_SHADOW_UNINTIALISED;
WM_REGTYPE regNum;
unsigned short regOffset;
/*
* Look up our chipdef.
*/
pChipDef = WMGetChipDef( hDevice );
if ( !pChipDef )
{
status = WMS_NO_SUPPORTED_DEVICE;
goto done;
}
/*
* Work out our array index.
*/
regOffset = pChipDef->regOffset;
regNum = reg / regOffset;
if ( regNum >= WM_MAX_SHADOW_REGS )
{
status = WMS_REG_NOT_PRESENT;
goto done;
}
/*
* Run through the registers.
*/
for ( shadow = 0; shadow < pChipDef->nShadowedRegisters; shadow++ )
{
/* Try and find a match for the register */
if ( pChipDef->pShadowedRegisters[ shadow ].reg == reg )
{
/* Read the default value from the shadow register */
*pValue = pChipDef->pShadowedRegisters[ shadow ].defaultValue;
/*
* If I2S device does not have a default value
* for this register report the error
*/
if ( WM_IS_I2S( hDevice ) && (WM_REGISTER_UNSET == *pValue) )
{
status = WMS_SHADOW_UNINTIALISED;
}
else
{
status = WMS_SUCCESS;
}
goto done;
}
}
done:
return status;
}
#endif/* WM_USE_SHADOW_REGISTERS */
/*------------------------------ END OF FILE ---------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -