Hi, I am trying to get works analog audio output on Banana Pi M2
Ultra sbc (it is based on sun8i-r40 soc). This patch (against 5.3.1)
make it works, but there are some confusing things in dmesg:
~# dmesg |grep codec
[ 11.524205] sun4i-codec 1c22c00.codec: ASoC: codec-analog@1c22f00 not
registered
[ 11.524225] sun4i-codec 1c22c00.codec: Failed to register our card
[ 11.531030] sun4i-codec 1c22c00.codec: ASoC: codec-analog@1c22f00 not
registered
[ 11.531051] sun4i-codec 1c22c00.codec: Failed to register our card
[ 11.608225] debugfs: Directory '1c22c00.codec' with parent 'H3 Audio
Codec' already present!
[ 11.608248] sun4i-codec 1c22c00.codec: ASoC: Failed to create
component debugfs directory: -17
[ 11.611693] sun4i-codec 1c22c00.codec: Codec <-> 1c22c00.codec mapping ok
root@bananapim2ultra:~#
The patch itself are correct ?, it would be a great to have analog
audio working with mainline kernel.
--
You received this message because you are subscribed to the Google Groups
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web, visit
https://groups.google.com/d/msgid/linux-sunxi/4c8bf07f-d200-941b-89fe-b24b40f6b5b2%40list.ru.
diff -urN a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts
--- a/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts 2019-09-21 08:19:47.000000000 +0300
+++ b/arch/arm/boot/dts/sun8i-r40-bananapi-m2-ultra.dts 2019-09-30 10:58:14.586509893 +0300
@@ -107,6 +107,14 @@
};
};
+&codec {
+ allwinner,audio-routing =
+ "Line Out", "LINEOUT",
+ "MIC1", "Mic",
+ "Mic", "MBIAS";
+ status = "okay";
+};
+
&ahci {
ahci-supply = <®_dldo4>;
phy-supply = <®_eldo3>;
diff -urN a/arch/arm/boot/dts/sun8i-r40.dtsi b/arch/arm/boot/dts/sun8i-r40.dtsi
--- a/arch/arm/boot/dts/sun8i-r40.dtsi 2019-09-21 08:19:47.000000000 +0300
+++ b/arch/arm/boot/dts/sun8i-r40.dtsi 2019-09-30 13:23:31.968243163 +0300
@@ -180,6 +180,15 @@
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
};
+ dma: dma-controller@1c02000 {
+ compatible = "allwinner,sun8i-r40-dma";
+ reg = <0x01c02000 0x1000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_DMA>;
+ resets = <&ccu RST_BUS_DMA>;
+ #dma-cells = <1>;
+ };
+
mmc0: mmc@1c0f000 {
compatible = "allwinner,sun8i-r40-mmc",
"allwinner,sun50i-a64-mmc";
@@ -406,6 +415,20 @@
reg = <0x01c20c90 0x10>;
};
+ codec: codec@1c22c00 {
+ #sound-dai-cells = <0>;
+ compatible = "allwinner,sun8i-r40-codec";
+ reg = <0x01c22c00 0x300>;
+ interrupts = <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&ccu CLK_BUS_CODEC>, <&ccu CLK_AC_DIG>;
+ clock-names = "apb", "codec";
+ resets = <&ccu RST_BUS_CODEC>;
+ dmas = <&dma 19>, <&dma 19>;
+ dma-names = "rx", "tx";
+ allwinner,codec-analog-controls = <&codec_analog>;
+ status = "disabled";
+ };
+
uart0: serial@1c28000 {
compatible = "snps,dw-apb-uart";
reg = <0x01c28000 0x400>;
@@ -551,6 +574,11 @@
#size-cells = <0>;
};
+ codec_analog: codec-analog@1c22f00 {
+ compatible = "allwinner,sun8i-r40-codec-analog";
+ reg = <0x01c22f00 0x4>;
+ };
+
ahci: sata@1c18000 {
compatible = "allwinner,sun8i-r40-ahci";
reg = <0x01c18000 0x1000>;
diff -urN a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.c 2019-09-21 08:19:47.000000000 +0300
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.c 2019-09-27 16:14:41.658308443 +0300
@@ -460,6 +460,9 @@
static SUNXI_CCU_GATE(bus_dbg_clk, "bus-dbg", "ahb1",
0x070, BIT(7), 0);
+static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
+ 0x140, BIT(31), CLK_SET_RATE_PARENT);
+
static const char * const ths_parents[] = { "osc24M" };
static struct ccu_div ths_clk = {
.enable = BIT(31),
@@ -941,6 +944,7 @@
&gpu_clk.common,
&outa_clk.common,
&outb_clk.common,
+ &ac_dig_clk.common,
};
/* Fixed Factor clocks */
@@ -1144,6 +1148,7 @@
[CLK_GPU] = &gpu_clk.common.hw,
[CLK_OUTA] = &outa_clk.common.hw,
[CLK_OUTB] = &outb_clk.common.hw,
+ [CLK_AC_DIG] = &ac_dig_clk.common.hw,
},
.num = CLK_NUMBER,
};
diff -urN a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h
--- a/drivers/clk/sunxi-ng/ccu-sun8i-r40.h 2019-09-21 08:19:47.000000000 +0300
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-r40.h 2019-09-27 19:45:25.374876987 +0300
@@ -59,6 +59,6 @@
/* Another bunch of module clocks are exported */
-#define CLK_NUMBER (CLK_OUTB + 1)
+#define CLK_NUMBER (CLK_AC_DIG + 1)
#endif /* _CCU_SUN8I_R40_H_ */
diff -urN a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
--- a/drivers/dma/sun6i-dma.c 2019-09-21 08:19:47.000000000 +0300
+++ b/drivers/dma/sun6i-dma.c 2019-09-30 13:35:25.692567440 +0300
@@ -1218,6 +1218,33 @@
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES),
};
+/*
+ * The R40 has 16 physical channels, a maximum DRQ port id of 31,
+ * and a total of 58 usable source and destination endpoints.
+ * It also supports additional burst lengths and bus widths,
+ * and the burst length fields have different offsets.
+ */
+
+static struct sun6i_dma_config sun8i_r40_dma_cfg = {
+ .nr_max_channels = 16,
+ .nr_max_requests = 31,
+ .nr_max_vchans = 58,
+ .clock_autogate_enable = sun6i_enable_clock_autogate_h3,
+ .set_burst_length = sun6i_set_burst_length_h3,
+ .set_drq = sun6i_set_drq_a31,
+ .set_mode = sun6i_set_mode_a31,
+ .src_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
+ .dst_burst_lengths = BIT(1) | BIT(4) | BIT(8) | BIT(16),
+ .src_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
+ .dst_addr_widths = BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) |
+ BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
+ BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
+};
+
static const struct of_device_id sun6i_dma_match[] = {
{ .compatible = "allwinner,sun6i-a31-dma", .data = &sun6i_a31_dma_cfg },
{ .compatible = "allwinner,sun8i-a23-dma", .data = &sun8i_a23_dma_cfg },
@@ -1226,6 +1253,7 @@
{ .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
{ .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
{ .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
+ { .compatible = "allwinner,sun8i-r40-dma", .data = &sun8i_r40_dma_cfg },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, sun6i_dma_match);
diff -urN a/include/dt-bindings/clock/sun8i-r40-ccu.h b/include/dt-bindings/clock/sun8i-r40-ccu.h
--- a/include/dt-bindings/clock/sun8i-r40-ccu.h 2019-09-21 08:19:47.000000000 +0300
+++ b/include/dt-bindings/clock/sun8i-r40-ccu.h 2019-09-27 14:59:05.883093590 +0300
@@ -188,4 +188,6 @@
#define CLK_OUTA 164
#define CLK_OUTB 165
+#define CLK_AC_DIG 166
+
#endif /* _DT_BINDINGS_CLK_SUN8I_R40_H_ */
diff -urN a/sound/soc/sunxi/sun4i-codec.c b/sound/soc/sunxi/sun4i-codec.c
--- a/sound/soc/sunxi/sun4i-codec.c 2019-09-21 08:19:47.000000000 +0300
+++ b/sound/soc/sunxi/sun4i-codec.c 2019-09-30 13:37:51.940398543 +0300
@@ -1659,6 +1659,23 @@
.reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
.has_reset = true,
};
+/*
+* just copy/paste from H3 for now.
+*/
+static const struct sun4i_codec_quirks sun8i_r40_codec_quirks = {
+ .regmap_config = &sun8i_h3_codec_regmap_config,
+ /*
+ * TODO Share the codec structure with A23 for now.
+ * This should be split out when adding digital audio
+ * processing support for the H3.
+ */
+ .codec = &sun8i_a23_codec_codec,
+ .create_card = sun8i_h3_codec_create_card,
+ .reg_adc_fifoc = REG_FIELD(SUN6I_CODEC_ADC_FIFOC, 0, 31),
+ .reg_dac_txdata = SUN8I_H3_CODEC_DAC_TXDATA,
+ .reg_adc_rxdata = SUN6I_CODEC_ADC_RXDATA,
+ .has_reset = true,
+};
static const struct of_device_id sun4i_codec_of_match[] = {
{
@@ -1685,6 +1702,10 @@
.compatible = "allwinner,sun8i-v3s-codec",
.data = &sun8i_v3s_codec_quirks,
},
+ {
+ .compatible = "allwinner,sun8i-r40-codec",
+ .data = &sun8i_r40_codec_quirks,
+ },
{}
};
MODULE_DEVICE_TABLE(of, sun4i_codec_of_match);
diff -urN a/sound/soc/sunxi/sun8i-codec-analog.c b/sound/soc/sunxi/sun8i-codec-analog.c
--- a/sound/soc/sunxi/sun8i-codec-analog.c 2019-09-21 08:19:47.000000000 +0300
+++ b/sound/soc/sunxi/sun8i-codec-analog.c 2019-09-30 10:44:00.755702435 +0300
@@ -1,7 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
/*
* This driver supports the analog controls for the internal codec
- * found in Allwinner's A31s, A23, A33 and H3 SoCs.
+ * found in Allwinner's A31s, A23, A33, H3 and R40 SoCs.
*
* Copyright 2016 Chen-Yu Tsai <[email protected]>
*/
@@ -686,6 +686,14 @@
.has_mic2 = true,
};
+static const struct sun8i_codec_analog_quirks sun8i_r40_quirks = {
+ .has_headphone = true,
+ .has_linein = true,
+ .has_lineout = true,
+ .has_mbias = true,
+ .has_mic2 = true,
+};
+
static int sun8i_codec_analog_add_mixer(struct snd_soc_component *cmpnt,
const struct sun8i_codec_analog_quirks *quirks)
{
@@ -813,6 +821,10 @@
.compatible = "allwinner,sun8i-v3s-codec-analog",
.data = &sun8i_v3s_quirks,
},
+ {
+ .compatible = "allwinner,sun8i-r40-codec-analog",
+ .data = &sun8i_r40_quirks,
+ },
{}
};
MODULE_DEVICE_TABLE(of, sun8i_codec_analog_of_match);