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