xref: /openbmc/linux/sound/soc/fsl/fsl_esai.c (revision d3964221)
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_FORMATS	(SNDRV_PCM_FMTBIT_S8 | \
23 				SNDRV_PCM_FMTBIT_S16_LE | \
24 				SNDRV_PCM_FMTBIT_S20_3LE | \
25 				SNDRV_PCM_FMTBIT_S24_LE)
26 
27 /**
28  * fsl_esai: ESAI private data
29  *
30  * @dma_params_rx: DMA parameters for receive channel
31  * @dma_params_tx: DMA parameters for transmit channel
32  * @pdev: platform device pointer
33  * @regmap: regmap handler
34  * @coreclk: clock source to access register
35  * @extalclk: esai clock source to derive HCK, SCK and FS
36  * @fsysclk: system clock source to derive HCK, SCK and FS
37  * @spbaclk: SPBA clock (optional, depending on SoC design)
38  * @fifo_depth: depth of tx/rx FIFO
39  * @slot_width: width of each DAI slot
40  * @slots: number of slots
41  * @hck_rate: clock rate of desired HCKx clock
42  * @sck_rate: clock rate of desired SCKx clock
43  * @hck_dir: the direction of HCKx pads
44  * @sck_div: if using PSR/PM dividers for SCKx clock
45  * @slave_mode: if fully using DAI slave mode
46  * @synchronous: if using tx/rx synchronous mode
47  * @name: driver name
48  */
49 struct fsl_esai {
50 	struct snd_dmaengine_dai_dma_data dma_params_rx;
51 	struct snd_dmaengine_dai_dma_data dma_params_tx;
52 	struct platform_device *pdev;
53 	struct regmap *regmap;
54 	struct clk *coreclk;
55 	struct clk *extalclk;
56 	struct clk *fsysclk;
57 	struct clk *spbaclk;
58 	u32 fifo_depth;
59 	u32 slot_width;
60 	u32 slots;
61 	u32 hck_rate[2];
62 	u32 sck_rate[2];
63 	bool hck_dir[2];
64 	bool sck_div[2];
65 	bool slave_mode;
66 	bool synchronous;
67 	char name[32];
68 };
69 
70 static irqreturn_t esai_isr(int irq, void *devid)
71 {
72 	struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
73 	struct platform_device *pdev = esai_priv->pdev;
74 	u32 esr;
75 
76 	regmap_read(esai_priv->regmap, REG_ESAI_ESR, &esr);
77 
78 	if (esr & ESAI_ESR_TINIT_MASK)
79 		dev_dbg(&pdev->dev, "isr: Transmission Initialized\n");
80 
81 	if (esr & ESAI_ESR_RFF_MASK)
82 		dev_warn(&pdev->dev, "isr: Receiving overrun\n");
83 
84 	if (esr & ESAI_ESR_TFE_MASK)
85 		dev_warn(&pdev->dev, "isr: Transmission underrun\n");
86 
87 	if (esr & ESAI_ESR_TLS_MASK)
88 		dev_dbg(&pdev->dev, "isr: Just transmitted the last slot\n");
89 
90 	if (esr & ESAI_ESR_TDE_MASK)
91 		dev_dbg(&pdev->dev, "isr: Transmission data exception\n");
92 
93 	if (esr & ESAI_ESR_TED_MASK)
94 		dev_dbg(&pdev->dev, "isr: Transmitting even slots\n");
95 
96 	if (esr & ESAI_ESR_TD_MASK)
97 		dev_dbg(&pdev->dev, "isr: Transmitting data\n");
98 
99 	if (esr & ESAI_ESR_RLS_MASK)
100 		dev_dbg(&pdev->dev, "isr: Just received the last slot\n");
101 
102 	if (esr & ESAI_ESR_RDE_MASK)
103 		dev_dbg(&pdev->dev, "isr: Receiving data exception\n");
104 
105 	if (esr & ESAI_ESR_RED_MASK)
106 		dev_dbg(&pdev->dev, "isr: Receiving even slots\n");
107 
108 	if (esr & ESAI_ESR_RD_MASK)
109 		dev_dbg(&pdev->dev, "isr: Receiving data\n");
110 
111 	return IRQ_HANDLED;
112 }
113 
114 /**
115  * This function is used to calculate the divisors of psr, pm, fp and it is
116  * supposed to be called in set_dai_sysclk() and set_bclk().
117  *
118  * @ratio: desired overall ratio for the paticipating dividers
119  * @usefp: for HCK setting, there is no need to set fp divider
120  * @fp: bypass other dividers by setting fp directly if fp != 0
121  * @tx: current setting is for playback or capture
122  */
123 static int fsl_esai_divisor_cal(struct snd_soc_dai *dai, bool tx, u32 ratio,
124 				bool usefp, u32 fp)
125 {
126 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
127 	u32 psr, pm = 999, maxfp, prod, sub, savesub, i, j;
128 
129 	maxfp = usefp ? 16 : 1;
130 
131 	if (usefp && fp)
132 		goto out_fp;
133 
134 	if (ratio > 2 * 8 * 256 * maxfp || ratio < 2) {
135 		dev_err(dai->dev, "the ratio is out of range (2 ~ %d)\n",
136 				2 * 8 * 256 * maxfp);
137 		return -EINVAL;
138 	} else if (ratio % 2) {
139 		dev_err(dai->dev, "the raio must be even if using upper divider\n");
140 		return -EINVAL;
141 	}
142 
143 	ratio /= 2;
144 
145 	psr = ratio <= 256 * maxfp ? ESAI_xCCR_xPSR_BYPASS : ESAI_xCCR_xPSR_DIV8;
146 
147 	/* Set the max fluctuation -- 0.1% of the max devisor */
148 	savesub = (psr ? 1 : 8)  * 256 * maxfp / 1000;
149 
150 	/* Find the best value for PM */
151 	for (i = 1; i <= 256; i++) {
152 		for (j = 1; j <= maxfp; j++) {
153 			/* PSR (1 or 8) * PM (1 ~ 256) * FP (1 ~ 16) */
154 			prod = (psr ? 1 : 8) * i * j;
155 
156 			if (prod == ratio)
157 				sub = 0;
158 			else if (prod / ratio == 1)
159 				sub = prod - ratio;
160 			else if (ratio / prod == 1)
161 				sub = ratio - prod;
162 			else
163 				continue;
164 
165 			/* Calculate the fraction */
166 			sub = sub * 1000 / ratio;
167 			if (sub < savesub) {
168 				savesub = sub;
169 				pm = i;
170 				fp = j;
171 			}
172 
173 			/* We are lucky */
174 			if (savesub == 0)
175 				goto out;
176 		}
177 	}
178 
179 	if (pm == 999) {
180 		dev_err(dai->dev, "failed to calculate proper divisors\n");
181 		return -EINVAL;
182 	}
183 
184 out:
185 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
186 			   ESAI_xCCR_xPSR_MASK | ESAI_xCCR_xPM_MASK,
187 			   psr | ESAI_xCCR_xPM(pm));
188 
189 out_fp:
190 	/* Bypass fp if not being required */
191 	if (maxfp <= 1)
192 		return 0;
193 
194 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
195 			   ESAI_xCCR_xFP_MASK, ESAI_xCCR_xFP(fp));
196 
197 	return 0;
198 }
199 
200 /**
201  * This function mainly configures the clock frequency of MCLK (HCKT/HCKR)
202  *
203  * @Parameters:
204  * clk_id: The clock source of HCKT/HCKR
205  *	  (Input from outside; output from inside, FSYS or EXTAL)
206  * freq: The required clock rate of HCKT/HCKR
207  * dir: The clock direction of HCKT/HCKR
208  *
209  * Note: If the direction is input, we do not care about clk_id.
210  */
211 static int fsl_esai_set_dai_sysclk(struct snd_soc_dai *dai, int clk_id,
212 				   unsigned int freq, int dir)
213 {
214 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
215 	struct clk *clksrc = esai_priv->extalclk;
216 	bool tx = clk_id <= ESAI_HCKT_EXTAL;
217 	bool in = dir == SND_SOC_CLOCK_IN;
218 	u32 ratio, ecr = 0;
219 	unsigned long clk_rate;
220 	int ret;
221 
222 	/* Bypass divider settings if the requirement doesn't change */
223 	if (freq == esai_priv->hck_rate[tx] && dir == esai_priv->hck_dir[tx])
224 		return 0;
225 
226 	/* sck_div can be only bypassed if ETO/ERO=0 and SNC_SOC_CLOCK_OUT */
227 	esai_priv->sck_div[tx] = true;
228 
229 	/* Set the direction of HCKT/HCKR pins */
230 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xCCR(tx),
231 			   ESAI_xCCR_xHCKD, in ? 0 : ESAI_xCCR_xHCKD);
232 
233 	if (in)
234 		goto out;
235 
236 	switch (clk_id) {
237 	case ESAI_HCKT_FSYS:
238 	case ESAI_HCKR_FSYS:
239 		clksrc = esai_priv->fsysclk;
240 		break;
241 	case ESAI_HCKT_EXTAL:
242 		ecr |= ESAI_ECR_ETI;
243 	case ESAI_HCKR_EXTAL:
244 		ecr |= ESAI_ECR_ERI;
245 		break;
246 	default:
247 		return -EINVAL;
248 	}
249 
250 	if (IS_ERR(clksrc)) {
251 		dev_err(dai->dev, "no assigned %s clock\n",
252 				clk_id % 2 ? "extal" : "fsys");
253 		return PTR_ERR(clksrc);
254 	}
255 	clk_rate = clk_get_rate(clksrc);
256 
257 	ratio = clk_rate / freq;
258 	if (ratio * freq > clk_rate)
259 		ret = ratio * freq - clk_rate;
260 	else if (ratio * freq < clk_rate)
261 		ret = clk_rate - ratio * freq;
262 	else
263 		ret = 0;
264 
265 	/* Block if clock source can not be divided into the required rate */
266 	if (ret != 0 && clk_rate / ret < 1000) {
267 		dev_err(dai->dev, "failed to derive required HCK%c rate\n",
268 				tx ? 'T' : 'R');
269 		return -EINVAL;
270 	}
271 
272 	/* Only EXTAL source can be output directly without using PSR and PM */
273 	if (ratio == 1 && clksrc == esai_priv->extalclk) {
274 		/* Bypass all the dividers if not being needed */
275 		ecr |= tx ? ESAI_ECR_ETO : ESAI_ECR_ERO;
276 		goto out;
277 	} else if (ratio < 2) {
278 		/* The ratio should be no less than 2 if using other sources */
279 		dev_err(dai->dev, "failed to derive required HCK%c rate\n",
280 				tx ? 'T' : 'R');
281 		return -EINVAL;
282 	}
283 
284 	ret = fsl_esai_divisor_cal(dai, tx, ratio, false, 0);
285 	if (ret)
286 		return ret;
287 
288 	esai_priv->sck_div[tx] = false;
289 
290 out:
291 	esai_priv->hck_dir[tx] = dir;
292 	esai_priv->hck_rate[tx] = freq;
293 
294 	regmap_update_bits(esai_priv->regmap, REG_ESAI_ECR,
295 			   tx ? ESAI_ECR_ETI | ESAI_ECR_ETO :
296 			   ESAI_ECR_ERI | ESAI_ECR_ERO, ecr);
297 
298 	return 0;
299 }
300 
301 /**
302  * This function configures the related dividers according to the bclk rate
303  */
304 static int fsl_esai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq)
305 {
306 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
307 	u32 hck_rate = esai_priv->hck_rate[tx];
308 	u32 sub, ratio = hck_rate / freq;
309 	int ret;
310 
311 	/* Don't apply for fully slave mode or unchanged bclk */
312 	if (esai_priv->slave_mode || esai_priv->sck_rate[tx] == freq)
313 		return 0;
314 
315 	if (ratio * freq > hck_rate)
316 		sub = ratio * freq - hck_rate;
317 	else if (ratio * freq < hck_rate)
318 		sub = hck_rate - ratio * freq;
319 	else
320 		sub = 0;
321 
322 	/* Block if clock source can not be divided into the required rate */
323 	if (sub != 0 && hck_rate / sub < 1000) {
324 		dev_err(dai->dev, "failed to derive required SCK%c rate\n",
325 				tx ? 'T' : 'R');
326 		return -EINVAL;
327 	}
328 
329 	/* The ratio should be contented by FP alone if bypassing PM and PSR */
330 	if (!esai_priv->sck_div[tx] && (ratio > 16 || ratio == 0)) {
331 		dev_err(dai->dev, "the ratio is out of range (1 ~ 16)\n");
332 		return -EINVAL;
333 	}
334 
335 	ret = fsl_esai_divisor_cal(dai, tx, ratio, true,
336 			esai_priv->sck_div[tx] ? 0 : ratio);
337 	if (ret)
338 		return ret;
339 
340 	/* Save current bclk rate */
341 	esai_priv->sck_rate[tx] = freq;
342 
343 	return 0;
344 }
345 
346 static int fsl_esai_set_dai_tdm_slot(struct snd_soc_dai *dai, u32 tx_mask,
347 				     u32 rx_mask, int slots, int slot_width)
348 {
349 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
350 
351 	regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
352 			   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
353 
354 	regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMA,
355 			   ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(tx_mask));
356 	regmap_update_bits(esai_priv->regmap, REG_ESAI_TSMB,
357 			   ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(tx_mask));
358 
359 	regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
360 			   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(slots));
361 
362 	regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMA,
363 			   ESAI_xSMA_xS_MASK, ESAI_xSMA_xS(rx_mask));
364 	regmap_update_bits(esai_priv->regmap, REG_ESAI_RSMB,
365 			   ESAI_xSMB_xS_MASK, ESAI_xSMB_xS(rx_mask));
366 
367 	esai_priv->slot_width = slot_width;
368 	esai_priv->slots = slots;
369 
370 	return 0;
371 }
372 
373 static int fsl_esai_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
374 {
375 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
376 	u32 xcr = 0, xccr = 0, mask;
377 
378 	/* DAI mode */
379 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
380 	case SND_SOC_DAIFMT_I2S:
381 		/* Data on rising edge of bclk, frame low, 1clk before data */
382 		xcr |= ESAI_xCR_xFSR;
383 		xccr |= ESAI_xCCR_xFSP | ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
384 		break;
385 	case SND_SOC_DAIFMT_LEFT_J:
386 		/* Data on rising edge of bclk, frame high */
387 		xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
388 		break;
389 	case SND_SOC_DAIFMT_RIGHT_J:
390 		/* Data on rising edge of bclk, frame high, right aligned */
391 		xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCR_xWA;
392 		break;
393 	case SND_SOC_DAIFMT_DSP_A:
394 		/* Data on rising edge of bclk, frame high, 1clk before data */
395 		xcr |= ESAI_xCR_xFSL | ESAI_xCR_xFSR;
396 		xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
397 		break;
398 	case SND_SOC_DAIFMT_DSP_B:
399 		/* Data on rising edge of bclk, frame high */
400 		xcr |= ESAI_xCR_xFSL;
401 		xccr |= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
402 		break;
403 	default:
404 		return -EINVAL;
405 	}
406 
407 	/* DAI clock inversion */
408 	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
409 	case SND_SOC_DAIFMT_NB_NF:
410 		/* Nothing to do for both normal cases */
411 		break;
412 	case SND_SOC_DAIFMT_IB_NF:
413 		/* Invert bit clock */
414 		xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP;
415 		break;
416 	case SND_SOC_DAIFMT_NB_IF:
417 		/* Invert frame clock */
418 		xccr ^= ESAI_xCCR_xFSP;
419 		break;
420 	case SND_SOC_DAIFMT_IB_IF:
421 		/* Invert both clocks */
422 		xccr ^= ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP;
423 		break;
424 	default:
425 		return -EINVAL;
426 	}
427 
428 	esai_priv->slave_mode = false;
429 
430 	/* DAI clock master masks */
431 	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
432 	case SND_SOC_DAIFMT_CBM_CFM:
433 		esai_priv->slave_mode = true;
434 		break;
435 	case SND_SOC_DAIFMT_CBS_CFM:
436 		xccr |= ESAI_xCCR_xCKD;
437 		break;
438 	case SND_SOC_DAIFMT_CBM_CFS:
439 		xccr |= ESAI_xCCR_xFSD;
440 		break;
441 	case SND_SOC_DAIFMT_CBS_CFS:
442 		xccr |= ESAI_xCCR_xFSD | ESAI_xCCR_xCKD;
443 		break;
444 	default:
445 		return -EINVAL;
446 	}
447 
448 	mask = ESAI_xCR_xFSL | ESAI_xCR_xFSR;
449 	regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR, mask, xcr);
450 	regmap_update_bits(esai_priv->regmap, REG_ESAI_RCR, mask, xcr);
451 
452 	mask = ESAI_xCCR_xCKP | ESAI_xCCR_xHCKP | ESAI_xCCR_xFSP |
453 		ESAI_xCCR_xFSD | ESAI_xCCR_xCKD | ESAI_xCR_xWA;
454 	regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR, mask, xccr);
455 	regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR, mask, xccr);
456 
457 	return 0;
458 }
459 
460 static int fsl_esai_startup(struct snd_pcm_substream *substream,
461 			    struct snd_soc_dai *dai)
462 {
463 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
464 	int ret;
465 
466 	/*
467 	 * Some platforms might use the same bit to gate all three or two of
468 	 * clocks, so keep all clocks open/close at the same time for safety
469 	 */
470 	ret = clk_prepare_enable(esai_priv->coreclk);
471 	if (ret)
472 		return ret;
473 	if (!IS_ERR(esai_priv->spbaclk)) {
474 		ret = clk_prepare_enable(esai_priv->spbaclk);
475 		if (ret)
476 			goto err_spbaclk;
477 	}
478 	if (!IS_ERR(esai_priv->extalclk)) {
479 		ret = clk_prepare_enable(esai_priv->extalclk);
480 		if (ret)
481 			goto err_extalck;
482 	}
483 	if (!IS_ERR(esai_priv->fsysclk)) {
484 		ret = clk_prepare_enable(esai_priv->fsysclk);
485 		if (ret)
486 			goto err_fsysclk;
487 	}
488 
489 	if (!dai->active) {
490 		/* Set synchronous mode */
491 		regmap_update_bits(esai_priv->regmap, REG_ESAI_SAICR,
492 				   ESAI_SAICR_SYNC, esai_priv->synchronous ?
493 				   ESAI_SAICR_SYNC : 0);
494 
495 		/* Set a default slot number -- 2 */
496 		regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
497 				   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
498 		regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
499 				   ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
500 	}
501 
502 	return 0;
503 
504 err_fsysclk:
505 	if (!IS_ERR(esai_priv->extalclk))
506 		clk_disable_unprepare(esai_priv->extalclk);
507 err_extalck:
508 	if (!IS_ERR(esai_priv->spbaclk))
509 		clk_disable_unprepare(esai_priv->spbaclk);
510 err_spbaclk:
511 	clk_disable_unprepare(esai_priv->coreclk);
512 
513 	return ret;
514 }
515 
516 static int fsl_esai_hw_params(struct snd_pcm_substream *substream,
517 			      struct snd_pcm_hw_params *params,
518 			      struct snd_soc_dai *dai)
519 {
520 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
521 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
522 	u32 width = params_width(params);
523 	u32 channels = params_channels(params);
524 	u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
525 	u32 slot_width = width;
526 	u32 bclk, mask, val;
527 	int ret;
528 
529 	/* Override slot_width if being specifically set */
530 	if (esai_priv->slot_width)
531 		slot_width = esai_priv->slot_width;
532 
533 	bclk = params_rate(params) * slot_width * esai_priv->slots;
534 
535 	ret = fsl_esai_set_bclk(dai, tx, bclk);
536 	if (ret)
537 		return ret;
538 
539 	/* Use Normal mode to support monaural audio */
540 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
541 			   ESAI_xCR_xMOD_MASK, params_channels(params) > 1 ?
542 			   ESAI_xCR_xMOD_NETWORK : 0);
543 
544 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
545 			   ESAI_xFCR_xFR_MASK, ESAI_xFCR_xFR);
546 
547 	mask = ESAI_xFCR_xFR_MASK | ESAI_xFCR_xWA_MASK | ESAI_xFCR_xFWM_MASK |
548 	      (tx ? ESAI_xFCR_TE_MASK | ESAI_xFCR_TIEN : ESAI_xFCR_RE_MASK);
549 	val = ESAI_xFCR_xWA(width) | ESAI_xFCR_xFWM(esai_priv->fifo_depth) |
550 	     (tx ? ESAI_xFCR_TE(pins) | ESAI_xFCR_TIEN : ESAI_xFCR_RE(pins));
551 
552 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx), mask, val);
553 
554 	mask = ESAI_xCR_xSWS_MASK | (tx ? ESAI_xCR_PADC : 0);
555 	val = ESAI_xCR_xSWS(slot_width, width) | (tx ? ESAI_xCR_PADC : 0);
556 
557 	regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx), mask, val);
558 
559 	/* Remove ESAI personal reset by configuring ESAI_PCRC and ESAI_PRRC */
560 	regmap_update_bits(esai_priv->regmap, REG_ESAI_PRRC,
561 			   ESAI_PRRC_PDC_MASK, ESAI_PRRC_PDC(ESAI_GPIO));
562 	regmap_update_bits(esai_priv->regmap, REG_ESAI_PCRC,
563 			   ESAI_PCRC_PC_MASK, ESAI_PCRC_PC(ESAI_GPIO));
564 	return 0;
565 }
566 
567 static void fsl_esai_shutdown(struct snd_pcm_substream *substream,
568 			      struct snd_soc_dai *dai)
569 {
570 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
571 
572 	if (!IS_ERR(esai_priv->fsysclk))
573 		clk_disable_unprepare(esai_priv->fsysclk);
574 	if (!IS_ERR(esai_priv->extalclk))
575 		clk_disable_unprepare(esai_priv->extalclk);
576 	if (!IS_ERR(esai_priv->spbaclk))
577 		clk_disable_unprepare(esai_priv->spbaclk);
578 	clk_disable_unprepare(esai_priv->coreclk);
579 }
580 
581 static int fsl_esai_trigger(struct snd_pcm_substream *substream, int cmd,
582 			    struct snd_soc_dai *dai)
583 {
584 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
585 	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
586 	u8 i, channels = substream->runtime->channels;
587 	u32 pins = DIV_ROUND_UP(channels, esai_priv->slots);
588 
589 	switch (cmd) {
590 	case SNDRV_PCM_TRIGGER_START:
591 	case SNDRV_PCM_TRIGGER_RESUME:
592 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
593 		regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
594 				   ESAI_xFCR_xFEN_MASK, ESAI_xFCR_xFEN);
595 
596 		/* Write initial words reqiured by ESAI as normal procedure */
597 		for (i = 0; tx && i < channels; i++)
598 			regmap_write(esai_priv->regmap, REG_ESAI_ETDR, 0x0);
599 
600 		regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
601 				   tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK,
602 				   tx ? ESAI_xCR_TE(pins) : ESAI_xCR_RE(pins));
603 		break;
604 	case SNDRV_PCM_TRIGGER_SUSPEND:
605 	case SNDRV_PCM_TRIGGER_STOP:
606 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
607 		regmap_update_bits(esai_priv->regmap, REG_ESAI_xCR(tx),
608 				   tx ? ESAI_xCR_TE_MASK : ESAI_xCR_RE_MASK, 0);
609 
610 		/* Disable and reset FIFO */
611 		regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
612 				   ESAI_xFCR_xFR | ESAI_xFCR_xFEN, ESAI_xFCR_xFR);
613 		regmap_update_bits(esai_priv->regmap, REG_ESAI_xFCR(tx),
614 				   ESAI_xFCR_xFR, 0);
615 		break;
616 	default:
617 		return -EINVAL;
618 	}
619 
620 	return 0;
621 }
622 
623 static const struct snd_soc_dai_ops fsl_esai_dai_ops = {
624 	.startup = fsl_esai_startup,
625 	.shutdown = fsl_esai_shutdown,
626 	.trigger = fsl_esai_trigger,
627 	.hw_params = fsl_esai_hw_params,
628 	.set_sysclk = fsl_esai_set_dai_sysclk,
629 	.set_fmt = fsl_esai_set_dai_fmt,
630 	.set_tdm_slot = fsl_esai_set_dai_tdm_slot,
631 };
632 
633 static int fsl_esai_dai_probe(struct snd_soc_dai *dai)
634 {
635 	struct fsl_esai *esai_priv = snd_soc_dai_get_drvdata(dai);
636 
637 	snd_soc_dai_init_dma_data(dai, &esai_priv->dma_params_tx,
638 				  &esai_priv->dma_params_rx);
639 
640 	return 0;
641 }
642 
643 static struct snd_soc_dai_driver fsl_esai_dai = {
644 	.probe = fsl_esai_dai_probe,
645 	.playback = {
646 		.stream_name = "CPU-Playback",
647 		.channels_min = 1,
648 		.channels_max = 12,
649 		.rates = SNDRV_PCM_RATE_8000_192000,
650 		.formats = FSL_ESAI_FORMATS,
651 	},
652 	.capture = {
653 		.stream_name = "CPU-Capture",
654 		.channels_min = 1,
655 		.channels_max = 8,
656 		.rates = SNDRV_PCM_RATE_8000_192000,
657 		.formats = FSL_ESAI_FORMATS,
658 	},
659 	.ops = &fsl_esai_dai_ops,
660 };
661 
662 static const struct snd_soc_component_driver fsl_esai_component = {
663 	.name		= "fsl-esai",
664 };
665 
666 static const struct reg_default fsl_esai_reg_defaults[] = {
667 	{REG_ESAI_ETDR,	 0x00000000},
668 	{REG_ESAI_ECR,	 0x00000000},
669 	{REG_ESAI_TFCR,	 0x00000000},
670 	{REG_ESAI_RFCR,	 0x00000000},
671 	{REG_ESAI_TX0,	 0x00000000},
672 	{REG_ESAI_TX1,	 0x00000000},
673 	{REG_ESAI_TX2,	 0x00000000},
674 	{REG_ESAI_TX3,	 0x00000000},
675 	{REG_ESAI_TX4,	 0x00000000},
676 	{REG_ESAI_TX5,	 0x00000000},
677 	{REG_ESAI_TSR,	 0x00000000},
678 	{REG_ESAI_SAICR, 0x00000000},
679 	{REG_ESAI_TCR,	 0x00000000},
680 	{REG_ESAI_TCCR,	 0x00000000},
681 	{REG_ESAI_RCR,	 0x00000000},
682 	{REG_ESAI_RCCR,	 0x00000000},
683 	{REG_ESAI_TSMA,  0x0000ffff},
684 	{REG_ESAI_TSMB,  0x0000ffff},
685 	{REG_ESAI_RSMA,  0x0000ffff},
686 	{REG_ESAI_RSMB,  0x0000ffff},
687 	{REG_ESAI_PRRC,  0x00000000},
688 	{REG_ESAI_PCRC,  0x00000000},
689 };
690 
691 static bool fsl_esai_readable_reg(struct device *dev, unsigned int reg)
692 {
693 	switch (reg) {
694 	case REG_ESAI_ERDR:
695 	case REG_ESAI_ECR:
696 	case REG_ESAI_ESR:
697 	case REG_ESAI_TFCR:
698 	case REG_ESAI_TFSR:
699 	case REG_ESAI_RFCR:
700 	case REG_ESAI_RFSR:
701 	case REG_ESAI_RX0:
702 	case REG_ESAI_RX1:
703 	case REG_ESAI_RX2:
704 	case REG_ESAI_RX3:
705 	case REG_ESAI_SAISR:
706 	case REG_ESAI_SAICR:
707 	case REG_ESAI_TCR:
708 	case REG_ESAI_TCCR:
709 	case REG_ESAI_RCR:
710 	case REG_ESAI_RCCR:
711 	case REG_ESAI_TSMA:
712 	case REG_ESAI_TSMB:
713 	case REG_ESAI_RSMA:
714 	case REG_ESAI_RSMB:
715 	case REG_ESAI_PRRC:
716 	case REG_ESAI_PCRC:
717 		return true;
718 	default:
719 		return false;
720 	}
721 }
722 
723 static bool fsl_esai_volatile_reg(struct device *dev, unsigned int reg)
724 {
725 	switch (reg) {
726 	case REG_ESAI_ERDR:
727 	case REG_ESAI_ESR:
728 	case REG_ESAI_TFSR:
729 	case REG_ESAI_RFSR:
730 	case REG_ESAI_RX0:
731 	case REG_ESAI_RX1:
732 	case REG_ESAI_RX2:
733 	case REG_ESAI_RX3:
734 	case REG_ESAI_SAISR:
735 		return true;
736 	default:
737 		return false;
738 	}
739 }
740 
741 static bool fsl_esai_writeable_reg(struct device *dev, unsigned int reg)
742 {
743 	switch (reg) {
744 	case REG_ESAI_ETDR:
745 	case REG_ESAI_ECR:
746 	case REG_ESAI_TFCR:
747 	case REG_ESAI_RFCR:
748 	case REG_ESAI_TX0:
749 	case REG_ESAI_TX1:
750 	case REG_ESAI_TX2:
751 	case REG_ESAI_TX3:
752 	case REG_ESAI_TX4:
753 	case REG_ESAI_TX5:
754 	case REG_ESAI_TSR:
755 	case REG_ESAI_SAICR:
756 	case REG_ESAI_TCR:
757 	case REG_ESAI_TCCR:
758 	case REG_ESAI_RCR:
759 	case REG_ESAI_RCCR:
760 	case REG_ESAI_TSMA:
761 	case REG_ESAI_TSMB:
762 	case REG_ESAI_RSMA:
763 	case REG_ESAI_RSMB:
764 	case REG_ESAI_PRRC:
765 	case REG_ESAI_PCRC:
766 		return true;
767 	default:
768 		return false;
769 	}
770 }
771 
772 static const struct regmap_config fsl_esai_regmap_config = {
773 	.reg_bits = 32,
774 	.reg_stride = 4,
775 	.val_bits = 32,
776 
777 	.max_register = REG_ESAI_PCRC,
778 	.reg_defaults = fsl_esai_reg_defaults,
779 	.num_reg_defaults = ARRAY_SIZE(fsl_esai_reg_defaults),
780 	.readable_reg = fsl_esai_readable_reg,
781 	.volatile_reg = fsl_esai_volatile_reg,
782 	.writeable_reg = fsl_esai_writeable_reg,
783 	.cache_type = REGCACHE_FLAT,
784 };
785 
786 static int fsl_esai_probe(struct platform_device *pdev)
787 {
788 	struct device_node *np = pdev->dev.of_node;
789 	struct fsl_esai *esai_priv;
790 	struct resource *res;
791 	const uint32_t *iprop;
792 	void __iomem *regs;
793 	int irq, ret;
794 
795 	esai_priv = devm_kzalloc(&pdev->dev, sizeof(*esai_priv), GFP_KERNEL);
796 	if (!esai_priv)
797 		return -ENOMEM;
798 
799 	esai_priv->pdev = pdev;
800 	strncpy(esai_priv->name, np->name, sizeof(esai_priv->name) - 1);
801 
802 	/* Get the addresses and IRQ */
803 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
804 	regs = devm_ioremap_resource(&pdev->dev, res);
805 	if (IS_ERR(regs))
806 		return PTR_ERR(regs);
807 
808 	esai_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
809 			"core", regs, &fsl_esai_regmap_config);
810 	if (IS_ERR(esai_priv->regmap)) {
811 		dev_err(&pdev->dev, "failed to init regmap: %ld\n",
812 				PTR_ERR(esai_priv->regmap));
813 		return PTR_ERR(esai_priv->regmap);
814 	}
815 
816 	esai_priv->coreclk = devm_clk_get(&pdev->dev, "core");
817 	if (IS_ERR(esai_priv->coreclk)) {
818 		dev_err(&pdev->dev, "failed to get core clock: %ld\n",
819 				PTR_ERR(esai_priv->coreclk));
820 		return PTR_ERR(esai_priv->coreclk);
821 	}
822 
823 	esai_priv->extalclk = devm_clk_get(&pdev->dev, "extal");
824 	if (IS_ERR(esai_priv->extalclk))
825 		dev_warn(&pdev->dev, "failed to get extal clock: %ld\n",
826 				PTR_ERR(esai_priv->extalclk));
827 
828 	esai_priv->fsysclk = devm_clk_get(&pdev->dev, "fsys");
829 	if (IS_ERR(esai_priv->fsysclk))
830 		dev_warn(&pdev->dev, "failed to get fsys clock: %ld\n",
831 				PTR_ERR(esai_priv->fsysclk));
832 
833 	esai_priv->spbaclk = devm_clk_get(&pdev->dev, "spba");
834 	if (IS_ERR(esai_priv->spbaclk))
835 		dev_warn(&pdev->dev, "failed to get spba clock: %ld\n",
836 				PTR_ERR(esai_priv->spbaclk));
837 
838 	irq = platform_get_irq(pdev, 0);
839 	if (irq < 0) {
840 		dev_err(&pdev->dev, "no irq for node %s\n", pdev->name);
841 		return irq;
842 	}
843 
844 	ret = devm_request_irq(&pdev->dev, irq, esai_isr, 0,
845 			       esai_priv->name, esai_priv);
846 	if (ret) {
847 		dev_err(&pdev->dev, "failed to claim irq %u\n", irq);
848 		return ret;
849 	}
850 
851 	/* Set a default slot number */
852 	esai_priv->slots = 2;
853 
854 	/* Set a default master/slave state */
855 	esai_priv->slave_mode = true;
856 
857 	/* Determine the FIFO depth */
858 	iprop = of_get_property(np, "fsl,fifo-depth", NULL);
859 	if (iprop)
860 		esai_priv->fifo_depth = be32_to_cpup(iprop);
861 	else
862 		esai_priv->fifo_depth = 64;
863 
864 	esai_priv->dma_params_tx.maxburst = 16;
865 	esai_priv->dma_params_rx.maxburst = 16;
866 	esai_priv->dma_params_tx.addr = res->start + REG_ESAI_ETDR;
867 	esai_priv->dma_params_rx.addr = res->start + REG_ESAI_ERDR;
868 
869 	esai_priv->synchronous =
870 		of_property_read_bool(np, "fsl,esai-synchronous");
871 
872 	/* Implement full symmetry for synchronous mode */
873 	if (esai_priv->synchronous) {
874 		fsl_esai_dai.symmetric_rates = 1;
875 		fsl_esai_dai.symmetric_channels = 1;
876 		fsl_esai_dai.symmetric_samplebits = 1;
877 	}
878 
879 	dev_set_drvdata(&pdev->dev, esai_priv);
880 
881 	/* Reset ESAI unit */
882 	ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ERST);
883 	if (ret) {
884 		dev_err(&pdev->dev, "failed to reset ESAI: %d\n", ret);
885 		return ret;
886 	}
887 
888 	/*
889 	 * We need to enable ESAI so as to access some of its registers.
890 	 * Otherwise, we would fail to dump regmap from user space.
891 	 */
892 	ret = regmap_write(esai_priv->regmap, REG_ESAI_ECR, ESAI_ECR_ESAIEN);
893 	if (ret) {
894 		dev_err(&pdev->dev, "failed to enable ESAI: %d\n", ret);
895 		return ret;
896 	}
897 
898 	ret = devm_snd_soc_register_component(&pdev->dev, &fsl_esai_component,
899 					      &fsl_esai_dai, 1);
900 	if (ret) {
901 		dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
902 		return ret;
903 	}
904 
905 	ret = imx_pcm_dma_init(pdev, IMX_ESAI_DMABUF_SIZE);
906 	if (ret)
907 		dev_err(&pdev->dev, "failed to init imx pcm dma: %d\n", ret);
908 
909 	return ret;
910 }
911 
912 static const struct of_device_id fsl_esai_dt_ids[] = {
913 	{ .compatible = "fsl,imx35-esai", },
914 	{ .compatible = "fsl,vf610-esai", },
915 	{}
916 };
917 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
918 
919 #ifdef CONFIG_PM_SLEEP
920 static int fsl_esai_suspend(struct device *dev)
921 {
922 	struct fsl_esai *esai = dev_get_drvdata(dev);
923 
924 	regcache_cache_only(esai->regmap, true);
925 	regcache_mark_dirty(esai->regmap);
926 
927 	return 0;
928 }
929 
930 static int fsl_esai_resume(struct device *dev)
931 {
932 	struct fsl_esai *esai = dev_get_drvdata(dev);
933 	int ret;
934 
935 	regcache_cache_only(esai->regmap, false);
936 
937 	/* FIFO reset for safety */
938 	regmap_update_bits(esai->regmap, REG_ESAI_TFCR,
939 			   ESAI_xFCR_xFR, ESAI_xFCR_xFR);
940 	regmap_update_bits(esai->regmap, REG_ESAI_RFCR,
941 			   ESAI_xFCR_xFR, ESAI_xFCR_xFR);
942 
943 	ret = regcache_sync(esai->regmap);
944 	if (ret)
945 		return ret;
946 
947 	/* FIFO reset done */
948 	regmap_update_bits(esai->regmap, REG_ESAI_TFCR, ESAI_xFCR_xFR, 0);
949 	regmap_update_bits(esai->regmap, REG_ESAI_RFCR, ESAI_xFCR_xFR, 0);
950 
951 	return 0;
952 }
953 #endif /* CONFIG_PM_SLEEP */
954 
955 static const struct dev_pm_ops fsl_esai_pm_ops = {
956 	SET_SYSTEM_SLEEP_PM_OPS(fsl_esai_suspend, fsl_esai_resume)
957 };
958 
959 static struct platform_driver fsl_esai_driver = {
960 	.probe = fsl_esai_probe,
961 	.driver = {
962 		.name = "fsl-esai-dai",
963 		.pm = &fsl_esai_pm_ops,
964 		.of_match_table = fsl_esai_dt_ids,
965 	},
966 };
967 
968 module_platform_driver(fsl_esai_driver);
969 
970 MODULE_AUTHOR("Freescale Semiconductor, Inc.");
971 MODULE_DESCRIPTION("Freescale ESAI CPU DAI driver");
972 MODULE_LICENSE("GPL v2");
973 MODULE_ALIAS("platform:fsl-esai-dai");
974