| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * atmel_ssc_dai.c -- ALSA SoC ATMEL SSC Audio Layer Platform driver |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 11 | 12 | * Frank Mandarino <fmandarino@endrelia.com> |
|---|
| 12 | 13 | * Based on pxa2xx Platform drivers by |
|---|
| 13 | 14 | * Liam Girdwood <lrg@slimlogic.co.uk> |
|---|
| 14 | | - * |
|---|
| 15 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 16 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 17 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 18 | | - * (at your option) any later version. |
|---|
| 19 | | - * |
|---|
| 20 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 21 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 22 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 23 | | - * GNU General Public License for more details. |
|---|
| 24 | | - * |
|---|
| 25 | | - * You should have received a copy of the GNU General Public License |
|---|
| 26 | | - * along with this program; if not, write to the Free Software |
|---|
| 27 | | - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 28 | 15 | */ |
|---|
| 29 | 16 | |
|---|
| 30 | 17 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 129 | 116 | static struct atmel_ssc_info ssc_info[NUM_SSC_DEVICES] = { |
|---|
| 130 | 117 | { |
|---|
| 131 | 118 | .name = "ssc0", |
|---|
| 132 | | - .lock = __SPIN_LOCK_UNLOCKED(ssc_info[0].lock), |
|---|
| 133 | 119 | .dir_mask = SSC_DIR_MASK_UNUSED, |
|---|
| 134 | 120 | .initialized = 0, |
|---|
| 135 | 121 | }, |
|---|
| 136 | 122 | { |
|---|
| 137 | 123 | .name = "ssc1", |
|---|
| 138 | | - .lock = __SPIN_LOCK_UNLOCKED(ssc_info[1].lock), |
|---|
| 139 | 124 | .dir_mask = SSC_DIR_MASK_UNUSED, |
|---|
| 140 | 125 | .initialized = 0, |
|---|
| 141 | 126 | }, |
|---|
| 142 | 127 | { |
|---|
| 143 | 128 | .name = "ssc2", |
|---|
| 144 | | - .lock = __SPIN_LOCK_UNLOCKED(ssc_info[2].lock), |
|---|
| 145 | 129 | .dir_mask = SSC_DIR_MASK_UNUSED, |
|---|
| 146 | 130 | .initialized = 0, |
|---|
| 147 | 131 | }, |
|---|
| .. | .. |
|---|
| 296 | 280 | |
|---|
| 297 | 281 | /* Enable PMC peripheral clock for this SSC */ |
|---|
| 298 | 282 | pr_debug("atmel_ssc_dai: Starting clock\n"); |
|---|
| 299 | | - clk_enable(ssc_p->ssc->clk); |
|---|
| 283 | + ret = clk_enable(ssc_p->ssc->clk); |
|---|
| 284 | + if (ret) |
|---|
| 285 | + return ret; |
|---|
| 286 | + |
|---|
| 300 | 287 | ssc_p->mck_rate = clk_get_rate(ssc_p->ssc->clk); |
|---|
| 301 | 288 | |
|---|
| 302 | 289 | /* Reset the SSC unless initialized to keep it in a clean state */ |
|---|
| .. | .. |
|---|
| 330 | 317 | |
|---|
| 331 | 318 | snd_soc_dai_set_dma_data(dai, substream, dma_params); |
|---|
| 332 | 319 | |
|---|
| 333 | | - spin_lock_irq(&ssc_p->lock); |
|---|
| 334 | | - if (ssc_p->dir_mask & dir_mask) { |
|---|
| 335 | | - spin_unlock_irq(&ssc_p->lock); |
|---|
| 320 | + if (ssc_p->dir_mask & dir_mask) |
|---|
| 336 | 321 | return -EBUSY; |
|---|
| 337 | | - } |
|---|
| 322 | + |
|---|
| 338 | 323 | ssc_p->dir_mask |= dir_mask; |
|---|
| 339 | | - spin_unlock_irq(&ssc_p->lock); |
|---|
| 340 | 324 | |
|---|
| 341 | 325 | return 0; |
|---|
| 342 | 326 | } |
|---|
| .. | .. |
|---|
| 368 | 352 | |
|---|
| 369 | 353 | dir_mask = 1 << dir; |
|---|
| 370 | 354 | |
|---|
| 371 | | - spin_lock_irq(&ssc_p->lock); |
|---|
| 372 | 355 | ssc_p->dir_mask &= ~dir_mask; |
|---|
| 373 | 356 | if (!ssc_p->dir_mask) { |
|---|
| 374 | 357 | if (ssc_p->initialized) { |
|---|
| .. | .. |
|---|
| 382 | 365 | ssc_p->cmr_div = ssc_p->tcmr_period = ssc_p->rcmr_period = 0; |
|---|
| 383 | 366 | ssc_p->forced_divider = 0; |
|---|
| 384 | 367 | } |
|---|
| 385 | | - spin_unlock_irq(&ssc_p->lock); |
|---|
| 386 | 368 | |
|---|
| 387 | 369 | /* Shutdown the SSC clock. */ |
|---|
| 388 | 370 | pr_debug("atmel_ssc_dai: Stopping clock\n"); |
|---|
| .. | .. |
|---|
| 484 | 466 | int dir, channels, bits; |
|---|
| 485 | 467 | u32 tfmr, rfmr, tcmr, rcmr; |
|---|
| 486 | 468 | int ret; |
|---|
| 487 | | - int fslen, fslen_ext; |
|---|
| 469 | + int fslen, fslen_ext, fs_osync, fs_edge; |
|---|
| 488 | 470 | u32 cmr_div; |
|---|
| 489 | 471 | u32 tcmr_period; |
|---|
| 490 | 472 | u32 rcmr_period; |
|---|
| .. | .. |
|---|
| 571 | 553 | /* |
|---|
| 572 | 554 | * Compute SSC register settings. |
|---|
| 573 | 555 | */ |
|---|
| 574 | | - switch (ssc_p->daifmt |
|---|
| 575 | | - & (SND_SOC_DAIFMT_FORMAT_MASK | SND_SOC_DAIFMT_MASTER_MASK)) { |
|---|
| 576 | 556 | |
|---|
| 577 | | - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS: |
|---|
| 557 | + fslen_ext = (bits - 1) / 16; |
|---|
| 558 | + fslen = (bits - 1) % 16; |
|---|
| 559 | + |
|---|
| 560 | + switch (ssc_p->daifmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
|---|
| 561 | + |
|---|
| 562 | + case SND_SOC_DAIFMT_LEFT_J: |
|---|
| 563 | + fs_osync = SSC_FSOS_POSITIVE; |
|---|
| 564 | + fs_edge = SSC_START_RISING_RF; |
|---|
| 565 | + |
|---|
| 566 | + rcmr = SSC_BF(RCMR_STTDLY, 0); |
|---|
| 567 | + tcmr = SSC_BF(TCMR_STTDLY, 0); |
|---|
| 568 | + |
|---|
| 569 | + break; |
|---|
| 570 | + |
|---|
| 571 | + case SND_SOC_DAIFMT_I2S: |
|---|
| 572 | + fs_osync = SSC_FSOS_NEGATIVE; |
|---|
| 573 | + fs_edge = SSC_START_FALLING_RF; |
|---|
| 574 | + |
|---|
| 575 | + rcmr = SSC_BF(RCMR_STTDLY, 1); |
|---|
| 576 | + tcmr = SSC_BF(TCMR_STTDLY, 1); |
|---|
| 577 | + |
|---|
| 578 | + break; |
|---|
| 579 | + |
|---|
| 580 | + case SND_SOC_DAIFMT_DSP_A: |
|---|
| 578 | 581 | /* |
|---|
| 579 | | - * I2S format, SSC provides BCLK and LRC clocks. |
|---|
| 580 | | - * |
|---|
| 581 | | - * The SSC transmit and receive clocks are generated |
|---|
| 582 | | - * from the MCK divider, and the BCLK signal |
|---|
| 583 | | - * is output on the SSC TK line. |
|---|
| 584 | | - */ |
|---|
| 585 | | - |
|---|
| 586 | | - if (bits > 16 && !ssc->pdata->has_fslen_ext) { |
|---|
| 587 | | - dev_err(dai->dev, |
|---|
| 588 | | - "sample size %d is too large for SSC device\n", |
|---|
| 589 | | - bits); |
|---|
| 590 | | - return -EINVAL; |
|---|
| 591 | | - } |
|---|
| 592 | | - |
|---|
| 593 | | - fslen_ext = (bits - 1) / 16; |
|---|
| 594 | | - fslen = (bits - 1) % 16; |
|---|
| 595 | | - |
|---|
| 596 | | - rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) |
|---|
| 597 | | - | SSC_BF(RCMR_STTDLY, START_DELAY) |
|---|
| 598 | | - | SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
|---|
| 599 | | - | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
|---|
| 600 | | - | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
|---|
| 601 | | - | SSC_BF(RCMR_CKS, SSC_CKS_DIV); |
|---|
| 602 | | - |
|---|
| 603 | | - rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) |
|---|
| 604 | | - | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 605 | | - | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) |
|---|
| 606 | | - | SSC_BF(RFMR_FSLEN, fslen) |
|---|
| 607 | | - | SSC_BF(RFMR_DATNB, (channels - 1)) |
|---|
| 608 | | - | SSC_BIT(RFMR_MSBF) |
|---|
| 609 | | - | SSC_BF(RFMR_LOOP, 0) |
|---|
| 610 | | - | SSC_BF(RFMR_DATLEN, (bits - 1)); |
|---|
| 611 | | - |
|---|
| 612 | | - tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) |
|---|
| 613 | | - | SSC_BF(TCMR_STTDLY, START_DELAY) |
|---|
| 614 | | - | SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
|---|
| 615 | | - | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
|---|
| 616 | | - | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
|---|
| 617 | | - | SSC_BF(TCMR_CKS, SSC_CKS_DIV); |
|---|
| 618 | | - |
|---|
| 619 | | - tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) |
|---|
| 620 | | - | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 621 | | - | SSC_BF(TFMR_FSDEN, 0) |
|---|
| 622 | | - | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) |
|---|
| 623 | | - | SSC_BF(TFMR_FSLEN, fslen) |
|---|
| 624 | | - | SSC_BF(TFMR_DATNB, (channels - 1)) |
|---|
| 625 | | - | SSC_BIT(TFMR_MSBF) |
|---|
| 626 | | - | SSC_BF(TFMR_DATDEF, 0) |
|---|
| 627 | | - | SSC_BF(TFMR_DATLEN, (bits - 1)); |
|---|
| 628 | | - break; |
|---|
| 629 | | - |
|---|
| 630 | | - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM: |
|---|
| 631 | | - /* I2S format, CODEC supplies BCLK and LRC clocks. */ |
|---|
| 632 | | - rcmr = SSC_BF(RCMR_PERIOD, 0) |
|---|
| 633 | | - | SSC_BF(RCMR_STTDLY, START_DELAY) |
|---|
| 634 | | - | SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
|---|
| 635 | | - | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
|---|
| 636 | | - | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
|---|
| 637 | | - | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 638 | | - SSC_CKS_PIN : SSC_CKS_CLOCK); |
|---|
| 639 | | - |
|---|
| 640 | | - rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 641 | | - | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
|---|
| 642 | | - | SSC_BF(RFMR_FSLEN, 0) |
|---|
| 643 | | - | SSC_BF(RFMR_DATNB, (channels - 1)) |
|---|
| 644 | | - | SSC_BIT(RFMR_MSBF) |
|---|
| 645 | | - | SSC_BF(RFMR_LOOP, 0) |
|---|
| 646 | | - | SSC_BF(RFMR_DATLEN, (bits - 1)); |
|---|
| 647 | | - |
|---|
| 648 | | - tcmr = SSC_BF(TCMR_PERIOD, 0) |
|---|
| 649 | | - | SSC_BF(TCMR_STTDLY, START_DELAY) |
|---|
| 650 | | - | SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
|---|
| 651 | | - | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
|---|
| 652 | | - | SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
|---|
| 653 | | - | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 654 | | - SSC_CKS_CLOCK : SSC_CKS_PIN); |
|---|
| 655 | | - |
|---|
| 656 | | - tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 657 | | - | SSC_BF(TFMR_FSDEN, 0) |
|---|
| 658 | | - | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
|---|
| 659 | | - | SSC_BF(TFMR_FSLEN, 0) |
|---|
| 660 | | - | SSC_BF(TFMR_DATNB, (channels - 1)) |
|---|
| 661 | | - | SSC_BIT(TFMR_MSBF) |
|---|
| 662 | | - | SSC_BF(TFMR_DATDEF, 0) |
|---|
| 663 | | - | SSC_BF(TFMR_DATLEN, (bits - 1)); |
|---|
| 664 | | - break; |
|---|
| 665 | | - |
|---|
| 666 | | - case SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFS: |
|---|
| 667 | | - /* I2S format, CODEC supplies BCLK, SSC supplies LRCLK. */ |
|---|
| 668 | | - if (bits > 16 && !ssc->pdata->has_fslen_ext) { |
|---|
| 669 | | - dev_err(dai->dev, |
|---|
| 670 | | - "sample size %d is too large for SSC device\n", |
|---|
| 671 | | - bits); |
|---|
| 672 | | - return -EINVAL; |
|---|
| 673 | | - } |
|---|
| 674 | | - |
|---|
| 675 | | - fslen_ext = (bits - 1) / 16; |
|---|
| 676 | | - fslen = (bits - 1) % 16; |
|---|
| 677 | | - |
|---|
| 678 | | - rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) |
|---|
| 679 | | - | SSC_BF(RCMR_STTDLY, START_DELAY) |
|---|
| 680 | | - | SSC_BF(RCMR_START, SSC_START_FALLING_RF) |
|---|
| 681 | | - | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
|---|
| 682 | | - | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
|---|
| 683 | | - | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 684 | | - SSC_CKS_PIN : SSC_CKS_CLOCK); |
|---|
| 685 | | - |
|---|
| 686 | | - rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) |
|---|
| 687 | | - | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 688 | | - | SSC_BF(RFMR_FSOS, SSC_FSOS_NEGATIVE) |
|---|
| 689 | | - | SSC_BF(RFMR_FSLEN, fslen) |
|---|
| 690 | | - | SSC_BF(RFMR_DATNB, (channels - 1)) |
|---|
| 691 | | - | SSC_BIT(RFMR_MSBF) |
|---|
| 692 | | - | SSC_BF(RFMR_LOOP, 0) |
|---|
| 693 | | - | SSC_BF(RFMR_DATLEN, (bits - 1)); |
|---|
| 694 | | - |
|---|
| 695 | | - tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) |
|---|
| 696 | | - | SSC_BF(TCMR_STTDLY, START_DELAY) |
|---|
| 697 | | - | SSC_BF(TCMR_START, SSC_START_FALLING_RF) |
|---|
| 698 | | - | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
|---|
| 699 | | - | SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
|---|
| 700 | | - | SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 701 | | - SSC_CKS_CLOCK : SSC_CKS_PIN); |
|---|
| 702 | | - |
|---|
| 703 | | - tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) |
|---|
| 704 | | - | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_NEGATIVE) |
|---|
| 705 | | - | SSC_BF(TFMR_FSDEN, 0) |
|---|
| 706 | | - | SSC_BF(TFMR_FSOS, SSC_FSOS_NEGATIVE) |
|---|
| 707 | | - | SSC_BF(TFMR_FSLEN, fslen) |
|---|
| 708 | | - | SSC_BF(TFMR_DATNB, (channels - 1)) |
|---|
| 709 | | - | SSC_BIT(TFMR_MSBF) |
|---|
| 710 | | - | SSC_BF(TFMR_DATDEF, 0) |
|---|
| 711 | | - | SSC_BF(TFMR_DATLEN, (bits - 1)); |
|---|
| 712 | | - break; |
|---|
| 713 | | - |
|---|
| 714 | | - case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBS_CFS: |
|---|
| 715 | | - /* |
|---|
| 716 | | - * DSP/PCM Mode A format, SSC provides BCLK and LRC clocks. |
|---|
| 717 | | - * |
|---|
| 718 | | - * The SSC transmit and receive clocks are generated from the |
|---|
| 719 | | - * MCK divider, and the BCLK signal is output |
|---|
| 720 | | - * on the SSC TK line. |
|---|
| 721 | | - */ |
|---|
| 722 | | - rcmr = SSC_BF(RCMR_PERIOD, rcmr_period) |
|---|
| 723 | | - | SSC_BF(RCMR_STTDLY, 1) |
|---|
| 724 | | - | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
|---|
| 725 | | - | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
|---|
| 726 | | - | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
|---|
| 727 | | - | SSC_BF(RCMR_CKS, SSC_CKS_DIV); |
|---|
| 728 | | - |
|---|
| 729 | | - rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 730 | | - | SSC_BF(RFMR_FSOS, SSC_FSOS_POSITIVE) |
|---|
| 731 | | - | SSC_BF(RFMR_FSLEN, 0) |
|---|
| 732 | | - | SSC_BF(RFMR_DATNB, (channels - 1)) |
|---|
| 733 | | - | SSC_BIT(RFMR_MSBF) |
|---|
| 734 | | - | SSC_BF(RFMR_LOOP, 0) |
|---|
| 735 | | - | SSC_BF(RFMR_DATLEN, (bits - 1)); |
|---|
| 736 | | - |
|---|
| 737 | | - tcmr = SSC_BF(TCMR_PERIOD, tcmr_period) |
|---|
| 738 | | - | SSC_BF(TCMR_STTDLY, 1) |
|---|
| 739 | | - | SSC_BF(TCMR_START, SSC_START_RISING_RF) |
|---|
| 740 | | - | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
|---|
| 741 | | - | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS) |
|---|
| 742 | | - | SSC_BF(TCMR_CKS, SSC_CKS_DIV); |
|---|
| 743 | | - |
|---|
| 744 | | - tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 745 | | - | SSC_BF(TFMR_FSDEN, 0) |
|---|
| 746 | | - | SSC_BF(TFMR_FSOS, SSC_FSOS_POSITIVE) |
|---|
| 747 | | - | SSC_BF(TFMR_FSLEN, 0) |
|---|
| 748 | | - | SSC_BF(TFMR_DATNB, (channels - 1)) |
|---|
| 749 | | - | SSC_BIT(TFMR_MSBF) |
|---|
| 750 | | - | SSC_BF(TFMR_DATDEF, 0) |
|---|
| 751 | | - | SSC_BF(TFMR_DATLEN, (bits - 1)); |
|---|
| 752 | | - break; |
|---|
| 753 | | - |
|---|
| 754 | | - case SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_CBM_CFM: |
|---|
| 755 | | - /* |
|---|
| 756 | | - * DSP/PCM Mode A format, CODEC supplies BCLK and LRC clocks. |
|---|
| 582 | + * DSP/PCM Mode A format |
|---|
| 757 | 583 | * |
|---|
| 758 | 584 | * Data is transferred on first BCLK after LRC pulse rising |
|---|
| 759 | 585 | * edge.If stereo, the right channel data is contiguous with |
|---|
| 760 | 586 | * the left channel data. |
|---|
| 761 | 587 | */ |
|---|
| 762 | | - rcmr = SSC_BF(RCMR_PERIOD, 0) |
|---|
| 763 | | - | SSC_BF(RCMR_STTDLY, START_DELAY) |
|---|
| 764 | | - | SSC_BF(RCMR_START, SSC_START_RISING_RF) |
|---|
| 765 | | - | SSC_BF(RCMR_CKI, SSC_CKI_RISING) |
|---|
| 766 | | - | SSC_BF(RCMR_CKO, SSC_CKO_NONE) |
|---|
| 767 | | - | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 768 | | - SSC_CKS_PIN : SSC_CKS_CLOCK); |
|---|
| 588 | + fs_osync = SSC_FSOS_POSITIVE; |
|---|
| 589 | + fs_edge = SSC_START_RISING_RF; |
|---|
| 590 | + fslen = fslen_ext = 0; |
|---|
| 769 | 591 | |
|---|
| 770 | | - rfmr = SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 771 | | - | SSC_BF(RFMR_FSOS, SSC_FSOS_NONE) |
|---|
| 772 | | - | SSC_BF(RFMR_FSLEN, 0) |
|---|
| 773 | | - | SSC_BF(RFMR_DATNB, (channels - 1)) |
|---|
| 774 | | - | SSC_BIT(RFMR_MSBF) |
|---|
| 775 | | - | SSC_BF(RFMR_LOOP, 0) |
|---|
| 776 | | - | SSC_BF(RFMR_DATLEN, (bits - 1)); |
|---|
| 592 | + rcmr = SSC_BF(RCMR_STTDLY, 1); |
|---|
| 593 | + tcmr = SSC_BF(TCMR_STTDLY, 1); |
|---|
| 777 | 594 | |
|---|
| 778 | | - tcmr = SSC_BF(TCMR_PERIOD, 0) |
|---|
| 779 | | - | SSC_BF(TCMR_STTDLY, START_DELAY) |
|---|
| 780 | | - | SSC_BF(TCMR_START, SSC_START_RISING_RF) |
|---|
| 781 | | - | SSC_BF(TCMR_CKI, SSC_CKI_FALLING) |
|---|
| 782 | | - | SSC_BF(TCMR_CKO, SSC_CKO_NONE) |
|---|
| 783 | | - | SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 784 | | - SSC_CKS_CLOCK : SSC_CKS_PIN); |
|---|
| 785 | | - |
|---|
| 786 | | - tfmr = SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 787 | | - | SSC_BF(TFMR_FSDEN, 0) |
|---|
| 788 | | - | SSC_BF(TFMR_FSOS, SSC_FSOS_NONE) |
|---|
| 789 | | - | SSC_BF(TFMR_FSLEN, 0) |
|---|
| 790 | | - | SSC_BF(TFMR_DATNB, (channels - 1)) |
|---|
| 791 | | - | SSC_BIT(TFMR_MSBF) |
|---|
| 792 | | - | SSC_BF(TFMR_DATDEF, 0) |
|---|
| 793 | | - | SSC_BF(TFMR_DATLEN, (bits - 1)); |
|---|
| 794 | 595 | break; |
|---|
| 795 | 596 | |
|---|
| 796 | 597 | default: |
|---|
| .. | .. |
|---|
| 798 | 599 | ssc_p->daifmt); |
|---|
| 799 | 600 | return -EINVAL; |
|---|
| 800 | 601 | } |
|---|
| 602 | + |
|---|
| 603 | + if (!atmel_ssc_cfs(ssc_p)) { |
|---|
| 604 | + fslen = fslen_ext = 0; |
|---|
| 605 | + rcmr_period = tcmr_period = 0; |
|---|
| 606 | + fs_osync = SSC_FSOS_NONE; |
|---|
| 607 | + } |
|---|
| 608 | + |
|---|
| 609 | + rcmr |= SSC_BF(RCMR_START, fs_edge); |
|---|
| 610 | + tcmr |= SSC_BF(TCMR_START, fs_edge); |
|---|
| 611 | + |
|---|
| 612 | + if (atmel_ssc_cbs(ssc_p)) { |
|---|
| 613 | + /* |
|---|
| 614 | + * SSC provides BCLK |
|---|
| 615 | + * |
|---|
| 616 | + * The SSC transmit and receive clocks are generated from the |
|---|
| 617 | + * MCK divider, and the BCLK signal is output |
|---|
| 618 | + * on the SSC TK line. |
|---|
| 619 | + */ |
|---|
| 620 | + rcmr |= SSC_BF(RCMR_CKS, SSC_CKS_DIV) |
|---|
| 621 | + | SSC_BF(RCMR_CKO, SSC_CKO_NONE); |
|---|
| 622 | + |
|---|
| 623 | + tcmr |= SSC_BF(TCMR_CKS, SSC_CKS_DIV) |
|---|
| 624 | + | SSC_BF(TCMR_CKO, SSC_CKO_CONTINUOUS); |
|---|
| 625 | + } else { |
|---|
| 626 | + rcmr |= SSC_BF(RCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 627 | + SSC_CKS_PIN : SSC_CKS_CLOCK) |
|---|
| 628 | + | SSC_BF(RCMR_CKO, SSC_CKO_NONE); |
|---|
| 629 | + |
|---|
| 630 | + tcmr |= SSC_BF(TCMR_CKS, ssc->clk_from_rk_pin ? |
|---|
| 631 | + SSC_CKS_CLOCK : SSC_CKS_PIN) |
|---|
| 632 | + | SSC_BF(TCMR_CKO, SSC_CKO_NONE); |
|---|
| 633 | + } |
|---|
| 634 | + |
|---|
| 635 | + rcmr |= SSC_BF(RCMR_PERIOD, rcmr_period) |
|---|
| 636 | + | SSC_BF(RCMR_CKI, SSC_CKI_RISING); |
|---|
| 637 | + |
|---|
| 638 | + tcmr |= SSC_BF(TCMR_PERIOD, tcmr_period) |
|---|
| 639 | + | SSC_BF(TCMR_CKI, SSC_CKI_FALLING); |
|---|
| 640 | + |
|---|
| 641 | + rfmr = SSC_BF(RFMR_FSLEN_EXT, fslen_ext) |
|---|
| 642 | + | SSC_BF(RFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 643 | + | SSC_BF(RFMR_FSOS, fs_osync) |
|---|
| 644 | + | SSC_BF(RFMR_FSLEN, fslen) |
|---|
| 645 | + | SSC_BF(RFMR_DATNB, (channels - 1)) |
|---|
| 646 | + | SSC_BIT(RFMR_MSBF) |
|---|
| 647 | + | SSC_BF(RFMR_LOOP, 0) |
|---|
| 648 | + | SSC_BF(RFMR_DATLEN, (bits - 1)); |
|---|
| 649 | + |
|---|
| 650 | + tfmr = SSC_BF(TFMR_FSLEN_EXT, fslen_ext) |
|---|
| 651 | + | SSC_BF(TFMR_FSEDGE, SSC_FSEDGE_POSITIVE) |
|---|
| 652 | + | SSC_BF(TFMR_FSDEN, 0) |
|---|
| 653 | + | SSC_BF(TFMR_FSOS, fs_osync) |
|---|
| 654 | + | SSC_BF(TFMR_FSLEN, fslen) |
|---|
| 655 | + | SSC_BF(TFMR_DATNB, (channels - 1)) |
|---|
| 656 | + | SSC_BIT(TFMR_MSBF) |
|---|
| 657 | + | SSC_BF(TFMR_DATDEF, 0) |
|---|
| 658 | + | SSC_BF(TFMR_DATLEN, (bits - 1)); |
|---|
| 659 | + |
|---|
| 660 | + if (fslen_ext && !ssc->pdata->has_fslen_ext) { |
|---|
| 661 | + dev_err(dai->dev, "sample size %d is too large for SSC device\n", |
|---|
| 662 | + bits); |
|---|
| 663 | + return -EINVAL; |
|---|
| 664 | + } |
|---|
| 665 | + |
|---|
| 801 | 666 | pr_debug("atmel_ssc_hw_params: " |
|---|
| 802 | 667 | "RCMR=%08x RFMR=%08x TCMR=%08x TFMR=%08x\n", |
|---|
| 803 | 668 | rcmr, rfmr, tcmr, tfmr); |
|---|
| .. | .. |
|---|
| 898 | 763 | } |
|---|
| 899 | 764 | |
|---|
| 900 | 765 | #ifdef CONFIG_PM |
|---|
| 901 | | -static int atmel_ssc_suspend(struct snd_soc_dai *cpu_dai) |
|---|
| 766 | +static int atmel_ssc_suspend(struct snd_soc_component *component) |
|---|
| 902 | 767 | { |
|---|
| 903 | 768 | struct atmel_ssc_info *ssc_p; |
|---|
| 904 | | - struct platform_device *pdev = to_platform_device(cpu_dai->dev); |
|---|
| 769 | + struct platform_device *pdev = to_platform_device(component->dev); |
|---|
| 905 | 770 | |
|---|
| 906 | | - if (!cpu_dai->active) |
|---|
| 771 | + if (!snd_soc_component_active(component)) |
|---|
| 907 | 772 | return 0; |
|---|
| 908 | 773 | |
|---|
| 909 | 774 | ssc_p = &ssc_info[pdev->id]; |
|---|
| .. | .. |
|---|
| 925 | 790 | return 0; |
|---|
| 926 | 791 | } |
|---|
| 927 | 792 | |
|---|
| 928 | | - |
|---|
| 929 | | - |
|---|
| 930 | | -static int atmel_ssc_resume(struct snd_soc_dai *cpu_dai) |
|---|
| 793 | +static int atmel_ssc_resume(struct snd_soc_component *component) |
|---|
| 931 | 794 | { |
|---|
| 932 | 795 | struct atmel_ssc_info *ssc_p; |
|---|
| 933 | | - struct platform_device *pdev = to_platform_device(cpu_dai->dev); |
|---|
| 796 | + struct platform_device *pdev = to_platform_device(component->dev); |
|---|
| 934 | 797 | u32 cr; |
|---|
| 935 | 798 | |
|---|
| 936 | | - if (!cpu_dai->active) |
|---|
| 799 | + if (!snd_soc_component_active(component)) |
|---|
| 937 | 800 | return 0; |
|---|
| 938 | 801 | |
|---|
| 939 | 802 | ssc_p = &ssc_info[pdev->id]; |
|---|
| .. | .. |
|---|
| 977 | 840 | }; |
|---|
| 978 | 841 | |
|---|
| 979 | 842 | static struct snd_soc_dai_driver atmel_ssc_dai = { |
|---|
| 980 | | - .suspend = atmel_ssc_suspend, |
|---|
| 981 | | - .resume = atmel_ssc_resume, |
|---|
| 982 | 843 | .playback = { |
|---|
| 983 | 844 | .channels_min = 1, |
|---|
| 984 | 845 | .channels_max = 2, |
|---|
| .. | .. |
|---|
| 998 | 859 | |
|---|
| 999 | 860 | static const struct snd_soc_component_driver atmel_ssc_component = { |
|---|
| 1000 | 861 | .name = "atmel-ssc", |
|---|
| 862 | + .suspend = atmel_ssc_suspend, |
|---|
| 863 | + .resume = atmel_ssc_resume, |
|---|
| 1001 | 864 | }; |
|---|
| 1002 | 865 | |
|---|
| 1003 | 866 | static int asoc_ssc_init(struct device *dev) |
|---|
| .. | .. |
|---|
| 1005 | 868 | struct ssc_device *ssc = dev_get_drvdata(dev); |
|---|
| 1006 | 869 | int ret; |
|---|
| 1007 | 870 | |
|---|
| 1008 | | - ret = snd_soc_register_component(dev, &atmel_ssc_component, |
|---|
| 871 | + ret = devm_snd_soc_register_component(dev, &atmel_ssc_component, |
|---|
| 1009 | 872 | &atmel_ssc_dai, 1); |
|---|
| 1010 | 873 | if (ret) { |
|---|
| 1011 | 874 | dev_err(dev, "Could not register DAI: %d\n", ret); |
|---|
| 1012 | | - goto err; |
|---|
| 875 | + return ret; |
|---|
| 1013 | 876 | } |
|---|
| 1014 | 877 | |
|---|
| 1015 | 878 | if (ssc->pdata->use_dma) |
|---|
| .. | .. |
|---|
| 1019 | 882 | |
|---|
| 1020 | 883 | if (ret) { |
|---|
| 1021 | 884 | dev_err(dev, "Could not register PCM: %d\n", ret); |
|---|
| 1022 | | - goto err_unregister_dai; |
|---|
| 885 | + return ret; |
|---|
| 1023 | 886 | } |
|---|
| 1024 | 887 | |
|---|
| 1025 | 888 | return 0; |
|---|
| 1026 | | - |
|---|
| 1027 | | -err_unregister_dai: |
|---|
| 1028 | | - snd_soc_unregister_component(dev); |
|---|
| 1029 | | -err: |
|---|
| 1030 | | - return ret; |
|---|
| 1031 | | -} |
|---|
| 1032 | | - |
|---|
| 1033 | | -static void asoc_ssc_exit(struct device *dev) |
|---|
| 1034 | | -{ |
|---|
| 1035 | | - struct ssc_device *ssc = dev_get_drvdata(dev); |
|---|
| 1036 | | - |
|---|
| 1037 | | - if (ssc->pdata->use_dma) |
|---|
| 1038 | | - atmel_pcm_dma_platform_unregister(dev); |
|---|
| 1039 | | - else |
|---|
| 1040 | | - atmel_pcm_pdc_platform_unregister(dev); |
|---|
| 1041 | | - |
|---|
| 1042 | | - snd_soc_unregister_component(dev); |
|---|
| 1043 | 889 | } |
|---|
| 1044 | 890 | |
|---|
| 1045 | 891 | /** |
|---|
| 1046 | 892 | * atmel_ssc_set_audio - Allocate the specified SSC for audio use. |
|---|
| 893 | + * @ssc_id: SSD ID in [0, NUM_SSC_DEVICES[ |
|---|
| 1047 | 894 | */ |
|---|
| 1048 | 895 | int atmel_ssc_set_audio(int ssc_id) |
|---|
| 1049 | 896 | { |
|---|
| .. | .. |
|---|
| 1070 | 917 | { |
|---|
| 1071 | 918 | struct ssc_device *ssc = ssc_info[ssc_id].ssc; |
|---|
| 1072 | 919 | |
|---|
| 1073 | | - asoc_ssc_exit(&ssc->pdev->dev); |
|---|
| 1074 | 920 | ssc_free(ssc); |
|---|
| 1075 | 921 | } |
|---|
| 1076 | 922 | EXPORT_SYMBOL_GPL(atmel_ssc_put_audio); |
|---|