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