📄 wm8753audio.c
字号:
format
));
status = WMS_UNSUPPORTED;
goto error;
}
/*
* Set data word length.
*/
switch ( width )
{
case WM_AUDIOIF_16BIT:
controlVal |= WM8753_WORD_LENGTH_16BIT;
break;
case WM_AUDIOIF_20BIT:
controlVal |= WM8753_WORD_LENGTH_20BIT;
break;
case WM_AUDIOIF_24BIT:
controlVal |= WM8753_WORD_LENGTH_24BIT;
break;
case WM_AUDIOIF_32BIT:
if ( WM_AUDIOIF_DSP_MODE_A == format ||
WM_AUDIOIF_DSP_MODE_B == format
)
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: 32-bit word length is not supported in DSP mode"
));
status = WMS_UNSUPPORTED;
goto error;
}
controlVal |= WM8753_WORD_LENGTH_32BIT;
break;
default:
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: unsupported word length %d",
width
));
status = WMS_UNSUPPORTED;
goto error;
}
/*
* Check for misc extras.
*/
/* Clock inversion */
if ( flags & WM_AUDIOIF_INVERT_CLOCK )
controlVal |= WM8753_DACCLKINV;
/* LR clock polarity inversion - doesn't apply to DSP mode */
if ( flags & WM_AUDIOIF_INVERT_LR_CLOCK )
{
if ( WM_AUDIOIF_DSP_MODE_A == format ||
WM_AUDIOIF_DSP_MODE_B == format
)
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: LR Clock invert is not relevant in DSP mode"
));
status = WMS_INVALID_PARAMETER;
goto error;
}
controlVal |= WM8753_LRC_INVERT;
}
/* Left/right channel swap - only applies to HiFi */
if ( flags & WM_AUDIOIF_LR_SWAP )
{
if ( WM_AUDIOIF_HIFI != audioIF )
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: Left/right swap is only supported for HiFi"
));
status = WMS_UNSUPPORTED;
goto error;
}
controlVal |= WM8753_HIFI_LR_SWAP;
}
/* Mono - only applies to Voice */
if ( flags & WM_AUDIOIF_MONO )
{
if ( WM_AUDIOIF_VOICE != audioIF )
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: Mono is only supported for Voice"
));
status = WMS_UNSUPPORTED;
goto error;
}
controlVal |= WM8753_VOICE_MONO;
}
/*
* Work out our I/F-specific details.
*/
switch ( audioIF )
{
case WM_AUDIOIF_HIFI:
/*
* Set up the HiFi digital interface.
*/
interfaceVal = WM8753_BITCLK_ENABLE |
WM8753_LRC_OUTPUT;
interfaceMask = WM8753_BITCLK_TRISTATE |
WM8753_VXDOUT_TRISTATE |
WM8753_ADCDAT_TRISTATE |
WM8753_LRC_OUTPUT |
WM8753_INTERFACE_MODE_MASK;
sampleRateVal = WM8753_BCLK_MCLK_DIV_4;
sampleRateMask = WM8753_BCLK_RATE_MASK;
if ( IS_VOICE_ENABLED( pDeviceContext ) )
{
interfaceVal |= WM8753_MODE_HIFI_VOICE |
WM8753_VXDOUT_OUTPUT |
WM8753_ADCDAT_TRISTATE;
adcRateMode = WM8753_ADC_SRMODE_PSR;
}
else
{
interfaceVal |= WM8753_MODE_HIFI |
WM8753_VXDOUT_TRISTATE |
WM8753_ADCDAT_OUTPUT;
adcRateMode = WM8753_ADC_SRMODE_SR;
}
/*
* And set our interface-specific variables.
*/
reg = WM8753_HIFI_AUDIO_INTERFACE;
pll = WM8753_PLL1;
break;
# if WM_VOICE
case WM_AUDIOIF_VOICE:
/*
* Set up voice digital interface.
*/
interfaceVal = WM8753_VXCLK_ENABLE |
WM8753_VXDOUT_OUTPUT |
WM8753_ADCDAT_TRISTATE |
WM8753_VXFS_OUTPUT |
WM8753_MODE_HIFI_VOICE;
interfaceMask = WM8753_VXCLK_TRISTATE |
WM8753_VXDOUT_TRISTATE |
WM8753_ADCDAT_TRISTATE |
WM8753_VXFS_OUTPUT |
WM8753_INTERFACE_MODE_MASK;
sampleRateVal = WM8753_VXCLK_MCLK_DIV_4;
sampleRateMask = WM8753_VXCLK_RATE_MASK;
adcRateMode = WM8753_ADC_SRMODE_PSR;
/*
* And set our interface-specific variables.
*/
reg = WM8753_VOICE_AUDIO_INTERFACE;
pll = WM8753_PLL2;
break;
# endif /* WM_VOICE */
default:
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: unsupported interface %d",
audioIF
));
status = WMS_UNSUPPORTED;
goto error;
}
/*
* Set up the interface pins.
*/
status = WMSetField( hDevice,
WM8753_INTERFACE_CONTROL,
interfaceVal,
interfaceMask
);
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: SetField failed: %s",
WMStatusText( status )
));
goto error;
}
/*
* Now do the interface-specific configuration.
*/
status = WMWrite( hDevice, reg, controlVal );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: Write failed: %s",
WMStatusText( status )
));
goto error;
}
/*
* In HiFi codec mode, the ADC interface is still controlled by
* the voice control register WM8753_VOICE_AUDIO_INTERFACE.
*/
if ( WM_AUDIOIF_HIFI == audioIF && !IS_VOICE_ENABLED( pDeviceContext ) )
{
WM_ASSERT( hDevice, WM8753_VOICE_AUDIO_INTERFACE != reg );
status = WMWrite( hDevice, WM8753_VOICE_AUDIO_INTERFACE, controlVal );
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, (
"WM8753ConfigureInterface: Write failed: %s",
WMStatusText( status )
));
goto error;
}
}
/*
* Set up the sample rate mode.
*/
status = WMSetField( hDevice,
WM8753_SAMPLE_RATE_CTRL_2,
sampleRateVal,
sampleRateMask
);
if ( WM_ERROR(status) )
{
goto error;
}
/*
* Write the sample rate to the codec.
*/
status = WMSetField( hDevice,
WM8753_SAMPLE_RATE_CTRL_1,
( adcRateMode |
WM8753_SAMPLE_256FS |
WM8753_SAMPLE_NORMAL
),
( WM8753_ADC_SRMODE_MASK |
WM8753_SAMPLE_FEQUENCY_MASK |
WM8753_SAMPLE_CLOCK_MASK
)
);
if ( WM_ERROR( status ) )
{
goto error;
}
/*
* We're done.
*/
return WMS_SUCCESS;
error:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WM8753UnconfigureInterface
*
* Unconfigures the streaming format for the link for the given interface.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* audioIF the interface to configure
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
WMSTATUS WM8753UnconfigureInterface( WM_DEVICE_HANDLE hDevice,
WM_AUDIO_INTERFACE audioIF
)
{
WMSTATUS status;
WM_REGVAL interfaceVal = 0, interfaceMask = 0;
/*
* Work out our I/F-specific details.
*/
switch ( audioIF )
{
case WM_AUDIOIF_HIFI:
/*
* Tristate the HiFi digital interface.
*/
interfaceVal = WM8753_BITCLK_TRISTATE |
WM8753_ADCDAT_TRISTATE |
WM8753_LRC_INPUT;
interfaceMask = WM8753_BITCLK_TRISTATE |
WM8753_ADCDAT_TRISTATE |
WM8753_LRC_OUTPUT;
break;
# if WM_VOICE
case WM_AUDIOIF_VOICE:
/*
* Tristate voice digital interface.
*/
interfaceVal = WM8753_VXCLK_TRISTATE |
WM8753_VXDOUT_TRISTATE |
WM8753_VXFS_INPUT;
interfaceMask = WM8753_VXCLK_TRISTATE |
WM8753_VXDOUT_TRISTATE |
WM8753_VXFS_OUTPUT;
break;
# endif /* WM_VOICE */
default:
WM_TRACE( hDevice, (
"WM8753UnconfigureInterface: unsupported interface %d",
audioIF
));
status = WMS_UNSUPPORTED;
goto error;
}
/*
* Tristate the interface pins.
*/
status = WMSetField( hDevice,
WM8753_INTERFACE_CONTROL,
interfaceVal,
interfaceMask
);
if ( WM_ERROR( status ) )
{
WM_TRACE( hDevice, (
"WM8753UnconfigureInterface: interface SetField failed: %s",
WMStatusText( status )
));
goto error;
}
/*
* We're done.
*/
return WMS_SUCCESS;
error:
return status;
}
/*-----------------------------------------------------------------------------
* Function: WM8753EnableStream
*
* Device-specific stuff for enabling a given stream.
*
* Parameters:
* hDevice handle to the device (from WMOpenDevice)
* stream The stream to enable
*
* Returns: WMSTATUS
* See WMStatus.h.
*---------------------------------------------------------------------------*/
WMSTATUS WM8753EnableStream( WM_DEVICE_HANDLE hDevice,
WM_STREAM_ID stream
)
{
WM_DEVICE_CONTEXT *pDeviceContext = WMHANDLE_TO_DEVICE( hDevice );
WMSTATUS status;
WM_AUDIO_INTERFACE audioIF;
WM_BOOL isMaster;
WM_AUDIOIF_FORMAT format;
WM_AUDIOIF_WIDTH width;
WM_AUDIOIF_FLAGS flags;
unsigned int configuredFlag;
/*
* Work out our which interface we need.
*/
switch ( stream )
{
case WM_STREAM_HIFI_OUT:
audioIF = WM_AUDIOIF_HIFI;
break;
case WM_STREAM_HIFI_IN:
if ( !IS_VOICE_ENABLED( pDeviceContext ) )
{
/*
* We're set up for HiFi only.
*/
status = WMSetField( hDevice,
WM8753_VOICE_AUDIO_INTERFACE,
WM8753_ADCDOP_ADCDAT,
WM8753_ADCDOP_MASK
);
audioIF = WM_AUDIOIF_HIFI;
break;
}
else
{
/*
* We're set up for HiFi DAC + voice codec => "HiFi in" is really
* voice in. Route VXDOUT through to ADCDAT and then fall through.
*
* Note: In this mode, the only way to record on the HiFi
* interface is to set up a switch on the VX and HiFi clock
* lines - see App Note 0152.
*/
status = WMSetField( hDevice,
WM8753_VOICE_AUDIO_INTERFACE,
WM8753_ADCDOP_ADCDAT_VXDOUT,
WM8753_ADCDOP_MASK
);
/*
* Now fall through to set up the voice interface.
*/
}
case WM_STREAM_VOICE_OUT:
case WM_STREAM_VOICE_IN:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -