xref: /linux/sound/soc/kirkwood/kirkwood-i2s.c (revision 2fbc38219c0af91afbeb3c9d97c62e1c7c74df61)
1 /*
2  * kirkwood-i2s.c
3  *
4  * (c) 2010 Arnaud Patard <apatard@mandriva.com>
5  * (c) 2010 Arnaud Patard <arnaud.patard@rtp-net.org>
6  *
7  *  This program is free software; you can redistribute  it and/or modify it
8  *  under  the terms of  the GNU General  Public License as published by the
9  *  Free Software Foundation;  either version 2 of the  License, or (at your
10  *  option) any later version.
11  */
12 
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
16 #include <linux/io.h>
17 #include <linux/slab.h>
18 #include <linux/mbus.h>
19 #include <linux/delay.h>
20 #include <linux/clk.h>
21 #include <sound/pcm.h>
22 #include <sound/pcm_params.h>
23 #include <sound/soc.h>
24 #include <linux/platform_data/asoc-kirkwood.h>
25 #include <linux/of.h>
26 
27 #include "kirkwood.h"
28 
29 #define DRV_NAME	"mvebu-audio"
30 
31 #define KIRKWOOD_I2S_FORMATS \
32 	(SNDRV_PCM_FMTBIT_S16_LE | \
33 	 SNDRV_PCM_FMTBIT_S24_LE | \
34 	 SNDRV_PCM_FMTBIT_S32_LE)
35 
36 #define KIRKWOOD_SPDIF_FORMATS \
37 	(SNDRV_PCM_FMTBIT_S16_LE | \
38 	 SNDRV_PCM_FMTBIT_S24_LE)
39 
40 static int kirkwood_i2s_set_fmt(struct snd_soc_dai *cpu_dai,
41 		unsigned int fmt)
42 {
43 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(cpu_dai);
44 	unsigned long mask;
45 	unsigned long value;
46 
47 	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
48 	case SND_SOC_DAIFMT_RIGHT_J:
49 		mask = KIRKWOOD_I2S_CTL_RJ;
50 		break;
51 	case SND_SOC_DAIFMT_LEFT_J:
52 		mask = KIRKWOOD_I2S_CTL_LJ;
53 		break;
54 	case SND_SOC_DAIFMT_I2S:
55 		mask = KIRKWOOD_I2S_CTL_I2S;
56 		break;
57 	default:
58 		return -EINVAL;
59 	}
60 
61 	/*
62 	 * Set same format for playback and record
63 	 * This avoids some troubles.
64 	 */
65 	value = readl(priv->io+KIRKWOOD_I2S_PLAYCTL);
66 	value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
67 	value |= mask;
68 	writel(value, priv->io+KIRKWOOD_I2S_PLAYCTL);
69 
70 	value = readl(priv->io+KIRKWOOD_I2S_RECCTL);
71 	value &= ~KIRKWOOD_I2S_CTL_JUST_MASK;
72 	value |= mask;
73 	writel(value, priv->io+KIRKWOOD_I2S_RECCTL);
74 
75 	return 0;
76 }
77 
78 static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
79 {
80 	unsigned long value;
81 
82 	value = KIRKWOOD_DCO_CTL_OFFSET_0;
83 	switch (rate) {
84 	default:
85 	case 44100:
86 		value |= KIRKWOOD_DCO_CTL_FREQ_11;
87 		break;
88 	case 48000:
89 		value |= KIRKWOOD_DCO_CTL_FREQ_12;
90 		break;
91 	case 96000:
92 		value |= KIRKWOOD_DCO_CTL_FREQ_24;
93 		break;
94 	}
95 	writel(value, io + KIRKWOOD_DCO_CTL);
96 
97 	/* wait for dco locked */
98 	do {
99 		cpu_relax();
100 		value = readl(io + KIRKWOOD_DCO_SPCR_STATUS);
101 		value &= KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK;
102 	} while (value == 0);
103 }
104 
105 static void kirkwood_set_rate(struct snd_soc_dai *dai,
106 	struct kirkwood_dma_data *priv, unsigned long rate)
107 {
108 	uint32_t clks_ctrl;
109 
110 	if (IS_ERR(priv->extclk)) {
111 		/* use internal dco for the supported rates
112 		 * defined in kirkwood_i2s_dai */
113 		dev_dbg(dai->dev, "%s: dco set rate = %lu\n",
114 			__func__, rate);
115 		kirkwood_set_dco(priv->io, rate);
116 
117 		clks_ctrl = KIRKWOOD_MCLK_SOURCE_DCO;
118 	} else {
119 		/* use the external clock for the other rates
120 		 * defined in kirkwood_i2s_dai_extclk */
121 		dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n",
122 			__func__, rate, 256 * rate);
123 		clk_set_rate(priv->extclk, 256 * rate);
124 
125 		clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK;
126 	}
127 	writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL);
128 }
129 
130 static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
131 		struct snd_soc_dai *dai)
132 {
133 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
134 
135 	snd_soc_dai_set_dma_data(dai, substream, priv);
136 	return 0;
137 }
138 
139 static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
140 				 struct snd_pcm_hw_params *params,
141 				 struct snd_soc_dai *dai)
142 {
143 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
144 	uint32_t ctl_play, ctl_rec;
145 	unsigned int i2s_reg;
146 	unsigned long i2s_value;
147 
148 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
149 		i2s_reg = KIRKWOOD_I2S_PLAYCTL;
150 	} else {
151 		i2s_reg = KIRKWOOD_I2S_RECCTL;
152 	}
153 
154 	kirkwood_set_rate(dai, priv, params_rate(params));
155 
156 	i2s_value = readl(priv->io+i2s_reg);
157 	i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
158 
159 	/*
160 	 * Size settings in play/rec i2s control regs and play/rec control
161 	 * regs must be the same.
162 	 */
163 	switch (params_format(params)) {
164 	case SNDRV_PCM_FORMAT_S16_LE:
165 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
166 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C |
167 			   KIRKWOOD_PLAYCTL_I2S_EN |
168 			   KIRKWOOD_PLAYCTL_SPDIF_EN;
169 		ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C |
170 			  KIRKWOOD_RECCTL_I2S_EN |
171 			  KIRKWOOD_RECCTL_SPDIF_EN;
172 		break;
173 	/*
174 	 * doesn't work... S20_3LE != kirkwood 20bit format ?
175 	 *
176 	case SNDRV_PCM_FORMAT_S20_3LE:
177 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
178 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 |
179 			   KIRKWOOD_PLAYCTL_I2S_EN;
180 		ctl_rec = KIRKWOOD_RECCTL_SIZE_20 |
181 			  KIRKWOOD_RECCTL_I2S_EN;
182 		break;
183 	*/
184 	case SNDRV_PCM_FORMAT_S24_LE:
185 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
186 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 |
187 			   KIRKWOOD_PLAYCTL_I2S_EN |
188 			   KIRKWOOD_PLAYCTL_SPDIF_EN;
189 		ctl_rec = KIRKWOOD_RECCTL_SIZE_24 |
190 			  KIRKWOOD_RECCTL_I2S_EN |
191 			  KIRKWOOD_RECCTL_SPDIF_EN;
192 		break;
193 	case SNDRV_PCM_FORMAT_S32_LE:
194 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
195 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 |
196 			   KIRKWOOD_PLAYCTL_I2S_EN;
197 		ctl_rec = KIRKWOOD_RECCTL_SIZE_32 |
198 			  KIRKWOOD_RECCTL_I2S_EN;
199 		break;
200 	default:
201 		return -EINVAL;
202 	}
203 
204 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
205 		if (params_channels(params) == 1)
206 			ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH;
207 		else
208 			ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF;
209 
210 		priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK |
211 				    KIRKWOOD_PLAYCTL_ENABLE_MASK |
212 				    KIRKWOOD_PLAYCTL_SIZE_MASK);
213 		priv->ctl_play |= ctl_play;
214 	} else {
215 		priv->ctl_rec &= ~(KIRKWOOD_RECCTL_ENABLE_MASK |
216 				   KIRKWOOD_RECCTL_SIZE_MASK);
217 		priv->ctl_rec |= ctl_rec;
218 	}
219 
220 	writel(i2s_value, priv->io+i2s_reg);
221 
222 	return 0;
223 }
224 
225 static unsigned kirkwood_i2s_play_mute(unsigned ctl)
226 {
227 	if (!(ctl & KIRKWOOD_PLAYCTL_I2S_EN))
228 		ctl |= KIRKWOOD_PLAYCTL_I2S_MUTE;
229 	if (!(ctl & KIRKWOOD_PLAYCTL_SPDIF_EN))
230 		ctl |= KIRKWOOD_PLAYCTL_SPDIF_MUTE;
231 	return ctl;
232 }
233 
234 static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
235 				int cmd, struct snd_soc_dai *dai)
236 {
237 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
238 	uint32_t ctl, value;
239 
240 	ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
241 	if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
242 		unsigned timeout = 5000;
243 		/*
244 		 * The Armada510 spec says that if we enter pause mode, the
245 		 * busy bit must be read back as clear _twice_.  Make sure
246 		 * we respect that otherwise we get DMA underruns.
247 		 */
248 		do {
249 			value = ctl;
250 			ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
251 			if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
252 				break;
253 			udelay(1);
254 		} while (timeout--);
255 
256 		if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
257 			dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
258 				   ctl);
259 	}
260 
261 	switch (cmd) {
262 	case SNDRV_PCM_TRIGGER_START:
263 		/* configure */
264 		ctl = priv->ctl_play;
265 		if (dai->id == 0)
266 			ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;	/* i2s */
267 		else
268 			ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;	/* spdif */
269 		ctl = kirkwood_i2s_play_mute(ctl);
270 		value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
271 		writel(value, priv->io + KIRKWOOD_PLAYCTL);
272 
273 		/* enable interrupts */
274 		value = readl(priv->io + KIRKWOOD_INT_MASK);
275 		value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
276 		writel(value, priv->io + KIRKWOOD_INT_MASK);
277 
278 		/* enable playback */
279 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
280 		break;
281 
282 	case SNDRV_PCM_TRIGGER_STOP:
283 		/* stop audio, disable interrupts */
284 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
285 				KIRKWOOD_PLAYCTL_SPDIF_MUTE;
286 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
287 
288 		value = readl(priv->io + KIRKWOOD_INT_MASK);
289 		value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
290 		writel(value, priv->io + KIRKWOOD_INT_MASK);
291 
292 		/* disable all playbacks */
293 		ctl &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
294 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
295 		break;
296 
297 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
298 	case SNDRV_PCM_TRIGGER_SUSPEND:
299 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
300 				KIRKWOOD_PLAYCTL_SPDIF_MUTE;
301 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
302 		break;
303 
304 	case SNDRV_PCM_TRIGGER_RESUME:
305 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
306 		ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
307 				KIRKWOOD_PLAYCTL_SPDIF_MUTE);
308 		ctl = kirkwood_i2s_play_mute(ctl);
309 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
310 		break;
311 
312 	default:
313 		return -EINVAL;
314 	}
315 
316 	return 0;
317 }
318 
319 static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
320 				int cmd, struct snd_soc_dai *dai)
321 {
322 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
323 	uint32_t ctl, value;
324 
325 	value = readl(priv->io + KIRKWOOD_RECCTL);
326 
327 	switch (cmd) {
328 	case SNDRV_PCM_TRIGGER_START:
329 		/* configure */
330 		ctl = priv->ctl_rec;
331 		if (dai->id == 0)
332 			ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN;	/* i2s */
333 		else
334 			ctl &= ~KIRKWOOD_RECCTL_I2S_EN;		/* spdif */
335 
336 		value = ctl & ~KIRKWOOD_RECCTL_ENABLE_MASK;
337 		writel(value, priv->io + KIRKWOOD_RECCTL);
338 
339 		/* enable interrupts */
340 		value = readl(priv->io + KIRKWOOD_INT_MASK);
341 		value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
342 		writel(value, priv->io + KIRKWOOD_INT_MASK);
343 
344 		/* enable record */
345 		writel(ctl, priv->io + KIRKWOOD_RECCTL);
346 		break;
347 
348 	case SNDRV_PCM_TRIGGER_STOP:
349 		/* stop audio, disable interrupts */
350 		value = readl(priv->io + KIRKWOOD_RECCTL);
351 		value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
352 		writel(value, priv->io + KIRKWOOD_RECCTL);
353 
354 		value = readl(priv->io + KIRKWOOD_INT_MASK);
355 		value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;
356 		writel(value, priv->io + KIRKWOOD_INT_MASK);
357 
358 		/* disable all records */
359 		value = readl(priv->io + KIRKWOOD_RECCTL);
360 		value &= ~KIRKWOOD_RECCTL_ENABLE_MASK;
361 		writel(value, priv->io + KIRKWOOD_RECCTL);
362 		break;
363 
364 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
365 	case SNDRV_PCM_TRIGGER_SUSPEND:
366 		value = readl(priv->io + KIRKWOOD_RECCTL);
367 		value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
368 		writel(value, priv->io + KIRKWOOD_RECCTL);
369 		break;
370 
371 	case SNDRV_PCM_TRIGGER_RESUME:
372 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
373 		value = readl(priv->io + KIRKWOOD_RECCTL);
374 		value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE);
375 		writel(value, priv->io + KIRKWOOD_RECCTL);
376 		break;
377 
378 	default:
379 		return -EINVAL;
380 	}
381 
382 	return 0;
383 }
384 
385 static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
386 			       struct snd_soc_dai *dai)
387 {
388 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
389 		return kirkwood_i2s_play_trigger(substream, cmd, dai);
390 	else
391 		return kirkwood_i2s_rec_trigger(substream, cmd, dai);
392 
393 	return 0;
394 }
395 
396 static int kirkwood_i2s_init(struct kirkwood_dma_data *priv)
397 {
398 	unsigned long value;
399 	unsigned int reg_data;
400 
401 	/* put system in a "safe" state : */
402 	/* disable audio interrupts */
403 	writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
404 	writel(0, priv->io + KIRKWOOD_INT_MASK);
405 
406 	reg_data = readl(priv->io + 0x1200);
407 	reg_data &= (~(0x333FF8));
408 	reg_data |= 0x111D18;
409 	writel(reg_data, priv->io + 0x1200);
410 
411 	msleep(500);
412 
413 	reg_data = readl(priv->io + 0x1200);
414 	reg_data &= (~(0x333FF8));
415 	reg_data |= 0x111D18;
416 	writel(reg_data, priv->io + 0x1200);
417 
418 	/* disable playback/record */
419 	value = readl(priv->io + KIRKWOOD_PLAYCTL);
420 	value &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
421 	writel(value, priv->io + KIRKWOOD_PLAYCTL);
422 
423 	value = readl(priv->io + KIRKWOOD_RECCTL);
424 	value &= ~KIRKWOOD_RECCTL_ENABLE_MASK;
425 	writel(value, priv->io + KIRKWOOD_RECCTL);
426 
427 	return 0;
428 
429 }
430 
431 static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
432 	.startup	= kirkwood_i2s_startup,
433 	.trigger	= kirkwood_i2s_trigger,
434 	.hw_params      = kirkwood_i2s_hw_params,
435 	.set_fmt        = kirkwood_i2s_set_fmt,
436 };
437 
438 static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = {
439     {
440 	.name = "i2s",
441 	.id = 0,
442 	.playback = {
443 		.channels_min = 1,
444 		.channels_max = 2,
445 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
446 				SNDRV_PCM_RATE_96000,
447 		.formats = KIRKWOOD_I2S_FORMATS,
448 	},
449 	.capture = {
450 		.channels_min = 1,
451 		.channels_max = 2,
452 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
453 				SNDRV_PCM_RATE_96000,
454 		.formats = KIRKWOOD_I2S_FORMATS,
455 	},
456 	.ops = &kirkwood_i2s_dai_ops,
457     },
458     {
459 	.name = "spdif",
460 	.id = 1,
461 	.playback = {
462 		.channels_min = 1,
463 		.channels_max = 2,
464 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
465 				SNDRV_PCM_RATE_96000,
466 		.formats = KIRKWOOD_SPDIF_FORMATS,
467 	},
468 	.capture = {
469 		.channels_min = 1,
470 		.channels_max = 2,
471 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
472 				SNDRV_PCM_RATE_96000,
473 		.formats = KIRKWOOD_SPDIF_FORMATS,
474 	},
475 	.ops = &kirkwood_i2s_dai_ops,
476     },
477 };
478 
479 static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
480     {
481 	.name = "i2s",
482 	.id = 0,
483 	.playback = {
484 		.channels_min = 1,
485 		.channels_max = 2,
486 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
487 		.rate_min = 5512,
488 		.rate_max = 192000,
489 		.formats = KIRKWOOD_I2S_FORMATS,
490 	},
491 	.capture = {
492 		.channels_min = 1,
493 		.channels_max = 2,
494 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
495 		.rate_min = 5512,
496 		.rate_max = 192000,
497 		.formats = KIRKWOOD_I2S_FORMATS,
498 	},
499 	.ops = &kirkwood_i2s_dai_ops,
500     },
501     {
502 	.name = "spdif",
503 	.id = 1,
504 	.playback = {
505 		.channels_min = 1,
506 		.channels_max = 2,
507 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
508 		.rate_min = 5512,
509 		.rate_max = 192000,
510 		.formats = KIRKWOOD_SPDIF_FORMATS,
511 	},
512 	.capture = {
513 		.channels_min = 1,
514 		.channels_max = 2,
515 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
516 		.rate_min = 5512,
517 		.rate_max = 192000,
518 		.formats = KIRKWOOD_SPDIF_FORMATS,
519 	},
520 	.ops = &kirkwood_i2s_dai_ops,
521     },
522 };
523 
524 static const struct snd_soc_component_driver kirkwood_i2s_component = {
525 	.name		= DRV_NAME,
526 };
527 
528 static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
529 {
530 	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
531 	struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai;
532 	struct kirkwood_dma_data *priv;
533 	struct resource *mem;
534 	struct device_node *np = pdev->dev.of_node;
535 	int err;
536 
537 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
538 	if (!priv) {
539 		dev_err(&pdev->dev, "allocation failed\n");
540 		return -ENOMEM;
541 	}
542 	dev_set_drvdata(&pdev->dev, priv);
543 
544 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
545 	priv->io = devm_ioremap_resource(&pdev->dev, mem);
546 	if (IS_ERR(priv->io))
547 		return PTR_ERR(priv->io);
548 
549 	priv->irq = platform_get_irq(pdev, 0);
550 	if (priv->irq <= 0) {
551 		dev_err(&pdev->dev, "platform_get_irq failed\n");
552 		return -ENXIO;
553 	}
554 
555 	if (np) {
556 		priv->burst = 128;		/* might be 32 or 128 */
557 	} else if (data) {
558 		priv->burst = data->burst;
559 	} else {
560 		dev_err(&pdev->dev, "no DT nor platform data ?!\n");
561 		return -EINVAL;
562 	}
563 
564 	priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
565 	if (IS_ERR(priv->clk)) {
566 		dev_err(&pdev->dev, "no clock\n");
567 		return PTR_ERR(priv->clk);
568 	}
569 
570 	err = clk_prepare_enable(priv->clk);
571 	if (err < 0)
572 		return err;
573 
574 	priv->extclk = devm_clk_get(&pdev->dev, "extclk");
575 	if (IS_ERR(priv->extclk)) {
576 		if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
577 			return -EPROBE_DEFER;
578 	} else {
579 		if (priv->extclk == priv->clk) {
580 			devm_clk_put(&pdev->dev, priv->extclk);
581 			priv->extclk = ERR_PTR(-EINVAL);
582 		} else {
583 			dev_info(&pdev->dev, "found external clock\n");
584 			clk_prepare_enable(priv->extclk);
585 			soc_dai = kirkwood_i2s_dai_extclk;
586 		}
587 	}
588 
589 	/* Some sensible defaults - this reflects the powerup values */
590 	priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
591 	priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
592 
593 	/* Select the burst size */
594 	if (priv->burst == 32) {
595 		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
596 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
597 	} else {
598 		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
599 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
600 	}
601 
602 	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
603 					 soc_dai, 2);
604 	if (err) {
605 		dev_err(&pdev->dev, "snd_soc_register_component failed\n");
606 		goto err_component;
607 	}
608 
609 	err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
610 	if (err) {
611 		dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
612 		goto err_platform;
613 	}
614 
615 	kirkwood_i2s_init(priv);
616 
617 	return 0;
618  err_platform:
619 	snd_soc_unregister_component(&pdev->dev);
620  err_component:
621 	if (!IS_ERR(priv->extclk))
622 		clk_disable_unprepare(priv->extclk);
623 	clk_disable_unprepare(priv->clk);
624 
625 	return err;
626 }
627 
628 static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
629 {
630 	struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
631 
632 	snd_soc_unregister_platform(&pdev->dev);
633 	snd_soc_unregister_component(&pdev->dev);
634 
635 	if (!IS_ERR(priv->extclk))
636 		clk_disable_unprepare(priv->extclk);
637 	clk_disable_unprepare(priv->clk);
638 
639 	return 0;
640 }
641 
642 #ifdef CONFIG_OF
643 static struct of_device_id mvebu_audio_of_match[] = {
644 	{ .compatible = "marvell,kirkwood-audio" },
645 	{ .compatible = "marvell,dove-audio" },
646 	{ .compatible = "marvell,armada370-audio" },
647 	{ }
648 };
649 MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
650 #endif
651 
652 static struct platform_driver kirkwood_i2s_driver = {
653 	.probe  = kirkwood_i2s_dev_probe,
654 	.remove = kirkwood_i2s_dev_remove,
655 	.driver = {
656 		.name = DRV_NAME,
657 		.owner = THIS_MODULE,
658 		.of_match_table = of_match_ptr(mvebu_audio_of_match),
659 	},
660 };
661 
662 module_platform_driver(kirkwood_i2s_driver);
663 
664 /* Module information */
665 MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
666 MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
667 MODULE_LICENSE("GPL");
668 MODULE_ALIAS("platform:mvebu-audio");
669