This allows changing the channel mapping for each digital input/output. This is useful when the DAI (or the device on the other end of the link) supports a different number of channels than are desired for routing, for example when using an I2S-format DAI link with a mono endpoint. Signed-off-by: Samuel Holland <samuel@xxxxxxxxxxxx> --- sound/soc/sunxi/sun8i-codec.c | 160 +++++++++++++++++++++++++++++++--- 1 file changed, 146 insertions(+), 14 deletions(-) diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index 71c4c1f47201..fdb9bf346cc2 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -56,9 +56,13 @@ #define SUN8I_AIF1_ADCDAT_CTRL 0x044 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA 15 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA 14 +#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC 10 +#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC 8 #define SUN8I_AIF1_DACDAT_CTRL 0x048 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA 15 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA 14 +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC 10 +#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC 8 #define SUN8I_AIF1_MXR_SRC 0x04c #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L 15 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL 14 @@ -71,9 +75,13 @@ #define SUN8I_AIF2_ADCDAT_CTRL 0x084 #define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_ENA 15 #define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_ENA 14 +#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC 10 +#define SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC 8 #define SUN8I_AIF2_DACDAT_CTRL 0x088 #define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_ENA 15 #define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_ENA 14 +#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC 10 +#define SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC 8 #define SUN8I_AIF2_MXR_SRC 0x08c #define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA0L 15 #define SUN8I_AIF2_MXR_SRC_ADCL_MXR_SRC_AIF1DA1L 14 @@ -511,6 +519,50 @@ static struct snd_soc_dai_driver sun8i_codec_dais[] = { }, }; +static const char *const sun8i_aif_stereo_mux_enum_names[] = { + "Stereo", "Reverse Stereo", "Sum Mono", "Mix Mono" +}; + +static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_ad0_stereo_mux_enum, + SUN8I_AIF1_ADCDAT_CTRL, + SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_SRC, + SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_SRC, + sun8i_aif_stereo_mux_enum_names); + +static const struct snd_kcontrol_new sun8i_aif1_ad0_stereo_mux_control = + SOC_DAPM_ENUM("AIF1 AD0 Stereo Capture Route", + sun8i_aif1_ad0_stereo_mux_enum); + +static SOC_ENUM_DOUBLE_DECL(sun8i_aif1_da0_stereo_mux_enum, + SUN8I_AIF1_DACDAT_CTRL, + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_SRC, + SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_SRC, + sun8i_aif_stereo_mux_enum_names); + +static const struct snd_kcontrol_new sun8i_aif1_da0_stereo_mux_control = + SOC_DAPM_ENUM("AIF1 DA0 Stereo Playback Route", + sun8i_aif1_da0_stereo_mux_enum); + +static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_adc_stereo_mux_enum, + SUN8I_AIF2_ADCDAT_CTRL, + SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCL_SRC, + SUN8I_AIF2_ADCDAT_CTRL_AIF2_ADCR_SRC, + sun8i_aif_stereo_mux_enum_names); + +static const struct snd_kcontrol_new sun8i_aif2_adc_stereo_mux_control = + SOC_DAPM_ENUM("AIF2 ADC Stereo Capture Route", + sun8i_aif2_adc_stereo_mux_enum); + +static SOC_ENUM_DOUBLE_DECL(sun8i_aif2_dac_stereo_mux_enum, + SUN8I_AIF2_DACDAT_CTRL, + SUN8I_AIF2_DACDAT_CTRL_AIF2_DACL_SRC, + SUN8I_AIF2_DACDAT_CTRL_AIF2_DACR_SRC, + sun8i_aif_stereo_mux_enum_names); + +static const struct snd_kcontrol_new sun8i_aif2_dac_stereo_mux_control = + SOC_DAPM_ENUM("AIF2 DAC Stereo Playback Route", + sun8i_aif2_dac_stereo_mux_enum); + static const char *const sun8i_aif3_mux_enum_names[] = { "None", "AIF2 Left", "AIF2 Right" }; @@ -609,6 +661,17 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = { SND_SOC_DAPM_AIF_OUT("AIF3 ADC", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), + /* AIF "ADC" Mono/Stereo Muxes */ + SND_SOC_DAPM_MUX("AIF1 AD0 Left Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif1_ad0_stereo_mux_control), + SND_SOC_DAPM_MUX("AIF1 AD0 Right Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif1_ad0_stereo_mux_control), + + SND_SOC_DAPM_MUX("AIF2 ADC Left Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif2_adc_stereo_mux_control), + SND_SOC_DAPM_MUX("AIF2 ADC Right Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif2_adc_stereo_mux_control), + /* AIF "ADC" Muxes */ SND_SOC_DAPM_MUX("AIF3 ADC Capture Route", SND_SOC_NOPM, 0, 0, &sun8i_aif3_adc_mux_control), @@ -630,6 +693,17 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = { SND_SOC_DAPM_MUX("AIF2 DAC Right Mux", SND_SOC_NOPM, 0, 0, &sun8i_aif2_dac_mux_control), + /* AIF "DAC" Mono/Stereo Muxes */ + SND_SOC_DAPM_MUX("AIF1 DA0 Left Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif1_da0_stereo_mux_control), + SND_SOC_DAPM_MUX("AIF1 DA0 Right Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif1_da0_stereo_mux_control), + + SND_SOC_DAPM_MUX("AIF2 DAC Left Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif2_dac_stereo_mux_control), + SND_SOC_DAPM_MUX("AIF2 DAC Right Stereo Mux", SND_SOC_NOPM, 0, 0, + &sun8i_aif2_dac_stereo_mux_control), + /* AIF "DAC" Inputs */ SND_SOC_DAPM_AIF_IN("AIF1 DA0 Left", "AIF1 Playback", 0, SUN8I_AIF1_DACDAT_CTRL, @@ -703,52 +777,110 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = { static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { /* AIF "ADC" Output Routes */ - { "AIF1 AD0 Left", NULL, "AIF1 AD0 Left Mixer" }, - { "AIF1 AD0 Right", NULL, "AIF1 AD0 Right Mixer" }, + { "AIF1 AD0 Left", NULL, "AIF1 AD0 Left Stereo Mux" }, + { "AIF1 AD0 Right", NULL, "AIF1 AD0 Right Stereo Mux" }, { "AIF1 AD0 Left", NULL, "AIF1CLK" }, { "AIF1 AD0 Right", NULL, "AIF1CLK" }, - { "AIF2 ADC Left", NULL, "AIF2 ADC Left Mixer" }, - { "AIF2 ADC Right", NULL, "AIF2 ADC Right Mixer" }, + { "AIF2 ADC Left", NULL, "AIF2 ADC Left Stereo Mux" }, + { "AIF2 ADC Right", NULL, "AIF2 ADC Right Stereo Mux" }, { "AIF2 ADC Left", NULL, "AIF2CLK" }, { "AIF2 ADC Right", NULL, "AIF2CLK" }, { "AIF3 ADC", NULL, "AIF3 ADC Capture Route" }, + /* AIF "ADC" Mono/Stereo Mux Routes */ + { "AIF1 AD0 Left Stereo Mux", "Stereo", "AIF1 AD0 Left Mixer" }, + { "AIF1 AD0 Left Stereo Mux", "Reverse Stereo", "AIF1 AD0 Right Mixer" }, + { "AIF1 AD0 Left Stereo Mux", "Sum Mono", "AIF1 AD0 Left Mixer" }, + { "AIF1 AD0 Left Stereo Mux", "Sum Mono", "AIF1 AD0 Right Mixer" }, + { "AIF1 AD0 Left Stereo Mux", "Mix Mono", "AIF1 AD0 Left Mixer" }, + { "AIF1 AD0 Left Stereo Mux", "Mix Mono", "AIF1 AD0 Right Mixer" }, + + { "AIF1 AD0 Right Stereo Mux", "Stereo", "AIF1 AD0 Right Mixer" }, + { "AIF1 AD0 Right Stereo Mux", "Reverse Stereo", "AIF1 AD0 Left Mixer" }, + { "AIF1 AD0 Right Stereo Mux", "Sum Mono", "AIF1 AD0 Left Mixer" }, + { "AIF1 AD0 Right Stereo Mux", "Sum Mono", "AIF1 AD0 Right Mixer" }, + { "AIF1 AD0 Right Stereo Mux", "Mix Mono", "AIF1 AD0 Left Mixer" }, + { "AIF1 AD0 Right Stereo Mux", "Mix Mono", "AIF1 AD0 Right Mixer" }, + + { "AIF2 ADC Left Stereo Mux", "Stereo", "AIF2 ADC Left Mixer" }, + { "AIF2 ADC Left Stereo Mux", "Reverse Stereo", "AIF2 ADC Right Mixer" }, + { "AIF2 ADC Left Stereo Mux", "Sum Mono", "AIF2 ADC Left Mixer" }, + { "AIF2 ADC Left Stereo Mux", "Sum Mono", "AIF2 ADC Right Mixer" }, + { "AIF2 ADC Left Stereo Mux", "Mix Mono", "AIF2 ADC Left Mixer" }, + { "AIF2 ADC Left Stereo Mux", "Mix Mono", "AIF2 ADC Right Mixer" }, + + { "AIF2 ADC Right Stereo Mux", "Stereo", "AIF2 ADC Right Mixer" }, + { "AIF2 ADC Right Stereo Mux", "Reverse Stereo", "AIF2 ADC Left Mixer" }, + { "AIF2 ADC Right Stereo Mux", "Sum Mono", "AIF2 ADC Left Mixer" }, + { "AIF2 ADC Right Stereo Mux", "Sum Mono", "AIF2 ADC Right Mixer" }, + { "AIF2 ADC Right Stereo Mux", "Mix Mono", "AIF2 ADC Left Mixer" }, + { "AIF2 ADC Right Stereo Mux", "Mix Mono", "AIF2 ADC Right Mixer" }, + /* AIF "ADC" Mux Routes */ { "AIF3 ADC Capture Route", "AIF2 Left", "AIF2 ADC Left Mixer" }, { "AIF3 ADC Capture Route", "AIF2 Right", "AIF2 ADC Right Mixer" }, /* AIF "ADC" Mixer Routes */ - { "AIF1 AD0 Left Mixer", "AIF1 AD0 Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Left" }, + { "AIF1 AD0 Left Mixer", "AIF1 AD0 Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Left Stereo Mux" }, { "AIF1 AD0 Left Mixer", "AIF1 AD0 Mixer AIF2 DAC Capture Switch", "AIF2 DAC Left Mux" }, { "AIF1 AD0 Left Mixer", "AIF1 AD0 Mixer ADC Capture Switch", "ADC Left" }, { "AIF1 AD0 Left Mixer", "AIF1 AD0 Mixer AIF2 DAC Rev Capture Switch", "AIF2 DAC Right Mux" }, - { "AIF1 AD0 Right Mixer", "AIF1 AD0 Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Right" }, + { "AIF1 AD0 Right Mixer", "AIF1 AD0 Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Right Stereo Mux" }, { "AIF1 AD0 Right Mixer", "AIF1 AD0 Mixer AIF2 DAC Capture Switch", "AIF2 DAC Right Mux" }, { "AIF1 AD0 Right Mixer", "AIF1 AD0 Mixer ADC Capture Switch", "ADC Right" }, { "AIF1 AD0 Right Mixer", "AIF1 AD0 Mixer AIF2 DAC Rev Capture Switch", "AIF2 DAC Left Mux" }, - { "AIF2 ADC Left Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Left" }, + { "AIF2 ADC Left Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Left Stereo Mux" }, { "AIF2 ADC Left Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DAC Right Mux" }, { "AIF2 ADC Left Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADC Left" }, - { "AIF2 ADC Right Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Right" }, + { "AIF2 ADC Right Mixer", "AIF2 ADC Mixer AIF1 DA0 Capture Switch", "AIF1 DA0 Right Stereo Mux" }, { "AIF2 ADC Right Mixer", "AIF2 ADC Mixer AIF2 DAC Rev Capture Switch", "AIF2 DAC Left Mux" }, { "AIF2 ADC Right Mixer", "AIF2 ADC Mixer ADC Capture Switch", "ADC Right" }, /* AIF "DAC" Mux Routes */ - { "AIF2 DAC Left Mux", "None", "AIF2 DAC Left" }, + { "AIF2 DAC Left Mux", "None", "AIF2 DAC Left Stereo Mux" }, { "AIF2 DAC Left Mux", "AIF2 Left", "AIF3 DAC" }, - { "AIF2 DAC Left Mux", "AIF2 Right", "AIF2 DAC Left" }, + { "AIF2 DAC Left Mux", "AIF2 Right", "AIF2 DAC Left Stereo Mux" }, - { "AIF2 DAC Right Mux", "None", "AIF2 DAC Right" }, - { "AIF2 DAC Right Mux", "AIF2 Left", "AIF2 DAC Right" }, + { "AIF2 DAC Right Mux", "None", "AIF2 DAC Right Stereo Mux" }, + { "AIF2 DAC Right Mux", "AIF2 Left", "AIF2 DAC Right Stereo Mux" }, { "AIF2 DAC Right Mux", "AIF2 Right", "AIF3 DAC" }, + /* AIF "DAC" Mono/Stereo Mux Routes */ + { "AIF1 DA0 Left Stereo Mux", "Stereo", "AIF1 DA0 Left" }, + { "AIF1 DA0 Left Stereo Mux", "Reverse Stereo", "AIF1 DA0 Right" }, + { "AIF1 DA0 Left Stereo Mux", "Sum Mono", "AIF1 DA0 Left" }, + { "AIF1 DA0 Left Stereo Mux", "Sum Mono", "AIF1 DA0 Right" }, + { "AIF1 DA0 Left Stereo Mux", "Mix Mono", "AIF1 DA0 Left" }, + { "AIF1 DA0 Left Stereo Mux", "Mix Mono", "AIF1 DA0 Right" }, + + { "AIF1 DA0 Right Stereo Mux", "Stereo", "AIF1 DA0 Right" }, + { "AIF1 DA0 Right Stereo Mux", "Reverse Stereo", "AIF1 DA0 Left" }, + { "AIF1 DA0 Right Stereo Mux", "Sum Mono", "AIF1 DA0 Left" }, + { "AIF1 DA0 Right Stereo Mux", "Sum Mono", "AIF1 DA0 Right" }, + { "AIF1 DA0 Right Stereo Mux", "Mix Mono", "AIF1 DA0 Left" }, + { "AIF1 DA0 Right Stereo Mux", "Mix Mono", "AIF1 DA0 Right" }, + + { "AIF2 DAC Left Stereo Mux", "Stereo", "AIF2 DAC Left" }, + { "AIF2 DAC Left Stereo Mux", "Reverse Stereo", "AIF2 DAC Right" }, + { "AIF2 DAC Left Stereo Mux", "Sum Mono", "AIF2 DAC Left" }, + { "AIF2 DAC Left Stereo Mux", "Sum Mono", "AIF2 DAC Right" }, + { "AIF2 DAC Left Stereo Mux", "Mix Mono", "AIF2 DAC Left" }, + { "AIF2 DAC Left Stereo Mux", "Mix Mono", "AIF2 DAC Right" }, + + { "AIF2 DAC Right Stereo Mux", "Stereo", "AIF2 DAC Right" }, + { "AIF2 DAC Right Stereo Mux", "Reverse Stereo", "AIF2 DAC Left" }, + { "AIF2 DAC Right Stereo Mux", "Sum Mono", "AIF2 DAC Left" }, + { "AIF2 DAC Right Stereo Mux", "Sum Mono", "AIF2 DAC Right" }, + { "AIF2 DAC Right Stereo Mux", "Mix Mono", "AIF2 DAC Left" }, + { "AIF2 DAC Right Stereo Mux", "Mix Mono", "AIF2 DAC Right" }, + /* AIF "DAC" Input Routes */ { "AIF1 DA0 Left", NULL, "AIF1CLK" }, { "AIF1 DA0 Right", NULL, "AIF1CLK" }, @@ -764,11 +896,11 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { { "DAC Right", NULL, "DAC" }, /* Main DAC Mixer Routes */ - { "DAC Left Mixer", "DAC Mixer AIF1 DA0 Playback Switch", "AIF1 DA0 Left" }, + { "DAC Left Mixer", "DAC Mixer AIF1 DA0 Playback Switch", "AIF1 DA0 Left Stereo Mux" }, { "DAC Left Mixer", "DAC Mixer AIF2 DAC Playback Switch", "AIF2 DAC Left Mux" }, { "DAC Left Mixer", "DAC Mixer ADC Playback Switch", "ADC Left" }, - { "DAC Right Mixer", "DAC Mixer AIF1 DA0 Playback Switch", "AIF1 DA0 Right" }, + { "DAC Right Mixer", "DAC Mixer AIF1 DA0 Playback Switch", "AIF1 DA0 Right Stereo Mux" }, { "DAC Right Mixer", "DAC Mixer AIF2 DAC Playback Switch", "AIF2 DAC Right Mux" }, { "DAC Right Mixer", "DAC Mixer ADC Playback Switch", "ADC Right" }, -- 2.24.1