xref: /linux/sound/soc/kirkwood/kirkwood-i2s.c (revision 8a537f85e9db8a43b323b0ffcf358c51448491de)
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 "kirkwood.h"
26 
27 #define DRV_NAME	"kirkwood-i2s"
28 
29 #define KIRKWOOD_I2S_FORMATS \
30 	(SNDRV_PCM_FMTBIT_S16_LE | \
31 	 SNDRV_PCM_FMTBIT_S24_LE | \
32 	 SNDRV_PCM_FMTBIT_S32_LE)
33 
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 
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 
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 (rate == 44100 || rate == 48000 || rate == 96000) {
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 
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 
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 		ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C |
163 			  KIRKWOOD_RECCTL_I2S_EN;
164 		break;
165 	/*
166 	 * doesn't work... S20_3LE != kirkwood 20bit format ?
167 	 *
168 	case SNDRV_PCM_FORMAT_S20_3LE:
169 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
170 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 |
171 			   KIRKWOOD_PLAYCTL_I2S_EN;
172 		ctl_rec = KIRKWOOD_RECCTL_SIZE_20 |
173 			  KIRKWOOD_RECCTL_I2S_EN;
174 		break;
175 	*/
176 	case SNDRV_PCM_FORMAT_S24_LE:
177 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
178 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 |
179 			   KIRKWOOD_PLAYCTL_I2S_EN;
180 		ctl_rec = KIRKWOOD_RECCTL_SIZE_24 |
181 			  KIRKWOOD_RECCTL_I2S_EN;
182 		break;
183 	case SNDRV_PCM_FORMAT_S32_LE:
184 		i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
185 		ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 |
186 			   KIRKWOOD_PLAYCTL_I2S_EN;
187 		ctl_rec = KIRKWOOD_RECCTL_SIZE_32 |
188 			  KIRKWOOD_RECCTL_I2S_EN;
189 		break;
190 	default:
191 		return -EINVAL;
192 	}
193 
194 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
195 		if (params_channels(params) == 1)
196 			ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH;
197 		else
198 			ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF;
199 
200 		priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK |
201 				    KIRKWOOD_PLAYCTL_I2S_EN |
202 				    KIRKWOOD_PLAYCTL_SPDIF_EN |
203 				    KIRKWOOD_PLAYCTL_SIZE_MASK);
204 		priv->ctl_play |= ctl_play;
205 	} else {
206 		priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK;
207 		priv->ctl_rec |= ctl_rec;
208 	}
209 
210 	writel(i2s_value, priv->io+i2s_reg);
211 
212 	return 0;
213 }
214 
215 static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
216 				int cmd, struct snd_soc_dai *dai)
217 {
218 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
219 	uint32_t ctl, value;
220 
221 	ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
222 	if (ctl & KIRKWOOD_PLAYCTL_PAUSE) {
223 		unsigned timeout = 5000;
224 		/*
225 		 * The Armada510 spec says that if we enter pause mode, the
226 		 * busy bit must be read back as clear _twice_.  Make sure
227 		 * we respect that otherwise we get DMA underruns.
228 		 */
229 		do {
230 			value = ctl;
231 			ctl = readl(priv->io + KIRKWOOD_PLAYCTL);
232 			if (!((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY))
233 				break;
234 			udelay(1);
235 		} while (timeout--);
236 
237 		if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY)
238 			dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n",
239 				   ctl);
240 	}
241 
242 	switch (cmd) {
243 	case SNDRV_PCM_TRIGGER_START:
244 		/* configure */
245 		ctl = priv->ctl_play;
246 		value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN |
247 				KIRKWOOD_PLAYCTL_SPDIF_EN);
248 		writel(value, priv->io + KIRKWOOD_PLAYCTL);
249 
250 		/* enable interrupts */
251 		value = readl(priv->io + KIRKWOOD_INT_MASK);
252 		value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
253 		writel(value, priv->io + KIRKWOOD_INT_MASK);
254 
255 		/* enable playback */
256 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
257 		break;
258 
259 	case SNDRV_PCM_TRIGGER_STOP:
260 		/* stop audio, disable interrupts */
261 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
262 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
263 
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 		/* disable all playbacks */
269 		ctl &= ~(KIRKWOOD_PLAYCTL_I2S_EN | KIRKWOOD_PLAYCTL_SPDIF_EN);
270 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
271 		break;
272 
273 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
274 	case SNDRV_PCM_TRIGGER_SUSPEND:
275 		ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE;
276 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
277 		break;
278 
279 	case SNDRV_PCM_TRIGGER_RESUME:
280 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
281 		ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE);
282 		writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
283 		break;
284 
285 	default:
286 		return -EINVAL;
287 	}
288 
289 	return 0;
290 }
291 
292 static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
293 				int cmd, struct snd_soc_dai *dai)
294 {
295 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
296 	uint32_t ctl, value;
297 
298 	value = readl(priv->io + KIRKWOOD_RECCTL);
299 
300 	switch (cmd) {
301 	case SNDRV_PCM_TRIGGER_START:
302 		/* configure */
303 		ctl = priv->ctl_rec;
304 		value = ctl & ~KIRKWOOD_RECCTL_I2S_EN;
305 		writel(value, priv->io + KIRKWOOD_RECCTL);
306 
307 		/* enable interrupts */
308 		value = readl(priv->io + KIRKWOOD_INT_MASK);
309 		value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
310 		writel(value, priv->io + KIRKWOOD_INT_MASK);
311 
312 		/* enable record */
313 		writel(ctl, priv->io + KIRKWOOD_RECCTL);
314 		break;
315 
316 	case SNDRV_PCM_TRIGGER_STOP:
317 		/* stop audio, disable interrupts */
318 		value = readl(priv->io + KIRKWOOD_RECCTL);
319 		value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
320 		writel(value, priv->io + KIRKWOOD_RECCTL);
321 
322 		value = readl(priv->io + KIRKWOOD_INT_MASK);
323 		value &= ~KIRKWOOD_INT_CAUSE_REC_BYTES;
324 		writel(value, priv->io + KIRKWOOD_INT_MASK);
325 
326 		/* disable all records */
327 		value = readl(priv->io + KIRKWOOD_RECCTL);
328 		value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
329 		writel(value, priv->io + KIRKWOOD_RECCTL);
330 		break;
331 
332 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
333 	case SNDRV_PCM_TRIGGER_SUSPEND:
334 		value = readl(priv->io + KIRKWOOD_RECCTL);
335 		value |= KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE;
336 		writel(value, priv->io + KIRKWOOD_RECCTL);
337 		break;
338 
339 	case SNDRV_PCM_TRIGGER_RESUME:
340 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
341 		value = readl(priv->io + KIRKWOOD_RECCTL);
342 		value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE);
343 		writel(value, priv->io + KIRKWOOD_RECCTL);
344 		break;
345 
346 	default:
347 		return -EINVAL;
348 	}
349 
350 	return 0;
351 }
352 
353 static int kirkwood_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
354 			       struct snd_soc_dai *dai)
355 {
356 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
357 		return kirkwood_i2s_play_trigger(substream, cmd, dai);
358 	else
359 		return kirkwood_i2s_rec_trigger(substream, cmd, dai);
360 
361 	return 0;
362 }
363 
364 static int kirkwood_i2s_probe(struct snd_soc_dai *dai)
365 {
366 	struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
367 	unsigned long value;
368 	unsigned int reg_data;
369 
370 	/* put system in a "safe" state : */
371 	/* disable audio interrupts */
372 	writel(0xffffffff, priv->io + KIRKWOOD_INT_CAUSE);
373 	writel(0, priv->io + KIRKWOOD_INT_MASK);
374 
375 	reg_data = readl(priv->io + 0x1200);
376 	reg_data &= (~(0x333FF8));
377 	reg_data |= 0x111D18;
378 	writel(reg_data, priv->io + 0x1200);
379 
380 	msleep(500);
381 
382 	reg_data = readl(priv->io + 0x1200);
383 	reg_data &= (~(0x333FF8));
384 	reg_data |= 0x111D18;
385 	writel(reg_data, priv->io + 0x1200);
386 
387 	/* disable playback/record */
388 	value = readl(priv->io + KIRKWOOD_PLAYCTL);
389 	value &= ~(KIRKWOOD_PLAYCTL_I2S_EN|KIRKWOOD_PLAYCTL_SPDIF_EN);
390 	writel(value, priv->io + KIRKWOOD_PLAYCTL);
391 
392 	value = readl(priv->io + KIRKWOOD_RECCTL);
393 	value &= ~(KIRKWOOD_RECCTL_I2S_EN | KIRKWOOD_RECCTL_SPDIF_EN);
394 	writel(value, priv->io + KIRKWOOD_RECCTL);
395 
396 	return 0;
397 
398 }
399 
400 static const struct snd_soc_dai_ops kirkwood_i2s_dai_ops = {
401 	.startup	= kirkwood_i2s_startup,
402 	.trigger	= kirkwood_i2s_trigger,
403 	.hw_params      = kirkwood_i2s_hw_params,
404 	.set_fmt        = kirkwood_i2s_set_fmt,
405 };
406 
407 
408 static struct snd_soc_dai_driver kirkwood_i2s_dai = {
409 	.probe = kirkwood_i2s_probe,
410 	.playback = {
411 		.channels_min = 1,
412 		.channels_max = 2,
413 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
414 				SNDRV_PCM_RATE_96000,
415 		.formats = KIRKWOOD_I2S_FORMATS,
416 	},
417 	.capture = {
418 		.channels_min = 1,
419 		.channels_max = 2,
420 		.rates = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000 |
421 				SNDRV_PCM_RATE_96000,
422 		.formats = KIRKWOOD_I2S_FORMATS,
423 	},
424 	.ops = &kirkwood_i2s_dai_ops,
425 };
426 
427 static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
428 	.probe = kirkwood_i2s_probe,
429 	.playback = {
430 		.channels_min = 1,
431 		.channels_max = 2,
432 		.rates = SNDRV_PCM_RATE_8000_192000 |
433 			 SNDRV_PCM_RATE_CONTINUOUS |
434 			 SNDRV_PCM_RATE_KNOT,
435 		.formats = KIRKWOOD_I2S_FORMATS,
436 	},
437 	.capture = {
438 		.channels_min = 1,
439 		.channels_max = 2,
440 		.rates = SNDRV_PCM_RATE_8000_192000 |
441 			 SNDRV_PCM_RATE_CONTINUOUS |
442 			 SNDRV_PCM_RATE_KNOT,
443 		.formats = KIRKWOOD_I2S_FORMATS,
444 	},
445 	.ops = &kirkwood_i2s_dai_ops,
446 };
447 
448 static const struct snd_soc_component_driver kirkwood_i2s_component = {
449 	.name		= DRV_NAME,
450 };
451 
452 static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
453 {
454 	struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
455 	struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai;
456 	struct kirkwood_dma_data *priv;
457 	struct resource *mem;
458 	int err;
459 
460 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
461 	if (!priv) {
462 		dev_err(&pdev->dev, "allocation failed\n");
463 		return -ENOMEM;
464 	}
465 	dev_set_drvdata(&pdev->dev, priv);
466 
467 	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
468 	priv->io = devm_ioremap_resource(&pdev->dev, mem);
469 	if (IS_ERR(priv->io))
470 		return PTR_ERR(priv->io);
471 
472 	priv->irq = platform_get_irq(pdev, 0);
473 	if (priv->irq <= 0) {
474 		dev_err(&pdev->dev, "platform_get_irq failed\n");
475 		return -ENXIO;
476 	}
477 
478 	if (!data) {
479 		dev_err(&pdev->dev, "no platform data ?!\n");
480 		return -EINVAL;
481 	}
482 
483 	priv->burst = data->burst;
484 
485 	priv->clk = devm_clk_get(&pdev->dev, NULL);
486 	if (IS_ERR(priv->clk)) {
487 		dev_err(&pdev->dev, "no clock\n");
488 		return PTR_ERR(priv->clk);
489 	}
490 
491 	err = clk_prepare_enable(priv->clk);
492 	if (err < 0)
493 		return err;
494 
495 	priv->extclk = devm_clk_get(&pdev->dev, "extclk");
496 	if (!IS_ERR(priv->extclk)) {
497 		if (priv->extclk == priv->clk) {
498 			priv->extclk = ERR_PTR(-EINVAL);
499 		} else {
500 			dev_info(&pdev->dev, "found external clock\n");
501 			clk_prepare_enable(priv->extclk);
502 			soc_dai = &kirkwood_i2s_dai_extclk;
503 		}
504 	}
505 
506 	/* Some sensible defaults - this reflects the powerup values */
507 	priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
508 	priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
509 
510 	/* Select the burst size */
511 	if (data->burst == 32) {
512 		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
513 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
514 	} else {
515 		priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
516 		priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
517 	}
518 
519 	err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component,
520 					 soc_dai, 1);
521 	if (!err)
522 		return 0;
523 	dev_err(&pdev->dev, "snd_soc_register_component failed\n");
524 
525 	if (!IS_ERR(priv->extclk))
526 		clk_disable_unprepare(priv->extclk);
527 	clk_disable_unprepare(priv->clk);
528 
529 	return err;
530 }
531 
532 static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
533 {
534 	struct kirkwood_dma_data *priv = dev_get_drvdata(&pdev->dev);
535 
536 	snd_soc_unregister_component(&pdev->dev);
537 
538 	if (!IS_ERR(priv->extclk))
539 		clk_disable_unprepare(priv->extclk);
540 	clk_disable_unprepare(priv->clk);
541 
542 	return 0;
543 }
544 
545 static struct platform_driver kirkwood_i2s_driver = {
546 	.probe  = kirkwood_i2s_dev_probe,
547 	.remove = kirkwood_i2s_dev_remove,
548 	.driver = {
549 		.name = DRV_NAME,
550 		.owner = THIS_MODULE,
551 	},
552 };
553 
554 module_platform_driver(kirkwood_i2s_driver);
555 
556 /* Module information */
557 MODULE_AUTHOR("Arnaud Patard, <arnaud.patard@rtp-net.org>");
558 MODULE_DESCRIPTION("Kirkwood I2S SoC Interface");
559 MODULE_LICENSE("GPL");
560 MODULE_ALIAS("platform:kirkwood-i2s");
561