diff options
| -rw-r--r-- | sound/soc/fsl/fsl_sai.c | 31 | ||||
| -rw-r--r-- | sound/soc/fsl/fsl_sai.h | 3 |
2 files changed, 28 insertions, 6 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 520dbadaa8b1..43ba5dc26775 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c | |||
| @@ -126,6 +126,17 @@ out: | |||
| 126 | return IRQ_HANDLED; | 126 | return IRQ_HANDLED; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | static int fsl_sai_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask, | ||
| 130 | u32 rx_mask, int slots, int slot_width) | ||
| 131 | { | ||
| 132 | struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai); | ||
| 133 | |||
| 134 | sai->slots = slots; | ||
| 135 | sai->slot_width = slot_width; | ||
| 136 | |||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 129 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, | 140 | static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai, |
| 130 | int clk_id, unsigned int freq, int fsl_dir) | 141 | int clk_id, unsigned int freq, int fsl_dir) |
| 131 | { | 142 | { |
| @@ -395,11 +406,19 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
| 395 | unsigned int channels = params_channels(params); | 406 | unsigned int channels = params_channels(params); |
| 396 | u32 word_width = snd_pcm_format_width(params_format(params)); | 407 | u32 word_width = snd_pcm_format_width(params_format(params)); |
| 397 | u32 val_cr4 = 0, val_cr5 = 0; | 408 | u32 val_cr4 = 0, val_cr5 = 0; |
| 409 | u32 slots = (channels == 1) ? 2 : channels; | ||
| 410 | u32 slot_width = word_width; | ||
| 398 | int ret; | 411 | int ret; |
| 399 | 412 | ||
| 413 | if (sai->slots) | ||
| 414 | slots = sai->slots; | ||
| 415 | |||
| 416 | if (sai->slot_width) | ||
| 417 | slot_width = sai->slot_width; | ||
| 418 | |||
| 400 | if (!sai->is_slave_mode) { | 419 | if (!sai->is_slave_mode) { |
| 401 | ret = fsl_sai_set_bclk(cpu_dai, tx, | 420 | ret = fsl_sai_set_bclk(cpu_dai, tx, |
| 402 | 2 * word_width * params_rate(params)); | 421 | slots * slot_width * params_rate(params)); |
| 403 | if (ret) | 422 | if (ret) |
| 404 | return ret; | 423 | return ret; |
| 405 | 424 | ||
| @@ -411,21 +430,20 @@ static int fsl_sai_hw_params(struct snd_pcm_substream *substream, | |||
| 411 | 430 | ||
| 412 | sai->mclk_streams |= BIT(substream->stream); | 431 | sai->mclk_streams |= BIT(substream->stream); |
| 413 | } | 432 | } |
| 414 | |||
| 415 | } | 433 | } |
| 416 | 434 | ||
| 417 | if (!sai->is_dsp_mode) | 435 | if (!sai->is_dsp_mode) |
| 418 | val_cr4 |= FSL_SAI_CR4_SYWD(word_width); | 436 | val_cr4 |= FSL_SAI_CR4_SYWD(slot_width); |
| 419 | 437 | ||
| 420 | val_cr5 |= FSL_SAI_CR5_WNW(word_width); | 438 | val_cr5 |= FSL_SAI_CR5_WNW(slot_width); |
| 421 | val_cr5 |= FSL_SAI_CR5_W0W(word_width); | 439 | val_cr5 |= FSL_SAI_CR5_W0W(slot_width); |
| 422 | 440 | ||
| 423 | if (sai->is_lsb_first) | 441 | if (sai->is_lsb_first) |
| 424 | val_cr5 |= FSL_SAI_CR5_FBT(0); | 442 | val_cr5 |= FSL_SAI_CR5_FBT(0); |
| 425 | else | 443 | else |
| 426 | val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); | 444 | val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1); |
| 427 | 445 | ||
| 428 | val_cr4 |= FSL_SAI_CR4_FRSZ(channels); | 446 | val_cr4 |= FSL_SAI_CR4_FRSZ(slots); |
| 429 | 447 | ||
| 430 | /* | 448 | /* |
| 431 | * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will | 449 | * For SAI master mode, when Tx(Rx) sync with Rx(Tx) clock, Rx(Tx) will |
| @@ -591,6 +609,7 @@ static void fsl_sai_shutdown(struct snd_pcm_substream *substream, | |||
| 591 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { | 609 | static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = { |
| 592 | .set_sysclk = fsl_sai_set_dai_sysclk, | 610 | .set_sysclk = fsl_sai_set_dai_sysclk, |
| 593 | .set_fmt = fsl_sai_set_dai_fmt, | 611 | .set_fmt = fsl_sai_set_dai_fmt, |
| 612 | .set_tdm_slot = fsl_sai_set_dai_tdm_slot, | ||
| 594 | .hw_params = fsl_sai_hw_params, | 613 | .hw_params = fsl_sai_hw_params, |
| 595 | .hw_free = fsl_sai_hw_free, | 614 | .hw_free = fsl_sai_hw_free, |
| 596 | .trigger = fsl_sai_trigger, | 615 | .trigger = fsl_sai_trigger, |
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index b95fbc3f68eb..d9ed7be8cb34 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h | |||
| @@ -143,6 +143,9 @@ struct fsl_sai { | |||
| 143 | 143 | ||
| 144 | unsigned int mclk_id[2]; | 144 | unsigned int mclk_id[2]; |
| 145 | unsigned int mclk_streams; | 145 | unsigned int mclk_streams; |
| 146 | unsigned int slots; | ||
| 147 | unsigned int slot_width; | ||
| 148 | |||
| 146 | struct snd_dmaengine_dai_dma_data dma_params_rx; | 149 | struct snd_dmaengine_dai_dma_data dma_params_rx; |
| 147 | struct snd_dmaengine_dai_dma_data dma_params_tx; | 150 | struct snd_dmaengine_dai_dma_data dma_params_tx; |
| 148 | }; | 151 | }; |
