aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-09 10:22:12 -0500
committerMark Brown <broonie@opensource.wolfsonmicro.com>2012-12-09 10:22:12 -0500
commit9a6806c0a7efd021dacfb7cd8bdfd11c2c6e860d (patch)
treebbc6b90d10a00f080208b0883b6433b44974ee49 /sound/soc
parent18620cc58683daacaa23d32e13eb4c27892137f6 (diff)
parent1703470aa7cfbef8d8e596106447bac894f5623e (diff)
Merge remote-tracking branch 'asoc/topic/kirkwood' into asoc-next
Diffstat (limited to 'sound/soc')
-rw-r--r--sound/soc/kirkwood/kirkwood-dma.c16
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c235
-rw-r--r--sound/soc/kirkwood/kirkwood.h11
3 files changed, 168 insertions, 94 deletions
diff --git a/sound/soc/kirkwood/kirkwood-dma.c b/sound/soc/kirkwood/kirkwood-dma.c
index 2ba08148655f..58d5a96b366f 100644
--- a/sound/soc/kirkwood/kirkwood-dma.c
+++ b/sound/soc/kirkwood/kirkwood-dma.c
@@ -22,12 +22,16 @@
22#include "kirkwood.h" 22#include "kirkwood.h"
23 23
24#define KIRKWOOD_RATES \ 24#define KIRKWOOD_RATES \
25 (SNDRV_PCM_RATE_44100 | \ 25 (SNDRV_PCM_RATE_8000_192000 | \
26 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000) 26 SNDRV_PCM_RATE_CONTINUOUS | \
27 SNDRV_PCM_RATE_KNOT)
28
27#define KIRKWOOD_FORMATS \ 29#define KIRKWOOD_FORMATS \
28 (SNDRV_PCM_FMTBIT_S16_LE | \ 30 (SNDRV_PCM_FMTBIT_S16_LE | \
29 SNDRV_PCM_FMTBIT_S24_LE | \ 31 SNDRV_PCM_FMTBIT_S24_LE | \
30 SNDRV_PCM_FMTBIT_S32_LE) 32 SNDRV_PCM_FMTBIT_S32_LE | \
33 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE | \
34 SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_BE)
31 35
32struct kirkwood_dma_priv { 36struct kirkwood_dma_priv {
33 struct snd_pcm_substream *play_stream; 37 struct snd_pcm_substream *play_stream;
@@ -43,10 +47,10 @@ static struct snd_pcm_hardware kirkwood_dma_snd_hw = {
43 SNDRV_PCM_INFO_PAUSE), 47 SNDRV_PCM_INFO_PAUSE),
44 .formats = KIRKWOOD_FORMATS, 48 .formats = KIRKWOOD_FORMATS,
45 .rates = KIRKWOOD_RATES, 49 .rates = KIRKWOOD_RATES,
46 .rate_min = 44100, 50 .rate_min = 8000,
47 .rate_max = 96000, 51 .rate_max = 384000,
48 .channels_min = 1, 52 .channels_min = 1,
49 .channels_max = 2, 53 .channels_max = 8,
50 .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS, 54 .buffer_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES * KIRKWOOD_SND_MAX_PERIODS,
51 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES, 55 .period_bytes_min = KIRKWOOD_SND_MIN_PERIOD_BYTES,
52 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES, 56 .period_bytes_max = KIRKWOOD_SND_MAX_PERIOD_BYTES,
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index 1d5db484d2df..d3629d5927e9 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -99,6 +99,29 @@ static inline void kirkwood_set_dco(void __iomem *io, unsigned long rate)
99 } while (value == 0); 99 } while (value == 0);
100} 100}
101 101
102static void kirkwood_set_rate(struct snd_soc_dai *dai,
103 struct kirkwood_dma_data *priv, unsigned long rate)
104{
105 uint32_t clks_ctrl;
106
107 if (rate == 44100 || rate == 48000 || rate == 96000) {
108 /* use internal dco for supported rates */
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 if (!IS_ERR(priv->extclk)) {
115 /* use optional external clk for other rates */
116 dev_dbg(dai->dev, "%s: extclk set rate = %lu -> %lu\n",
117 __func__, rate, 256 * rate);
118 clk_set_rate(priv->extclk, 256 * rate);
119
120 clks_ctrl = KIRKWOOD_MCLK_SOURCE_EXTCLK;
121 }
122 writel(clks_ctrl, priv->io + KIRKWOOD_CLOCKS_CTRL);
123}
124
102static int kirkwood_i2s_startup(struct snd_pcm_substream *substream, 125static int kirkwood_i2s_startup(struct snd_pcm_substream *substream,
103 struct snd_soc_dai *dai) 126 struct snd_soc_dai *dai)
104{ 127{
@@ -113,26 +136,21 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
113 struct snd_soc_dai *dai) 136 struct snd_soc_dai *dai)
114{ 137{
115 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 138 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
116 unsigned int i2s_reg, reg; 139 uint32_t ctl_play, ctl_rec;
117 unsigned long i2s_value, value; 140 unsigned int i2s_reg;
141 unsigned long i2s_value;
118 142
119 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 143 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
120 i2s_reg = KIRKWOOD_I2S_PLAYCTL; 144 i2s_reg = KIRKWOOD_I2S_PLAYCTL;
121 reg = KIRKWOOD_PLAYCTL;
122 } else { 145 } else {
123 i2s_reg = KIRKWOOD_I2S_RECCTL; 146 i2s_reg = KIRKWOOD_I2S_RECCTL;
124 reg = KIRKWOOD_RECCTL;
125 } 147 }
126 148
127 /* set dco conf */ 149 kirkwood_set_rate(dai, priv, params_rate(params));
128 kirkwood_set_dco(priv->io, params_rate(params));
129 150
130 i2s_value = readl(priv->io+i2s_reg); 151 i2s_value = readl(priv->io+i2s_reg);
131 i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK; 152 i2s_value &= ~KIRKWOOD_I2S_CTL_SIZE_MASK;
132 153
133 value = readl(priv->io+reg);
134 value &= ~KIRKWOOD_PLAYCTL_SIZE_MASK;
135
136 /* 154 /*
137 * Size settings in play/rec i2s control regs and play/rec control 155 * Size settings in play/rec i2s control regs and play/rec control
138 * regs must be the same. 156 * regs must be the same.
@@ -140,38 +158,57 @@ static int kirkwood_i2s_hw_params(struct snd_pcm_substream *substream,
140 switch (params_format(params)) { 158 switch (params_format(params)) {
141 case SNDRV_PCM_FORMAT_S16_LE: 159 case SNDRV_PCM_FORMAT_S16_LE:
142 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16; 160 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_16;
143 value |= KIRKWOOD_PLAYCTL_SIZE_16_C; 161 ctl_play = KIRKWOOD_PLAYCTL_SIZE_16_C |
162 KIRKWOOD_PLAYCTL_I2S_EN;
163 ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C |
164 KIRKWOOD_RECCTL_I2S_EN;
144 break; 165 break;
145 /* 166 /*
146 * doesn't work... S20_3LE != kirkwood 20bit format ? 167 * doesn't work... S20_3LE != kirkwood 20bit format ?
147 * 168 *
148 case SNDRV_PCM_FORMAT_S20_3LE: 169 case SNDRV_PCM_FORMAT_S20_3LE:
149 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; 170 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20;
150 value |= KIRKWOOD_PLAYCTL_SIZE_20; 171 ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 |
172 KIRKWOOD_PLAYCTL_I2S_EN;
173 ctl_rec = KIRKWOOD_RECCTL_SIZE_20 |
174 KIRKWOOD_RECCTL_I2S_EN;
151 break; 175 break;
152 */ 176 */
153 case SNDRV_PCM_FORMAT_S24_LE: 177 case SNDRV_PCM_FORMAT_S24_LE:
154 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; 178 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24;
155 value |= KIRKWOOD_PLAYCTL_SIZE_24; 179 ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 |
180 KIRKWOOD_PLAYCTL_I2S_EN;
181 ctl_rec = KIRKWOOD_RECCTL_SIZE_24 |
182 KIRKWOOD_RECCTL_I2S_EN;
156 break; 183 break;
157 case SNDRV_PCM_FORMAT_S32_LE: 184 case SNDRV_PCM_FORMAT_S32_LE:
158 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; 185 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32;
159 value |= KIRKWOOD_PLAYCTL_SIZE_32; 186 ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 |
187 KIRKWOOD_PLAYCTL_I2S_EN;
188 ctl_rec = KIRKWOOD_RECCTL_SIZE_32 |
189 KIRKWOOD_RECCTL_I2S_EN;
160 break; 190 break;
161 default: 191 default:
162 return -EINVAL; 192 return -EINVAL;
163 } 193 }
164 194
165 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 195 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
166 value &= ~KIRKWOOD_PLAYCTL_MONO_MASK;
167 if (params_channels(params) == 1) 196 if (params_channels(params) == 1)
168 value |= KIRKWOOD_PLAYCTL_MONO_BOTH; 197 ctl_play |= KIRKWOOD_PLAYCTL_MONO_BOTH;
169 else 198 else
170 value |= KIRKWOOD_PLAYCTL_MONO_OFF; 199 ctl_play |= KIRKWOOD_PLAYCTL_MONO_OFF;
200
201 priv->ctl_play &= ~(KIRKWOOD_PLAYCTL_MONO_MASK |
202 KIRKWOOD_PLAYCTL_I2S_EN |
203 KIRKWOOD_PLAYCTL_SPDIF_EN |
204 KIRKWOOD_PLAYCTL_SIZE_MASK);
205 priv->ctl_play |= ctl_play;
206 } else {
207 priv->ctl_rec &= ~KIRKWOOD_RECCTL_SIZE_MASK;
208 priv->ctl_rec |= ctl_rec;
171 } 209 }
172 210
173 writel(i2s_value, priv->io+i2s_reg); 211 writel(i2s_value, priv->io+i2s_reg);
174 writel(value, priv->io+reg);
175 212
176 return 0; 213 return 0;
177} 214}
@@ -205,20 +242,18 @@ static int kirkwood_i2s_play_trigger(struct snd_pcm_substream *substream,
205 242
206 switch (cmd) { 243 switch (cmd) {
207 case SNDRV_PCM_TRIGGER_START: 244 case SNDRV_PCM_TRIGGER_START:
245 /* configure */
246 ctl = priv->ctl_play;
247 value = ctl & ~(KIRKWOOD_PLAYCTL_I2S_EN |
248 KIRKWOOD_PLAYCTL_SPDIF_EN);
249 writel(value, priv->io + KIRKWOOD_PLAYCTL);
250
251 /* enable interrupts */
208 value = readl(priv->io + KIRKWOOD_INT_MASK); 252 value = readl(priv->io + KIRKWOOD_INT_MASK);
209 value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES; 253 value |= KIRKWOOD_INT_CAUSE_PLAY_BYTES;
210 writel(value, priv->io + KIRKWOOD_INT_MASK); 254 writel(value, priv->io + KIRKWOOD_INT_MASK);
211 255
212 /* configure audio & enable i2s playback */ 256 /* enable playback */
213 ctl &= ~KIRKWOOD_PLAYCTL_BURST_MASK;
214 ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE
215 | KIRKWOOD_PLAYCTL_SPDIF_EN);
216
217 if (priv->burst == 32)
218 ctl |= KIRKWOOD_PLAYCTL_BURST_32;
219 else
220 ctl |= KIRKWOOD_PLAYCTL_BURST_128;
221 ctl |= KIRKWOOD_PLAYCTL_I2S_EN;
222 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 257 writel(ctl, priv->io + KIRKWOOD_PLAYCTL);
223 break; 258 break;
224 259
@@ -259,30 +294,24 @@ static int kirkwood_i2s_rec_trigger(struct snd_pcm_substream *substream,
259 int cmd, struct snd_soc_dai *dai) 294 int cmd, struct snd_soc_dai *dai)
260{ 295{
261 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai); 296 struct kirkwood_dma_data *priv = snd_soc_dai_get_drvdata(dai);
262 unsigned long value; 297 uint32_t ctl, value;
263 298
264 value = readl(priv->io + KIRKWOOD_RECCTL); 299 value = readl(priv->io + KIRKWOOD_RECCTL);
265 300
266 switch (cmd) { 301 switch (cmd) {
267 case SNDRV_PCM_TRIGGER_START: 302 case SNDRV_PCM_TRIGGER_START:
303 /* configure */
304 ctl = priv->ctl_rec;
305 value = ctl & ~KIRKWOOD_RECCTL_I2S_EN;
306 writel(value, priv->io + KIRKWOOD_RECCTL);
307
308 /* enable interrupts */
268 value = readl(priv->io + KIRKWOOD_INT_MASK); 309 value = readl(priv->io + KIRKWOOD_INT_MASK);
269 value |= KIRKWOOD_INT_CAUSE_REC_BYTES; 310 value |= KIRKWOOD_INT_CAUSE_REC_BYTES;
270 writel(value, priv->io + KIRKWOOD_INT_MASK); 311 writel(value, priv->io + KIRKWOOD_INT_MASK);
271 312
272 /* configure audio & enable i2s record */ 313 /* enable record */
273 value = readl(priv->io + KIRKWOOD_RECCTL); 314 writel(ctl, priv->io + KIRKWOOD_RECCTL);
274 value &= ~KIRKWOOD_RECCTL_BURST_MASK;
275 value &= ~KIRKWOOD_RECCTL_MONO;
276 value &= ~(KIRKWOOD_RECCTL_PAUSE | KIRKWOOD_RECCTL_MUTE
277 | KIRKWOOD_RECCTL_SPDIF_EN);
278
279 if (priv->burst == 32)
280 value |= KIRKWOOD_RECCTL_BURST_32;
281 else
282 value |= KIRKWOOD_RECCTL_BURST_128;
283 value |= KIRKWOOD_RECCTL_I2S_EN;
284
285 writel(value, priv->io + KIRKWOOD_RECCTL);
286 break; 315 break;
287 316
288 case SNDRV_PCM_TRIGGER_STOP: 317 case SNDRV_PCM_TRIGGER_STOP:
@@ -389,90 +418,125 @@ static struct snd_soc_dai_driver kirkwood_i2s_dai = {
389 .channels_min = 1, 418 .channels_min = 1,
390 .channels_max = 2, 419 .channels_max = 2,
391 .rates = KIRKWOOD_I2S_RATES, 420 .rates = KIRKWOOD_I2S_RATES,
392 .formats = KIRKWOOD_I2S_FORMATS,}, 421 .formats = KIRKWOOD_I2S_FORMATS,
422 },
393 .capture = { 423 .capture = {
394 .channels_min = 1, 424 .channels_min = 1,
395 .channels_max = 2, 425 .channels_max = 2,
396 .rates = KIRKWOOD_I2S_RATES, 426 .rates = KIRKWOOD_I2S_RATES,
397 .formats = KIRKWOOD_I2S_FORMATS,}, 427 .formats = KIRKWOOD_I2S_FORMATS,
428 },
429 .ops = &kirkwood_i2s_dai_ops,
430};
431
432static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = {
433 .probe = kirkwood_i2s_probe,
434 .remove = kirkwood_i2s_remove,
435 .playback = {
436 .channels_min = 1,
437 .channels_max = 2,
438 .rates = SNDRV_PCM_RATE_8000_192000 |
439 SNDRV_PCM_RATE_CONTINUOUS |
440 SNDRV_PCM_RATE_KNOT,
441 .formats = KIRKWOOD_I2S_FORMATS,
442 },
443 .capture = {
444 .channels_min = 1,
445 .channels_max = 2,
446 .rates = SNDRV_PCM_RATE_8000_192000 |
447 SNDRV_PCM_RATE_CONTINUOUS |
448 SNDRV_PCM_RATE_KNOT,
449 .formats = KIRKWOOD_I2S_FORMATS,
450 },
398 .ops = &kirkwood_i2s_dai_ops, 451 .ops = &kirkwood_i2s_dai_ops,
399}; 452};
400 453
401static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev) 454static __devinit int kirkwood_i2s_dev_probe(struct platform_device *pdev)
402{ 455{
403 struct resource *mem; 456 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data;
404 struct kirkwood_asoc_platform_data *data = 457 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai;
405 pdev->dev.platform_data;
406 struct kirkwood_dma_data *priv; 458 struct kirkwood_dma_data *priv;
459 struct resource *mem;
407 int err; 460 int err;
408 461
409 priv = kzalloc(sizeof(struct kirkwood_dma_data), GFP_KERNEL); 462 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
410 if (!priv) { 463 if (!priv) {
411 dev_err(&pdev->dev, "allocation failed\n"); 464 dev_err(&pdev->dev, "allocation failed\n");
412 err = -ENOMEM; 465 return -ENOMEM;
413 goto error;
414 } 466 }
415 dev_set_drvdata(&pdev->dev, priv); 467 dev_set_drvdata(&pdev->dev, priv);
416 468
417 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); 469 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
418 if (!mem) { 470 if (!mem) {
419 dev_err(&pdev->dev, "platform_get_resource failed\n"); 471 dev_err(&pdev->dev, "platform_get_resource failed\n");
420 err = -ENXIO; 472 return -ENXIO;
421 goto err_alloc;
422 }
423
424 priv->mem = request_mem_region(mem->start, SZ_16K, DRV_NAME);
425 if (!priv->mem) {
426 dev_err(&pdev->dev, "request_mem_region failed\n");
427 err = -EBUSY;
428 goto err_alloc;
429 } 473 }
430 474
431 priv->io = ioremap(priv->mem->start, SZ_16K); 475 priv->io = devm_request_and_ioremap(&pdev->dev, mem);
432 if (!priv->io) { 476 if (!priv->io) {
433 dev_err(&pdev->dev, "ioremap failed\n"); 477 dev_err(&pdev->dev, "devm_request_and_ioremap failed\n");
434 err = -ENOMEM; 478 return -ENOMEM;
435 goto err_iomem;
436 } 479 }
437 480
438 priv->irq = platform_get_irq(pdev, 0); 481 priv->irq = platform_get_irq(pdev, 0);
439 if (priv->irq <= 0) { 482 if (priv->irq <= 0) {
440 dev_err(&pdev->dev, "platform_get_irq failed\n"); 483 dev_err(&pdev->dev, "platform_get_irq failed\n");
441 err = -ENXIO; 484 return -ENXIO;
442 goto err_ioremap;
443 } 485 }
444 486
445 if (!data) { 487 if (!data) {
446 dev_err(&pdev->dev, "no platform data ?!\n"); 488 dev_err(&pdev->dev, "no platform data ?!\n");
447 err = -EINVAL; 489 return -EINVAL;
448 goto err_ioremap;
449 } 490 }
450 491
451 priv->burst = data->burst; 492 priv->burst = data->burst;
452 493
453 priv->clk = clk_get(&pdev->dev, NULL); 494 priv->clk = devm_clk_get(&pdev->dev, NULL);
454 if (IS_ERR(priv->clk)) { 495 if (IS_ERR(priv->clk)) {
455 dev_err(&pdev->dev, "no clock\n"); 496 dev_err(&pdev->dev, "no clock\n");
456 err = PTR_ERR(priv->clk); 497 return PTR_ERR(priv->clk);
457 goto err_ioremap; 498 }
499
500 err = clk_prepare_enable(priv->clk);
501 if (err < 0)
502 return err;
503
504 priv->extclk = clk_get(&pdev->dev, "extclk");
505 if (!IS_ERR(priv->extclk)) {
506 if (priv->extclk == priv->clk) {
507 clk_put(priv->extclk);
508 priv->extclk = ERR_PTR(-EINVAL);
509 } else {
510 dev_info(&pdev->dev, "found external clock\n");
511 clk_prepare_enable(priv->extclk);
512 soc_dai = &kirkwood_i2s_dai_extclk;
513 }
514 }
515
516 /* Some sensible defaults - this reflects the powerup values */
517 priv->ctl_play = KIRKWOOD_PLAYCTL_SIZE_24;
518 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
519
520 /* Select the burst size */
521 if (data->burst == 32) {
522 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
523 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
524 } else {
525 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128;
526 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128;
458 } 527 }
459 clk_prepare_enable(priv->clk);
460 528
461 err = snd_soc_register_dai(&pdev->dev, &kirkwood_i2s_dai); 529 err = snd_soc_register_dai(&pdev->dev, soc_dai);
462 if (!err) 530 if (!err)
463 return 0; 531 return 0;
464 dev_err(&pdev->dev, "snd_soc_register_dai failed\n"); 532 dev_err(&pdev->dev, "snd_soc_register_dai failed\n");
465 533
534 if (!IS_ERR(priv->extclk)) {
535 clk_disable_unprepare(priv->extclk);
536 clk_put(priv->extclk);
537 }
466 clk_disable_unprepare(priv->clk); 538 clk_disable_unprepare(priv->clk);
467 clk_put(priv->clk); 539
468
469err_ioremap:
470 iounmap(priv->io);
471err_iomem:
472 release_mem_region(priv->mem->start, SZ_16K);
473err_alloc:
474 kfree(priv);
475error:
476 return err; 540 return err;
477} 541}
478 542
@@ -482,12 +546,11 @@ static __devexit int kirkwood_i2s_dev_remove(struct platform_device *pdev)
482 546
483 snd_soc_unregister_dai(&pdev->dev); 547 snd_soc_unregister_dai(&pdev->dev);
484 548
549 if (!IS_ERR(priv->extclk)) {
550 clk_disable_unprepare(priv->extclk);
551 clk_put(priv->extclk);
552 }
485 clk_disable_unprepare(priv->clk); 553 clk_disable_unprepare(priv->clk);
486 clk_put(priv->clk);
487
488 iounmap(priv->io);
489 release_mem_region(priv->mem->start, SZ_16K);
490 kfree(priv);
491 554
492 return 0; 555 return 0;
493} 556}
diff --git a/sound/soc/kirkwood/kirkwood.h b/sound/soc/kirkwood/kirkwood.h
index f9084d83e6bd..4d92637ddb3f 100644
--- a/sound/soc/kirkwood/kirkwood.h
+++ b/sound/soc/kirkwood/kirkwood.h
@@ -77,6 +77,11 @@
77#define KIRKWOOD_DCO_SPCR_STATUS 0x120c 77#define KIRKWOOD_DCO_SPCR_STATUS 0x120c
78#define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16) 78#define KIRKWOOD_DCO_SPCR_STATUS_DCO_LOCK (1<<16)
79 79
80#define KIRKWOOD_CLOCKS_CTRL 0x1230
81#define KIRKWOOD_MCLK_SOURCE_MASK (3<<0)
82#define KIRKWOOD_MCLK_SOURCE_DCO (0<<0)
83#define KIRKWOOD_MCLK_SOURCE_EXTCLK (3<<0)
84
80#define KIRKWOOD_ERR_CAUSE 0x1300 85#define KIRKWOOD_ERR_CAUSE 0x1300
81#define KIRKWOOD_ERR_MASK 0x1304 86#define KIRKWOOD_ERR_MASK 0x1304
82 87
@@ -119,11 +124,13 @@
119#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000 124#define KIRKWOOD_SND_MAX_PERIOD_BYTES 0x4000
120 125
121struct kirkwood_dma_data { 126struct kirkwood_dma_data {
122 struct resource *mem;
123 void __iomem *io; 127 void __iomem *io;
128 struct clk *clk;
129 struct clk *extclk;
130 uint32_t ctl_play;
131 uint32_t ctl_rec;
124 int irq; 132 int irq;
125 int burst; 133 int burst;
126 struct clk *clk;
127}; 134};
128 135
129#endif 136#endif