[PATCH 0/7] Allwinner A64 digital audio codec fixes
This series fixes a couple of issues with the digital audio codec in the Allwinner A64 SoC: 1) Left/right channels were swapped when playing/recording audio 2) DAPM topology was wrong, breaking some kcontrols
This is the minimum set of changes necessary to fix these issues in a backward-compatible way. For that reason, some DAPM widgets still have incorrect or confusing names; those and other issues will be fixed in later patch sets.
Samuel Holland (7): ASoC: dt-bindings: Add a new compatible for the A64 codec ASoC: sun8i-codec: Fix DAPM to match the hardware topology ASoC: sun8i-codec: Add missing mixer routes ASoC: sun8i-codec: Add a quirk for LRCK inversion ARM: dts: sun8i: a33: Update codec widget names arm64: dts: allwinner: a64: Update codec widget names arm64: dts: allwinner: a64: Update the audio codec compatible
.../sound/allwinner,sun8i-a33-codec.yaml | 6 +- arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 4 +- arch/arm/boot/dts/sun8i-a33.dtsi | 4 +- .../dts/allwinner/sun50i-a64-bananapi-m64.dts | 8 +- .../dts/allwinner/sun50i-a64-orangepi-win.dts | 8 +- .../boot/dts/allwinner/sun50i-a64-pine64.dts | 8 +- .../dts/allwinner/sun50i-a64-pinebook.dts | 8 +- .../dts/allwinner/sun50i-a64-pinephone.dtsi | 8 +- .../boot/dts/allwinner/sun50i-a64-pinetab.dts | 8 +- .../allwinner/sun50i-a64-sopine-baseboard.dts | 8 +- .../boot/dts/allwinner/sun50i-a64-teres-i.dts | 8 +- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 11 +- sound/soc/sunxi/sun8i-codec.c | 137 ++++++++++++++---- 13 files changed, 155 insertions(+), 71 deletions(-)
The audio codecs in the A33 and A64 are both integrated variants of the X-Powers AC100 codec. However, there are some differences between them that merit having a separate compatible: - The A64 has a second DRC block, not present in the AC100 or A33. - The A33 has some extra muxing options for AIF1/2/3 in the AIF3_SGP_CTRL register, which are not present in the AC100 or A64. - The A33 is missing registers providing jack detection functionality. - The A33 is claimed to invert LRCK, but this is not seen on A64.
Since the driver will continue to work on the A64 using the A33 compatible, albeit without jack detection functionality and with possibly inverted channels, as it does now, allow the A33 compatible to be used as a fallback.
Signed-off-by: Samuel Holland samuel@sholland.org --- .../bindings/sound/allwinner,sun8i-a33-codec.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml index 55d28268d2f4..67405e6d8168 100644 --- a/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml +++ b/Documentation/devicetree/bindings/sound/allwinner,sun8i-a33-codec.yaml @@ -15,7 +15,11 @@ properties: const: 0
compatible: - const: allwinner,sun8i-a33-codec + oneOf: + - items: + - const: allwinner,sun50i-a64-codec + - const: allwinner,sun8i-a33-codec + - const: allwinner,sun8i-a33-codec
reg: maxItems: 1
On Sat, 25 Jul 2020 20:25:51 -0500, Samuel Holland wrote:
The audio codecs in the A33 and A64 are both integrated variants of the X-Powers AC100 codec. However, there are some differences between them that merit having a separate compatible:
- The A64 has a second DRC block, not present in the AC100 or A33.
- The A33 has some extra muxing options for AIF1/2/3 in the AIF3_SGP_CTRL register, which are not present in the AC100 or A64.
- The A33 is missing registers providing jack detection functionality.
- The A33 is claimed to invert LRCK, but this is not seen on A64.
Since the driver will continue to work on the A64 using the A33 compatible, albeit without jack detection functionality and with possibly inverted channels, as it does now, allow the A33 compatible to be used as a fallback.
Signed-off-by: Samuel Holland samuel@sholland.org
.../bindings/sound/allwinner,sun8i-a33-codec.yaml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
Reviewed-by: Rob Herring robh@kernel.org
The A33/A64 digital codec has 4 physical inputs and 4 physical outputs: 3 AIFs/DAIs and one ADC/DAC pair. Internal routing is accomplished by a 4-channel mixer connected to each output.
The analog and digital sides of the ADC/DAC are in separate ASoC components, so card-level DAPM routes (provided in the device tree) are necessary to connect them together. Currently, these routes are wrong.
For AIF1 Playback, the correct topology is:
||<<============ sun8i-codec ===========>>|| || || CPU DAI -> AIF1 DA0 -> DAC Mixer -> DAC (digital) -> DAC (analog) || ||
but the driver and device trees currently describe:
|| || CPU DAI -> AIF1 DA0 -------------------------------> DAC (analog) || --> DAC Mixer -> ??? [dead end] ||
For AIF1 Capture, there is an additional problem, because the Mixer route is backward. The topology should be:
|| || ADC (analog) -> ADC (digital) -> AIF1 AD0 Mixer -> AIF1 AD0 -> CPU DAI || ||
but the driver and device trees currently describe:
|| || ADC (analog) -> AIF1 AD0 ------------------------------------> CPU DAI || --> ADC Mixer -> ??? [dead end] ||
The ADC/DAC are only powered because AIF1 AD0 (capture) has supply routes from the ADC, and AIF1 DA0 (playback) has supply routes from the DAC. However, neither set of supply routes matches the hardware topology. Audio can be routed among AIF1/2/3 without using the ADC or DAC at all; and audio can be routed from the ADC to the DAC without using any AIFs (via the "ADC Digital DAC Playback Switch"). Because the DAPM routes are wrong, both of these use cases are currently broken.
This commit adds the necessary widgets and routes to represent the real hardware topology, with functionality equivalent to the current driver.
For the existing "allwinner,sun8i-a33-codec" compatible, widgets with the old names are kept as wrappers around the new widgets, so existing device trees will continue to work. For "allwinner,sun50i-a64-codec", the old widgets can be omitted, because no device trees yet use that compatible.
Signed-off-by: Samuel Holland samuel@sholland.org --- sound/soc/sunxi/sun8i-codec.c | 120 +++++++++++++++++++++++++++------- 1 file changed, 95 insertions(+), 25 deletions(-)
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index ca51af114419..ffeac150c086 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -13,6 +13,7 @@ #include <linux/delay.h> #include <linux/clk.h> #include <linux/io.h> +#include <linux/of_device.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/log2.h> @@ -85,10 +86,15 @@ #define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK GENMASK(8, 6) #define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK GENMASK(12, 9)
+struct sun8i_codec_quirks { + bool legacy_widgets : 1; +}; + struct sun8i_codec { - struct regmap *regmap; - struct clk *clk_module; - struct clk *clk_bus; + struct regmap *regmap; + struct clk *clk_module; + struct clk *clk_bus; + const struct sun8i_codec_quirks *quirks; };
static int sun8i_codec_runtime_resume(struct device *dev) @@ -388,22 +394,30 @@ static const struct snd_soc_dapm_widget sun8i_codec_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("ADC", SUN8I_ADC_DIG_CTRL, SUN8I_ADC_DIG_CTRL_ENDA, 0, NULL, 0),
- /* Analog DAC AIF */ - SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left", "Playback", 0, + /* AIF "DAC" Inputs */ + SND_SOC_DAPM_AIF_IN("AIF1 DA0L", "Playback", 0, SUN8I_AIF1_DACDAT_CTRL, SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0L_ENA, 0), - SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Right", "Playback", 0, + SND_SOC_DAPM_AIF_IN("AIF1 DA0R", "Playback", 0, SUN8I_AIF1_DACDAT_CTRL, SUN8I_AIF1_DACDAT_CTRL_AIF1_DA0R_ENA, 0),
- /* Analog ADC AIF */ - SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Left ADC", "Capture", 0, + /* AIF "ADC" Outputs */ + SND_SOC_DAPM_AIF_IN("AIF1 AD0L", "Capture", 0, SUN8I_AIF1_ADCDAT_CTRL, SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0L_ENA, 0), - SND_SOC_DAPM_AIF_IN("AIF1 Slot 0 Right ADC", "Capture", 0, + SND_SOC_DAPM_AIF_IN("AIF1 AD0R", "Capture", 0, SUN8I_AIF1_ADCDAT_CTRL, SUN8I_AIF1_ADCDAT_CTRL_AIF1_DA0R_ENA, 0),
+ /* ADC Inputs (connected to analog codec DAPM context) */ + SND_SOC_DAPM_ADC("ADCL", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_ADC("ADCR", NULL, SND_SOC_NOPM, 0, 0), + + /* DAC Outputs (connected to analog codec DAPM context) */ + SND_SOC_DAPM_DAC("DACL", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DACR", NULL, SND_SOC_NOPM, 0, 0), + /* DAC and ADC Mixers */ SOC_MIXER_ARRAY("Left Digital DAC Mixer", SND_SOC_NOPM, 0, 0, sun8i_dac_mixer_controls), @@ -449,40 +463,86 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = { /* Clock Routes */ { "AIF1", NULL, "SYSCLK AIF1" }, { "AIF1 PLL", NULL, "AIF1" }, - { "RST AIF1", NULL, "AIF1 PLL" }, + { "SYSCLK", NULL, "AIF1 PLL" }, + + { "RST AIF1", NULL, "SYSCLK" }, { "MODCLK AFI1", NULL, "RST AIF1" }, - { "DAC", NULL, "MODCLK AFI1" }, - { "ADC", NULL, "MODCLK AFI1" }, + { "AIF1 AD0L", NULL, "MODCLK AFI1" }, + { "AIF1 AD0R", NULL, "MODCLK AFI1" }, + { "AIF1 DA0L", NULL, "MODCLK AFI1" }, + { "AIF1 DA0R", NULL, "MODCLK AFI1" },
{ "RST DAC", NULL, "SYSCLK" }, { "MODCLK DAC", NULL, "RST DAC" }, { "DAC", NULL, "MODCLK DAC" }, + { "DACL", NULL, "DAC" }, + { "DACR", NULL, "DAC" },
{ "RST ADC", NULL, "SYSCLK" }, { "MODCLK ADC", NULL, "RST ADC" }, { "ADC", NULL, "MODCLK ADC" }, + { "ADCL", NULL, "ADC" }, + { "ADCR", NULL, "ADC" },
/* DAC Routes */ - { "AIF1 Slot 0 Right", NULL, "DAC" }, - { "AIF1 Slot 0 Left", NULL, "DAC" }, + { "DACL", NULL, "Left Digital DAC Mixer" }, + { "DACR", NULL, "Right Digital DAC Mixer" },
/* DAC Mixer Routes */ - { "Left Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", - "AIF1 Slot 0 Left"}, - { "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", - "AIF1 Slot 0 Right"}, + { "Left Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L" }, + { "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R" },
/* ADC Routes */ - { "AIF1 Slot 0 Right ADC", NULL, "ADC" }, - { "AIF1 Slot 0 Left ADC", NULL, "ADC" }, + { "AIF1 AD0L", NULL, "Left Digital ADC Mixer" }, + { "AIF1 AD0R", NULL, "Right Digital ADC Mixer" },
/* ADC Mixer Routes */ - { "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", - "AIF1 Slot 0 Left ADC" }, - { "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", - "AIF1 Slot 0 Right ADC" }, + { "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" }, + { "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" }, +}; + +static const struct snd_soc_dapm_widget sun8i_codec_legacy_widgets[] = { + /* Legacy ADC Inputs (connected to analog codec DAPM context) */ + SND_SOC_DAPM_ADC("AIF1 Slot 0 Left ADC", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_ADC("AIF1 Slot 0 Right ADC", NULL, SND_SOC_NOPM, 0, 0), + + /* Legacy DAC Outputs (connected to analog codec DAPM context) */ + SND_SOC_DAPM_DAC("AIF1 Slot 0 Left", NULL, SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("AIF1 Slot 0 Right", NULL, SND_SOC_NOPM, 0, 0), +}; + +static const struct snd_soc_dapm_route sun8i_codec_legacy_routes[] = { + /* Legacy ADC Routes */ + { "ADCL", NULL, "AIF1 Slot 0 Left ADC" }, + { "ADCR", NULL, "AIF1 Slot 0 Right ADC" }, + + /* Legacy DAC Routes */ + { "AIF1 Slot 0 Left", NULL, "DACL" }, + { "AIF1 Slot 0 Right", NULL, "DACR" }, };
+static int sun8i_codec_component_probe(struct snd_soc_component *component) +{ + struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); + struct sun8i_codec *scodec = snd_soc_component_get_drvdata(component); + int ret; + + /* Add widgets for backward compatibility with old device trees. */ + if (scodec->quirks->legacy_widgets) { + ret = snd_soc_dapm_new_controls(dapm, sun8i_codec_legacy_widgets, + ARRAY_SIZE(sun8i_codec_legacy_widgets)); + if (ret) + return ret; + + ret = snd_soc_dapm_add_routes(dapm, sun8i_codec_legacy_routes, + ARRAY_SIZE(sun8i_codec_legacy_routes)); + if (ret) + return ret; + } + + return 0; +} + static const struct snd_soc_dai_ops sun8i_codec_dai_ops = { .hw_params = sun8i_codec_hw_params, .set_fmt = sun8i_set_fmt, @@ -566,6 +626,8 @@ static int sun8i_codec_probe(struct platform_device *pdev) return PTR_ERR(scodec->regmap); }
+ scodec->quirks = of_device_get_match_data(&pdev->dev); + platform_set_drvdata(pdev, scodec);
pm_runtime_enable(&pdev->dev); @@ -603,8 +665,16 @@ static int sun8i_codec_remove(struct platform_device *pdev) return 0; }
+static const struct sun8i_codec_quirks sun8i_a33_quirks = { + .legacy_widgets = true, +}; + +static const struct sun8i_codec_quirks sun50i_a64_quirks = { +}; + static const struct of_device_id sun8i_codec_of_match[] = { - { .compatible = "allwinner,sun8i-a33-codec" }, + { .compatible = "allwinner,sun8i-a33-codec", .data = &sun8i_a33_quirks }, + { .compatible = "allwinner,sun50i-a64-codec", .data = &sun50i_a64_quirks }, {} }; MODULE_DEVICE_TABLE(of, sun8i_codec_of_match);
The sun8i-codec driver provides ALSA controls for enabling/disabling each of the inputs to the AIF1 Slot 0 and DAC mixers. For two of these inputs (ADC->DAC and AIF1 DA0->AIF1 AD0), the audio source is implemented, so the mixer inputs can be used.
However, because the DAPM routes are missing, these mixer inputs only work when both the source and the mixer happen to be part of other active audio paths. Adding the appropriate routes makes these ALSA controls function all of the time.
Signed-off-by: Samuel Holland samuel@sholland.org --- sound/soc/sunxi/sun8i-codec.c | 6 ++++++ 1 file changed, 6 insertions(+)
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index ffeac150c086..a75be9e82d22 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -490,14 +490,20 @@ static const struct snd_soc_dapm_route sun8i_codec_dapm_routes[] = {
/* DAC Mixer Routes */ { "Left Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0L" }, + { "Left Digital DAC Mixer", "ADC Digital DAC Playback Switch", "ADCL" }, + { "Right Digital DAC Mixer", "AIF1 Slot 0 Digital DAC Playback Switch", "AIF1 DA0R" }, + { "Right Digital DAC Mixer", "ADC Digital DAC Playback Switch", "ADCR" },
/* ADC Routes */ { "AIF1 AD0L", NULL, "Left Digital ADC Mixer" }, { "AIF1 AD0R", NULL, "Right Digital ADC Mixer" },
/* ADC Mixer Routes */ + { "Left Digital ADC Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0L" }, { "Left Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCL" }, + + { "Right Digital ADC Mixer", "AIF1 Slot 0 Digital ADC Capture Switch", "AIF1 DA0R" }, { "Right Digital ADC Mixer", "AIF1 Data Digital ADC Capture Switch", "ADCR" }, };
On the A64, as tested using the PinePhone, the current code causes the left/right channels to be swapped during I2S playback from the CPU on AIF1, and breaks DSP_A communication with the modem on AIF2. Both of these are fixed when LRCK is no longer inverted.
Trusting that the comment in the code is correct, the existing behavior is kept for the A33.
Signed-off-by: Samuel Holland samuel@sholland.org --- sound/soc/sunxi/sun8i-codec.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index a75be9e82d22..304683a71acd 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -88,6 +88,7 @@
struct sun8i_codec_quirks { bool legacy_widgets : 1; + bool lrck_inversion : 1; };
struct sun8i_codec { @@ -215,18 +216,19 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) value << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_INV);
/* - * It appears that the DAI and the codec don't share the same - * polarity for the LRCK signal when they mean 'normal' and - * 'inverted' in the datasheet. + * It appears that the DAI and the codec in the A33 SoC don't + * share the same polarity for the LRCK signal when they mean + * 'normal' and 'inverted' in the datasheet. * * Since the DAI here is our regular i2s driver that have been * tested with way more codecs than just this one, it means * that the codec probably gets it backward, and we have to * invert the value here. */ + value ^= scodec->quirks->lrck_inversion; regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL, BIT(SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV), - !value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV); + value << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV);
/* DAI format */ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { @@ -673,6 +675,7 @@ static int sun8i_codec_remove(struct platform_device *pdev)
static const struct sun8i_codec_quirks sun8i_a33_quirks = { .legacy_widgets = true, + .lrck_inversion = true, };
static const struct sun8i_codec_quirks sun50i_a64_quirks = {
The sun8i-codec driver introduced a new set of DAPM widgets that more accurately describe the hardware topology. Update the various device trees to use the new widget names.
Signed-off-by: Samuel Holland samuel@sholland.org --- arch/arm/boot/dts/sun8i-a33-olinuxino.dts | 4 ++-- arch/arm/boot/dts/sun8i-a33.dtsi | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts index 3d78169cdeed..a1953b2872d0 100644 --- a/arch/arm/boot/dts/sun8i-a33-olinuxino.dts +++ b/arch/arm/boot/dts/sun8i-a33-olinuxino.dts @@ -194,8 +194,8 @@ &sound { "Headphone", "Headphone Jack"; /* Board level routing. First 2 routes copied from SoC level */ simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "HP", "HPCOM", "Headphone Jack", "HP", "MIC1", "Microphone Jack", diff --git a/arch/arm/boot/dts/sun8i-a33.dtsi b/arch/arm/boot/dts/sun8i-a33.dtsi index cfd3858afb3e..c458f5fb124f 100644 --- a/arch/arm/boot/dts/sun8i-a33.dtsi +++ b/arch/arm/boot/dts/sun8i-a33.dtsi @@ -189,8 +189,8 @@ sound: sound { simple-audio-card,mclk-fs = <128>; simple-audio-card,aux-devs = <&codec_analog>; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right"; + "Left DAC", "DACL", + "Right DAC", "DACR"; status = "disabled";
simple-audio-card,cpu {
The sun8i-codec driver introduced a new set of DAPM widgets that more accurately describe the hardware topology. Update the various device trees to use the new widget names.
Signed-off-by: Samuel Holland samuel@sholland.org --- arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts | 8 ++++---- .../boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts | 8 ++++---- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 8 ++++---- 9 files changed, 36 insertions(+), 36 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts index 883f217efb81..3ea5182ca489 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts @@ -331,10 +331,10 @@ &sound { "Microphone", "Microphone Jack", "Microphone", "Onboard Microphone"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Headphone Jack", "HP", "MIC2", "Microphone Jack", "Onboard Microphone", "MBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts index fde9c7a99b17..d894ec5fa8a1 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts @@ -330,10 +330,10 @@ &sound { "Microphone", "Microphone Jack", "Microphone", "Onboard Microphone"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Headphone Jack", "HP", "MIC2", "Microphone Jack", "Onboard Microphone", "MBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts index 2165f238af13..329cf276561e 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts @@ -261,11 +261,11 @@ &sound { simple-audio-card,widgets = "Microphone", "Microphone Jack", "Headphone", "Headphone Jack"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "MIC2", "Microphone Jack"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts index 64b1c54f87c0..896f34fd9fc3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts @@ -374,15 +374,15 @@ &sound { "Headphone", "Headphone Jack", "Speaker", "Internal Speaker"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", "Internal Speaker", "Speaker Amp OUTL", "Internal Speaker", "Speaker Amp OUTR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Internal Microphone Left", "MBIAS", "MIC1", "Internal Microphone Left", "Internal Microphone Right", "HBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi index cefda145c3c9..93b091313323 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinephone.dtsi @@ -342,10 +342,10 @@ &sound { "Internal Speaker", "Speaker Amp OUTR", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Internal Microphone", "MBIAS", "MIC1", "Internal Microphone", "Headset Microphone", "HBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts index dc4ab6b434f9..3ab0f0347bc9 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pinetab.dts @@ -421,15 +421,15 @@ &sound { "Headphone", "Headphone Jack", "Speaker", "Internal Speaker"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", "Internal Speaker", "Speaker Amp OUTL", "Internal Speaker", "Speaker Amp OUTR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Internal Microphone Left", "MBIAS", "MIC1", "Internal Microphone Left", "Internal Microphone Right", "HBIAS", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts index 2f6ea9f3f6a2..9ebb9e07fae3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts @@ -159,11 +159,11 @@ &sound { simple-audio-card,widgets = "Microphone", "Microphone Jack", "Headphone", "Headphone Jack"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", + "Left DAC", "DACL", + "Right DAC", "DACR", "Headphone Jack", "HP", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "MIC2", "Microphone Jack"; status = "okay"; }; diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts index f5df5f705b72..a1864a89fb89 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-teres-i.dts @@ -340,10 +340,10 @@ &sound { "Microphone", "Internal Microphone", "Speaker", "Internal Speaker"; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC", + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC", "Headphone Jack", "HP", "Speaker Amp INL", "LINEOUT", "Speaker Amp INR", "LINEOUT", diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 8dfbcd144072..73ae7656e0f3 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -139,10 +139,10 @@ sound: sound { simple-audio-card,mclk-fs = <128>; simple-audio-card,aux-devs = <&codec_analog>; simple-audio-card,routing = - "Left DAC", "AIF1 Slot 0 Left", - "Right DAC", "AIF1 Slot 0 Right", - "AIF1 Slot 0 Left ADC", "Left ADC", - "AIF1 Slot 0 Right ADC", "Right ADC"; + "Left DAC", "DACL", + "Right DAC", "DACR", + "ADCL", "Left ADC", + "ADCR", "Right ADC"; status = "disabled";
cpudai: simple-audio-card,cpu {
The audio codec in the A64 has some differences from the A33 codec, so it needs its own compatible. Since the two codecs are similar, the A33 codec compatible is kept as a fallback.
Using the correct compatible fixes a channel inversion issue and cleans up some DAPM widgets that are no longer used.
Signed-off-by: Samuel Holland samuel@sholland.org --- arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi index 73ae7656e0f3..26df6278dfb7 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi @@ -860,7 +860,8 @@ dai: dai@1c22c00 {
codec: codec@1c22e00 { #sound-dai-cells = <0>; - compatible = "allwinner,sun8i-a33-codec"; + compatible = "allwinner,sun50i-a64-codec", + "allwinner,sun8i-a33-codec"; reg = <0x01c22e00 0x600>; interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
On Sat, 25 Jul 2020 20:25:50 -0500, Samuel Holland wrote:
This series fixes a couple of issues with the digital audio codec in the Allwinner A64 SoC:
- Left/right channels were swapped when playing/recording audio
- DAPM topology was wrong, breaking some kcontrols
This is the minimum set of changes necessary to fix these issues in a backward-compatible way. For that reason, some DAPM widgets still have incorrect or confusing names; those and other issues will be fixed in later patch sets.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/7] ASoC: dt-bindings: Add a new compatible for the A64 codec commit: cef305d4eb0733f25215793ed30b056a7db9bb62 [2/7] ASoC: sun8i-codec: Fix DAPM to match the hardware topology commit: 90cac932976e93b17203b4216ba83bdcd68e0ed0 [3/7] ASoC: sun8i-codec: Add missing mixer routes commit: e47d2dcd88fc3e6837f8aa0060ce820ec9001e26 [4/7] ASoC: sun8i-codec: Add a quirk for LRCK inversion commit: 7518805fb636308909a6a7953e9fdb194abb15f8 [5/7] ARM: dts: sun8i: a33: Update codec widget names (no commit info) [6/7] arm64: dts: allwinner: a64: Update codec widget names (no commit info) [7/7] arm64: dts: allwinner: a64: Update the audio codec compatible (no commit info)
All being well this means that it will be integrated into the linux-next tree (usually sometime in the next 24 hours) and sent to Linus during the next merge window (or sooner if it is a bug fix), however if problems are discovered then the patch may be dropped or reverted.
You may get further e-mails resulting from automated or manual testing and review of the tree, please engage with people reporting problems and send followup patches addressing any issues that are reported if needed.
If any updates are required or you are submitting further changes they should be sent as incremental updates against current git, existing patches will not be replaced.
Please add any relevant lists and maintainers to the CCs when replying to this mail.
Thanks, Mark
Hi Mark,
On Tue, Aug 18, 2020 at 05:54:50PM +0100, Mark Brown wrote:
On Sat, 25 Jul 2020 20:25:50 -0500, Samuel Holland wrote:
This series fixes a couple of issues with the digital audio codec in the Allwinner A64 SoC:
- Left/right channels were swapped when playing/recording audio
- DAPM topology was wrong, breaking some kcontrols
This is the minimum set of changes necessary to fix these issues in a backward-compatible way. For that reason, some DAPM widgets still have incorrect or confusing names; those and other issues will be fixed in later patch sets.
[...]
Applied to
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next
Thanks!
[1/7] ASoC: dt-bindings: Add a new compatible for the A64 codec commit: cef305d4eb0733f25215793ed30b056a7db9bb62 [2/7] ASoC: sun8i-codec: Fix DAPM to match the hardware topology commit: 90cac932976e93b17203b4216ba83bdcd68e0ed0 [3/7] ASoC: sun8i-codec: Add missing mixer routes commit: e47d2dcd88fc3e6837f8aa0060ce820ec9001e26 [4/7] ASoC: sun8i-codec: Add a quirk for LRCK inversion commit: 7518805fb636308909a6a7953e9fdb194abb15f8 [5/7] ARM: dts: sun8i: a33: Update codec widget names (no commit info) [6/7] arm64: dts: allwinner: a64: Update codec widget names (no commit info) [7/7] arm64: dts: allwinner: a64: Update the audio codec compatible (no commit info)
Ideally we should get the DT patches through arm-soc, can you drop the patches 5 to 7?
Thanks! Maxime
On Mon, Aug 24, 2020 at 04:03:34PM +0200, Maxime Ripard wrote:
[5/7] ARM: dts: sun8i: a33: Update codec widget names (no commit info) [6/7] arm64: dts: allwinner: a64: Update codec widget names (no commit info) [7/7] arm64: dts: allwinner: a64: Update the audio codec compatible (no commit info)
Ideally we should get the DT patches through arm-soc, can you drop the patches 5 to 7?
When it says "no commit info" that means the patch wasn't applied.
On Tue, Aug 25, 2020 at 04:36:52PM +0100, Mark Brown wrote:
On Mon, Aug 24, 2020 at 04:03:34PM +0200, Maxime Ripard wrote:
[5/7] ARM: dts: sun8i: a33: Update codec widget names (no commit info) [6/7] arm64: dts: allwinner: a64: Update codec widget names (no commit info) [7/7] arm64: dts: allwinner: a64: Update the audio codec compatible (no commit info)
Ideally we should get the DT patches through arm-soc, can you drop the patches 5 to 7?
When it says "no commit info" that means the patch wasn't applied.
My bad, thanks :)
Maxime
On Sat, Jul 25, 2020 at 08:25:50PM -0500, Samuel Holland wrote:
This series fixes a couple of issues with the digital audio codec in the Allwinner A64 SoC:
- Left/right channels were swapped when playing/recording audio
- DAPM topology was wrong, breaking some kcontrols
This is the minimum set of changes necessary to fix these issues in a backward-compatible way. For that reason, some DAPM widgets still have incorrect or confusing names; those and other issues will be fixed in later patch sets.
Samuel Holland (7): ASoC: dt-bindings: Add a new compatible for the A64 codec ASoC: sun8i-codec: Fix DAPM to match the hardware topology ASoC: sun8i-codec: Add missing mixer routes ASoC: sun8i-codec: Add a quirk for LRCK inversion ARM: dts: sun8i: a33: Update codec widget names arm64: dts: allwinner: a64: Update codec widget names arm64: dts: allwinner: a64: Update the audio codec compatible
Applied patcehs 5-7
Maxime
This caught my eye and brought up an issue I've been wondering about for some time:
On Fri, 28 Aug 2020, Maxime Ripard wrote:
On Sat, Jul 25, 2020 at 08:25:50PM -0500, Samuel Holland wrote:
... some DAPM widgets still have incorrect or confusing names; those and other issues will be fixed in later patch sets.
As a general and firm rule in the Linux kernel when it comes to upgrades and fixes is "We do not break userspace". Which means that for instance an application must not stop working after a kernel upgrade due to some API changing.
So does this mean that the name of an ALSA control, once it's in the mainline kernel, can never be changed, for whatever reason?
Or devicetree properties, does the same apply there? Say a property as a confusing name, is it possible to change it at all?
Or are these things open to debate, depending on the severity and consequences etc?
/Ricard
participants (5)
-
Mark Brown
-
Maxime Ripard
-
Ricard Wanderlof
-
Rob Herring
-
Samuel Holland