aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/Kconfig3
-rw-r--r--sound/soc/fsl/Makefile2
-rw-r--r--sound/soc/fsl/fsl_dma.c7
-rw-r--r--sound/soc/fsl/fsl_esai.c815
-rw-r--r--sound/soc/fsl/fsl_esai.h354
-rw-r--r--sound/soc/fsl/fsl_sai.c7
-rw-r--r--sound/soc/fsl/fsl_ssi.c583
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c3
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c3
-rw-r--r--sound/soc/fsl/mpc5200_dma.c4
10 files changed, 1577 insertions, 204 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 514c275c6108..324988dea4bd 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -8,6 +8,9 @@ config SND_SOC_FSL_SSI
8config SND_SOC_FSL_SPDIF 8config SND_SOC_FSL_SPDIF
9 tristate 9 tristate
10 10
11config SND_SOC_FSL_ESAI
12 tristate
13
11config SND_SOC_FSL_UTILS 14config SND_SOC_FSL_UTILS
12 tristate 15 tristate
13 16
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index aaccbee17006..b12ad4b9b4da 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -14,11 +14,13 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
14snd-soc-fsl-sai-objs := fsl_sai.o 14snd-soc-fsl-sai-objs := fsl_sai.o
15snd-soc-fsl-ssi-objs := fsl_ssi.o 15snd-soc-fsl-ssi-objs := fsl_ssi.o
16snd-soc-fsl-spdif-objs := fsl_spdif.o 16snd-soc-fsl-spdif-objs := fsl_spdif.o
17snd-soc-fsl-esai-objs := fsl_esai.o
17snd-soc-fsl-utils-objs := fsl_utils.o 18snd-soc-fsl-utils-objs := fsl_utils.o
18snd-soc-fsl-dma-objs := fsl_dma.o 19snd-soc-fsl-dma-objs := fsl_dma.o
19obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o 20obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
20obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o 21obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
21obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o 22obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
23obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
22obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o 24obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
23obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o 25obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
24 26
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index d570f8c81dc6..6bb0ea59284f 100644
--- a/sound/soc/fsl/fsl_dma.c
+++ b/sound/soc/fsl/fsl_dma.c
@@ -55,10 +55,6 @@
55 SNDRV_PCM_FMTBIT_S32_BE | \ 55 SNDRV_PCM_FMTBIT_S32_BE | \
56 SNDRV_PCM_FMTBIT_U32_LE | \ 56 SNDRV_PCM_FMTBIT_U32_LE | \
57 SNDRV_PCM_FMTBIT_U32_BE) 57 SNDRV_PCM_FMTBIT_U32_BE)
58
59#define FSLDMA_PCM_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \
60 SNDRV_PCM_RATE_CONTINUOUS)
61
62struct dma_object { 58struct dma_object {
63 struct snd_soc_platform_driver dai; 59 struct snd_soc_platform_driver dai;
64 dma_addr_t ssi_stx_phys; 60 dma_addr_t ssi_stx_phys;
@@ -140,9 +136,6 @@ static const struct snd_pcm_hardware fsl_dma_hardware = {
140 SNDRV_PCM_INFO_JOINT_DUPLEX | 136 SNDRV_PCM_INFO_JOINT_DUPLEX |
141 SNDRV_PCM_INFO_PAUSE, 137 SNDRV_PCM_INFO_PAUSE,
142 .formats = FSLDMA_PCM_FORMATS, 138 .formats = FSLDMA_PCM_FORMATS,
143 .rates = FSLDMA_PCM_RATES,
144 .rate_min = 5512,
145 .rate_max = 192000,
146 .period_bytes_min = 512, /* A reasonable limit */ 139 .period_bytes_min = 512, /* A reasonable limit */
147 .period_bytes_max = (u32) -1, 140 .period_bytes_max = (u32) -1,
148 .periods_min = NUM_DMA_LINKS, 141 .periods_min = NUM_DMA_LINKS,
diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
new file mode 100644
index 000000000000..d0c72ed261e7
--- /dev/null
+++ b/sound/soc/fsl/fsl_esai.c
@@ -0,0 +1,815 @@
1/*
2 * Freescale ESAI ALSA SoC Digital Audio Interface (DAI) driver
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 */
10
11#include <linux/clk.h>
12#include <linux/dmaengine.h>
13#include <linux/module.h>
14#include <linux/of_irq.h>
15#include <linux/of_platform.h>
16#include <sound/dmaengine_pcm.h>
17#include <sound/pcm_params.h>
18
19#include "fsl_esai.h"
20#include "imx-pcm.h"
21
22#define FSL_ESAI_RATES SNDRV_PCM_RATE_8000_192000
23#define FSL_ESAI_FORMATS (SNDRV_PCM_FMTBIT_S8 | \
24 SNDRV_PCM_FMTBIT_S16_LE | \
25 SNDRV_PCM_FMTBIT_S20_3LE | \
26 SNDRV_PCM_FMTBIT_S24_LE)
27
28/**
29 * fsl_esai: ESAI private data
30 *
31 * @dma_params_rx: DMA parameters for receive channel
32 * @dma_params_tx: DMA parameters for transmit channel
33 * @pdev: platform device pointer
34 * @regmap: regmap handler
35 * @coreclk: clock source to access register
36 * @extalclk: esai 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
39 * @slot_width: width of each DAI slot
40 * @hck_rate: clock rate of desired HCKx clock
41 * @sck_div: if using PSR/PM dividers for SCKx clock
42 * @slave_mode: if fully using DAI slave mode
43 * @synchronous: if using tx/rx synchronous mode
44 * @name: driver name
45 */
46struct fsl_esai {
47 struct snd_dmaengine_dai_dma_data dma_params_rx;
48 struct snd_dmaengine_dai_dma_data dma_params_tx;
49 struct platform_device *pdev;
50 struct regmap *regmap;
51 struct clk *coreclk;
52 struct clk *extalclk;
53 struct clk *fsysclk;
54 u32 fifo_depth;
55 u32 slot_width;
56 u32 hck_rate[2];
57 bool sck_div[2];
58 bool slave_mode;
59 bool synchronous;
60 char name[32];
61};
62
63static irqreturn_t esai_isr(int irq, void *devid)
64{
65 struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
66 struct platform_device *pdev = esai_priv->pdev;
67 u32 esr;
68
69 regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
70
71 if (esr & ESAI_ESR_TINIT_MASK)
72 dev_dbg(&pdev->dev, "isr: Transmition Initialized\n");
73
74 if (esr & ESAI_ESR_RFF_MASK)
75 dev_warn(&pdev->dev, "isr: Receiving overrun\n");
76
77 if (esr & ESAI_ESR_TFE_MASK)
78 dev_warn(&pdev->dev, "isr: Transmition underrun\n");
79
80 if (esr & ESAI_ESR_TLS_MASK)
81 dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
82
83 if (esr & ESAI_ESR_TDE_MASK)
84 dev_dbg(&pdev->dev, "isr: Transmition data exception\n");
85
86 if (esr & ESAI_ESR_TED_MASK)
87 dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
88
89 if (esr & ESAI_ESR_TD_MASK)
90 dev_dbg(&pdev->dev, "isr: Transmitting data\n");
91
92 if (esr & ESAI_ESR_RLS_MASK)
93 dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
94
95 if (esr & ESAI_ESR_RDE_MASK)
96 dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
97
98 if (esr & ESAI_ESR_RED_MASK)
99 dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
100
101 if (esr & ESAI_ESR_RD_MASK)
102 dev_dbg(&pdev->dev, "isr: Receiving data\n");
103
104 return IRQ_HANDLED;
105}
106
107/**
108 * This function is used to calculate the divisors of psr, pm, fp and it is
109 * supposed to be called in set_dai_sysclk() and set_bclk().
110 *
111 * @ratio: desired overall ratio for the paticipating dividers
112 * @usefp: for HCK setting, there is no need to set fp divider
113 * @fp: bypass other dividers by setting fp directly if fp != 0
114 * @tx: current setting is for playback or capture
115 */
116static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
117 bool usefp, u32 fp)
118{
119 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
120 u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
121
122 maxfp = usefp ? 16 : 1;
123
124 if (usefp && fp)
125 goto out_fp;
126
127 if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
128 dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
129 2 * 8 * 256 * maxfp);
130 return -EINVAL;
131 } else if (ratio % 2) {
132 dev_err(dai->dev, "the raio must be even if using upper divider\n");
133 return -EINVAL;
134 }
135
136 ratio /= 2;
137
138 psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
139
140 /* Set the max fluctuation -- 0.1% of the max devisor */
141 savesub = (psr ? 1 : 8) * 256 * maxfp / 1000;
142
143 /* Find the best value for PM */
144 for (i = 1; i <= 256; i++) {
145 for (j = 1; j <= maxfp; j++) {
146 /* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */
147 prod = (psr ? 1 : 8) * i * j;
148
149 if (prod == ratio)
150 sub = 0;
151 else if (prod / ratio == 1)
152 sub = prod - ratio;
153 else if (ratio / prod == 1)
154 sub = ratio - prod;
155 else
156 continue;
157
158 /* Calculate the fraction */
159 sub = sub * 1000 / ratio;
160 if (sub < savesub) {
161 savesub = sub;
162 pm = i;
163 fp = j;
164 }
165
166 /* We are lucky */
167 if (savesub == 0)
168 goto out;
169 }
170 }
171
172 if (pm == 999) {
173 dev_err(dai->dev, "failed to calculate proper divisors\n");
174 return -EINVAL;
175 }
176
177out:
178 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
179 ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
180 psr | ESAI_xCCR_xPM(pm));
181
182out_fp:
183 /* Bypass fp if not being required */
184 if (maxfp <= 1)
185 return 0;
186
187 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
188 ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
189
190 return 0;
191}
192
193/**
194 * This function mainly configures the clock frequency of MCLK (HCKT/HCKR)
195 *
196 * @Parameters:
197 * clk_id: The clock source of HCKT/HCKR
198 * (Input from outside; output from inside, FSYS or EXTAL)
199 * freq: The required clock rate of HCKT/HCKR
200 * dir: The clock direction of HCKT/HCKR
201 *
202 * Note: If the direction is input, we do not care about clk_id.
203 */
204static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
205 unsigned int freq, int dir)
206{
207 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
208 struct clk *clksrc = esai_priv->extalclk;
209 bool tx = clk_id <= ESAI_HCKT_EXTAL;
210 bool in = dir == SND_SOC_CLOCK_IN;
211 u32 ret, ratio, ecr = 0;
212 unsigned long clk_rate;
213
214 /* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
215 esai_priv->sck_div[tx] = true;
216
217 /* Set the direction of HCKT/HCKR pins */
218 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
219 ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
220
221 if (in)
222 goto out;
223
224 switch (clk_id) {
225 case ESAI_HCKT_FSYS:
226 case ESAI_HCKR_FSYS:
227 clksrc = esai_priv->fsysclk;
228 break;
229 case ESAI_HCKT_EXTAL:
230 ecr |= ESAI_ECR_ETI;
231 case ESAI_HCKR_EXTAL:
232 ecr |= ESAI_ECR_ERI;
233 break;
234 default:
235 return -EINVAL;
236 }
237
238 if (IS_ERR(clksrc)) {
239 dev_err(dai->dev, "no assigned %s clock\n",
240 clk_id % 2 ? "extal" : "fsys");
241 return PTR_ERR(clksrc);
242 }
243 clk_rate = clk_get_rate(clksrc);
244
245 ratio = clk_rate / freq;
246 if (ratio * freq > clk_rate)
247 ret = ratio * freq - clk_rate;
248 else if (ratio * freq < clk_rate)
249 ret = clk_rate - ratio * freq;
250 else
251 ret = 0;
252
253 /* Block if clock source can not be divided into the required rate */
254 if (ret != 0 && clk_rate / ret < 1000) {
255 dev_err(dai->dev, "failed to derive required HCK%c rate\n",
256 tx ? 'T' : 'R');
257 return -EINVAL;
258 }
259
260 if (ratio == 1) {
261 /* Bypass all the dividers if not being needed */
262 ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
263 goto out;
264 }
265
266 ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
267 if (ret)
268 return ret;
269
270 esai_priv->sck_div[tx] = false;
271
272out:
273 esai_priv->hck_rate[tx] = freq;
274
275 regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
276 tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
277 ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
278
279 return 0;
280}
281
282/**
283 * This function configures the related dividers according to the bclk rate
284 */
285static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
286{
287 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
288 u32 hck_rate = esai_priv->hck_rate[tx];
289 u32 sub, ratio = hck_rate / freq;
290
291 /* Don't apply for fully slave mode*/
292 if (esai_priv->slave_mode)
293 return 0;
294
295 if (ratio * freq > hck_rate)
296 sub = ratio * freq - hck_rate;
297 else if (ratio * freq < hck_rate)
298 sub = hck_rate - ratio * freq;
299 else
300 sub = 0;
301
302 /* Block if clock source can not be divided into the required rate */
303 if (sub != 0 && hck_rate / sub < 1000) {
304 dev_err(dai->dev, "failed to derive required SCK%c rate\n",
305 tx ? 'T' : 'R');
306 return -EINVAL;
307 }
308
309 if (esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
310 dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
311 return -EINVAL;
312 }
313
314 return fsl_esai_divisor_cal(dai, tx, ratio, true,
315 esai_priv->sck_div[tx] ? 0 : ratio);
316}
317
318static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
319 u32 rx_mask, int slots, int slot_width)
320{
321 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
322
323 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
324 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
325
326 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA,
327 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask));
328 regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB,
329 ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(tx_mask));
330
331 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
332 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
333
334 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA,
335 ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask));
336 regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB,
337 ESAI_xSMA_xS_MASK, ESAI_xSMB_xS(rx_mask));
338
339 esai_priv->slot_width = slot_width;
340
341 return 0;
342}
343
344static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
345{
346 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
347 u32 xcr = 0, xccr = 0, mask;
348
349 /* DAI mode */
350 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
351 case SND_SOC_DAIFMT_I2S:
352 /* Data on rising edge of bclk, frame low, 1clk before data */
353 xcr |= ESAI_xCR_xFSR;
354 xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
355 break;
356 case SND_SOC_DAIFMT_LEFT_J:
357 /* Data on rising edge of bclk, frame high */
358 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
359 break;
360 case SND_SOC_DAIFMT_RIGHT_J:
361 /* Data on rising edge of bclk, frame high, right aligned */
362 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA;
363 break;
364 case SND_SOC_DAIFMT_DSP_A:
365 /* Data on rising edge of bclk, frame high, 1clk before data */
366 xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
367 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
368 break;
369 case SND_SOC_DAIFMT_DSP_B:
370 /* Data on rising edge of bclk, frame high */
371 xcr |= ESAI_xCR_xFSL;
372 xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
373 break;
374 default:
375 return -EINVAL;
376 }
377
378 /* DAI clock inversion */
379 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
380 case SND_SOC_DAIFMT_NB_NF:
381 /* Nothing to do for both normal cases */
382 break;
383 case SND_SOC_DAIFMT_IB_NF:
384 /* Invert bit clock */
385 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
386 break;
387 case SND_SOC_DAIFMT_NB_IF:
388 /* Invert frame clock */
389 xccr ^= ESAI_xCCR_xFSP;
390 break;
391 case SND_SOC_DAIFMT_IB_IF:
392 /* Invert both clocks */
393 xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
394 break;
395 default:
396 return -EINVAL;
397 }
398
399 esai_priv->slave_mode = false;
400
401 /* DAI clock master masks */
402 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
403 case SND_SOC_DAIFMT_CBM_CFM:
404 esai_priv->slave_mode = true;
405 break;
406 case SND_SOC_DAIFMT_CBS_CFM:
407 xccr |= ESAI_xCCR_xCKD;
408 break;
409 case SND_SOC_DAIFMT_CBM_CFS:
410 xccr |= ESAI_xCCR_xFSD;
411 break;
412 case SND_SOC_DAIFMT_CBS_CFS:
413 xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
414 break;
415 default:
416 return -EINVAL;
417 }
418
419 mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR;
420 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
421 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
422
423 mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
424 ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA;
425 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
426 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
427
428 return 0;
429}
430
431static int fsl_esai_startup(struct snd_pcm_substream *substream,
432 struct snd_soc_dai *dai)
433{
434 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
435
436 /*
437 * Some platforms might use the same bit to gate all three or two of
438 * clocks, so keep all clocks open/close at the same time for safety
439 */
440 clk_prepare_enable(esai_priv->coreclk);
441 if (!IS_ERR(esai_priv->extalclk))
442 clk_prepare_enable(esai_priv->extalclk);
443 if (!IS_ERR(esai_priv->fsysclk))
444 clk_prepare_enable(esai_priv->fsysclk);
445
446 if (!dai->active) {
447 /* Reset Port C */
448 regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
449 ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
450 regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
451 ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
452
453 /* Set synchronous mode */
454 regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
455 ESAI_SAICR_SYNC, esai_priv->synchronous ?
456 ESAI_SAICR_SYNC : 0);
457
458 /* Set a default slot number -- 2 */
459 regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
460 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
461 regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
462 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
463 }
464
465 return 0;
466}
467
468static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
469 struct snd_pcm_hw_params *params,
470 struct snd_soc_dai *dai)
471{
472 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
473 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
474 u32 width = snd_pcm_format_width(params_format(params));
475 u32 channels = params_channels(params);
476 u32 bclk, mask, val, ret;
477
478 bclk = params_rate(params) * esai_priv->slot_width * 2;
479
480 ret = fsl_esai_set_bclk(dai, tx, bclk);
481 if (ret)
482 return ret;
483
484 /* Use Normal mode to support monaural audio */
485 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
486 ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
487 ESAI_xCR_xMOD_NETWORK : 0);
488
489 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
490 ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
491
492 mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
493 (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
494 val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
495 (tx ? ESAI_xFCR_TE(channels) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(channels));
496
497 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
498
499 mask = ESAI_xCR_xSWS_MASK | (tx ? ESAI_xCR_PADC : 0);
500 val = ESAI_xCR_xSWS(esai_priv->slot_width, width) | (tx ? ESAI_xCR_PADC : 0);
501
502 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
503
504 return 0;
505}
506
507static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
508 struct snd_soc_dai *dai)
509{
510 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
511
512 if (!IS_ERR(esai_priv->fsysclk))
513 clk_disable_unprepare(esai_priv->fsysclk);
514 if (!IS_ERR(esai_priv->extalclk))
515 clk_disable_unprepare(esai_priv->extalclk);
516 clk_disable_unprepare(esai_priv->coreclk);
517}
518
519static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
520 struct snd_soc_dai *dai)
521{
522 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
523 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
524 u8 i, channels = substream->runtime->channels;
525
526 switch (cmd) {
527 case SNDRV_PCM_TRIGGER_START:
528 case SNDRV_PCM_TRIGGER_RESUME:
529 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
530 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
531 ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
532
533 /* Write initial words reqiured by ESAI as normal procedure */
534 for (i = 0; tx && i < channels; i++)
535 regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
536
537 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
538 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
539 tx ? ESAI_xCR_TE(channels) : ESAI_xCR_RE(channels));
540 break;
541 case SNDRV_PCM_TRIGGER_SUSPEND:
542 case SNDRV_PCM_TRIGGER_STOP:
543 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
544 regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
545 tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
546
547 /* Disable and reset FIFO */
548 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
549 ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
550 regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
551 ESAI_xFCR_xFR, 0);
552 break;
553 default:
554 return -EINVAL;
555 }
556
557 return 0;
558}
559
560static struct snd_soc_dai_ops fsl_esai_dai_ops = {
561 .startup = fsl_esai_startup,
562 .shutdown = fsl_esai_shutdown,
563 .trigger = fsl_esai_trigger,
564 .hw_params = fsl_esai_hw_params,
565 .set_sysclk = fsl_esai_set_dai_sysclk,
566 .set_fmt = fsl_esai_set_dai_fmt,
567 .set_tdm_slot = fsl_esai_set_dai_tdm_slot,
568};
569
570static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
571{
572 struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
573
574 snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
575 &esai_priv->dma_params_rx);
576
577 return 0;
578}
579
580static struct snd_soc_dai_driver fsl_esai_dai = {
581 .probe = fsl_esai_dai_probe,
582 .playback = {
583 .channels_min = 1,
584 .channels_max = 12,
585 .rates = FSL_ESAI_RATES,
586 .formats = FSL_ESAI_FORMATS,
587 },
588 .capture = {
589 .channels_min = 1,
590 .channels_max = 8,
591 .rates = FSL_ESAI_RATES,
592 .formats = FSL_ESAI_FORMATS,
593 },
594 .ops = &fsl_esai_dai_ops,
595};
596
597static const struct snd_soc_component_driver fsl_esai_component = {
598 .name = "fsl-esai",
599};
600
601static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
602{
603 switch (reg) {
604 case REG_ESAI_ERDR:
605 case REG_ESAI_ECR:
606 case REG_ESAI_ESR:
607 case REG_ESAI_TFCR:
608 case REG_ESAI_TFSR:
609 case REG_ESAI_RFCR:
610 case REG_ESAI_RFSR:
611 case REG_ESAI_RX0:
612 case REG_ESAI_RX1:
613 case REG_ESAI_RX2:
614 case REG_ESAI_RX3:
615 case REG_ESAI_SAISR:
616 case REG_ESAI_SAICR:
617 case REG_ESAI_TCR:
618 case REG_ESAI_TCCR:
619 case REG_ESAI_RCR:
620 case REG_ESAI_RCCR:
621 case REG_ESAI_TSMA:
622 case REG_ESAI_TSMB:
623 case REG_ESAI_RSMA:
624 case REG_ESAI_RSMB:
625 case REG_ESAI_PRRC:
626 case REG_ESAI_PCRC:
627 return true;
628 default:
629 return false;
630 }
631}
632
633static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
634{
635 switch (reg) {
636 case REG_ESAI_ETDR:
637 case REG_ESAI_ECR:
638 case REG_ESAI_TFCR:
639 case REG_ESAI_RFCR:
640 case REG_ESAI_TX0:
641 case REG_ESAI_TX1:
642 case REG_ESAI_TX2:
643 case REG_ESAI_TX3:
644 case REG_ESAI_TX4:
645 case REG_ESAI_TX5:
646 case REG_ESAI_TSR:
647 case REG_ESAI_SAICR:
648 case REG_ESAI_TCR:
649 case REG_ESAI_TCCR:
650 case REG_ESAI_RCR:
651 case REG_ESAI_RCCR:
652 case REG_ESAI_TSMA:
653 case REG_ESAI_TSMB:
654 case REG_ESAI_RSMA:
655 case REG_ESAI_RSMB:
656 case REG_ESAI_PRRC:
657 case REG_ESAI_PCRC:
658 return true;
659 default:
660 return false;
661 }
662}
663
664static const struct regmap_config fsl_esai_regmap_config = {
665 .reg_bits = 32,
666 .reg_stride = 4,
667 .val_bits = 32,
668
669 .max_register = REG_ESAI_PCRC,
670 .readable_reg = fsl_esai_readable_reg,
671 .writeable_reg = fsl_esai_writeable_reg,
672};
673
674static int fsl_esai_probe(struct platform_device *pdev)
675{
676 struct device_node *np = pdev->dev.of_node;
677 struct fsl_esai *esai_priv;
678 struct resource *res;
679 const uint32_t *iprop;
680 void __iomem *regs;
681 int irq, ret;
682
683 esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
684 if (!esai_priv)
685 return -ENOMEM;
686
687 esai_priv->pdev = pdev;
688 strcpy(esai_priv->name, np->name);
689
690 /* Get the addresses and IRQ */
691 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
692 regs = devm_ioremap_resource(&pdev->dev, res);
693 if (IS_ERR(regs))
694 return PTR_ERR(regs);
695
696 esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
697 "core", regs, &fsl_esai_regmap_config);
698 if (IS_ERR(esai_priv->regmap)) {
699 dev_err(&pdev->dev, "failed to init regmap: %ld\n",
700 PTR_ERR(esai_priv->regmap));
701 return PTR_ERR(esai_priv->regmap);
702 }
703
704 esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
705 if (IS_ERR(esai_priv->coreclk)) {
706 dev_err(&pdev->dev, "failed to get core clock: %ld\n",
707 PTR_ERR(esai_priv->coreclk));
708 return PTR_ERR(esai_priv->coreclk);
709 }
710
711 esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
712 if (IS_ERR(esai_priv->extalclk))
713 dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
714 PTR_ERR(esai_priv->extalclk));
715
716 esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
717 if (IS_ERR(esai_priv->fsysclk))
718 dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
719 PTR_ERR(esai_priv->fsysclk));
720
721 irq = platform_get_irq(pdev, 0);
722 if (irq < 0) {
723 dev_err(&pdev->dev, "no irq for node %s\n", np->full_name);
724 return irq;
725 }
726
727 ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
728 esai_priv->name, esai_priv);
729 if (ret) {
730 dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
731 return ret;
732 }
733
734 /* Set a default slot size */
735 esai_priv->slot_width = 32;
736
737 /* Set a default master/slave state */
738 esai_priv->slave_mode = true;
739
740 /* Determine the FIFO depth */
741 iprop = of_get_property(np, "fsl,fifo-depth", NULL);
742 if (iprop)
743 esai_priv->fifo_depth = be32_to_cpup(iprop);
744 else
745 esai_priv->fifo_depth = 64;
746
747 esai_priv->dma_params_tx.maxburst = 16;
748 esai_priv->dma_params_rx.maxburst = 16;
749 esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
750 esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
751
752 esai_priv->synchronous =
753 of_property_read_bool(np, "fsl,esai-synchronous");
754
755 /* Implement full symmetry for synchronous mode */
756 if (esai_priv->synchronous) {
757 fsl_esai_dai.symmetric_rates = 1;
758 fsl_esai_dai.symmetric_channels = 1;
759 fsl_esai_dai.symmetric_samplebits = 1;
760 }
761
762 dev_set_drvdata(&pdev->dev, esai_priv);
763
764 /* Reset ESAI unit */
765 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
766 if (ret) {
767 dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
768 return ret;
769 }
770
771 /*
772 * We need to enable ESAI so as to access some of its registers.
773 * Otherwise, we would fail to dump regmap from user space.
774 */
775 ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
776 if (ret) {
777 dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
778 return ret;
779 }
780
781 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
782 &fsl_esai_dai, 1);
783 if (ret) {
784 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
785 return ret;
786 }
787
788 ret = imx_pcm_dma_init(pdev);
789 if (ret)
790 dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
791
792 return ret;
793}
794
795static const struct of_device_id fsl_esai_dt_ids[] = {
796 { .compatible = "fsl,imx35-esai", },
797 {}
798};
799MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
800
801static struct platform_driver fsl_esai_driver = {
802 .probe = fsl_esai_probe,
803 .driver = {
804 .name = "fsl-esai-dai",
805 .owner = THIS_MODULE,
806 .of_match_table = fsl_esai_dt_ids,
807 },
808};
809
810module_platform_driver(fsl_esai_driver);
811
812MODULE_AUTHOR("Freescale Semiconductor, Inc.");
813MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
814MODULE_LICENSE("GPL v2");
815MODULE_ALIAS("platform:fsl-esai-dai");
diff --git a/sound/soc/fsl/fsl_esai.h b/sound/soc/fsl/fsl_esai.h
new file mode 100644
index 000000000000..9c9f957fcae1
--- /dev/null
+++ b/sound/soc/fsl/fsl_esai.h
@@ -0,0 +1,354 @@
1/*
2 * fsl_esai.h - ALSA ESAI interface for the Freescale i.MX SoC
3 *
4 * Copyright (C) 2014 Freescale Semiconductor, Inc.
5 *
6 * Author: Nicolin Chen <Guangyu.Chen@freescale.com>
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#ifndef _FSL_ESAI_DAI_H
14#define _FSL_ESAI_DAI_H
15
16/* ESAI Register Map */
17#define REG_ESAI_ETDR 0x00
18#define REG_ESAI_ERDR 0x04
19#define REG_ESAI_ECR 0x08
20#define REG_ESAI_ESR 0x0C
21#define REG_ESAI_TFCR 0x10
22#define REG_ESAI_TFSR 0x14
23#define REG_ESAI_RFCR 0x18
24#define REG_ESAI_RFSR 0x1C
25#define REG_ESAI_xFCR(tx) (tx ? REG_ESAI_TFCR : REG_ESAI_RFCR)
26#define REG_ESAI_xFSR(tx) (tx ? REG_ESAI_TFSR : REG_ESAI_RFSR)
27#define REG_ESAI_TX0 0x80
28#define REG_ESAI_TX1 0x84
29#define REG_ESAI_TX2 0x88
30#define REG_ESAI_TX3 0x8C
31#define REG_ESAI_TX4 0x90
32#define REG_ESAI_TX5 0x94
33#define REG_ESAI_TSR 0x98
34#define REG_ESAI_RX0 0xA0
35#define REG_ESAI_RX1 0xA4
36#define REG_ESAI_RX2 0xA8
37#define REG_ESAI_RX3 0xAC
38#define REG_ESAI_SAISR 0xCC
39#define REG_ESAI_SAICR 0xD0
40#define REG_ESAI_TCR 0xD4
41#define REG_ESAI_TCCR 0xD8
42#define REG_ESAI_RCR 0xDC
43#define REG_ESAI_RCCR 0xE0
44#define REG_ESAI_xCR(tx) (tx ? REG_ESAI_TCR : REG_ESAI_RCR)
45#define REG_ESAI_xCCR(tx) (tx ? REG_ESAI_TCCR : REG_ESAI_RCCR)
46#define REG_ESAI_TSMA 0xE4
47#define REG_ESAI_TSMB 0xE8
48#define REG_ESAI_RSMA 0xEC
49#define REG_ESAI_RSMB 0xF0
50#define REG_ESAI_xSMA(tx) (tx ? REG_ESAI_TSMA : REG_ESAI_RSMA)
51#define REG_ESAI_xSMB(tx) (tx ? REG_ESAI_TSMB : REG_ESAI_RSMB)
52#define REG_ESAI_PRRC 0xF8
53#define REG_ESAI_PCRC 0xFC
54
55/* ESAI Control Register -- REG_ESAI_ECR 0x8 */
56#define ESAI_ECR_ETI_SHIFT 19
57#define ESAI_ECR_ETI_MASK (1 << ESAI_ECR_ETI_SHIFT)
58#define ESAI_ECR_ETI (1 << ESAI_ECR_ETI_SHIFT)
59#define ESAI_ECR_ETO_SHIFT 18
60#define ESAI_ECR_ETO_MASK (1 << ESAI_ECR_ETO_SHIFT)
61#define ESAI_ECR_ETO (1 << ESAI_ECR_ETO_SHIFT)
62#define ESAI_ECR_ERI_SHIFT 17
63#define ESAI_ECR_ERI_MASK (1 << ESAI_ECR_ERI_SHIFT)
64#define ESAI_ECR_ERI (1 << ESAI_ECR_ERI_SHIFT)
65#define ESAI_ECR_ERO_SHIFT 16
66#define ESAI_ECR_ERO_MASK (1 << ESAI_ECR_ERO_SHIFT)
67#define ESAI_ECR_ERO (1 << ESAI_ECR_ERO_SHIFT)
68#define ESAI_ECR_ERST_SHIFT 1
69#define ESAI_ECR_ERST_MASK (1 << ESAI_ECR_ERST_SHIFT)
70#define ESAI_ECR_ERST (1 << ESAI_ECR_ERST_SHIFT)
71#define ESAI_ECR_ESAIEN_SHIFT 0
72#define ESAI_ECR_ESAIEN_MASK (1 << ESAI_ECR_ESAIEN_SHIFT)
73#define ESAI_ECR_ESAIEN (1 << ESAI_ECR_ESAIEN_SHIFT)
74
75/* ESAI Status Register -- REG_ESAI_ESR 0xC */
76#define ESAI_ESR_TINIT_SHIFT 10
77#define ESAI_ESR_TINIT_MASK (1 << ESAI_ESR_TINIT_SHIFT)
78#define ESAI_ESR_TINIT (1 << ESAI_ESR_TINIT_SHIFT)
79#define ESAI_ESR_RFF_SHIFT 9
80#define ESAI_ESR_RFF_MASK (1 << ESAI_ESR_RFF_SHIFT)
81#define ESAI_ESR_RFF (1 << ESAI_ESR_RFF_SHIFT)
82#define ESAI_ESR_TFE_SHIFT 8
83#define ESAI_ESR_TFE_MASK (1 << ESAI_ESR_TFE_SHIFT)
84#define ESAI_ESR_TFE (1 << ESAI_ESR_TFE_SHIFT)
85#define ESAI_ESR_TLS_SHIFT 7
86#define ESAI_ESR_TLS_MASK (1 << ESAI_ESR_TLS_SHIFT)
87#define ESAI_ESR_TLS (1 << ESAI_ESR_TLS_SHIFT)
88#define ESAI_ESR_TDE_SHIFT 6
89#define ESAI_ESR_TDE_MASK (1 << ESAI_ESR_TDE_SHIFT)
90#define ESAI_ESR_TDE (1 << ESAI_ESR_TDE_SHIFT)
91#define ESAI_ESR_TED_SHIFT 5
92#define ESAI_ESR_TED_MASK (1 << ESAI_ESR_TED_SHIFT)
93#define ESAI_ESR_TED (1 << ESAI_ESR_TED_SHIFT)
94#define ESAI_ESR_TD_SHIFT 4
95#define ESAI_ESR_TD_MASK (1 << ESAI_ESR_TD_SHIFT)
96#define ESAI_ESR_TD (1 << ESAI_ESR_TD_SHIFT)
97#define ESAI_ESR_RLS_SHIFT 3
98#define ESAI_ESR_RLS_MASK (1 << ESAI_ESR_RLS_SHIFT)
99#define ESAI_ESR_RLS (1 << ESAI_ESR_RLS_SHIFT)
100#define ESAI_ESR_RDE_SHIFT 2
101#define ESAI_ESR_RDE_MASK (1 << ESAI_ESR_RDE_SHIFT)
102#define ESAI_ESR_RDE (1 << ESAI_ESR_RDE_SHIFT)
103#define ESAI_ESR_RED_SHIFT 1
104#define ESAI_ESR_RED_MASK (1 << ESAI_ESR_RED_SHIFT)
105#define ESAI_ESR_RED (1 << ESAI_ESR_RED_SHIFT)
106#define ESAI_ESR_RD_SHIFT 0
107#define ESAI_ESR_RD_MASK (1 << ESAI_ESR_RD_SHIFT)
108#define ESAI_ESR_RD (1 << ESAI_ESR_RD_SHIFT)
109
110/*
111 * Transmit FIFO Configuration Register -- REG_ESAI_TFCR 0x10
112 * Receive FIFO Configuration Register -- REG_ESAI_RFCR 0x18
113 */
114#define ESAI_xFCR_TIEN_SHIFT 19
115#define ESAI_xFCR_TIEN_MASK (1 << ESAI_xFCR_TIEN_SHIFT)
116#define ESAI_xFCR_TIEN (1 << ESAI_xFCR_TIEN_SHIFT)
117#define ESAI_xFCR_REXT_SHIFT 19
118#define ESAI_xFCR_REXT_MASK (1 << ESAI_xFCR_REXT_SHIFT)
119#define ESAI_xFCR_REXT (1 << ESAI_xFCR_REXT_SHIFT)
120#define ESAI_xFCR_xWA_SHIFT 16
121#define ESAI_xFCR_xWA_WIDTH 3
122#define ESAI_xFCR_xWA_MASK (((1 << ESAI_xFCR_xWA_WIDTH) - 1) << ESAI_xFCR_xWA_SHIFT)
123#define ESAI_xFCR_xWA(v) (((8 - ((v) >> 2)) << ESAI_xFCR_xWA_SHIFT) & ESAI_xFCR_xWA_MASK)
124#define ESAI_xFCR_xFWM_SHIFT 8
125#define ESAI_xFCR_xFWM_WIDTH 8
126#define ESAI_xFCR_xFWM_MASK (((1 << ESAI_xFCR_xFWM_WIDTH) - 1) << ESAI_xFCR_xFWM_SHIFT)
127#define ESAI_xFCR_xFWM(v) ((((v) - 1) << ESAI_xFCR_xFWM_SHIFT) & ESAI_xFCR_xFWM_MASK)
128#define ESAI_xFCR_xE_SHIFT 2
129#define ESAI_xFCR_TE_WIDTH 6
130#define ESAI_xFCR_RE_WIDTH 4
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)
133#define ESAI_xFCR_TE(x) ((ESAI_xFCR_TE_MASK >> (ESAI_xFCR_TE_WIDTH - ((x + 1) >> 1))) & 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)
135#define ESAI_xFCR_xFR_SHIFT 1
136#define ESAI_xFCR_xFR_MASK (1 << ESAI_xFCR_xFR_SHIFT)
137#define ESAI_xFCR_xFR (1 << ESAI_xFCR_xFR_SHIFT)
138#define ESAI_xFCR_xFEN_SHIFT 0
139#define ESAI_xFCR_xFEN_MASK (1 << ESAI_xFCR_xFEN_SHIFT)
140#define ESAI_xFCR_xFEN (1 << ESAI_xFCR_xFEN_SHIFT)
141
142/*
143 * Transmit FIFO Status Register -- REG_ESAI_TFSR 0x14
144 * Receive FIFO Status Register --REG_ESAI_RFSR 0x1C
145 */
146#define ESAI_xFSR_NTFO_SHIFT 12
147#define ESAI_xFSR_NRFI_SHIFT 12
148#define ESAI_xFSR_NTFI_SHIFT 8
149#define ESAI_xFSR_NRFO_SHIFT 8
150#define ESAI_xFSR_NTFx_WIDTH 3
151#define ESAI_xFSR_NRFx_WIDTH 2
152#define ESAI_xFSR_NTFO_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFO_SHIFT)
153#define ESAI_xFSR_NTFI_MASK (((1 << ESAI_xFSR_NTFx_WIDTH) - 1) << ESAI_xFSR_NTFI_SHIFT)
154#define ESAI_xFSR_NRFO_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFO_SHIFT)
155#define ESAI_xFSR_NRFI_MASK (((1 << ESAI_xFSR_NRFx_WIDTH) - 1) << ESAI_xFSR_NRFI_SHIFT)
156#define ESAI_xFSR_xFCNT_SHIFT 0
157#define ESAI_xFSR_xFCNT_WIDTH 8
158#define ESAI_xFSR_xFCNT_MASK (((1 << ESAI_xFSR_xFCNT_WIDTH) - 1) << ESAI_xFSR_xFCNT_SHIFT)
159
160/* ESAI Transmit Slot Register -- REG_ESAI_TSR 0x98 */
161#define ESAI_TSR_SHIFT 0
162#define ESAI_TSR_WIDTH 24
163#define ESAI_TSR_MASK (((1 << ESAI_TSR_WIDTH) - 1) << ESAI_TSR_SHIFT)
164
165/* Serial Audio Interface Status Register -- REG_ESAI_SAISR 0xCC */
166#define ESAI_SAISR_TODFE_SHIFT 17
167#define ESAI_SAISR_TODFE_MASK (1 << ESAI_SAISR_TODFE_SHIFT)
168#define ESAI_SAISR_TODFE (1 << ESAI_SAISR_TODFE_SHIFT)
169#define ESAI_SAISR_TEDE_SHIFT 16
170#define ESAI_SAISR_TEDE_MASK (1 << ESAI_SAISR_TEDE_SHIFT)
171#define ESAI_SAISR_TEDE (1 << ESAI_SAISR_TEDE_SHIFT)
172#define ESAI_SAISR_TDE_SHIFT 15
173#define ESAI_SAISR_TDE_MASK (1 << ESAI_SAISR_TDE_SHIFT)
174#define ESAI_SAISR_TDE (1 << ESAI_SAISR_TDE_SHIFT)
175#define ESAI_SAISR_TUE_SHIFT 14
176#define ESAI_SAISR_TUE_MASK (1 << ESAI_SAISR_TUE_SHIFT)
177#define ESAI_SAISR_TUE (1 << ESAI_SAISR_TUE_SHIFT)
178#define ESAI_SAISR_TFS_SHIFT 13
179#define ESAI_SAISR_TFS_MASK (1 << ESAI_SAISR_TFS_SHIFT)
180#define ESAI_SAISR_TFS (1 << ESAI_SAISR_TFS_SHIFT)
181#define ESAI_SAISR_RODF_SHIFT 10
182#define ESAI_SAISR_RODF_MASK (1 << ESAI_SAISR_RODF_SHIFT)
183#define ESAI_SAISR_RODF (1 << ESAI_SAISR_RODF_SHIFT)
184#define ESAI_SAISR_REDF_SHIFT 9
185#define ESAI_SAISR_REDF_MASK (1 << ESAI_SAISR_REDF_SHIFT)
186#define ESAI_SAISR_REDF (1 << ESAI_SAISR_REDF_SHIFT)
187#define ESAI_SAISR_RDF_SHIFT 8
188#define ESAI_SAISR_RDF_MASK (1 << ESAI_SAISR_RDF_SHIFT)
189#define ESAI_SAISR_RDF (1 << ESAI_SAISR_RDF_SHIFT)
190#define ESAI_SAISR_ROE_SHIFT 7
191#define ESAI_SAISR_ROE_MASK (1 << ESAI_SAISR_ROE_SHIFT)
192#define ESAI_SAISR_ROE (1 << ESAI_SAISR_ROE_SHIFT)
193#define ESAI_SAISR_RFS_SHIFT 6
194#define ESAI_SAISR_RFS_MASK (1 << ESAI_SAISR_RFS_SHIFT)
195#define ESAI_SAISR_RFS (1 << ESAI_SAISR_RFS_SHIFT)
196#define ESAI_SAISR_IF2_SHIFT 2
197#define ESAI_SAISR_IF2_MASK (1 << ESAI_SAISR_IF2_SHIFT)
198#define ESAI_SAISR_IF2 (1 << ESAI_SAISR_IF2_SHIFT)
199#define ESAI_SAISR_IF1_SHIFT 1
200#define ESAI_SAISR_IF1_MASK (1 << ESAI_SAISR_IF1_SHIFT)
201#define ESAI_SAISR_IF1 (1 << ESAI_SAISR_IF1_SHIFT)
202#define ESAI_SAISR_IF0_SHIFT 0
203#define ESAI_SAISR_IF0_MASK (1 << ESAI_SAISR_IF0_SHIFT)
204#define ESAI_SAISR_IF0 (1 << ESAI_SAISR_IF0_SHIFT)
205
206/* Serial Audio Interface Control Register -- REG_ESAI_SAICR 0xD0 */
207#define ESAI_SAICR_ALC_SHIFT 8
208#define ESAI_SAICR_ALC_MASK (1 << ESAI_SAICR_ALC_SHIFT)
209#define ESAI_SAICR_ALC (1 << ESAI_SAICR_ALC_SHIFT)
210#define ESAI_SAICR_TEBE_SHIFT 7
211#define ESAI_SAICR_TEBE_MASK (1 << ESAI_SAICR_TEBE_SHIFT)
212#define ESAI_SAICR_TEBE (1 << ESAI_SAICR_TEBE_SHIFT)
213#define ESAI_SAICR_SYNC_SHIFT 6
214#define ESAI_SAICR_SYNC_MASK (1 << ESAI_SAICR_SYNC_SHIFT)
215#define ESAI_SAICR_SYNC (1 << ESAI_SAICR_SYNC_SHIFT)
216#define ESAI_SAICR_OF2_SHIFT 2
217#define ESAI_SAICR_OF2_MASK (1 << ESAI_SAICR_OF2_SHIFT)
218#define ESAI_SAICR_OF2 (1 << ESAI_SAICR_OF2_SHIFT)
219#define ESAI_SAICR_OF1_SHIFT 1
220#define ESAI_SAICR_OF1_MASK (1 << ESAI_SAICR_OF1_SHIFT)
221#define ESAI_SAICR_OF1 (1 << ESAI_SAICR_OF1_SHIFT)
222#define ESAI_SAICR_OF0_SHIFT 0
223#define ESAI_SAICR_OF0_MASK (1 << ESAI_SAICR_OF0_SHIFT)
224#define ESAI_SAICR_OF0 (1 << ESAI_SAICR_OF0_SHIFT)
225
226/*
227 * Transmit Control Register -- REG_ESAI_TCR 0xD4
228 * Receive Control Register -- REG_ESAI_RCR 0xDC
229 */
230#define ESAI_xCR_xLIE_SHIFT 23
231#define ESAI_xCR_xLIE_MASK (1 << ESAI_xCR_xLIE_SHIFT)
232#define ESAI_xCR_xLIE (1 << ESAI_xCR_xLIE_SHIFT)
233#define ESAI_xCR_xIE_SHIFT 22
234#define ESAI_xCR_xIE_MASK (1 << ESAI_xCR_xIE_SHIFT)
235#define ESAI_xCR_xIE (1 << ESAI_xCR_xIE_SHIFT)
236#define ESAI_xCR_xEDIE_SHIFT 21
237#define ESAI_xCR_xEDIE_MASK (1 << ESAI_xCR_xEDIE_SHIFT)
238#define ESAI_xCR_xEDIE (1 << ESAI_xCR_xEDIE_SHIFT)
239#define ESAI_xCR_xEIE_SHIFT 20
240#define ESAI_xCR_xEIE_MASK (1 << ESAI_xCR_xEIE_SHIFT)
241#define ESAI_xCR_xEIE (1 << ESAI_xCR_xEIE_SHIFT)
242#define ESAI_xCR_xPR_SHIFT 19
243#define ESAI_xCR_xPR_MASK (1 << ESAI_xCR_xPR_SHIFT)
244#define ESAI_xCR_xPR (1 << ESAI_xCR_xPR_SHIFT)
245#define ESAI_xCR_PADC_SHIFT 17
246#define ESAI_xCR_PADC_MASK (1 << ESAI_xCR_PADC_SHIFT)
247#define ESAI_xCR_PADC (1 << ESAI_xCR_PADC_SHIFT)
248#define ESAI_xCR_xFSR_SHIFT 16
249#define ESAI_xCR_xFSR_MASK (1 << ESAI_xCR_xFSR_SHIFT)
250#define ESAI_xCR_xFSR (1 << ESAI_xCR_xFSR_SHIFT)
251#define ESAI_xCR_xFSL_SHIFT 15
252#define ESAI_xCR_xFSL_MASK (1 << ESAI_xCR_xFSL_SHIFT)
253#define ESAI_xCR_xFSL (1 << ESAI_xCR_xFSL_SHIFT)
254#define ESAI_xCR_xSWS_SHIFT 10
255#define ESAI_xCR_xSWS_WIDTH 5
256#define ESAI_xCR_xSWS_MASK (((1 << ESAI_xCR_xSWS_WIDTH) - 1) << ESAI_xCR_xSWS_SHIFT)
257#define ESAI_xCR_xSWS(s, w) ((w < 24 ? (s - w + ((w - 8) >> 2)) : (s < 32 ? 0x1e : 0x1f)) << ESAI_xCR_xSWS_SHIFT)
258#define ESAI_xCR_xMOD_SHIFT 8
259#define ESAI_xCR_xMOD_WIDTH 2
260#define ESAI_xCR_xMOD_MASK (((1 << ESAI_xCR_xMOD_WIDTH) - 1) << ESAI_xCR_xMOD_SHIFT)
261#define ESAI_xCR_xMOD_ONDEMAND (0x1 << ESAI_xCR_xMOD_SHIFT)
262#define ESAI_xCR_xMOD_NETWORK (0x1 << ESAI_xCR_xMOD_SHIFT)
263#define ESAI_xCR_xMOD_AC97 (0x3 << ESAI_xCR_xMOD_SHIFT)
264#define ESAI_xCR_xWA_SHIFT 7
265#define ESAI_xCR_xWA_MASK (1 << ESAI_xCR_xWA_SHIFT)
266#define ESAI_xCR_xWA (1 << ESAI_xCR_xWA_SHIFT)
267#define ESAI_xCR_xSHFD_SHIFT 6
268#define ESAI_xCR_xSHFD_MASK (1 << ESAI_xCR_xSHFD_SHIFT)
269#define ESAI_xCR_xSHFD (1 << ESAI_xCR_xSHFD_SHIFT)
270#define ESAI_xCR_xE_SHIFT 0
271#define ESAI_xCR_TE_WIDTH 6
272#define ESAI_xCR_RE_WIDTH 4
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)
275#define ESAI_xCR_TE(x) ((ESAI_xCR_TE_MASK >> (ESAI_xCR_TE_WIDTH - ((x + 1) >> 1))) & 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)
277
278/*
279 * Transmit Clock Control Register -- REG_ESAI_TCCR 0xD8
280 * Receive Clock Control Register -- REG_ESAI_RCCR 0xE0
281 */
282#define ESAI_xCCR_xHCKD_SHIFT 23
283#define ESAI_xCCR_xHCKD_MASK (1 << ESAI_xCCR_xHCKD_SHIFT)
284#define ESAI_xCCR_xHCKD (1 << ESAI_xCCR_xHCKD_SHIFT)
285#define ESAI_xCCR_xFSD_SHIFT 22
286#define ESAI_xCCR_xFSD_MASK (1 << ESAI_xCCR_xFSD_SHIFT)
287#define ESAI_xCCR_xFSD (1 << ESAI_xCCR_xFSD_SHIFT)
288#define ESAI_xCCR_xCKD_SHIFT 21
289#define ESAI_xCCR_xCKD_MASK (1 << ESAI_xCCR_xCKD_SHIFT)
290#define ESAI_xCCR_xCKD (1 << ESAI_xCCR_xCKD_SHIFT)
291#define ESAI_xCCR_xHCKP_SHIFT 20
292#define ESAI_xCCR_xHCKP_MASK (1 << ESAI_xCCR_xHCKP_SHIFT)
293#define ESAI_xCCR_xHCKP (1 << ESAI_xCCR_xHCKP_SHIFT)
294#define ESAI_xCCR_xFSP_SHIFT 19
295#define ESAI_xCCR_xFSP_MASK (1 << ESAI_xCCR_xFSP_SHIFT)
296#define ESAI_xCCR_xFSP (1 << ESAI_xCCR_xFSP_SHIFT)
297#define ESAI_xCCR_xCKP_SHIFT 18
298#define ESAI_xCCR_xCKP_MASK (1 << ESAI_xCCR_xCKP_SHIFT)
299#define ESAI_xCCR_xCKP (1 << ESAI_xCCR_xCKP_SHIFT)
300#define ESAI_xCCR_xFP_SHIFT 14
301#define ESAI_xCCR_xFP_WIDTH 4
302#define ESAI_xCCR_xFP_MASK (((1 << ESAI_xCCR_xFP_WIDTH) - 1) << ESAI_xCCR_xFP_SHIFT)
303#define ESAI_xCCR_xFP(v) ((((v) - 1) << ESAI_xCCR_xFP_SHIFT) & ESAI_xCCR_xFP_MASK)
304#define ESAI_xCCR_xDC_SHIFT 9
305#define ESAI_xCCR_xDC_WIDTH 4
306#define ESAI_xCCR_xDC_MASK (((1 << ESAI_xCCR_xDC_WIDTH) - 1) << ESAI_xCCR_xDC_SHIFT)
307#define ESAI_xCCR_xDC(v) ((((v) - 1) << ESAI_xCCR_xDC_SHIFT) & ESAI_xCCR_xDC_MASK)
308#define ESAI_xCCR_xPSR_SHIFT 8
309#define ESAI_xCCR_xPSR_MASK (1 << ESAI_xCCR_xPSR_SHIFT)
310#define ESAI_xCCR_xPSR_BYPASS (1 << ESAI_xCCR_xPSR_SHIFT)
311#define ESAI_xCCR_xPSR_DIV8 (0 << ESAI_xCCR_xPSR_SHIFT)
312#define ESAI_xCCR_xPM_SHIFT 0
313#define ESAI_xCCR_xPM_WIDTH 8
314#define ESAI_xCCR_xPM_MASK (((1 << ESAI_xCCR_xPM_WIDTH) - 1) << ESAI_xCCR_xPM_SHIFT)
315#define ESAI_xCCR_xPM(v) ((((v) - 1) << ESAI_xCCR_xPM_SHIFT) & ESAI_xCCR_xPM_MASK)
316
317/* Transmit Slot Mask Register A/B -- REG_ESAI_TSMA/B 0xE4 ~ 0xF0 */
318#define ESAI_xSMA_xS_SHIFT 0
319#define ESAI_xSMA_xS_WIDTH 16
320#define ESAI_xSMA_xS_MASK (((1 << ESAI_xSMA_xS_WIDTH) - 1) << ESAI_xSMA_xS_SHIFT)
321#define ESAI_xSMA_xS(v) ((v) & ESAI_xSMA_xS_MASK)
322#define ESAI_xSMB_xS_SHIFT 0
323#define ESAI_xSMB_xS_WIDTH 16
324#define ESAI_xSMB_xS_MASK (((1 << ESAI_xSMB_xS_WIDTH) - 1) << ESAI_xSMB_xS_SHIFT)
325#define ESAI_xSMB_xS(v) (((v) >> ESAI_xSMA_xS_WIDTH) & ESAI_xSMA_xS_MASK)
326
327/* Port C Direction Register -- REG_ESAI_PRRC 0xF8 */
328#define ESAI_PRRC_PDC_SHIFT 0
329#define ESAI_PRRC_PDC_WIDTH 12
330#define ESAI_PRRC_PDC_MASK (((1 << ESAI_PRRC_PDC_WIDTH) - 1) << ESAI_PRRC_PDC_SHIFT)
331#define ESAI_PRRC_PDC(v) ((v) & ESAI_PRRC_PDC_MASK)
332
333/* Port C Control Register -- REG_ESAI_PCRC 0xFC */
334#define ESAI_PCRC_PC_SHIFT 0
335#define ESAI_PCRC_PC_WIDTH 12
336#define ESAI_PCRC_PC_MASK (((1 << ESAI_PCRC_PC_WIDTH) - 1) << ESAI_PCRC_PC_SHIFT)
337#define ESAI_PCRC_PC(v) ((v) & ESAI_PCRC_PC_MASK)
338
339#define ESAI_GPIO 0xfff
340
341/* ESAI clock source */
342#define ESAI_HCKT_FSYS 0
343#define ESAI_HCKT_EXTAL 1
344#define ESAI_HCKR_FSYS 2
345#define ESAI_HCKR_EXTAL 3
346
347/* ESAI clock divider */
348#define ESAI_TX_DIV_PSR 0
349#define ESAI_TX_DIV_PM 1
350#define ESAI_TX_DIV_FP 2
351#define ESAI_RX_DIV_PSR 3
352#define ESAI_RX_DIV_PM 4
353#define ESAI_RX_DIV_FP 5
354#endif /* _FSL_ESAI_DAI_H */
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 5d38a6749b9f..cdd3fa830704 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -62,26 +62,25 @@ static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
62 reg_cr2 = FSL_SAI_RCR2; 62 reg_cr2 = FSL_SAI_RCR2;
63 63
64 val_cr2 = sai_readl(sai, sai->base + reg_cr2); 64 val_cr2 = sai_readl(sai, sai->base + reg_cr2);
65 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
66
65 switch (clk_id) { 67 switch (clk_id) {
66 case FSL_SAI_CLK_BUS: 68 case FSL_SAI_CLK_BUS:
67 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
68 val_cr2 |= FSL_SAI_CR2_MSEL_BUS; 69 val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
69 break; 70 break;
70 case FSL_SAI_CLK_MAST1: 71 case FSL_SAI_CLK_MAST1:
71 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
72 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1; 72 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
73 break; 73 break;
74 case FSL_SAI_CLK_MAST2: 74 case FSL_SAI_CLK_MAST2:
75 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
76 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2; 75 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
77 break; 76 break;
78 case FSL_SAI_CLK_MAST3: 77 case FSL_SAI_CLK_MAST3:
79 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
80 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3; 78 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
81 break; 79 break;
82 default: 80 default:
83 return -EINVAL; 81 return -EINVAL;
84 } 82 }
83
85 sai_writel(sai, val_cr2, sai->base + reg_cr2); 84 sai_writel(sai, val_cr2, sai->base + reg_cr2);
86 85
87 return 0; 86 return 0;
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 76e56b39db01..f9090b167ad7 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,6 +35,7 @@
35#include <linux/module.h> 35#include <linux/module.h>
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/clk.h> 37#include <linux/clk.h>
38#include <linux/debugfs.h>
38#include <linux/device.h> 39#include <linux/device.h>
39#include <linux/delay.h> 40#include <linux/delay.h>
40#include <linux/slab.h> 41#include <linux/slab.h>
@@ -106,12 +107,33 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
106 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE) 107 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
107#endif 108#endif
108 109
109/* SIER bitflag of interrupts to enable */ 110#define FSLSSI_SIER_DBG_RX_FLAGS (CCSR_SSI_SIER_RFF0_EN | \
110#define SIER_FLAGS (CCSR_SSI_SIER_TFRC_EN | CCSR_SSI_SIER_TDMAE | \ 111 CCSR_SSI_SIER_RLS_EN | CCSR_SSI_SIER_RFS_EN | \
111 CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TUE0_EN | \ 112 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_RFRC_EN)
112 CCSR_SSI_SIER_TUE1_EN | CCSR_SSI_SIER_RFRC_EN | \ 113#define FSLSSI_SIER_DBG_TX_FLAGS (CCSR_SSI_SIER_TFE0_EN | \
113 CCSR_SSI_SIER_RDMAE | CCSR_SSI_SIER_RIE | \ 114 CCSR_SSI_SIER_TLS_EN | CCSR_SSI_SIER_TFS_EN | \
114 CCSR_SSI_SIER_ROE0_EN | CCSR_SSI_SIER_ROE1_EN) 115 CCSR_SSI_SIER_TUE0_EN | CCSR_SSI_SIER_TFRC_EN)
116#define FSLSSI_SISR_MASK (FSLSSI_SIER_DBG_RX_FLAGS | FSLSSI_SIER_DBG_TX_FLAGS)
117
118
119enum fsl_ssi_type {
120 FSL_SSI_MCP8610,
121 FSL_SSI_MX21,
122 FSL_SSI_MX35,
123 FSL_SSI_MX51,
124};
125
126struct fsl_ssi_reg_val {
127 u32 sier;
128 u32 srcr;
129 u32 stcr;
130 u32 scr;
131};
132
133struct fsl_ssi_rxtx_reg_val {
134 struct fsl_ssi_reg_val rx;
135 struct fsl_ssi_reg_val tx;
136};
115 137
116/** 138/**
117 * fsl_ssi_private: per-SSI private data 139 * fsl_ssi_private: per-SSI private data
@@ -132,14 +154,16 @@ struct fsl_ssi_private {
132 unsigned int irq; 154 unsigned int irq;
133 unsigned int fifo_depth; 155 unsigned int fifo_depth;
134 struct snd_soc_dai_driver cpu_dai_drv; 156 struct snd_soc_dai_driver cpu_dai_drv;
135 struct device_attribute dev_attr;
136 struct platform_device *pdev; 157 struct platform_device *pdev;
137 158
159 enum fsl_ssi_type hw_type;
138 bool new_binding; 160 bool new_binding;
139 bool ssi_on_imx; 161 bool ssi_on_imx;
140 bool imx_ac97; 162 bool imx_ac97;
141 bool use_dma; 163 bool use_dma;
142 bool baudclk_locked; 164 bool baudclk_locked;
165 bool irq_stats;
166 bool offline_config;
143 u8 i2s_mode; 167 u8 i2s_mode;
144 spinlock_t baudclk_lock; 168 spinlock_t baudclk_lock;
145 struct clk *baudclk; 169 struct clk *baudclk;
@@ -149,6 +173,8 @@ struct fsl_ssi_private {
149 struct imx_dma_data filter_data_tx; 173 struct imx_dma_data filter_data_tx;
150 struct imx_dma_data filter_data_rx; 174 struct imx_dma_data filter_data_rx;
151 struct imx_pcm_fiq_params fiq_params; 175 struct imx_pcm_fiq_params fiq_params;
176 /* Register values for rx/tx configuration */
177 struct fsl_ssi_rxtx_reg_val rxtx_reg_val;
152 178
153 struct { 179 struct {
154 unsigned int rfrc; 180 unsigned int rfrc;
@@ -173,10 +199,21 @@ struct fsl_ssi_private {
173 unsigned int tfe1; 199 unsigned int tfe1;
174 unsigned int tfe0; 200 unsigned int tfe0;
175 } stats; 201 } stats;
202 struct dentry *dbg_dir;
203 struct dentry *dbg_stats;
176 204
177 char name[1]; 205 char name[1];
178}; 206};
179 207
208static const struct of_device_id fsl_ssi_ids[] = {
209 { .compatible = "fsl,mpc8610-ssi", .data = (void *) FSL_SSI_MCP8610},
210 { .compatible = "fsl,imx51-ssi", .data = (void *) FSL_SSI_MX51},
211 { .compatible = "fsl,imx35-ssi", .data = (void *) FSL_SSI_MX35},
212 { .compatible = "fsl,imx21-ssi", .data = (void *) FSL_SSI_MX21},
213 {}
214};
215MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
216
180/** 217/**
181 * fsl_ssi_isr: SSI interrupt handler 218 * fsl_ssi_isr: SSI interrupt handler
182 * 219 *
@@ -195,23 +232,40 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
195 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 232 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
196 irqreturn_t ret = IRQ_NONE; 233 irqreturn_t ret = IRQ_NONE;
197 __be32 sisr; 234 __be32 sisr;
198 __be32 sisr2 = 0; 235 __be32 sisr2;
236 __be32 sisr_write_mask = 0;
237
238 switch (ssi_private->hw_type) {
239 case FSL_SSI_MX21:
240 sisr_write_mask = 0;
241 break;
242
243 case FSL_SSI_MCP8610:
244 case FSL_SSI_MX35:
245 sisr_write_mask = CCSR_SSI_SISR_RFRC | CCSR_SSI_SISR_TFRC |
246 CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
247 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
248 break;
249
250 case FSL_SSI_MX51:
251 sisr_write_mask = CCSR_SSI_SISR_ROE0 | CCSR_SSI_SISR_ROE1 |
252 CCSR_SSI_SISR_TUE0 | CCSR_SSI_SISR_TUE1;
253 break;
254 }
199 255
200 /* We got an interrupt, so read the status register to see what we 256 /* We got an interrupt, so read the status register to see what we
201 were interrupted for. We mask it with the Interrupt Enable register 257 were interrupted for. We mask it with the Interrupt Enable register
202 so that we only check for events that we're interested in. 258 so that we only check for events that we're interested in.
203 */ 259 */
204 sisr = read_ssi(&ssi->sisr) & SIER_FLAGS; 260 sisr = read_ssi(&ssi->sisr) & FSLSSI_SISR_MASK;
205 261
206 if (sisr & CCSR_SSI_SISR_RFRC) { 262 if (sisr & CCSR_SSI_SISR_RFRC) {
207 ssi_private->stats.rfrc++; 263 ssi_private->stats.rfrc++;
208 sisr2 |= CCSR_SSI_SISR_RFRC;
209 ret = IRQ_HANDLED; 264 ret = IRQ_HANDLED;
210 } 265 }
211 266
212 if (sisr & CCSR_SSI_SISR_TFRC) { 267 if (sisr & CCSR_SSI_SISR_TFRC) {
213 ssi_private->stats.tfrc++; 268 ssi_private->stats.tfrc++;
214 sisr2 |= CCSR_SSI_SISR_TFRC;
215 ret = IRQ_HANDLED; 269 ret = IRQ_HANDLED;
216 } 270 }
217 271
@@ -252,25 +306,21 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
252 306
253 if (sisr & CCSR_SSI_SISR_ROE1) { 307 if (sisr & CCSR_SSI_SISR_ROE1) {
254 ssi_private->stats.roe1++; 308 ssi_private->stats.roe1++;
255 sisr2 |= CCSR_SSI_SISR_ROE1;
256 ret = IRQ_HANDLED; 309 ret = IRQ_HANDLED;
257 } 310 }
258 311
259 if (sisr & CCSR_SSI_SISR_ROE0) { 312 if (sisr & CCSR_SSI_SISR_ROE0) {
260 ssi_private->stats.roe0++; 313 ssi_private->stats.roe0++;
261 sisr2 |= CCSR_SSI_SISR_ROE0;
262 ret = IRQ_HANDLED; 314 ret = IRQ_HANDLED;
263 } 315 }
264 316
265 if (sisr & CCSR_SSI_SISR_TUE1) { 317 if (sisr & CCSR_SSI_SISR_TUE1) {
266 ssi_private->stats.tue1++; 318 ssi_private->stats.tue1++;
267 sisr2 |= CCSR_SSI_SISR_TUE1;
268 ret = IRQ_HANDLED; 319 ret = IRQ_HANDLED;
269 } 320 }
270 321
271 if (sisr & CCSR_SSI_SISR_TUE0) { 322 if (sisr & CCSR_SSI_SISR_TUE0) {
272 ssi_private->stats.tue0++; 323 ssi_private->stats.tue0++;
273 sisr2 |= CCSR_SSI_SISR_TUE0;
274 ret = IRQ_HANDLED; 324 ret = IRQ_HANDLED;
275 } 325 }
276 326
@@ -314,6 +364,7 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
314 ret = IRQ_HANDLED; 364 ret = IRQ_HANDLED;
315 } 365 }
316 366
367 sisr2 = sisr & sisr_write_mask;
317 /* Clear the bits that we set */ 368 /* Clear the bits that we set */
318 if (sisr2) 369 if (sisr2)
319 write_ssi(sisr2, &ssi->sisr); 370 write_ssi(sisr2, &ssi->sisr);
@@ -321,6 +372,245 @@ static irqreturn_t fsl_ssi_isr(int irq, void *dev_id)
321 return ret; 372 return ret;
322} 373}
323 374
375#if IS_ENABLED(CONFIG_DEBUG_FS)
376/* Show the statistics of a flag only if its interrupt is enabled. The
377 * compiler will optimze this code to a no-op if the interrupt is not
378 * enabled.
379 */
380#define SIER_SHOW(flag, name) \
381 do { \
382 if (FSLSSI_SISR_MASK & CCSR_SSI_SIER_##flag) \
383 seq_printf(s, #name "=%u\n", ssi_private->stats.name); \
384 } while (0)
385
386
387/**
388 * fsl_sysfs_ssi_show: display SSI statistics
389 *
390 * Display the statistics for the current SSI device. To avoid confusion,
391 * we only show those counts that are enabled.
392 */
393static int fsl_ssi_stats_show(struct seq_file *s, void *unused)
394{
395 struct fsl_ssi_private *ssi_private = s->private;
396
397 SIER_SHOW(RFRC_EN, rfrc);
398 SIER_SHOW(TFRC_EN, tfrc);
399 SIER_SHOW(CMDAU_EN, cmdau);
400 SIER_SHOW(CMDDU_EN, cmddu);
401 SIER_SHOW(RXT_EN, rxt);
402 SIER_SHOW(RDR1_EN, rdr1);
403 SIER_SHOW(RDR0_EN, rdr0);
404 SIER_SHOW(TDE1_EN, tde1);
405 SIER_SHOW(TDE0_EN, tde0);
406 SIER_SHOW(ROE1_EN, roe1);
407 SIER_SHOW(ROE0_EN, roe0);
408 SIER_SHOW(TUE1_EN, tue1);
409 SIER_SHOW(TUE0_EN, tue0);
410 SIER_SHOW(TFS_EN, tfs);
411 SIER_SHOW(RFS_EN, rfs);
412 SIER_SHOW(TLS_EN, tls);
413 SIER_SHOW(RLS_EN, rls);
414 SIER_SHOW(RFF1_EN, rff1);
415 SIER_SHOW(RFF0_EN, rff0);
416 SIER_SHOW(TFE1_EN, tfe1);
417 SIER_SHOW(TFE0_EN, tfe0);
418
419 return 0;
420}
421
422static int fsl_ssi_stats_open(struct inode *inode, struct file *file)
423{
424 return single_open(file, fsl_ssi_stats_show, inode->i_private);
425}
426
427static const struct file_operations fsl_ssi_stats_ops = {
428 .open = fsl_ssi_stats_open,
429 .read = seq_read,
430 .llseek = seq_lseek,
431 .release = single_release,
432};
433
434static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
435 struct device *dev)
436{
437 ssi_private->dbg_dir = debugfs_create_dir(dev_name(dev), NULL);
438 if (!ssi_private->dbg_dir)
439 return -ENOMEM;
440
441 ssi_private->dbg_stats = debugfs_create_file("stats", S_IRUGO,
442 ssi_private->dbg_dir, ssi_private, &fsl_ssi_stats_ops);
443 if (!ssi_private->dbg_stats) {
444 debugfs_remove(ssi_private->dbg_dir);
445 return -ENOMEM;
446 }
447
448 return 0;
449}
450
451static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
452{
453 debugfs_remove(ssi_private->dbg_stats);
454 debugfs_remove(ssi_private->dbg_dir);
455}
456
457#else
458
459static int fsl_ssi_debugfs_create(struct fsl_ssi_private *ssi_private,
460 struct device *dev)
461{
462 return 0;
463}
464
465static void fsl_ssi_debugfs_remove(struct fsl_ssi_private *ssi_private)
466{
467}
468
469#endif /* IS_ENABLED(CONFIG_DEBUG_FS) */
470
471/*
472 * Enable/Disable all rx/tx config flags at once.
473 */
474static void fsl_ssi_rxtx_config(struct fsl_ssi_private *ssi_private,
475 bool enable)
476{
477 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
478 struct fsl_ssi_rxtx_reg_val *vals = &ssi_private->rxtx_reg_val;
479
480 if (enable) {
481 write_ssi_mask(&ssi->sier, 0, vals->rx.sier | vals->tx.sier);
482 write_ssi_mask(&ssi->srcr, 0, vals->rx.srcr | vals->tx.srcr);
483 write_ssi_mask(&ssi->stcr, 0, vals->rx.stcr | vals->tx.stcr);
484 } else {
485 write_ssi_mask(&ssi->srcr, vals->rx.srcr | vals->tx.srcr, 0);
486 write_ssi_mask(&ssi->stcr, vals->rx.stcr | vals->tx.stcr, 0);
487 write_ssi_mask(&ssi->sier, vals->rx.sier | vals->tx.sier, 0);
488 }
489}
490
491/*
492 * Enable/Disable a ssi configuration. You have to pass either
493 * ssi_private->rxtx_reg_val.rx or tx as vals parameter.
494 */
495static void fsl_ssi_config(struct fsl_ssi_private *ssi_private, bool enable,
496 struct fsl_ssi_reg_val *vals)
497{
498 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
499 struct fsl_ssi_reg_val *avals;
500 u32 scr_val = read_ssi(&ssi->scr);
501 int nr_active_streams = !!(scr_val & CCSR_SSI_SCR_TE) +
502 !!(scr_val & CCSR_SSI_SCR_RE);
503
504 /* Find the other direction values rx or tx which we do not want to
505 * modify */
506 if (&ssi_private->rxtx_reg_val.rx == vals)
507 avals = &ssi_private->rxtx_reg_val.tx;
508 else
509 avals = &ssi_private->rxtx_reg_val.rx;
510
511 /* If vals should be disabled, start with disabling the unit */
512 if (!enable) {
513 u32 scr = vals->scr & (vals->scr ^ avals->scr);
514 write_ssi_mask(&ssi->scr, scr, 0);
515 }
516
517 /*
518 * We are running on a SoC which does not support online SSI
519 * reconfiguration, so we have to enable all necessary flags at once
520 * even if we do not use them later (capture and playback configuration)
521 */
522 if (ssi_private->offline_config) {
523 if ((enable && !nr_active_streams) ||
524 (!enable && nr_active_streams == 1))
525 fsl_ssi_rxtx_config(ssi_private, enable);
526
527 goto config_done;
528 }
529
530 /*
531 * Configure single direction units while the SSI unit is running
532 * (online configuration)
533 */
534 if (enable) {
535 write_ssi_mask(&ssi->sier, 0, vals->sier);
536 write_ssi_mask(&ssi->srcr, 0, vals->srcr);
537 write_ssi_mask(&ssi->stcr, 0, vals->stcr);
538 } else {
539 u32 sier;
540 u32 srcr;
541 u32 stcr;
542
543 /*
544 * Disabling the necessary flags for one of rx/tx while the
545 * other stream is active is a little bit more difficult. We
546 * have to disable only those flags that differ between both
547 * streams (rx XOR tx) and that are set in the stream that is
548 * disabled now. Otherwise we could alter flags of the other
549 * stream
550 */
551
552 /* These assignments are simply vals without bits set in avals*/
553 sier = vals->sier & (vals->sier ^ avals->sier);
554 srcr = vals->srcr & (vals->srcr ^ avals->srcr);
555 stcr = vals->stcr & (vals->stcr ^ avals->stcr);
556
557 write_ssi_mask(&ssi->srcr, srcr, 0);
558 write_ssi_mask(&ssi->stcr, stcr, 0);
559 write_ssi_mask(&ssi->sier, sier, 0);
560 }
561
562config_done:
563 /* Enabling of subunits is done after configuration */
564 if (enable)
565 write_ssi_mask(&ssi->scr, 0, vals->scr);
566}
567
568
569static void fsl_ssi_rx_config(struct fsl_ssi_private *ssi_private, bool enable)
570{
571 fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.rx);
572}
573
574static void fsl_ssi_tx_config(struct fsl_ssi_private *ssi_private, bool enable)
575{
576 fsl_ssi_config(ssi_private, enable, &ssi_private->rxtx_reg_val.tx);
577}
578
579/*
580 * Setup rx/tx register values used to enable/disable the streams. These will
581 * be used later in fsl_ssi_config to setup the streams without the need to
582 * check for all different SSI modes.
583 */
584static void fsl_ssi_setup_reg_vals(struct fsl_ssi_private *ssi_private)
585{
586 struct fsl_ssi_rxtx_reg_val *reg = &ssi_private->rxtx_reg_val;
587
588 reg->rx.sier = CCSR_SSI_SIER_RFF0_EN;
589 reg->rx.srcr = CCSR_SSI_SRCR_RFEN0;
590 reg->rx.scr = 0;
591 reg->tx.sier = CCSR_SSI_SIER_TFE0_EN;
592 reg->tx.stcr = CCSR_SSI_STCR_TFEN0;
593 reg->tx.scr = 0;
594
595 if (!ssi_private->imx_ac97) {
596 reg->rx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE;
597 reg->rx.sier |= CCSR_SSI_SIER_RFF0_EN;
598 reg->tx.scr = CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE;
599 reg->tx.sier |= CCSR_SSI_SIER_TFE0_EN;
600 }
601
602 if (ssi_private->use_dma) {
603 reg->rx.sier |= CCSR_SSI_SIER_RDMAE;
604 reg->tx.sier |= CCSR_SSI_SIER_TDMAE;
605 } else {
606 reg->rx.sier |= CCSR_SSI_SIER_RIE;
607 reg->tx.sier |= CCSR_SSI_SIER_TIE;
608 }
609
610 reg->rx.sier |= FSLSSI_SIER_DBG_RX_FLAGS;
611 reg->tx.sier |= FSLSSI_SIER_DBG_TX_FLAGS;
612}
613
324static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private) 614static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
325{ 615{
326 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 616 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
@@ -357,6 +647,8 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
357 u8 wm; 647 u8 wm;
358 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; 648 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
359 649
650 fsl_ssi_setup_reg_vals(ssi_private);
651
360 if (ssi_private->imx_ac97) 652 if (ssi_private->imx_ac97)
361 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET; 653 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_NORMAL | CCSR_SSI_SCR_NET;
362 else 654 else
@@ -380,13 +672,12 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
380 ssi_private->i2s_mode | 672 ssi_private->i2s_mode |
381 (synchronous ? CCSR_SSI_SCR_SYN : 0)); 673 (synchronous ? CCSR_SSI_SCR_SYN : 0));
382 674
383 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 675 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI |
384 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 676 CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr);
385 CCSR_SSI_STCR_TSCKP, &ssi->stcr); 677
678 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFSI |
679 CCSR_SSI_SRCR_REFS | CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
386 680
387 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
388 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
389 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
390 /* 681 /*
391 * The DC and PM bits are only used if the SSI is the clock master. 682 * The DC and PM bits are only used if the SSI is the clock master.
392 */ 683 */
@@ -419,6 +710,17 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
419 if (ssi_private->imx_ac97) 710 if (ssi_private->imx_ac97)
420 fsl_ssi_setup_ac97(ssi_private); 711 fsl_ssi_setup_ac97(ssi_private);
421 712
713 /*
714 * Set a default slot number so that there is no need for those common
715 * cases like I2S mode to call the extra set_tdm_slot() any more.
716 */
717 if (!ssi_private->imx_ac97) {
718 write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
719 CCSR_SSI_SxCCR_DC(2));
720 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
721 CCSR_SSI_SxCCR_DC(2));
722 }
723
422 return 0; 724 return 0;
423} 725}
424 726
@@ -761,50 +1063,26 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
761 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1063 struct snd_soc_pcm_runtime *rtd = substream->private_data;
762 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai); 1064 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
763 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 1065 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
764 unsigned int sier_bits;
765 unsigned long flags; 1066 unsigned long flags;
766 1067
767 /*
768 * Enable only the interrupts and DMA requests
769 * that are needed for the channel. As the fiq
770 * is polling for this bits, we have to ensure
771 * that this are aligned with the preallocated
772 * buffers
773 */
774
775 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
776 if (ssi_private->use_dma)
777 sier_bits = SIER_FLAGS;
778 else
779 sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN;
780 } else {
781 if (ssi_private->use_dma)
782 sier_bits = SIER_FLAGS;
783 else
784 sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN;
785 }
786
787 switch (cmd) { 1068 switch (cmd) {
788 case SNDRV_PCM_TRIGGER_START: 1069 case SNDRV_PCM_TRIGGER_START:
789 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1070 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
790 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1071 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
791 write_ssi_mask(&ssi->scr, 0, 1072 fsl_ssi_tx_config(ssi_private, true);
792 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
793 else 1073 else
794 write_ssi_mask(&ssi->scr, 0, 1074 fsl_ssi_rx_config(ssi_private, true);
795 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
796 break; 1075 break;
797 1076
798 case SNDRV_PCM_TRIGGER_STOP: 1077 case SNDRV_PCM_TRIGGER_STOP:
799 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1078 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
800 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1079 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
801 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); 1080 fsl_ssi_tx_config(ssi_private, false);
802 else 1081 else
803 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); 1082 fsl_ssi_rx_config(ssi_private, false);
804 1083
805 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & 1084 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
806 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) { 1085 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
807 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0);
808 spin_lock_irqsave(&ssi_private->baudclk_lock, flags); 1086 spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
809 ssi_private->baudclk_locked = false; 1087 ssi_private->baudclk_locked = false;
810 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags); 1088 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
@@ -815,7 +1093,12 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
815 return -EINVAL; 1093 return -EINVAL;
816 } 1094 }
817 1095
818 write_ssi(sier_bits, &ssi->sier); 1096 if (ssi_private->imx_ac97) {
1097 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1098 write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
1099 else
1100 write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
1101 }
819 1102
820 return 0; 1103 return 0;
821} 1104}
@@ -863,58 +1146,6 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
863 .name = "fsl-ssi", 1146 .name = "fsl-ssi",
864}; 1147};
865 1148
866/**
867 * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
868 *
869 * This function is called by ALSA to start, stop, pause, and resume the
870 * transfer of data.
871 */
872static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
873 struct snd_soc_dai *dai)
874{
875 struct snd_soc_pcm_runtime *rtd = substream->private_data;
876 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
877 rtd->cpu_dai);
878 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
879
880 switch (cmd) {
881 case SNDRV_PCM_TRIGGER_START:
882 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
883 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
884 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
885 CCSR_SSI_SIER_TFE0_EN);
886 else
887 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
888 CCSR_SSI_SIER_RFF0_EN);
889 break;
890
891 case SNDRV_PCM_TRIGGER_STOP:
892 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
893 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
894 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
895 CCSR_SSI_SIER_TFE0_EN, 0);
896 else
897 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
898 CCSR_SSI_SIER_RFF0_EN, 0);
899 break;
900
901 default:
902 return -EINVAL;
903 }
904
905 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
906 write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
907 else
908 write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
909
910 return 0;
911}
912
913static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
914 .startup = fsl_ssi_startup,
915 .trigger = fsl_ssi_ac97_trigger,
916};
917
918static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { 1149static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
919 .ac97_control = 1, 1150 .ac97_control = 1,
920 .playback = { 1151 .playback = {
@@ -931,7 +1162,7 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
931 .rates = SNDRV_PCM_RATE_48000, 1162 .rates = SNDRV_PCM_RATE_48000,
932 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1163 .formats = SNDRV_PCM_FMTBIT_S16_LE,
933 }, 1164 },
934 .ops = &fsl_ssi_ac97_dai_ops, 1165 .ops = &fsl_ssi_dai_ops,
935}; 1166};
936 1167
937 1168
@@ -989,56 +1220,6 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
989 .write = fsl_ssi_ac97_write, 1220 .write = fsl_ssi_ac97_write,
990}; 1221};
991 1222
992/* Show the statistics of a flag only if its interrupt is enabled. The
993 * compiler will optimze this code to a no-op if the interrupt is not
994 * enabled.
995 */
996#define SIER_SHOW(flag, name) \
997 do { \
998 if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
999 length += sprintf(buf + length, #name "=%u\n", \
1000 ssi_private->stats.name); \
1001 } while (0)
1002
1003
1004/**
1005 * fsl_sysfs_ssi_show: display SSI statistics
1006 *
1007 * Display the statistics for the current SSI device. To avoid confusion,
1008 * we only show those counts that are enabled.
1009 */
1010static ssize_t fsl_sysfs_ssi_show(struct device *dev,
1011 struct device_attribute *attr, char *buf)
1012{
1013 struct fsl_ssi_private *ssi_private =
1014 container_of(attr, struct fsl_ssi_private, dev_attr);
1015 ssize_t length = 0;
1016
1017 SIER_SHOW(RFRC_EN, rfrc);
1018 SIER_SHOW(TFRC_EN, tfrc);
1019 SIER_SHOW(CMDAU_EN, cmdau);
1020 SIER_SHOW(CMDDU_EN, cmddu);
1021 SIER_SHOW(RXT_EN, rxt);
1022 SIER_SHOW(RDR1_EN, rdr1);
1023 SIER_SHOW(RDR0_EN, rdr0);
1024 SIER_SHOW(TDE1_EN, tde1);
1025 SIER_SHOW(TDE0_EN, tde0);
1026 SIER_SHOW(ROE1_EN, roe1);
1027 SIER_SHOW(ROE0_EN, roe0);
1028 SIER_SHOW(TUE1_EN, tue1);
1029 SIER_SHOW(TUE0_EN, tue0);
1030 SIER_SHOW(TFS_EN, tfs);
1031 SIER_SHOW(RFS_EN, rfs);
1032 SIER_SHOW(TLS_EN, tls);
1033 SIER_SHOW(RLS_EN, rls);
1034 SIER_SHOW(RFF1_EN, rff1);
1035 SIER_SHOW(RFF0_EN, rff0);
1036 SIER_SHOW(TFE1_EN, tfe1);
1037 SIER_SHOW(TFE0_EN, tfe0);
1038
1039 return length;
1040}
1041
1042/** 1223/**
1043 * Make every character in a string lower-case 1224 * Make every character in a string lower-case
1044 */ 1225 */
@@ -1060,6 +1241,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1060 int ret = 0; 1241 int ret = 0;
1061 struct device_attribute *dev_attr = NULL; 1242 struct device_attribute *dev_attr = NULL;
1062 struct device_node *np = pdev->dev.of_node; 1243 struct device_node *np = pdev->dev.of_node;
1244 const struct of_device_id *of_id;
1245 enum fsl_ssi_type hw_type;
1063 const char *p, *sprop; 1246 const char *p, *sprop;
1064 const uint32_t *iprop; 1247 const uint32_t *iprop;
1065 struct resource res; 1248 struct resource res;
@@ -1074,6 +1257,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1074 if (!of_device_is_available(np)) 1257 if (!of_device_is_available(np))
1075 return -ENODEV; 1258 return -ENODEV;
1076 1259
1260 of_id = of_match_device(fsl_ssi_ids, &pdev->dev);
1261 if (!of_id)
1262 return -EINVAL;
1263 hw_type = (enum fsl_ssi_type) of_id->data;
1264
1077 /* We only support the SSI in "I2S Slave" mode */ 1265 /* We only support the SSI in "I2S Slave" mode */
1078 sprop = of_get_property(np, "fsl,mode", NULL); 1266 sprop = of_get_property(np, "fsl,mode", NULL);
1079 if (!sprop) { 1267 if (!sprop) {
@@ -1100,6 +1288,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1100 1288
1101 ssi_private->use_dma = !of_property_read_bool(np, 1289 ssi_private->use_dma = !of_property_read_bool(np,
1102 "fsl,fiq-stream-filter"); 1290 "fsl,fiq-stream-filter");
1291 ssi_private->hw_type = hw_type;
1103 1292
1104 if (ac97) { 1293 if (ac97) {
1105 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, 1294 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
@@ -1153,7 +1342,34 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1153 ssi_private->baudclk_locked = false; 1342 ssi_private->baudclk_locked = false;
1154 spin_lock_init(&ssi_private->baudclk_lock); 1343 spin_lock_init(&ssi_private->baudclk_lock);
1155 1344
1156 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { 1345 /*
1346 * imx51 and later SoCs have a slightly different IP that allows the
1347 * SSI configuration while the SSI unit is running.
1348 *
1349 * More important, it is necessary on those SoCs to configure the
1350 * sperate TX/RX DMA bits just before starting the stream
1351 * (fsl_ssi_trigger). The SDMA unit has to be configured before fsl_ssi
1352 * sends any DMA requests to the SDMA unit, otherwise it is not defined
1353 * how the SDMA unit handles the DMA request.
1354 *
1355 * SDMA units are present on devices starting at imx35 but the imx35
1356 * reference manual states that the DMA bits should not be changed
1357 * while the SSI unit is running (SSIEN). So we support the necessary
1358 * online configuration of fsl-ssi starting at imx51.
1359 */
1360 switch (hw_type) {
1361 case FSL_SSI_MCP8610:
1362 case FSL_SSI_MX21:
1363 case FSL_SSI_MX35:
1364 ssi_private->offline_config = true;
1365 break;
1366 case FSL_SSI_MX51:
1367 ssi_private->offline_config = false;
1368 break;
1369 }
1370
1371 if (hw_type == FSL_SSI_MX21 || hw_type == FSL_SSI_MX51 ||
1372 hw_type == FSL_SSI_MX35) {
1157 u32 dma_events[2]; 1373 u32 dma_events[2];
1158 ssi_private->ssi_on_imx = true; 1374 ssi_private->ssi_on_imx = true;
1159 1375
@@ -1175,7 +1391,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1175 */ 1391 */
1176 ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud"); 1392 ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
1177 if (IS_ERR(ssi_private->baudclk)) 1393 if (IS_ERR(ssi_private->baudclk))
1178 dev_warn(&pdev->dev, "could not get baud clock: %d\n", ret); 1394 dev_warn(&pdev->dev, "could not get baud clock: %ld\n",
1395 PTR_ERR(ssi_private->baudclk));
1179 else 1396 else
1180 clk_prepare_enable(ssi_private->baudclk); 1397 clk_prepare_enable(ssi_private->baudclk);
1181 1398
@@ -1217,32 +1434,25 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1217 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); 1434 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1218 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, 1435 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
1219 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); 1436 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1220 } else if (ssi_private->use_dma) { 1437 }
1438
1439 /*
1440 * Enable interrupts only for MCP8610 and MX51. The other MXs have
1441 * different writeable interrupt status registers.
1442 */
1443 if (ssi_private->use_dma) {
1221 /* The 'name' should not have any slashes in it. */ 1444 /* The 'name' should not have any slashes in it. */
1222 ret = devm_request_irq(&pdev->dev, ssi_private->irq, 1445 ret = devm_request_irq(&pdev->dev, ssi_private->irq,
1223 fsl_ssi_isr, 0, ssi_private->name, 1446 fsl_ssi_isr, 0, ssi_private->name,
1224 ssi_private); 1447 ssi_private);
1448 ssi_private->irq_stats = true;
1225 if (ret < 0) { 1449 if (ret < 0) {
1226 dev_err(&pdev->dev, "could not claim irq %u\n", 1450 dev_err(&pdev->dev, "could not claim irq %u\n",
1227 ssi_private->irq); 1451 ssi_private->irq);
1228 goto error_irqmap; 1452 goto error_clk;
1229 } 1453 }
1230 } 1454 }
1231 1455
1232 /* Initialize the the device_attribute structure */
1233 dev_attr = &ssi_private->dev_attr;
1234 sysfs_attr_init(&dev_attr->attr);
1235 dev_attr->attr.name = "statistics";
1236 dev_attr->attr.mode = S_IRUGO;
1237 dev_attr->show = fsl_sysfs_ssi_show;
1238
1239 ret = device_create_file(&pdev->dev, dev_attr);
1240 if (ret) {
1241 dev_err(&pdev->dev, "could not create sysfs %s file\n",
1242 ssi_private->dev_attr.attr.name);
1243 goto error_clk;
1244 }
1245
1246 /* Register with ASoC */ 1456 /* Register with ASoC */
1247 dev_set_drvdata(&pdev->dev, ssi_private); 1457 dev_set_drvdata(&pdev->dev, ssi_private);
1248 1458
@@ -1253,6 +1463,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1253 goto error_dev; 1463 goto error_dev;
1254 } 1464 }
1255 1465
1466 ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev);
1467 if (ret)
1468 goto error_dbgfs;
1469
1256 if (ssi_private->ssi_on_imx) { 1470 if (ssi_private->ssi_on_imx) {
1257 if (!ssi_private->use_dma) { 1471 if (!ssi_private->use_dma) {
1258 1472
@@ -1272,11 +1486,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1272 1486
1273 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); 1487 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
1274 if (ret) 1488 if (ret)
1275 goto error_dev; 1489 goto error_pcm;
1276 } else { 1490 } else {
1277 ret = imx_pcm_dma_init(pdev); 1491 ret = imx_pcm_dma_init(pdev);
1278 if (ret) 1492 if (ret)
1279 goto error_dev; 1493 goto error_pcm;
1280 } 1494 }
1281 } 1495 }
1282 1496
@@ -1318,6 +1532,13 @@ done:
1318 return 0; 1532 return 0;
1319 1533
1320error_dai: 1534error_dai:
1535 if (ssi_private->ssi_on_imx && !ssi_private->use_dma)
1536 imx_pcm_fiq_exit(pdev);
1537
1538error_pcm:
1539 fsl_ssi_debugfs_remove(ssi_private);
1540
1541error_dbgfs:
1321 snd_soc_unregister_component(&pdev->dev); 1542 snd_soc_unregister_component(&pdev->dev);
1322 1543
1323error_dev: 1544error_dev:
@@ -1331,7 +1552,8 @@ error_clk:
1331 } 1552 }
1332 1553
1333error_irqmap: 1554error_irqmap:
1334 irq_dispose_mapping(ssi_private->irq); 1555 if (ssi_private->irq_stats)
1556 irq_dispose_mapping(ssi_private->irq);
1335 1557
1336 return ret; 1558 return ret;
1337} 1559}
@@ -1340,27 +1562,22 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1340{ 1562{
1341 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); 1563 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
1342 1564
1565 fsl_ssi_debugfs_remove(ssi_private);
1566
1343 if (!ssi_private->new_binding) 1567 if (!ssi_private->new_binding)
1344 platform_device_unregister(ssi_private->pdev); 1568 platform_device_unregister(ssi_private->pdev);
1345 snd_soc_unregister_component(&pdev->dev); 1569 snd_soc_unregister_component(&pdev->dev);
1346 device_remove_file(&pdev->dev, &ssi_private->dev_attr);
1347 if (ssi_private->ssi_on_imx) { 1570 if (ssi_private->ssi_on_imx) {
1348 if (!IS_ERR(ssi_private->baudclk)) 1571 if (!IS_ERR(ssi_private->baudclk))
1349 clk_disable_unprepare(ssi_private->baudclk); 1572 clk_disable_unprepare(ssi_private->baudclk);
1350 clk_disable_unprepare(ssi_private->clk); 1573 clk_disable_unprepare(ssi_private->clk);
1351 } 1574 }
1352 irq_dispose_mapping(ssi_private->irq); 1575 if (ssi_private->irq_stats)
1576 irq_dispose_mapping(ssi_private->irq);
1353 1577
1354 return 0; 1578 return 0;
1355} 1579}
1356 1580
1357static const struct of_device_id fsl_ssi_ids[] = {
1358 { .compatible = "fsl,mpc8610-ssi", },
1359 { .compatible = "fsl,imx21-ssi", },
1360 {}
1361};
1362MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
1363
1364static struct platform_driver fsl_ssi_driver = { 1581static struct platform_driver fsl_ssi_driver = {
1365 .driver = { 1582 .driver = {
1366 .name = "fsl-ssi-dai", 1583 .name = "fsl-ssi-dai",
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index c5e47f866b4b..2585ae44e634 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -41,9 +41,6 @@ static const struct snd_pcm_hardware imx_pcm_hardware = {
41 SNDRV_PCM_INFO_PAUSE | 41 SNDRV_PCM_INFO_PAUSE |
42 SNDRV_PCM_INFO_RESUME, 42 SNDRV_PCM_INFO_RESUME,
43 .formats = SNDRV_PCM_FMTBIT_S16_LE, 43 .formats = SNDRV_PCM_FMTBIT_S16_LE,
44 .rate_min = 8000,
45 .channels_min = 2,
46 .channels_max = 2,
47 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, 44 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
48 .period_bytes_min = 128, 45 .period_bytes_min = 128,
49 .period_bytes_max = 65535, /* Limited by SDMA engine */ 46 .period_bytes_max = 65535, /* Limited by SDMA engine */
diff --git a/sound/soc/fsl/imx-pcm-fiq.c b/sound/soc/fsl/imx-pcm-fiq.c
index c75d43bb2e92..6553202dd48c 100644
--- a/sound/soc/fsl/imx-pcm-fiq.c
+++ b/sound/soc/fsl/imx-pcm-fiq.c
@@ -162,9 +162,6 @@ static struct snd_pcm_hardware snd_imx_hardware = {
162 SNDRV_PCM_INFO_PAUSE | 162 SNDRV_PCM_INFO_PAUSE |
163 SNDRV_PCM_INFO_RESUME, 163 SNDRV_PCM_INFO_RESUME,
164 .formats = SNDRV_PCM_FMTBIT_S16_LE, 164 .formats = SNDRV_PCM_FMTBIT_S16_LE,
165 .rate_min = 8000,
166 .channels_min = 2,
167 .channels_max = 2,
168 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, 165 .buffer_bytes_max = IMX_SSI_DMABUF_SIZE,
169 .period_bytes_min = 128, 166 .period_bytes_min = 128,
170 .period_bytes_max = 16 * 1024, 167 .period_bytes_max = 16 * 1024,
diff --git a/sound/soc/fsl/mpc5200_dma.c b/sound/soc/fsl/mpc5200_dma.c
index 71bf2f248cd4..f2b5d756b1f3 100644
--- a/sound/soc/fsl/mpc5200_dma.c
+++ b/sound/soc/fsl/mpc5200_dma.c
@@ -200,10 +200,6 @@ static const struct snd_pcm_hardware psc_dma_hardware = {
200 SNDRV_PCM_INFO_BATCH, 200 SNDRV_PCM_INFO_BATCH,
201 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE | 201 .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_BE |
202 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE, 202 SNDRV_PCM_FMTBIT_S24_BE | SNDRV_PCM_FMTBIT_S32_BE,
203 .rate_min = 8000,
204 .rate_max = 48000,
205 .channels_min = 1,
206 .channels_max = 2,
207 .period_bytes_max = 1024 * 1024, 203 .period_bytes_max = 1024 * 1024,
208 .period_bytes_min = 32, 204 .period_bytes_min = 32,
209 .periods_min = 2, 205 .periods_min = 2,