kirkwood-i2s.c (1f1b65796ef882bb9101d22b17e1a1824b3a6489) | kirkwood-i2s.c (75b9b65ee5a80e99efe2fd551d08bc86f115550f) |
---|---|
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 --- 146 unchanged lines hidden (view full) --- 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 | | 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 --- 146 unchanged lines hidden (view full) --- 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; | 163 KIRKWOOD_PLAYCTL_I2S_EN | 164 KIRKWOOD_PLAYCTL_SPDIF_EN; |
164 ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | | 165 ctl_rec = KIRKWOOD_RECCTL_SIZE_16_C | |
165 KIRKWOOD_RECCTL_I2S_EN; | 166 KIRKWOOD_RECCTL_I2S_EN | 167 KIRKWOOD_RECCTL_SPDIF_EN; |
166 break; 167 /* 168 * doesn't work... S20_3LE != kirkwood 20bit format ? 169 * 170 case SNDRV_PCM_FORMAT_S20_3LE: 171 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_20; 172 ctl_play = KIRKWOOD_PLAYCTL_SIZE_20 | 173 KIRKWOOD_PLAYCTL_I2S_EN; 174 ctl_rec = KIRKWOOD_RECCTL_SIZE_20 | 175 KIRKWOOD_RECCTL_I2S_EN; 176 break; 177 */ 178 case SNDRV_PCM_FORMAT_S24_LE: 179 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_24; 180 ctl_play = KIRKWOOD_PLAYCTL_SIZE_24 | | 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 | |
181 KIRKWOOD_PLAYCTL_I2S_EN; | 183 KIRKWOOD_PLAYCTL_I2S_EN | 184 KIRKWOOD_PLAYCTL_SPDIF_EN; |
182 ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | | 185 ctl_rec = KIRKWOOD_RECCTL_SIZE_24 | |
183 KIRKWOOD_RECCTL_I2S_EN; | 186 KIRKWOOD_RECCTL_I2S_EN | 187 KIRKWOOD_RECCTL_SPDIF_EN; |
184 break; 185 case SNDRV_PCM_FORMAT_S32_LE: 186 i2s_value |= KIRKWOOD_I2S_CTL_SIZE_32; 187 ctl_play = KIRKWOOD_PLAYCTL_SIZE_32 | 188 KIRKWOOD_PLAYCTL_I2S_EN; 189 ctl_rec = KIRKWOOD_RECCTL_SIZE_32 | 190 KIRKWOOD_RECCTL_I2S_EN; 191 break; --- 43 unchanged lines hidden (view full) --- 235 udelay(1); 236 } while (timeout--); 237 238 if ((ctl | value) & KIRKWOOD_PLAYCTL_PLAY_BUSY) 239 dev_notice(dai->dev, "timed out waiting for busy to deassert: %08x\n", 240 ctl); 241 } 242 | 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; --- 43 unchanged lines hidden (view full) --- 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 |
|
243 switch (cmd) { 244 case SNDRV_PCM_TRIGGER_START: 245 /* configure */ 246 ctl = priv->ctl_play; 247 value = ctl & ~KIRKWOOD_PLAYCTL_ENABLE_MASK; 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 */ | 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 */ |
261 ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; | 270 ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | 271 KIRKWOOD_PLAYCTL_SPDIF_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_ENABLE_MASK; 270 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 271 break; 272 273 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 274 case SNDRV_PCM_TRIGGER_SUSPEND: | 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: |
275 ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE; | 285 ctl |= KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | 286 KIRKWOOD_PLAYCTL_SPDIF_MUTE; |
276 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 277 break; 278 279 case SNDRV_PCM_TRIGGER_RESUME: 280 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 287 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 288 break; 289 290 case SNDRV_PCM_TRIGGER_RESUME: 291 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
281 ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE); | 292 ctl &= ~(KIRKWOOD_PLAYCTL_PAUSE | KIRKWOOD_PLAYCTL_I2S_MUTE | 293 KIRKWOOD_PLAYCTL_SPDIF_MUTE); |
282 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 283 break; 284 285 default: 286 return -EINVAL; 287 } 288 289 return 0; --- 6 unchanged lines hidden (view full) --- 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; | 294 writel(ctl, priv->io + KIRKWOOD_PLAYCTL); 295 break; 296 297 default: 298 return -EINVAL; 299 } 300 301 return 0; --- 6 unchanged lines hidden (view full) --- 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; |
304 value = ctl & ~KIRKWOOD_RECCTL_I2S_EN; | 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); |
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 */ --- 43 unchanged lines hidden (view full) --- 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 | 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 */ --- 43 unchanged lines hidden (view full) --- 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 |
364static int kirkwood_i2s_probe(struct snd_soc_dai *dai) | 382static int kirkwood_i2s_init(struct kirkwood_dma_data *priv) |
365{ | 383{ |
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 --- 24 unchanged lines hidden (view full) --- 399 400static 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 | 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 --- 24 unchanged lines hidden (view full) --- 416 417static 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 |
407 408static struct snd_soc_dai_driver kirkwood_i2s_dai = { 409 .probe = kirkwood_i2s_probe, | 424static struct snd_soc_dai_driver kirkwood_i2s_dai[2] = { 425 { 426 .name = "i2s", 427 .id = 0, |
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, | 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 }, |
|
425}; 426 | 463}; 464 |
427static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk = { 428 .probe = kirkwood_i2s_probe, | 465static struct snd_soc_dai_driver kirkwood_i2s_dai_extclk[2] = { 466 { 467 .name = "i2s", 468 .id = 0, |
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, | 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 }, |
|
446}; 447 448static const struct snd_soc_component_driver kirkwood_i2s_component = { 449 .name = DRV_NAME, 450}; 451 452static int kirkwood_i2s_dev_probe(struct platform_device *pdev) 453{ 454 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; | 508}; 509 510static const struct snd_soc_component_driver kirkwood_i2s_component = { 511 .name = DRV_NAME, 512}; 513 514static int kirkwood_i2s_dev_probe(struct platform_device *pdev) 515{ 516 struct kirkwood_asoc_platform_data *data = pdev->dev.platform_data; |
455 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; | 517 struct snd_soc_dai_driver *soc_dai = kirkwood_i2s_dai; |
456 struct kirkwood_dma_data *priv; 457 struct resource *mem; 458 struct device_node *np = pdev->dev.of_node; 459 int err; 460 461 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 462 if (!priv) { 463 dev_err(&pdev->dev, "allocation failed\n"); --- 55 unchanged lines hidden (view full) --- 519 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; 520 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; 521 } else { 522 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_128; 523 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_128; 524 } 525 526 err = snd_soc_register_component(&pdev->dev, &kirkwood_i2s_component, | 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"); --- 55 unchanged lines hidden (view full) --- 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, |
527 soc_dai, 1); | 589 soc_dai, 2); |
528 if (err) { 529 dev_err(&pdev->dev, "snd_soc_register_component failed\n"); 530 goto err_component; 531 } 532 533 err = snd_soc_register_platform(&pdev->dev, &kirkwood_soc_platform); 534 if (err) { 535 dev_err(&pdev->dev, "snd_soc_register_platform failed\n"); 536 goto err_platform; 537 } | 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 |
|
538 return 0; 539 err_platform: 540 snd_soc_unregister_component(&pdev->dev); 541 err_component: 542 if (!IS_ERR(priv->extclk)) 543 clk_disable_unprepare(priv->extclk); 544 clk_disable_unprepare(priv->clk); 545 --- 43 unchanged lines hidden --- | 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 --- 43 unchanged lines hidden --- |