@@ -310,6 +310,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
310
310
unsigned int sampling_rate = params_rate (params );
311
311
unsigned int data_length , data_delay , bclk_ratio ;
312
312
unsigned int ch1pos , ch2pos , mode , format ;
313
+ unsigned int previous_ftxp , previous_frxp ;
313
314
unsigned int mash = BCM2835_CLK_MASH_1 ;
314
315
unsigned int divi , divf , target_frequency ;
315
316
int clk_src = -1 ;
@@ -320,6 +321,7 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
320
321
bool frame_master = (master == SND_SOC_DAIFMT_CBS_CFS
321
322
|| master == SND_SOC_DAIFMT_CBM_CFS );
322
323
uint32_t csreg ;
324
+ bool packed ;
323
325
324
326
/*
325
327
* If a stream is already enabled,
@@ -465,26 +467,46 @@ static int bcm2835_i2s_hw_params(struct snd_pcm_substream *substream,
465
467
return - EINVAL ;
466
468
}
467
469
468
- /*
469
- * Set format for both streams.
470
- * We cannot set another frame length
471
- * (and therefore word length) anyway,
472
- * so the format will be the same.
473
- */
474
- regmap_write (dev -> i2s_regmap , BCM2835_I2S_RXC_A_REG , format );
475
- regmap_write (dev -> i2s_regmap , BCM2835_I2S_TXC_A_REG , format );
470
+ /* Set the format for the matching stream direction. */
471
+ switch (substream -> stream ) {
472
+ case SNDRV_PCM_STREAM_PLAYBACK :
473
+ regmap_write (dev -> i2s_regmap , BCM2835_I2S_TXC_A_REG , format );
474
+ break ;
475
+ case SNDRV_PCM_STREAM_CAPTURE :
476
+ regmap_write (dev -> i2s_regmap , BCM2835_I2S_RXC_A_REG , format );
477
+ break ;
478
+ default :
479
+ return - EINVAL ;
480
+ }
476
481
477
482
/* Setup the I2S mode */
483
+ /* Keep existing FTXP and FRXP values. */
484
+ regmap_read (dev -> i2s_regmap , BCM2835_I2S_MODE_A_REG , & mode );
485
+
486
+ previous_ftxp = mode & BCM2835_I2S_FTXP ;
487
+ previous_frxp = mode & BCM2835_I2S_FRXP ;
488
+
478
489
mode = 0 ;
479
490
480
- if (data_length <= 16 ) {
481
- /*
482
- * Use frame packed mode (2 channels per 32 bit word)
483
- * We cannot set another frame length in the second stream
484
- * (and therefore word length) anyway,
485
- * so the format will be the same.
486
- */
487
- mode |= BCM2835_I2S_FTXP | BCM2835_I2S_FRXP ;
491
+ /*
492
+ * Retain the frame packed mode (2 channels per 32 bit word)
493
+ * of the other direction stream intact. The formats of each
494
+ * direction can be different as long as the frame length is
495
+ * shared for both.
496
+ */
497
+ packed = data_length <= 16 ;
498
+
499
+ switch (substream -> stream ) {
500
+ case SNDRV_PCM_STREAM_PLAYBACK :
501
+ mode |= previous_frxp ;
502
+ mode |= packed ? BCM2835_I2S_FTXP : 0 ;
503
+ break ;
504
+ case SNDRV_PCM_STREAM_CAPTURE :
505
+ mode |= previous_ftxp ;
506
+ mode |= packed ? BCM2835_I2S_FRXP : 0 ;
507
+ break ;
508
+ default :
509
+ return - EINVAL ;
488
510
}
489
511
490
512
mode |= BCM2835_I2S_FLEN (bclk_ratio - 1 );
0 commit comments