* [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC
@ 2022-09-30 14:56 Trevor Wu
2022-09-30 14:56 ` [PATCH 01/12] ASoC: mediatek: common: add SMC ops ID Trevor Wu
` (10 more replies)
0 siblings, 11 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
This series of patches adds support for Mediatek AFE of MT8188 SoC.
Patches are based on broonie tree "for-next" branch.
Trevor Wu (12):
ASoC: mediatek: common: add SMC ops ID
ASoC: mediatek: mt8188: add common header
ASoC: mediatek: mt8188: support audsys clock
ASoC: mediatek: mt8188: support adda in platform driver
ASoC: mediatek: mt8188: support etdm in platform driver
ASoC: mediatek: mt8188: support pcmif in platform driver
ASoC: mediatek: mt8188: support audio clock control
ASoC: mediatek: mt8188: add platform driver
ASoC: mediatek: mt8188: add control for timing select
dt-bindings: mediatek: mt8188: add audio afe document
ASoC: mediatek: mt8188: add machine driver with mt6359
dt-bindings: mediatek: mt8188: add mt8188-mt6359 document
.../bindings/sound/mt8188-afe-pcm.yaml | 202 +
.../bindings/sound/mt8188-mt6359.yaml | 70 +
sound/soc/mediatek/Kconfig | 23 +
sound/soc/mediatek/Makefile | 1 +
sound/soc/mediatek/common/mtk-base-afe.h | 16 +
sound/soc/mediatek/mt8188/Makefile | 15 +
sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 656 ++++
sound/soc/mediatek/mt8188/mt8188-afe-clk.h | 114 +
sound/soc/mediatek/mt8188/mt8188-afe-common.h | 151 +
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 3451 +++++++++++++++++
sound/soc/mediatek/mt8188/mt8188-audsys-clk.c | 206 +
sound/soc/mediatek/mt8188/mt8188-audsys-clk.h | 15 +
.../soc/mediatek/mt8188/mt8188-audsys-clkid.h | 83 +
sound/soc/mediatek/mt8188/mt8188-dai-adda.c | 639 +++
sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 2598 +++++++++++++
sound/soc/mediatek/mt8188/mt8188-dai-pcm.c | 362 ++
sound/soc/mediatek/mt8188/mt8188-mt6359.c | 810 ++++
sound/soc/mediatek/mt8188/mt8188-reg.h | 3300 ++++++++++++++++
18 files changed, 12712 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
create mode 100644 Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
create mode 100644 sound/soc/mediatek/mt8188/Makefile
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-clk.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-clk.h
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-common.h
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
create mode 100644 sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h
create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-adda.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-pcm.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-mt6359.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-reg.h
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* [PATCH 01/12] ASoC: mediatek: common: add SMC ops ID
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 14:56 ` [PATCH 03/12] ASoC: mediatek: mt8188: support audsys clock Trevor Wu
` (9 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
SMC call is required to communicate with ATF for some secure operations,
so we add SMC ops IDs to common header.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/common/mtk-base-afe.h | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h
index ef83e78c22a8..d33c2a3f54a9 100644
--- a/sound/soc/mediatek/common/mtk-base-afe.h
+++ b/sound/soc/mediatek/common/mtk-base-afe.h
@@ -11,6 +11,22 @@
#define MTK_STREAM_NUM (SNDRV_PCM_STREAM_LAST + 1)
+/* SMC CALL Operations */
+enum mtk_audio_smc_call_op {
+ MTK_AUDIO_SMC_OP_INIT = 0,
+ MTK_AUDIO_SMC_OP_DRAM_REQUEST,
+ MTK_AUDIO_SMC_OP_DRAM_RELEASE,
+ MTK_AUDIO_SMC_OP_SRAM_REQUEST,
+ MTK_AUDIO_SMC_OP_SRAM_RELEASE,
+ MTK_AUDIO_SMC_OP_ADSP_REQUEST,
+ MTK_AUDIO_SMC_OP_ADSP_RELEASE,
+ MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS,
+ MTK_AUDIO_SMC_OP_BTCVSD_WRITE,
+ MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_CLEAR,
+ MTK_AUDIO_SMC_OP_BTCVSD_UPDATE_CTRL_UNDERFLOW,
+ MTK_AUDIO_SMC_OP_NUM
+};
+
struct mtk_base_memif_data {
int id;
const char *name;
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 03/12] ASoC: mediatek: mt8188: support audsys clock
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
2022-09-30 14:56 ` [PATCH 01/12] ASoC: mediatek: common: add SMC ops ID Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 14:56 ` [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver Trevor Wu
` (8 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mt8188 audio cg clock control. Audio clock gates are registered to CCF
for reference count and clock parent management.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/mt8188/mt8188-audsys-clk.c | 206 ++++++++++++++++++
sound/soc/mediatek/mt8188/mt8188-audsys-clk.h | 15 ++
.../soc/mediatek/mt8188/mt8188-audsys-clkid.h | 83 +++++++
3 files changed, 304 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
create mode 100644 sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h
diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
new file mode 100644
index 000000000000..30a1f50b4c45
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8188-audsys-clk.c -- Mediatek 8188 audsys clock control
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/clkdev.h>
+#include "mt8188-afe-common.h"
+#include "mt8188-audsys-clk.h"
+#include "mt8188-audsys-clkid.h"
+#include "mt8188-reg.h"
+
+struct afe_gate {
+ int id;
+ const char *name;
+ const char *parent_name;
+ int reg;
+ u8 bit;
+ const struct clk_ops *ops;
+ unsigned long flags;
+ u8 cg_flags;
+};
+
+#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\
+ .id = _id, \
+ .name = _name, \
+ .parent_name = _parent, \
+ .reg = _reg, \
+ .bit = _bit, \
+ .flags = _flags, \
+ .cg_flags = _cgflags, \
+ }
+
+#define GATE_AFE(_id, _name, _parent, _reg, _bit) \
+ GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, \
+ CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, CLK_GATE_SET_TO_DISABLE)
+
+#define GATE_AUD0(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit)
+
+#define GATE_AUD1(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit)
+
+#define GATE_AUD3(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit)
+
+#define GATE_AUD4(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit)
+
+#define GATE_AUD5(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit)
+
+#define GATE_AUD6(_id, _name, _parent, _bit) \
+ GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit)
+
+static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = {
+ /* AUD0 */
+ GATE_AUD0(CLK_AUD_AFE, "aud_afe", "top_a1sys_hp", 2),
+ GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "top_a1sys_hp", 4),
+ GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "top_apll4", 10),
+ GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "top_apll4", 11),
+ GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "top_a1sys_hp", 18),
+ GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "top_apll1", 19),
+ GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "top_apll2", 20),
+ GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "top_aud_iec_clk", 21),
+ GATE_AUD0(CLK_AUD_APLL, "aud_apll", "top_apll1", 23),
+ GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "top_apll2", 24),
+ GATE_AUD0(CLK_AUD_DAC, "aud_dac", "top_a1sys_hp", 25),
+ GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "top_a1sys_hp", 26),
+ GATE_AUD0(CLK_AUD_TML, "aud_tml", "top_a1sys_hp", 27),
+ GATE_AUD0(CLK_AUD_ADC, "aud_adc", "top_a1sys_hp", 28),
+ GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "top_audio_h", 31),
+
+ /* AUD1 */
+ GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "top_a1sys_hp", 2),
+ GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "top_a1sys_hp", 10),
+ GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "top_a1sys_hp", 11),
+ GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "top_a1sys_hp", 12),
+ GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "top_a1sys_hp", 13),
+ GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "top_a1sys_hp", 14),
+ GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "top_audio_h", 16),
+ GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "top_audio_h", 17),
+
+ /* AUD3 */
+ GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "top_apll5", 5),
+ GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "top_apll3", 7),
+
+ /* AUD4 */
+ GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "top_a1sys_hp", 0),
+ GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "top_a1sys_hp", 1),
+ GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "top_a1sys_hp", 6),
+ GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "top_a1sys_hp", 7),
+ GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "top_a1sys_hp", 8),
+ GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "top_a1sys_hp", 16),
+ GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "top_a1sys_hp", 17),
+ GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19),
+ GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "top_intdir", 20),
+ GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "top_a1sys_hp", 21),
+ GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "top_a2sys", 22),
+ GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "top_a1sys_hp", 24),
+ GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "top_a3sys", 30),
+ GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "top_a4sys", 31),
+
+ /* AUD5 */
+ GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "top_a1sys_hp", 0),
+ GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "top_a1sys_hp", 1),
+ GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "top_a1sys_hp", 2),
+ GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "top_a1sys_hp", 3),
+ GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "top_a1sys_hp", 4),
+ GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "top_a1sys_hp", 5),
+ GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "top_a1sys_hp", 7),
+ GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "top_a1sys_hp", 8),
+ GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "top_a1sys_hp", 9),
+ GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "top_a1sys_hp", 18),
+ GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "top_a1sys_hp", 19),
+ GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "top_a1sys_hp", 22),
+ GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "top_a1sys_hp", 23),
+ GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "top_a1sys_hp", 24),
+ GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "top_a1sys_hp", 26),
+ GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "top_a1sys_hp", 27),
+
+ /* AUD6 */
+ GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "top_asm_h", 0),
+ GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "top_asm_h", 1),
+ GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "top_asm_h", 2),
+ GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "top_asm_h", 3),
+ GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "top_asm_h", 4),
+ GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "top_asm_h", 5),
+ GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "top_asm_h", 6),
+ GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "top_asm_h", 7),
+ GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "top_asm_h", 8),
+ GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "top_asm_h", 9),
+ GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "top_asm_h", 10),
+ GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "top_asm_h", 11),
+};
+
+int mt8188_audsys_clk_register(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct clk *clk;
+ struct clk_lookup *cl;
+ int i;
+
+ afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK,
+ sizeof(*afe_priv->lookup),
+ GFP_KERNEL);
+
+ if (!afe_priv->lookup)
+ return -ENOMEM;
+
+ for (i = 0; i < ARRAY_SIZE(aud_clks); i++) {
+ const struct afe_gate *gate = &aud_clks[i];
+
+ clk = clk_register_gate(afe->dev, gate->name, gate->parent_name,
+ gate->flags, afe->base_addr + gate->reg,
+ gate->bit, gate->cg_flags, NULL);
+
+ if (IS_ERR(clk)) {
+ dev_err(afe->dev, "Failed to register clk %s: %ld\n",
+ gate->name, PTR_ERR(clk));
+ continue;
+ }
+
+ /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */
+ cl = kzalloc(sizeof(*cl), GFP_KERNEL);
+ if (!cl)
+ return -ENOMEM;
+
+ cl->clk = clk;
+ cl->con_id = gate->name;
+ cl->dev_id = dev_name(afe->dev);
+ cl->clk_hw = NULL;
+ clkdev_add(cl);
+
+ afe_priv->lookup[i] = cl;
+ }
+
+ return 0;
+}
+
+void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct clk *clk;
+ struct clk_lookup *cl;
+ int i;
+
+ if (!afe_priv)
+ return;
+
+ for (i = 0; i < CLK_AUD_NR_CLK; i++) {
+ cl = afe_priv->lookup[i];
+ if (!cl)
+ continue;
+
+ clk = cl->clk;
+ clk_unregister_gate(clk);
+
+ clkdev_drop(cl);
+ }
+}
+
diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clk.h b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
new file mode 100644
index 000000000000..943f0f1d06e1
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clk.h
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8188-audsys-clk.h -- Mediatek 8188 audsys clock definition
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#ifndef _MT8188_AUDSYS_CLK_H_
+#define _MT8188_AUDSYS_CLK_H_
+
+int mt8188_audsys_clk_register(struct mtk_base_afe *afe);
+void mt8188_audsys_clk_unregister(struct mtk_base_afe *afe);
+
+#endif
diff --git a/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h b/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h
new file mode 100644
index 000000000000..aecdbd9d6d37
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-audsys-clkid.h
@@ -0,0 +1,83 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8188-audsys-clkid.h -- Mediatek 8188 audsys clock id definition
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#ifndef _MT8188_AUDSYS_CLKID_H_
+#define _MT8188_AUDSYS_CLKID_H_
+
+enum{
+ CLK_AUD_AFE,
+ CLK_AUD_LRCK_CNT,
+ CLK_AUD_SPDIFIN_TUNER_APLL,
+ CLK_AUD_SPDIFIN_TUNER_DBG,
+ CLK_AUD_UL_TML,
+ CLK_AUD_APLL1_TUNER,
+ CLK_AUD_APLL2_TUNER,
+ CLK_AUD_TOP0_SPDF,
+ CLK_AUD_APLL,
+ CLK_AUD_APLL2,
+ CLK_AUD_DAC,
+ CLK_AUD_DAC_PREDIS,
+ CLK_AUD_TML,
+ CLK_AUD_ADC,
+ CLK_AUD_DAC_HIRES,
+ CLK_AUD_A1SYS_HP,
+ CLK_AUD_AFE_DMIC1,
+ CLK_AUD_AFE_DMIC2,
+ CLK_AUD_AFE_DMIC3,
+ CLK_AUD_AFE_DMIC4,
+ CLK_AUD_AFE_26M_DMIC_TM,
+ CLK_AUD_UL_TML_HIRES,
+ CLK_AUD_ADC_HIRES,
+ CLK_AUD_LINEIN_TUNER,
+ CLK_AUD_EARC_TUNER,
+ CLK_AUD_I2SIN,
+ CLK_AUD_TDM_IN,
+ CLK_AUD_I2S_OUT,
+ CLK_AUD_TDM_OUT,
+ CLK_AUD_HDMI_OUT,
+ CLK_AUD_ASRC11,
+ CLK_AUD_ASRC12,
+ CLK_AUD_MULTI_IN,
+ CLK_AUD_INTDIR,
+ CLK_AUD_A1SYS,
+ CLK_AUD_A2SYS,
+ CLK_AUD_PCMIF,
+ CLK_AUD_A3SYS,
+ CLK_AUD_A4SYS,
+ CLK_AUD_MEMIF_UL1,
+ CLK_AUD_MEMIF_UL2,
+ CLK_AUD_MEMIF_UL3,
+ CLK_AUD_MEMIF_UL4,
+ CLK_AUD_MEMIF_UL5,
+ CLK_AUD_MEMIF_UL6,
+ CLK_AUD_MEMIF_UL8,
+ CLK_AUD_MEMIF_UL9,
+ CLK_AUD_MEMIF_UL10,
+ CLK_AUD_MEMIF_DL2,
+ CLK_AUD_MEMIF_DL3,
+ CLK_AUD_MEMIF_DL6,
+ CLK_AUD_MEMIF_DL7,
+ CLK_AUD_MEMIF_DL8,
+ CLK_AUD_MEMIF_DL10,
+ CLK_AUD_MEMIF_DL11,
+ CLK_AUD_GASRC0,
+ CLK_AUD_GASRC1,
+ CLK_AUD_GASRC2,
+ CLK_AUD_GASRC3,
+ CLK_AUD_GASRC4,
+ CLK_AUD_GASRC5,
+ CLK_AUD_GASRC6,
+ CLK_AUD_GASRC7,
+ CLK_AUD_GASRC8,
+ CLK_AUD_GASRC9,
+ CLK_AUD_GASRC10,
+ CLK_AUD_GASRC11,
+ CLK_AUD_NR_CLK,
+};
+
+#endif
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
2022-09-30 14:56 ` [PATCH 01/12] ASoC: mediatek: common: add SMC ops ID Trevor Wu
2022-09-30 14:56 ` [PATCH 03/12] ASoC: mediatek: mt8188: support audsys clock Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-10-04 9:37 ` AngeloGioacchino Del Regno
2022-09-30 14:56 ` [PATCH 05/12] ASoC: mediatek: mt8188: support etdm " Trevor Wu
` (7 subsequent siblings)
10 siblings, 1 reply; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mt8188 adda dai driver support.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/mt8188/mt8188-dai-adda.c | 639 ++++++++++++++++++++
1 file changed, 639 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-adda.c
diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
new file mode 100644
index 000000000000..ba8f622bb107
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
@@ -0,0 +1,639 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI ADDA Control
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#include <linux/delay.h>
+#include <linux/regmap.h>
+#include "mt8188-afe-clk.h"
+#include "mt8188-afe-common.h"
+#include "mt8188-reg.h"
+
+#define ADDA_HIRES_THRES 48000
+
+enum {
+ SUPPLY_SEQ_CLOCK_SEL,
+ SUPPLY_SEQ_ADDA_DL_ON,
+ SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+ SUPPLY_SEQ_ADDA_UL_ON,
+ SUPPLY_SEQ_ADDA_AFE_ON,
+};
+
+enum {
+ MTK_AFE_ADDA_DL_RATE_8K = 0,
+ MTK_AFE_ADDA_DL_RATE_11K = 1,
+ MTK_AFE_ADDA_DL_RATE_12K = 2,
+ MTK_AFE_ADDA_DL_RATE_16K = 3,
+ MTK_AFE_ADDA_DL_RATE_22K = 4,
+ MTK_AFE_ADDA_DL_RATE_24K = 5,
+ MTK_AFE_ADDA_DL_RATE_32K = 6,
+ MTK_AFE_ADDA_DL_RATE_44K = 7,
+ MTK_AFE_ADDA_DL_RATE_48K = 8,
+ MTK_AFE_ADDA_DL_RATE_96K = 9,
+ MTK_AFE_ADDA_DL_RATE_192K = 10,
+};
+
+enum {
+ MTK_AFE_ADDA_UL_RATE_8K = 0,
+ MTK_AFE_ADDA_UL_RATE_16K = 1,
+ MTK_AFE_ADDA_UL_RATE_32K = 2,
+ MTK_AFE_ADDA_UL_RATE_48K = 3,
+ MTK_AFE_ADDA_UL_RATE_96K = 4,
+ MTK_AFE_ADDA_UL_RATE_192K = 5,
+};
+
+enum {
+ DELAY_DATA_MISO1 = 0,
+ DELAY_DATA_MISO0 = 1,
+};
+
+struct mtk_dai_adda_priv {
+ unsigned int dl_rate;
+ unsigned int ul_rate;
+};
+
+static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe,
+ unsigned int rate)
+{
+ switch (rate) {
+ case 8000:
+ return MTK_AFE_ADDA_DL_RATE_8K;
+ case 11025:
+ return MTK_AFE_ADDA_DL_RATE_11K;
+ case 12000:
+ return MTK_AFE_ADDA_DL_RATE_12K;
+ case 16000:
+ return MTK_AFE_ADDA_DL_RATE_16K;
+ case 22050:
+ return MTK_AFE_ADDA_DL_RATE_22K;
+ case 24000:
+ return MTK_AFE_ADDA_DL_RATE_24K;
+ case 32000:
+ return MTK_AFE_ADDA_DL_RATE_32K;
+ case 44100:
+ return MTK_AFE_ADDA_DL_RATE_44K;
+ case 48000:
+ return MTK_AFE_ADDA_DL_RATE_48K;
+ case 96000:
+ return MTK_AFE_ADDA_DL_RATE_96K;
+ case 192000:
+ return MTK_AFE_ADDA_DL_RATE_192K;
+ default:
+ dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+ __func__, rate);
+ return MTK_AFE_ADDA_DL_RATE_48K;
+ }
+}
+
+static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe,
+ unsigned int rate)
+{
+ switch (rate) {
+ case 8000:
+ return MTK_AFE_ADDA_UL_RATE_8K;
+ case 16000:
+ return MTK_AFE_ADDA_UL_RATE_16K;
+ case 32000:
+ return MTK_AFE_ADDA_UL_RATE_32K;
+ case 48000:
+ return MTK_AFE_ADDA_UL_RATE_48K;
+ case 96000:
+ return MTK_AFE_ADDA_UL_RATE_96K;
+ case 192000:
+ return MTK_AFE_ADDA_UL_RATE_192K;
+ default:
+ dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n",
+ __func__, rate);
+ return MTK_AFE_ADDA_UL_RATE_48K;
+ }
+}
+
+static int mt8188_adda_mtkaif_init(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ int delay_data;
+ int delay_cycle;
+ unsigned int mask = 0;
+ unsigned int val = 0;
+
+ /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
+ mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+ val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
+
+ regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);
+
+ mask = RG_RX_PROTOCOL2;
+ val = RG_RX_PROTOCOL2;
+ regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
+
+ if (!param->mtkaif_calibration_ok) {
+ dev_info(afe->dev, "%s(), calibration fail\n", __func__);
+ return 0;
+ }
+
+ /* set delay for ch1, ch2 */
+ if (param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] >=
+ param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]) {
+ delay_data = DELAY_DATA_MISO1;
+ delay_cycle =
+ param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] -
+ param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1];
+ } else {
+ delay_data = DELAY_DATA_MISO0;
+ delay_cycle =
+ param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] -
+ param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0];
+ }
+
+ val = 0;
+ mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
+ val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
+ MTKAIF_RXIF_DELAY_CYCLE_MASK;
+ val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
+ regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
+
+ return 0;
+}
+
+static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ mt8188_adda_mtkaif_init(afe);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_POST_PMD:
+ /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+ usleep_range(125, 135);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, bool dmic)
+{
+ unsigned int reg = AFE_ADDA_UL_SRC_CON0;
+ unsigned int val = 0;
+ unsigned int mask;
+
+ mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
+ UL_MODE_3P25M_CH2_CTL);
+
+ /* turn on dmic, ch1, ch2 */
+ if (dmic)
+ val = mask;
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+}
+
+static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ mtk_adda_ul_mictype(afe, param->mtkaif_dmic_on);
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
+ usleep_range(125, 135);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w,
+ struct snd_kcontrol *kcontrol,
+ int event)
+{
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct clk *clk = afe_priv->clk[MT8188_CLK_TOP_AUDIO_H_SEL];
+ struct clk *clk_parent;
+
+ dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
+ __func__, w->name, event);
+
+ switch (event) {
+ case SND_SOC_DAPM_PRE_PMU:
+ clk_parent = afe_priv->clk[MT8188_CLK_TOP_APLL1];
+ break;
+ case SND_SOC_DAPM_POST_PMD:
+ clk_parent = afe_priv->clk[MT8188_CLK_XTAL_26M];
+ break;
+ default:
+ return 0;
+ }
+ mt8188_afe_set_clk_parent(afe, clk, clk_parent);
+
+ return 0;
+}
+
+static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ struct snd_soc_dapm_widget *w = source;
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_adda_priv *adda_priv;
+
+ adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
+
+ if (!adda_priv) {
+ dev_err(afe->dev, "%s adda_priv == NULL", __func__);
+ return 0;
+ }
+
+ return (adda_priv->ul_rate > ADDA_HIRES_THRES) ? 1 : 0;
+}
+
+static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget *source,
+ struct snd_soc_dapm_widget *sink)
+{
+ struct snd_soc_dapm_widget *w = source;
+ struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_adda_priv *adda_priv;
+
+ adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
+
+ if (!adda_priv) {
+ dev_err(afe->dev, "%s adda_priv == NULL", __func__);
+ return 0;
+ }
+
+ return (adda_priv->dl_rate > ADDA_HIRES_THRES) ? 1 : 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0),
+};
+
+static const char * const adda_dlgain_mux_map[] = {
+ "Bypass", "Connect",
+};
+
+static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum,
+ SND_SOC_NOPM, 0,
+ adda_dlgain_mux_map);
+
+static const struct snd_kcontrol_new adda_dlgain_mux_control =
+ SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum);
+
+static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = {
+ SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0,
+ mtk_dai_adda_o176_mix,
+ ARRAY_SIZE(mtk_dai_adda_o176_mix)),
+ SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0,
+ mtk_dai_adda_o177_mix,
+ ARRAY_SIZE(mtk_dai_adda_o177_mix)),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON,
+ AFE_ADDA_UL_DL_CON0,
+ ADDA_AFE_ON_SHIFT, 0,
+ NULL,
+ 0),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON,
+ AFE_ADDA_DL_SRC2_CON0,
+ DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0,
+ mtk_adda_dl_event,
+ SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON,
+ AFE_ADDA_UL_SRC_CON0,
+ UL_SRC_ON_TMP_CTL_SHIFT, 0,
+ mtk_adda_ul_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL,
+ SND_SOC_NOPM,
+ 0, 0,
+ mtk_audio_hires_event,
+ SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD),
+
+ SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG,
+ SND_SOC_NOPM,
+ 0, 0,
+ mtk_adda_mtkaif_cfg_event,
+ SND_SOC_DAPM_PRE_PMU),
+
+ SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0,
+ &adda_dlgain_mux_control),
+
+ SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0,
+ DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0),
+
+ SND_SOC_DAPM_INPUT("ADDA_INPUT"),
+ SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"),
+
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = {
+ {"ADDA Capture", NULL, "ADDA Enable"},
+ {"ADDA Capture", NULL, "ADDA Capture Enable"},
+ {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"},
+ {"ADDA Capture", NULL, "aud_adc"},
+ {"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adc_hires_connect},
+ {"aud_adc_hires", NULL, "AUDIO_HIRES"},
+
+ {"I168", NULL, "ADDA Capture"},
+ {"I169", NULL, "ADDA Capture"},
+
+ {"ADDA Playback", NULL, "ADDA Enable"},
+ {"ADDA Playback", NULL, "ADDA Playback Enable"},
+ {"ADDA Playback", NULL, "aud_dac"},
+ {"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_dac_hires_connect},
+ {"aud_dac_hires", NULL, "AUDIO_HIRES"},
+
+ {"DL_GAIN", NULL, "O176"},
+ {"DL_GAIN", NULL, "O177"},
+
+ {"DL_GAIN_MUX", "Bypass", "O176"},
+ {"DL_GAIN_MUX", "Bypass", "O177"},
+ {"DL_GAIN_MUX", "Connect", "DL_GAIN"},
+
+ {"ADDA Playback", NULL, "DL_GAIN_MUX"},
+
+ {"O176", "I000 Switch", "I000"},
+ {"O177", "I001 Switch", "I001"},
+
+ {"O176", "I002 Switch", "I002"},
+ {"O177", "I003 Switch", "I003"},
+
+ {"O176", "I020 Switch", "I020"},
+ {"O177", "I021 Switch", "I021"},
+
+ {"O176", "I022 Switch", "I022"},
+ {"O177", "I023 Switch", "I023"},
+
+ {"O176", "I070 Switch", "I070"},
+ {"O177", "I071 Switch", "I071"},
+
+ {"ADDA Capture", NULL, "ADDA_INPUT"},
+ {"ADDA_OUTPUT", NULL, "ADDA Playback"},
+};
+
+static int mt8188_adda_dmic_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+
+ ucontrol->value.integer.value[0] = param->mtkaif_dmic_on;
+ return 0;
+}
+
+static int mt8188_adda_dmic_set(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtkaif_param *param = &afe_priv->mtkaif_params;
+ int dmic_on;
+
+ dmic_on = !!ucontrol->value.integer.value[0];
+
+ dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n",
+ __func__, kcontrol->id.name, dmic_on);
+
+ if (param->mtkaif_dmic_on == dmic_on)
+ return 0;
+
+ param->mtkaif_dmic_on = dmic_on;
+ return 1;
+}
+
+static const struct snd_kcontrol_new mtk_dai_adda_controls[] = {
+ SOC_SINGLE("ADDA_DL_GAIN", AFE_ADDA_DL_SRC2_CON1,
+ DL_2_GAIN_CTL_PRE_SHIFT, 65535, 0),
+ SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC Switch", 0,
+ mt8188_adda_dmic_get, mt8188_adda_dmic_set),
+};
+
+static int mtk_dai_da_configure(struct mtk_base_afe *afe,
+ unsigned int rate, int id)
+{
+ unsigned int val = 0;
+ unsigned int mask = 0;
+
+ /* set sampling rate */
+ mask |= DL_2_INPUT_MODE_CTL_MASK;
+ val |= DL_2_INPUT_MODE_CTL(afe_adda_dl_rate_transform(afe, rate));
+
+ /* turn off saturation */
+ mask |= DL_2_CH1_SATURATION_EN_CTL;
+ mask |= DL_2_CH2_SATURATION_EN_CTL;
+
+ /* turn off mute function */
+ mask |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+ mask |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+ val |= DL_2_MUTE_CH1_OFF_CTL_PRE;
+ val |= DL_2_MUTE_CH2_OFF_CTL_PRE;
+
+ /* set voice input data if input sample rate is 8k or 16k */
+ mask |= DL_2_VOICE_MODE_CTL_PRE;
+ if (rate == 8000 || rate == 16000)
+ val |= DL_2_VOICE_MODE_CTL_PRE;
+
+ regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* new 2nd sdm */
+ mask |= DL_USE_NEW_2ND_SDM;
+ val |= DL_USE_NEW_2ND_SDM;
+ regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val);
+
+ return 0;
+}
+
+static int mtk_dai_ad_configure(struct mtk_base_afe *afe,
+ unsigned int rate, int id)
+{
+ unsigned int val = 0;
+ unsigned int mask = 0;
+
+ mask |= UL_VOICE_MODE_CTL_MASK;
+ val |= UL_VOICE_MODE_CTL(afe_adda_ul_rate_transform(afe, rate));
+
+ regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0,
+ mask, val);
+ return 0;
+}
+
+static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id];
+ unsigned int rate = params_rate(params);
+ int id = dai->id;
+ int ret = 0;
+
+ dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n",
+ __func__, id, substream->stream, rate);
+
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+ adda_priv->dl_rate = rate;
+ ret = mtk_dai_da_configure(afe, rate, id);
+ } else {
+ adda_priv->ul_rate = rate;
+ ret = mtk_dai_ad_configure(afe, rate, id);
+ }
+
+ return ret;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_adda_ops = {
+ .hw_params = mtk_dai_adda_hw_params,
+};
+
+/* dai driver */
+#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\
+ SNDRV_PCM_RATE_96000 |\
+ SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\
+ SNDRV_PCM_RATE_16000 |\
+ SNDRV_PCM_RATE_32000 |\
+ SNDRV_PCM_RATE_48000 |\
+ SNDRV_PCM_RATE_96000 |\
+ SNDRV_PCM_RATE_192000)
+
+#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_adda_driver[] = {
+ {
+ .name = "ADDA",
+ .id = MT8188_AFE_IO_ADDA,
+ .playback = {
+ .stream_name = "ADDA Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_ADDA_PLAYBACK_RATES,
+ .formats = MTK_ADDA_FORMATS,
+ },
+ .capture = {
+ .stream_name = "ADDA Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_ADDA_CAPTURE_RATES,
+ .formats = MTK_ADDA_FORMATS,
+ },
+ .ops = &mtk_dai_adda_ops,
+ },
+};
+
+static int init_adda_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_adda_priv *adda_priv;
+
+ adda_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_adda_priv),
+ GFP_KERNEL);
+ if (!adda_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[MT8188_AFE_IO_ADDA] = adda_priv;
+
+ return 0;
+}
+
+int mt8188_dai_adda_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mtk_dai_adda_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver);
+
+ dai->dapm_widgets = mtk_dai_adda_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets);
+ dai->dapm_routes = mtk_dai_adda_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes);
+ dai->controls = mtk_dai_adda_controls;
+ dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls);
+
+ return init_adda_priv_data(afe);
+}
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 05/12] ASoC: mediatek: mt8188: support etdm in platform driver
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (2 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 14:56 ` [PATCH 06/12] ASoC: mediatek: mt8188: support pcmif " Trevor Wu
` (6 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mt8188 etdm dai driver support.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 2598 +++++++++++++++++++
1 file changed, 2598 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
new file mode 100644
index 000000000000..e4e1a23b70f0
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c
@@ -0,0 +1,2598 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI eTDM Control
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8188-afe-clk.h"
+#include "mt8188-afe-common.h"
+#include "mt8188-reg.h"
+
+#define MT8188_ETDM_MAX_CHANNELS 16
+#define MT8188_ETDM_NORMAL_MAX_BCK_RATE 24576000
+#define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START)
+#define ENUM_TO_STR(x) #x
+
+enum {
+ MTK_DAI_ETDM_FORMAT_I2S = 0,
+ MTK_DAI_ETDM_FORMAT_LJ,
+ MTK_DAI_ETDM_FORMAT_RJ,
+ MTK_DAI_ETDM_FORMAT_EIAJ,
+ MTK_DAI_ETDM_FORMAT_DSPA,
+ MTK_DAI_ETDM_FORMAT_DSPB,
+};
+
+enum {
+ MTK_DAI_ETDM_DATA_ONE_PIN = 0,
+ MTK_DAI_ETDM_DATA_MULTI_PIN,
+};
+
+enum {
+ ETDM_IN,
+ ETDM_OUT,
+};
+
+enum {
+ COWORK_ETDM_NONE = 0,
+ COWORK_ETDM_IN1_M = 2,
+ COWORK_ETDM_IN1_S = 3,
+ COWORK_ETDM_IN2_M = 4,
+ COWORK_ETDM_IN2_S = 5,
+ COWORK_ETDM_OUT1_M = 10,
+ COWORK_ETDM_OUT1_S = 11,
+ COWORK_ETDM_OUT2_M = 12,
+ COWORK_ETDM_OUT2_S = 13,
+ COWORK_ETDM_OUT3_M = 14,
+ COWORK_ETDM_OUT3_S = 15,
+};
+
+enum {
+ ETDM_RELATCH_TIMING_A1A2SYS,
+ ETDM_RELATCH_TIMING_A3SYS,
+ ETDM_RELATCH_TIMING_A4SYS,
+};
+
+enum {
+ ETDM_SYNC_NONE,
+ ETDM_SYNC_FROM_IN1 = 2,
+ ETDM_SYNC_FROM_IN2 = 4,
+ ETDM_SYNC_FROM_OUT1 = 10,
+ ETDM_SYNC_FROM_OUT2 = 12,
+ ETDM_SYNC_FROM_OUT3 = 14,
+};
+
+struct etdm_con_reg {
+ unsigned int con0;
+ unsigned int con1;
+ unsigned int con2;
+ unsigned int con3;
+ unsigned int con4;
+ unsigned int con5;
+};
+
+struct mtk_dai_etdm_rate {
+ unsigned int rate;
+ unsigned int reg_value;
+};
+
+struct mtk_dai_etdm_priv {
+ unsigned int clock_mode;
+ unsigned int data_mode;
+ bool slave_mode;
+ bool lrck_inv;
+ bool bck_inv;
+ unsigned int format;
+ unsigned int slots;
+ unsigned int lrck_width;
+ unsigned int mclk_freq;
+ unsigned int mclk_fixed_apll;
+ unsigned int mclk_apll;
+ unsigned int mclk_dir;
+ int cowork_source_id; //dai id
+ unsigned int cowork_slv_count;
+ int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id
+ bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS];
+ unsigned int en_ref_cnt;
+ bool is_prepared;
+};
+
+static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = {
+ { .rate = 8000, .reg_value = 0, },
+ { .rate = 12000, .reg_value = 1, },
+ { .rate = 16000, .reg_value = 2, },
+ { .rate = 24000, .reg_value = 3, },
+ { .rate = 32000, .reg_value = 4, },
+ { .rate = 48000, .reg_value = 5, },
+ { .rate = 96000, .reg_value = 7, },
+ { .rate = 192000, .reg_value = 9, },
+ { .rate = 384000, .reg_value = 11, },
+ { .rate = 11025, .reg_value = 16, },
+ { .rate = 22050, .reg_value = 17, },
+ { .rate = 44100, .reg_value = 18, },
+ { .rate = 88200, .reg_value = 19, },
+ { .rate = 176400, .reg_value = 20, },
+ { .rate = 352800, .reg_value = 21, },
+};
+
+static int get_etdm_fs_timing(unsigned int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mt8188_etdm_rates); i++)
+ if (mt8188_etdm_rates[i].rate == rate)
+ return mt8188_etdm_rates[i].reg_value;
+
+ return -EINVAL;
+}
+
+static unsigned int get_etdm_ch_fixup(unsigned int channels)
+{
+ if (channels > 16)
+ return 24;
+ else if (channels > 8)
+ return 16;
+ else if (channels > 4)
+ return 8;
+ else if (channels > 2)
+ return 4;
+ else
+ return 2;
+}
+
+static int get_etdm_reg(unsigned int dai_id, struct etdm_con_reg *etdm_reg)
+{
+ switch (dai_id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ etdm_reg->con0 = ETDM_IN1_CON0;
+ etdm_reg->con1 = ETDM_IN1_CON1;
+ etdm_reg->con2 = ETDM_IN1_CON2;
+ etdm_reg->con3 = ETDM_IN1_CON3;
+ etdm_reg->con4 = ETDM_IN1_CON4;
+ etdm_reg->con5 = ETDM_IN1_CON5;
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ etdm_reg->con0 = ETDM_IN2_CON0;
+ etdm_reg->con1 = ETDM_IN2_CON1;
+ etdm_reg->con2 = ETDM_IN2_CON2;
+ etdm_reg->con3 = ETDM_IN2_CON3;
+ etdm_reg->con4 = ETDM_IN2_CON4;
+ etdm_reg->con5 = ETDM_IN2_CON5;
+ break;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ etdm_reg->con0 = ETDM_OUT1_CON0;
+ etdm_reg->con1 = ETDM_OUT1_CON1;
+ etdm_reg->con2 = ETDM_OUT1_CON2;
+ etdm_reg->con3 = ETDM_OUT1_CON3;
+ etdm_reg->con4 = ETDM_OUT1_CON4;
+ etdm_reg->con5 = ETDM_OUT1_CON5;
+ break;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ etdm_reg->con0 = ETDM_OUT2_CON0;
+ etdm_reg->con1 = ETDM_OUT2_CON1;
+ etdm_reg->con2 = ETDM_OUT2_CON2;
+ etdm_reg->con3 = ETDM_OUT2_CON3;
+ etdm_reg->con4 = ETDM_OUT2_CON4;
+ etdm_reg->con5 = ETDM_OUT2_CON5;
+ break;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ case MT8188_AFE_IO_DPTX:
+ etdm_reg->con0 = ETDM_OUT3_CON0;
+ etdm_reg->con1 = ETDM_OUT3_CON1;
+ etdm_reg->con2 = ETDM_OUT3_CON2;
+ etdm_reg->con3 = ETDM_OUT3_CON3;
+ etdm_reg->con4 = ETDM_OUT3_CON4;
+ etdm_reg->con5 = ETDM_OUT3_CON5;
+ break;
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int get_etdm_dir(unsigned int dai_id)
+{
+ switch (dai_id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ case MT8188_AFE_IO_ETDM2_IN:
+ return ETDM_IN;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ case MT8188_AFE_IO_ETDM2_OUT:
+ case MT8188_AFE_IO_ETDM3_OUT:
+ return ETDM_OUT;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int get_etdm_wlen(unsigned int bitwidth)
+{
+ return bitwidth <= 16 ? 16 : 32;
+}
+
+static bool is_valid_etdm_dai(int dai_id)
+{
+ if (dai_id < MT8188_AFE_IO_ETDM_START || dai_id >= MT8188_AFE_IO_ETDM_END)
+ return false;
+ else
+ return true;
+}
+
+static int is_cowork_mode(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ return (etdm_data->cowork_slv_count > 0 ||
+ etdm_data->cowork_source_id != COWORK_ETDM_NONE);
+}
+
+static int sync_to_dai_id(int source_sel)
+{
+ switch (source_sel) {
+ case ETDM_SYNC_FROM_IN1:
+ return MT8188_AFE_IO_ETDM1_IN;
+ case ETDM_SYNC_FROM_IN2:
+ return MT8188_AFE_IO_ETDM2_IN;
+ case ETDM_SYNC_FROM_OUT1:
+ return MT8188_AFE_IO_ETDM1_OUT;
+ case ETDM_SYNC_FROM_OUT2:
+ return MT8188_AFE_IO_ETDM2_OUT;
+ case ETDM_SYNC_FROM_OUT3:
+ return MT8188_AFE_IO_ETDM3_OUT;
+ default:
+ return 0;
+ }
+}
+
+static int get_etdm_cowork_master_id(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ int dai_id;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+ dai_id = etdm_data->cowork_source_id;
+
+ if (dai_id == COWORK_ETDM_NONE)
+ dai_id = dai->id;
+
+ return dai_id;
+}
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o048_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN48, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN48, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN48_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN48_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o049_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN49, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN49, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN49_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN49_2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o050_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN50, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN50_1, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o051_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN51, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN51_1, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o052_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN52, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN52_1, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o053_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN53, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN53_1, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o054_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN54, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN54_1, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o055_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN55, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN55_1, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o056_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN56, 30, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN56_1, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o057_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN57, 31, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN57_1, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o058_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN58_1, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN58_1, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o059_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN59_1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN59_1, 25, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o060_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN60_1, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN60_1, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o061_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN61_1, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN61_1, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o062_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN62_1, 4, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN62_1, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o063_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN63_1, 5, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN63_1, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o072_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN72, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN72, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN72_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN72_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o073_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN73, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN73, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN73_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN73_2, 7, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o074_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN74, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN74_1, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o075_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN75, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN75_1, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o076_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN76, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN76_1, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o077_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN77, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN77_1, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o078_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN78, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN78_1, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o079_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN79, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN79_1, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o080_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN80, 30, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I054 Switch", AFE_CONN80_1, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o081_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN81, 31, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I055 Switch", AFE_CONN81_1, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o082_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN82_1, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I056 Switch", AFE_CONN82_1, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o083_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN83_1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I057 Switch", AFE_CONN83_1, 25, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o084_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN84_1, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I058 Switch", AFE_CONN84_1, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o085_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN85_1, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I059 Switch", AFE_CONN85_1, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o086_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN86_1, 4, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I060 Switch", AFE_CONN86_1, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_etdm_o087_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN87_1, 5, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I061 Switch", AFE_CONN87_1, 29, 1, 0),
+};
+
+static const char * const mt8188_etdm_clk_src_sel_text[] = {
+ "26m",
+ "a1sys_a2sys",
+ "a3sys",
+ "a4sys",
+};
+
+static SOC_ENUM_SINGLE_EXT_DECL(etdmout_clk_src_enum,
+ mt8188_etdm_clk_src_sel_text);
+
+static const char * const hdmitx_dptx_mux_map[] = {
+ "Disconnect", "Connect",
+};
+
+static int hdmitx_dptx_mux_map_value[] = {
+ 0, 1,
+};
+
+/* HDMI_OUT_MUX */
+static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(hdmi_out_mux_map_enum,
+ SND_SOC_NOPM,
+ 0,
+ 1,
+ hdmitx_dptx_mux_map,
+ hdmitx_dptx_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_out_mux_control =
+ SOC_DAPM_ENUM("HDMI_OUT_MUX", hdmi_out_mux_map_enum);
+
+/* DPTX_OUT_MUX */
+static SOC_VALUE_ENUM_SINGLE_AUTODISABLE_DECL(dptx_out_mux_map_enum,
+ SND_SOC_NOPM,
+ 0,
+ 1,
+ hdmitx_dptx_mux_map,
+ hdmitx_dptx_mux_map_value);
+
+static const struct snd_kcontrol_new dptx_out_mux_control =
+ SOC_DAPM_ENUM("DPTX_OUT_MUX", dptx_out_mux_map_enum);
+
+/* HDMI_CH0_MUX ~ HDMI_CH7_MUX */
+static const char *const afe_conn_hdmi_mux_map[] = {
+ "CH0", "CH1", "CH2", "CH3", "CH4", "CH5", "CH6", "CH7",
+};
+
+static int afe_conn_hdmi_mux_map_value[] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+};
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch0_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 0,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch0_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH0_MUX", hdmi_ch0_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch1_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 4,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch1_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH1_MUX", hdmi_ch1_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch2_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 8,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch2_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH2_MUX", hdmi_ch2_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch3_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 12,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch3_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH3_MUX", hdmi_ch3_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch4_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 16,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch4_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH4_MUX", hdmi_ch4_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch5_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 20,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch5_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH5_MUX", hdmi_ch5_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch6_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 24,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch6_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH6_MUX", hdmi_ch6_mux_map_enum);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(hdmi_ch7_mux_map_enum,
+ AFE_TDMOUT_CONN0,
+ 28,
+ 0xf,
+ afe_conn_hdmi_mux_map,
+ afe_conn_hdmi_mux_map_value);
+
+static const struct snd_kcontrol_new hdmi_ch7_mux_control =
+ SOC_DAPM_ENUM("HDMI_CH7_MUX", hdmi_ch7_mux_map_enum);
+
+static int mt8188_etdm_clk_src_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ unsigned int source = ucontrol->value.enumerated.item[0];
+ unsigned int val;
+ unsigned int old_val;
+ unsigned int mask;
+ unsigned int reg;
+ unsigned int shift;
+
+ if (source >= e->items)
+ return -EINVAL;
+
+ reg = 0;
+ if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
+ reg = ETDM_OUT1_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ val = ETDM_OUT_CON4_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
+ reg = ETDM_OUT2_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ val = ETDM_OUT_CON4_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
+ reg = ETDM_OUT3_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ val = ETDM_OUT_CON4_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
+ reg = ETDM_IN1_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ shift = ETDM_IN_CON2_CLOCK_SHIFT;
+ val = ETDM_IN_CON2_CLOCK(source);
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
+ reg = ETDM_IN2_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ shift = ETDM_IN_CON2_CLOCK_SHIFT;
+ val = ETDM_IN_CON2_CLOCK(source);
+ }
+
+ if (reg) {
+ regmap_read(afe->regmap, reg, &old_val);
+ old_val &= mask;
+ old_val >>= shift;
+
+ if (old_val == val)
+ return 0;
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+ }
+
+ return 1;
+}
+
+static int mt8188_etdm_clk_src_sel_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ unsigned int value = 0;
+ unsigned int reg = 0;
+ unsigned int mask = 0;
+ unsigned int shift = 0;
+
+ if (!strcmp(kcontrol->id.name, "ETDM_OUT1_Clock_Source")) {
+ reg = ETDM_OUT1_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT2_Clock_Source")) {
+ reg = ETDM_OUT2_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_OUT3_Clock_Source")) {
+ reg = ETDM_OUT3_CON4;
+ mask = ETDM_OUT_CON4_CLOCK_MASK;
+ shift = ETDM_OUT_CON4_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN1_Clock_Source")) {
+ reg = ETDM_IN1_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ shift = ETDM_IN_CON2_CLOCK_SHIFT;
+ } else if (!strcmp(kcontrol->id.name, "ETDM_IN2_Clock_Source")) {
+ reg = ETDM_IN2_CON2;
+ mask = ETDM_IN_CON2_CLOCK_MASK;
+ shift = ETDM_IN_CON2_CLOCK_SHIFT;
+ }
+
+ if (reg)
+ regmap_read(afe->regmap, reg, &value);
+
+ value &= mask;
+ value >>= shift;
+ ucontrol->value.enumerated.item[0] = value;
+ return 0;
+}
+
+static const struct snd_kcontrol_new mtk_dai_etdm_controls[] = {
+ SOC_ENUM_EXT("ETDM_OUT1_Clock_Source", etdmout_clk_src_enum,
+ mt8188_etdm_clk_src_sel_get,
+ mt8188_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_OUT2_Clock_Source", etdmout_clk_src_enum,
+ mt8188_etdm_clk_src_sel_get,
+ mt8188_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_OUT3_Clock_Source", etdmout_clk_src_enum,
+ mt8188_etdm_clk_src_sel_get,
+ mt8188_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_IN1_Clock_Source", etdmout_clk_src_enum,
+ mt8188_etdm_clk_src_sel_get,
+ mt8188_etdm_clk_src_sel_put),
+ SOC_ENUM_EXT("ETDM_IN2_Clock_Source", etdmout_clk_src_enum,
+ mt8188_etdm_clk_src_sel_get,
+ mt8188_etdm_clk_src_sel_put),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = {
+ /* eTDM_IN2 */
+ SND_SOC_DAPM_MIXER("I012", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I013", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I014", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I015", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I016", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I017", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I018", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I019", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I188", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I189", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I190", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I191", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I192", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I193", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I194", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I195", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* eTDM_IN1 */
+ SND_SOC_DAPM_MIXER("I072", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I073", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I074", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I075", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I076", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I077", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I078", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I079", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I080", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I081", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I082", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I083", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I084", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I085", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I086", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I087", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* eTDM_OUT2 */
+ SND_SOC_DAPM_MIXER("O048", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o048_mix, ARRAY_SIZE(mtk_dai_etdm_o048_mix)),
+ SND_SOC_DAPM_MIXER("O049", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o049_mix, ARRAY_SIZE(mtk_dai_etdm_o049_mix)),
+ SND_SOC_DAPM_MIXER("O050", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o050_mix, ARRAY_SIZE(mtk_dai_etdm_o050_mix)),
+ SND_SOC_DAPM_MIXER("O051", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o051_mix, ARRAY_SIZE(mtk_dai_etdm_o051_mix)),
+ SND_SOC_DAPM_MIXER("O052", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o052_mix, ARRAY_SIZE(mtk_dai_etdm_o052_mix)),
+ SND_SOC_DAPM_MIXER("O053", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o053_mix, ARRAY_SIZE(mtk_dai_etdm_o053_mix)),
+ SND_SOC_DAPM_MIXER("O054", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o054_mix, ARRAY_SIZE(mtk_dai_etdm_o054_mix)),
+ SND_SOC_DAPM_MIXER("O055", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o055_mix, ARRAY_SIZE(mtk_dai_etdm_o055_mix)),
+ SND_SOC_DAPM_MIXER("O056", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o056_mix, ARRAY_SIZE(mtk_dai_etdm_o056_mix)),
+ SND_SOC_DAPM_MIXER("O057", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o057_mix, ARRAY_SIZE(mtk_dai_etdm_o057_mix)),
+ SND_SOC_DAPM_MIXER("O058", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o058_mix, ARRAY_SIZE(mtk_dai_etdm_o058_mix)),
+ SND_SOC_DAPM_MIXER("O059", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o059_mix, ARRAY_SIZE(mtk_dai_etdm_o059_mix)),
+ SND_SOC_DAPM_MIXER("O060", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o060_mix, ARRAY_SIZE(mtk_dai_etdm_o060_mix)),
+ SND_SOC_DAPM_MIXER("O061", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o061_mix, ARRAY_SIZE(mtk_dai_etdm_o061_mix)),
+ SND_SOC_DAPM_MIXER("O062", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o062_mix, ARRAY_SIZE(mtk_dai_etdm_o062_mix)),
+ SND_SOC_DAPM_MIXER("O063", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o063_mix, ARRAY_SIZE(mtk_dai_etdm_o063_mix)),
+
+ /* eTDM_OUT1 */
+ SND_SOC_DAPM_MIXER("O072", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o072_mix, ARRAY_SIZE(mtk_dai_etdm_o072_mix)),
+ SND_SOC_DAPM_MIXER("O073", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o073_mix, ARRAY_SIZE(mtk_dai_etdm_o073_mix)),
+ SND_SOC_DAPM_MIXER("O074", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o074_mix, ARRAY_SIZE(mtk_dai_etdm_o074_mix)),
+ SND_SOC_DAPM_MIXER("O075", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o075_mix, ARRAY_SIZE(mtk_dai_etdm_o075_mix)),
+ SND_SOC_DAPM_MIXER("O076", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o076_mix, ARRAY_SIZE(mtk_dai_etdm_o076_mix)),
+ SND_SOC_DAPM_MIXER("O077", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o077_mix, ARRAY_SIZE(mtk_dai_etdm_o077_mix)),
+ SND_SOC_DAPM_MIXER("O078", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o078_mix, ARRAY_SIZE(mtk_dai_etdm_o078_mix)),
+ SND_SOC_DAPM_MIXER("O079", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o079_mix, ARRAY_SIZE(mtk_dai_etdm_o079_mix)),
+ SND_SOC_DAPM_MIXER("O080", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o080_mix, ARRAY_SIZE(mtk_dai_etdm_o080_mix)),
+ SND_SOC_DAPM_MIXER("O081", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o081_mix, ARRAY_SIZE(mtk_dai_etdm_o081_mix)),
+ SND_SOC_DAPM_MIXER("O082", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o082_mix, ARRAY_SIZE(mtk_dai_etdm_o082_mix)),
+ SND_SOC_DAPM_MIXER("O083", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o083_mix, ARRAY_SIZE(mtk_dai_etdm_o083_mix)),
+ SND_SOC_DAPM_MIXER("O084", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o084_mix, ARRAY_SIZE(mtk_dai_etdm_o084_mix)),
+ SND_SOC_DAPM_MIXER("O085", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o085_mix, ARRAY_SIZE(mtk_dai_etdm_o085_mix)),
+ SND_SOC_DAPM_MIXER("O086", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o086_mix, ARRAY_SIZE(mtk_dai_etdm_o086_mix)),
+ SND_SOC_DAPM_MIXER("O087", SND_SOC_NOPM, 0, 0,
+ mtk_dai_etdm_o087_mix, ARRAY_SIZE(mtk_dai_etdm_o087_mix)),
+
+ /* eTDM_OUT3 */
+ SND_SOC_DAPM_MUX("HDMI_OUT_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_out_mux_control),
+ SND_SOC_DAPM_MUX("DPTX_OUT_MUX", SND_SOC_NOPM, 0, 0,
+ &dptx_out_mux_control),
+
+ SND_SOC_DAPM_MUX("HDMI_CH0_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch0_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH1_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch1_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH2_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch2_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH3_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch3_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH4_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch4_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH5_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch5_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH6_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch6_mux_control),
+ SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0,
+ &hdmi_ch7_mux_control),
+
+ SND_SOC_DAPM_INPUT("ETDM_INPUT"),
+ SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = {
+ {"I012", NULL, "ETDM2 Capture"},
+ {"I013", NULL, "ETDM2 Capture"},
+ {"I014", NULL, "ETDM2 Capture"},
+ {"I015", NULL, "ETDM2 Capture"},
+ {"I016", NULL, "ETDM2 Capture"},
+ {"I017", NULL, "ETDM2 Capture"},
+ {"I018", NULL, "ETDM2 Capture"},
+ {"I019", NULL, "ETDM2 Capture"},
+ {"I188", NULL, "ETDM2 Capture"},
+ {"I189", NULL, "ETDM2 Capture"},
+ {"I190", NULL, "ETDM2 Capture"},
+ {"I191", NULL, "ETDM2 Capture"},
+ {"I192", NULL, "ETDM2 Capture"},
+ {"I193", NULL, "ETDM2 Capture"},
+ {"I194", NULL, "ETDM2 Capture"},
+ {"I195", NULL, "ETDM2 Capture"},
+
+ {"I072", NULL, "ETDM1 Capture"},
+ {"I073", NULL, "ETDM1 Capture"},
+ {"I074", NULL, "ETDM1 Capture"},
+ {"I075", NULL, "ETDM1 Capture"},
+ {"I076", NULL, "ETDM1 Capture"},
+ {"I077", NULL, "ETDM1 Capture"},
+ {"I078", NULL, "ETDM1 Capture"},
+ {"I079", NULL, "ETDM1 Capture"},
+ {"I080", NULL, "ETDM1 Capture"},
+ {"I081", NULL, "ETDM1 Capture"},
+ {"I082", NULL, "ETDM1 Capture"},
+ {"I083", NULL, "ETDM1 Capture"},
+ {"I084", NULL, "ETDM1 Capture"},
+ {"I085", NULL, "ETDM1 Capture"},
+ {"I086", NULL, "ETDM1 Capture"},
+ {"I087", NULL, "ETDM1 Capture"},
+
+ {"UL8", NULL, "ETDM1 Capture"},
+ {"UL3", NULL, "ETDM2 Capture"},
+
+ {"ETDM2 Playback", NULL, "O048"},
+ {"ETDM2 Playback", NULL, "O049"},
+ {"ETDM2 Playback", NULL, "O050"},
+ {"ETDM2 Playback", NULL, "O051"},
+ {"ETDM2 Playback", NULL, "O052"},
+ {"ETDM2 Playback", NULL, "O053"},
+ {"ETDM2 Playback", NULL, "O054"},
+ {"ETDM2 Playback", NULL, "O055"},
+ {"ETDM2 Playback", NULL, "O056"},
+ {"ETDM2 Playback", NULL, "O057"},
+ {"ETDM2 Playback", NULL, "O058"},
+ {"ETDM2 Playback", NULL, "O059"},
+ {"ETDM2 Playback", NULL, "O060"},
+ {"ETDM2 Playback", NULL, "O061"},
+ {"ETDM2 Playback", NULL, "O062"},
+ {"ETDM2 Playback", NULL, "O063"},
+
+ {"ETDM1 Playback", NULL, "O072"},
+ {"ETDM1 Playback", NULL, "O073"},
+ {"ETDM1 Playback", NULL, "O074"},
+ {"ETDM1 Playback", NULL, "O075"},
+ {"ETDM1 Playback", NULL, "O076"},
+ {"ETDM1 Playback", NULL, "O077"},
+ {"ETDM1 Playback", NULL, "O078"},
+ {"ETDM1 Playback", NULL, "O079"},
+ {"ETDM1 Playback", NULL, "O080"},
+ {"ETDM1 Playback", NULL, "O081"},
+ {"ETDM1 Playback", NULL, "O082"},
+ {"ETDM1 Playback", NULL, "O083"},
+ {"ETDM1 Playback", NULL, "O084"},
+ {"ETDM1 Playback", NULL, "O085"},
+ {"ETDM1 Playback", NULL, "O086"},
+ {"ETDM1 Playback", NULL, "O087"},
+
+ {"O048", "I020 Switch", "I020"},
+ {"O049", "I021 Switch", "I021"},
+
+ {"O048", "I022 Switch", "I022"},
+ {"O049", "I023 Switch", "I023"},
+ {"O050", "I024 Switch", "I024"},
+ {"O051", "I025 Switch", "I025"},
+ {"O052", "I026 Switch", "I026"},
+ {"O053", "I027 Switch", "I027"},
+ {"O054", "I028 Switch", "I028"},
+ {"O055", "I029 Switch", "I029"},
+ {"O056", "I030 Switch", "I030"},
+ {"O057", "I031 Switch", "I031"},
+ {"O058", "I032 Switch", "I032"},
+ {"O059", "I033 Switch", "I033"},
+ {"O060", "I034 Switch", "I034"},
+ {"O061", "I035 Switch", "I035"},
+ {"O062", "I036 Switch", "I036"},
+ {"O063", "I037 Switch", "I037"},
+
+ {"O048", "I046 Switch", "I046"},
+ {"O049", "I047 Switch", "I047"},
+ {"O050", "I048 Switch", "I048"},
+ {"O051", "I049 Switch", "I049"},
+ {"O052", "I050 Switch", "I050"},
+ {"O053", "I051 Switch", "I051"},
+ {"O054", "I052 Switch", "I052"},
+ {"O055", "I053 Switch", "I053"},
+ {"O056", "I054 Switch", "I054"},
+ {"O057", "I055 Switch", "I055"},
+ {"O058", "I056 Switch", "I056"},
+ {"O059", "I057 Switch", "I057"},
+ {"O060", "I058 Switch", "I058"},
+ {"O061", "I059 Switch", "I059"},
+ {"O062", "I060 Switch", "I060"},
+ {"O063", "I061 Switch", "I061"},
+
+ {"O048", "I070 Switch", "I070"},
+ {"O049", "I071 Switch", "I071"},
+
+ {"O072", "I020 Switch", "I020"},
+ {"O073", "I021 Switch", "I021"},
+
+ {"O072", "I022 Switch", "I022"},
+ {"O073", "I023 Switch", "I023"},
+ {"O074", "I024 Switch", "I024"},
+ {"O075", "I025 Switch", "I025"},
+ {"O076", "I026 Switch", "I026"},
+ {"O077", "I027 Switch", "I027"},
+ {"O078", "I028 Switch", "I028"},
+ {"O079", "I029 Switch", "I029"},
+ {"O080", "I030 Switch", "I030"},
+ {"O081", "I031 Switch", "I031"},
+ {"O082", "I032 Switch", "I032"},
+ {"O083", "I033 Switch", "I033"},
+ {"O084", "I034 Switch", "I034"},
+ {"O085", "I035 Switch", "I035"},
+ {"O086", "I036 Switch", "I036"},
+ {"O087", "I037 Switch", "I037"},
+
+ {"O072", "I046 Switch", "I046"},
+ {"O073", "I047 Switch", "I047"},
+ {"O074", "I048 Switch", "I048"},
+ {"O075", "I049 Switch", "I049"},
+ {"O076", "I050 Switch", "I050"},
+ {"O077", "I051 Switch", "I051"},
+ {"O078", "I052 Switch", "I052"},
+ {"O079", "I053 Switch", "I053"},
+ {"O080", "I054 Switch", "I054"},
+ {"O081", "I055 Switch", "I055"},
+ {"O082", "I056 Switch", "I056"},
+ {"O083", "I057 Switch", "I057"},
+ {"O084", "I058 Switch", "I058"},
+ {"O085", "I059 Switch", "I059"},
+ {"O086", "I060 Switch", "I060"},
+ {"O087", "I061 Switch", "I061"},
+
+ {"O072", "I070 Switch", "I070"},
+ {"O073", "I071 Switch", "I071"},
+
+ {"HDMI_CH0_MUX", "CH0", "DL10"},
+ {"HDMI_CH0_MUX", "CH1", "DL10"},
+ {"HDMI_CH0_MUX", "CH2", "DL10"},
+ {"HDMI_CH0_MUX", "CH3", "DL10"},
+ {"HDMI_CH0_MUX", "CH4", "DL10"},
+ {"HDMI_CH0_MUX", "CH5", "DL10"},
+ {"HDMI_CH0_MUX", "CH6", "DL10"},
+ {"HDMI_CH0_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH1_MUX", "CH0", "DL10"},
+ {"HDMI_CH1_MUX", "CH1", "DL10"},
+ {"HDMI_CH1_MUX", "CH2", "DL10"},
+ {"HDMI_CH1_MUX", "CH3", "DL10"},
+ {"HDMI_CH1_MUX", "CH4", "DL10"},
+ {"HDMI_CH1_MUX", "CH5", "DL10"},
+ {"HDMI_CH1_MUX", "CH6", "DL10"},
+ {"HDMI_CH1_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH2_MUX", "CH0", "DL10"},
+ {"HDMI_CH2_MUX", "CH1", "DL10"},
+ {"HDMI_CH2_MUX", "CH2", "DL10"},
+ {"HDMI_CH2_MUX", "CH3", "DL10"},
+ {"HDMI_CH2_MUX", "CH4", "DL10"},
+ {"HDMI_CH2_MUX", "CH5", "DL10"},
+ {"HDMI_CH2_MUX", "CH6", "DL10"},
+ {"HDMI_CH2_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH3_MUX", "CH0", "DL10"},
+ {"HDMI_CH3_MUX", "CH1", "DL10"},
+ {"HDMI_CH3_MUX", "CH2", "DL10"},
+ {"HDMI_CH3_MUX", "CH3", "DL10"},
+ {"HDMI_CH3_MUX", "CH4", "DL10"},
+ {"HDMI_CH3_MUX", "CH5", "DL10"},
+ {"HDMI_CH3_MUX", "CH6", "DL10"},
+ {"HDMI_CH3_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH4_MUX", "CH0", "DL10"},
+ {"HDMI_CH4_MUX", "CH1", "DL10"},
+ {"HDMI_CH4_MUX", "CH2", "DL10"},
+ {"HDMI_CH4_MUX", "CH3", "DL10"},
+ {"HDMI_CH4_MUX", "CH4", "DL10"},
+ {"HDMI_CH4_MUX", "CH5", "DL10"},
+ {"HDMI_CH4_MUX", "CH6", "DL10"},
+ {"HDMI_CH4_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH5_MUX", "CH0", "DL10"},
+ {"HDMI_CH5_MUX", "CH1", "DL10"},
+ {"HDMI_CH5_MUX", "CH2", "DL10"},
+ {"HDMI_CH5_MUX", "CH3", "DL10"},
+ {"HDMI_CH5_MUX", "CH4", "DL10"},
+ {"HDMI_CH5_MUX", "CH5", "DL10"},
+ {"HDMI_CH5_MUX", "CH6", "DL10"},
+ {"HDMI_CH5_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH6_MUX", "CH0", "DL10"},
+ {"HDMI_CH6_MUX", "CH1", "DL10"},
+ {"HDMI_CH6_MUX", "CH2", "DL10"},
+ {"HDMI_CH6_MUX", "CH3", "DL10"},
+ {"HDMI_CH6_MUX", "CH4", "DL10"},
+ {"HDMI_CH6_MUX", "CH5", "DL10"},
+ {"HDMI_CH6_MUX", "CH6", "DL10"},
+ {"HDMI_CH6_MUX", "CH7", "DL10"},
+
+ {"HDMI_CH7_MUX", "CH0", "DL10"},
+ {"HDMI_CH7_MUX", "CH1", "DL10"},
+ {"HDMI_CH7_MUX", "CH2", "DL10"},
+ {"HDMI_CH7_MUX", "CH3", "DL10"},
+ {"HDMI_CH7_MUX", "CH4", "DL10"},
+ {"HDMI_CH7_MUX", "CH5", "DL10"},
+ {"HDMI_CH7_MUX", "CH6", "DL10"},
+ {"HDMI_CH7_MUX", "CH7", "DL10"},
+
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH0_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH1_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH2_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH3_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH4_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH5_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH6_MUX"},
+ {"HDMI_OUT_MUX", "Connect", "HDMI_CH7_MUX"},
+
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH0_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH1_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH2_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH3_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH4_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH5_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH6_MUX"},
+ {"DPTX_OUT_MUX", "Connect", "HDMI_CH7_MUX"},
+
+ {"ETDM3 Playback", NULL, "HDMI_OUT_MUX"},
+ {"DPTX Playback", NULL, "DPTX_OUT_MUX"},
+
+ {"ETDM_OUTPUT", NULL, "DPTX Playback"},
+ {"ETDM_OUTPUT", NULL, "ETDM1 Playback"},
+ {"ETDM_OUTPUT", NULL, "ETDM2 Playback"},
+ {"ETDM_OUTPUT", NULL, "ETDM3 Playback"},
+ {"ETDM1 Capture", NULL, "ETDM_INPUT"},
+ {"ETDM2 Capture", NULL, "ETDM_INPUT"},
+};
+
+static int mt8188_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id)
+{
+ int ret = 0;
+ struct etdm_con_reg etdm_reg;
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ unsigned long flags;
+
+ if (!is_valid_etdm_dai(dai_id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
+ spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
+ etdm_data->en_ref_cnt++;
+ if (etdm_data->en_ref_cnt == 1) {
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ goto out;
+
+ regmap_update_bits(afe->regmap, etdm_reg.con0,
+ ETDM_CON0_EN, ETDM_CON0_EN);
+ }
+
+out:
+ spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
+ return ret;
+}
+
+static int mt8188_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id)
+{
+ int ret = 0;
+ struct etdm_con_reg etdm_reg;
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ unsigned long flags;
+
+ if (!is_valid_etdm_dai(dai_id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt);
+ spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags);
+ if (etdm_data->en_ref_cnt > 0) {
+ etdm_data->en_ref_cnt--;
+ if (etdm_data->en_ref_cnt == 0) {
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ goto out;
+ regmap_update_bits(afe->regmap, etdm_reg.con0,
+ ETDM_CON0_EN, 0);
+ }
+ }
+
+out:
+ spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags);
+ return ret;
+}
+
+static int etdm_cowork_slv_sel(int id, int slave_mode)
+{
+ if (slave_mode) {
+ switch (id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ return COWORK_ETDM_IN1_S;
+ case MT8188_AFE_IO_ETDM2_IN:
+ return COWORK_ETDM_IN2_S;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ return COWORK_ETDM_OUT1_S;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ return COWORK_ETDM_OUT2_S;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ return COWORK_ETDM_OUT3_S;
+ default:
+ return -EINVAL;
+ }
+ } else {
+ switch (id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ return COWORK_ETDM_IN1_M;
+ case MT8188_AFE_IO_ETDM2_IN:
+ return COWORK_ETDM_IN2_M;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ return COWORK_ETDM_OUT1_M;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ return COWORK_ETDM_OUT2_M;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ return COWORK_ETDM_OUT3_M;
+ default:
+ return -EINVAL;
+ }
+ }
+}
+
+static int etdm_cowork_sync_sel(int id)
+{
+ switch (id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ return ETDM_SYNC_FROM_IN1;
+ case MT8188_AFE_IO_ETDM2_IN:
+ return ETDM_SYNC_FROM_IN2;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ return ETDM_SYNC_FROM_OUT1;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ return ETDM_SYNC_FROM_OUT2;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ return ETDM_SYNC_FROM_OUT3;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int mt8188_etdm_sync_mode_slv(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ unsigned int reg = 0;
+ unsigned int mask;
+ unsigned int val;
+ int cowork_source_sel;
+
+ if (!is_valid_etdm_dai(dai_id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ cowork_source_sel = etdm_cowork_slv_sel(etdm_data->cowork_source_id,
+ true);
+ if (cowork_source_sel < 0)
+ return cowork_source_sel;
+
+ switch (dai_id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ reg = ETDM_COWORK_CON1;
+ mask = ETDM_IN1_SLAVE_SEL_MASK;
+ val = ETDM_IN1_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_IN2_SLAVE_SEL_MASK;
+ val = ETDM_IN2_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ reg = ETDM_COWORK_CON0;
+ mask = ETDM_OUT1_SLAVE_SEL_MASK;
+ val = ETDM_OUT1_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_OUT2_SLAVE_SEL_MASK;
+ val = ETDM_OUT2_SLAVE_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_OUT3_SLAVE_SEL_MASK;
+ val = ETDM_OUT3_SLAVE_SEL(cowork_source_sel);
+ break;
+ default:
+ return 0;
+ }
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+
+ return 0;
+}
+
+static int mt8188_etdm_sync_mode_mst(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ struct etdm_con_reg etdm_reg;
+ unsigned int reg = 0;
+ unsigned int mask;
+ unsigned int val;
+ int cowork_source_sel;
+ int ret;
+
+ if (!is_valid_etdm_dai(dai_id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ cowork_source_sel = etdm_cowork_sync_sel(etdm_data->cowork_source_id);
+ if (cowork_source_sel < 0)
+ return cowork_source_sel;
+
+ switch (dai_id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ reg = ETDM_COWORK_CON1;
+ mask = ETDM_IN1_SYNC_SEL_MASK;
+ val = ETDM_IN1_SYNC_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_IN2_SYNC_SEL_MASK;
+ val = ETDM_IN2_SYNC_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ reg = ETDM_COWORK_CON0;
+ mask = ETDM_OUT1_SYNC_SEL_MASK;
+ val = ETDM_OUT1_SYNC_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_OUT2_SYNC_SEL_MASK;
+ val = ETDM_OUT2_SYNC_SEL(cowork_source_sel);
+ break;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ reg = ETDM_COWORK_CON2;
+ mask = ETDM_OUT3_SYNC_SEL_MASK;
+ val = ETDM_OUT3_SYNC_SEL(cowork_source_sel);
+ break;
+ default:
+ return 0;
+ }
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+
+ regmap_update_bits(afe->regmap, etdm_reg.con0,
+ ETDM_CON0_SYNC_MODE, ETDM_CON0_SYNC_MODE);
+
+ return 0;
+}
+
+static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+
+ if (!is_valid_etdm_dai(dai_id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ if (etdm_data->cowork_source_id == COWORK_ETDM_NONE)
+ return 0;
+
+ if (etdm_data->slave_mode)
+ mt8188_etdm_sync_mode_slv(afe, dai_id);
+ else
+ mt8188_etdm_sync_mode_mst(afe, dai_id);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_get_cg_id_by_dai_id(int dai_id)
+{
+ int cg_id = -1;
+
+ switch (dai_id) {
+ case MT8188_AFE_IO_DPTX:
+ cg_id = MT8188_CLK_AUD_HDMI_OUT;
+ break;
+ case MT8188_AFE_IO_ETDM1_IN:
+ cg_id = MT8188_CLK_AUD_TDM_IN;
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ cg_id = MT8188_CLK_AUD_I2SIN;
+ break;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ cg_id = MT8188_CLK_AUD_TDM_OUT;
+ break;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ cg_id = MT8188_CLK_AUD_I2S_OUT;
+ break;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ cg_id = MT8188_CLK_AUD_HDMI_OUT;
+ break;
+ default:
+ break;
+ }
+
+ return cg_id;
+}
+
+static int mtk_dai_etdm_get_clk_id_by_dai_id(int dai_id)
+{
+ int clk_id = -1;
+
+ switch (dai_id) {
+ case MT8188_AFE_IO_DPTX:
+ clk_id = MT8188_CLK_TOP_DPTX_M_SEL;
+ break;
+ case MT8188_AFE_IO_ETDM1_IN:
+ clk_id = MT8188_CLK_TOP_I2SI1_M_SEL;
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ clk_id = MT8188_CLK_TOP_I2SI2_M_SEL;
+ break;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ clk_id = MT8188_CLK_TOP_I2SO1_M_SEL;
+ break;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ clk_id = MT8188_CLK_TOP_I2SO2_M_SEL;
+ break;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ default:
+ break;
+ }
+
+ return clk_id;
+}
+
+static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id)
+{
+ int clk_id = -1;
+
+ switch (dai_id) {
+ case MT8188_AFE_IO_DPTX:
+ clk_id = MT8188_CLK_TOP_APLL12_DIV9;
+ break;
+ case MT8188_AFE_IO_ETDM1_IN:
+ clk_id = MT8188_CLK_TOP_APLL12_DIV0;
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ clk_id = MT8188_CLK_TOP_APLL12_DIV1;
+ break;
+ case MT8188_AFE_IO_ETDM1_OUT:
+ clk_id = MT8188_CLK_TOP_APLL12_DIV2;
+ break;
+ case MT8188_AFE_IO_ETDM2_OUT:
+ clk_id = MT8188_CLK_TOP_APLL12_DIV3;
+ break;
+ case MT8188_AFE_IO_ETDM3_OUT:
+ default:
+ break;
+ }
+
+ return clk_id;
+}
+
+static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+
+ if (clkdiv_id < 0)
+ return -EINVAL;
+
+ mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+
+ if (clkdiv_id < 0)
+ return -EINVAL;
+
+ mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]);
+
+ return 0;
+}
+
+/* dai ops */
+static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int cg_id;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ if (!is_valid_etdm_dai(mst_dai_id))
+ return -EINVAL;
+ mtk_dai_etdm_enable_mclk(afe, mst_dai_id);
+
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
+ if (cg_id >= 0)
+ mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
+ if (cg_id >= 0)
+ mt8188_afe_enable_clk(afe,
+ afe_priv->clk[cg_id]);
+ }
+ } else {
+ mtk_dai_etdm_enable_mclk(afe, dai->id);
+
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+ if (cg_id >= 0)
+ mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+ }
+
+ return 0;
+}
+
+static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data = afe_priv->dai_priv[dai->id];
+ int cg_id;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+ int ret = 0;
+
+ dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
+ mst_etdm_data->is_prepared);
+
+ if (mst_etdm_data->is_prepared) {
+ mst_etdm_data->is_prepared = false;
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ if (!is_valid_etdm_dai(mst_dai_id))
+ return;
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+
+ ret |= mt8188_afe_disable_etdm(afe, mst_dai_id);
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ ret |= mt8188_afe_disable_etdm(afe, slv_dai_id);
+ }
+ } else {
+ ret = mt8188_afe_disable_etdm(afe, dai->id);
+ }
+
+ if (ret)
+ dev_dbg(afe->dev, "%s disable failed\n", __func__);
+ }
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ if (!is_valid_etdm_dai(mst_dai_id))
+ return;
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id);
+ if (cg_id >= 0)
+ mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id);
+ if (cg_id >= 0)
+ mt8188_afe_disable_clk(afe,
+ afe_priv->clk[cg_id]);
+ }
+ mtk_dai_etdm_disable_mclk(afe, mst_dai_id);
+ } else {
+ cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+ if (cg_id >= 0)
+ mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+
+ mtk_dai_etdm_disable_mclk(afe, dai->id);
+ }
+}
+
+static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe,
+ int dai_id, unsigned int rate)
+{
+ unsigned int mode = 0;
+ unsigned int reg = 0;
+ unsigned int val = 0;
+ unsigned int mask = (ETDM_IN_AFIFO_MODE_MASK | ETDM_IN_USE_AFIFO);
+
+ if (rate != 0)
+ mode = mt8188_afe_fs_timing(rate);
+
+ switch (dai_id) {
+ case MT8188_AFE_IO_ETDM1_IN:
+ reg = ETDM_IN1_AFIFO_CON;
+ if (rate == 0)
+ mode = MT8188_ETDM_IN1_1X_EN;
+ break;
+ case MT8188_AFE_IO_ETDM2_IN:
+ reg = ETDM_IN2_AFIFO_CON;
+ if (rate == 0)
+ mode = MT8188_ETDM_IN2_1X_EN;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ val = (mode | ETDM_IN_USE_AFIFO);
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+ return 0;
+}
+
+static int mtk_dai_etdm_in_configure(struct mtk_base_afe *afe,
+ unsigned int rate,
+ unsigned int channels,
+ int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ struct etdm_con_reg etdm_reg;
+ bool slave_mode = etdm_data->slave_mode;
+ unsigned int data_mode = etdm_data->data_mode;
+ unsigned int lrck_width = etdm_data->lrck_width;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int i;
+ int ret;
+
+ dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n",
+ __func__, rate, channels, dai_id);
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE)
+ slave_mode = true;
+
+ /* afifo */
+ if (slave_mode)
+ mtk_dai_etdm_fifo_mode(afe, dai_id, 0);
+ else
+ mtk_dai_etdm_fifo_mode(afe, dai_id, rate);
+
+ /* con1 */
+ if (lrck_width > 0) {
+ mask |= (ETDM_IN_CON1_LRCK_AUTO_MODE |
+ ETDM_IN_CON1_LRCK_WIDTH_MASK);
+ val |= ETDM_IN_CON1_LRCK_WIDTH(lrck_width);
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con2 */
+ if (!slave_mode) {
+ mask |= ETDM_IN_CON2_UPDATE_GAP_MASK;
+ if (rate == 352800 || rate == 384000)
+ val |= ETDM_IN_CON2_UPDATE_GAP(4);
+ else
+ val |= ETDM_IN_CON2_UPDATE_GAP(3);
+ }
+ mask |= (ETDM_IN_CON2_MULTI_IP_2CH_MODE |
+ ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK);
+ if (data_mode == MTK_DAI_ETDM_DATA_MULTI_PIN) {
+ val |= ETDM_IN_CON2_MULTI_IP_2CH_MODE |
+ ETDM_IN_CON2_MULTI_IP_TOTAL_CH(channels);
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con2, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con3 */
+ mask |= ETDM_IN_CON3_DISABLE_OUT_MASK;
+ for (i = 0; i < channels; i += 2) {
+ if (etdm_data->in_disable_ch[i] &&
+ etdm_data->in_disable_ch[i + 1])
+ val |= ETDM_IN_CON3_DISABLE_OUT(i >> 1);
+ }
+ if (!slave_mode) {
+ mask |= ETDM_IN_CON3_FS_MASK;
+ val |= ETDM_IN_CON3_FS(get_etdm_fs_timing(rate));
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con3, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con4 */
+ mask |= (ETDM_IN_CON4_MASTER_LRCK_INV | ETDM_IN_CON4_MASTER_BCK_INV |
+ ETDM_IN_CON4_SLAVE_LRCK_INV | ETDM_IN_CON4_SLAVE_BCK_INV);
+ if (slave_mode) {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_IN_CON4_SLAVE_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_IN_CON4_SLAVE_BCK_INV;
+ } else {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_IN_CON4_MASTER_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_IN_CON4_MASTER_BCK_INV;
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con5 */
+ mask |= ETDM_IN_CON5_LR_SWAP_MASK;
+ mask |= ETDM_IN_CON5_ENABLE_ODD_MASK;
+ for (i = 0; i < channels; i += 2) {
+ if (etdm_data->in_disable_ch[i] &&
+ !etdm_data->in_disable_ch[i + 1]) {
+ val |= ETDM_IN_CON5_LR_SWAP(i >> 1);
+ val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1);
+ } else if (!etdm_data->in_disable_ch[i] &&
+ etdm_data->in_disable_ch[i + 1]) {
+ val |= ETDM_IN_CON5_ENABLE_ODD(i >> 1);
+ }
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val);
+ return 0;
+}
+
+static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe,
+ unsigned int rate,
+ unsigned int channels,
+ int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ struct etdm_con_reg etdm_reg;
+ bool slave_mode = etdm_data->slave_mode;
+ unsigned int lrck_width = etdm_data->lrck_width;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int ret;
+ int fs = 0;
+
+ dev_dbg(afe->dev, "%s rate %u channels %u, id %d\n",
+ __func__, rate, channels, dai_id);
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE)
+ slave_mode = true;
+
+ /* con0 */
+ mask = ETDM_OUT_CON0_RELATCH_DOMAIN_MASK;
+ val = ETDM_OUT_CON0_RELATCH_DOMAIN(ETDM_RELATCH_TIMING_A1A2SYS);
+ regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con1 */
+ if (lrck_width > 0) {
+ mask |= (ETDM_OUT_CON1_LRCK_AUTO_MODE |
+ ETDM_OUT_CON1_LRCK_WIDTH_MASK);
+ val |= ETDM_OUT_CON1_LRCK_WIDTH(lrck_width);
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ if (!slave_mode) {
+ /* con4 */
+ mask |= ETDM_OUT_CON4_FS_MASK;
+ val |= ETDM_OUT_CON4_FS(get_etdm_fs_timing(rate));
+ }
+
+ mask |= ETDM_OUT_CON4_RELATCH_EN_MASK;
+ if (dai_id == MT8188_AFE_IO_ETDM1_OUT)
+ fs = MT8188_ETDM_OUT1_1X_EN;
+ else if (dai_id == MT8188_AFE_IO_ETDM2_OUT)
+ fs = MT8188_ETDM_OUT2_1X_EN;
+
+ val |= ETDM_OUT_CON4_RELATCH_EN(fs);
+
+ regmap_update_bits(afe->regmap, etdm_reg.con4, mask, val);
+
+ mask = 0;
+ val = 0;
+
+ /* con5 */
+ mask |= (ETDM_OUT_CON5_MASTER_LRCK_INV | ETDM_OUT_CON5_MASTER_BCK_INV |
+ ETDM_OUT_CON5_SLAVE_LRCK_INV | ETDM_OUT_CON5_SLAVE_BCK_INV);
+ if (slave_mode) {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_OUT_CON5_SLAVE_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_OUT_CON5_SLAVE_BCK_INV;
+ } else {
+ if (etdm_data->lrck_inv)
+ val |= ETDM_OUT_CON5_MASTER_LRCK_INV;
+ if (etdm_data->bck_inv)
+ val |= ETDM_OUT_CON5_MASTER_BCK_INV;
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con5, mask, val);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id);
+ int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id);
+ int apll;
+ int apll_clk_id;
+ struct etdm_con_reg etdm_reg;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int ret = 0;
+
+ if (clk_id < 0 || clkdiv_id < 0)
+ return 0;
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ mask |= ETDM_CON1_MCLK_OUTPUT;
+ if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+ val |= ETDM_CON1_MCLK_OUTPUT;
+ regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val);
+
+ if (etdm_data->mclk_freq) {
+ apll = etdm_data->mclk_apll;
+ apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
+ if (apll_clk_id < 0)
+ return apll_clk_id;
+
+ /* select apll */
+ ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clk_id],
+ afe_priv->clk[apll_clk_id]);
+ if (ret)
+ return ret;
+
+ /* set rate */
+ ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id],
+ etdm_data->mclk_freq);
+ } else {
+ if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT)
+ dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__);
+ }
+
+ return ret;
+}
+
+static int mtk_dai_etdm_configure(struct mtk_base_afe *afe,
+ unsigned int rate,
+ unsigned int channels,
+ unsigned int bit_width,
+ int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id];
+ struct etdm_con_reg etdm_reg;
+ bool slave_mode = etdm_data->slave_mode;
+ unsigned int etdm_channels;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ unsigned int bck;
+ unsigned int wlen = get_etdm_wlen(bit_width);
+ int ret;
+
+ ret = get_etdm_reg(dai_id, &etdm_reg);
+ if (ret < 0)
+ return ret;
+
+ dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n",
+ __func__, etdm_data->format, etdm_data->data_mode,
+ etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv,
+ etdm_data->clock_mode, etdm_data->slave_mode);
+ dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n",
+ __func__, rate, channels, bit_width, dai_id);
+
+ etdm_channels = (etdm_data->data_mode == MTK_DAI_ETDM_DATA_ONE_PIN) ?
+ get_etdm_ch_fixup(channels) : 2;
+
+ bck = rate * etdm_channels * wlen;
+ if (bck > MT8188_ETDM_NORMAL_MAX_BCK_RATE) {
+ dev_info(afe->dev, "%s bck rate %u not support\n",
+ __func__, bck);
+ return -EINVAL;
+ }
+
+ /* con0 */
+ mask |= ETDM_CON0_BIT_LEN_MASK;
+ val |= ETDM_CON0_BIT_LEN(bit_width);
+ mask |= ETDM_CON0_WORD_LEN_MASK;
+ val |= ETDM_CON0_WORD_LEN(wlen);
+ mask |= ETDM_CON0_FORMAT_MASK;
+ val |= ETDM_CON0_FORMAT(etdm_data->format);
+ mask |= ETDM_CON0_CH_NUM_MASK;
+ val |= ETDM_CON0_CH_NUM(etdm_channels);
+
+ mask |= ETDM_CON0_SLAVE_MODE;
+ if (slave_mode) {
+ if (dai_id == MT8188_AFE_IO_ETDM1_OUT) {
+ dev_info(afe->dev, "%s id %d only support master mode\n",
+ __func__, dai_id);
+ return -EINVAL;
+ }
+ val |= ETDM_CON0_SLAVE_MODE;
+ }
+ regmap_update_bits(afe->regmap, etdm_reg.con0, mask, val);
+
+ if (get_etdm_dir(dai_id) == ETDM_IN)
+ mtk_dai_etdm_in_configure(afe, rate, channels, dai_id);
+ else
+ mtk_dai_etdm_out_configure(afe, rate, channels, dai_id);
+
+ return 0;
+}
+
+static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ int ret = 0;
+ unsigned int rate = params_rate(params);
+ unsigned int bit_width = params_width(params);
+ unsigned int channels = params_channels(params);
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+
+ dev_dbg(afe->dev, "%s '%s' period %u-%u\n",
+ __func__, snd_pcm_stream_str(substream),
+ params_period_size(params), params_periods(params));
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+
+ ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id);
+ if (ret)
+ return ret;
+
+ ret = mtk_dai_etdm_configure(afe, rate, channels,
+ bit_width, mst_dai_id);
+ if (ret)
+ return ret;
+
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ ret = mtk_dai_etdm_configure(afe, rate, channels,
+ bit_width, slv_dai_id);
+ if (ret)
+ return ret;
+
+ ret = mt8188_etdm_sync_mode_configure(afe, slv_dai_id);
+ if (ret)
+ return ret;
+ }
+ } else {
+ ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
+ if (ret)
+ return ret;
+
+ ret = mtk_dai_etdm_configure(afe, rate, channels,
+ bit_width, dai->id);
+ }
+
+ return ret;
+}
+
+static int mtk_dai_etdm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *mst_etdm_data;
+ int mst_dai_id;
+ int slv_dai_id;
+ int i;
+ int ret = 0;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ mst_etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
+ mst_etdm_data->is_prepared);
+
+ if (mst_etdm_data->is_prepared)
+ return 0;
+
+ mst_etdm_data->is_prepared = true;
+
+ if (is_cowork_mode(dai)) {
+ mst_dai_id = get_etdm_cowork_master_id(dai);
+ mst_etdm_data = afe_priv->dai_priv[mst_dai_id];
+
+ for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) {
+ slv_dai_id = mst_etdm_data->cowork_slv_id[i];
+ ret |= mt8188_afe_enable_etdm(afe, slv_dai_id);
+ }
+
+ ret |= mt8188_afe_enable_etdm(afe, mst_dai_id);
+ } else {
+ ret = mt8188_afe_enable_etdm(afe, dai->id);
+ }
+
+ return ret;
+}
+
+static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ int apll;
+ int apll_rate;
+
+ if (!is_valid_etdm_dai(dai_id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ if (freq == 0) {
+ etdm_data->mclk_freq = freq;
+ return 0;
+ }
+
+ if (etdm_data->mclk_fixed_apll == 0)
+ apll = mt8188_afe_get_default_mclk_source_by_rate(freq);
+ else
+ apll = etdm_data->mclk_apll;
+
+ apll_rate = mt8188_afe_get_mclk_source_rate(afe, apll);
+
+ if (freq > apll_rate) {
+ dev_info(afe->dev, "freq %d > apll rate %d\n", freq, apll_rate);
+ return -EINVAL;
+ }
+
+ if (apll_rate % freq != 0) {
+ dev_info(afe->dev, "APLL%d cannot generate freq Hz\n", apll);
+ return -EINVAL;
+ }
+
+ if (etdm_data->mclk_fixed_apll == 0)
+ etdm_data->mclk_apll = apll;
+ etdm_data->mclk_freq = freq;
+
+ return 0;
+}
+
+static int mtk_dai_etdm_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id, unsigned int freq, int dir)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ int dai_id;
+
+ dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n",
+ __func__, dai->id, freq, dir);
+ if (is_cowork_mode(dai))
+ dai_id = get_etdm_cowork_master_id(dai);
+ else
+ dai_id = dai->id;
+
+ etdm_data = afe_priv->dai_priv[dai_id];
+ etdm_data->mclk_dir = dir;
+ return mtk_dai_etdm_cal_mclk(afe, freq, dai_id);
+}
+
+static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int slot_width)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s id %d slot_width %d\n",
+ __func__, dai->id, slot_width);
+
+ etdm_data->slots = slots;
+ etdm_data->lrck_width = slot_width;
+ return 0;
+}
+
+static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_I2S;
+ break;
+ case SND_SOC_DAIFMT_LEFT_J:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_LJ;
+ break;
+ case SND_SOC_DAIFMT_RIGHT_J:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_RJ;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPA;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ etdm_data->format = MTK_DAI_ETDM_FORMAT_DSPB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ etdm_data->bck_inv = false;
+ etdm_data->lrck_inv = false;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ etdm_data->bck_inv = false;
+ etdm_data->lrck_inv = true;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ etdm_data->bck_inv = true;
+ etdm_data->lrck_inv = false;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ etdm_data->bck_inv = true;
+ etdm_data->lrck_inv = true;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_CBP_CFP:
+ etdm_data->slave_mode = true;
+ break;
+ case SND_SOC_DAIFMT_CBC_CFC:
+ etdm_data->slave_mode = false;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+
+ if (cg_id >= 0)
+ mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]);
+
+ mtk_dai_etdm_enable_mclk(afe, dai->id);
+
+ return 0;
+}
+
+static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id);
+ struct mtk_dai_etdm_priv *etdm_data;
+ int ret = 0;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ if (etdm_data->is_prepared) {
+ etdm_data->is_prepared = false;
+ /* disable etdm_out3 */
+ ret = mt8188_afe_disable_etdm(afe, dai->id);
+
+ if (ret)
+ dev_dbg(afe->dev, "%s disable failed\n", __func__);
+
+ /* disable dptx interface */
+ if (dai->id == MT8188_AFE_IO_DPTX)
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_ON_MASK, 0);
+ }
+
+ mtk_dai_etdm_disable_mclk(afe, dai->id);
+
+ if (cg_id >= 0)
+ mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]);
+}
+
+static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel)
+{
+ switch (channel) {
+ case 1 ... 2:
+ return AFE_DPTX_CON_CH_EN_2CH;
+ case 3 ... 4:
+ return AFE_DPTX_CON_CH_EN_4CH;
+ case 5 ... 6:
+ return AFE_DPTX_CON_CH_EN_6CH;
+ case 7 ... 8:
+ return AFE_DPTX_CON_CH_EN_8CH;
+ default:
+ return AFE_DPTX_CON_CH_EN_2CH;
+ }
+}
+
+static unsigned int mtk_dai_get_dptx_ch(unsigned int ch)
+{
+ return (ch > 2) ?
+ AFE_DPTX_CON_CH_NUM_8CH : AFE_DPTX_CON_CH_NUM_2CH;
+}
+
+static unsigned int mtk_dai_get_dptx_wlen(snd_pcm_format_t format)
+{
+ return snd_pcm_format_physical_width(format) <= 16 ?
+ AFE_DPTX_CON_16BIT : AFE_DPTX_CON_24BIT;
+}
+
+static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ unsigned int rate = params_rate(params);
+ unsigned int channels = params_channels(params);
+ snd_pcm_format_t format = params_format(params);
+ int width = snd_pcm_format_physical_width(format);
+ int ret = 0;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ /* dptx configure */
+ if (dai->id == MT8188_AFE_IO_DPTX) {
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_CH_EN_MASK,
+ mtk_dai_get_dptx_ch_en(channels));
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_CH_NUM_MASK,
+ mtk_dai_get_dptx_ch(channels));
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_16BIT_MASK,
+ mtk_dai_get_dptx_wlen(format));
+
+ if (mtk_dai_get_dptx_ch(channels) == AFE_DPTX_CON_CH_NUM_8CH) {
+ etdm_data->data_mode = MTK_DAI_ETDM_DATA_ONE_PIN;
+ channels = 8;
+ } else {
+ channels = 2;
+ }
+ } else {
+ etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN;
+ }
+
+ ret = mtk_dai_etdm_mclk_configure(afe, dai->id);
+ if (ret)
+ return ret;
+
+ ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id);
+
+ return ret;
+}
+
+static int mtk_dai_hdmitx_dptx_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ int ret = 0;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id,
+ etdm_data->is_prepared);
+
+ if (etdm_data->is_prepared)
+ return 0;
+
+ etdm_data->is_prepared = true;
+
+ /* enable dptx interface */
+ if (dai->id == MT8188_AFE_IO_DPTX)
+ regmap_update_bits(afe->regmap, AFE_DPTX_CON,
+ AFE_DPTX_CON_ON_MASK, AFE_DPTX_CON_ON);
+
+ /* enable etdm_out3 */
+ ret = mt8188_afe_enable_etdm(afe, dai->id);
+
+ return ret;
+}
+
+static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai,
+ int clk_id,
+ unsigned int freq,
+ int dir)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s id %d freq %u, dir %d\n",
+ __func__, dai->id, freq, dir);
+
+ etdm_data->mclk_dir = dir;
+ return mtk_dai_etdm_cal_mclk(afe, freq, dai->id);
+}
+
+static const struct snd_soc_dai_ops mtk_dai_etdm_ops = {
+ .startup = mtk_dai_etdm_startup,
+ .shutdown = mtk_dai_etdm_shutdown,
+ .hw_params = mtk_dai_etdm_hw_params,
+ .prepare = mtk_dai_etdm_prepare,
+ .set_sysclk = mtk_dai_etdm_set_sysclk,
+ .set_fmt = mtk_dai_etdm_set_fmt,
+ .set_tdm_slot = mtk_dai_etdm_set_tdm_slot,
+};
+
+static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = {
+ .startup = mtk_dai_hdmitx_dptx_startup,
+ .shutdown = mtk_dai_hdmitx_dptx_shutdown,
+ .hw_params = mtk_dai_hdmitx_dptx_hw_params,
+ .prepare = mtk_dai_hdmitx_dptx_prepare,
+ .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk,
+ .set_fmt = mtk_dai_etdm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_192000)
+
+#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static int mtk_dai_etdm_probe(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+
+ if (!is_valid_etdm_dai(dai->id))
+ return -EINVAL;
+ etdm_data = afe_priv->dai_priv[dai->id];
+
+ dev_dbg(dai->dev, "%s id %d\n", __func__, dai->id);
+
+ if (etdm_data->mclk_freq) {
+ dev_dbg(afe->dev, "MCLK always on, rate %d\n",
+ etdm_data->mclk_freq);
+ pm_runtime_get_sync(afe->dev);
+ mtk_dai_etdm_mclk_configure(afe, dai->id);
+ mtk_dai_etdm_enable_mclk(afe, dai->id);
+ pm_runtime_put_sync(afe->dev);
+ }
+ return 0;
+}
+
+static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = {
+ {
+ .name = "DPTX",
+ .id = MT8188_AFE_IO_DPTX,
+ .playback = {
+ .stream_name = "DPTX Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_hdmitx_dptx_ops,
+ },
+ {
+ .name = "ETDM1_IN",
+ .id = MT8188_AFE_IO_ETDM1_IN,
+ .capture = {
+ .stream_name = "ETDM1 Capture",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM2_IN",
+ .id = MT8188_AFE_IO_ETDM2_IN,
+ .capture = {
+ .stream_name = "ETDM2 Capture",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM1_OUT",
+ .id = MT8188_AFE_IO_ETDM1_OUT,
+ .playback = {
+ .stream_name = "ETDM1 Playback",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM2_OUT",
+ .id = MT8188_AFE_IO_ETDM2_OUT,
+ .playback = {
+ .stream_name = "ETDM2 Playback",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_etdm_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+ {
+ .name = "ETDM3_OUT",
+ .id = MT8188_AFE_IO_ETDM3_OUT,
+ .playback = {
+ .stream_name = "ETDM3 Playback",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_ETDM_RATES,
+ .formats = MTK_ETDM_FORMATS,
+ },
+ .ops = &mtk_dai_hdmitx_dptx_ops,
+ .probe = mtk_dai_etdm_probe,
+ },
+};
+
+static void mt8188_etdm_update_sync_info(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ struct mtk_dai_etdm_priv *mst_data;
+ int i;
+ int mst_dai_id;
+
+ for (i = MT8188_AFE_IO_ETDM_START; i < MT8188_AFE_IO_ETDM_END; i++) {
+ etdm_data = afe_priv->dai_priv[i];
+ if (etdm_data->cowork_source_id != COWORK_ETDM_NONE) {
+ mst_dai_id = etdm_data->cowork_source_id;
+ mst_data = afe_priv->dai_priv[mst_dai_id];
+ if (mst_data->cowork_source_id != COWORK_ETDM_NONE)
+ dev_info(afe->dev, "%s [%d] wrong sync source\n"
+ , __func__, i);
+ mst_data->cowork_slv_id[mst_data->cowork_slv_count] = i;
+ mst_data->cowork_slv_count++;
+ }
+ }
+}
+
+static void mt8188_dai_etdm_parse_of(struct mtk_base_afe *afe)
+{
+ const struct device_node *of_node = afe->dev->of_node;
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_data;
+ int i, j;
+ char prop[48];
+ u8 disable_chn[MT8188_ETDM_MAX_CHANNELS];
+ int max_chn = MT8188_ETDM_MAX_CHANNELS;
+ u32 sel;
+ int ret;
+ int dai_id;
+ unsigned int sync_id;
+ struct {
+ const char *name;
+ const unsigned int sync_id;
+ } of_afe_etdms[MT8188_AFE_IO_ETDM_NUM] = {
+ {"etdm-in1", ETDM_SYNC_FROM_IN1},
+ {"etdm-in2", ETDM_SYNC_FROM_IN2},
+ {"etdm-out1", ETDM_SYNC_FROM_OUT1},
+ {"etdm-out2", ETDM_SYNC_FROM_OUT2},
+ {"etdm-out3", ETDM_SYNC_FROM_OUT3},
+ };
+
+ for (i = 0; i < MT8188_AFE_IO_ETDM_NUM; i++) {
+ dai_id = ETDM_TO_DAI_ID(i);
+ etdm_data = afe_priv->dai_priv[dai_id];
+
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-mclk-always-on-rate",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = of_property_read_u32(of_node, prop, &sel);
+ if (ret == 0) {
+ etdm_data->mclk_dir = SND_SOC_CLOCK_OUT;
+ if (mtk_dai_etdm_cal_mclk(afe, sel, dai_id))
+ dev_info(afe->dev, "%s unsupported mclk %uHz\n",
+ __func__, sel);
+ }
+
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-multi-pin-mode",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ etdm_data->data_mode = of_property_read_bool(of_node, prop);
+
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-cowork-source",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = of_property_read_u32(of_node, prop, &sel);
+ if (ret == 0) {
+ if (sel >= MT8188_AFE_IO_ETDM_NUM) {
+ dev_info(afe->dev, "%s invalid id=%d\n",
+ __func__, sel);
+ etdm_data->cowork_source_id = COWORK_ETDM_NONE;
+ } else {
+ sync_id = of_afe_etdms[sel].sync_id;
+ etdm_data->cowork_source_id =
+ sync_to_dai_id(sync_id);
+ }
+ } else {
+ etdm_data->cowork_source_id = COWORK_ETDM_NONE;
+ }
+ }
+
+ /* etdm in only */
+ for (i = 0; i < 2; i++) {
+ ret = snprintf(prop, sizeof(prop),
+ "mediatek,%s-chn-disabled",
+ of_afe_etdms[i].name);
+ if (ret < 0) {
+ dev_info(afe->dev, "%s snprintf err=%d\n",
+ __func__, ret);
+ return;
+ }
+ ret = of_property_read_variable_u8_array(of_node, prop,
+ disable_chn,
+ 1, max_chn);
+ if (ret < 0)
+ continue;
+
+ for (j = 0; j < ret; j++) {
+ if (disable_chn[j] >= MT8188_ETDM_MAX_CHANNELS)
+ dev_info(afe->dev, "%s [%d] invalid chn %u\n",
+ __func__, j, disable_chn[j]);
+ else
+ etdm_data->in_disable_ch[disable_chn[j]] = true;
+ }
+ }
+ mt8188_etdm_update_sync_info(afe);
+}
+
+static int init_etdm_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_etdm_priv *etdm_priv;
+ int i;
+
+ for (i = MT8188_AFE_IO_ETDM_START; i < MT8188_AFE_IO_ETDM_END; i++) {
+ etdm_priv = devm_kzalloc(afe->dev,
+ sizeof(struct mtk_dai_etdm_priv),
+ GFP_KERNEL);
+ if (!etdm_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[i] = etdm_priv;
+ }
+
+ afe_priv->dai_priv[MT8188_AFE_IO_DPTX] =
+ afe_priv->dai_priv[MT8188_AFE_IO_ETDM3_OUT];
+
+ mt8188_dai_etdm_parse_of(afe);
+ return 0;
+}
+
+int mt8188_dai_etdm_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mtk_dai_etdm_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_etdm_driver);
+
+ dai->dapm_widgets = mtk_dai_etdm_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_etdm_widgets);
+ dai->dapm_routes = mtk_dai_etdm_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_etdm_routes);
+ dai->controls = mtk_dai_etdm_controls;
+ dai->num_controls = ARRAY_SIZE(mtk_dai_etdm_controls);
+
+ return init_etdm_priv_data(afe);
+}
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 06/12] ASoC: mediatek: mt8188: support pcmif in platform driver
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (3 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 05/12] ASoC: mediatek: mt8188: support etdm " Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 14:56 ` [PATCH 07/12] ASoC: mediatek: mt8188: support audio clock control Trevor Wu
` (5 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mt8188 pcmif dai driver support
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/mt8188/mt8188-dai-pcm.c | 362 +++++++++++++++++++++
1 file changed, 362 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-pcm.c
diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-pcm.c b/sound/soc/mediatek/mt8188/mt8188-dai-pcm.c
new file mode 100644
index 000000000000..40a634cffebf
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-dai-pcm.c
@@ -0,0 +1,362 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek ALSA SoC Audio DAI PCM I/F Control
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8188-afe-clk.h"
+#include "mt8188-afe-common.h"
+#include "mt8188-reg.h"
+
+enum {
+ MTK_DAI_PCM_FMT_I2S,
+ MTK_DAI_PCM_FMT_EIAJ,
+ MTK_DAI_PCM_FMT_MODEA,
+ MTK_DAI_PCM_FMT_MODEB,
+};
+
+enum {
+ MTK_DAI_PCM_CLK_A1SYS,
+ MTK_DAI_PCM_CLK_A2SYS,
+ MTK_DAI_PCM_CLK_26M_48K,
+ MTK_DAI_PCM_CLK_26M_441K,
+};
+
+struct mtk_dai_pcm_rate {
+ unsigned int rate;
+ unsigned int reg_value;
+};
+
+struct mtk_dai_pcmif_priv {
+ unsigned int slave_mode;
+ unsigned int lrck_inv;
+ unsigned int bck_inv;
+ unsigned int format;
+};
+
+static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = {
+ { .rate = 8000, .reg_value = 0, },
+ { .rate = 16000, .reg_value = 1, },
+ { .rate = 32000, .reg_value = 2, },
+ { .rate = 48000, .reg_value = 3, },
+ { .rate = 11025, .reg_value = 1, },
+ { .rate = 22050, .reg_value = 2, },
+ { .rate = 44100, .reg_value = 3, },
+};
+
+static int mtk_dai_pcm_mode(unsigned int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++)
+ if (mtk_dai_pcm_rates[i].rate == rate)
+ return mtk_dai_pcm_rates[i].reg_value;
+
+ return -EINVAL;
+}
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0),
+};
+
+static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0),
+};
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+ SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0,
+ mtk_dai_pcm_o000_mix,
+ ARRAY_SIZE(mtk_dai_pcm_o000_mix)),
+ SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0,
+ mtk_dai_pcm_o001_mix,
+ ARRAY_SIZE(mtk_dai_pcm_o001_mix)),
+
+ SND_SOC_DAPM_SUPPLY("PCM_1_EN", PCM_INTF_CON1, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_INPUT("PCM1_INPUT"),
+ SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"),
+
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_asrc11"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_asrc12"),
+ SND_SOC_DAPM_CLOCK_SUPPLY("aud_pcmif"),
+};
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+ {"I002", NULL, "PCM1 Capture"},
+ {"I003", NULL, "PCM1 Capture"},
+
+ {"O000", "I000 Switch", "I000"},
+ {"O001", "I001 Switch", "I001"},
+
+ {"O000", "I070 Switch", "I070"},
+ {"O001", "I071 Switch", "I071"},
+
+ {"PCM1 Playback", NULL, "O000"},
+ {"PCM1 Playback", NULL, "O001"},
+
+ {"PCM1 Playback", NULL, "PCM_1_EN"},
+ {"PCM1 Playback", NULL, "aud_asrc12"},
+ {"PCM1 Playback", NULL, "aud_pcmif"},
+
+ {"PCM1 Capture", NULL, "PCM_1_EN"},
+ {"PCM1 Capture", NULL, "aud_asrc11"},
+ {"PCM1 Capture", NULL, "aud_pcmif"},
+
+ {"PCM1_OUTPUT", NULL, "PCM1 Playback"},
+ {"PCM1 Capture", NULL, "PCM1_INPUT"},
+};
+
+static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_pcm_runtime * const runtime = substream->runtime;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_pcmif_priv *pcmif_priv = NULL;
+ unsigned int slave_mode = 0;
+ unsigned int lrck_inv = 0;
+ unsigned int bck_inv = 0;
+ unsigned int fmt = 0;
+ unsigned int bit_width = dai->sample_bits;
+ unsigned int val = 0;
+ unsigned int mask = 0;
+ int fs = 0;
+ int mode = 0;
+
+ if (dai->id < 0)
+ return -EINVAL;
+
+ pcmif_priv = afe_priv->dai_priv[dai->id];
+ slave_mode = pcmif_priv->slave_mode;
+ lrck_inv = pcmif_priv->lrck_inv;
+ bck_inv = pcmif_priv->bck_inv;
+ fmt = pcmif_priv->format;
+
+ /* sync freq mode */
+ fs = mt8188_afe_fs_timing(runtime->rate);
+ if (fs < 0)
+ return -EINVAL;
+ val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs);
+ mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK;
+
+ /* clk domain sel */
+ if (runtime->rate % 8000)
+ val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K);
+ else
+ val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K);
+ mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK;
+
+ regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val);
+
+ val = 0;
+ mask = 0;
+
+ /* pcm mode */
+ mode = mtk_dai_pcm_mode(runtime->rate);
+ if (mode < 0)
+ return -EINVAL;
+ val |= PCM_INTF_CON1_PCM_MODE(mode);
+ mask |= PCM_INTF_CON1_PCM_MODE_MASK;
+
+ /* pcm format */
+ val |= PCM_INTF_CON1_PCM_FMT(fmt);
+ mask |= PCM_INTF_CON1_PCM_FMT_MASK;
+
+ /* pcm sync length */
+ if (fmt == MTK_DAI_PCM_FMT_MODEA ||
+ fmt == MTK_DAI_PCM_FMT_MODEB)
+ val |= PCM_INTF_CON1_SYNC_LENGTH(1);
+ else
+ val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width);
+ mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK;
+
+ /* pcm bits, word length */
+ if (bit_width > 16) {
+ val |= PCM_INTF_CON1_PCM_24BIT;
+ val |= PCM_INTF_CON1_PCM_WLEN_64BCK;
+ } else {
+ val |= PCM_INTF_CON1_PCM_16BIT;
+ val |= PCM_INTF_CON1_PCM_WLEN_32BCK;
+ }
+ mask |= PCM_INTF_CON1_PCM_BIT_MASK;
+ mask |= PCM_INTF_CON1_PCM_WLEN_MASK;
+
+ /* master/slave */
+ if (!slave_mode) {
+ val |= PCM_INTF_CON1_PCM_MASTER;
+
+ if (lrck_inv)
+ val |= PCM_INTF_CON1_SYNC_OUT_INV;
+ if (bck_inv)
+ val |= PCM_INTF_CON1_BCLK_OUT_INV;
+ mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK;
+ } else {
+ val |= PCM_INTF_CON1_PCM_SLAVE;
+
+ if (lrck_inv)
+ val |= PCM_INTF_CON1_SYNC_IN_INV;
+ if (bck_inv)
+ val |= PCM_INTF_CON1_BCLK_IN_INV;
+ mask |= PCM_INTF_CON1_CLK_IN_INV_MASK;
+
+ // TODO: add asrc setting for slave mode
+ }
+ mask |= PCM_INTF_CON1_PCM_M_S_MASK;
+
+ regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val);
+
+ return 0;
+}
+
+/* dai ops */
+static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ if (dai->playback_widget->active || dai->capture_widget->active)
+ return 0;
+
+ return mtk_dai_pcm_configure(substream, dai);
+}
+
+static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_pcmif_priv *pcmif_priv = NULL;
+
+ dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt);
+
+ if (dai->id < 0)
+ return -EINVAL;
+
+ pcmif_priv = afe_priv->dai_priv[dai->id];
+
+ switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+ case SND_SOC_DAIFMT_I2S:
+ pcmif_priv->format = MTK_DAI_PCM_FMT_I2S;
+ break;
+ case SND_SOC_DAIFMT_DSP_A:
+ pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA;
+ break;
+ case SND_SOC_DAIFMT_DSP_B:
+ pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+ case SND_SOC_DAIFMT_NB_NF:
+ pcmif_priv->bck_inv = 0;
+ pcmif_priv->lrck_inv = 0;
+ break;
+ case SND_SOC_DAIFMT_NB_IF:
+ pcmif_priv->bck_inv = 0;
+ pcmif_priv->lrck_inv = 1;
+ break;
+ case SND_SOC_DAIFMT_IB_NF:
+ pcmif_priv->bck_inv = 1;
+ pcmif_priv->lrck_inv = 0;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ pcmif_priv->bck_inv = 1;
+ pcmif_priv->lrck_inv = 1;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
+ case SND_SOC_DAIFMT_CBP_CFP:
+ pcmif_priv->slave_mode = 1;
+ break;
+ case SND_SOC_DAIFMT_CBC_CFC:
+ pcmif_priv->slave_mode = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct snd_soc_dai_ops mtk_dai_pcm_ops = {
+ .prepare = mtk_dai_pcm_prepare,
+ .set_fmt = mtk_dai_pcm_set_fmt,
+};
+
+/* dai driver */
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+ {
+ .name = "PCM1",
+ .id = MT8188_AFE_IO_PCM,
+ .playback = {
+ .stream_name = "PCM1 Playback",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .capture = {
+ .stream_name = "PCM1 Capture",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mtk_dai_pcm_ops,
+ .symmetric_rate = 1,
+ .symmetric_sample_bits = 1,
+ },
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_pcmif_priv *pcmif_priv;
+
+ pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv),
+ GFP_KERNEL);
+ if (!pcmif_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[MT8188_AFE_IO_PCM] = pcmif_priv;
+ return 0;
+}
+
+int mt8188_dai_pcm_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mtk_dai_pcm_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+
+ dai->dapm_widgets = mtk_dai_pcm_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+ dai->dapm_routes = mtk_dai_pcm_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+
+ return init_pcmif_priv_data(afe);
+}
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 07/12] ASoC: mediatek: mt8188: support audio clock control
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (4 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 06/12] ASoC: mediatek: mt8188: support pcmif " Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 14:56 ` [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver Trevor Wu
` (4 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add audio clock wrapper and audio tuner control.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 656 +++++++++++++++++++++
sound/soc/mediatek/mt8188/mt8188-afe-clk.h | 114 ++++
2 files changed, 770 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-clk.c
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-clk.h
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
new file mode 100644
index 000000000000..3d31a441524e
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c
@@ -0,0 +1,656 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8188-afe-clk.c -- Mediatek 8188 afe clock ctrl
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#include <linux/clk.h>
+
+#include "mt8188-afe-common.h"
+#include "mt8188-afe-clk.h"
+#include "mt8188-audsys-clk.h"
+#include "mt8188-reg.h"
+
+static const char *aud_clks[MT8188_CLK_NUM] = {
+ /* xtal */
+ [MT8188_CLK_XTAL_26M] = "clk26m",
+
+ /* divider */
+ [MT8188_CLK_TOP_APLL1] = "apll1_ck",
+ [MT8188_CLK_TOP_APLL2] = "apll2_ck",
+ [MT8188_CLK_TOP_APLL12_DIV0] = "apll12_div0",
+ [MT8188_CLK_TOP_APLL12_DIV1] = "apll12_div1",
+ [MT8188_CLK_TOP_APLL12_DIV2] = "apll12_div2",
+ [MT8188_CLK_TOP_APLL12_DIV3] = "apll12_div3",
+ [MT8188_CLK_TOP_APLL12_DIV9] = "apll12_div9",
+
+ /* mux */
+ [MT8188_CLK_TOP_A1SYS_HP_SEL] = "top_a1sys_hp",
+ [MT8188_CLK_TOP_AUD_INTBUS_SEL] = "top_aud_intbus",
+ [MT8188_CLK_TOP_AUDIO_H_SEL] = "top_audio_h",
+ [MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL] = "top_audio_local_bus",
+ [MT8188_CLK_TOP_DPTX_M_SEL] = "top_dptx",
+ [MT8188_CLK_TOP_I2SO1_M_SEL] = "top_i2so1",
+ [MT8188_CLK_TOP_I2SO2_M_SEL] = "top_i2so2",
+ [MT8188_CLK_TOP_I2SI1_M_SEL] = "top_i2si1",
+ [MT8188_CLK_TOP_I2SI2_M_SEL] = "top_i2si2",
+
+ /* clock gate */
+ [MT8188_CLK_ADSP_AUDIO_26M] = "adsp_audio_26m",
+ /* afe clock gate */
+ [MT8188_CLK_AUD_AFE] = "aud_afe",
+ [MT8188_CLK_AUD_APLL1_TUNER] = "aud_apll1_tuner",
+ [MT8188_CLK_AUD_APLL2_TUNER] = "aud_apll2_tuner",
+ [MT8188_CLK_AUD_APLL] = "aud_apll",
+ [MT8188_CLK_AUD_APLL2] = "aud_apll2",
+ [MT8188_CLK_AUD_DAC] = "aud_dac",
+ [MT8188_CLK_AUD_ADC] = "aud_adc",
+ [MT8188_CLK_AUD_DAC_HIRES] = "aud_dac_hires",
+ [MT8188_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp",
+ [MT8188_CLK_AUD_ADC_HIRES] = "aud_adc_hires",
+ [MT8188_CLK_AUD_I2SIN] = "aud_i2sin",
+ [MT8188_CLK_AUD_TDM_IN] = "aud_tdm_in",
+ [MT8188_CLK_AUD_I2S_OUT] = "aud_i2s_out",
+ [MT8188_CLK_AUD_TDM_OUT] = "aud_tdm_out",
+ [MT8188_CLK_AUD_HDMI_OUT] = "aud_hdmi_out",
+ [MT8188_CLK_AUD_ASRC11] = "aud_asrc11",
+ [MT8188_CLK_AUD_ASRC12] = "aud_asrc12",
+ [MT8188_CLK_AUD_A1SYS] = "aud_a1sys",
+ [MT8188_CLK_AUD_A2SYS] = "aud_a2sys",
+ [MT8188_CLK_AUD_PCMIF] = "aud_pcmif",
+ [MT8188_CLK_AUD_MEMIF_UL1] = "aud_memif_ul1",
+ [MT8188_CLK_AUD_MEMIF_UL2] = "aud_memif_ul2",
+ [MT8188_CLK_AUD_MEMIF_UL3] = "aud_memif_ul3",
+ [MT8188_CLK_AUD_MEMIF_UL4] = "aud_memif_ul4",
+ [MT8188_CLK_AUD_MEMIF_UL5] = "aud_memif_ul5",
+ [MT8188_CLK_AUD_MEMIF_UL6] = "aud_memif_ul6",
+ [MT8188_CLK_AUD_MEMIF_UL8] = "aud_memif_ul8",
+ [MT8188_CLK_AUD_MEMIF_UL9] = "aud_memif_ul9",
+ [MT8188_CLK_AUD_MEMIF_UL10] = "aud_memif_ul10",
+ [MT8188_CLK_AUD_MEMIF_DL2] = "aud_memif_dl2",
+ [MT8188_CLK_AUD_MEMIF_DL3] = "aud_memif_dl3",
+ [MT8188_CLK_AUD_MEMIF_DL6] = "aud_memif_dl6",
+ [MT8188_CLK_AUD_MEMIF_DL7] = "aud_memif_dl7",
+ [MT8188_CLK_AUD_MEMIF_DL8] = "aud_memif_dl8",
+ [MT8188_CLK_AUD_MEMIF_DL10] = "aud_memif_dl10",
+ [MT8188_CLK_AUD_MEMIF_DL11] = "aud_memif_dl11",
+};
+
+struct mt8188_afe_tuner_cfg {
+ unsigned int id;
+ int apll_div_reg;
+ unsigned int apll_div_shift;
+ unsigned int apll_div_maskbit;
+ unsigned int apll_div_default;
+ int ref_ck_sel_reg;
+ unsigned int ref_ck_sel_shift;
+ unsigned int ref_ck_sel_maskbit;
+ unsigned int ref_ck_sel_default;
+ int tuner_en_reg;
+ unsigned int tuner_en_shift;
+ unsigned int tuner_en_maskbit;
+ int upper_bound_reg;
+ unsigned int upper_bound_shift;
+ unsigned int upper_bound_maskbit;
+ unsigned int upper_bound_default;
+ spinlock_t ctrl_lock; /* lock for apll tuner ctrl*/
+ int ref_cnt;
+};
+
+static struct mt8188_afe_tuner_cfg
+ mt8188_afe_tuner_cfgs[MT8188_AUD_PLL_NUM] = {
+ [MT8188_AUD_PLL1] = {
+ .id = MT8188_AUD_PLL1,
+ .apll_div_reg = AFE_APLL_TUNER_CFG,
+ .apll_div_shift = 4,
+ .apll_div_maskbit = 0xf,
+ .apll_div_default = 0x7,
+ .ref_ck_sel_reg = AFE_APLL_TUNER_CFG,
+ .ref_ck_sel_shift = 1,
+ .ref_ck_sel_maskbit = 0x3,
+ .ref_ck_sel_default = 0x2,
+ .tuner_en_reg = AFE_APLL_TUNER_CFG,
+ .tuner_en_shift = 0,
+ .tuner_en_maskbit = 0x1,
+ .upper_bound_reg = AFE_APLL_TUNER_CFG,
+ .upper_bound_shift = 8,
+ .upper_bound_maskbit = 0xff,
+ .upper_bound_default = 0x3,
+ },
+ [MT8188_AUD_PLL2] = {
+ .id = MT8188_AUD_PLL2,
+ .apll_div_reg = AFE_APLL_TUNER_CFG1,
+ .apll_div_shift = 4,
+ .apll_div_maskbit = 0xf,
+ .apll_div_default = 0x7,
+ .ref_ck_sel_reg = AFE_APLL_TUNER_CFG1,
+ .ref_ck_sel_shift = 1,
+ .ref_ck_sel_maskbit = 0x3,
+ .ref_ck_sel_default = 0x1,
+ .tuner_en_reg = AFE_APLL_TUNER_CFG1,
+ .tuner_en_shift = 0,
+ .tuner_en_maskbit = 0x1,
+ .upper_bound_reg = AFE_APLL_TUNER_CFG1,
+ .upper_bound_shift = 8,
+ .upper_bound_maskbit = 0xff,
+ .upper_bound_default = 0x3,
+ },
+ [MT8188_AUD_PLL3] = {
+ .id = MT8188_AUD_PLL3,
+ .apll_div_reg = AFE_EARC_APLL_TUNER_CFG,
+ .apll_div_shift = 4,
+ .apll_div_maskbit = 0x3f,
+ .apll_div_default = 0x3,
+ .ref_ck_sel_reg = AFE_EARC_APLL_TUNER_CFG,
+ .ref_ck_sel_shift = 24,
+ .ref_ck_sel_maskbit = 0x3,
+ .ref_ck_sel_default = 0x0,
+ .tuner_en_reg = AFE_EARC_APLL_TUNER_CFG,
+ .tuner_en_shift = 0,
+ .tuner_en_maskbit = 0x1,
+ .upper_bound_reg = AFE_EARC_APLL_TUNER_CFG,
+ .upper_bound_shift = 12,
+ .upper_bound_maskbit = 0xff,
+ .upper_bound_default = 0x4,
+ },
+ [MT8188_AUD_PLL4] = {
+ .id = MT8188_AUD_PLL4,
+ .apll_div_reg = AFE_SPDIFIN_APLL_TUNER_CFG,
+ .apll_div_shift = 4,
+ .apll_div_maskbit = 0x3f,
+ .apll_div_default = 0x7,
+ .ref_ck_sel_reg = AFE_SPDIFIN_APLL_TUNER_CFG1,
+ .ref_ck_sel_shift = 8,
+ .ref_ck_sel_maskbit = 0x1,
+ .ref_ck_sel_default = 0,
+ .tuner_en_reg = AFE_SPDIFIN_APLL_TUNER_CFG,
+ .tuner_en_shift = 0,
+ .tuner_en_maskbit = 0x1,
+ .upper_bound_reg = AFE_SPDIFIN_APLL_TUNER_CFG,
+ .upper_bound_shift = 12,
+ .upper_bound_maskbit = 0xff,
+ .upper_bound_default = 0x4,
+ },
+ [MT8188_AUD_PLL5] = {
+ .id = MT8188_AUD_PLL5,
+ .apll_div_reg = AFE_LINEIN_APLL_TUNER_CFG,
+ .apll_div_shift = 4,
+ .apll_div_maskbit = 0x3f,
+ .apll_div_default = 0x3,
+ .ref_ck_sel_reg = AFE_LINEIN_APLL_TUNER_CFG,
+ .ref_ck_sel_shift = 24,
+ .ref_ck_sel_maskbit = 0x1,
+ .ref_ck_sel_default = 0,
+ .tuner_en_reg = AFE_LINEIN_APLL_TUNER_CFG,
+ .tuner_en_shift = 0,
+ .tuner_en_maskbit = 0x1,
+ .upper_bound_reg = AFE_LINEIN_APLL_TUNER_CFG,
+ .upper_bound_shift = 12,
+ .upper_bound_maskbit = 0xff,
+ .upper_bound_default = 0x4,
+ },
+};
+
+static struct mt8188_afe_tuner_cfg *mt8188_afe_found_apll_tuner(unsigned int id)
+{
+ if (id >= MT8188_AUD_PLL_NUM)
+ return NULL;
+
+ return &mt8188_afe_tuner_cfgs[id];
+}
+
+static int mt8188_afe_init_apll_tuner(unsigned int id)
+{
+ struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);
+
+ if (!cfg)
+ return -EINVAL;
+
+ cfg->ref_cnt = 0;
+ spin_lock_init(&cfg->ctrl_lock);
+
+ return 0;
+}
+
+static int mt8188_afe_setup_apll_tuner(struct mtk_base_afe *afe, unsigned int id)
+{
+ const struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);
+
+ if (!cfg)
+ return -EINVAL;
+
+ regmap_update_bits(afe->regmap,
+ cfg->apll_div_reg,
+ cfg->apll_div_maskbit << cfg->apll_div_shift,
+ cfg->apll_div_default << cfg->apll_div_shift);
+
+ regmap_update_bits(afe->regmap,
+ cfg->ref_ck_sel_reg,
+ cfg->ref_ck_sel_maskbit << cfg->ref_ck_sel_shift,
+ cfg->ref_ck_sel_default << cfg->ref_ck_sel_shift);
+
+ regmap_update_bits(afe->regmap,
+ cfg->upper_bound_reg,
+ cfg->upper_bound_maskbit << cfg->upper_bound_shift,
+ cfg->upper_bound_default << cfg->upper_bound_shift);
+
+ return 0;
+}
+
+static int mt8188_afe_enable_tuner_clk(struct mtk_base_afe *afe,
+ unsigned int id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ switch (id) {
+ case MT8188_AUD_PLL1:
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL]);
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL1_TUNER]);
+ break;
+ case MT8188_AUD_PLL2:
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2]);
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2_TUNER]);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mt8188_afe_disable_tuner_clk(struct mtk_base_afe *afe,
+ unsigned int id)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ switch (id) {
+ case MT8188_AUD_PLL1:
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL1_TUNER]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL]);
+ break;
+ case MT8188_AUD_PLL2:
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2_TUNER]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_APLL2]);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int mt8188_afe_enable_apll_tuner(struct mtk_base_afe *afe, unsigned int id)
+{
+ struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);
+ unsigned long flags;
+ int ret;
+
+ if (!cfg)
+ return -EINVAL;
+
+ ret = mt8188_afe_setup_apll_tuner(afe, id);
+ if (ret)
+ return ret;
+
+ ret = mt8188_afe_enable_tuner_clk(afe, id);
+ if (ret)
+ return ret;
+
+ spin_lock_irqsave(&cfg->ctrl_lock, flags);
+
+ cfg->ref_cnt++;
+ if (cfg->ref_cnt == 1)
+ regmap_update_bits(afe->regmap,
+ cfg->tuner_en_reg,
+ cfg->tuner_en_maskbit << cfg->tuner_en_shift,
+ 1 << cfg->tuner_en_shift);
+
+ spin_unlock_irqrestore(&cfg->ctrl_lock, flags);
+
+ return 0;
+}
+
+static int mt8188_afe_disable_apll_tuner(struct mtk_base_afe *afe, unsigned int id)
+{
+ struct mt8188_afe_tuner_cfg *cfg = mt8188_afe_found_apll_tuner(id);
+ unsigned long flags;
+ int ret;
+
+ if (!cfg)
+ return -EINVAL;
+
+ spin_lock_irqsave(&cfg->ctrl_lock, flags);
+
+ cfg->ref_cnt--;
+ if (cfg->ref_cnt == 0)
+ regmap_update_bits(afe->regmap,
+ cfg->tuner_en_reg,
+ cfg->tuner_en_maskbit << cfg->tuner_en_shift,
+ 0 << cfg->tuner_en_shift);
+ else if (cfg->ref_cnt < 0)
+ cfg->ref_cnt = 0;
+
+ spin_unlock_irqrestore(&cfg->ctrl_lock, flags);
+
+ ret = mt8188_afe_disable_tuner_clk(afe, id);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+int mt8188_afe_get_mclk_source_clk_id(int sel)
+{
+ switch (sel) {
+ case MT8188_MCK_SEL_26M:
+ return MT8188_CLK_XTAL_26M;
+ case MT8188_MCK_SEL_APLL1:
+ return MT8188_CLK_TOP_APLL1;
+ case MT8188_MCK_SEL_APLL2:
+ return MT8188_CLK_TOP_APLL2;
+ default:
+ return -EINVAL;
+ }
+}
+
+int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ int clk_id = mt8188_afe_get_mclk_source_clk_id(apll);
+
+ if (clk_id < 0) {
+ dev_dbg(afe->dev, "invalid clk id\n");
+ return 0;
+ }
+
+ return clk_get_rate(afe_priv->clk[clk_id]);
+}
+
+int mt8188_afe_get_default_mclk_source_by_rate(int rate)
+{
+ return ((rate % 8000) == 0) ?
+ MT8188_MCK_SEL_APLL1 : MT8188_MCK_SEL_APLL2;
+}
+
+int mt8188_afe_init_clock(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ int i, ret;
+
+ ret = mt8188_audsys_clk_register(afe);
+ if (ret) {
+ dev_err(afe->dev, "register audsys clk fail %d\n", ret);
+ return ret;
+ }
+
+ afe_priv->clk =
+ devm_kcalloc(afe->dev, MT8188_CLK_NUM, sizeof(*afe_priv->clk),
+ GFP_KERNEL);
+ if (!afe_priv->clk)
+ return -ENOMEM;
+
+ for (i = 0; i < MT8188_CLK_NUM; i++) {
+ afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
+ if (IS_ERR(afe_priv->clk[i])) {
+ dev_err(afe->dev, "%s(), devm_clk_get %s fail, ret %ld\n",
+ __func__, aud_clks[i],
+ PTR_ERR(afe_priv->clk[i]));
+ return PTR_ERR(afe_priv->clk[i]);
+ }
+ }
+
+ /* initial tuner */
+ for (i = 0; i < MT8188_AUD_PLL_NUM; i++) {
+ ret = mt8188_afe_init_apll_tuner(i);
+ if (ret) {
+ dev_info(afe->dev, "%s(), init apll_tuner%d failed",
+ __func__, (i + 1));
+ return -EINVAL;
+ }
+ }
+
+ return 0;
+}
+
+void mt8188_afe_deinit_clock(void *priv)
+{
+ struct mtk_base_afe *afe = priv;
+
+ mt8188_audsys_clk_unregister(afe);
+}
+
+int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk)
+{
+ int ret;
+
+ if (clk) {
+ ret = clk_prepare_enable(clk);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to enable clk\n",
+ __func__);
+ return ret;
+ }
+ } else {
+ dev_dbg(afe->dev, "NULL clk\n");
+ }
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt8188_afe_enable_clk);
+
+void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk)
+{
+ if (clk)
+ clk_disable_unprepare(clk);
+ else
+ dev_dbg(afe->dev, "NULL clk\n");
+}
+EXPORT_SYMBOL_GPL(mt8188_afe_disable_clk);
+
+int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
+ unsigned int rate)
+{
+ int ret;
+
+ if (clk) {
+ ret = clk_set_rate(clk, rate);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to set clk rate\n",
+ __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
+ struct clk *parent)
+{
+ int ret;
+
+ if (clk && parent) {
+ ret = clk_set_parent(clk, parent);
+ if (ret) {
+ dev_dbg(afe->dev, "%s(), failed to set clk parent\n",
+ __func__);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static unsigned int get_top_cg_reg(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8188_TOP_CG_A1SYS_TIMING:
+ case MT8188_TOP_CG_A2SYS_TIMING:
+ case MT8188_TOP_CG_26M_TIMING:
+ return ASYS_TOP_CON;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_top_cg_mask(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8188_TOP_CG_A1SYS_TIMING:
+ return ASYS_TOP_CON_A1SYS_TIMING_ON;
+ case MT8188_TOP_CG_A2SYS_TIMING:
+ return ASYS_TOP_CON_A2SYS_TIMING_ON;
+ case MT8188_TOP_CG_26M_TIMING:
+ return ASYS_TOP_CON_26M_TIMING_ON;
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_top_cg_on_val(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8188_TOP_CG_A1SYS_TIMING:
+ case MT8188_TOP_CG_A2SYS_TIMING:
+ case MT8188_TOP_CG_26M_TIMING:
+ return get_top_cg_mask(cg_type);
+ default:
+ return 0;
+ }
+}
+
+static unsigned int get_top_cg_off_val(unsigned int cg_type)
+{
+ switch (cg_type) {
+ case MT8188_TOP_CG_A1SYS_TIMING:
+ case MT8188_TOP_CG_A2SYS_TIMING:
+ case MT8188_TOP_CG_26M_TIMING:
+ return 0;
+ default:
+ return get_top_cg_mask(cg_type);
+ }
+}
+
+static int mt8188_afe_enable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
+{
+ unsigned int reg = get_top_cg_reg(cg_type);
+ unsigned int mask = get_top_cg_mask(cg_type);
+ unsigned int val = get_top_cg_on_val(cg_type);
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+
+ return 0;
+}
+
+static int mt8188_afe_disable_top_cg(struct mtk_base_afe *afe, unsigned int cg_type)
+{
+ unsigned int reg = get_top_cg_reg(cg_type);
+ unsigned int mask = get_top_cg_mask(cg_type);
+ unsigned int val = get_top_cg_off_val(cg_type);
+
+ regmap_update_bits(afe->regmap, reg, mask, val);
+
+ return 0;
+}
+
+int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ /* bus clock for AFE external access, like DRAM */
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL]);
+
+ /* bus clock for AFE internal access, like AFE SRAM */
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUD_INTBUS_SEL]);
+
+ /* audio 26m clock source */
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_ADSP_AUDIO_26M]);
+
+ /* AFE hw clock */
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE]);
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS_HP]);
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+
+ return 0;
+}
+
+int mt8188_afe_disable_reg_rw_clk(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS_HP]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_AFE]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_ADSP_AUDIO_26M]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUD_INTBUS_SEL]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL]);
+
+ return 0;
+}
+
+static int mt8188_afe_enable_afe_on(struct mtk_base_afe *afe)
+{
+ regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1);
+ return 0;
+}
+
+static int mt8188_afe_disable_afe_on(struct mtk_base_afe *afe)
+{
+ regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0);
+ return 0;
+}
+
+static int mt8188_afe_enable_timing_sys(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+ mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+
+ mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+ mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+ mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+
+ return 0;
+}
+
+static int mt8188_afe_disable_timing_sys(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]);
+ mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]);
+
+ mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING);
+ mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING);
+ mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING);
+
+ return 0;
+}
+
+int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe)
+{
+ mt8188_afe_enable_timing_sys(afe);
+
+ mt8188_afe_enable_afe_on(afe);
+
+ mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1);
+ mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2);
+
+ return 0;
+}
+
+int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe)
+{
+ mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2);
+ mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1);
+
+ mt8188_afe_disable_afe_on(afe);
+
+ mt8188_afe_disable_timing_sys(afe);
+
+ return 0;
+}
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
new file mode 100644
index 000000000000..32bec98ac6a5
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * mt8188-afe-clk.h -- Mediatek 8188 afe clock ctrl definition
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#ifndef _MT8188_AFE_CLK_H_
+#define _MT8188_AFE_CLK_H_
+
+enum {
+ /* xtal */
+ MT8188_CLK_XTAL_26M,
+ /* divider */
+ MT8188_CLK_TOP_APLL1,
+ MT8188_CLK_TOP_APLL2,
+ MT8188_CLK_TOP_APLL12_DIV0,
+ MT8188_CLK_TOP_APLL12_DIV1,
+ MT8188_CLK_TOP_APLL12_DIV2,
+ MT8188_CLK_TOP_APLL12_DIV3,
+ MT8188_CLK_TOP_APLL12_DIV9,
+ /* mux */
+ MT8188_CLK_TOP_A1SYS_HP_SEL,
+ MT8188_CLK_TOP_AUD_INTBUS_SEL,
+ MT8188_CLK_TOP_AUDIO_H_SEL,
+ MT8188_CLK_TOP_AUDIO_LOCAL_BUS_SEL,
+ MT8188_CLK_TOP_DPTX_M_SEL,
+ MT8188_CLK_TOP_I2SO1_M_SEL,
+ MT8188_CLK_TOP_I2SO2_M_SEL,
+ MT8188_CLK_TOP_I2SI1_M_SEL,
+ MT8188_CLK_TOP_I2SI2_M_SEL,
+ /* clock gate */
+ MT8188_CLK_ADSP_AUDIO_26M,
+ MT8188_CLK_AUD_AFE,
+ MT8188_CLK_AUD_APLL1_TUNER,
+ MT8188_CLK_AUD_APLL2_TUNER,
+ MT8188_CLK_AUD_TOP0_SPDF,
+ MT8188_CLK_AUD_APLL,
+ MT8188_CLK_AUD_APLL2,
+ MT8188_CLK_AUD_DAC,
+ MT8188_CLK_AUD_ADC,
+ MT8188_CLK_AUD_DAC_HIRES,
+ MT8188_CLK_AUD_A1SYS_HP,
+ MT8188_CLK_AUD_ADC_HIRES,
+ MT8188_CLK_AUD_I2SIN,
+ MT8188_CLK_AUD_TDM_IN,
+ MT8188_CLK_AUD_I2S_OUT,
+ MT8188_CLK_AUD_TDM_OUT,
+ MT8188_CLK_AUD_HDMI_OUT,
+ MT8188_CLK_AUD_ASRC11,
+ MT8188_CLK_AUD_ASRC12,
+ MT8188_CLK_AUD_A1SYS,
+ MT8188_CLK_AUD_A2SYS,
+ MT8188_CLK_AUD_PCMIF,
+ MT8188_CLK_AUD_MEMIF_UL1,
+ MT8188_CLK_AUD_MEMIF_UL2,
+ MT8188_CLK_AUD_MEMIF_UL3,
+ MT8188_CLK_AUD_MEMIF_UL4,
+ MT8188_CLK_AUD_MEMIF_UL5,
+ MT8188_CLK_AUD_MEMIF_UL6,
+ MT8188_CLK_AUD_MEMIF_UL8,
+ MT8188_CLK_AUD_MEMIF_UL9,
+ MT8188_CLK_AUD_MEMIF_UL10,
+ MT8188_CLK_AUD_MEMIF_DL2,
+ MT8188_CLK_AUD_MEMIF_DL3,
+ MT8188_CLK_AUD_MEMIF_DL6,
+ MT8188_CLK_AUD_MEMIF_DL7,
+ MT8188_CLK_AUD_MEMIF_DL8,
+ MT8188_CLK_AUD_MEMIF_DL10,
+ MT8188_CLK_AUD_MEMIF_DL11,
+ MT8188_CLK_NUM,
+};
+
+enum {
+ MT8188_AUD_PLL1,
+ MT8188_AUD_PLL2,
+ MT8188_AUD_PLL3,
+ MT8188_AUD_PLL4,
+ MT8188_AUD_PLL5,
+ MT8188_AUD_PLL_NUM,
+};
+
+enum {
+ MT8188_MCK_SEL_26M,
+ MT8188_MCK_SEL_APLL1,
+ MT8188_MCK_SEL_APLL2,
+ MT8188_MCK_SEL_APLL3,
+ MT8188_MCK_SEL_APLL4,
+ MT8188_MCK_SEL_APLL5,
+ MT8188_MCK_SEL_NUM,
+};
+
+struct mtk_base_afe;
+
+int mt8188_afe_get_mclk_source_clk_id(int sel);
+int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll);
+int mt8188_afe_get_default_mclk_source_by_rate(int rate);
+int mt8188_afe_init_clock(struct mtk_base_afe *afe);
+void mt8188_afe_deinit_clock(void *priv);
+int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk);
+void mt8188_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk);
+int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk,
+ unsigned int rate);
+int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk,
+ struct clk *parent);
+int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe);
+int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe);
+int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe);
+int mt8188_afe_disable_reg_rw_clk(struct mtk_base_afe *afe);
+
+#endif
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (5 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 07/12] ASoC: mediatek: mt8188: support audio clock control Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-10-04 9:36 ` AngeloGioacchino Del Regno
[not found] ` <202210011740.ZdLtxKq1-lkp@intel.com>
2022-09-30 14:56 ` [PATCH 09/12] ASoC: mediatek: mt8188: add control for timing select Trevor Wu
` (3 subsequent siblings)
10 siblings, 2 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mt8188 platform driver.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
This patch depends on the following series that has not been accepted.
[1] Add power domain support for MT8188
https://patchwork.kernel.org/project/linux-mediatek/list/?series=681359
(linux/soc/mediatek/infracfg.h is included)
---
sound/soc/mediatek/Kconfig | 13 +
sound/soc/mediatek/Makefile | 1 +
sound/soc/mediatek/mt8188/Makefile | 12 +
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 2945 ++++++++++++++++++++
4 files changed, 2971 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/Makefile
create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index 363fa4d47680..cf0e4c6b61e7 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -206,6 +206,19 @@ config SND_SOC_MTK_BTCVSD
Select Y if you have such device.
If unsure select "N".
+config SND_SOC_MT8188
+ tristate "ASoC support for Mediatek MT8188 chip"
+ depends on ARCH_MEDIATEK || COMPILE_TEST
+ depends on COMMON_CLK
+ select SND_SOC_MEDIATEK
+ select SND_SOC_MT6359
+ select MFD_SYSCON if SND_SOC_MT6359
+ help
+ This adds ASoC platform driver support for Mediatek MT8188 chip
+ that can be used with other codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
config SND_SOC_MT8192
tristate "ASoC support for Mediatek MT8192 chip"
depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
index 5571c640a288..3de38cfc69e5 100644
--- a/sound/soc/mediatek/Makefile
+++ b/sound/soc/mediatek/Makefile
@@ -5,5 +5,6 @@ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
+obj-$(CONFIG_SND_SOC_MT8188) += mt8188/
obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
obj-$(CONFIG_SND_SOC_MT8195) += mt8195/
diff --git a/sound/soc/mediatek/mt8188/Makefile b/sound/soc/mediatek/mt8188/Makefile
new file mode 100644
index 000000000000..fa5d383c5e47
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/Makefile
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0
+
+# platform driver
+snd-soc-mt8188-afe-objs := \
+ mt8188-afe-clk.o \
+ mt8188-afe-pcm.o \
+ mt8188-audsys-clk.o \
+ mt8188-dai-adda.o \
+ mt8188-dai-etdm.o \
+ mt8188-dai-pcm.o
+
+obj-$(CONFIG_SND_SOC_MT8188) += snd-soc-mt8188-afe.o
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
new file mode 100644
index 000000000000..5d8e01c99714
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -0,0 +1,2945 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek ALSA SoC AFE platform driver for 8188
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
+ * Trevor Wu <trevor.wu@mediatek.com>
+ * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
+ */
+
+#include <linux/arm-smccc.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/module.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/pm_runtime.h>
+#include <linux/reset.h>
+#include <linux/soc/mediatek/infracfg.h>
+#include <linux/soc/mediatek/mtk_sip_svc.h>
+#include <sound/pcm_params.h>
+#include "mt8188-afe-common.h"
+#include "mt8188-afe-clk.h"
+#include "mt8188-reg.h"
+#include "../common/mtk-afe-platform-driver.h"
+#include "../common/mtk-afe-fe-dai.h"
+
+#define MTK_SIP_AUDIO_CONTROL MTK_SIP_SMC_CMD(0x517)
+
+#define MT8188_MEMIF_BUFFER_BYTES_ALIGN (0x40)
+#define MT8188_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff)
+
+#define MEMIF_AXI_MINLEN 9 //register default value
+
+struct mtk_dai_memif_priv {
+ unsigned int asys_timing_sel;
+ unsigned int fs_timing;
+};
+
+static const struct snd_pcm_hardware mt8188_afe_hardware = {
+ .info = SNDRV_PCM_INFO_MMAP |
+ SNDRV_PCM_INFO_INTERLEAVED |
+ SNDRV_PCM_INFO_MMAP_VALID,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE |
+ SNDRV_PCM_FMTBIT_S32_LE,
+ .period_bytes_min = 64,
+ .period_bytes_max = 256 * 1024,
+ .periods_min = 2,
+ .periods_max = 256,
+ .buffer_bytes_max = 256 * 2 * 1024,
+};
+
+struct mt8188_afe_rate {
+ unsigned int rate;
+ unsigned int reg_value;
+};
+
+static const struct mt8188_afe_rate mt8188_afe_rates[] = {
+ { .rate = 8000, .reg_value = 0, },
+ { .rate = 12000, .reg_value = 1, },
+ { .rate = 16000, .reg_value = 2, },
+ { .rate = 24000, .reg_value = 3, },
+ { .rate = 32000, .reg_value = 4, },
+ { .rate = 48000, .reg_value = 5, },
+ { .rate = 96000, .reg_value = 6, },
+ { .rate = 192000, .reg_value = 7, },
+ { .rate = 384000, .reg_value = 8, },
+ { .rate = 7350, .reg_value = 16, },
+ { .rate = 11025, .reg_value = 17, },
+ { .rate = 14700, .reg_value = 18, },
+ { .rate = 22050, .reg_value = 19, },
+ { .rate = 29400, .reg_value = 20, },
+ { .rate = 44100, .reg_value = 21, },
+ { .rate = 88200, .reg_value = 22, },
+ { .rate = 176400, .reg_value = 23, },
+ { .rate = 352800, .reg_value = 24, },
+};
+
+int mt8188_afe_fs_timing(unsigned int rate)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mt8188_afe_rates); i++)
+ if (mt8188_afe_rates[i].rate == rate)
+ return mt8188_afe_rates[i].reg_value;
+
+ return -EINVAL;
+}
+
+static int mt8188_memif_fs(struct snd_pcm_substream *substream,
+ unsigned int rate)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_soc_component *component = NULL;
+ struct mtk_base_afe *afe = NULL;
+ struct mt8188_afe_private *afe_priv = NULL;
+ struct mtk_base_afe_memif *memif = NULL;
+ struct mtk_dai_memif_priv *memif_priv = NULL;
+ int fs = mt8188_afe_fs_timing(rate);
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+
+ if (id < 0)
+ return -EINVAL;
+
+ component = snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+ if (!component)
+ return -EINVAL;
+
+ afe = snd_soc_component_get_drvdata(component);
+ memif = &afe->memif[id];
+
+ switch (memif->data->id) {
+ case MT8188_AFE_MEMIF_DL10:
+ fs = MT8188_ETDM_OUT3_1X_EN;
+ break;
+ case MT8188_AFE_MEMIF_UL8:
+ fs = MT8188_ETDM_IN1_NX_EN;
+ break;
+ case MT8188_AFE_MEMIF_UL3:
+ fs = MT8188_ETDM_IN2_NX_EN;
+ break;
+ default:
+ afe_priv = afe->platform_priv;
+ memif_priv = afe_priv->dai_priv[id];
+ if (memif_priv->fs_timing)
+ fs = memif_priv->fs_timing;
+ break;
+ }
+
+ return fs;
+}
+
+static int mt8188_irq_fs(struct snd_pcm_substream *substream,
+ unsigned int rate)
+{
+ int fs = mt8188_memif_fs(substream, rate);
+
+ switch (fs) {
+ case MT8188_ETDM_IN1_NX_EN:
+ fs = MT8188_ETDM_IN1_1X_EN;
+ break;
+ case MT8188_ETDM_IN2_NX_EN:
+ fs = MT8188_ETDM_IN2_1X_EN;
+ break;
+ default:
+ break;
+ }
+
+ return fs;
+}
+
+enum {
+ MT8188_AFE_CM0,
+ MT8188_AFE_CM1,
+ MT8188_AFE_CM2,
+ MT8188_AFE_CM_NUM,
+};
+
+struct mt8188_afe_channel_merge {
+ int id;
+ int reg;
+ unsigned int sel_shift;
+ unsigned int sel_maskbit;
+ unsigned int sel_default;
+ unsigned int ch_num_shift;
+ unsigned int ch_num_maskbit;
+ unsigned int en_shift;
+ unsigned int en_maskbit;
+ unsigned int update_cnt_shift;
+ unsigned int update_cnt_maskbit;
+ unsigned int update_cnt_default;
+};
+
+static const struct mt8188_afe_channel_merge
+ mt8188_afe_cm[MT8188_AFE_CM_NUM] = {
+ [MT8188_AFE_CM0] = {
+ .id = MT8188_AFE_CM0,
+ .reg = AFE_CM0_CON,
+ .sel_shift = 30,
+ .sel_maskbit = 0x1,
+ .sel_default = 1,
+ .ch_num_shift = 2,
+ .ch_num_maskbit = 0x3f,
+ .en_shift = 0,
+ .en_maskbit = 0x1,
+ .update_cnt_shift = 16,
+ .update_cnt_maskbit = 0x1fff,
+ .update_cnt_default = 0x3,
+ },
+ [MT8188_AFE_CM1] = {
+ .id = MT8188_AFE_CM1,
+ .reg = AFE_CM1_CON,
+ .sel_shift = 30,
+ .sel_maskbit = 0x1,
+ .sel_default = 1,
+ .ch_num_shift = 2,
+ .ch_num_maskbit = 0x1f,
+ .en_shift = 0,
+ .en_maskbit = 0x1,
+ .update_cnt_shift = 16,
+ .update_cnt_maskbit = 0x1fff,
+ .update_cnt_default = 0x3,
+ },
+ [MT8188_AFE_CM2] = {
+ .id = MT8188_AFE_CM2,
+ .reg = AFE_CM2_CON,
+ .sel_shift = 30,
+ .sel_maskbit = 0x1,
+ .sel_default = 1,
+ .ch_num_shift = 2,
+ .ch_num_maskbit = 0x1f,
+ .en_shift = 0,
+ .en_maskbit = 0x1,
+ .update_cnt_shift = 16,
+ .update_cnt_maskbit = 0x1fff,
+ .update_cnt_default = 0x3,
+ },
+};
+
+static int mt8188_afe_memif_is_ul(int id)
+{
+ if (id >= MT8188_AFE_MEMIF_UL_START && id < MT8188_AFE_MEMIF_END)
+ return 1;
+ else
+ return 0;
+}
+
+static const struct mt8188_afe_channel_merge *
+ mt8188_afe_found_cm(struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int id = -EINVAL;
+
+ if (mt8188_afe_memif_is_ul(dai->id) == 0)
+ return NULL;
+
+ switch (dai->id) {
+ case MT8188_AFE_MEMIF_UL9:
+ id = MT8188_AFE_CM0;
+ break;
+ case MT8188_AFE_MEMIF_UL2:
+ id = MT8188_AFE_CM1;
+ break;
+ case MT8188_AFE_MEMIF_UL10:
+ id = MT8188_AFE_CM2;
+ break;
+ default:
+ break;
+ }
+
+ if (id < 0) {
+ dev_dbg(afe->dev, "%s, memif %d cannot find CM!\n", __func__, dai->id);
+ return NULL;
+ }
+
+ return &mt8188_afe_cm[id];
+}
+
+static int mt8188_afe_config_cm(struct mtk_base_afe *afe,
+ const struct mt8188_afe_channel_merge *cm,
+ unsigned int channels)
+{
+ if (!cm)
+ return -EINVAL;
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->sel_maskbit << cm->sel_shift,
+ cm->sel_default << cm->sel_shift);
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->ch_num_maskbit << cm->ch_num_shift,
+ (channels - 1) << cm->ch_num_shift);
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->update_cnt_maskbit << cm->update_cnt_shift,
+ cm->update_cnt_default << cm->update_cnt_shift);
+
+ return 0;
+}
+
+static int mt8188_afe_enable_cm(struct mtk_base_afe *afe,
+ const struct mt8188_afe_channel_merge *cm,
+ bool enable)
+{
+ if (!cm)
+ return -EINVAL;
+
+ regmap_update_bits(afe->regmap,
+ cm->reg,
+ cm->en_maskbit << cm->en_shift,
+ enable << cm->en_shift);
+
+ return 0;
+}
+
+static int mt8188_afe_fe_startup(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ int ret;
+
+ ret = mtk_afe_fe_startup(substream, dai);
+
+ snd_pcm_hw_constraint_step(runtime, 0,
+ SNDRV_PCM_HW_PARAM_BUFFER_BYTES,
+ MT8188_MEMIF_BUFFER_BYTES_ALIGN);
+
+ if (id != MT8188_AFE_MEMIF_DL7)
+ goto out;
+
+ ret = snd_pcm_hw_constraint_minmax(runtime,
+ SNDRV_PCM_HW_PARAM_PERIOD_SIZE, 1,
+ MT8188_MEMIF_DL7_MAX_PERIOD_SIZE);
+ if (ret < 0)
+ dev_dbg(afe->dev, "hw_constraint_minmax failed\n");
+out:
+ return ret;
+}
+
+static void mt8188_afe_fe_shutdown(struct snd_pcm_substream *substream,
+ struct snd_soc_dai *dai)
+{
+ mtk_afe_fe_shutdown(substream, dai);
+}
+
+static int mt8188_afe_fe_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params,
+ struct snd_soc_dai *dai)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ struct mtk_base_afe_memif *memif = &afe->memif[id];
+ const struct mtk_base_memif_data *data = memif->data;
+ const struct mt8188_afe_channel_merge *cm = mt8188_afe_found_cm(dai);
+ unsigned int channels = params_channels(params);
+
+ mt8188_afe_config_cm(afe, cm, channels);
+
+ if (data->ch_num_reg >= 0) {
+ regmap_update_bits(afe->regmap, data->ch_num_reg,
+ data->ch_num_maskbit << data->ch_num_shift,
+ channels << data->ch_num_shift);
+ }
+
+ return mtk_afe_fe_hw_params(substream, params, dai);
+}
+
+static int mt8188_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd,
+ struct snd_soc_dai *dai)
+{
+ struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+ const struct mt8188_afe_channel_merge *cm = mt8188_afe_found_cm(dai);
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ struct snd_pcm_runtime * const runtime = substream->runtime;
+ int id = asoc_rtd_to_cpu(rtd, 0)->id;
+ struct mtk_base_afe_memif *memif = &afe->memif[id];
+ struct mtk_base_afe_irq *irqs = &afe->irqs[memif->irq_usage];
+ const struct mtk_base_irq_data *irq_data = irqs->irq_data;
+ unsigned int counter = runtime->period_size;
+ int fs;
+ int ret;
+
+ switch (cmd) {
+ case SNDRV_PCM_TRIGGER_START:
+ case SNDRV_PCM_TRIGGER_RESUME:
+ mt8188_afe_enable_cm(afe, cm, true);
+
+ ret = mtk_memif_set_enable(afe, id);
+ if (ret) {
+ dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
+ __func__, id, ret);
+ return ret;
+ }
+
+ /* set irq counter */
+ regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg,
+ irq_data->irq_cnt_maskbit << irq_data->irq_cnt_shift,
+ counter << irq_data->irq_cnt_shift);
+
+ /* set irq fs */
+ fs = afe->irq_fs(substream, runtime->rate);
+
+ if (fs < 0)
+ return -EINVAL;
+
+ if (irq_data->irq_fs_reg >= 0)
+ regmap_update_bits(afe->regmap, irq_data->irq_fs_reg,
+ irq_data->irq_fs_maskbit << irq_data->irq_fs_shift,
+ fs << irq_data->irq_fs_shift);
+
+ /* delay for uplink */
+ if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
+ u32 sample_delay;
+
+ sample_delay = ((MEMIF_AXI_MINLEN + 1) * 64 +
+ (runtime->channels * runtime->sample_bits - 1)) /
+ (runtime->channels * runtime->sample_bits) + 1;
+
+ udelay(sample_delay * 1000000 / runtime->rate);
+ }
+
+ /* enable interrupt */
+ regmap_update_bits(afe->regmap, irq_data->irq_en_reg,
+ 1 << irq_data->irq_en_shift,
+ 1 << irq_data->irq_en_shift);
+ return 0;
+ case SNDRV_PCM_TRIGGER_STOP:
+ case SNDRV_PCM_TRIGGER_SUSPEND:
+ mt8188_afe_enable_cm(afe, cm, false);
+
+ ret = mtk_memif_set_disable(afe, id);
+ if (ret)
+ dev_err(afe->dev, "%s(), error, id %d, memif enable, ret %d\n",
+ __func__, id, ret);
+
+ /* disable interrupt */
+ regmap_update_bits(afe->regmap, irq_data->irq_en_reg,
+ 1 << irq_data->irq_en_shift,
+ 0 << irq_data->irq_en_shift);
+ /* and clear pending IRQ */
+ regmap_write(afe->regmap, irq_data->irq_clr_reg,
+ 1 << irq_data->irq_clr_shift);
+ return ret;
+ default:
+ return -EINVAL;
+ }
+}
+
+static const struct snd_soc_dai_ops mt8188_afe_fe_dai_ops = {
+ .startup = mt8188_afe_fe_startup,
+ .shutdown = mt8188_afe_fe_shutdown,
+ .hw_params = mt8188_afe_fe_hw_params,
+ .hw_free = mtk_afe_fe_hw_free,
+ .prepare = mtk_afe_fe_prepare,
+ .trigger = mt8188_afe_fe_trigger,
+};
+
+#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000 |\
+ SNDRV_PCM_RATE_88200 |\
+ SNDRV_PCM_RATE_96000 |\
+ SNDRV_PCM_RATE_176400 |\
+ SNDRV_PCM_RATE_192000 |\
+ SNDRV_PCM_RATE_352800 |\
+ SNDRV_PCM_RATE_384000)
+
+#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
+ SNDRV_PCM_FMTBIT_S24_LE |\
+ SNDRV_PCM_FMTBIT_S32_LE)
+
+static struct snd_soc_dai_driver mt8188_memif_dai_driver[] = {
+ /* FE DAIs: memory intefaces to CPU */
+ {
+ .name = "DL2",
+ .id = MT8188_AFE_MEMIF_DL2,
+ .playback = {
+ .stream_name = "DL2",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL3",
+ .id = MT8188_AFE_MEMIF_DL3,
+ .playback = {
+ .stream_name = "DL3",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL6",
+ .id = MT8188_AFE_MEMIF_DL6,
+ .playback = {
+ .stream_name = "DL6",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL7",
+ .id = MT8188_AFE_MEMIF_DL7,
+ .playback = {
+ .stream_name = "DL7",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL8",
+ .id = MT8188_AFE_MEMIF_DL8,
+ .playback = {
+ .stream_name = "DL8",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL10",
+ .id = MT8188_AFE_MEMIF_DL10,
+ .playback = {
+ .stream_name = "DL10",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "DL11",
+ .id = MT8188_AFE_MEMIF_DL11,
+ .playback = {
+ .stream_name = "DL11",
+ .channels_min = 1,
+ .channels_max = 32,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL1",
+ .id = MT8188_AFE_MEMIF_UL1,
+ .capture = {
+ .stream_name = "UL1",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL2",
+ .id = MT8188_AFE_MEMIF_UL2,
+ .capture = {
+ .stream_name = "UL2",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL3",
+ .id = MT8188_AFE_MEMIF_UL3,
+ .capture = {
+ .stream_name = "UL3",
+ .channels_min = 1,
+ .channels_max = 16,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL4",
+ .id = MT8188_AFE_MEMIF_UL4,
+ .capture = {
+ .stream_name = "UL4",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL5",
+ .id = MT8188_AFE_MEMIF_UL5,
+ .capture = {
+ .stream_name = "UL5",
+ .channels_min = 1,
+ .channels_max = 2,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL6",
+ .id = MT8188_AFE_MEMIF_UL6,
+ .capture = {
+ .stream_name = "UL6",
+ .channels_min = 1,
+ .channels_max = 8,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL8",
+ .id = MT8188_AFE_MEMIF_UL8,
+ .capture = {
+ .stream_name = "UL8",
+ .channels_min = 1,
+ .channels_max = 24,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL9",
+ .id = MT8188_AFE_MEMIF_UL9,
+ .capture = {
+ .stream_name = "UL9",
+ .channels_min = 1,
+ .channels_max = 32,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+ {
+ .name = "UL10",
+ .id = MT8188_AFE_MEMIF_UL10,
+ .capture = {
+ .stream_name = "UL10",
+ .channels_min = 1,
+ .channels_max = 4,
+ .rates = MTK_PCM_RATES,
+ .formats = MTK_PCM_FORMATS,
+ },
+ .ops = &mt8188_afe_fe_dai_ops,
+ },
+};
+
+static const struct snd_kcontrol_new o002_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN2, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN2, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN2, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN2, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN2_2, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I072 Switch", AFE_CONN2_2, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN2_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o003_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN3, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN3, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN3, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN3, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN3_2, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I073 Switch", AFE_CONN3_2, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN3_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o004_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN4, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I014 Switch", AFE_CONN4, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN4, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I074 Switch", AFE_CONN4_2, 10, 1, 0),
+};
+
+static const struct snd_kcontrol_new o005_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN5, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I015 Switch", AFE_CONN5, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN5, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I075 Switch", AFE_CONN5_2, 11, 1, 0),
+};
+
+static const struct snd_kcontrol_new o006_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN6, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I016 Switch", AFE_CONN6, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN6, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I076 Switch", AFE_CONN6_2, 12, 1, 0),
+};
+
+static const struct snd_kcontrol_new o007_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN7, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I017 Switch", AFE_CONN7, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN7, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I077 Switch", AFE_CONN7_2, 13, 1, 0),
+};
+
+static const struct snd_kcontrol_new o008_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I018 Switch", AFE_CONN8, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN8, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I078 Switch", AFE_CONN8_2, 14, 1, 0),
+};
+
+static const struct snd_kcontrol_new o009_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I019 Switch", AFE_CONN9, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN9, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I079 Switch", AFE_CONN9_2, 15, 1, 0),
+};
+
+static const struct snd_kcontrol_new o010_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN10, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I030 Switch", AFE_CONN10, 30, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN10_1, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I072 Switch", AFE_CONN10_2, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I080 Switch", AFE_CONN10_2, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I188 Switch", AFE_CONN10_5, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new o011_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN11, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I031 Switch", AFE_CONN11, 31, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN11_1, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I073 Switch", AFE_CONN11_2, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I081 Switch", AFE_CONN11_2, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I189 Switch", AFE_CONN11_5, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new o012_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN12, 24, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I032 Switch", AFE_CONN12_1, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN12_1, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I074 Switch", AFE_CONN12_2, 10, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I082 Switch", AFE_CONN12_2, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I190 Switch", AFE_CONN12_5, 30, 1, 0),
+};
+
+static const struct snd_kcontrol_new o013_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN13, 25, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I033 Switch", AFE_CONN13_1, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN13_1, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I075 Switch", AFE_CONN13_2, 11, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I083 Switch", AFE_CONN13_2, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I191 Switch", AFE_CONN13_5, 31, 1, 0),
+};
+
+static const struct snd_kcontrol_new o014_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN14, 26, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I034 Switch", AFE_CONN14_1, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN14_1, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I076 Switch", AFE_CONN14_2, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I084 Switch", AFE_CONN14_2, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I192 Switch", AFE_CONN14_6, 0, 1, 0),
+};
+
+static const struct snd_kcontrol_new o015_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN15, 27, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I035 Switch", AFE_CONN15_1, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN15_1, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I077 Switch", AFE_CONN15_2, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I085 Switch", AFE_CONN15_2, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I193 Switch", AFE_CONN15_6, 1, 1, 0),
+};
+
+static const struct snd_kcontrol_new o016_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN16, 28, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I036 Switch", AFE_CONN16_1, 4, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN16_1, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I078 Switch", AFE_CONN16_2, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I086 Switch", AFE_CONN16_2, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I194 Switch", AFE_CONN16_6, 2, 1, 0),
+};
+
+static const struct snd_kcontrol_new o017_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN17, 29, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I037 Switch", AFE_CONN17_1, 5, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN17_1, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I079 Switch", AFE_CONN17_2, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I087 Switch", AFE_CONN17_2, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I195 Switch", AFE_CONN17_6, 3, 1, 0),
+};
+
+static const struct snd_kcontrol_new o018_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I080 Switch", AFE_CONN18_2, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new o019_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I081 Switch", AFE_CONN19_2, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new o020_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I082 Switch", AFE_CONN20_2, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new o021_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I083 Switch", AFE_CONN21_2, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new o022_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I084 Switch", AFE_CONN22_2, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new o023_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I085 Switch", AFE_CONN23_2, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new o024_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I086 Switch", AFE_CONN24_2, 22, 1, 0),
+};
+
+static const struct snd_kcontrol_new o025_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I087 Switch", AFE_CONN25_2, 23, 1, 0),
+};
+
+static const struct snd_kcontrol_new o026_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I046 Switch", AFE_CONN26_1, 14, 1, 0),
+};
+
+static const struct snd_kcontrol_new o027_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN27_1, 15, 1, 0),
+};
+
+static const struct snd_kcontrol_new o028_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN28_1, 16, 1, 0),
+};
+
+static const struct snd_kcontrol_new o029_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN29_1, 17, 1, 0),
+};
+
+static const struct snd_kcontrol_new o030_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN30_1, 18, 1, 0),
+};
+
+static const struct snd_kcontrol_new o031_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN31_1, 19, 1, 0),
+};
+
+static const struct snd_kcontrol_new o032_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN32_1, 20, 1, 0),
+};
+
+static const struct snd_kcontrol_new o033_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN33_1, 21, 1, 0),
+};
+
+static const struct snd_kcontrol_new o034_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN34, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN34, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN34, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN34, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN34_2, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I072 Switch", AFE_CONN34_2, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN34_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o035_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN35, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN35, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN35, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN35, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN35_2, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I073 Switch", AFE_CONN35_2, 9, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN35_5, 8, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN35_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o036_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN36, 0, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN36, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN36, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN36_2, 6, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN36_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o037_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN37, 1, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN37, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN37, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN37_2, 7, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN37_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o038_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN38, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN38_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o039_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN39, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN39_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o040_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN40, 2, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I012 Switch", AFE_CONN40, 12, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN40, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I168 Switch", AFE_CONN40_5, 8, 1, 0),
+};
+
+static const struct snd_kcontrol_new o041_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN41, 3, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I013 Switch", AFE_CONN41, 13, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN41, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I169 Switch", AFE_CONN41_5, 9, 1, 0),
+};
+
+static const struct snd_kcontrol_new o042_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I014 Switch", AFE_CONN42, 14, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN42, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new o043_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I015 Switch", AFE_CONN43, 15, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN43, 25, 1, 0),
+};
+
+static const struct snd_kcontrol_new o044_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I016 Switch", AFE_CONN44, 16, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I026 Switch", AFE_CONN44, 26, 1, 0),
+};
+
+static const struct snd_kcontrol_new o045_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I017 Switch", AFE_CONN45, 17, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I027 Switch", AFE_CONN45, 27, 1, 0),
+};
+
+static const struct snd_kcontrol_new o046_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I018 Switch", AFE_CONN46, 18, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I028 Switch", AFE_CONN46, 28, 1, 0),
+};
+
+static const struct snd_kcontrol_new o047_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I019 Switch", AFE_CONN47, 19, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I029 Switch", AFE_CONN47, 29, 1, 0),
+};
+
+static const struct snd_kcontrol_new o182_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN182, 20, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN182, 22, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I024 Switch", AFE_CONN182, 24, 1, 0),
+};
+
+static const struct snd_kcontrol_new o183_mix[] = {
+ SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN183, 21, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN183, 23, 1, 0),
+ SOC_DAPM_SINGLE_AUTODISABLE("I025 Switch", AFE_CONN183, 25, 1, 0),
+};
+
+static const char * const dl8_dl11_data_sel_mux_text[] = {
+ "dl8", "dl11",
+};
+
+static SOC_ENUM_SINGLE_DECL(dl8_dl11_data_sel_mux_enum,
+ AFE_DAC_CON2, 0, dl8_dl11_data_sel_mux_text);
+
+static const struct snd_kcontrol_new dl8_dl11_data_sel_mux =
+ SOC_DAPM_ENUM("DL8_DL11 Sink",
+ dl8_dl11_data_sel_mux_enum);
+
+static const struct snd_soc_dapm_widget mt8188_memif_widgets[] = {
+ /* DL6 */
+ SND_SOC_DAPM_MIXER("I000", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I001", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL3 */
+ SND_SOC_DAPM_MIXER("I020", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I021", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL11 */
+ SND_SOC_DAPM_MIXER("I022", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I023", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I024", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I025", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I026", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I027", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I028", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I029", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I030", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I031", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I034", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I035", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I036", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I037", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL11/DL8 */
+ SND_SOC_DAPM_MIXER("I046", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I047", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I048", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I049", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I050", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I051", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I052", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I053", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I054", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I055", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I056", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I057", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I058", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I059", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I060", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I061", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ /* DL2 */
+ SND_SOC_DAPM_MIXER("I070", SND_SOC_NOPM, 0, 0, NULL, 0),
+ SND_SOC_DAPM_MIXER("I071", SND_SOC_NOPM, 0, 0, NULL, 0),
+
+ SND_SOC_DAPM_MUX("DL8_DL11 Mux",
+ SND_SOC_NOPM, 0, 0, &dl8_dl11_data_sel_mux),
+
+ /* UL9 */
+ SND_SOC_DAPM_MIXER("O002", SND_SOC_NOPM, 0, 0,
+ o002_mix, ARRAY_SIZE(o002_mix)),
+ SND_SOC_DAPM_MIXER("O003", SND_SOC_NOPM, 0, 0,
+ o003_mix, ARRAY_SIZE(o003_mix)),
+ SND_SOC_DAPM_MIXER("O004", SND_SOC_NOPM, 0, 0,
+ o004_mix, ARRAY_SIZE(o004_mix)),
+ SND_SOC_DAPM_MIXER("O005", SND_SOC_NOPM, 0, 0,
+ o005_mix, ARRAY_SIZE(o005_mix)),
+ SND_SOC_DAPM_MIXER("O006", SND_SOC_NOPM, 0, 0,
+ o006_mix, ARRAY_SIZE(o006_mix)),
+ SND_SOC_DAPM_MIXER("O007", SND_SOC_NOPM, 0, 0,
+ o007_mix, ARRAY_SIZE(o007_mix)),
+ SND_SOC_DAPM_MIXER("O008", SND_SOC_NOPM, 0, 0,
+ o008_mix, ARRAY_SIZE(o008_mix)),
+ SND_SOC_DAPM_MIXER("O009", SND_SOC_NOPM, 0, 0,
+ o009_mix, ARRAY_SIZE(o009_mix)),
+ SND_SOC_DAPM_MIXER("O010", SND_SOC_NOPM, 0, 0,
+ o010_mix, ARRAY_SIZE(o010_mix)),
+ SND_SOC_DAPM_MIXER("O011", SND_SOC_NOPM, 0, 0,
+ o011_mix, ARRAY_SIZE(o011_mix)),
+ SND_SOC_DAPM_MIXER("O012", SND_SOC_NOPM, 0, 0,
+ o012_mix, ARRAY_SIZE(o012_mix)),
+ SND_SOC_DAPM_MIXER("O013", SND_SOC_NOPM, 0, 0,
+ o013_mix, ARRAY_SIZE(o013_mix)),
+ SND_SOC_DAPM_MIXER("O014", SND_SOC_NOPM, 0, 0,
+ o014_mix, ARRAY_SIZE(o014_mix)),
+ SND_SOC_DAPM_MIXER("O015", SND_SOC_NOPM, 0, 0,
+ o015_mix, ARRAY_SIZE(o015_mix)),
+ SND_SOC_DAPM_MIXER("O016", SND_SOC_NOPM, 0, 0,
+ o016_mix, ARRAY_SIZE(o016_mix)),
+ SND_SOC_DAPM_MIXER("O017", SND_SOC_NOPM, 0, 0,
+ o017_mix, ARRAY_SIZE(o017_mix)),
+ SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0,
+ o018_mix, ARRAY_SIZE(o018_mix)),
+ SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0,
+ o019_mix, ARRAY_SIZE(o019_mix)),
+ SND_SOC_DAPM_MIXER("O020", SND_SOC_NOPM, 0, 0,
+ o020_mix, ARRAY_SIZE(o020_mix)),
+ SND_SOC_DAPM_MIXER("O021", SND_SOC_NOPM, 0, 0,
+ o021_mix, ARRAY_SIZE(o021_mix)),
+ SND_SOC_DAPM_MIXER("O022", SND_SOC_NOPM, 0, 0,
+ o022_mix, ARRAY_SIZE(o022_mix)),
+ SND_SOC_DAPM_MIXER("O023", SND_SOC_NOPM, 0, 0,
+ o023_mix, ARRAY_SIZE(o023_mix)),
+ SND_SOC_DAPM_MIXER("O024", SND_SOC_NOPM, 0, 0,
+ o024_mix, ARRAY_SIZE(o024_mix)),
+ SND_SOC_DAPM_MIXER("O025", SND_SOC_NOPM, 0, 0,
+ o025_mix, ARRAY_SIZE(o025_mix)),
+ SND_SOC_DAPM_MIXER("O026", SND_SOC_NOPM, 0, 0,
+ o026_mix, ARRAY_SIZE(o026_mix)),
+ SND_SOC_DAPM_MIXER("O027", SND_SOC_NOPM, 0, 0,
+ o027_mix, ARRAY_SIZE(o027_mix)),
+ SND_SOC_DAPM_MIXER("O028", SND_SOC_NOPM, 0, 0,
+ o028_mix, ARRAY_SIZE(o028_mix)),
+ SND_SOC_DAPM_MIXER("O029", SND_SOC_NOPM, 0, 0,
+ o029_mix, ARRAY_SIZE(o029_mix)),
+ SND_SOC_DAPM_MIXER("O030", SND_SOC_NOPM, 0, 0,
+ o030_mix, ARRAY_SIZE(o030_mix)),
+ SND_SOC_DAPM_MIXER("O031", SND_SOC_NOPM, 0, 0,
+ o031_mix, ARRAY_SIZE(o031_mix)),
+ SND_SOC_DAPM_MIXER("O032", SND_SOC_NOPM, 0, 0,
+ o032_mix, ARRAY_SIZE(o032_mix)),
+ SND_SOC_DAPM_MIXER("O033", SND_SOC_NOPM, 0, 0,
+ o033_mix, ARRAY_SIZE(o033_mix)),
+
+ /* UL4 */
+ SND_SOC_DAPM_MIXER("O034", SND_SOC_NOPM, 0, 0,
+ o034_mix, ARRAY_SIZE(o034_mix)),
+ SND_SOC_DAPM_MIXER("O035", SND_SOC_NOPM, 0, 0,
+ o035_mix, ARRAY_SIZE(o035_mix)),
+
+ /* UL5 */
+ SND_SOC_DAPM_MIXER("O036", SND_SOC_NOPM, 0, 0,
+ o036_mix, ARRAY_SIZE(o036_mix)),
+ SND_SOC_DAPM_MIXER("O037", SND_SOC_NOPM, 0, 0,
+ o037_mix, ARRAY_SIZE(o037_mix)),
+
+ /* UL10 */
+ SND_SOC_DAPM_MIXER("O038", SND_SOC_NOPM, 0, 0,
+ o038_mix, ARRAY_SIZE(o038_mix)),
+ SND_SOC_DAPM_MIXER("O039", SND_SOC_NOPM, 0, 0,
+ o039_mix, ARRAY_SIZE(o039_mix)),
+ SND_SOC_DAPM_MIXER("O182", SND_SOC_NOPM, 0, 0,
+ o182_mix, ARRAY_SIZE(o182_mix)),
+ SND_SOC_DAPM_MIXER("O183", SND_SOC_NOPM, 0, 0,
+ o183_mix, ARRAY_SIZE(o183_mix)),
+
+ /* UL2 */
+ SND_SOC_DAPM_MIXER("O040", SND_SOC_NOPM, 0, 0,
+ o040_mix, ARRAY_SIZE(o040_mix)),
+ SND_SOC_DAPM_MIXER("O041", SND_SOC_NOPM, 0, 0,
+ o041_mix, ARRAY_SIZE(o041_mix)),
+ SND_SOC_DAPM_MIXER("O042", SND_SOC_NOPM, 0, 0,
+ o042_mix, ARRAY_SIZE(o042_mix)),
+ SND_SOC_DAPM_MIXER("O043", SND_SOC_NOPM, 0, 0,
+ o043_mix, ARRAY_SIZE(o043_mix)),
+ SND_SOC_DAPM_MIXER("O044", SND_SOC_NOPM, 0, 0,
+ o044_mix, ARRAY_SIZE(o044_mix)),
+ SND_SOC_DAPM_MIXER("O045", SND_SOC_NOPM, 0, 0,
+ o045_mix, ARRAY_SIZE(o045_mix)),
+ SND_SOC_DAPM_MIXER("O046", SND_SOC_NOPM, 0, 0,
+ o046_mix, ARRAY_SIZE(o046_mix)),
+ SND_SOC_DAPM_MIXER("O047", SND_SOC_NOPM, 0, 0,
+ o047_mix, ARRAY_SIZE(o047_mix)),
+};
+
+static const struct snd_soc_dapm_route mt8188_memif_routes[] = {
+ {"I000", NULL, "DL6"},
+ {"I001", NULL, "DL6"},
+
+ {"I020", NULL, "DL3"},
+ {"I021", NULL, "DL3"},
+
+ {"I022", NULL, "DL11"},
+ {"I023", NULL, "DL11"},
+ {"I024", NULL, "DL11"},
+ {"I025", NULL, "DL11"},
+ {"I026", NULL, "DL11"},
+ {"I027", NULL, "DL11"},
+ {"I028", NULL, "DL11"},
+ {"I029", NULL, "DL11"},
+ {"I030", NULL, "DL11"},
+ {"I031", NULL, "DL11"},
+ {"I032", NULL, "DL11"},
+ {"I033", NULL, "DL11"},
+ {"I034", NULL, "DL11"},
+ {"I035", NULL, "DL11"},
+ {"I036", NULL, "DL11"},
+ {"I037", NULL, "DL11"},
+
+ {"DL8_DL11 Mux", "dl8", "DL8"},
+ {"DL8_DL11 Mux", "dl11", "DL11"},
+
+ {"I046", NULL, "DL8_DL11 Mux"},
+ {"I047", NULL, "DL8_DL11 Mux"},
+ {"I048", NULL, "DL8_DL11 Mux"},
+ {"I049", NULL, "DL8_DL11 Mux"},
+ {"I050", NULL, "DL8_DL11 Mux"},
+ {"I051", NULL, "DL8_DL11 Mux"},
+ {"I052", NULL, "DL8_DL11 Mux"},
+ {"I053", NULL, "DL8_DL11 Mux"},
+ {"I054", NULL, "DL8_DL11 Mux"},
+ {"I055", NULL, "DL8_DL11 Mux"},
+ {"I056", NULL, "DL8_DL11 Mux"},
+ {"I057", NULL, "DL8_DL11 Mux"},
+ {"I058", NULL, "DL8_DL11 Mux"},
+ {"I059", NULL, "DL8_DL11 Mux"},
+ {"I060", NULL, "DL8_DL11 Mux"},
+ {"I061", NULL, "DL8_DL11 Mux"},
+
+ {"I070", NULL, "DL2"},
+ {"I071", NULL, "DL2"},
+
+ {"UL9", NULL, "O002"},
+ {"UL9", NULL, "O003"},
+ {"UL9", NULL, "O004"},
+ {"UL9", NULL, "O005"},
+ {"UL9", NULL, "O006"},
+ {"UL9", NULL, "O007"},
+ {"UL9", NULL, "O008"},
+ {"UL9", NULL, "O009"},
+ {"UL9", NULL, "O010"},
+ {"UL9", NULL, "O011"},
+ {"UL9", NULL, "O012"},
+ {"UL9", NULL, "O013"},
+ {"UL9", NULL, "O014"},
+ {"UL9", NULL, "O015"},
+ {"UL9", NULL, "O016"},
+ {"UL9", NULL, "O017"},
+ {"UL9", NULL, "O018"},
+ {"UL9", NULL, "O019"},
+ {"UL9", NULL, "O020"},
+ {"UL9", NULL, "O021"},
+ {"UL9", NULL, "O022"},
+ {"UL9", NULL, "O023"},
+ {"UL9", NULL, "O024"},
+ {"UL9", NULL, "O025"},
+ {"UL9", NULL, "O026"},
+ {"UL9", NULL, "O027"},
+ {"UL9", NULL, "O028"},
+ {"UL9", NULL, "O029"},
+ {"UL9", NULL, "O030"},
+ {"UL9", NULL, "O031"},
+ {"UL9", NULL, "O032"},
+ {"UL9", NULL, "O033"},
+
+ {"UL4", NULL, "O034"},
+ {"UL4", NULL, "O035"},
+
+ {"UL5", NULL, "O036"},
+ {"UL5", NULL, "O037"},
+
+ {"UL10", NULL, "O038"},
+ {"UL10", NULL, "O039"},
+ {"UL10", NULL, "O182"},
+ {"UL10", NULL, "O183"},
+
+ {"UL2", NULL, "O040"},
+ {"UL2", NULL, "O041"},
+ {"UL2", NULL, "O042"},
+ {"UL2", NULL, "O043"},
+ {"UL2", NULL, "O044"},
+ {"UL2", NULL, "O045"},
+ {"UL2", NULL, "O046"},
+ {"UL2", NULL, "O047"},
+
+ {"O004", "I000 Switch", "I000"},
+ {"O005", "I001 Switch", "I001"},
+
+ {"O006", "I000 Switch", "I000"},
+ {"O007", "I001 Switch", "I001"},
+
+ {"O010", "I022 Switch", "I022"},
+ {"O011", "I023 Switch", "I023"},
+ {"O012", "I024 Switch", "I024"},
+ {"O013", "I025 Switch", "I025"},
+ {"O014", "I026 Switch", "I026"},
+ {"O015", "I027 Switch", "I027"},
+ {"O016", "I028 Switch", "I028"},
+ {"O017", "I029 Switch", "I029"},
+
+ {"O010", "I046 Switch", "I046"},
+ {"O011", "I047 Switch", "I047"},
+ {"O012", "I048 Switch", "I048"},
+ {"O013", "I049 Switch", "I049"},
+ {"O014", "I050 Switch", "I050"},
+ {"O015", "I051 Switch", "I051"},
+ {"O016", "I052 Switch", "I052"},
+ {"O017", "I053 Switch", "I053"},
+
+ {"O002", "I022 Switch", "I022"},
+ {"O003", "I023 Switch", "I023"},
+ {"O004", "I024 Switch", "I024"},
+ {"O005", "I025 Switch", "I025"},
+ {"O006", "I026 Switch", "I026"},
+ {"O007", "I027 Switch", "I027"},
+ {"O008", "I028 Switch", "I028"},
+ {"O009", "I029 Switch", "I029"},
+ {"O010", "I030 Switch", "I030"},
+ {"O011", "I031 Switch", "I031"},
+ {"O012", "I032 Switch", "I032"},
+ {"O013", "I033 Switch", "I033"},
+ {"O014", "I034 Switch", "I034"},
+ {"O015", "I035 Switch", "I035"},
+ {"O016", "I036 Switch", "I036"},
+ {"O017", "I037 Switch", "I037"},
+ {"O026", "I046 Switch", "I046"},
+ {"O027", "I047 Switch", "I047"},
+ {"O028", "I048 Switch", "I048"},
+ {"O029", "I049 Switch", "I049"},
+ {"O030", "I050 Switch", "I050"},
+ {"O031", "I051 Switch", "I051"},
+ {"O032", "I052 Switch", "I052"},
+ {"O033", "I053 Switch", "I053"},
+
+ {"O002", "I000 Switch", "I000"},
+ {"O003", "I001 Switch", "I001"},
+ {"O002", "I020 Switch", "I020"},
+ {"O003", "I021 Switch", "I021"},
+ {"O002", "I070 Switch", "I070"},
+ {"O003", "I071 Switch", "I071"},
+
+ {"O034", "I000 Switch", "I000"},
+ {"O035", "I001 Switch", "I001"},
+ {"O034", "I002 Switch", "I002"},
+ {"O035", "I003 Switch", "I003"},
+ {"O034", "I012 Switch", "I012"},
+ {"O035", "I013 Switch", "I013"},
+ {"O034", "I020 Switch", "I020"},
+ {"O035", "I021 Switch", "I021"},
+ {"O034", "I070 Switch", "I070"},
+ {"O035", "I071 Switch", "I071"},
+ {"O034", "I072 Switch", "I072"},
+ {"O035", "I073 Switch", "I073"},
+
+ {"O036", "I000 Switch", "I000"},
+ {"O037", "I001 Switch", "I001"},
+ {"O036", "I012 Switch", "I012"},
+ {"O037", "I013 Switch", "I013"},
+ {"O036", "I020 Switch", "I020"},
+ {"O037", "I021 Switch", "I021"},
+ {"O036", "I070 Switch", "I070"},
+ {"O037", "I071 Switch", "I071"},
+ {"O036", "I168 Switch", "I168"},
+ {"O037", "I169 Switch", "I169"},
+
+ {"O038", "I022 Switch", "I022"},
+ {"O039", "I023 Switch", "I023"},
+ {"O182", "I024 Switch", "I024"},
+ {"O183", "I025 Switch", "I025"},
+
+ {"O038", "I168 Switch", "I168"},
+ {"O039", "I169 Switch", "I169"},
+
+ {"O182", "I020 Switch", "I020"},
+ {"O183", "I021 Switch", "I021"},
+
+ {"O182", "I022 Switch", "I022"},
+ {"O183", "I023 Switch", "I023"},
+
+ {"O040", "I022 Switch", "I022"},
+ {"O041", "I023 Switch", "I023"},
+ {"O042", "I024 Switch", "I024"},
+ {"O043", "I025 Switch", "I025"},
+ {"O044", "I026 Switch", "I026"},
+ {"O045", "I027 Switch", "I027"},
+ {"O046", "I028 Switch", "I028"},
+ {"O047", "I029 Switch", "I029"},
+
+ {"O040", "I002 Switch", "I002"},
+ {"O041", "I003 Switch", "I003"},
+
+ {"O002", "I012 Switch", "I012"},
+ {"O003", "I013 Switch", "I013"},
+ {"O004", "I014 Switch", "I014"},
+ {"O005", "I015 Switch", "I015"},
+ {"O006", "I016 Switch", "I016"},
+ {"O007", "I017 Switch", "I017"},
+ {"O008", "I018 Switch", "I018"},
+ {"O009", "I019 Switch", "I019"},
+ {"O010", "I188 Switch", "I188"},
+ {"O011", "I189 Switch", "I189"},
+ {"O012", "I190 Switch", "I190"},
+ {"O013", "I191 Switch", "I191"},
+ {"O014", "I192 Switch", "I192"},
+ {"O015", "I193 Switch", "I193"},
+ {"O016", "I194 Switch", "I194"},
+ {"O017", "I195 Switch", "I195"},
+
+ {"O040", "I012 Switch", "I012"},
+ {"O041", "I013 Switch", "I013"},
+ {"O042", "I014 Switch", "I014"},
+ {"O043", "I015 Switch", "I015"},
+ {"O044", "I016 Switch", "I016"},
+ {"O045", "I017 Switch", "I017"},
+ {"O046", "I018 Switch", "I018"},
+ {"O047", "I019 Switch", "I019"},
+
+ {"O002", "I072 Switch", "I072"},
+ {"O003", "I073 Switch", "I073"},
+ {"O004", "I074 Switch", "I074"},
+ {"O005", "I075 Switch", "I075"},
+ {"O006", "I076 Switch", "I076"},
+ {"O007", "I077 Switch", "I077"},
+ {"O008", "I078 Switch", "I078"},
+ {"O009", "I079 Switch", "I079"},
+ {"O010", "I080 Switch", "I080"},
+ {"O011", "I081 Switch", "I081"},
+ {"O012", "I082 Switch", "I082"},
+ {"O013", "I083 Switch", "I083"},
+ {"O014", "I084 Switch", "I084"},
+ {"O015", "I085 Switch", "I085"},
+ {"O016", "I086 Switch", "I086"},
+ {"O017", "I087 Switch", "I087"},
+
+ {"O010", "I072 Switch", "I072"},
+ {"O011", "I073 Switch", "I073"},
+ {"O012", "I074 Switch", "I074"},
+ {"O013", "I075 Switch", "I075"},
+ {"O014", "I076 Switch", "I076"},
+ {"O015", "I077 Switch", "I077"},
+ {"O016", "I078 Switch", "I078"},
+ {"O017", "I079 Switch", "I079"},
+ {"O018", "I080 Switch", "I080"},
+ {"O019", "I081 Switch", "I081"},
+ {"O020", "I082 Switch", "I082"},
+ {"O021", "I083 Switch", "I083"},
+ {"O022", "I084 Switch", "I084"},
+ {"O023", "I085 Switch", "I085"},
+ {"O024", "I086 Switch", "I086"},
+ {"O025", "I087 Switch", "I087"},
+
+ {"O002", "I168 Switch", "I168"},
+ {"O003", "I169 Switch", "I169"},
+
+ {"O034", "I168 Switch", "I168"},
+ {"O035", "I168 Switch", "I168"},
+ {"O035", "I169 Switch", "I169"},
+
+ {"O040", "I168 Switch", "I168"},
+ {"O041", "I169 Switch", "I169"},
+};
+
+static const struct snd_soc_component_driver mt8188_afe_pcm_dai_component = {
+ .name = "mt8188-afe-pcm-dai",
+};
+
+static const struct mtk_base_memif_data memif_data[MT8188_AFE_MEMIF_NUM] = {
+ [MT8188_AFE_MEMIF_DL2] = {
+ .name = "DL2",
+ .id = MT8188_AFE_MEMIF_DL2,
+ .reg_ofs_base = AFE_DL2_BASE,
+ .reg_ofs_cur = AFE_DL2_CUR,
+ .reg_ofs_end = AFE_DL2_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON0,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 18,
+ .hd_reg = AFE_DL2_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 18,
+ .ch_num_reg = AFE_DL2_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 18,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 18,
+ },
+ [MT8188_AFE_MEMIF_DL3] = {
+ .name = "DL3",
+ .id = MT8188_AFE_MEMIF_DL3,
+ .reg_ofs_base = AFE_DL3_BASE,
+ .reg_ofs_cur = AFE_DL3_CUR,
+ .reg_ofs_end = AFE_DL3_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON0,
+ .fs_shift = 15,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 19,
+ .hd_reg = AFE_DL3_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 19,
+ .ch_num_reg = AFE_DL3_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 19,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 19,
+ },
+ [MT8188_AFE_MEMIF_DL6] = {
+ .name = "DL6",
+ .id = MT8188_AFE_MEMIF_DL6,
+ .reg_ofs_base = AFE_DL6_BASE,
+ .reg_ofs_cur = AFE_DL6_CUR,
+ .reg_ofs_end = AFE_DL6_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 0,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 22,
+ .hd_reg = AFE_DL6_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 22,
+ .ch_num_reg = AFE_DL6_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 22,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 22,
+ },
+ [MT8188_AFE_MEMIF_DL7] = {
+ .name = "DL7",
+ .id = MT8188_AFE_MEMIF_DL7,
+ .reg_ofs_base = AFE_DL7_BASE,
+ .reg_ofs_cur = AFE_DL7_CUR,
+ .reg_ofs_end = AFE_DL7_END,
+ .fs_reg = -1,
+ .fs_shift = 0,
+ .fs_maskbit = 0,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 23,
+ .hd_reg = AFE_DL7_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 23,
+ .ch_num_reg = AFE_DL7_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 23,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 23,
+ },
+ [MT8188_AFE_MEMIF_DL8] = {
+ .name = "DL8",
+ .id = MT8188_AFE_MEMIF_DL8,
+ .reg_ofs_base = AFE_DL8_BASE,
+ .reg_ofs_cur = AFE_DL8_CUR,
+ .reg_ofs_end = AFE_DL8_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 24,
+ .hd_reg = AFE_DL8_CON0,
+ .hd_shift = 6,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 24,
+ .ch_num_reg = AFE_DL8_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x3f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 24,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 24,
+ },
+ [MT8188_AFE_MEMIF_DL10] = {
+ .name = "DL10",
+ .id = MT8188_AFE_MEMIF_DL10,
+ .reg_ofs_base = AFE_DL10_BASE,
+ .reg_ofs_cur = AFE_DL10_CUR,
+ .reg_ofs_end = AFE_DL10_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 20,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 26,
+ .hd_reg = AFE_DL10_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 26,
+ .ch_num_reg = AFE_DL10_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x1f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 26,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 26,
+ },
+ [MT8188_AFE_MEMIF_DL11] = {
+ .name = "DL11",
+ .id = MT8188_AFE_MEMIF_DL11,
+ .reg_ofs_base = AFE_DL11_BASE,
+ .reg_ofs_cur = AFE_DL11_CUR,
+ .reg_ofs_end = AFE_DL11_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON1,
+ .fs_shift = 25,
+ .fs_maskbit = 0x1f,
+ .mono_reg = -1,
+ .mono_shift = 0,
+ .int_odd_flag_reg = -1,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 27,
+ .hd_reg = AFE_DL11_CON0,
+ .hd_shift = 7,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 27,
+ .ch_num_reg = AFE_DL11_CON0,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0x7f,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 27,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 27,
+ },
+ [MT8188_AFE_MEMIF_UL1] = {
+ .name = "UL1",
+ .id = MT8188_AFE_MEMIF_UL1,
+ .reg_ofs_base = AFE_UL1_BASE,
+ .reg_ofs_cur = AFE_UL1_CUR,
+ .reg_ofs_end = AFE_UL1_END,
+ .fs_reg = -1,
+ .fs_shift = 0,
+ .fs_maskbit = 0,
+ .mono_reg = AFE_UL1_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL1_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 1,
+ .hd_reg = AFE_UL1_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 0,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 0,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 0,
+ },
+ [MT8188_AFE_MEMIF_UL2] = {
+ .name = "UL2",
+ .id = MT8188_AFE_MEMIF_UL2,
+ .reg_ofs_base = AFE_UL2_BASE,
+ .reg_ofs_cur = AFE_UL2_CUR,
+ .reg_ofs_end = AFE_UL2_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 5,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL2_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL2_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 2,
+ .hd_reg = AFE_UL2_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 1,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 1,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 1,
+ },
+ [MT8188_AFE_MEMIF_UL3] = {
+ .name = "UL3",
+ .id = MT8188_AFE_MEMIF_UL3,
+ .reg_ofs_base = AFE_UL3_BASE,
+ .reg_ofs_cur = AFE_UL3_CUR,
+ .reg_ofs_end = AFE_UL3_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL3_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL3_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 3,
+ .hd_reg = AFE_UL3_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 2,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 2,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 2,
+ },
+ [MT8188_AFE_MEMIF_UL4] = {
+ .name = "UL4",
+ .id = MT8188_AFE_MEMIF_UL4,
+ .reg_ofs_base = AFE_UL4_BASE,
+ .reg_ofs_cur = AFE_UL4_CUR,
+ .reg_ofs_end = AFE_UL4_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 15,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL4_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL4_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 4,
+ .hd_reg = AFE_UL4_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 3,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 3,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 3,
+ },
+ [MT8188_AFE_MEMIF_UL5] = {
+ .name = "UL5",
+ .id = MT8188_AFE_MEMIF_UL5,
+ .reg_ofs_base = AFE_UL5_BASE,
+ .reg_ofs_cur = AFE_UL5_CUR,
+ .reg_ofs_end = AFE_UL5_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON2,
+ .fs_shift = 20,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL5_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL5_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 5,
+ .hd_reg = AFE_UL5_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 4,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 4,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 4,
+ },
+ [MT8188_AFE_MEMIF_UL6] = {
+ .name = "UL6",
+ .id = MT8188_AFE_MEMIF_UL6,
+ .reg_ofs_base = AFE_UL6_BASE,
+ .reg_ofs_cur = AFE_UL6_CUR,
+ .reg_ofs_end = AFE_UL6_END,
+ .fs_reg = -1,
+ .fs_shift = 0,
+ .fs_maskbit = 0,
+ .mono_reg = AFE_UL6_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL6_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 6,
+ .hd_reg = AFE_UL6_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 5,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 5,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 5,
+ },
+ [MT8188_AFE_MEMIF_UL8] = {
+ .name = "UL8",
+ .id = MT8188_AFE_MEMIF_UL8,
+ .reg_ofs_base = AFE_UL8_BASE,
+ .reg_ofs_cur = AFE_UL8_CUR,
+ .reg_ofs_end = AFE_UL8_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON3,
+ .fs_shift = 5,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL8_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL8_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 8,
+ .hd_reg = AFE_UL8_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 7,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 7,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 7,
+ },
+ [MT8188_AFE_MEMIF_UL9] = {
+ .name = "UL9",
+ .id = MT8188_AFE_MEMIF_UL9,
+ .reg_ofs_base = AFE_UL9_BASE,
+ .reg_ofs_cur = AFE_UL9_CUR,
+ .reg_ofs_end = AFE_UL9_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON3,
+ .fs_shift = 10,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL9_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL9_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 9,
+ .hd_reg = AFE_UL9_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 8,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 8,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 8,
+ },
+ [MT8188_AFE_MEMIF_UL10] = {
+ .name = "UL10",
+ .id = MT8188_AFE_MEMIF_UL10,
+ .reg_ofs_base = AFE_UL10_BASE,
+ .reg_ofs_cur = AFE_UL10_CUR,
+ .reg_ofs_end = AFE_UL10_END,
+ .fs_reg = AFE_MEMIF_AGENT_FS_CON3,
+ .fs_shift = 15,
+ .fs_maskbit = 0x1f,
+ .mono_reg = AFE_UL10_CON0,
+ .mono_shift = 1,
+ .int_odd_flag_reg = AFE_UL10_CON0,
+ .int_odd_flag_shift = 0,
+ .enable_reg = AFE_DAC_CON0,
+ .enable_shift = 10,
+ .hd_reg = AFE_UL10_CON0,
+ .hd_shift = 5,
+ .agent_disable_reg = AUDIO_TOP_CON5,
+ .agent_disable_shift = 9,
+ .ch_num_reg = -1,
+ .ch_num_shift = 0,
+ .ch_num_maskbit = 0,
+ .msb_reg = AFE_NORMAL_BASE_ADR_MSB,
+ .msb_shift = 9,
+ .msb_end_reg = AFE_NORMAL_END_ADR_MSB,
+ .msb_end_shift = 9,
+ },
+};
+
+static const struct mtk_base_irq_data irq_data[MT8188_AFE_IRQ_NUM] = {
+ [MT8188_AFE_IRQ_1] = {
+ .id = MT8188_AFE_IRQ_1,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ1_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 0,
+ .irq_status_shift = 16,
+ },
+ [MT8188_AFE_IRQ_2] = {
+ .id = MT8188_AFE_IRQ_2,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ2_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 1,
+ .irq_status_shift = 17,
+ },
+ [MT8188_AFE_IRQ_3] = {
+ .id = MT8188_AFE_IRQ_3,
+ .irq_cnt_reg = AFE_IRQ3_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ3_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 2,
+ .irq_status_shift = 18,
+ },
+ [MT8188_AFE_IRQ_8] = {
+ .id = MT8188_AFE_IRQ_8,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ8_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 7,
+ .irq_status_shift = 23,
+ },
+ [MT8188_AFE_IRQ_9] = {
+ .id = MT8188_AFE_IRQ_9,
+ .irq_cnt_reg = AFE_IRQ9_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ9_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 8,
+ .irq_status_shift = 24,
+ },
+ [MT8188_AFE_IRQ_10] = {
+ .id = MT8188_AFE_IRQ_10,
+ .irq_cnt_reg = -1,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0,
+ .irq_fs_reg = -1,
+ .irq_fs_shift = 0,
+ .irq_fs_maskbit = 0,
+ .irq_en_reg = AFE_IRQ10_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = AFE_IRQ_MCU_CLR,
+ .irq_clr_shift = 9,
+ .irq_status_shift = 25,
+ },
+ [MT8188_AFE_IRQ_13] = {
+ .id = MT8188_AFE_IRQ_13,
+ .irq_cnt_reg = ASYS_IRQ1_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ1_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ1_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 0,
+ .irq_status_shift = 0,
+ },
+ [MT8188_AFE_IRQ_14] = {
+ .id = MT8188_AFE_IRQ_14,
+ .irq_cnt_reg = ASYS_IRQ2_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ2_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ2_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 1,
+ .irq_status_shift = 1,
+ },
+ [MT8188_AFE_IRQ_15] = {
+ .id = MT8188_AFE_IRQ_15,
+ .irq_cnt_reg = ASYS_IRQ3_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ3_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ3_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 2,
+ .irq_status_shift = 2,
+ },
+ [MT8188_AFE_IRQ_16] = {
+ .id = MT8188_AFE_IRQ_16,
+ .irq_cnt_reg = ASYS_IRQ4_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ4_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ4_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 3,
+ .irq_status_shift = 3,
+ },
+ [MT8188_AFE_IRQ_17] = {
+ .id = MT8188_AFE_IRQ_17,
+ .irq_cnt_reg = ASYS_IRQ5_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ5_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ5_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 4,
+ .irq_status_shift = 4,
+ },
+ [MT8188_AFE_IRQ_18] = {
+ .id = MT8188_AFE_IRQ_18,
+ .irq_cnt_reg = ASYS_IRQ6_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ6_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ6_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 5,
+ .irq_status_shift = 5,
+ },
+ [MT8188_AFE_IRQ_19] = {
+ .id = MT8188_AFE_IRQ_19,
+ .irq_cnt_reg = ASYS_IRQ7_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ7_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ7_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 6,
+ .irq_status_shift = 6,
+ },
+ [MT8188_AFE_IRQ_20] = {
+ .id = MT8188_AFE_IRQ_20,
+ .irq_cnt_reg = ASYS_IRQ8_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ8_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ8_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 7,
+ .irq_status_shift = 7,
+ },
+ [MT8188_AFE_IRQ_21] = {
+ .id = MT8188_AFE_IRQ_21,
+ .irq_cnt_reg = ASYS_IRQ9_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ9_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ9_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 8,
+ .irq_status_shift = 8,
+ },
+ [MT8188_AFE_IRQ_22] = {
+ .id = MT8188_AFE_IRQ_22,
+ .irq_cnt_reg = ASYS_IRQ10_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ10_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ10_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 9,
+ .irq_status_shift = 9,
+ },
+ [MT8188_AFE_IRQ_23] = {
+ .id = MT8188_AFE_IRQ_23,
+ .irq_cnt_reg = ASYS_IRQ11_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ11_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ11_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 10,
+ .irq_status_shift = 10,
+ },
+ [MT8188_AFE_IRQ_24] = {
+ .id = MT8188_AFE_IRQ_24,
+ .irq_cnt_reg = ASYS_IRQ12_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ12_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ12_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 11,
+ .irq_status_shift = 11,
+ },
+ [MT8188_AFE_IRQ_25] = {
+ .id = MT8188_AFE_IRQ_25,
+ .irq_cnt_reg = ASYS_IRQ13_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ13_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ13_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 12,
+ .irq_status_shift = 12,
+ },
+ [MT8188_AFE_IRQ_26] = {
+ .id = MT8188_AFE_IRQ_26,
+ .irq_cnt_reg = ASYS_IRQ14_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ14_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ14_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 13,
+ .irq_status_shift = 13,
+ },
+ [MT8188_AFE_IRQ_27] = {
+ .id = MT8188_AFE_IRQ_27,
+ .irq_cnt_reg = ASYS_IRQ15_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ15_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ15_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 14,
+ .irq_status_shift = 14,
+ },
+ [MT8188_AFE_IRQ_28] = {
+ .id = MT8188_AFE_IRQ_28,
+ .irq_cnt_reg = ASYS_IRQ16_CON,
+ .irq_cnt_shift = 0,
+ .irq_cnt_maskbit = 0xffffff,
+ .irq_fs_reg = ASYS_IRQ16_CON,
+ .irq_fs_shift = 24,
+ .irq_fs_maskbit = 0x1ffff,
+ .irq_en_reg = ASYS_IRQ16_CON,
+ .irq_en_shift = 31,
+ .irq_clr_reg = ASYS_IRQ_CLR,
+ .irq_clr_shift = 15,
+ .irq_status_shift = 15,
+ },
+};
+
+static const int mt8188_afe_memif_const_irqs[MT8188_AFE_MEMIF_NUM] = {
+ [MT8188_AFE_MEMIF_DL2] = MT8188_AFE_IRQ_13,
+ [MT8188_AFE_MEMIF_DL3] = MT8188_AFE_IRQ_14,
+ [MT8188_AFE_MEMIF_DL6] = MT8188_AFE_IRQ_15,
+ [MT8188_AFE_MEMIF_DL7] = MT8188_AFE_IRQ_1,
+ [MT8188_AFE_MEMIF_DL8] = MT8188_AFE_IRQ_16,
+ [MT8188_AFE_MEMIF_DL10] = MT8188_AFE_IRQ_17,
+ [MT8188_AFE_MEMIF_DL11] = MT8188_AFE_IRQ_18,
+ [MT8188_AFE_MEMIF_UL1] = MT8188_AFE_IRQ_3,
+ [MT8188_AFE_MEMIF_UL2] = MT8188_AFE_IRQ_19,
+ [MT8188_AFE_MEMIF_UL3] = MT8188_AFE_IRQ_20,
+ [MT8188_AFE_MEMIF_UL4] = MT8188_AFE_IRQ_21,
+ [MT8188_AFE_MEMIF_UL5] = MT8188_AFE_IRQ_22,
+ [MT8188_AFE_MEMIF_UL6] = MT8188_AFE_IRQ_9,
+ [MT8188_AFE_MEMIF_UL8] = MT8188_AFE_IRQ_23,
+ [MT8188_AFE_MEMIF_UL9] = MT8188_AFE_IRQ_24,
+ [MT8188_AFE_MEMIF_UL10] = MT8188_AFE_IRQ_25,
+};
+
+static bool mt8188_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+ /* these auto-gen reg has read-only bit, so put it as volatile */
+ /* volatile reg cannot be cached, so cannot be set when power off */
+ switch (reg) {
+ case AUDIO_TOP_CON0:
+ case AUDIO_TOP_CON1:
+ case AUDIO_TOP_CON3:
+ case AUDIO_TOP_CON4:
+ case AUDIO_TOP_CON5:
+ case AUDIO_TOP_CON6:
+ case ASYS_IRQ_CLR:
+ case ASYS_IRQ_STATUS:
+ case ASYS_IRQ_MON1:
+ case ASYS_IRQ_MON2:
+ case AFE_IRQ_MCU_CLR:
+ case AFE_IRQ_STATUS:
+ case AFE_IRQ3_CON_MON:
+ case AFE_IRQ_MCU_MON2:
+ case ADSP_IRQ_STATUS:
+ case AUDIO_TOP_STA0:
+ case AUDIO_TOP_STA1:
+ case AFE_GAIN1_CUR:
+ case AFE_GAIN2_CUR:
+ case AFE_IEC_BURST_INFO:
+ case AFE_IEC_CHL_STAT0:
+ case AFE_IEC_CHL_STAT1:
+ case AFE_IEC_CHR_STAT0:
+ case AFE_IEC_CHR_STAT1:
+ case AFE_SPDIFIN_CHSTS1:
+ case AFE_SPDIFIN_CHSTS2:
+ case AFE_SPDIFIN_CHSTS3:
+ case AFE_SPDIFIN_CHSTS4:
+ case AFE_SPDIFIN_CHSTS5:
+ case AFE_SPDIFIN_CHSTS6:
+ case AFE_SPDIFIN_DEBUG1:
+ case AFE_SPDIFIN_DEBUG2:
+ case AFE_SPDIFIN_DEBUG3:
+ case AFE_SPDIFIN_DEBUG4:
+ case AFE_SPDIFIN_EC:
+ case AFE_SPDIFIN_CKLOCK_CFG:
+ case AFE_SPDIFIN_BR_DBG1:
+ case AFE_SPDIFIN_CKFBDIV:
+ case AFE_SPDIFIN_INT_EXT:
+ case AFE_SPDIFIN_INT_EXT2:
+ case SPDIFIN_FREQ_STATUS:
+ case SPDIFIN_USERCODE1:
+ case SPDIFIN_USERCODE2:
+ case SPDIFIN_USERCODE3:
+ case SPDIFIN_USERCODE4:
+ case SPDIFIN_USERCODE5:
+ case SPDIFIN_USERCODE6:
+ case SPDIFIN_USERCODE7:
+ case SPDIFIN_USERCODE8:
+ case SPDIFIN_USERCODE9:
+ case SPDIFIN_USERCODE10:
+ case SPDIFIN_USERCODE11:
+ case SPDIFIN_USERCODE12:
+ case AFE_LINEIN_APLL_TUNER_MON:
+ case AFE_EARC_APLL_TUNER_MON:
+ case AFE_CM0_MON:
+ case AFE_CM1_MON:
+ case AFE_CM2_MON:
+ case AFE_MPHONE_MULTI_DET_MON0:
+ case AFE_MPHONE_MULTI_DET_MON1:
+ case AFE_MPHONE_MULTI_DET_MON2:
+ case AFE_MPHONE_MULTI2_DET_MON0:
+ case AFE_MPHONE_MULTI2_DET_MON1:
+ case AFE_MPHONE_MULTI2_DET_MON2:
+ case AFE_ADDA_MTKAIF_MON0:
+ case AFE_ADDA_MTKAIF_MON1:
+ case AFE_AUD_PAD_TOP:
+ case AFE_ADDA6_MTKAIF_MON0:
+ case AFE_ADDA6_MTKAIF_MON1:
+ case AFE_ADDA6_SRC_DEBUG_MON0:
+ case AFE_ADDA6_UL_SRC_MON0:
+ case AFE_ADDA6_UL_SRC_MON1:
+ case AFE_ASRC11_NEW_CON8:
+ case AFE_ASRC11_NEW_CON9:
+ case AFE_ASRC12_NEW_CON8:
+ case AFE_ASRC12_NEW_CON9:
+ case AFE_LRCK_CNT:
+ case AFE_DAC_MON0:
+ case AFE_DL2_CUR:
+ case AFE_DL3_CUR:
+ case AFE_DL6_CUR:
+ case AFE_DL7_CUR:
+ case AFE_DL8_CUR:
+ case AFE_DL10_CUR:
+ case AFE_DL11_CUR:
+ case AFE_UL1_CUR:
+ case AFE_UL2_CUR:
+ case AFE_UL3_CUR:
+ case AFE_UL4_CUR:
+ case AFE_UL5_CUR:
+ case AFE_UL6_CUR:
+ case AFE_UL8_CUR:
+ case AFE_UL9_CUR:
+ case AFE_UL10_CUR:
+ case AFE_DL8_CHK_SUM1:
+ case AFE_DL8_CHK_SUM2:
+ case AFE_DL8_CHK_SUM3:
+ case AFE_DL8_CHK_SUM4:
+ case AFE_DL8_CHK_SUM5:
+ case AFE_DL8_CHK_SUM6:
+ case AFE_DL10_CHK_SUM1:
+ case AFE_DL10_CHK_SUM2:
+ case AFE_DL10_CHK_SUM3:
+ case AFE_DL10_CHK_SUM4:
+ case AFE_DL10_CHK_SUM5:
+ case AFE_DL10_CHK_SUM6:
+ case AFE_DL11_CHK_SUM1:
+ case AFE_DL11_CHK_SUM2:
+ case AFE_DL11_CHK_SUM3:
+ case AFE_DL11_CHK_SUM4:
+ case AFE_DL11_CHK_SUM5:
+ case AFE_DL11_CHK_SUM6:
+ case AFE_UL1_CHK_SUM1:
+ case AFE_UL1_CHK_SUM2:
+ case AFE_UL2_CHK_SUM1:
+ case AFE_UL2_CHK_SUM2:
+ case AFE_UL3_CHK_SUM1:
+ case AFE_UL3_CHK_SUM2:
+ case AFE_UL4_CHK_SUM1:
+ case AFE_UL4_CHK_SUM2:
+ case AFE_UL5_CHK_SUM1:
+ case AFE_UL5_CHK_SUM2:
+ case AFE_UL6_CHK_SUM1:
+ case AFE_UL6_CHK_SUM2:
+ case AFE_UL8_CHK_SUM1:
+ case AFE_UL8_CHK_SUM2:
+ case AFE_DL2_CHK_SUM1:
+ case AFE_DL2_CHK_SUM2:
+ case AFE_DL3_CHK_SUM1:
+ case AFE_DL3_CHK_SUM2:
+ case AFE_DL6_CHK_SUM1:
+ case AFE_DL6_CHK_SUM2:
+ case AFE_DL7_CHK_SUM1:
+ case AFE_DL7_CHK_SUM2:
+ case AFE_UL9_CHK_SUM1:
+ case AFE_UL9_CHK_SUM2:
+ case AFE_BUS_MON1:
+ case UL1_MOD2AGT_CNT_LAT:
+ case UL2_MOD2AGT_CNT_LAT:
+ case UL3_MOD2AGT_CNT_LAT:
+ case UL4_MOD2AGT_CNT_LAT:
+ case UL5_MOD2AGT_CNT_LAT:
+ case UL6_MOD2AGT_CNT_LAT:
+ case UL8_MOD2AGT_CNT_LAT:
+ case UL9_MOD2AGT_CNT_LAT:
+ case UL10_MOD2AGT_CNT_LAT:
+ case AFE_MEMIF_BUF_FULL_MON:
+ case AFE_MEMIF_BUF_MON1:
+ case AFE_MEMIF_BUF_MON3:
+ case AFE_MEMIF_BUF_MON4:
+ case AFE_MEMIF_BUF_MON5:
+ case AFE_MEMIF_BUF_MON6:
+ case AFE_MEMIF_BUF_MON7:
+ case AFE_MEMIF_BUF_MON8:
+ case AFE_MEMIF_BUF_MON9:
+ case AFE_MEMIF_BUF_MON10:
+ case DL2_AGENT2MODULE_CNT:
+ case DL3_AGENT2MODULE_CNT:
+ case DL6_AGENT2MODULE_CNT:
+ case DL7_AGENT2MODULE_CNT:
+ case DL8_AGENT2MODULE_CNT:
+ case DL10_AGENT2MODULE_CNT:
+ case DL11_AGENT2MODULE_CNT:
+ case UL1_MODULE2AGENT_CNT:
+ case UL2_MODULE2AGENT_CNT:
+ case UL3_MODULE2AGENT_CNT:
+ case UL4_MODULE2AGENT_CNT:
+ case UL5_MODULE2AGENT_CNT:
+ case UL6_MODULE2AGENT_CNT:
+ case UL8_MODULE2AGENT_CNT:
+ case UL9_MODULE2AGENT_CNT:
+ case UL10_MODULE2AGENT_CNT:
+ case AFE_DMIC0_SRC_DEBUG_MON0:
+ case AFE_DMIC0_UL_SRC_MON0:
+ case AFE_DMIC0_UL_SRC_MON1:
+ case AFE_DMIC1_SRC_DEBUG_MON0:
+ case AFE_DMIC1_UL_SRC_MON0:
+ case AFE_DMIC1_UL_SRC_MON1:
+ case AFE_DMIC2_SRC_DEBUG_MON0:
+ case AFE_DMIC2_UL_SRC_MON0:
+ case AFE_DMIC2_UL_SRC_MON1:
+ case AFE_DMIC3_SRC_DEBUG_MON0:
+ case AFE_DMIC3_UL_SRC_MON0:
+ case AFE_DMIC3_UL_SRC_MON1:
+ case DMIC_GAIN1_CUR:
+ case DMIC_GAIN2_CUR:
+ case DMIC_GAIN3_CUR:
+ case DMIC_GAIN4_CUR:
+ case ETDM_IN1_MONITOR:
+ case ETDM_IN2_MONITOR:
+ case ETDM_OUT1_MONITOR:
+ case ETDM_OUT2_MONITOR:
+ case ETDM_OUT3_MONITOR:
+ case AFE_ADDA_SRC_DEBUG_MON0:
+ case AFE_ADDA_SRC_DEBUG_MON1:
+ case AFE_ADDA_DL_SDM_FIFO_MON:
+ case AFE_ADDA_DL_SRC_LCH_MON:
+ case AFE_ADDA_DL_SRC_RCH_MON:
+ case AFE_ADDA_DL_SDM_OUT_MON:
+ case AFE_GASRC0_NEW_CON8:
+ case AFE_GASRC0_NEW_CON9:
+ case AFE_GASRC0_NEW_CON12:
+ case AFE_GASRC1_NEW_CON8:
+ case AFE_GASRC1_NEW_CON9:
+ case AFE_GASRC1_NEW_CON12:
+ case AFE_GASRC2_NEW_CON8:
+ case AFE_GASRC2_NEW_CON9:
+ case AFE_GASRC2_NEW_CON12:
+ case AFE_GASRC3_NEW_CON8:
+ case AFE_GASRC3_NEW_CON9:
+ case AFE_GASRC3_NEW_CON12:
+ case AFE_GASRC4_NEW_CON8:
+ case AFE_GASRC4_NEW_CON9:
+ case AFE_GASRC4_NEW_CON12:
+ case AFE_GASRC5_NEW_CON8:
+ case AFE_GASRC5_NEW_CON9:
+ case AFE_GASRC5_NEW_CON12:
+ case AFE_GASRC6_NEW_CON8:
+ case AFE_GASRC6_NEW_CON9:
+ case AFE_GASRC6_NEW_CON12:
+ case AFE_GASRC7_NEW_CON8:
+ case AFE_GASRC7_NEW_CON9:
+ case AFE_GASRC7_NEW_CON12:
+ case AFE_GASRC8_NEW_CON8:
+ case AFE_GASRC8_NEW_CON9:
+ case AFE_GASRC8_NEW_CON12:
+ case AFE_GASRC9_NEW_CON8:
+ case AFE_GASRC9_NEW_CON9:
+ case AFE_GASRC9_NEW_CON12:
+ case AFE_GASRC10_NEW_CON8:
+ case AFE_GASRC10_NEW_CON9:
+ case AFE_GASRC10_NEW_CON12:
+ case AFE_GASRC11_NEW_CON8:
+ case AFE_GASRC11_NEW_CON9:
+ case AFE_GASRC11_NEW_CON12:
+ return true;
+ default:
+ return false;
+ };
+}
+
+static const struct regmap_config mt8188_afe_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .volatile_reg = mt8188_is_volatile_reg,
+ .max_register = AFE_MAX_REGISTER,
+ .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1),
+ .cache_type = REGCACHE_FLAT,
+};
+
+#define AFE_IRQ_CLR_BITS (0x387)
+#define ASYS_IRQ_CLR_BITS (0xffff)
+
+static irqreturn_t mt8188_afe_irq_handler(int irq_id, void *dev_id)
+{
+ struct mtk_base_afe *afe = dev_id;
+ unsigned int val = 0;
+ unsigned int asys_irq_clr_bits = 0;
+ unsigned int afe_irq_clr_bits = 0;
+ unsigned int irq_status_bits = 0;
+ unsigned int irq_clr_bits = 0;
+ unsigned int mcu_irq_mask = 0;
+ int i = 0;
+ int ret = 0;
+
+ ret = regmap_read(afe->regmap, AFE_IRQ_STATUS, &val);
+ if (ret) {
+ dev_err(afe->dev, "%s irq status err\n", __func__);
+ afe_irq_clr_bits = AFE_IRQ_CLR_BITS;
+ asys_irq_clr_bits = ASYS_IRQ_CLR_BITS;
+ goto err_irq;
+ }
+
+ ret = regmap_read(afe->regmap, AFE_IRQ_MASK, &mcu_irq_mask);
+ if (ret) {
+ dev_err(afe->dev, "%s read irq mask err\n", __func__);
+ afe_irq_clr_bits = AFE_IRQ_CLR_BITS;
+ asys_irq_clr_bits = ASYS_IRQ_CLR_BITS;
+ goto err_irq;
+ }
+
+ /* only clr cpu irq */
+ val &= mcu_irq_mask;
+
+ for (i = 0; i < MT8188_AFE_MEMIF_NUM; i++) {
+ struct mtk_base_afe_memif *memif = &afe->memif[i];
+ struct mtk_base_irq_data const *irq_data;
+
+ if (memif->irq_usage < 0)
+ continue;
+
+ irq_data = afe->irqs[memif->irq_usage].irq_data;
+
+ irq_status_bits = BIT(irq_data->irq_status_shift);
+ irq_clr_bits = BIT(irq_data->irq_clr_shift);
+
+ if (!(val & irq_status_bits))
+ continue;
+
+ if (irq_data->irq_clr_reg == ASYS_IRQ_CLR)
+ asys_irq_clr_bits |= irq_clr_bits;
+ else
+ afe_irq_clr_bits |= irq_clr_bits;
+
+ snd_pcm_period_elapsed(memif->substream);
+ }
+
+err_irq:
+ /* clear irq */
+ if (asys_irq_clr_bits)
+ regmap_write(afe->regmap, ASYS_IRQ_CLR, asys_irq_clr_bits);
+ if (afe_irq_clr_bits)
+ regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, afe_irq_clr_bits);
+
+ return IRQ_HANDLED;
+}
+
+static int mt8188_afe_runtime_suspend(struct device *dev)
+{
+ struct mtk_base_afe *afe = dev_get_drvdata(dev);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
+ goto skip_regmap;
+
+ mt8188_afe_disable_main_clock(afe);
+
+ regcache_cache_only(afe->regmap, true);
+ regcache_mark_dirty(afe->regmap);
+
+skip_regmap:
+ mt8188_afe_disable_reg_rw_clk(afe);
+
+ return 0;
+}
+
+static int mt8188_afe_runtime_resume(struct device *dev)
+{
+ struct mtk_base_afe *afe = dev_get_drvdata(dev);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct arm_smccc_res res;
+
+ arm_smccc_smc(MTK_SIP_AUDIO_CONTROL,
+ MTK_AUDIO_SMC_OP_DOMAIN_SIDEBANDS,
+ 0, 0, 0, 0, 0, 0, &res);
+
+ mt8188_afe_enable_reg_rw_clk(afe);
+
+ if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
+ goto skip_regmap;
+
+ regcache_cache_only(afe->regmap, false);
+ regcache_sync(afe->regmap);
+
+ mt8188_afe_enable_main_clock(afe);
+skip_regmap:
+ return 0;
+}
+
+static int mt8188_afe_component_probe(struct snd_soc_component *component)
+{
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ int ret;
+
+ snd_soc_component_init_regmap(component, afe->regmap);
+
+ ret = mtk_afe_add_sub_dai_control(component);
+
+ return ret;
+}
+
+static const struct snd_soc_component_driver mt8188_afe_component = {
+ .name = AFE_PCM_NAME,
+ .pointer = mtk_afe_pcm_pointer,
+ .pcm_construct = mtk_afe_pcm_new,
+ .probe = mt8188_afe_component_probe,
+};
+
+static int init_memif_priv_data(struct mtk_base_afe *afe)
+{
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_memif_priv *memif_priv;
+ int i;
+
+ for (i = MT8188_AFE_MEMIF_START; i < MT8188_AFE_MEMIF_END; i++) {
+ memif_priv = devm_kzalloc(afe->dev,
+ sizeof(struct mtk_dai_memif_priv),
+ GFP_KERNEL);
+ if (!memif_priv)
+ return -ENOMEM;
+
+ afe_priv->dai_priv[i] = memif_priv;
+ }
+
+ return 0;
+}
+
+static int mt8188_dai_memif_register(struct mtk_base_afe *afe)
+{
+ struct mtk_base_afe_dai *dai;
+
+ dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+ if (!dai)
+ return -ENOMEM;
+
+ list_add(&dai->list, &afe->sub_dais);
+
+ dai->dai_drivers = mt8188_memif_dai_driver;
+ dai->num_dai_drivers = ARRAY_SIZE(mt8188_memif_dai_driver);
+
+ dai->dapm_widgets = mt8188_memif_widgets;
+ dai->num_dapm_widgets = ARRAY_SIZE(mt8188_memif_widgets);
+ dai->dapm_routes = mt8188_memif_routes;
+ dai->num_dapm_routes = ARRAY_SIZE(mt8188_memif_routes);
+
+ return init_memif_priv_data(afe);
+}
+
+typedef int (*dai_register_cb)(struct mtk_base_afe *);
+static const dai_register_cb dai_register_cbs[] = {
+ mt8188_dai_adda_register,
+ mt8188_dai_etdm_register,
+ mt8188_dai_pcm_register,
+ mt8188_dai_memif_register,
+};
+
+static const struct reg_sequence mt8188_afe_reg_defaults[] = {
+ { AFE_IRQ_MASK, 0x387ffff },
+ { AFE_IRQ3_CON, BIT(30) },
+ { AFE_IRQ9_CON, BIT(30) },
+ { ETDM_IN1_CON4, 0x12000100 },
+ { ETDM_IN2_CON4, 0x12000100 },
+};
+
+static const struct reg_sequence mt8188_cg_patch[] = {
+ { AUDIO_TOP_CON0, 0xfffffffb },
+ { AUDIO_TOP_CON1, 0xfffffff8 },
+};
+
+static int mt8188_afe_init_registers(struct mtk_base_afe *afe)
+{
+ return regmap_multi_reg_write(afe->regmap,
+ mt8188_afe_reg_defaults,
+ ARRAY_SIZE(mt8188_afe_reg_defaults));
+}
+
+static int mt8188_afe_parse_of(struct mtk_base_afe *afe,
+ struct device_node *np)
+{
+#if IS_ENABLED(CONFIG_SND_SOC_MT6359)
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+
+ afe_priv->topckgen = syscon_regmap_lookup_by_phandle(afe->dev->of_node,
+ "mediatek,topckgen");
+ if (IS_ERR(afe_priv->topckgen))
+ return dev_err_probe(afe->dev, PTR_ERR(afe_priv->topckgen),
+ "%s() Cannot find topckgen controller\n",
+ __func__);
+#endif
+ return 0;
+}
+
+#define MT8188_DELAY_US 10
+#define MT8188_TIMEOUT_US USEC_PER_SEC
+
+static int bus_protect_enable(struct regmap *regmap)
+{
+ int ret;
+ u32 val;
+ u32 mask;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, (val & mask) == mask,
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, (val & mask) == mask,
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int bus_protect_disable(struct regmap *regmap)
+{
+ int ret;
+ u32 val;
+ u32 mask;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, !(val & mask),
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ val = 0;
+ mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
+ regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
+
+ ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA,
+ val, !(val & mask),
+ MT8188_DELAY_US, MT8188_TIMEOUT_US);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev)
+{
+ struct mtk_base_afe *afe;
+ struct mt8188_afe_private *afe_priv;
+ struct device *dev;
+ int i, irq_id, ret;
+ struct snd_soc_component *component;
+ struct reset_control *rstc;
+ //void __iomem *bus_remap_ctrl;
+ struct regmap *infra_ao;
+ //uint32_t val;
+ struct arm_smccc_res res;
+
+ ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33));
+ if (ret)
+ return ret;
+
+ afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
+ if (!afe)
+ return -ENOMEM;
+
+ afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
+ GFP_KERNEL);
+ if (!afe->platform_priv)
+ return -ENOMEM;
+
+ afe_priv = afe->platform_priv;
+ afe->dev = &pdev->dev;
+ dev = afe->dev;
+
+ afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
+ if (IS_ERR(afe->base_addr))
+ return dev_err_probe(dev, PTR_ERR(afe->base_addr),
+ "AFE base_addr not found\n");
+
+ infra_ao = syscon_regmap_lookup_by_phandle(dev->of_node,
+ "mediatek,infracfg");
+ if (IS_ERR(infra_ao))
+ return dev_err_probe(dev, PTR_ERR(infra_ao),
+ "%s() Cannot find infra_ao controller\n",
+ __func__);
+
+ /* reset controller to reset audio regs before regmap cache */
+ rstc = devm_reset_control_get_exclusive(dev, "audiosys");
+ if (IS_ERR(rstc))
+ return dev_err_probe(dev, PTR_ERR(rstc),
+ "could not get audiosys reset\n");
+
+ ret = bus_protect_enable(infra_ao);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "bus_protect_enable failed\n");
+
+ ret = reset_control_reset(rstc);
+ if (ret) {
+ dev_err(dev, "failed to trigger audio reset:%d\n", ret);
+ bus_protect_disable(infra_ao);
+ return ret;
+ }
+
+ ret = bus_protect_disable(infra_ao);
+ if (ret)
+ return dev_err_probe(dev, ret,
+ "bus_protect_disable failed\n");
+
+ /* initial audio related clock */
+ ret = mt8188_afe_init_clock(afe);
+ if (ret)
+ return dev_err_probe(dev, ret, "init clock error");
+
+ ret = devm_add_action_or_reset(dev, mt8188_afe_deinit_clock, (void *)afe);
+ if (ret)
+ return ret;
+
+ spin_lock_init(&afe_priv->afe_ctrl_lock);
+
+ mutex_init(&afe->irq_alloc_lock);
+
+ /* irq initialize */
+ afe->irqs_size = MT8188_AFE_IRQ_NUM;
+ afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
+ GFP_KERNEL);
+ if (!afe->irqs)
+ return -ENOMEM;
+
+ for (i = 0; i < afe->irqs_size; i++)
+ afe->irqs[i].irq_data = &irq_data[i];
+
+ /* init memif */
+ afe->memif_size = MT8188_AFE_MEMIF_NUM;
+ afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
+ GFP_KERNEL);
+ if (!afe->memif)
+ return -ENOMEM;
+
+ for (i = 0; i < afe->memif_size; i++) {
+ afe->memif[i].data = &memif_data[i];
+ afe->memif[i].irq_usage = mt8188_afe_memif_const_irqs[i];
+ afe->memif[i].const_irq = 1;
+ afe->irqs[afe->memif[i].irq_usage].irq_occupyed = true;
+ }
+
+ /* request irq */
+ irq_id = platform_get_irq(pdev, 0);
+ if (irq_id < 0)
+ return dev_err_probe(dev, irq_id < 0 ? irq_id : -ENXIO,
+ "no irq found");
+
+ ret = devm_request_irq(dev, irq_id, mt8188_afe_irq_handler,
+ IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
+ if (ret)
+ return dev_err_probe(dev, ret, "could not request_irq for asys-isr\n");
+
+ /* init sub_dais */
+ INIT_LIST_HEAD(&afe->sub_dais);
+
+ for (i = 0; i < ARRAY_SIZE(dai_register_cbs); i++) {
+ ret = dai_register_cbs[i](afe);
+ if (ret)
+ return dev_err_probe(dev, ret, "dai register i %d fail\n", i);
+ }
+
+ /* init dai_driver and component_driver */
+ ret = mtk_afe_combine_sub_dai(afe);
+ if (ret)
+ return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n");
+
+ afe->mtk_afe_hardware = &mt8188_afe_hardware;
+ afe->memif_fs = mt8188_memif_fs;
+ afe->irq_fs = mt8188_irq_fs;
+
+ afe->runtime_resume = mt8188_afe_runtime_resume;
+ afe->runtime_suspend = mt8188_afe_runtime_suspend;
+
+ platform_set_drvdata(pdev, afe);
+
+ ret = mt8188_afe_parse_of(afe, pdev->dev.of_node);
+ if (ret)
+ return ret;
+
+ /* init arm_smccc_smc call */
+ arm_smccc_smc(MTK_SIP_AUDIO_CONTROL, MTK_AUDIO_SMC_OP_INIT,
+ 0, 0, 0, 0, 0, 0, &res);
+
+ ret = devm_pm_runtime_enable(dev);
+ if (ret)
+ return ret;
+
+ /* enable clock for regcache get default value from hw */
+ afe_priv->pm_runtime_bypass_reg_ctl = true;
+ ret = pm_runtime_resume_and_get(dev);
+ if (ret)
+ return dev_err_probe(dev, ret, "failed to resume device\n");
+
+ afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
+ &mt8188_afe_regmap_config);
+ if (IS_ERR(afe->regmap)) {
+ ret = PTR_ERR(afe->regmap);
+ goto err_pm_put;
+ }
+
+ ret = regmap_register_patch(afe->regmap, mt8188_cg_patch,
+ ARRAY_SIZE(mt8188_cg_patch));
+ if (ret < 0) {
+ dev_info(dev, "Failed to apply cg patch\n");
+ goto err_pm_put;
+ }
+
+ /* register component */
+ ret = devm_snd_soc_register_component(dev, &mt8188_afe_component,
+ NULL, 0);
+ if (ret) {
+ dev_warn(dev, "err_platform\n");
+ goto err_pm_put;
+ }
+
+ component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL);
+ if (!component) {
+ ret = -ENOMEM;
+ goto err_pm_put;
+ }
+
+ ret = snd_soc_component_initialize(component,
+ &mt8188_afe_pcm_dai_component,
+ &pdev->dev);
+ if (ret)
+ goto err_pm_put;
+#ifdef CONFIG_DEBUG_FS
+ component->debugfs_prefix = "pcm";
+#endif
+ ret = snd_soc_add_component(component,
+ afe->dai_drivers,
+ afe->num_dai_drivers);
+ if (ret) {
+ dev_warn(dev, "err_add_component\n");
+ goto err_pm_put;
+ }
+
+ mt8188_afe_init_registers(afe);
+
+ pm_runtime_put_sync(&pdev->dev);
+ afe_priv->pm_runtime_bypass_reg_ctl = false;
+
+ regcache_cache_only(afe->regmap, true);
+ regcache_mark_dirty(afe->regmap);
+
+ return 0;
+err_pm_put:
+ pm_runtime_put_sync(dev);
+
+ return ret;
+}
+
+static int mt8188_afe_pcm_dev_remove(struct platform_device *pdev)
+{
+ snd_soc_unregister_component(&pdev->dev);
+
+ return 0;
+}
+
+static const struct of_device_id mt8188_afe_pcm_dt_match[] = {
+ { .compatible = "mediatek,mt8188-audio", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, mt8188_afe_pcm_dt_match);
+
+static const struct dev_pm_ops mt8188_afe_pm_ops = {
+ SET_RUNTIME_PM_OPS(mt8188_afe_runtime_suspend,
+ mt8188_afe_runtime_resume, NULL)
+};
+
+static struct platform_driver mt8188_afe_pcm_driver = {
+ .driver = {
+ .name = "mt8188-audio",
+ .of_match_table = mt8188_afe_pcm_dt_match,
+ .pm = &mt8188_afe_pm_ops,
+ },
+ .probe = mt8188_afe_pcm_dev_probe,
+ .remove = mt8188_afe_pcm_dev_remove,
+};
+
+module_platform_driver(mt8188_afe_pcm_driver);
+
+MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8188");
+MODULE_AUTHOR("Chun-Chia.Chiu <chun-chia.chiu@mediatek.com>");
+MODULE_LICENSE("GPL");
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 09/12] ASoC: mediatek: mt8188: add control for timing select
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (6 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 14:56 ` [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document Trevor Wu
` (2 subsequent siblings)
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mixer control for irq and memif timing selection.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 506 +++++++++++++++++++++
1 file changed, 506 insertions(+)
diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
index 5d8e01c99714..b2e0b50dcca5 100644
--- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
+++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
@@ -1399,6 +1399,510 @@ static const struct snd_soc_dapm_route mt8188_memif_routes[] = {
{"O041", "I169 Switch", "I169"},
};
+static const char * const mt8188_afe_1x_en_sel_text[] = {
+ "a1sys_a2sys", "a3sys", "a4sys",
+};
+
+static const unsigned int mt8188_afe_1x_en_sel_values[] = {
+ 0, 1, 2,
+};
+
+static SOC_VALUE_ENUM_SINGLE_DECL(dl2_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 18, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl3_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 20, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl6_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 22, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl7_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 24, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl8_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 26, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl10_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 28, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl11_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 30, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul1_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 0, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul2_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 2, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul3_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 4, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul4_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 6, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul5_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 8, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul6_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 10, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul8_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 12, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul9_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 14, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul10_1x_en_sel_enum,
+ A3_A4_TIMING_SEL1, 16, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq1_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 0, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq2_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 2, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq3_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 4, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq4_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 6, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq5_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 8, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq6_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 10, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq7_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 12, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq8_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 14, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq9_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 16, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq10_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 18, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq11_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 20, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq12_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 22, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq13_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 24, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq14_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 26, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq15_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 28, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq16_1x_en_sel_enum,
+ A3_A4_TIMING_SEL6, 30, 0x3,
+ mt8188_afe_1x_en_sel_text,
+ mt8188_afe_1x_en_sel_values);
+
+static const char * const mt8188_afe_fs_timing_sel_text[] = {
+ "asys",
+ "etdmout1_1x_en",
+ "etdmout2_1x_en",
+ "etdmout3_1x_en",
+ "etdmin1_1x_en",
+ "etdmin2_1x_en",
+ "etdmin1_nx_en",
+ "etdmin2_nx_en",
+};
+
+static const unsigned int mt8188_afe_fs_timing_sel_values[] = {
+ 0,
+ MT8188_ETDM_OUT1_1X_EN,
+ MT8188_ETDM_OUT2_1X_EN,
+ MT8188_ETDM_OUT3_1X_EN,
+ MT8188_ETDM_IN1_1X_EN,
+ MT8188_ETDM_IN2_1X_EN,
+ MT8188_ETDM_IN1_NX_EN,
+ MT8188_ETDM_IN2_NX_EN,
+};
+
+static SOC_VALUE_ENUM_SINGLE_DECL(dl2_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl3_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl6_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl8_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(dl11_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul2_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul4_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul5_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul9_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+static SOC_VALUE_ENUM_SINGLE_DECL(ul10_fs_timing_sel_enum,
+ SND_SOC_NOPM, 0, 0,
+ mt8188_afe_fs_timing_sel_text,
+ mt8188_afe_fs_timing_sel_values);
+
+static int mt8188_memif_1x_en_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_memif_priv *memif_priv;
+ unsigned int dai_id = kcontrol->id.device;
+ long val = ucontrol->value.integer.value[0];
+ int ret = 0;
+
+ memif_priv = afe_priv->dai_priv[dai_id];
+
+ if (val == memif_priv->asys_timing_sel)
+ return 0;
+
+ ret = snd_soc_put_enum_double(kcontrol, ucontrol);
+
+ memif_priv->asys_timing_sel = val;
+
+ return ret;
+}
+
+static int mt8188_asys_irq_1x_en_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component =
+ snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ unsigned int id = kcontrol->id.device;
+ long val = ucontrol->value.integer.value[0];
+ int ret = 0;
+
+ if (val == afe_priv->irq_priv[id].asys_timing_sel)
+ return 0;
+
+ ret = snd_soc_put_enum_double(kcontrol, ucontrol);
+
+ afe_priv->irq_priv[id].asys_timing_sel = val;
+
+ return ret;
+}
+
+static int mt8188_memif_fs_timing_sel_get(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_memif_priv *memif_priv;
+ unsigned int dai_id = kcontrol->id.device;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+
+ memif_priv = afe_priv->dai_priv[dai_id];
+
+ ucontrol->value.enumerated.item[0] =
+ snd_soc_enum_val_to_item(e, memif_priv->fs_timing);
+
+ return 0;
+}
+
+static int mt8188_memif_fs_timing_sel_put(struct snd_kcontrol *kcontrol,
+ struct snd_ctl_elem_value *ucontrol)
+{
+ struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol);
+ struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
+ struct mt8188_afe_private *afe_priv = afe->platform_priv;
+ struct mtk_dai_memif_priv *memif_priv;
+ unsigned int dai_id = kcontrol->id.device;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
+ unsigned int *item = ucontrol->value.enumerated.item;
+ unsigned int prev_item = 0;
+
+ if (item[0] >= e->items)
+ return -EINVAL;
+
+ memif_priv = afe_priv->dai_priv[dai_id];
+
+ prev_item = snd_soc_enum_val_to_item(e, memif_priv->fs_timing);
+
+ if (item[0] == prev_item)
+ return 0;
+
+ memif_priv->fs_timing = snd_soc_enum_item_to_val(e, item[0]);
+
+ return 1;
+}
+
+static const struct snd_kcontrol_new mt8188_memif_controls[] = {
+ MT8188_SOC_ENUM_EXT("dl2_1x_en_sel",
+ dl2_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL2),
+ MT8188_SOC_ENUM_EXT("dl3_1x_en_sel",
+ dl3_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL3),
+ MT8188_SOC_ENUM_EXT("dl6_1x_en_sel",
+ dl6_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL6),
+ MT8188_SOC_ENUM_EXT("dl7_1x_en_sel",
+ dl7_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL7),
+ MT8188_SOC_ENUM_EXT("dl8_1x_en_sel",
+ dl8_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL8),
+ MT8188_SOC_ENUM_EXT("dl10_1x_en_sel",
+ dl10_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL10),
+ MT8188_SOC_ENUM_EXT("dl11_1x_en_sel",
+ dl11_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_DL11),
+ MT8188_SOC_ENUM_EXT("ul1_1x_en_sel",
+ ul1_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL1),
+ MT8188_SOC_ENUM_EXT("ul2_1x_en_sel",
+ ul2_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL2),
+ MT8188_SOC_ENUM_EXT("ul3_1x_en_sel",
+ ul3_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL3),
+ MT8188_SOC_ENUM_EXT("ul4_1x_en_sel",
+ ul4_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL4),
+ MT8188_SOC_ENUM_EXT("ul5_1x_en_sel",
+ ul5_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL5),
+ MT8188_SOC_ENUM_EXT("ul6_1x_en_sel",
+ ul6_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL6),
+ MT8188_SOC_ENUM_EXT("ul8_1x_en_sel",
+ ul8_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL8),
+ MT8188_SOC_ENUM_EXT("ul9_1x_en_sel",
+ ul9_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL9),
+ MT8188_SOC_ENUM_EXT("ul10_1x_en_sel",
+ ul10_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_memif_1x_en_sel_put,
+ MT8188_AFE_MEMIF_UL10),
+ MT8188_SOC_ENUM_EXT("asys_irq1_1x_en_sel",
+ asys_irq1_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_13),
+ MT8188_SOC_ENUM_EXT("asys_irq2_1x_en_sel",
+ asys_irq2_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_14),
+ MT8188_SOC_ENUM_EXT("asys_irq3_1x_en_sel",
+ asys_irq3_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_15),
+ MT8188_SOC_ENUM_EXT("asys_irq4_1x_en_sel",
+ asys_irq4_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_16),
+ MT8188_SOC_ENUM_EXT("asys_irq5_1x_en_sel",
+ asys_irq5_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_17),
+ MT8188_SOC_ENUM_EXT("asys_irq6_1x_en_sel",
+ asys_irq6_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_18),
+ MT8188_SOC_ENUM_EXT("asys_irq7_1x_en_sel",
+ asys_irq7_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_19),
+ MT8188_SOC_ENUM_EXT("asys_irq8_1x_en_sel",
+ asys_irq8_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_20),
+ MT8188_SOC_ENUM_EXT("asys_irq9_1x_en_sel",
+ asys_irq9_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_21),
+ MT8188_SOC_ENUM_EXT("asys_irq10_1x_en_sel",
+ asys_irq10_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_22),
+ MT8188_SOC_ENUM_EXT("asys_irq11_1x_en_sel",
+ asys_irq11_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_23),
+ MT8188_SOC_ENUM_EXT("asys_irq12_1x_en_sel",
+ asys_irq12_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_24),
+ MT8188_SOC_ENUM_EXT("asys_irq13_1x_en_sel",
+ asys_irq13_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_25),
+ MT8188_SOC_ENUM_EXT("asys_irq14_1x_en_sel",
+ asys_irq14_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_26),
+ MT8188_SOC_ENUM_EXT("asys_irq15_1x_en_sel",
+ asys_irq15_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_27),
+ MT8188_SOC_ENUM_EXT("asys_irq16_1x_en_sel",
+ asys_irq16_1x_en_sel_enum,
+ snd_soc_get_enum_double,
+ mt8188_asys_irq_1x_en_sel_put,
+ MT8188_AFE_IRQ_28),
+ MT8188_SOC_ENUM_EXT("dl2_fs_timing_sel",
+ dl2_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_DL2),
+ MT8188_SOC_ENUM_EXT("dl3_fs_timing_sel",
+ dl3_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_DL3),
+ MT8188_SOC_ENUM_EXT("dl6_fs_timing_sel",
+ dl6_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_DL6),
+ MT8188_SOC_ENUM_EXT("dl8_fs_timing_sel",
+ dl8_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_DL8),
+ MT8188_SOC_ENUM_EXT("dl11_fs_timing_sel",
+ dl11_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_DL11),
+ MT8188_SOC_ENUM_EXT("ul2_fs_timing_sel",
+ ul2_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_UL2),
+ MT8188_SOC_ENUM_EXT("ul4_fs_timing_sel",
+ ul4_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_UL4),
+ MT8188_SOC_ENUM_EXT("ul5_fs_timing_sel",
+ ul5_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_UL5),
+ MT8188_SOC_ENUM_EXT("ul9_fs_timing_sel",
+ ul9_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_UL9),
+ MT8188_SOC_ENUM_EXT("ul10_fs_timing_sel",
+ ul10_fs_timing_sel_enum,
+ mt8188_memif_fs_timing_sel_get,
+ mt8188_memif_fs_timing_sel_put,
+ MT8188_AFE_MEMIF_UL10),
+};
+
static const struct snd_soc_component_driver mt8188_afe_pcm_dai_component = {
.name = "mt8188-afe-pcm-dai",
};
@@ -2588,6 +3092,8 @@ static int mt8188_dai_memif_register(struct mtk_base_afe *afe)
dai->num_dapm_widgets = ARRAY_SIZE(mt8188_memif_widgets);
dai->dapm_routes = mt8188_memif_routes;
dai->num_dapm_routes = ARRAY_SIZE(mt8188_memif_routes);
+ dai->controls = mt8188_memif_controls;
+ dai->num_controls = ARRAY_SIZE(mt8188_memif_controls);
return init_memif_priv_data(afe);
}
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (7 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 09/12] ASoC: mediatek: mt8188: add control for timing select Trevor Wu
@ 2022-09-30 14:56 ` Trevor Wu
2022-09-30 22:05 ` Rob Herring
2022-10-03 16:30 ` Rob Herring
2022-09-30 14:57 ` [PATCH 11/12] ASoC: mediatek: mt8188: add machine driver with mt6359 Trevor Wu
2022-09-30 14:57 ` [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document Trevor Wu
10 siblings, 2 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:56 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add mt8188 audio afe document.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
.../bindings/sound/mt8188-afe-pcm.yaml | 202 ++++++++++++++++++
1 file changed, 202 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
diff --git a/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
new file mode 100644
index 000000000000..50d53c5d59ad
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
@@ -0,0 +1,202 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8188-afe-pcm.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Mediatek AFE PCM controller for mt8188
+
+maintainers:
+ - Trevor Wu <trevor.wu@mediatek.com>
+
+properties:
+ compatible:
+ const: mediatek,mt8188-audio
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ resets:
+ maxItems: 1
+
+ reset-names:
+ const: audiosys
+
+ memory-region:
+ maxItems: 1
+ description: |
+ Shared memory region for AFE memif. A "shared-dma-pool".
+ See ../reserved-memory/reserved-memory.txt for details.
+
+ mediatek,topckgen:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+ description: The phandle of the mediatek topckgen controller
+
+ mediatek,infracfg:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+ description: The phandle of the mediatek infracfg controller
+
+ power-domains:
+ maxItems: 1
+
+ clocks:
+ items:
+ - description: 26M clock
+ - description: audio pll1 clock
+ - description: audio pll2 clock
+ - description: clock divider for i2si1_mck
+ - description: clock divider for i2si2_mck
+ - description: clock divider for i2so1_mck
+ - description: clock divider for i2so2_mck
+ - description: clock divider for dptx_mck
+ - description: a1sys hoping clock
+ - description: audio intbus clock
+ - description: audio hires clock
+ - description: audio local bus clock
+ - description: mux for dptx_mck
+ - description: mux for i2so1_mck
+ - description: mux for i2so2_mck
+ - description: mux for i2si1_mck
+ - description: mux for i2si2_mck
+ - description: audio 26m clock
+
+ clock-names:
+ items:
+ - const: clk26m
+ - const: apll1_ck
+ - const: apll2_ck
+ - const: apll12_div0
+ - const: apll12_div1
+ - const: apll12_div2
+ - const: apll12_div3
+ - const: apll12_div9
+ - const: a1sys_hp_sel
+ - const: aud_intbus_sel
+ - const: audio_h_sel
+ - const: audio_local_bus_sel
+ - const: dptx_m_sel
+ - const: i2so1_m_sel
+ - const: i2so2_m_sel
+ - const: i2si1_m_sel
+ - const: i2si2_m_sel
+ - const: adsp_audio26m
+
+ mediatek,etdm-in1-chn-disabled:
+ $ref: /schemas/types.yaml#/definitions/uint8-array
+ maxItems: 16
+ description: Specify which input channel should be disabled.
+
+ mediatek,etdm-in2-chn-disabled:
+ $ref: /schemas/types.yaml#/definitions/uint8-array
+ maxItems: 16
+ description: Specify which input channel should be disabled.
+
+patternProperties:
+ "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
+ description: Specify etdm in mclk output rate for always on case.
+
+ "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
+ description: Specify etdm out mclk output rate for always on case.
+
+ "^mediatek,etdm-in[1-2]-multi-pin-mode$":
+ type: boolean
+ description: if present, the etdm data mode is I2S.
+
+ "^mediatek,etdm-out[1-3]-multi-pin-mode$":
+ type: boolean
+ description: if present, the etdm data mode is I2S.
+
+ "^mediatek,etdm-in[1-2]-cowork-source$":
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ etdm modules can share the same external clock pin. Specify
+ which etdm clock source is required by this etdm in moudule.
+ enum:
+ - 0 # etdm1_in
+ - 1 # etdm2_in
+ - 2 # etdm1_out
+ - 3 # etdm2_out
+
+ "^mediatek,etdm-out[1-2]-cowork-source$":
+ $ref: /schemas/types.yaml#/definitions/uint32
+ description: |
+ etdm modules can share the same external clock pin. Specify
+ which etdm clock source is required by this etdm out moudule.
+ enum:
+ - 0 # etdm1_in
+ - 1 # etdm2_in
+ - 2 # etdm1_out
+ - 3 # etdm2_out
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - resets
+ - reset-names
+ - mediatek,topckgen
+ - mediatek,infracfg
+ - power-domains
+ - clocks
+ - clock-names
+ - memory-region
+
+additionalProperties: false
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/arm-gic.h>
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ afe: afe@10b10000 {
+ compatible = "mediatek,mt8188-audio";
+ reg = <0x10b10000 0x10000>;
+ interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
+ resets = <&watchdog 14>;
+ reset-names = "audiosys";
+ mediatek,topckgen = <&topckgen>;
+ mediatek,infracfg = <&infracfg_ao>;
+ power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
+ memory-region = <&snd_dma_mem_reserved>;
+ clocks = <&clk26m>,
+ <&topckgen 72>, //CLK_TOP_APLL1
+ <&topckgen 73>, //CLK_TOP_APLL2
+ <&topckgen 186>, //CLK_TOP_APLL12_CK_DIV0
+ <&topckgen 187>, //CLK_TOP_APLL12_CK_DIV1
+ <&topckgen 188>, //CLK_TOP_APLL12_CK_DIV2
+ <&topckgen 189>, //CLK_TOP_APLL12_CK_DIV3
+ <&topckgen 191>, //CLK_TOP_APLL12_CK_DIV9
+ <&topckgen 83>, //CLK_TOP_A1SYS_HP
+ <&topckgen 31>, //CLK_TOP_AUD_INTBUS
+ <&topckgen 32>, //CLK_TOP_AUDIO_H
+ <&topckgen 69>, //CLK_TOP_AUDIO_LOCAL_BUS
+ <&topckgen 81>, //CLK_TOP_DPTX
+ <&topckgen 77>, //CLK_TOP_I2SO1
+ <&topckgen 78>, //CLK_TOP_I2SO2
+ <&topckgen 79>, //CLK_TOP_I2SI1
+ <&topckgen 80>, //CLK_TOP_I2SI2
+ <&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
+ clock-names = "clk26m",
+ "apll1_ck",
+ "apll2_ck",
+ "apll12_div0",
+ "apll12_div1",
+ "apll12_div2",
+ "apll12_div3",
+ "apll12_div9",
+ "a1sys_hp_sel",
+ "aud_intbus_sel",
+ "audio_h_sel",
+ "audio_local_bus_sel",
+ "dptx_m_sel",
+ "i2so1_m_sel",
+ "i2so2_m_sel",
+ "i2si1_m_sel",
+ "i2si2_m_sel",
+ "adsp_audio_26m";
+ };
+
+...
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 11/12] ASoC: mediatek: mt8188: add machine driver with mt6359
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (8 preceding siblings ...)
2022-09-30 14:56 ` [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document Trevor Wu
@ 2022-09-30 14:57 ` Trevor Wu
2022-09-30 14:57 ` [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document Trevor Wu
10 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:57 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add support for mt8188 board with mt6359.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
sound/soc/mediatek/Kconfig | 10 +
sound/soc/mediatek/mt8188/Makefile | 3 +
sound/soc/mediatek/mt8188/mt8188-mt6359.c | 810 ++++++++++++++++++++++
3 files changed, 823 insertions(+)
create mode 100644 sound/soc/mediatek/mt8188/mt8188-mt6359.c
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
index cf0e4c6b61e7..b746ef8f7aff 100644
--- a/sound/soc/mediatek/Kconfig
+++ b/sound/soc/mediatek/Kconfig
@@ -219,6 +219,16 @@ config SND_SOC_MT8188
Select Y if you have such device.
If unsure select "N".
+config SND_SOC_MT8188_MT6359
+ tristate "ASoC Audio driver for MT8188 with MT6359 and I2S codecs"
+ depends on SND_SOC_MT8188 && MTK_PMIC_WRAP
+ select SND_SOC_HDMI_CODEC
+ help
+ This adds support for ASoC machine driver for Mediatek MT8188
+ boards with the MT6359 and other I2S audio codecs.
+ Select Y if you have such device.
+ If unsure select "N".
+
config SND_SOC_MT8192
tristate "ASoC support for Mediatek MT8192 chip"
depends on ARCH_MEDIATEK
diff --git a/sound/soc/mediatek/mt8188/Makefile b/sound/soc/mediatek/mt8188/Makefile
index fa5d383c5e47..781e61cbb22b 100644
--- a/sound/soc/mediatek/mt8188/Makefile
+++ b/sound/soc/mediatek/mt8188/Makefile
@@ -10,3 +10,6 @@ snd-soc-mt8188-afe-objs := \
mt8188-dai-pcm.o
obj-$(CONFIG_SND_SOC_MT8188) += snd-soc-mt8188-afe.o
+
+# machine driver
+obj-$(CONFIG_SND_SOC_MT8188_MT6359) += mt8188-mt6359.o
diff --git a/sound/soc/mediatek/mt8188/mt8188-mt6359.c b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
new file mode 100644
index 000000000000..2642ca1291be
--- /dev/null
+++ b/sound/soc/mediatek/mt8188/mt8188-mt6359.c
@@ -0,0 +1,810 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * mt8188-mt6359.c -- MT8188-MT6359 ALSA SoC machine driver
+ *
+ * Copyright (c) 2022 MediaTek Inc.
+ * Author: Trevor Wu <trevor.wu@mediatek.com>
+ */
+
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/pm_runtime.h>
+#include <sound/jack.h>
+#include <sound/pcm_params.h>
+#include <sound/soc.h>
+#include "mt8188-afe-common.h"
+#include "../../codecs/mt6359.h"
+#include "../common/mtk-afe-platform-driver.h"
+
+/* FE */
+SND_SOC_DAILINK_DEFS(playback2,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL2")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(playback3,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL3")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(playback6,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL6")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(playback7,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL7")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(playback8,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL8")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(playback10,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL10")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(playback11,
+ DAILINK_COMP_ARRAY(COMP_CPU("DL11")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture1,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL1")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture2,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL2")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture3,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL3")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture4,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL4")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture5,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL5")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture6,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL6")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture8,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL8")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture9,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL9")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(capture10,
+ DAILINK_COMP_ARRAY(COMP_CPU("UL10")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+/* BE */
+SND_SOC_DAILINK_DEFS(adda,
+ DAILINK_COMP_ARRAY(COMP_CPU("ADDA")),
+ DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound",
+ "mt6359-snd-codec-aif1")),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(dptx,
+ DAILINK_COMP_ARRAY(COMP_CPU("DPTX")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(etdm1_in,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(etdm2_in,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(etdm1_out,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(etdm2_out,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(etdm3_out,
+ DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+SND_SOC_DAILINK_DEFS(pcm1,
+ DAILINK_COMP_ARRAY(COMP_CPU("PCM1")),
+ DAILINK_COMP_ARRAY(COMP_DUMMY()),
+ DAILINK_COMP_ARRAY(COMP_EMPTY()));
+
+struct mt8188_mt6359_priv {
+ struct snd_soc_jack dp_jack;
+ struct snd_soc_jack hdmi_jack;
+};
+
+struct mt8188_card_data {
+ const char *name;
+ unsigned long quirk;
+};
+
+static const struct snd_soc_dapm_widget mt8188_mt6359_widgets[] = {
+ SND_SOC_DAPM_HP("Headphone", NULL),
+ SND_SOC_DAPM_MIC("Headset Mic", NULL),
+};
+
+static const struct snd_kcontrol_new mt8188_mt6359_controls[] = {
+ SOC_DAPM_PIN_SWITCH("Headphone"),
+ SOC_DAPM_PIN_SWITCH("Headset Mic"),
+};
+
+#define CKSYS_AUD_TOP_CFG 0x032c
+#define CKSYS_AUD_TOP_MON 0x0330
+
+static int mt8188_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *cmpnt_afe =
+ snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME);
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+ struct mtk_base_afe *afe;
+ struct mt8188_afe_private *afe_priv;
+ struct mtkaif_param *param;
+ int chosen_phase_1, chosen_phase_2;
+ int prev_cycle_1, prev_cycle_2;
+ int test_done_1, test_done_2;
+ int cycle_1, cycle_2;
+ int mtkaif_chosen_phase[MT8188_MTKAIF_MISO_NUM];
+ int mtkaif_phase_cycle[MT8188_MTKAIF_MISO_NUM];
+ int mtkaif_calibration_num_phase;
+ bool mtkaif_calibration_ok;
+ unsigned int monitor = 0;
+ int counter;
+ int phase;
+ int i;
+
+ if (!cmpnt_afe)
+ return -EINVAL;
+
+ afe = snd_soc_component_get_drvdata(cmpnt_afe);
+ afe_priv = afe->platform_priv;
+ param = &afe_priv->mtkaif_params;
+
+ dev_dbg(afe->dev, "%s(), start\n", __func__);
+
+ param->mtkaif_calibration_ok = false;
+ for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++) {
+ param->mtkaif_chosen_phase[i] = -1;
+ param->mtkaif_phase_cycle[i] = 0;
+ mtkaif_chosen_phase[i] = -1;
+ mtkaif_phase_cycle[i] = 0;
+ }
+
+ if (IS_ERR(afe_priv->topckgen)) {
+ dev_info(afe->dev, "%s() Cannot find topckgen controller\n",
+ __func__);
+ return 0;
+ }
+
+ pm_runtime_get_sync(afe->dev);
+ mt6359_mtkaif_calibration_enable(cmpnt_codec);
+
+ /* set test type to synchronizer pulse */
+ regmap_update_bits(afe_priv->topckgen,
+ CKSYS_AUD_TOP_CFG, 0xffff, 0x4);
+ mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */
+ mtkaif_calibration_ok = true;
+
+ for (phase = 0;
+ phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok;
+ phase++) {
+ mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+ phase, phase, phase);
+
+ regmap_update_bits(afe_priv->topckgen,
+ CKSYS_AUD_TOP_CFG, 0x1, 0x1);
+
+ test_done_1 = 0;
+ test_done_2 = 0;
+
+ cycle_1 = -1;
+ cycle_2 = -1;
+
+ counter = 0;
+ while (!(test_done_1 & test_done_2)) {
+ regmap_read(afe_priv->topckgen,
+ CKSYS_AUD_TOP_MON, &monitor);
+ test_done_1 = (monitor >> 28) & 0x1;
+ test_done_2 = (monitor >> 29) & 0x1;
+
+ if (test_done_1 == 1)
+ cycle_1 = monitor & 0xf;
+
+ if (test_done_2 == 1)
+ cycle_2 = (monitor >> 4) & 0xf;
+
+ /* handle if never test done */
+ if (++counter > 10000) {
+ dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, monitor 0x%x\n",
+ __func__,
+ cycle_1, cycle_2, monitor);
+ mtkaif_calibration_ok = false;
+ break;
+ }
+ }
+
+ if (phase == 0) {
+ prev_cycle_1 = cycle_1;
+ prev_cycle_2 = cycle_2;
+ }
+
+ if (cycle_1 != prev_cycle_1 &&
+ mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) {
+ mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = phase - 1;
+ mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] = prev_cycle_1;
+ }
+
+ if (cycle_2 != prev_cycle_2 &&
+ mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) {
+ mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = phase - 1;
+ mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] = prev_cycle_2;
+ }
+
+ regmap_update_bits(afe_priv->topckgen,
+ CKSYS_AUD_TOP_CFG, 0x1, 0x0);
+
+ if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] >= 0 &&
+ mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] >= 0)
+ break;
+ }
+
+ if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] < 0) {
+ mtkaif_calibration_ok = false;
+ chosen_phase_1 = 0;
+ } else {
+ chosen_phase_1 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0];
+ }
+
+ if (mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] < 0) {
+ mtkaif_calibration_ok = false;
+ chosen_phase_2 = 0;
+ } else {
+ chosen_phase_2 = mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1];
+ }
+
+ mt6359_set_mtkaif_calibration_phase(cmpnt_codec,
+ chosen_phase_1,
+ chosen_phase_2,
+ 0);
+
+ mt6359_mtkaif_calibration_disable(cmpnt_codec);
+ pm_runtime_put(afe->dev);
+
+ param->mtkaif_calibration_ok = mtkaif_calibration_ok;
+ param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_0] = chosen_phase_1;
+ param->mtkaif_chosen_phase[MT8188_MTKAIF_MISO_1] = chosen_phase_2;
+
+ for (i = 0; i < MT8188_MTKAIF_MISO_NUM; i++)
+ param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i];
+
+ dev_info(afe->dev, "%s(), end, calibration ok %d\n",
+ __func__, param->mtkaif_calibration_ok);
+
+ return 0;
+}
+
+static int mt8188_mt6359_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct snd_soc_component *cmpnt_codec =
+ asoc_rtd_to_codec(rtd, 0)->component;
+ struct snd_soc_card *card = rtd->card;
+ struct snd_soc_dapm_context *dapm = &card->dapm;
+
+ /* set mtkaif protocol */
+ mt6359_set_mtkaif_protocol(cmpnt_codec,
+ MT6359_MTKAIF_PROTOCOL_2_CLK_P2);
+
+ /* mtkaif calibration */
+ mt8188_mt6359_mtkaif_calibration(rtd);
+
+ /* disable widget at init, in case of unexpected completed path */
+ snd_soc_dapm_disable_pin(dapm, "Receiver");
+ snd_soc_dapm_disable_pin(dapm, "Headphone L");
+ snd_soc_dapm_disable_pin(dapm, "Headphone R");
+ snd_soc_dapm_disable_pin(dapm, "Headphone L Ext Spk Amp");
+ snd_soc_dapm_disable_pin(dapm, "Headphone R Ext Spk Amp");
+ snd_soc_dapm_disable_pin(dapm, "LINEOUT L");
+
+ return 0;
+}
+
+enum {
+ DAI_LINK_DL2_FE,
+ DAI_LINK_DL3_FE,
+ DAI_LINK_DL6_FE,
+ DAI_LINK_DL7_FE,
+ DAI_LINK_DL8_FE,
+ DAI_LINK_DL10_FE,
+ DAI_LINK_DL11_FE,
+ DAI_LINK_UL1_FE,
+ DAI_LINK_UL2_FE,
+ DAI_LINK_UL3_FE,
+ DAI_LINK_UL4_FE,
+ DAI_LINK_UL5_FE,
+ DAI_LINK_UL6_FE,
+ DAI_LINK_UL8_FE,
+ DAI_LINK_UL9_FE,
+ DAI_LINK_UL10_FE,
+ DAI_LINK_ADDA_BE,
+ DAI_LINK_DPTX_BE,
+ DAI_LINK_ETDM1_IN_BE,
+ DAI_LINK_ETDM2_IN_BE,
+ DAI_LINK_ETDM1_OUT_BE,
+ DAI_LINK_ETDM2_OUT_BE,
+ DAI_LINK_ETDM3_OUT_BE,
+ DAI_LINK_PCM1_BE,
+};
+
+static int mt8188_dptx_hw_params(struct snd_pcm_substream *substream,
+ struct snd_pcm_hw_params *params)
+{
+ struct snd_soc_pcm_runtime *rtd = substream->private_data;
+ unsigned int rate = params_rate(params);
+ unsigned int mclk_fs_ratio = 256;
+ unsigned int mclk_fs = rate * mclk_fs_ratio;
+ struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0);
+
+ return snd_soc_dai_set_sysclk(dai, 0, mclk_fs, SND_SOC_CLOCK_OUT);
+}
+
+static const struct snd_soc_ops mt8188_dptx_ops = {
+ .hw_params = mt8188_dptx_hw_params,
+};
+
+static int mt8188_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
+ struct snd_pcm_hw_params *params)
+{
+ /* fix BE i2s format to 32bit, clean param mask first */
+ snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT),
+ 0, SNDRV_PCM_FORMAT_LAST);
+
+ params_set_format(params, SNDRV_PCM_FORMAT_S32_LE);
+
+ return 0;
+}
+
+static int mt8188_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+ int ret = 0;
+
+ ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT,
+ &priv->hdmi_jack);
+ if (ret) {
+ dev_info(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = snd_soc_component_set_jack(component, &priv->hdmi_jack, NULL);
+ if (ret)
+ dev_info(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",
+ __func__, component->name, ret);
+
+ return ret;
+}
+
+static int mt8188_dptx_codec_init(struct snd_soc_pcm_runtime *rtd)
+{
+ struct mt8188_mt6359_priv *priv = snd_soc_card_get_drvdata(rtd->card);
+ struct snd_soc_component *component = asoc_rtd_to_codec(rtd, 0)->component;
+ int ret = 0;
+
+ ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT,
+ &priv->dp_jack);
+ if (ret) {
+ dev_info(rtd->dev, "%s, new jack failed: %d\n", __func__, ret);
+ return ret;
+ }
+
+ ret = snd_soc_component_set_jack(component, &priv->dp_jack, NULL);
+ if (ret)
+ dev_info(rtd->dev, "%s, set jack failed on %s (ret=%d)\n",
+ __func__, component->name, ret);
+
+ return ret;
+}
+
+static struct snd_soc_dai_link mt8188_mt6359_dai_links[] = {
+ /* FE */
+ [DAI_LINK_DL2_FE] = {
+ .name = "DL2_FE",
+ .stream_name = "DL2 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback2),
+ },
+ [DAI_LINK_DL3_FE] = {
+ .name = "DL3_FE",
+ .stream_name = "DL3 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback3),
+ },
+ [DAI_LINK_DL6_FE] = {
+ .name = "DL6_FE",
+ .stream_name = "DL6 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback6),
+ },
+ [DAI_LINK_DL7_FE] = {
+ .name = "DL7_FE",
+ .stream_name = "DL7 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_PRE,
+ SND_SOC_DPCM_TRIGGER_PRE,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback7),
+ },
+ [DAI_LINK_DL8_FE] = {
+ .name = "DL8_FE",
+ .stream_name = "DL8 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback8),
+ },
+ [DAI_LINK_DL10_FE] = {
+ .name = "DL10_FE",
+ .stream_name = "DL10 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback10),
+ },
+ [DAI_LINK_DL11_FE] = {
+ .name = "DL11_FE",
+ .stream_name = "DL11 Playback",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(playback11),
+ },
+ [DAI_LINK_UL1_FE] = {
+ .name = "UL1_FE",
+ .stream_name = "UL1 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_PRE,
+ SND_SOC_DPCM_TRIGGER_PRE,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture1),
+ },
+ [DAI_LINK_UL2_FE] = {
+ .name = "UL2_FE",
+ .stream_name = "UL2 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture2),
+ },
+ [DAI_LINK_UL3_FE] = {
+ .name = "UL3_FE",
+ .stream_name = "UL3 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture3),
+ },
+ [DAI_LINK_UL4_FE] = {
+ .name = "UL4_FE",
+ .stream_name = "UL4 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture4),
+ },
+ [DAI_LINK_UL5_FE] = {
+ .name = "UL5_FE",
+ .stream_name = "UL5 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture5),
+ },
+ [DAI_LINK_UL6_FE] = {
+ .name = "UL6_FE",
+ .stream_name = "UL6 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_PRE,
+ SND_SOC_DPCM_TRIGGER_PRE,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture6),
+ },
+ [DAI_LINK_UL8_FE] = {
+ .name = "UL8_FE",
+ .stream_name = "UL8 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture8),
+ },
+ [DAI_LINK_UL9_FE] = {
+ .name = "UL9_FE",
+ .stream_name = "UL9 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture9),
+ },
+ [DAI_LINK_UL10_FE] = {
+ .name = "UL10_FE",
+ .stream_name = "UL10 Capture",
+ .trigger = {
+ SND_SOC_DPCM_TRIGGER_POST,
+ SND_SOC_DPCM_TRIGGER_POST,
+ },
+ .dynamic = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(capture10),
+ },
+ /* BE */
+ [DAI_LINK_ADDA_BE] = {
+ .name = "ADDA_BE",
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ .init = mt8188_mt6359_init,
+ SND_SOC_DAILINK_REG(adda),
+ },
+ [DAI_LINK_DPTX_BE] = {
+ .name = "DPTX_BE",
+ .ops = &mt8188_dptx_ops,
+ .be_hw_params_fixup = mt8188_dptx_hw_params_fixup,
+ .no_pcm = 1,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(dptx),
+ },
+ [DAI_LINK_ETDM1_IN_BE] = {
+ .name = "ETDM1_IN_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ .ignore_suspend = 1,
+ SND_SOC_DAILINK_REG(etdm1_in),
+ },
+ [DAI_LINK_ETDM2_IN_BE] = {
+ .name = "ETDM2_IN_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBP_CFP,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(etdm2_in),
+ },
+ [DAI_LINK_ETDM1_OUT_BE] = {
+ .name = "ETDM1_OUT_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(etdm1_out),
+ },
+ [DAI_LINK_ETDM2_OUT_BE] = {
+ .name = "ETDM2_OUT_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(etdm2_out),
+ },
+ [DAI_LINK_ETDM3_OUT_BE] = {
+ .name = "ETDM3_OUT_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ SND_SOC_DAILINK_REG(etdm3_out),
+ },
+ [DAI_LINK_PCM1_BE] = {
+ .name = "PCM1_BE",
+ .no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_NB_NF |
+ SND_SOC_DAIFMT_CBC_CFC,
+ .dpcm_playback = 1,
+ .dpcm_capture = 1,
+ SND_SOC_DAILINK_REG(pcm1),
+ },
+};
+
+static struct snd_soc_card mt8188_mt6359_soc_card = {
+ .owner = THIS_MODULE,
+ .dai_link = mt8188_mt6359_dai_links,
+ .num_links = ARRAY_SIZE(mt8188_mt6359_dai_links),
+ .dapm_widgets = mt8188_mt6359_widgets,
+ .num_dapm_widgets = ARRAY_SIZE(mt8188_mt6359_widgets),
+ .controls = mt8188_mt6359_controls,
+ .num_controls = ARRAY_SIZE(mt8188_mt6359_controls),
+};
+
+static int mt8188_mt6359_dev_probe(struct platform_device *pdev)
+{
+ struct snd_soc_card *card = &mt8188_mt6359_soc_card;
+ struct device_node *platform_node, *dp_node, *hdmi_node;
+ struct mt8188_mt6359_priv *priv;
+ struct mt8188_card_data *card_data;
+ struct snd_soc_dai_link *dai_link;
+ int ret, i;
+
+ card_data = (struct mt8188_card_data *)of_device_get_match_data(&pdev->dev);
+ card->dev = &pdev->dev;
+
+ ret = snd_soc_of_parse_card_name(card, "model");
+ if (ret)
+ return dev_err_probe(&pdev->dev, ret, "%s new card name parsing error\n",
+ __func__);
+
+ if (!card->name)
+ card->name = card_data->name;
+
+ priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
+
+ if (of_property_read_bool(pdev->dev.of_node, "audio-routing")) {
+ ret = snd_soc_of_parse_audio_routing(card, "audio-routing");
+ if (ret)
+ return ret;
+ }
+
+ platform_node = of_parse_phandle(pdev->dev.of_node,
+ "mediatek,platform", 0);
+ if (!platform_node) {
+ ret = -EINVAL;
+ return dev_err_probe(&pdev->dev, ret, "Property 'platform' missing or invalid\n");
+ }
+
+ dp_node = of_parse_phandle(pdev->dev.of_node, "mediatek,dptx-codec", 0);
+ hdmi_node = of_parse_phandle(pdev->dev.of_node,
+ "mediatek,hdmi-codec", 0);
+ for_each_card_prelinks(card, i, dai_link) {
+ if (dai_link->platforms->name)
+ continue;
+ dai_link->platforms->of_node = platform_node;
+
+ if (strcmp(dai_link->name, "DPTX_BE") == 0) {
+ if (!dp_node) {
+ dev_dbg(&pdev->dev, "No property 'dptx-codec'\n");
+ } else {
+ dai_link->codecs->of_node = dp_node;
+ dai_link->codecs->name = NULL;
+ dai_link->codecs->dai_name = "i2s-hifi";
+ dai_link->init = mt8188_dptx_codec_init;
+ }
+ } else if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) {
+ if (!hdmi_node) {
+ dev_dbg(&pdev->dev, "No property 'hdmi-codec'\n");
+ } else {
+ dai_link->codecs->of_node = hdmi_node;
+ dai_link->codecs->name = NULL;
+ dai_link->codecs->dai_name = "i2s-hifi";
+ dai_link->init = mt8188_hdmi_codec_init;
+ }
+ }
+ }
+
+ snd_soc_card_set_drvdata(card, priv);
+
+ ret = devm_snd_soc_register_card(&pdev->dev, card);
+ if (ret)
+ dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n",
+ __func__);
+
+ of_node_put(dp_node);
+ of_node_put(hdmi_node);
+ of_node_put(platform_node);
+
+ return ret;
+}
+
+static struct mt8188_card_data mt8188_evb_card = {
+ .name = "mt8188-sound",
+};
+
+static const struct of_device_id mt8188_mt6359_dt_match[] = {
+ {
+ .compatible = "mediatek,mt8188-sound",
+ .data = &mt8188_evb_card,
+ },
+ {},
+};
+
+static struct platform_driver mt8188_mt6359_driver = {
+ .driver = {
+ .name = "mt8188-sound",
+ .of_match_table = mt8188_mt6359_dt_match,
+ .pm = &snd_soc_pm_ops,
+ },
+ .probe = mt8188_mt6359_dev_probe,
+};
+
+module_platform_driver(mt8188_mt6359_driver);
+
+/* Module information */
+MODULE_DESCRIPTION("MT8188-MT6359 ALSA SoC machine driver");
+MODULE_AUTHOR("Trevor Wu <trevor.wu@mediatek.com>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("mt8188 mt6359 soc card");
+
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
` (9 preceding siblings ...)
2022-09-30 14:57 ` [PATCH 11/12] ASoC: mediatek: mt8188: add machine driver with mt6359 Trevor Wu
@ 2022-09-30 14:57 ` Trevor Wu
2022-10-03 16:38 ` Rob Herring
10 siblings, 1 reply; 29+ messages in thread
From: Trevor Wu @ 2022-09-30 14:57 UTC (permalink / raw)
To: broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: trevor.wu, alsa-devel, linux-mediatek, linux-arm-kernel,
linux-kernel, devicetree
Add document for mt8188 board with mt6359.
Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
---
.../bindings/sound/mt8188-mt6359.yaml | 70 +++++++++++++++++++
1 file changed, 70 insertions(+)
create mode 100644 Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
diff --git a/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
new file mode 100644
index 000000000000..57c7c5ceef8a
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
@@ -0,0 +1,70 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/mt8188-mt6359.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: MediaTek MT8188 ASoC sound card driver
+
+maintainers:
+ - Trevor Wu <trevor.wu@mediatek.com>
+
+description:
+ This binding describes the MT8188 sound card.
+
+properties:
+ compatible:
+ enum:
+ - mediatek,mt8188-sound
+
+ model:
+ $ref: /schemas/types.yaml#/definitions/string
+ description: User specified audio sound card name
+
+ audio-routing:
+ $ref: /schemas/types.yaml#/definitions/non-unique-string-array
+ description:
+ A list of the connections between audio components. Each entry is a
+ sink/source pair of strings. Valid names could be the input or output
+ widgets of audio components, power supplies, MicBias of codec and the
+ software switch.
+
+ mediatek,platform:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+ description: The phandle of MT8188 ASoC platform.
+
+ mediatek,dptx-codec:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+ description: The phandle of MT8188 Display Port Tx codec node.
+
+ mediatek,hdmi-codec:
+ $ref: "/schemas/types.yaml#/definitions/phandle"
+ description: The phandle of MT8188 HDMI codec node.
+
+ mediatek,dai-link:
+ $ref: /schemas/types.yaml#/definitions/string-array
+ description:
+ A list of the desired dai-links in the sound card. Each entry is a
+ name defined in the machine driver.
+
+additionalProperties: false
+
+required:
+ - compatible
+ - mediatek,platform
+
+examples:
+ - |
+
+ sound: mt8188-sound {
+ compatible = "mediatek,mt8188-sound";
+ mediatek,platform = <&afe>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&aud_pins_default>;
+ audio-routing =
+ "Headphone", "Headphone L",
+ "Headphone", "Headphone R",
+ "AIN1", "Headset Mic";
+ };
+
+...
--
2.18.0
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 29+ messages in thread
* Re: [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document
2022-09-30 14:56 ` [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document Trevor Wu
@ 2022-09-30 22:05 ` Rob Herring
2022-10-05 3:57 ` Trevor Wu (吳文良)
2022-10-03 16:30 ` Rob Herring
1 sibling, 1 reply; 29+ messages in thread
From: Rob Herring @ 2022-09-30 22:05 UTC (permalink / raw)
To: Trevor Wu
Cc: linux-kernel, devicetree, p.zabel, linux-mediatek, matthias.bgg,
alsa-devel, robh+dt, tiwai, broonie, linux-arm-kernel
On Fri, 30 Sep 2022 22:56:59 +0800, Trevor Wu wrote:
> Add mt8188 audio afe document.
>
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
> .../bindings/sound/mt8188-afe-pcm.yaml | 202 ++++++++++++++++++
> 1 file changed, 202 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
>
My bot found errors running 'make DT_CHECKER_FLAGS=-m dt_binding_check'
on your patch (DT_CHECKER_FLAGS is new in v5.13):
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.example.dtb: afe@10b10000: clock-names:17: 'adsp_audio26m' was expected
From schema: /builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/patch/
This check can fail if there are any dependencies. The base for a patch
series is generally the most recent rc1.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document
2022-09-30 14:56 ` [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document Trevor Wu
2022-09-30 22:05 ` Rob Herring
@ 2022-10-03 16:30 ` Rob Herring
2022-10-05 10:12 ` Trevor Wu (吳文良)
1 sibling, 1 reply; 29+ messages in thread
From: Rob Herring @ 2022-10-03 16:30 UTC (permalink / raw)
To: Trevor Wu
Cc: broonie, tiwai, matthias.bgg, p.zabel, alsa-devel,
linux-mediatek, linux-arm-kernel, linux-kernel, devicetree
On Fri, Sep 30, 2022 at 10:56:59PM +0800, Trevor Wu wrote:
> Add mt8188 audio afe document.
>
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
> .../bindings/sound/mt8188-afe-pcm.yaml | 202 ++++++++++++++++++
> 1 file changed, 202 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
>
> diff --git a/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
> new file mode 100644
> index 000000000000..50d53c5d59ad
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
> @@ -0,0 +1,202 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/mt8188-afe-pcm.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Mediatek AFE PCM controller for mt8188
> +
> +maintainers:
> + - Trevor Wu <trevor.wu@mediatek.com>
> +
> +properties:
> + compatible:
> + const: mediatek,mt8188-audio
If the block is called 'AFE PCM controller', then perhaps use some of
that for the name instead of just 'audio'.
> +
> + reg:
> + maxItems: 1
> +
> + interrupts:
> + maxItems: 1
> +
> + resets:
> + maxItems: 1
> +
> + reset-names:
> + const: audiosys
> +
> + memory-region:
> + maxItems: 1
> + description: |
> + Shared memory region for AFE memif. A "shared-dma-pool".
> + See ../reserved-memory/reserved-memory.txt for details.
What does that file contain?
No need to provide generic descriptions of common properties, so the
reference can just be dropped.
> +
> + mediatek,topckgen:
> + $ref: "/schemas/types.yaml#/definitions/phandle"
Don't need quotes.
> + description: The phandle of the mediatek topckgen controller
> +
> + mediatek,infracfg:
> + $ref: "/schemas/types.yaml#/definitions/phandle"
> + description: The phandle of the mediatek infracfg controller
> +
> + power-domains:
> + maxItems: 1
> +
> + clocks:
> + items:
> + - description: 26M clock
> + - description: audio pll1 clock
> + - description: audio pll2 clock
> + - description: clock divider for i2si1_mck
> + - description: clock divider for i2si2_mck
> + - description: clock divider for i2so1_mck
> + - description: clock divider for i2so2_mck
> + - description: clock divider for dptx_mck
> + - description: a1sys hoping clock
> + - description: audio intbus clock
> + - description: audio hires clock
> + - description: audio local bus clock
> + - description: mux for dptx_mck
> + - description: mux for i2so1_mck
> + - description: mux for i2so2_mck
> + - description: mux for i2si1_mck
> + - description: mux for i2si2_mck
> + - description: audio 26m clock
> +
> + clock-names:
> + items:
> + - const: clk26m
> + - const: apll1_ck
> + - const: apll2_ck
> + - const: apll12_div0
> + - const: apll12_div1
> + - const: apll12_div2
> + - const: apll12_div3
> + - const: apll12_div9
> + - const: a1sys_hp_sel
> + - const: aud_intbus_sel
> + - const: audio_h_sel
> + - const: audio_local_bus_sel
> + - const: dptx_m_sel
> + - const: i2so1_m_sel
> + - const: i2so2_m_sel
> + - const: i2si1_m_sel
> + - const: i2si2_m_sel
> + - const: adsp_audio26m
> +
> + mediatek,etdm-in1-chn-disabled:
> + $ref: /schemas/types.yaml#/definitions/uint8-array
> + maxItems: 16
> + description: Specify which input channel should be disabled.
What value disables/enables?
items:
enum: [ ??? ]
> +
> + mediatek,etdm-in2-chn-disabled:
> + $ref: /schemas/types.yaml#/definitions/uint8-array
> + maxItems: 16
> + description: Specify which input channel should be disabled.
> +
> +patternProperties:
> + "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
> + description: Specify etdm in mclk output rate for always on case.
> +
> + "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
> + description: Specify etdm out mclk output rate for always on case.
> +
> + "^mediatek,etdm-in[1-2]-multi-pin-mode$":
> + type: boolean
> + description: if present, the etdm data mode is I2S.
> +
> + "^mediatek,etdm-out[1-3]-multi-pin-mode$":
> + type: boolean
> + description: if present, the etdm data mode is I2S.
> +
> + "^mediatek,etdm-in[1-2]-cowork-source$":
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description: |
> + etdm modules can share the same external clock pin. Specify
> + which etdm clock source is required by this etdm in moudule.
> + enum:
> + - 0 # etdm1_in
> + - 1 # etdm2_in
> + - 2 # etdm1_out
> + - 3 # etdm2_out
> +
> + "^mediatek,etdm-out[1-2]-cowork-source$":
> + $ref: /schemas/types.yaml#/definitions/uint32
> + description: |
> + etdm modules can share the same external clock pin. Specify
> + which etdm clock source is required by this etdm out moudule.
> + enum:
> + - 0 # etdm1_in
> + - 1 # etdm2_in
> + - 2 # etdm1_out
> + - 3 # etdm2_out
> +
> +required:
> + - compatible
> + - reg
> + - interrupts
> + - resets
> + - reset-names
> + - mediatek,topckgen
> + - mediatek,infracfg
> + - power-domains
> + - clocks
> + - clock-names
> + - memory-region
> +
> +additionalProperties: false
> +
> +examples:
> + - |
> + #include <dt-bindings/interrupt-controller/arm-gic.h>
> + #include <dt-bindings/interrupt-controller/irq.h>
> +
> + afe: afe@10b10000 {
> + compatible = "mediatek,mt8188-audio";
> + reg = <0x10b10000 0x10000>;
> + interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
> + resets = <&watchdog 14>;
> + reset-names = "audiosys";
> + mediatek,topckgen = <&topckgen>;
> + mediatek,infracfg = <&infracfg_ao>;
> + power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
> + memory-region = <&snd_dma_mem_reserved>;
> + clocks = <&clk26m>,
> + <&topckgen 72>, //CLK_TOP_APLL1
> + <&topckgen 73>, //CLK_TOP_APLL2
> + <&topckgen 186>, //CLK_TOP_APLL12_CK_DIV0
> + <&topckgen 187>, //CLK_TOP_APLL12_CK_DIV1
> + <&topckgen 188>, //CLK_TOP_APLL12_CK_DIV2
> + <&topckgen 189>, //CLK_TOP_APLL12_CK_DIV3
> + <&topckgen 191>, //CLK_TOP_APLL12_CK_DIV9
> + <&topckgen 83>, //CLK_TOP_A1SYS_HP
> + <&topckgen 31>, //CLK_TOP_AUD_INTBUS
> + <&topckgen 32>, //CLK_TOP_AUDIO_H
> + <&topckgen 69>, //CLK_TOP_AUDIO_LOCAL_BUS
> + <&topckgen 81>, //CLK_TOP_DPTX
> + <&topckgen 77>, //CLK_TOP_I2SO1
> + <&topckgen 78>, //CLK_TOP_I2SO2
> + <&topckgen 79>, //CLK_TOP_I2SI1
> + <&topckgen 80>, //CLK_TOP_I2SI2
> + <&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
> + clock-names = "clk26m",
> + "apll1_ck",
> + "apll2_ck",
> + "apll12_div0",
> + "apll12_div1",
> + "apll12_div2",
> + "apll12_div3",
> + "apll12_div9",
> + "a1sys_hp_sel",
> + "aud_intbus_sel",
> + "audio_h_sel",
> + "audio_local_bus_sel",
> + "dptx_m_sel",
> + "i2so1_m_sel",
> + "i2so2_m_sel",
> + "i2si1_m_sel",
> + "i2si2_m_sel",
> + "adsp_audio_26m";
> + };
> +
> +...
> --
> 2.18.0
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document
2022-09-30 14:57 ` [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document Trevor Wu
@ 2022-10-03 16:38 ` Rob Herring
2022-10-06 2:38 ` Trevor Wu (吳文良)
0 siblings, 1 reply; 29+ messages in thread
From: Rob Herring @ 2022-10-03 16:38 UTC (permalink / raw)
To: Trevor Wu
Cc: broonie, tiwai, matthias.bgg, p.zabel, alsa-devel,
linux-mediatek, linux-arm-kernel, linux-kernel, devicetree
On Fri, Sep 30, 2022 at 10:57:01PM +0800, Trevor Wu wrote:
> Add document for mt8188 board with mt6359.
>
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
> .../bindings/sound/mt8188-mt6359.yaml | 70 +++++++++++++++++++
> 1 file changed, 70 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
>
> diff --git a/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml b/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
> new file mode 100644
> index 000000000000..57c7c5ceef8a
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
> @@ -0,0 +1,70 @@
> +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/mt8188-mt6359.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: MediaTek MT8188 ASoC sound card driver
> +
> +maintainers:
> + - Trevor Wu <trevor.wu@mediatek.com>
> +
> +description:
> + This binding describes the MT8188 sound card.
> +
> +properties:
> + compatible:
> + enum:
> + - mediatek,mt8188-sound
> +
> + model:
> + $ref: /schemas/types.yaml#/definitions/string
> + description: User specified audio sound card name
> +
> + audio-routing:
> + $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> + description:
> + A list of the connections between audio components. Each entry is a
> + sink/source pair of strings. Valid names could be the input or output
> + widgets of audio components, power supplies, MicBias of codec and the
> + software switch.
> +
> + mediatek,platform:
> + $ref: "/schemas/types.yaml#/definitions/phandle"
Don't need quotes.
> + description: The phandle of MT8188 ASoC platform.
> +
> + mediatek,dptx-codec:
> + $ref: "/schemas/types.yaml#/definitions/phandle"
> + description: The phandle of MT8188 Display Port Tx codec node.
> +
> + mediatek,hdmi-codec:
> + $ref: "/schemas/types.yaml#/definitions/phandle"
> + description: The phandle of MT8188 HDMI codec node.
> +
> + mediatek,dai-link:
> + $ref: /schemas/types.yaml#/definitions/string-array
> + description:
> + A list of the desired dai-links in the sound card. Each entry is a
> + name defined in the machine driver.
Names have to be defined here.
> +
> +additionalProperties: false
> +
> +required:
> + - compatible
> + - mediatek,platform
> +
> +examples:
> + - |
> +
> + sound: mt8188-sound {
> + compatible = "mediatek,mt8188-sound";
> + mediatek,platform = <&afe>:
> + pinctrl-names = "default";
> + pinctrl-0 = <&aud_pins_default>;
> + audio-routing =
> + "Headphone", "Headphone L",
> + "Headphone", "Headphone R",
> + "AIN1", "Headset Mic";
> + };
> +
> +...
> --
> 2.18.0
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
2022-09-30 14:56 ` [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver Trevor Wu
@ 2022-10-04 9:36 ` AngeloGioacchino Del Regno
2022-10-06 2:48 ` Trevor Wu (吳文良)
[not found] ` <202210011740.ZdLtxKq1-lkp@intel.com>
1 sibling, 1 reply; 29+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-10-04 9:36 UTC (permalink / raw)
To: Trevor Wu, broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: alsa-devel, linux-mediatek, linux-arm-kernel, linux-kernel, devicetree
Il 30/09/22 16:56, Trevor Wu ha scritto:
> Add mt8188 platform driver.
>
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
> This patch depends on the following series that has not been accepted.
>
> [1] Add power domain support for MT8188
> https://patchwork.kernel.org/project/linux-mediatek/list/?series=681359
> (linux/soc/mediatek/infracfg.h is included)
> ---
> sound/soc/mediatek/Kconfig | 13 +
> sound/soc/mediatek/Makefile | 1 +
> sound/soc/mediatek/mt8188/Makefile | 12 +
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 2945 ++++++++++++++++++++
> 4 files changed, 2971 insertions(+)
> create mode 100644 sound/soc/mediatek/mt8188/Makefile
> create mode 100644 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
>
> diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig
> index 363fa4d47680..cf0e4c6b61e7 100644
> --- a/sound/soc/mediatek/Kconfig
> +++ b/sound/soc/mediatek/Kconfig
> @@ -206,6 +206,19 @@ config SND_SOC_MTK_BTCVSD
> Select Y if you have such device.
> If unsure select "N".
>
> +config SND_SOC_MT8188
> + tristate "ASoC support for Mediatek MT8188 chip"
> + depends on ARCH_MEDIATEK || COMPILE_TEST
> + depends on COMMON_CLK
> + select SND_SOC_MEDIATEK
> + select SND_SOC_MT6359
> + select MFD_SYSCON if SND_SOC_MT6359
> + help
> + This adds ASoC platform driver support for Mediatek MT8188 chip
> + that can be used with other codecs.
> + Select Y if you have such device.
> + If unsure select "N".
> +
> config SND_SOC_MT8192
> tristate "ASoC support for Mediatek MT8192 chip"
> depends on ARCH_MEDIATEK
> diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile
> index 5571c640a288..3de38cfc69e5 100644
> --- a/sound/soc/mediatek/Makefile
> +++ b/sound/soc/mediatek/Makefile
> @@ -5,5 +5,6 @@ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
> obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
> obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
> obj-$(CONFIG_SND_SOC_MT8186) += mt8186/
> +obj-$(CONFIG_SND_SOC_MT8188) += mt8188/
> obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
> obj-$(CONFIG_SND_SOC_MT8195) += mt8195/
> diff --git a/sound/soc/mediatek/mt8188/Makefile b/sound/soc/mediatek/mt8188/Makefile
> new file mode 100644
> index 000000000000..fa5d383c5e47
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8188/Makefile
> @@ -0,0 +1,12 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
> +# platform driver
> +snd-soc-mt8188-afe-objs := \
> + mt8188-afe-clk.o \
> + mt8188-afe-pcm.o \
> + mt8188-audsys-clk.o \
> + mt8188-dai-adda.o \
> + mt8188-dai-etdm.o \
> + mt8188-dai-pcm.o
> +
> +obj-$(CONFIG_SND_SOC_MT8188) += snd-soc-mt8188-afe.o
> diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
> new file mode 100644
> index 000000000000..5d8e01c99714
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
> @@ -0,0 +1,2945 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Mediatek ALSA SoC AFE platform driver for 8188
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
> + * Trevor Wu <trevor.wu@mediatek.com>
> + * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
> + */
> +
> +#include <linux/arm-smccc.h>
> +#include <linux/delay.h>
> +#include <linux/dma-mapping.h>
> +#include <linux/module.h>
> +#include <linux/mfd/syscon.h>
> +#include <linux/of.h>
> +#include <linux/of_address.h>
> +#include <linux/of_platform.h>
> +#include <linux/pm_runtime.h>
> +#include <linux/reset.h>
> +#include <linux/soc/mediatek/infracfg.h>
> +#include <linux/soc/mediatek/mtk_sip_svc.h>
> +#include <sound/pcm_params.h>
> +#include "mt8188-afe-common.h"
> +#include "mt8188-afe-clk.h"
> +#include "mt8188-reg.h"
> +#include "../common/mtk-afe-platform-driver.h"
> +#include "../common/mtk-afe-fe-dai.h"
> +
> +#define MTK_SIP_AUDIO_CONTROL MTK_SIP_SMC_CMD(0x517)
This definition goes to include/linux/soc/mediatek/mtk_sip_svc.h
> +
> +#define MT8188_MEMIF_BUFFER_BYTES_ALIGN (0x40)
> +#define MT8188_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff)
> +
> +#define MEMIF_AXI_MINLEN 9 //register default value
...and please fix comments style.
> +
> +struct mtk_dai_memif_priv {
> + unsigned int asys_timing_sel;
> + unsigned int fs_timing;
> +};
> +
..snip..
> +
> +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8188");
MediaTek SoC AFE platform driver for ALSA MT8188
> +MODULE_AUTHOR("Chun-Chia.Chiu <chun-chia.chiu@mediatek.com>");
> +MODULE_LICENSE("GPL");
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver
2022-09-30 14:56 ` [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver Trevor Wu
@ 2022-10-04 9:37 ` AngeloGioacchino Del Regno
2022-10-05 7:14 ` Trevor Wu (吳文良)
0 siblings, 1 reply; 29+ messages in thread
From: AngeloGioacchino Del Regno @ 2022-10-04 9:37 UTC (permalink / raw)
To: Trevor Wu, broonie, tiwai, robh+dt, matthias.bgg, p.zabel
Cc: alsa-devel, linux-mediatek, linux-arm-kernel, linux-kernel, devicetree
Il 30/09/22 16:56, Trevor Wu ha scritto:
> Add mt8188 adda dai driver support.
>
> Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> ---
> sound/soc/mediatek/mt8188/mt8188-dai-adda.c | 639 ++++++++++++++++++++
> 1 file changed, 639 insertions(+)
> create mode 100644 sound/soc/mediatek/mt8188/mt8188-dai-adda.c
>
> diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-adda.c b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
> new file mode 100644
> index 000000000000..ba8f622bb107
> --- /dev/null
> +++ b/sound/soc/mediatek/mt8188/mt8188-dai-adda.c
> @@ -0,0 +1,639 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek ALSA SoC Audio DAI ADDA Control
> + *
> + * Copyright (c) 2022 MediaTek Inc.
> + * Author: Bicycle Tsai <bicycle.tsai@mediatek.com>
> + * Trevor Wu <trevor.wu@mediatek.com>
> + * Chun-Chia Chiu <chun-chia.chiu@mediatek.com>
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/regmap.h>
> +#include "mt8188-afe-clk.h"
> +#include "mt8188-afe-common.h"
> +#include "mt8188-reg.h"
> +
> +#define ADDA_HIRES_THRES 48000
> +
> +enum {
> + SUPPLY_SEQ_CLOCK_SEL,
> + SUPPLY_SEQ_ADDA_DL_ON,
> + SUPPLY_SEQ_ADDA_MTKAIF_CFG,
> + SUPPLY_SEQ_ADDA_UL_ON,
> + SUPPLY_SEQ_ADDA_AFE_ON,
> +};
> +
> +enum {
> + MTK_AFE_ADDA_DL_RATE_8K = 0,
> + MTK_AFE_ADDA_DL_RATE_11K = 1,
> + MTK_AFE_ADDA_DL_RATE_12K = 2,
> + MTK_AFE_ADDA_DL_RATE_16K = 3,
> + MTK_AFE_ADDA_DL_RATE_22K = 4,
> + MTK_AFE_ADDA_DL_RATE_24K = 5,
> + MTK_AFE_ADDA_DL_RATE_32K = 6,
> + MTK_AFE_ADDA_DL_RATE_44K = 7,
> + MTK_AFE_ADDA_DL_RATE_48K = 8,
> + MTK_AFE_ADDA_DL_RATE_96K = 9,
> + MTK_AFE_ADDA_DL_RATE_192K = 10,
> +};
> +
> +enum {
> + MTK_AFE_ADDA_UL_RATE_8K = 0,
> + MTK_AFE_ADDA_UL_RATE_16K = 1,
> + MTK_AFE_ADDA_UL_RATE_32K = 2,
> + MTK_AFE_ADDA_UL_RATE_48K = 3,
> + MTK_AFE_ADDA_UL_RATE_96K = 4,
> + MTK_AFE_ADDA_UL_RATE_192K = 5,
> +};
> +
> +enum {
> + DELAY_DATA_MISO1 = 0,
> + DELAY_DATA_MISO0 = 1,
> +};
> +
> +struct mtk_dai_adda_priv {
> + unsigned int dl_rate;
> + unsigned int ul_rate;
> +};
> +
..snip..
> +
> +static int mt8188_adda_mtkaif_init(struct mtk_base_afe *afe)
> +{
> + struct mt8188_afe_private *afe_priv = afe->platform_priv;
> + struct mtkaif_param *param = &afe_priv->mtkaif_params;
> + int delay_data;
> + int delay_cycle;
> + unsigned int mask = 0;
> + unsigned int val = 0;
> +
> + /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
> + mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
> + val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
> +
> + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val);
This should be
regmap_set_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
> +
> + mask = RG_RX_PROTOCOL2;
> + val = RG_RX_PROTOCOL2;
> + regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
regmap_set_bits() again
> +
> + if (!param->mtkaif_calibration_ok) {
> + dev_info(afe->dev, "%s(), calibration fail\n", __func__);
> + return 0;
> + }
> +
> + /* set delay for ch1, ch2 */
> + if (param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] >=
> + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]) {
> + delay_data = DELAY_DATA_MISO1;
> + delay_cycle =
> + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] -
> + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1];
> + } else {
> + delay_data = DELAY_DATA_MISO0;
> + delay_cycle =
> + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1] -
> + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0];
> + }
> +
> + val = 0;
> + mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
> + val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
> + MTKAIF_RXIF_DELAY_CYCLE_MASK;
val = FIELD_PREP(MTKAIF_RXIF_DELAY_CYCLE_MASK, delay_cycle);
> + val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
val |= FIELD_PREP(MTKAIF_RXIF_DELAY_DATA, delay_data);
Can you please use bitfield access macros across the entire file (and the others)?
This will both increase human readability and add compile-time checks on register
fields.
> + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val);
> +
> + return 0;
> +}
> +
> +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w,
> + struct snd_kcontrol *kcontrol,
> + int event)
> +{
> + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +
> + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
> + __func__, w->name, event);
> +
> + switch (event) {
> + case SND_SOC_DAPM_PRE_PMU:
> + mt8188_adda_mtkaif_init(afe);
> + break;
> + default:
> + break;
> + }
> +
> + return 0;
> +}
> +
> +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
> + struct snd_kcontrol *kcontrol,
> + int event)
> +{
> + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> +
> + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
> + __func__, w->name, event);
> +
> + switch (event) {
> + case SND_SOC_DAPM_POST_PMD:
> + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */
> + usleep_range(125, 135);
> + break;
> + default:
> + break;
> + }
> +
> + return 0;
> +}
> +
> +static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, bool dmic)
> +{
> + unsigned int reg = AFE_ADDA_UL_SRC_CON0;
> + unsigned int val = 0;
> + unsigned int mask;
> +
> + mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
> + UL_MODE_3P25M_CH2_CTL);
val = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL | UL_MODE_3P25M_CH2_CTL);
> +
> + /* turn on dmic, ch1, ch2 */
> + if (dmic)
regmap_set_bits(afe->regmap, reg, val);
else
regmap_clear_bits(afe->regmap, reg, val);
> + val = mask;
> +
> + regmap_update_bits(afe->regmap, reg, mask, val);
> +}
> +
..snip..
> +
> +static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget *source,
> + struct snd_soc_dapm_widget *sink)
> +{
> + struct snd_soc_dapm_widget *w = source;
> + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> + struct mt8188_afe_private *afe_priv = afe->platform_priv;
> + struct mtk_dai_adda_priv *adda_priv;
> +
> + adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
> +
> + if (!adda_priv) {
> + dev_err(afe->dev, "%s adda_priv == NULL", __func__);
> + return 0;
return -EINVAL?
> + }
> +
> + return (adda_priv->ul_rate > ADDA_HIRES_THRES) ? 1 : 0;
return !!(adda_priv->ul_rate > ADDA_HIRES_THRES);
> +}
> +
> +static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget *source,
> + struct snd_soc_dapm_widget *sink)
> +{
> + struct snd_soc_dapm_widget *w = source;
> + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm);
> + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt);
> + struct mt8188_afe_private *afe_priv = afe->platform_priv;
> + struct mtk_dai_adda_priv *adda_priv;
> +
> + adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
> +
> + if (!adda_priv) {
> + dev_err(afe->dev, "%s adda_priv == NULL", __func__);
> + return 0;
same here
> + }
> +
> + return (adda_priv->dl_rate > ADDA_HIRES_THRES) ? 1 : 0;
> +}
> +
..snip..
Regards,
Angelo
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document
2022-09-30 22:05 ` Rob Herring
@ 2022-10-05 3:57 ` Trevor Wu (吳文良)
2022-10-28 23:46 ` Krzysztof Kozlowski
0 siblings, 1 reply; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-05 3:57 UTC (permalink / raw)
To: robh
Cc: linux-kernel, linux-mediatek, robh+dt, devicetree, broonie,
p.zabel, tiwai, linux-arm-kernel, matthias.bgg, alsa-devel
On Fri, 2022-09-30 at 17:05 -0500, Rob Herring wrote:
> On Fri, 30 Sep 2022 22:56:59 +0800, Trevor Wu wrote:
> > Add mt8188 audio afe document.
> >
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> > .../bindings/sound/mt8188-afe-pcm.yaml | 202
> > ++++++++++++++++++
> > 1 file changed, 202 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/mt8188-
> > afe-pcm.yaml
> >
>
> My bot found errors running 'make DT_CHECKER_FLAGS=-m
> dt_binding_check'
> on your patch (DT_CHECKER_FLAGS is new in v5.13):
>
> yamllint warnings/errors:
>
> dtschema/dtc warnings/errors:
> /builds/robherring/dt-review-
> ci/linux/Documentation/devicetree/bindings/sound/mt8188-afe-
> pcm.example.dtb: afe@10b10000: clock-names:17: 'adsp_audio26m' was
> expected
> From schema: /builds/robherring/dt-review-
> ci/linux/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
>
> doc reference errors (make refcheckdocs):
>
> See https://patchwork.ozlabs.org/patch/
>
> This check can fail if there are any dependencies. The base for a
> patch
> series is generally the most recent rc1.
>
> If you already ran 'make dt_binding_check' and didn't see the above
> error(s), then make sure 'yamllint' is installed and dt-schema is up
> to
> date:
>
> pip3 install dtschema --upgrade
>
> Please check and re-submit.
>
After upgrading dtschema, I can see the problem.
I will correct it in V2.
Thanks,
Trevor
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
[not found] ` <202210011740.ZdLtxKq1-lkp@intel.com>
@ 2022-10-05 6:50 ` Trevor Wu (吳文良)
2022-10-05 10:59 ` Mark Brown
0 siblings, 1 reply; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-05 6:50 UTC (permalink / raw)
To: p.zabel, matthias.bgg, lkp, broonie, tiwai, robh+dt
Cc: kbuild-all, linux-arm-kernel, linux-mediatek, linux-kernel,
alsa-devel, devicetree
Hi maintainers,
As I mentioned in the comment, this patch depends on a reviewing
series.
Should I remove the related code from this patch in case of the build
error?
Thanks,
Trevor
On Sat, 2022-10-01 at 17:17 +0800, kernel test robot wrote:
> Hi Trevor,
>
> Thank you for the patch! Yet something to improve:
>
> [auto build test ERROR on broonie-sound/for-next]
> [also build test ERROR on broonie-spi/for-next tiwai-sound/for-next
> linus/master v6.0-rc7 next-20220930]
> [If your patch is applied to the wrong git tree, kindly drop us a
> note.
> And when submitting patch, we suggest to use '--base' as documented
> in
>
https://urldefense.com/v3/__https://git-scm.com/docs/git-format-patch*_base_tree_information__;Iw!!CTRNKA9wMg0ARbw!zH8i2KTwLCuHKyCuVMxGmO2ybS8oDN4t6suHxraLKrmfrn6SFI0bxxEdFfZ77PE7Rg$
> ]
>
> url:
> https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux/commits/Trevor-Wu/ASoC-mediatek-Add-support-for-MT8188-SoC/20220930-230009__;!!CTRNKA9wMg0ARbw!zH8i2KTwLCuHKyCuVMxGmO2ybS8oDN4t6suHxraLKrmfrn6SFI0bxxEdFfY6vzwyJg$
>
> base:
> https://urldefense.com/v3/__https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git__;!!CTRNKA9wMg0ARbw!zH8i2KTwLCuHKyCuVMxGmO2ybS8oDN4t6suHxraLKrmfrn6SFI0bxxEdFfY9CuKUxg$
> for-next
> config: s390-allyesconfig
> compiler: s390-linux-gcc (GCC) 12.1.0
> reproduce (this is a W=1 build):
> wget
> https://urldefense.com/v3/__https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross__;!!CTRNKA9wMg0ARbw!zH8i2KTwLCuHKyCuVMxGmO2ybS8oDN4t6suHxraLKrmfrn6SFI0bxxEdFfYvE9N_pg$
> -O ~/bin/make.cross
> chmod +x ~/bin/make.cross
> #
> https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux/commit/65c941d291852582ccbe6a8196ff3b60fb4d1243__;!!CTRNKA9wMg0ARbw!zH8i2KTwLCuHKyCuVMxGmO2ybS8oDN4t6suHxraLKrmfrn6SFI0bxxEdFfb2BtdE-w$
>
> git remote add linux-review
> https://urldefense.com/v3/__https://github.com/intel-lab-lkp/linux__;!!CTRNKA9wMg0ARbw!zH8i2KTwLCuHKyCuVMxGmO2ybS8oDN4t6suHxraLKrmfrn6SFI0bxxEdFfbWjiP_lw$
>
> git fetch --no-tags linux-review Trevor-Wu/ASoC-mediatek-Add-
> support-for-MT8188-SoC/20220930-230009
> git checkout 65c941d291852582ccbe6a8196ff3b60fb4d1243
> # save the config file
> mkdir build_dir && cp config build_dir/.config
> COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0
> make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash
>
> If you fix the issue, kindly add following tag where applicable
> > Reported-by: kernel test robot <lkp@intel.com>
>
> All errors (new ones prefixed by >>):
>
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c: In function
> 'bus_protect_enable':
> > > sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2649:16: error:
> > > 'MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1' undeclared (first use in
> > > this function); did you mean
> > > 'MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1'?
>
> 2649 | mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2649:16: note: each
> undeclared identifier is reported only once for each function it
> appears in
> > > sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2650:30: error:
> > > 'MT8188_TOP_AXI_PROT_EN_2_SET' undeclared (first use in this
> > > function); did you mean 'MT8186_TOP_AXI_PROT_EN_2_SET'?
>
> 2650 | regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET,
> mask);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | MT8186_TOP_AXI_PROT_EN_2_SET
> In file included from include/linux/regmap.h:20,
> from sound/soc/mediatek/mt8188/mt8188-afe-
> common.h:15,
> from sound/soc/mediatek/mt8188/mt8188-afe-
> pcm.c:24:
> > > sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2652:48: error:
> > > 'MT8188_TOP_AXI_PROT_EN_2_STA' undeclared (first use in this
> > > function); did you mean 'MT8186_TOP_AXI_PROT_EN_2_STA'?
>
> 2652 | ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> | ^~~~~~~~~~~
> ~~~~~~~~~~~~~~~~~
> include/linux/iopoll.h:46:28: note: in definition of macro
> 'read_poll_timeout'
> 46 | (val) = op(args); \
> | ^~~~
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2652:15: note: in
> expansion of macro 'regmap_read_poll_timeout'
> 2652 | ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> | ^~~~~~~~~~~~~~~~~~~~~~~~
> > > sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2659:16: error:
> > > 'MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2' undeclared (first use in
> > > this function); did you mean
> > > 'MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1'?
>
> 2659 | mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c: In function
> 'bus_protect_disable':
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2678:16: error:
> 'MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2' undeclared (first use in this
> function); did you mean 'MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1'?
> 2678 | mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1
> > > sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2679:30: error:
> > > 'MT8188_TOP_AXI_PROT_EN_2_CLR' undeclared (first use in this
> > > function); did you mean 'MT8186_TOP_AXI_PROT_EN_2_CLR'?
>
> 2679 | regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR,
> mask);
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | MT8186_TOP_AXI_PROT_EN_2_CLR
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2681:48: error:
> 'MT8188_TOP_AXI_PROT_EN_2_STA' undeclared (first use in this
> function); did you mean 'MT8186_TOP_AXI_PROT_EN_2_STA'?
> 2681 | ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> | ^~~~~~~~~~~
> ~~~~~~~~~~~~~~~~~
> include/linux/iopoll.h:46:28: note: in definition of macro
> 'read_poll_timeout'
> 46 | (val) = op(args); \
> | ^~~~
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2681:15: note: in
> expansion of macro 'regmap_read_poll_timeout'
> 2681 | ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> | ^~~~~~~~~~~~~~~~~~~~~~~~
> sound/soc/mediatek/mt8188/mt8188-afe-pcm.c:2688:16: error:
> 'MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1' undeclared (first use in this
> function); did you mean 'MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1'?
> 2688 | mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> | MT8186_TOP_AXI_PROT_EN_1_DIS_STEP1
>
>
> vim +2649 sound/soc/mediatek/mt8188/mt8188-afe-pcm.c
>
> 2641
> 2642 static int bus_protect_enable(struct regmap *regmap)
> 2643 {
> 2644 int ret;
> 2645 u32 val;
> 2646 u32 mask;
> 2647
> 2648 val = 0;
> > 2649 mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
> > 2650 regmap_write(regmap,
> > MT8188_TOP_AXI_PROT_EN_2_SET, mask);
>
> 2651
> > 2652 ret = regmap_read_poll_timeout(regmap,
> > MT8188_TOP_AXI_PROT_EN_2_STA,
>
> 2653 val, (val &
> mask) == mask,
> 2654 MT8188_DELAY_US,
> MT8188_TIMEOUT_US);
> 2655 if (ret)
> 2656 return ret;
> 2657
> 2658 val = 0;
> > 2659 mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
>
> 2660 regmap_write(regmap,
> MT8188_TOP_AXI_PROT_EN_2_SET, mask);
> 2661
> 2662 ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> 2663 val, (val &
> mask) == mask,
> 2664 MT8188_DELAY_US,
> MT8188_TIMEOUT_US);
> 2665 if (ret)
> 2666 return ret;
> 2667
> 2668 return 0;
> 2669 }
> 2670
> 2671 static int bus_protect_disable(struct regmap *regmap)
> 2672 {
> 2673 int ret;
> 2674 u32 val;
> 2675 u32 mask;
> 2676
> 2677 val = 0;
> 2678 mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2;
> > 2679 regmap_write(regmap,
> > MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
>
> 2680
> 2681 ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> 2682 val, !(val &
> mask),
> 2683 MT8188_DELAY_US,
> MT8188_TIMEOUT_US);
> 2684 if (ret)
> 2685 return ret;
> 2686
> 2687 val = 0;
> 2688 mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1;
> 2689 regmap_write(regmap,
> MT8188_TOP_AXI_PROT_EN_2_CLR, mask);
> 2690
> 2691 ret = regmap_read_poll_timeout(regmap,
> MT8188_TOP_AXI_PROT_EN_2_STA,
> 2692 val, !(val &
> mask),
> 2693 MT8188_DELAY_US,
> MT8188_TIMEOUT_US);
> 2694 if (ret)
> 2695 return ret;
> 2696
> 2697 return 0;
> 2698 }
> 2699
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver
2022-10-04 9:37 ` AngeloGioacchino Del Regno
@ 2022-10-05 7:14 ` Trevor Wu (吳文良)
0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-05 7:14 UTC (permalink / raw)
To: robh+dt, matthias.bgg, p.zabel, angelogioacchino.delregno,
broonie, tiwai
Cc: linux-arm-kernel, linux-kernel, linux-mediatek, alsa-devel, devicetree
On Tue, 2022-10-04 at 11:37 +0200, AngeloGioacchino Del Regno wrote:
> Il 30/09/22 16:56, Trevor Wu ha scritto:
> >
..snip..
>
> > +
> > +static int mt8188_adda_mtkaif_init(struct mtk_base_afe *afe)
> > +{
> > + struct mt8188_afe_private *afe_priv = afe->platform_priv;
> > + struct mtkaif_param *param = &afe_priv->mtkaif_params;
> > + int delay_data;
> > + int delay_cycle;
> > + unsigned int mask = 0;
> > + unsigned int val = 0;
> > +
> > + /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */
> > + mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
> > + val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2);
> > +
> > + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask,
> > val);
>
> This should be
> regmap_set_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0,
> MTKAIF_RXIF_CLKINV_ADC |
> MTKAIF_RXIF_PROTOCOL2);
OK. I will replace all similar usages in V2.
> > +
> > + mask = RG_RX_PROTOCOL2;
> > + val = RG_RX_PROTOCOL2;
> > + regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val);
>
> regmap_set_bits() again
>
> > +
> > + if (!param->mtkaif_calibration_ok) {
> > + dev_info(afe->dev, "%s(), calibration
> > fail\n", __func__);
> > + return 0;
> > + }
> > +
> > + /* set delay for ch1, ch2 */
> > + if (param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0] >=
> > + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]) {
> > + delay_data = DELAY_DATA_MISO1;
> > + delay_cycle =
> > + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0]
> > -
> > + param-
> > >mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1];
> > + } else {
> > + delay_data = DELAY_DATA_MISO0;
> > + delay_cycle =
> > + param->mtkaif_phase_cycle[MT8188_MTKAIF_MISO_1]
> > -
> > + param-
> > >mtkaif_phase_cycle[MT8188_MTKAIF_MISO_0];
> > + }
> > +
> > + val = 0;
> > + mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK);
> > + val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) &
> > + MTKAIF_RXIF_DELAY_CYCLE_MASK;
>
> val = FIELD_PREP(MTKAIF_RXIF_DELAY_CYCLE_MASK, delay_cycle);
>
> > + val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT;
>
> val |= FIELD_PREP(MTKAIF_RXIF_DELAY_DATA, delay_data);
>
> Can you please use bitfield access macros across the entire file (and
> the others)?
> This will both increase human readability and add compile-time checks
> on register
> fields.
>
Thanks for your suggestion.
compile-time checks are helpful to find some unexpected errors.
I will update it in V2.
> > + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask,
> > val);
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget
> > *w,
> > + struct snd_kcontrol *kcontrol,
> > + int event)
> > +{
> > + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > + struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +
> > + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
> > + __func__, w->name, event);
> > +
> > + switch (event) {
> > + case SND_SOC_DAPM_PRE_PMU:
> > + mt8188_adda_mtkaif_init(afe);
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w,
> > + struct snd_kcontrol *kcontrol,
> > + int event)
> > +{
> > + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > + struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > +
> > + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n",
> > + __func__, w->name, event);
> > +
> > + switch (event) {
> > + case SND_SOC_DAPM_POST_PMD:
> > + /* should delayed 1/fs(smallest is 8k) = 125us before
> > afe off */
> > + usleep_range(125, 135);
> > + break;
> > + default:
> > + break;
> > + }
> > +
> > + return 0;
> > +}
> > +
> > +static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, bool
> > dmic)
> > +{
> > + unsigned int reg = AFE_ADDA_UL_SRC_CON0;
> > + unsigned int val = 0;
> > + unsigned int mask;
> > +
> > + mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
> > + UL_MODE_3P25M_CH2_CTL);
>
> val = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL |
> UL_MODE_3P25M_CH2_CTL);
>
> > +
> > + /* turn on dmic, ch1, ch2 */
> > + if (dmic)
>
> regmap_set_bits(afe->regmap, reg, val);
> else
> regmap_clear_bits(afe->regmap, reg, val);
>
>
OK. I will update this part in V2.
> > + val = mask;
> > +
> > + regmap_update_bits(afe->regmap, reg, mask, val);
> > +}
> > +
>
> ..snip..
>
> > +
> > +static int mtk_afe_adc_hires_connect(struct snd_soc_dapm_widget
> > *source,
> > + struct snd_soc_dapm_widget *sink)
> > +{
> > + struct snd_soc_dapm_widget *w = source;
> > + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > + struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > + struct mt8188_afe_private *afe_priv = afe->platform_priv;
> > + struct mtk_dai_adda_priv *adda_priv;
> > +
> > + adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
> > +
> > + if (!adda_priv) {
> > + dev_err(afe->dev, "%s adda_priv == NULL", __func__);
> > + return 0;
>
> return -EINVAL?
>
dapm_supply_check_power doesn't handled error return value, so it seems
to be better to keep return 0 here.
> > + }
> > +
> > + return (adda_priv->ul_rate > ADDA_HIRES_THRES) ? 1 : 0;
>
> return !!(adda_priv->ul_rate > ADDA_HIRES_THRES);
>
OK. I will update it in V2.
> > +}
> > +
> > +static int mtk_afe_dac_hires_connect(struct snd_soc_dapm_widget
> > *source,
> > + struct snd_soc_dapm_widget *sink)
> > +{
> > + struct snd_soc_dapm_widget *w = source;
> > + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w-
> > >dapm);
> > + struct mtk_base_afe *afe =
> > snd_soc_component_get_drvdata(cmpnt);
> > + struct mt8188_afe_private *afe_priv = afe->platform_priv;
> > + struct mtk_dai_adda_priv *adda_priv;
> > +
> > + adda_priv = afe_priv->dai_priv[MT8188_AFE_IO_ADDA];
> > +
> > + if (!adda_priv) {
> > + dev_err(afe->dev, "%s adda_priv == NULL", __func__);
> > + return 0;
>
> same here
>
> > + }
> > +
> > + return (adda_priv->dl_rate > ADDA_HIRES_THRES) ? 1 : 0;
> > +}
> > +
>
> ..snip..
>
> Regards,
> Angelo
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document
2022-10-03 16:30 ` Rob Herring
@ 2022-10-05 10:12 ` Trevor Wu (吳文良)
0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-05 10:12 UTC (permalink / raw)
To: robh
Cc: linux-mediatek, linux-kernel, devicetree, broonie, p.zabel,
tiwai, linux-arm-kernel, matthias.bgg, alsa-devel
On Mon, 2022-10-03 at 11:30 -0500, Rob Herring wrote:
> On Fri, Sep 30, 2022 at 10:56:59PM +0800, Trevor Wu wrote:
> > Add mt8188 audio afe document.
> >
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> > .../bindings/sound/mt8188-afe-pcm.yaml | 202
> > ++++++++++++++++++
> > 1 file changed, 202 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/mt8188-
> > afe-pcm.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/mt8188-afe-
> > pcm.yaml b/Documentation/devicetree/bindings/sound/mt8188-afe-
> > pcm.yaml
> > new file mode 100644
> > index 000000000000..50d53c5d59ad
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/mt8188-afe-pcm.yaml
> > @@ -0,0 +1,202 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id:
> > https://urldefense.com/v3/__http://devicetree.org/schemas/sound/mt8188-afe-pcm.yaml*__;Iw!!CTRNKA9wMg0ARbw!xwWXHB7ARJJusyOyhgO1AwihlxFMNOrcEU6Qs5vpVCj2VHgxRXNRfpHvNTkqt1MlsQ$
> >
> > +$schema:
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!xwWXHB7ARJJusyOyhgO1AwihlxFMNOrcEU6Qs5vpVCj2VHgxRXNRfpHvNTk0c9L9VQ$
> >
> > +
> > +title: Mediatek AFE PCM controller for mt8188
> > +
> > +maintainers:
> > + - Trevor Wu <trevor.wu@mediatek.com>
> > +
> > +properties:
> > + compatible:
> > + const: mediatek,mt8188-audio
>
> If the block is called 'AFE PCM controller', then perhaps use some
> of
> that for the name instead of just 'audio'.
OK. Is "mediatek,mt8188-afe" better for you?
>
> > +
> > + reg:
> > + maxItems: 1
> > +
> > + interrupts:
> > + maxItems: 1
> > +
> > + resets:
> > + maxItems: 1
> > +
> > + reset-names:
> > + const: audiosys
> > +
> > + memory-region:
> > + maxItems: 1
> > + description: |
> > + Shared memory region for AFE memif. A "shared-dma-pool".
> > + See ../reserved-memory/reserved-memory.txt for details.
>
> What does that file contain?
>
> No need to provide generic descriptions of common properties, so the
> reference can just be dropped.
>
"../reserved-memory/reserved-memory" contains the detail of reserved-
memory, and it's replaced by reserved-memory.yaml now.
I will remove the item in V2, because it's still not supported in the
current code base.
Next time I will remove the description, when I add common properties.
> > +
> > + mediatek,topckgen:
> > + $ref: "/schemas/types.yaml#/definitions/phandle"
>
> Don't need quotes.
>
Did you mean I should delete this line, and only leave description
here?
> > + description: The phandle of the mediatek topckgen controller
> > +
> > + mediatek,infracfg:
> > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > + description: The phandle of the mediatek infracfg controller
> > +
> > + power-domains:
> > + maxItems: 1
> > +
> > + clocks:
> > + items:
> > + - description: 26M clock
> > + - description: audio pll1 clock
> > + - description: audio pll2 clock
> > + - description: clock divider for i2si1_mck
> > + - description: clock divider for i2si2_mck
> > + - description: clock divider for i2so1_mck
> > + - description: clock divider for i2so2_mck
> > + - description: clock divider for dptx_mck
> > + - description: a1sys hoping clock
> > + - description: audio intbus clock
> > + - description: audio hires clock
> > + - description: audio local bus clock
> > + - description: mux for dptx_mck
> > + - description: mux for i2so1_mck
> > + - description: mux for i2so2_mck
> > + - description: mux for i2si1_mck
> > + - description: mux for i2si2_mck
> > + - description: audio 26m clock
> > +
> > + clock-names:
> > + items:
> > + - const: clk26m
> > + - const: apll1_ck
> > + - const: apll2_ck
> > + - const: apll12_div0
> > + - const: apll12_div1
> > + - const: apll12_div2
> > + - const: apll12_div3
> > + - const: apll12_div9
> > + - const: a1sys_hp_sel
> > + - const: aud_intbus_sel
> > + - const: audio_h_sel
> > + - const: audio_local_bus_sel
> > + - const: dptx_m_sel
> > + - const: i2so1_m_sel
> > + - const: i2so2_m_sel
> > + - const: i2si1_m_sel
> > + - const: i2si2_m_sel
> > + - const: adsp_audio26m
> > +
> > + mediatek,etdm-in1-chn-disabled:
> > + $ref: /schemas/types.yaml#/definitions/uint8-array
> > + maxItems: 16
> > + description: Specify which input channel should be disabled.
>
> What value disables/enables?
>
> items:
> enum: [ ??? ]
>
Max channel number is 16, so the value could be 0~15 in the array.
For example, when 0 and 2 are configured, the input channel 0 and
channel 2 won't be put in data on memory.
I will add enum: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
here.
> > +
> > + mediatek,etdm-in2-chn-disabled:
> > + $ref: /schemas/types.yaml#/definitions/uint8-array
> > + maxItems: 16
> > + description: Specify which input channel should be disabled.
> > +
> > +patternProperties:
> > + "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$":
> > + description: Specify etdm in mclk output rate for always on
> > case.
> > +
> > + "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$":
> > + description: Specify etdm out mclk output rate for always on
> > case.
> > +
> > + "^mediatek,etdm-in[1-2]-multi-pin-mode$":
> > + type: boolean
> > + description: if present, the etdm data mode is I2S.
> > +
> > + "^mediatek,etdm-out[1-3]-multi-pin-mode$":
> > + type: boolean
> > + description: if present, the etdm data mode is I2S.
> > +
> > + "^mediatek,etdm-in[1-2]-cowork-source$":
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description: |
> > + etdm modules can share the same external clock pin. Specify
> > + which etdm clock source is required by this etdm in moudule.
> > + enum:
> > + - 0 # etdm1_in
> > + - 1 # etdm2_in
> > + - 2 # etdm1_out
> > + - 3 # etdm2_out
> > +
> > + "^mediatek,etdm-out[1-2]-cowork-source$":
> > + $ref: /schemas/types.yaml#/definitions/uint32
> > + description: |
> > + etdm modules can share the same external clock pin. Specify
> > + which etdm clock source is required by this etdm out
> > moudule.
> > + enum:
> > + - 0 # etdm1_in
> > + - 1 # etdm2_in
> > + - 2 # etdm1_out
> > + - 3 # etdm2_out
> > +
> > +required:
> > + - compatible
> > + - reg
> > + - interrupts
> > + - resets
> > + - reset-names
> > + - mediatek,topckgen
> > + - mediatek,infracfg
> > + - power-domains
> > + - clocks
> > + - clock-names
> > + - memory-region
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > + - |
> > + #include <dt-bindings/interrupt-controller/arm-gic.h>
> > + #include <dt-bindings/interrupt-controller/irq.h>
> > +
> > + afe: afe@10b10000 {
> > + compatible = "mediatek,mt8188-audio";
> > + reg = <0x10b10000 0x10000>;
> > + interrupts = <GIC_SPI 822 IRQ_TYPE_LEVEL_HIGH 0>;
> > + resets = <&watchdog 14>;
> > + reset-names = "audiosys";
> > + mediatek,topckgen = <&topckgen>;
> > + mediatek,infracfg = <&infracfg_ao>;
> > + power-domains = <&spm 7>; //MT8195_POWER_DOMAIN_AUDIO
> > + memory-region = <&snd_dma_mem_reserved>;
> > + clocks = <&clk26m>,
> > + <&topckgen 72>, //CLK_TOP_APLL1
> > + <&topckgen 73>, //CLK_TOP_APLL2
> > + <&topckgen 186>, //CLK_TOP_APLL12_CK_DIV0
> > + <&topckgen 187>, //CLK_TOP_APLL12_CK_DIV1
> > + <&topckgen 188>, //CLK_TOP_APLL12_CK_DIV2
> > + <&topckgen 189>, //CLK_TOP_APLL12_CK_DIV3
> > + <&topckgen 191>, //CLK_TOP_APLL12_CK_DIV9
> > + <&topckgen 83>, //CLK_TOP_A1SYS_HP
> > + <&topckgen 31>, //CLK_TOP_AUD_INTBUS
> > + <&topckgen 32>, //CLK_TOP_AUDIO_H
> > + <&topckgen 69>, //CLK_TOP_AUDIO_LOCAL_BUS
> > + <&topckgen 81>, //CLK_TOP_DPTX
> > + <&topckgen 77>, //CLK_TOP_I2SO1
> > + <&topckgen 78>, //CLK_TOP_I2SO2
> > + <&topckgen 79>, //CLK_TOP_I2SI1
> > + <&topckgen 80>, //CLK_TOP_I2SI2
> > + <&adsp_audio26m 0>; //CLK_AUDIODSP_AUDIO26M
> > + clock-names = "clk26m",
> > + "apll1_ck",
> > + "apll2_ck",
> > + "apll12_div0",
> > + "apll12_div1",
> > + "apll12_div2",
> > + "apll12_div3",
> > + "apll12_div9",
> > + "a1sys_hp_sel",
> > + "aud_intbus_sel",
> > + "audio_h_sel",
> > + "audio_local_bus_sel",
> > + "dptx_m_sel",
> > + "i2so1_m_sel",
> > + "i2so2_m_sel",
> > + "i2si1_m_sel",
> > + "i2si2_m_sel",
> > + "adsp_audio_26m";
> > + };
> > +
> > +...
> > --
> > 2.18.0
> >
> >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
2022-10-05 6:50 ` Trevor Wu (吳文良)
@ 2022-10-05 10:59 ` Mark Brown
2022-10-06 3:13 ` Trevor Wu (吳文良)
0 siblings, 1 reply; 29+ messages in thread
From: Mark Brown @ 2022-10-05 10:59 UTC (permalink / raw)
To: Trevor Wu (吳文良)
Cc: p.zabel, matthias.bgg, lkp, tiwai, robh+dt, kbuild-all,
linux-arm-kernel, linux-mediatek, linux-kernel, alsa-devel,
devicetree
[-- Attachment #1.1: Type: text/plain, Size: 358 bytes --]
On Wed, Oct 05, 2022 at 06:50:53AM +0000, Trevor Wu (吳文良) wrote:
> Hi maintainers,
>
> As I mentioned in the comment, this patch depends on a reviewing
> series.
> Should I remove the related code from this patch in case of the build
> error?
It's bit easier to do that, though it should be fine to just note in the
cover like you've done.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document
2022-10-03 16:38 ` Rob Herring
@ 2022-10-06 2:38 ` Trevor Wu (吳文良)
2022-10-21 8:54 ` Trevor Wu (吳文良)
2022-10-21 8:58 ` Trevor Wu (吳文良)
0 siblings, 2 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-06 2:38 UTC (permalink / raw)
To: robh
Cc: linux-mediatek, linux-kernel, devicetree, broonie, p.zabel,
tiwai, linux-arm-kernel, matthias.bgg, alsa-devel
On Mon, 2022-10-03 at 11:38 -0500, Rob Herring wrote:
> On Fri, Sep 30, 2022 at 10:57:01PM +0800, Trevor Wu wrote:
> > Add document for mt8188 board with mt6359.
> >
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> > .../bindings/sound/mt8188-mt6359.yaml | 70
> > +++++++++++++++++++
> > 1 file changed, 70 insertions(+)
> > create mode 100644 Documentation/devicetree/bindings/sound/mt8188-
> > mt6359.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/mt8188-
> > mt6359.yaml b/Documentation/devicetree/bindings/sound/mt8188-
> > mt6359.yaml
> > new file mode 100644
> > index 000000000000..57c7c5ceef8a
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
> > @@ -0,0 +1,70 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id:
> > https://urldefense.com/v3/__http://devicetree.org/schemas/sound/mt8188-mt6359.yaml*__;Iw!!CTRNKA9wMg0ARbw!wMc6I2aXRzI45UPQTEAzU4ZujV6VaiFGkiKBy18A_5DlQehTxU00u1QSpiOzgAgKtA$
> >
> > +$schema:
> > https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!wMc6I2aXRzI45UPQTEAzU4ZujV6VaiFGkiKBy18A_5DlQehTxU00u1QSpiMSKPWbtQ$
> >
> > +
> > +title: MediaTek MT8188 ASoC sound card driver
> > +
> > +maintainers:
> > + - Trevor Wu <trevor.wu@mediatek.com>
> > +
> > +description:
> > + This binding describes the MT8188 sound card.
> > +
> > +properties:
> > + compatible:
> > + enum:
> > + - mediatek,mt8188-sound
> > +
> > + model:
> > + $ref: /schemas/types.yaml#/definitions/string
> > + description: User specified audio sound card name
> > +
> > + audio-routing:
> > + $ref: /schemas/types.yaml#/definitions/non-unique-string-array
> > + description:
> > + A list of the connections between audio components. Each
> > entry is a
> > + sink/source pair of strings. Valid names could be the input
> > or output
> > + widgets of audio components, power supplies, MicBias of
> > codec and the
> > + software switch.
> > +
> > + mediatek,platform:
> > + $ref: "/schemas/types.yaml#/definitions/phandle"
>
> Don't need quotes.
Hi Rob,
Which one are you expected?
1. remove the line
2. $ref: /schemas/types.yaml#/definitions/phandle
>
> > + description: The phandle of MT8188 ASoC platform.
> > +
> > + mediatek,dptx-codec:
> > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > + description: The phandle of MT8188 Display Port Tx codec node.
> > +
> > + mediatek,hdmi-codec:
> > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > + description: The phandle of MT8188 HDMI codec node.
> > +
> > + mediatek,dai-link:
> > + $ref: /schemas/types.yaml#/definitions/string-array
> > + description:
> > + A list of the desired dai-links in the sound card. Each
> > entry is a
> > + name defined in the machine driver.
>
> Names have to be defined here.
>
OK, I will add enum here for listing all available dai-links.
Thanks,
Trevor
> > +
> > +additionalProperties: false
> > +
> > +required:
> > + - compatible
> > + - mediatek,platform
> > +
> > +examples:
> > + - |
> > +
> > + sound: mt8188-sound {
> > + compatible = "mediatek,mt8188-sound";
> > + mediatek,platform = <&afe>:
> > + pinctrl-names = "default";
> > + pinctrl-0 = <&aud_pins_default>;
> > + audio-routing =
> > + "Headphone", "Headphone L",
> > + "Headphone", "Headphone R",
> > + "AIN1", "Headset Mic";
> > + };
> > +
> > +...
> > --
> > 2.18.0
> >
> >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
2022-10-04 9:36 ` AngeloGioacchino Del Regno
@ 2022-10-06 2:48 ` Trevor Wu (吳文良)
2022-10-15 2:27 ` Trevor Wu (吳文良)
0 siblings, 1 reply; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-06 2:48 UTC (permalink / raw)
To: robh+dt, matthias.bgg, p.zabel, angelogioacchino.delregno,
broonie, tiwai
Cc: linux-arm-kernel, linux-kernel, linux-mediatek, alsa-devel, devicetree
On Tue, 2022-10-04 at 11:36 +0200, AngeloGioacchino Del Regno wrote:
> Il 30/09/22 16:56, Trevor Wu ha scritto:
> > Add mt8188 platform driver.
> >
> > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > ---
> > This patch depends on the following series that has not been
> > accepted.
> >
> > [1] Add power domain support for MT8188
> >
https://urldefense.com/v3/__https://patchwork.kernel.org/project/linux-mediatek/list/?series=681359__;!!CTRNKA9wMg0ARbw!3U0sxKMgA8D7xhhaJ3nSEOj4DWLrWj6_QsYGwDbCvtBvZpoKuDq5yXLDfMW1acoPog$
> >
> > (linux/soc/mediatek/infracfg.h is included)
> > ---
> > sound/soc/mediatek/Kconfig | 13 +
> > sound/soc/mediatek/Makefile | 1 +
> > sound/soc/mediatek/mt8188/Makefile | 12 +
> > sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 2945
> > ++++++++++++++++++++
> >
..snip
> > +#include <linux/arm-smccc.h>
> > +#include <linux/delay.h>
> > +#include <linux/dma-mapping.h>
> > +#include <linux/module.h>
> > +#include <linux/mfd/syscon.h>
> > +#include <linux/of.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_platform.h>
> > +#include <linux/pm_runtime.h>
> > +#include <linux/reset.h>
> > +#include <linux/soc/mediatek/infracfg.h>
> > +#include <linux/soc/mediatek/mtk_sip_svc.h>
> > +#include <sound/pcm_params.h>
> > +#include "mt8188-afe-common.h"
> > +#include "mt8188-afe-clk.h"
> > +#include "mt8188-reg.h"
> > +#include "../common/mtk-afe-platform-driver.h"
> > +#include "../common/mtk-afe-fe-dai.h"
> > +
> > +#define MTK_SIP_AUDIO_CONTROL MTK_SIP_SMC_CMD(0x517)
>
> This definition goes to include/linux/soc/mediatek/mtk_sip_svc.h
>
Hi Angelo,
If I move the definition to "include/linux/soc/mediatek/mtk_sip_svc.h",
I should submit it to another tree.
In the case, do you have any suggestion to handle the dependent
problem?
> > +
> > +#define MT8188_MEMIF_BUFFER_BYTES_ALIGN (0x40)
> > +#define MT8188_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff)
> > +
> > +#define MEMIF_AXI_MINLEN 9 //register default value
>
> ...and please fix comments style.
OK.
>
> > +
> > +struct mtk_dai_memif_priv {
> > + unsigned int asys_timing_sel;
> > + unsigned int fs_timing;
> > +};
> > +
>
> ..snip..
>
> > +
> > +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for
> > 8188");
>
> MediaTek SoC AFE platform driver for ALSA MT8188
>
OK. I will update the description in V2.
Thanks,
Trevor
> > +MODULE_AUTHOR("Chun-Chia.Chiu <chun-chia.chiu@mediatek.com>");
> > +MODULE_LICENSE("GPL");
>
>
>
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
2022-10-05 10:59 ` Mark Brown
@ 2022-10-06 3:13 ` Trevor Wu (吳文良)
0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-06 3:13 UTC (permalink / raw)
To: broonie
Cc: lkp, linux-mediatek, robh+dt, linux-kernel, devicetree, p.zabel,
tiwai, linux-arm-kernel, matthias.bgg, kbuild-all, alsa-devel
On Wed, 2022-10-05 at 11:59 +0100, Mark Brown wrote:
> On Wed, Oct 05, 2022 at 06:50:53AM +0000, Trevor Wu (吳文良) wrote:
> > Hi maintainers,
> >
> > As I mentioned in the comment, this patch depends on a reviewing
> > series.
> > Should I remove the related code from this patch in case of the
> > build
> > error?
>
> It's bit easier to do that, though it should be fine to just note in
> the
> cover like you've done.
Got it, I will remove the code if the patch is not merged before V2.
Thanks,
Trevor
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver
2022-10-06 2:48 ` Trevor Wu (吳文良)
@ 2022-10-15 2:27 ` Trevor Wu (吳文良)
0 siblings, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-15 2:27 UTC (permalink / raw)
To: robh+dt, matthias.bgg, p.zabel, angelogioacchino.delregno,
broonie, tiwai
Cc: linux-arm-kernel, linux-kernel, linux-mediatek, alsa-devel, devicetree
On Thu, 2022-10-06 at 10:48 +0800, Trevor Wu wrote:
> On Tue, 2022-10-04 at 11:36 +0200, AngeloGioacchino Del Regno wrote:
..snip
>
> > >
> > > +#include "mt8188-afe-common.h"
> > > +#include "mt8188-afe-clk.h"
> > > +#include "mt8188-reg.h"
> > > +#include "../common/mtk-afe-platform-driver.h"
> > > +#include "../common/mtk-afe-fe-dai.h"
> > > +
> > > +#define MTK_SIP_AUDIO_CONTROL MTK_SIP_SMC_CMD(0x517)
> >
> > This definition goes to include/linux/soc/mediatek/mtk_sip_svc.h
> >
>
> Hi Angelo,
>
> If I move the definition to
> "include/linux/soc/mediatek/mtk_sip_svc.h",
> I should submit it to another tree.
> In the case, do you have any suggestion to handle the dependent
> problem?
>
> > > +
> > >
Hi Angelo,
I found ohter MTK drivers[1][2] also put the definition under module
driver insted of mtk_sip_svc.h.
I still prefer to put the definition under sound/soc/mediatek in case
of dependency problem, but I will move it to
sound/soc/mediatek/common/mtk-afe-base.h in v2 becasue this is common
for MTK sound driver.
Thanks,
Trevor
[1]
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git/tree/drivers/gpu/drm/mediatek/mtk_dp.c?h=next-20221014#n37
[2]
https://elixir.bootlin.com/linux/latest/source/drivers/ufs/host/ufs-mediatek.h#L83
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document
2022-10-06 2:38 ` Trevor Wu (吳文良)
@ 2022-10-21 8:54 ` Trevor Wu (吳文良)
2022-10-21 8:58 ` Trevor Wu (吳文良)
1 sibling, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-21 8:54 UTC (permalink / raw)
To: robh
Cc: linux-mediatek, linux-kernel, devicetree, broonie, p.zabel,
tiwai, linux-arm-kernel, matthias.bgg, alsa-devel
On Thu, 2022-10-06 at 10:38 +0800, Trevor Wu wrote:
> On Mon, 2022-10-03 at 11:38 -0500, Rob Herring wrote:
> > On Fri, Sep 30, 2022 at 10:57:01PM +0800, Trevor Wu wrote:
> > > Add document for mt8188 board with mt6359.
> > >
> > > Signed-off-by: Trevor Wu <trevor.wu@mediatek.com>
> > > ---
> > > .../bindings/sound/mt8188-mt6359.yaml | 70
> > > +++++++++++++++++++
> > > 1 file changed, 70 insertions(+)
> > > create mode 100644
> > > Documentation/devicetree/bindings/sound/mt8188-
> > > mt6359.yaml
> > >
> > > diff --git a/Documentation/devicetree/bindings/sound/mt8188-
> > > mt6359.yaml b/Documentation/devicetree/bindings/sound/mt8188-
> > > mt6359.yaml
> > > new file mode 100644
> > > index 000000000000..57c7c5ceef8a
> > > --- /dev/null
> > > +++ b/Documentation/devicetree/bindings/sound/mt8188-mt6359.yaml
> > > @@ -0,0 +1,70 @@
> > > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > > +%YAML 1.2
> > > +---
> > > +$id:
> > >
https://urldefense.com/v3/__http://devicetree.org/schemas/sound/mt8188-mt6359.yaml*__;Iw!!CTRNKA9wMg0ARbw!wMc6I2aXRzI45UPQTEAzU4ZujV6VaiFGkiKBy18A_5DlQehTxU00u1QSpiOzgAgKtA$
> > >
> > > +$schema:
> > >
https://urldefense.com/v3/__http://devicetree.org/meta-schemas/core.yaml*__;Iw!!CTRNKA9wMg0ARbw!wMc6I2aXRzI45UPQTEAzU4ZujV6VaiFGkiKBy18A_5DlQehTxU00u1QSpiMSKPWbtQ$
> > >
> > > +
> > > +title: MediaTek MT8188 ASoC sound card driver
> > > +
> > > +maintainers:
> > > + - Trevor Wu <trevor.wu@mediatek.com>
> > > +
> > > +description:
> > > + This binding describes the MT8188 sound card.
> > > +
> > > +properties:
> > > + compatible:
> > > + enum:
> > > + - mediatek,mt8188-sound
> > > +
> > > + model:
> > > + $ref: /schemas/types.yaml#/definitions/string
> > > + description: User specified audio sound card name
> > > +
> > > + audio-routing:
> > > + $ref: /schemas/types.yaml#/definitions/non-unique-string-
> > > array
> > > + description:
> > > + A list of the connections between audio components. Each
> > > entry is a
> > > + sink/source pair of strings. Valid names could be the
> > > input
> > > or output
> > > + widgets of audio components, power supplies, MicBias of
> > > codec and the
> > > + software switch.
> > > +
> > > + mediatek,platform:
> > > + $ref: "/schemas/types.yaml#/definitions/phandle"
> >
> > Don't need quotes.
>
> Hi Rob,
>
> Which one are you expected?
> 1. remove the line
> 2. $ref: /schemas/types.yaml#/definitions/phandle
>
> >
> > > + description: The phandle of MT8188 ASoC platform.
> > > +
> > > + mediatek,dptx-codec:
> > > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > > + description: The phandle of MT8188 Display Port Tx codec
> > > node.
> > > +
> > > + mediatek,hdmi-codec:
> > > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > > + description: The phandle of MT8188 HDMI codec node.
> > > +
> > > + mediatek,dai-link:
> > > + $ref: /schemas/types.yaml#/definitions/string-array
> > > + description:
> > > + A list of the desired dai-links in the sound card. Each
> > > entry is a
> > > + name defined in the machine driver.
> >
> > Names have to be defined here.
> >
>
> OK, I will add enum here for listing all available dai-links.
>
> Thanks,
> Trevor
>
> > > +
> > > +additionalProperties: false
> > > +
> > > +required:
> > > + - compatible
> > > + - mediatek,platform
> > > +
> > > +examples:
> > > + - |
> > > +
> > > + sound: mt8188-sound {
> > > + compatible = "mediatek,mt8188-sound";
> > > + mediatek,platform = <&afe>:
> > > + pinctrl-names = "default";
> > > + pinctrl-0 = <&aud_pins_default>;
> > > + audio-routing =
> > > + "Headphone", "Headphone L",
> > > + "Headphone", "Headphone R",
> > > + "AIN1", "Headset Mic";
> > > + };
> > > +
> > > +...
> > > --
> > > 2.18.0
> > >
> > >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document
2022-10-06 2:38 ` Trevor Wu (吳文良)
2022-10-21 8:54 ` Trevor Wu (吳文良)
@ 2022-10-21 8:58 ` Trevor Wu (吳文良)
1 sibling, 0 replies; 29+ messages in thread
From: Trevor Wu (吳文良) @ 2022-10-21 8:58 UTC (permalink / raw)
To: robh
Cc: linux-mediatek, linux-kernel, devicetree, broonie, p.zabel,
tiwai, linux-arm-kernel, matthias.bgg, alsa-devel
> >
..snip
> > > + description: The phandle of MT8188 ASoC platform.
> > > +
> > > + mediatek,dptx-codec:
> > > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > > + description: The phandle of MT8188 Display Port Tx codec
> > > node.
> > > +
> > > + mediatek,hdmi-codec:
> > > + $ref: "/schemas/types.yaml#/definitions/phandle"
> > > + description: The phandle of MT8188 HDMI codec node.
> > > +
> > > + mediatek,dai-link:
> > > + $ref: /schemas/types.yaml#/definitions/string-array
> > > + description:
> > > + A list of the desired dai-links in the sound card. Each
> > > entry is a
> > > + name defined in the machine driver.
> >
> > Names have to be defined here.
> >
>
> OK, I will add enum here for listing all available dai-links.
>
> Thanks,
> Trevor
>
Hi Rob,
I found the implementation of "mediatek,dai-link" is not included in
the series, so I remove the item in V2.
I will add enum when I add the item in the future.
Thansk,
Trevor
> > > +
> > > +additionalProperties: false
> > > +
> > > +required:
> > > + - compatible
> > > + - mediatek,platform
> > > +
> > > +examples:
> > > + - |
> > > +
> > > + sound: mt8188-sound {
> > > + compatible = "mediatek,mt8188-sound";
> > > + mediatek,platform = <&afe>:
> > > + pinctrl-names = "default";
> > > + pinctrl-0 = <&aud_pins_default>;
> > > + audio-routing =
> > > + "Headphone", "Headphone L",
> > > + "Headphone", "Headphone R",
> > > + "AIN1", "Headset Mic";
> > > + };
> > > +
> > > +...
> > > --
> > > 2.18.0
> > >
> > >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
* Re: [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document
2022-10-05 3:57 ` Trevor Wu (吳文良)
@ 2022-10-28 23:46 ` Krzysztof Kozlowski
0 siblings, 0 replies; 29+ messages in thread
From: Krzysztof Kozlowski @ 2022-10-28 23:46 UTC (permalink / raw)
To: Trevor Wu (吳文良), robh
Cc: linux-kernel, linux-mediatek, robh+dt, devicetree, broonie,
p.zabel, tiwai, linux-arm-kernel, matthias.bgg, alsa-devel
On 04/10/2022 23:57, Trevor Wu (吳文良) wrote:
>> date:
>>
>> pip3 install dtschema --upgrade
>>
>> Please check and re-submit.
>>
>
> After upgrading dtschema, I can see the problem.
> I will correct it in V2.
Correct also cc list.
Best regards,
Krzysztof
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 29+ messages in thread
end of thread, other threads:[~2022-10-28 23:48 UTC | newest]
Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-09-30 14:56 [PATCH 00/12] ASoC: mediatek: Add support for MT8188 SoC Trevor Wu
2022-09-30 14:56 ` [PATCH 01/12] ASoC: mediatek: common: add SMC ops ID Trevor Wu
2022-09-30 14:56 ` [PATCH 03/12] ASoC: mediatek: mt8188: support audsys clock Trevor Wu
2022-09-30 14:56 ` [PATCH 04/12] ASoC: mediatek: mt8188: support adda in platform driver Trevor Wu
2022-10-04 9:37 ` AngeloGioacchino Del Regno
2022-10-05 7:14 ` Trevor Wu (吳文良)
2022-09-30 14:56 ` [PATCH 05/12] ASoC: mediatek: mt8188: support etdm " Trevor Wu
2022-09-30 14:56 ` [PATCH 06/12] ASoC: mediatek: mt8188: support pcmif " Trevor Wu
2022-09-30 14:56 ` [PATCH 07/12] ASoC: mediatek: mt8188: support audio clock control Trevor Wu
2022-09-30 14:56 ` [PATCH 08/12] ASoC: mediatek: mt8188: add platform driver Trevor Wu
2022-10-04 9:36 ` AngeloGioacchino Del Regno
2022-10-06 2:48 ` Trevor Wu (吳文良)
2022-10-15 2:27 ` Trevor Wu (吳文良)
[not found] ` <202210011740.ZdLtxKq1-lkp@intel.com>
2022-10-05 6:50 ` Trevor Wu (吳文良)
2022-10-05 10:59 ` Mark Brown
2022-10-06 3:13 ` Trevor Wu (吳文良)
2022-09-30 14:56 ` [PATCH 09/12] ASoC: mediatek: mt8188: add control for timing select Trevor Wu
2022-09-30 14:56 ` [PATCH 10/12] dt-bindings: mediatek: mt8188: add audio afe document Trevor Wu
2022-09-30 22:05 ` Rob Herring
2022-10-05 3:57 ` Trevor Wu (吳文良)
2022-10-28 23:46 ` Krzysztof Kozlowski
2022-10-03 16:30 ` Rob Herring
2022-10-05 10:12 ` Trevor Wu (吳文良)
2022-09-30 14:57 ` [PATCH 11/12] ASoC: mediatek: mt8188: add machine driver with mt6359 Trevor Wu
2022-09-30 14:57 ` [PATCH 12/12] dt-bindings: mediatek: mt8188: add mt8188-mt6359 document Trevor Wu
2022-10-03 16:38 ` Rob Herring
2022-10-06 2:38 ` Trevor Wu (吳文良)
2022-10-21 8:54 ` Trevor Wu (吳文良)
2022-10-21 8:58 ` Trevor Wu (吳文良)
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).