diff options
-rw-r--r-- | sound/soc/fsl/fsl_esai.c | 14 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_esai.h | 8 |
2 files changed, 15 insertions, 7 deletions
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c index 72d154e7dd03..f252370073e5 100644 --- a/sound/soc/fsl/fsl_esai.c +++ b/sound/soc/fsl/fsl_esai.c | |||
@@ -38,6 +38,7 @@ | |||
38 | * @fsysclk: system clock source to derive HCK, SCK and FS | 38 | * @fsysclk: system clock source to derive HCK, SCK and FS |
39 | * @fifo_depth: depth of tx/rx FIFO | 39 | * @fifo_depth: depth of tx/rx FIFO |
40 | * @slot_width: width of each DAI slot | 40 | * @slot_width: width of each DAI slot |
41 | * @slots: number of slots | ||
41 | * @hck_rate: clock rate of desired HCKx clock | 42 | * @hck_rate: clock rate of desired HCKx clock |
42 | * @sck_rate: clock rate of desired SCKx clock | 43 | * @sck_rate: clock rate of desired SCKx clock |
43 | * @hck_dir: the direction of HCKx pads | 44 | * @hck_dir: the direction of HCKx pads |
@@ -56,6 +57,7 @@ struct fsl_esai { | |||
56 | struct clk *fsysclk; | 57 | struct clk *fsysclk; |
57 | u32 fifo_depth; | 58 | u32 fifo_depth; |
58 | u32 slot_width; | 59 | u32 slot_width; |
60 | u32 slots; | ||
59 | u32 hck_rate[2]; | 61 | u32 hck_rate[2]; |
60 | u32 sck_rate[2]; | 62 | u32 sck_rate[2]; |
61 | bool hck_dir[2]; | 63 | bool hck_dir[2]; |
@@ -363,6 +365,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask, | |||
363 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); | 365 | ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); |
364 | 366 | ||
365 | esai_priv->slot_width = slot_width; | 367 | esai_priv->slot_width = slot_width; |
368 | esai_priv->slots = slots; | ||
366 | 369 | ||
367 | return 0; | 370 | return 0; |
368 | } | 371 | } |
@@ -510,10 +513,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, | |||
510 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 513 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
511 | u32 width = snd_pcm_format_width(params_format(params)); | 514 | u32 width = snd_pcm_format_width(params_format(params)); |
512 | u32 channels = params_channels(params); | 515 | u32 channels = params_channels(params); |
516 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | ||
513 | u32 bclk, mask, val; | 517 | u32 bclk, mask, val; |
514 | int ret; | 518 | int ret; |
515 | 519 | ||
516 | bclk = params_rate(params) * esai_priv->slot_width * 2; | 520 | bclk = params_rate(params) * esai_priv->slot_width * esai_priv->slots; |
517 | 521 | ||
518 | ret = fsl_esai_set_bclk(dai, tx, bclk); | 522 | ret = fsl_esai_set_bclk(dai, tx, bclk); |
519 | if (ret) | 523 | if (ret) |
@@ -530,7 +534,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream, | |||
530 | mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | | 534 | mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | |
531 | (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); | 535 | (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); |
532 | val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | | 536 | val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | |
533 | (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels)); | 537 | (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins)); |
534 | 538 | ||
535 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); | 539 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); |
536 | 540 | ||
@@ -565,6 +569,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
565 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); | 569 | struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); |
566 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; | 570 | bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; |
567 | u8 i, channels = substream->runtime->channels; | 571 | u8 i, channels = substream->runtime->channels; |
572 | u32 pins = DIV_ROUND_UP(channels, esai_priv->slots); | ||
568 | 573 | ||
569 | switch (cmd) { | 574 | switch (cmd) { |
570 | case SNDRV_PCM_TRIGGER_START: | 575 | case SNDRV_PCM_TRIGGER_START: |
@@ -579,7 +584,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd, | |||
579 | 584 | ||
580 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), | 585 | regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), |
581 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, | 586 | tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, |
582 | tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels)); | 587 | tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins)); |
583 | break; | 588 | break; |
584 | case SNDRV_PCM_TRIGGER_SUSPEND: | 589 | case SNDRV_PCM_TRIGGER_SUSPEND: |
585 | case SNDRV_PCM_TRIGGER_STOP: | 590 | case SNDRV_PCM_TRIGGER_STOP: |
@@ -783,6 +788,9 @@ static int fsl_esai_probe(struct platform_device *pdev) | |||
783 | /* Set a default slot size */ | 788 | /* Set a default slot size */ |
784 | esai_priv->slot_width = 32; | 789 | esai_priv->slot_width = 32; |
785 | 790 | ||
791 | /* Set a default slot number */ | ||
792 | esai_priv->slots = 2; | ||
793 | |||
786 | /* Set a default master/slave state */ | 794 | /* Set a default master/slave state */ |
787 | esai_priv->slave_mode = true; | 795 | esai_priv->slave_mode = true; |
788 | 796 | ||
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h index 75e14033e8d8..91a550f4a10d 100644 --- a/sound/soc/fsl/fsl_esai.h +++ b/sound/soc/fsl/fsl_esai.h | |||
@@ -130,8 +130,8 @@ | |||
130 | #define ESAI_xFCR_RE_WIDTH 4 | 130 | #define ESAI_xFCR_RE_WIDTH 4 |
131 | #define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) | 131 | #define ESAI_xFCR_TE_MASK (((1 << ESAI_xFCR_TE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) |
132 | #define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) | 132 | #define ESAI_xFCR_RE_MASK (((1 << ESAI_xFCR_RE_WIDTH) - 1) << ESAI_xFCR_xE_SHIFT) |
133 | #define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_TE_MASK) | 133 | #define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - x)) & ESAI_xFCR_TE_MASK) |
134 | #define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xFCR_RE_MASK) | 134 | #define ESAI_xFCR_RE(x) ((ESAI_xFCR_RE_MASK >> (ESAI_xFCR_RE_WIDTH - x)) & ESAI_xFCR_RE_MASK) |
135 | #define ESAI_xFCR_xFR_SHIFT 1 | 135 | #define ESAI_xFCR_xFR_SHIFT 1 |
136 | #define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT) | 136 | #define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT) |
137 | #define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT) | 137 | #define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT) |
@@ -272,8 +272,8 @@ | |||
272 | #define ESAI_xCR_RE_WIDTH 4 | 272 | #define ESAI_xCR_RE_WIDTH 4 |
273 | #define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) | 273 | #define ESAI_xCR_TE_MASK (((1 << ESAI_xCR_TE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) |
274 | #define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) | 274 | #define ESAI_xCR_RE_MASK (((1 << ESAI_xCR_RE_WIDTH) - 1) << ESAI_xCR_xE_SHIFT) |
275 | #define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_TE_MASK) | 275 | #define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - x)) & ESAI_xCR_TE_MASK) |
276 | #define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - ((x + 1) >> 1))) & ESAI_xCR_RE_MASK) | 276 | #define ESAI_xCR_RE(x) ((ESAI_xCR_RE_MASK >> (ESAI_xCR_RE_WIDTH - x)) & ESAI_xCR_RE_MASK) |
277 | 277 | ||
278 | /* | 278 | /* |
279 | * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8 | 279 | * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8 |