.. | .. |
---|
| 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); |
---|