audio: update eARC_RX/ARC_RX driver [1/1]

PD#SWPL-6863

Problem:
eARCRX/ARCRX function for sm1/tm2

Solution:
add eARCRX/ARCRX driver for sm1/tm2
plug in/out HDMI cable, notify user space current attended type

Verify:
tested on ac200, ab311

Change-Id: I0332723ef9c9d45f7797df38a7077561fddb13bf
Signed-off-by: Xing Wang <xing.wang@amlogic.com>
This commit is contained in:
Xing Wang
2019-05-16 21:43:26 +08:00
committed by Tao Zeng
parent 292c315e42
commit 140240ecb4
44 changed files with 880 additions and 364 deletions

View File

@@ -18,7 +18,7 @@
/dts-v1/;
#include "mesonsm1.dtsi"
#include "partition_mbox_normal.dtsi"
#include "partition_mbox_normal_P_32.dtsi"
#include "mesonsm1_skt-panel.dtsi"
/ {
@@ -1314,8 +1314,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1324,10 +1324,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1376,8 +1376,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1386,10 +1386,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1392,8 +1392,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1402,10 +1402,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1324,8 +1324,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1334,10 +1334,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1324,8 +1324,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1334,10 +1334,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1319,8 +1319,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1329,10 +1329,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1287,8 +1287,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1297,10 +1297,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1349,8 +1349,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1359,10 +1359,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -940,7 +940,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1468,7 +1468,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1501,7 +1501,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1600,7 +1600,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1595,7 +1595,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1603,8 +1603,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1621,10 +1621,10 @@
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1534,8 +1534,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1550,11 +1550,12 @@
"tx_dmac",
"tx_cmdc_srcpll",
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1607,8 +1607,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1625,10 +1625,10 @@
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1535,8 +1535,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1551,11 +1551,12 @@
"tx_dmac",
"tx_cmdc_srcpll",
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1588,8 +1588,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1606,10 +1606,10 @@
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1311,8 +1311,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1321,10 +1321,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1373,8 +1373,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1383,10 +1383,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1389,8 +1389,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1399,10 +1399,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1322,8 +1322,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1332,10 +1332,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1323,8 +1323,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1333,10 +1333,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1317,8 +1317,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1327,10 +1327,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1351,8 +1351,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1361,10 +1361,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1426,8 +1426,8 @@
clocks = <&clkaudio CLKID_AUDIO_GATE_EARCRX
&clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
>;
clock-names = "rx_gate",
"rx_cmdc",
@@ -1436,10 +1436,9 @@
"rx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx";
status = "okay";
};

View File

@@ -1499,7 +1499,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1597,7 +1597,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1589,7 +1589,7 @@
};
extn:extn {
compatible = "amlogic, snd-extn";
compatible = "amlogic, tl1-snd-extn";
#sound-dai-cells = <0>;
interrupts =

View File

@@ -1598,8 +1598,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1616,10 +1616,10 @@
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1534,8 +1534,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1551,10 +1551,10 @@
"tx_cmdc_srcpll",
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1604,8 +1604,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1622,10 +1622,10 @@
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1535,8 +1535,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1552,10 +1552,10 @@
"tx_cmdc_srcpll",
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -1590,8 +1590,8 @@
clocks = < &clkaudio CLKID_EARCRX_CMDC
&clkaudio CLKID_EARCRX_DMAC
&clkc CLKID_FCLK_DIV5
&clkc CLKID_FCLK_DIV3
&clkc CLKID_FCLK_DIV4
&clkc CLKID_FCLK_DIV4
&clkaudio CLKID_EARCTX_CMDC
&clkaudio CLKID_EARCTX_DMAC
&clkc CLKID_FCLK_DIV5
@@ -1608,10 +1608,10 @@
"tx_dmac_srcpll";
interrupts = <
GIC_SPI 88 IRQ_TYPE_EDGE_RISING
GIC_SPI 87 IRQ_TYPE_EDGE_RISING
GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH
GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH
>;
interrupt-names = "rx_cmdc", "rx_dmac";
interrupt-names = "earc_rx", "earc_tx";
status = "okay";
};

View File

@@ -151,6 +151,16 @@ struct __extcon_info {
.id = EXTCON_SPDIFIN_AUDIOTYPE,
.name = "SPDIFIN-AUDIOTYPE",
},
[EXTCON_EARCRX_ATNDTYP_ARC] = {
.type = EXTCON_TYPE_MISC,
.id = EXTCON_EARCRX_ATNDTYP_ARC,
.name = "EARCRX-ARC",
},
[EXTCON_EARCRX_ATNDTYP_EARC] = {
.type = EXTCON_TYPE_MISC,
.id = EXTCON_EARCRX_ATNDTYP_EARC,
.name = "EARCRX-EARC",
},
#endif
/* Display external connector */
[EXTCON_DISP_HDMI] = {

View File

@@ -67,6 +67,8 @@
#ifdef CONFIG_AMLOGIC_SND_SOC_AUGE
#define EXTCON_SPDIFIN_SAMPLERATE 28 /* spdif in sample rate changed */
#define EXTCON_SPDIFIN_AUDIOTYPE 29 /* spdif in PcPd detect */
#define EXTCON_EARCRX_ATNDTYP_ARC 30 /* attended type, ARC */
#define EXTCON_EARCRX_ATNDTYP_EARC 31 /* attended type, eARC */
#endif
/* Display external connector */
#define EXTCON_DISP_HDMI 40 /* High-Definition Multimedia Interface */

View File

@@ -111,7 +111,16 @@ static struct platform_driver audio_clocks_driver = {
},
.probe = audio_clocks_probe,
};
module_platform_driver(audio_clocks_driver);
int __init audio_clocks_init(void)
{
int ret;
ret = platform_driver_register(&audio_clocks_driver);
return ret;
}
core_initcall(audio_clocks_init);
MODULE_AUTHOR("Amlogic, Inc.");
MODULE_DESCRIPTION("Amlogic audio clocks ASoc driver");

View File

@@ -556,29 +556,48 @@ static int aml_card_dai_link_of(struct device_node *node,
goto dai_link_of_err;
}
dai_link->cpu_of_node = of_parse_phandle(cpu, DAI, 0);
if (!dai_link->cpu_of_node) {
dev_err(dev, "error getting cpu phandle\n");
return -EINVAL;
}
ret = aml_card_parse_daifmt(dev, node, codec,
prefix, &dai_link->dai_fmt);
if (ret < 0)
if (ret < 0) {
dev_err(dev, "%s, dai fmt not found\n",
__func__);
goto dai_link_of_err;
}
of_property_read_u32(node, "mclk-fs", &dai_props->mclk_fs);
ret = aml_card_parse_cpu(cpu, dai_link,
DAI, CELL, &single_cpu);
if (ret < 0)
if (ret < 0) {
dev_err(dev, "%s, dai-link idx:%d, error getting cpu dai name:%s\n",
__func__,
idx,
dai_link->cpu_dai_name);
goto dai_link_of_err;
}
#if 0
ret = aml_card_parse_codec(codec, dai_link, DAI, CELL);
#else
ret = snd_soc_of_get_dai_link_codecs(dev, codec, dai_link);
#endif
if (ret < 0)
if (ret < 0) {
dev_err(dev, "%s, dai-link idx:%d, error getting codec dai name:%s\n",
__func__,
idx,
dai_link->codec_dai_name);
goto dai_link_of_err;
}
ret = aml_card_parse_platform(plat, dai_link, DAI, CELL);
if (ret < 0)
if (ret < 0) {
dev_err(dev, "%s, platform not found\n",
__func__);
goto dai_link_of_err;
}
ret = snd_soc_of_parse_tdm_slot(cpu, &cpu_dai->tx_slot_mask,
&cpu_dai->rx_slot_mask,
@@ -602,12 +621,6 @@ static int aml_card_dai_link_of(struct device_node *node,
if (ret < 0)
goto dai_link_of_err;
#if 0
ret = aml_card_parse_clk_codec(codec, dai_link, codec_dai);
if (ret < 0)
goto dai_link_of_err;
#endif
ret = aml_card_canonicalize_dailink(dai_link);
if (ret < 0)
goto dai_link_of_err;
@@ -949,8 +962,10 @@ static int aml_card_probe(struct platform_device *pdev)
ret = aml_card_parse_of(np, priv);
if (ret < 0) {
dev_err(dev, "%s, parse error %d\n",
__func__, ret);
dev_err(dev, "%s, aml_card_parse_of error %d %s\n",
__func__,
ret,
(ret == -EPROBE_DEFER) ? "PROBE RETRY" : "");
goto err;
}
@@ -988,6 +1003,7 @@ static int aml_card_probe(struct platform_device *pdev)
sizeof(priv->dai_props->codec_dai));
}
platform_set_drvdata(pdev, priv);
snd_soc_card_set_drvdata(&priv->snd_card, priv);
ret = devm_snd_soc_register_card(&pdev->dev, &priv->snd_card);

View File

@@ -104,7 +104,6 @@ static struct toddr *register_toddr_l(struct device *dev,
/* (1 << 31)|(1 << mask_bit));*/
to->dev = dev;
to->actrl = actrl;
to->in_use = true;
pr_debug("toddrs[%d] registered by device %s\n", i, dev_name(dev));
return to;
@@ -145,7 +144,6 @@ static int unregister_toddr_l(struct device *dev, void *data)
free_irq(to->irq, data);
to->dev = NULL;
to->actrl = NULL;
to->in_use = false;
pr_debug("toddrs[%d] released by device %s\n", i, dev_name(dev));
@@ -970,7 +968,6 @@ static struct frddr *register_frddr_l(struct device *dev,
return NULL;
}
from->dev = dev;
from->actrl = actrl;
from->in_use = true;
pr_debug("frddrs[%d] registered by device %s\n", i, dev_name(dev));
return from;
@@ -1011,7 +1008,6 @@ static int unregister_frddr_l(struct device *dev, void *data)
free_irq(from->irq, data);
from->dev = NULL;
from->actrl = NULL;
from->in_use = false;
pr_debug("frddrs[%d] released by device %s\n", i, dev_name(dev));
return 0;
@@ -1741,77 +1737,93 @@ static struct notifier_block ddr_pm_notifier_block = {
.notifier_call = ddr_pm_event,
};
/* table Must in order */
static struct ddr_info ddr_info[] = {
{EE_AUDIO_TODDR_A_CTRL0, EE_AUDIO_FRDDR_A_CTRL0, "toddr_a", "frddr_a"},
{EE_AUDIO_TODDR_B_CTRL0, EE_AUDIO_FRDDR_B_CTRL0, "toddr_b", "frddr_b"},
{EE_AUDIO_TODDR_C_CTRL0, EE_AUDIO_FRDDR_C_CTRL0, "toddr_c", "frddr_c"},
{EE_AUDIO_TODDR_D_CTRL0, EE_AUDIO_FRDDR_D_CTRL0, "toddr_d", "frddr_d"},
};
static int ddr_get_toddr_base_addr_by_idx(int idx)
{
return ddr_info[idx].toddr_addr;
}
static int ddr_get_frddr_base_addr_by_idx(int idx)
{
return ddr_info[idx].frddr_addr;
}
static char *ddr_get_toddr_name_by_idx(int idx)
{
return ddr_info[idx].toddr_name;
}
static char *ddr_get_frddr_name_by_idx(int idx)
{
return ddr_info[idx].frddr_name;
}
static int aml_ddr_mngr_platform_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct device_node *node_prt = NULL;
struct platform_device *pdev_parent;
struct aml_audio_controller *actrl = NULL;
struct ddr_chipinfo *p_ddr_chipinfo;
int ddr_num = 3; /* early chipset support max 3 ddr num */
int i, ret;
/* get audio controller */
node_prt = of_get_parent(node);
if (!node_prt)
return -ENXIO;
pdev_parent = of_find_device_by_node(node_prt);
of_node_put(node_prt);
actrl = (struct aml_audio_controller *)
platform_get_drvdata(pdev_parent);
p_ddr_chipinfo = (struct ddr_chipinfo *)
of_device_get_match_data(&pdev->dev);
if (!p_ddr_chipinfo)
dev_warn_once(&pdev->dev,
"check whether to update ddr_mngr chipinfo\n");
/* irqs */
toddrs[DDR_A].irq = platform_get_irq_byname(pdev, "toddr_a");
toddrs[DDR_B].irq = platform_get_irq_byname(pdev, "toddr_b");
toddrs[DDR_C].irq = platform_get_irq_byname(pdev, "toddr_c");
frddrs[DDR_A].irq = platform_get_irq_byname(pdev, "frddr_a");
frddrs[DDR_B].irq = platform_get_irq_byname(pdev, "frddr_b");
frddrs[DDR_C].irq = platform_get_irq_byname(pdev, "frddr_c");
if (p_ddr_chipinfo
&& (p_ddr_chipinfo->fifo_num == 4)) {
toddrs[DDR_D].irq = platform_get_irq_byname(pdev, "toddr_d");
frddrs[DDR_D].irq = platform_get_irq_byname(pdev, "frddr_d");
if (toddrs[DDR_D].irq < 0 || frddrs[DDR_D].irq < 0)
dev_err(&pdev->dev, "check irq for DDR_D\n");
ddr_num = p_ddr_chipinfo->fifo_num;
if (!p_ddr_chipinfo) {
dev_err(&pdev->dev,
"check to update ddr_mngr chipinfo\n");
return -EINVAL;
}
if (p_ddr_chipinfo->fifo_num == 2)
ddr_num = p_ddr_chipinfo->fifo_num;
else if (p_ddr_chipinfo->fifo_num == 4)
ddr_num = p_ddr_chipinfo->fifo_num;
for (i = 0; i < ddr_num; i++) {
pr_info("%d, irqs toddr %d, frddr %d\n",
i, toddrs[i].irq, frddrs[i].irq);
toddrs[i].irq =
platform_get_irq_byname(pdev,
ddr_get_toddr_name_by_idx(i));
toddrs[i].reg_base = ddr_get_toddr_base_addr_by_idx(i);
toddrs[i].fifo_id = i;
toddrs[i].chipinfo = p_ddr_chipinfo;
toddrs[i].actrl = actrl;
frddrs[i].irq =
platform_get_irq_byname(pdev,
ddr_get_frddr_name_by_idx(i));
frddrs[i].reg_base = ddr_get_frddr_base_addr_by_idx(i);
frddrs[i].fifo_id = i;
frddrs[i].chipinfo = p_ddr_chipinfo;
frddrs[i].actrl = actrl;
dev_info(&pdev->dev, "%d, irqs toddr %d, frddr %d\n",
i, toddrs[i].irq, frddrs[i].irq);
if (toddrs[i].irq <= 0 || frddrs[i].irq <= 0) {
dev_err(&pdev->dev, "platform_get_irq_byname failed\n");
dev_err(&pdev->dev, "%s, get irq failed\n", __func__);
return -ENXIO;
}
}
/* inits */
toddrs[DDR_A].reg_base = EE_AUDIO_TODDR_A_CTRL0;
toddrs[DDR_B].reg_base = EE_AUDIO_TODDR_B_CTRL0;
toddrs[DDR_C].reg_base = EE_AUDIO_TODDR_C_CTRL0;
toddrs[DDR_A].fifo_id = DDR_A;
toddrs[DDR_B].fifo_id = DDR_B;
toddrs[DDR_C].fifo_id = DDR_C;
frddrs[DDR_A].reg_base = EE_AUDIO_FRDDR_A_CTRL0;
frddrs[DDR_B].reg_base = EE_AUDIO_FRDDR_B_CTRL0;
frddrs[DDR_C].reg_base = EE_AUDIO_FRDDR_C_CTRL0;
frddrs[DDR_A].fifo_id = DDR_A;
frddrs[DDR_B].fifo_id = DDR_B;
frddrs[DDR_C].fifo_id = DDR_C;
if (p_ddr_chipinfo) {
toddrs[DDR_A].chipinfo = p_ddr_chipinfo;
toddrs[DDR_B].chipinfo = p_ddr_chipinfo;
toddrs[DDR_C].chipinfo = p_ddr_chipinfo;
frddrs[DDR_A].chipinfo = p_ddr_chipinfo;
frddrs[DDR_B].chipinfo = p_ddr_chipinfo;
frddrs[DDR_C].chipinfo = p_ddr_chipinfo;
if (p_ddr_chipinfo->fifo_num == 4) {
toddrs[DDR_D].reg_base = EE_AUDIO_TODDR_D_CTRL0;
toddrs[DDR_D].fifo_id = DDR_D;
frddrs[DDR_D].reg_base = EE_AUDIO_FRDDR_D_CTRL0;
frddrs[DDR_D].fifo_id = DDR_D;
}
}
ret = register_pm_notifier(&ddr_pm_notifier_block);
if (ret)
pr_warn("[%s] failed to register PM notifier %d\n",

View File

@@ -233,6 +233,13 @@ struct frddr {
bool reserved;
};
struct ddr_info {
unsigned int toddr_addr;
unsigned int frddr_addr;
char *toddr_name;
char *frddr_name;
};
/* to ddrs */
struct toddr *fetch_toddr_by_src(int toddr_src);
struct toddr *aml_audio_register_toddr(struct device *dev,

View File

@@ -27,6 +27,7 @@
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/clk.h>
#include <linux/extcon.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/initval.h>
@@ -34,6 +35,7 @@
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <linux/amlogic/media/sound/hdmi_earc.h>
#include "ddr_mngr.h"
#include "earc_hw.h"
@@ -57,24 +59,20 @@ struct earc {
struct toddr *tddr;
struct frddr *fddr;
int irq_rx_cmdc;
int irq_rx_dmac;
int irq_tx_cmdc;
int irq_tx_dmac;
int irq_earc_rx;
int irq_earc_tx;
int sysclk_freq;
/* external connect */
struct extcon_dev *rx_edev;
bool rx_cmdc_clk_on;
bool rx_dmac_clk_on;
};
#include <linux/amlogic/media/sound/hdmi_earc.h>
void earc_hdmirx_hpdst(int earc_port, bool st)
{
};
void earc_hdmitx_hpdst(bool st)
{
};
#define PREALLOC_BUFFER_MAX (256 * 1024)
#define EARC_RATES (SNDRV_PCM_RATE_8000_192000)
@@ -104,10 +102,10 @@ static const struct snd_pcm_hardware earc_hardware = {
.channels_max = 32,
};
static irqreturn_t earc_ddr_isr(int irq, void *devid)
static irqreturn_t earc_ddr_isr(int irq, void *data)
{
struct snd_pcm_substream *substream =
(struct snd_pcm_substream *)devid;
(struct snd_pcm_substream *)data;
if (!snd_pcm_running(substream))
return IRQ_HANDLED;
@@ -117,22 +115,99 @@ static irqreturn_t earc_ddr_isr(int irq, void *devid)
return IRQ_HANDLED;
}
static irqreturn_t earc_rx_cmdc_isr(int irq, void *devid)
static void earcrx_update_attend_event(struct earc *p_earc,
bool is_earc, bool state)
{
if (state) {
if (is_earc) {
extcon_set_state_sync(p_earc->rx_edev,
EXTCON_EARCRX_ATNDTYP_ARC, false);
extcon_set_state_sync(p_earc->rx_edev,
EXTCON_EARCRX_ATNDTYP_EARC, state);
} else {
extcon_set_state_sync(p_earc->rx_edev,
EXTCON_EARCRX_ATNDTYP_ARC, state);
extcon_set_state_sync(p_earc->rx_edev,
EXTCON_EARCRX_ATNDTYP_EARC, false);
}
} else {
extcon_set_state_sync(p_earc->rx_edev,
EXTCON_EARCRX_ATNDTYP_ARC, state);
extcon_set_state_sync(p_earc->rx_edev,
EXTCON_EARCRX_ATNDTYP_EARC, state);
}
}
static irqreturn_t earc_rx_isr(int irq, void *data)
{
struct earc *p_earc = (struct earc *)data;
if (p_earc->rx_cmdc_clk_on) {
unsigned int status0 = earcrx_cdmc_get_irqs();
if (status0 & INT_EARCRX_CMDC_IDLE2) {
earcrx_update_attend_event(p_earc,
false, true);
pr_info("%s EARCRX_CMDC_IDLE2\n", __func__);
}
if (status0 & INT_EARCRX_CMDC_IDLE1) {
earcrx_update_attend_event(p_earc,
false, false);
pr_info("%s EARCRX_CMDC_IDLE1\n", __func__);
}
if (status0 & INT_EARCRX_CMDC_DISC2)
pr_info("%s EARCRX_CMDC_DISC2\n", __func__);
if (status0 & INT_EARCRX_CMDC_DISC1)
pr_info("%s EARCRX_CMDC_DISC1\n", __func__);
if (status0 & INT_EARCRX_CMDC_EARC) {
earcrx_update_attend_event(p_earc,
true, true);
pr_info("%s EARCRX_CMDC_EARC\n", __func__);
}
if (status0 & INT_EARCRX_CMDC_HB_STATUS)
pr_debug("%s EARCRX_CMDC_HB_STATUS\n", __func__);
if (status0 & INT_EARCRX_CMDC_LOSTHB)
pr_info("%s EARCRX_CMDC_LOSTHB\n", __func__);
if (status0 & INT_EARCRX_CMDC_TIMEOUT) {
earcrx_update_attend_event(p_earc,
false, true);
pr_info("%s EARCRX_CMDC_TIMEOUT\n", __func__);
}
if (status0)
earcrx_cdmc_clr_irqs(status0);
}
if (p_earc->rx_dmac_clk_on) {
unsigned int status1 = earcrx_dmac_get_irqs();
if (status1 & INT_ARCRX_BIPHASE_DECODE_C_FIND_PAPB)
pr_debug("%s ARCRX_C_FIND_PAPB\n", __func__);
if (status1 & INT_ARCRX_BIPHASE_DECODE_C_VALID_CHANGE)
pr_debug("%s ARCRX_C_VALID_CHANGE\n", __func__);
if (status1 & INT_ARCRX_BIPHASE_DECODE_C_FIND_NONPCM2PCM)
pr_debug("%s ARCRX_C_FIND_NONPCM2PCM\n", __func__);
if (status1 & INT_ARCRX_BIPHASE_DECODE_C_PCPD_CHANGE)
pr_debug("%s ARCRX_C_PCPD_CHANGE\n", __func__);
if (status1 & INT_ARCRX_BIPHASE_DECODE_C_CH_STATUS_CHANGE)
pr_debug("%s ARCRX_C_CH_STATUS_CHANGE\n", __func__);
if (status1 & INT_ARCRX_BIPHASE_DECODE_I_SAMPLE_MODE_CHANGE)
pr_debug("%s ARCRX_I_SAMPLE_MODE_CHANGE\n", __func__);
if (status1 & INT_ARCRX_BIPHASE_DECODE_R_PARITY_ERR)
pr_debug("%s ARCRX_R_PARITY_ERR\n", __func__);
if (status1)
earcrx_dmac_clr_irqs(status1);
}
return IRQ_HANDLED;
}
static irqreturn_t earc_rx_dmac_isr(int irq, void *devid)
{
return IRQ_HANDLED;
}
static irqreturn_t earc_tx_cmdc_isr(int irq, void *devid)
{
return IRQ_HANDLED;
}
static irqreturn_t earc_tx_dmac_isr(int irq, void *devid)
static irqreturn_t earc_tx_isr(int irq, void *data)
{
return IRQ_HANDLED;
}
@@ -159,23 +234,13 @@ static int earc_open(struct snd_pcm_substream *substream)
dev_err(dev, "failed to claim from ddr\n");
return -ENXIO;
}
if (p_earc->irq_tx_cmdc > 0) {
ret = request_irq(p_earc->irq_tx_cmdc,
earc_tx_cmdc_isr, 0, "tx_cmdc",
if (p_earc->irq_earc_tx > 0) {
ret = request_irq(p_earc->irq_earc_tx,
earc_tx_isr, 0, "earc_tx",
p_earc);
if (ret) {
dev_err(p_earc->dev, "failed to claim irq_tx_cmdc %u\n",
p_earc->irq_tx_cmdc);
return ret;
}
}
if (p_earc->irq_tx_dmac > 0) {
ret = request_irq(p_earc->irq_tx_dmac,
earc_tx_dmac_isr, 0, "tx_dmac",
p_earc);
if (ret) {
dev_err(p_earc->dev, "failed to claim irq_tx_dmac %u\n",
p_earc->irq_tx_dmac);
dev_err(p_earc->dev, "failed to claim irq_earc_tx %u\n",
p_earc->irq_earc_tx);
return ret;
}
}
@@ -187,23 +252,6 @@ static int earc_open(struct snd_pcm_substream *substream)
dev_err(dev, "failed to claim to ddr\n");
return -ENXIO;
}
ret = request_irq(p_earc->irq_rx_cmdc,
earc_rx_cmdc_isr, 0, "rx_cmdc",
p_earc);
if (ret) {
dev_err(p_earc->dev, "failed to claim irq_rx_cmdc %u\n",
p_earc->irq_rx_cmdc);
return ret;
}
ret = request_irq(p_earc->irq_rx_dmac,
earc_rx_dmac_isr, 0, "rx_dmac",
p_earc);
if (ret) {
dev_err(p_earc->dev, "failed to claim rx_dmac %u\n",
p_earc->irq_rx_dmac);
return ret;
}
}
runtime->private_data = p_earc;
@@ -221,15 +269,10 @@ static int earc_close(struct snd_pcm_substream *substream)
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
aml_audio_unregister_frddr(p_earc->dev, substream);
if (p_earc->irq_tx_cmdc > 0)
free_irq(p_earc->irq_tx_cmdc, p_earc);
if (p_earc->irq_tx_dmac > 0)
free_irq(p_earc->irq_tx_dmac, p_earc);
if (p_earc->irq_earc_tx > 0)
free_irq(p_earc->irq_earc_tx, p_earc);
} else {
aml_audio_unregister_toddr(p_earc->dev, substream);
free_irq(p_earc->irq_rx_cmdc, p_earc);
free_irq(p_earc->irq_rx_dmac, p_earc);
}
runtime->private_data = NULL;
@@ -382,6 +425,12 @@ static int earc_dai_prepare(
unsigned int msb = 0, lsb = 0, toddr_type = 0;
unsigned int src = EARCRX_DMAC;
struct toddr_fmt fmt;
enum attend_type type = earcrx_cmdc_get_attended_type();
if (type == ATNDTYP_DISCNCT) {
dev_err(p_earc->dev, "Neither eARC or ARC is attended!\n");
return -ENOTCONN;
}
if (bit_depth == 32)
toddr_type = 3;
@@ -412,10 +461,8 @@ static int earc_dai_prepare(
aml_toddr_set_format(to, &fmt);
aml_toddr_set_fifos(to, 0x40);
earcrx_cmdc_init();
earcrx_dmac_init();
earc_arc_init();
earcrx_arc_init();
}
return 0;
@@ -439,7 +486,7 @@ static int earc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
aml_toddr_enable(p_earc->tddr, true);
earc_rx_enable(true);
earcrx_enable(true);
}
break;
case SNDRV_PCM_TRIGGER_STOP:
@@ -452,7 +499,7 @@ static int earc_dai_trigger(struct snd_pcm_substream *substream, int cmd,
} else {
dev_info(substream->pcm->card->dev, "eARC/ARC RX disable\n");
earc_rx_enable(false);
earcrx_enable(false);
aml_toddr_enable(p_earc->tddr, false);
}
@@ -473,10 +520,10 @@ static int earc_dai_hw_params(
unsigned int rate = params_rate(params);
int ret = 0;
pr_info("%s:rate:%d, sysclk:%d\n",
pr_info("%s:rate:%d, tddr:%p\n",
__func__,
rate,
p_earc->sysclk_freq);
p_earc->tddr);
return ret;
}
@@ -495,12 +542,10 @@ static int earc_dai_set_sysclk(struct snd_soc_dai *cpu_dai,
{
struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
p_earc->sysclk_freq = freq;
pr_info("earc_dai_set_sysclk, %d, %d, %d\n",
clk_id, freq, dir);
pr_info("%s, %d, %d, %d\n",
__func__, clk_id, freq, dir);
clk_set_rate(p_earc->clk_rx_cmdc, 10000000);
clk_set_rate(p_earc->clk_rx_dmac, 250000000);
clk_set_rate(p_earc->clk_rx_dmac, 500000000);
pr_info("earc rx cmdc clk:%lu rx dmac clk:%lu\n",
clk_get_rate(p_earc->clk_rx_cmdc),
@@ -516,32 +561,18 @@ static int earc_dai_startup(
struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
int ret;
/* enable clock gate */
if (!IS_ERR(p_earc->clk_rx_gate)) {
ret = clk_prepare_enable(p_earc->clk_rx_gate);
if (ret) {
pr_err("Can't enable earc rx_gate: %d\n", ret);
goto err;
}
}
pr_info("%s\n", __func__);
audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x1 << 6);
/* enable clock */
if (!IS_ERR(p_earc->clk_rx_cmdc)) {
ret = clk_prepare_enable(p_earc->clk_rx_cmdc);
if (ret) {
pr_err("Can't enable earc clk_rx_cmdc: %d\n", ret);
goto err;
}
}
/* rx dmac clk */
if (!IS_ERR(p_earc->clk_rx_dmac)) {
ret = clk_prepare_enable(p_earc->clk_rx_dmac);
if (ret) {
pr_err("Can't enable earc clk_rx_dmac: %d\n", ret);
goto err;
}
p_earc->rx_dmac_clk_on = true;
}
if (!IS_ERR(p_earc->clk_tx_cmdc)) {
ret = clk_prepare_enable(p_earc->clk_tx_cmdc);
if (ret) {
@@ -549,6 +580,8 @@ static int earc_dai_startup(
goto err;
}
}
/* tx dmac clk */
if (!IS_ERR(p_earc->clk_tx_dmac)) {
ret = clk_prepare_enable(p_earc->clk_tx_dmac);
if (ret) {
@@ -570,19 +603,15 @@ static void earc_dai_shutdown(
{
struct earc *p_earc = snd_soc_dai_get_drvdata(cpu_dai);
/* disable clock and gate */
if (!IS_ERR(p_earc->clk_rx_cmdc))
clk_disable_unprepare(p_earc->clk_rx_cmdc);
if (!IS_ERR(p_earc->clk_rx_dmac))
if (!IS_ERR(p_earc->clk_rx_dmac)) {
clk_disable_unprepare(p_earc->clk_rx_dmac);
p_earc->rx_dmac_clk_on = false;
}
if (!IS_ERR(p_earc->clk_tx_cmdc))
clk_disable_unprepare(p_earc->clk_tx_cmdc);
if (!IS_ERR(p_earc->clk_tx_dmac))
clk_disable_unprepare(p_earc->clk_tx_dmac);
if (!IS_ERR(p_earc->clk_rx_gate))
clk_disable_unprepare(p_earc->clk_rx_gate);
audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x0 << 6);
}
static struct snd_soc_dai_ops earc_dai_ops = {
@@ -617,9 +646,69 @@ static struct snd_soc_dai_driver earc_dai[] = {
},
};
static const char *const attended_type[] = {
"DISCONNECT",
"ARC",
"eARC"
};
const struct soc_enum attended_type_enum =
SOC_ENUM_SINGLE(SND_SOC_NOPM, 0, ARRAY_SIZE(attended_type),
attended_type);
int earcrx_get_attend_type(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
ucontrol->value.integer.value[0] = earcrx_cmdc_get_attended_type();
return 0;
}
int earcrx_set_attend_type(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
enum cmdc_st state = earcrx_cmdc_get_state();
if (state != CMDC_ST_IDLE2)
return 0;
//ucontrol->value.integer.value[0];
/* only support set cmdc from idle to ARC */
return 0;
}
static int earcrx_arc_get_enable(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
enum attend_type type = earcrx_cmdc_get_attended_type();
ucontrol->value.integer.value[0] = (bool)(type == ATNDTYP_ARC);
return 0;
}
static int earcrx_arc_set_enable(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
earcrx_cmdc_arc_connect((bool)ucontrol->value.integer.value[0]);
return 0;
}
static const struct snd_kcontrol_new earc_controls[] = {
SOC_ENUM_EXT("eARC_RX attended type",
attended_type_enum,
earcrx_get_attend_type,
earcrx_set_attend_type),
SOC_SINGLE_BOOL_EXT("HDMI ARC Switch",
0,
earcrx_arc_get_enable,
earcrx_arc_set_enable),
};
static const struct snd_soc_component_driver earc_component = {
@@ -640,6 +729,82 @@ static const struct of_device_id earc_device_id[] = {
MODULE_DEVICE_TABLE(of, earc_device_id);
static const unsigned int earcrx_extcon[] = {
EXTCON_EARCRX_ATNDTYP_ARC,
EXTCON_EARCRX_ATNDTYP_EARC,
EXTCON_NONE,
};
static int earcrx_extcon_register(struct earc *p_earc)
{
int ret = 0;
/* earc or arc connect */
p_earc->rx_edev = devm_extcon_dev_allocate(p_earc->dev, earcrx_extcon);
if (IS_ERR(p_earc->rx_edev)) {
pr_err("failed to allocate earc extcon!!!\n");
ret = -ENOMEM;
return ret;
}
p_earc->rx_edev->dev.parent = p_earc->dev;
p_earc->rx_edev->name = "earcrx";
dev_set_name(&p_earc->rx_edev->dev, "earcrx");
ret = extcon_dev_register(p_earc->rx_edev);
if (ret < 0) {
pr_err("earc extcon failed to register!!\n");
return ret;
}
return ret;
}
void earc_hdmitx_hpdst(bool st)
{
pr_info("%s, %s\n",
__func__,
st ? "plugin" : "plugout");
/* ensure clock gate */
audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x1 << 6);
earcrx_cmdc_hpd_detect(st);
}
static int earcrx_cmdc_setup(struct earc *p_earc)
{
int ret = 0;
/* set cmdc clk */
audiobus_update_bits(EE_AUDIO_CLK_GATE_EN1, 0x1 << 6, 0x1 << 6);
if (!IS_ERR(p_earc->clk_rx_cmdc)) {
ret = clk_prepare_enable(p_earc->clk_rx_cmdc);
if (ret) {
pr_err("Can't enable earc clk_rx_cmdc: %d\n", ret);
return ret;
}
}
p_earc->rx_cmdc_clk_on = true;
clk_set_rate(p_earc->clk_rx_cmdc, 10000000);
/* rx cmdc init */
earcrx_cmdc_init();
/* Default: arc arc_initiated */
earcrx_cmdc_arc_connect(true);
/* register irq */
ret = request_irq(p_earc->irq_earc_rx,
earc_rx_isr, 0, "earc_rx",
p_earc);
if (ret) {
dev_err(p_earc->dev, "failed to claim rx_dmac %u\n",
p_earc->irq_earc_rx);
return ret;
}
return ret;
}
static int earc_platform_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
@@ -650,6 +815,7 @@ static int earc_platform_probe(struct platform_device *pdev)
struct earc *p_earc = NULL;
int ret = 0;
pr_info("%s\n", __func__);
p_earc = devm_kzalloc(dev, sizeof(struct earc), GFP_KERNEL);
if (!p_earc)
@@ -761,26 +927,16 @@ static int earc_platform_probe(struct platform_device *pdev)
}
/* irqs */
p_earc->irq_rx_cmdc =
platform_get_irq_byname(pdev, "rx_cmdc");
if (p_earc->irq_rx_cmdc < 0) {
dev_err(dev, "platform get irq rx_cmdc failed\n");
return p_earc->irq_rx_cmdc;
p_earc->irq_earc_rx =
platform_get_irq_byname(pdev, "earc_rx");
if (p_earc->irq_earc_rx < 0) {
dev_err(dev, "platform get irq earc_rx failed\n");
return p_earc->irq_earc_rx;
}
p_earc->irq_rx_dmac =
platform_get_irq_byname(pdev, "rx_dmac");
if (p_earc->irq_rx_dmac < 0) {
dev_err(dev, "platform get irq rx_dmac failed\n");
return p_earc->irq_rx_dmac;
}
p_earc->irq_tx_cmdc =
platform_get_irq_byname(pdev, "tx_cmdc");
if (p_earc->irq_tx_cmdc < 0)
dev_err(dev, "platform get irq tx_cmdc failed, Check whether support eARC TX\n");
p_earc->irq_tx_dmac =
platform_get_irq_byname(pdev, "tx_dmac");
if (p_earc->irq_tx_dmac < 0)
dev_err(dev, "platform get irq tx_dmac failed, Check whether support eARC TX\n");
p_earc->irq_earc_tx =
platform_get_irq_byname(pdev, "earc_tx");
if (p_earc->irq_earc_tx < 0)
dev_err(dev, "platform get irq earc_tx failed, Check whether support eARC TX\n");
ret = snd_soc_register_component(&pdev->dev,
&earc_component,
@@ -792,6 +948,9 @@ static int earc_platform_probe(struct platform_device *pdev)
return ret;
}
earcrx_extcon_register(p_earc);
earcrx_cmdc_setup(p_earc);
pr_info("%s, register soc platform\n", __func__);
return devm_snd_soc_register_platform(dev, &earc_platform);
@@ -804,7 +963,12 @@ struct platform_driver earc_driver = {
},
.probe = earc_platform_probe,
};
module_platform_driver(earc_driver);
static int __init earc_init(void)
{
return platform_driver_register(&earc_driver);
}
arch_initcall_sync(earc_init);
MODULE_AUTHOR("Amlogic, Inc.");
MODULE_DESCRIPTION("Amlogic eARC/ARC TX/RX ASoc driver");

View File

@@ -15,6 +15,7 @@
*
*/
#include <linux/types.h>
#include <linux/kernel.h>
#include "earc_hw.h"
@@ -23,14 +24,14 @@ void earcrx_cmdc_init(void)
{
/* set irq mask */
earcrx_top_write(EARCRX_CMDC_INT_MASK,
(0 << 15) | /* idle2_int */
(0 << 14) | /* idle1_int */
(0 << 13) | /* disc2_int */
(0 << 12) | /* disc1_int */
(0 << 11) | /* earc_int */
(1 << 15) | /* idle2_int */
(1 << 14) | /* idle1_int */
(1 << 13) | /* disc2_int */
(1 << 12) | /* disc1_int */
(1 << 11) | /* earc_int */
(1 << 10) | /* hb_status_int */
(0 << 9) | /* losthb_int */
(0 << 8) | /* timeout_int */
(1 << 9) | /* losthb_int */
(1 << 8) | /* timeout_int */
(0 << 7) | /* status_ch_int */
(0 << 6) | /* int_rec_invalid_id */
(0 << 5) | /* int_rec_invalid_offset */
@@ -38,16 +39,104 @@ void earcrx_cmdc_init(void)
(0 << 3) | /* int_rec_ecc_err */
(0 << 2) | /* int_rec_parity_err */
(0 << 1) | /* int_recv_packet */
(0 << 0) /* int_rec_time_out */
(0 << 0) /* int_rec_time_out */
);
earcrx_top_write(EARCRX_ANA_CTRL0, 0x90884814);
earcrx_top_write(EARCRX_PLL_CTRL3, 0x242000);
earcrx_top_write(EARCRX_PLL_CTRL0, 0x10800400);
earcrx_top_write(EARCRX_ANA_CTRL0,
0x1 << 31 | /* earcrx_en_d2a */
0x10 << 24 | /* earcrx_cmdcrx_reftrim */
0x8 << 20 | /* earcrx_idr_trim */
0x10 << 15 | /* earcrx_rterm_trim */
0x4 << 12 | /* earcrx_cmdctx_ack_hystrim */
0x10 << 7 | /* earcrx_cmdctx_ack_reftrim */
0x1 << 4 | /* earcrx_cmdcrx_rcfilter_sel */
0x4 << 0 /* earcrx_cmdcrx_hystrim */
);
earcrx_top_write(EARCRX_PLL_CTRL3,
0x2 << 20 | /* earcrx_pll_bias_adj */
0x4 << 16 | /* earcrx_pll_rou */
0x1 << 13 /* earcrx_pll_dco_sdm_e */
);
earcrx_top_write(EARCRX_PLL_CTRL0,
0x1 << 28 | /* earcrx_pll_en */
0x1 << 23 | /* earcrx_pll_dmacrx_sqout_rstn_sel */
0x1 << 10 /* earcrx_pll_n */
);
}
void earcrx_cmdc_arc_connect(bool init)
{
if (init)
earcrx_cmdc_update_bits(
EARC_RX_CMDC_VSM_CTRL0,
0x7 << 25,
0x1 << 27 | /* arc_initiated */
0x0 << 26 | /* arc_terminated */
0x1 << 25 /* arc_enable */
);
else
earcrx_cmdc_update_bits(
EARC_RX_CMDC_VSM_CTRL0,
0x7 << 25,
0x0 << 27 | /* arc_initiated */
0x1 << 26 | /* arc_terminated */
0x0 << 25 /* arc_enable */
);
}
void earcrx_cmdc_hpd_detect(bool st)
{
if (st) {
earcrx_cmdc_update_bits(
EARC_RX_CMDC_VSM_CTRL0,
0x1 << 19,
0x1 << 19 /* comma_cnt_rst */
);
earcrx_cmdc_update_bits(
EARC_RX_CMDC_VSM_CTRL0,
0x1 << 19 | 0xff << 0,
0x1 << 19 | /* comma_cnt_rst */
0xff << 0
);
} else {
/* soft reset */
earcrx_cmdc_update_bits(
EARC_RX_CMDC_TOP_CTRL1,
0xf << 1,
0xf << 1);
earcrx_cmdc_update_bits(
EARC_RX_CMDC_TOP_CTRL1,
0xf << 1,
0x0 << 1);
}
}
void earcrx_dmac_init(void)
{
earcrx_top_write(EARCRX_DMAC_INT_MASK,
(0x0 << 17) | /* earcrx_ana_rst c_new_format_set */
(0x0 << 16) | /* earcrx_ana_rst c_earcrx_div2_hold_set */
(0x0 << 15) | /* earcrx_err_correct c_bcherr_int_set */
(0x0 << 14) | /* earcrx_err_correct r_afifo_overflow_set */
(0x0 << 13) | /* earcrx_err_correct r_fifo_overflow_set */
(0x0 << 12) | /* earcrx_user_bit_check r_fifo_overflow */
(0x0 << 11) | /* earcrx_user_bit_check c_fifo_thd_pass */
(0x0 << 10) | /* earcrx_user_bit_check c_u_pk_lost_int_set */
(0x0 << 9) | /* arcrx_user_bit_check c_iu_pk_end */
(0x0 << 8) | /* arcrx_biphase_decode c_chst_mute_clr */
(0x1 << 7) | /* arcrx_biphase_decode c_find_papb */
(0x1 << 6) | /* arcrx_biphase_decode c_valid_change */
(0x1 << 5) | /* arcrx_biphase_decode c_find_nonpcm2pcm */
(0x1 << 4) | /* arcrx_biphase_decode c_pcpd_change */
(0x1 << 3) | /* arcrx_biphase_decode c_ch_status_change */
(0x1 << 2) | /* arcrx_biphase_decode sample_mod_change */
(0x1 << 1) | /* arcrx_biphase_decode r_parity_err */
(0x0 << 0) /* arcrx_dmac_sync afifo_overflow */
);
earcrx_dmac_write(EARCRX_DMAC_SYNC_CTRL0,
(1 << 16) | /* reg_ana_buf_data_sel_en */
(3 << 12) | /* reg_ana_buf_data_sel */
@@ -62,13 +151,72 @@ void earcrx_dmac_init(void)
earcrx_dmac_write(EARCRX_ANA_RST_CTRL0, 1 << 31);
}
void earc_arc_init(void)
void earcrx_arc_init(void)
{
unsigned int spdifin_clk = 500000000;
/* sysclk/rate/32(bit)/2(ch)/2(bmc) */
unsigned int counter_32k = (spdifin_clk / (32000 * 64));
unsigned int counter_44k = (spdifin_clk / (44100 * 64));
unsigned int counter_48k = (spdifin_clk / (48000 * 64));
unsigned int counter_88k = (spdifin_clk / (88200 * 64));
unsigned int counter_96k = (spdifin_clk / (96000 * 64));
unsigned int counter_176k = (spdifin_clk / (176400 * 64));
unsigned int counter_192k = (spdifin_clk / (192000 * 64));
unsigned int mode0_th = 3 * (counter_32k + counter_44k) >> 1;
unsigned int mode1_th = 3 * (counter_44k + counter_48k) >> 1;
unsigned int mode2_th = 3 * (counter_48k + counter_88k) >> 1;
unsigned int mode3_th = 3 * (counter_88k + counter_96k) >> 1;
unsigned int mode4_th = 3 * (counter_96k + counter_176k) >> 1;
unsigned int mode5_th = 3 * (counter_176k + counter_192k) >> 1;
unsigned int mode0_timer = counter_32k >> 1;
unsigned int mode1_timer = counter_44k >> 1;
unsigned int mode2_timer = counter_48k >> 1;
unsigned int mode3_timer = counter_88k >> 1;
unsigned int mode4_timer = counter_96k >> 1;
unsigned int mode5_timer = (counter_176k >> 1);
unsigned int mode6_timer = (counter_192k >> 1);
earcrx_dmac_write(
EARCRX_SPDIFIN_SAMPLE_CTRL0,
0x0 << 28 | /* detect by max_width */
(spdifin_clk / 10000) << 0 /* base timer */
);
earcrx_dmac_write(
EARCRX_SPDIFIN_SAMPLE_CTRL1,
mode0_th << 20 |
mode1_th << 10 |
mode2_th << 0);
earcrx_dmac_write(
EARCRX_SPDIFIN_SAMPLE_CTRL2,
mode3_th << 20 |
mode4_th << 10 |
mode5_th << 0);
earcrx_dmac_write(
EARCRX_SPDIFIN_SAMPLE_CTRL3,
(mode0_timer << 24) |
(mode1_timer << 16) |
(mode2_timer << 8) |
(mode3_timer << 0)
);
earcrx_dmac_write(
EARCRX_SPDIFIN_SAMPLE_CTRL4,
(mode4_timer << 24) |
(mode5_timer << 16) |
(mode6_timer << 8)
);
earcrx_dmac_write(EARCRX_SPDIFIN_CTRL0,
(1 << 31) | /* reg_work_en */
(1 << 30) | /* reg_chnum_sel */
(1 << 25) | /* reg_findpapb_en */
(0xFFF<<12) /* reg_nonpcm2pcm_th */
0x1 << 31 | /* reg_work_en */
0x1 << 30 | /* reg_chnum_sel */
0x1 << 25 | /* reg_findpapb_en */
0x1 << 24 | /* nonpcm2pcm_th enable */
0xFFF<<12 /* reg_nonpcm2pcm_th */
);
earcrx_dmac_write(EARCRX_SPDIFIN_CTRL2,
(1 << 14) | /* reg_earc_auto */
@@ -80,8 +228,52 @@ void earc_arc_init(void)
);
}
void earc_rx_enable(bool enable)
enum cmdc_st earcrx_cmdc_get_state(void)
{
int val = earcrx_cmdc_read(EARC_RX_CMDC_STATUS0);
enum cmdc_st state = (enum cmdc_st)(val & 0x7);
return state;
}
enum attend_type earcrx_cmdc_get_attended_type(void)
{
int val = earcrx_cmdc_read(EARC_RX_CMDC_STATUS0);
enum cmdc_st state = (enum cmdc_st)(val & 0x7);
enum attend_type type = ATNDTYP_DISCNCT;
if ((val & (1 << 0x3)) && (state == CMDC_ST_ARC))
type = ATNDTYP_ARC;
else if ((val & (1 << 0x4)) && (state == CMDC_ST_EARC))
type = ATNDTYP_eARC;
return type;
}
void earcrx_cdmc_clr_irqs(int clr)
{
earcrx_top_write(EARCRX_CMDC_INT_PENDING, clr);
}
int earcrx_cdmc_get_irqs(void)
{
return earcrx_top_read(EARCRX_CMDC_INT_PENDING);
}
void earcrx_dmac_clr_irqs(int clr)
{
earcrx_top_write(EARCRX_DMAC_INT_PENDING, clr);
}
int earcrx_dmac_get_irqs(void)
{
return earcrx_top_read(EARCRX_DMAC_INT_PENDING);
}
void earcrx_enable(bool enable)
{
enum attend_type type = earcrx_cmdc_get_attended_type();
if (enable) {
earcrx_dmac_update_bits(EARCRX_DMAC_SYNC_CTRL0,
1 << 30, /* reg_rst_afifo_out_n */
@@ -108,9 +300,18 @@ void earc_rx_enable(bool enable)
0x3 << 28, 0x0 << 28);
}
earcrx_dmac_update_bits(EARCRX_DMAC_SYNC_CTRL0,
1 << 31, /* reg_work_en */
enable << 31);
if (type == ATNDTYP_eARC)
earcrx_dmac_update_bits(EARCRX_DMAC_SYNC_CTRL0,
1 << 31, /* reg_work_en */
enable << 31);
else if (type == ATNDTYP_ARC) {
earcrx_dmac_update_bits(
EARCRX_SPDIFIN_SAMPLE_CTRL0,
0x1 << 31, /* reg_work_enable */
enable << 31);
earcrx_dmac_write(EARCRX_DMAC_SYNC_CTRL0, 0x0);
}
earcrx_dmac_update_bits(EARCRX_DMAC_UBIT_CTRL0,
1 << 31, /* reg_work_enable */

View File

@@ -20,8 +20,70 @@
#include "regs.h"
#include "iomap.h"
#define INT_EARCRX_CMDC_IDLE2 (0x1 << 15)
#define INT_EARCRX_CMDC_IDLE1 (0x1 << 14)
#define INT_EARCRX_CMDC_DISC2 (0x1 << 13)
#define INT_EARCRX_CMDC_DISC1 (0x1 << 12)
#define INT_EARCRX_CMDC_EARC (0x1 << 11)
#define INT_EARCRX_CMDC_HB_STATUS (0x1 << 10)
#define INT_EARCRX_CMDC_LOSTHB (0x1 << 9)
#define INT_EARCRX_CMDC_TIMEOUT (0x1 << 8)
#define INT_EARCRX_CMDC_STATUS_CH (0x1 << 7)
#define INT_EARCRX_CMDC_REC_INVALID_ID (0x1 << 6)
#define INT_EARCRX_CMDC_REC_INVALID_OFFSET (0x1 << 5)
#define INT_EARCRX_CMDC_REC_UNEXP (0x1 << 4)
#define INT_EARCRX_CMDC_REC_ECC_ERR (0x1 << 3)
#define INT_EARCRX_CMDC_REC_PARITY_ERR (0x1 << 2)
#define INT_EARCRX_CMDC_RECV_PACKET (0x1 << 1)
#define INT_EARCRX_CMDC_REC_TIME_OUT (0x1 << 0)
#define INT_EARCRX_ANA_RST_C_NEW_FORMAT_SET (0x1 << 17)
#define INT_EARCRX_ANA_RST_C_EARCRX_DIV2_HOLD_SET (0x1 << 16)
#define INT_EARCRX_ERR_CORRECT_C_BCHERR_INT_SET (0x1 << 15)
#define INT_EARCRX_ERR_CORRECT_R_AFIFO_OVERFLOW_SET (0x1 << 14)
#define INT_EARCRX_ERR_CORRECT_R_FIFO_OVERFLOW_SET (0x1 << 13)
#define INT_EARCRX_USER_BIT_CHECK_R_FIFO_OVERFLOW (0x1 << 12)
#define INT_EARCRX_USER_BIT_CHECK_C_FIFO_THD_PASS (0x1 << 11)
#define INT_EARCRX_USER_BIT_CHECK_C_U_PK_LOST_INT_SET (0x1 << 10)
#define INT_ARCRX_USER_BIT_CHECK_C_IU_PK_END (0x1 << 9)
#define INT_ARCRX_BIPHASE_DECODE_C_CHST_MUTE_CLR (0x1 << 8)
#define INT_ARCRX_BIPHASE_DECODE_C_FIND_PAPB (0x1 << 7)
#define INT_ARCRX_BIPHASE_DECODE_C_VALID_CHANGE (0x1 << 6)
#define INT_ARCRX_BIPHASE_DECODE_C_FIND_NONPCM2PCM (0x1 << 5)
#define INT_ARCRX_BIPHASE_DECODE_C_PCPD_CHANGE (0x1 << 4)
#define INT_ARCRX_BIPHASE_DECODE_C_CH_STATUS_CHANGE (0x1 << 3)
#define INT_ARCRX_BIPHASE_DECODE_I_SAMPLE_MODE_CHANGE (0x1 << 2)
#define INT_ARCRX_BIPHASE_DECODE_R_PARITY_ERR (0x1 << 1)
#define INT_ARCRX_DMAC_SYNC_AFIFO_OVERFLOW (0x1 << 0)
/* cmdc discovery and disconnect state */
enum cmdc_st {
CMDC_ST_OFF,
CMDC_ST_IDLE1,
CMDC_ST_IDLE2,
CMDC_ST_DISC1,
CMDC_ST_DISC2,
CMDC_ST_EARC,
CMDC_ST_ARC
};
/* attended type: disconect, ARC, eARC */
enum attend_type {
ATNDTYP_DISCNCT,
ATNDTYP_ARC,
ATNDTYP_eARC
};
extern void earcrx_cmdc_init(void);
void earcrx_cmdc_arc_connect(bool init);
void earcrx_cmdc_hpd_detect(bool st);
extern void earcrx_dmac_init(void);
extern void earc_arc_init(void);
extern void earc_rx_enable(bool enable);
extern void earcrx_arc_init(void);
enum cmdc_st earcrx_cmdc_get_state(void);
enum attend_type earcrx_cmdc_get_attended_type(void);
extern void earcrx_cdmc_clr_irqs(int clr);
extern int earcrx_cdmc_get_irqs(void);
extern void earcrx_dmac_clr_irqs(int clr);
extern int earcrx_dmac_get_irqs(void);
extern void earcrx_enable(bool enable);
#endif

View File

@@ -35,6 +35,7 @@
#include <sound/control.h>
#include <sound/soc.h>
#include <sound/pcm_params.h>
#include <sound/tlv.h>
#include "ddr_mngr.h"
#include "audio_utils.h"
@@ -47,11 +48,19 @@
#define MAX_INT 0x7ffffff
#define DYNC_KCNTL_CNT 2
struct extn_chipinfo {
/* try to check papb before fetch pcpd
* no nonpcm2pcm irq for tl1
*/
bool no_nonpcm2pcm_clr;
/* eARC-ARC or CEC-ARC
* CEC-ARC: tl1
* eARC-ARC: sm1/tm2, etc
*/
bool cec_arc;
};
struct extn {
@@ -91,6 +100,8 @@ struct extn {
bool nonpcm_flag;
struct extn_chipinfo *chipinfo;
struct snd_kcontrol *controls[DYNC_KCNTL_CNT];
};
#define PREALLOC_BUFFER (256 * 1024)
@@ -402,10 +413,19 @@ struct snd_soc_platform_driver extn_platform = {
.pcm_new = extn_new,
};
static int extn_create_controls(struct snd_card *card,
struct extn *p_extn);
static int extn_dai_probe(struct snd_soc_dai *cpu_dai)
{
struct snd_card *card = cpu_dai->component->card->snd_card;
struct extn *p_extn = snd_soc_dai_get_drvdata(cpu_dai);
pr_info("asoc debug: %s-%d\n", __func__, __LINE__);
if (p_extn->chipinfo && p_extn->chipinfo->cec_arc)
extn_create_controls(card, p_extn);
return 0;
}
@@ -807,8 +827,7 @@ static int hdmirx_audio_type_get_enum(
}
#endif
static const struct snd_kcontrol_new extn_controls[] = {
/* Out */
static const struct snd_kcontrol_new extn_arc_controls[DYNC_KCNTL_CNT] = {
SOC_ENUM_EXT("HDMI ARC Source",
arc_src_enum,
arc_get_src,
@@ -818,6 +837,34 @@ static const struct snd_kcontrol_new extn_controls[] = {
0,
arc_get_enable,
arc_set_enable),
};
static int extn_create_controls(struct snd_card *card,
struct extn *p_extn)
{
int i, err = 0;
memset(p_extn->controls, 0, sizeof(p_extn->controls));
for (i = 0; i < DYNC_KCNTL_CNT; i++) {
p_extn->controls[i] =
snd_ctl_new1(&extn_arc_controls[i], NULL);
err = snd_ctl_add(card, p_extn->controls[i]);
if (err < 0)
goto __error;
}
return 0;
__error:
for (i = 0; i < DYNC_KCNTL_CNT; i++)
if (p_extn->controls[i])
snd_ctl_remove(card, p_extn->controls[i]);
return err;
}
static const struct snd_kcontrol_new extn_controls[] = {
/* In */
SOC_SINGLE_BOOL_EXT("SPDIFIN PAO",
@@ -886,12 +933,12 @@ static const struct snd_soc_component_driver extn_component = {
struct extn_chipinfo tl1_extn_chipinfo = {
.no_nonpcm2pcm_clr = true,
.cec_arc = true,
};
static const struct of_device_id extn_device_id[] = {
{
.compatible = "amlogic, snd-extn",
.data = &tl1_extn_chipinfo,
},
{
.compatible = "amlogic, tl1-snd-extn",