2019-07-22 04:32:12 +03:00
// SPDX-License-Identifier: GPL-2.0
//
// soc-dai.c
//
// Copyright (C) 2019 Renesas Electronics Corp.
// Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
//
# include <sound/soc.h>
# include <sound/soc-dai.h>
2020-04-24 02:14:38 +03:00
# define soc_dai_ret(dai, ret) _soc_dai_ret(dai, __func__, ret)
static inline int _soc_dai_ret ( struct snd_soc_dai * dai ,
const char * func , int ret )
{
switch ( ret ) {
case - EPROBE_DEFER :
case - ENOTSUPP :
case 0 :
break ;
default :
dev_err ( dai - > dev ,
" ASoC: error at %s on %s: %d \n " ,
func , dai - > name , ret ) ;
}
return ret ;
}
2019-07-22 04:32:12 +03:00
/**
* snd_soc_dai_set_sysclk - configure DAI system or master clock .
* @ dai : DAI
* @ clk_id : DAI specific clock ID
* @ freq : new clock frequency in Hz
* @ dir : new clock direction - input / output .
*
* Configures the DAI master ( MCLK ) or system ( SYSCLK ) clocking .
*/
int snd_soc_dai_set_sysclk ( struct snd_soc_dai * dai , int clk_id ,
unsigned int freq , int dir )
{
2020-04-24 02:14:38 +03:00
int ret ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_sysclk )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_sysclk ( dai , clk_id , freq , dir ) ;
else
ret = snd_soc_component_set_sysclk ( dai - > component , clk_id , 0 ,
freq , dir ) ;
2019-07-22 04:32:12 +03:00
2020-04-24 02:14:38 +03:00
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_sysclk ) ;
/**
* snd_soc_dai_set_clkdiv - configure DAI clock dividers .
* @ dai : DAI
* @ div_id : DAI specific clock divider ID
* @ div : new clock divisor .
*
* Configures the clock dividers . This is used to derive the best DAI bit and
* frame clocks from the system or master clock . It ' s best to set the DAI bit
* and frame clocks as low as possible to save system power .
*/
int snd_soc_dai_set_clkdiv ( struct snd_soc_dai * dai ,
int div_id , int div )
{
2020-04-24 02:14:38 +03:00
int ret = - EINVAL ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_clkdiv )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_clkdiv ( dai , div_id , div ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_clkdiv ) ;
/**
* snd_soc_dai_set_pll - configure DAI PLL .
* @ dai : DAI
* @ pll_id : DAI specific PLL ID
* @ source : DAI specific source for the PLL
* @ freq_in : PLL input clock frequency in Hz
* @ freq_out : requested PLL output clock frequency in Hz
*
* Configures and enables PLL to generate output clock based on input clock .
*/
int snd_soc_dai_set_pll ( struct snd_soc_dai * dai , int pll_id , int source ,
unsigned int freq_in , unsigned int freq_out )
{
2020-04-24 02:14:38 +03:00
int ret ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_pll )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_pll ( dai , pll_id , source ,
freq_in , freq_out ) ;
else
ret = snd_soc_component_set_pll ( dai - > component , pll_id , source ,
freq_in , freq_out ) ;
2019-07-22 04:32:12 +03:00
2020-04-24 02:14:38 +03:00
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_pll ) ;
/**
* snd_soc_dai_set_bclk_ratio - configure BCLK to sample rate ratio .
* @ dai : DAI
* @ ratio : Ratio of BCLK to Sample rate .
*
* Configures the DAI for a preset BCLK to sample rate ratio .
*/
int snd_soc_dai_set_bclk_ratio ( struct snd_soc_dai * dai , unsigned int ratio )
{
2020-04-24 02:14:38 +03:00
int ret = - EINVAL ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_bclk_ratio )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_bclk_ratio ( dai , ratio ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_bclk_ratio ) ;
/**
* snd_soc_dai_set_fmt - configure DAI hardware audio format .
* @ dai : DAI
* @ fmt : SND_SOC_DAIFMT_ * format value .
*
* Configures the DAI hardware format and clocking .
*/
int snd_soc_dai_set_fmt ( struct snd_soc_dai * dai , unsigned int fmt )
{
2020-04-24 02:14:38 +03:00
int ret = - ENOTSUPP ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_fmt )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_fmt ( dai , fmt ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_fmt ) ;
/**
* snd_soc_xlate_tdm_slot - generate tx / rx slot mask .
* @ slots : Number of slots in use .
* @ tx_mask : bitmask representing active TX slots .
* @ rx_mask : bitmask representing active RX slots .
*
* Generates the TDM tx and rx slot default masks for DAI .
*/
static int snd_soc_xlate_tdm_slot_mask ( unsigned int slots ,
unsigned int * tx_mask ,
unsigned int * rx_mask )
{
if ( * tx_mask | | * rx_mask )
return 0 ;
if ( ! slots )
return - EINVAL ;
* tx_mask = ( 1 < < slots ) - 1 ;
* rx_mask = ( 1 < < slots ) - 1 ;
return 0 ;
}
/**
* snd_soc_dai_set_tdm_slot ( ) - Configures a DAI for TDM operation
* @ dai : The DAI to configure
* @ tx_mask : bitmask representing active TX slots .
* @ rx_mask : bitmask representing active RX slots .
* @ slots : Number of slots in use .
* @ slot_width : Width in bits for each slot .
*
* This function configures the specified DAI for TDM operation . @ slot contains
* the total number of slots of the TDM stream and @ slot_with the width of each
* slot in bit clock cycles . @ tx_mask and @ rx_mask are bitmasks specifying the
* active slots of the TDM stream for the specified DAI , i . e . which slots the
* DAI should write to or read from . If a bit is set the corresponding slot is
* active , if a bit is cleared the corresponding slot is inactive . Bit 0 maps to
* the first slot , bit 1 to the second slot and so on . The first active slot
* maps to the first channel of the DAI , the second active slot to the second
* channel and so on .
*
* TDM mode can be disabled by passing 0 for @ slots . In this case @ tx_mask ,
* @ rx_mask and @ slot_width will be ignored .
*
* Returns 0 on success , a negative error code otherwise .
*/
int snd_soc_dai_set_tdm_slot ( struct snd_soc_dai * dai ,
unsigned int tx_mask , unsigned int rx_mask ,
int slots , int slot_width )
{
2020-04-24 02:14:38 +03:00
int ret = - ENOTSUPP ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > xlate_tdm_slot_mask )
2019-07-22 04:32:12 +03:00
dai - > driver - > ops - > xlate_tdm_slot_mask ( slots ,
& tx_mask , & rx_mask ) ;
else
snd_soc_xlate_tdm_slot_mask ( slots , & tx_mask , & rx_mask ) ;
dai - > tx_mask = tx_mask ;
dai - > rx_mask = rx_mask ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_tdm_slot )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_tdm_slot ( dai , tx_mask , rx_mask ,
2019-07-22 04:32:12 +03:00
slots , slot_width ) ;
2020-04-24 02:14:38 +03:00
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_tdm_slot ) ;
/**
* snd_soc_dai_set_channel_map - configure DAI audio channel map
* @ dai : DAI
* @ tx_num : how many TX channels
* @ tx_slot : pointer to an array which imply the TX slot number channel
* 0 ~ num - 1 uses
* @ rx_num : how many RX channels
* @ rx_slot : pointer to an array which imply the RX slot number channel
* 0 ~ num - 1 uses
*
* configure the relationship between channel number and TDM slot number .
*/
int snd_soc_dai_set_channel_map ( struct snd_soc_dai * dai ,
unsigned int tx_num , unsigned int * tx_slot ,
unsigned int rx_num , unsigned int * rx_slot )
{
2020-04-24 02:14:38 +03:00
int ret = - ENOTSUPP ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_channel_map )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_channel_map ( dai , tx_num , tx_slot ,
rx_num , rx_slot ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_channel_map ) ;
/**
* snd_soc_dai_get_channel_map - Get DAI audio channel map
* @ dai : DAI
* @ tx_num : how many TX channels
* @ tx_slot : pointer to an array which imply the TX slot number channel
* 0 ~ num - 1 uses
* @ rx_num : how many RX channels
* @ rx_slot : pointer to an array which imply the RX slot number channel
* 0 ~ num - 1 uses
*/
int snd_soc_dai_get_channel_map ( struct snd_soc_dai * dai ,
unsigned int * tx_num , unsigned int * tx_slot ,
unsigned int * rx_num , unsigned int * rx_slot )
{
2020-04-24 02:14:38 +03:00
int ret = - ENOTSUPP ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > get_channel_map )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > get_channel_map ( dai , tx_num , tx_slot ,
rx_num , rx_slot ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_get_channel_map ) ;
/**
* snd_soc_dai_set_tristate - configure DAI system or master clock .
* @ dai : DAI
* @ tristate : tristate enable
*
* Tristates the DAI so that others can use it .
*/
int snd_soc_dai_set_tristate ( struct snd_soc_dai * dai , int tristate )
{
2020-04-24 02:14:38 +03:00
int ret = - EINVAL ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > set_tristate )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > set_tristate ( dai , tristate ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_set_tristate ) ;
/**
* snd_soc_dai_digital_mute - configure DAI system or master clock .
* @ dai : DAI
* @ mute : mute enable
* @ direction : stream to mute
*
* Mutes the DAI DAC .
*/
int snd_soc_dai_digital_mute ( struct snd_soc_dai * dai , int mute ,
int direction )
{
2020-04-24 02:14:38 +03:00
int ret = - ENOTSUPP ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > mute_stream )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > mute_stream ( dai , mute , direction ) ;
2019-07-22 04:32:12 +03:00
else if ( direction = = SNDRV_PCM_STREAM_PLAYBACK & &
2020-04-24 02:14:43 +03:00
dai - > driver - > ops & &
2019-07-22 04:32:12 +03:00
dai - > driver - > ops - > digital_mute )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > ops - > digital_mute ( dai , mute ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:32:12 +03:00
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_digital_mute ) ;
2019-07-22 04:33:04 +03:00
int snd_soc_dai_hw_params ( struct snd_soc_dai * dai ,
struct snd_pcm_substream * substream ,
struct snd_pcm_hw_params * params )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
2020-04-24 02:14:38 +03:00
int ret = 0 ;
2019-07-22 04:33:04 +03:00
/* perform any topology hw_params fixups before DAI */
if ( rtd - > dai_link - > be_hw_params_fixup ) {
ret = rtd - > dai_link - > be_hw_params_fixup ( rtd , params ) ;
2020-04-24 02:14:38 +03:00
if ( ret < 0 )
goto end ;
2019-07-22 04:33:04 +03:00
}
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > hw_params )
2019-07-22 04:33:04 +03:00
ret = dai - > driver - > ops - > hw_params ( substream , params , dai ) ;
2020-04-24 02:14:38 +03:00
end :
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:33:04 +03:00
}
2019-07-22 04:33:19 +03:00
void snd_soc_dai_hw_free ( struct snd_soc_dai * dai ,
struct snd_pcm_substream * substream )
{
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > hw_free )
2019-07-22 04:33:19 +03:00
dai - > driver - > ops - > hw_free ( substream , dai ) ;
}
2019-07-22 04:33:32 +03:00
int snd_soc_dai_startup ( struct snd_soc_dai * dai ,
struct snd_pcm_substream * substream )
{
int ret = 0 ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > startup )
2019-07-22 04:33:32 +03:00
ret = dai - > driver - > ops - > startup ( substream , dai ) ;
2020-04-24 02:14:38 +03:00
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:33:32 +03:00
}
2019-07-22 04:33:39 +03:00
void snd_soc_dai_shutdown ( struct snd_soc_dai * dai ,
struct snd_pcm_substream * substream )
{
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > shutdown )
2019-07-22 04:33:39 +03:00
dai - > driver - > ops - > shutdown ( substream , dai ) ;
}
2019-07-22 04:33:45 +03:00
2019-07-22 04:34:09 +03:00
snd_pcm_sframes_t snd_soc_dai_delay ( struct snd_soc_dai * dai ,
struct snd_pcm_substream * substream )
{
int delay = 0 ;
2020-04-24 02:14:43 +03:00
if ( dai - > driver - > ops & &
dai - > driver - > ops - > delay )
2019-07-22 04:34:09 +03:00
delay = dai - > driver - > ops - > delay ( substream , dai ) ;
return delay ;
}
2019-07-22 04:34:29 +03:00
2019-07-22 04:35:29 +03:00
int snd_soc_dai_compress_new ( struct snd_soc_dai * dai ,
struct snd_soc_pcm_runtime * rtd , int num )
{
2020-04-24 02:14:38 +03:00
int ret = - ENOTSUPP ;
2019-07-22 04:35:29 +03:00
if ( dai - > driver - > compress_new )
2020-04-24 02:14:38 +03:00
ret = dai - > driver - > compress_new ( rtd , num ) ;
return soc_dai_ret ( dai , ret ) ;
2019-07-22 04:35:29 +03:00
}
2019-07-22 04:36:16 +03:00
/*
* snd_soc_dai_stream_valid ( ) - check if a DAI supports the given stream
*
* Returns true if the DAI supports the indicated stream type .
*/
bool snd_soc_dai_stream_valid ( struct snd_soc_dai * dai , int dir )
{
2020-02-19 09:56:30 +03:00
struct snd_soc_pcm_stream * stream = snd_soc_dai_get_pcm_stream ( dai , dir ) ;
2019-07-22 04:36:16 +03:00
/* If the codec specifies any channels at all, it supports the stream */
return stream - > channels_min ;
}
2020-04-24 02:14:48 +03:00
2020-04-24 02:15:15 +03:00
int snd_soc_pcm_dai_probe ( struct snd_soc_pcm_runtime * rtd , int order )
{
struct snd_soc_dai * dai ;
int i ;
for_each_rtd_dais ( rtd , i , dai ) {
if ( dai - > driver - > probe_order ! = order )
continue ;
if ( dai - > driver - > probe ) {
int ret = dai - > driver - > probe ( dai ) ;
if ( ret < 0 )
return soc_dai_ret ( dai , ret ) ;
}
dai - > probed = 1 ;
}
return 0 ;
}
2020-04-24 02:15:20 +03:00
int snd_soc_pcm_dai_remove ( struct snd_soc_pcm_runtime * rtd , int order )
{
struct snd_soc_dai * dai ;
int i , r , ret = 0 ;
for_each_rtd_dais ( rtd , i , dai ) {
if ( dai - > driver - > remove_order ! = order )
continue ;
if ( dai - > probed & &
dai - > driver - > remove ) {
r = dai - > driver - > remove ( dai ) ;
if ( r < 0 )
ret = r ; /* use last error */
}
dai - > probed = 0 ;
}
return ret ;
}
2020-04-24 02:14:48 +03:00
int snd_soc_pcm_dai_new ( struct snd_soc_pcm_runtime * rtd )
{
struct snd_soc_dai * dai ;
int i , ret = 0 ;
for_each_rtd_dais ( rtd , i , dai ) {
if ( dai - > driver - > pcm_new ) {
ret = dai - > driver - > pcm_new ( rtd , dai ) ;
if ( ret < 0 )
return soc_dai_ret ( dai , ret ) ;
}
}
return 0 ;
}
2020-04-24 02:14:53 +03:00
int snd_soc_pcm_dai_prepare ( struct snd_pcm_substream * substream )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
struct snd_soc_dai * dai ;
int i , ret ;
for_each_rtd_dais ( rtd , i , dai ) {
if ( dai - > driver - > ops & &
dai - > driver - > ops - > prepare ) {
ret = dai - > driver - > ops - > prepare ( substream , dai ) ;
if ( ret < 0 )
return soc_dai_ret ( dai , ret ) ;
}
}
return 0 ;
}
2020-04-24 02:15:04 +03:00
int snd_soc_pcm_dai_trigger ( struct snd_pcm_substream * substream ,
int cmd )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
struct snd_soc_dai * dai ;
int i , ret ;
for_each_rtd_dais ( rtd , i , dai ) {
if ( dai - > driver - > ops & &
dai - > driver - > ops - > trigger ) {
ret = dai - > driver - > ops - > trigger ( substream , cmd , dai ) ;
if ( ret < 0 )
return soc_dai_ret ( dai , ret ) ;
}
}
return 0 ;
}
2020-04-24 02:15:09 +03:00
int snd_soc_pcm_dai_bespoke_trigger ( struct snd_pcm_substream * substream ,
int cmd )
{
struct snd_soc_pcm_runtime * rtd = substream - > private_data ;
struct snd_soc_dai * dai ;
int i , ret ;
for_each_rtd_dais ( rtd , i , dai ) {
if ( dai - > driver - > ops & &
dai - > driver - > ops - > bespoke_trigger ) {
ret = dai - > driver - > ops - > bespoke_trigger ( substream ,
cmd , dai ) ;
if ( ret < 0 )
return soc_dai_ret ( dai , ret ) ;
}
}
return 0 ;
}
2020-04-24 02:15:24 +03:00
int snd_soc_dai_compr_startup ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream )
{
int ret = 0 ;
if ( dai - > driver - > cops & &
dai - > driver - > cops - > startup )
ret = dai - > driver - > cops - > startup ( cstream , dai ) ;
return soc_dai_ret ( dai , ret ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_startup ) ;
2020-04-24 02:15:28 +03:00
void snd_soc_dai_compr_shutdown ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream )
{
if ( dai - > driver - > cops & &
dai - > driver - > cops - > shutdown )
dai - > driver - > cops - > shutdown ( cstream , dai ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_shutdown ) ;
2020-04-24 02:15:32 +03:00
int snd_soc_dai_compr_trigger ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream , int cmd )
{
int ret = 0 ;
if ( dai - > driver - > cops & &
dai - > driver - > cops - > trigger )
ret = dai - > driver - > cops - > trigger ( cstream , cmd , dai ) ;
return soc_dai_ret ( dai , ret ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_trigger ) ;
2020-04-24 02:15:36 +03:00
int snd_soc_dai_compr_set_params ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream ,
struct snd_compr_params * params )
{
int ret = 0 ;
if ( dai - > driver - > cops & &
dai - > driver - > cops - > set_params )
ret = dai - > driver - > cops - > set_params ( cstream , params , dai ) ;
return soc_dai_ret ( dai , ret ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_set_params ) ;
2020-04-24 02:15:40 +03:00
int snd_soc_dai_compr_get_params ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream ,
struct snd_codec * params )
{
int ret = 0 ;
if ( dai - > driver - > cops & &
dai - > driver - > cops - > get_params )
ret = dai - > driver - > cops - > get_params ( cstream , params , dai ) ;
return soc_dai_ret ( dai , ret ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_get_params ) ;
2020-04-24 02:15:45 +03:00
int snd_soc_dai_compr_ack ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream ,
size_t bytes )
{
int ret = 0 ;
if ( dai - > driver - > cops & &
dai - > driver - > cops - > ack )
ret = dai - > driver - > cops - > ack ( cstream , bytes , dai ) ;
return soc_dai_ret ( dai , ret ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_ack ) ;
2020-04-24 02:15:49 +03:00
int snd_soc_dai_compr_pointer ( struct snd_soc_dai * dai ,
struct snd_compr_stream * cstream ,
struct snd_compr_tstamp * tstamp )
{
int ret = 0 ;
if ( dai - > driver - > cops & &
dai - > driver - > cops - > pointer )
ret = dai - > driver - > cops - > pointer ( cstream , tstamp , dai ) ;
return soc_dai_ret ( dai , ret ) ;
}
EXPORT_SYMBOL_GPL ( snd_soc_dai_compr_pointer ) ;