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