aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl/fsl_esai.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl/fsl_esai.c')
-rw-r--r--sound/soc/fsl/fsl_esai.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index a3b29ed84963..8bcdfda09d7a 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -37,6 +37,7 @@
37 * @fsysclk: system clock source to derive HCK, SCK and FS 37 * @fsysclk: system clock source to derive HCK, SCK and FS
38 * @fifo_depth: depth of tx/rx FIFO 38 * @fifo_depth: depth of tx/rx FIFO
39 * @slot_width: width of each DAI slot 39 * @slot_width: width of each DAI slot
40 * @slots: number of slots
40 * @hck_rate: clock rate of desired HCKx clock 41 * @hck_rate: clock rate of desired HCKx clock
41 * @sck_rate: clock rate of desired SCKx clock 42 * @sck_rate: clock rate of desired SCKx clock
42 * @hck_dir: the direction of HCKx pads 43 * @hck_dir: the direction of HCKx pads
@@ -55,6 +56,7 @@ struct fsl_esai {
55 struct clk *fsysclk; 56 struct clk *fsysclk;
56 u32 fifo_depth; 57 u32 fifo_depth;
57 u32 slot_width; 58 u32 slot_width;
59 u32 slots;
58 u32 hck_rate[2]; 60 u32 hck_rate[2];
59 u32 sck_rate[2]; 61 u32 sck_rate[2];
60 bool hck_dir[2]; 62 bool hck_dir[2];
@@ -362,6 +364,7 @@ static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
362 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask)); 364 ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask));
363 365
364 esai_priv->slot_width = slot_width; 366 esai_priv->slot_width = slot_width;
367 esai_priv->slots = slots;
365 368
366 return 0; 369 return 0;
367} 370}
@@ -509,10 +512,11 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
509 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 512 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
510 u32 width = snd_pcm_format_width(params_format(params)); 513 u32 width = snd_pcm_format_width(params_format(params));
511 u32 channels = params_channels(params); 514 u32 channels = params_channels(params);
515 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
512 u32 bclk, mask, val; 516 u32 bclk, mask, val;
513 int ret; 517 int ret;
514 518
515 bclk = params_rate(params) * esai_priv->slot_width * 2; 519 bclk = params_rate(params) * esai_priv->slot_width * esai_priv->slots;
516 520
517 ret = fsl_esai_set_bclk(dai, tx, bclk); 521 ret = fsl_esai_set_bclk(dai, tx, bclk);
518 if (ret) 522 if (ret)
@@ -529,7 +533,7 @@ static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
529 mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK | 533 mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
530 (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK); 534 (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
531 val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) | 535 val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
532 (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels)); 536 (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
533 537
534 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val); 538 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
535 539
@@ -564,6 +568,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
564 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai); 568 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
565 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; 569 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
566 u8 i, channels = substream->runtime->channels; 570 u8 i, channels = substream->runtime->channels;
571 u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
567 572
568 switch (cmd) { 573 switch (cmd) {
569 case SNDRV_PCM_TRIGGER_START: 574 case SNDRV_PCM_TRIGGER_START:
@@ -578,7 +583,7 @@ static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
578 583
579 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), 584 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
580 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 585 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
581 tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels)); 586 tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
582 break; 587 break;
583 case SNDRV_PCM_TRIGGER_SUSPEND: 588 case SNDRV_PCM_TRIGGER_SUSPEND:
584 case SNDRV_PCM_TRIGGER_STOP: 589 case SNDRV_PCM_TRIGGER_STOP:
@@ -705,7 +710,7 @@ static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
705 } 710 }
706} 711}
707 712
708static struct regmap_config fsl_esai_regmap_config = { 713static const struct regmap_config fsl_esai_regmap_config = {
709 .reg_bits = 32, 714 .reg_bits = 32,
710 .reg_stride = 4, 715 .reg_stride = 4,
711 .val_bits = 32, 716 .val_bits = 32,
@@ -731,9 +736,6 @@ static int fsl_esai_probe(struct platform_device *pdev)
731 esai_priv->pdev = pdev; 736 esai_priv->pdev = pdev;
732 strcpy(esai_priv->name, np->name); 737 strcpy(esai_priv->name, np->name);
733 738
734 if (of_property_read_bool(np, "big-endian"))
735 fsl_esai_regmap_config.val_format_endian = REGMAP_ENDIAN_BIG;
736
737 /* Get the addresses and IRQ */ 739 /* Get the addresses and IRQ */
738 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 740 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
739 regs = devm_ioremap_resource(&pdev->dev, res); 741 regs = devm_ioremap_resource(&pdev->dev, res);
@@ -781,6 +783,9 @@ static int fsl_esai_probe(struct platform_device *pdev)
781 /* Set a default slot size */ 783 /* Set a default slot size */
782 esai_priv->slot_width = 32; 784 esai_priv->slot_width = 32;
783 785
786 /* Set a default slot number */
787 esai_priv->slots = 2;
788
784 /* Set a default master/slave state */ 789 /* Set a default master/slave state */
785 esai_priv->slave_mode = true; 790 esai_priv->slave_mode = true;
786 791