Commit 18ebd62c authored by Samuel Holland's avatar Samuel Holland Committed by Mark Brown

ASoC: sun8i-codec: Enable AIF mono/stereo control

Each left/right pair of AIF input/output channels can be swapped or
combined. This is useful for sending a mono audio source to both sides
of a stereo sink, or for creating complex mixing scenarios.

Add the support to control this feature from userspace.
Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
Acked-by: default avatarMaxime Ripard <mripard@kernel.org>
Link: https://lore.kernel.org/r/20201001021148.15852-8-samuel@sholland.orgSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 4ab60cef
...@@ -54,9 +54,13 @@ ...@@ -54,9 +54,13 @@
#define SUN8I_AIF1_ADCDAT_CTRL 0x044 #define SUN8I_AIF1_ADCDAT_CTRL 0x044
#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA 15 #define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0L_ENA 15
#define SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA 14 #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 0x048
#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA 15 #define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA 15
#define SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA 14 #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 0x04c
#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L 15 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF1DA0L 15
#define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL 14 #define SUN8I_AIF1_MXR_SRC_AD0L_MXR_SRC_AIF2DACL 14
...@@ -332,6 +336,20 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream, ...@@ -332,6 +336,20 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
return 0; return 0;
} }
static const char *const sun8i_aif_stereo_mux_enum_values[] = {
"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_values);
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 const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = { static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = {
SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch", SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital ADC Capture Switch",
SUN8I_AIF1_MXR_SRC, SUN8I_AIF1_MXR_SRC,
...@@ -351,6 +369,16 @@ static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = { ...@@ -351,6 +369,16 @@ static const struct snd_kcontrol_new sun8i_aif1_ad0_mixer_controls[] = {
SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0), SUN8I_AIF1_MXR_SRC_AD0R_MXR_SRC_AIF2DACL, 1, 0),
}; };
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_values);
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 const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = { static const struct snd_kcontrol_new sun8i_dac_mixer_controls[] = {
SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch", SOC_DAPM_DOUBLE("AIF1 Slot 0 Digital DAC Playback Switch",
SUN8I_DAC_MXR_SRC, SUN8I_DAC_MXR_SRC,
...@@ -417,12 +445,24 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = { ...@@ -417,12 +445,24 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = {
SUN8I_AIF1_ADCDAT_CTRL, SUN8I_AIF1_ADCDAT_CTRL,
SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA, 0), SUN8I_AIF1_ADCDAT_CTRL_AIF1_AD0R_ENA, 0),
/* AIF "ADC" Mono/Stereo Muxes */
SND_SOC_DAPM_MUX("AIF1 AD0L Stereo Mux", SND_SOC_NOPM, 0, 0,
&sun8i_aif1_ad0_stereo_mux_control),
SND_SOC_DAPM_MUX("AIF1 AD0R Stereo Mux", SND_SOC_NOPM, 0, 0,
&sun8i_aif1_ad0_stereo_mux_control),
/* AIF "ADC" Mixers */ /* AIF "ADC" Mixers */
SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0, SOC_MIXER_ARRAY("AIF1 AD0L Mixer", SND_SOC_NOPM, 0, 0,
sun8i_aif1_ad0_mixer_controls), sun8i_aif1_ad0_mixer_controls),
SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0, SOC_MIXER_ARRAY("AIF1 AD0R Mixer", SND_SOC_NOPM, 0, 0,
sun8i_aif1_ad0_mixer_controls), sun8i_aif1_ad0_mixer_controls),
/* AIF "DAC" Mono/Stereo Muxes */
SND_SOC_DAPM_MUX("AIF1 DA0L Stereo Mux", SND_SOC_NOPM, 0, 0,
&sun8i_aif1_da0_stereo_mux_control),
SND_SOC_DAPM_MUX("AIF1 DA0R Stereo Mux", SND_SOC_NOPM, 0, 0,
&sun8i_aif1_da0_stereo_mux_control),
/* AIF "DAC" Inputs */ /* AIF "DAC" Inputs */
SND_SOC_DAPM_AIF_IN("AIF1 DA0L", "Playback", 0, SND_SOC_DAPM_AIF_IN("AIF1 DA0L", "Playback", 0,
SUN8I_AIF1_DACDAT_CTRL, SUN8I_AIF1_DACDAT_CTRL,
...@@ -473,25 +513,55 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { ...@@ -473,25 +513,55 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
{ "DACR", NULL, "DAC" }, { "DACR", NULL, "DAC" },
/* AIF "ADC" Output Routes */ /* AIF "ADC" Output Routes */
{ "AIF1 AD0L", NULL, "AIF1 AD0L Mixer" }, { "AIF1 AD0L", NULL, "AIF1 AD0L Stereo Mux" },
{ "AIF1 AD0R", NULL, "AIF1 AD0R Mixer" }, { "AIF1 AD0R", NULL, "AIF1 AD0R Stereo Mux" },
/* AIF "ADC" Mono/Stereo Mux Routes */
{ "AIF1 AD0L Stereo Mux", "Stereo", "AIF1 AD0L Mixer" },
{ "AIF1 AD0L Stereo Mux", "Reverse Stereo", "AIF1 AD0R Mixer" },
{ "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
{ "AIF1 AD0L Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
{ "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
{ "AIF1 AD0L Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
{ "AIF1 AD0R Stereo Mux", "Stereo", "AIF1 AD0R Mixer" },
{ "AIF1 AD0R Stereo Mux", "Reverse Stereo", "AIF1 AD0L Mixer" },
{ "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0L Mixer" },
{ "AIF1 AD0R Stereo Mux", "Sum Mono", "AIF1 AD0R Mixer" },
{ "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0L Mixer" },
{ "AIF1 AD0R Stereo Mux", "Mix Mono", "AIF1 AD0R Mixer" },
/* AIF "ADC" Mixer Routes */ /* AIF "ADC" Mixer Routes */
{ "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L" }, { "AIF1 AD0L Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L Stereo Mux" },
{ "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" }, { "AIF1 AD0L Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" },
{ "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R" }, { "AIF1 AD0R Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R Stereo Mux" },
{ "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" }, { "AIF1 AD0R Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" },
/* AIF "DAC" Mono/Stereo Mux Routes */
{ "AIF1 DA0L Stereo Mux", "Stereo", "AIF1 DA0L" },
{ "AIF1 DA0L Stereo Mux", "Reverse Stereo", "AIF1 DA0R" },
{ "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0L" },
{ "AIF1 DA0L Stereo Mux", "Sum Mono", "AIF1 DA0R" },
{ "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0L" },
{ "AIF1 DA0L Stereo Mux", "Mix Mono", "AIF1 DA0R" },
{ "AIF1 DA0R Stereo Mux", "Stereo", "AIF1 DA0R" },
{ "AIF1 DA0R Stereo Mux", "Reverse Stereo", "AIF1 DA0L" },
{ "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0L" },
{ "AIF1 DA0R Stereo Mux", "Sum Mono", "AIF1 DA0R" },
{ "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0L" },
{ "AIF1 DA0R Stereo Mux", "Mix Mono", "AIF1 DA0R" },
/* DAC Output Routes */ /* DAC Output Routes */
{ "DACL", NULL, "DACL Mixer" }, { "DACL", NULL, "DACL Mixer" },
{ "DACR", NULL, "DACR Mixer" }, { "DACR", NULL, "DACR Mixer" },
/* DAC Mixer Routes */ /* DAC Mixer Routes */
{ "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L" }, { "DACL Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L Stereo Mux" },
{ "DACL Mixer", "ADC Digital DAC Playback Switch", "ADCL" }, { "DACL Mixer", "ADC Digital DAC Playback Switch", "ADCL" },
{ "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R" }, { "DACR Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R Stereo Mux" },
{ "DACR Mixer", "ADC Digital DAC Playback Switch", "ADCR" }, { "DACR Mixer", "ADC Digital DAC Playback Switch", "ADCR" },
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment