xref: /linux/sound/soc/kirkwood/kirkwood-i2s.c (revision 6772190632ebce6c5c6010d2bc77d5de866831b6)
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 int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
226 				int cmd, struct snd_soc_dai *dai)
227 {
228 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
229 	uint32_t ctl, value;
230 
231 	ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
232 	if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
233 		unsigned timeout = 5000;
234 		/*
235 		 * The Armada510 spec says that if we enter pause mode, the
236 		 * busy bit must be read back as clear _twice_.  Make sure
237 		 * we respect that otherwise we get DMA underruns.
238 		 */
239 		do {
240 			value = ctl;
241 			ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
242 			if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
243 				break;
244 			udelay(1);
245 		} while (timeout--);
246 
247 		if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
248 			dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
249 				   ctl);
250 	}
251 
252 	switch (cmd) {
253 	case SNDRV_PCM_TRIGGER_START:
254 		/* configure */
255 		ctl = priv->ctl_play;
256 		if (dai->id == 0)
257 			ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;	/* i2s */
258 		else
259 			ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;	/* spdif */
260 
261 		value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
262 		writel(value, priv->io + KIRKWOOD_PLAYCTL);
263 
264 		/* enable interrupts */
265 		value = readl(priv->io + KIRKWOOD_INT_MASK);
266 		value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
267 		writel(value, priv->io + KIRKWOOD_INT_MASK);
268 
269 		/* enable playback */
270 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
271 		break;
272 
273 	case SNDRV_PCM_TRIGGER_STOP:
274 		/* stop audio, disable interrupts */
275 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
276 				KIRKWOOD_PLAYCTL_SPDIF_MUTE;
277 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
278 
279 		value = readl(priv->io + KIRKWOOD_INT_MASK);
280 		value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
281 		writel(value, priv->io + KIRKWOOD_INT_MASK);
282 
283 		/* disable all playbacks */
284 		ctl &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
285 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
286 		break;
287 
288 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
289 	case SNDRV_PCM_TRIGGER_SUSPEND:
290 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
291 				KIRKWOOD_PLAYCTL_SPDIF_MUTE;
292 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
293 		break;
294 
295 	case SNDRV_PCM_TRIGGER_RESUME:
296 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
297 		ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
298 				KIRKWOOD_PLAYCTL_SPDIF_MUTE);
299 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
300 		break;
301 
302 	default:
303 		return -EINVAL;
304 	}
305 
306 	return 0;
307 }
308 
309 static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
310 				int cmd, struct snd_soc_dai *dai)
311 {
312 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
313 	uint32_t ctl, value;
314 
315 	value = readl(priv->io + KIRKWOOD_RECCTL);
316 
317 	switch (cmd) {
318 	case SNDRV_PCM_TRIGGER_START:
319 		/* configure */
320 		ctl = priv->ctl_rec;
321 		if (dai->id == 0)
322 			ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN;	/* i2s */
323 		else
324 			ctl &= ~KIRKWOOD_RECCTL_I2S_EN;		/* spdif */
325 
326 		value = ctl & ~KIRKWOOD_RECCTL_ENABLE_MASK;
327 		writel(value, priv->io + KIRKWOOD_RECCTL);
328 
329 		/* enable interrupts */
330 		value = readl(priv->io + KIRKWOOD_INT_MASK);
331 		value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
332 		writel(value, priv->io + KIRKWOOD_INT_MASK);
333 
334 		/* enable record */
335 		writel(ctl, priv->io + KIRKWOOD_RECCTL);
336 		break;
337 
338 	case SNDRV_PCM_TRIGGER_STOP:
339 		/* stop audio, disable interrupts */
340 		value = readl(priv->io + KIRKWOOD_RECCTL);
341 		value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
342 		writel(value, priv->io + KIRKWOOD_RECCTL);
343 
344 		value = readl(priv->io + KIRKWOOD_INT_MASK);
345 		value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;
346 		writel(value, priv->io + KIRKWOOD_INT_MASK);
347 
348 		/* disable all records */
349 		value = readl(priv->io + KIRKWOOD_RECCTL);
350 		value &= ~KIRKWOOD_RECCTL_ENABLE_MASK;
351 		writel(value, priv->io + KIRKWOOD_RECCTL);
352 		break;
353 
354 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
355 	case SNDRV_PCM_TRIGGER_SUSPEND:
356 		value = readl(priv->io + KIRKWOOD_RECCTL);
357 		value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
358 		writel(value, priv->io + KIRKWOOD_RECCTL);
359 		break;
360 
361 	case SNDRV_PCM_TRIGGER_RESUME:
362 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
363 		value = readl(priv->io + KIRKWOOD_RECCTL);
364 		value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE);
365 		writel(value, priv->io + KIRKWOOD_RECCTL);
366 		break;
367 
368 	default:
369 		return -EINVAL;
370 	}
371 
372 	return 0;
373 }
374 
375 static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
376 			       struct snd_soc_dai *dai)
377 {
378 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
379 		return kirkwood_i2s_play_trigger(substream, cmd, dai);
380 	else
381 		return kirkwood_i2s_rec_trigger(substream, cmd, dai);
382 
383 	return 0;
384 }
385 
386 static int kirkwood_i2s_init(struct kirkwood_dma_data *priv)
387 {
388 	unsigned long value;
389 	unsigned int reg_data;
390 
391 	/* put system in a "safe" state : */
392 	/* disable audio interrupts */
393 	writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
394 	writel(0, priv->io + KIRKWOOD_INT_MASK);
395 
396 	reg_data = readl(priv->io + 0x1200);
397 	reg_data &= (~(0x333FF8));
398 	reg_data |= 0x111D18;
399 	writel(reg_data, priv->io + 0x1200);
400 
401 	msleep(500);
402 
403 	reg_data = readl(priv->io + 0x1200);
404 	reg_data &= (~(0x333FF8));
405 	reg_data |= 0x111D18;
406 	writel(reg_data, priv->io + 0x1200);
407 
408 	/* disable playback/record */
409 	value = readl(priv->io + KIRKWOOD_PLAYCTL);
410 	value &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
411 	writel(value, priv->io + KIRKWOOD_PLAYCTL);
412 
413 	value = readl(priv->io + KIRKWOOD_RECCTL);
414 	value &= ~KIRKWOOD_RECCTL_ENABLE_MASK;
415 	writel(value, priv->io + KIRKWOOD_RECCTL);
416 
417 	return 0;
418 
419 }
420 
421 static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
422 	.startup	= kirkwood_i2s_startup,
423 	.trigger	= kirkwood_i2s_trigger,
424 	.hw_params      = kirkwood_i2s_hw_params,
425 	.set_fmt        = kirkwood_i2s_set_fmt,
426 };
427 
428 static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = {
429     {
430 	.name = "i2s",
431 	.id = 0,
432 	.playback = {
433 		.channels_min = 1,
434 		.channels_max = 2,
435 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
436 				SNDRV_PCM_RATE_96000,
437 		.formats = KIRKWOOD_I2S_FORMATS,
438 	},
439 	.capture = {
440 		.channels_min = 1,
441 		.channels_max = 2,
442 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
443 				SNDRV_PCM_RATE_96000,
444 		.formats = KIRKWOOD_I2S_FORMATS,
445 	},
446 	.ops = &kirkwood_i2s_dai_ops,
447     },
448     {
449 	.name = "spdif",
450 	.id = 1,
451 	.playback = {
452 		.channels_min = 1,
453 		.channels_max = 2,
454 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
455 				SNDRV_PCM_RATE_96000,
456 		.formats = KIRKWOOD_SPDIF_FORMATS,
457 	},
458 	.capture = {
459 		.channels_min = 1,
460 		.channels_max = 2,
461 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
462 				SNDRV_PCM_RATE_96000,
463 		.formats = KIRKWOOD_SPDIF_FORMATS,
464 	},
465 	.ops = &kirkwood_i2s_dai_ops,
466     },
467 };
468 
469 static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = {
470     {
471 	.name = "i2s",
472 	.id = 0,
473 	.playback = {
474 		.channels_min = 1,
475 		.channels_max = 2,
476 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
477 		.rate_min = 5512,
478 		.rate_max = 192000,
479 		.formats = KIRKWOOD_I2S_FORMATS,
480 	},
481 	.capture = {
482 		.channels_min = 1,
483 		.channels_max = 2,
484 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
485 		.rate_min = 5512,
486 		.rate_max = 192000,
487 		.formats = KIRKWOOD_I2S_FORMATS,
488 	},
489 	.ops = &kirkwood_i2s_dai_ops,
490     },
491     {
492 	.name = "spdif",
493 	.id = 1,
494 	.playback = {
495 		.channels_min = 1,
496 		.channels_max = 2,
497 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
498 		.rate_min = 5512,
499 		.rate_max = 192000,
500 		.formats = KIRKWOOD_SPDIF_FORMATS,
501 	},
502 	.capture = {
503 		.channels_min = 1,
504 		.channels_max = 2,
505 		.rates = SNDRV_PCM_RATE_CONTINUOUS,
506 		.rate_min = 5512,
507 		.rate_max = 192000,
508 		.formats = KIRKWOOD_SPDIF_FORMATS,
509 	},
510 	.ops = &kirkwood_i2s_dai_ops,
511     },
512 };
513 
514 static const struct snd_soc_component_driver kirkwood_i2s_component = {
515 	.name		= DRV_NAME,
516 };
517 
518 static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
519 {
520 	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
521 	struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai;
522 	struct kirkwood_dma_data *priv;
523 	struct resource *mem;
524 	struct device_node *np = pdev->dev.of_node;
525 	int err;
526 
527 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
528 	if (!priv) {
529 		dev_err(&pdev->dev, "allocation failed\n");
530 		return -ENOMEM;
531 	}
532 	dev_set_drvdata(&pdev->dev, priv);
533 
534 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
535 	priv->io = devm_ioremap_resource(&pdev->dev, mem);
536 	if (IS_ERR(priv->io))
537 		return PTR_ERR(priv->io);
538 
539 	priv->irq = platform_get_irq(pdev, 0);
540 	if (priv->irq <= 0) {
541 		dev_err(&pdev->dev, "platform_get_irq failed\n");
542 		return -ENXIO;
543 	}
544 
545 	if (np) {
546 		priv->burst = 128;		/* might be 32 or 128 */
547 	} else if (data) {
548 		priv->burst = data->burst;
549 	} else {
550 		dev_err(&pdev->dev, "no DT nor platform data ?!\n");
551 		return -EINVAL;
552 	}
553 
554 	priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
555 	if (IS_ERR(priv->clk)) {
556 		dev_err(&pdev->dev, "no clock\n");
557 		return PTR_ERR(priv->clk);
558 	}
559 
560 	err = clk_prepare_enable(priv->clk);
561 	if (err < 0)
562 		return err;
563 
564 	priv->extclk = devm_clk_get(&pdev->dev, "extclk");
565 	if (IS_ERR(priv->extclk)) {
566 		if (PTR_ERR(priv->extclk) == -EPROBE_DEFER)
567 			return -EPROBE_DEFER;
568 	} else {
569 		if (priv->extclk == priv->clk) {
570 			devm_clk_put(&pdev->dev, priv->extclk);
571 			priv->extclk = ERR_PTR(-EINVAL);
572 		} else {
573 			dev_info(&pdev->dev, "found external clock\n");
574 			clk_prepare_enable(priv->extclk);
575 			soc_dai = kirkwood_i2s_dai_extclk;
576 		}
577 	}
578 
579 	/* Some sensible defaults - this reflects the powerup values */
580 	priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
581 	priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
582 
583 	/* Select the burst size */
584 	if (priv->burst == 32) {
585 		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
586 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
587 	} else {
588 		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
589 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
590 	}
591 
592 	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
593 					 soc_dai, 2);
594 	if (err) {
595 		dev_err(&pdev->dev, "snd_soc_register_component failed\n");
596 		goto err_component;
597 	}
598 
599 	err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform);
600 	if (err) {
601 		dev_err(&pdev->dev, "snd_soc_register_platform failed\n");
602 		goto err_platform;
603 	}
604 
605 	kirkwood_i2s_init(priv);
606 
607 	return 0;
608  err_platform:
609 	snd_soc_unregister_component(&pdev->dev);
610  err_component:
611 	if (!IS_ERR(priv->extclk))
612 		clk_disable_unprepare(priv->extclk);
613 	clk_disable_unprepare(priv->clk);
614 
615 	return err;
616 }
617 
618 static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
619 {
620 	struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
621 
622 	snd_soc_unregister_platform(&pdev->dev);
623 	snd_soc_unregister_component(&pdev->dev);
624 
625 	if (!IS_ERR(priv->extclk))
626 		clk_disable_unprepare(priv->extclk);
627 	clk_disable_unprepare(priv->clk);
628 
629 	return 0;
630 }
631 
632 #ifdef CONFIG_OF
633 static struct of_device_id mvebu_audio_of_match[] = {
634 	{ .compatible = "marvell,kirkwood-audio" },
635 	{ .compatible = "marvell,dove-audio" },
636 	{ .compatible = "marvell,armada370-audio" },
637 	{ }
638 };
639 MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
640 #endif
641 
642 static struct platform_driver kirkwood_i2s_driver = {
643 	.probe  = kirkwood_i2s_dev_probe,
644 	.remove = kirkwood_i2s_dev_remove,
645 	.driver = {
646 		.name = DRV_NAME,
647 		.owner = THIS_MODULE,
648 		.of_match_table = of_match_ptr(mvebu_audio_of_match),
649 	},
650 };
651 
652 module_platform_driver(kirkwood_i2s_driver);
653 
654 /* Module information */
655 MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
656 MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
657 MODULE_LICENSE("GPL");
658 MODULE_ALIAS("platform:mvebu-audio");
659