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