@@ -200,6 +200,7 @@ struct atmel_i2s_dev {
200200 unsigned int fmt ;
201201 const struct atmel_i2s_gck_param * gck_param ;
202202 const struct atmel_i2s_caps * caps ;
203+ int clk_use_no ;
203204};
204205
205206static irqreturn_t atmel_i2s_interrupt (int irq , void * dev_id )
@@ -321,9 +322,16 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
321322{
322323 struct atmel_i2s_dev * dev = snd_soc_dai_get_drvdata (dai );
323324 bool is_playback = (substream -> stream == SNDRV_PCM_STREAM_PLAYBACK );
324- unsigned int mr = 0 ;
325+ unsigned int mr = 0 , mr_mask ;
325326 int ret ;
326327
328+ mr_mask = ATMEL_I2SC_MR_FORMAT_MASK | ATMEL_I2SC_MR_MODE_MASK |
329+ ATMEL_I2SC_MR_DATALENGTH_MASK ;
330+ if (is_playback )
331+ mr_mask |= ATMEL_I2SC_MR_TXMONO ;
332+ else
333+ mr_mask |= ATMEL_I2SC_MR_RXMONO ;
334+
327335 switch (dev -> fmt & SND_SOC_DAIFMT_FORMAT_MASK ) {
328336 case SND_SOC_DAIFMT_I2S :
329337 mr |= ATMEL_I2SC_MR_FORMAT_I2S ;
@@ -402,7 +410,7 @@ static int atmel_i2s_hw_params(struct snd_pcm_substream *substream,
402410 return - EINVAL ;
403411 }
404412
405- return regmap_write (dev -> regmap , ATMEL_I2SC_MR , mr );
413+ return regmap_update_bits (dev -> regmap , ATMEL_I2SC_MR , mr_mask , mr );
406414}
407415
408416static int atmel_i2s_switch_mck_generator (struct atmel_i2s_dev * dev ,
@@ -495,18 +503,28 @@ static int atmel_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
495503 is_master = (mr & ATMEL_I2SC_MR_MODE_MASK ) == ATMEL_I2SC_MR_MODE_MASTER ;
496504
497505 /* If master starts, enable the audio clock. */
498- if (is_master && mck_enabled )
499- err = atmel_i2s_switch_mck_generator (dev , true);
500- if (err )
501- return err ;
506+ if (is_master && mck_enabled ) {
507+ if (!dev -> clk_use_no ) {
508+ err = atmel_i2s_switch_mck_generator (dev , true);
509+ if (err )
510+ return err ;
511+ }
512+ dev -> clk_use_no ++ ;
513+ }
502514
503515 err = regmap_write (dev -> regmap , ATMEL_I2SC_CR , cr );
504516 if (err )
505517 return err ;
506518
507519 /* If master stops, disable the audio clock. */
508- if (is_master && !mck_enabled )
509- err = atmel_i2s_switch_mck_generator (dev , false);
520+ if (is_master && !mck_enabled ) {
521+ if (dev -> clk_use_no == 1 ) {
522+ err = atmel_i2s_switch_mck_generator (dev , false);
523+ if (err )
524+ return err ;
525+ }
526+ dev -> clk_use_no -- ;
527+ }
510528
511529 return err ;
512530}
@@ -542,6 +560,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = {
542560 },
543561 .ops = & atmel_i2s_dai_ops ,
544562 .symmetric_rates = 1 ,
563+ .symmetric_samplebits = 1 ,
545564};
546565
547566static const struct snd_soc_component_driver atmel_i2s_component = {
0 commit comments