@ -489,7 +489,6 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai,
struct stm32_i2s_data * i2s = snd_soc_dai_get_drvdata ( cpu_dai ) ;
int format = params_width ( params ) ;
u32 cfgr , cfgr_mask , cfg1 , cfg1_mask ;
bool playback_flg = ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ) ;
unsigned int fthlv ;
int ret ;
@ -515,19 +514,13 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai,
}
if ( STM32_I2S_IS_SLAVE ( i2s ) ) {
if ( playback_flg )
cfgr | = I2S_CGFR_I2SCFG_SET ( I2S_I2SMOD_TX_SLAVE ) ;
else
cfgr | = I2S_CGFR_I2SCFG_SET ( I2S_I2SMOD_RX_SLAVE ) ;
cfgr | = I2S_CGFR_I2SCFG_SET ( I2S_I2SMOD_FD_SLAVE ) ;
/* As data length is either 16 or 32 bits, fixch always set */
cfgr | = I2S_CGFR_FIXCH ;
cfgr_mask | = I2S_CGFR_FIXCH ;
} else {
if ( playback_flg )
cfgr | = I2S_CGFR_I2SCFG_SET ( I2S_I2SMOD_TX_MASTER ) ;
else
cfgr | = I2S_CGFR_I2SCFG_SET ( I2S_I2SMOD_RX_MASTER ) ;
cfgr | = I2S_CGFR_I2SCFG_SET ( I2S_I2SMOD_FD_MASTER ) ;
}
cfgr_mask | = I2S_CGFR_I2SCFG_MASK ;
@ -536,9 +529,7 @@ static int stm32_i2s_configure(struct snd_soc_dai *cpu_dai,
if ( ret < 0 )
return ret ;
cfg1 = I2S_CFG1_RXDMAEN ;
if ( playback_flg )
cfg1 = I2S_CFG1_TXDMAEN ;
cfg1 = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN ;
cfg1_mask = cfg1 ;
fthlv = STM32_I2S_FIFO_SIZE * I2S_FIFO_TH_ONE_QUARTER / 4 ;
@ -553,32 +544,15 @@ static int stm32_i2s_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai * cpu_dai )
{
struct stm32_i2s_data * i2s = snd_soc_dai_get_drvdata ( cpu_dai ) ;
int ret , ier ;
i2s - > substream = substream ;
spin_lock ( & i2s - > lock_fd ) ;
if ( i2s - > refcount ) {
dev_err ( cpu_dai - > dev , " %s stream already started \n " ,
( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ?
" Capture " : " Playback " ) ) ;
spin_unlock ( & i2s - > lock_fd ) ;
return - EBUSY ;
}
i2s - > refcount = 1 ;
i2s - > refcount + + ;
spin_unlock ( & i2s - > lock_fd ) ;
ret = regmap_update_bits ( i2s - > regmap , STM32_I2S_IFCR_REG ,
I2S_IFCR_MASK , I2S_IFCR_MASK ) ;
if ( ret < 0 )
return ret ;
/* Enable ITs */
ier = I2S_IER_OVRIE | I2S_IER_UDRIE ;
if ( STM32_I2S_IS_SLAVE ( i2s ) )
ier | = I2S_IER_TIFREIE ;
return regmap_update_bits ( i2s - > regmap , STM32_I2S_IER_REG , ier , ier ) ;
return regmap_update_bits ( i2s - > regmap , STM32_I2S_IFCR_REG ,
I2S_IFCR_MASK , I2S_IFCR_MASK ) ;
}
static int stm32_i2s_hw_params ( struct snd_pcm_substream * substream ,
@ -605,7 +579,7 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
{
struct stm32_i2s_data * i2s = snd_soc_dai_get_drvdata ( cpu_dai ) ;
bool playback_flg = ( substream - > stream = = SNDRV_PCM_STREAM_PLAYBACK ) ;
u32 cfg1_mask ;
u32 cfg1_mask , ier ;
int ret ;
switch ( cmd ) {
@ -628,10 +602,48 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
dev_err ( cpu_dai - > dev , " Error %d starting I2S \n " , ret ) ;
return ret ;
}
regmap_update_bits ( i2s - > regmap , STM32_I2S_IFCR_REG ,
I2S_IFCR_MASK , I2S_IFCR_MASK ) ;
if ( playback_flg ) {
ier = I2S_IER_UDRIE ;
} else {
ier = I2S_IER_OVRIE ;
spin_lock ( & i2s - > lock_fd ) ;
if ( i2s - > refcount = = 1 )
/* dummy write to trigger capture */
regmap_write ( i2s - > regmap ,
STM32_I2S_TXDR_REG , 0 ) ;
spin_unlock ( & i2s - > lock_fd ) ;
}
if ( STM32_I2S_IS_SLAVE ( i2s ) )
ier | = I2S_IER_TIFREIE ;
regmap_update_bits ( i2s - > regmap , STM32_I2S_IER_REG , ier , ier ) ;
break ;
case SNDRV_PCM_TRIGGER_STOP :
case SNDRV_PCM_TRIGGER_SUSPEND :
case SNDRV_PCM_TRIGGER_PAUSE_PUSH :
if ( playback_flg )
regmap_update_bits ( i2s - > regmap , STM32_I2S_IER_REG ,
I2S_IER_UDRIE ,
( unsigned int ) ~ I2S_IER_UDRIE ) ;
else
regmap_update_bits ( i2s - > regmap , STM32_I2S_IER_REG ,
I2S_IER_OVRIE ,
( unsigned int ) ~ I2S_IER_OVRIE ) ;
spin_lock ( & i2s - > lock_fd ) ;
i2s - > refcount - - ;
if ( i2s - > refcount ) {
spin_unlock ( & i2s - > lock_fd ) ;
break ;
}
spin_unlock ( & i2s - > lock_fd ) ;
dev_dbg ( cpu_dai - > dev , " stop I2S \n " ) ;
ret = regmap_update_bits ( i2s - > regmap , STM32_I2S_CR1_REG ,
@ -641,10 +653,7 @@ static int stm32_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
return ret ;
}
cfg1_mask = I2S_CFG1_RXDMAEN ;
if ( playback_flg )
cfg1_mask = I2S_CFG1_TXDMAEN ;
cfg1_mask = I2S_CFG1_RXDMAEN | I2S_CFG1_TXDMAEN ;
regmap_update_bits ( i2s - > regmap , STM32_I2S_CFG1_REG ,
cfg1_mask , 0 ) ;
break ;
@ -662,10 +671,6 @@ static void stm32_i2s_shutdown(struct snd_pcm_substream *substream,
i2s - > substream = NULL ;
spin_lock ( & i2s - > lock_fd ) ;
i2s - > refcount = 0 ;
spin_unlock ( & i2s - > lock_fd ) ;
regmap_update_bits ( i2s - > regmap , STM32_I2S_CGFR_REG ,
I2S_CGFR_MCKOE , ( unsigned int ) ~ I2S_CGFR_MCKOE ) ;
}