aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShengjiu Wang <shengjiu.wang@freescale.com>2014-08-08 02:47:21 -0400
committerMark Brown <broonie@linaro.org>2014-08-13 14:50:21 -0400
commitd177143c3670aa57ee08c73880beb55ee9d8ab7c (patch)
treef362587cb952cb02048bd623f7d783749de0ebe6
parentae34a78c430c37c06404f032fb04e51315204281 (diff)
ASoC: fsl_esai: refine esai for TDM support
Original driver didn't store the number of slots, just fix the slot number to 2, use this default number to calculate bclk and pins for TX/RX. In this patch, add one parameter for slots, and update the calculation of bclk and pins of TX/RX. Then driver will be compatible with slots > 2 in TDM mode. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com> Acked-by: Nicolin Chen <nicoleotsuka@gmail.com> Signed-off-by: Mark Brown <broonie@linaro.org>
-rw-r--r--sound/soc/fsl/fsl_esai.c14
-rw-r--r--sound/soc/fsl/fsl_esai.h8
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