aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/fsl
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/fsl')
-rw-r--r--sound/soc/fsl/Kconfig8
-rw-r--r--sound/soc/fsl/Makefile6
-rw-r--r--sound/soc/fsl/fsl_dma.c9
-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.c459
-rw-r--r--sound/soc/fsl/fsl_sai.h114
-rw-r--r--sound/soc/fsl/fsl_spdif.c8
-rw-r--r--sound/soc/fsl/fsl_ssi.c1015
-rw-r--r--sound/soc/fsl/fsl_ssi.h2
-rw-r--r--sound/soc/fsl/imx-pcm-dma.c12
-rw-r--r--sound/soc/fsl/imx-pcm-fiq.c3
-rw-r--r--sound/soc/fsl/imx-pcm.h5
-rw-r--r--sound/soc/fsl/imx-spdif.c85
-rw-r--r--sound/soc/fsl/imx-ssi.c12
-rw-r--r--sound/soc/fsl/imx-ssi.h1
-rw-r--r--sound/soc/fsl/imx-wm8962.c2
-rw-r--r--sound/soc/fsl/mpc5200_dma.c4
-rw-r--r--sound/soc/fsl/mpc5200_psc_i2s.c3
-rw-r--r--sound/soc/fsl/pcm030-audio-fabric.c3
20 files changed, 2513 insertions, 407 deletions
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index b7ab71f2ccc1..324988dea4bd 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -1,9 +1,16 @@
1config SND_SOC_FSL_SAI
2 tristate
3 select SND_SOC_GENERIC_DMAENGINE_PCM
4
1config SND_SOC_FSL_SSI 5config SND_SOC_FSL_SSI
2 tristate 6 tristate
3 7
4config SND_SOC_FSL_SPDIF 8config SND_SOC_FSL_SPDIF
5 tristate 9 tristate
6 10
11config SND_SOC_FSL_ESAI
12 tristate
13
7config SND_SOC_FSL_UTILS 14config SND_SOC_FSL_UTILS
8 tristate 15 tristate
9 16
@@ -197,7 +204,6 @@ config SND_SOC_IMX_SPDIF
197 tristate "SoC Audio support for i.MX boards with S/PDIF" 204 tristate "SoC Audio support for i.MX boards with S/PDIF"
198 select SND_SOC_IMX_PCM_DMA 205 select SND_SOC_IMX_PCM_DMA
199 select SND_SOC_FSL_SPDIF 206 select SND_SOC_FSL_SPDIF
200 select SND_SOC_SPDIF
201 select REGMAP_MMIO 207 select REGMAP_MMIO
202 help 208 help
203 SoC Audio support for i.MX boards with S/PDIF 209 SoC Audio support for i.MX boards with S/PDIF
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 8db705b0fdf9..b12ad4b9b4da 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -10,13 +10,17 @@ obj-$(CONFIG_SND_SOC_P1022_DS) += snd-soc-p1022-ds.o
10snd-soc-p1022-rdk-objs := p1022_rdk.o 10snd-soc-p1022-rdk-objs := p1022_rdk.o
11obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o 11obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
12 12
13# Freescale PowerPC SSI/DMA Platform Support 13# Freescale SSI/DMA/SAI/SPDIF Support
14snd-soc-fsl-sai-objs := fsl_sai.o
14snd-soc-fsl-ssi-objs := fsl_ssi.o 15snd-soc-fsl-ssi-objs := fsl_ssi.o
15snd-soc-fsl-spdif-objs := fsl_spdif.o 16snd-soc-fsl-spdif-objs := fsl_spdif.o
17snd-soc-fsl-esai-objs := fsl_esai.o
16snd-soc-fsl-utils-objs := fsl_utils.o 18snd-soc-fsl-utils-objs := fsl_utils.o
17snd-soc-fsl-dma-objs := fsl_dma.o 19snd-soc-fsl-dma-objs := fsl_dma.o
20obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
18obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o 21obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
19obj-$(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
20obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o 24obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
21obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o 25obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
22 26
diff --git a/sound/soc/fsl/fsl_dma.c b/sound/soc/fsl/fsl_dma.c
index fb9bb9eb5ca3..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,
@@ -852,7 +845,7 @@ static void fsl_dma_free_dma_buffers(struct snd_pcm *pcm)
852} 845}
853 846
854/** 847/**
855 * find_ssi_node -- returns the SSI node that points to his DMA channel node 848 * find_ssi_node -- returns the SSI node that points to its DMA channel node
856 * 849 *
857 * Although this DMA driver attempts to operate independently of the other 850 * Although this DMA driver attempts to operate independently of the other
858 * devices, it still needs to determine some information about the SSI device 851 * devices, it still needs to determine some information about the SSI device
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
new file mode 100644
index 000000000000..cdd3fa830704
--- /dev/null
+++ b/sound/soc/fsl/fsl_sai.c
@@ -0,0 +1,459 @@
1/*
2 * Freescale ALSA SoC Digital Audio Interface (SAI) driver.
3 *
4 * Copyright 2012-2013 Freescale Semiconductor, Inc.
5 *
6 * This program is free software, you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 2 of the License, or(at your
9 * option) any later version.
10 *
11 */
12
13#include <linux/clk.h>
14#include <linux/delay.h>
15#include <linux/dmaengine.h>
16#include <linux/module.h>
17#include <linux/of_address.h>
18#include <linux/slab.h>
19#include <sound/core.h>
20#include <sound/dmaengine_pcm.h>
21#include <sound/pcm_params.h>
22
23#include "fsl_sai.h"
24
25static inline u32 sai_readl(struct fsl_sai *sai,
26 const void __iomem *addr)
27{
28 u32 val;
29
30 val = __raw_readl(addr);
31
32 if (likely(sai->big_endian_regs))
33 val = be32_to_cpu(val);
34 else
35 val = le32_to_cpu(val);
36 rmb();
37
38 return val;
39}
40
41static inline void sai_writel(struct fsl_sai *sai,
42 u32 val, void __iomem *addr)
43{
44 wmb();
45 if (likely(sai->big_endian_regs))
46 val = cpu_to_be32(val);
47 else
48 val = cpu_to_le32(val);
49
50 __raw_writel(val, addr);
51}
52
53static int fsl_sai_set_dai_sysclk_tr(struct snd_soc_dai *cpu_dai,
54 int clk_id, unsigned int freq, int fsl_dir)
55{
56 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
57 u32 val_cr2, reg_cr2;
58
59 if (fsl_dir == FSL_FMT_TRANSMITTER)
60 reg_cr2 = FSL_SAI_TCR2;
61 else
62 reg_cr2 = FSL_SAI_RCR2;
63
64 val_cr2 = sai_readl(sai, sai->base + reg_cr2);
65 val_cr2 &= ~FSL_SAI_CR2_MSEL_MASK;
66
67 switch (clk_id) {
68 case FSL_SAI_CLK_BUS:
69 val_cr2 |= FSL_SAI_CR2_MSEL_BUS;
70 break;
71 case FSL_SAI_CLK_MAST1:
72 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK1;
73 break;
74 case FSL_SAI_CLK_MAST2:
75 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK2;
76 break;
77 case FSL_SAI_CLK_MAST3:
78 val_cr2 |= FSL_SAI_CR2_MSEL_MCLK3;
79 break;
80 default:
81 return -EINVAL;
82 }
83
84 sai_writel(sai, val_cr2, sai->base + reg_cr2);
85
86 return 0;
87}
88
89static int fsl_sai_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
90 int clk_id, unsigned int freq, int dir)
91{
92 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
93 int ret;
94
95 if (dir == SND_SOC_CLOCK_IN)
96 return 0;
97
98 ret = clk_prepare_enable(sai->clk);
99 if (ret)
100 return ret;
101
102 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
103 FSL_FMT_TRANSMITTER);
104 if (ret) {
105 dev_err(cpu_dai->dev, "Cannot set tx sysclk: %d\n", ret);
106 goto err_clk;
107 }
108
109 ret = fsl_sai_set_dai_sysclk_tr(cpu_dai, clk_id, freq,
110 FSL_FMT_RECEIVER);
111 if (ret) {
112 dev_err(cpu_dai->dev, "Cannot set rx sysclk: %d\n", ret);
113 goto err_clk;
114 }
115
116err_clk:
117 clk_disable_unprepare(sai->clk);
118
119 return ret;
120}
121
122static int fsl_sai_set_dai_fmt_tr(struct snd_soc_dai *cpu_dai,
123 unsigned int fmt, int fsl_dir)
124{
125 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
126 u32 val_cr2, val_cr4, reg_cr2, reg_cr4;
127
128 if (fsl_dir == FSL_FMT_TRANSMITTER) {
129 reg_cr2 = FSL_SAI_TCR2;
130 reg_cr4 = FSL_SAI_TCR4;
131 } else {
132 reg_cr2 = FSL_SAI_RCR2;
133 reg_cr4 = FSL_SAI_RCR4;
134 }
135
136 val_cr2 = sai_readl(sai, sai->base + reg_cr2);
137 val_cr4 = sai_readl(sai, sai->base + reg_cr4);
138
139 if (sai->big_endian_data)
140 val_cr4 &= ~FSL_SAI_CR4_MF;
141 else
142 val_cr4 |= FSL_SAI_CR4_MF;
143
144 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
145 case SND_SOC_DAIFMT_I2S:
146 val_cr4 |= FSL_SAI_CR4_FSE;
147 break;
148 default:
149 return -EINVAL;
150 }
151
152 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
153 case SND_SOC_DAIFMT_IB_IF:
154 val_cr4 |= FSL_SAI_CR4_FSP;
155 val_cr2 &= ~FSL_SAI_CR2_BCP;
156 break;
157 case SND_SOC_DAIFMT_IB_NF:
158 val_cr4 &= ~FSL_SAI_CR4_FSP;
159 val_cr2 &= ~FSL_SAI_CR2_BCP;
160 break;
161 case SND_SOC_DAIFMT_NB_IF:
162 val_cr4 |= FSL_SAI_CR4_FSP;
163 val_cr2 |= FSL_SAI_CR2_BCP;
164 break;
165 case SND_SOC_DAIFMT_NB_NF:
166 val_cr4 &= ~FSL_SAI_CR4_FSP;
167 val_cr2 |= FSL_SAI_CR2_BCP;
168 break;
169 default:
170 return -EINVAL;
171 }
172
173 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
174 case SND_SOC_DAIFMT_CBS_CFS:
175 val_cr2 |= FSL_SAI_CR2_BCD_MSTR;
176 val_cr4 |= FSL_SAI_CR4_FSD_MSTR;
177 break;
178 case SND_SOC_DAIFMT_CBM_CFM:
179 val_cr2 &= ~FSL_SAI_CR2_BCD_MSTR;
180 val_cr4 &= ~FSL_SAI_CR4_FSD_MSTR;
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 sai_writel(sai, val_cr2, sai->base + reg_cr2);
187 sai_writel(sai, val_cr4, sai->base + reg_cr4);
188
189 return 0;
190}
191
192static int fsl_sai_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
193{
194 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
195 int ret;
196
197 ret = clk_prepare_enable(sai->clk);
198 if (ret)
199 return ret;
200
201 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_TRANSMITTER);
202 if (ret) {
203 dev_err(cpu_dai->dev, "Cannot set tx format: %d\n", ret);
204 goto err_clk;
205 }
206
207 ret = fsl_sai_set_dai_fmt_tr(cpu_dai, fmt, FSL_FMT_RECEIVER);
208 if (ret) {
209 dev_err(cpu_dai->dev, "Cannot set rx format: %d\n", ret);
210 goto err_clk;
211 }
212
213err_clk:
214 clk_disable_unprepare(sai->clk);
215
216 return ret;
217}
218
219static int fsl_sai_hw_params(struct snd_pcm_substream *substream,
220 struct snd_pcm_hw_params *params,
221 struct snd_soc_dai *cpu_dai)
222{
223 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
224 u32 val_cr4, val_cr5, val_mr, reg_cr4, reg_cr5, reg_mr;
225 unsigned int channels = params_channels(params);
226 u32 word_width = snd_pcm_format_width(params_format(params));
227
228 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
229 reg_cr4 = FSL_SAI_TCR4;
230 reg_cr5 = FSL_SAI_TCR5;
231 reg_mr = FSL_SAI_TMR;
232 } else {
233 reg_cr4 = FSL_SAI_RCR4;
234 reg_cr5 = FSL_SAI_RCR5;
235 reg_mr = FSL_SAI_RMR;
236 }
237
238 val_cr4 = sai_readl(sai, sai->base + reg_cr4);
239 val_cr4 &= ~FSL_SAI_CR4_SYWD_MASK;
240 val_cr4 &= ~FSL_SAI_CR4_FRSZ_MASK;
241
242 val_cr5 = sai_readl(sai, sai->base + reg_cr5);
243 val_cr5 &= ~FSL_SAI_CR5_WNW_MASK;
244 val_cr5 &= ~FSL_SAI_CR5_W0W_MASK;
245 val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
246
247 val_cr4 |= FSL_SAI_CR4_SYWD(word_width);
248 val_cr5 |= FSL_SAI_CR5_WNW(word_width);
249 val_cr5 |= FSL_SAI_CR5_W0W(word_width);
250
251 val_cr5 &= ~FSL_SAI_CR5_FBT_MASK;
252 if (sai->big_endian_data)
253 val_cr5 |= FSL_SAI_CR5_FBT(0);
254 else
255 val_cr5 |= FSL_SAI_CR5_FBT(word_width - 1);
256
257 val_cr4 |= FSL_SAI_CR4_FRSZ(channels);
258 val_mr = ~0UL - ((1 << channels) - 1);
259
260 sai_writel(sai, val_cr4, sai->base + reg_cr4);
261 sai_writel(sai, val_cr5, sai->base + reg_cr5);
262 sai_writel(sai, val_mr, sai->base + reg_mr);
263
264 return 0;
265}
266
267static int fsl_sai_trigger(struct snd_pcm_substream *substream, int cmd,
268 struct snd_soc_dai *cpu_dai)
269{
270 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
271 u32 tcsr, rcsr, val_cr2, val_cr3, reg_cr3;
272
273 val_cr2 = sai_readl(sai, sai->base + FSL_SAI_TCR2);
274 val_cr2 &= ~FSL_SAI_CR2_SYNC;
275 sai_writel(sai, val_cr2, sai->base + FSL_SAI_TCR2);
276
277 val_cr2 = sai_readl(sai, sai->base + FSL_SAI_RCR2);
278 val_cr2 |= FSL_SAI_CR2_SYNC;
279 sai_writel(sai, val_cr2, sai->base + FSL_SAI_RCR2);
280
281 tcsr = sai_readl(sai, sai->base + FSL_SAI_TCSR);
282 rcsr = sai_readl(sai, sai->base + FSL_SAI_RCSR);
283
284 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
285 tcsr |= FSL_SAI_CSR_FRDE;
286 rcsr &= ~FSL_SAI_CSR_FRDE;
287 reg_cr3 = FSL_SAI_TCR3;
288 } else {
289 rcsr |= FSL_SAI_CSR_FRDE;
290 tcsr &= ~FSL_SAI_CSR_FRDE;
291 reg_cr3 = FSL_SAI_RCR3;
292 }
293
294 val_cr3 = sai_readl(sai, sai->base + reg_cr3);
295
296 switch (cmd) {
297 case SNDRV_PCM_TRIGGER_START:
298 case SNDRV_PCM_TRIGGER_RESUME:
299 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
300 tcsr |= FSL_SAI_CSR_TERE;
301 rcsr |= FSL_SAI_CSR_TERE;
302 val_cr3 |= FSL_SAI_CR3_TRCE;
303
304 sai_writel(sai, val_cr3, sai->base + reg_cr3);
305 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
306 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
307 break;
308
309 case SNDRV_PCM_TRIGGER_STOP:
310 case SNDRV_PCM_TRIGGER_SUSPEND:
311 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
312 if (!(cpu_dai->playback_active || cpu_dai->capture_active)) {
313 tcsr &= ~FSL_SAI_CSR_TERE;
314 rcsr &= ~FSL_SAI_CSR_TERE;
315 }
316
317 val_cr3 &= ~FSL_SAI_CR3_TRCE;
318
319 sai_writel(sai, tcsr, sai->base + FSL_SAI_TCSR);
320 sai_writel(sai, rcsr, sai->base + FSL_SAI_RCSR);
321 sai_writel(sai, val_cr3, sai->base + reg_cr3);
322 break;
323 default:
324 return -EINVAL;
325 }
326
327 return 0;
328}
329
330static int fsl_sai_startup(struct snd_pcm_substream *substream,
331 struct snd_soc_dai *cpu_dai)
332{
333 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
334
335 return clk_prepare_enable(sai->clk);
336}
337
338static void fsl_sai_shutdown(struct snd_pcm_substream *substream,
339 struct snd_soc_dai *cpu_dai)
340{
341 struct fsl_sai *sai = snd_soc_dai_get_drvdata(cpu_dai);
342
343 clk_disable_unprepare(sai->clk);
344}
345
346static const struct snd_soc_dai_ops fsl_sai_pcm_dai_ops = {
347 .set_sysclk = fsl_sai_set_dai_sysclk,
348 .set_fmt = fsl_sai_set_dai_fmt,
349 .hw_params = fsl_sai_hw_params,
350 .trigger = fsl_sai_trigger,
351 .startup = fsl_sai_startup,
352 .shutdown = fsl_sai_shutdown,
353};
354
355static int fsl_sai_dai_probe(struct snd_soc_dai *cpu_dai)
356{
357 struct fsl_sai *sai = dev_get_drvdata(cpu_dai->dev);
358 int ret;
359
360 ret = clk_prepare_enable(sai->clk);
361 if (ret)
362 return ret;
363
364 sai_writel(sai, 0x0, sai->base + FSL_SAI_RCSR);
365 sai_writel(sai, 0x0, sai->base + FSL_SAI_TCSR);
366 sai_writel(sai, FSL_SAI_MAXBURST_TX * 2, sai->base + FSL_SAI_TCR1);
367 sai_writel(sai, FSL_SAI_MAXBURST_RX - 1, sai->base + FSL_SAI_RCR1);
368
369 clk_disable_unprepare(sai->clk);
370
371 snd_soc_dai_init_dma_data(cpu_dai, &sai->dma_params_tx,
372 &sai->dma_params_rx);
373
374 snd_soc_dai_set_drvdata(cpu_dai, sai);
375
376 return 0;
377}
378
379static struct snd_soc_dai_driver fsl_sai_dai = {
380 .probe = fsl_sai_dai_probe,
381 .playback = {
382 .channels_min = 1,
383 .channels_max = 2,
384 .rates = SNDRV_PCM_RATE_8000_96000,
385 .formats = FSL_SAI_FORMATS,
386 },
387 .capture = {
388 .channels_min = 1,
389 .channels_max = 2,
390 .rates = SNDRV_PCM_RATE_8000_96000,
391 .formats = FSL_SAI_FORMATS,
392 },
393 .ops = &fsl_sai_pcm_dai_ops,
394};
395
396static const struct snd_soc_component_driver fsl_component = {
397 .name = "fsl-sai",
398};
399
400static int fsl_sai_probe(struct platform_device *pdev)
401{
402 struct device_node *np = pdev->dev.of_node;
403 struct fsl_sai *sai;
404 struct resource *res;
405 int ret;
406
407 sai = devm_kzalloc(&pdev->dev, sizeof(*sai), GFP_KERNEL);
408 if (!sai)
409 return -ENOMEM;
410
411 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
412 sai->base = devm_ioremap_resource(&pdev->dev, res);
413 if (IS_ERR(sai->base))
414 return PTR_ERR(sai->base);
415
416 sai->clk = devm_clk_get(&pdev->dev, "sai");
417 if (IS_ERR(sai->clk)) {
418 dev_err(&pdev->dev, "Cannot get SAI's clock\n");
419 return PTR_ERR(sai->clk);
420 }
421
422 sai->dma_params_rx.addr = res->start + FSL_SAI_RDR;
423 sai->dma_params_tx.addr = res->start + FSL_SAI_TDR;
424 sai->dma_params_rx.maxburst = FSL_SAI_MAXBURST_RX;
425 sai->dma_params_tx.maxburst = FSL_SAI_MAXBURST_TX;
426
427 sai->big_endian_regs = of_property_read_bool(np, "big-endian-regs");
428 sai->big_endian_data = of_property_read_bool(np, "big-endian-data");
429
430 platform_set_drvdata(pdev, sai);
431
432 ret = devm_snd_soc_register_component(&pdev->dev, &fsl_component,
433 &fsl_sai_dai, 1);
434 if (ret)
435 return ret;
436
437 return devm_snd_dmaengine_pcm_register(&pdev->dev, NULL,
438 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE);
439}
440
441static const struct of_device_id fsl_sai_ids[] = {
442 { .compatible = "fsl,vf610-sai", },
443 { /* sentinel */ }
444};
445
446static struct platform_driver fsl_sai_driver = {
447 .probe = fsl_sai_probe,
448 .driver = {
449 .name = "fsl-sai",
450 .owner = THIS_MODULE,
451 .of_match_table = fsl_sai_ids,
452 },
453};
454module_platform_driver(fsl_sai_driver);
455
456MODULE_DESCRIPTION("Freescale Soc SAI Interface");
457MODULE_AUTHOR("Xiubo Li, <Li.Xiubo@freescale.com>");
458MODULE_ALIAS("platform:fsl-sai");
459MODULE_LICENSE("GPL");
diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h
new file mode 100644
index 000000000000..41bb62e69361
--- /dev/null
+++ b/sound/soc/fsl/fsl_sai.h
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2012-2013 Freescale Semiconductor, Inc.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#ifndef __FSL_SAI_H
10#define __FSL_SAI_H
11
12#include <sound/dmaengine_pcm.h>
13
14#define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
15 SNDRV_PCM_FMTBIT_S20_3LE |\
16 SNDRV_PCM_FMTBIT_S24_LE)
17
18/* SAI Transmit/Recieve Control Register */
19#define FSL_SAI_TCSR 0x00
20#define FSL_SAI_RCSR 0x80
21#define FSL_SAI_CSR_TERE BIT(31)
22#define FSL_SAI_CSR_FWF BIT(17)
23#define FSL_SAI_CSR_FRIE BIT(8)
24#define FSL_SAI_CSR_FRDE BIT(0)
25
26/* SAI Transmit Data/FIFO/MASK Register */
27#define FSL_SAI_TDR 0x20
28#define FSL_SAI_TFR 0x40
29#define FSL_SAI_TMR 0x60
30
31/* SAI Recieve Data/FIFO/MASK Register */
32#define FSL_SAI_RDR 0xa0
33#define FSL_SAI_RFR 0xc0
34#define FSL_SAI_RMR 0xe0
35
36/* SAI Transmit and Recieve Configuration 1 Register */
37#define FSL_SAI_TCR1 0x04
38#define FSL_SAI_RCR1 0x84
39
40/* SAI Transmit and Recieve Configuration 2 Register */
41#define FSL_SAI_TCR2 0x08
42#define FSL_SAI_RCR2 0x88
43#define FSL_SAI_CR2_SYNC BIT(30)
44#define FSL_SAI_CR2_MSEL_MASK (0xff << 26)
45#define FSL_SAI_CR2_MSEL_BUS 0
46#define FSL_SAI_CR2_MSEL_MCLK1 BIT(26)
47#define FSL_SAI_CR2_MSEL_MCLK2 BIT(27)
48#define FSL_SAI_CR2_MSEL_MCLK3 (BIT(26) | BIT(27))
49#define FSL_SAI_CR2_BCP BIT(25)
50#define FSL_SAI_CR2_BCD_MSTR BIT(24)
51
52/* SAI Transmit and Recieve Configuration 3 Register */
53#define FSL_SAI_TCR3 0x0c
54#define FSL_SAI_RCR3 0x8c
55#define FSL_SAI_CR3_TRCE BIT(16)
56#define FSL_SAI_CR3_WDFL(x) (x)
57#define FSL_SAI_CR3_WDFL_MASK 0x1f
58
59/* SAI Transmit and Recieve Configuration 4 Register */
60#define FSL_SAI_TCR4 0x10
61#define FSL_SAI_RCR4 0x90
62#define FSL_SAI_CR4_FRSZ(x) (((x) - 1) << 16)
63#define FSL_SAI_CR4_FRSZ_MASK (0x1f << 16)
64#define FSL_SAI_CR4_SYWD(x) (((x) - 1) << 8)
65#define FSL_SAI_CR4_SYWD_MASK (0x1f << 8)
66#define FSL_SAI_CR4_MF BIT(4)
67#define FSL_SAI_CR4_FSE BIT(3)
68#define FSL_SAI_CR4_FSP BIT(1)
69#define FSL_SAI_CR4_FSD_MSTR BIT(0)
70
71/* SAI Transmit and Recieve Configuration 5 Register */
72#define FSL_SAI_TCR5 0x14
73#define FSL_SAI_RCR5 0x94
74#define FSL_SAI_CR5_WNW(x) (((x) - 1) << 24)
75#define FSL_SAI_CR5_WNW_MASK (0x1f << 24)
76#define FSL_SAI_CR5_W0W(x) (((x) - 1) << 16)
77#define FSL_SAI_CR5_W0W_MASK (0x1f << 16)
78#define FSL_SAI_CR5_FBT(x) ((x) << 8)
79#define FSL_SAI_CR5_FBT_MASK (0x1f << 8)
80
81/* SAI type */
82#define FSL_SAI_DMA BIT(0)
83#define FSL_SAI_USE_AC97 BIT(1)
84#define FSL_SAI_NET BIT(2)
85#define FSL_SAI_TRA_SYN BIT(3)
86#define FSL_SAI_REC_SYN BIT(4)
87#define FSL_SAI_USE_I2S_SLAVE BIT(5)
88
89#define FSL_FMT_TRANSMITTER 0
90#define FSL_FMT_RECEIVER 1
91
92/* SAI clock sources */
93#define FSL_SAI_CLK_BUS 0
94#define FSL_SAI_CLK_MAST1 1
95#define FSL_SAI_CLK_MAST2 2
96#define FSL_SAI_CLK_MAST3 3
97
98/* SAI data transfer numbers per DMA request */
99#define FSL_SAI_MAXBURST_TX 6
100#define FSL_SAI_MAXBURST_RX 6
101
102struct fsl_sai {
103 struct clk *clk;
104
105 void __iomem *base;
106
107 bool big_endian_regs;
108 bool big_endian_data;
109
110 struct snd_dmaengine_dai_dma_data dma_params_rx;
111 struct snd_dmaengine_dai_dma_data dma_params_tx;
112};
113
114#endif /* __FSL_SAI_H */
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 55193a5596ca..4d075f1abe78 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -1181,13 +1181,6 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1181 return ret; 1181 return ret;
1182} 1182}
1183 1183
1184static int fsl_spdif_remove(struct platform_device *pdev)
1185{
1186 imx_pcm_dma_exit(pdev);
1187
1188 return 0;
1189}
1190
1191static const struct of_device_id fsl_spdif_dt_ids[] = { 1184static const struct of_device_id fsl_spdif_dt_ids[] = {
1192 { .compatible = "fsl,imx35-spdif", }, 1185 { .compatible = "fsl,imx35-spdif", },
1193 {} 1186 {}
@@ -1201,7 +1194,6 @@ static struct platform_driver fsl_spdif_driver = {
1201 .of_match_table = fsl_spdif_dt_ids, 1194 .of_match_table = fsl_spdif_dt_ids,
1202 }, 1195 },
1203 .probe = fsl_spdif_probe, 1196 .probe = fsl_spdif_probe,
1204 .remove = fsl_spdif_remove,
1205}; 1197};
1206 1198
1207module_platform_driver(fsl_spdif_driver); 1199module_platform_driver(fsl_spdif_driver);
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 35e277379b86..f9090b167ad7 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -35,9 +35,11 @@
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>
42#include <linux/spinlock.h>
41#include <linux/of_address.h> 43#include <linux/of_address.h>
42#include <linux/of_irq.h> 44#include <linux/of_irq.h>
43#include <linux/of_platform.h> 45#include <linux/of_platform.h>
@@ -79,8 +81,7 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
79 * ALSA that we support all rates and let the codec driver decide what rates 81 * ALSA that we support all rates and let the codec driver decide what rates
80 * are really supported. 82 * are really supported.
81 */ 83 */
82#define FSLSSI_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ 84#define FSLSSI_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS
83 SNDRV_PCM_RATE_CONTINUOUS)
84 85
85/** 86/**
86 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI 87 * FSLSSI_I2S_FORMATS: audio formats supported by the SSI
@@ -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
@@ -119,8 +141,6 @@ static inline void write_ssi_mask(u32 __iomem *addr, u32 clear, u32 set)
119 * @ssi: pointer to the SSI's registers 141 * @ssi: pointer to the SSI's registers
120 * @ssi_phys: physical address of the SSI registers 142 * @ssi_phys: physical address of the SSI registers
121 * @irq: IRQ of this SSI 143 * @irq: IRQ of this SSI
122 * @first_stream: pointer to the stream that was opened first
123 * @second_stream: pointer to second stream
124 * @playback: the number of playback streams opened 144 * @playback: the number of playback streams opened
125 * @capture: the number of capture streams opened 145 * @capture: the number of capture streams opened
126 * @cpu_dai: the CPU DAI for this device 146 * @cpu_dai: the CPU DAI for this device
@@ -132,23 +152,29 @@ struct fsl_ssi_private {
132 struct ccsr_ssi __iomem *ssi; 152 struct ccsr_ssi __iomem *ssi;
133 dma_addr_t ssi_phys; 153 dma_addr_t ssi_phys;
134 unsigned int irq; 154 unsigned int irq;
135 struct snd_pcm_substream *first_stream;
136 struct snd_pcm_substream *second_stream;
137 unsigned int fifo_depth; 155 unsigned int fifo_depth;
138 struct snd_soc_dai_driver cpu_dai_drv; 156 struct snd_soc_dai_driver cpu_dai_drv;
139 struct device_attribute dev_attr;
140 struct platform_device *pdev; 157 struct platform_device *pdev;
141 158
159 enum fsl_ssi_type hw_type;
142 bool new_binding; 160 bool new_binding;
143 bool ssi_on_imx; 161 bool ssi_on_imx;
144 bool imx_ac97; 162 bool imx_ac97;
145 bool use_dma; 163 bool use_dma;
164 bool baudclk_locked;
165 bool irq_stats;
166 bool offline_config;
167 u8 i2s_mode;
168 spinlock_t baudclk_lock;
169 struct clk *baudclk;
146 struct clk *clk; 170 struct clk *clk;
147 struct snd_dmaengine_dai_dma_data dma_params_tx; 171 struct snd_dmaengine_dai_dma_data dma_params_tx;
148 struct snd_dmaengine_dai_dma_data dma_params_rx; 172 struct snd_dmaengine_dai_dma_data dma_params_rx;
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,17 +372,287 @@ 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
614static void fsl_ssi_setup_ac97(struct fsl_ssi_private *ssi_private)
615{
616 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
617
618 /*
619 * Setup the clock control register
620 */
621 write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
622 &ssi->stccr);
623 write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
624 &ssi->srccr);
625
626 /*
627 * Enable AC97 mode and startup the SSI
628 */
629 write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
630 &ssi->sacnt);
631 write_ssi(0xff, &ssi->saccdis);
632 write_ssi(0x300, &ssi->saccen);
633
634 /*
635 * Enable SSI, Transmit and Receive. AC97 has to communicate with the
636 * codec before a stream is started.
637 */
638 write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN |
639 CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
640
641 write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor);
642}
643
324static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private) 644static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
325{ 645{
326 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 646 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
327 u8 i2s_mode;
328 u8 wm; 647 u8 wm;
329 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; 648 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates;
330 649
650 fsl_ssi_setup_reg_vals(ssi_private);
651
331 if (ssi_private->imx_ac97) 652 if (ssi_private->imx_ac97)
332 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;
333 else 654 else
334 i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE; 655 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
335 656
336 /* 657 /*
337 * Section 16.5 of the MPC8610 reference manual says that the SSI needs 658 * Section 16.5 of the MPC8610 reference manual says that the SSI needs
@@ -348,16 +669,15 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
348 write_ssi_mask(&ssi->scr, 669 write_ssi_mask(&ssi->scr,
349 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN, 670 CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_SYN,
350 CCSR_SSI_SCR_TFR_CLK_DIS | 671 CCSR_SSI_SCR_TFR_CLK_DIS |
351 i2s_mode | 672 ssi_private->i2s_mode |
352 (synchronous ? CCSR_SSI_SCR_SYN : 0)); 673 (synchronous ? CCSR_SSI_SCR_SYN : 0));
353 674
354 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFEN0 | 675 write_ssi(CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFSI |
355 CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TEFS | 676 CCSR_SSI_STCR_TEFS | CCSR_SSI_STCR_TSCKP, &ssi->stcr);
356 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);
357 680
358 write_ssi(CCSR_SSI_SRCR_RXBIT0 | CCSR_SSI_SRCR_RFEN0 |
359 CCSR_SSI_SRCR_RFSI | CCSR_SSI_SRCR_REFS |
360 CCSR_SSI_SRCR_RSCKP, &ssi->srcr);
361 /* 681 /*
362 * 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.
363 */ 683 */
@@ -387,30 +707,18 @@ static int fsl_ssi_setup(struct fsl_ssi_private *ssi_private)
387 * because it is also running without an active substream. Normally SSI 707 * because it is also running without an active substream. Normally SSI
388 * is only enabled when there is a substream. 708 * is only enabled when there is a substream.
389 */ 709 */
390 if (ssi_private->imx_ac97) { 710 if (ssi_private->imx_ac97)
391 /* 711 fsl_ssi_setup_ac97(ssi_private);
392 * Setup the clock control register
393 */
394 write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
395 &ssi->stccr);
396 write_ssi(CCSR_SSI_SxCCR_WL(17) | CCSR_SSI_SxCCR_DC(13),
397 &ssi->srccr);
398
399 /*
400 * Enable AC97 mode and startup the SSI
401 */
402 write_ssi(CCSR_SSI_SACNT_AC97EN | CCSR_SSI_SACNT_FV,
403 &ssi->sacnt);
404 write_ssi(0xff, &ssi->saccdis);
405 write_ssi(0x300, &ssi->saccen);
406
407 /*
408 * Enable SSI, Transmit and Receive
409 */
410 write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN |
411 CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE);
412 712
413 write_ssi(CCSR_SSI_SOR_WAIT(3), &ssi->sor); 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));
414 } 722 }
415 723
416 return 0; 724 return 0;
@@ -431,53 +739,17 @@ static int fsl_ssi_startup(struct snd_pcm_substream *substream,
431 struct snd_soc_pcm_runtime *rtd = substream->private_data; 739 struct snd_soc_pcm_runtime *rtd = substream->private_data;
432 struct fsl_ssi_private *ssi_private = 740 struct fsl_ssi_private *ssi_private =
433 snd_soc_dai_get_drvdata(rtd->cpu_dai); 741 snd_soc_dai_get_drvdata(rtd->cpu_dai);
434 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates; 742 unsigned long flags;
435 743
436 /* 744 /* First, we only do fsl_ssi_setup() when SSI is going to be active.
437 * If this is the first stream opened, then request the IRQ 745 * Second, fsl_ssi_setup was already called by ac97_init earlier if
438 * and initialize the SSI registers. 746 * the driver is in ac97 mode.
439 */ 747 */
440 if (!ssi_private->first_stream) { 748 if (!dai->active && !ssi_private->imx_ac97) {
441 ssi_private->first_stream = substream; 749 fsl_ssi_setup(ssi_private);
442 750 spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
443 /* 751 ssi_private->baudclk_locked = false;
444 * fsl_ssi_setup was already called by ac97_init earlier if 752 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
445 * the driver is in ac97 mode.
446 */
447 if (!ssi_private->imx_ac97)
448 fsl_ssi_setup(ssi_private);
449 } else {
450 if (synchronous) {
451 struct snd_pcm_runtime *first_runtime =
452 ssi_private->first_stream->runtime;
453 /*
454 * This is the second stream open, and we're in
455 * synchronous mode, so we need to impose sample
456 * sample size constraints. This is because STCCR is
457 * used for playback and capture in synchronous mode,
458 * so there's no way to specify different word
459 * lengths.
460 *
461 * Note that this can cause a race condition if the
462 * second stream is opened before the first stream is
463 * fully initialized. We provide some protection by
464 * checking to make sure the first stream is
465 * initialized, but it's not perfect. ALSA sometimes
466 * re-initializes the driver with a different sample
467 * rate or size. If the second stream is opened
468 * before the first stream has received its final
469 * parameters, then the second stream may be
470 * constrained to the wrong sample rate or size.
471 */
472 if (first_runtime->sample_bits) {
473 snd_pcm_hw_constraint_minmax(substream->runtime,
474 SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
475 first_runtime->sample_bits,
476 first_runtime->sample_bits);
477 }
478 }
479
480 ssi_private->second_stream = substream;
481 } 753 }
482 754
483 return 0; 755 return 0;
@@ -501,6 +773,7 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
501{ 773{
502 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai); 774 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
503 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 775 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
776 unsigned int channels = params_channels(hw_params);
504 unsigned int sample_size = 777 unsigned int sample_size =
505 snd_pcm_format_width(params_format(hw_params)); 778 snd_pcm_format_width(params_format(hw_params));
506 u32 wl = CCSR_SSI_SxCCR_WL(sample_size); 779 u32 wl = CCSR_SSI_SxCCR_WL(sample_size);
@@ -530,6 +803,248 @@ static int fsl_ssi_hw_params(struct snd_pcm_substream *substream,
530 else 803 else
531 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl); 804 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_WL_MASK, wl);
532 805
806 if (!ssi_private->imx_ac97)
807 write_ssi_mask(&ssi->scr,
808 CCSR_SSI_SCR_NET | CCSR_SSI_SCR_I2S_MODE_MASK,
809 channels == 1 ? 0 : ssi_private->i2s_mode);
810
811 return 0;
812}
813
814/**
815 * fsl_ssi_set_dai_fmt - configure Digital Audio Interface Format.
816 */
817static int fsl_ssi_set_dai_fmt(struct snd_soc_dai *cpu_dai, unsigned int fmt)
818{
819 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
820 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
821 u32 strcr = 0, stcr, srcr, scr, mask;
822
823 scr = read_ssi(&ssi->scr) & ~(CCSR_SSI_SCR_SYN | CCSR_SSI_SCR_I2S_MODE_MASK);
824 scr |= CCSR_SSI_SCR_NET;
825
826 mask = CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR |
827 CCSR_SSI_STCR_TSCKP | CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TFSL |
828 CCSR_SSI_STCR_TEFS;
829 stcr = read_ssi(&ssi->stcr) & ~mask;
830 srcr = read_ssi(&ssi->srcr) & ~mask;
831
832 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
833 case SND_SOC_DAIFMT_I2S:
834 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
835 case SND_SOC_DAIFMT_CBS_CFS:
836 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_MASTER;
837 break;
838 case SND_SOC_DAIFMT_CBM_CFM:
839 ssi_private->i2s_mode = CCSR_SSI_SCR_I2S_MODE_SLAVE;
840 break;
841 default:
842 return -EINVAL;
843 }
844 scr |= ssi_private->i2s_mode;
845
846 /* Data on rising edge of bclk, frame low, 1clk before data */
847 strcr |= CCSR_SSI_STCR_TFSI | CCSR_SSI_STCR_TSCKP |
848 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS;
849 break;
850 case SND_SOC_DAIFMT_LEFT_J:
851 /* Data on rising edge of bclk, frame high */
852 strcr |= CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TSCKP;
853 break;
854 case SND_SOC_DAIFMT_DSP_A:
855 /* Data on rising edge of bclk, frame high, 1clk before data */
856 strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
857 CCSR_SSI_STCR_TXBIT0 | CCSR_SSI_STCR_TEFS;
858 break;
859 case SND_SOC_DAIFMT_DSP_B:
860 /* Data on rising edge of bclk, frame high */
861 strcr |= CCSR_SSI_STCR_TFSL | CCSR_SSI_STCR_TSCKP |
862 CCSR_SSI_STCR_TXBIT0;
863 break;
864 default:
865 return -EINVAL;
866 }
867
868 /* DAI clock inversion */
869 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
870 case SND_SOC_DAIFMT_NB_NF:
871 /* Nothing to do for both normal cases */
872 break;
873 case SND_SOC_DAIFMT_IB_NF:
874 /* Invert bit clock */
875 strcr ^= CCSR_SSI_STCR_TSCKP;
876 break;
877 case SND_SOC_DAIFMT_NB_IF:
878 /* Invert frame clock */
879 strcr ^= CCSR_SSI_STCR_TFSI;
880 break;
881 case SND_SOC_DAIFMT_IB_IF:
882 /* Invert both clocks */
883 strcr ^= CCSR_SSI_STCR_TSCKP;
884 strcr ^= CCSR_SSI_STCR_TFSI;
885 break;
886 default:
887 return -EINVAL;
888 }
889
890 /* DAI clock master masks */
891 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
892 case SND_SOC_DAIFMT_CBS_CFS:
893 strcr |= CCSR_SSI_STCR_TFDIR | CCSR_SSI_STCR_TXDIR;
894 scr |= CCSR_SSI_SCR_SYS_CLK_EN;
895 break;
896 case SND_SOC_DAIFMT_CBM_CFM:
897 scr &= ~CCSR_SSI_SCR_SYS_CLK_EN;
898 break;
899 default:
900 return -EINVAL;
901 }
902
903 stcr |= strcr;
904 srcr |= strcr;
905
906 if (ssi_private->cpu_dai_drv.symmetric_rates) {
907 /* Need to clear RXDIR when using SYNC mode */
908 srcr &= ~CCSR_SSI_SRCR_RXDIR;
909 scr |= CCSR_SSI_SCR_SYN;
910 }
911
912 write_ssi(stcr, &ssi->stcr);
913 write_ssi(srcr, &ssi->srcr);
914 write_ssi(scr, &ssi->scr);
915
916 return 0;
917}
918
919/**
920 * fsl_ssi_set_dai_sysclk - configure Digital Audio Interface bit clock
921 *
922 * Note: This function can be only called when using SSI as DAI master
923 *
924 * Quick instruction for parameters:
925 * freq: Output BCLK frequency = samplerate * 32 (fixed) * channels
926 * dir: SND_SOC_CLOCK_OUT -> TxBCLK, SND_SOC_CLOCK_IN -> RxBCLK.
927 */
928static int fsl_ssi_set_dai_sysclk(struct snd_soc_dai *cpu_dai,
929 int clk_id, unsigned int freq, int dir)
930{
931 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
932 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
933 int synchronous = ssi_private->cpu_dai_drv.symmetric_rates, ret;
934 u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
935 unsigned long flags, clkrate, baudrate, tmprate;
936 u64 sub, savesub = 100000;
937
938 /* Don't apply it to any non-baudclk circumstance */
939 if (IS_ERR(ssi_private->baudclk))
940 return -EINVAL;
941
942 /* It should be already enough to divide clock by setting pm alone */
943 psr = 0;
944 div2 = 0;
945
946 factor = (div2 + 1) * (7 * psr + 1) * 2;
947
948 for (i = 0; i < 255; i++) {
949 /* The bclk rate must be smaller than 1/5 sysclk rate */
950 if (factor * (i + 1) < 5)
951 continue;
952
953 tmprate = freq * factor * (i + 2);
954 clkrate = clk_round_rate(ssi_private->baudclk, tmprate);
955
956 do_div(clkrate, factor);
957 afreq = (u32)clkrate / (i + 1);
958
959 if (freq == afreq)
960 sub = 0;
961 else if (freq / afreq == 1)
962 sub = freq - afreq;
963 else if (afreq / freq == 1)
964 sub = afreq - freq;
965 else
966 continue;
967
968 /* Calculate the fraction */
969 sub *= 100000;
970 do_div(sub, freq);
971
972 if (sub < savesub) {
973 baudrate = tmprate;
974 savesub = sub;
975 pm = i;
976 }
977
978 /* We are lucky */
979 if (savesub == 0)
980 break;
981 }
982
983 /* No proper pm found if it is still remaining the initial value */
984 if (pm == 999) {
985 dev_err(cpu_dai->dev, "failed to handle the required sysclk\n");
986 return -EINVAL;
987 }
988
989 stccr = CCSR_SSI_SxCCR_PM(pm + 1) | (div2 ? CCSR_SSI_SxCCR_DIV2 : 0) |
990 (psr ? CCSR_SSI_SxCCR_PSR : 0);
991 mask = CCSR_SSI_SxCCR_PM_MASK | CCSR_SSI_SxCCR_DIV2 | CCSR_SSI_SxCCR_PSR;
992
993 if (dir == SND_SOC_CLOCK_OUT || synchronous)
994 write_ssi_mask(&ssi->stccr, mask, stccr);
995 else
996 write_ssi_mask(&ssi->srccr, mask, stccr);
997
998 spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
999 if (!ssi_private->baudclk_locked) {
1000 ret = clk_set_rate(ssi_private->baudclk, baudrate);
1001 if (ret) {
1002 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
1003 dev_err(cpu_dai->dev, "failed to set baudclk rate\n");
1004 return -EINVAL;
1005 }
1006 ssi_private->baudclk_locked = true;
1007 }
1008 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
1009
1010 return 0;
1011}
1012
1013/**
1014 * fsl_ssi_set_dai_tdm_slot - set TDM slot number
1015 *
1016 * Note: This function can be only called when using SSI as DAI master
1017 */
1018static int fsl_ssi_set_dai_tdm_slot(struct snd_soc_dai *cpu_dai, u32 tx_mask,
1019 u32 rx_mask, int slots, int slot_width)
1020{
1021 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(cpu_dai);
1022 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
1023 u32 val;
1024
1025 /* The slot number should be >= 2 if using Network mode or I2S mode */
1026 val = read_ssi(&ssi->scr) & (CCSR_SSI_SCR_I2S_MODE_MASK | CCSR_SSI_SCR_NET);
1027 if (val && slots < 2) {
1028 dev_err(cpu_dai->dev, "slot number should be >= 2 in I2S or NET\n");
1029 return -EINVAL;
1030 }
1031
1032 write_ssi_mask(&ssi->stccr, CCSR_SSI_SxCCR_DC_MASK,
1033 CCSR_SSI_SxCCR_DC(slots));
1034 write_ssi_mask(&ssi->srccr, CCSR_SSI_SxCCR_DC_MASK,
1035 CCSR_SSI_SxCCR_DC(slots));
1036
1037 /* The register SxMSKs needs SSI to provide essential clock due to
1038 * hardware design. So we here temporarily enable SSI to set them.
1039 */
1040 val = read_ssi(&ssi->scr) & CCSR_SSI_SCR_SSIEN;
1041 write_ssi_mask(&ssi->scr, 0, CCSR_SSI_SCR_SSIEN);
1042
1043 write_ssi(tx_mask, &ssi->stmsk);
1044 write_ssi(rx_mask, &ssi->srmsk);
1045
1046 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, val);
1047
533 return 0; 1048 return 0;
534} 1049}
535 1050
@@ -548,77 +1063,46 @@ static int fsl_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
548 struct snd_soc_pcm_runtime *rtd = substream->private_data; 1063 struct snd_soc_pcm_runtime *rtd = substream->private_data;
549 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);
550 struct ccsr_ssi __iomem *ssi = ssi_private->ssi; 1065 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
551 unsigned int sier_bits; 1066 unsigned long flags;
552
553 /*
554 * Enable only the interrupts and DMA requests
555 * that are needed for the channel. As the fiq
556 * is polling for this bits, we have to ensure
557 * that this are aligned with the preallocated
558 * buffers
559 */
560
561 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
562 if (ssi_private->use_dma)
563 sier_bits = SIER_FLAGS;
564 else
565 sier_bits = CCSR_SSI_SIER_TIE | CCSR_SSI_SIER_TFE0_EN;
566 } else {
567 if (ssi_private->use_dma)
568 sier_bits = SIER_FLAGS;
569 else
570 sier_bits = CCSR_SSI_SIER_RIE | CCSR_SSI_SIER_RFF0_EN;
571 }
572 1067
573 switch (cmd) { 1068 switch (cmd) {
574 case SNDRV_PCM_TRIGGER_START: 1069 case SNDRV_PCM_TRIGGER_START:
575 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1070 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
576 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1071 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
577 write_ssi_mask(&ssi->scr, 0, 1072 fsl_ssi_tx_config(ssi_private, true);
578 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_TE);
579 else 1073 else
580 write_ssi_mask(&ssi->scr, 0, 1074 fsl_ssi_rx_config(ssi_private, true);
581 CCSR_SSI_SCR_SSIEN | CCSR_SSI_SCR_RE);
582 break; 1075 break;
583 1076
584 case SNDRV_PCM_TRIGGER_STOP: 1077 case SNDRV_PCM_TRIGGER_STOP:
585 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1078 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
586 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) 1079 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
587 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_TE, 0); 1080 fsl_ssi_tx_config(ssi_private, false);
588 else 1081 else
589 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_RE, 0); 1082 fsl_ssi_rx_config(ssi_private, false);
590 1083
591 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) & 1084 if (!ssi_private->imx_ac97 && (read_ssi(&ssi->scr) &
592 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) 1085 (CCSR_SSI_SCR_TE | CCSR_SSI_SCR_RE)) == 0) {
593 write_ssi_mask(&ssi->scr, CCSR_SSI_SCR_SSIEN, 0); 1086 spin_lock_irqsave(&ssi_private->baudclk_lock, flags);
1087 ssi_private->baudclk_locked = false;
1088 spin_unlock_irqrestore(&ssi_private->baudclk_lock, flags);
1089 }
594 break; 1090 break;
595 1091
596 default: 1092 default:
597 return -EINVAL; 1093 return -EINVAL;
598 } 1094 }
599 1095
600 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 }
601 1102
602 return 0; 1103 return 0;
603} 1104}
604 1105
605/**
606 * fsl_ssi_shutdown: shutdown the SSI
607 *
608 * Shutdown the SSI if there are no other substreams open.
609 */
610static void fsl_ssi_shutdown(struct snd_pcm_substream *substream,
611 struct snd_soc_dai *dai)
612{
613 struct snd_soc_pcm_runtime *rtd = substream->private_data;
614 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(rtd->cpu_dai);
615
616 if (ssi_private->first_stream == substream)
617 ssi_private->first_stream = ssi_private->second_stream;
618
619 ssi_private->second_stream = NULL;
620}
621
622static int fsl_ssi_dai_probe(struct snd_soc_dai *dai) 1106static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
623{ 1107{
624 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai); 1108 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(dai);
@@ -634,7 +1118,9 @@ static int fsl_ssi_dai_probe(struct snd_soc_dai *dai)
634static const struct snd_soc_dai_ops fsl_ssi_dai_ops = { 1118static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
635 .startup = fsl_ssi_startup, 1119 .startup = fsl_ssi_startup,
636 .hw_params = fsl_ssi_hw_params, 1120 .hw_params = fsl_ssi_hw_params,
637 .shutdown = fsl_ssi_shutdown, 1121 .set_fmt = fsl_ssi_set_dai_fmt,
1122 .set_sysclk = fsl_ssi_set_dai_sysclk,
1123 .set_tdm_slot = fsl_ssi_set_dai_tdm_slot,
638 .trigger = fsl_ssi_trigger, 1124 .trigger = fsl_ssi_trigger,
639}; 1125};
640 1126
@@ -642,14 +1128,13 @@ static const struct snd_soc_dai_ops fsl_ssi_dai_ops = {
642static struct snd_soc_dai_driver fsl_ssi_dai_template = { 1128static struct snd_soc_dai_driver fsl_ssi_dai_template = {
643 .probe = fsl_ssi_dai_probe, 1129 .probe = fsl_ssi_dai_probe,
644 .playback = { 1130 .playback = {
645 /* The SSI does not support monaural audio. */ 1131 .channels_min = 1,
646 .channels_min = 2,
647 .channels_max = 2, 1132 .channels_max = 2,
648 .rates = FSLSSI_I2S_RATES, 1133 .rates = FSLSSI_I2S_RATES,
649 .formats = FSLSSI_I2S_FORMATS, 1134 .formats = FSLSSI_I2S_FORMATS,
650 }, 1135 },
651 .capture = { 1136 .capture = {
652 .channels_min = 2, 1137 .channels_min = 1,
653 .channels_max = 2, 1138 .channels_max = 2,
654 .rates = FSLSSI_I2S_RATES, 1139 .rates = FSLSSI_I2S_RATES,
655 .formats = FSLSSI_I2S_FORMATS, 1140 .formats = FSLSSI_I2S_FORMATS,
@@ -661,59 +1146,6 @@ static const struct snd_soc_component_driver fsl_ssi_component = {
661 .name = "fsl-ssi", 1146 .name = "fsl-ssi",
662}; 1147};
663 1148
664/**
665 * fsl_ssi_ac97_trigger: start and stop the AC97 receive/transmit.
666 *
667 * This function is called by ALSA to start, stop, pause, and resume the
668 * transfer of data.
669 */
670static int fsl_ssi_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
671 struct snd_soc_dai *dai)
672{
673 struct snd_soc_pcm_runtime *rtd = substream->private_data;
674 struct fsl_ssi_private *ssi_private = snd_soc_dai_get_drvdata(
675 rtd->cpu_dai);
676 struct ccsr_ssi __iomem *ssi = ssi_private->ssi;
677
678 switch (cmd) {
679 case SNDRV_PCM_TRIGGER_START:
680 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
681 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
682 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_TIE |
683 CCSR_SSI_SIER_TFE0_EN);
684 else
685 write_ssi_mask(&ssi->sier, 0, CCSR_SSI_SIER_RIE |
686 CCSR_SSI_SIER_RFF0_EN);
687 break;
688
689 case SNDRV_PCM_TRIGGER_STOP:
690 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
691 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
692 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_TIE |
693 CCSR_SSI_SIER_TFE0_EN, 0);
694 else
695 write_ssi_mask(&ssi->sier, CCSR_SSI_SIER_RIE |
696 CCSR_SSI_SIER_RFF0_EN, 0);
697 break;
698
699 default:
700 return -EINVAL;
701 }
702
703 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
704 write_ssi(CCSR_SSI_SOR_TX_CLR, &ssi->sor);
705 else
706 write_ssi(CCSR_SSI_SOR_RX_CLR, &ssi->sor);
707
708 return 0;
709}
710
711static const struct snd_soc_dai_ops fsl_ssi_ac97_dai_ops = {
712 .startup = fsl_ssi_startup,
713 .shutdown = fsl_ssi_shutdown,
714 .trigger = fsl_ssi_ac97_trigger,
715};
716
717static struct snd_soc_dai_driver fsl_ssi_ac97_dai = { 1149static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
718 .ac97_control = 1, 1150 .ac97_control = 1,
719 .playback = { 1151 .playback = {
@@ -730,7 +1162,7 @@ static struct snd_soc_dai_driver fsl_ssi_ac97_dai = {
730 .rates = SNDRV_PCM_RATE_48000, 1162 .rates = SNDRV_PCM_RATE_48000,
731 .formats = SNDRV_PCM_FMTBIT_S16_LE, 1163 .formats = SNDRV_PCM_FMTBIT_S16_LE,
732 }, 1164 },
733 .ops = &fsl_ssi_ac97_dai_ops, 1165 .ops = &fsl_ssi_dai_ops,
734}; 1166};
735 1167
736 1168
@@ -788,56 +1220,6 @@ static struct snd_ac97_bus_ops fsl_ssi_ac97_ops = {
788 .write = fsl_ssi_ac97_write, 1220 .write = fsl_ssi_ac97_write,
789}; 1221};
790 1222
791/* Show the statistics of a flag only if its interrupt is enabled. The
792 * compiler will optimze this code to a no-op if the interrupt is not
793 * enabled.
794 */
795#define SIER_SHOW(flag, name) \
796 do { \
797 if (SIER_FLAGS & CCSR_SSI_SIER_##flag) \
798 length += sprintf(buf + length, #name "=%u\n", \
799 ssi_private->stats.name); \
800 } while (0)
801
802
803/**
804 * fsl_sysfs_ssi_show: display SSI statistics
805 *
806 * Display the statistics for the current SSI device. To avoid confusion,
807 * we only show those counts that are enabled.
808 */
809static ssize_t fsl_sysfs_ssi_show(struct device *dev,
810 struct device_attribute *attr, char *buf)
811{
812 struct fsl_ssi_private *ssi_private =
813 container_of(attr, struct fsl_ssi_private, dev_attr);
814 ssize_t length = 0;
815
816 SIER_SHOW(RFRC_EN, rfrc);
817 SIER_SHOW(TFRC_EN, tfrc);
818 SIER_SHOW(CMDAU_EN, cmdau);
819 SIER_SHOW(CMDDU_EN, cmddu);
820 SIER_SHOW(RXT_EN, rxt);
821 SIER_SHOW(RDR1_EN, rdr1);
822 SIER_SHOW(RDR0_EN, rdr0);
823 SIER_SHOW(TDE1_EN, tde1);
824 SIER_SHOW(TDE0_EN, tde0);
825 SIER_SHOW(ROE1_EN, roe1);
826 SIER_SHOW(ROE0_EN, roe0);
827 SIER_SHOW(TUE1_EN, tue1);
828 SIER_SHOW(TUE0_EN, tue0);
829 SIER_SHOW(TFS_EN, tfs);
830 SIER_SHOW(RFS_EN, rfs);
831 SIER_SHOW(TLS_EN, tls);
832 SIER_SHOW(RLS_EN, rls);
833 SIER_SHOW(RFF1_EN, rff1);
834 SIER_SHOW(RFF0_EN, rff0);
835 SIER_SHOW(TFE1_EN, tfe1);
836 SIER_SHOW(TFE0_EN, tfe0);
837
838 return length;
839}
840
841/** 1223/**
842 * Make every character in a string lower-case 1224 * Make every character in a string lower-case
843 */ 1225 */
@@ -859,6 +1241,8 @@ static int fsl_ssi_probe(struct platform_device *pdev)
859 int ret = 0; 1241 int ret = 0;
860 struct device_attribute *dev_attr = NULL; 1242 struct device_attribute *dev_attr = NULL;
861 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;
862 const char *p, *sprop; 1246 const char *p, *sprop;
863 const uint32_t *iprop; 1247 const uint32_t *iprop;
864 struct resource res; 1248 struct resource res;
@@ -873,6 +1257,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
873 if (!of_device_is_available(np)) 1257 if (!of_device_is_available(np))
874 return -ENODEV; 1258 return -ENODEV;
875 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
876 /* We only support the SSI in "I2S Slave" mode */ 1265 /* We only support the SSI in "I2S Slave" mode */
877 sprop = of_get_property(np, "fsl,mode", NULL); 1266 sprop = of_get_property(np, "fsl,mode", NULL);
878 if (!sprop) { 1267 if (!sprop) {
@@ -899,6 +1288,7 @@ static int fsl_ssi_probe(struct platform_device *pdev)
899 1288
900 ssi_private->use_dma = !of_property_read_bool(np, 1289 ssi_private->use_dma = !of_property_read_bool(np,
901 "fsl,fiq-stream-filter"); 1290 "fsl,fiq-stream-filter");
1291 ssi_private->hw_type = hw_type;
902 1292
903 if (ac97) { 1293 if (ac97) {
904 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai, 1294 memcpy(&ssi_private->cpu_dai_drv, &fsl_ssi_ac97_dai,
@@ -935,8 +1325,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
935 } 1325 }
936 1326
937 /* Are the RX and the TX clocks locked? */ 1327 /* Are the RX and the TX clocks locked? */
938 if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) 1328 if (!of_find_property(np, "fsl,ssi-asynchronous", NULL)) {
939 ssi_private->cpu_dai_drv.symmetric_rates = 1; 1329 ssi_private->cpu_dai_drv.symmetric_rates = 1;
1330 ssi_private->cpu_dai_drv.symmetric_channels = 1;
1331 ssi_private->cpu_dai_drv.symmetric_samplebits = 1;
1332 }
940 1333
941 /* Determine the FIFO depth. */ 1334 /* Determine the FIFO depth. */
942 iprop = of_get_property(np, "fsl,fifo-depth", NULL); 1335 iprop = of_get_property(np, "fsl,fifo-depth", NULL);
@@ -946,7 +1339,37 @@ static int fsl_ssi_probe(struct platform_device *pdev)
946 /* Older 8610 DTs didn't have the fifo-depth property */ 1339 /* Older 8610 DTs didn't have the fifo-depth property */
947 ssi_private->fifo_depth = 8; 1340 ssi_private->fifo_depth = 8;
948 1341
949 if (of_device_is_compatible(pdev->dev.of_node, "fsl,imx21-ssi")) { 1342 ssi_private->baudclk_locked = false;
1343 spin_lock_init(&ssi_private->baudclk_lock);
1344
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) {
950 u32 dma_events[2]; 1373 u32 dma_events[2];
951 ssi_private->ssi_on_imx = true; 1374 ssi_private->ssi_on_imx = true;
952 1375
@@ -963,6 +1386,16 @@ static int fsl_ssi_probe(struct platform_device *pdev)
963 goto error_irqmap; 1386 goto error_irqmap;
964 } 1387 }
965 1388
1389 /* For those SLAVE implementations, we ingore non-baudclk cases
1390 * and, instead, abandon MASTER mode that needs baud clock.
1391 */
1392 ssi_private->baudclk = devm_clk_get(&pdev->dev, "baud");
1393 if (IS_ERR(ssi_private->baudclk))
1394 dev_warn(&pdev->dev, "could not get baud clock: %ld\n",
1395 PTR_ERR(ssi_private->baudclk));
1396 else
1397 clk_prepare_enable(ssi_private->baudclk);
1398
966 /* 1399 /*
967 * We have burstsize be "fifo_depth - 2" to match the SSI 1400 * We have burstsize be "fifo_depth - 2" to match the SSI
968 * watermark setting in fsl_ssi_startup(). 1401 * watermark setting in fsl_ssi_startup().
@@ -1001,32 +1434,25 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1001 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); 1434 dma_events[0], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1002 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx, 1435 imx_pcm_dma_params_init_data(&ssi_private->filter_data_rx,
1003 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI); 1436 dma_events[1], shared ? IMX_DMATYPE_SSI_SP : IMX_DMATYPE_SSI);
1004 } 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) {
1005 /* The 'name' should not have any slashes in it. */ 1444 /* The 'name' should not have any slashes in it. */
1006 ret = devm_request_irq(&pdev->dev, ssi_private->irq, 1445 ret = devm_request_irq(&pdev->dev, ssi_private->irq,
1007 fsl_ssi_isr, 0, ssi_private->name, 1446 fsl_ssi_isr, 0, ssi_private->name,
1008 ssi_private); 1447 ssi_private);
1448 ssi_private->irq_stats = true;
1009 if (ret < 0) { 1449 if (ret < 0) {
1010 dev_err(&pdev->dev, "could not claim irq %u\n", 1450 dev_err(&pdev->dev, "could not claim irq %u\n",
1011 ssi_private->irq); 1451 ssi_private->irq);
1012 goto error_irqmap; 1452 goto error_clk;
1013 } 1453 }
1014 } 1454 }
1015 1455
1016 /* Initialize the the device_attribute structure */
1017 dev_attr = &ssi_private->dev_attr;
1018 sysfs_attr_init(&dev_attr->attr);
1019 dev_attr->attr.name = "statistics";
1020 dev_attr->attr.mode = S_IRUGO;
1021 dev_attr->show = fsl_sysfs_ssi_show;
1022
1023 ret = device_create_file(&pdev->dev, dev_attr);
1024 if (ret) {
1025 dev_err(&pdev->dev, "could not create sysfs %s file\n",
1026 ssi_private->dev_attr.attr.name);
1027 goto error_clk;
1028 }
1029
1030 /* Register with ASoC */ 1456 /* Register with ASoC */
1031 dev_set_drvdata(&pdev->dev, ssi_private); 1457 dev_set_drvdata(&pdev->dev, ssi_private);
1032 1458
@@ -1037,6 +1463,10 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1037 goto error_dev; 1463 goto error_dev;
1038 } 1464 }
1039 1465
1466 ret = fsl_ssi_debugfs_create(ssi_private, &pdev->dev);
1467 if (ret)
1468 goto error_dbgfs;
1469
1040 if (ssi_private->ssi_on_imx) { 1470 if (ssi_private->ssi_on_imx) {
1041 if (!ssi_private->use_dma) { 1471 if (!ssi_private->use_dma) {
1042 1472
@@ -1056,11 +1486,11 @@ static int fsl_ssi_probe(struct platform_device *pdev)
1056 1486
1057 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params); 1487 ret = imx_pcm_fiq_init(pdev, &ssi_private->fiq_params);
1058 if (ret) 1488 if (ret)
1059 goto error_dev; 1489 goto error_pcm;
1060 } else { 1490 } else {
1061 ret = imx_pcm_dma_init(pdev); 1491 ret = imx_pcm_dma_init(pdev);
1062 if (ret) 1492 if (ret)
1063 goto error_dev; 1493 goto error_pcm;
1064 } 1494 }
1065 } 1495 }
1066 1496
@@ -1102,19 +1532,28 @@ done:
1102 return 0; 1532 return 0;
1103 1533
1104error_dai: 1534error_dai:
1105 if (ssi_private->ssi_on_imx) 1535 if (ssi_private->ssi_on_imx && !ssi_private->use_dma)
1106 imx_pcm_dma_exit(pdev); 1536 imx_pcm_fiq_exit(pdev);
1537
1538error_pcm:
1539 fsl_ssi_debugfs_remove(ssi_private);
1540
1541error_dbgfs:
1107 snd_soc_unregister_component(&pdev->dev); 1542 snd_soc_unregister_component(&pdev->dev);
1108 1543
1109error_dev: 1544error_dev:
1110 device_remove_file(&pdev->dev, dev_attr); 1545 device_remove_file(&pdev->dev, dev_attr);
1111 1546
1112error_clk: 1547error_clk:
1113 if (ssi_private->ssi_on_imx) 1548 if (ssi_private->ssi_on_imx) {
1549 if (!IS_ERR(ssi_private->baudclk))
1550 clk_disable_unprepare(ssi_private->baudclk);
1114 clk_disable_unprepare(ssi_private->clk); 1551 clk_disable_unprepare(ssi_private->clk);
1552 }
1115 1553
1116error_irqmap: 1554error_irqmap:
1117 irq_dispose_mapping(ssi_private->irq); 1555 if (ssi_private->irq_stats)
1556 irq_dispose_mapping(ssi_private->irq);
1118 1557
1119 return ret; 1558 return ret;
1120} 1559}
@@ -1123,26 +1562,22 @@ static int fsl_ssi_remove(struct platform_device *pdev)
1123{ 1562{
1124 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev); 1563 struct fsl_ssi_private *ssi_private = dev_get_drvdata(&pdev->dev);
1125 1564
1565 fsl_ssi_debugfs_remove(ssi_private);
1566
1126 if (!ssi_private->new_binding) 1567 if (!ssi_private->new_binding)
1127 platform_device_unregister(ssi_private->pdev); 1568 platform_device_unregister(ssi_private->pdev);
1128 if (ssi_private->ssi_on_imx)
1129 imx_pcm_dma_exit(pdev);
1130 snd_soc_unregister_component(&pdev->dev); 1569 snd_soc_unregister_component(&pdev->dev);
1131 device_remove_file(&pdev->dev, &ssi_private->dev_attr); 1570 if (ssi_private->ssi_on_imx) {
1132 if (ssi_private->ssi_on_imx) 1571 if (!IS_ERR(ssi_private->baudclk))
1572 clk_disable_unprepare(ssi_private->baudclk);
1133 clk_disable_unprepare(ssi_private->clk); 1573 clk_disable_unprepare(ssi_private->clk);
1134 irq_dispose_mapping(ssi_private->irq); 1574 }
1575 if (ssi_private->irq_stats)
1576 irq_dispose_mapping(ssi_private->irq);
1135 1577
1136 return 0; 1578 return 0;
1137} 1579}
1138 1580
1139static const struct of_device_id fsl_ssi_ids[] = {
1140 { .compatible = "fsl,mpc8610-ssi", },
1141 { .compatible = "fsl,imx21-ssi", },
1142 {}
1143};
1144MODULE_DEVICE_TABLE(of, fsl_ssi_ids);
1145
1146static struct platform_driver fsl_ssi_driver = { 1581static struct platform_driver fsl_ssi_driver = {
1147 .driver = { 1582 .driver = {
1148 .name = "fsl-ssi-dai", 1583 .name = "fsl-ssi-dai",
diff --git a/sound/soc/fsl/fsl_ssi.h b/sound/soc/fsl/fsl_ssi.h
index e6b9a69e2a68..e6b63240a3d7 100644
--- a/sound/soc/fsl/fsl_ssi.h
+++ b/sound/soc/fsl/fsl_ssi.h
@@ -125,7 +125,9 @@ struct ccsr_ssi {
125#define CCSR_SSI_SRCR_REFS 0x00000001 125#define CCSR_SSI_SRCR_REFS 0x00000001
126 126
127/* STCCR and SRCCR */ 127/* STCCR and SRCCR */
128#define CCSR_SSI_SxCCR_DIV2_SHIFT 18
128#define CCSR_SSI_SxCCR_DIV2 0x00040000 129#define CCSR_SSI_SxCCR_DIV2 0x00040000
130#define CCSR_SSI_SxCCR_PSR_SHIFT 17
129#define CCSR_SSI_SxCCR_PSR 0x00020000 131#define CCSR_SSI_SxCCR_PSR 0x00020000
130#define CCSR_SSI_SxCCR_WL_SHIFT 13 132#define CCSR_SSI_SxCCR_WL_SHIFT 13
131#define CCSR_SSI_SxCCR_WL_MASK 0x0001E000 133#define CCSR_SSI_SxCCR_WL_MASK 0x0001E000
diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index aee23077080a..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 */
@@ -61,16 +58,11 @@ static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
61 58
62int imx_pcm_dma_init(struct platform_device *pdev) 59int imx_pcm_dma_init(struct platform_device *pdev)
63{ 60{
64 return snd_dmaengine_pcm_register(&pdev->dev, &imx_dmaengine_pcm_config, 61 return devm_snd_dmaengine_pcm_register(&pdev->dev,
62 &imx_dmaengine_pcm_config,
65 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE | 63 SND_DMAENGINE_PCM_FLAG_NO_RESIDUE |
66 SND_DMAENGINE_PCM_FLAG_COMPAT); 64 SND_DMAENGINE_PCM_FLAG_COMPAT);
67} 65}
68EXPORT_SYMBOL_GPL(imx_pcm_dma_init); 66EXPORT_SYMBOL_GPL(imx_pcm_dma_init);
69 67
70void imx_pcm_dma_exit(struct platform_device *pdev)
71{
72 snd_dmaengine_pcm_unregister(&pdev->dev);
73}
74EXPORT_SYMBOL_GPL(imx_pcm_dma_exit);
75
76MODULE_LICENSE("GPL"); 68MODULE_LICENSE("GPL");
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/imx-pcm.h b/sound/soc/fsl/imx-pcm.h
index 5d5b73303e11..c79cb27473be 100644
--- a/sound/soc/fsl/imx-pcm.h
+++ b/sound/soc/fsl/imx-pcm.h
@@ -40,16 +40,11 @@ struct imx_pcm_fiq_params {
40 40
41#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA) 41#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_DMA)
42int imx_pcm_dma_init(struct platform_device *pdev); 42int imx_pcm_dma_init(struct platform_device *pdev);
43void imx_pcm_dma_exit(struct platform_device *pdev);
44#else 43#else
45static inline int imx_pcm_dma_init(struct platform_device *pdev) 44static inline int imx_pcm_dma_init(struct platform_device *pdev)
46{ 45{
47 return -ENODEV; 46 return -ENODEV;
48} 47}
49
50static inline void imx_pcm_dma_exit(struct platform_device *pdev)
51{
52}
53#endif 48#endif
54 49
55#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ) 50#if IS_ENABLED(CONFIG_SND_SOC_IMX_PCM_FIQ)
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
index 8499d5292f08..e1dc40143600 100644
--- a/sound/soc/fsl/imx-spdif.c
+++ b/sound/soc/fsl/imx-spdif.c
@@ -14,17 +14,15 @@
14#include <sound/soc.h> 14#include <sound/soc.h>
15 15
16struct imx_spdif_data { 16struct imx_spdif_data {
17 struct snd_soc_dai_link dai[2]; 17 struct snd_soc_dai_link dai;
18 struct snd_soc_card card; 18 struct snd_soc_card card;
19 struct platform_device *txdev;
20 struct platform_device *rxdev;
21}; 19};
22 20
23static int imx_spdif_audio_probe(struct platform_device *pdev) 21static int imx_spdif_audio_probe(struct platform_device *pdev)
24{ 22{
25 struct device_node *spdif_np, *np = pdev->dev.of_node; 23 struct device_node *spdif_np, *np = pdev->dev.of_node;
26 struct imx_spdif_data *data; 24 struct imx_spdif_data *data;
27 int ret = 0, num_links = 0; 25 int ret = 0;
28 26
29 spdif_np = of_parse_phandle(np, "spdif-controller", 0); 27 spdif_np = of_parse_phandle(np, "spdif-controller", 0);
30 if (!spdif_np) { 28 if (!spdif_np) {
@@ -35,74 +33,46 @@ static int imx_spdif_audio_probe(struct platform_device *pdev)
35 33
36 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); 34 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
37 if (!data) { 35 if (!data) {
38 dev_err(&pdev->dev, "failed to allocate memory\n");
39 ret = -ENOMEM; 36 ret = -ENOMEM;
40 goto end; 37 goto end;
41 } 38 }
42 39
43 if (of_property_read_bool(np, "spdif-out")) { 40 data->dai.name = "S/PDIF PCM";
44 data->dai[num_links].name = "S/PDIF TX"; 41 data->dai.stream_name = "S/PDIF PCM";
45 data->dai[num_links].stream_name = "S/PDIF PCM Playback"; 42 data->dai.codec_dai_name = "snd-soc-dummy-dai";
46 data->dai[num_links].codec_dai_name = "dit-hifi"; 43 data->dai.codec_name = "snd-soc-dummy";
47 data->dai[num_links].codec_name = "spdif-dit"; 44 data->dai.cpu_of_node = spdif_np;
48 data->dai[num_links].cpu_of_node = spdif_np; 45 data->dai.platform_of_node = spdif_np;
49 data->dai[num_links].platform_of_node = spdif_np; 46 data->dai.playback_only = true;
50 num_links++; 47 data->dai.capture_only = true;
51
52 data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0);
53 if (IS_ERR(data->txdev)) {
54 ret = PTR_ERR(data->txdev);
55 dev_err(&pdev->dev, "register dit failed: %d\n", ret);
56 goto end;
57 }
58 }
59 48
60 if (of_property_read_bool(np, "spdif-in")) { 49 if (of_property_read_bool(np, "spdif-out"))
61 data->dai[num_links].name = "S/PDIF RX"; 50 data->dai.capture_only = false;
62 data->dai[num_links].stream_name = "S/PDIF PCM Capture"; 51
63 data->dai[num_links].codec_dai_name = "dir-hifi"; 52 if (of_property_read_bool(np, "spdif-in"))
64 data->dai[num_links].codec_name = "spdif-dir"; 53 data->dai.playback_only = false;
65 data->dai[num_links].cpu_of_node = spdif_np;
66 data->dai[num_links].platform_of_node = spdif_np;
67 num_links++;
68
69 data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0);
70 if (IS_ERR(data->rxdev)) {
71 ret = PTR_ERR(data->rxdev);
72 dev_err(&pdev->dev, "register dir failed: %d\n", ret);
73 goto error_dit;
74 }
75 }
76 54
77 if (!num_links) { 55 if (data->dai.playback_only && data->dai.capture_only) {
78 dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n"); 56 dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n");
79 goto error_dir; 57 goto end;
80 } 58 }
81 59
82 data->card.dev = &pdev->dev; 60 data->card.dev = &pdev->dev;
83 data->card.num_links = num_links; 61 data->card.dai_link = &data->dai;
84 data->card.dai_link = data->dai; 62 data->card.num_links = 1;
85 63
86 ret = snd_soc_of_parse_card_name(&data->card, "model"); 64 ret = snd_soc_of_parse_card_name(&data->card, "model");
87 if (ret) 65 if (ret)
88 goto error_dir; 66 goto end;
89 67
90 ret = devm_snd_soc_register_card(&pdev->dev, &data->card); 68 ret = devm_snd_soc_register_card(&pdev->dev, &data->card);
91 if (ret) { 69 if (ret) {
92 dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret); 70 dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
93 goto error_dir; 71 goto end;
94 } 72 }
95 73
96 platform_set_drvdata(pdev, data); 74 platform_set_drvdata(pdev, data);
97 75
98 goto end;
99
100error_dir:
101 if (data->rxdev)
102 platform_device_unregister(data->rxdev);
103error_dit:
104 if (data->txdev)
105 platform_device_unregister(data->txdev);
106end: 76end:
107 if (spdif_np) 77 if (spdif_np)
108 of_node_put(spdif_np); 78 of_node_put(spdif_np);
@@ -110,18 +80,6 @@ end:
110 return ret; 80 return ret;
111} 81}
112 82
113static int imx_spdif_audio_remove(struct platform_device *pdev)
114{
115 struct imx_spdif_data *data = platform_get_drvdata(pdev);
116
117 if (data->rxdev)
118 platform_device_unregister(data->rxdev);
119 if (data->txdev)
120 platform_device_unregister(data->txdev);
121
122 return 0;
123}
124
125static const struct of_device_id imx_spdif_dt_ids[] = { 83static const struct of_device_id imx_spdif_dt_ids[] = {
126 { .compatible = "fsl,imx-audio-spdif", }, 84 { .compatible = "fsl,imx-audio-spdif", },
127 { /* sentinel */ } 85 { /* sentinel */ }
@@ -135,7 +93,6 @@ static struct platform_driver imx_spdif_driver = {
135 .of_match_table = imx_spdif_dt_ids, 93 .of_match_table = imx_spdif_dt_ids,
136 }, 94 },
137 .probe = imx_spdif_audio_probe, 95 .probe = imx_spdif_audio_probe,
138 .remove = imx_spdif_audio_remove,
139}; 96};
140 97
141module_platform_driver(imx_spdif_driver); 98module_platform_driver(imx_spdif_driver);
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c
index f5f248c91c16..df552fa1aa65 100644
--- a/sound/soc/fsl/imx-ssi.c
+++ b/sound/soc/fsl/imx-ssi.c
@@ -304,8 +304,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
304 scr |= SSI_SCR_RE; 304 scr |= SSI_SCR_RE;
305 sier |= sier_bits; 305 sier |= sier_bits;
306 306
307 if (++ssi->enabled == 1) 307 scr |= SSI_SCR_SSIEN;
308 scr |= SSI_SCR_SSIEN;
309 308
310 break; 309 break;
311 310
@@ -318,7 +317,7 @@ static int imx_ssi_trigger(struct snd_pcm_substream *substream, int cmd,
318 scr &= ~SSI_SCR_RE; 317 scr &= ~SSI_SCR_RE;
319 sier &= ~sier_bits; 318 sier &= ~sier_bits;
320 319
321 if (--ssi->enabled == 0) 320 if (!(scr & (SSI_SCR_TE | SSI_SCR_RE)))
322 scr &= ~SSI_SCR_SSIEN; 321 scr &= ~SSI_SCR_SSIEN;
323 322
324 break; 323 break;
@@ -536,7 +535,9 @@ static int imx_ssi_probe(struct platform_device *pdev)
536 ret); 535 ret);
537 goto failed_clk; 536 goto failed_clk;
538 } 537 }
539 clk_prepare_enable(ssi->clk); 538 ret = clk_prepare_enable(ssi->clk);
539 if (ret)
540 goto failed_clk;
540 541
541 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 542 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
542 ssi->base = devm_ioremap_resource(&pdev->dev, res); 543 ssi->base = devm_ioremap_resource(&pdev->dev, res);
@@ -624,9 +625,6 @@ static int imx_ssi_remove(struct platform_device *pdev)
624{ 625{
625 struct imx_ssi *ssi = platform_get_drvdata(pdev); 626 struct imx_ssi *ssi = platform_get_drvdata(pdev);
626 627
627 if (!ssi->dma_init)
628 imx_pcm_dma_exit(pdev);
629
630 if (!ssi->fiq_init) 628 if (!ssi->fiq_init)
631 imx_pcm_fiq_exit(pdev); 629 imx_pcm_fiq_exit(pdev);
632 630
diff --git a/sound/soc/fsl/imx-ssi.h b/sound/soc/fsl/imx-ssi.h
index 560c40fc9ebb..be6562365b6a 100644
--- a/sound/soc/fsl/imx-ssi.h
+++ b/sound/soc/fsl/imx-ssi.h
@@ -213,7 +213,6 @@ struct imx_ssi {
213 213
214 int fiq_init; 214 int fiq_init;
215 int dma_init; 215 int dma_init;
216 int enabled;
217}; 216};
218 217
219#endif /* _IMX_SSI_H */ 218#endif /* _IMX_SSI_H */
diff --git a/sound/soc/fsl/imx-wm8962.c b/sound/soc/fsl/imx-wm8962.c
index 61e48852b9e8..3fd76bc391de 100644
--- a/sound/soc/fsl/imx-wm8962.c
+++ b/sound/soc/fsl/imx-wm8962.c
@@ -130,8 +130,6 @@ static int imx_wm8962_set_bias_level(struct snd_soc_card *card,
130 break; 130 break;
131 } 131 }
132 132
133 dapm->bias_level = level;
134
135 return 0; 133 return 0;
136} 134}
137 135
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,
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index f4efaadb80a2..5d07e8a74a21 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -26,8 +26,7 @@
26 * ALSA that we support all rates and let the codec driver decide what rates 26 * ALSA that we support all rates and let the codec driver decide what rates
27 * are really supported. 27 * are really supported.
28 */ 28 */
29#define PSC_I2S_RATES (SNDRV_PCM_RATE_5512 | SNDRV_PCM_RATE_8000_192000 | \ 29#define PSC_I2S_RATES SNDRV_PCM_RATE_CONTINUOUS
30 SNDRV_PCM_RATE_CONTINUOUS)
31 30
32/** 31/**
33 * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode 32 * PSC_I2S_FORMATS: audio formats supported by the PSC I2S mode
diff --git a/sound/soc/fsl/pcm030-audio-fabric.c b/sound/soc/fsl/pcm030-audio-fabric.c
index eb4373840bb6..3665f612819d 100644
--- a/sound/soc/fsl/pcm030-audio-fabric.c
+++ b/sound/soc/fsl/pcm030-audio-fabric.c
@@ -69,7 +69,6 @@ static int pcm030_fabric_probe(struct platform_device *op)
69 return -ENOMEM; 69 return -ENOMEM;
70 70
71 card->dev = &op->dev; 71 card->dev = &op->dev;
72 platform_set_drvdata(op, pdata);
73 72
74 pdata->card = card; 73 pdata->card = card;
75 74
@@ -98,6 +97,8 @@ static int pcm030_fabric_probe(struct platform_device *op)
98 if (ret) 97 if (ret)
99 dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret); 98 dev_err(&op->dev, "snd_soc_register_card() failed: %d\n", ret);
100 99
100 platform_set_drvdata(op, pdata);
101
101 return ret; 102 return ret;
102} 103}
103 104