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