xref: /linux/sound/soc/kirkwood/kirkwood-i2s.c (revision 41be702a542a0d14bb0b1c16e824fa9ed27616ec)
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_SIZE_MASK;
216 		priv->ctl_rec |= ctl_rec;
217 	}
218 
219 	writel(i2s_value, priv->io+i2s_reg);
220 
221 	return 0;
222 }
223 
224 static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
225 				int cmd, struct snd_soc_dai *dai)
226 {
227 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
228 	uint32_t ctl, value;
229 
230 	ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
231 	if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
232 		unsigned timeout = 5000;
233 		/*
234 		 * The Armada510 spec says that if we enter pause mode, the
235 		 * busy bit must be read back as clear _twice_.  Make sure
236 		 * we respect that otherwise we get DMA underruns.
237 		 */
238 		do {
239 			value = ctl;
240 			ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
241 			if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
242 				break;
243 			udelay(1);
244 		} while (timeout--);
245 
246 		if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
247 			dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
248 				   ctl);
249 	}
250 
251 	switch (cmd) {
252 	case SNDRV_PCM_TRIGGER_START:
253 		/* configure */
254 		ctl = priv->ctl_play;
255 		if (dai->id == 0)
256 			ctl &= ~KIRKWOOD_PLAYCTL_SPDIF_EN;	/* i2s */
257 		else
258 			ctl &= ~KIRKWOOD_PLAYCTL_I2S_EN;	/* spdif */
259 
260 		value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
261 		writel(value, priv->io + KIRKWOOD_PLAYCTL);
262 
263 		/* enable interrupts */
264 		value = readl(priv->io + KIRKWOOD_INT_MASK);
265 		value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
266 		writel(value, priv->io + KIRKWOOD_INT_MASK);
267 
268 		/* enable playback */
269 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
270 		break;
271 
272 	case SNDRV_PCM_TRIGGER_STOP:
273 		/* stop audio, disable interrupts */
274 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
275 				KIRKWOOD_PLAYCTL_SPDIF_MUTE;
276 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
277 
278 		value = readl(priv->io + KIRKWOOD_INT_MASK);
279 		value &= ~KIRKWOOD_INT_CAUSE_PLAY_BYTES;
280 		writel(value, priv->io + KIRKWOOD_INT_MASK);
281 
282 		/* disable all playbacks */
283 		ctl &= ~KIRKWOOD_PLAYCTL_ENABLE_MASK;
284 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
285 		break;
286 
287 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
288 	case SNDRV_PCM_TRIGGER_SUSPEND:
289 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
290 				KIRKWOOD_PLAYCTL_SPDIF_MUTE;
291 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
292 		break;
293 
294 	case SNDRV_PCM_TRIGGER_RESUME:
295 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
296 		ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE |
297 				KIRKWOOD_PLAYCTL_SPDIF_MUTE);
298 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
299 		break;
300 
301 	default:
302 		return -EINVAL;
303 	}
304 
305 	return 0;
306 }
307 
308 static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
309 				int cmd, struct snd_soc_dai *dai)
310 {
311 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
312 	uint32_t ctl, value;
313 
314 	value = readl(priv->io + KIRKWOOD_RECCTL);
315 
316 	switch (cmd) {
317 	case SNDRV_PCM_TRIGGER_START:
318 		/* configure */
319 		ctl = priv->ctl_rec;
320 		if (dai->id == 0)
321 			ctl &= ~KIRKWOOD_RECCTL_SPDIF_EN;	/* i2s */
322 		else
323 			ctl &= ~KIRKWOOD_RECCTL_I2S_EN;		/* spdif */
324 
325 		value = ctl & ~(KIRKWOOD_RECCTL_I2S_EN |
326 				KIRKWOOD_RECCTL_SPDIF_EN);
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_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
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_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
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 	{ }
637 };
638 MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
639 #endif
640 
641 static struct platform_driver kirkwood_i2s_driver = {
642 	.probe  = kirkwood_i2s_dev_probe,
643 	.remove = kirkwood_i2s_dev_remove,
644 	.driver = {
645 		.name = DRV_NAME,
646 		.owner = THIS_MODULE,
647 		.of_match_table = of_match_ptr(mvebu_audio_of_match),
648 	},
649 };
650 
651 module_platform_driver(kirkwood_i2s_driver);
652 
653 /* Module information */
654 MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
655 MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
656 MODULE_LICENSE("GPL");
657 MODULE_ALIAS("platform:mvebu-audio");
658