From 8ed024affb2d361f271f26ee3fa9d7726ac94237 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:34 +0800 Subject: [PATCH 01/24] ASoC: mediatek: mt8195: update mediatek common driver Update mediatek common driver to support MT8195 Signed-off-by: Trevor Wu Reported-by: kernel test robot --- sound/soc/mediatek/common/mtk-afe-fe-dai.c | 22 +++++++++++++++++++--- sound/soc/mediatek/common/mtk-base-afe.h | 10 ++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c index 3cb2adf420bbf7..baaa5881b1d484 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c @@ -139,7 +139,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, substream->runtime->dma_area, substream->runtime->dma_bytes); - memset_io(substream->runtime->dma_area, 0, + memset_io((void __force __iomem *)substream->runtime->dma_area, 0, substream->runtime->dma_bytes); /* set addr */ @@ -433,11 +433,20 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, phys_buf_addr_upper_32); } - /* set MSB to 33-bit */ - if (memif->data->msb_reg >= 0) + /* + * set MSB to 33-bit, for memif address + * only for memif base address, if msb_end_reg exists + */ + if (memif->data->msb_reg) mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg, 1, msb_at_bit33, memif->data->msb_shift); + /* set MSB to 33-bit, for memif end address */ + if (memif->data->msb_end_reg) + mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg, + 1, msb_at_bit33, + memif->data->msb_end_shift); + return 0; } EXPORT_SYMBOL_GPL(mtk_memif_set_addr); @@ -464,6 +473,13 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe, else mono = (channel == 1) ? 1 : 0; + /* for specific configuration of memif mono mode */ + if (memif->data->int_odd_flag_reg) + mtk_regmap_update_bits(afe->regmap, + memif->data->int_odd_flag_reg, + 1, mono, + memif->data->int_odd_flag_shift); + return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg, 1, mono, memif->data->mono_shift); } diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h index a6f68c68581ccc..ef83e78c22a84c 100644 --- a/sound/soc/mediatek/common/mtk-base-afe.h +++ b/sound/soc/mediatek/common/mtk-base-afe.h @@ -29,6 +29,8 @@ struct mtk_base_memif_data { int quad_ch_reg; int quad_ch_mask; int quad_ch_shift; + int int_odd_flag_reg; + int int_odd_flag_shift; int enable_reg; int enable_shift; int hd_reg; @@ -37,10 +39,13 @@ struct mtk_base_memif_data { int hd_align_mshift; int msb_reg; int msb_shift; - int msb2_reg; - int msb2_shift; + int msb_end_reg; + int msb_end_shift; int agent_disable_reg; int agent_disable_shift; + int ch_num_reg; + int ch_num_shift; + int ch_num_maskbit; /* playback memif only */ int pbuf_reg; int pbuf_mask; @@ -62,6 +67,7 @@ struct mtk_base_irq_data { int irq_en_shift; int irq_clr_reg; int irq_clr_shift; + int irq_status_shift; }; struct device; From ed20695a4438b529c595fee1bfe5d3039b53c58b Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:35 +0800 Subject: [PATCH 02/24] ASoC: mediatek: mt8195: support audsys clock control This patch adds mt8195 audio cg control. Audio clock gates are registered to CCF for reference count and clock parent management. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-audsys-clk.c | 214 ++++++++++++++++++ sound/soc/mediatek/mt8195/mt8195-audsys-clk.h | 15 ++ .../soc/mediatek/mt8195/mt8195-audsys-clkid.h | 93 ++++++++ 3 files changed, 322 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c new file mode 100644 index 00000000000000..740aa6ddda0ec7 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8195-audsys-clk.h -- Mediatek 8195 audsys clock control + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Trevor Wu + */ + +#include +#include +#include +#include "mt8195-afe-common.h" +#include "mt8195-audsys-clk.h" +#include "mt8195-audsys-clkid.h" +#include "mt8195-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_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", "a1sys_hp_sel", 2), + GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "a1sys_hp_sel", 4), + GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "apll4_sel", 10), + GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "apll4_sel", 11), + GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "a1sys_hp_sel", 18), + GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "apll1_sel", 19), + GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "apll2_sel", 20), + GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "aud_iec_sel", 21), + GATE_AUD0(CLK_AUD_APLL, "aud_apll", "apll1_sel", 23), + GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "apll2_sel", 24), + GATE_AUD0(CLK_AUD_DAC, "aud_dac", "a1sys_hp_sel", 25), + GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "a1sys_hp_sel", 26), + GATE_AUD0(CLK_AUD_TML, "aud_tml", "a1sys_hp_sel", 27), + GATE_AUD0(CLK_AUD_ADC, "aud_adc", "a1sys_hp_sel", 28), + GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 31), + + /* AUD1 */ + GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "a1sys_hp_sel", 2), + GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "a1sys_hp_sel", 10), + GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "a1sys_hp_sel", 11), + GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "a1sys_hp_sel", 12), + GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "a1sys_hp_sel", 13), + GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "a1sys_hp_sel", 14), + GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "audio_h_sel", 16), + GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 17), + GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "a1sys_hp_sel", 18), + GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 19), + + /* AUD3 */ + GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "apll5_sel", 5), + GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "apll3_sel", 7), + + /* AUD4 */ + GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "a1sys_hp_sel", 0), + GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "a1sys_hp_sel", 1), + GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "a1sys_hp_sel", 6), + GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "a1sys_hp_sel", 7), + GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "a1sys_hp_sel", 8), + GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "a1sys_hp_sel", 16), + GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "a1sys_hp_sel", 17), + GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19), + GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "intdir_sel", 20), + GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "a1sys_hp_sel", 21), + GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "a2sys_sel", 22), + GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "a1sys_hp_sel", 24), + GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "a3sys_sel", 30), + GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "a4sys_sel", 31), + + /* AUD5 */ + GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "a1sys_hp_sel", 0), + GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "a1sys_hp_sel", 1), + GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "a1sys_hp_sel", 2), + GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "a1sys_hp_sel", 3), + GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "a1sys_hp_sel", 4), + GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "a1sys_hp_sel", 5), + GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "a1sys_hp_sel", 7), + GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "a1sys_hp_sel", 8), + GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "a1sys_hp_sel", 9), + GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "a1sys_hp_sel", 18), + GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "a1sys_hp_sel", 19), + GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "a1sys_hp_sel", 22), + GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "a1sys_hp_sel", 23), + GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "a1sys_hp_sel", 24), + GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "a1sys_hp_sel", 26), + GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "a1sys_hp_sel", 27), + + /* AUD6 */ + GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "asm_h_sel", 0), + GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "asm_h_sel", 1), + GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "asm_h_sel", 2), + GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "asm_h_sel", 3), + GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "asm_h_sel", 4), + GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "asm_h_sel", 5), + GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "asm_h_sel", 6), + GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "asm_h_sel", 7), + GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "asm_h_sel", 8), + GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "asm_h_sel", 9), + GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "asm_h_sel", 10), + GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "asm_h_sel", 11), + GATE_AUD6(CLK_AUD_GASRC12, "aud_gasrc12", "asm_h_sel", 12), + GATE_AUD6(CLK_AUD_GASRC13, "aud_gasrc13", "asm_h_sel", 13), + GATE_AUD6(CLK_AUD_GASRC14, "aud_gasrc14", "asm_h_sel", 14), + GATE_AUD6(CLK_AUD_GASRC15, "aud_gasrc15", "asm_h_sel", 15), + GATE_AUD6(CLK_AUD_GASRC16, "aud_gasrc16", "asm_h_sel", 16), + GATE_AUD6(CLK_AUD_GASRC17, "aud_gasrc17", "asm_h_sel", 17), + GATE_AUD6(CLK_AUD_GASRC18, "aud_gasrc18", "asm_h_sel", 18), + GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "asm_h_sel", 19), +}; + +int mt8195_audsys_clk_register(struct mtk_base_afe *afe) +{ + struct mt8195_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); + clkdev_add(cl); + + afe_priv->lookup[i] = cl; + } + + return 0; +} + +void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe) +{ + struct mt8195_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/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h new file mode 100644 index 00000000000000..239d31016ba76c --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-audsys-clk.h -- Mediatek 8195 audsys clock definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Trevor Wu + */ + +#ifndef _MT8195_AUDSYS_CLK_H_ +#define _MT8195_AUDSYS_CLK_H_ + +int mt8195_audsys_clk_register(struct mtk_base_afe *afe); +void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h new file mode 100644 index 00000000000000..4dd0a5c8b8fa5f --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-audsys-clkid.h -- Mediatek 8195 audsys clock id definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Trevor Wu + */ + +#ifndef _MT8195_AUDSYS_CLKID_H_ +#define _MT8195_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_ADDA6_ADC, + CLK_AUD_ADDA6_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_GASRC12, + CLK_AUD_GASRC13, + CLK_AUD_GASRC14, + CLK_AUD_GASRC15, + CLK_AUD_GASRC16, + CLK_AUD_GASRC17, + CLK_AUD_GASRC18, + CLK_AUD_GASRC19, + CLK_AUD_NR_CLK, +}; + +#endif From 36479c7a92d63102cc466ceed1d80cb59f967450 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:36 +0800 Subject: [PATCH 03/24] ASoC: mediatek: mt8195: support etdm in platform driver This patch adds mt8195 tdm/i2s dai driver. MCLK clock tree is as follows. PLL -> MUX -> DIVIDER -> MCLK For PLL source of MCLK, driver only supports APLL1 and APLL2 now. APLL3 and APLL4 are used to track external clock source, so they are only used when slave input is connected. For example, case 1: (HDMI RX connected) DL memif (a1sys) -> etdm out2 (clk from apll1/apll2) -> codec case 2: (HDMI RX disconnected) HDMI RX -> a3sys -> UL memif (a3sys) -> DL memif (a3sys) -> .... -> etdm out2 (clk from apll3) -> codec We keep all modules in the pipeline working on the same clock domain. MCLK is expected to output the clock generated from the same clock source as the pipeline, so dynamic reparenting is required for MCLK configuration. As a result, clk_set_parent() is used to select PLL source, and clk_set_rate() is used to configure divider to get MCLK output rate. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-dai-etdm.c | 2639 +++++++++++++++++++ 1 file changed, 2639 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-etdm.c diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c new file mode 100644 index 00000000000000..bd9876cf02c893 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-dai-etdm.c @@ -0,0 +1,2639 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI eTDM Control + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include +#include +#include +#include +#include "mt8195-afe-clk.h" +#include "mt8195-afe-common.h" +#include "mt8195-reg.h" + +#define MT8195_ETDM_MAX_CHANNELS 24 +#define MT8195_ETDM_NORMAL_MAX_BCK_RATE 24576000 +#define ETDM_TO_DAI_ID(x) ((x) + MT8195_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 { + ETDM_IN_FROM_PAD, + ETDM_IN_FROM_ETDM_OUT1, + ETDM_IN_FROM_ETDM_OUT2, +}; + +enum { + ETDM_IN_SLAVE_FROM_PAD, + ETDM_IN_SLAVE_FROM_ETDM_OUT1, + ETDM_IN_SLAVE_FROM_ETDM_OUT2, +}; + +enum { + ETDM_OUT_SLAVE_FROM_PAD, + ETDM_OUT_SLAVE_FROM_ETDM_IN1, + ETDM_OUT_SLAVE_FROM_ETDM_IN2, +}; + +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, + ETDM_SYNC_FROM_IN2, + ETDM_SYNC_FROM_OUT1, + ETDM_SYNC_FROM_OUT2, + ETDM_SYNC_FROM_OUT3, +}; + +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_apll; + unsigned int mclk_dir; + int cowork_source_id; //dai id + unsigned int cowork_slv_count; + int cowork_slv_id[MT8195_AFE_IO_ETDM_NUM - 1]; //dai_id + bool in_disable_ch[MT8195_ETDM_MAX_CHANNELS]; + unsigned int en_ref_cnt; +}; + +static const struct mtk_dai_etdm_rate mt8195_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(mt8195_etdm_rates); i++) + if (mt8195_etdm_rates[i].rate == rate) + return mt8195_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 MT8195_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 MT8195_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 MT8195_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 MT8195_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 MT8195_AFE_IO_ETDM3_OUT: + case MT8195_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 MT8195_AFE_IO_ETDM1_IN: + case MT8195_AFE_IO_ETDM2_IN: + return ETDM_IN; + case MT8195_AFE_IO_ETDM1_OUT: + case MT8195_AFE_IO_ETDM2_OUT: + case MT8195_AFE_IO_ETDM3_OUT: + return ETDM_OUT; + default: + return -EINVAL; + } +} + +static int get_etdm_wlen(unsigned int bitwidth) +{ + return bitwidth <= 16 ? 16 : 32; +} + +static int is_cowork_mode(struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *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 MT8195_AFE_IO_ETDM1_IN; + case ETDM_SYNC_FROM_IN2: + return MT8195_AFE_IO_ETDM2_IN; + case ETDM_SYNC_FROM_OUT1: + return MT8195_AFE_IO_ETDM1_OUT; + case ETDM_SYNC_FROM_OUT2: + return MT8195_AFE_IO_ETDM2_OUT; + case ETDM_SYNC_FROM_OUT3: + return MT8195_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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id]; + int 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_o064_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I038 Switch", AFE_CONN64_1, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I062 Switch", AFE_CONN64_1, 30, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o065_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I039 Switch", AFE_CONN65_1, 7, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I063 Switch", AFE_CONN65_1, 31, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o066_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I040 Switch", AFE_CONN66_1, 8, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I064 Switch", AFE_CONN66_2, 0, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o067_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I041 Switch", AFE_CONN67_1, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I065 Switch", AFE_CONN67_2, 1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o068_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I042 Switch", AFE_CONN68_1, 10, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I066 Switch", AFE_CONN68_2, 2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o069_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I043 Switch", AFE_CONN69_1, 11, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I067 Switch", AFE_CONN69_2, 3, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o070_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I044 Switch", AFE_CONN70_1, 12, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I068 Switch", AFE_CONN70_2, 4, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o071_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I045 Switch", AFE_CONN71_1, 13, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I069 Switch", AFE_CONN71_2, 5, 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 struct snd_kcontrol_new mtk_dai_etdm_o088_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I038 Switch", AFE_CONN88_1, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I062 Switch", AFE_CONN88_1, 30, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o089_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I039 Switch", AFE_CONN89_1, 7, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I063 Switch", AFE_CONN89_1, 31, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o090_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I040 Switch", AFE_CONN90_1, 8, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I064 Switch", AFE_CONN90_2, 0, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o091_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I041 Switch", AFE_CONN91_1, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I065 Switch", AFE_CONN91_2, 1, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o092_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I042 Switch", AFE_CONN92_1, 10, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I066 Switch", AFE_CONN92_2, 2, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o093_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I043 Switch", AFE_CONN93_1, 11, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I067 Switch", AFE_CONN93_2, 3, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o094_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I044 Switch", AFE_CONN94_1, 12, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I068 Switch", AFE_CONN94_2, 4, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_etdm_o095_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I045 Switch", AFE_CONN95_1, 13, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I069 Switch", AFE_CONN95_2, 5, 1, 0), +}; + +static const char * const mt8195_etdm_clk_src_sel_text[] = { + "26m", + "a1sys_a2sys", + "a3sys", + "a4sys", +}; + +static SOC_ENUM_SINGLE_EXT_DECL(etdmout_clk_src_enum, + mt8195_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 mt8195_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 mask; + unsigned int reg; + + 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; + 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; + 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; + 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; + 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; + val = ETDM_IN_CON2_CLOCK(source); + } + + if (reg) + regmap_update_bits(afe->regmap, reg, mask, val); + + return 0; +} + +static int mt8195_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, + mt8195_etdm_clk_src_sel_get, + mt8195_etdm_clk_src_sel_put), + SOC_ENUM_EXT("ETDM_OUT2_Clock_Source", + etdmout_clk_src_enum, + mt8195_etdm_clk_src_sel_get, + mt8195_etdm_clk_src_sel_put), + SOC_ENUM_EXT("ETDM_OUT3_Clock_Source", + etdmout_clk_src_enum, + mt8195_etdm_clk_src_sel_get, + mt8195_etdm_clk_src_sel_put), + SOC_ENUM_EXT("ETDM_IN1_Clock_Source", + etdmout_clk_src_enum, + mt8195_etdm_clk_src_sel_get, + mt8195_etdm_clk_src_sel_put), + SOC_ENUM_EXT("ETDM_IN2_Clock_Source", + etdmout_clk_src_enum, + mt8195_etdm_clk_src_sel_get, + mt8195_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), + + /* 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), + SND_SOC_DAPM_MIXER("I088", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I089", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I090", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I091", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I092", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I093", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I094", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I095", 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)), + SND_SOC_DAPM_MIXER("O064", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o064_mix, + ARRAY_SIZE(mtk_dai_etdm_o064_mix)), + SND_SOC_DAPM_MIXER("O065", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o065_mix, + ARRAY_SIZE(mtk_dai_etdm_o065_mix)), + SND_SOC_DAPM_MIXER("O066", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o066_mix, + ARRAY_SIZE(mtk_dai_etdm_o066_mix)), + SND_SOC_DAPM_MIXER("O067", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o067_mix, + ARRAY_SIZE(mtk_dai_etdm_o067_mix)), + SND_SOC_DAPM_MIXER("O068", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o068_mix, + ARRAY_SIZE(mtk_dai_etdm_o068_mix)), + SND_SOC_DAPM_MIXER("O069", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o069_mix, + ARRAY_SIZE(mtk_dai_etdm_o069_mix)), + SND_SOC_DAPM_MIXER("O070", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o070_mix, + ARRAY_SIZE(mtk_dai_etdm_o070_mix)), + SND_SOC_DAPM_MIXER("O071", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o071_mix, + ARRAY_SIZE(mtk_dai_etdm_o071_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)), + SND_SOC_DAPM_MIXER("O088", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o088_mix, + ARRAY_SIZE(mtk_dai_etdm_o088_mix)), + SND_SOC_DAPM_MIXER("O089", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o089_mix, + ARRAY_SIZE(mtk_dai_etdm_o089_mix)), + SND_SOC_DAPM_MIXER("O090", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o090_mix, + ARRAY_SIZE(mtk_dai_etdm_o090_mix)), + SND_SOC_DAPM_MIXER("O091", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o091_mix, + ARRAY_SIZE(mtk_dai_etdm_o091_mix)), + SND_SOC_DAPM_MIXER("O092", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o092_mix, + ARRAY_SIZE(mtk_dai_etdm_o092_mix)), + SND_SOC_DAPM_MIXER("O093", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o093_mix, + ARRAY_SIZE(mtk_dai_etdm_o093_mix)), + SND_SOC_DAPM_MIXER("O094", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o094_mix, + ARRAY_SIZE(mtk_dai_etdm_o094_mix)), + SND_SOC_DAPM_MIXER("O095", SND_SOC_NOPM, 0, 0, + mtk_dai_etdm_o095_mix, + ARRAY_SIZE(mtk_dai_etdm_o095_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"}, + + {"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"}, + {"I088", NULL, "ETDM1 Capture"}, + {"I089", NULL, "ETDM1 Capture"}, + {"I090", NULL, "ETDM1 Capture"}, + {"I091", NULL, "ETDM1 Capture"}, + {"I092", NULL, "ETDM1 Capture"}, + {"I093", NULL, "ETDM1 Capture"}, + {"I094", NULL, "ETDM1 Capture"}, + {"I095", 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"}, + {"ETDM2 Playback", NULL, "O064"}, + {"ETDM2 Playback", NULL, "O065"}, + {"ETDM2 Playback", NULL, "O066"}, + {"ETDM2 Playback", NULL, "O067"}, + {"ETDM2 Playback", NULL, "O068"}, + {"ETDM2 Playback", NULL, "O069"}, + {"ETDM2 Playback", NULL, "O070"}, + {"ETDM2 Playback", NULL, "O071"}, + + {"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"}, + {"ETDM1 Playback", NULL, "O088"}, + {"ETDM1 Playback", NULL, "O089"}, + {"ETDM1 Playback", NULL, "O090"}, + {"ETDM1 Playback", NULL, "O091"}, + {"ETDM1 Playback", NULL, "O092"}, + {"ETDM1 Playback", NULL, "O093"}, + {"ETDM1 Playback", NULL, "O094"}, + {"ETDM1 Playback", NULL, "O095"}, + + {"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"}, + {"O064", "I038 Switch", "I038"}, + {"O065", "I039 Switch", "I039"}, + {"O066", "I040 Switch", "I040"}, + {"O067", "I041 Switch", "I041"}, + {"O068", "I042 Switch", "I042"}, + {"O069", "I043 Switch", "I043"}, + {"O070", "I044 Switch", "I044"}, + {"O071", "I045 Switch", "I045"}, + + {"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"}, + {"O064", "I062 Switch", "I062"}, + {"O065", "I063 Switch", "I063"}, + {"O066", "I064 Switch", "I064"}, + {"O067", "I065 Switch", "I065"}, + {"O068", "I066 Switch", "I066"}, + {"O069", "I067 Switch", "I067"}, + {"O070", "I068 Switch", "I068"}, + {"O071", "I069 Switch", "I069"}, + + {"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"}, + {"O088", "I038 Switch", "I038"}, + {"O089", "I039 Switch", "I039"}, + {"O090", "I040 Switch", "I040"}, + {"O091", "I041 Switch", "I041"}, + {"O092", "I042 Switch", "I042"}, + {"O093", "I043 Switch", "I043"}, + {"O094", "I044 Switch", "I044"}, + {"O095", "I045 Switch", "I045"}, + + {"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"}, + {"O088", "I062 Switch", "I062"}, + {"O089", "I063 Switch", "I063"}, + {"O090", "I064 Switch", "I064"}, + {"O091", "I065 Switch", "I065"}, + {"O092", "I066 Switch", "I066"}, + {"O093", "I067 Switch", "I067"}, + {"O094", "I068 Switch", "I068"}, + {"O095", "I069 Switch", "I069"}, + + {"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 mt8195_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id) +{ + int ret = 0; + struct etdm_con_reg etdm_reg; + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id]; + unsigned long flags; + + 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 mt8195_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id) +{ + int ret = 0; + struct etdm_con_reg etdm_reg; + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id]; + unsigned long flags; + + 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 0; +} + +static int etdm_cowork_slv_sel(int id, int slave_mode) +{ + if (slave_mode) { + switch (id) { + case MT8195_AFE_IO_ETDM1_IN: + return COWORK_ETDM_IN1_S; + case MT8195_AFE_IO_ETDM2_IN: + return COWORK_ETDM_IN2_S; + case MT8195_AFE_IO_ETDM1_OUT: + return COWORK_ETDM_OUT1_S; + case MT8195_AFE_IO_ETDM2_OUT: + return COWORK_ETDM_OUT2_S; + case MT8195_AFE_IO_ETDM3_OUT: + return COWORK_ETDM_OUT3_S; + default: + return -EINVAL; + } + } else { + switch (id) { + case MT8195_AFE_IO_ETDM1_IN: + return COWORK_ETDM_IN1_M; + case MT8195_AFE_IO_ETDM2_IN: + return COWORK_ETDM_IN2_M; + case MT8195_AFE_IO_ETDM1_OUT: + return COWORK_ETDM_OUT1_M; + case MT8195_AFE_IO_ETDM2_OUT: + return COWORK_ETDM_OUT2_M; + case MT8195_AFE_IO_ETDM3_OUT: + return COWORK_ETDM_OUT3_M; + default: + return -EINVAL; + } + } +} + +static int mt8195_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id]; + unsigned int reg = 0; + unsigned int mask; + unsigned int val; + int cowork_source_sel; + + if (etdm_data->cowork_source_id == COWORK_ETDM_NONE) + return 0; + + cowork_source_sel = etdm_cowork_slv_sel(etdm_data->cowork_source_id, + etdm_data->slave_mode); + if (cowork_source_sel < 0) + return cowork_source_sel; + + switch (dai_id) { + case MT8195_AFE_IO_ETDM1_IN: + reg = ETDM_COWORK_CON1; + mask = ETDM_IN1_SLAVE_SEL_MASK; + val = ETDM_IN1_SLAVE_SEL(cowork_source_sel); + break; + case MT8195_AFE_IO_ETDM2_IN: + reg = ETDM_COWORK_CON2; + mask = ETDM_IN2_SLAVE_SEL_MASK; + val = ETDM_IN2_SLAVE_SEL(cowork_source_sel); + break; + case MT8195_AFE_IO_ETDM1_OUT: + reg = ETDM_COWORK_CON0; + mask = ETDM_OUT1_SLAVE_SEL_MASK; + val = ETDM_OUT1_SLAVE_SEL(cowork_source_sel); + break; + case MT8195_AFE_IO_ETDM2_OUT: + reg = ETDM_COWORK_CON2; + mask = ETDM_OUT2_SLAVE_SEL_MASK; + val = ETDM_OUT2_SLAVE_SEL(cowork_source_sel); + break; + case MT8195_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 mtk_dai_etdm_get_cg_id_by_dai_id(int dai_id) +{ + int cg_id = -1; + + switch (dai_id) { + case MT8195_AFE_IO_DPTX: + cg_id = MT8195_CLK_AUD_HDMI_OUT; + break; + case MT8195_AFE_IO_ETDM1_IN: + cg_id = MT8195_CLK_AUD_TDM_IN; + break; + case MT8195_AFE_IO_ETDM2_IN: + cg_id = MT8195_CLK_AUD_I2SIN; + break; + case MT8195_AFE_IO_ETDM1_OUT: + cg_id = MT8195_CLK_AUD_TDM_OUT; + break; + case MT8195_AFE_IO_ETDM2_OUT: + cg_id = MT8195_CLK_AUD_I2S_OUT; + break; + case MT8195_AFE_IO_ETDM3_OUT: + cg_id = MT8195_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 MT8195_AFE_IO_DPTX: + clk_id = MT8195_CLK_TOP_DPTX_M_SEL; + break; + case MT8195_AFE_IO_ETDM1_IN: + clk_id = MT8195_CLK_TOP_I2SI1_M_SEL; + break; + case MT8195_AFE_IO_ETDM2_IN: + clk_id = MT8195_CLK_TOP_I2SI2_M_SEL; + break; + case MT8195_AFE_IO_ETDM1_OUT: + clk_id = MT8195_CLK_TOP_I2SO1_M_SEL; + break; + case MT8195_AFE_IO_ETDM2_OUT: + clk_id = MT8195_CLK_TOP_I2SO2_M_SEL; + break; + case MT8195_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 MT8195_AFE_IO_DPTX: + clk_id = MT8195_CLK_TOP_APLL12_DIV9; + break; + case MT8195_AFE_IO_ETDM1_IN: + clk_id = MT8195_CLK_TOP_APLL12_DIV0; + break; + case MT8195_AFE_IO_ETDM2_IN: + clk_id = MT8195_CLK_TOP_APLL12_DIV1; + break; + case MT8195_AFE_IO_ETDM1_OUT: + clk_id = MT8195_CLK_TOP_APLL12_DIV2; + break; + case MT8195_AFE_IO_ETDM2_OUT: + clk_id = MT8195_CLK_TOP_APLL12_DIV3; + break; + case MT8195_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 mt8195_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; + + mt8195_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 mt8195_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; + + mt8195_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 mt8195_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); + 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) + mt8195_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) + mt8195_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) + mt8195_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 mt8195_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); + cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id); + if (cg_id >= 0) + mt8195_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) + mt8195_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) + mt8195_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 = mt8195_afe_fs_timing(rate); + + switch (dai_id) { + case MT8195_AFE_IO_ETDM1_IN: + reg = ETDM_IN1_AFIFO_CON; + if (rate == 0) + mode = MT8195_ETDM_IN1_1X_EN; + break; + case MT8195_AFE_IO_ETDM2_IN: + reg = ETDM_IN2_AFIFO_CON; + if (rate == 0) + mode = MT8195_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 mt8195_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]) { + if (i == (channels - 2)) + val |= ETDM_IN_CON5_LR_SWAP(15); + else + 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 mt8195_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) { + /* con2 */ + mask = (ETDM_OUT_CON2_LRCK_DELAY_BCK_INV | + ETDM_OUT_CON2_LRCK_DELAY_0P5T_EN); + val = (ETDM_OUT_CON2_LRCK_DELAY_BCK_INV | + ETDM_OUT_CON2_LRCK_DELAY_0P5T_EN); + regmap_update_bits(afe->regmap, etdm_reg.con2, + mask, val); + mask = 0; + val = 0; + } else { + /* 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 == MT8195_AFE_IO_ETDM1_OUT) + fs = MT8195_ETDM_OUT1_1X_EN; + else if (dai_id == MT8195_AFE_IO_ETDM2_OUT) + fs = MT8195_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 mt8195_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 = mt8195_afe_get_mclk_source_clk_id(apll); + if (apll_clk_id < 0) + return apll_clk_id; + + /* select apll */ + ret = mt8195_afe_set_clk_parent(afe, afe_priv->clk[clk_id], + afe_priv->clk[apll_clk_id]); + if (ret) + return ret; + + /* set rate */ + ret = mt8195_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 mt8195_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; + + if (etdm_data->cowork_source_id != COWORK_ETDM_NONE) + slave_mode = true; + + 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 bitwiedh %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 > MT8195_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 == MT8195_AFE_IO_ETDM1_OUT && + etdm_data->cowork_source_id == COWORK_ETDM_NONE) { + 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 mt8195_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 = mt8195_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_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int ret = 0; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_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(), cmd %d, dai id %d\n", __func__, cmd, dai->id); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + if (is_cowork_mode(dai)) { + mst_dai_id = get_etdm_cowork_master_id(dai); + mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; + + //open master first + ret |= mt8195_afe_enable_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 |= mt8195_afe_enable_etdm(afe, slv_dai_id); + } + } else { + ret = mt8195_afe_enable_etdm(afe, dai->id); + } + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + 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 |= mt8195_afe_disable_etdm(afe, slv_dai_id); + } + // close master at last + ret |= mt8195_afe_disable_etdm(afe, mst_dai_id); + } else { + ret = mt8195_afe_disable_etdm(afe, dai->id); + } + break; + default: + break; + } + return ret; +} + +static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai_id]; + int apll; + int apll_rate; + + if (freq == 0) { + etdm_data->mclk_freq = freq; + return 0; + } + + apll = mt8195_afe_get_default_mclk_source_by_rate(freq); + apll_rate = mt8195_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; + } + + 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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id]; + 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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *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_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + etdm_data->slave_mode = true; + break; + case SND_SOC_DAIFMT_CBS_CFS: + 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 mt8195_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) + mt8195_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 mt8195_afe_private *afe_priv = afe->platform_priv; + int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); + + mtk_dai_etdm_disable_mclk(afe, dai->id); + + if (cg_id >= 0) + mt8195_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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data = afe_priv->dai_priv[dai->id]; + 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; + + /* dptx configure */ + if (dai->id == MT8195_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_trigger(struct snd_pcm_substream *substream, + int cmd, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + /* enable dptx interface */ + if (dai->id == MT8195_AFE_IO_DPTX) + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + AFE_DPTX_CON_ON_MASK, + AFE_DPTX_CON_ON); + + /* enable etdm_out3 */ + ret = mt8195_afe_enable_etdm(afe, dai->id); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + /* disable etdm_out3 */ + ret = mt8195_afe_disable_etdm(afe, dai->id); + + /* disable dptx interface */ + if (dai->id == MT8195_AFE_IO_DPTX) + regmap_update_bits(afe->regmap, AFE_DPTX_CON, + AFE_DPTX_CON_ON_MASK, 0); + break; + default: + return -EINVAL; + } + + 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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *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, + .trigger = mtk_dai_etdm_trigger, + .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, + .trigger = mtk_dai_hdmitx_dptx_trigger, + .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_384000) + +#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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *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 = MT8195_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 = MT8195_AFE_IO_ETDM1_IN, + .capture = { + .stream_name = "ETDM1 Capture", + .channels_min = 1, + .channels_max = 24, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_etdm_ops, + .probe = mtk_dai_etdm_probe, + }, + { + .name = "ETDM2_IN", + .id = MT8195_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 = MT8195_AFE_IO_ETDM1_OUT, + .playback = { + .stream_name = "ETDM1 Playback", + .channels_min = 1, + .channels_max = 24, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_etdm_ops, + .probe = mtk_dai_etdm_probe, + }, + { + .name = "ETDM2_OUT", + .id = MT8195_AFE_IO_ETDM2_OUT, + .playback = { + .stream_name = "ETDM2 Playback", + .channels_min = 1, + .channels_max = 24, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_etdm_ops, + .probe = mtk_dai_etdm_probe, + }, + { + .name = "ETDM3_OUT", + .id = MT8195_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 mt8195_etdm_update_sync_info(struct mtk_base_afe *afe) +{ + struct mt8195_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 = MT8195_AFE_IO_ETDM_START; i < MT8195_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 mt8195_dai_etdm_parse_of(struct mtk_base_afe *afe) +{ + const struct device_node *of_node = afe->dev->of_node; + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data; + int i, j; + char prop[48]; + u8 disable_chn[MT8195_ETDM_MAX_CHANNELS]; + int max_chn = MT8195_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[MT8195_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 < MT8195_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 >= MT8195_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] >= MT8195_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; + } + } + mt8195_etdm_update_sync_info(afe); +} + +static int init_etdm_priv_data(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_priv; + int i; + + for (i = MT8195_AFE_IO_ETDM_START; i < MT8195_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[MT8195_AFE_IO_DPTX] = + afe_priv->dai_priv[MT8195_AFE_IO_ETDM3_OUT]; + + mt8195_dai_etdm_parse_of(afe); + return 0; +} + +int mt8195_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); +} From 830a096e2ce689bb2a4ece8e374297d7e50fec56 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:37 +0800 Subject: [PATCH 04/24] ASoC: mediatek: mt8195: support adda in platform driver This patch adds mt8195 adda dai driver. audio_h clock is used by ADSP bus and ADDA module. When ADDA requires audio_h clock, it is switched to APLL1, otherwise it is switched to Xtal_26m so that APLL1 can be turned off when audio feature is not used. ADSP bus only requires that the clock is on, so dynamic reparenting is used for the purpose of lowering power consumption. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-dai-adda.c | 830 ++++++++++++++++++++ 1 file changed, 830 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-adda.c b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c new file mode 100644 index 00000000000000..878dec0b69ed38 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI ADDA Control + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include +#include +#include "mt8195-afe-clk.h" +#include "mt8195-afe-common.h" +#include "mt8195-reg.h" + +#define ADDA_DL_GAIN_LOOPBACK 0x1800 +#define ADDA_HIRES_THRES 48000 + +enum { + SUPPLY_SEQ_CLOCK_SEL, + SUPPLY_SEQ_CLOCK_ON, + 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, + DELAY_DATA_MISO2 = 1, +}; + +enum { + MTK_AFE_ADDA, + MTK_AFE_ADDA6, +}; + +struct mtk_dai_adda_priv { + bool hires_required; +}; + +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 mt8195_adda_mtkaif_init(struct mtk_base_afe *afe) +{ + struct mt8195_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); + regmap_update_bits(afe->regmap, AFE_ADDA6_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[MT8195_MTKAIF_MISO_0] >= + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]; + } else { + delay_data = DELAY_DATA_MISO0; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] - + param->mtkaif_phase_cycle[MT8195_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); + + /* set delay between ch3 and ch2 */ + if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >= + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2]; + } + + 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_ADDA6_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: + mt8195_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, int adda, bool dmic) +{ + unsigned int reg = 0; + unsigned int mask = 0; + unsigned int val = 0; + + switch (adda) { + case MTK_AFE_ADDA: + reg = AFE_ADDA_UL_SRC_CON0; + break; + case MTK_AFE_ADDA6: + reg = AFE_ADDA6_UL_SRC_CON0; + break; + default: + dev_info(afe->dev, "%s(), wrong parameter\n", __func__); + return; + } + + 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 mt8195_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, MTK_AFE_ADDA, 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_adda6_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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + unsigned int val; + + 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, MTK_AFE_ADDA6, param->mtkaif_dmic_on); + + val = (param->mtkaif_adda6_only ? + ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0); + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_SYNCWORD_CFG, + ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE, + val); + 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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct clk *clk = afe_priv->clk[MT8195_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[MT8195_CLK_TOP_APLL1]; + break; + case SND_SOC_DAPM_POST_PMD: + clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M]; + break; + default: + return 0; + } + mt8195_afe_set_clk_parent(afe, clk, clk_parent); + + return 0; +} + +static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int dai_id; + + if (strstr(name, "aud_adc_hires")) + dai_id = MT8195_AFE_IO_UL_SRC1; + else if (strstr(name, "aud_adda6_adc_hires")) + dai_id = MT8195_AFE_IO_UL_SRC2; + else if (strstr(name, "aud_dac_hires")) + dai_id = MT8195_AFE_IO_DL_SRC; + else + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +static int mtk_afe_adda_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 mtk_dai_adda_priv *adda_priv; + + adda_priv = get_adda_priv_by_name(afe, w->name); + + if (!adda_priv) { + dev_info(afe->dev, "adda_priv == NULL"); + return 0; + } + + return (adda_priv->hires_required) ? 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("I170", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I171", 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("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA6_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SHIFT, 0, + mtk_adda6_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_adda6_adc"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_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_adda_hires_connect}, + {"aud_adc_hires", NULL, "AUDIO_HIRES"}, + + {"ADDA6 Capture", NULL, "ADDA Enable"}, + {"ADDA6 Capture", NULL, "ADDA6 Capture Enable"}, + {"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"}, + {"ADDA6 Capture", NULL, "aud_adda6_adc"}, + {"ADDA6 Capture", NULL, "aud_adda6_adc_hires", + mtk_afe_adda_hires_connect}, + {"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"}, + + {"I168", NULL, "ADDA Capture"}, + {"I169", NULL, "ADDA Capture"}, + {"I170", NULL, "ADDA6 Capture"}, + {"I171", NULL, "ADDA6 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_adda_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"}, + {"ADDA6 Capture", NULL, "ADDA_INPUT"}, + {"ADDA_OUTPUT", NULL, "ADDA Playback"}, +}; + +static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + unsigned int reg = AFE_ADDA_DL_SRC2_CON1; + unsigned int mask = DL_2_GAIN_CTL_PRE_MASK; + unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]); + + regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value)); + return 0; +} + +static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + unsigned int reg = AFE_ADDA_DL_SRC2_CON1; + unsigned int mask = DL_2_GAIN_CTL_PRE_MASK; + unsigned int value = 0; + + regmap_read(afe->regmap, reg, &value); + + ucontrol->value.integer.value[0] = ((value & mask) >> + DL_2_GAIN_CTL_PRE_SHIFT); + return 0; +} + +static int mt8195_adda6_only_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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + + ucontrol->value.integer.value[0] = param->mtkaif_adda6_only; + return 0; +} + +static int mt8195_adda6_only_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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + int mtkaif_adda6_only; + + mtkaif_adda6_only = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n", + __func__, kcontrol->id.name, mtkaif_adda6_only); + + param->mtkaif_adda6_only = mtkaif_adda6_only; + + return 0; +} + +static int mt8195_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 mt8195_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 mt8195_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 mt8195_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); + + param->mtkaif_dmic_on = dmic_on; + return 0; +} + +static const struct snd_kcontrol_new mtk_dai_adda_controls[] = { + SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0, + mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put), + SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0, + mt8195_adda_dmic_get, mt8195_adda_dmic_set), + SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0, + mt8195_adda6_only_get, + mt8195_adda6_only_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)); + + switch (id) { + case MT8195_AFE_IO_UL_SRC1: + regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, + mask, val); + break; + case MT8195_AFE_IO_UL_SRC2: + regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0, + mask, val); + break; + default: + break; + } + 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 mt8195_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 (rate > ADDA_HIRES_THRES) + adda_priv->hires_required = 1; + else + adda_priv->hires_required = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = mtk_dai_da_configure(afe, rate, id); + else + 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 = "DL_SRC", + .id = MT8195_AFE_IO_DL_SRC, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "UL_SRC1", + .id = MT8195_AFE_IO_UL_SRC1, + .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, + }, + { + .name = "UL_SRC2", + .id = MT8195_AFE_IO_UL_SRC2, + .capture = { + .stream_name = "ADDA6 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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_adda_priv *adda_priv; + int adda_dai_list[] = { MT8195_AFE_IO_DL_SRC, + MT8195_AFE_IO_UL_SRC1, + MT8195_AFE_IO_UL_SRC2}; + int i; + + for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) { + adda_priv = devm_kzalloc(afe->dev, + sizeof(struct mtk_dai_adda_priv), + GFP_KERNEL); + if (!adda_priv) + return -ENOMEM; + + afe_priv->dai_priv[adda_dai_list[i]] = adda_priv; + } + + return 0; +} + +int mt8195_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); +} From cdd32ef01d49377203e9ba3e5227a5590f76c926 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:38 +0800 Subject: [PATCH 05/24] ASoC: mediatek: mt8195: support pcm in platform driver This patch adds mt8195 pcm dai driver. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 389 +++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c new file mode 100644 index 00000000000000..5d10d2c4c991c6 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c @@ -0,0 +1,389 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI PCM I/F Control + * + * Copyright (c) 2020 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include +#include +#include "mt8195-afe-clk.h" +#include "mt8195-afe-common.h" +#include "mt8195-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_INPUT("PCM1_INPUT"), + SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"), +}; + +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_OUTPUT", NULL, "PCM1 Playback"}, + {"PCM1 Capture", NULL, "PCM1_INPUT"}, +}; + +static void mtk_dai_pcm_enable(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN); +} + +static void mtk_dai_pcm_disable(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_PCM_EN, 0x0); +} + +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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id]; + unsigned int slave_mode = pcmif_priv->slave_mode; + unsigned int lrck_inv = pcmif_priv->lrck_inv; + unsigned int bck_inv = pcmif_priv->bck_inv; + unsigned int fmt = pcmif_priv->format; + unsigned int bit_width = dai->sample_bits; + unsigned int val = 0; + unsigned int mask = 0; + int fs = 0; + int mode = 0; + + /* sync freq mode */ + fs = mt8195_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_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + + if (dai->component->active) + return 0; + + mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]); + mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]); + mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]); + + return 0; +} + +static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + + if (dai->component->active) + return; + + mtk_dai_pcm_disable(afe); + + mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]); + mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]); + mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]); +} + +static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) && + snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) + return 0; + + ret = mtk_dai_pcm_configure(substream, dai); + if (ret) + return ret; + + mtk_dai_pcm_enable(afe); + + return 0; +} + +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 mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id]; + + dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt); + + 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_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + pcmif_priv->slave_mode = 1; + break; + case SND_SOC_DAIFMT_CBS_CFS: + pcmif_priv->slave_mode = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { + .startup = mtk_dai_pcm_startup, + .shutdown = mtk_dai_pcm_shutdown, + .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 = MT8195_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 mt8195_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[MT8195_AFE_IO_PCM] = pcmif_priv; + return 0; +} + +int mt8195_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); +} From 1db6b58ea8d08ce631a4398f4a437abf20fa20b7 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:39 +0800 Subject: [PATCH 06/24] ASoC: mediatek: mt8195: add platform driver This patch adds mt8195 platform and affiliated driver. Signed-off-by: Trevor Wu Reported-by: kernel test robot --- sound/soc/mediatek/Kconfig | 9 + sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/mt8195/Makefile | 12 + sound/soc/mediatek/mt8195/mt8195-afe-clk.c | 441 +++ sound/soc/mediatek/mt8195/mt8195-afe-clk.h | 109 + sound/soc/mediatek/mt8195/mt8195-afe-common.h | 158 + sound/soc/mediatek/mt8195/mt8195-afe-pcm.c | 3281 +++++++++++++++++ sound/soc/mediatek/mt8195/mt8195-reg.h | 2796 ++++++++++++++ 8 files changed, 6807 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/Makefile create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.c create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-clk.h create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-common.h create mode 100644 sound/soc/mediatek/mt8195/mt8195-afe-pcm.c create mode 100644 sound/soc/mediatek/mt8195/mt8195-reg.h diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 74dae4332d1705..3389f382be068a 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -184,3 +184,12 @@ config SND_SOC_MT8192_MT6359_RT1015_RT5682 with the MT6359 RT1015 RT5682 audio codec. Select Y if you have such device. If unsure select "N". + +config SND_SOC_MT8195 + tristate "ASoC support for Mediatek MT8195 chip" + select SND_SOC_MEDIATEK + help + This adds ASoC platform driver support for Mediatek MT8195 chip + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index f6cb6b8508e3f8..34778ca12106fe 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/ obj-$(CONFIG_SND_SOC_MT8173) += mt8173/ obj-$(CONFIG_SND_SOC_MT8183) += mt8183/ obj-$(CONFIG_SND_SOC_MT8192) += mt8192/ +obj-$(CONFIG_SND_SOC_MT8195) += mt8195/ diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile new file mode 100644 index 00000000000000..6529dd5beb2b6c --- /dev/null +++ b/sound/soc/mediatek/mt8195/Makefile @@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0 + +# platform driver +snd-soc-mt8195-afe-objs := \ + mt8195-audsys-clk.o \ + mt8195-afe-clk.o \ + mt8195-afe-pcm.o \ + mt8195-dai-adda.o \ + mt8195-dai-etdm.o \ + mt8195-dai-pcm.o + +obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.c b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c new file mode 100644 index 00000000000000..8420b2c71332a4 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8195-afe-clk.c -- Mediatek 8195 afe clock ctrl + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include + +#include "mt8195-afe-common.h" +#include "mt8195-afe-clk.h" +#include "mt8195-reg.h" +#include "mt8195-audsys-clk.h" + +static const char *aud_clks[MT8195_CLK_NUM] = { + /* xtal */ + [MT8195_CLK_XTAL_26M] = "clk26m", + /* divider */ + [MT8195_CLK_TOP_APLL1] = "apll1_ck", + [MT8195_CLK_TOP_APLL2] = "apll2_ck", + [MT8195_CLK_TOP_APLL12_DIV0] = "apll12_div0", + [MT8195_CLK_TOP_APLL12_DIV1] = "apll12_div1", + [MT8195_CLK_TOP_APLL12_DIV2] = "apll12_div2", + [MT8195_CLK_TOP_APLL12_DIV3] = "apll12_div3", + [MT8195_CLK_TOP_APLL12_DIV9] = "apll12_div9", + /* mux */ + [MT8195_CLK_TOP_A1SYS_HP_SEL] = "a1sys_hp_sel", + [MT8195_CLK_TOP_AUD_INTBUS_SEL] = "aud_intbus_sel", + [MT8195_CLK_TOP_AUDIO_H_SEL] = "audio_h_sel", + [MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL] = "audio_local_bus_sel", + [MT8195_CLK_TOP_DPTX_M_SEL] = "dptx_m_sel", + [MT8195_CLK_TOP_I2SO1_M_SEL] = "i2so1_m_sel", + [MT8195_CLK_TOP_I2SO2_M_SEL] = "i2so2_m_sel", + [MT8195_CLK_TOP_I2SI1_M_SEL] = "i2si1_m_sel", + [MT8195_CLK_TOP_I2SI2_M_SEL] = "i2si2_m_sel", + /* clock gate */ + [MT8195_CLK_INFRA_AO_AUDIO_26M_B] = "infra_ao_audio_26m_b", + [MT8195_CLK_SCP_ADSP_AUDIODSP] = "scp_adsp_audiodsp", + /* afe clock gate */ + [MT8195_CLK_AUD_AFE] = "aud_afe", + [MT8195_CLK_AUD_APLL] = "aud_apll", + [MT8195_CLK_AUD_APLL2] = "aud_apll2", + [MT8195_CLK_AUD_DAC] = "aud_dac", + [MT8195_CLK_AUD_ADC] = "aud_adc", + [MT8195_CLK_AUD_DAC_HIRES] = "aud_dac_hires", + [MT8195_CLK_AUD_A1SYS_HP] = "aud_a1sys_hp", + [MT8195_CLK_AUD_ADC_HIRES] = "aud_adc_hires", + [MT8195_CLK_AUD_ADDA6_ADC] = "aud_adda6_adc", + [MT8195_CLK_AUD_ADDA6_ADC_HIRES] = "aud_adda6_adc_hires", + [MT8195_CLK_AUD_I2SIN] = "aud_i2sin", + [MT8195_CLK_AUD_TDM_IN] = "aud_tdm_in", + [MT8195_CLK_AUD_I2S_OUT] = "aud_i2s_out", + [MT8195_CLK_AUD_TDM_OUT] = "aud_tdm_out", + [MT8195_CLK_AUD_HDMI_OUT] = "aud_hdmi_out", + [MT8195_CLK_AUD_ASRC11] = "aud_asrc11", + [MT8195_CLK_AUD_ASRC12] = "aud_asrc12", + [MT8195_CLK_AUD_A1SYS] = "aud_a1sys", + [MT8195_CLK_AUD_A2SYS] = "aud_a2sys", + [MT8195_CLK_AUD_PCMIF] = "aud_pcmif", + [MT8195_CLK_AUD_MEMIF_UL1] = "aud_memif_ul1", + [MT8195_CLK_AUD_MEMIF_UL2] = "aud_memif_ul2", + [MT8195_CLK_AUD_MEMIF_UL3] = "aud_memif_ul3", + [MT8195_CLK_AUD_MEMIF_UL4] = "aud_memif_ul4", + [MT8195_CLK_AUD_MEMIF_UL5] = "aud_memif_ul5", + [MT8195_CLK_AUD_MEMIF_UL6] = "aud_memif_ul6", + [MT8195_CLK_AUD_MEMIF_UL8] = "aud_memif_ul8", + [MT8195_CLK_AUD_MEMIF_UL9] = "aud_memif_ul9", + [MT8195_CLK_AUD_MEMIF_UL10] = "aud_memif_ul10", + [MT8195_CLK_AUD_MEMIF_DL2] = "aud_memif_dl2", + [MT8195_CLK_AUD_MEMIF_DL3] = "aud_memif_dl3", + [MT8195_CLK_AUD_MEMIF_DL6] = "aud_memif_dl6", + [MT8195_CLK_AUD_MEMIF_DL7] = "aud_memif_dl7", + [MT8195_CLK_AUD_MEMIF_DL8] = "aud_memif_dl8", + [MT8195_CLK_AUD_MEMIF_DL10] = "aud_memif_dl10", + [MT8195_CLK_AUD_MEMIF_DL11] = "aud_memif_dl11", +}; + +int mt8195_afe_get_mclk_source_clk_id(int sel) +{ + switch (sel) { + case MT8195_MCK_SEL_26M: + return MT8195_CLK_XTAL_26M; + case MT8195_MCK_SEL_APLL1: + return MT8195_CLK_TOP_APLL1; + case MT8195_MCK_SEL_APLL2: + return MT8195_CLK_TOP_APLL2; + default: + return -EINVAL; + } +} + +int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int clk_id = mt8195_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 mt8195_afe_get_default_mclk_source_by_rate(int rate) +{ + return ((rate % 8000) == 0) ? + MT8195_MCK_SEL_APLL1 : MT8195_MCK_SEL_APLL2; +} + +int mt8195_afe_init_clock(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int i; + + mt8195_audsys_clk_register(afe); + + afe_priv->clk = + devm_kcalloc(afe->dev, MT8195_CLK_NUM, sizeof(*afe_priv->clk), + GFP_KERNEL); + if (!afe_priv->clk) + return -ENOMEM; + + for (i = 0; i < MT8195_CLK_NUM; i++) { + afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]); + if (IS_ERR(afe_priv->clk[i])) { + dev_dbg(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]); + } + } + + return 0; +} + +void mt8195_afe_deinit_clock(struct mtk_base_afe *afe) +{ + mt8195_audsys_clk_unregister(afe); +} + +int mt8195_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(mt8195_afe_enable_clk); + +void mt8195_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(mt8195_afe_disable_clk); + +int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk) +{ + int ret; + + if (clk) { + ret = clk_prepare(clk); + if (ret) { + dev_dbg(afe->dev, "%s(), failed to prepare clk\n", + __func__); + return ret; + } + } else { + dev_dbg(afe->dev, "NULL clk\n"); + } + return 0; +} + +void mt8195_afe_unprepare_clk(struct mtk_base_afe *afe, struct clk *clk) +{ + if (clk) + clk_unprepare(clk); + else + dev_dbg(afe->dev, "NULL clk\n"); +} + +int mt8195_afe_enable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk) +{ + int ret; + + if (clk) { + ret = clk_enable(clk); + if (ret) { + dev_dbg(afe->dev, "%s(), failed to clk enable\n", + __func__); + return ret; + } + } else { + dev_dbg(afe->dev, "NULL clk\n"); + } + return 0; +} + +void mt8195_afe_disable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk) +{ + if (clk) + clk_disable(clk); + else + dev_dbg(afe->dev, "NULL clk\n"); +} + +int mt8195_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 mt8195_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 MT8195_TOP_CG_A1SYS_TIMING: + case MT8195_TOP_CG_A2SYS_TIMING: + case MT8195_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 MT8195_TOP_CG_A1SYS_TIMING: + return ASYS_TOP_CON_A1SYS_TIMING_ON; + case MT8195_TOP_CG_A2SYS_TIMING: + return ASYS_TOP_CON_A2SYS_TIMING_ON; + case MT8195_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 MT8195_TOP_CG_A1SYS_TIMING: + case MT8195_TOP_CG_A2SYS_TIMING: + case MT8195_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 MT8195_TOP_CG_A1SYS_TIMING: + case MT8195_TOP_CG_A2SYS_TIMING: + case MT8195_TOP_CG_26M_TIMING: + return 0; + default: + return get_top_cg_mask(cg_type); + } +} + +static int mt8195_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 mt8195_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 mt8195_afe_enable_reg_rw_clk(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int i; + unsigned int clk_array[] = { + MT8195_CLK_SCP_ADSP_AUDIODSP, /* bus clock for infra */ + MT8195_CLK_TOP_AUDIO_H_SEL, /* clock for ADSP bus */ + MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL, /* bus clock for DRAM access */ + MT8195_CLK_TOP_AUD_INTBUS_SEL, /* bus clock for AFE SRAM access */ + MT8195_CLK_INFRA_AO_AUDIO_26M_B, /* audio 26M clock */ + MT8195_CLK_AUD_AFE, /* AFE HW master switch */ + MT8195_CLK_AUD_A1SYS_HP, /* AFE HW clock*/ + MT8195_CLK_AUD_A1SYS, /* AFE HW clock */ + }; + + for (i = 0; i < ARRAY_SIZE(clk_array); i++) + mt8195_afe_enable_clk(afe, afe_priv->clk[clk_array[i]]); + + return 0; +} + +int mt8195_afe_disable_reg_rw_clk(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int i; + unsigned int clk_array[] = { + MT8195_CLK_AUD_A1SYS, + MT8195_CLK_AUD_A1SYS_HP, + MT8195_CLK_AUD_AFE, + MT8195_CLK_INFRA_AO_AUDIO_26M_B, + MT8195_CLK_TOP_AUD_INTBUS_SEL, + MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL, + MT8195_CLK_TOP_AUDIO_H_SEL, + MT8195_CLK_SCP_ADSP_AUDIODSP, + }; + + for (i = 0; i < ARRAY_SIZE(clk_array); i++) + mt8195_afe_disable_clk(afe, afe_priv->clk[clk_array[i]]); + + return 0; +} + +static int mt8195_afe_enable_afe_on(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x1); + return 0; +} + +static int mt8195_afe_disable_afe_on(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, AFE_DAC_CON0, 0x1, 0x0); + return 0; +} + +static int mt8195_afe_enable_timing_sys(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int i; + unsigned int clk_array[] = { + MT8195_CLK_AUD_A1SYS, + MT8195_CLK_AUD_A2SYS, + }; + unsigned int cg_array[] = { + MT8195_TOP_CG_A1SYS_TIMING, + MT8195_TOP_CG_A2SYS_TIMING, + MT8195_TOP_CG_26M_TIMING, + }; + + for (i = 0; i < ARRAY_SIZE(clk_array); i++) + mt8195_afe_enable_clk(afe, afe_priv->clk[clk_array[i]]); + + for (i = 0; i < ARRAY_SIZE(cg_array); i++) + mt8195_afe_enable_top_cg(afe, cg_array[i]); + + return 0; +} + +static int mt8195_afe_disable_timing_sys(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int i; + unsigned int clk_array[] = { + MT8195_CLK_AUD_A2SYS, + MT8195_CLK_AUD_A1SYS, + }; + unsigned int cg_array[] = { + MT8195_TOP_CG_26M_TIMING, + MT8195_TOP_CG_A2SYS_TIMING, + MT8195_TOP_CG_A1SYS_TIMING, + }; + + for (i = 0; i < ARRAY_SIZE(cg_array); i++) + mt8195_afe_disable_top_cg(afe, cg_array[i]); + + for (i = 0; i < ARRAY_SIZE(clk_array); i++) + mt8195_afe_disable_clk(afe, afe_priv->clk[clk_array[i]]); + + return 0; +} + +int mt8195_afe_enable_main_clock(struct mtk_base_afe *afe) +{ + mt8195_afe_enable_timing_sys(afe); + + mt8195_afe_enable_afe_on(afe); + + return 0; +} + +int mt8195_afe_disable_main_clock(struct mtk_base_afe *afe) +{ + mt8195_afe_disable_afe_on(afe); + + mt8195_afe_disable_timing_sys(afe); + + return 0; +} diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-clk.h b/sound/soc/mediatek/mt8195/mt8195-afe-clk.h new file mode 100644 index 00000000000000..f8e6eeb29a8955 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-afe-clk.h @@ -0,0 +1,109 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-afe-clk.h -- Mediatek 8195 afe clock ctrl definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#ifndef _MT8195_AFE_CLK_H_ +#define _MT8195_AFE_CLK_H_ + +enum { + /* xtal */ + MT8195_CLK_XTAL_26M, + /* divider */ + MT8195_CLK_TOP_APLL1, + MT8195_CLK_TOP_APLL2, + MT8195_CLK_TOP_APLL12_DIV0, + MT8195_CLK_TOP_APLL12_DIV1, + MT8195_CLK_TOP_APLL12_DIV2, + MT8195_CLK_TOP_APLL12_DIV3, + MT8195_CLK_TOP_APLL12_DIV9, + /* mux */ + MT8195_CLK_TOP_A1SYS_HP_SEL, + MT8195_CLK_TOP_AUD_INTBUS_SEL, + MT8195_CLK_TOP_AUDIO_H_SEL, + MT8195_CLK_TOP_AUDIO_LOCAL_BUS_SEL, + MT8195_CLK_TOP_DPTX_M_SEL, + MT8195_CLK_TOP_I2SO1_M_SEL, + MT8195_CLK_TOP_I2SO2_M_SEL, + MT8195_CLK_TOP_I2SI1_M_SEL, + MT8195_CLK_TOP_I2SI2_M_SEL, + /* clock gate */ + MT8195_CLK_INFRA_AO_AUDIO_26M_B, + MT8195_CLK_SCP_ADSP_AUDIODSP, + MT8195_CLK_AUD_AFE, + MT8195_CLK_AUD_APLL, + MT8195_CLK_AUD_APLL2, + MT8195_CLK_AUD_DAC, + MT8195_CLK_AUD_ADC, + MT8195_CLK_AUD_DAC_HIRES, + MT8195_CLK_AUD_A1SYS_HP, + MT8195_CLK_AUD_ADC_HIRES, + MT8195_CLK_AUD_ADDA6_ADC, + MT8195_CLK_AUD_ADDA6_ADC_HIRES, + MT8195_CLK_AUD_I2SIN, + MT8195_CLK_AUD_TDM_IN, + MT8195_CLK_AUD_I2S_OUT, + MT8195_CLK_AUD_TDM_OUT, + MT8195_CLK_AUD_HDMI_OUT, + MT8195_CLK_AUD_ASRC11, + MT8195_CLK_AUD_ASRC12, + MT8195_CLK_AUD_A1SYS, + MT8195_CLK_AUD_A2SYS, + MT8195_CLK_AUD_PCMIF, + MT8195_CLK_AUD_MEMIF_UL1, + MT8195_CLK_AUD_MEMIF_UL2, + MT8195_CLK_AUD_MEMIF_UL3, + MT8195_CLK_AUD_MEMIF_UL4, + MT8195_CLK_AUD_MEMIF_UL5, + MT8195_CLK_AUD_MEMIF_UL6, + MT8195_CLK_AUD_MEMIF_UL8, + MT8195_CLK_AUD_MEMIF_UL9, + MT8195_CLK_AUD_MEMIF_UL10, + MT8195_CLK_AUD_MEMIF_DL2, + MT8195_CLK_AUD_MEMIF_DL3, + MT8195_CLK_AUD_MEMIF_DL6, + MT8195_CLK_AUD_MEMIF_DL7, + MT8195_CLK_AUD_MEMIF_DL8, + MT8195_CLK_AUD_MEMIF_DL10, + MT8195_CLK_AUD_MEMIF_DL11, + MT8195_CLK_NUM, +}; + +enum { + MT8195_MCK_SEL_26M, + MT8195_MCK_SEL_APLL1, + MT8195_MCK_SEL_APLL2, + MT8195_MCK_SEL_APLL3, + MT8195_MCK_SEL_APLL4, + MT8195_MCK_SEL_APLL5, + MT8195_MCK_SEL_HDMIRX_APLL, + MT8195_MCK_SEL_NUM, +}; + +struct mtk_base_afe; + +int mt8195_afe_get_mclk_source_clk_id(int sel); +int mt8195_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll); +int mt8195_afe_get_default_mclk_source_by_rate(int rate); +int mt8195_afe_init_clock(struct mtk_base_afe *afe); +void mt8195_afe_deinit_clock(struct mtk_base_afe *afe); +int mt8195_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk); +void mt8195_afe_disable_clk(struct mtk_base_afe *afe, struct clk *clk); +int mt8195_afe_prepare_clk(struct mtk_base_afe *afe, struct clk *clk); +void mt8195_afe_unprepare_clk(struct mtk_base_afe *afe, struct clk *clk); +int mt8195_afe_enable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk); +void mt8195_afe_disable_clk_atomic(struct mtk_base_afe *afe, struct clk *clk); +int mt8195_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, + unsigned int rate); +int mt8195_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, + struct clk *parent); +int mt8195_afe_enable_main_clock(struct mtk_base_afe *afe); +int mt8195_afe_disable_main_clock(struct mtk_base_afe *afe); +int mt8195_afe_enable_reg_rw_clk(struct mtk_base_afe *afe); +int mt8195_afe_disable_reg_rw_clk(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-common.h b/sound/soc/mediatek/mt8195/mt8195-afe-common.h new file mode 100644 index 00000000000000..f93f439e2bd94c --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-afe-common.h @@ -0,0 +1,158 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-afe-common.h -- Mediatek 8195 audio driver definitions + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#ifndef _MT_8195_AFE_COMMON_H_ +#define _MT_8195_AFE_COMMON_H_ + +#include +#include +#include +#include "../common/mtk-base-afe.h" + +enum { + MT8195_DAI_START, + MT8195_AFE_MEMIF_START = MT8195_DAI_START, + MT8195_AFE_MEMIF_DL2 = MT8195_AFE_MEMIF_START, + MT8195_AFE_MEMIF_DL3, + MT8195_AFE_MEMIF_DL6, + MT8195_AFE_MEMIF_DL7, + MT8195_AFE_MEMIF_DL8, + MT8195_AFE_MEMIF_DL10, + MT8195_AFE_MEMIF_DL11, + MT8195_AFE_MEMIF_UL_START, + MT8195_AFE_MEMIF_UL1 = MT8195_AFE_MEMIF_UL_START, + MT8195_AFE_MEMIF_UL2, + MT8195_AFE_MEMIF_UL3, + MT8195_AFE_MEMIF_UL4, + MT8195_AFE_MEMIF_UL5, + MT8195_AFE_MEMIF_UL6, + MT8195_AFE_MEMIF_UL8, + MT8195_AFE_MEMIF_UL9, + MT8195_AFE_MEMIF_UL10, + MT8195_AFE_MEMIF_END, + MT8195_AFE_MEMIF_NUM = (MT8195_AFE_MEMIF_END - MT8195_AFE_MEMIF_START), + MT8195_AFE_IO_START = MT8195_AFE_MEMIF_END, + MT8195_AFE_IO_DL_SRC = MT8195_AFE_IO_START, + MT8195_AFE_IO_DPTX, + MT8195_AFE_IO_ETDM_START, + MT8195_AFE_IO_ETDM1_IN = MT8195_AFE_IO_ETDM_START, + MT8195_AFE_IO_ETDM2_IN, + MT8195_AFE_IO_ETDM1_OUT, + MT8195_AFE_IO_ETDM2_OUT, + MT8195_AFE_IO_ETDM3_OUT, + MT8195_AFE_IO_ETDM_END, + MT8195_AFE_IO_ETDM_NUM = + (MT8195_AFE_IO_ETDM_END - MT8195_AFE_IO_ETDM_START), + MT8195_AFE_IO_PCM = MT8195_AFE_IO_ETDM_END, + MT8195_AFE_IO_UL_SRC1, + MT8195_AFE_IO_UL_SRC2, + MT8195_AFE_IO_END, + MT8195_AFE_IO_NUM = (MT8195_AFE_IO_END - MT8195_AFE_IO_START), + MT8195_DAI_END = MT8195_AFE_IO_END, + MT8195_DAI_NUM = (MT8195_DAI_END - MT8195_DAI_START), +}; + +enum { + MT8195_TOP_CG_A1SYS_TIMING, + MT8195_TOP_CG_A2SYS_TIMING, + MT8195_TOP_CG_26M_TIMING, + MT8195_TOP_CG_NUM, +}; + +enum { + MT8195_AFE_IRQ_1, + MT8195_AFE_IRQ_2, + MT8195_AFE_IRQ_3, + MT8195_AFE_IRQ_8, + MT8195_AFE_IRQ_9, + MT8195_AFE_IRQ_10, + MT8195_AFE_IRQ_13, + MT8195_AFE_IRQ_14, + MT8195_AFE_IRQ_15, + MT8195_AFE_IRQ_16, + MT8195_AFE_IRQ_17, + MT8195_AFE_IRQ_18, + MT8195_AFE_IRQ_19, + MT8195_AFE_IRQ_20, + MT8195_AFE_IRQ_21, + MT8195_AFE_IRQ_22, + MT8195_AFE_IRQ_23, + MT8195_AFE_IRQ_24, + MT8195_AFE_IRQ_25, + MT8195_AFE_IRQ_26, + MT8195_AFE_IRQ_27, + MT8195_AFE_IRQ_28, + MT8195_AFE_IRQ_NUM, +}; + +enum { + MT8195_ETDM_OUT1_1X_EN = 9, + MT8195_ETDM_OUT2_1X_EN = 10, + MT8195_ETDM_OUT3_1X_EN = 11, + MT8195_ETDM_IN1_1X_EN = 12, + MT8195_ETDM_IN2_1X_EN = 13, + MT8195_ETDM_IN1_NX_EN = 25, + MT8195_ETDM_IN2_NX_EN = 26, +}; + +enum { + MT8195_MTKAIF_MISO_0, + MT8195_MTKAIF_MISO_1, + MT8195_MTKAIF_MISO_2, + MT8195_MTKAIF_MISO_NUM, +}; + +struct mtk_dai_memif_irq_priv { + unsigned int asys_timing_sel; +}; + +struct mtkaif_param { + bool mtkaif_calibration_ok; + int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM]; + int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM]; + int mtkaif_dmic_on; + int mtkaif_adda6_only; +}; + +struct clk; + +struct mt8195_afe_private { + struct clk **clk; + struct clk_lookup **lookup; + struct regmap *topckgen; + int pm_runtime_bypass_reg_ctl; +#ifdef CONFIG_DEBUG_FS + struct dentry **debugfs_dentry; +#endif + int afe_on_ref_cnt; + int top_cg_ref_cnt[MT8195_TOP_CG_NUM]; + spinlock_t afe_ctrl_lock; /* Lock for afe control */ + struct mtk_dai_memif_irq_priv irq_priv[MT8195_AFE_IRQ_NUM]; + struct mtkaif_param mtkaif_params; + + /* dai */ + void *dai_priv[MT8195_DAI_NUM]; +}; + +int mt8195_afe_fs_timing(unsigned int rate); +/* dai register */ +int mt8195_dai_adda_register(struct mtk_base_afe *afe); +int mt8195_dai_etdm_register(struct mtk_base_afe *afe); +int mt8195_dai_pcm_register(struct mtk_base_afe *afe); + +#define MT8195_SOC_ENUM_EXT(xname, xenum, xhandler_get, xhandler_put, id) \ +{ \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_enum_double, \ + .get = xhandler_get, .put = xhandler_put, \ + .device = id, \ + .private_value = (unsigned long)&xenum, \ +} + +#endif diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c new file mode 100644 index 00000000000000..6635c3f72eccc0 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c @@ -0,0 +1,3281 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Mediatek ALSA SoC AFE platform driver for 8195 + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "mt8195-afe-common.h" +#include "mt8195-afe-clk.h" +#include "mt8195-reg.h" +#include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-afe-fe-dai.h" + +#define MT8195_MEMIF_BUFFER_BYTES_ALIGN (0x40) +#define MT8195_MEMIF_DL7_MAX_PERIOD_SIZE (0x3fff) + +struct mtk_dai_memif_priv { + unsigned int asys_timing_sel; +}; + +static const struct snd_pcm_hardware mt8195_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 mt8195_afe_rate { + unsigned int rate; + unsigned int reg_value; +}; + +static const struct mt8195_afe_rate mt8195_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 mt8195_afe_fs_timing(unsigned int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mt8195_afe_rates); i++) + if (mt8195_afe_rates[i].rate == rate) + return mt8195_afe_rates[i].reg_value; + + return -EINVAL; +} + +static int mt8195_memif_fs(struct snd_pcm_substream *substream, + unsigned int rate) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_component *component = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + int id = asoc_rtd_to_cpu(rtd, 0)->id; + struct mtk_base_afe_memif *memif = &afe->memif[id]; + int fs = mt8195_afe_fs_timing(rate); + + switch (memif->data->id) { + case MT8195_AFE_MEMIF_DL10: + fs = MT8195_ETDM_OUT3_1X_EN; + break; + case MT8195_AFE_MEMIF_UL8: + fs = MT8195_ETDM_IN1_NX_EN; + break; + case MT8195_AFE_MEMIF_UL3: + fs = MT8195_ETDM_IN2_NX_EN; + break; + default: + break; + } + + return fs; +} + +static int mt8195_irq_fs(struct snd_pcm_substream *substream, + unsigned int rate) +{ + int fs = mt8195_memif_fs(substream, rate); + + switch (fs) { + case MT8195_ETDM_IN1_NX_EN: + fs = MT8195_ETDM_IN1_1X_EN; + break; + case MT8195_ETDM_IN2_NX_EN: + fs = MT8195_ETDM_IN2_1X_EN; + break; + default: + break; + } + + return fs; +} + +enum { + MT8195_AFE_CM0, + MT8195_AFE_CM1, + MT8195_AFE_CM2, + MT8195_AFE_CM_NUM, +}; + +struct mt8195_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 mt8195_afe_channel_merge + mt8195_afe_cm[MT8195_AFE_CM_NUM] = { + [MT8195_AFE_CM0] = { + .id = MT8195_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, + }, + [MT8195_AFE_CM1] = { + .id = MT8195_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, + }, + [MT8195_AFE_CM2] = { + .id = MT8195_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 mt8195_afe_memif_is_ul(int id) +{ + if (id >= MT8195_AFE_MEMIF_UL_START && id < MT8195_AFE_MEMIF_END) + return 1; + else + return 0; +} + +static const struct mt8195_afe_channel_merge* +mt8195_afe_found_cm(struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int id = -EINVAL; + + if (mt8195_afe_memif_is_ul(dai->id) == 0) + return NULL; + + switch (dai->id) { + case MT8195_AFE_MEMIF_UL9: + id = MT8195_AFE_CM0; + break; + case MT8195_AFE_MEMIF_UL2: + id = MT8195_AFE_CM1; + break; + case MT8195_AFE_MEMIF_UL10: + id = MT8195_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 &mt8195_afe_cm[id]; +} + +static int mt8195_afe_config_cm(struct mtk_base_afe *afe, + const struct mt8195_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 mt8195_afe_enable_cm(struct mtk_base_afe *afe, + const struct mt8195_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 +mt8195_afe_paired_memif_clk_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai, + int enable) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int id = asoc_rtd_to_cpu(rtd, 0)->id; + int clk_id; + + if (id != MT8195_AFE_MEMIF_DL8 && id != MT8195_AFE_MEMIF_DL10) + return 0; + + if (enable) { + clk_id = MT8195_CLK_AUD_MEMIF_DL10; + mt8195_afe_prepare_clk(afe, afe_priv->clk[clk_id]); + clk_id = MT8195_CLK_AUD_MEMIF_DL8; + mt8195_afe_prepare_clk(afe, afe_priv->clk[clk_id]); + } else { + clk_id = MT8195_CLK_AUD_MEMIF_DL8; + mt8195_afe_unprepare_clk(afe, afe_priv->clk[clk_id]); + clk_id = MT8195_CLK_AUD_MEMIF_DL10; + mt8195_afe_unprepare_clk(afe, afe_priv->clk[clk_id]); + } + + return 0; +} + +static int +mt8195_afe_paired_memif_clk_enable(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai, + int enable) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int id = asoc_rtd_to_cpu(rtd, 0)->id; + int clk_id; + + if (id != MT8195_AFE_MEMIF_DL8 && id != MT8195_AFE_MEMIF_DL10) + return 0; + + if (enable) { + /* DL8_DL10_MEM */ + clk_id = MT8195_CLK_AUD_MEMIF_DL10; + mt8195_afe_enable_clk_atomic(afe, afe_priv->clk[clk_id]); + udelay(1); + /* DL8_DL10_AGENT */ + clk_id = MT8195_CLK_AUD_MEMIF_DL8; + mt8195_afe_enable_clk_atomic(afe, afe_priv->clk[clk_id]); + } else { + /* DL8_DL10_AGENT */ + clk_id = MT8195_CLK_AUD_MEMIF_DL8; + mt8195_afe_disable_clk_atomic(afe, afe_priv->clk[clk_id]); + /* DL8_DL10_MEM */ + clk_id = MT8195_CLK_AUD_MEMIF_DL10; + mt8195_afe_disable_clk_atomic(afe, afe_priv->clk[clk_id]); + } + + return 0; +} + +static int mt8195_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 = 0; + + mt8195_afe_paired_memif_clk_prepare(substream, dai, 1); + + ret = mtk_afe_fe_startup(substream, dai); + + snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + MT8195_MEMIF_BUFFER_BYTES_ALIGN); + + if (id != MT8195_AFE_MEMIF_DL7) + goto out; + + ret = snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, + 1, + MT8195_MEMIF_DL7_MAX_PERIOD_SIZE); + if (ret < 0) + dev_dbg(afe->dev, "hw_constraint_minmax failed\n"); +out: + return ret; +} + +static void mt8195_afe_fe_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + mtk_afe_fe_shutdown(substream, dai); + mt8195_afe_paired_memif_clk_prepare(substream, dai, 0); +} + +static int mt8195_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 mt8195_afe_channel_merge *cm = mt8195_afe_found_cm(dai); + unsigned int ch_num = params_channels(params); + + mt8195_afe_config_cm(afe, cm, params_channels(params)); + + if (data->ch_num_reg >= 0) { + regmap_update_bits(afe->regmap, data->ch_num_reg, + data->ch_num_maskbit << data->ch_num_shift, + ch_num << data->ch_num_shift); + } + + return mtk_afe_fe_hw_params(substream, params, dai); +} + +static int mt8195_afe_fe_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return mtk_afe_fe_hw_free(substream, dai); +} + +static int mt8195_afe_fe_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + return mtk_afe_fe_prepare(substream, dai); +} + +static int mt8195_afe_fe_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int ret = 0; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + const struct mt8195_afe_channel_merge *cm = mt8195_afe_found_cm(dai); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + mt8195_afe_enable_cm(afe, cm, true); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + mt8195_afe_enable_cm(afe, cm, false); + break; + default: + break; + } + + ret = mtk_afe_fe_trigger(substream, cmd, dai); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + mt8195_afe_paired_memif_clk_enable(substream, dai, 1); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + mt8195_afe_paired_memif_clk_enable(substream, dai, 0); + break; + default: + break; + } + + return ret; +} + +static int mt8195_afe_fe_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + return 0; +} + +static const struct snd_soc_dai_ops mt8195_afe_fe_dai_ops = { + .startup = mt8195_afe_fe_startup, + .shutdown = mt8195_afe_fe_shutdown, + .hw_params = mt8195_afe_fe_hw_params, + .hw_free = mt8195_afe_fe_hw_free, + .prepare = mt8195_afe_fe_prepare, + .trigger = mt8195_afe_fe_trigger, + .set_fmt = mt8195_afe_fe_set_fmt, +}; + +#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 mt8195_memif_dai_driver[] = { + /* FE DAIs: memory intefaces to CPU */ + { + .name = "DL2", + .id = MT8195_AFE_MEMIF_DL2, + .playback = { + .stream_name = "DL2", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "DL3", + .id = MT8195_AFE_MEMIF_DL3, + .playback = { + .stream_name = "DL3", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "DL6", + .id = MT8195_AFE_MEMIF_DL6, + .playback = { + .stream_name = "DL6", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "DL7", + .id = MT8195_AFE_MEMIF_DL7, + .playback = { + .stream_name = "DL7", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "DL8", + .id = MT8195_AFE_MEMIF_DL8, + .playback = { + .stream_name = "DL8", + .channels_min = 1, + .channels_max = 24, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "DL10", + .id = MT8195_AFE_MEMIF_DL10, + .playback = { + .stream_name = "DL10", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "DL11", + .id = MT8195_AFE_MEMIF_DL11, + .playback = { + .stream_name = "DL11", + .channels_min = 1, + .channels_max = 48, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL1", + .id = MT8195_AFE_MEMIF_UL1, + .capture = { + .stream_name = "UL1", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL2", + .id = MT8195_AFE_MEMIF_UL2, + .capture = { + .stream_name = "UL2", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL3", + .id = MT8195_AFE_MEMIF_UL3, + .capture = { + .stream_name = "UL3", + .channels_min = 1, + .channels_max = 16, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL4", + .id = MT8195_AFE_MEMIF_UL4, + .capture = { + .stream_name = "UL4", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL5", + .id = MT8195_AFE_MEMIF_UL5, + .capture = { + .stream_name = "UL5", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL6", + .id = MT8195_AFE_MEMIF_UL6, + .capture = { + .stream_name = "UL6", + .channels_min = 1, + .channels_max = 8, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL8", + .id = MT8195_AFE_MEMIF_UL8, + .capture = { + .stream_name = "UL8", + .channels_min = 1, + .channels_max = 24, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL9", + .id = MT8195_AFE_MEMIF_UL9, + .capture = { + .stream_name = "UL9", + .channels_min = 1, + .channels_max = 32, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_afe_fe_dai_ops, + }, + { + .name = "UL10", + .id = MT8195_AFE_MEMIF_UL10, + .capture = { + .stream_name = "UL10", + .channels_min = 1, + .channels_max = 4, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mt8195_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), + SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN4_5, 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), + SOC_DAPM_SINGLE_AUTODISABLE("I171 Switch", AFE_CONN5_5, 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), +}; + +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), +}; + +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), +}; + +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), +}; + +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), +}; + +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), +}; + +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), +}; + +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), +}; + +static const struct snd_kcontrol_new o018_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I038 Switch", AFE_CONN18_1, 6, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I080 Switch", AFE_CONN18_2, 16, 1, 0), +}; + +static const struct snd_kcontrol_new o019_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I039 Switch", AFE_CONN19_1, 7, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I081 Switch", AFE_CONN19_2, 17, 1, 0), +}; + +static const struct snd_kcontrol_new o020_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I040 Switch", AFE_CONN20_1, 8, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I082 Switch", AFE_CONN20_2, 18, 1, 0), +}; + +static const struct snd_kcontrol_new o021_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I041 Switch", AFE_CONN21_1, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I083 Switch", AFE_CONN21_2, 19, 1, 0), +}; + +static const struct snd_kcontrol_new o022_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I042 Switch", AFE_CONN22_1, 10, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I084 Switch", AFE_CONN22_2, 20, 1, 0), +}; + +static const struct snd_kcontrol_new o023_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I043 Switch", AFE_CONN23_1, 11, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I085 Switch", AFE_CONN23_2, 21, 1, 0), +}; + +static const struct snd_kcontrol_new o024_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I044 Switch", AFE_CONN24_1, 12, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I086 Switch", AFE_CONN24_2, 22, 1, 0), +}; + +static const struct snd_kcontrol_new o025_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I045 Switch", AFE_CONN25_1, 13, 1, 0), + 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), + SOC_DAPM_SINGLE_AUTODISABLE("I088 Switch", AFE_CONN26_2, 24, 1, 0), +}; + +static const struct snd_kcontrol_new o027_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I047 Switch", AFE_CONN27_1, 15, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I089 Switch", AFE_CONN27_2, 25, 1, 0), +}; + +static const struct snd_kcontrol_new o028_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I048 Switch", AFE_CONN28_1, 16, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I090 Switch", AFE_CONN28_2, 26, 1, 0), +}; + +static const struct snd_kcontrol_new o029_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I049 Switch", AFE_CONN29_1, 17, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I091 Switch", AFE_CONN29_2, 27, 1, 0), +}; + +static const struct snd_kcontrol_new o030_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I050 Switch", AFE_CONN30_1, 18, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I092 Switch", AFE_CONN30_2, 28, 1, 0), +}; + +static const struct snd_kcontrol_new o031_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I051 Switch", AFE_CONN31_1, 19, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I093 Switch", AFE_CONN31_2, 29, 1, 0), +}; + +static const struct snd_kcontrol_new o032_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I052 Switch", AFE_CONN32_1, 20, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I094 Switch", AFE_CONN32_2, 30, 1, 0), +}; + +static const struct snd_kcontrol_new o033_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I053 Switch", AFE_CONN33_1, 21, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I095 Switch", AFE_CONN33_2, 31, 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), + SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN34_5, 10, 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("I137 Switch", AFE_CONN35_4, 9, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I139 Switch", AFE_CONN35_4, 11, 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), + SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN35_5, 10, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I171 Switch", AFE_CONN35_5, 11, 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), +}; + +static const struct snd_kcontrol_new o039_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN39, 23, 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), + SOC_DAPM_SINGLE_AUTODISABLE("I170 Switch", AFE_CONN42_5, 10, 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), + SOC_DAPM_SINGLE_AUTODISABLE("I171 Switch", AFE_CONN43_5, 11, 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("I024 Switch", AFE_CONN182, 24, 1, 0), +}; + +static const struct snd_kcontrol_new o183_mix[] = { + 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 mt8195_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), + SND_SOC_DAPM_MIXER("I038", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I039", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I040", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I041", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I042", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I043", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I044", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I045", 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), + SND_SOC_DAPM_MIXER("I062", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I063", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I064", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I065", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I066", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I067", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I068", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I069", 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 mt8195_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"}, + {"I038", NULL, "DL11"}, + {"I039", NULL, "DL11"}, + {"I040", NULL, "DL11"}, + {"I041", NULL, "DL11"}, + {"I042", NULL, "DL11"}, + {"I043", NULL, "DL11"}, + {"I044", NULL, "DL11"}, + {"I045", 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"}, + {"I062", NULL, "DL8_DL11 Mux"}, + {"I063", NULL, "DL8_DL11 Mux"}, + {"I064", NULL, "DL8_DL11 Mux"}, + {"I065", NULL, "DL8_DL11 Mux"}, + {"I066", NULL, "DL8_DL11 Mux"}, + {"I067", NULL, "DL8_DL11 Mux"}, + {"I068", NULL, "DL8_DL11 Mux"}, + {"I069", 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"}, + {"O018", "I038 Switch", "I038"}, + {"O019", "I039 Switch", "I039"}, + {"O020", "I040 Switch", "I040"}, + {"O021", "I041 Switch", "I041"}, + {"O022", "I042 Switch", "I042"}, + {"O023", "I043 Switch", "I043"}, + {"O024", "I044 Switch", "I044"}, + {"O025", "I045 Switch", "I045"}, + {"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"}, + + {"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"}, + + {"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", "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"}, + {"O026", "I088 Switch", "I088"}, + {"O027", "I089 Switch", "I089"}, + {"O028", "I090 Switch", "I090"}, + {"O029", "I091 Switch", "I091"}, + {"O030", "I092 Switch", "I092"}, + {"O031", "I093 Switch", "I093"}, + {"O032", "I094 Switch", "I094"}, + {"O033", "I095 Switch", "I095"}, + + {"O002", "I168 Switch", "I168"}, + {"O003", "I169 Switch", "I169"}, + {"O004", "I170 Switch", "I170"}, + {"O005", "I171 Switch", "I171"}, + + {"O034", "I168 Switch", "I168"}, + {"O035", "I168 Switch", "I168"}, + {"O035", "I169 Switch", "I169"}, + + {"O034", "I170 Switch", "I170"}, + {"O035", "I170 Switch", "I170"}, + {"O035", "I171 Switch", "I171"}, + + {"O040", "I168 Switch", "I168"}, + {"O041", "I169 Switch", "I169"}, + {"O042", "I170 Switch", "I170"}, + {"O043", "I171 Switch", "I171"}, +}; + +static const char * const mt8195_afe_1x_en_sel_text[] = { + "a1sys_a2sys", "a3sys", "a4sys", +}; + +static const unsigned int mt8195_afe_1x_en_sel_values[] = { + 0, 1, 2, +}; + +static int mt8195_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 mt8195_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 mt8195_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 mt8195_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 SOC_VALUE_ENUM_SINGLE_DECL(dl2_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 18, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(dl3_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 20, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(dl6_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 22, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(dl7_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 24, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(dl8_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 26, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(dl10_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 28, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(dl11_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 30, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul1_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 0, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul2_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 2, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul3_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 4, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul4_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 6, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul5_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 8, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul6_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 10, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul8_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 12, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul9_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 14, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(ul10_1x_en_sel_enum, + A3_A4_TIMING_SEL1, 16, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); + +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq1_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 0, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq2_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 2, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq3_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 4, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq4_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 6, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq5_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 8, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq6_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 10, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq7_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 12, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq8_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 14, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq9_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 16, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq10_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 18, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq11_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 20, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq12_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 22, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq13_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 24, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq14_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 26, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq15_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 28, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); +static SOC_VALUE_ENUM_SINGLE_DECL(asys_irq16_1x_en_sel_enum, + A3_A4_TIMING_SEL6, 30, 0x3, + mt8195_afe_1x_en_sel_text, + mt8195_afe_1x_en_sel_values); + +static const struct snd_kcontrol_new mt8195_memif_controls[] = { + MT8195_SOC_ENUM_EXT("dl2_1x_en_sel", + dl2_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL2), + MT8195_SOC_ENUM_EXT("dl3_1x_en_sel", + dl3_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL3), + MT8195_SOC_ENUM_EXT("dl6_1x_en_sel", + dl6_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL6), + MT8195_SOC_ENUM_EXT("dl7_1x_en_sel", + dl7_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL7), + MT8195_SOC_ENUM_EXT("dl8_1x_en_sel", + dl8_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL8), + MT8195_SOC_ENUM_EXT("dl10_1x_en_sel", + dl10_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL10), + MT8195_SOC_ENUM_EXT("dl11_1x_en_sel", + dl11_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_DL11), + MT8195_SOC_ENUM_EXT("ul1_1x_en_sel", + ul1_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL1), + MT8195_SOC_ENUM_EXT("ul2_1x_en_sel", + ul2_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL2), + MT8195_SOC_ENUM_EXT("ul3_1x_en_sel", + ul3_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL3), + MT8195_SOC_ENUM_EXT("ul4_1x_en_sel", + ul4_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL4), + MT8195_SOC_ENUM_EXT("ul5_1x_en_sel", + ul5_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL5), + MT8195_SOC_ENUM_EXT("ul6_1x_en_sel", + ul6_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL6), + MT8195_SOC_ENUM_EXT("ul8_1x_en_sel", + ul8_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL8), + MT8195_SOC_ENUM_EXT("ul9_1x_en_sel", + ul9_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL9), + MT8195_SOC_ENUM_EXT("ul10_1x_en_sel", + ul10_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_memif_1x_en_sel_put, + MT8195_AFE_MEMIF_UL10), + MT8195_SOC_ENUM_EXT("asys_irq1_1x_en_sel", + asys_irq1_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_13), + MT8195_SOC_ENUM_EXT("asys_irq2_1x_en_sel", + asys_irq2_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_14), + MT8195_SOC_ENUM_EXT("asys_irq3_1x_en_sel", + asys_irq3_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_15), + MT8195_SOC_ENUM_EXT("asys_irq4_1x_en_sel", + asys_irq4_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_16), + MT8195_SOC_ENUM_EXT("asys_irq5_1x_en_sel", + asys_irq5_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_17), + MT8195_SOC_ENUM_EXT("asys_irq6_1x_en_sel", + asys_irq6_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_18), + MT8195_SOC_ENUM_EXT("asys_irq7_1x_en_sel", + asys_irq7_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_19), + MT8195_SOC_ENUM_EXT("asys_irq8_1x_en_sel", + asys_irq8_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_20), + MT8195_SOC_ENUM_EXT("asys_irq9_1x_en_sel", + asys_irq9_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_21), + MT8195_SOC_ENUM_EXT("asys_irq10_1x_en_sel", + asys_irq10_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_22), + MT8195_SOC_ENUM_EXT("asys_irq11_1x_en_sel", + asys_irq11_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_23), + MT8195_SOC_ENUM_EXT("asys_irq12_1x_en_sel", + asys_irq12_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_24), + MT8195_SOC_ENUM_EXT("asys_irq13_1x_en_sel", + asys_irq13_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_25), + MT8195_SOC_ENUM_EXT("asys_irq14_1x_en_sel", + asys_irq14_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_26), + MT8195_SOC_ENUM_EXT("asys_irq15_1x_en_sel", + asys_irq15_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_27), + MT8195_SOC_ENUM_EXT("asys_irq16_1x_en_sel", + asys_irq16_1x_en_sel_enum, + snd_soc_get_enum_double, + mt8195_asys_irq_1x_en_sel_put, + MT8195_AFE_IRQ_28), +}; + +static const struct snd_soc_component_driver mt8195_afe_pcm_dai_component = { + .name = "mt8195-afe-pcm-dai", +}; + +static const struct mtk_base_memif_data memif_data[MT8195_AFE_MEMIF_NUM] = { + [MT8195_AFE_MEMIF_DL2] = { + .name = "DL2", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_DL3] = { + .name = "DL3", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_DL6] = { + .name = "DL6", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_DL7] = { + .name = "DL7", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_DL8] = { + .name = "DL8", + .id = MT8195_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 = -1, + .agent_disable_shift = 0, + .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, + }, + [MT8195_AFE_MEMIF_DL10] = { + .name = "DL10", + .id = MT8195_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 = -1, + .agent_disable_shift = 0, + .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, + }, + [MT8195_AFE_MEMIF_DL11] = { + .name = "DL11", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL1] = { + .name = "UL1", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL2] = { + .name = "UL2", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL3] = { + .name = "UL3", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL4] = { + .name = "UL4", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL5] = { + .name = "UL5", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL6] = { + .name = "UL6", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL8] = { + .name = "UL8", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL9] = { + .name = "UL9", + .id = MT8195_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, + }, + [MT8195_AFE_MEMIF_UL10] = { + .name = "UL10", + .id = MT8195_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[MT8195_AFE_IRQ_NUM] = { + [MT8195_AFE_IRQ_1] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_2] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_3] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_8] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_9] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_10] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_13] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_14] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_15] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_16] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_17] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_18] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_19] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_20] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_21] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_22] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_23] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_24] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_25] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_26] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_27] = { + .id = MT8195_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, + }, + [MT8195_AFE_IRQ_28] = { + .id = MT8195_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 mt8195_afe_memif_const_irqs[MT8195_AFE_MEMIF_NUM] = { + [MT8195_AFE_MEMIF_DL2] = MT8195_AFE_IRQ_13, + [MT8195_AFE_MEMIF_DL3] = MT8195_AFE_IRQ_14, + [MT8195_AFE_MEMIF_DL6] = MT8195_AFE_IRQ_15, + [MT8195_AFE_MEMIF_DL7] = MT8195_AFE_IRQ_1, + [MT8195_AFE_MEMIF_DL8] = MT8195_AFE_IRQ_16, + [MT8195_AFE_MEMIF_DL10] = MT8195_AFE_IRQ_17, + [MT8195_AFE_MEMIF_DL11] = MT8195_AFE_IRQ_18, + [MT8195_AFE_MEMIF_UL1] = MT8195_AFE_IRQ_3, + [MT8195_AFE_MEMIF_UL2] = MT8195_AFE_IRQ_19, + [MT8195_AFE_MEMIF_UL3] = MT8195_AFE_IRQ_20, + [MT8195_AFE_MEMIF_UL4] = MT8195_AFE_IRQ_21, + [MT8195_AFE_MEMIF_UL5] = MT8195_AFE_IRQ_22, + [MT8195_AFE_MEMIF_UL6] = MT8195_AFE_IRQ_9, + [MT8195_AFE_MEMIF_UL8] = MT8195_AFE_IRQ_23, + [MT8195_AFE_MEMIF_UL9] = MT8195_AFE_IRQ_24, + [MT8195_AFE_MEMIF_UL10] = MT8195_AFE_IRQ_25, +}; + +static bool mt8195_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 AFE_APLL_TUNER_CFG: + case AFE_APLL_TUNER_CFG1: + 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_SPDIFIN_APLL_TUNER_CFG: + 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: + case AFE_GASRC12_NEW_CON8: + case AFE_GASRC12_NEW_CON9: + case AFE_GASRC12_NEW_CON12: + case AFE_GASRC13_NEW_CON8: + case AFE_GASRC13_NEW_CON9: + case AFE_GASRC13_NEW_CON12: + case AFE_GASRC14_NEW_CON8: + case AFE_GASRC14_NEW_CON9: + case AFE_GASRC14_NEW_CON12: + case AFE_GASRC15_NEW_CON8: + case AFE_GASRC15_NEW_CON9: + case AFE_GASRC15_NEW_CON12: + case AFE_GASRC16_NEW_CON8: + case AFE_GASRC16_NEW_CON9: + case AFE_GASRC16_NEW_CON12: + case AFE_GASRC17_NEW_CON8: + case AFE_GASRC17_NEW_CON9: + case AFE_GASRC17_NEW_CON12: + case AFE_GASRC18_NEW_CON8: + case AFE_GASRC18_NEW_CON9: + case AFE_GASRC18_NEW_CON12: + case AFE_GASRC19_NEW_CON8: + case AFE_GASRC19_NEW_CON9: + case AFE_GASRC19_NEW_CON12: + return true; + default: + return false; + }; +} + +static const struct regmap_config mt8195_afe_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .volatile_reg = mt8195_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 mt8195_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_info(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_info(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 < MT8195_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 mt8195_afe_runtime_suspend(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + + if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl) + goto skip_regmap; + + mt8195_afe_disable_main_clock(afe); + + regcache_cache_only(afe->regmap, true); + regcache_mark_dirty(afe->regmap); + +skip_regmap: + mt8195_afe_disable_reg_rw_clk(afe); + + return 0; +} + +static int mt8195_afe_runtime_resume(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + + mt8195_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); + + mt8195_afe_enable_main_clock(afe); +skip_regmap: + return 0; +} + +static int mt8195_afe_component_probe(struct snd_soc_component *component) +{ + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + int ret = 0; + + 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 mt8195_afe_component = { + .name = AFE_PCM_NAME, + .pointer = mtk_afe_pcm_pointer, + .pcm_construct = mtk_afe_pcm_new, + .probe = mt8195_afe_component_probe, +}; + +static int init_memif_priv_data(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_memif_priv *memif_priv; + int i; + + for (i = MT8195_AFE_MEMIF_START; i < MT8195_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 mt8195_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 = mt8195_memif_dai_driver; + dai->num_dai_drivers = ARRAY_SIZE(mt8195_memif_dai_driver); + + dai->dapm_widgets = mt8195_memif_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mt8195_memif_widgets); + dai->dapm_routes = mt8195_memif_routes; + dai->num_dapm_routes = ARRAY_SIZE(mt8195_memif_routes); + dai->controls = mt8195_memif_controls; + dai->num_controls = ARRAY_SIZE(mt8195_memif_controls); + + return init_memif_priv_data(afe); +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = { + mt8195_dai_adda_register, + mt8195_dai_etdm_register, + mt8195_dai_pcm_register, + mt8195_dai_memif_register, +}; + +static const struct reg_sequence mt8195_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 mt8195_cg_patch[] = { + { AUDIO_TOP_CON0, 0xfffffffb }, + { AUDIO_TOP_CON1, 0xfffffffa }, +}; + +static int mt8195_afe_init_registers(struct mtk_base_afe *afe) +{ + return regmap_multi_reg_write(afe->regmap, + mt8195_afe_reg_defaults, + ARRAY_SIZE(mt8195_afe_reg_defaults)); +} + +static void mt8195_afe_parse_of(struct mtk_base_afe *afe, + struct device_node *np) +{ +#if IS_ENABLED(CONFIG_SND_SOC_MT6359) + struct mt8195_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)) { + dev_info(afe->dev, "%s() Cannot find topckgen controller: %ld\n", + __func__, PTR_ERR(afe_priv->topckgen)); + } +#endif +} + +static int mt8195_afe_pcm_dev_probe(struct platform_device *pdev) +{ + struct mtk_base_afe *afe; + struct mt8195_afe_private *afe_priv; + struct resource *res; + struct device *dev = &pdev->dev; + int i, irq_id, ret; + struct snd_soc_component *component; + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(33)); + if (ret) + return ret; + + afe = devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + + afe->platform_priv = devm_kzalloc(dev, sizeof(*afe_priv), + GFP_KERNEL); + if (!afe->platform_priv) + return -ENOMEM; + + afe_priv = afe->platform_priv; + afe->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + afe->base_addr = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); + + /* initial audio related clock */ + ret = mt8195_afe_init_clock(afe); + if (ret) { + dev_err(dev, "init clock error\n"); + return ret; + } + + spin_lock_init(&afe_priv->afe_ctrl_lock); + + mutex_init(&afe->irq_alloc_lock); + + /* irq initialize */ + afe->irqs_size = MT8195_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 = MT8195_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 = mt8195_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) { + dev_err(dev, "%s no irq found\n", dev->of_node->name); + return -ENXIO; + } + + ret = devm_request_irq(dev, irq_id, mt8195_afe_irq_handler, + IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); + if (ret) { + dev_err(dev, "could not request_irq for asys-isr\n"); + return ret; + } + + /* 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) { + dev_warn(dev, "dai register i %d fail, ret %d\n", + i, ret); + return ret; + } + } + + /* init dai_driver and component_driver */ + ret = mtk_afe_combine_sub_dai(afe); + if (ret) { + dev_warn(dev, "mtk_afe_combine_sub_dai fail, ret %d\n", + ret); + return ret; + } + + afe->mtk_afe_hardware = &mt8195_afe_hardware; + afe->memif_fs = mt8195_memif_fs; + afe->irq_fs = mt8195_irq_fs; + + afe->runtime_resume = mt8195_afe_runtime_resume; + afe->runtime_suspend = mt8195_afe_runtime_suspend; + + platform_set_drvdata(pdev, afe); + + mt8195_afe_parse_of(afe, pdev->dev.of_node); + + pm_runtime_enable(dev); + if (!pm_runtime_enabled(dev)) { + ret = mt8195_afe_runtime_resume(dev); + if (ret) + return ret; + } + + /* enable clock for regcache get default value from hw */ + afe_priv->pm_runtime_bypass_reg_ctl = true; + pm_runtime_get_sync(dev); + + afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, + &mt8195_afe_regmap_config); + if (IS_ERR(afe->regmap)) { + ret = PTR_ERR(afe->regmap); + goto err_pm_put; + } + + ret = regmap_register_patch(afe->regmap, mt8195_cg_patch, + ARRAY_SIZE(mt8195_cg_patch)); + if (ret < 0) { + dev_err(dev, "Failed to apply cg patch\n"); + goto err_pm_put; + } + + /* register component */ + ret = devm_snd_soc_register_component(dev, &mt8195_afe_component, + NULL, 0); + if (ret) { + dev_warn(dev, "err_platform\n"); + goto err_pm_put; + } + + component = devm_kzalloc(dev, sizeof(*component), GFP_KERNEL); + if (!component) { + ret = -ENOMEM; + goto err_pm_put; + } + + ret = snd_soc_component_initialize(component, + &mt8195_afe_pcm_dai_component, + 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_dai_component\n"); + goto err_pm_put; + } + + mt8195_afe_init_registers(afe); + + pm_runtime_put_sync(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); + pm_runtime_disable(dev); + + return ret; +} + +static int mt8195_afe_pcm_dev_remove(struct platform_device *pdev) +{ + struct mtk_base_afe *afe = platform_get_drvdata(pdev); + + snd_soc_unregister_component(&pdev->dev); + + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + mt8195_afe_runtime_suspend(&pdev->dev); + + mt8195_afe_deinit_clock(afe); + return 0; +} + +static const struct of_device_id mt8195_afe_pcm_dt_match[] = { + {.compatible = "mediatek,mt8195-audio", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt8195_afe_pcm_dt_match); + +static const struct dev_pm_ops mt8195_afe_pm_ops = { + SET_RUNTIME_PM_OPS(mt8195_afe_runtime_suspend, + mt8195_afe_runtime_resume, NULL) +}; + +static struct platform_driver mt8195_afe_pcm_driver = { + .driver = { + .name = "mt8195-audio", + .of_match_table = mt8195_afe_pcm_dt_match, +#ifdef CONFIG_PM + .pm = &mt8195_afe_pm_ops, +#endif + }, + .probe = mt8195_afe_pcm_dev_probe, + .remove = mt8195_afe_pcm_dev_remove, +}; + +module_platform_driver(mt8195_afe_pcm_driver); + +MODULE_DESCRIPTION("Mediatek ALSA SoC AFE platform driver for 8195"); +MODULE_AUTHOR("Bicycle Tsai "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/mediatek/mt8195/mt8195-reg.h b/sound/soc/mediatek/mt8195/mt8195-reg.h new file mode 100644 index 00000000000000..d06f9cf85a4ecc --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-reg.h @@ -0,0 +1,2796 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-reg.h -- Mediatek 8195 audio driver reg definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#ifndef _MT8195_REG_H_ +#define _MT8195_REG_H_ + +#define AFE_SRAM_BASE (0x10880000) +#define AFE_SRAM_SIZE (0x10000) + +#define AUDIO_TOP_CON0 (0x0000) +#define AUDIO_TOP_CON1 (0x0004) +#define AUDIO_TOP_CON2 (0x0008) +#define AUDIO_TOP_CON3 (0x000c) +#define AUDIO_TOP_CON4 (0x0010) +#define AUDIO_TOP_CON5 (0x0014) +#define AUDIO_TOP_CON6 (0x0018) +#define AFE_MAS_HADDR_MSB (0x0020) +#define PWR1_ASM_CON1 (0x0108) +#define ASYS_IRQ_CONFIG (0x0110) +#define ASYS_IRQ1_CON (0x0114) +#define ASYS_IRQ2_CON (0x0118) +#define ASYS_IRQ3_CON (0x011c) +#define ASYS_IRQ4_CON (0x0120) +#define ASYS_IRQ5_CON (0x0124) +#define ASYS_IRQ6_CON (0x0128) +#define ASYS_IRQ7_CON (0x012c) +#define ASYS_IRQ8_CON (0x0130) +#define ASYS_IRQ9_CON (0x0134) +#define ASYS_IRQ10_CON (0x0138) +#define ASYS_IRQ11_CON (0x013c) +#define ASYS_IRQ12_CON (0x0140) +#define ASYS_IRQ13_CON (0x0144) +#define ASYS_IRQ14_CON (0x0148) +#define ASYS_IRQ15_CON (0x014c) +#define ASYS_IRQ16_CON (0x0150) +#define ASYS_IRQ_CLR (0x0154) +#define ASYS_IRQ_STATUS (0x0158) +#define ASYS_IRQ_MON1 (0x015c) +#define ASYS_IRQ_MON2 (0x0160) +#define AFE_IRQ1_CON (0x0164) +#define AFE_IRQ2_CON (0x0168) +#define AFE_IRQ3_CON (0x016c) +#define AFE_IRQ_MCU_CLR (0x0170) +#define AFE_IRQ_STATUS (0x0174) +#define AFE_IRQ_MASK (0x0178) +#define ASYS_IRQ_MASK (0x017c) +#define AFE_IRQ3_CON_MON (0x01b0) +#define AFE_IRQ_MCU_MON2 (0x01b4) +#define AFE_IRQ8_CON (0x01b8) +#define AFE_IRQ9_CON (0x01bc) +#define AFE_IRQ10_CON (0x01c0) +#define AFE_IRQ9_CON_MON (0x01c4) +#define ADSP_IRQ_MASK (0x01c8) +#define ADSP_IRQ_STATUS (0x01cc) +#define AFE_SINEGEN_CON0 (0x01f0) +#define AFE_SINEGEN_CON1 (0x01f4) +#define AFE_SINEGEN_CON2 (0x01f8) +#define AFE_SINEGEN_CON3 (0x01fc) +#define AFE_SPDIF_OUT_CON0 (0x0380) +#define AFE_TDMOUT_CONN0 (0x0390) +#define PWR1_ASM_CON2 (0x03b0) +#define PWR1_ASM_CON3 (0x03b4) +#define PWR1_ASM_CON4 (0x03b8) +#define AFE_APLL_TUNER_CFG (0x03f8) +#define AFE_APLL_TUNER_CFG1 (0x03fc) +#define AUDIO_TOP_STA0 (0x0400) +#define AUDIO_TOP_STA1 (0x0404) +#define AFE_GAIN1_CON0 (0x0410) +#define AFE_GAIN1_CON1 (0x0414) +#define AFE_GAIN1_CON2 (0x0418) +#define AFE_GAIN1_CON3 (0x041c) +#define AFE_GAIN1_CUR (0x0424) +#define AFE_GAIN2_CON0 (0x0428) +#define AFE_GAIN2_CON1 (0x042c) +#define AFE_GAIN2_CON2 (0x0430) +#define AFE_GAIN2_CON3 (0x0434) +#define AFE_GAIN2_CUR (0x043c) +#define AFE_IEC_CFG (0x0480) +#define AFE_IEC_NSNUM (0x0484) +#define AFE_IEC_BURST_INFO (0x0488) +#define AFE_IEC_BURST_LEN (0x048c) +#define AFE_IEC_NSADR (0x0490) +#define AFE_IEC_CHL_STAT0 (0x04a0) +#define AFE_IEC_CHL_STAT1 (0x04a4) +#define AFE_IEC_CHR_STAT0 (0x04a8) +#define AFE_IEC_CHR_STAT1 (0x04ac) +#define AFE_SPDIFIN_CFG0 (0x0500) +#define AFE_SPDIFIN_CFG1 (0x0504) +#define AFE_SPDIFIN_CHSTS1 (0x0508) +#define AFE_SPDIFIN_CHSTS2 (0x050c) +#define AFE_SPDIFIN_CHSTS3 (0x0510) +#define AFE_SPDIFIN_CHSTS4 (0x0514) +#define AFE_SPDIFIN_CHSTS5 (0x0518) +#define AFE_SPDIFIN_CHSTS6 (0x051c) +#define AFE_SPDIFIN_DEBUG1 (0x0520) +#define AFE_SPDIFIN_DEBUG2 (0x0524) +#define AFE_SPDIFIN_DEBUG3 (0x0528) +#define AFE_SPDIFIN_DEBUG4 (0x052c) +#define AFE_SPDIFIN_EC (0x0530) +#define AFE_SPDIFIN_CKLOCK_CFG (0x0534) +#define AFE_SPDIFIN_BR (0x053c) +#define AFE_SPDIFIN_BR_DBG1 (0x0540) +#define AFE_SPDIFIN_CKFBDIV (0x0544) +#define AFE_SPDIFIN_INT_EXT (0x0548) +#define AFE_SPDIFIN_INT_EXT2 (0x054c) +#define SPDIFIN_FREQ_INFO (0x0550) +#define SPDIFIN_FREQ_INFO_2 (0x0554) +#define SPDIFIN_FREQ_INFO_3 (0x0558) +#define SPDIFIN_FREQ_STATUS (0x055c) +#define SPDIFIN_USERCODE1 (0x0560) +#define SPDIFIN_USERCODE2 (0x0564) +#define SPDIFIN_USERCODE3 (0x0568) +#define SPDIFIN_USERCODE4 (0x056c) +#define SPDIFIN_USERCODE5 (0x0570) +#define SPDIFIN_USERCODE6 (0x0574) +#define SPDIFIN_USERCODE7 (0x0578) +#define SPDIFIN_USERCODE8 (0x057c) +#define SPDIFIN_USERCODE9 (0x0580) +#define SPDIFIN_USERCODE10 (0x0584) +#define SPDIFIN_USERCODE11 (0x0588) +#define SPDIFIN_USERCODE12 (0x058c) +#define AFE_SPDIFIN_APLL_TUNER_CFG (0x0594) +#define AFE_SPDIFIN_APLL_TUNER_CFG1 (0x0598) +#define ASYS_TOP_CON (0x0600) +#define AFE_LINEIN_APLL_TUNER_CFG (0x0610) +#define AFE_LINEIN_APLL_TUNER_MON (0x0614) +#define AFE_EARC_APLL_TUNER_CFG (0x0618) +#define AFE_EARC_APLL_TUNER_MON (0x061c) +#define PWR2_TOP_CON0 (0x0634) +#define PWR2_TOP_CON1 (0x0638) +#define PCM_INTF_CON1 (0x063c) +#define PCM_INTF_CON2 (0x0640) +#define AFE_CM0_CON (0x0660) +#define AFE_CM1_CON (0x0664) +#define AFE_CM2_CON (0x0668) +#define AFE_CM0_MON (0x0670) +#define AFE_CM1_MON (0x0674) +#define AFE_CM2_MON (0x0678) +#define AFE_MPHONE_MULTI_CON0 (0x06a4) +#define AFE_MPHONE_MULTI_CON1 (0x06a8) +#define AFE_MPHONE_MULTI_CON2 (0x06ac) +#define AFE_MPHONE_MULTI_MON (0x06b0) +#define AFE_MPHONE_MULTI_DET_REG_CON0 (0x06b4) +#define AFE_MPHONE_MULTI_DET_REG_CON1 (0x06b8) +#define AFE_MPHONE_MULTI_DET_REG_CON2 (0x06bc) +#define AFE_MPHONE_MULTI_DET_REG_CON3 (0x06c0) +#define AFE_MPHONE_MULTI_DET_MON0 (0x06c4) +#define AFE_MPHONE_MULTI_DET_MON1 (0x06c8) +#define AFE_MPHONE_MULTI_DET_MON2 (0x06d0) +#define AFE_MPHONE_MULTI2_CON0 (0x06d4) +#define AFE_MPHONE_MULTI2_CON1 (0x06d8) +#define AFE_MPHONE_MULTI2_CON2 (0x06dc) +#define AFE_MPHONE_MULTI2_MON (0x06e0) +#define AFE_MPHONE_MULTI2_DET_REG_CON0 (0x06e4) +#define AFE_MPHONE_MULTI2_DET_REG_CON1 (0x06e8) +#define AFE_MPHONE_MULTI2_DET_REG_CON2 (0x06ec) +#define AFE_MPHONE_MULTI2_DET_REG_CON3 (0x06f0) +#define AFE_MPHONE_MULTI2_DET_MON0 (0x06f4) +#define AFE_MPHONE_MULTI2_DET_MON1 (0x06f8) +#define AFE_MPHONE_MULTI2_DET_MON2 (0x06fc) +#define AFE_ADDA_IIR_COEF_02_01 (0x0700) +#define AFE_ADDA_IIR_COEF_04_03 (0x0704) +#define AFE_ADDA_IIR_COEF_06_05 (0x0708) +#define AFE_ADDA_IIR_COEF_08_07 (0x070c) +#define AFE_ADDA_IIR_COEF_10_09 (0x0710) +#define AFE_ADDA_ULCF_CFG_02_01 (0x0714) +#define AFE_ADDA_ULCF_CFG_04_03 (0x0718) +#define AFE_ADDA_ULCF_CFG_06_05 (0x071c) +#define AFE_ADDA_ULCF_CFG_08_07 (0x0720) +#define AFE_ADDA_ULCF_CFG_10_09 (0x0724) +#define AFE_ADDA_ULCF_CFG_12_11 (0x0728) +#define AFE_ADDA_ULCF_CFG_14_13 (0x072c) +#define AFE_ADDA_ULCF_CFG_16_15 (0x0730) +#define AFE_ADDA_ULCF_CFG_18_17 (0x0734) +#define AFE_ADDA_ULCF_CFG_20_19 (0x0738) +#define AFE_ADDA_ULCF_CFG_22_21 (0x073c) +#define AFE_ADDA_ULCF_CFG_24_23 (0x0740) +#define AFE_ADDA_ULCF_CFG_26_25 (0x0744) +#define AFE_ADDA_ULCF_CFG_28_27 (0x0748) +#define AFE_ADDA_ULCF_CFG_30_29 (0x074c) +#define AFE_ADDA6_IIR_COEF_02_01 (0x0750) +#define AFE_ADDA6_IIR_COEF_04_03 (0x0754) +#define AFE_ADDA6_IIR_COEF_06_05 (0x0758) +#define AFE_ADDA6_IIR_COEF_08_07 (0x075c) +#define AFE_ADDA6_IIR_COEF_10_09 (0x0760) +#define AFE_ADDA6_ULCF_CFG_02_01 (0x0764) +#define AFE_ADDA6_ULCF_CFG_04_03 (0x0768) +#define AFE_ADDA6_ULCF_CFG_06_05 (0x076c) +#define AFE_ADDA6_ULCF_CFG_08_07 (0x0770) +#define AFE_ADDA6_ULCF_CFG_10_09 (0x0774) +#define AFE_ADDA6_ULCF_CFG_12_11 (0x0778) +#define AFE_ADDA6_ULCF_CFG_14_13 (0x077c) +#define AFE_ADDA6_ULCF_CFG_16_15 (0x0780) +#define AFE_ADDA6_ULCF_CFG_18_17 (0x0784) +#define AFE_ADDA6_ULCF_CFG_20_19 (0x0788) +#define AFE_ADDA6_ULCF_CFG_22_21 (0x078c) +#define AFE_ADDA6_ULCF_CFG_24_23 (0x0790) +#define AFE_ADDA6_ULCF_CFG_26_25 (0x0794) +#define AFE_ADDA6_ULCF_CFG_28_27 (0x0798) +#define AFE_ADDA6_ULCF_CFG_30_29 (0x079c) +#define AFE_ADDA_MTKAIF_CFG0 (0x07a0) +#define AFE_ADDA_MTKAIF_SYNCWORD_CFG (0x07a8) +#define AFE_ADDA_MTKAIF_RX_CFG0 (0x07b4) +#define AFE_ADDA_MTKAIF_RX_CFG1 (0x07b8) +#define AFE_ADDA_MTKAIF_RX_CFG2 (0x07bc) +#define AFE_ADDA_MTKAIF_MON0 (0x07c8) +#define AFE_ADDA_MTKAIF_MON1 (0x07cc) +#define AFE_AUD_PAD_TOP (0x07d4) +#define AFE_ADDA6_MTKAIF_MON0 (0x07d8) +#define AFE_ADDA6_MTKAIF_MON1 (0x07dc) +#define AFE_ADDA6_MTKAIF_CFG0 (0x07e0) +#define AFE_ADDA6_MTKAIF_RX_CFG0 (0x07e4) +#define AFE_ADDA6_MTKAIF_RX_CFG1 (0x07e8) +#define AFE_ADDA6_MTKAIF_RX_CFG2 (0x07ec) +#define AFE_ADDA6_TOP_CON0 (0x07f0) +#define AFE_ADDA6_UL_SRC_CON0 (0x07f4) +#define AFE_ADDA6_UL_SRC_CON1 (0x07f8) +#define AFE_ADDA6_SRC_DEBUG (0x0800) +#define AFE_ADDA6_SRC_DEBUG_MON0 (0x0804) +#define AFE_ADDA6_UL_SRC_MON0 (0x0818) +#define AFE_ADDA6_UL_SRC_MON1 (0x081c) +#define AFE_CONN0_5 (0x0830) +#define AFE_CONN1_5 (0x0834) +#define AFE_CONN2_5 (0x0838) +#define AFE_CONN3_5 (0x083c) +#define AFE_CONN4_5 (0x0840) +#define AFE_CONN5_5 (0x0844) +#define AFE_CONN6_5 (0x0848) +#define AFE_CONN7_5 (0x084c) +#define AFE_CONN8_5 (0x0850) +#define AFE_CONN9_5 (0x0854) +#define AFE_CONN10_5 (0x0858) +#define AFE_CONN11_5 (0x085c) +#define AFE_CONN12_5 (0x0860) +#define AFE_CONN13_5 (0x0864) +#define AFE_CONN14_5 (0x0868) +#define AFE_CONN15_5 (0x086c) +#define AFE_CONN16_5 (0x0870) +#define AFE_CONN17_5 (0x0874) +#define AFE_CONN18_5 (0x0878) +#define AFE_CONN19_5 (0x087c) +#define AFE_CONN20_5 (0x0880) +#define AFE_CONN21_5 (0x0884) +#define AFE_CONN22_5 (0x0888) +#define AFE_CONN23_5 (0x088c) +#define AFE_CONN24_5 (0x0890) +#define AFE_CONN25_5 (0x0894) +#define AFE_CONN26_5 (0x0898) +#define AFE_CONN27_5 (0x089c) +#define AFE_CONN28_5 (0x08a0) +#define AFE_CONN29_5 (0x08a4) +#define AFE_CONN30_5 (0x08a8) +#define AFE_CONN31_5 (0x08ac) +#define AFE_CONN32_5 (0x08b0) +#define AFE_CONN33_5 (0x08b4) +#define AFE_CONN34_5 (0x08b8) +#define AFE_CONN35_5 (0x08bc) +#define AFE_CONN36_5 (0x08c0) +#define AFE_CONN37_5 (0x08c4) +#define AFE_CONN38_5 (0x08c8) +#define AFE_CONN39_5 (0x08cc) +#define AFE_CONN40_5 (0x08d0) +#define AFE_CONN41_5 (0x08d4) +#define AFE_CONN42_5 (0x08d8) +#define AFE_CONN43_5 (0x08dc) +#define AFE_CONN44_5 (0x08e0) +#define AFE_CONN45_5 (0x08e4) +#define AFE_CONN46_5 (0x08e8) +#define AFE_CONN47_5 (0x08ec) +#define AFE_CONN48_5 (0x08f0) +#define AFE_CONN49_5 (0x08f4) +#define AFE_CONN50_5 (0x08f8) +#define AFE_CONN51_5 (0x08fc) +#define AFE_CONN52_5 (0x0900) +#define AFE_CONN53_5 (0x0904) +#define AFE_CONN54_5 (0x0908) +#define AFE_CONN55_5 (0x090c) +#define AFE_CONN56_5 (0x0910) +#define AFE_CONN57_5 (0x0914) +#define AFE_CONN58_5 (0x0918) +#define AFE_CONN59_5 (0x091c) +#define AFE_CONN60_5 (0x0920) +#define AFE_CONN61_5 (0x0924) +#define AFE_CONN62_5 (0x0928) +#define AFE_CONN63_5 (0x092c) +#define AFE_CONN64_5 (0x0930) +#define AFE_CONN65_5 (0x0934) +#define AFE_CONN66_5 (0x0938) +#define AFE_CONN67_5 (0x093c) +#define AFE_CONN68_5 (0x0940) +#define AFE_CONN69_5 (0x0944) +#define AFE_CONN70_5 (0x0948) +#define AFE_CONN71_5 (0x094c) +#define AFE_CONN72_5 (0x0950) +#define AFE_CONN73_5 (0x0954) +#define AFE_CONN74_5 (0x0958) +#define AFE_CONN75_5 (0x095c) +#define AFE_CONN76_5 (0x0960) +#define AFE_CONN77_5 (0x0964) +#define AFE_CONN78_5 (0x0968) +#define AFE_CONN79_5 (0x096c) +#define AFE_CONN80_5 (0x0970) +#define AFE_CONN81_5 (0x0974) +#define AFE_CONN82_5 (0x0978) +#define AFE_CONN83_5 (0x097c) +#define AFE_CONN84_5 (0x0980) +#define AFE_CONN85_5 (0x0984) +#define AFE_CONN86_5 (0x0988) +#define AFE_CONN87_5 (0x098c) +#define AFE_CONN88_5 (0x0990) +#define AFE_CONN89_5 (0x0994) +#define AFE_CONN90_5 (0x0998) +#define AFE_CONN91_5 (0x099c) +#define AFE_CONN92_5 (0x09a0) +#define AFE_CONN93_5 (0x09a4) +#define AFE_CONN94_5 (0x09a8) +#define AFE_CONN95_5 (0x09ac) +#define AFE_CONN96_5 (0x09b0) +#define AFE_CONN97_5 (0x09b4) +#define AFE_CONN98_5 (0x09b8) +#define AFE_CONN99_5 (0x09bc) +#define AFE_CONN100_5 (0x09c0) +#define AFE_CONN101_5 (0x09c4) +#define AFE_CONN102_5 (0x09c8) +#define AFE_CONN103_5 (0x09cc) +#define AFE_CONN104_5 (0x09d0) +#define AFE_CONN105_5 (0x09d4) +#define AFE_CONN106_5 (0x09d8) +#define AFE_CONN107_5 (0x09dc) +#define AFE_CONN108_5 (0x09e0) +#define AFE_CONN109_5 (0x09e4) +#define AFE_CONN110_5 (0x09e8) +#define AFE_CONN111_5 (0x09ec) +#define AFE_CONN112_5 (0x09f0) +#define AFE_CONN113_5 (0x09f4) +#define AFE_CONN114_5 (0x09f8) +#define AFE_CONN115_5 (0x09fc) +#define AFE_CONN116_5 (0x0a00) +#define AFE_CONN117_5 (0x0a04) +#define AFE_CONN118_5 (0x0a08) +#define AFE_CONN119_5 (0x0a0c) +#define AFE_CONN120_5 (0x0a10) +#define AFE_CONN121_5 (0x0a14) +#define AFE_CONN122_5 (0x0a18) +#define AFE_CONN123_5 (0x0a1c) +#define AFE_CONN124_5 (0x0a20) +#define AFE_CONN125_5 (0x0a24) +#define AFE_CONN126_5 (0x0a28) +#define AFE_CONN127_5 (0x0a2c) +#define AFE_CONN128_5 (0x0a30) +#define AFE_CONN129_5 (0x0a34) +#define AFE_CONN130_5 (0x0a38) +#define AFE_CONN131_5 (0x0a3c) +#define AFE_CONN132_5 (0x0a40) +#define AFE_CONN133_5 (0x0a44) +#define AFE_CONN134_5 (0x0a48) +#define AFE_CONN135_5 (0x0a4c) +#define AFE_CONN136_5 (0x0a50) +#define AFE_CONN137_5 (0x0a54) +#define AFE_CONN138_5 (0x0a58) +#define AFE_CONN139_5 (0x0a5c) +#define AFE_CONN_RS_5 (0x0a60) +#define AFE_CONN_DI_5 (0x0a64) +#define AFE_CONN_16BIT_5 (0x0a68) +#define AFE_CONN_24BIT_5 (0x0a6c) +#define AFE_ASRC11_NEW_CON0 (0x0d80) +#define AFE_ASRC11_NEW_CON1 (0x0d84) +#define AFE_ASRC11_NEW_CON2 (0x0d88) +#define AFE_ASRC11_NEW_CON3 (0x0d8c) +#define AFE_ASRC11_NEW_CON4 (0x0d90) +#define AFE_ASRC11_NEW_CON5 (0x0d94) +#define AFE_ASRC11_NEW_CON6 (0x0d98) +#define AFE_ASRC11_NEW_CON7 (0x0d9c) +#define AFE_ASRC11_NEW_CON8 (0x0da0) +#define AFE_ASRC11_NEW_CON9 (0x0da4) +#define AFE_ASRC11_NEW_CON10 (0x0da8) +#define AFE_ASRC11_NEW_CON11 (0x0dac) +#define AFE_ASRC11_NEW_CON13 (0x0db4) +#define AFE_ASRC11_NEW_CON14 (0x0db8) +#define AFE_ASRC12_NEW_CON0 (0x0dc0) +#define AFE_ASRC12_NEW_CON1 (0x0dc4) +#define AFE_ASRC12_NEW_CON2 (0x0dc8) +#define AFE_ASRC12_NEW_CON3 (0x0dcc) +#define AFE_ASRC12_NEW_CON4 (0x0dd0) +#define AFE_ASRC12_NEW_CON5 (0x0dd4) +#define AFE_ASRC12_NEW_CON6 (0x0dd8) +#define AFE_ASRC12_NEW_CON7 (0x0ddc) +#define AFE_ASRC12_NEW_CON8 (0x0de0) +#define AFE_ASRC12_NEW_CON9 (0x0de4) +#define AFE_ASRC12_NEW_CON10 (0x0de8) +#define AFE_ASRC12_NEW_CON11 (0x0dec) +#define AFE_ASRC12_NEW_CON13 (0x0df4) +#define AFE_ASRC12_NEW_CON14 (0x0df8) +#define AFE_LRCK_CNT (0x1018) +#define AFE_DAC_CON0 (0x1200) +#define AFE_DAC_CON1 (0x1204) +#define AFE_DAC_CON2 (0x1208) +#define AFE_DAC_MON0 (0x1218) +#define AFE_DL2_BASE (0x1250) +#define AFE_DL2_CUR (0x1254) +#define AFE_DL2_END (0x1258) +#define AFE_DL2_CON0 (0x125c) +#define AFE_DL3_BASE (0x1260) +#define AFE_DL3_CUR (0x1264) +#define AFE_DL3_END (0x1268) +#define AFE_DL3_CON0 (0x126c) +#define AFE_DL6_BASE (0x1290) +#define AFE_DL6_CUR (0x1294) +#define AFE_DL6_END (0x1298) +#define AFE_DL6_CON0 (0x129c) +#define AFE_DL7_BASE (0x12a0) +#define AFE_DL7_CUR (0x12a4) +#define AFE_DL7_END (0x12a8) +#define AFE_DL7_CON0 (0x12ac) +#define AFE_DL8_BASE (0x12b0) +#define AFE_DL8_CUR (0x12b4) +#define AFE_DL8_END (0x12b8) +#define AFE_DL8_CON0 (0x12bc) +#define AFE_DL10_BASE (0x12d0) +#define AFE_DL10_CUR (0x12d4) +#define AFE_DL10_END (0x12d8) +#define AFE_DL10_CON0 (0x12dc) +#define AFE_DL11_BASE (0x12e0) +#define AFE_DL11_CUR (0x12e4) +#define AFE_DL11_END (0x12e8) +#define AFE_DL11_CON0 (0x12ec) +#define AFE_UL1_BASE (0x1300) +#define AFE_UL1_CUR (0x1304) +#define AFE_UL1_END (0x1308) +#define AFE_UL1_CON0 (0x130c) +#define AFE_UL2_BASE (0x1310) +#define AFE_UL2_CUR (0x1314) +#define AFE_UL2_END (0x1318) +#define AFE_UL2_CON0 (0x131c) +#define AFE_UL3_BASE (0x1320) +#define AFE_UL3_CUR (0x1324) +#define AFE_UL3_END (0x1328) +#define AFE_UL3_CON0 (0x132c) +#define AFE_UL4_BASE (0x1330) +#define AFE_UL4_CUR (0x1334) +#define AFE_UL4_END (0x1338) +#define AFE_UL4_CON0 (0x133c) +#define AFE_UL5_BASE (0x1340) +#define AFE_UL5_CUR (0x1344) +#define AFE_UL5_END (0x1348) +#define AFE_UL5_CON0 (0x134c) +#define AFE_UL6_BASE (0x1350) +#define AFE_UL6_CUR (0x1354) +#define AFE_UL6_END (0x1358) +#define AFE_UL6_CON0 (0x135c) +#define AFE_UL8_BASE (0x1370) +#define AFE_UL8_CUR (0x1374) +#define AFE_UL8_END (0x1378) +#define AFE_UL8_CON0 (0x137c) +#define AFE_UL9_BASE (0x1380) +#define AFE_UL9_CUR (0x1384) +#define AFE_UL9_END (0x1388) +#define AFE_UL9_CON0 (0x138c) +#define AFE_UL10_BASE (0x13d0) +#define AFE_UL10_CUR (0x13d4) +#define AFE_UL10_END (0x13d8) +#define AFE_UL10_CON0 (0x13dc) +#define AFE_DL8_CHK_SUM1 (0x1400) +#define AFE_DL8_CHK_SUM2 (0x1404) +#define AFE_DL8_CHK_SUM3 (0x1408) +#define AFE_DL8_CHK_SUM4 (0x140c) +#define AFE_DL8_CHK_SUM5 (0x1410) +#define AFE_DL8_CHK_SUM6 (0x1414) +#define AFE_DL10_CHK_SUM1 (0x1418) +#define AFE_DL10_CHK_SUM2 (0x141c) +#define AFE_DL10_CHK_SUM3 (0x1420) +#define AFE_DL10_CHK_SUM4 (0x1424) +#define AFE_DL10_CHK_SUM5 (0x1428) +#define AFE_DL10_CHK_SUM6 (0x142c) +#define AFE_DL11_CHK_SUM1 (0x1430) +#define AFE_DL11_CHK_SUM2 (0x1434) +#define AFE_DL11_CHK_SUM3 (0x1438) +#define AFE_DL11_CHK_SUM4 (0x143c) +#define AFE_DL11_CHK_SUM5 (0x1440) +#define AFE_DL11_CHK_SUM6 (0x1444) +#define AFE_UL1_CHK_SUM1 (0x1450) +#define AFE_UL1_CHK_SUM2 (0x1454) +#define AFE_UL2_CHK_SUM1 (0x1458) +#define AFE_UL2_CHK_SUM2 (0x145c) +#define AFE_UL3_CHK_SUM1 (0x1460) +#define AFE_UL3_CHK_SUM2 (0x1464) +#define AFE_UL4_CHK_SUM1 (0x1468) +#define AFE_UL4_CHK_SUM2 (0x146c) +#define AFE_UL5_CHK_SUM1 (0x1470) +#define AFE_UL5_CHK_SUM2 (0x1474) +#define AFE_UL6_CHK_SUM1 (0x1478) +#define AFE_UL6_CHK_SUM2 (0x147c) +#define AFE_UL8_CHK_SUM1 (0x1488) +#define AFE_UL8_CHK_SUM2 (0x148c) +#define AFE_DL2_CHK_SUM1 (0x14a0) +#define AFE_DL2_CHK_SUM2 (0x14a4) +#define AFE_DL3_CHK_SUM1 (0x14b0) +#define AFE_DL3_CHK_SUM2 (0x14b4) +#define AFE_DL6_CHK_SUM1 (0x14e0) +#define AFE_DL6_CHK_SUM2 (0x14e4) +#define AFE_DL7_CHK_SUM1 (0x14f0) +#define AFE_DL7_CHK_SUM2 (0x14f4) +#define AFE_UL9_CHK_SUM1 (0x1528) +#define AFE_UL9_CHK_SUM2 (0x152c) +#define AFE_BUS_MON1 (0x1540) +#define UL1_MOD2AGT_CNT_LAT (0x1568) +#define UL2_MOD2AGT_CNT_LAT (0x156c) +#define UL3_MOD2AGT_CNT_LAT (0x1570) +#define UL4_MOD2AGT_CNT_LAT (0x1574) +#define UL5_MOD2AGT_CNT_LAT (0x1578) +#define UL6_MOD2AGT_CNT_LAT (0x157c) +#define UL8_MOD2AGT_CNT_LAT (0x1588) +#define UL9_MOD2AGT_CNT_LAT (0x158c) +#define UL10_MOD2AGT_CNT_LAT (0x1590) +#define AFE_MEMIF_AGENT_FS_CON0 (0x15a0) +#define AFE_MEMIF_AGENT_FS_CON1 (0x15a4) +#define AFE_MEMIF_AGENT_FS_CON2 (0x15a8) +#define AFE_MEMIF_AGENT_FS_CON3 (0x15ac) +#define AFE_MEMIF_BURST_CFG (0x1600) +#define AFE_MEMIF_BUF_FULL_MON (0x1610) +#define AFE_MEMIF_BUF_MON1 (0x161c) +#define AFE_MEMIF_BUF_MON3 (0x1624) +#define AFE_MEMIF_BUF_MON4 (0x1628) +#define AFE_MEMIF_BUF_MON5 (0x162c) +#define AFE_MEMIF_BUF_MON6 (0x1630) +#define AFE_MEMIF_BUF_MON7 (0x1634) +#define AFE_MEMIF_BUF_MON8 (0x1638) +#define AFE_MEMIF_BUF_MON9 (0x163c) +#define AFE_MEMIF_BUF_MON10 (0x1640) +#define DL2_AGENT2MODULE_CNT (0x1678) +#define DL3_AGENT2MODULE_CNT (0x167c) +#define DL6_AGENT2MODULE_CNT (0x1688) +#define DL7_AGENT2MODULE_CNT (0x168c) +#define DL8_AGENT2MODULE_CNT (0x1690) +#define DL10_AGENT2MODULE_CNT (0x1698) +#define DL11_AGENT2MODULE_CNT (0x169c) +#define UL1_MODULE2AGENT_CNT (0x16a0) +#define UL2_MODULE2AGENT_CNT (0x16a4) +#define UL3_MODULE2AGENT_CNT (0x16a8) +#define UL4_MODULE2AGENT_CNT (0x16ac) +#define UL5_MODULE2AGENT_CNT (0x16b0) +#define UL6_MODULE2AGENT_CNT (0x16b4) +#define UL8_MODULE2AGENT_CNT (0x16bc) +#define UL9_MODULE2AGENT_CNT (0x16c0) +#define UL10_MODULE2AGENT_CNT (0x16c4) +#define AFE_SECURE_CON2 (0x1798) +#define AFE_SECURE_CON1 (0x179c) +#define AFE_SECURE_CON (0x17a0) +#define AFE_SRAM_BOUND (0x17a4) +#define AFE_SE_SECURE_CON (0x17a8) +#define AFE_SECURE_MASK_LOOPBACK (0x17bc) +#define AFE_SECURE_SIDEBAND0 (0x1908) +#define AFE_SECURE_SIDEBAND1 (0x190c) +#define AFE_SECURE_SIDEBAND2 (0x1910) +#define AFE_SECURE_SIDEBAND3 (0x1914) +#define AFE_SECURE_MASK_BASE_ADR_MSB (0x1920) +#define AFE_SECURE_MASK_END_ADR_MSB (0x1924) +#define AFE_NORMAL_BASE_ADR_MSB (0x192c) +#define AFE_NORMAL_END_ADR_MSB (0x1930) +#define AFE_SECURE_MASK_LOOPBACK0 (0x1940) +#define AFE_SECURE_MASK_LOOPBACK1 (0x1944) +#define AFE_SECURE_MASK_LOOPBACK2 (0x1948) +#define AFE_LOOPBACK_CFG0 (0x1950) +#define AFE_LOOPBACK_CFG1 (0x1954) +#define AFE_LOOPBACK_CFG2 (0x1958) +#define AFE_DMIC0_UL_SRC_CON0 (0x1a00) +#define AFE_DMIC0_UL_SRC_CON1 (0x1a04) +#define AFE_DMIC0_SRC_DEBUG (0x1a08) +#define AFE_DMIC0_SRC_DEBUG_MON0 (0x1a0c) +#define AFE_DMIC0_UL_SRC_MON0 (0x1a10) +#define AFE_DMIC0_UL_SRC_MON1 (0x1a14) +#define AFE_DMIC0_IIR_COEF_02_01 (0x1a18) +#define AFE_DMIC0_IIR_COEF_04_03 (0x1a1c) +#define AFE_DMIC0_IIR_COEF_06_05 (0x1a20) +#define AFE_DMIC0_IIR_COEF_08_07 (0x1a24) +#define AFE_DMIC0_IIR_COEF_10_09 (0x1a28) +#define AFE_DMIC1_UL_SRC_CON0 (0x1a68) +#define AFE_DMIC1_UL_SRC_CON1 (0x1a6c) +#define AFE_DMIC1_SRC_DEBUG (0x1a70) +#define AFE_DMIC1_SRC_DEBUG_MON0 (0x1a74) +#define AFE_DMIC1_UL_SRC_MON0 (0x1a78) +#define AFE_DMIC1_UL_SRC_MON1 (0x1a7c) +#define AFE_DMIC1_IIR_COEF_02_01 (0x1a80) +#define AFE_DMIC1_IIR_COEF_04_03 (0x1a84) +#define AFE_DMIC1_IIR_COEF_06_05 (0x1a88) +#define AFE_DMIC1_IIR_COEF_08_07 (0x1a8c) +#define AFE_DMIC1_IIR_COEF_10_09 (0x1a90) +#define AFE_DMIC2_UL_SRC_CON0 (0x1ad0) +#define AFE_DMIC2_UL_SRC_CON1 (0x1ad4) +#define AFE_DMIC2_SRC_DEBUG (0x1ad8) +#define AFE_DMIC2_SRC_DEBUG_MON0 (0x1adc) +#define AFE_DMIC2_UL_SRC_MON0 (0x1ae0) +#define AFE_DMIC2_UL_SRC_MON1 (0x1ae4) +#define AFE_DMIC2_IIR_COEF_02_01 (0x1ae8) +#define AFE_DMIC2_IIR_COEF_04_03 (0x1aec) +#define AFE_DMIC2_IIR_COEF_06_05 (0x1af0) +#define AFE_DMIC2_IIR_COEF_08_07 (0x1af4) +#define AFE_DMIC2_IIR_COEF_10_09 (0x1af8) +#define AFE_DMIC3_UL_SRC_CON0 (0x1b38) +#define AFE_DMIC3_UL_SRC_CON1 (0x1b3c) +#define AFE_DMIC3_SRC_DEBUG (0x1b40) +#define AFE_DMIC3_SRC_DEBUG_MON0 (0x1b44) +#define AFE_DMIC3_UL_SRC_MON0 (0x1b48) +#define AFE_DMIC3_UL_SRC_MON1 (0x1b4c) +#define AFE_DMIC3_IIR_COEF_02_01 (0x1b50) +#define AFE_DMIC3_IIR_COEF_04_03 (0x1b54) +#define AFE_DMIC3_IIR_COEF_06_05 (0x1b58) +#define AFE_DMIC3_IIR_COEF_08_07 (0x1b5c) +#define AFE_DMIC3_IIR_COEF_10_09 (0x1b60) +#define DMIC_BYPASS_HW_GAIN (0x1bf0) +#define DMIC_GAIN1_CON0 (0x1c00) +#define DMIC_GAIN1_CON1 (0x1c04) +#define DMIC_GAIN1_CON2 (0x1c08) +#define DMIC_GAIN1_CON3 (0x1c0c) +#define DMIC_GAIN1_CUR (0x1c10) +#define DMIC_GAIN2_CON0 (0x1c20) +#define DMIC_GAIN2_CON1 (0x1c24) +#define DMIC_GAIN2_CON2 (0x1c28) +#define DMIC_GAIN2_CON3 (0x1c2c) +#define DMIC_GAIN2_CUR (0x1c30) +#define DMIC_GAIN3_CON0 (0x1c40) +#define DMIC_GAIN3_CON1 (0x1c44) +#define DMIC_GAIN3_CON2 (0x1c48) +#define DMIC_GAIN3_CON3 (0x1c4c) +#define DMIC_GAIN3_CUR (0x1c50) +#define DMIC_GAIN4_CON0 (0x1c60) +#define DMIC_GAIN4_CON1 (0x1c64) +#define DMIC_GAIN4_CON2 (0x1c68) +#define DMIC_GAIN4_CON3 (0x1c6c) +#define DMIC_GAIN4_CUR (0x1c70) +#define ETDM_OUT1_DSD_FADE_CON (0x2260) +#define ETDM_OUT1_DSD_FADE_CON1 (0x2264) +#define ETDM_OUT3_DSD_FADE_CON (0x2280) +#define ETDM_OUT3_DSD_FADE_CON1 (0x2284) +#define ETDM_IN1_AFIFO_CON (0x2294) +#define ETDM_IN2_AFIFO_CON (0x2298) +#define ETDM_IN1_MONITOR (0x22c0) +#define ETDM_IN2_MONITOR (0x22c4) +#define ETDM_OUT1_MONITOR (0x22d0) +#define ETDM_OUT2_MONITOR (0x22d4) +#define ETDM_OUT3_MONITOR (0x22d8) +#define ETDM_COWORK_SEC_CON0 (0x22e0) +#define ETDM_COWORK_SEC_CON1 (0x22e4) +#define ETDM_COWORK_SEC_CON2 (0x22e8) +#define ETDM_COWORK_SEC_CON3 (0x22ec) +#define ETDM_COWORK_CON0 (0x22f0) +#define ETDM_COWORK_CON1 (0x22f4) +#define ETDM_COWORK_CON2 (0x22f8) +#define ETDM_COWORK_CON3 (0x22fc) +#define ETDM_IN1_CON0 (0x2300) +#define ETDM_IN1_CON1 (0x2304) +#define ETDM_IN1_CON2 (0x2308) +#define ETDM_IN1_CON3 (0x230c) +#define ETDM_IN1_CON4 (0x2310) +#define ETDM_IN1_CON5 (0x2314) +#define ETDM_IN1_CON6 (0x2318) +#define ETDM_IN1_CON7 (0x231c) +#define ETDM_IN2_CON0 (0x2320) +#define ETDM_IN2_CON1 (0x2324) +#define ETDM_IN2_CON2 (0x2328) +#define ETDM_IN2_CON3 (0x232c) +#define ETDM_IN2_CON4 (0x2330) +#define ETDM_IN2_CON5 (0x2334) +#define ETDM_IN2_CON6 (0x2338) +#define ETDM_IN2_CON7 (0x233c) +#define ETDM_OUT1_CON0 (0x2380) +#define ETDM_OUT1_CON1 (0x2384) +#define ETDM_OUT1_CON2 (0x2388) +#define ETDM_OUT1_CON3 (0x238c) +#define ETDM_OUT1_CON4 (0x2390) +#define ETDM_OUT1_CON5 (0x2394) +#define ETDM_OUT1_CON6 (0x2398) +#define ETDM_OUT1_CON7 (0x239c) +#define ETDM_OUT2_CON0 (0x23a0) +#define ETDM_OUT2_CON1 (0x23a4) +#define ETDM_OUT2_CON2 (0x23a8) +#define ETDM_OUT2_CON3 (0x23ac) +#define ETDM_OUT2_CON4 (0x23b0) +#define ETDM_OUT2_CON5 (0x23b4) +#define ETDM_OUT2_CON6 (0x23b8) +#define ETDM_OUT2_CON7 (0x23bc) +#define ETDM_OUT3_CON0 (0x23c0) +#define ETDM_OUT3_CON1 (0x23c4) +#define ETDM_OUT3_CON2 (0x23c8) +#define ETDM_OUT3_CON3 (0x23cc) +#define ETDM_OUT3_CON4 (0x23d0) +#define ETDM_OUT3_CON5 (0x23d4) +#define ETDM_OUT3_CON6 (0x23d8) +#define ETDM_OUT3_CON7 (0x23dc) +#define ETDM_OUT3_CON8 (0x23e0) +#define ETDM_OUT1_CON8 (0x23e4) +#define ETDM_OUT2_CON8 (0x23e8) +#define GASRC_TIMING_CON0 (0x2414) +#define GASRC_TIMING_CON1 (0x2418) +#define GASRC_TIMING_CON2 (0x241c) +#define GASRC_TIMING_CON3 (0x2420) +#define GASRC_TIMING_CON4 (0x2424) +#define GASRC_TIMING_CON5 (0x2428) +#define GASRC_TIMING_CON6 (0x242c) +#define GASRC_TIMING_CON7 (0x2430) +#define A3_A4_TIMING_SEL0 (0x2440) +#define A3_A4_TIMING_SEL1 (0x2444) +#define A3_A4_TIMING_SEL2 (0x2448) +#define A3_A4_TIMING_SEL3 (0x244c) +#define A3_A4_TIMING_SEL4 (0x2450) +#define A3_A4_TIMING_SEL5 (0x2454) +#define A3_A4_TIMING_SEL6 (0x2458) +#define ASYS_TOP_DEBUG (0x2500) +#define AFE_DPTX_CON (0x2558) +#define AFE_DPTX_MON (0x255c) +#define AFE_ADDA_DL_SRC2_CON0 (0x2d00) +#define AFE_ADDA_DL_SRC2_CON1 (0x2d04) +#define AFE_ADDA_TOP_CON0 (0x2d0c) +#define AFE_ADDA_UL_DL_CON0 (0x2d10) +#define AFE_ADDA_SRC_DEBUG (0x2d14) +#define AFE_ADDA_SRC_DEBUG_MON0 (0x2d18) +#define AFE_ADDA_SRC_DEBUG_MON1 (0x2d20) +#define AFE_ADDA_PREDIS_CON0 (0x2d24) +#define AFE_ADDA_PREDIS_CON1 (0x2d28) +#define AFE_ADDA_PREDIS_CON2 (0x2d2c) +#define AFE_ADDA_PREDIS_CON3 (0x2d30) +#define AFE_ADDA_DL_SDM_DCCOMP_CON (0x2d34) +#define AFE_ADDA_DL_SDM_TEST (0x2d38) +#define AFE_ADDA_DL_DC_COMP_CFG0 (0x2d3c) +#define AFE_ADDA_DL_DC_COMP_CFG1 (0x2d40) +#define AFE_ADDA_DL_SDM_FIFO_MON (0x2d44) +#define AFE_ADDA_DL_SRC_LCH_MON (0x2d50) +#define AFE_ADDA_DL_SRC_RCH_MON (0x2d54) +#define AFE_ADDA_DL_SDM_OUT_MON (0x2d58) +#define AFE_ADDA_DL_SDM_DITHER_CON (0x2d5c) +#define AFE_ADDA_DL_SDM_AUTO_RESET_CON (0x2d60) +#define AFE_ADDA_UL_SRC_CON0 (0x2e3c) +#define AFE_ADDA_UL_SRC_CON1 (0x2e40) +#define AFE_CONN0 (0x3000) +#define AFE_CONN0_1 (0x3004) +#define AFE_CONN0_2 (0x3008) +#define AFE_CONN0_3 (0x300c) +#define AFE_CONN0_4 (0x3010) +#define AFE_CONN1 (0x3014) +#define AFE_CONN1_1 (0x3018) +#define AFE_CONN1_2 (0x301c) +#define AFE_CONN1_3 (0x3020) +#define AFE_CONN1_4 (0x3024) +#define AFE_CONN2 (0x3028) +#define AFE_CONN2_1 (0x302c) +#define AFE_CONN2_2 (0x3030) +#define AFE_CONN2_3 (0x3034) +#define AFE_CONN2_4 (0x3038) +#define AFE_CONN3 (0x303c) +#define AFE_CONN3_1 (0x3040) +#define AFE_CONN3_2 (0x3044) +#define AFE_CONN3_3 (0x3048) +#define AFE_CONN3_4 (0x304c) +#define AFE_CONN4 (0x3050) +#define AFE_CONN4_1 (0x3054) +#define AFE_CONN4_2 (0x3058) +#define AFE_CONN4_3 (0x305c) +#define AFE_CONN4_4 (0x3060) +#define AFE_CONN5 (0x3064) +#define AFE_CONN5_1 (0x3068) +#define AFE_CONN5_2 (0x306c) +#define AFE_CONN5_3 (0x3070) +#define AFE_CONN5_4 (0x3074) +#define AFE_CONN6 (0x3078) +#define AFE_CONN6_1 (0x307c) +#define AFE_CONN6_2 (0x3080) +#define AFE_CONN6_3 (0x3084) +#define AFE_CONN6_4 (0x3088) +#define AFE_CONN7 (0x308c) +#define AFE_CONN7_1 (0x3090) +#define AFE_CONN7_2 (0x3094) +#define AFE_CONN7_3 (0x3098) +#define AFE_CONN7_4 (0x309c) +#define AFE_CONN8 (0x30a0) +#define AFE_CONN8_1 (0x30a4) +#define AFE_CONN8_2 (0x30a8) +#define AFE_CONN8_3 (0x30ac) +#define AFE_CONN8_4 (0x30b0) +#define AFE_CONN9 (0x30b4) +#define AFE_CONN9_1 (0x30b8) +#define AFE_CONN9_2 (0x30bc) +#define AFE_CONN9_3 (0x30c0) +#define AFE_CONN9_4 (0x30c4) +#define AFE_CONN10 (0x30c8) +#define AFE_CONN10_1 (0x30cc) +#define AFE_CONN10_2 (0x30d0) +#define AFE_CONN10_3 (0x30d4) +#define AFE_CONN10_4 (0x30d8) +#define AFE_CONN11 (0x30dc) +#define AFE_CONN11_1 (0x30e0) +#define AFE_CONN11_2 (0x30e4) +#define AFE_CONN11_3 (0x30e8) +#define AFE_CONN11_4 (0x30ec) +#define AFE_CONN12 (0x30f0) +#define AFE_CONN12_1 (0x30f4) +#define AFE_CONN12_2 (0x30f8) +#define AFE_CONN12_3 (0x30fc) +#define AFE_CONN12_4 (0x3100) +#define AFE_CONN13 (0x3104) +#define AFE_CONN13_1 (0x3108) +#define AFE_CONN13_2 (0x310c) +#define AFE_CONN13_3 (0x3110) +#define AFE_CONN13_4 (0x3114) +#define AFE_CONN14 (0x3118) +#define AFE_CONN14_1 (0x311c) +#define AFE_CONN14_2 (0x3120) +#define AFE_CONN14_3 (0x3124) +#define AFE_CONN14_4 (0x3128) +#define AFE_CONN15 (0x312c) +#define AFE_CONN15_1 (0x3130) +#define AFE_CONN15_2 (0x3134) +#define AFE_CONN15_3 (0x3138) +#define AFE_CONN15_4 (0x313c) +#define AFE_CONN16 (0x3140) +#define AFE_CONN16_1 (0x3144) +#define AFE_CONN16_2 (0x3148) +#define AFE_CONN16_3 (0x314c) +#define AFE_CONN16_4 (0x3150) +#define AFE_CONN17 (0x3154) +#define AFE_CONN17_1 (0x3158) +#define AFE_CONN17_2 (0x315c) +#define AFE_CONN17_3 (0x3160) +#define AFE_CONN17_4 (0x3164) +#define AFE_CONN18 (0x3168) +#define AFE_CONN18_1 (0x316c) +#define AFE_CONN18_2 (0x3170) +#define AFE_CONN18_3 (0x3174) +#define AFE_CONN18_4 (0x3178) +#define AFE_CONN19 (0x317c) +#define AFE_CONN19_1 (0x3180) +#define AFE_CONN19_2 (0x3184) +#define AFE_CONN19_3 (0x3188) +#define AFE_CONN19_4 (0x318c) +#define AFE_CONN20 (0x3190) +#define AFE_CONN20_1 (0x3194) +#define AFE_CONN20_2 (0x3198) +#define AFE_CONN20_3 (0x319c) +#define AFE_CONN20_4 (0x31a0) +#define AFE_CONN21 (0x31a4) +#define AFE_CONN21_1 (0x31a8) +#define AFE_CONN21_2 (0x31ac) +#define AFE_CONN21_3 (0x31b0) +#define AFE_CONN21_4 (0x31b4) +#define AFE_CONN22 (0x31b8) +#define AFE_CONN22_1 (0x31bc) +#define AFE_CONN22_2 (0x31c0) +#define AFE_CONN22_3 (0x31c4) +#define AFE_CONN22_4 (0x31c8) +#define AFE_CONN23 (0x31cc) +#define AFE_CONN23_1 (0x31d0) +#define AFE_CONN23_2 (0x31d4) +#define AFE_CONN23_3 (0x31d8) +#define AFE_CONN23_4 (0x31dc) +#define AFE_CONN24 (0x31e0) +#define AFE_CONN24_1 (0x31e4) +#define AFE_CONN24_2 (0x31e8) +#define AFE_CONN24_3 (0x31ec) +#define AFE_CONN24_4 (0x31f0) +#define AFE_CONN25 (0x31f4) +#define AFE_CONN25_1 (0x31f8) +#define AFE_CONN25_2 (0x31fc) +#define AFE_CONN25_3 (0x3200) +#define AFE_CONN25_4 (0x3204) +#define AFE_CONN26 (0x3208) +#define AFE_CONN26_1 (0x320c) +#define AFE_CONN26_2 (0x3210) +#define AFE_CONN26_3 (0x3214) +#define AFE_CONN26_4 (0x3218) +#define AFE_CONN27 (0x321c) +#define AFE_CONN27_1 (0x3220) +#define AFE_CONN27_2 (0x3224) +#define AFE_CONN27_3 (0x3228) +#define AFE_CONN27_4 (0x322c) +#define AFE_CONN28 (0x3230) +#define AFE_CONN28_1 (0x3234) +#define AFE_CONN28_2 (0x3238) +#define AFE_CONN28_3 (0x323c) +#define AFE_CONN28_4 (0x3240) +#define AFE_CONN29 (0x3244) +#define AFE_CONN29_1 (0x3248) +#define AFE_CONN29_2 (0x324c) +#define AFE_CONN29_3 (0x3250) +#define AFE_CONN29_4 (0x3254) +#define AFE_CONN30 (0x3258) +#define AFE_CONN30_1 (0x325c) +#define AFE_CONN30_2 (0x3260) +#define AFE_CONN30_3 (0x3264) +#define AFE_CONN30_4 (0x3268) +#define AFE_CONN31 (0x326c) +#define AFE_CONN31_1 (0x3270) +#define AFE_CONN31_2 (0x3274) +#define AFE_CONN31_3 (0x3278) +#define AFE_CONN31_4 (0x327c) +#define AFE_CONN32 (0x3280) +#define AFE_CONN32_1 (0x3284) +#define AFE_CONN32_2 (0x3288) +#define AFE_CONN32_3 (0x328c) +#define AFE_CONN32_4 (0x3290) +#define AFE_CONN33 (0x3294) +#define AFE_CONN33_1 (0x3298) +#define AFE_CONN33_2 (0x329c) +#define AFE_CONN33_3 (0x32a0) +#define AFE_CONN33_4 (0x32a4) +#define AFE_CONN34 (0x32a8) +#define AFE_CONN34_1 (0x32ac) +#define AFE_CONN34_2 (0x32b0) +#define AFE_CONN34_3 (0x32b4) +#define AFE_CONN34_4 (0x32b8) +#define AFE_CONN35 (0x32bc) +#define AFE_CONN35_1 (0x32c0) +#define AFE_CONN35_2 (0x32c4) +#define AFE_CONN35_3 (0x32c8) +#define AFE_CONN35_4 (0x32cc) +#define AFE_CONN36 (0x32d0) +#define AFE_CONN36_1 (0x32d4) +#define AFE_CONN36_2 (0x32d8) +#define AFE_CONN36_3 (0x32dc) +#define AFE_CONN36_4 (0x32e0) +#define AFE_CONN37 (0x32e4) +#define AFE_CONN37_1 (0x32e8) +#define AFE_CONN37_2 (0x32ec) +#define AFE_CONN37_3 (0x32f0) +#define AFE_CONN37_4 (0x32f4) +#define AFE_CONN38 (0x32f8) +#define AFE_CONN38_1 (0x32fc) +#define AFE_CONN38_2 (0x3300) +#define AFE_CONN38_3 (0x3304) +#define AFE_CONN38_4 (0x3308) +#define AFE_CONN39 (0x330c) +#define AFE_CONN39_1 (0x3310) +#define AFE_CONN39_2 (0x3314) +#define AFE_CONN39_3 (0x3318) +#define AFE_CONN39_4 (0x331c) +#define AFE_CONN40 (0x3320) +#define AFE_CONN40_1 (0x3324) +#define AFE_CONN40_2 (0x3328) +#define AFE_CONN40_3 (0x332c) +#define AFE_CONN40_4 (0x3330) +#define AFE_CONN41 (0x3334) +#define AFE_CONN41_1 (0x3338) +#define AFE_CONN41_2 (0x333c) +#define AFE_CONN41_3 (0x3340) +#define AFE_CONN41_4 (0x3344) +#define AFE_CONN42 (0x3348) +#define AFE_CONN42_1 (0x334c) +#define AFE_CONN42_2 (0x3350) +#define AFE_CONN42_3 (0x3354) +#define AFE_CONN42_4 (0x3358) +#define AFE_CONN43 (0x335c) +#define AFE_CONN43_1 (0x3360) +#define AFE_CONN43_2 (0x3364) +#define AFE_CONN43_3 (0x3368) +#define AFE_CONN43_4 (0x336c) +#define AFE_CONN44 (0x3370) +#define AFE_CONN44_1 (0x3374) +#define AFE_CONN44_2 (0x3378) +#define AFE_CONN44_3 (0x337c) +#define AFE_CONN44_4 (0x3380) +#define AFE_CONN45 (0x3384) +#define AFE_CONN45_1 (0x3388) +#define AFE_CONN45_2 (0x338c) +#define AFE_CONN45_3 (0x3390) +#define AFE_CONN45_4 (0x3394) +#define AFE_CONN46 (0x3398) +#define AFE_CONN46_1 (0x339c) +#define AFE_CONN46_2 (0x33a0) +#define AFE_CONN46_3 (0x33a4) +#define AFE_CONN46_4 (0x33a8) +#define AFE_CONN47 (0x33ac) +#define AFE_CONN47_1 (0x33b0) +#define AFE_CONN47_2 (0x33b4) +#define AFE_CONN47_3 (0x33b8) +#define AFE_CONN47_4 (0x33bc) +#define AFE_CONN48 (0x33c0) +#define AFE_CONN48_1 (0x33c4) +#define AFE_CONN48_2 (0x33c8) +#define AFE_CONN48_3 (0x33cc) +#define AFE_CONN48_4 (0x33d0) +#define AFE_CONN49 (0x33d4) +#define AFE_CONN49_1 (0x33d8) +#define AFE_CONN49_2 (0x33dc) +#define AFE_CONN49_3 (0x33e0) +#define AFE_CONN49_4 (0x33e4) +#define AFE_CONN50 (0x33e8) +#define AFE_CONN50_1 (0x33ec) +#define AFE_CONN50_2 (0x33f0) +#define AFE_CONN50_3 (0x33f4) +#define AFE_CONN50_4 (0x33f8) +#define AFE_CONN51 (0x33fc) +#define AFE_CONN51_1 (0x3400) +#define AFE_CONN51_2 (0x3404) +#define AFE_CONN51_3 (0x3408) +#define AFE_CONN51_4 (0x340c) +#define AFE_CONN52 (0x3410) +#define AFE_CONN52_1 (0x3414) +#define AFE_CONN52_2 (0x3418) +#define AFE_CONN52_3 (0x341c) +#define AFE_CONN52_4 (0x3420) +#define AFE_CONN53 (0x3424) +#define AFE_CONN53_1 (0x3428) +#define AFE_CONN53_2 (0x342c) +#define AFE_CONN53_3 (0x3430) +#define AFE_CONN53_4 (0x3434) +#define AFE_CONN54 (0x3438) +#define AFE_CONN54_1 (0x343c) +#define AFE_CONN54_2 (0x3440) +#define AFE_CONN54_3 (0x3444) +#define AFE_CONN54_4 (0x3448) +#define AFE_CONN55 (0x344c) +#define AFE_CONN55_1 (0x3450) +#define AFE_CONN55_2 (0x3454) +#define AFE_CONN55_3 (0x3458) +#define AFE_CONN55_4 (0x345c) +#define AFE_CONN56 (0x3460) +#define AFE_CONN56_1 (0x3464) +#define AFE_CONN56_2 (0x3468) +#define AFE_CONN56_3 (0x346c) +#define AFE_CONN56_4 (0x3470) +#define AFE_CONN57 (0x3474) +#define AFE_CONN57_1 (0x3478) +#define AFE_CONN57_2 (0x347c) +#define AFE_CONN57_3 (0x3480) +#define AFE_CONN57_4 (0x3484) +#define AFE_CONN58 (0x3488) +#define AFE_CONN58_1 (0x348c) +#define AFE_CONN58_2 (0x3490) +#define AFE_CONN58_3 (0x3494) +#define AFE_CONN58_4 (0x3498) +#define AFE_CONN59 (0x349c) +#define AFE_CONN59_1 (0x34a0) +#define AFE_CONN59_2 (0x34a4) +#define AFE_CONN59_3 (0x34a8) +#define AFE_CONN59_4 (0x34ac) +#define AFE_CONN60 (0x34b0) +#define AFE_CONN60_1 (0x34b4) +#define AFE_CONN60_2 (0x34b8) +#define AFE_CONN60_3 (0x34bc) +#define AFE_CONN60_4 (0x34c0) +#define AFE_CONN61 (0x34c4) +#define AFE_CONN61_1 (0x34c8) +#define AFE_CONN61_2 (0x34cc) +#define AFE_CONN61_3 (0x34d0) +#define AFE_CONN61_4 (0x34d4) +#define AFE_CONN62 (0x34d8) +#define AFE_CONN62_1 (0x34dc) +#define AFE_CONN62_2 (0x34e0) +#define AFE_CONN62_3 (0x34e4) +#define AFE_CONN62_4 (0x34e8) +#define AFE_CONN63 (0x34ec) +#define AFE_CONN63_1 (0x34f0) +#define AFE_CONN63_2 (0x34f4) +#define AFE_CONN63_3 (0x34f8) +#define AFE_CONN63_4 (0x34fc) +#define AFE_CONN64 (0x3500) +#define AFE_CONN64_1 (0x3504) +#define AFE_CONN64_2 (0x3508) +#define AFE_CONN64_3 (0x350c) +#define AFE_CONN64_4 (0x3510) +#define AFE_CONN65 (0x3514) +#define AFE_CONN65_1 (0x3518) +#define AFE_CONN65_2 (0x351c) +#define AFE_CONN65_3 (0x3520) +#define AFE_CONN65_4 (0x3524) +#define AFE_CONN66 (0x3528) +#define AFE_CONN66_1 (0x352c) +#define AFE_CONN66_2 (0x3530) +#define AFE_CONN66_3 (0x3534) +#define AFE_CONN66_4 (0x3538) +#define AFE_CONN67 (0x353c) +#define AFE_CONN67_1 (0x3540) +#define AFE_CONN67_2 (0x3544) +#define AFE_CONN67_3 (0x3548) +#define AFE_CONN67_4 (0x354c) +#define AFE_CONN68 (0x3550) +#define AFE_CONN68_1 (0x3554) +#define AFE_CONN68_2 (0x3558) +#define AFE_CONN68_3 (0x355c) +#define AFE_CONN68_4 (0x3560) +#define AFE_CONN69 (0x3564) +#define AFE_CONN69_1 (0x3568) +#define AFE_CONN69_2 (0x356c) +#define AFE_CONN69_3 (0x3570) +#define AFE_CONN69_4 (0x3574) +#define AFE_CONN70 (0x3578) +#define AFE_CONN70_1 (0x357c) +#define AFE_CONN70_2 (0x3580) +#define AFE_CONN70_3 (0x3584) +#define AFE_CONN70_4 (0x3588) +#define AFE_CONN71 (0x358c) +#define AFE_CONN71_1 (0x3590) +#define AFE_CONN71_2 (0x3594) +#define AFE_CONN71_3 (0x3598) +#define AFE_CONN71_4 (0x359c) +#define AFE_CONN72 (0x35a0) +#define AFE_CONN72_1 (0x35a4) +#define AFE_CONN72_2 (0x35a8) +#define AFE_CONN72_3 (0x35ac) +#define AFE_CONN72_4 (0x35b0) +#define AFE_CONN73 (0x35b4) +#define AFE_CONN73_1 (0x35b8) +#define AFE_CONN73_2 (0x35bc) +#define AFE_CONN73_3 (0x35c0) +#define AFE_CONN73_4 (0x35c4) +#define AFE_CONN74 (0x35c8) +#define AFE_CONN74_1 (0x35cc) +#define AFE_CONN74_2 (0x35d0) +#define AFE_CONN74_3 (0x35d4) +#define AFE_CONN74_4 (0x35d8) +#define AFE_CONN75 (0x35dc) +#define AFE_CONN75_1 (0x35e0) +#define AFE_CONN75_2 (0x35e4) +#define AFE_CONN75_3 (0x35e8) +#define AFE_CONN75_4 (0x35ec) +#define AFE_CONN76 (0x35f0) +#define AFE_CONN76_1 (0x35f4) +#define AFE_CONN76_2 (0x35f8) +#define AFE_CONN76_3 (0x35fc) +#define AFE_CONN76_4 (0x3600) +#define AFE_CONN77 (0x3604) +#define AFE_CONN77_1 (0x3608) +#define AFE_CONN77_2 (0x360c) +#define AFE_CONN77_3 (0x3610) +#define AFE_CONN77_4 (0x3614) +#define AFE_CONN78 (0x3618) +#define AFE_CONN78_1 (0x361c) +#define AFE_CONN78_2 (0x3620) +#define AFE_CONN78_3 (0x3624) +#define AFE_CONN78_4 (0x3628) +#define AFE_CONN79 (0x362c) +#define AFE_CONN79_1 (0x3630) +#define AFE_CONN79_2 (0x3634) +#define AFE_CONN79_3 (0x3638) +#define AFE_CONN79_4 (0x363c) +#define AFE_CONN80 (0x3640) +#define AFE_CONN80_1 (0x3644) +#define AFE_CONN80_2 (0x3648) +#define AFE_CONN80_3 (0x364c) +#define AFE_CONN80_4 (0x3650) +#define AFE_CONN81 (0x3654) +#define AFE_CONN81_1 (0x3658) +#define AFE_CONN81_2 (0x365c) +#define AFE_CONN81_3 (0x3660) +#define AFE_CONN81_4 (0x3664) +#define AFE_CONN82 (0x3668) +#define AFE_CONN82_1 (0x366c) +#define AFE_CONN82_2 (0x3670) +#define AFE_CONN82_3 (0x3674) +#define AFE_CONN82_4 (0x3678) +#define AFE_CONN83 (0x367c) +#define AFE_CONN83_1 (0x3680) +#define AFE_CONN83_2 (0x3684) +#define AFE_CONN83_3 (0x3688) +#define AFE_CONN83_4 (0x368c) +#define AFE_CONN84 (0x3690) +#define AFE_CONN84_1 (0x3694) +#define AFE_CONN84_2 (0x3698) +#define AFE_CONN84_3 (0x369c) +#define AFE_CONN84_4 (0x36a0) +#define AFE_CONN85 (0x36a4) +#define AFE_CONN85_1 (0x36a8) +#define AFE_CONN85_2 (0x36ac) +#define AFE_CONN85_3 (0x36b0) +#define AFE_CONN85_4 (0x36b4) +#define AFE_CONN86 (0x36b8) +#define AFE_CONN86_1 (0x36bc) +#define AFE_CONN86_2 (0x36c0) +#define AFE_CONN86_3 (0x36c4) +#define AFE_CONN86_4 (0x36c8) +#define AFE_CONN87 (0x36cc) +#define AFE_CONN87_1 (0x36d0) +#define AFE_CONN87_2 (0x36d4) +#define AFE_CONN87_3 (0x36d8) +#define AFE_CONN87_4 (0x36dc) +#define AFE_CONN88 (0x36e0) +#define AFE_CONN88_1 (0x36e4) +#define AFE_CONN88_2 (0x36e8) +#define AFE_CONN88_3 (0x36ec) +#define AFE_CONN88_4 (0x36f0) +#define AFE_CONN89 (0x36f4) +#define AFE_CONN89_1 (0x36f8) +#define AFE_CONN89_2 (0x36fc) +#define AFE_CONN89_3 (0x3700) +#define AFE_CONN89_4 (0x3704) +#define AFE_CONN90 (0x3708) +#define AFE_CONN90_1 (0x370c) +#define AFE_CONN90_2 (0x3710) +#define AFE_CONN90_3 (0x3714) +#define AFE_CONN90_4 (0x3718) +#define AFE_CONN91 (0x371c) +#define AFE_CONN91_1 (0x3720) +#define AFE_CONN91_2 (0x3724) +#define AFE_CONN91_3 (0x3728) +#define AFE_CONN91_4 (0x372c) +#define AFE_CONN92 (0x3730) +#define AFE_CONN92_1 (0x3734) +#define AFE_CONN92_2 (0x3738) +#define AFE_CONN92_3 (0x373c) +#define AFE_CONN92_4 (0x3740) +#define AFE_CONN93 (0x3744) +#define AFE_CONN93_1 (0x3748) +#define AFE_CONN93_2 (0x374c) +#define AFE_CONN93_3 (0x3750) +#define AFE_CONN93_4 (0x3754) +#define AFE_CONN94 (0x3758) +#define AFE_CONN94_1 (0x375c) +#define AFE_CONN94_2 (0x3760) +#define AFE_CONN94_3 (0x3764) +#define AFE_CONN94_4 (0x3768) +#define AFE_CONN95 (0x376c) +#define AFE_CONN95_1 (0x3770) +#define AFE_CONN95_2 (0x3774) +#define AFE_CONN95_3 (0x3778) +#define AFE_CONN95_4 (0x377c) +#define AFE_CONN96 (0x3780) +#define AFE_CONN96_1 (0x3784) +#define AFE_CONN96_2 (0x3788) +#define AFE_CONN96_3 (0x378c) +#define AFE_CONN96_4 (0x3790) +#define AFE_CONN97 (0x3794) +#define AFE_CONN97_1 (0x3798) +#define AFE_CONN97_2 (0x379c) +#define AFE_CONN97_3 (0x37a0) +#define AFE_CONN97_4 (0x37a4) +#define AFE_CONN98 (0x37a8) +#define AFE_CONN98_1 (0x37ac) +#define AFE_CONN98_2 (0x37b0) +#define AFE_CONN98_3 (0x37b4) +#define AFE_CONN98_4 (0x37b8) +#define AFE_CONN99 (0x37bc) +#define AFE_CONN99_1 (0x37c0) +#define AFE_CONN99_2 (0x37c4) +#define AFE_CONN99_3 (0x37c8) +#define AFE_CONN99_4 (0x37cc) +#define AFE_CONN100 (0x37d0) +#define AFE_CONN100_1 (0x37d4) +#define AFE_CONN100_2 (0x37d8) +#define AFE_CONN100_3 (0x37dc) +#define AFE_CONN100_4 (0x37e0) +#define AFE_CONN101 (0x37e4) +#define AFE_CONN101_1 (0x37e8) +#define AFE_CONN101_2 (0x37ec) +#define AFE_CONN101_3 (0x37f0) +#define AFE_CONN101_4 (0x37f4) +#define AFE_CONN102 (0x37f8) +#define AFE_CONN102_1 (0x37fc) +#define AFE_CONN102_2 (0x3800) +#define AFE_CONN102_3 (0x3804) +#define AFE_CONN102_4 (0x3808) +#define AFE_CONN103 (0x380c) +#define AFE_CONN103_1 (0x3810) +#define AFE_CONN103_2 (0x3814) +#define AFE_CONN103_3 (0x3818) +#define AFE_CONN103_4 (0x381c) +#define AFE_CONN104 (0x3820) +#define AFE_CONN104_1 (0x3824) +#define AFE_CONN104_2 (0x3828) +#define AFE_CONN104_3 (0x382c) +#define AFE_CONN104_4 (0x3830) +#define AFE_CONN105 (0x3834) +#define AFE_CONN105_1 (0x3838) +#define AFE_CONN105_2 (0x383c) +#define AFE_CONN105_3 (0x3840) +#define AFE_CONN105_4 (0x3844) +#define AFE_CONN106 (0x3848) +#define AFE_CONN106_1 (0x384c) +#define AFE_CONN106_2 (0x3850) +#define AFE_CONN106_3 (0x3854) +#define AFE_CONN106_4 (0x3858) +#define AFE_CONN107 (0x385c) +#define AFE_CONN107_1 (0x3860) +#define AFE_CONN107_2 (0x3864) +#define AFE_CONN107_3 (0x3868) +#define AFE_CONN107_4 (0x386c) +#define AFE_CONN108 (0x3870) +#define AFE_CONN108_1 (0x3874) +#define AFE_CONN108_2 (0x3878) +#define AFE_CONN108_3 (0x387c) +#define AFE_CONN108_4 (0x3880) +#define AFE_CONN109 (0x3884) +#define AFE_CONN109_1 (0x3888) +#define AFE_CONN109_2 (0x388c) +#define AFE_CONN109_3 (0x3890) +#define AFE_CONN109_4 (0x3894) +#define AFE_CONN110 (0x3898) +#define AFE_CONN110_1 (0x389c) +#define AFE_CONN110_2 (0x38a0) +#define AFE_CONN110_3 (0x38a4) +#define AFE_CONN110_4 (0x38a8) +#define AFE_CONN111 (0x38ac) +#define AFE_CONN111_1 (0x38b0) +#define AFE_CONN111_2 (0x38b4) +#define AFE_CONN111_3 (0x38b8) +#define AFE_CONN111_4 (0x38bc) +#define AFE_CONN112 (0x38c0) +#define AFE_CONN112_1 (0x38c4) +#define AFE_CONN112_2 (0x38c8) +#define AFE_CONN112_3 (0x38cc) +#define AFE_CONN112_4 (0x38d0) +#define AFE_CONN113 (0x38d4) +#define AFE_CONN113_1 (0x38d8) +#define AFE_CONN113_2 (0x38dc) +#define AFE_CONN113_3 (0x38e0) +#define AFE_CONN113_4 (0x38e4) +#define AFE_CONN114 (0x38e8) +#define AFE_CONN114_1 (0x38ec) +#define AFE_CONN114_2 (0x38f0) +#define AFE_CONN114_3 (0x38f4) +#define AFE_CONN114_4 (0x38f8) +#define AFE_CONN115 (0x38fc) +#define AFE_CONN115_1 (0x3900) +#define AFE_CONN115_2 (0x3904) +#define AFE_CONN115_3 (0x3908) +#define AFE_CONN115_4 (0x390c) +#define AFE_CONN116 (0x3910) +#define AFE_CONN116_1 (0x3914) +#define AFE_CONN116_2 (0x3918) +#define AFE_CONN116_3 (0x391c) +#define AFE_CONN116_4 (0x3920) +#define AFE_CONN117 (0x3924) +#define AFE_CONN117_1 (0x3928) +#define AFE_CONN117_2 (0x392c) +#define AFE_CONN117_3 (0x3930) +#define AFE_CONN117_4 (0x3934) +#define AFE_CONN118 (0x3938) +#define AFE_CONN118_1 (0x393c) +#define AFE_CONN118_2 (0x3940) +#define AFE_CONN118_3 (0x3944) +#define AFE_CONN118_4 (0x3948) +#define AFE_CONN119 (0x394c) +#define AFE_CONN119_1 (0x3950) +#define AFE_CONN119_2 (0x3954) +#define AFE_CONN119_3 (0x3958) +#define AFE_CONN119_4 (0x395c) +#define AFE_CONN120 (0x3960) +#define AFE_CONN120_1 (0x3964) +#define AFE_CONN120_2 (0x3968) +#define AFE_CONN120_3 (0x396c) +#define AFE_CONN120_4 (0x3970) +#define AFE_CONN121 (0x3974) +#define AFE_CONN121_1 (0x3978) +#define AFE_CONN121_2 (0x397c) +#define AFE_CONN121_3 (0x3980) +#define AFE_CONN121_4 (0x3984) +#define AFE_CONN122 (0x3988) +#define AFE_CONN122_1 (0x398c) +#define AFE_CONN122_2 (0x3990) +#define AFE_CONN122_3 (0x3994) +#define AFE_CONN122_4 (0x3998) +#define AFE_CONN123 (0x399c) +#define AFE_CONN123_1 (0x39a0) +#define AFE_CONN123_2 (0x39a4) +#define AFE_CONN123_3 (0x39a8) +#define AFE_CONN123_4 (0x39ac) +#define AFE_CONN124 (0x39b0) +#define AFE_CONN124_1 (0x39b4) +#define AFE_CONN124_2 (0x39b8) +#define AFE_CONN124_3 (0x39bc) +#define AFE_CONN124_4 (0x39c0) +#define AFE_CONN125 (0x39c4) +#define AFE_CONN125_1 (0x39c8) +#define AFE_CONN125_2 (0x39cc) +#define AFE_CONN125_3 (0x39d0) +#define AFE_CONN125_4 (0x39d4) +#define AFE_CONN126 (0x39d8) +#define AFE_CONN126_1 (0x39dc) +#define AFE_CONN126_2 (0x39e0) +#define AFE_CONN126_3 (0x39e4) +#define AFE_CONN126_4 (0x39e8) +#define AFE_CONN127 (0x39ec) +#define AFE_CONN127_1 (0x39f0) +#define AFE_CONN127_2 (0x39f4) +#define AFE_CONN127_3 (0x39f8) +#define AFE_CONN127_4 (0x39fc) +#define AFE_CONN128 (0x3a00) +#define AFE_CONN128_1 (0x3a04) +#define AFE_CONN128_2 (0x3a08) +#define AFE_CONN128_3 (0x3a0c) +#define AFE_CONN128_4 (0x3a10) +#define AFE_CONN129 (0x3a14) +#define AFE_CONN129_1 (0x3a18) +#define AFE_CONN129_2 (0x3a1c) +#define AFE_CONN129_3 (0x3a20) +#define AFE_CONN129_4 (0x3a24) +#define AFE_CONN130 (0x3a28) +#define AFE_CONN130_1 (0x3a2c) +#define AFE_CONN130_2 (0x3a30) +#define AFE_CONN130_3 (0x3a34) +#define AFE_CONN130_4 (0x3a38) +#define AFE_CONN131 (0x3a3c) +#define AFE_CONN131_1 (0x3a40) +#define AFE_CONN131_2 (0x3a44) +#define AFE_CONN131_3 (0x3a48) +#define AFE_CONN131_4 (0x3a4c) +#define AFE_CONN132 (0x3a50) +#define AFE_CONN132_1 (0x3a54) +#define AFE_CONN132_2 (0x3a58) +#define AFE_CONN132_3 (0x3a5c) +#define AFE_CONN132_4 (0x3a60) +#define AFE_CONN133 (0x3a64) +#define AFE_CONN133_1 (0x3a68) +#define AFE_CONN133_2 (0x3a6c) +#define AFE_CONN133_3 (0x3a70) +#define AFE_CONN133_4 (0x3a74) +#define AFE_CONN134 (0x3a78) +#define AFE_CONN134_1 (0x3a7c) +#define AFE_CONN134_2 (0x3a80) +#define AFE_CONN134_3 (0x3a84) +#define AFE_CONN134_4 (0x3a88) +#define AFE_CONN135 (0x3a8c) +#define AFE_CONN135_1 (0x3a90) +#define AFE_CONN135_2 (0x3a94) +#define AFE_CONN135_3 (0x3a98) +#define AFE_CONN135_4 (0x3a9c) +#define AFE_CONN136 (0x3aa0) +#define AFE_CONN136_1 (0x3aa4) +#define AFE_CONN136_2 (0x3aa8) +#define AFE_CONN136_3 (0x3aac) +#define AFE_CONN136_4 (0x3ab0) +#define AFE_CONN137 (0x3ab4) +#define AFE_CONN137_1 (0x3ab8) +#define AFE_CONN137_2 (0x3abc) +#define AFE_CONN137_3 (0x3ac0) +#define AFE_CONN137_4 (0x3ac4) +#define AFE_CONN138 (0x3ac8) +#define AFE_CONN138_1 (0x3acc) +#define AFE_CONN138_2 (0x3ad0) +#define AFE_CONN138_3 (0x3ad4) +#define AFE_CONN138_4 (0x3ad8) +#define AFE_CONN139 (0x3adc) +#define AFE_CONN139_1 (0x3ae0) +#define AFE_CONN139_2 (0x3ae4) +#define AFE_CONN139_3 (0x3ae8) +#define AFE_CONN139_4 (0x3aec) +#define AFE_CONN_RS (0x3af0) +#define AFE_CONN_RS_1 (0x3af4) +#define AFE_CONN_RS_2 (0x3af8) +#define AFE_CONN_RS_3 (0x3afc) +#define AFE_CONN_RS_4 (0x3b00) +#define AFE_CONN_16BIT (0x3b04) +#define AFE_CONN_16BIT_1 (0x3b08) +#define AFE_CONN_16BIT_2 (0x3b0c) +#define AFE_CONN_16BIT_3 (0x3b10) +#define AFE_CONN_16BIT_4 (0x3b14) +#define AFE_CONN_24BIT (0x3b18) +#define AFE_CONN_24BIT_1 (0x3b1c) +#define AFE_CONN_24BIT_2 (0x3b20) +#define AFE_CONN_24BIT_3 (0x3b24) +#define AFE_CONN_24BIT_4 (0x3b28) +#define AFE_CONN_DI (0x3b2c) +#define AFE_CONN_DI_1 (0x3b30) +#define AFE_CONN_DI_2 (0x3b34) +#define AFE_CONN_DI_3 (0x3b38) +#define AFE_CONN_DI_4 (0x3b3c) +#define AFE_CONN176 (0x3ea0) +#define AFE_CONN176_1 (0x3ea4) +#define AFE_CONN176_2 (0x3ea8) +#define AFE_CONN176_3 (0x3eac) +#define AFE_CONN176_4 (0x3eb0) +#define AFE_CONN176_5 (0x3eb4) +#define AFE_CONN177 (0x3eb8) +#define AFE_CONN177_1 (0x3ebc) +#define AFE_CONN177_2 (0x3ec0) +#define AFE_CONN177_3 (0x3ec4) +#define AFE_CONN177_4 (0x3ec8) +#define AFE_CONN177_5 (0x3ecc) +#define AFE_CONN182 (0x3f30) +#define AFE_CONN182_1 (0x3f34) +#define AFE_CONN182_2 (0x3f38) +#define AFE_CONN182_3 (0x3f3c) +#define AFE_CONN182_4 (0x3f40) +#define AFE_CONN182_5 (0x3f44) +#define AFE_CONN183 (0x3f48) +#define AFE_CONN183_1 (0x3f4c) +#define AFE_CONN183_2 (0x3f50) +#define AFE_CONN183_3 (0x3f54) +#define AFE_CONN183_4 (0x3f58) +#define AFE_CONN183_5 (0x3f5c) +#define AFE_SECURE_MASK_CONN0 (0x4000) +#define AFE_SECURE_MASK_CONN0_1 (0x4004) +#define AFE_SECURE_MASK_CONN0_2 (0x4008) +#define AFE_SECURE_MASK_CONN0_3 (0x400c) +#define AFE_SECURE_MASK_CONN0_4 (0x4010) +#define AFE_SECURE_MASK_CONN1 (0x4014) +#define AFE_SECURE_MASK_CONN1_1 (0x4018) +#define AFE_SECURE_MASK_CONN1_2 (0x401c) +#define AFE_SECURE_MASK_CONN1_3 (0x4020) +#define AFE_SECURE_MASK_CONN1_4 (0x4024) +#define AFE_SECURE_MASK_CONN2 (0x4028) +#define AFE_SECURE_MASK_CONN2_1 (0x402c) +#define AFE_SECURE_MASK_CONN2_2 (0x4030) +#define AFE_SECURE_MASK_CONN2_3 (0x4034) +#define AFE_SECURE_MASK_CONN2_4 (0x4038) +#define AFE_SECURE_MASK_CONN3 (0x403c) +#define AFE_SECURE_MASK_CONN3_1 (0x4040) +#define AFE_SECURE_MASK_CONN3_2 (0x4044) +#define AFE_SECURE_MASK_CONN3_3 (0x4048) +#define AFE_SECURE_MASK_CONN3_4 (0x404c) +#define AFE_SECURE_MASK_CONN4 (0x4050) +#define AFE_SECURE_MASK_CONN4_1 (0x4054) +#define AFE_SECURE_MASK_CONN4_2 (0x4058) +#define AFE_SECURE_MASK_CONN4_3 (0x405c) +#define AFE_SECURE_MASK_CONN4_4 (0x4060) +#define AFE_SECURE_MASK_CONN5 (0x4064) +#define AFE_SECURE_MASK_CONN5_1 (0x4068) +#define AFE_SECURE_MASK_CONN5_2 (0x406c) +#define AFE_SECURE_MASK_CONN5_3 (0x4070) +#define AFE_SECURE_MASK_CONN5_4 (0x4074) +#define AFE_SECURE_MASK_CONN6 (0x4078) +#define AFE_SECURE_MASK_CONN6_1 (0x407c) +#define AFE_SECURE_MASK_CONN6_2 (0x4080) +#define AFE_SECURE_MASK_CONN6_3 (0x4084) +#define AFE_SECURE_MASK_CONN6_4 (0x4088) +#define AFE_SECURE_MASK_CONN7 (0x408c) +#define AFE_SECURE_MASK_CONN7_1 (0x4090) +#define AFE_SECURE_MASK_CONN7_2 (0x4094) +#define AFE_SECURE_MASK_CONN7_3 (0x4098) +#define AFE_SECURE_MASK_CONN7_4 (0x409c) +#define AFE_SECURE_MASK_CONN8 (0x40a0) +#define AFE_SECURE_MASK_CONN8_1 (0x40a4) +#define AFE_SECURE_MASK_CONN8_2 (0x40a8) +#define AFE_SECURE_MASK_CONN8_3 (0x40ac) +#define AFE_SECURE_MASK_CONN8_4 (0x40b0) +#define AFE_SECURE_MASK_CONN9 (0x40b4) +#define AFE_SECURE_MASK_CONN9_1 (0x40b8) +#define AFE_SECURE_MASK_CONN9_2 (0x40bc) +#define AFE_SECURE_MASK_CONN9_3 (0x40c0) +#define AFE_SECURE_MASK_CONN9_4 (0x40c4) +#define AFE_SECURE_MASK_CONN10 (0x40c8) +#define AFE_SECURE_MASK_CONN10_1 (0x40cc) +#define AFE_SECURE_MASK_CONN10_2 (0x40d0) +#define AFE_SECURE_MASK_CONN10_3 (0x40d4) +#define AFE_SECURE_MASK_CONN10_4 (0x40d8) +#define AFE_SECURE_MASK_CONN11 (0x40dc) +#define AFE_SECURE_MASK_CONN11_1 (0x40e0) +#define AFE_SECURE_MASK_CONN11_2 (0x40e4) +#define AFE_SECURE_MASK_CONN11_3 (0x40e8) +#define AFE_SECURE_MASK_CONN11_4 (0x40ec) +#define AFE_SECURE_MASK_CONN12 (0x40f0) +#define AFE_SECURE_MASK_CONN12_1 (0x40f4) +#define AFE_SECURE_MASK_CONN12_2 (0x40f8) +#define AFE_SECURE_MASK_CONN12_3 (0x40fc) +#define AFE_SECURE_MASK_CONN12_4 (0x4100) +#define AFE_SECURE_MASK_CONN13 (0x4104) +#define AFE_SECURE_MASK_CONN13_1 (0x4108) +#define AFE_SECURE_MASK_CONN13_2 (0x410c) +#define AFE_SECURE_MASK_CONN13_3 (0x4110) +#define AFE_SECURE_MASK_CONN13_4 (0x4114) +#define AFE_SECURE_MASK_CONN14 (0x4118) +#define AFE_SECURE_MASK_CONN14_1 (0x411c) +#define AFE_SECURE_MASK_CONN14_2 (0x4120) +#define AFE_SECURE_MASK_CONN14_3 (0x4124) +#define AFE_SECURE_MASK_CONN14_4 (0x4128) +#define AFE_SECURE_MASK_CONN15 (0x412c) +#define AFE_SECURE_MASK_CONN15_1 (0x4130) +#define AFE_SECURE_MASK_CONN15_2 (0x4134) +#define AFE_SECURE_MASK_CONN15_3 (0x4138) +#define AFE_SECURE_MASK_CONN15_4 (0x413c) +#define AFE_SECURE_MASK_CONN16 (0x4140) +#define AFE_SECURE_MASK_CONN16_1 (0x4144) +#define AFE_SECURE_MASK_CONN16_2 (0x4148) +#define AFE_SECURE_MASK_CONN16_3 (0x414c) +#define AFE_SECURE_MASK_CONN16_4 (0x4150) +#define AFE_SECURE_MASK_CONN17 (0x4154) +#define AFE_SECURE_MASK_CONN17_1 (0x4158) +#define AFE_SECURE_MASK_CONN17_2 (0x415c) +#define AFE_SECURE_MASK_CONN17_3 (0x4160) +#define AFE_SECURE_MASK_CONN17_4 (0x4164) +#define AFE_SECURE_MASK_CONN18 (0x4168) +#define AFE_SECURE_MASK_CONN18_1 (0x416c) +#define AFE_SECURE_MASK_CONN18_2 (0x4170) +#define AFE_SECURE_MASK_CONN18_3 (0x4174) +#define AFE_SECURE_MASK_CONN18_4 (0x4178) +#define AFE_SECURE_MASK_CONN19 (0x417c) +#define AFE_SECURE_MASK_CONN19_1 (0x4180) +#define AFE_SECURE_MASK_CONN19_2 (0x4184) +#define AFE_SECURE_MASK_CONN19_3 (0x4188) +#define AFE_SECURE_MASK_CONN19_4 (0x418c) +#define AFE_SECURE_MASK_CONN20 (0x4190) +#define AFE_SECURE_MASK_CONN20_1 (0x4194) +#define AFE_SECURE_MASK_CONN20_2 (0x4198) +#define AFE_SECURE_MASK_CONN20_3 (0x419c) +#define AFE_SECURE_MASK_CONN20_4 (0x41a0) +#define AFE_SECURE_MASK_CONN21 (0x41a4) +#define AFE_SECURE_MASK_CONN21_1 (0x41a8) +#define AFE_SECURE_MASK_CONN21_2 (0x41ac) +#define AFE_SECURE_MASK_CONN21_3 (0x41b0) +#define AFE_SECURE_MASK_CONN21_4 (0x41b4) +#define AFE_SECURE_MASK_CONN22 (0x41b8) +#define AFE_SECURE_MASK_CONN22_1 (0x41bc) +#define AFE_SECURE_MASK_CONN22_2 (0x41c0) +#define AFE_SECURE_MASK_CONN22_3 (0x41c4) +#define AFE_SECURE_MASK_CONN22_4 (0x41c8) +#define AFE_SECURE_MASK_CONN23 (0x41cc) +#define AFE_SECURE_MASK_CONN23_1 (0x41d0) +#define AFE_SECURE_MASK_CONN23_2 (0x41d4) +#define AFE_SECURE_MASK_CONN23_3 (0x41d8) +#define AFE_SECURE_MASK_CONN23_4 (0x41dc) +#define AFE_SECURE_MASK_CONN24 (0x41e0) +#define AFE_SECURE_MASK_CONN24_1 (0x41e4) +#define AFE_SECURE_MASK_CONN24_2 (0x41e8) +#define AFE_SECURE_MASK_CONN24_3 (0x41ec) +#define AFE_SECURE_MASK_CONN24_4 (0x41f0) +#define AFE_SECURE_MASK_CONN25 (0x41f4) +#define AFE_SECURE_MASK_CONN25_1 (0x41f8) +#define AFE_SECURE_MASK_CONN25_2 (0x41fc) +#define AFE_SECURE_MASK_CONN25_3 (0x4200) +#define AFE_SECURE_MASK_CONN25_4 (0x4204) +#define AFE_SECURE_MASK_CONN26 (0x4208) +#define AFE_SECURE_MASK_CONN26_1 (0x420c) +#define AFE_SECURE_MASK_CONN26_2 (0x4210) +#define AFE_SECURE_MASK_CONN26_3 (0x4214) +#define AFE_SECURE_MASK_CONN26_4 (0x4218) +#define AFE_SECURE_MASK_CONN27 (0x421c) +#define AFE_SECURE_MASK_CONN27_1 (0x4220) +#define AFE_SECURE_MASK_CONN27_2 (0x4224) +#define AFE_SECURE_MASK_CONN27_3 (0x4228) +#define AFE_SECURE_MASK_CONN27_4 (0x422c) +#define AFE_SECURE_MASK_CONN28 (0x4230) +#define AFE_SECURE_MASK_CONN28_1 (0x4234) +#define AFE_SECURE_MASK_CONN28_2 (0x4238) +#define AFE_SECURE_MASK_CONN28_3 (0x423c) +#define AFE_SECURE_MASK_CONN28_4 (0x4240) +#define AFE_SECURE_MASK_CONN29 (0x4244) +#define AFE_SECURE_MASK_CONN29_1 (0x4248) +#define AFE_SECURE_MASK_CONN29_2 (0x424c) +#define AFE_SECURE_MASK_CONN29_3 (0x4250) +#define AFE_SECURE_MASK_CONN29_4 (0x4254) +#define AFE_SECURE_MASK_CONN30 (0x4258) +#define AFE_SECURE_MASK_CONN30_1 (0x425c) +#define AFE_SECURE_MASK_CONN30_2 (0x4260) +#define AFE_SECURE_MASK_CONN30_3 (0x4264) +#define AFE_SECURE_MASK_CONN30_4 (0x4268) +#define AFE_SECURE_MASK_CONN31 (0x426c) +#define AFE_SECURE_MASK_CONN31_1 (0x4270) +#define AFE_SECURE_MASK_CONN31_2 (0x4274) +#define AFE_SECURE_MASK_CONN31_3 (0x4278) +#define AFE_SECURE_MASK_CONN31_4 (0x427c) +#define AFE_SECURE_MASK_CONN32 (0x4280) +#define AFE_SECURE_MASK_CONN32_1 (0x4284) +#define AFE_SECURE_MASK_CONN32_2 (0x4288) +#define AFE_SECURE_MASK_CONN32_3 (0x428c) +#define AFE_SECURE_MASK_CONN32_4 (0x4290) +#define AFE_SECURE_MASK_CONN33 (0x4294) +#define AFE_SECURE_MASK_CONN33_1 (0x4298) +#define AFE_SECURE_MASK_CONN33_2 (0x429c) +#define AFE_SECURE_MASK_CONN33_3 (0x42a0) +#define AFE_SECURE_MASK_CONN33_4 (0x42a4) +#define AFE_SECURE_MASK_CONN34 (0x42a8) +#define AFE_SECURE_MASK_CONN34_1 (0x42ac) +#define AFE_SECURE_MASK_CONN34_2 (0x42b0) +#define AFE_SECURE_MASK_CONN34_3 (0x42b4) +#define AFE_SECURE_MASK_CONN34_4 (0x42b8) +#define AFE_SECURE_MASK_CONN35 (0x42bc) +#define AFE_SECURE_MASK_CONN35_1 (0x42c0) +#define AFE_SECURE_MASK_CONN35_2 (0x42c4) +#define AFE_SECURE_MASK_CONN35_3 (0x42c8) +#define AFE_SECURE_MASK_CONN35_4 (0x42cc) +#define AFE_SECURE_MASK_CONN36 (0x42d0) +#define AFE_SECURE_MASK_CONN36_1 (0x42d4) +#define AFE_SECURE_MASK_CONN36_2 (0x42d8) +#define AFE_SECURE_MASK_CONN36_3 (0x42dc) +#define AFE_SECURE_MASK_CONN36_4 (0x42e0) +#define AFE_SECURE_MASK_CONN37 (0x42e4) +#define AFE_SECURE_MASK_CONN37_1 (0x42e8) +#define AFE_SECURE_MASK_CONN37_2 (0x42ec) +#define AFE_SECURE_MASK_CONN37_3 (0x42f0) +#define AFE_SECURE_MASK_CONN37_4 (0x42f4) +#define AFE_SECURE_MASK_CONN38 (0x42f8) +#define AFE_SECURE_MASK_CONN38_1 (0x42fc) +#define AFE_SECURE_MASK_CONN38_2 (0x4300) +#define AFE_SECURE_MASK_CONN38_3 (0x4304) +#define AFE_SECURE_MASK_CONN38_4 (0x4308) +#define AFE_SECURE_MASK_CONN39 (0x430c) +#define AFE_SECURE_MASK_CONN39_1 (0x4310) +#define AFE_SECURE_MASK_CONN39_2 (0x4314) +#define AFE_SECURE_MASK_CONN39_3 (0x4318) +#define AFE_SECURE_MASK_CONN39_4 (0x431c) +#define AFE_SECURE_MASK_CONN40 (0x4320) +#define AFE_SECURE_MASK_CONN40_1 (0x4324) +#define AFE_SECURE_MASK_CONN40_2 (0x4328) +#define AFE_SECURE_MASK_CONN40_3 (0x432c) +#define AFE_SECURE_MASK_CONN40_4 (0x4330) +#define AFE_SECURE_MASK_CONN41 (0x4334) +#define AFE_SECURE_MASK_CONN41_1 (0x4338) +#define AFE_SECURE_MASK_CONN41_2 (0x433c) +#define AFE_SECURE_MASK_CONN41_3 (0x4340) +#define AFE_SECURE_MASK_CONN41_4 (0x4344) +#define AFE_SECURE_MASK_CONN42 (0x4348) +#define AFE_SECURE_MASK_CONN42_1 (0x434c) +#define AFE_SECURE_MASK_CONN42_2 (0x4350) +#define AFE_SECURE_MASK_CONN42_3 (0x4354) +#define AFE_SECURE_MASK_CONN42_4 (0x4358) +#define AFE_SECURE_MASK_CONN43 (0x435c) +#define AFE_SECURE_MASK_CONN43_1 (0x4360) +#define AFE_SECURE_MASK_CONN43_2 (0x4364) +#define AFE_SECURE_MASK_CONN43_3 (0x4368) +#define AFE_SECURE_MASK_CONN43_4 (0x436c) +#define AFE_SECURE_MASK_CONN44 (0x4370) +#define AFE_SECURE_MASK_CONN44_1 (0x4374) +#define AFE_SECURE_MASK_CONN44_2 (0x4378) +#define AFE_SECURE_MASK_CONN44_3 (0x437c) +#define AFE_SECURE_MASK_CONN44_4 (0x4380) +#define AFE_SECURE_MASK_CONN45 (0x4384) +#define AFE_SECURE_MASK_CONN45_1 (0x4388) +#define AFE_SECURE_MASK_CONN45_2 (0x438c) +#define AFE_SECURE_MASK_CONN45_3 (0x4390) +#define AFE_SECURE_MASK_CONN45_4 (0x4394) +#define AFE_SECURE_MASK_CONN46 (0x4398) +#define AFE_SECURE_MASK_CONN46_1 (0x439c) +#define AFE_SECURE_MASK_CONN46_2 (0x43a0) +#define AFE_SECURE_MASK_CONN46_3 (0x43a4) +#define AFE_SECURE_MASK_CONN46_4 (0x43a8) +#define AFE_SECURE_MASK_CONN47 (0x43ac) +#define AFE_SECURE_MASK_CONN47_1 (0x43b0) +#define AFE_SECURE_MASK_CONN47_2 (0x43b4) +#define AFE_SECURE_MASK_CONN47_3 (0x43b8) +#define AFE_SECURE_MASK_CONN47_4 (0x43bc) +#define AFE_SECURE_MASK_CONN48 (0x43c0) +#define AFE_SECURE_MASK_CONN48_1 (0x43c4) +#define AFE_SECURE_MASK_CONN48_2 (0x43c8) +#define AFE_SECURE_MASK_CONN48_3 (0x43cc) +#define AFE_SECURE_MASK_CONN48_4 (0x43d0) +#define AFE_SECURE_MASK_CONN49 (0x43d4) +#define AFE_SECURE_MASK_CONN49_1 (0x43d8) +#define AFE_SECURE_MASK_CONN49_2 (0x43dc) +#define AFE_SECURE_MASK_CONN49_3 (0x43e0) +#define AFE_SECURE_MASK_CONN49_4 (0x43e4) +#define AFE_SECURE_MASK_CONN50 (0x43e8) +#define AFE_SECURE_MASK_CONN50_1 (0x43ec) +#define AFE_SECURE_MASK_CONN50_2 (0x43f0) +#define AFE_SECURE_MASK_CONN50_3 (0x43f4) +#define AFE_SECURE_MASK_CONN50_4 (0x43f8) +#define AFE_SECURE_MASK_CONN51 (0x43fc) +#define AFE_SECURE_MASK_CONN51_1 (0x4400) +#define AFE_SECURE_MASK_CONN51_2 (0x4404) +#define AFE_SECURE_MASK_CONN51_3 (0x4408) +#define AFE_SECURE_MASK_CONN51_4 (0x440c) +#define AFE_SECURE_MASK_CONN52 (0x4410) +#define AFE_SECURE_MASK_CONN52_1 (0x4414) +#define AFE_SECURE_MASK_CONN52_2 (0x4418) +#define AFE_SECURE_MASK_CONN52_3 (0x441c) +#define AFE_SECURE_MASK_CONN52_4 (0x4420) +#define AFE_SECURE_MASK_CONN53 (0x4424) +#define AFE_SECURE_MASK_CONN53_1 (0x4428) +#define AFE_SECURE_MASK_CONN53_2 (0x442c) +#define AFE_SECURE_MASK_CONN53_3 (0x4430) +#define AFE_SECURE_MASK_CONN53_4 (0x4434) +#define AFE_SECURE_MASK_CONN54 (0x4438) +#define AFE_SECURE_MASK_CONN54_1 (0x443c) +#define AFE_SECURE_MASK_CONN54_2 (0x4440) +#define AFE_SECURE_MASK_CONN54_3 (0x4444) +#define AFE_SECURE_MASK_CONN54_4 (0x4448) +#define AFE_SECURE_MASK_CONN55 (0x444c) +#define AFE_SECURE_MASK_CONN55_1 (0x4450) +#define AFE_SECURE_MASK_CONN55_2 (0x4454) +#define AFE_SECURE_MASK_CONN55_3 (0x4458) +#define AFE_SECURE_MASK_CONN55_4 (0x445c) +#define AFE_SECURE_MASK_CONN56 (0x4460) +#define AFE_SECURE_MASK_CONN56_1 (0x4464) +#define AFE_SECURE_MASK_CONN56_2 (0x4468) +#define AFE_SECURE_MASK_CONN56_3 (0x446c) +#define AFE_SECURE_MASK_CONN56_4 (0x4470) +#define AFE_SECURE_MASK_CONN57 (0x4474) +#define AFE_SECURE_MASK_CONN57_1 (0x4478) +#define AFE_SECURE_MASK_CONN57_2 (0x447c) +#define AFE_SECURE_MASK_CONN57_3 (0x4480) +#define AFE_SECURE_MASK_CONN57_4 (0x4484) +#define AFE_SECURE_MASK_CONN58 (0x4488) +#define AFE_SECURE_MASK_CONN58_1 (0x448c) +#define AFE_SECURE_MASK_CONN58_2 (0x4490) +#define AFE_SECURE_MASK_CONN58_3 (0x4494) +#define AFE_SECURE_MASK_CONN58_4 (0x4498) +#define AFE_SECURE_MASK_CONN59 (0x449c) +#define AFE_SECURE_MASK_CONN59_1 (0x44a0) +#define AFE_SECURE_MASK_CONN59_2 (0x44a4) +#define AFE_SECURE_MASK_CONN59_3 (0x44a8) +#define AFE_SECURE_MASK_CONN59_4 (0x44ac) +#define AFE_SECURE_MASK_CONN60 (0x44b0) +#define AFE_SECURE_MASK_CONN60_1 (0x44b4) +#define AFE_SECURE_MASK_CONN60_2 (0x44b8) +#define AFE_SECURE_MASK_CONN60_3 (0x44bc) +#define AFE_SECURE_MASK_CONN60_4 (0x44c0) +#define AFE_SECURE_MASK_CONN61 (0x44c4) +#define AFE_SECURE_MASK_CONN61_1 (0x44c8) +#define AFE_SECURE_MASK_CONN61_2 (0x44cc) +#define AFE_SECURE_MASK_CONN61_3 (0x44d0) +#define AFE_SECURE_MASK_CONN61_4 (0x44d4) +#define AFE_SECURE_MASK_CONN62 (0x44d8) +#define AFE_SECURE_MASK_CONN62_1 (0x44dc) +#define AFE_SECURE_MASK_CONN62_2 (0x44e0) +#define AFE_SECURE_MASK_CONN62_3 (0x44e4) +#define AFE_SECURE_MASK_CONN62_4 (0x44e8) +#define AFE_SECURE_MASK_CONN63 (0x44ec) +#define AFE_SECURE_MASK_CONN63_1 (0x44f0) +#define AFE_SECURE_MASK_CONN63_2 (0x44f4) +#define AFE_SECURE_MASK_CONN63_3 (0x44f8) +#define AFE_SECURE_MASK_CONN63_4 (0x44fc) +#define AFE_SECURE_MASK_CONN64 (0x4500) +#define AFE_SECURE_MASK_CONN64_1 (0x4504) +#define AFE_SECURE_MASK_CONN64_2 (0x4508) +#define AFE_SECURE_MASK_CONN64_3 (0x450c) +#define AFE_SECURE_MASK_CONN64_4 (0x4510) +#define AFE_SECURE_MASK_CONN65 (0x4514) +#define AFE_SECURE_MASK_CONN65_1 (0x4518) +#define AFE_SECURE_MASK_CONN65_2 (0x451c) +#define AFE_SECURE_MASK_CONN65_3 (0x4520) +#define AFE_SECURE_MASK_CONN65_4 (0x4524) +#define AFE_SECURE_MASK_CONN66 (0x4528) +#define AFE_SECURE_MASK_CONN66_1 (0x452c) +#define AFE_SECURE_MASK_CONN66_2 (0x4530) +#define AFE_SECURE_MASK_CONN66_3 (0x4534) +#define AFE_SECURE_MASK_CONN66_4 (0x4538) +#define AFE_SECURE_MASK_CONN67 (0x453c) +#define AFE_SECURE_MASK_CONN67_1 (0x4540) +#define AFE_SECURE_MASK_CONN67_2 (0x4544) +#define AFE_SECURE_MASK_CONN67_3 (0x4548) +#define AFE_SECURE_MASK_CONN67_4 (0x454c) +#define AFE_SECURE_MASK_CONN68 (0x4550) +#define AFE_SECURE_MASK_CONN68_1 (0x4554) +#define AFE_SECURE_MASK_CONN68_2 (0x4558) +#define AFE_SECURE_MASK_CONN68_3 (0x455c) +#define AFE_SECURE_MASK_CONN68_4 (0x4560) +#define AFE_SECURE_MASK_CONN69 (0x4564) +#define AFE_SECURE_MASK_CONN69_1 (0x4568) +#define AFE_SECURE_MASK_CONN69_2 (0x456c) +#define AFE_SECURE_MASK_CONN69_3 (0x4570) +#define AFE_SECURE_MASK_CONN69_4 (0x4574) +#define AFE_SECURE_MASK_CONN70 (0x4578) +#define AFE_SECURE_MASK_CONN70_1 (0x457c) +#define AFE_SECURE_MASK_CONN70_2 (0x4580) +#define AFE_SECURE_MASK_CONN70_3 (0x4584) +#define AFE_SECURE_MASK_CONN70_4 (0x4588) +#define AFE_SECURE_MASK_CONN71 (0x458c) +#define AFE_SECURE_MASK_CONN71_1 (0x4590) +#define AFE_SECURE_MASK_CONN71_2 (0x4594) +#define AFE_SECURE_MASK_CONN71_3 (0x4598) +#define AFE_SECURE_MASK_CONN71_4 (0x459c) +#define AFE_SECURE_MASK_CONN72 (0x45a0) +#define AFE_SECURE_MASK_CONN72_1 (0x45a4) +#define AFE_SECURE_MASK_CONN72_2 (0x45a8) +#define AFE_SECURE_MASK_CONN72_3 (0x45ac) +#define AFE_SECURE_MASK_CONN72_4 (0x45b0) +#define AFE_SECURE_MASK_CONN73 (0x45b4) +#define AFE_SECURE_MASK_CONN73_1 (0x45b8) +#define AFE_SECURE_MASK_CONN73_2 (0x45bc) +#define AFE_SECURE_MASK_CONN73_3 (0x45c0) +#define AFE_SECURE_MASK_CONN73_4 (0x45c4) +#define AFE_SECURE_MASK_CONN74 (0x45c8) +#define AFE_SECURE_MASK_CONN74_1 (0x45cc) +#define AFE_SECURE_MASK_CONN74_2 (0x45d0) +#define AFE_SECURE_MASK_CONN74_3 (0x45d4) +#define AFE_SECURE_MASK_CONN74_4 (0x45d8) +#define AFE_SECURE_MASK_CONN75 (0x45dc) +#define AFE_SECURE_MASK_CONN75_1 (0x45e0) +#define AFE_SECURE_MASK_CONN75_2 (0x45e4) +#define AFE_SECURE_MASK_CONN75_3 (0x45e8) +#define AFE_SECURE_MASK_CONN75_4 (0x45ec) +#define AFE_SECURE_MASK_CONN76 (0x45f0) +#define AFE_SECURE_MASK_CONN76_1 (0x45f4) +#define AFE_SECURE_MASK_CONN76_2 (0x45f8) +#define AFE_SECURE_MASK_CONN76_3 (0x45fc) +#define AFE_SECURE_MASK_CONN76_4 (0x4600) +#define AFE_SECURE_MASK_CONN77 (0x4604) +#define AFE_SECURE_MASK_CONN77_1 (0x4608) +#define AFE_SECURE_MASK_CONN77_2 (0x460c) +#define AFE_SECURE_MASK_CONN77_3 (0x4610) +#define AFE_SECURE_MASK_CONN77_4 (0x4614) +#define AFE_SECURE_MASK_CONN78 (0x4618) +#define AFE_SECURE_MASK_CONN78_1 (0x461c) +#define AFE_SECURE_MASK_CONN78_2 (0x4620) +#define AFE_SECURE_MASK_CONN78_3 (0x4624) +#define AFE_SECURE_MASK_CONN78_4 (0x4628) +#define AFE_SECURE_MASK_CONN79 (0x462c) +#define AFE_SECURE_MASK_CONN79_1 (0x4630) +#define AFE_SECURE_MASK_CONN79_2 (0x4634) +#define AFE_SECURE_MASK_CONN79_3 (0x4638) +#define AFE_SECURE_MASK_CONN79_4 (0x463c) +#define AFE_SECURE_MASK_CONN80 (0x4640) +#define AFE_SECURE_MASK_CONN80_1 (0x4644) +#define AFE_SECURE_MASK_CONN80_2 (0x4648) +#define AFE_SECURE_MASK_CONN80_3 (0x464c) +#define AFE_SECURE_MASK_CONN80_4 (0x4650) +#define AFE_SECURE_MASK_CONN81 (0x4654) +#define AFE_SECURE_MASK_CONN81_1 (0x4658) +#define AFE_SECURE_MASK_CONN81_2 (0x465c) +#define AFE_SECURE_MASK_CONN81_3 (0x4660) +#define AFE_SECURE_MASK_CONN81_4 (0x4664) +#define AFE_SECURE_MASK_CONN82 (0x4668) +#define AFE_SECURE_MASK_CONN82_1 (0x466c) +#define AFE_SECURE_MASK_CONN82_2 (0x4670) +#define AFE_SECURE_MASK_CONN82_3 (0x4674) +#define AFE_SECURE_MASK_CONN82_4 (0x4678) +#define AFE_SECURE_MASK_CONN83 (0x467c) +#define AFE_SECURE_MASK_CONN83_1 (0x4680) +#define AFE_SECURE_MASK_CONN83_2 (0x4684) +#define AFE_SECURE_MASK_CONN83_3 (0x4688) +#define AFE_SECURE_MASK_CONN83_4 (0x468c) +#define AFE_SECURE_MASK_CONN84 (0x4690) +#define AFE_SECURE_MASK_CONN84_1 (0x4694) +#define AFE_SECURE_MASK_CONN84_2 (0x4698) +#define AFE_SECURE_MASK_CONN84_3 (0x469c) +#define AFE_SECURE_MASK_CONN84_4 (0x46a0) +#define AFE_SECURE_MASK_CONN85 (0x46a4) +#define AFE_SECURE_MASK_CONN85_1 (0x46a8) +#define AFE_SECURE_MASK_CONN85_2 (0x46ac) +#define AFE_SECURE_MASK_CONN85_3 (0x46b0) +#define AFE_SECURE_MASK_CONN85_4 (0x46b4) +#define AFE_SECURE_MASK_CONN86 (0x46b8) +#define AFE_SECURE_MASK_CONN86_1 (0x46bc) +#define AFE_SECURE_MASK_CONN86_2 (0x46c0) +#define AFE_SECURE_MASK_CONN86_3 (0x46c4) +#define AFE_SECURE_MASK_CONN86_4 (0x46c8) +#define AFE_SECURE_MASK_CONN87 (0x46cc) +#define AFE_SECURE_MASK_CONN87_1 (0x46d0) +#define AFE_SECURE_MASK_CONN87_2 (0x46d4) +#define AFE_SECURE_MASK_CONN87_3 (0x46d8) +#define AFE_SECURE_MASK_CONN87_4 (0x46dc) +#define AFE_SECURE_MASK_CONN88 (0x46e0) +#define AFE_SECURE_MASK_CONN88_1 (0x46e4) +#define AFE_SECURE_MASK_CONN88_2 (0x46e8) +#define AFE_SECURE_MASK_CONN88_3 (0x46ec) +#define AFE_SECURE_MASK_CONN88_4 (0x46f0) +#define AFE_SECURE_MASK_CONN89 (0x46f4) +#define AFE_SECURE_MASK_CONN89_1 (0x46f8) +#define AFE_SECURE_MASK_CONN89_2 (0x46fc) +#define AFE_SECURE_MASK_CONN89_3 (0x4700) +#define AFE_SECURE_MASK_CONN89_4 (0x4704) +#define AFE_SECURE_MASK_CONN90 (0x4708) +#define AFE_SECURE_MASK_CONN90_1 (0x470c) +#define AFE_SECURE_MASK_CONN90_2 (0x4710) +#define AFE_SECURE_MASK_CONN90_3 (0x4714) +#define AFE_SECURE_MASK_CONN90_4 (0x4718) +#define AFE_SECURE_MASK_CONN91 (0x471c) +#define AFE_SECURE_MASK_CONN91_1 (0x4720) +#define AFE_SECURE_MASK_CONN91_2 (0x4724) +#define AFE_SECURE_MASK_CONN91_3 (0x4728) +#define AFE_SECURE_MASK_CONN91_4 (0x472c) +#define AFE_SECURE_MASK_CONN92 (0x4730) +#define AFE_SECURE_MASK_CONN92_1 (0x4734) +#define AFE_SECURE_MASK_CONN92_2 (0x4738) +#define AFE_SECURE_MASK_CONN92_3 (0x473c) +#define AFE_SECURE_MASK_CONN92_4 (0x4740) +#define AFE_SECURE_MASK_CONN93 (0x4744) +#define AFE_SECURE_MASK_CONN93_1 (0x4748) +#define AFE_SECURE_MASK_CONN93_2 (0x474c) +#define AFE_SECURE_MASK_CONN93_3 (0x4750) +#define AFE_SECURE_MASK_CONN93_4 (0x4754) +#define AFE_SECURE_MASK_CONN94 (0x4758) +#define AFE_SECURE_MASK_CONN94_1 (0x475c) +#define AFE_SECURE_MASK_CONN94_2 (0x4760) +#define AFE_SECURE_MASK_CONN94_3 (0x4764) +#define AFE_SECURE_MASK_CONN94_4 (0x4768) +#define AFE_SECURE_MASK_CONN95 (0x476c) +#define AFE_SECURE_MASK_CONN95_1 (0x4770) +#define AFE_SECURE_MASK_CONN95_2 (0x4774) +#define AFE_SECURE_MASK_CONN95_3 (0x4778) +#define AFE_SECURE_MASK_CONN95_4 (0x477c) +#define AFE_SECURE_MASK_CONN96 (0x4780) +#define AFE_SECURE_MASK_CONN96_1 (0x4784) +#define AFE_SECURE_MASK_CONN96_2 (0x4788) +#define AFE_SECURE_MASK_CONN96_3 (0x478c) +#define AFE_SECURE_MASK_CONN96_4 (0x4790) +#define AFE_SECURE_MASK_CONN97 (0x4794) +#define AFE_SECURE_MASK_CONN97_1 (0x4798) +#define AFE_SECURE_MASK_CONN97_2 (0x479c) +#define AFE_SECURE_MASK_CONN97_3 (0x47a0) +#define AFE_SECURE_MASK_CONN97_4 (0x47a4) +#define AFE_SECURE_MASK_CONN98 (0x47a8) +#define AFE_SECURE_MASK_CONN98_1 (0x47ac) +#define AFE_SECURE_MASK_CONN98_2 (0x47b0) +#define AFE_SECURE_MASK_CONN98_3 (0x47b4) +#define AFE_SECURE_MASK_CONN98_4 (0x47b8) +#define AFE_SECURE_MASK_CONN99 (0x47bc) +#define AFE_SECURE_MASK_CONN99_1 (0x47c0) +#define AFE_SECURE_MASK_CONN99_2 (0x47c4) +#define AFE_SECURE_MASK_CONN99_3 (0x47c8) +#define AFE_SECURE_MASK_CONN99_4 (0x47cc) +#define AFE_SECURE_MASK_CONN100 (0x47d0) +#define AFE_SECURE_MASK_CONN100_1 (0x47d4) +#define AFE_SECURE_MASK_CONN100_2 (0x47d8) +#define AFE_SECURE_MASK_CONN100_3 (0x47dc) +#define AFE_SECURE_MASK_CONN100_4 (0x47e0) +#define AFE_SECURE_MASK_CONN101 (0x47e4) +#define AFE_SECURE_MASK_CONN101_1 (0x47e8) +#define AFE_SECURE_MASK_CONN101_2 (0x47ec) +#define AFE_SECURE_MASK_CONN101_3 (0x47f0) +#define AFE_SECURE_MASK_CONN101_4 (0x47f4) +#define AFE_SECURE_MASK_CONN102 (0x47f8) +#define AFE_SECURE_MASK_CONN102_1 (0x47fc) +#define AFE_SECURE_MASK_CONN102_2 (0x4800) +#define AFE_SECURE_MASK_CONN102_3 (0x4804) +#define AFE_SECURE_MASK_CONN102_4 (0x4808) +#define AFE_SECURE_MASK_CONN103 (0x480c) +#define AFE_SECURE_MASK_CONN103_1 (0x4810) +#define AFE_SECURE_MASK_CONN103_2 (0x4814) +#define AFE_SECURE_MASK_CONN103_3 (0x4818) +#define AFE_SECURE_MASK_CONN103_4 (0x481c) +#define AFE_SECURE_MASK_CONN104 (0x4820) +#define AFE_SECURE_MASK_CONN104_1 (0x4824) +#define AFE_SECURE_MASK_CONN104_2 (0x4828) +#define AFE_SECURE_MASK_CONN104_3 (0x482c) +#define AFE_SECURE_MASK_CONN104_4 (0x4830) +#define AFE_SECURE_MASK_CONN105 (0x4834) +#define AFE_SECURE_MASK_CONN105_1 (0x4838) +#define AFE_SECURE_MASK_CONN105_2 (0x483c) +#define AFE_SECURE_MASK_CONN105_3 (0x4840) +#define AFE_SECURE_MASK_CONN105_4 (0x4844) +#define AFE_SECURE_MASK_CONN106 (0x4848) +#define AFE_SECURE_MASK_CONN106_1 (0x484c) +#define AFE_SECURE_MASK_CONN106_2 (0x4850) +#define AFE_SECURE_MASK_CONN106_3 (0x4854) +#define AFE_SECURE_MASK_CONN106_4 (0x4858) +#define AFE_SECURE_MASK_CONN107 (0x485c) +#define AFE_SECURE_MASK_CONN107_1 (0x4860) +#define AFE_SECURE_MASK_CONN107_2 (0x4864) +#define AFE_SECURE_MASK_CONN107_3 (0x4868) +#define AFE_SECURE_MASK_CONN107_4 (0x486c) +#define AFE_SECURE_MASK_CONN108 (0x4870) +#define AFE_SECURE_MASK_CONN108_1 (0x4874) +#define AFE_SECURE_MASK_CONN108_2 (0x4878) +#define AFE_SECURE_MASK_CONN108_3 (0x487c) +#define AFE_SECURE_MASK_CONN108_4 (0x4880) +#define AFE_SECURE_MASK_CONN109 (0x4884) +#define AFE_SECURE_MASK_CONN109_1 (0x4888) +#define AFE_SECURE_MASK_CONN109_2 (0x488c) +#define AFE_SECURE_MASK_CONN109_3 (0x4890) +#define AFE_SECURE_MASK_CONN109_4 (0x4894) +#define AFE_SECURE_MASK_CONN110 (0x4898) +#define AFE_SECURE_MASK_CONN110_1 (0x489c) +#define AFE_SECURE_MASK_CONN110_2 (0x48a0) +#define AFE_SECURE_MASK_CONN110_3 (0x48a4) +#define AFE_SECURE_MASK_CONN110_4 (0x48a8) +#define AFE_SECURE_MASK_CONN111 (0x48ac) +#define AFE_SECURE_MASK_CONN111_1 (0x48b0) +#define AFE_SECURE_MASK_CONN111_2 (0x48b4) +#define AFE_SECURE_MASK_CONN111_3 (0x48b8) +#define AFE_SECURE_MASK_CONN111_4 (0x48bc) +#define AFE_SECURE_MASK_CONN112 (0x48c0) +#define AFE_SECURE_MASK_CONN112_1 (0x48c4) +#define AFE_SECURE_MASK_CONN112_2 (0x48c8) +#define AFE_SECURE_MASK_CONN112_3 (0x48cc) +#define AFE_SECURE_MASK_CONN112_4 (0x48d0) +#define AFE_SECURE_MASK_CONN113 (0x48d4) +#define AFE_SECURE_MASK_CONN113_1 (0x48d8) +#define AFE_SECURE_MASK_CONN113_2 (0x48dc) +#define AFE_SECURE_MASK_CONN113_3 (0x48e0) +#define AFE_SECURE_MASK_CONN113_4 (0x48e4) +#define AFE_SECURE_MASK_CONN114 (0x48e8) +#define AFE_SECURE_MASK_CONN114_1 (0x48ec) +#define AFE_SECURE_MASK_CONN114_2 (0x48f0) +#define AFE_SECURE_MASK_CONN114_3 (0x48f4) +#define AFE_SECURE_MASK_CONN114_4 (0x48f8) +#define AFE_SECURE_MASK_CONN115 (0x48fc) +#define AFE_SECURE_MASK_CONN115_1 (0x4900) +#define AFE_SECURE_MASK_CONN115_2 (0x4904) +#define AFE_SECURE_MASK_CONN115_3 (0x4908) +#define AFE_SECURE_MASK_CONN115_4 (0x490c) +#define AFE_SECURE_MASK_CONN116 (0x4910) +#define AFE_SECURE_MASK_CONN116_1 (0x4914) +#define AFE_SECURE_MASK_CONN116_2 (0x4918) +#define AFE_SECURE_MASK_CONN116_3 (0x491c) +#define AFE_SECURE_MASK_CONN116_4 (0x4920) +#define AFE_SECURE_MASK_CONN117 (0x4924) +#define AFE_SECURE_MASK_CONN117_1 (0x4928) +#define AFE_SECURE_MASK_CONN117_2 (0x492c) +#define AFE_SECURE_MASK_CONN117_3 (0x4930) +#define AFE_SECURE_MASK_CONN117_4 (0x4934) +#define AFE_SECURE_MASK_CONN118 (0x4938) +#define AFE_SECURE_MASK_CONN118_1 (0x493c) +#define AFE_SECURE_MASK_CONN118_2 (0x4940) +#define AFE_SECURE_MASK_CONN118_3 (0x4944) +#define AFE_SECURE_MASK_CONN118_4 (0x4948) +#define AFE_SECURE_MASK_CONN119 (0x494c) +#define AFE_SECURE_MASK_CONN119_1 (0x4950) +#define AFE_SECURE_MASK_CONN119_2 (0x4954) +#define AFE_SECURE_MASK_CONN119_3 (0x4958) +#define AFE_SECURE_MASK_CONN119_4 (0x495c) +#define AFE_SECURE_MASK_CONN120 (0x4960) +#define AFE_SECURE_MASK_CONN120_1 (0x4964) +#define AFE_SECURE_MASK_CONN120_2 (0x4968) +#define AFE_SECURE_MASK_CONN120_3 (0x496c) +#define AFE_SECURE_MASK_CONN120_4 (0x4970) +#define AFE_SECURE_MASK_CONN121 (0x4974) +#define AFE_SECURE_MASK_CONN121_1 (0x4978) +#define AFE_SECURE_MASK_CONN121_2 (0x497c) +#define AFE_SECURE_MASK_CONN121_3 (0x4980) +#define AFE_SECURE_MASK_CONN121_4 (0x4984) +#define AFE_SECURE_MASK_CONN122 (0x4988) +#define AFE_SECURE_MASK_CONN122_1 (0x498c) +#define AFE_SECURE_MASK_CONN122_2 (0x4990) +#define AFE_SECURE_MASK_CONN122_3 (0x4994) +#define AFE_SECURE_MASK_CONN122_4 (0x4998) +#define AFE_SECURE_MASK_CONN123 (0x499c) +#define AFE_SECURE_MASK_CONN123_1 (0x49a0) +#define AFE_SECURE_MASK_CONN123_2 (0x49a4) +#define AFE_SECURE_MASK_CONN123_3 (0x49a8) +#define AFE_SECURE_MASK_CONN123_4 (0x49ac) +#define AFE_SECURE_MASK_CONN124 (0x49b0) +#define AFE_SECURE_MASK_CONN124_1 (0x49b4) +#define AFE_SECURE_MASK_CONN124_2 (0x49b8) +#define AFE_SECURE_MASK_CONN124_3 (0x49bc) +#define AFE_SECURE_MASK_CONN124_4 (0x49c0) +#define AFE_SECURE_MASK_CONN125 (0x49c4) +#define AFE_SECURE_MASK_CONN125_1 (0x49c8) +#define AFE_SECURE_MASK_CONN125_2 (0x49cc) +#define AFE_SECURE_MASK_CONN125_3 (0x49d0) +#define AFE_SECURE_MASK_CONN125_4 (0x49d4) +#define AFE_SECURE_MASK_CONN126 (0x49d8) +#define AFE_SECURE_MASK_CONN126_1 (0x49dc) +#define AFE_SECURE_MASK_CONN126_2 (0x49e0) +#define AFE_SECURE_MASK_CONN126_3 (0x49e4) +#define AFE_SECURE_MASK_CONN126_4 (0x49e8) +#define AFE_SECURE_MASK_CONN127 (0x49ec) +#define AFE_SECURE_MASK_CONN127_1 (0x49f0) +#define AFE_SECURE_MASK_CONN127_2 (0x49f4) +#define AFE_SECURE_MASK_CONN127_3 (0x49f8) +#define AFE_SECURE_MASK_CONN127_4 (0x49fc) +#define AFE_SECURE_MASK_CONN128 (0x4a00) +#define AFE_SECURE_MASK_CONN128_1 (0x4a04) +#define AFE_SECURE_MASK_CONN128_2 (0x4a08) +#define AFE_SECURE_MASK_CONN128_3 (0x4a0c) +#define AFE_SECURE_MASK_CONN128_4 (0x4a10) +#define AFE_SECURE_MASK_CONN129 (0x4a14) +#define AFE_SECURE_MASK_CONN129_1 (0x4a18) +#define AFE_SECURE_MASK_CONN129_2 (0x4a1c) +#define AFE_SECURE_MASK_CONN129_3 (0x4a20) +#define AFE_SECURE_MASK_CONN129_4 (0x4a24) +#define AFE_SECURE_MASK_CONN130 (0x4a28) +#define AFE_SECURE_MASK_CONN130_1 (0x4a2c) +#define AFE_SECURE_MASK_CONN130_2 (0x4a30) +#define AFE_SECURE_MASK_CONN130_3 (0x4a34) +#define AFE_SECURE_MASK_CONN130_4 (0x4a38) +#define AFE_SECURE_MASK_CONN131 (0x4a3c) +#define AFE_SECURE_MASK_CONN131_1 (0x4a40) +#define AFE_SECURE_MASK_CONN131_2 (0x4a44) +#define AFE_SECURE_MASK_CONN131_3 (0x4a48) +#define AFE_SECURE_MASK_CONN131_4 (0x4a4c) +#define AFE_SECURE_MASK_CONN132 (0x4a50) +#define AFE_SECURE_MASK_CONN132_1 (0x4a54) +#define AFE_SECURE_MASK_CONN132_2 (0x4a58) +#define AFE_SECURE_MASK_CONN132_3 (0x4a5c) +#define AFE_SECURE_MASK_CONN132_4 (0x4a60) +#define AFE_SECURE_MASK_CONN133 (0x4a64) +#define AFE_SECURE_MASK_CONN133_1 (0x4a68) +#define AFE_SECURE_MASK_CONN133_2 (0x4a6c) +#define AFE_SECURE_MASK_CONN133_3 (0x4a70) +#define AFE_SECURE_MASK_CONN133_4 (0x4a74) +#define AFE_SECURE_MASK_CONN134 (0x4a78) +#define AFE_SECURE_MASK_CONN134_1 (0x4a7c) +#define AFE_SECURE_MASK_CONN134_2 (0x4a80) +#define AFE_SECURE_MASK_CONN134_3 (0x4a84) +#define AFE_SECURE_MASK_CONN134_4 (0x4a88) +#define AFE_SECURE_MASK_CONN135 (0x4a8c) +#define AFE_SECURE_MASK_CONN135_1 (0x4a90) +#define AFE_SECURE_MASK_CONN135_2 (0x4a94) +#define AFE_SECURE_MASK_CONN135_3 (0x4a98) +#define AFE_SECURE_MASK_CONN135_4 (0x4a9c) +#define AFE_SECURE_MASK_CONN136 (0x4aa0) +#define AFE_SECURE_MASK_CONN136_1 (0x4aa4) +#define AFE_SECURE_MASK_CONN136_2 (0x4aa8) +#define AFE_SECURE_MASK_CONN136_3 (0x4aac) +#define AFE_SECURE_MASK_CONN136_4 (0x4ab0) +#define AFE_SECURE_MASK_CONN137 (0x4ab4) +#define AFE_SECURE_MASK_CONN137_1 (0x4ab8) +#define AFE_SECURE_MASK_CONN137_2 (0x4abc) +#define AFE_SECURE_MASK_CONN137_3 (0x4ac0) +#define AFE_SECURE_MASK_CONN137_4 (0x4ac4) +#define AFE_SECURE_MASK_CONN138 (0x4ac8) +#define AFE_SECURE_MASK_CONN138_1 (0x4acc) +#define AFE_SECURE_MASK_CONN138_2 (0x4ad0) +#define AFE_SECURE_MASK_CONN138_3 (0x4ad4) +#define AFE_SECURE_MASK_CONN138_4 (0x4ad8) +#define AFE_SECURE_MASK_CONN139 (0x4adc) +#define AFE_SECURE_MASK_CONN139_1 (0x4ae0) +#define AFE_SECURE_MASK_CONN139_2 (0x4ae4) +#define AFE_SECURE_MASK_CONN139_3 (0x4ae8) +#define AFE_SECURE_MASK_CONN139_4 (0x4aec) +#define AFE_SECURE_MASK_CONN_RS (0x4af0) +#define AFE_SECURE_MASK_CONN_RS_1 (0x4af4) +#define AFE_SECURE_MASK_CONN_RS_2 (0x4af8) +#define AFE_SECURE_MASK_CONN_RS_3 (0x4afc) +#define AFE_SECURE_MASK_CONN_RS_4 (0x4b00) +#define AFE_SECURE_MASK_CONN_16BIT (0x4b04) +#define AFE_SECURE_MASK_CONN_16BIT_1 (0x4b08) +#define AFE_SECURE_MASK_CONN_16BIT_2 (0x4b0c) +#define AFE_SECURE_MASK_CONN_16BIT_3 (0x4b10) +#define AFE_SECURE_MASK_CONN_16BIT_4 (0x4b14) +#define AFE_SECURE_MASK_CONN_24BIT (0x4b18) +#define AFE_SECURE_MASK_CONN_24BIT_1 (0x4b1c) +#define AFE_SECURE_MASK_CONN_24BIT_2 (0x4b20) +#define AFE_SECURE_MASK_CONN_24BIT_3 (0x4b24) +#define AFE_SECURE_MASK_CONN_24BIT_4 (0x4b28) +#define AFE_GASRC0_NEW_CON0 (0x4c40) +#define AFE_GASRC0_NEW_CON1 (0x4c44) +#define AFE_GASRC0_NEW_CON2 (0x4c48) +#define AFE_GASRC0_NEW_CON3 (0x4c4c) +#define AFE_GASRC0_NEW_CON4 (0x4c50) +#define AFE_GASRC0_NEW_CON5 (0x4c54) +#define AFE_GASRC0_NEW_CON6 (0x4c58) +#define AFE_GASRC0_NEW_CON7 (0x4c5c) +#define AFE_GASRC0_NEW_CON8 (0x4c60) +#define AFE_GASRC0_NEW_CON9 (0x4c64) +#define AFE_GASRC0_NEW_CON10 (0x4c68) +#define AFE_GASRC0_NEW_CON11 (0x4c6c) +#define AFE_GASRC0_NEW_CON12 (0x4c70) +#define AFE_GASRC0_NEW_CON13 (0x4c74) +#define AFE_GASRC0_NEW_CON14 (0x4c78) +#define AFE_GASRC1_NEW_CON0 (0x4c80) +#define AFE_GASRC1_NEW_CON1 (0x4c84) +#define AFE_GASRC1_NEW_CON2 (0x4c88) +#define AFE_GASRC1_NEW_CON3 (0x4c8c) +#define AFE_GASRC1_NEW_CON4 (0x4c90) +#define AFE_GASRC1_NEW_CON5 (0x4c94) +#define AFE_GASRC1_NEW_CON6 (0x4c98) +#define AFE_GASRC1_NEW_CON7 (0x4c9c) +#define AFE_GASRC1_NEW_CON8 (0x4ca0) +#define AFE_GASRC1_NEW_CON9 (0x4ca4) +#define AFE_GASRC1_NEW_CON10 (0x4ca8) +#define AFE_GASRC1_NEW_CON11 (0x4cac) +#define AFE_GASRC1_NEW_CON12 (0x4cb0) +#define AFE_GASRC1_NEW_CON13 (0x4cb4) +#define AFE_GASRC1_NEW_CON14 (0x4cb8) +#define AFE_GASRC2_NEW_CON0 (0x4cc0) +#define AFE_GASRC2_NEW_CON1 (0x4cc4) +#define AFE_GASRC2_NEW_CON2 (0x4cc8) +#define AFE_GASRC2_NEW_CON3 (0x4ccc) +#define AFE_GASRC2_NEW_CON4 (0x4cd0) +#define AFE_GASRC2_NEW_CON5 (0x4cd4) +#define AFE_GASRC2_NEW_CON6 (0x4cd8) +#define AFE_GASRC2_NEW_CON7 (0x4cdc) +#define AFE_GASRC2_NEW_CON8 (0x4ce0) +#define AFE_GASRC2_NEW_CON9 (0x4ce4) +#define AFE_GASRC2_NEW_CON10 (0x4ce8) +#define AFE_GASRC2_NEW_CON11 (0x4cec) +#define AFE_GASRC2_NEW_CON12 (0x4cf0) +#define AFE_GASRC2_NEW_CON13 (0x4cf4) +#define AFE_GASRC2_NEW_CON14 (0x4cf8) +#define AFE_GASRC3_NEW_CON0 (0x4d00) +#define AFE_GASRC3_NEW_CON1 (0x4d04) +#define AFE_GASRC3_NEW_CON2 (0x4d08) +#define AFE_GASRC3_NEW_CON3 (0x4d0c) +#define AFE_GASRC3_NEW_CON4 (0x4d10) +#define AFE_GASRC3_NEW_CON5 (0x4d14) +#define AFE_GASRC3_NEW_CON6 (0x4d18) +#define AFE_GASRC3_NEW_CON7 (0x4d1c) +#define AFE_GASRC3_NEW_CON8 (0x4d20) +#define AFE_GASRC3_NEW_CON9 (0x4d24) +#define AFE_GASRC3_NEW_CON10 (0x4d28) +#define AFE_GASRC3_NEW_CON11 (0x4d2c) +#define AFE_GASRC3_NEW_CON12 (0x4d30) +#define AFE_GASRC3_NEW_CON13 (0x4d34) +#define AFE_GASRC3_NEW_CON14 (0x4d38) +#define AFE_GASRC4_NEW_CON0 (0x4d40) +#define AFE_GASRC4_NEW_CON1 (0x4d44) +#define AFE_GASRC4_NEW_CON2 (0x4d48) +#define AFE_GASRC4_NEW_CON3 (0x4d4c) +#define AFE_GASRC4_NEW_CON4 (0x4d50) +#define AFE_GASRC4_NEW_CON5 (0x4d54) +#define AFE_GASRC4_NEW_CON6 (0x4d58) +#define AFE_GASRC4_NEW_CON7 (0x4d5c) +#define AFE_GASRC4_NEW_CON8 (0x4d60) +#define AFE_GASRC4_NEW_CON9 (0x4d64) +#define AFE_GASRC4_NEW_CON10 (0x4d68) +#define AFE_GASRC4_NEW_CON11 (0x4d6c) +#define AFE_GASRC4_NEW_CON12 (0x4d70) +#define AFE_GASRC4_NEW_CON13 (0x4d74) +#define AFE_GASRC4_NEW_CON14 (0x4d78) +#define AFE_GASRC5_NEW_CON0 (0x4d80) +#define AFE_GASRC5_NEW_CON1 (0x4d84) +#define AFE_GASRC5_NEW_CON2 (0x4d88) +#define AFE_GASRC5_NEW_CON3 (0x4d8c) +#define AFE_GASRC5_NEW_CON4 (0x4d90) +#define AFE_GASRC5_NEW_CON5 (0x4d94) +#define AFE_GASRC5_NEW_CON6 (0x4d98) +#define AFE_GASRC5_NEW_CON7 (0x4d9c) +#define AFE_GASRC5_NEW_CON8 (0x4da0) +#define AFE_GASRC5_NEW_CON9 (0x4da4) +#define AFE_GASRC5_NEW_CON10 (0x4da8) +#define AFE_GASRC5_NEW_CON11 (0x4dac) +#define AFE_GASRC5_NEW_CON12 (0x4db0) +#define AFE_GASRC5_NEW_CON13 (0x4db4) +#define AFE_GASRC5_NEW_CON14 (0x4db8) +#define AFE_GASRC6_NEW_CON0 (0x4dc0) +#define AFE_GASRC6_NEW_CON1 (0x4dc4) +#define AFE_GASRC6_NEW_CON2 (0x4dc8) +#define AFE_GASRC6_NEW_CON3 (0x4dcc) +#define AFE_GASRC6_NEW_CON4 (0x4dd0) +#define AFE_GASRC6_NEW_CON5 (0x4dd4) +#define AFE_GASRC6_NEW_CON6 (0x4dd8) +#define AFE_GASRC6_NEW_CON7 (0x4ddc) +#define AFE_GASRC6_NEW_CON8 (0x4de0) +#define AFE_GASRC6_NEW_CON9 (0x4de4) +#define AFE_GASRC6_NEW_CON10 (0x4de8) +#define AFE_GASRC6_NEW_CON11 (0x4dec) +#define AFE_GASRC6_NEW_CON12 (0x4df0) +#define AFE_GASRC6_NEW_CON13 (0x4df4) +#define AFE_GASRC6_NEW_CON14 (0x4df8) +#define AFE_GASRC7_NEW_CON0 (0x4e00) +#define AFE_GASRC7_NEW_CON1 (0x4e04) +#define AFE_GASRC7_NEW_CON2 (0x4e08) +#define AFE_GASRC7_NEW_CON3 (0x4e0c) +#define AFE_GASRC7_NEW_CON4 (0x4e10) +#define AFE_GASRC7_NEW_CON5 (0x4e14) +#define AFE_GASRC7_NEW_CON6 (0x4e18) +#define AFE_GASRC7_NEW_CON7 (0x4e1c) +#define AFE_GASRC7_NEW_CON8 (0x4e20) +#define AFE_GASRC7_NEW_CON9 (0x4e24) +#define AFE_GASRC7_NEW_CON10 (0x4e28) +#define AFE_GASRC7_NEW_CON11 (0x4e2c) +#define AFE_GASRC7_NEW_CON12 (0x4e30) +#define AFE_GASRC7_NEW_CON13 (0x4e34) +#define AFE_GASRC7_NEW_CON14 (0x4e38) +#define AFE_GASRC8_NEW_CON0 (0x4e40) +#define AFE_GASRC8_NEW_CON1 (0x4e44) +#define AFE_GASRC8_NEW_CON2 (0x4e48) +#define AFE_GASRC8_NEW_CON3 (0x4e4c) +#define AFE_GASRC8_NEW_CON4 (0x4e50) +#define AFE_GASRC8_NEW_CON5 (0x4e54) +#define AFE_GASRC8_NEW_CON6 (0x4e58) +#define AFE_GASRC8_NEW_CON7 (0x4e5c) +#define AFE_GASRC8_NEW_CON8 (0x4e60) +#define AFE_GASRC8_NEW_CON9 (0x4e64) +#define AFE_GASRC8_NEW_CON10 (0x4e68) +#define AFE_GASRC8_NEW_CON11 (0x4e6c) +#define AFE_GASRC8_NEW_CON12 (0x4e70) +#define AFE_GASRC8_NEW_CON13 (0x4e74) +#define AFE_GASRC8_NEW_CON14 (0x4e78) +#define AFE_GASRC9_NEW_CON0 (0x4e80) +#define AFE_GASRC9_NEW_CON1 (0x4e84) +#define AFE_GASRC9_NEW_CON2 (0x4e88) +#define AFE_GASRC9_NEW_CON3 (0x4e8c) +#define AFE_GASRC9_NEW_CON4 (0x4e90) +#define AFE_GASRC9_NEW_CON5 (0x4e94) +#define AFE_GASRC9_NEW_CON6 (0x4e98) +#define AFE_GASRC9_NEW_CON7 (0x4e9c) +#define AFE_GASRC9_NEW_CON8 (0x4ea0) +#define AFE_GASRC9_NEW_CON9 (0x4ea4) +#define AFE_GASRC9_NEW_CON10 (0x4ea8) +#define AFE_GASRC9_NEW_CON11 (0x4eac) +#define AFE_GASRC9_NEW_CON12 (0x4eb0) +#define AFE_GASRC9_NEW_CON13 (0x4eb4) +#define AFE_GASRC9_NEW_CON14 (0x4eb8) +#define AFE_GASRC10_NEW_CON0 (0x4ec0) +#define AFE_GASRC10_NEW_CON1 (0x4ec4) +#define AFE_GASRC10_NEW_CON2 (0x4ec8) +#define AFE_GASRC10_NEW_CON3 (0x4ecc) +#define AFE_GASRC10_NEW_CON4 (0x4ed0) +#define AFE_GASRC10_NEW_CON5 (0x4ed4) +#define AFE_GASRC10_NEW_CON6 (0x4ed8) +#define AFE_GASRC10_NEW_CON7 (0x4edc) +#define AFE_GASRC10_NEW_CON8 (0x4ee0) +#define AFE_GASRC10_NEW_CON9 (0x4ee4) +#define AFE_GASRC10_NEW_CON10 (0x4ee8) +#define AFE_GASRC10_NEW_CON11 (0x4eec) +#define AFE_GASRC10_NEW_CON12 (0x4ef0) +#define AFE_GASRC10_NEW_CON13 (0x4ef4) +#define AFE_GASRC10_NEW_CON14 (0x4ef8) +#define AFE_GASRC11_NEW_CON0 (0x4f00) +#define AFE_GASRC11_NEW_CON1 (0x4f04) +#define AFE_GASRC11_NEW_CON2 (0x4f08) +#define AFE_GASRC11_NEW_CON3 (0x4f0c) +#define AFE_GASRC11_NEW_CON4 (0x4f10) +#define AFE_GASRC11_NEW_CON5 (0x4f14) +#define AFE_GASRC11_NEW_CON6 (0x4f18) +#define AFE_GASRC11_NEW_CON7 (0x4f1c) +#define AFE_GASRC11_NEW_CON8 (0x4f20) +#define AFE_GASRC11_NEW_CON9 (0x4f24) +#define AFE_GASRC11_NEW_CON10 (0x4f28) +#define AFE_GASRC11_NEW_CON11 (0x4f2c) +#define AFE_GASRC11_NEW_CON12 (0x4f30) +#define AFE_GASRC11_NEW_CON13 (0x4f34) +#define AFE_GASRC11_NEW_CON14 (0x4f38) +#define AFE_GASRC12_NEW_CON0 (0x4f40) +#define AFE_GASRC12_NEW_CON1 (0x4f44) +#define AFE_GASRC12_NEW_CON2 (0x4f48) +#define AFE_GASRC12_NEW_CON3 (0x4f4c) +#define AFE_GASRC12_NEW_CON4 (0x4f50) +#define AFE_GASRC12_NEW_CON5 (0x4f54) +#define AFE_GASRC12_NEW_CON6 (0x4f58) +#define AFE_GASRC12_NEW_CON7 (0x4f5c) +#define AFE_GASRC12_NEW_CON8 (0x4f60) +#define AFE_GASRC12_NEW_CON9 (0x4f64) +#define AFE_GASRC12_NEW_CON10 (0x4f68) +#define AFE_GASRC12_NEW_CON11 (0x4f6c) +#define AFE_GASRC12_NEW_CON12 (0x4f70) +#define AFE_GASRC12_NEW_CON13 (0x4f74) +#define AFE_GASRC12_NEW_CON14 (0x4f78) +#define AFE_GASRC13_NEW_CON0 (0x4f80) +#define AFE_GASRC13_NEW_CON1 (0x4f84) +#define AFE_GASRC13_NEW_CON2 (0x4f88) +#define AFE_GASRC13_NEW_CON3 (0x4f8c) +#define AFE_GASRC13_NEW_CON4 (0x4f90) +#define AFE_GASRC13_NEW_CON5 (0x4f94) +#define AFE_GASRC13_NEW_CON6 (0x4f98) +#define AFE_GASRC13_NEW_CON7 (0x4f9c) +#define AFE_GASRC13_NEW_CON8 (0x4fa0) +#define AFE_GASRC13_NEW_CON9 (0x4fa4) +#define AFE_GASRC13_NEW_CON10 (0x4fa8) +#define AFE_GASRC13_NEW_CON11 (0x4fac) +#define AFE_GASRC13_NEW_CON12 (0x4fb0) +#define AFE_GASRC13_NEW_CON13 (0x4fb4) +#define AFE_GASRC13_NEW_CON14 (0x4fb8) +#define AFE_GASRC14_NEW_CON0 (0x4fc0) +#define AFE_GASRC14_NEW_CON1 (0x4fc4) +#define AFE_GASRC14_NEW_CON2 (0x4fc8) +#define AFE_GASRC14_NEW_CON3 (0x4fcc) +#define AFE_GASRC14_NEW_CON4 (0x4fd0) +#define AFE_GASRC14_NEW_CON5 (0x4fd4) +#define AFE_GASRC14_NEW_CON6 (0x4fd8) +#define AFE_GASRC14_NEW_CON7 (0x4fdc) +#define AFE_GASRC14_NEW_CON8 (0x4fe0) +#define AFE_GASRC14_NEW_CON9 (0x4fe4) +#define AFE_GASRC14_NEW_CON10 (0x4fe8) +#define AFE_GASRC14_NEW_CON11 (0x4fec) +#define AFE_GASRC14_NEW_CON12 (0x4ff0) +#define AFE_GASRC14_NEW_CON13 (0x4ff4) +#define AFE_GASRC14_NEW_CON14 (0x4ff8) +#define AFE_GASRC15_NEW_CON0 (0x5000) +#define AFE_GASRC15_NEW_CON1 (0x5004) +#define AFE_GASRC15_NEW_CON2 (0x5008) +#define AFE_GASRC15_NEW_CON3 (0x500c) +#define AFE_GASRC15_NEW_CON4 (0x5010) +#define AFE_GASRC15_NEW_CON5 (0x5014) +#define AFE_GASRC15_NEW_CON6 (0x5018) +#define AFE_GASRC15_NEW_CON7 (0x501c) +#define AFE_GASRC15_NEW_CON8 (0x5020) +#define AFE_GASRC15_NEW_CON9 (0x5024) +#define AFE_GASRC15_NEW_CON10 (0x5028) +#define AFE_GASRC15_NEW_CON11 (0x502c) +#define AFE_GASRC15_NEW_CON12 (0x5030) +#define AFE_GASRC15_NEW_CON13 (0x5034) +#define AFE_GASRC15_NEW_CON14 (0x5038) +#define AFE_GASRC16_NEW_CON0 (0x5040) +#define AFE_GASRC16_NEW_CON1 (0x5044) +#define AFE_GASRC16_NEW_CON2 (0x5048) +#define AFE_GASRC16_NEW_CON3 (0x504c) +#define AFE_GASRC16_NEW_CON4 (0x5050) +#define AFE_GASRC16_NEW_CON5 (0x5054) +#define AFE_GASRC16_NEW_CON6 (0x5058) +#define AFE_GASRC16_NEW_CON7 (0x505c) +#define AFE_GASRC16_NEW_CON8 (0x5060) +#define AFE_GASRC16_NEW_CON9 (0x5064) +#define AFE_GASRC16_NEW_CON10 (0x5068) +#define AFE_GASRC16_NEW_CON11 (0x506c) +#define AFE_GASRC16_NEW_CON12 (0x5070) +#define AFE_GASRC16_NEW_CON13 (0x5074) +#define AFE_GASRC16_NEW_CON14 (0x5078) +#define AFE_GASRC17_NEW_CON0 (0x5080) +#define AFE_GASRC17_NEW_CON1 (0x5084) +#define AFE_GASRC17_NEW_CON2 (0x5088) +#define AFE_GASRC17_NEW_CON3 (0x508c) +#define AFE_GASRC17_NEW_CON4 (0x5090) +#define AFE_GASRC17_NEW_CON5 (0x5094) +#define AFE_GASRC17_NEW_CON6 (0x5098) +#define AFE_GASRC17_NEW_CON7 (0x509c) +#define AFE_GASRC17_NEW_CON8 (0x50a0) +#define AFE_GASRC17_NEW_CON9 (0x50a4) +#define AFE_GASRC17_NEW_CON10 (0x50a8) +#define AFE_GASRC17_NEW_CON11 (0x50ac) +#define AFE_GASRC17_NEW_CON12 (0x50b0) +#define AFE_GASRC17_NEW_CON13 (0x50b4) +#define AFE_GASRC17_NEW_CON14 (0x50b8) +#define AFE_GASRC18_NEW_CON0 (0x50c0) +#define AFE_GASRC18_NEW_CON1 (0x50c4) +#define AFE_GASRC18_NEW_CON2 (0x50c8) +#define AFE_GASRC18_NEW_CON3 (0x50cc) +#define AFE_GASRC18_NEW_CON4 (0x50d0) +#define AFE_GASRC18_NEW_CON5 (0x50d4) +#define AFE_GASRC18_NEW_CON6 (0x50d8) +#define AFE_GASRC18_NEW_CON7 (0x50dc) +#define AFE_GASRC18_NEW_CON8 (0x50e0) +#define AFE_GASRC18_NEW_CON9 (0x50e4) +#define AFE_GASRC18_NEW_CON10 (0x50e8) +#define AFE_GASRC18_NEW_CON11 (0x50ec) +#define AFE_GASRC18_NEW_CON12 (0x50f0) +#define AFE_GASRC18_NEW_CON13 (0x50f4) +#define AFE_GASRC18_NEW_CON14 (0x50f8) +#define AFE_GASRC19_NEW_CON0 (0x5100) +#define AFE_GASRC19_NEW_CON1 (0x5104) +#define AFE_GASRC19_NEW_CON2 (0x5108) +#define AFE_GASRC19_NEW_CON3 (0x510c) +#define AFE_GASRC19_NEW_CON4 (0x5110) +#define AFE_GASRC19_NEW_CON5 (0x5114) +#define AFE_GASRC19_NEW_CON6 (0x5118) +#define AFE_GASRC19_NEW_CON7 (0x511c) +#define AFE_GASRC19_NEW_CON8 (0x5120) +#define AFE_GASRC19_NEW_CON9 (0x5124) +#define AFE_GASRC19_NEW_CON10 (0x5128) +#define AFE_GASRC19_NEW_CON11 (0x512c) +#define AFE_GASRC19_NEW_CON12 (0x5130) +#define AFE_GASRC19_NEW_CON13 (0x5134) +#define AFE_GASRC19_NEW_CON14 (0x5138) + +#define AFE_MAX_REGISTER (AFE_GASRC19_NEW_CON14) + +/* ASYS_TOP_CON */ +#define ASYS_TOP_CON_A1SYS_TIMING_ON BIT(0) +#define ASYS_TOP_CON_A2SYS_TIMING_ON BIT(1) +#define ASYS_TOP_CON_A3SYS_TIMING_ON BIT(4) +#define ASYS_TOP_CON_A4SYS_TIMING_ON BIT(5) +#define ASYS_TOP_CON_26M_TIMING_ON BIT(2) + +/* PWR2_TOP_CON0 */ +#define PWR2_TOP_CON_DMIC8_SRC_SEL_MASK GENMASK(31, 29) +#define PWR2_TOP_CON_DMIC7_SRC_SEL_MASK GENMASK(28, 26) +#define PWR2_TOP_CON_DMIC6_SRC_SEL_MASK GENMASK(25, 23) +#define PWR2_TOP_CON_DMIC5_SRC_SEL_MASK GENMASK(22, 20) +#define PWR2_TOP_CON_DMIC4_SRC_SEL_MASK GENMASK(19, 17) +#define PWR2_TOP_CON_DMIC3_SRC_SEL_MASK GENMASK(16, 14) +#define PWR2_TOP_CON_DMIC2_SRC_SEL_MASK GENMASK(13, 11) +#define PWR2_TOP_CON_DMIC1_SRC_SEL_MASK GENMASK(10, 8) +#define PWR2_TOP_CON_DMIC8_SRC_SEL_VAL(x) ((x) << 29) +#define PWR2_TOP_CON_DMIC7_SRC_SEL_VAL(x) ((x) << 26) +#define PWR2_TOP_CON_DMIC6_SRC_SEL_VAL(x) ((x) << 23) +#define PWR2_TOP_CON_DMIC5_SRC_SEL_VAL(x) ((x) << 20) +#define PWR2_TOP_CON_DMIC4_SRC_SEL_VAL(x) ((x) << 17) +#define PWR2_TOP_CON_DMIC3_SRC_SEL_VAL(x) ((x) << 14) +#define PWR2_TOP_CON_DMIC2_SRC_SEL_VAL(x) ((x) << 11) +#define PWR2_TOP_CON_DMIC1_SRC_SEL_VAL(x) ((x) << 8) + +/* PWR2_TOP_CON1 */ +#define PWR2_TOP_CON1_DMIC_CKDIV_ON BIT(1) + +/* PCM_INTF_CON1 */ +#define PCM_INTF_CON1_SYNC_OUT_INV BIT(23) +#define PCM_INTF_CON1_BCLK_OUT_INV BIT(22) +#define PCM_INTF_CON1_CLK_OUT_INV_MASK GENMASK(23, 22) +#define PCM_INTF_CON1_SYNC_IN_INV BIT(21) +#define PCM_INTF_CON1_BCLK_IN_INV BIT(20) +#define PCM_INTF_CON1_CLK_IN_INV_MASK GENMASK(21, 20) +#define PCM_INTF_CON1_PCM_24BIT (0x1 << 16) +#define PCM_INTF_CON1_PCM_16BIT (0x0 << 16) +#define PCM_INTF_CON1_PCM_BIT_MASK BIT(16) +#define PCM_INTF_CON1_PCM_WLEN_32BCK (0x0 << 14) +#define PCM_INTF_CON1_PCM_WLEN_64BCK (0x1 << 14) +#define PCM_INTF_CON1_PCM_WLEN_MASK BIT(14) +#define PCM_INTF_CON1_SYNC_LENGTH(x) (((x) & 0x1f) << 9) +#define PCM_INTF_CON1_SYNC_LENGTH_MASK (0x1f << 9) +#define PCM_INTF_CON1_PCM_SLAVE (0x1 << 5) +#define PCM_INTF_CON1_PCM_MASTER (0x0 << 5) +#define PCM_INTF_CON1_PCM_M_S_MASK BIT(5) +#define PCM_INTF_CON1_PCM_MODE(x) (((x) & 0x3) << 3) +#define PCM_INTF_CON1_PCM_MODE_MASK (0x3 << 3) +#define PCM_INTF_CON1_PCM_FMT(x) (((x) & 0x3) << 1) +#define PCM_INTF_CON1_PCM_FMT_MASK (0x3 << 1) +#define PCM_INTF_CON1_PCM_EN BIT(0) + +/* PCM_INTF_CON2 */ +#define PCM_INTF_CON2_CLK_DOMAIN_SEL(x) (((x) & 0x3) << 23) +#define PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK (0x3 << 23) +#define PCM_INTF_CON2_SYNC_FREQ_MODE(x) (((x) & 0x1f) << 12) +#define PCM_INTF_CON2_SYNC_FREQ_MODE_MASK (0x1f << 12) +#define PCM_INTF_CON2_PCM_TX2RX_LPBK BIT(8) + +/* AFE_MPHONE_MULTIx_CON0 */ +#define AFE_MPHONE_MULTI_CON0_16BIT_SWAP BIT(3) +#define AFE_MPHONE_MULTI_CON0_16BIT_SWAP_MASK BIT(3) +#define AFE_MPHONE_MULTI_CON0_24BIT_DATA (0x1 << 1) +#define AFE_MPHONE_MULTI_CON0_16BIT_DATA (0x0 << 1) +#define AFE_MPHONE_MULIT_CON0_24BIT_DATA_MASK BIT(1) +#define AFE_MPHONE_MULTI_CON0_EN BIT(0) +#define AFE_MPHONE_MULTI_CON0_EN_MASK BIT(0) + +/* AFE_MPHONE_MULTIx_CON1 */ +#define AFE_MPHONE_MULTI_CON1_SYNC_ON BIT(24) +#define AFE_MPHONE_MULTI_CON1_SYNC_ON_MASK BIT(24) +#define AFE_MPHONE_MULTI_CON1_24BIT_SWAP_BYPASS BIT(22) +#define AFE_MPHONE_MULTI_CON1_24BIT_SWAP_BYPASS_MASK BIT(22) +#define AFE_MPHONE_MULTI_CON1_NON_COMPACT_MODE (0x1 << 19) +#define AFE_MPHONE_MULTI_CON1_COMPACT_MODE (0x0 << 19) +#define AFE_MPHONE_MULTI_CON1_NON_COMPACT_MODE_MASK BIT(19) +#define AFE_MPHONE_MULTI_CON1_HBR_MODE BIT(18) +#define AFE_MPHONE_MULTI_CON1_HBR_MODE_MASK BIT(18) +#define AFE_MPHONE_MULTI_CON1_LRCK_32_CYCLE (0x2 << 16) +#define AFE_MPHONE_MULTI_CON1_LRCK_24_CYCLE (0x1 << 16) +#define AFE_MPHONE_MULTI_CON1_LRCK_16_CYCLE (0x0 << 16) +#define AFE_MPHONE_MULTI_CON1_LRCK_CYCLE_SEL_MASK GENMASK(17, 16) +#define AFE_MPHONE_MULTI_CON1_LRCK_INV BIT(15) +#define AFE_MPHONE_MULTI_CON1_LRCK_INV_MASK BIT(15) +#define AFE_MPHONE_MULTI_CON1_DELAY_DATA BIT(14) +#define AFE_MPHONE_MULTI_CON1_DELAY_DATA_MASK BIT(14) +#define AFE_MPHONE_MULTI_CON1_LEFT_ALIGN BIT(13) +#define AFE_MPHONE_MULTI_CON1_LEFT_ALIGN_MASK BIT(13) +#define AFE_MPHONE_MULTI_CON1_BIT_NUM(x) ((((x) - 1) & 0x1f) << 8) +#define AFE_MPHONE_MULTI_CON1_BIT_NUM_MASK GENMASK(12, 8) +#define AFE_MPHONE_MULTI_CON1_BCK_INV BIT(6) +#define AFE_MPHONE_MULTI_CON1_BCK_INV_MASK BIT(6) +#define AFE_MPHONE_MULTI_CON1_CH_NUM(x) ((((x) >> 1) - 1) & 0x3) +#define AFE_MPHONE_MULTI_CON1_CH_NUM_MASK GENMASK(1, 0) + +/* AFE_MPHONE_MULTIx_CON2 */ +#define AFE_MPHONE_MULTI_CON2_SEL_SPDIFIN BIT(19) +#define AFE_MPHONE_MULTI_CON2_SEL_SPDIFIN_MASK BIT(19) + +/* AFE_AUD_PAD_TOP */ +#define RG_RX_PROTOCOL2 BIT(3) +#define RG_RX_FIFO_ON BIT(0) + +/* AFE_ADDA_MTKAIF_CFG0 */ +#define MTKAIF_RXIF_CLKINV_ADC BIT(31) +#define MTKAIF_RXIF_PROTOCOL2 BIT(16) +#define MTKAIF_TXIF_PROTOCOL2 BIT(4) +#define MTKAIF_TXIF_8TO5 BIT(2) +#define MTKAIF_RXIF_8TO5 BIT(1) +#define MTKAIF_IF_LOOPBACK1 BIT(0) + +/* AFE_ADDA_MTKAIF_RX_CFG2 */ +#define MTKAIF_RXIF_DELAY_CYCLE(x) ((x) << 12) +#define MTKAIF_RXIF_DELAY_CYCLE_MASK GENMASK(15, 12) +#define MTKAIF_RXIF_DELAY_DATA BIT(8) +#define MTKAIF_RXIF_DELAY_DATA_SHIFT 8 + +/* AFE_ADDA_MTKAIF_SYNCWORD_CFG */ +#define ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE BIT(23) + +/* AFE_DMICx_UL_SRC_CON0 */ +#define AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH1(x) (((x) & 0x7) << 27) +#define AFE_DMIC_UL_SRC_CON0_UL_PHASE_SEL_CH2(x) (((x) & 0x7) << 24) +#define AFE_DMIC_UL_SRC_CON0_UL_TWO_WIRE_MODE_CTL BIT(23) +#define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH2_CTL BIT(22) +#define AFE_DMIC_UL_SRC_CON0_UL_MODE_3P25M_CH1_CTL BIT(21) +#define AFE_DMIC_UL_VOICE_MODE(x) (((x) & 0x7) << 17) +#define AFE_DMIC_UL_CON0_VOCIE_MODE_8K AFE_DMIC_UL_VOICE_MODE(0) +#define AFE_DMIC_UL_CON0_VOCIE_MODE_16K AFE_DMIC_UL_VOICE_MODE(1) +#define AFE_DMIC_UL_CON0_VOCIE_MODE_32K AFE_DMIC_UL_VOICE_MODE(2) +#define AFE_DMIC_UL_CON0_VOCIE_MODE_48K AFE_DMIC_UL_VOICE_MODE(3) +#define AFE_DMIC_UL_SRC_CON0_UL_IIR_MODE_CTL(x) (((x) & 0x7) << 7) +#define AFE_DMIC_UL_SRC_CON0_UL_IIR_ON_TMP_CTL BIT(10) +#define AFE_DMIC_UL_SRC_CON0_UL_SDM_3_LEVEL_CTL BIT(1) +#define AFE_DMIC_UL_SRC_CON0_UL_SRC_ON_TMP_CTL BIT(0) + +/* ETDM_INx_AFIFO_CON */ +#define ETDM_IN_USE_AFIFO BIT(8) +#define ETDM_IN_AFIFO_CLOCK(x) ((x) << 5) +#define ETDM_IN_AFIFO_CLOCK_MASK GENMASK(7, 5) +#define ETDM_IN_AFIFO_MODE(x) ((x) << 0) +#define ETDM_IN_AFIFO_MODE_MASK GENMASK(4, 0) + +/* ETDM_COWORK_CON0 */ +#define ETDM_OUT1_SLAVE_SEL(x) ((x) << 20) +#define ETDM_OUT1_SLAVE_SEL_MASK GENMASK(23, 20) +#define ETDM_OUT1_SLAVE_SEL_SHIFT 20 + +/* ETDM_COWORK_CON1 */ +#define ETDM_IN1_SDATA_SEL(x) ((x) << 20) +#define ETDM_IN1_SDATA_SEL_MASK GENMASK(23, 20) +#define ETDM_IN1_SDATA_SEL_SHIFT 20 +#define ETDM_IN1_SDATA0_SEL(x) ((x) << 16) +#define ETDM_IN1_SDATA0_SEL_MASK GENMASK(19, 16) +#define ETDM_IN1_SDATA0_SEL_SHIFT 16 +#define ETDM_IN1_SLAVE_SEL(x) ((x) << 8) +#define ETDM_IN1_SLAVE_SEL_MASK GENMASK(11, 8) +#define ETDM_IN1_SLAVE_SEL_SHIFT 8 + +/* ETDM_COWORK_CON2 */ +#define ETDM_IN2_SLAVE_SEL(x) ((x) << 24) +#define ETDM_IN2_SLAVE_SEL_MASK GENMASK(27, 24) +#define ETDM_IN2_SLAVE_SEL_SHIFT 24 +#define ETDM_OUT3_SLAVE_SEL(x) ((x) << 20) +#define ETDM_OUT3_SLAVE_SEL_MASK GENMASK(23, 20) +#define ETDM_OUT3_SLAVE_SEL_SHIFT 20 +#define ETDM_OUT2_SLAVE_SEL(x) ((x) << 8) +#define ETDM_OUT2_SLAVE_SEL_MASK GENMASK(11, 8) +#define ETDM_OUT2_SLAVE_SEL_SHIFT 8 + +/* ETDM_COWORK_CON3 */ +#define ETDM_IN2_SDATA_SEL(x) ((x) << 4) +#define ETDM_IN2_SDATA_SEL_MASK GENMASK(7, 4) +#define ETDM_IN2_SDATA_SEL_SHIFT 4 +#define ETDM_IN2_SDATA0_SEL(x) ((x) << 0) +#define ETDM_IN2_SDATA0_SEL_MASK GENMASK(3, 0) +#define ETDM_IN2_SDATA0_SEL_SHIFT 0 + +/* ETDM_x_CONx */ +#define ETDM_CON0_CH_NUM(x) (((x) - 1) << 23) +#define ETDM_CON0_CH_NUM_MASK GENMASK(27, 23) +#define ETDM_CON0_WORD_LEN(x) (((x) - 1) << 16) +#define ETDM_CON0_WORD_LEN_MASK GENMASK(20, 16) +#define ETDM_CON0_BIT_LEN(x) (((x) - 1) << 11) +#define ETDM_CON0_BIT_LEN_MASK GENMASK(15, 11) +#define ETDM_CON0_FORMAT(x) ((x) << 6) +#define ETDM_CON0_FORMAT_MASK GENMASK(8, 6) +#define ETDM_CON0_SLAVE_MODE BIT(5) +#define ETDM_CON0_EN BIT(0) + +#define ETDM_OUT_CON0_RELATCH_DOMAIN(x) ((x) << 28) +#define ETDM_OUT_CON0_RELATCH_DOMAIN_MASK GENMASK(29, 28) + +#define ETDM_CON1_MCLK_OUTPUT BIT(16) +#define ETDM_IN_CON1_LRCK_AUTO_MODE BIT(31) +#define ETDM_IN_CON1_LRCK_WIDTH(x) (((x) - 1) << 20) +#define ETDM_IN_CON1_LRCK_WIDTH_MASK GENMASK(29, 20) +#define ETDM_OUT_CON1_LRCK_AUTO_MODE BIT(29) +#define ETDM_OUT_CON1_LRCK_WIDTH(x) (((x) - 1) << 19) +#define ETDM_OUT_CON1_LRCK_WIDTH_MASK GENMASK(28, 19) + +#define ETDM_IN_CON2_MULTI_IP_2CH_MODE BIT(31) +#define ETDM_IN_CON2_MULTI_IP_TOTAL_CH(x) (((x) - 1) << 15) +#define ETDM_IN_CON2_MULTI_IP_TOTAL_CH_MASK GENMASK(19, 15) +#define ETDM_IN_CON2_CLOCK(x) ((x) << 10) +#define ETDM_IN_CON2_CLOCK_MASK GENMASK(12, 10) +#define ETDM_IN_CON2_CLOCK_SHIFT 10 +#define ETDM_IN_CON2_UPDATE_GAP(x) ((x) << 5) +#define ETDM_IN_CON2_UPDATE_GAP_MASK GENMASK(9, 5) + +#define ETDM_OUT_CON2_LRCK_DELAY_BCK_INV BIT(30) +#define ETDM_OUT_CON2_LRCK_DELAY_0P5T_EN BIT(29) + +#define ETDM_IN_CON3_FS(x) ((x) << 26) +#define ETDM_IN_CON3_FS_MASK GENMASK(30, 26) +#define ETDM_IN_CON3_DISABLE_OUT(x) BIT(((x) & 0xf)) +#define ETDM_IN_CON3_DISABLE_OUT_MASK GENMASK(15, 0) + +#define ETDM_IN_CON4_MASTER_LRCK_INV BIT(19) +#define ETDM_IN_CON4_MASTER_BCK_INV BIT(18) +#define ETDM_IN_CON4_SLAVE_LRCK_INV BIT(17) +#define ETDM_IN_CON4_SLAVE_BCK_INV BIT(16) + +#define ETDM_OUT_CON4_RELATCH_EN(x) ((x) << 24) +#define ETDM_OUT_CON4_RELATCH_EN_MASK GENMASK(28, 24) +#define ETDM_OUT_CON4_CLOCK(x) ((x) << 6) +#define ETDM_OUT_CON4_CLOCK_MASK GENMASK(8, 6) +#define ETDM_OUT_CON4_CLOCK_SHIFT 6 +#define ETDM_OUT_CON4_FS(x) ((x) << 0) +#define ETDM_OUT_CON4_FS_MASK GENMASK(4, 0) + +#define ETDM_IN_CON5_LR_SWAP(x) BIT(((x) & 0xf) + 16) +#define ETDM_IN_CON5_LR_SWAP_MASK GENMASK(31, 16) +#define ETDM_IN_CON5_ENABLE_ODD(x) BIT(((x) & 0xf)) +#define ETDM_IN_CON5_ENABLE_ODD_MASK GENMASK(15, 0) + +#define ETDM_OUT_CON5_MASTER_LRCK_INV BIT(10) +#define ETDM_OUT_CON5_MASTER_BCK_INV BIT(9) +#define ETDM_OUT_CON5_SLAVE_LRCK_INV BIT(8) +#define ETDM_OUT_CON5_SLAVE_BCK_INV BIT(7) + +/* AFE_DPTX_CON */ +#define AFE_DPTX_CON_CH_EN(x) (((x) & 0xff) << 8) +#define AFE_DPTX_CON_CH_EN_2CH (AFE_DPTX_CON_CH_EN(GENMASK(1, 0))) +#define AFE_DPTX_CON_CH_EN_4CH (AFE_DPTX_CON_CH_EN(GENMASK(3, 0))) +#define AFE_DPTX_CON_CH_EN_6CH (AFE_DPTX_CON_CH_EN(GENMASK(5, 0))) +#define AFE_DPTX_CON_CH_EN_8CH (AFE_DPTX_CON_CH_EN(GENMASK(7, 0))) +#define AFE_DPTX_CON_CH_EN_MASK GENMASK(15, 8) +#define AFE_DPTX_CON_16BIT (0x1 << 2) +#define AFE_DPTX_CON_24BIT (0x0 << 2) +#define AFE_DPTX_CON_16BIT_MASK BIT(2) +#define AFE_DPTX_CON_CH_NUM(x) (((x) & 0x1) << 1) +#define AFE_DPTX_CON_CH_NUM_2CH (AFE_DPTX_CON_CH_NUM(0)) +#define AFE_DPTX_CON_CH_NUM_8CH (AFE_DPTX_CON_CH_NUM(1)) +#define AFE_DPTX_CON_CH_NUM_MASK (0x1 << 1) +#define AFE_DPTX_CON_ON BIT(0) +#define AFE_DPTX_CON_ON_MASK BIT(0) + +/* AFE_ADDA_UL_DL_CON0 */ +#define ADDA_AFE_ON_SHIFT 0 + +/* AFE_ADDA_DL_SRC2_CON0 */ +#define DL_2_INPUT_MODE_CTL(x) ((x) << 28) +#define DL_2_INPUT_MODE_CTL_MASK GENMASK(31, 28) +#define DL_2_CH1_SATURATION_EN_CTL BIT(27) +#define DL_2_CH2_SATURATION_EN_CTL BIT(26) +#define DL_2_MUTE_CH1_OFF_CTL_PRE BIT(12) +#define DL_2_MUTE_CH2_OFF_CTL_PRE BIT(11) +#define DL_2_VOICE_MODE_CTL_PRE BIT(5) +#define DL_2_GAIN_ON_CTL_PRE_SHIFT 1 +#define DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT 0 + +/* AFE_ADDA_DL_SRC2_CON1 */ +#define DL_2_GAIN_CTL_PRE(x) ((x) << 16) +#define DL_2_GAIN_CTL_PRE_MASK GENMASK(31, 16) +#define DL_2_GAIN_CTL_PRE_SHIFT 16 + +/* AFE_ADDA_TOP_CON0 */ +#define C_LOOPBACK_MODE_CTL_MASK GENMASK(15, 12) +#define DL_INPUT_FROM_SINEGEN (4 << 12) + +/* AFE_ADDA_DL_SDM_DCCOMP_CON */ +#define DL_USE_NEW_2ND_SDM BIT(30) +#define ATTGAIN_CTL_MASK GENMASK(5, 0) + +/* AFE_ADDA_UL_SRC_CON0 */ +#define UL_MODE_3P25M_CH2_CTL BIT(22) +#define UL_MODE_3P25M_CH1_CTL BIT(21) +#define UL_VOICE_MODE_CTL(x) ((x) << 17) +#define UL_VOICE_MODE_CTL_MASK GENMASK(19, 17) +#define UL_LOOPBACK_MODE_CTL BIT(2) +#define UL_SDM3_LEVEL_CTL BIT(1) +#define UL_SRC_ON_TMP_CTL_SHIFT 0 + +#endif From e84ee3997bfcdc3031bd6a63d1c9737cd68e1fd0 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:40 +0800 Subject: [PATCH 07/24] dt-bindings: mediatek: mt8195: add audio afe document This patch adds mt8195 audio afe document. In order to support dynamic clock reparenting for ADDA and ETDM, PLL and MUX clocks are requested even though they are not consumed by afe directly. Signed-off-by: Trevor Wu --- .../bindings/sound/mt8195-afe-pcm.yaml | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml new file mode 100644 index 00000000000000..53e9434a6d9d86 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml @@ -0,0 +1,184 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mt8195-afe-pcm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek AFE PCM controller for mt8195 + +maintainers: + - Trevor Wu + +properties: + compatible: + const: mediatek,mt8195-audio + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + mediatek,topckgen: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of the mediatek topckgen 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 infra 26M clock + - description: infra bus 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: infra_ao_audio_26m_b + - const: scp_adsp_audiodsp + + mediatek,etdm-in1-chn-disabled: + $ref: /schemas/types.yaml#/definitions/uint8-array + maxItems: 24 + 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 + - mediatek,topckgen + - power-domains + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + afe: mt8195-afe-pcm@10890000 { + compatible = "mediatek,mt8195-audio"; + reg = <0x10890000 0x10000>; + interrupts = ; + mediatek,topckgen = <&topckgen>; + power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>; + clocks = <&clk26m>, + <&topckgen CLK_TOP_APLL1>, + <&topckgen CLK_TOP_APLL2>, + <&topckgen CLK_TOP_APLL12_DIV0>, + <&topckgen CLK_TOP_APLL12_DIV1>, + <&topckgen CLK_TOP_APLL12_DIV2>, + <&topckgen CLK_TOP_APLL12_DIV3>, + <&topckgen CLK_TOP_APLL12_DIV9>, + <&topckgen CLK_TOP_A1SYS_HP_SEL>, + <&topckgen CLK_TOP_AUD_INTBUS_SEL>, + <&topckgen CLK_TOP_AUDIO_H_SEL>, + <&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>, + <&topckgen CLK_TOP_DPTX_M_SEL>, + <&topckgen CLK_TOP_I2SO1_M_SEL>, + <&topckgen CLK_TOP_I2SO2_M_SEL>, + <&topckgen CLK_TOP_I2SI1_M_SEL>, + <&topckgen CLK_TOP_I2SI2_M_SEL>, + <&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>, + <&scp_adsp CLK_SCP_ADSP_AUDIODSP>; + 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", + "infra_ao_audio_26m_b", + "scp_adsp_audiodsp"; + }; + +... From d6abd2e705419a91bfb0eb57a87ec4719e903d13 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:41 +0800 Subject: [PATCH 08/24] ASoC: mediatek: mt8195: add machine driver with mt6359, rt1019 and rt5682 This patch adds support for mt8195 board with mt6359, rt1019 and rt5682. Signed-off-by: Trevor Wu Reported-by: kernel test robot --- sound/soc/mediatek/Kconfig | 14 + sound/soc/mediatek/mt8195/Makefile | 3 + .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 977 ++++++++++++++++++ 3 files changed, 994 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 3389f382be068a..bfee954d0c7ccb 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -193,3 +193,17 @@ config SND_SOC_MT8195 that can be used with other codecs. Select Y if you have such device. If unsure select "N". + +config SND_SOC_MT8195_MT6359_RT1019_RT5682 + tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec" + depends on I2C + depends on SND_SOC_MT8195 + select SND_SOC_MT6359 + select SND_SOC_RT1015P + select SND_SOC_RT5682_I2C + select SND_SOC_DMIC + help + This adds ASoC driver for Mediatek MT8195 boards + with the MT6359 RT1019 RT5682 audio codec. + Select Y if you have such device. + If unsure select "N". diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile index 6529dd5beb2b6c..44775f400b4042 100644 --- a/sound/soc/mediatek/mt8195/Makefile +++ b/sound/soc/mediatek/mt8195/Makefile @@ -10,3 +10,6 @@ snd-soc-mt8195-afe-objs := \ mt8195-dai-pcm.o obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o + +# machine driver +obj-$(CONFIG_SND_SOC_MT8195_MT6359_RT1019_RT5682) += mt8195-mt6359-rt1019-rt5682.o diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c new file mode 100644 index 00000000000000..39b33aecc1e95d --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -0,0 +1,977 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mt8195-mt6359-rt1019-rt5682.c -- +// MT8195-MT6359-RT1019-RT6358 ALSA SoC machine driver +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Trevor Wu +// + +#include +#include +#include +#include +#include +#include +#include +#include "../../codecs/mt6359.h" +#include "../../codecs/rt5682.h" +#include "../common/mtk-afe-platform-driver.h" +#include "mt8195-afe-common.h" + +#define RT1019_CODEC_DAI "HiFi" +#define RT1019_DEV0_NAME "rt1019p" + +#define RT5682_CODEC_DAI "rt5682-aif1" +#define RT5682_DEV0_NAME "rt5682.2-001a" + +struct mt8195_mt6359_rt1019_rt5682_priv { + struct snd_soc_jack headset_jack; +}; + +static const struct snd_soc_dapm_widget + mt8195_mt6359_rt1019_rt5682_widgets[] = { + SND_SOC_DAPM_SPK("Speakers", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = { + /* speaker */ + { "Speakers", NULL, "Speaker" }, + /* headset */ + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + { "IN1P", NULL, "Headset Mic" }, +}; + +static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = { + SOC_DAPM_PIN_SWITCH("Speakers"), + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 128; + unsigned int mclk_fs = rate * mclk_fs_ratio; + int bitwidth; + int ret; + + bitwidth = snd_pcm_format_width(params_format(params)); + if (bitwidth < 0) { + dev_err(card->dev, "invalid bit width: %d\n", bitwidth); + return bitwidth; + } + + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); + if (ret) { + dev_err(card->dev, "failed to set tdm slot\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, + RT5682_PLL1_S_BCLK1, + params_rate(params) * 64, + params_rate(params) * 512); + if (ret) { + dev_err(card->dev, "failed to set pll\n"); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, + RT5682_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret) { + dev_err(card->dev, "failed to set sysclk\n"); + return ret; + } + + return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8195_rt5682_etdm_ops = { + .hw_params = mt8195_rt5682_etdm_hw_params, +}; + +#define CKSYS_AUD_TOP_CFG 0x032c +#define CKSYS_AUD_TOP_MON 0x0330 + +static int mt8195_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 = snd_soc_component_get_drvdata(cmpnt_afe); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + int phase; + unsigned int monitor; + int mtkaif_calibration_num_phase; + int test_done_1, test_done_2, test_done_3; + int cycle_1, cycle_2, cycle_3; + int prev_cycle_1, prev_cycle_2, prev_cycle_3; + int chosen_phase_1, chosen_phase_2, chosen_phase_3; + int counter; + bool mtkaif_calibration_ok; + int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM]; + int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM]; + int i; + + dev_info(afe->dev, "%s(), start\n", __func__); + + param->mtkaif_calibration_ok = false; + for (i = 0; i < MT8195_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; + test_done_3 = 0; + cycle_1 = -1; + cycle_2 = -1; + cycle_3 = -1; + counter = 0; + while (!(test_done_1 & test_done_2 & test_done_3)) { + regmap_read(afe_priv->topckgen, + CKSYS_AUD_TOP_MON, &monitor); + test_done_1 = (monitor >> 28) & 0x1; + test_done_2 = (monitor >> 29) & 0x1; + test_done_3 = (monitor >> 30) & 0x1; + if (test_done_1 == 1) + cycle_1 = monitor & 0xf; + + if (test_done_2 == 1) + cycle_2 = (monitor >> 4) & 0xf; + + if (test_done_3 == 1) + cycle_3 = (monitor >> 8) & 0xf; + + /* handle if never test done */ + if (++counter > 10000) { + dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n", + __func__, + cycle_1, cycle_2, cycle_3, monitor); + mtkaif_calibration_ok = false; + break; + } + } + + if (phase == 0) { + prev_cycle_1 = cycle_1; + prev_cycle_2 = cycle_2; + prev_cycle_3 = cycle_3; + } + + if (cycle_1 != prev_cycle_1 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1; + mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1; + } + + if (cycle_2 != prev_cycle_2 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1; + mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2; + } + + if (cycle_3 != prev_cycle_3 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1; + mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3; + } + + regmap_update_bits(afe_priv->topckgen, + CKSYS_AUD_TOP_CFG, 0x1, 0x0); + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0) + break; + } + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { + mtkaif_calibration_ok = false; + chosen_phase_1 = 0; + } else { + chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0]; + } + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { + mtkaif_calibration_ok = false; + chosen_phase_2 = 0; + } else { + chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1]; + } + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { + mtkaif_calibration_ok = false; + chosen_phase_3 = 0; + } else { + chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2]; + } + + mt6359_set_mtkaif_calibration_phase(cmpnt_codec, + chosen_phase_1, + chosen_phase_2, + chosen_phase_3); + + mt6359_mtkaif_calibration_disable(cmpnt_codec); + pm_runtime_put(afe->dev); + + param->mtkaif_calibration_ok = mtkaif_calibration_ok; + param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1; + param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2; + param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3; + for (i = 0; i < MT8195_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 mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + + /* set mtkaif protocol */ + mt6359_set_mtkaif_protocol(cmpnt_codec, + MT6359_MTKAIF_PROTOCOL_2_CLK_P2); + + /* mtkaif calibration */ + mt8195_mt6359_mtkaif_calibration(rtd); + + return 0; +} + +static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + struct mt8195_mt6359_rt1019_rt5682_priv *priv = + snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &priv->headset_jack; + int ret; + + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, NULL, 0); + if (ret) { + dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL); + if (ret) { + dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret); + return ret; + } + + return 0; +}; + +static int mt8195_etdm_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, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 256; + unsigned int mclk_fs = rate * mclk_fs_ratio; + + return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, + SND_SOC_CLOCK_OUT); +} + +static struct snd_soc_ops mt8195_dptx_ops = { + .hw_params = mt8195_dptx_hw_params, +}; + +static int mt8195_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, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int mt8195_playback_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000 + }; + static const unsigned int channels[] = { + 2 + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); + return ret; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list channel failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_playback_ops = { + .startup = mt8195_playback_startup, +}; + +static int mt8195_capture_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000 + }; + static const unsigned int channels[] = { + 1, 2 + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); + return ret; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list channel failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_capture_ops = { + .startup = mt8195_capture_startup, +}; + +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_DL_SRC_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, + DAI_LINK_UL_SRC1_BE, + DAI_LINK_UL_SRC2_BE, +}; + +/* FE */ +SND_SOC_DAILINK_DEFS(DL2_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL3_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL6_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL7_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL7")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL8_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL8")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL10_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL10")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL11_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL11")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL1_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL2_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL3_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL4_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL5_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL5")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL6_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL8_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL8")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL9_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL9")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL10_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL10")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +/* BE */ +SND_SOC_DAILINK_DEFS(DL_SRC_BE, + DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", + "mt6359-snd-codec-aif1")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DPTX_BE, + DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM1_IN_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM2_IN_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME, + RT5682_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME, + RT5682_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME, + RT1019_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(PCM1_BE, + DAILINK_COMP_ARRAY(COMP_CPU("PCM1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL_SRC1_BE, + DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", + "mt6359-snd-codec-aif1"), + COMP_CODEC("dmic-codec", + "dmic-hifi")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL_SRC2_BE, + DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", + "mt6359-snd-codec-aif2")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_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, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL2_FE), + }, + [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, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL3_FE), + }, + [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, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL6_FE), + }, + [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(DL7_FE), + }, + [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, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL8_FE), + }, + [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(DL10_FE), + }, + [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, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL11_FE), + }, + [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(UL1_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL2_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL3_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL4_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL5_FE), + }, + [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(UL6_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL8_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL9_FE), + }, + [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, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL10_FE), + }, + /* BE */ + [DAI_LINK_DL_SRC_BE] = { + .name = "DL_SRC_BE", + .init = mt8195_mt6359_init, + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(DL_SRC_BE), + }, + [DAI_LINK_DPTX_BE] = { + .name = "DPTX_BE", + .no_pcm = 1, + .dpcm_playback = 1, + .ops = &mt8195_dptx_ops, + .be_hw_params_fixup = mt8195_dptx_hw_params_fixup, + SND_SOC_DAILINK_REG(DPTX_BE), + }, + [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_CBS_CFS, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ETDM1_IN_BE), + }, + [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_CBS_CFS, + .dpcm_capture = 1, + .init = mt8195_rt5682_init, + .ops = &mt8195_rt5682_etdm_ops, + .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, + SND_SOC_DAILINK_REG(ETDM2_IN_BE), + }, + [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_CBS_CFS, + .dpcm_playback = 1, + .ops = &mt8195_rt5682_etdm_ops, + .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, + SND_SOC_DAILINK_REG(ETDM1_OUT_BE), + }, + [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_CBS_CFS, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(ETDM2_OUT_BE), + }, + [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_CBS_CFS, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(ETDM3_OUT_BE), + }, + [DAI_LINK_PCM1_BE] = { + .name = "PCM1_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(PCM1_BE), + }, + [DAI_LINK_UL_SRC1_BE] = { + .name = "UL_SRC1_BE", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(UL_SRC1_BE), + }, + [DAI_LINK_UL_SRC2_BE] = { + .name = "UL_SRC2_BE", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(UL_SRC2_BE), + }, +}; + +static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = { + .name = "mt8195_r1019_5682", + .owner = THIS_MODULE, + .dai_link = mt8195_mt6359_rt1019_rt5682_dai_links, + .num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links), + .controls = mt8195_mt6359_rt1019_rt5682_controls, + .num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls), + .dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets), + .dapm_routes = mt8195_mt6359_rt1019_rt5682_routes, + .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes), +}; + +static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card; + struct device_node *platform_node; + struct snd_soc_dai_link *dai_link; + struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL; + + int ret, i; + + card->dev = &pdev->dev; + + platform_node = of_parse_phandle(pdev->dev.of_node, + "mediatek,platform", 0); + if (!platform_node) { + dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n"); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + if (!dai_link->platforms->name) + dai_link->platforms->of_node = platform_node; + } + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + snd_soc_card_set_drvdata(card, priv); + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) + dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n", + __func__, ret); + return ret; +} + +#ifdef CONFIG_OF +static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = { + {.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",}, + {} +}; +#endif + +static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = { + .poweroff = snd_soc_poweroff, + .restore = snd_soc_resume, +}; + +static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = { + .driver = { + .name = "mt8195_mt6359_rt1019_rt5682", +#ifdef CONFIG_OF + .of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match, +#endif + .pm = &mt8195_mt6359_rt1019_rt5682_pm_ops, + }, + .probe = mt8195_mt6359_rt1019_rt5682_dev_probe, +}; + +module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver); + +/* Module information */ +MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver"); +MODULE_AUTHOR("Trevor Wu "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card"); From caab8f98ddfcf42c8ea9a317ff2fc881a35be872 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:42 +0800 Subject: [PATCH 09/24] ASoC: mediatek: mt8195: add DPTX audio support This patch adds DPTX audio support on mt8195-mt6359-rt1019-rt5682 board. Signed-off-by: Trevor Wu --- sound/soc/mediatek/Kconfig | 1 + .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 88 +++++++++++++++++-- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index bfee954d0c7ccb..cf567a89f421b4 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -202,6 +202,7 @@ config SND_SOC_MT8195_MT6359_RT1019_RT5682 select SND_SOC_RT1015P select SND_SOC_RT5682_I2C select SND_SOC_DMIC + select SND_SOC_HDMI_CODEC help This adds ASoC driver for Mediatek MT8195 boards with the MT6359 RT1019 RT5682 audio codec. diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c index 39b33aecc1e95d..d853bc445753d6 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -27,6 +27,7 @@ struct mt8195_mt6359_rt1019_rt5682_priv { struct snd_soc_jack headset_jack; + struct snd_soc_jack dp_jack; }; static const struct snd_soc_dapm_widget @@ -327,6 +328,52 @@ static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000 + }; + static const unsigned int channels[] = { + 2, 4, 6, 8 + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); + return ret; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list channel failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = { + .startup = mt8195_hdmitx_dptx_startup, +}; + static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -344,8 +391,25 @@ static struct snd_soc_ops mt8195_dptx_ops = { .hw_params = mt8195_dptx_hw_params, }; -static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) +static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mt8195_mt6359_rt1019_rt5682_priv *priv = + snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_component *cmpnt_codec = + 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, NULL, 0); + if (ret) + return ret; + + return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL); +} + +static int mt8195_hdmitx_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), @@ -687,6 +751,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { }, .dynamic = 1, .dpcm_playback = 1, + .ops = &mt8195_hdmitx_dptx_playback_ops, SND_SOC_DAILINK_REG(DL10_FE), }, [DAI_LINK_DL11_FE] = { @@ -820,7 +885,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { .no_pcm = 1, .dpcm_playback = 1, .ops = &mt8195_dptx_ops, - .be_hw_params_fixup = mt8195_dptx_hw_params_fixup, + .be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup, SND_SOC_DAILINK_REG(DPTX_BE), }, [DAI_LINK_ETDM1_IN_BE] = { @@ -915,7 +980,6 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) struct device_node *platform_node; struct snd_soc_dai_link *dai_link; struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL; - int ret, i; card->dev = &pdev->dev; @@ -930,6 +994,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) for_each_card_prelinks(card, i, dai_link) { if (!dai_link->platforms->name) dai_link->platforms->of_node = platform_node; + + if (strcmp(dai_link->name, "DPTX_BE") == 0) { + dai_link->codecs->of_node = + of_parse_phandle(pdev->dev.of_node, + "mediatek,dptx-codec", 0); + if (!dai_link->codecs->of_node) { + dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n"); + return -EINVAL; + } + + dai_link->codecs->name = NULL; + dai_link->codecs->dai_name = "i2s-hifi"; + dai_link->init = mt8195_dptx_codec_init; + } } priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -940,7 +1018,7 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) - dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n", + dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", __func__, ret); return ret; } From d4e27ec28b4b10d5c2ae23375c0355085283ec3d Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:43 +0800 Subject: [PATCH 10/24] ASoC: mediatek: mt8195: add HDMITX audio support This patch adds HDMITX audio support on mt8195-mt6359-rt1019-rt5682 board. Signed-off-by: Trevor Wu --- .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c index d853bc445753d6..5dc217f59bd6e1 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -28,6 +28,7 @@ struct mt8195_mt6359_rt1019_rt5682_priv { struct snd_soc_jack headset_jack; struct snd_soc_jack dp_jack; + struct snd_soc_jack hdmi_jack; }; static const struct snd_soc_dapm_widget @@ -407,6 +408,22 @@ static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL); } +static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mt8195_mt6359_rt1019_rt5682_priv *priv = + snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_component *cmpnt_codec = + 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, NULL, 0); + if (ret) + return ret; + + return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); +} + static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -936,6 +953,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .dpcm_playback = 1, + .be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM3_OUT_BE), }, [DAI_LINK_PCM1_BE] = { @@ -1008,6 +1026,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) dai_link->codecs->dai_name = "i2s-hifi"; dai_link->init = mt8195_dptx_codec_init; } + + if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { + dai_link->codecs->of_node = + of_parse_phandle(pdev->dev.of_node, + "mediatek,hdmi-codec", 0); + if (!dai_link->codecs->of_node) { + dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n"); + return -EINVAL; + } + + dai_link->codecs->name = NULL; + dai_link->codecs->dai_name = "i2s-hifi"; + dai_link->init = mt8195_hdmi_codec_init; + } } priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); From 87b70a9891184ee2fde8e8e48819b7d86cfe8108 Mon Sep 17 00:00:00 2001 From: Trevor Wu Date: Thu, 19 Aug 2021 16:41:44 +0800 Subject: [PATCH 11/24] dt-bindings: mediatek: mt8195: add mt8195-mt6359-rt1019-rt5682 document This patch adds document for mt8195 board with mt6359, rt1019 and rt5682 Signed-off-by: Trevor Wu --- .../sound/mt8195-mt6359-rt1019-rt5682.yaml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml diff --git a/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml new file mode 100644 index 00000000000000..20bc0ffd0e3431 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver + +maintainers: + - Trevor Wu + +description: + This binding describes the MT8195 sound card. + +properties: + compatible: + const: mediatek,mt8195_mt6359_rt1019_rt5682 + + mediatek,platform: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of MT8195 ASoC platform. + + mediatek,dptx-codec: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of MT8195 Display Port Tx codec node. + + mediatek,hdmi-codec: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of MT8195 HDMI codec node. + +additionalProperties: false + +required: + - compatible + - mediatek,platform + +examples: + - | + + sound: mt8195-sound { + compatible = "mediatek,mt8195_mt6359_rt1019_rt5682"; + mediatek,platform = <&afe>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_pins_default>; + }; + +... From ee0f944da534a61a7518b80b6c86ac3e189e3d98 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Fri, 27 Aug 2021 23:26:20 +0800 Subject: [PATCH 12/24] ASoC: SOF: tokens: add token for Mediatek AFE Add the definition for Mediatek audio front end(AFE) tokens,include AFE sampling rate, channels, and format. Signed-off-by: YC Hung --- include/uapi/sound/sof/tokens.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/uapi/sound/sof/tokens.h b/include/uapi/sound/sof/tokens.h index 02b71a8deea455..b72fa385bebf51 100644 --- a/include/uapi/sound/sof/tokens.h +++ b/include/uapi/sound/sof/tokens.h @@ -140,4 +140,9 @@ #define SOF_TKN_INTEL_HDA_RATE 1500 #define SOF_TKN_INTEL_HDA_CH 1501 +/* AFE */ +#define SOF_TKN_MEDIATEK_AFE_RATE 1600 +#define SOF_TKN_MEDIATEK_AFE_CH 1601 +#define SOF_TKN_MEDIATEK_AFE_FORMAT 1602 + #endif From 2dc101d366553091b86d0dd26ab8bf780585dd84 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Fri, 27 Aug 2021 23:29:14 +0800 Subject: [PATCH 13/24] ASoC: SOF: topology: Add support for Mediatek AFE DAI Add new sof dai and config to pass topology file configuration to SOF firmware running on Mediatek platform DSP core. Add mediatek audio front end(AFE) to the list of supported sof_dais Signed-off-by: YC Hung --- include/sound/sof/dai-mediatek.h | 24 ++++++++++++ include/sound/sof/dai.h | 3 ++ sound/soc/sof/pcm.c | 12 ++++++ sound/soc/sof/topology.c | 65 ++++++++++++++++++++++++++++++++ 4 files changed, 104 insertions(+) create mode 100644 include/sound/sof/dai-mediatek.h diff --git a/include/sound/sof/dai-mediatek.h b/include/sound/sof/dai-mediatek.h new file mode 100644 index 00000000000000..9a7606287607b5 --- /dev/null +++ b/include/sound/sof/dai-mediatek.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * Copyright(c) 2021 Mediatek Corporation. All rights reserved. + * + * Author: Bo Pan + * YC Hung + */ + +#ifndef __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__ +#define __INCLUDE_SOUND_SOF_DAI_MEDIATEK_H__ + +#include + +struct sof_ipc_dai_mtk_afe_params { + struct sof_ipc_hdr hdr; + u32 channels; + u32 rate; + u32 format; + u32 stream_id; + u32 reserved[4]; /* reserve for future */ +} __packed; + +#endif + diff --git a/include/sound/sof/dai.h b/include/sound/sof/dai.h index 9625f47557b8ef..02652509838160 100644 --- a/include/sound/sof/dai.h +++ b/include/sound/sof/dai.h @@ -12,6 +12,7 @@ #include #include #include +#include /* * DAI Configuration. @@ -66,6 +67,7 @@ enum sof_ipc_dai_type { SOF_DAI_INTEL_ALH, /**< Intel ALH */ SOF_DAI_IMX_SAI, /**< i.MX SAI */ SOF_DAI_IMX_ESAI, /**< i.MX ESAI */ + SOF_DAI_MEDIATEK_AFE, /**< Mediatek AFE */ }; /* general purpose DAI configuration */ @@ -90,6 +92,7 @@ struct sof_ipc_dai_config { struct sof_ipc_dai_alh_params alh; struct sof_ipc_dai_esai_params esai; struct sof_ipc_dai_sai_params sai; + struct sof_ipc_dai_mtk_afe_params afe; }; } __packed; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index cde3f65c43780b..cf1806f57cf4b6 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -808,6 +808,18 @@ int sof_pcm_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_pa channels->min = dai->dai_config->esai.tdm_slots; channels->max = dai->dai_config->esai.tdm_slots; + dev_dbg(component->dev, + "rate_min: %d rate_max: %d\n", rate->min, rate->max); + dev_dbg(component->dev, + "channels_min: %d channels_max: %d\n", + channels->min, channels->max); + break; + case SOF_DAI_MEDIATEK_AFE: + rate->min = dai->dai_config->afe.rate; + rate->max = dai->dai_config->afe.rate; + channels->min = dai->dai_config->afe.channels; + channels->max = dai->dai_config->afe.channels; + dev_dbg(component->dev, "rate_min: %d rate_max: %d\n", rate->min, rate->max); dev_dbg(component->dev, diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 5c31c8dff575f9..276d5840d30cf0 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -376,6 +376,7 @@ static const struct sof_dai_types sof_dais[] = { {"ALH", SOF_DAI_INTEL_ALH}, {"SAI", SOF_DAI_IMX_SAI}, {"ESAI", SOF_DAI_IMX_ESAI}, + {"AFE", SOF_DAI_MEDIATEK_AFE}, }; static enum sof_ipc_dai_type find_dai(const char *name) @@ -803,6 +804,19 @@ static const struct sof_topology_token led_tokens[] = { get_token_u32, offsetof(struct snd_sof_led_control, direction), 0}, }; +/* AFE */ +static const struct sof_topology_token afe_tokens[] = { + {SOF_TKN_MEDIATEK_AFE_RATE, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_mtk_afe_params, rate), 0}, + {SOF_TKN_MEDIATEK_AFE_CH, + SND_SOC_TPLG_TUPLE_TYPE_WORD, get_token_u32, + offsetof(struct sof_ipc_dai_mtk_afe_params, channels), 0}, + {SOF_TKN_MEDIATEK_AFE_FORMAT, + SND_SOC_TPLG_TUPLE_TYPE_STRING, get_token_comp_format, + offsetof(struct sof_ipc_dai_mtk_afe_params, format), 0}, +}; + static int sof_parse_uuid_tokens(struct snd_soc_component *scomp, void *object, const struct sof_topology_token *tokens, @@ -2892,6 +2906,54 @@ static int sof_link_esai_load(struct snd_soc_component *scomp, int index, return ret; } +static int sof_link_afe_load(struct snd_soc_component *scomp, int index, + struct snd_soc_dai_link *link, + struct snd_soc_tplg_link_config *cfg, + struct snd_soc_tplg_hw_config *hw_config, + struct sof_ipc_dai_config *config) +{ + struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(scomp); + struct snd_soc_tplg_private *private = &cfg->priv; + struct snd_soc_dai *dai; + u32 size = sizeof(*config); + int ret; + + /* handle master/slave and inverted clocks */ + sof_dai_set_format(hw_config, config); + + /* init IPC */ + memset(&config->afe, 0, sizeof(struct sof_ipc_dai_mtk_afe_params)); + config->hdr.size = size; + + /* get any bespoke DAI tokens */ + ret = sof_parse_tokens(scomp, &config->afe, afe_tokens, + ARRAY_SIZE(afe_tokens), private->array, + le32_to_cpu(private->size)); + if (ret != 0) { + dev_err(scomp->dev, "parse afe tokens failed %d\n", + le32_to_cpu(private->size)); + return ret; + } + + dev_info(scomp->dev, "AFE config rate %d channels %d format:%d\n", + config->afe.rate, config->afe.channels, config->afe.format); + + dai = snd_soc_find_dai(link->cpus); + if (!dai) { + dev_err(scomp->dev, "failed to find dai %s in %s", + link->cpus->dai_name, __func__); + return -EINVAL; + } + + config->afe.stream_id = DMA_CHAN_INVALID; + + ret = sof_set_dai_config(sdev, size, link, config); + if (ret < 0) + dev_err(scomp->dev, "failed to process afe dai link %s", link->name); + + return ret; +} + static int sof_link_dmic_load(struct snd_soc_component *scomp, int index, struct snd_soc_dai_link *link, struct snd_soc_tplg_link_config *cfg, @@ -3177,6 +3239,9 @@ static int sof_link_load(struct snd_soc_component *scomp, int index, case SOF_DAI_IMX_ESAI: ret = sof_link_esai_load(scomp, index, link, cfg, hw_config + curr_conf, config); break; + case SOF_DAI_MEDIATEK_AFE: + ret = sof_link_afe_load(scomp, index, link, cfg, hw_config + curr_conf, config); + break; default: dev_err(scomp->dev, "error: invalid DAI type %d\n", common_config.type); ret = -EINVAL; From 6c2ce175fbbe00e46256c58fd29631f2cba4a965 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Fri, 27 Aug 2021 23:27:24 +0800 Subject: [PATCH 14/24] ASoC: SOF: pcm: add no ignore machine checking Add no_ignore_machine to check if ignore machine, set to 1 to not use ignore_machine and still use the original platform driver. Signed-off-by: YC Hung --- include/sound/sof.h | 3 +++ sound/soc/sof/pcm.c | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/include/sound/sof.h b/include/sound/sof.h index 23b374311d1616..83580f5b6ba4a0 100644 --- a/include/sound/sof.h +++ b/include/sound/sof.h @@ -68,6 +68,9 @@ struct sof_dev_desc { bool use_acpi_target_states; + /*set to 1 to not use ignore_machine and still use the original platform driver*/ + bool no_ignore_machine; + /* Platform resource indexes in BAR / ACPI resources. */ /* Must set to -1 if not used - add new items to end */ int resindex_lpe_base; diff --git a/sound/soc/sof/pcm.c b/sound/soc/sof/pcm.c index cf1806f57cf4b6..b5600531becfa2 100644 --- a/sound/soc/sof/pcm.c +++ b/sound/soc/sof/pcm.c @@ -913,7 +913,8 @@ void snd_sof_new_platform_drv(struct snd_sof_dev *sdev) pd->compress_ops = &sof_probe_compressed_ops; #endif pd->pcm_construct = sof_pcm_new; - pd->ignore_machine = drv_name; + if (!plat_data->desc->no_ignore_machine) + pd->ignore_machine = drv_name; pd->be_hw_params_fixup = sof_pcm_dai_link_fixup; pd->be_pcm_base = SOF_BE_PCM_BASE; pd->use_dai_pcm_id = true; From 248a3d86d036c83ffe27293062725569d541a8ae Mon Sep 17 00:00:00 2001 From: YC Hung Date: Fri, 27 Aug 2021 23:25:09 +0800 Subject: [PATCH 15/24] ASoC: SOF: mediatek: Add mt8195 hardware support This patch initialize to support SOF on Mediatek mt8195 platform. MT8195 has four Coretex A78 cores paired with four Coretex A55 cores. It also has Cadence HiFi-4 DSP single core. There are shared DRAM and mailbox interrupt between AP and DSP to use for IPC communication. The clocks of bus and dsp core are managed by CCF module. The power domain of DSP will be handled by mtk-scpsys. Signed-off-by: YC Hung --- sound/soc/sof/Kconfig | 1 + sound/soc/sof/Makefile | 1 + sound/soc/sof/mediatek/Kconfig | 23 ++ sound/soc/sof/mediatek/Makefile | 2 + sound/soc/sof/mediatek/adsp_helper.h | 55 ++++ sound/soc/sof/mediatek/mt8195/Makefile | 4 + sound/soc/sof/mediatek/mt8195/mt8195-clk.c | 183 +++++++++++ sound/soc/sof/mediatek/mt8195/mt8195-clk.h | 30 ++ sound/soc/sof/mediatek/mt8195/mt8195.c | 357 +++++++++++++++++++++ sound/soc/sof/mediatek/mt8195/mt8195.h | 151 +++++++++ 10 files changed, 807 insertions(+) create mode 100644 sound/soc/sof/mediatek/Kconfig create mode 100644 sound/soc/sof/mediatek/Makefile create mode 100644 sound/soc/sof/mediatek/adsp_helper.h create mode 100644 sound/soc/sof/mediatek/mt8195/Makefile create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195-clk.c create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195-clk.h create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195.c create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195.h diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index f44df48da65fba..93d01ae3c71ba9 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -226,5 +226,6 @@ config SND_SOC_SOF_PROBE_WORK_QUEUE source "sound/soc/sof/imx/Kconfig" source "sound/soc/sof/intel/Kconfig" source "sound/soc/sof/xtensa/Kconfig" +source "sound/soc/sof/mediatek/Kconfig" endif diff --git a/sound/soc/sof/Makefile b/sound/soc/sof/Makefile index 06e5f49f7ee861..9f9006ad58c573 100644 --- a/sound/soc/sof/Makefile +++ b/sound/soc/sof/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_SND_SOC_SOF_PCI_DEV) += snd-sof-pci.o obj-$(CONFIG_SND_SOC_SOF_INTEL_TOPLEVEL) += intel/ obj-$(CONFIG_SND_SOC_SOF_IMX_TOPLEVEL) += imx/ obj-$(CONFIG_SND_SOC_SOF_XTENSA) += xtensa/ +obj-$(CONFIG_SND_SOC_SOF_MTK_TOPLEVEL) += snd-sof.o mediatek/ diff --git a/sound/soc/sof/mediatek/Kconfig b/sound/soc/sof/mediatek/Kconfig new file mode 100644 index 00000000000000..53be76813ab956 --- /dev/null +++ b/sound/soc/sof/mediatek/Kconfig @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) + +config SND_SOC_SOF_MTK_TOPLEVEL + bool "SOF support for MTK audio DSPs" + depends on ARM64|| COMPILE_TEST + depends on SND_SOC_SOF_OF + help + This adds support for Sound Open Firmware for Mediatek platforms. + It is top level for all mediatek platforms. + Say Y if you have such a device. + If unsure select "N". + +if SND_SOC_SOF_MTK_TOPLEVEL +config SND_SOC_SOF_MT8195 + tristate "SOF support for MT8195 audio DSP" + select SND_SOC_SOF_XTENSA + help + This adds support for Sound Open Firmware for Mediatek platforms + using the mt8195 processors. + Say Y if you have such a device. + If unsure select "N". + +endif ## SND_SOC_SOF_MTK_TOPLEVEL diff --git a/sound/soc/sof/mediatek/Makefile b/sound/soc/sof/mediatek/Makefile new file mode 100644 index 00000000000000..e8ec6da981de4a --- /dev/null +++ b/sound/soc/sof/mediatek/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +obj-$(CONFIG_SND_SOC_SOF_MT8195) += mt8195/ diff --git a/sound/soc/sof/mediatek/adsp_helper.h b/sound/soc/sof/mediatek/adsp_helper.h new file mode 100644 index 00000000000000..d62d0a8ff9400a --- /dev/null +++ b/sound/soc/sof/mediatek/adsp_helper.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (c) 2021 MediaTek Corporation. All rights reserved. + */ + +#ifndef __ADSP_HELPER_H__ +#define __ADSP_HELPER_H__ + +/* + * Global important adsp data structure. + */ +#define DSP_MBOX_NUM 3 + +struct adsp_chip_info { + phys_addr_t pa_sram; + phys_addr_t pa_dram; /* adsp dram physical base */ + phys_addr_t pa_shared_dram; /* adsp dram physical base */ + phys_addr_t pa_cfgreg; + phys_addr_t pa_mboxreg[DSP_MBOX_NUM]; + u32 srammsize; + u32 dramsize; + u32 cfgregsize; + void __iomem *va_sram; /* corresponding to pa_sram */ + void __iomem *va_dram; /* corresponding to pa_dram */ + void __iomem *va_cfgreg; + void __iomem *va_mboxreg[DSP_MBOX_NUM]; + void __iomem *shared_sram; /* part of va_sram */ + void __iomem *shared_dram; /* part of va_dram */ + phys_addr_t adsp_bootup_addr; + int dram_offset; /*dram offset between system and dsp view*/ +}; + +struct adsp_priv { + struct device *dev; + struct snd_sof_dev *sdev; + + /* DSP IPC handler */ + struct mbox_controller *adsp_mbox; + + /* Power domain handling */ + int num_domains; + struct device **pd_dev; + struct device_link **link; + + struct adsp_chip_info *adsp; + + u32 (*ap2adsp_addr)(u32 addr); + u32 (*adsp2ap_addr)(u32 addr); + + void *private_data; +}; + +extern int g_dsp_wdt_irq_id; +#endif diff --git a/sound/soc/sof/mediatek/mt8195/Makefile b/sound/soc/sof/mediatek/mt8195/Makefile new file mode 100644 index 00000000000000..870b752a2a8659 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +snd-sof-mt8195-objs := mt8195.o mt8195-clk.o +obj-$(CONFIG_SND_SOC_SOF_MT8195) += snd-sof-mt8195.o + diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-clk.c b/sound/soc/sof/mediatek/mt8195/mt8195-clk.c new file mode 100644 index 00000000000000..8b39d98c54c458 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195-clk.c @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2021 Mediatek Corporation. All rights reserved. +// +// Author: YC Hung +// +// Hardware interface for mt8195 DSP clock + +#include +#include +#include +#include "mt8195.h" +#include "mt8195-clk.h" + +struct clk *clk_handle[ADSP_CLK_NUM]; + +int platform_parse_clock(struct device *dev) +{ + clk_handle[CLK_TOP_DSP_SEL] = devm_clk_get(dev, "dsp_sel"); + if (IS_ERR(clk_handle[CLK_TOP_DSP_SEL])) { + dev_err(dev, "clk_get(\"dsp_sel\") failed\n"); + return PTR_ERR(clk_handle[CLK_TOP_DSP_SEL]); + } + + clk_handle[CLK_TOP_CLK26M] = devm_clk_get(dev, "clk26m_ck"); + if (IS_ERR(clk_handle[CLK_TOP_CLK26M])) { + dev_err(dev, "clk_get(\"clk26m_ck\") failed\n"); + return PTR_ERR(clk_handle[CLK_TOP_CLK26M]); + } + + clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL] = devm_clk_get(dev, "audio_local_bus"); + if (IS_ERR(clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL])) { + dev_err(dev, "clk_get(\"audio_local_bus\") failed\n"); + return PTR_ERR(clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL]); + } + + clk_handle[CLK_TOP_MAINPLL_D7_D2] = devm_clk_get(dev, "mainpll_d7_d2"); + if (IS_ERR(clk_handle[CLK_TOP_MAINPLL_D7_D2])) { + dev_err(dev, "clk_get(\"mainpll_d7_d2\") failed\n"); + return PTR_ERR(clk_handle[CLK_TOP_MAINPLL_D7_D2]); + } + + clk_handle[CLK_SCP_ADSP_AUDIODSP] = devm_clk_get(dev, "scp_adsp_audiodsp"); + if (IS_ERR(clk_handle[CLK_SCP_ADSP_AUDIODSP])) { + dev_err(dev, "clk_get(\"scp_adsp_audiodsp\") failed\n"); + return PTR_ERR(clk_handle[CLK_SCP_ADSP_AUDIODSP]); + } + + clk_handle[CLK_TOP_AUDIO_H_SEL] = devm_clk_get(dev, "audio_h_sel"); + if (IS_ERR(clk_handle[CLK_TOP_AUDIO_H_SEL])) { + dev_err(dev, "clk_get(\"audio_h_sel\") failed\n"); + return PTR_ERR(clk_handle[CLK_TOP_AUDIO_H_SEL]); + } + + return 0; +} + +int adsp_enable_clock(struct device *dev) +{ + int ret; + + ret = clk_prepare_enable(clk_handle[CLK_TOP_MAINPLL_D7_D2]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(mainpll_d7_d2) fail %d\n", + __func__, ret); + return ret; + } + + ret = clk_prepare_enable(clk_handle[CLK_TOP_DSP_SEL]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(dsp_sel) fail %d\n", + __func__, ret); + goto disable_mainpll_d7_d2_clk; + } + + ret = clk_prepare_enable(clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(audio_local_bus) fail %d\n", + __func__, ret); + goto disable_dsp_sel_clk; + } + + ret = clk_prepare_enable(clk_handle[CLK_SCP_ADSP_AUDIODSP]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(scp_adsp_audiodsp) fail %d\n", + __func__, ret); + goto disable_audio_local_bus_clk; + } + + ret = clk_prepare_enable(clk_handle[CLK_TOP_AUDIO_H_SEL]); + if (ret) { + dev_err(dev, "%s clk_prepare_enable(audio_h_sel) fail %d\n", + __func__, ret); + goto disable_scp_adsp_audiodsp_clk; + } + + return 0; + +disable_scp_adsp_audiodsp_clk: + clk_disable_unprepare(clk_handle[CLK_SCP_ADSP_AUDIODSP]); +disable_audio_local_bus_clk: + clk_disable_unprepare(clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL]); +disable_dsp_sel_clk: + clk_disable_unprepare(clk_handle[CLK_TOP_DSP_SEL]); +disable_mainpll_d7_d2_clk: + clk_disable_unprepare(clk_handle[CLK_TOP_MAINPLL_D7_D2]); + + return ret; +} + +int adsp_sram_power_on(struct device *dev, bool val) +{ + void __iomem **va_dspsysreg; + + va_dspsysreg = devm_ioremap(dev, ADSP_SRAM_POOL_CON, 0x4); + if (!va_dspsysreg) { + dev_err(dev, "error: failed to ioremap sram pool base 0x%x\n", + ADSP_SRAM_POOL_CON); + return -ENOMEM; + } + + if (val) /* Power on ADSP SRAM */ + writel(readl(va_dspsysreg) & ~DSP_SRAM_POOL_PD_MASK, va_dspsysreg); + else /* Power down ADSP SRAM */ + writel(readl(va_dspsysreg) | DSP_SRAM_POOL_PD_MASK, va_dspsysreg); + + return 0; +} + +void adsp_disable_clock(struct device *dev) +{ + clk_disable_unprepare(clk_handle[CLK_TOP_AUDIO_H_SEL]); + clk_disable_unprepare(clk_handle[CLK_SCP_ADSP_AUDIODSP]); + clk_disable_unprepare(clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL]); + clk_disable_unprepare(clk_handle[CLK_TOP_DSP_SEL]); + clk_disable_unprepare(clk_handle[CLK_TOP_MAINPLL_D7_D2]); +} + +int adsp_default_clk_init(struct device *dev, int enable) +{ + int ret = 0; + + dev_dbg(dev, "%s: %s\n", __func__, enable ? "on" : "off"); + + if (enable) { + ret = clk_set_parent(clk_handle[CLK_TOP_DSP_SEL], + clk_handle[CLK_TOP_CLK26M]); + if (ret) { + dev_err(dev, "failed to set dsp_sel to clk26m: %d\n", ret); + return ret; + } + + ret = clk_set_parent(clk_handle[CLK_TOP_AUDIO_LOCAL_BUS_SEL], + clk_handle[CLK_TOP_MAINPLL_D7_D2]); + if (ret) { + dev_err(dev, "set audio_local_bus failed %d\n", ret); + return ret; + } + + ret = adsp_enable_clock(dev); + if (ret) + dev_err(dev, "failed to adsp_enable_clock: %d\n", ret); + + return ret; + } + + adsp_disable_clock(dev); + + return ret; +} + +int adsp_clock_on(struct device *dev) +{ + /* Open ADSP clock */ + return adsp_default_clk_init(dev, 1); +} + +int adsp_clock_off(struct device *dev) +{ + /* Close ADSP clock */ + return adsp_default_clk_init(dev, 0); +} + diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-clk.h b/sound/soc/sof/mediatek/mt8195/mt8195-clk.h new file mode 100644 index 00000000000000..30a1368b01e513 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195-clk.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (c) 2021 MediaTek Corporation. All rights reserved. + * + * Header file for the mt8195 DSP clock definition + */ + +#ifndef __MT8195_CLK_H +#define __MT8195_CLK_H + +/*DSP clock*/ +enum ADSP_CLK_ID { + CLK_TOP_DSP_SEL, + CLK_TOP_CLK26M, + CLK_TOP_AUDIO_LOCAL_BUS_SEL, + CLK_TOP_MAINPLL_D7_D2, + CLK_SCP_ADSP_AUDIODSP, + CLK_TOP_AUDIO_H_SEL, + ADSP_CLK_NUM +}; + +int platform_parse_clock(struct device *dev); +int adsp_default_clk_init(struct device *dev, int enable); +int adsp_enable_clock(struct device *dev); +void adsp_disable_clock(struct device *dev); +int adsp_clock_on(struct device *dev); +int adsp_clock_off(struct device *dev); +int adsp_sram_power_on(struct device *dev, bool val); +#endif diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c new file mode 100644 index 00000000000000..e889d54d13619d --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -0,0 +1,357 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2021 Mediatek Inc. All rights reserved. +// +// Author: YC Hung +// + +/* + * Hardware interface for audio DSP on mt8195 + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "mt8195.h" +#include "mt8195-clk.h" +#include "../adsp_helper.h" +#include "../../ops.h" +#include "../../sof-audio.h" + +static struct adsp_chip_info *adsp_info; + +static void *get_adsp_chip_data(void) +{ + return (void *)adsp_info; +} + +void __iomem *get_mbox_reg_base(u32 id) +{ + struct adsp_chip_info *adsp; + + if (id >= DSP_MBOX_NUM) + return NULL; + + adsp = get_adsp_chip_data(); + if (!adsp) + return NULL; + + return adsp->va_mboxreg[id]; +} +EXPORT_SYMBOL(get_mbox_reg_base); + +static int platform_parse_resource(struct platform_device *pdev, void *data) +{ + struct resource *res; + struct resource resource; + struct device_node *mem_region; + struct device *dev = &pdev->dev; + struct adsp_chip_info *adsp = data; + int i, ret; + + res = &resource; + mem_region = of_parse_phandle(dev->of_node, "memory-region", 0); + if (!mem_region) { + dev_err(dev, "no 'memory-region' phandle\n"); + return -ENODEV; + } + + ret = of_address_to_resource(mem_region, 0, res); + if (ret) { + dev_err(dev, "of_address_to_resource failed\n"); + return ret; + } + + dev_info(dev, "[ADSP][DMA] pbase=0x%llx, size=0x%llx\n", + (phys_addr_t)res->start, + resource_size(res)); + + ret = of_reserved_mem_device_init(dev); + if (ret) { + dev_err(dev, "of_reserved_mem_device_init failed\n"); + return ret; + } + + mem_region = of_parse_phandle(dev->of_node, "memory-region", 1); + if (!mem_region) { + dev_err(dev, "no 'memory-region' phandle\n"); + return -ENODEV; + } + + ret = of_address_to_resource(mem_region, 0, res); + if (ret) { + dev_err(dev, "of_address_to_resource failed\n"); + return ret; + } + + adsp->pa_dram = (phys_addr_t)res->start; + adsp->dramsize = (u32)resource_size(res); + if (((u32)adsp->pa_dram) & 0x1000) { + dev_err(dev, "adsp memory(0x%x) is not 4K-aligned\n", + (u32)adsp->pa_dram); + return -EINVAL; + } + + if (adsp->dramsize < TOTAL_SIZE_SHARED_DRAM_FROM_TAIL) { + dev_err(dev, "adsp memory(0x%x) is not enough for share\n", + (u32)adsp->dramsize); + return -EINVAL; + } + + dev_dbg(dev, "[ADSP] dram pbase=%pa, dramsize=0x%x\n", + &adsp->pa_dram, adsp->dramsize); + + /* Parse CFG base */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(dev, "no ADSP-CFG register resource\n"); + return -ENXIO; + } + /* remap for DSP register accessing */ + adsp->va_cfgreg = devm_ioremap_resource(dev, res); + if (IS_ERR(adsp->va_cfgreg)) + return PTR_ERR(adsp->va_cfgreg); + + adsp->pa_cfgreg = (phys_addr_t)res->start; + adsp->cfgregsize = (u32)resource_size(res); + + dev_dbg(dev, "[ADSP] cfgreg-vbase=%p, cfgregsize=0x%x\n", + adsp->va_cfgreg, adsp->cfgregsize); + + /* Parse SRAM */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { + dev_err(dev, "no SRAM resource\n"); + return -ENXIO; + } + + adsp->pa_sram = (phys_addr_t)res->start; + adsp->srammsize = (u32)resource_size(res); + if (adsp->srammsize < TOTAL_SIZE_SHARED_SRAM_FROM_TAIL) { + dev_err(dev, "adsp SRAM(0x%x) is not enough for share\n", + (u32)adsp->srammsize); + return -EINVAL; + } + + dev_dbg(dev, "[ADSP] sram pbase=%pa,0x%x\n", &adsp->pa_sram, adsp->srammsize); + + /* Parse MBOX base */ + for (i = 0; i < DSP_MBOX_NUM; i++) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 2 + i); + if (!res) { + dev_err(dev, "no MBOX resource %d\n", i); + return -ENXIO; + } + + adsp->pa_mboxreg[i] = (phys_addr_t)res->start; + adsp->va_mboxreg[i] = devm_ioremap_resource(dev, res); + if (IS_ERR(adsp->va_mboxreg[i])) + return PTR_ERR(adsp->va_mboxreg[i]); + + dev_dbg(dev, "[ADSP]MBOX%d pa_mboxreg:%pa, va_mboxreg:%p\n", + i, &adsp->pa_mboxreg[i], adsp->va_mboxreg[i]); + } + + return ret; +} + +/* Init the basic DSP DRAM address */ +static int adsp_memory_remap_init(struct device *dev) +{ + void __iomem *vaddr_emi_map; + struct adsp_chip_info *adsp; + int offset; + + adsp = get_adsp_chip_data(); + if (!adsp) + return -ENXIO; + + vaddr_emi_map = devm_ioremap(dev, DSP_EMI_MAP_ADDR, 0x4); + if (!vaddr_emi_map) { + dev_err(dev, "error: failed to ioremap emi map base 0x%x\n", + DSP_EMI_MAP_ADDR); + return -ENOMEM; + } + + offset = adsp->pa_dram - DRAM_PHYS_BASE_FROM_DSP_VIEW; + adsp->dram_offset = offset; + offset >>= 12; + dev_info(dev, "adsp->pa_dram %llx, offset 0x%x\n", adsp->pa_dram, + offset); + WARN_ON(offset < 0); + writel(offset, vaddr_emi_map); + dev_info(dev, "After vaddr_emi_map 0x%x\n", readl(vaddr_emi_map)); + + return 0; +} + +static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data) +{ + struct device *dev = &pdev->dev; + struct adsp_chip_info *adsp = data; + u32 shared_size; + int ret = 0; + + /* remap shared-dram base to be non-cachable */ + shared_size = TOTAL_SIZE_SHARED_DRAM_FROM_TAIL; + adsp->pa_shared_dram = adsp->pa_dram + adsp->dramsize - shared_size; + if (adsp->va_dram) { + adsp->shared_dram = adsp->va_dram + DSP_DRAM_SIZE - shared_size; + } else { + adsp->shared_dram = devm_ioremap(dev, adsp->pa_shared_dram, + shared_size); + if (!adsp->shared_dram) { + dev_err(dev, "ioremap failed at line %d\n", __LINE__); + ret = -ENOMEM; + goto err; + } + } + dev_info(dev, "[ADSP] shared-dram vbase=%p, phy addr :%llx, size=0x%x\n", + adsp->shared_dram, adsp->pa_shared_dram, shared_size); +err: + return ret; +} + +static int mt8195_dsp_probe(struct snd_sof_dev *sdev) +{ + struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); + struct adsp_priv *priv; + int ret, mailbox_type; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + sdev->pdata->hw_pdata = priv; + priv->dev = sdev->dev; + priv->sdev = sdev; + + priv->adsp = devm_kzalloc(&pdev->dev, sizeof(struct adsp_chip_info), + GFP_KERNEL); + + if (!priv->adsp) + return -ENOMEM; + + adsp_info = priv->adsp; + + ret = platform_parse_resource(pdev, adsp_info); + if (ret) + return ret; + + ret = platform_parse_clock(&pdev->dev); + if (ret) + return ret; + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); + + ret = adsp_clock_on(&pdev->dev); + if (ret) { + dev_err(sdev->dev, "adsp_clock_on fail!\n"); + goto err_pm_disable; + } + + ret = adsp_sram_power_on(sdev->dev, true); + if (ret) { + dev_err(sdev->dev, "adsp_sram_power_on fail!\n"); + goto err_adsp_clock_off; + } + + ret = adsp_memory_remap_init(&pdev->dev); + if (ret) { + dev_err(sdev->dev, "adsp_memory_remap_init fail!\n"); + goto err_adsp_sram_power_off; + } + + sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, + priv->adsp->pa_sram, + priv->adsp->srammsize); + if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { + dev_err(sdev->dev, "failed to ioremap base %pa size 0x%x\n", + &priv->adsp->pa_sram, priv->adsp->srammsize); + ret = -EINVAL; + goto err_adsp_sram_power_off; + } + + sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, + priv->adsp->pa_dram, + priv->adsp->dramsize); + if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { + dev_err(sdev->dev, "failed to ioremap base %pa size 0x%x\n", + &priv->adsp->pa_dram, priv->adsp->dramsize); + ret = -EINVAL; + goto err_adsp_sram_power_off; + } + adsp_info->va_dram = sdev->bar[SOF_FW_BLK_TYPE_SRAM]; + mailbox_type = SOF_FW_BLK_TYPE_SRAM; + + ret = adsp_shared_base_ioremap(pdev, adsp_info); + if (ret) { + dev_err(sdev->dev, "adsp_shared_base_ioremap fail!\n"); + goto err_adsp_sram_power_off; + } + + sdev->mmio_bar = mailbox_type; + sdev->mailbox_bar = mailbox_type; + + return 0; + +err_adsp_sram_power_off: + adsp_sram_power_on(&pdev->dev, false); +err_adsp_clock_off: + adsp_clock_off(&pdev->dev); +err_pm_disable: + pm_runtime_disable(&pdev->dev); + + return ret; +} + +static int mt8195_dsp_remove(struct snd_sof_dev *sdev) +{ + struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); + + adsp_clock_off(&pdev->dev); + adsp_sram_power_on(&pdev->dev, false); + pm_runtime_disable(&pdev->dev); + return 0; +} + +static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type) +{ + return type; +} + +/* mt8195 ops */ +struct snd_sof_dsp_ops sof_mt8195_ops = { + /* probe and remove */ + .probe = mt8195_dsp_probe, + .remove = mt8195_dsp_remove, + + /* Block IO */ + .block_read = sof_block_read, + .block_write = sof_block_write, + + /* Register IO */ + .write = sof_io_write, + .read = sof_io_read, + .write64 = sof_io_write64, + .read64 = sof_io_read64, + + /* misc */ + .get_bar_index = mt8195_get_bar_index, + + /* Firmware ops */ + .dsp_arch_ops = &sof_xtensa_arch_ops, +}; +EXPORT_SYMBOL(sof_mt8195_ops); + +MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); +MODULE_LICENSE("Dual BSD/GPL"); diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.h b/sound/soc/sof/mediatek/mt8195/mt8195.h new file mode 100644 index 00000000000000..c1a8ac39a13797 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195.h @@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +/* + * Copyright (c) 2021 MediaTek Corporation. All rights reserved. + * + * Header file for the mt8195 DSP register definition + */ + +#ifndef __MT8195_H +#define __MT8195_H + +void __iomem *get_mbox_reg_base(u32 id); + +#define DSP_REG_BASE 0x10803000 +#define DSP_MBOX_REG_BASE(x) (get_mbox_reg_base(x)) +#define SCP_CFGREG_BASE 0x10724000 +#define DSP_SYSAO_BASE 0x1080C000 + +/***************************************************************************** + * R E G I S T E R TABLE + *****************************************************************************/ +#define DSP_JTAGMUX (0x0000) +#define DSP_ALTRESETVEC (0x0004) +#define DSP_PDEBUGDATA (0x0008) +#define DSP_PDEBUGBUS0 (0x000c) + #define PDEBUG_ENABLE BIT(0) +#define DSP_PDEBUGBUS1 (0x0010) +#define DSP_PDEBUGINST (0x0014) +#define DSP_PDEBUGLS0STAT (0x0018) +#define DSP_PDEBUGLS1STAT (0x001c) +#define DSP_PDEBUGPC (0x0020) +#define DSP_RESET_SW (0x0024) + /*reset sw*/ + #define BRESET_SW BIT(0) + #define DRESET_SW BIT(1) + #define RUNSTALL BIT(3) + #define STATVECTOR_SEL BIT(4) +#define DSP_PFAULTBUS (0x0028) +#define DSP_PFAULTINFO (0x002c) +#define DSP_GPR00 (0x0030) +#define DSP_GPR01 (0x0034) +#define DSP_GPR02 (0x0038) +#define DSP_GPR03 (0x003c) +#define DSP_GPR04 (0x0040) +#define DSP_GPR05 (0x0044) +#define DSP_GPR06 (0x0048) +#define DSP_GPR07 (0x004c) +#define DSP_GPR08 (0x0050) +#define DSP_GPR09 (0x0054) +#define DSP_GPR0A (0x0058) +#define DSP_GPR0B (0x005c) +#define DSP_GPR0C (0x0060) +#define DSP_GPR0D (0x0064) +#define DSP_GPR0E (0x0068) +#define DSP_GPR0F (0x006c) +#define DSP_GPR10 (0x0070) +#define DSP_GPR11 (0x0074) +#define DSP_GPR12 (0x0078) +#define DSP_GPR13 (0x007c) +#define DSP_GPR14 (0x0080) +#define DSP_GPR15 (0x0084) +#define DSP_GPR16 (0x0088) +#define DSP_GPR17 (0x008c) +#define DSP_GPR18 (0x0090) +#define DSP_GPR19 (0x0094) +#define DSP_GPR1A (0x0098) +#define DSP_GPR1B (0x009c) +#define DSP_GPR1C (0x00a0) +#define DSP_GPR1D (0x00a4) +#define DSP_GPR1E (0x00a8) +#define DSP_GPR1F (0x00ac) +#define DSP_TCM_OFFSET (0x00b0) /* not used */ +#define DSP_DDR_OFFSET (0x00b4) /* not used */ +#define DSP_INTFDSP (0x00d0) +#define DSP_INTFDSP_CLR (0x00d4) +#define DSP_SRAM_PD_SW1 (0x00d8) +#define DSP_SRAM_PD_SW2 (0x00dc) +#define DSP_OCD (0x00e0) +#define DSP_RG_DSP_IRQ_POL (0x00f0) /* not used */ +#define DSP_DSP_IRQ_EN (0x00f4) /* not used */ +#define DSP_DSP_IRQ_LEVEL (0x00f8) /* not used */ +#define DSP_DSP_IRQ_STATUS (0x00fc) /* not used */ +#define DSP_RG_INT2CIRQ (0x0114) +#define DSP_RG_INT_POL_CTL0 (0x0120) +#define DSP_RG_INT_EN_CTL0 (0x0130) +#define DSP_RG_INT_LV_CTL0 (0x0140) +#define DSP_RG_INT_STATUS0 (0x0150) +#define DSP_PDEBUGSTATUS0 (0x0200) +#define DSP_PDEBUGSTATUS1 (0x0204) +#define DSP_PDEBUGSTATUS2 (0x0208) +#define DSP_PDEBUGSTATUS3 (0x020c) +#define DSP_PDEBUGSTATUS4 (0x0210) +#define DSP_PDEBUGSTATUS5 (0x0214) +#define DSP_PDEBUGSTATUS6 (0x0218) +#define DSP_PDEBUGSTATUS7 (0x021c) +#define DSP_DSP2PSRAM_PRIORITY (0x0220) /* not used */ +#define DSP_AUDIO_DSP2SPM_INT (0x0224) +#define DSP_AUDIO_DSP2SPM_INT_ACK (0x0228) +#define DSP_AUDIO_DSP_DEBUG_SEL (0x022C) +#define DSP_AUDIO_DSP_EMI_BASE_ADDR (0x02E0) /* not used */ +#define DSP_AUDIO_DSP_SHARED_IRAM (0x02E4) +#define DSP_AUDIO_DSP_CKCTRL_P2P_CK_CON (0x02F0) +#define DSP_RG_SEMAPHORE00 (0x0300) +#define DSP_RG_SEMAPHORE01 (0x0304) +#define DSP_RG_SEMAPHORE02 (0x0308) +#define DSP_RG_SEMAPHORE03 (0x030C) +#define DSP_RG_SEMAPHORE04 (0x0310) +#define DSP_RG_SEMAPHORE05 (0x0314) +#define DSP_RG_SEMAPHORE06 (0x0318) +#define DSP_RG_SEMAPHORE07 (0x031C) +#define DSP_RESERVED_0 (0x03F0) +#define DSP_RESERVED_1 (0x03F4) + +/* dsp wdt */ +#define DSP_WDT_MODE (0x0400) + +/* dsp mbox */ +#define DSP_MBOX_IN_CMD(x) (DSP_MBOX_REG_BASE(x) + 0x0) +#define DSP_MBOX_IN_CMD_CLR(x) (DSP_MBOX_REG_BASE(x) + 0x04) +#define DSP_MBOX_OUT_CMD(x) (DSP_MBOX_REG_BASE(x) + 0x1c) +#define DSP_MBOX_OUT_CMD_CLR(x) (DSP_MBOX_REG_BASE(x) + 0x20) + +#define DSP_MBOX_IN_MSG0(x) (DSP_MBOX_REG_BASE(x) + 0x08) +#define DSP_MBOX_IN_MSG1(x) (DSP_MBOX_REG_BASE(x) + 0x0C) +#define DSP_MBOX_OUT_MSG0(x) (DSP_MBOX_REG_BASE(x) + 0x24) +#define DSP_MBOX_OUT_MSG1(x) (DSP_MBOX_REG_BASE(x) + 0x28) + +/*dsp sys ao*/ +#define ADSP_SRAM_POOL_CON (DSP_SYSAO_BASE + 0x30) +#define DSP_SRAM_POOL_PD_MASK 0xf +#define DSP_EMI_MAP_ADDR (DSP_SYSAO_BASE + 0x81c) + +/* DSP memories */ +#define MBOX_OFFSET 0x800000 // DRAM +#define MBOX_SIZE 0x1000 // memory.h in sof fw +#define DSP_DRAM_SIZE 0x1000000 /*16M*/ + +#define DSP_REG_BAR 4 + +#define TOTAL_SIZE_SHARED_SRAM_FROM_TAIL 0x0 + +#define SIZE_SHARED_DRAM_DL 0x40000 /*Shared buffer for Downlink*/ +#define SIZE_SHARED_DRAM_UL 0x40000 /*Shared buffer for Uplink*/ + +#define TOTAL_SIZE_SHARED_DRAM_FROM_TAIL \ + (SIZE_SHARED_DRAM_DL + SIZE_SHARED_DRAM_UL) + +#define SRAM_PHYS_BASE_FROM_DSP_VIEW (0x40000000) /* MT8195 DSP view */ +#define DRAM_PHYS_BASE_FROM_DSP_VIEW (0x60000000) /* MT8195 DSP view */ + +#endif From 488f3d388330e7ec2cb3d60b519177af6b3da0dd Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 7 Sep 2021 20:45:07 +0800 Subject: [PATCH 16/24] ASoC: SOF: mediatek: Add machine driver dsp ops for mt8195 platform Add dsp ops callback to select and register machine driver. Signed-off-by: YC Hung --- sound/soc/sof/mediatek/mt8195/mt8195.c | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index e889d54d13619d..08a7869be85731 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -28,6 +28,12 @@ static struct adsp_chip_info *adsp_info; +static struct snd_soc_acpi_mach sof_mt8195_mach = { + .id = "819501", + .drv_name = "mt8195_mt6359_rt1019_rt5682", + .sof_tplg_filename = "sof-mt8195-mt6359-rt1019-rt5682.tplg", +}; + static void *get_adsp_chip_data(void) { return (void *)adsp_info; @@ -324,6 +330,26 @@ static int mt8195_dsp_remove(struct snd_sof_dev *sdev) return 0; } +static void mt8195_machine_select(struct snd_sof_dev *sdev) +{ + struct snd_sof_pdata *sof_pdata = sdev->pdata; + struct snd_soc_acpi_mach *mach; + + mach = &sof_mt8195_mach; + if (!mach) { + dev_warn(sdev->dev, "No matching ASoC machine driver found\n"); + return; + } + + sof_pdata->tplg_filename = mach->sof_tplg_filename; + sof_pdata->machine = mach; + + /* get machine node and save it to mach->pdata */ + mach->pdata = of_get_child_by_name(sdev->dev->of_node, "sound"); + if (!mach->pdata) + dev_warn(sdev->dev, "get child machine node \"sound\" failed\n"); +} + static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type) { return type; @@ -345,6 +371,10 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { .write64 = sof_io_write64, .read64 = sof_io_read64, + /* machine driver */ + .machine_select = mt8195_machine_select, + .machine_register = sof_machine_register, + /* misc */ .get_bar_index = mt8195_get_bar_index, From 1659d6dbd769e127baedb43b14ec63d88ee9b004 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 7 Sep 2021 20:51:20 +0800 Subject: [PATCH 17/24] ASoC: SOF: mediatek: Add dai driver dsp ops callback for mt8195 Add dsp ops callback to register AFE DL2/DL3/UL4/UL5 sof dai's with ALSA Signed-off-by: YC Hung --- sound/soc/sof/mediatek/mt8195/mt8195.c | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 08a7869be85731..859b1136dc93b9 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -350,11 +350,43 @@ static void mt8195_machine_select(struct snd_sof_dev *sdev) dev_warn(sdev->dev, "get child machine node \"sound\" failed\n"); } +/* on MT8195 there is 1 to 1 match between type and BAR idx*/ static int mt8195_get_bar_index(struct snd_sof_dev *sdev, u32 type) { return type; } +static struct snd_soc_dai_driver mt8195_dai[] = { +{ + .name = "SOF_DL2", + .playback = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_DL3", + .playback = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_UL4", + .capture = { + .channels_min = 1, + .channels_max = 2, + }, +}, +{ + .name = "SOF_UL5", + .capture = { + .channels_min = 1, + .channels_max = 2, + }, +}, +}; + /* mt8195 ops */ struct snd_sof_dsp_ops sof_mt8195_ops = { /* probe and remove */ @@ -380,6 +412,10 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { /* Firmware ops */ .dsp_arch_ops = &sof_xtensa_arch_ops, + + /* DAI drivers */ + .drv = mt8195_dai, + .num_drv = ARRAY_SIZE(mt8195_dai), }; EXPORT_SYMBOL(sof_mt8195_ops); From a85c74fc2b280d9ab860e96bf9c2f58f6428219f Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 7 Sep 2021 21:48:16 +0800 Subject: [PATCH 18/24] ASoC: SOF: mediatek: Add fw loader and mt8195 dsp ops to load firmware Add mt8195-loader module with ops callback to load and run firmware on mt8195 platform. Signed-off-by: YC Hung --- sound/soc/sof/mediatek/mt8195/Makefile | 2 +- sound/soc/sof/mediatek/mt8195/mt8195-loader.c | 69 +++++++++++++++++++ sound/soc/sof/mediatek/mt8195/mt8195.c | 20 ++++++ sound/soc/sof/mediatek/mt8195/mt8195.h | 2 + 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195-loader.c diff --git a/sound/soc/sof/mediatek/mt8195/Makefile b/sound/soc/sof/mediatek/mt8195/Makefile index 870b752a2a8659..650f4bce99b247 100644 --- a/sound/soc/sof/mediatek/mt8195/Makefile +++ b/sound/soc/sof/mediatek/mt8195/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -snd-sof-mt8195-objs := mt8195.o mt8195-clk.o +snd-sof-mt8195-objs := mt8195.o mt8195-clk.o mt8195-loader.o obj-$(CONFIG_SND_SOC_SOF_MT8195) += snd-sof-mt8195.o diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-loader.c b/sound/soc/sof/mediatek/mt8195/mt8195-loader.c new file mode 100644 index 00000000000000..f5447ebefc1c89 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195-loader.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright (c) 2021 Mediatek Corporation. All rights reserved. +// +// Author: YC Hung +// +// Hardware interface for mt8195 DSP code loader + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "mt8195.h" +#include "../../ops.h" + +void hifixdsp_boot_sequence(void *pdev, u32 boot_addr) +{ + struct snd_sof_dev *sdev = pdev; + + /* ADSP bootup base */ + snd_sof_dsp_write(sdev, DSP_REG_BAR, DSP_ALTRESETVEC, boot_addr); + + /* pull high RunStall (set bit3 to 1) */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, + RUNSTALL, RUNSTALL); + + /* pull high StatVectorSel to use AltResetVec (set bit4 to 1) */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, + DSP_RESET_SW, DSP_RESET_SW); + + /* toggle DReset & BReset */ + /* pull high DReset & BReset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, + BRESET_SW | DRESET_SW, + BRESET_SW | DRESET_SW); + + /* pull low DReset & BReset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, + BRESET_SW | DRESET_SW, + 0); + + /* Enable PDebug */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_PDEBUGBUS0, + PDEBUG_ENABLE, + PDEBUG_ENABLE); + + /* release RunStall (set bit3 to 0) */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, + RUNSTALL, 0); +} + +void hifixdsp_shutdown(void *pdev) +{ + struct snd_sof_dev *sdev = pdev; + + /* Clear to 0 firstly */ + snd_sof_dsp_write(sdev, DSP_REG_BAR, DSP_RESET_SW, 0x0); + + /* RUN_STALL pull high again to reset */ + snd_sof_dsp_update_bits(sdev, DSP_REG_BAR, DSP_RESET_SW, + RUNSTALL, RUNSTALL); +} + diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 859b1136dc93b9..f0b1cbb993779b 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -226,6 +226,18 @@ static int adsp_shared_base_ioremap(struct platform_device *pdev, void *data) return ret; } +static int mt8195_run(struct snd_sof_dev *sdev) +{ + u32 adsp_bootup_addr; + + adsp_bootup_addr = SRAM_PHYS_BASE_FROM_DSP_VIEW; + dev_info(sdev->dev, "[ADSP] HIFIxDSP boot from base : 0x%08X\n", + adsp_bootup_addr); + hifixdsp_boot_sequence((void *)sdev, adsp_bootup_addr); + + return 0; +} + static int mt8195_dsp_probe(struct snd_sof_dev *sdev) { struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); @@ -393,6 +405,9 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { .probe = mt8195_dsp_probe, .remove = mt8195_dsp_remove, + /* DSP core boot */ + .run = mt8195_run, + /* Block IO */ .block_read = sof_block_read, .block_write = sof_block_write, @@ -407,6 +422,11 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { .machine_select = mt8195_machine_select, .machine_register = sof_machine_register, + /* module loading */ + .load_module = snd_sof_parse_module_memcpy, + /* firmware loading */ + .load_firmware = snd_sof_load_firmware_memcpy, + /* misc */ .get_bar_index = mt8195_get_bar_index, diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.h b/sound/soc/sof/mediatek/mt8195/mt8195.h index c1a8ac39a13797..48e67cf91c24a7 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.h +++ b/sound/soc/sof/mediatek/mt8195/mt8195.h @@ -148,4 +148,6 @@ void __iomem *get_mbox_reg_base(u32 id); #define SRAM_PHYS_BASE_FROM_DSP_VIEW (0x40000000) /* MT8195 DSP view */ #define DRAM_PHYS_BASE_FROM_DSP_VIEW (0x60000000) /* MT8195 DSP view */ +void hifixdsp_boot_sequence(void *pdev, u32 boot_addr); +void hifixdsp_shutdown(void *pdev); #endif From b4f7aa75a5f541ef1b353ff7b327ff50a0e066b7 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 7 Sep 2021 22:15:10 +0800 Subject: [PATCH 19/24] ASoC: SOF: mediatek: Add PCM stream callback for mt8195 Support pcm stream callback for hw_params and hw_free Signed-off-by: YC Hung --- sound/soc/sof/mediatek/Makefile | 3 +- sound/soc/sof/mediatek/adsp_helper.h | 3 + sound/soc/sof/mediatek/adsp_pcm.c | 224 +++++++++++++++++++++++++ sound/soc/sof/mediatek/adsp_pcm.h | 67 ++++++++ sound/soc/sof/mediatek/mt8195/mt8195.c | 11 ++ 5 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/mediatek/adsp_pcm.c create mode 100644 sound/soc/sof/mediatek/adsp_pcm.h diff --git a/sound/soc/sof/mediatek/Makefile b/sound/soc/sof/mediatek/Makefile index e8ec6da981de4a..c5aea1bd5ca847 100644 --- a/sound/soc/sof/mediatek/Makefile +++ b/sound/soc/sof/mediatek/Makefile @@ -1,2 +1,3 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -obj-$(CONFIG_SND_SOC_SOF_MT8195) += mt8195/ +snd-sof-mtk-dsp-objs := adsp_pcm.o +obj-$(CONFIG_SND_SOC_SOF_MT8195) += snd-sof-mtk-dsp.o mt8195/ diff --git a/sound/soc/sof/mediatek/adsp_helper.h b/sound/soc/sof/mediatek/adsp_helper.h index d62d0a8ff9400a..ca4f6742ea6e02 100644 --- a/sound/soc/sof/mediatek/adsp_helper.h +++ b/sound/soc/sof/mediatek/adsp_helper.h @@ -7,6 +7,7 @@ #ifndef __ADSP_HELPER_H__ #define __ADSP_HELPER_H__ +#include "adsp_pcm.h" /* * Global important adsp data structure. */ @@ -48,6 +49,8 @@ struct adsp_priv { u32 (*ap2adsp_addr)(u32 addr); u32 (*adsp2ap_addr)(u32 addr); + struct adsp_mem_pool mem_pool; + void *private_data; }; diff --git a/sound/soc/sof/mediatek/adsp_pcm.c b/sound/soc/sof/mediatek/adsp_pcm.c new file mode 100644 index 00000000000000..4c60dfe9ef3bbe --- /dev/null +++ b/sound/soc/sof/mediatek/adsp_pcm.c @@ -0,0 +1,224 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2021 Mediatek Corporation. All rights reserved. +// +// Author: Bo Pan +// YC Hung +// +// The Mediatek ADSP PCM implementation +// + +#include "adsp_helper.h" + +int adsp_genpool_create(struct adsp_mem_pool *mem_pool, + struct adsp_mem *mem_info) +{ + int ret; + unsigned long va_start; + size_t va_chunk; + + mem_pool->dram_pool = gen_pool_create(SOF_MIN_ADSP_SHIFT, -1); + if (!mem_pool->dram_pool) + return -ENOMEM; + + va_start = mem_info->va_addr; + va_chunk = mem_info->size; + if (!va_start || !va_chunk) { + ret = -EINVAL; + goto out; + } + ret = gen_pool_add_virt(mem_pool->dram_pool, va_start, + mem_info->phy_addr, va_chunk, -1); + if (ret) + goto out; + + mem_pool->dram = mem_info; + + return 0; + +out: + gen_pool_destroy(mem_pool->dram_pool); + mem_pool->dram_pool = NULL; + return ret; +} + +int adsp_genpool_destroy(struct adsp_mem_pool *mem_pool) +{ + gen_pool_destroy(mem_pool->dram_pool); + mem_pool->dram_pool = NULL; + mem_pool->dram = NULL; + return 0; +} + +int adsp_genpool_alloc(struct adsp_mem_pool *mem_pool, unsigned char **vaddr, + dma_addr_t *paddr, unsigned int size) +{ + if (!mem_pool || !mem_pool->dram_pool) + return -EINVAL; + + *vaddr = (unsigned char *)gen_pool_dma_alloc(mem_pool->dram_pool, + size, paddr); + if (!*vaddr) + return -ENOMEM; + + return 0; +} + +int adsp_genpool_alloc_align(struct adsp_mem_pool *mem_pool, + unsigned char **vaddr, dma_addr_t *paddr, + unsigned int size, int align) +{ + if (!mem_pool || !mem_pool->dram_pool) + return -EINVAL; + + *vaddr = (unsigned char *)gen_pool_dma_alloc_align(mem_pool->dram_pool, + size, paddr, align); + if (!*vaddr) + return -ENOMEM; + + return 0; +} + +int adsp_genpool_free(struct adsp_mem_pool *mem_pool, + unsigned char *vaddr, size_t size) +{ + if (!mem_pool || !mem_pool->dram_pool) + return -EINVAL; + + /* allocate VA with gen pool */ + if (*vaddr) + gen_pool_free(mem_pool->dram_pool, (unsigned long)vaddr, size); + + return 0; +} + +int adsp_pcm_hw_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct sof_ipc_stream_params *ipc_params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_component *scomp = sdev->component; + struct device *dev = sdev->dev; + struct snd_sof_pcm *spcm; + struct snd_dma_buffer *dmab; + struct snd_dma_buffer *pg_table; + struct snd_dma_buffer *pg_table_backup; + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct adsp_mem_pool *mem_pool = &priv->mem_pool; + size_t dma_bytes; + int ret; + + dma_bytes = runtime->dma_bytes; + + spcm = snd_sof_find_spcm_dai(scomp, rtd); + if (!spcm) { + dev_err(sdev->dev, "%s : can't find PCM with DAI ID %d\n", + __func__, rtd->dai_link->id); + return -EINVAL; + } + + pg_table = &spcm->stream[substream->stream].page_table; + + if (runtime->buffer_changed && substream->managed_buffer_alloc) { + /* free dma pages allocated by common layer + * if page table private data is not NULL, + * this hw_params may be trigged by PCM xrun + */ + if (pg_table->private_data) + return 0; + + snd_pcm_lib_free_pages(substream); + + /* prepare dma buf struct for dsp runtime dma and page table*/ + dmab = kzalloc(sizeof(*dmab) * 2, GFP_KERNEL); + if (!dmab) + return -ENOMEM; + pg_table_backup = dmab + 1; + /* backup original page table address */ + pg_table_backup->area = pg_table->area; + pg_table_backup->addr = pg_table->addr; + pg_table->private_data = pg_table_backup; + ret = adsp_genpool_alloc(mem_pool, &pg_table->area, + &pg_table->addr, pg_table->bytes); + if (ret != 0) + goto out; + + pg_table->addr = priv->ap2adsp_addr(pg_table->addr); + dmab->dev.type = SNDRV_DMA_TYPE_DEV; + dmab->dev.dev = substream->pcm->card->dev; + dmab->bytes = dma_bytes; + /* allocate dma pages from dsp share buffer */ + ret = adsp_genpool_alloc_align(mem_pool, &dmab->area, &dmab->addr, + dma_bytes, PAGE_SIZE); + if (ret != 0) + goto out; + + dmab->addr = priv->ap2adsp_addr(dmab->addr); + snd_pcm_set_runtime_buffer(substream, dmab); + snd_sof_create_page_table(dev, dmab, + pg_table->area, dma_bytes); + + /* replace ipc parameters for dma buffer */ + ipc_params->buffer.phy_addr = pg_table->addr; + } + + return 0; +out: + if (dmab->area) + adsp_genpool_free(mem_pool, dmab->area, dmab->bytes); + + if (pg_table_backup->area && pg_table->area) { + adsp_genpool_free(mem_pool, pg_table->area, + pg_table->bytes); + pg_table->area = pg_table_backup->area; + pg_table->addr = pg_table_backup->addr; + pg_table->private_data = NULL; + } + + kfree(dmab); + + return ret; +} + +int adsp_pcm_hw_free(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_soc_component *scomp = sdev->component; + struct snd_dma_buffer *dmab; + struct snd_dma_buffer *pg_table; + struct snd_dma_buffer *pg_table_backup; + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct adsp_mem_pool *mem_pool = &priv->mem_pool; + struct snd_sof_pcm *spcm; + + spcm = snd_sof_find_spcm_dai(scomp, rtd); + if (!spcm) { + dev_err(sdev->dev, "%s : can't find PCM with DAI ID %d\n", + __func__, rtd->dai_link->id); + return -EINVAL; + } + + pg_table = &spcm->stream[substream->stream].page_table; + + if (substream->managed_buffer_alloc) { + pg_table_backup = pg_table->private_data; + dmab = snd_pcm_get_dma_buf(substream); + if (dmab && dmab->area) + adsp_genpool_free(mem_pool, dmab->area, dmab->bytes); + snd_pcm_set_runtime_buffer(substream, NULL); + if (pg_table_backup && pg_table->area) { + adsp_genpool_free(mem_pool, pg_table->area, + pg_table->bytes); + pg_table->area = pg_table_backup->area; + pg_table->addr = pg_table_backup->addr; + pg_table->private_data = NULL; + } + + kfree(dmab); + } + return 0; +} + diff --git a/sound/soc/sof/mediatek/adsp_pcm.h b/sound/soc/sof/mediatek/adsp_pcm.h new file mode 100644 index 00000000000000..72ea048c82bbb5 --- /dev/null +++ b/sound/soc/sof/mediatek/adsp_pcm.h @@ -0,0 +1,67 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +/* + * This file is provided under a dual BSD/GPLv2 license. When using or + * redistributing this file, you may do so under either license. + * + * Copyright(c) 2021 Mediatek Corporation. All rights reserved. + * + * Author: Bo Pan + * YC Hung + */ + +#ifndef __SOF_ADSP_PCM_H +#define __SOF_ADSP_PCM_H +#include +#include +#include +#include +#include "../ops.h" +#include "../sof-audio.h" + +#define SOF_MIN_ADSP_SHIFT (8) +#define SOF_MIN_ADSP_POOL_SIZE BIT(SOF_MIN_ADSP_SHIFT) + +struct adsp_mem { + unsigned long long phy_addr; + unsigned long long va_addr; + unsigned long long size; + unsigned char *vir_addr; +}; + +struct adsp_mem_pool { + struct gen_pool *dram_pool; + struct adsp_mem *dram; +}; + +/* adsp share memory manage */ +int adsp_genpool_create(struct adsp_mem_pool *mem_pool, + struct adsp_mem *mem_info); + +int adsp_genpool_destroy(struct adsp_mem_pool *mem_pool); + +int adsp_genpool_alloc(struct adsp_mem_pool *mem_pool, + unsigned char **vaddr, + dma_addr_t *paddr, + unsigned int size); + +int adsp_genpool_alloc_align(struct adsp_mem_pool *mem_pool, + unsigned char **vaddr, + dma_addr_t *paddr, + unsigned int size, + int align); + +int adsp_genpool_free(struct adsp_mem_pool *mem_pool, + unsigned char *vaddr, + size_t size); + +/* SOF adsp pcm */ +int adsp_pcm_hw_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct sof_ipc_stream_params *ipc_params); + +int adsp_pcm_hw_free(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream); + +#endif /* __SOF_ADSP_PCM_H */ + diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index f0b1cbb993779b..99a9648a72a5d4 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -427,6 +427,10 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { /* firmware loading */ .load_firmware = snd_sof_load_firmware_memcpy, + /* stream callbacks */ + .pcm_hw_params = adsp_pcm_hw_params, + .pcm_hw_free = adsp_pcm_hw_free, + /* misc */ .get_bar_index = mt8195_get_bar_index, @@ -436,6 +440,13 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { /* DAI drivers */ .drv = mt8195_dai, .num_drv = ARRAY_SIZE(mt8195_dai), + + /* ALSA HW info flags */ + .hw_info = SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, }; EXPORT_SYMBOL(sof_mt8195_ops); From 583f14f9fb0d6bafce737cddb408eb75732de4af Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 7 Sep 2021 23:33:11 +0800 Subject: [PATCH 20/24] ASoC: SOF: mediatek: Add DSP PM callback for mt8195 Add DSP PM callback for supsend and resume Signed-off-by: YC Hung --- sound/soc/sof/mediatek/mt8195/mt8195.c | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 99a9648a72a5d4..53392737cba016 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -342,6 +342,42 @@ static int mt8195_dsp_remove(struct snd_sof_dev *sdev) return 0; } +static int mt8195_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) +{ + struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); + + /* stall and reset dsp */ + hifixdsp_shutdown(sdev); + + /* turn off adsp clock */ + adsp_clock_off(&pdev->dev); + + /* power down adsp sram */ + adsp_sram_power_on(&pdev->dev, false); + + return 0; +} + +static int mt8195_dsp_resume(struct snd_sof_dev *sdev) +{ + struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); + int ret; + + /* turn on adsp clock */ + ret = adsp_clock_on(&pdev->dev); + if (ret) { + dev_err(sdev->dev, "adsp_clock_on fail!\n"); + return ret; + } + + /* power on adsp sram */ + ret = adsp_sram_power_on(sdev->dev, true); + if (ret) + dev_err(sdev->dev, "[ADSP] adsp_sram_power_on fail!\n"); + + return ret; +} + static void mt8195_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *sof_pdata = sdev->pdata; @@ -441,6 +477,10 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { .drv = mt8195_dai, .num_drv = ARRAY_SIZE(mt8195_dai), + /* PM */ + .suspend = mt8195_dsp_suspend, + .resume = mt8195_dsp_resume, + /* ALSA HW info flags */ .hw_info = SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_MMAP_VALID | From 2ac0d186ef66b23da6f426673c03397f6284de00 Mon Sep 17 00:00:00 2001 From: YC Hung Date: Wed, 8 Sep 2021 00:10:16 +0800 Subject: [PATCH 21/24] ASoC: SOF: mediatek: Add IPC support for mt8195 Add IPC module for mt8195 and exposed ops callback for to synchronize SOF IPC message between host and DSP Signed-off-by: YC Hung --- sound/soc/sof/mediatek/Makefile | 2 +- sound/soc/sof/mediatek/adsp_helper.h | 4 +- sound/soc/sof/mediatek/adsp_ipc.c | 69 ++++++ sound/soc/sof/mediatek/adsp_ipc.h | 47 ++++ sound/soc/sof/mediatek/mt8195/Makefile | 2 +- sound/soc/sof/mediatek/mt8195/mt8195-ipc.c | 249 +++++++++++++++++++++ sound/soc/sof/mediatek/mt8195/mt8195-ipc.h | 14 ++ sound/soc/sof/mediatek/mt8195/mt8195.c | 97 ++++++++ 8 files changed, 480 insertions(+), 4 deletions(-) create mode 100644 sound/soc/sof/mediatek/adsp_ipc.c create mode 100644 sound/soc/sof/mediatek/adsp_ipc.h create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195-ipc.c create mode 100644 sound/soc/sof/mediatek/mt8195/mt8195-ipc.h diff --git a/sound/soc/sof/mediatek/Makefile b/sound/soc/sof/mediatek/Makefile index c5aea1bd5ca847..978e1244d63198 100644 --- a/sound/soc/sof/mediatek/Makefile +++ b/sound/soc/sof/mediatek/Makefile @@ -1,3 +1,3 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -snd-sof-mtk-dsp-objs := adsp_pcm.o +snd-sof-mtk-dsp-objs := adsp_ipc.o adsp_pcm.o obj-$(CONFIG_SND_SOC_SOF_MT8195) += snd-sof-mtk-dsp.o mt8195/ diff --git a/sound/soc/sof/mediatek/adsp_helper.h b/sound/soc/sof/mediatek/adsp_helper.h index ca4f6742ea6e02..c48501549c24cc 100644 --- a/sound/soc/sof/mediatek/adsp_helper.h +++ b/sound/soc/sof/mediatek/adsp_helper.h @@ -8,11 +8,10 @@ #define __ADSP_HELPER_H__ #include "adsp_pcm.h" +#include "adsp_ipc.h" /* * Global important adsp data structure. */ -#define DSP_MBOX_NUM 3 - struct adsp_chip_info { phys_addr_t pa_sram; phys_addr_t pa_dram; /* adsp dram physical base */ @@ -38,6 +37,7 @@ struct adsp_priv { /* DSP IPC handler */ struct mbox_controller *adsp_mbox; + struct mtk_adsp_ipi ipi[DSP_MBOX_NUM]; /* Power domain handling */ int num_domains; diff --git a/sound/soc/sof/mediatek/adsp_ipc.c b/sound/soc/sof/mediatek/adsp_ipc.c new file mode 100644 index 00000000000000..945efaaf3f1d2c --- /dev/null +++ b/sound/soc/sof/mediatek/adsp_ipc.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2021 Mediatek Corporation. All rights reserved. +// +//Author: Allen-KH Cheng +// +// The Mediatek ADSP IPC implementation +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "adsp_helper.h" + +/* DSP SOF IPC API */ + +static void adsp_ipi_recv(struct mbox_client *c, void *mssg) +{ + struct mtk_adsp_ipi *ipi = container_of(c, struct mtk_adsp_ipi, cl); + + if (ipi->ops && ipi->ops->handle_recv) + ipi->ops->handle_recv(ipi); +} + +int adsp_ipi_send(struct snd_sof_dev *sdev, int idx, uint32_t op) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct adsp_mbox_ch_info *ch_info = priv->ipi[idx].chan->con_priv; + int ret; + + ch_info->ipi_op_val = op; + ret = mbox_send_message(priv->ipi[idx].chan, NULL); + if (ret < 0) + dev_err(sdev->dev, "failed to send message via mbox: %d\n", ret); + + return ret; +} + +void adsp_ipi_request(struct snd_sof_dev *sdev, int idx, struct mtk_adsp_ipi_ops *ops) +{ + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct mbox_client *cl; + + cl = &priv->ipi[idx].cl; + cl->dev = sdev->dev; + cl->tx_block = false; + cl->knows_txdone = false; + cl->tx_prepare = NULL; + cl->rx_callback = adsp_ipi_recv; + + priv->ipi[idx].chan = mbox_request_channel(cl, idx); + priv->ipi[idx].ops = ops; + priv->ipi[idx].private_data = priv; +} + +void *adsp_ipi_get_data(struct mtk_adsp_ipi *ipi) +{ + if (!ipi) + return NULL; + + return ipi->private_data; +} + diff --git a/sound/soc/sof/mediatek/adsp_ipc.h b/sound/soc/sof/mediatek/adsp_ipc.h new file mode 100644 index 00000000000000..f39298dc1fa9ff --- /dev/null +++ b/sound/soc/sof/mediatek/adsp_ipc.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2021 Mediatek Corporation. All rights reserved. + * + * Header file for the DSP IPC implementation + */ + +#ifndef ADSP_IPC_H +#define ADSP_IPC_H + +#include +#include +#include +#include +#include +#include "../ops.h" + +struct mtk_adsp_ipi; + +struct mtk_adsp_ipi_ops { + void (*handle_recv)(struct mtk_adsp_ipi *ipc); +}; + +struct mtk_adsp_ipi { + struct mbox_client cl; + struct mbox_chan *chan; + struct mtk_adsp_ipi_ops *ops; + void *private_data; +}; + +struct adsp_mbox_ch_info { + u32 id; + u32 ipi_op_val; + struct adsp_priv *priv; +}; + +#define DSP_MBOX_NUM 3 + +#define ADSP_IPI_MBOX_REQ 0 +#define ADSP_IPI_MBOX_RSP 1 +#define ADSP_IPI_OP_REQ 0x1 +#define ADSP_IPI_OP_RSP 0x2 + +void adsp_ipi_request(struct snd_sof_dev *sdev, int idx, struct mtk_adsp_ipi_ops *ops); +void *adsp_ipi_get_data(struct mtk_adsp_ipi *ipi); +int adsp_ipi_send(struct snd_sof_dev *sdev, int idx, uint32_t op); +#endif /* ADSP_IPC_H */ diff --git a/sound/soc/sof/mediatek/mt8195/Makefile b/sound/soc/sof/mediatek/mt8195/Makefile index 650f4bce99b247..6e8aef9410b6a7 100644 --- a/sound/soc/sof/mediatek/mt8195/Makefile +++ b/sound/soc/sof/mediatek/mt8195/Makefile @@ -1,4 +1,4 @@ # SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) -snd-sof-mt8195-objs := mt8195.o mt8195-clk.o mt8195-loader.o +snd-sof-mt8195-objs := mt8195.o mt8195-clk.o mt8195-loader.o mt8195-ipc.o obj-$(CONFIG_SND_SOC_SOF_MT8195) += snd-sof-mt8195.o diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-ipc.c b/sound/soc/sof/mediatek/mt8195/mt8195-ipc.c new file mode 100644 index 00000000000000..a6eeaec5c96ff2 --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195-ipc.c @@ -0,0 +1,249 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// Copyright(c) 2021 Mediatek Corporation. All rights reserved. +// +//Author: Allen-KH Cheng +// +// The Mediatek ADSP IPC implementation +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../adsp_ipc.h" +#include "../adsp_helper.h" +#include "mt8195-ipc.h" +#include "mt8195.h" + +int trace_boot_event; + +static void mt8195_get_reply(struct snd_sof_dev *sdev) +{ + struct snd_sof_ipc_msg *msg = sdev->msg; + struct sof_ipc_reply reply; + int ret = 0; + + if (!msg) { + dev_warn(sdev->dev, "unexpected ipc interrupt\n"); + return; + } + + /* get reply */ + sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply)); + + if (reply.error < 0) { + memcpy(msg->reply_data, &reply, sizeof(reply)); + ret = reply.error; + } else { + /* reply has correct size? */ + if (reply.hdr.size != msg->reply_size) { + dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", + msg->reply_size, reply.hdr.size); + ret = -EINVAL; + } + + /* read the message */ + if (msg->reply_size > 0) + sof_mailbox_read(sdev, sdev->host_box.offset, + msg->reply_data, msg->reply_size); + } + + msg->reply_error = ret; +} + +static void mt8195_dsp_handle_reply(struct mtk_adsp_ipi *ipi) +{ + struct adsp_priv *priv = adsp_ipi_get_data(ipi); + unsigned long flags; + + spin_lock_irqsave(&priv->sdev->ipc_lock, flags); + mt8195_get_reply(priv->sdev); + snd_sof_ipc_reply(priv->sdev, 0); + spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); +} + +static void mt8195_dsp_handle_request(struct mtk_adsp_ipi *ipi) +{ + struct adsp_priv *priv = adsp_ipi_get_data(ipi); + u32 p; /* panic code */ + int ret; + + /* Read the message from the debug box. */ + sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, + &p, sizeof(p)); + + /* Check to see if the message is a panic code 0x0dead*** */ + if ((p & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { + snd_sof_dsp_panic(priv->sdev, p); + } else { + snd_sof_ipc_msgs_rx(priv->sdev); + + /* tell DSP cmd is done */ + ret = adsp_ipi_send(priv->sdev, ADSP_IPI_MBOX_RSP, ADSP_IPI_OP_RSP); + if (ret) + dev_err(priv->dev, "request send ipi failed"); + } +} + +static void mt8195_dsp_handle_debug_message(struct mtk_adsp_ipi *ipi) +{ + trace_boot_event = *(u32 *)DSP_MBOX_OUT_MSG0(2); +} + +static struct mtk_adsp_ipi_ops mt8195_ipi_dsp_reply = { + .handle_recv = mt8195_dsp_handle_reply, +}; + +static struct mtk_adsp_ipi_ops mt8195_ipi_dsp_request = { + .handle_recv = mt8195_dsp_handle_request, +}; + +static struct mtk_adsp_ipi_ops mt8195_debug_dsp_message = { + .handle_recv = mt8195_dsp_handle_debug_message, +}; + +static irqreturn_t mt8195_ipi_irq_handler(int irq, void *data) +{ + struct mbox_chan *ch = (struct mbox_chan *)data; + struct adsp_mbox_ch_info *ch_info = ch->con_priv; + u32 id = ch_info->id; + u32 op = *(u32 *)DSP_MBOX_OUT_CMD(id); + + *(u32 *)DSP_MBOX_OUT_CMD_CLR(id) = op; /* clear DSP->CPU int */ + return IRQ_WAKE_THREAD; +} + +static irqreturn_t mt8195_ipi_handler(int irq, void *data) +{ + struct mbox_chan *ch = (struct mbox_chan *)data; + struct adsp_mbox_ch_info *ch_info = ch->con_priv; + + mbox_chan_received_data(ch, ch_info); + + return IRQ_HANDLED; +} + +static struct mbox_chan *mt8195_mbox_xlate(struct mbox_controller *mbox, + const struct of_phandle_args *sp) +{ + return &mbox->chans[sp->args[0]]; +} + +static int mt8195_mbox_startup(struct mbox_chan *chan) +{ + struct adsp_mbox_ch_info *ch_info = chan->con_priv; + struct device *dev = chan->mbox->dev; + struct snd_sof_dev *sdev; + struct platform_device *pdev; + int ret; + int irq; + char *name; + + sdev = ch_info->priv->sdev; + pdev = container_of(sdev->dev, struct platform_device, dev); + + name = kasprintf(GFP_KERNEL, "mbox%d", ch_info->id); + if (!name) + return -ENOMEM; + + irq = platform_get_irq_byname(pdev, name); + if (irq < 0) { + dev_err(sdev->dev, "Failed to get ipc irq\n"); + ret = -ENODEV; + goto err_name_free; + } + + ret = devm_request_threaded_irq(dev, irq, + mt8195_ipi_irq_handler, mt8195_ipi_handler, + IRQF_TRIGGER_NONE, name, + chan); + if (ret < 0) + dev_err(dev, "failed to request irq %d\n", irq); + +err_name_free: + kfree(name); + return ret; +} + +/* TODO:: implement later , cuurently no use*/ +static void mt8195_mbox_shutdown(struct mbox_chan *chan) +{ +} + +static int mt8195_mbox_send_data(struct mbox_chan *chan, void *data) +{ + struct adsp_mbox_ch_info *ch_info = chan->con_priv; + + *(u32 *)DSP_MBOX_IN_CMD(ch_info->id) = ch_info->ipi_op_val; + + return 0; +} + +static bool mt8195_mbox_last_tx_done(struct mbox_chan *chan) +{ + return true; +} + +static const struct mbox_chan_ops adsp_mbox_chan_ops = { + .send_data = mt8195_mbox_send_data, + .startup = mt8195_mbox_startup, + .shutdown = mt8195_mbox_shutdown, + .last_tx_done = mt8195_mbox_last_tx_done, +}; + +int mt8195_mbox_init(struct snd_sof_dev *sdev) +{ + struct device *dev = sdev->dev; + struct adsp_priv *priv = sdev->pdata->hw_pdata; + struct mbox_controller *mbox; + int ret; + int i; + + mbox = devm_kzalloc(dev, sizeof(*mbox), GFP_KERNEL); + if (!mbox) + return -ENOMEM; + + priv->adsp_mbox = mbox; + mbox->dev = dev; + mbox->ops = &adsp_mbox_chan_ops; + mbox->txdone_irq = false; + mbox->txdone_poll = true; + mbox->of_xlate = mt8195_mbox_xlate; + mbox->num_chans = DSP_MBOX_NUM; + mbox->chans = devm_kcalloc(mbox->dev, mbox->num_chans, + sizeof(*mbox->chans), GFP_KERNEL); + if (!mbox->chans) + return -ENOMEM; + + for (i = 0; i < mbox->num_chans; i++) { + struct adsp_mbox_ch_info *ch_info; + + ch_info = devm_kzalloc(mbox->dev, sizeof(*ch_info), GFP_KERNEL); + if (!ch_info) + return -ENOMEM; + + ch_info->id = i; + ch_info->priv = priv; + mbox->chans[i].con_priv = ch_info; + } + + ret = mbox_controller_register(mbox); + if (ret < 0) { + dev_err(dev, "error: failed to register mailbox:%d\n", ret); + return ret; + } + + /* init value */ + trace_boot_event = 0xffff; + adsp_ipi_request(sdev, 0, &mt8195_ipi_dsp_reply); + adsp_ipi_request(sdev, 1, &mt8195_ipi_dsp_request); + adsp_ipi_request(sdev, 2, &mt8195_debug_dsp_message); + + return ret; +} diff --git a/sound/soc/sof/mediatek/mt8195/mt8195-ipc.h b/sound/soc/sof/mediatek/mt8195/mt8195-ipc.h new file mode 100644 index 00000000000000..bd1f89b381a3ae --- /dev/null +++ b/sound/soc/sof/mediatek/mt8195/mt8195-ipc.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2021 Mediatek + * + * Header file for the DSP IPC implementation + */ + +#ifndef MT8195_IPC_H +#define MT8195_IPC_H +#include "../../sof-priv.h" + +int mt8195_mbox_init(struct snd_sof_dev *sdev); + +#endif /* MT8195_IPC_H */ diff --git a/sound/soc/sof/mediatek/mt8195/mt8195.c b/sound/soc/sof/mediatek/mt8195/mt8195.c index 53392737cba016..d4f5faa4e7b2ca 100644 --- a/sound/soc/sof/mediatek/mt8195/mt8195.c +++ b/sound/soc/sof/mediatek/mt8195/mt8195.c @@ -22,6 +22,7 @@ #include #include "mt8195.h" #include "mt8195-clk.h" +#include "mt8195-ipc.h" #include "../adsp_helper.h" #include "../../ops.h" #include "../../sof-audio.h" @@ -54,6 +55,30 @@ void __iomem *get_mbox_reg_base(u32 id) } EXPORT_SYMBOL(get_mbox_reg_base); +static int mt8195_get_mailbox_offset(struct snd_sof_dev *sdev) +{ + return MBOX_OFFSET; +} + +static int mt8195_get_window_offset(struct snd_sof_dev *sdev, u32 id) +{ + return MBOX_OFFSET; +} + +static int mt8195_ipi_init(struct snd_sof_dev *sdev) +{ + return mt8195_mbox_init(sdev); +} + +static int mt8195_send_msg(struct snd_sof_dev *sdev, + struct snd_sof_ipc_msg *msg) +{ + sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, + msg->msg_size); + + return adsp_ipi_send(sdev, ADSP_IPI_MBOX_REQ, ADSP_IPI_OP_REQ); +} + static int platform_parse_resource(struct platform_device *pdev, void *data) { struct resource *res; @@ -238,10 +263,31 @@ static int mt8195_run(struct snd_sof_dev *sdev) return 0; } +static u32 dram_remap_to_dsp(u32 dram_addr) +{ + struct adsp_chip_info *adsp = get_adsp_chip_data(); + u32 dsp_dram_addr; + + dsp_dram_addr = dram_addr - adsp->dram_offset; + + return dsp_dram_addr; +} + +static u32 dram_remap_to_ap(u32 dram_addr) +{ + struct adsp_chip_info *adsp = get_adsp_chip_data(); + u32 dsp_dram_addr; + + dsp_dram_addr = dram_addr + adsp->dram_offset; + + return dsp_dram_addr; +} + static int mt8195_dsp_probe(struct snd_sof_dev *sdev) { struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); struct adsp_priv *priv; + struct adsp_mem share_dram; int ret, mailbox_type; priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -289,6 +335,12 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev) goto err_adsp_sram_power_off; } + ret = mt8195_ipi_init(sdev); + if (ret < 0) { + dev_err(sdev->dev, "failed to init adsp ipi:%d\n", ret); + goto err_adsp_sram_power_off; + } + sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, priv->adsp->pa_sram, priv->adsp->srammsize); @@ -317,9 +369,27 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev) goto err_adsp_sram_power_off; } + sdev->bar[DSP_REG_BAR] = adsp_info->va_cfgreg; + sdev->mmio_bar = mailbox_type; sdev->mailbox_bar = mailbox_type; + /* set default mailbox offset for FW ready message */ + sdev->dsp_box.offset = mt8195_get_mailbox_offset(sdev); + + priv->adsp2ap_addr = dram_remap_to_ap; + priv->ap2adsp_addr = dram_remap_to_dsp; + share_dram.phy_addr = priv->adsp->pa_shared_dram; + share_dram.va_addr = (unsigned long long)priv->adsp->shared_dram; + share_dram.vir_addr = (unsigned char *)priv->adsp->shared_dram; + share_dram.size = SIZE_SHARED_DRAM_UL + SIZE_SHARED_DRAM_DL; + + ret = adsp_genpool_create(&priv->mem_pool, &share_dram); + if (ret) { + dev_err(sdev->dev, "adsp_genpool_create fail!\n"); + goto err_adsp_sram_power_off; + } + return 0; err_adsp_sram_power_off: @@ -335,10 +405,12 @@ static int mt8195_dsp_probe(struct snd_sof_dev *sdev) static int mt8195_dsp_remove(struct snd_sof_dev *sdev) { struct platform_device *pdev = container_of(sdev->dev, struct platform_device, dev); + struct adsp_priv *priv = sdev->pdata->hw_pdata; adsp_clock_off(&pdev->dev); adsp_sram_power_on(&pdev->dev, false); pm_runtime_disable(&pdev->dev); + adsp_genpool_destroy(&priv->mem_pool); return 0; } @@ -378,6 +450,22 @@ static int mt8195_dsp_resume(struct snd_sof_dev *sdev) return ret; } +static int mt8195_ipc_msg_data(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + void *p, size_t sz) +{ + sof_mailbox_read(sdev, sdev->dsp_box.offset, p, sz); + + return 0; +} + +static int mt8195_ipc_pcm_params(struct snd_sof_dev *sdev, + struct snd_pcm_substream *substream, + const struct sof_ipc_pcm_params_reply *reply) +{ + return 0; +} + static void mt8195_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *sof_pdata = sdev->pdata; @@ -454,6 +542,15 @@ struct snd_sof_dsp_ops sof_mt8195_ops = { .write64 = sof_io_write64, .read64 = sof_io_read64, + /* ipc */ + .send_msg = mt8195_send_msg, + .fw_ready = sof_fw_ready, + .get_mailbox_offset = mt8195_get_mailbox_offset, + .get_window_offset = mt8195_get_window_offset, + + .ipc_msg_data = mt8195_ipc_msg_data, + .ipc_pcm_params = mt8195_ipc_pcm_params, + /* machine driver */ .machine_select = mt8195_machine_select, .machine_register = sof_machine_register, From 8f38f9979372bb6d213faab016649ae20a31f34e Mon Sep 17 00:00:00 2001 From: YC Hung Date: Fri, 27 Aug 2021 23:05:21 +0800 Subject: [PATCH 22/24] dt-ndings: mediatek: mt8195: add dsp document This patch adds document for mt8195 DSP Signed-off-by: YC Hung --- .../bindings/dsp/mtk,mt8195-dsp.yaml | 131 ++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Documentation/devicetree/bindings/dsp/mtk,mt8195-dsp.yaml diff --git a/Documentation/devicetree/bindings/dsp/mtk,mt8195-dsp.yaml b/Documentation/devicetree/bindings/dsp/mtk,mt8195-dsp.yaml new file mode 100644 index 00000000000000..2ace3fe1ff6144 --- /dev/null +++ b/Documentation/devicetree/bindings/dsp/mtk,mt8195-dsp.yaml @@ -0,0 +1,131 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/dsp/mtk,mt8195-dsp.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek mt8195 DSP core + +maintainers: + - YC Hung + +description: | + Some boards from mt8195 contain a DSP core used for + advanced pre- and post- audio processing. + +properties: + compatible: + const: mediatek,mt8195-audio_dsp + + reg: + maxItems: 5 + + reg-names: + maxItems: 5 + + interrupts: + maxItems: 4 + + interrupt-names: + maxItems: 4 + + clocks: + items: + - description: mux for dsp clock + - description: 26M clock + - description: mux for audio dsp local bus + - description: default audio dsp local bus clock source + - description: clock gate for dsp clock + - description: mux for dsp access external bus + + clock-names: + items: + - const: dsp_sel + - const: clk26m_ck + - const: audio_local_bus + - const: mainpll_d7_d2 + - const: scp_adsp_audiodsp + - const: audio_h_sel + + power-domains: + maxItems: 1 + + mboxes: + maxItems: 3 + + mbox-names: + items: + - const: adsp 0 + - const: adsp 1 + - const: adsp 2 + + "#mbox-cells": + const: 1 + description: + The first cell is the client-id, and the second cell is the signal-id. + + sound: + maxItems: 3 + + memory-region: + description: + phandle to a node describing reserved memory (System RAM memory) + used by DSP (see bindings/reserved-memory/reserved-memory.txt) + maxItems: 2 + +required: + - compatible + - reg + - clocks + - clock-names + - power-domains + - mboxes + - mbox-names + - memory-region + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + #include + #include + + adsp: adsp@10803000 { + compatible = "mediatek,mt8195-audio_dsp"; + reg = <0x10803000 0x1000>, + <0x10840000 0x40000>, + <0x10816000 0x1000>, + <0x10817000 0x1000>, + <0x10818000 0x1000>; + reg-names = "cfg", "sram", "mbox0", "mbox1", "mbox2"; + interrupts = , + , + , + ; + interrupt-names = "wdt", "mbox0", "mbox1", "mbox2"; + clocks = <&topckgen 10>, //CLK_TOP_DSP_SEL + <&clk26m>, + <&topckgen 107>, //CLK_TOP_AUDIO_LOCAL_BUS_SEL + <&topckgen 136>, //CLK_TOP_MAINPLL_D7_D2 + <&scp_adsp 0>, //CLK_SCP_ADSP_AUDIODSP + <&topckgen 34>; //CLK_TOP_AUDIO_H_SEL + clock-names = "dsp_sel", + "clk26m_ck", + "audio_local_bus", + "mainpll_d7_d2", + "scp_adsp_audiodsp", + "audio_h_sel"; + memory-region = <&adsp_dma_mem_reserved>, + <&adsp_mem_reserved>; + power-domains = <&spm 6>; //MT8195_POWER_DOMAIN_ADSP + #mbox-cells = <1>; + mboxes = <&adsp 0>, <&adsp 1>, <&adsp 2>; + status = "disabled"; + + sound { + mediatek,dptx-codec = <&dp_tx>; + mediatek,hdmi-codec = <&hdmi0>; + mediatek,platform = <&afe>; + }; + }; From c836c0d5e1b49d259b3d6d04fa63bd3045c73e1a Mon Sep 17 00:00:00 2001 From: YC Hung Date: Fri, 27 Aug 2021 23:01:42 +0800 Subject: [PATCH 23/24] ASoC: SOF: Add mt8195 device descriptor Add SOF device and DT descriptor for Mediatek mt8195 platform. Signed-off-by: YC Hung --- sound/soc/sof/Kconfig | 2 +- sound/soc/sof/mediatek/mediatek-ops.h | 8 ++++++++ sound/soc/sof/sof-of-dev.c | 14 ++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 sound/soc/sof/mediatek/mediatek-ops.h diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index 93d01ae3c71ba9..e099eef09ba447 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -43,7 +43,7 @@ config SND_SOC_SOF_OF select SND_SOC_SOF help This adds support for Device Tree enumeration. This option is - required to enable i.MX8 devices. + required to enable i.MX8 or Mediatek devices. Say Y if you need this option. If unsure select "N". config SND_SOC_SOF_COMPRESS diff --git a/sound/soc/sof/mediatek/mediatek-ops.h b/sound/soc/sof/mediatek/mediatek-ops.h new file mode 100644 index 00000000000000..351b2d1168dc75 --- /dev/null +++ b/sound/soc/sof/mediatek/mediatek-ops.h @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ + +#ifndef __MEDIATEK_OPS_H__ +#define __MEDIATEK_OPS_H__ + +extern struct snd_sof_dsp_ops sof_mt8195_ops; + +#endif diff --git a/sound/soc/sof/sof-of-dev.c b/sound/soc/sof/sof-of-dev.c index 885430a42226ea..39598ee838d3dd 100644 --- a/sound/soc/sof/sof-of-dev.c +++ b/sound/soc/sof/sof-of-dev.c @@ -13,6 +13,7 @@ #include "ops.h" #include "imx/imx-ops.h" +#include "mediatek/mediatek-ops.h" static char *fw_path; module_param(fw_path, charp, 0444); @@ -50,6 +51,16 @@ static struct sof_dev_desc sof_of_imx8mp_desc = { .ops = &sof_imx8m_ops, }; #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) +static struct sof_dev_desc sof_of_mt8195_desc = { + .no_ignore_machine = true, + .default_fw_path = "mediatek/sof", + .default_tplg_path = "mediatek/sof-tplg", + .default_fw_filename = "sof-mt8195.ri", + .nocodec_tplg_filename = "sof-mt8195-nocodec.tplg", + .ops = &sof_mt8195_ops, +}; +#endif static const struct dev_pm_ops sof_of_pm = { .prepare = snd_sof_prepare, @@ -130,6 +141,9 @@ static const struct of_device_id sof_of_ids[] = { #endif #if IS_ENABLED(CONFIG_SND_SOC_SOF_IMX8M) { .compatible = "fsl,imx8mp-dsp", .data = &sof_of_imx8mp_desc}, +#endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + { .compatible = "mediatek,mt8195-audio_dsp", .data = &sof_of_mt8195_desc}, #endif { } }; From 46d26ca9477140462ea2ca5762cf82c91889ceda Mon Sep 17 00:00:00 2001 From: YC Hung Date: Tue, 31 Aug 2021 19:17:38 +0800 Subject: [PATCH 24/24] ASoC: mediatek: mt8195: add sof to machine driver Add SOF platform driver and use connection table to connect sof platform driver and normal platform driver. Use no_ignore_machine in sof device descriptor and set as 1 to keep and reuse original platform driver. Signed-off-by: YC Hung --- .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 260 ++++++++++++++++++ 1 file changed, 260 insertions(+) diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c index 5dc217f59bd6e1..bdf6e8b780e465 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -25,6 +25,21 @@ #define RT5682_CODEC_DAI "rt5682-aif1" #define RT5682_DEV0_NAME "rt5682.2-001a" +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) +#include +#define SOF_DMA_DL2 "SOF_DMA_DL2" +#define SOF_DMA_DL3 "SOF_DMA_DL3" +#define SOF_DMA_UL4 "SOF_DMA_UL4" +#define SOF_DMA_UL5 "SOF_DMA_UL5" + +struct sof_conn_stream { + const char *normal_link; + const char *sof_link; + const char *sof_dma; + int stream_dir; +}; +#endif + struct mt8195_mt6359_rt1019_rt5682_priv { struct snd_soc_jack headset_jack; struct snd_soc_jack dp_jack; @@ -36,6 +51,12 @@ static const struct snd_soc_dapm_widget SND_SOC_DAPM_SPK("Speakers", NULL), SND_SOC_DAPM_HP("Headphone Jack", NULL), SND_SOC_DAPM_MIC("Headset Mic", NULL), +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + SND_SOC_DAPM_MIXER(SOF_DMA_DL2, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_DL3, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL4, SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER(SOF_DMA_UL5, SND_SOC_NOPM, 0, 0, NULL, 0), +#endif }; static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = { @@ -45,6 +66,18 @@ static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = { { "Headphone Jack", NULL, "HPOL" }, { "Headphone Jack", NULL, "HPOR" }, { "IN1P", NULL, "Headset Mic" }, +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + /* SOF Uplink */ + {SOF_DMA_UL4, NULL, "O034"}, + {SOF_DMA_UL4, NULL, "O035"}, + {SOF_DMA_UL5, NULL, "O036"}, + {SOF_DMA_UL5, NULL, "O037"}, + /* SOF Downlink */ + {"I070", NULL, SOF_DMA_DL2}, + {"I071", NULL, SOF_DMA_DL2}, + {"I020", NULL, SOF_DMA_DL3}, + {"I021", NULL, SOF_DMA_DL3}, +#endif }; static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = { @@ -556,6 +589,12 @@ enum { DAI_LINK_PCM1_BE, DAI_LINK_UL_SRC1_BE, DAI_LINK_UL_SRC2_BE, +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + DAI_LINK_SOF_DL2_BE, + DAI_LINK_SOF_DL3_BE, + DAI_LINK_SOF_UL4_BE, + DAI_LINK_SOF_UL5_BE, +#endif }; /* FE */ @@ -698,6 +737,171 @@ SND_SOC_DAILINK_DEFS(UL_SRC2_BE, "mt6359-snd-codec-aif2")), DAILINK_COMP_ARRAY(COMP_EMPTY())); +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) +SND_SOC_DAILINK_DEFS(AFE_SOF_DL2, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp"))); + +SND_SOC_DAILINK_DEFS(AFE_SOF_DL3, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_DL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp"))); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL4, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp"))); + +SND_SOC_DAILINK_DEFS(AFE_SOF_UL5, + DAILINK_COMP_ARRAY(COMP_CPU("SOF_UL5")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_PLATFORM("10803000.adsp"))); + +static const struct sof_conn_stream g_sof_conn_streams[] = { + { "ETDM2_OUT_BE", "AFE_SOF_DL2", SOF_DMA_DL2, SNDRV_PCM_STREAM_PLAYBACK}, + { "ETDM1_OUT_BE", "AFE_SOF_DL3", SOF_DMA_DL3, SNDRV_PCM_STREAM_PLAYBACK}, + { "UL_SRC1_BE", "AFE_SOF_UL4", SOF_DMA_UL4, SNDRV_PCM_STREAM_CAPTURE}, + { "ETDM2_IN_BE", "AFE_SOF_UL5", SOF_DMA_UL5, SNDRV_PCM_STREAM_CAPTURE}, +}; + +/* fixup the BE DAI link to match any values from topology */ +static int mt8195_dai_link_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + int i, j, ret = 0; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai_link *sof_dai_link; + struct snd_soc_pcm_runtime *runtime; + struct snd_soc_dai *cpu_dai; + + for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) { + const struct sof_conn_stream *conn = &g_sof_conn_streams[i]; + + sof_dai_link = NULL; + + if (strcmp(rtd->dai_link->name, conn->normal_link)) + continue; + + for_each_card_rtds(card, runtime) { + if (strcmp(runtime->dai_link->name, conn->sof_link)) + continue; + + for_each_rtd_cpu_dais(runtime, j, cpu_dai) { + if (cpu_dai->stream_active[conn->stream_dir] > 0) { + sof_dai_link = runtime->dai_link; + break; + } + } + break; + } + + if (sof_dai_link && sof_dai_link->be_hw_params_fixup) { + ret = sof_dai_link->be_hw_params_fixup(runtime, params); + if (!strcmp(rtd->dai_link->name, "ETDM2_IN_BE") || + !strcmp(rtd->dai_link->name, "ETDM1_OUT_BE")) { + mt8195_etdm_hw_params_fixup(runtime, params); + } + break; + } + } + + return ret; +} + +static int mt8195_mt6359_rt1019_rt5682_card_late_probe(struct snd_soc_card *card) +{ + struct snd_soc_pcm_runtime *runtime; + struct snd_soc_component *sof_comp; + int i; + + /* 1. find sof component */ + for_each_card_rtds(card, runtime) { + for (i = 0; i < runtime->num_components; i++) { + if (!runtime->components[i]->driver->name) + continue; + if (!strcmp(runtime->components[i]->driver->name, "sof-audio-component")) { + sof_comp = runtime->components[i]; + break; + } + } + } + + if (!sof_comp) { + dev_info(card->dev, " probe without component\n"); + return 0; + } + /* 2. add route path and fixup callback */ + for (i = 0; i < ARRAY_SIZE(g_sof_conn_streams); i++) { + const struct sof_conn_stream *conn = &g_sof_conn_streams[i]; + struct snd_soc_pcm_runtime *sof_rtd = NULL; + struct snd_soc_pcm_runtime *normal_rtd = NULL; + struct snd_soc_pcm_runtime *rtd; + + for_each_card_rtds(card, rtd) { + if (!strcmp(rtd->dai_link->stream_name, conn->sof_link)) { + sof_rtd = rtd; + continue; + } + if (!strcmp(rtd->dai_link->name, conn->normal_link)) { + normal_rtd = rtd; + continue; + } + if (normal_rtd && sof_rtd) + break; + } + if (normal_rtd && sof_rtd) { + int j; + struct snd_soc_dai *cpu_dai; + + for_each_rtd_cpu_dais(sof_rtd, j, cpu_dai) { + struct snd_soc_dapm_route route; + struct snd_soc_dapm_path *p = NULL; + struct snd_soc_dapm_widget *play_widget = + cpu_dai->playback_widget; + struct snd_soc_dapm_widget *cap_widget = + cpu_dai->capture_widget; + memset(&route, 0, sizeof(route)); + if (conn->stream_dir == SNDRV_PCM_STREAM_CAPTURE && + cap_widget) { + snd_soc_dapm_widget_for_each_sink_path(cap_widget, p) { + route.source = conn->sof_dma; + route.sink = p->sink->name; + snd_soc_dapm_add_routes(&card->dapm, &route, 1); + } + } else if (conn->stream_dir == SNDRV_PCM_STREAM_PLAYBACK && + play_widget){ + snd_soc_dapm_widget_for_each_source_path(play_widget, p) { + route.source = p->source->name; + route.sink = conn->sof_dma; + snd_soc_dapm_add_routes(&card->dapm, &route, 1); + } + } else { + dev_err(cpu_dai->dev, "stream dir and widget not pair\n"); + } + } + normal_rtd->dai_link->be_hw_params_fixup = mt8195_dai_link_fixup; + sof_rtd->dai_link->be_hw_params_fixup = + sof_comp->driver->be_hw_params_fixup; + } + } + + return 0; +} + +static int mt8195_mt6359_rt1019_rt5682_card_probe(struct snd_soc_card *card) +{ + int i; + struct snd_soc_dai_link *dai_link; + + for_each_card_prelinks(card, i, dai_link) { + if (dai_link->no_pcm && !dai_link->stream_name && dai_link->name) + dai_link->stream_name = dai_link->name; + } + return 0; +} +#endif + static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { /* FE */ [DAI_LINK_DL2_FE] = { @@ -977,6 +1181,33 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { .dpcm_capture = 1, SND_SOC_DAILINK_REG(UL_SRC2_BE), }, +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + /* SOF BE */ + [DAI_LINK_SOF_DL2_BE] = { + .name = "AFE_SOF_DL2", + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(AFE_SOF_DL2), + }, + [DAI_LINK_SOF_DL3_BE] = { + .name = "AFE_SOF_DL3", + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(AFE_SOF_DL3), + }, + [DAI_LINK_SOF_UL4_BE] = { + .name = "AFE_SOF_UL4", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(AFE_SOF_UL4), + }, + [DAI_LINK_SOF_UL5_BE] = { + .name = "AFE_SOF_UL5", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(AFE_SOF_UL5), + }, +#endif }; static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = { @@ -990,6 +1221,10 @@ static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = { .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets), .dapm_routes = mt8195_mt6359_rt1019_rt5682_routes, .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes), +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + .late_probe = mt8195_mt6359_rt1019_rt5682_card_late_probe, + .probe = mt8195_mt6359_rt1019_rt5682_card_probe, +#endif }; static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) @@ -998,12 +1233,25 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) struct device_node *platform_node; struct snd_soc_dai_link *dai_link; struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL; + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + struct device_node *machine_node; + struct snd_soc_acpi_mach *mach; +#endif + int ret, i; card->dev = &pdev->dev; +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + mach = pdev->dev.platform_data; + machine_node = mach->pdata; + platform_node = of_parse_phandle(machine_node, "mediatek,platform", 0); +#else platform_node = of_parse_phandle(pdev->dev.of_node, "mediatek,platform", 0); +#endif + if (!platform_node) { dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n"); return -EINVAL; @@ -1014,9 +1262,15 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) dai_link->platforms->of_node = platform_node; if (strcmp(dai_link->name, "DPTX_BE") == 0) { +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + dai_link->codecs->of_node = + of_parse_phandle(machine_node, + "mediatek,dptx-codec", 0); +#else dai_link->codecs->of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,dptx-codec", 0); +#endif if (!dai_link->codecs->of_node) { dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n"); return -EINVAL; @@ -1028,9 +1282,15 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) } if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { +#if IS_ENABLED(CONFIG_SND_SOC_SOF_MT8195) + dai_link->codecs->of_node = + of_parse_phandle(machine_node, + "mediatek,hdmi-codec", 0); +#else dai_link->codecs->of_node = of_parse_phandle(pdev->dev.of_node, "mediatek,hdmi-codec", 0); +#endif if (!dai_link->codecs->of_node) { dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n"); return -EINVAL;