.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright 2014 Emilio López <emilio@elopez.com.ar> |
---|
3 | 4 | * Copyright 2014 Jon Smirl <jonsmirl@gmail.com> |
---|
.. | .. |
---|
6 | 7 | * Copyright 2016 Chen-Yu Tsai <wens@csie.org> |
---|
7 | 8 | * |
---|
8 | 9 | * Based on the Allwinner SDK driver, released under the GPL. |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License as published by |
---|
12 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
13 | | - * (at your option) any later version. |
---|
14 | | - * |
---|
15 | | - * This program is distributed in the hope that it will be useful, |
---|
16 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
17 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
18 | | - * GNU General Public License for more details. |
---|
19 | 10 | */ |
---|
20 | 11 | |
---|
21 | 12 | #include <linux/init.h> |
---|
.. | .. |
---|
64 | 55 | #define SUN4I_CODEC_DAC_ACTL_DACAENR (31) |
---|
65 | 56 | #define SUN4I_CODEC_DAC_ACTL_DACAENL (30) |
---|
66 | 57 | #define SUN4I_CODEC_DAC_ACTL_MIXEN (29) |
---|
| 58 | +#define SUN4I_CODEC_DAC_ACTL_LNG (26) |
---|
| 59 | +#define SUN4I_CODEC_DAC_ACTL_FMG (23) |
---|
| 60 | +#define SUN4I_CODEC_DAC_ACTL_MICG (20) |
---|
| 61 | +#define SUN4I_CODEC_DAC_ACTL_LLNS (19) |
---|
| 62 | +#define SUN4I_CODEC_DAC_ACTL_RLNS (18) |
---|
| 63 | +#define SUN4I_CODEC_DAC_ACTL_LFMS (17) |
---|
| 64 | +#define SUN4I_CODEC_DAC_ACTL_RFMS (16) |
---|
67 | 65 | #define SUN4I_CODEC_DAC_ACTL_LDACLMIXS (15) |
---|
68 | 66 | #define SUN4I_CODEC_DAC_ACTL_RDACRMIXS (14) |
---|
69 | 67 | #define SUN4I_CODEC_DAC_ACTL_LDACRMIXS (13) |
---|
| 68 | +#define SUN4I_CODEC_DAC_ACTL_MIC1LS (12) |
---|
| 69 | +#define SUN4I_CODEC_DAC_ACTL_MIC1RS (11) |
---|
| 70 | +#define SUN4I_CODEC_DAC_ACTL_MIC2LS (10) |
---|
| 71 | +#define SUN4I_CODEC_DAC_ACTL_MIC2RS (9) |
---|
70 | 72 | #define SUN4I_CODEC_DAC_ACTL_DACPAS (8) |
---|
71 | 73 | #define SUN4I_CODEC_DAC_ACTL_MIXPAS (7) |
---|
72 | 74 | #define SUN4I_CODEC_DAC_ACTL_PA_MUTE (6) |
---|
.. | .. |
---|
94 | 96 | #define SUN4I_CODEC_ADC_ACTL_PREG1EN (29) |
---|
95 | 97 | #define SUN4I_CODEC_ADC_ACTL_PREG2EN (28) |
---|
96 | 98 | #define SUN4I_CODEC_ADC_ACTL_VMICEN (27) |
---|
| 99 | +#define SUN4I_CODEC_ADC_ACTL_PREG1 (25) |
---|
| 100 | +#define SUN4I_CODEC_ADC_ACTL_PREG2 (23) |
---|
97 | 101 | #define SUN4I_CODEC_ADC_ACTL_VADCG (20) |
---|
98 | 102 | #define SUN4I_CODEC_ADC_ACTL_ADCIS (17) |
---|
| 103 | +#define SUN4I_CODEC_ADC_ACTL_LNPREG (13) |
---|
99 | 104 | #define SUN4I_CODEC_ADC_ACTL_PA_EN (4) |
---|
100 | 105 | #define SUN4I_CODEC_ADC_ACTL_DDE (3) |
---|
101 | 106 | #define SUN4I_CODEC_ADC_DEBUG (0x2c) |
---|
.. | .. |
---|
109 | 114 | |
---|
110 | 115 | /* Microphone controls (sun7i only) */ |
---|
111 | 116 | #define SUN7I_CODEC_AC_MIC_PHONE_CAL (0x3c) |
---|
| 117 | + |
---|
| 118 | +#define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1 (29) |
---|
| 119 | +#define SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2 (26) |
---|
112 | 120 | |
---|
113 | 121 | /* |
---|
114 | 122 | * sun6i specific registers |
---|
.. | .. |
---|
278 | 286 | static int sun4i_codec_trigger(struct snd_pcm_substream *substream, int cmd, |
---|
279 | 287 | struct snd_soc_dai *dai) |
---|
280 | 288 | { |
---|
281 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 289 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
282 | 290 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
---|
283 | 291 | |
---|
284 | 292 | switch (cmd) { |
---|
.. | .. |
---|
310 | 318 | static int sun4i_codec_prepare_capture(struct snd_pcm_substream *substream, |
---|
311 | 319 | struct snd_soc_dai *dai) |
---|
312 | 320 | { |
---|
313 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 321 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
314 | 322 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
---|
315 | 323 | |
---|
316 | 324 | |
---|
.. | .. |
---|
327 | 335 | |
---|
328 | 336 | /* |
---|
329 | 337 | * FIXME: Undocumented in the datasheet, but |
---|
330 | | - * Allwinner's code mentions that it is related |
---|
| 338 | + * Allwinner's code mentions that it is |
---|
331 | 339 | * related to microphone gain |
---|
332 | 340 | */ |
---|
333 | 341 | if (of_device_is_compatible(scodec->dev->of_node, |
---|
.. | .. |
---|
352 | 360 | static int sun4i_codec_prepare_playback(struct snd_pcm_substream *substream, |
---|
353 | 361 | struct snd_soc_dai *dai) |
---|
354 | 362 | { |
---|
355 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 363 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
356 | 364 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
---|
357 | 365 | u32 val; |
---|
358 | 366 | |
---|
.. | .. |
---|
565 | 573 | struct snd_pcm_hw_params *params, |
---|
566 | 574 | struct snd_soc_dai *dai) |
---|
567 | 575 | { |
---|
568 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 576 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
569 | 577 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
---|
570 | 578 | unsigned long clk_freq; |
---|
571 | 579 | int ret, hwrate; |
---|
.. | .. |
---|
606 | 614 | static int sun4i_codec_startup(struct snd_pcm_substream *substream, |
---|
607 | 615 | struct snd_soc_dai *dai) |
---|
608 | 616 | { |
---|
609 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 617 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
610 | 618 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
---|
611 | 619 | |
---|
612 | 620 | snd_pcm_hw_constraint_list(substream->runtime, 0, |
---|
.. | .. |
---|
626 | 634 | static void sun4i_codec_shutdown(struct snd_pcm_substream *substream, |
---|
627 | 635 | struct snd_soc_dai *dai) |
---|
628 | 636 | { |
---|
629 | | - struct snd_soc_pcm_runtime *rtd = substream->private_data; |
---|
| 637 | + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); |
---|
630 | 638 | struct sun4i_codec *scodec = snd_soc_card_get_drvdata(rtd->card); |
---|
631 | 639 | |
---|
632 | 640 | clk_disable_unprepare(scodec->clk_module); |
---|
.. | .. |
---|
673 | 681 | SUN4I_CODEC_DAC_ACTL_PA_MUTE, 1, 0); |
---|
674 | 682 | |
---|
675 | 683 | static DECLARE_TLV_DB_SCALE(sun4i_codec_pa_volume_scale, -6300, 100, 1); |
---|
| 684 | +static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_loopback_gain_scale, -150, 150, |
---|
| 685 | + 0); |
---|
| 686 | +static DECLARE_TLV_DB_SCALE(sun4i_codec_linein_preamp_gain_scale, -1200, 300, |
---|
| 687 | + 0); |
---|
| 688 | +static DECLARE_TLV_DB_SCALE(sun4i_codec_fmin_loopback_gain_scale, -450, 150, |
---|
| 689 | + 0); |
---|
| 690 | +static DECLARE_TLV_DB_SCALE(sun4i_codec_micin_loopback_gain_scale, -450, 150, |
---|
| 691 | + 0); |
---|
| 692 | +static DECLARE_TLV_DB_RANGE(sun4i_codec_micin_preamp_gain_scale, |
---|
| 693 | + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), |
---|
| 694 | + 1, 7, TLV_DB_SCALE_ITEM(3500, 300, 0)); |
---|
| 695 | +static DECLARE_TLV_DB_RANGE(sun7i_codec_micin_preamp_gain_scale, |
---|
| 696 | + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), |
---|
| 697 | + 1, 7, TLV_DB_SCALE_ITEM(2400, 300, 0)); |
---|
676 | 698 | |
---|
677 | 699 | static const struct snd_kcontrol_new sun4i_codec_controls[] = { |
---|
678 | 700 | SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, |
---|
679 | 701 | SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, |
---|
680 | 702 | sun4i_codec_pa_volume_scale), |
---|
| 703 | + SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 704 | + SUN4I_CODEC_DAC_ACTL_LNG, 1, 0, |
---|
| 705 | + sun4i_codec_linein_loopback_gain_scale), |
---|
| 706 | + SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL, |
---|
| 707 | + SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0, |
---|
| 708 | + sun4i_codec_linein_preamp_gain_scale), |
---|
| 709 | + SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 710 | + SUN4I_CODEC_DAC_ACTL_FMG, 3, 0, |
---|
| 711 | + sun4i_codec_fmin_loopback_gain_scale), |
---|
| 712 | + SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 713 | + SUN4I_CODEC_DAC_ACTL_MICG, 7, 0, |
---|
| 714 | + sun4i_codec_micin_loopback_gain_scale), |
---|
| 715 | + SOC_SINGLE_TLV("Mic1 Boost Volume", SUN4I_CODEC_ADC_ACTL, |
---|
| 716 | + SUN4I_CODEC_ADC_ACTL_PREG1, 3, 0, |
---|
| 717 | + sun4i_codec_micin_preamp_gain_scale), |
---|
| 718 | + SOC_SINGLE_TLV("Mic2 Boost Volume", SUN4I_CODEC_ADC_ACTL, |
---|
| 719 | + SUN4I_CODEC_ADC_ACTL_PREG2, 3, 0, |
---|
| 720 | + sun4i_codec_micin_preamp_gain_scale), |
---|
681 | 721 | }; |
---|
682 | 722 | |
---|
683 | | -static const struct snd_kcontrol_new sun4i_codec_left_mixer_controls[] = { |
---|
684 | | - SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
685 | | - SUN4I_CODEC_DAC_ACTL_LDACLMIXS, 1, 0), |
---|
| 723 | +static const struct snd_kcontrol_new sun7i_codec_controls[] = { |
---|
| 724 | + SOC_SINGLE_TLV("Power Amplifier Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 725 | + SUN4I_CODEC_DAC_ACTL_PA_VOL, 0x3F, 0, |
---|
| 726 | + sun4i_codec_pa_volume_scale), |
---|
| 727 | + SOC_SINGLE_TLV("Line Playback Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 728 | + SUN4I_CODEC_DAC_ACTL_LNG, 1, 0, |
---|
| 729 | + sun4i_codec_linein_loopback_gain_scale), |
---|
| 730 | + SOC_SINGLE_TLV("Line Boost Volume", SUN4I_CODEC_ADC_ACTL, |
---|
| 731 | + SUN4I_CODEC_ADC_ACTL_LNPREG, 7, 0, |
---|
| 732 | + sun4i_codec_linein_preamp_gain_scale), |
---|
| 733 | + SOC_SINGLE_TLV("FM Playback Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 734 | + SUN4I_CODEC_DAC_ACTL_FMG, 3, 0, |
---|
| 735 | + sun4i_codec_fmin_loopback_gain_scale), |
---|
| 736 | + SOC_SINGLE_TLV("Mic Playback Volume", SUN4I_CODEC_DAC_ACTL, |
---|
| 737 | + SUN4I_CODEC_DAC_ACTL_MICG, 7, 0, |
---|
| 738 | + sun4i_codec_micin_loopback_gain_scale), |
---|
| 739 | + SOC_SINGLE_TLV("Mic1 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL, |
---|
| 740 | + SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG1, 7, 0, |
---|
| 741 | + sun7i_codec_micin_preamp_gain_scale), |
---|
| 742 | + SOC_SINGLE_TLV("Mic2 Boost Volume", SUN7I_CODEC_AC_MIC_PHONE_CAL, |
---|
| 743 | + SUN7I_CODEC_AC_MIC_PHONE_CAL_PREG2, 7, 0, |
---|
| 744 | + sun7i_codec_micin_preamp_gain_scale), |
---|
686 | 745 | }; |
---|
687 | 746 | |
---|
688 | | -static const struct snd_kcontrol_new sun4i_codec_right_mixer_controls[] = { |
---|
689 | | - SOC_DAPM_SINGLE("Right DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
690 | | - SUN4I_CODEC_DAC_ACTL_RDACRMIXS, 1, 0), |
---|
691 | | - SOC_DAPM_SINGLE("Left DAC Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
| 747 | +static const struct snd_kcontrol_new sun4i_codec_mixer_controls[] = { |
---|
| 748 | + SOC_DAPM_SINGLE("Left Mixer Left DAC Playback Switch", |
---|
| 749 | + SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_LDACLMIXS, |
---|
| 750 | + 1, 0), |
---|
| 751 | + SOC_DAPM_SINGLE("Right Mixer Right DAC Playback Switch", |
---|
| 752 | + SUN4I_CODEC_DAC_ACTL, SUN4I_CODEC_DAC_ACTL_RDACRMIXS, |
---|
| 753 | + 1, 0), |
---|
| 754 | + SOC_DAPM_SINGLE("Right Mixer Left DAC Playback Switch", |
---|
| 755 | + SUN4I_CODEC_DAC_ACTL, |
---|
692 | 756 | SUN4I_CODEC_DAC_ACTL_LDACRMIXS, 1, 0), |
---|
| 757 | + SOC_DAPM_DOUBLE("Line Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
| 758 | + SUN4I_CODEC_DAC_ACTL_LLNS, |
---|
| 759 | + SUN4I_CODEC_DAC_ACTL_RLNS, 1, 0), |
---|
| 760 | + SOC_DAPM_DOUBLE("FM Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
| 761 | + SUN4I_CODEC_DAC_ACTL_LFMS, |
---|
| 762 | + SUN4I_CODEC_DAC_ACTL_RFMS, 1, 0), |
---|
| 763 | + SOC_DAPM_DOUBLE("Mic1 Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
| 764 | + SUN4I_CODEC_DAC_ACTL_MIC1LS, |
---|
| 765 | + SUN4I_CODEC_DAC_ACTL_MIC1RS, 1, 0), |
---|
| 766 | + SOC_DAPM_DOUBLE("Mic2 Playback Switch", SUN4I_CODEC_DAC_ACTL, |
---|
| 767 | + SUN4I_CODEC_DAC_ACTL_MIC2LS, |
---|
| 768 | + SUN4I_CODEC_DAC_ACTL_MIC2RS, 1, 0), |
---|
693 | 769 | }; |
---|
694 | 770 | |
---|
695 | 771 | static const struct snd_kcontrol_new sun4i_codec_pa_mixer_controls[] = { |
---|
.. | .. |
---|
724 | 800 | |
---|
725 | 801 | /* Mixers */ |
---|
726 | 802 | SND_SOC_DAPM_MIXER("Left Mixer", SND_SOC_NOPM, 0, 0, |
---|
727 | | - sun4i_codec_left_mixer_controls, |
---|
728 | | - ARRAY_SIZE(sun4i_codec_left_mixer_controls)), |
---|
| 803 | + sun4i_codec_mixer_controls, |
---|
| 804 | + ARRAY_SIZE(sun4i_codec_mixer_controls)), |
---|
729 | 805 | SND_SOC_DAPM_MIXER("Right Mixer", SND_SOC_NOPM, 0, 0, |
---|
730 | | - sun4i_codec_right_mixer_controls, |
---|
731 | | - ARRAY_SIZE(sun4i_codec_right_mixer_controls)), |
---|
| 806 | + sun4i_codec_mixer_controls, |
---|
| 807 | + ARRAY_SIZE(sun4i_codec_mixer_controls)), |
---|
732 | 808 | |
---|
733 | 809 | /* Global Mixer Enable */ |
---|
734 | 810 | SND_SOC_DAPM_SUPPLY("Mixer Enable", SUN4I_CODEC_DAC_ACTL, |
---|
.. | .. |
---|
741 | 817 | /* Mic Pre-Amplifiers */ |
---|
742 | 818 | SND_SOC_DAPM_PGA("MIC1 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL, |
---|
743 | 819 | SUN4I_CODEC_ADC_ACTL_PREG1EN, 0, NULL, 0), |
---|
| 820 | + SND_SOC_DAPM_PGA("MIC2 Pre-Amplifier", SUN4I_CODEC_ADC_ACTL, |
---|
| 821 | + SUN4I_CODEC_ADC_ACTL_PREG2EN, 0, NULL, 0), |
---|
744 | 822 | |
---|
745 | 823 | /* Power Amplifier */ |
---|
746 | 824 | SND_SOC_DAPM_MIXER("Power Amplifier", SUN4I_CODEC_ADC_ACTL, |
---|
.. | .. |
---|
750 | 828 | SND_SOC_DAPM_SWITCH("Power Amplifier Mute", SND_SOC_NOPM, 0, 0, |
---|
751 | 829 | &sun4i_codec_pa_mute), |
---|
752 | 830 | |
---|
| 831 | + SND_SOC_DAPM_INPUT("Line Right"), |
---|
| 832 | + SND_SOC_DAPM_INPUT("Line Left"), |
---|
| 833 | + SND_SOC_DAPM_INPUT("FM Right"), |
---|
| 834 | + SND_SOC_DAPM_INPUT("FM Left"), |
---|
753 | 835 | SND_SOC_DAPM_INPUT("Mic1"), |
---|
| 836 | + SND_SOC_DAPM_INPUT("Mic2"), |
---|
754 | 837 | |
---|
755 | 838 | SND_SOC_DAPM_OUTPUT("HP Right"), |
---|
756 | 839 | SND_SOC_DAPM_OUTPUT("HP Left"), |
---|
.. | .. |
---|
767 | 850 | |
---|
768 | 851 | /* Right Mixer Routes */ |
---|
769 | 852 | { "Right Mixer", NULL, "Mixer Enable" }, |
---|
770 | | - { "Right Mixer", "Left DAC Playback Switch", "Left DAC" }, |
---|
771 | | - { "Right Mixer", "Right DAC Playback Switch", "Right DAC" }, |
---|
| 853 | + { "Right Mixer", "Right Mixer Left DAC Playback Switch", "Left DAC" }, |
---|
| 854 | + { "Right Mixer", "Right Mixer Right DAC Playback Switch", "Right DAC" }, |
---|
| 855 | + { "Right Mixer", "Line Playback Switch", "Line Right" }, |
---|
| 856 | + { "Right Mixer", "FM Playback Switch", "FM Right" }, |
---|
| 857 | + { "Right Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" }, |
---|
| 858 | + { "Right Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" }, |
---|
772 | 859 | |
---|
773 | 860 | /* Left Mixer Routes */ |
---|
774 | 861 | { "Left Mixer", NULL, "Mixer Enable" }, |
---|
775 | | - { "Left Mixer", "Left DAC Playback Switch", "Left DAC" }, |
---|
| 862 | + { "Left Mixer", "Left Mixer Left DAC Playback Switch", "Left DAC" }, |
---|
| 863 | + { "Left Mixer", "Line Playback Switch", "Line Left" }, |
---|
| 864 | + { "Left Mixer", "FM Playback Switch", "FM Left" }, |
---|
| 865 | + { "Left Mixer", "Mic1 Playback Switch", "MIC1 Pre-Amplifier" }, |
---|
| 866 | + { "Left Mixer", "Mic2 Playback Switch", "MIC2 Pre-Amplifier" }, |
---|
776 | 867 | |
---|
777 | 868 | /* Power Amplifier Routes */ |
---|
778 | 869 | { "Power Amplifier", "Mixer Playback Switch", "Left Mixer" }, |
---|
.. | .. |
---|
790 | 881 | { "Right ADC", NULL, "MIC1 Pre-Amplifier" }, |
---|
791 | 882 | { "MIC1 Pre-Amplifier", NULL, "Mic1"}, |
---|
792 | 883 | { "Mic1", NULL, "VMIC" }, |
---|
| 884 | + |
---|
| 885 | + /* Mic2 Routes */ |
---|
| 886 | + { "Left ADC", NULL, "MIC2 Pre-Amplifier" }, |
---|
| 887 | + { "Right ADC", NULL, "MIC2 Pre-Amplifier" }, |
---|
| 888 | + { "MIC2 Pre-Amplifier", NULL, "Mic2"}, |
---|
| 889 | + { "Mic2", NULL, "VMIC" }, |
---|
793 | 890 | }; |
---|
794 | 891 | |
---|
795 | 892 | static const struct snd_soc_component_driver sun4i_codec_codec = { |
---|
796 | 893 | .controls = sun4i_codec_controls, |
---|
797 | 894 | .num_controls = ARRAY_SIZE(sun4i_codec_controls), |
---|
| 895 | + .dapm_widgets = sun4i_codec_codec_dapm_widgets, |
---|
| 896 | + .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), |
---|
| 897 | + .dapm_routes = sun4i_codec_codec_dapm_routes, |
---|
| 898 | + .num_dapm_routes = ARRAY_SIZE(sun4i_codec_codec_dapm_routes), |
---|
| 899 | + .idle_bias_on = 1, |
---|
| 900 | + .use_pmdown_time = 1, |
---|
| 901 | + .endianness = 1, |
---|
| 902 | + .non_legacy_dai_naming = 1, |
---|
| 903 | +}; |
---|
| 904 | + |
---|
| 905 | +static const struct snd_soc_component_driver sun7i_codec_codec = { |
---|
| 906 | + .controls = sun7i_codec_controls, |
---|
| 907 | + .num_controls = ARRAY_SIZE(sun7i_codec_controls), |
---|
798 | 908 | .dapm_widgets = sun4i_codec_codec_dapm_widgets, |
---|
799 | 909 | .num_dapm_widgets = ARRAY_SIZE(sun4i_codec_codec_dapm_widgets), |
---|
800 | 910 | .dapm_routes = sun4i_codec_codec_dapm_routes, |
---|
.. | .. |
---|
1186 | 1296 | { |
---|
1187 | 1297 | struct snd_soc_dai_link *link = devm_kzalloc(dev, sizeof(*link), |
---|
1188 | 1298 | GFP_KERNEL); |
---|
1189 | | - if (!link) |
---|
| 1299 | + struct snd_soc_dai_link_component *dlc = devm_kzalloc(dev, |
---|
| 1300 | + 3 * sizeof(*dlc), GFP_KERNEL); |
---|
| 1301 | + if (!link || !dlc) |
---|
1190 | 1302 | return NULL; |
---|
| 1303 | + |
---|
| 1304 | + link->cpus = &dlc[0]; |
---|
| 1305 | + link->codecs = &dlc[1]; |
---|
| 1306 | + link->platforms = &dlc[2]; |
---|
| 1307 | + |
---|
| 1308 | + link->num_cpus = 1; |
---|
| 1309 | + link->num_codecs = 1; |
---|
| 1310 | + link->num_platforms = 1; |
---|
1191 | 1311 | |
---|
1192 | 1312 | link->name = "cdc"; |
---|
1193 | 1313 | link->stream_name = "CDC PCM"; |
---|
1194 | | - link->codec_dai_name = "Codec"; |
---|
1195 | | - link->cpu_dai_name = dev_name(dev); |
---|
1196 | | - link->codec_name = dev_name(dev); |
---|
1197 | | - link->platform_name = dev_name(dev); |
---|
| 1314 | + link->codecs->dai_name = "Codec"; |
---|
| 1315 | + link->cpus->dai_name = dev_name(dev); |
---|
| 1316 | + link->codecs->name = dev_name(dev); |
---|
| 1317 | + link->platforms->name = dev_name(dev); |
---|
1198 | 1318 | link->dai_fmt = SND_SOC_DAIFMT_I2S; |
---|
1199 | 1319 | |
---|
1200 | 1320 | *num_links = 1; |
---|
.. | .. |
---|
1209 | 1329 | |
---|
1210 | 1330 | gpiod_set_value_cansleep(scodec->gpio_pa, |
---|
1211 | 1331 | !!SND_SOC_DAPM_EVENT_ON(event)); |
---|
| 1332 | + |
---|
| 1333 | + if (SND_SOC_DAPM_EVENT_ON(event)) { |
---|
| 1334 | + /* |
---|
| 1335 | + * Need a delay to wait for DAC to push the data. 700ms seems |
---|
| 1336 | + * to be the best compromise not to feel this delay while |
---|
| 1337 | + * playing a sound. |
---|
| 1338 | + */ |
---|
| 1339 | + msleep(700); |
---|
| 1340 | + } |
---|
1212 | 1341 | |
---|
1213 | 1342 | return 0; |
---|
1214 | 1343 | } |
---|
.. | .. |
---|
1297 | 1426 | }; |
---|
1298 | 1427 | |
---|
1299 | 1428 | static struct snd_soc_aux_dev aux_dev = { |
---|
1300 | | - .name = "Codec Analog Controls", |
---|
| 1429 | + .dlc = COMP_EMPTY(), |
---|
1301 | 1430 | }; |
---|
1302 | 1431 | |
---|
1303 | 1432 | static struct snd_soc_card *sun8i_a23_codec_create_card(struct device *dev) |
---|
.. | .. |
---|
1309 | 1438 | if (!card) |
---|
1310 | 1439 | return ERR_PTR(-ENOMEM); |
---|
1311 | 1440 | |
---|
1312 | | - aux_dev.codec_of_node = of_parse_phandle(dev->of_node, |
---|
| 1441 | + aux_dev.dlc.of_node = of_parse_phandle(dev->of_node, |
---|
1313 | 1442 | "allwinner,codec-analog-controls", |
---|
1314 | 1443 | 0); |
---|
1315 | | - if (!aux_dev.codec_of_node) { |
---|
| 1444 | + if (!aux_dev.dlc.of_node) { |
---|
1316 | 1445 | dev_err(dev, "Can't find analog controls for codec.\n"); |
---|
1317 | 1446 | return ERR_PTR(-EINVAL); |
---|
1318 | | - }; |
---|
| 1447 | + } |
---|
1319 | 1448 | |
---|
1320 | 1449 | card->dai_link = sun4i_codec_create_link(dev, &card->num_links); |
---|
1321 | 1450 | if (!card->dai_link) |
---|
.. | .. |
---|
1348 | 1477 | if (!card) |
---|
1349 | 1478 | return ERR_PTR(-ENOMEM); |
---|
1350 | 1479 | |
---|
1351 | | - aux_dev.codec_of_node = of_parse_phandle(dev->of_node, |
---|
| 1480 | + aux_dev.dlc.of_node = of_parse_phandle(dev->of_node, |
---|
1352 | 1481 | "allwinner,codec-analog-controls", |
---|
1353 | 1482 | 0); |
---|
1354 | | - if (!aux_dev.codec_of_node) { |
---|
| 1483 | + if (!aux_dev.dlc.of_node) { |
---|
1355 | 1484 | dev_err(dev, "Can't find analog controls for codec.\n"); |
---|
1356 | 1485 | return ERR_PTR(-EINVAL); |
---|
1357 | | - }; |
---|
| 1486 | + } |
---|
1358 | 1487 | |
---|
1359 | 1488 | card->dai_link = sun4i_codec_create_link(dev, &card->num_links); |
---|
1360 | 1489 | if (!card->dai_link) |
---|
.. | .. |
---|
1387 | 1516 | if (!card) |
---|
1388 | 1517 | return ERR_PTR(-ENOMEM); |
---|
1389 | 1518 | |
---|
1390 | | - aux_dev.codec_of_node = of_parse_phandle(dev->of_node, |
---|
| 1519 | + aux_dev.dlc.of_node = of_parse_phandle(dev->of_node, |
---|
1391 | 1520 | "allwinner,codec-analog-controls", |
---|
1392 | 1521 | 0); |
---|
1393 | | - if (!aux_dev.codec_of_node) { |
---|
| 1522 | + if (!aux_dev.dlc.of_node) { |
---|
1394 | 1523 | dev_err(dev, "Can't find analog controls for codec.\n"); |
---|
1395 | 1524 | return ERR_PTR(-EINVAL); |
---|
1396 | | - }; |
---|
| 1525 | + } |
---|
1397 | 1526 | |
---|
1398 | 1527 | card->dai_link = sun4i_codec_create_link(dev, &card->num_links); |
---|
1399 | 1528 | if (!card->dai_link) |
---|
.. | .. |
---|
1490 | 1619 | |
---|
1491 | 1620 | static const struct sun4i_codec_quirks sun7i_codec_quirks = { |
---|
1492 | 1621 | .regmap_config = &sun7i_codec_regmap_config, |
---|
1493 | | - .codec = &sun4i_codec_codec, |
---|
| 1622 | + .codec = &sun7i_codec_codec, |
---|
1494 | 1623 | .create_card = sun4i_codec_create_card, |
---|
1495 | 1624 | .reg_adc_fifoc = REG_FIELD(SUN4I_CODEC_ADC_FIFOC, 0, 31), |
---|
1496 | 1625 | .reg_dac_txdata = SUN4I_CODEC_DAC_TXDATA, |
---|