[PATCH 0/7] ASoC: mediatek: Add support for MT79xx SoC
From: Maso Huang maso.huang@mediatek.com
This series of patches adds support for MediaTek AFE of MT79xx SoC. Patches are based on broonie tree "for-next" branch.
Maso Huang (7): ASoC: mediatek: mt79xx: add common header ASoC: mediatek: mt79xx: support audio clock control ASoC: mediatek: mt79xx: add platform driver ASoC: mediatek: mt79xx: support etdm in platform driver ASoC: mediatek: mt79xx: add machine driver with wm8960 ASoC: dt-bindings: mediatek,mt79xx-wm8960: add mt79xx-wm8960 document ASoC: dt-bindings: mediatek,mt79xx-afe: add audio afe document
.../bindings/sound/mediatek,mt79xx-afe.yaml | 102 +++ .../sound/mediatek,mt79xx-wm8960.yaml | 53 ++ sound/soc/mediatek/Kconfig | 20 + sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/mt79xx/Makefile | 10 + sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c | 123 ++++ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h | 18 + sound/soc/mediatek/mt79xx/mt79xx-afe-common.h | 49 ++ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c | 608 ++++++++++++++++++ sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c | 421 ++++++++++++ sound/soc/mediatek/mt79xx/mt79xx-reg.h | 206 ++++++ sound/soc/mediatek/mt79xx/mt79xx-wm8960.c | 185 ++++++ 12 files changed, 1796 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml create mode 100644 sound/soc/mediatek/mt79xx/Makefile create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-common.h create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-reg.h create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-wm8960.c
From: Maso Huang maso.huang@mediatek.com
Add header files for register definition and structure.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- sound/soc/mediatek/mt79xx/mt79xx-afe-common.h | 49 +++++ sound/soc/mediatek/mt79xx/mt79xx-reg.h | 206 ++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-common.h create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-reg.h
diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-common.h b/sound/soc/mediatek/mt79xx/mt79xx-afe-common.h new file mode 100644 index 000000000000..13c9e51d7b38 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-common.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt79xx-afe-common.h -- MediaTek 79xx audio driver definitions + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#ifndef _MT_79XX_AFE_COMMON_H_ +#define _MT_79XX_AFE_COMMON_H_ + +#include <sound/soc.h> +#include <linux/list.h> +#include <linux/regmap.h> +#include "../common/mtk-base-afe.h" + +enum { + MT79XX_MEMIF_DL1, + MT79XX_MEMIF_VUL12, + MT79XX_MEMIF_NUM, + MT79XX_DAI_ETDM = MT79XX_MEMIF_NUM, + MT79XX_DAI_NUM, +}; + +enum { + MT79XX_IRQ_0, + MT79XX_IRQ_1, + MT79XX_IRQ_2, + MT79XX_IRQ_NUM, +}; + +struct clk; + +struct mt79xx_afe_private { + struct clk **clk; + + int pm_runtime_bypass_reg_ctl; + + /* dai */ + void *dai_priv[MT79XX_DAI_NUM]; +}; + +unsigned int mt79xx_afe_rate_transform(struct device *dev, + unsigned int rate); + +/* dai register */ +int mt79xx_dai_etdm_register(struct mtk_base_afe *afe); +#endif diff --git a/sound/soc/mediatek/mt79xx/mt79xx-reg.h b/sound/soc/mediatek/mt79xx/mt79xx-reg.h new file mode 100644 index 000000000000..28c0aeba9bdf --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-reg.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt79xx-reg.h -- MediaTek 79xx audio driver reg definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#ifndef _MT79XX_REG_H_ +#define _MT79XX_REG_H_ + +#define AUDIO_TOP_CON2 0x0008 +#define AUDIO_TOP_CON4 0x0010 +#define AUDIO_ENGEN_CON0 0x0014 +#define AFE_IRQ_MCU_EN 0x0100 +#define AFE_IRQ_MCU_STATUS 0x0120 +#define AFE_IRQ_MCU_CLR 0x0128 +#define AFE_IRQ0_MCU_CFG0 0x0140 +#define AFE_IRQ0_MCU_CFG1 0x0144 +#define AFE_IRQ1_MCU_CFG0 0x0148 +#define AFE_IRQ1_MCU_CFG1 0x014c +#define AFE_IRQ2_MCU_CFG0 0x0150 +#define AFE_IRQ2_MCU_CFG1 0x0154 +#define ETDM_IN5_CON0 0x13f0 +#define ETDM_IN5_CON1 0x13f4 +#define ETDM_IN5_CON2 0x13f8 +#define ETDM_IN5_CON3 0x13fc +#define ETDM_IN5_CON4 0x1400 +#define ETDM_OUT5_CON0 0x1570 +#define ETDM_OUT5_CON4 0x1580 +#define ETDM_OUT5_CON5 0x1584 +#define ETDM_4_7_COWORK_CON0 0x15e0 +#define ETDM_4_7_COWORK_CON1 0x15e4 +#define AFE_CONN018_1 0x1b44 +#define AFE_CONN018_4 0x1b50 +#define AFE_CONN019_1 0x1b64 +#define AFE_CONN019_4 0x1b70 +#define AFE_CONN124_1 0x2884 +#define AFE_CONN124_4 0x2890 +#define AFE_CONN125_1 0x28a4 +#define AFE_CONN125_4 0x28b0 +#define AFE_CONN_RS_0 0x3920 +#define AFE_CONN_RS_3 0x392c +#define AFE_CONN_16BIT_0 0x3960 +#define AFE_CONN_16BIT_3 0x396c +#define AFE_CONN_24BIT_0 0x3980 +#define AFE_CONN_24BIT_3 0x398c +#define AFE_MEMIF_CON0 0x3d98 +#define AFE_MEMIF_RD_MON 0x3da0 +#define AFE_MEMIF_WR_MON 0x3da4 +#define AFE_DL0_BASE_MSB 0x3e40 +#define AFE_DL0_BASE 0x3e44 +#define AFE_DL0_CUR_MSB 0x3e48 +#define AFE_DL0_CUR 0x3e4c +#define AFE_DL0_END_MSB 0x3e50 +#define AFE_DL0_END 0x3e54 +#define AFE_DL0_RCH_MON 0x3e58 +#define AFE_DL0_LCH_MON 0x3e5c +#define AFE_DL0_CON0 0x3e60 +#define AFE_VUL0_BASE_MSB 0x4220 +#define AFE_VUL0_BASE 0x4224 +#define AFE_VUL0_CUR_MSB 0x4228 +#define AFE_VUL0_CUR 0x422c +#define AFE_VUL0_END_MSB 0x4230 +#define AFE_VUL0_END 0x4234 +#define AFE_VUL0_CON0 0x4238 + +#define AFE_MAX_REGISTER AFE_VUL0_CON0 +#define AFE_IRQ_STATUS_BITS 0x7 +#define AFE_IRQ_CNT_SHIFT 0 +#define AFE_IRQ_CNT_MASK 0xffffff + +/* AUDIO_TOP_CON2 */ +#define CLK_OUT5_PDN BIT(14) +#define CLK_OUT5_PDN_MASK BIT(14) +#define CLK_IN5_PDN BIT(7) +#define CLK_IN5_PDN_MASK BIT(7) + +/* AUDIO_TOP_CON4 */ +#define PDN_APLL_TUNER2 BIT(12) +#define PDN_APLL_TUNER2_MASK BIT(12) + +/* AUDIO_ENGEN_CON0 */ +#define AUD_APLL2_EN BIT(3) +#define AUD_APLL2_EN_MASK BIT(3) +#define AUD_26M_EN BIT(0) +#define AUD_26M_EN_MASK BIT(0) + +/* AFE_DL0_CON0 */ +#define DL0_ON_SFT 28 +#define DL0_ON_MASK 0x1 +#define DL0_ON_MASK_SFT BIT(28) +#define DL0_MINLEN_SFT 20 +#define DL0_MINLEN_MASK 0xf +#define DL0_MINLEN_MASK_SFT (0xf << 20) +#define DL0_MODE_SFT 8 +#define DL0_MODE_MASK 0x1f +#define DL0_MODE_MASK_SFT (0x1f << 8) +#define DL0_PBUF_SIZE_SFT 5 +#define DL0_PBUF_SIZE_MASK 0x3 +#define DL0_PBUF_SIZE_MASK_SFT (0x3 << 5) +#define DL0_MONO_SFT 4 +#define DL0_MONO_MASK 0x1 +#define DL0_MONO_MASK_SFT BIT(4) +#define DL0_HALIGN_SFT 2 +#define DL0_HALIGN_MASK 0x1 +#define DL0_HALIGN_MASK_SFT BIT(2) +#define DL0_HD_MODE_SFT 0 +#define DL0_HD_MODE_MASK 0x3 +#define DL0_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_VUL0_CON0 */ +#define VUL0_ON_SFT 28 +#define VUL0_ON_MASK 0x1 +#define VUL0_ON_MASK_SFT BIT(28) +#define VUL0_MODE_SFT 8 +#define VUL0_MODE_MASK 0x1f +#define VUL0_MODE_MASK_SFT (0x1f << 8) +#define VUL0_MONO_SFT 4 +#define VUL0_MONO_MASK 0x1 +#define VUL0_MONO_MASK_SFT BIT(4) +#define VUL0_HALIGN_SFT 2 +#define VUL0_HALIGN_MASK 0x1 +#define VUL0_HALIGN_MASK_SFT BIT(2) +#define VUL0_HD_MODE_SFT 0 +#define VUL0_HD_MODE_MASK 0x3 +#define VUL0_HD_MODE_MASK_SFT (0x3 << 0) + +/* AFE_IRQ_MCU_CON */ +#define IRQ_MCU_MODE_SFT 4 +#define IRQ_MCU_MODE_MASK 0x1f +#define IRQ_MCU_MODE_MASK_SFT (0x1f << 4) +#define IRQ_MCU_ON_SFT 0 +#define IRQ_MCU_ON_MASK 0x1 +#define IRQ_MCU_ON_MASK_SFT BIT(0) +#define IRQ0_MCU_CLR_SFT 0 +#define IRQ0_MCU_CLR_MASK 0x1 +#define IRQ0_MCU_CLR_MASK_SFT BIT(0) +#define IRQ1_MCU_CLR_SFT 1 +#define IRQ1_MCU_CLR_MASK 0x1 +#define IRQ1_MCU_CLR_MASK_SFT BIT(1) +#define IRQ2_MCU_CLR_SFT 2 +#define IRQ2_MCU_CLR_MASK 0x1 +#define IRQ2_MCU_CLR_MASK_SFT BIT(2) + +/* ETDM_IN5_CON2 */ +#define IN_CLK_SRC(x) ((x) << 10) +#define IN_CLK_SRC_SFT 10 +#define IN_CLK_SRC_MASK GENMASK(12, 10) + +/* ETDM_IN5_CON3 */ +#define IN_SEL_FS(x) ((x) << 26) +#define IN_SEL_FS_SFT 26 +#define IN_SEL_FS_MASK GENMASK(30, 26) + +/* ETDM_IN5_CON4 */ +#define IN_RELATCH(x) ((x) << 20) +#define IN_RELATCH_SFT 20 +#define IN_RELATCH_MASK GENMASK(24, 20) +#define IN_CLK_INV BIT(18) +#define IN_CLK_INV_MASK BIT(18) + +/* ETDM_IN5_CON0 & ETDM_OUT5_CON0 */ +#define RELATCH_SRC(x) ((x) << 28) +#define RELATCH_SRC_SFT 28 +#define RELATCH_SRC_MASK GENMASK(30, 28) +#define ETDM_CH_NUM(x) (((x) - 1) << 23) +#define ETDM_CH_NUM_SFT 23 +#define ETDM_CH_NUM_MASK GENMASK(27, 23) +#define ETDM_WRD_LEN(x) (((x) - 1) << 16) +#define ETDM_WRD_LEN_SFT 16 +#define ETDM_WRD_LEN_MASK GENMASK(20, 16) +#define ETDM_BIT_LEN(x) (((x) - 1) << 11) +#define ETDM_BIT_LEN_SFT 11 +#define ETDM_BIT_LEN_MASK GENMASK(15, 11) +#define ETDM_FMT(x) ((x) << 6) +#define ETDM_FMT_SFT 6 +#define ETDM_FMT_MASK GENMASK(8, 6) +#define ETDM_SYNC BIT(1) +#define ETDM_SYNC_MASK BIT(1) +#define ETDM_EN BIT(0) +#define ETDM_EN_MASK BIT(0) + +/* ETDM_OUT5_CON4 */ +#define OUT_RELATCH(x) ((x) << 24) +#define OUT_RELATCH_SFT 24 +#define OUT_RELATCH_MASK GENMASK(28, 24) +#define OUT_CLK_SRC(x) ((x) << 6) +#define OUT_CLK_SRC_SFT 6 +#define OUT_CLK_SRC_MASK GENMASK(8, 6) +#define OUT_SEL_FS(x) ((x) << 0) +#define OUT_SEL_FS_SFT 0 +#define OUT_SEL_FS_MASK GENMASK(4, 0) + +/* ETDM_OUT5_CON5 */ +#define ETDM_CLK_DIV BIT(12) +#define ETDM_CLK_DIV_MASK BIT(12) +#define OUT_CLK_INV BIT(9) +#define OUT_CLK_INV_MASK BIT(9) + +/* ETDM_4_7_COWORK_CON0 */ +#define OUT_SEL(x) ((x) << 12) +#define OUT_SEL_SFT 12 +#define OUT_SEL_MASK GENMASK(15, 12) +#endif
Il 12/06/23 12:52, Maso Hunag ha scritto:
From: Maso Huang maso.huang@mediatek.com
Add header files for register definition and structure.
Signed-off-by: Maso Huang maso.huang@mediatek.com
sound/soc/mediatek/mt79xx/mt79xx-afe-common.h | 49 +++++ sound/soc/mediatek/mt79xx/mt79xx-reg.h | 206 ++++++++++++++++++
Please, s/mt79xx/mt7981/g. Wildcards are not permitted.
2 files changed, 255 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-common.h create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-reg.h
diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-common.h b/sound/soc/mediatek/mt79xx/mt79xx-afe-common.h new file mode 100644 index 000000000000..13c9e51d7b38 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-common.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- mt79xx-afe-common.h -- MediaTek 79xx audio driver definitions
- Copyright (c) 2021 MediaTek Inc.
- Author: Vic Wu vic.wu@mediatek.com
Maso Huang <maso.huang@mediatek.com>
- */
+#ifndef _MT_79XX_AFE_COMMON_H_ +#define _MT_79XX_AFE_COMMON_H_
+#include <sound/soc.h> +#include <linux/list.h> +#include <linux/regmap.h> +#include "../common/mtk-base-afe.h"
+enum {
- MT79XX_MEMIF_DL1,
- MT79XX_MEMIF_VUL12,
- MT79XX_MEMIF_NUM,
- MT79XX_DAI_ETDM = MT79XX_MEMIF_NUM,
- MT79XX_DAI_NUM,
+};
Same for the enumeration entries, and the definitions and the function names. Please change everything to `mt7981` (strategy is to use the name of the oldest SoC: if the oldest is not 7981, change accordingly).
+enum {
- MT79XX_IRQ_0,
- MT79XX_IRQ_1,
- MT79XX_IRQ_2,
- MT79XX_IRQ_NUM,
+};
+struct clk;
+struct mt79xx_afe_private {
- struct clk **clk;
- int pm_runtime_bypass_reg_ctl;
- /* dai */
- void *dai_priv[MT79XX_DAI_NUM];
+};
+unsigned int mt79xx_afe_rate_transform(struct device *dev,
unsigned int rate);
+/* dai register */ +int mt79xx_dai_etdm_register(struct mtk_base_afe *afe); +#endif diff --git a/sound/soc/mediatek/mt79xx/mt79xx-reg.h b/sound/soc/mediatek/mt79xx/mt79xx-reg.h new file mode 100644 index 000000000000..28c0aeba9bdf --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-reg.h @@ -0,0 +1,206 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- mt79xx-reg.h -- MediaTek 79xx audio driver reg definition
- Copyright (c) 2021 MediaTek Inc.
- Author: Vic Wu vic.wu@mediatek.com
Maso Huang <maso.huang@mediatek.com>
- */
+#ifndef _MT79XX_REG_H_ +#define _MT79XX_REG_H_
_MT7981_REG_H_
Everything else looks ok.
Thanks, Angelo
From: Maso Huang maso.huang@mediatek.com
Add audio clock wrapper and audio tuner control.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c | 123 +++++++++++++++++++++ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h | 18 +++ 2 files changed, 141 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h
diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c new file mode 100644 index 000000000000..f00f0d7de861 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt79xx-afe-clk.c -- MediaTek 79xx afe clock ctrl + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#include <linux/clk.h> + +#include "mt79xx-afe-common.h" +#include "mt79xx-afe-clk.h" +#include "mt79xx-reg.h" + +enum { + CK_INFRA_AUD_BUS_CK = 0, + CK_INFRA_AUD_26M_CK, + CK_INFRA_AUD_L_CK, + CK_INFRA_AUD_AUD_CK, + CK_INFRA_AUD_EG2_CK, + CLK_NUM +}; + +static const char *aud_clks[CLK_NUM] = { + [CK_INFRA_AUD_BUS_CK] = "aud_bus_ck", + [CK_INFRA_AUD_26M_CK] = "aud_26m_ck", + [CK_INFRA_AUD_L_CK] = "aud_l_ck", + [CK_INFRA_AUD_AUD_CK] = "aud_aud_ck", + [CK_INFRA_AUD_EG2_CK] = "aud_eg2_ck", +}; + +int mt79xx_init_clock(struct mtk_base_afe *afe) +{ + struct mt79xx_afe_private *afe_priv = afe->platform_priv; + int i; + + afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk), + GFP_KERNEL); + if (!afe_priv->clk) + return -ENOMEM; + + for (i = 0; i < CLK_NUM; i++) { + afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]); + if (IS_ERR(afe_priv->clk[i])) { + dev_err(afe->dev, "%s(), devm_clk_get %s fail, + ret %ld\n", __func__, aud_clks[i], + PTR_ERR(afe_priv->clk[i])); + return PTR_ERR(afe_priv->clk[i]); + } + } + + return 0; +} + +int mt79xx_afe_enable_clock(struct mtk_base_afe *afe) +{ + struct mt79xx_afe_private *afe_priv = afe->platform_priv; + int ret; + + ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_BUS_CK]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CK_INFRA_AUD_BUS_CK], ret); + goto CK_INFRA_AUD_BUS_CK_ERR; + } + + ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_26M_CK]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CK_INFRA_AUD_26M_CK], ret); + goto CK_INFRA_AUD_26M_ERR; + } + + ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_L_CK]); + if (ret) { + dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CK_INFRA_AUD_L_CK], ret); + goto CK_INFRA_AUD_L_CK_ERR; + } + + ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_AUD_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CK_INFRA_AUD_AUD_CK], ret); + goto CK_INFRA_AUD_AUD_CK_ERR; + } + + ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_EG2_CK]); + if (ret) { + dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n", + __func__, aud_clks[CK_INFRA_AUD_EG2_CK], ret); + goto CK_INFRA_AUD_EG2_CK_ERR; + } + + return 0; + +CK_INFRA_AUD_EG2_CK_ERR: + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_AUD_CK]); +CK_INFRA_AUD_AUD_CK_ERR: + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_L_CK]); +CK_INFRA_AUD_L_CK_ERR: + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_26M_CK]); +CK_INFRA_AUD_26M_ERR: + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_BUS_CK]); +CK_INFRA_AUD_BUS_CK_ERR: + return ret; +} +EXPORT_SYMBOL_GPL(mt79xx_afe_enable_clock); + +int mt79xx_afe_disable_clock(struct mtk_base_afe *afe) +{ + struct mt79xx_afe_private *afe_priv = afe->platform_priv; + + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_EG2_CK]); + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_AUD_CK]); + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_L_CK]); + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_26M_CK]); + clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_BUS_CK]); + + return 0; +} +EXPORT_SYMBOL_GPL(mt79xx_afe_disable_clock); diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h new file mode 100644 index 000000000000..bf9c3edb6922 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt79xx-afe-clk.h -- MediaTek 79xx afe clock ctrl definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#ifndef _MT79XX_AFE_CLK_H_ +#define _MT79XX_AFE_CLK_H_ + +struct mtk_base_afe; + +int mt79xx_init_clock(struct mtk_base_afe *afe); +int mt79xx_afe_enable_clock(struct mtk_base_afe *afe); +int mt79xx_afe_disable_clock(struct mtk_base_afe *afe); +#endif
On 12.06.2023 13:52, Maso Hunag wrote:
[You don't often get email from maso.huang@mediatek.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ]
EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
From: Maso Huang maso.huang@mediatek.com
Add audio clock wrapper and audio tuner control.
Signed-off-by: Maso Huang maso.huang@mediatek.com
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c | 123 +++++++++++++++++++++ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h | 18 +++ 2 files changed, 141 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h
diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c new file mode 100644 index 000000000000..f00f0d7de861 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c @@ -0,0 +1,123 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- mt79xx-afe-clk.c -- MediaTek 79xx afe clock ctrl
- Copyright (c) 2021 MediaTek Inc.
- Author: Vic Wu vic.wu@mediatek.com
Maso Huang <maso.huang@mediatek.com>
- */
+#include <linux/clk.h>
+#include "mt79xx-afe-common.h" +#include "mt79xx-afe-clk.h" +#include "mt79xx-reg.h"
+enum {
CK_INFRA_AUD_BUS_CK = 0,
CK_INFRA_AUD_26M_CK,
CK_INFRA_AUD_L_CK,
CK_INFRA_AUD_AUD_CK,
CK_INFRA_AUD_EG2_CK,
CLK_NUM
+};
+static const char *aud_clks[CLK_NUM] = {
[CK_INFRA_AUD_BUS_CK] = "aud_bus_ck",
[CK_INFRA_AUD_26M_CK] = "aud_26m_ck",
[CK_INFRA_AUD_L_CK] = "aud_l_ck",
[CK_INFRA_AUD_AUD_CK] = "aud_aud_ck",
[CK_INFRA_AUD_EG2_CK] = "aud_eg2_ck",
+};
+int mt79xx_init_clock(struct mtk_base_afe *afe) +{
struct mt79xx_afe_private *afe_priv = afe->platform_priv;
int i;
afe_priv->clk = devm_kcalloc(afe->dev, CLK_NUM, sizeof(*afe_priv->clk),
GFP_KERNEL);
if (!afe_priv->clk)
return -ENOMEM;
for (i = 0; i < CLK_NUM; i++) {
afe_priv->clk[i] = devm_clk_get(afe->dev, aud_clks[i]);
if (IS_ERR(afe_priv->clk[i])) {
dev_err(afe->dev, "%s(), devm_clk_get %s fail,
ret %ld\n", __func__, aud_clks[i],
PTR_ERR(afe_priv->clk[i]));
return PTR_ERR(afe_priv->clk[i]);
}
}
You can use devm_clk_bulk_get()
return 0;
+}
+int mt79xx_afe_enable_clock(struct mtk_base_afe *afe) +{
struct mt79xx_afe_private *afe_priv = afe->platform_priv;
int ret;
ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_BUS_CK]);
if (ret) {
dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
__func__, aud_clks[CK_INFRA_AUD_BUS_CK], ret);
goto CK_INFRA_AUD_BUS_CK_ERR;
}
ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_26M_CK]);
if (ret) {
dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
__func__, aud_clks[CK_INFRA_AUD_26M_CK], ret);
goto CK_INFRA_AUD_26M_ERR;
}
ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_L_CK]);
if (ret) {
dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
__func__, aud_clks[CK_INFRA_AUD_L_CK], ret);
goto CK_INFRA_AUD_L_CK_ERR;
}
ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_AUD_CK]);
if (ret) {
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
__func__, aud_clks[CK_INFRA_AUD_AUD_CK], ret);
goto CK_INFRA_AUD_AUD_CK_ERR;
}
ret = clk_prepare_enable(afe_priv->clk[CK_INFRA_AUD_EG2_CK]);
if (ret) {
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
__func__, aud_clks[CK_INFRA_AUD_EG2_CK], ret);
goto CK_INFRA_AUD_EG2_CK_ERR;
}
And clk_bulk_prepare_enable() instead all these.
return 0;
+CK_INFRA_AUD_EG2_CK_ERR:
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_AUD_CK]);
+CK_INFRA_AUD_AUD_CK_ERR:
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_L_CK]);
+CK_INFRA_AUD_L_CK_ERR:
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_26M_CK]);
+CK_INFRA_AUD_26M_ERR:
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_BUS_CK]);
+CK_INFRA_AUD_BUS_CK_ERR:
return ret;
+} +EXPORT_SYMBOL_GPL(mt79xx_afe_enable_clock);
+int mt79xx_afe_disable_clock(struct mtk_base_afe *afe) +{
struct mt79xx_afe_private *afe_priv = afe->platform_priv;
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_EG2_CK]);
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_AUD_CK]);
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_L_CK]);
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_26M_CK]);
clk_disable_unprepare(afe_priv->clk[CK_INFRA_AUD_BUS_CK]);
And also clk_bulk_disable_unprepare() here.
return 0;
+} +EXPORT_SYMBOL_GPL(mt79xx_afe_disable_clock); diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h new file mode 100644 index 000000000000..bf9c3edb6922 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-clk.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/*
- mt79xx-afe-clk.h -- MediaTek 79xx afe clock ctrl definition
- Copyright (c) 2021 MediaTek Inc.
- Author: Vic Wu vic.wu@mediatek.com
Maso Huang <maso.huang@mediatek.com>
- */
+#ifndef _MT79XX_AFE_CLK_H_ +#define _MT79XX_AFE_CLK_H_
+struct mtk_base_afe;
+int mt79xx_init_clock(struct mtk_base_afe *afe); +int mt79xx_afe_enable_clock(struct mtk_base_afe *afe); +int mt79xx_afe_disable_clock(struct mtk_base_afe *afe);
+#endif
2.18.0
linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Maso Huang maso.huang@mediatek.com
Add mt79xx platform driver.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- sound/soc/mediatek/Kconfig | 10 + sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/mt79xx/Makefile | 9 + sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c | 608 +++++++++++++++++++++ 4 files changed, 628 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/Makefile create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 4baac72677d9..192546078d5e 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -54,6 +54,16 @@ config SND_SOC_MT6797_MT6351 Select Y if you have such device. If unsure select "N".
+config SND_SOC_MT79XX + tristate "ASoC support for Mediatek MT79XX chip" + depends on ARCH_MEDIATEK + select SND_SOC_MEDIATEK + help + This adds ASoC platform driver support for MediaTek MT79XX chip + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". + config SND_SOC_MT8173 tristate "ASoC support for Mediatek MT8173 chip" depends on ARCH_MEDIATEK diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index 3de38cfc69e5..b2e530629887 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -2,6 +2,7 @@ obj-$(CONFIG_SND_SOC_MEDIATEK) += common/ obj-$(CONFIG_SND_SOC_MT2701) += mt2701/ obj-$(CONFIG_SND_SOC_MT6797) += mt6797/ +obj-$(CONFIG_SND_SOC_MT79XX) += mt79xx/ obj-$(CONFIG_SND_SOC_MT8173) += mt8173/ obj-$(CONFIG_SND_SOC_MT8183) += mt8183/ obj-$(CONFIG_SND_SOC_MT8186) += mt8186/ diff --git a/sound/soc/mediatek/mt79xx/Makefile b/sound/soc/mediatek/mt79xx/Makefile new file mode 100644 index 000000000000..984b20ae8819 --- /dev/null +++ b/sound/soc/mediatek/mt79xx/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 + +# platform driver +snd-soc-mt79xx-afe-objs := \ + mt79xx-afe-pcm.o \ + mt79xx-afe-clk.o \ + mt79xx-dai-etdm.o + +obj-$(CONFIG_SND_SOC_MT79XX) += snd-soc-mt79xx-afe.o diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c b/sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c new file mode 100644 index 000000000000..69c5f3f3f84b --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c @@ -0,0 +1,608 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC AFE platform driver for MT79xx + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/pm_runtime.h> + +#include "mt79xx-afe-common.h" +#include "mt79xx-afe-clk.h" +#include "mt79xx-reg.h" +#include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-afe-fe-dai.h" + +enum { + MTK_AFE_RATE_8K = 0, + MTK_AFE_RATE_11K = 1, + MTK_AFE_RATE_12K = 2, + MTK_AFE_RATE_16K = 4, + MTK_AFE_RATE_22K = 5, + MTK_AFE_RATE_24K = 6, + MTK_AFE_RATE_32K = 8, + MTK_AFE_RATE_44K = 9, + MTK_AFE_RATE_48K = 10, + MTK_AFE_RATE_88K = 13, + MTK_AFE_RATE_96K = 14, + MTK_AFE_RATE_176K = 17, + MTK_AFE_RATE_192K = 18, +}; + +unsigned int mt79xx_afe_rate_transform(struct device *dev, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_RATE_8K; + case 11025: + return MTK_AFE_RATE_11K; + case 12000: + return MTK_AFE_RATE_12K; + case 16000: + return MTK_AFE_RATE_16K; + case 22050: + return MTK_AFE_RATE_22K; + case 24000: + return MTK_AFE_RATE_24K; + case 32000: + return MTK_AFE_RATE_32K; + case 44100: + return MTK_AFE_RATE_44K; + case 48000: + return MTK_AFE_RATE_48K; + case 88200: + return MTK_AFE_RATE_88K; + case 96000: + return MTK_AFE_RATE_96K; + case 176400: + return MTK_AFE_RATE_176K; + case 192000: + return MTK_AFE_RATE_192K; + default: + dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n", + __func__, rate, MTK_AFE_RATE_48K); + return MTK_AFE_RATE_48K; + } +} + +static const struct snd_pcm_hardware mt79xx_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 = 256, + .period_bytes_max = 4 * 48 * 1024, + .periods_min = 2, + .periods_max = 256, + .buffer_bytes_max = 8 * 48 * 1024, + .fifo_size = 0, +}; + +static int mt79xx_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); + + return mt79xx_afe_rate_transform(afe->dev, rate); +} + +static int mt79xx_irq_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); + + return mt79xx_afe_rate_transform(afe->dev, rate); +} + +#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) + +#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 mt79xx_memif_dai_driver[] = { + /* FE DAIs: memory intefaces to CPU */ + { + .name = "DL1", + .id = MT79XX_MEMIF_DL1, + .playback = { + .stream_name = "DL1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mtk_afe_fe_ops, + }, + { + .name = "UL1", + .id = MT79XX_MEMIF_VUL12, + .capture = { + .stream_name = "UL1", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mtk_afe_fe_ops, + }, +}; + +static const struct snd_kcontrol_new o018_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I150_Switch", AFE_CONN018_4, 22, 1, 0), +}; + +static const struct snd_kcontrol_new o019_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I151_Switch", AFE_CONN019_4, 23, 1, 0), +}; + +static const struct snd_soc_dapm_widget mt79xx_memif_widgets[] = { + /* DL */ + SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* UL */ + 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)), +}; + +static const struct snd_soc_dapm_route mt79xx_memif_routes[] = { + {"I032", NULL, "DL1"}, + {"I033", NULL, "DL1"}, + {"UL1", NULL, "O018"}, + {"UL1", NULL, "O019"}, + {"O018", "I150_Switch", "I150"}, + {"O019", "I151_Switch", "I151"}, +}; + +static const struct snd_soc_component_driver mt79xx_afe_pcm_dai_component = { + .name = "mt79xx-afe-pcm-dai", +}; + +static const struct mtk_base_memif_data memif_data[MT79XX_MEMIF_NUM] = { + [MT79XX_MEMIF_DL1] = { + .name = "DL1", + .id = MT79XX_MEMIF_DL1, + .reg_ofs_base = AFE_DL0_BASE, + .reg_ofs_cur = AFE_DL0_CUR, + .reg_ofs_end = AFE_DL0_END, + .reg_ofs_base_msb = AFE_DL0_BASE_MSB, + .reg_ofs_cur_msb = AFE_DL0_CUR_MSB, + .reg_ofs_end_msb = AFE_DL0_END_MSB, + .fs_reg = AFE_DL0_CON0, + .fs_shift = DL0_MODE_SFT, + .fs_maskbit = DL0_MODE_MASK, + .mono_reg = AFE_DL0_CON0, + .mono_shift = DL0_MONO_SFT, + .enable_reg = AFE_DL0_CON0, + .enable_shift = DL0_ON_SFT, + .hd_reg = AFE_DL0_CON0, + .hd_shift = DL0_HD_MODE_SFT, + .hd_align_reg = AFE_DL0_CON0, + .hd_align_mshift = DL0_HALIGN_SFT, + .pbuf_reg = AFE_DL0_CON0, + .pbuf_shift = DL0_PBUF_SIZE_SFT, + .minlen_reg = AFE_DL0_CON0, + .minlen_shift = DL0_MINLEN_SFT, + }, + [MT79XX_MEMIF_VUL12] = { + .name = "VUL12", + .id = MT79XX_MEMIF_VUL12, + .reg_ofs_base = AFE_VUL0_BASE, + .reg_ofs_cur = AFE_VUL0_CUR, + .reg_ofs_end = AFE_VUL0_END, + .reg_ofs_base_msb = AFE_VUL0_BASE_MSB, + .reg_ofs_cur_msb = AFE_VUL0_CUR_MSB, + .reg_ofs_end_msb = AFE_VUL0_END_MSB, + .fs_reg = AFE_VUL0_CON0, + .fs_shift = VUL0_MODE_SFT, + .fs_maskbit = VUL0_MODE_MASK, + .mono_reg = AFE_VUL0_CON0, + .mono_shift = VUL0_MONO_SFT, + .enable_reg = AFE_VUL0_CON0, + .enable_shift = VUL0_ON_SFT, + .hd_reg = AFE_VUL0_CON0, + .hd_shift = VUL0_HD_MODE_SFT, + .hd_align_reg = AFE_VUL0_CON0, + .hd_align_mshift = VUL0_HALIGN_SFT, + }, +}; + +static const struct mtk_base_irq_data irq_data[MT79XX_IRQ_NUM] = { + [MT79XX_IRQ_0] = { + .id = MT79XX_IRQ_0, + .irq_cnt_reg = AFE_IRQ0_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ0_MCU_CFG0, + .irq_fs_shift = IRQ_MCU_MODE_SFT, + .irq_fs_maskbit = IRQ_MCU_MODE_MASK, + .irq_en_reg = AFE_IRQ0_MCU_CFG0, + .irq_en_shift = IRQ_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = IRQ0_MCU_CLR_SFT, + }, + [MT79XX_IRQ_1] = { + .id = MT79XX_IRQ_1, + .irq_cnt_reg = AFE_IRQ1_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ1_MCU_CFG0, + .irq_fs_shift = IRQ_MCU_MODE_SFT, + .irq_fs_maskbit = IRQ_MCU_MODE_MASK, + .irq_en_reg = AFE_IRQ1_MCU_CFG0, + .irq_en_shift = IRQ_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = IRQ1_MCU_CLR_SFT, + }, + [MT79XX_IRQ_2] = { + .id = MT79XX_IRQ_2, + .irq_cnt_reg = AFE_IRQ2_MCU_CFG1, + .irq_cnt_shift = AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit = AFE_IRQ_CNT_MASK, + .irq_fs_reg = AFE_IRQ2_MCU_CFG0, + .irq_fs_shift = IRQ_MCU_MODE_SFT, + .irq_fs_maskbit = IRQ_MCU_MODE_MASK, + .irq_en_reg = AFE_IRQ2_MCU_CFG0, + .irq_en_shift = IRQ_MCU_ON_SFT, + .irq_clr_reg = AFE_IRQ_MCU_CLR, + .irq_clr_shift = IRQ2_MCU_CLR_SFT, + }, +}; + +static bool mt79xx_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 AFE_DL0_CUR_MSB: + case AFE_DL0_CUR: + case AFE_DL0_RCH_MON: + case AFE_DL0_LCH_MON: + case AFE_VUL0_CUR_MSB: + case AFE_VUL0_CUR: + case AFE_IRQ_MCU_STATUS: + case AFE_MEMIF_RD_MON: + case AFE_MEMIF_WR_MON: + return true; + default: + return false; + }; +} + +static const struct regmap_config mt79xx_afe_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .volatile_reg = mt79xx_is_volatile_reg, + .max_register = AFE_MAX_REGISTER, + .num_reg_defaults_raw = ((AFE_MAX_REGISTER / 4) + 1), +}; + +static irqreturn_t mt79xx_afe_irq_handler(int irq_id, void *dev) +{ + struct mtk_base_afe *afe = dev; + struct mtk_base_afe_irq *irq; + unsigned int status; + unsigned int status_mcu; + unsigned int mcu_en; + int ret; + int i; + irqreturn_t irq_ret = IRQ_HANDLED; + + /* get irq that is sent to MCU */ + regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en); + + ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status); + /* only care IRQ which is sent to MCU */ + status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS; + + if (ret || status_mcu == 0) { + dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, + mcu_en 0x%x\n", __func__, ret, status, mcu_en); + + irq_ret = IRQ_NONE; + goto err_irq; + } + + for (i = 0; i < MT79XX_MEMIF_NUM; i++) { + struct mtk_base_afe_memif *memif = &afe->memif[i]; + + if (!memif->substream) + continue; + + if (memif->irq_usage < 0) + continue; + + irq = &afe->irqs[memif->irq_usage]; + + if (status_mcu & (1 << irq->irq_data->irq_en_shift)) + snd_pcm_period_elapsed(memif->substream); + } + +err_irq: + /* clear irq */ + regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, status_mcu); + + return irq_ret; +} + +static int mt79xx_afe_runtime_suspend(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct mt79xx_afe_private *afe_priv = afe->platform_priv; + + if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl) + goto skip_regmap; + + /* disable clk*/ + regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0x3fff); + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK, + 0); + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK, + 0); + + /* make sure all irq status are cleared, twice intended */ + regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CLR, 0xffff, 0xffff); + +skip_regmap: + return mt79xx_afe_disable_clock(afe); +} + +static int mt79xx_afe_runtime_resume(struct device *dev) +{ + struct mtk_base_afe *afe = dev_get_drvdata(dev); + struct mt79xx_afe_private *afe_priv = afe->platform_priv; + int ret; + + ret = mt79xx_afe_enable_clock(afe); + if (ret) + return ret; + + if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl) + goto skip_regmap; + + /* enable clk*/ + regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0); + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK, + AUD_APLL2_EN); + regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK, + AUD_26M_EN); + +skip_regmap: + return 0; +} + +static int mt79xx_afe_component_probe(struct snd_soc_component *component) +{ + return mtk_afe_add_sub_dai_control(component); +} + +static const struct snd_soc_component_driver mt79xx_afe_component = { + .name = AFE_PCM_NAME, + .probe = mt79xx_afe_component_probe, + .pointer = mtk_afe_pcm_pointer, + .pcm_construct = mtk_afe_pcm_new, +}; + +static int mt79xx_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 = mt79xx_memif_dai_driver; + dai->num_dai_drivers = ARRAY_SIZE(mt79xx_memif_dai_driver); + + dai->dapm_widgets = mt79xx_memif_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mt79xx_memif_widgets); + dai->dapm_routes = mt79xx_memif_routes; + dai->num_dapm_routes = ARRAY_SIZE(mt79xx_memif_routes); + + return 0; +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = { + mt79xx_dai_etdm_register, + mt79xx_dai_memif_register, +}; + +static int mt79xx_afe_pcm_dev_probe(struct platform_device *pdev) +{ + struct mtk_base_afe *afe; + struct mt79xx_afe_private *afe_priv; + struct device *dev; + int i, irq_id, ret; + + afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + platform_set_drvdata(pdev, afe); + + afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv), + GFP_KERNEL); + if (!afe->platform_priv) + return -ENOMEM; + + afe_priv = afe->platform_priv; + afe->dev = &pdev->dev; + dev = afe->dev; + + afe->base_addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); + + /* initial audio related clock */ + ret = mt79xx_init_clock(afe); + if (ret) { + dev_err(dev, "init clock error\n"); + return ret; + } + + pm_runtime_enable(dev); + + /* enable clock for regcache get default value from hw */ + afe_priv->pm_runtime_bypass_reg_ctl = true; + pm_runtime_get_sync(&pdev->dev); + + afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr, + &mt79xx_afe_regmap_config); + if (IS_ERR(afe->regmap)) { + ret = PTR_ERR(afe->regmap); + goto err_pm_disable; + } + + pm_runtime_put_sync(&pdev->dev); + afe_priv->pm_runtime_bypass_reg_ctl = false; + + /* init memif */ + afe->memif_size = MT79XX_MEMIF_NUM; + afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), + GFP_KERNEL); + if (!afe->memif) + goto err_pm_disable; + + for (i = 0; i < afe->memif_size; i++) { + afe->memif[i].data = &memif_data[i]; + afe->memif[i].irq_usage = -1; + } + + mutex_init(&afe->irq_alloc_lock); + + /* irq initialize */ + afe->irqs_size = MT79XX_IRQ_NUM; + afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), + GFP_KERNEL); + if (!afe->irqs) + goto err_pm_disable; + + for (i = 0; i < afe->irqs_size; i++) + afe->irqs[i].irq_data = &irq_data[i]; + + /* request irq */ + irq_id = platform_get_irq(pdev, 0); + if (!irq_id) { + dev_err(dev, "%pOFn no irq found\n", dev->of_node); + goto err_pm_disable; + } + ret = devm_request_irq(dev, irq_id, mt79xx_afe_irq_handler, + IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); + if (ret) { + dev_err(dev, "could not request_irq for asys-isr\n"); + goto err_pm_disable; + } + + /* 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(afe->dev, "dai register i %d fail, ret %d\n", + i, ret); + goto err_pm_disable; + } + } + + /* init dai_driver and component_driver */ + ret = mtk_afe_combine_sub_dai(afe); + if (ret) { + dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n", + ret); + goto err_pm_disable; + } + + afe->mtk_afe_hardware = &mt79xx_afe_hardware; + afe->memif_fs = mt79xx_memif_fs; + afe->irq_fs = mt79xx_irq_fs; + + afe->runtime_resume = mt79xx_afe_runtime_resume; + afe->runtime_suspend = mt79xx_afe_runtime_suspend; + + /* register component */ + ret = devm_snd_soc_register_component(&pdev->dev, + &mt79xx_afe_component, + NULL, 0); + if (ret) { + dev_warn(dev, "err_platform\n"); + goto err_pm_disable; + } + + ret = devm_snd_soc_register_component(afe->dev, + &mt79xx_afe_pcm_dai_component, + afe->dai_drivers, + afe->num_dai_drivers); + if (ret) { + dev_warn(dev, "err_dai_component\n"); + goto err_pm_disable; + } + + return ret; + +err_pm_disable: + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + return ret; +} + +static int mt79xx_afe_pcm_dev_remove(struct platform_device *pdev) +{ + pm_runtime_disable(&pdev->dev); + if (!pm_runtime_status_suspended(&pdev->dev)) + mt79xx_afe_runtime_suspend(&pdev->dev); + + return 0; +} + +static const struct of_device_id mt79xx_afe_pcm_dt_match[] = { + { .compatible = "mediatek,mt79xx-afe", }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt79xx_afe_pcm_dt_match); + +static const struct dev_pm_ops mt79xx_afe_pm_ops = { + SET_RUNTIME_PM_OPS(mt79xx_afe_runtime_suspend, + mt79xx_afe_runtime_resume, NULL) +}; + +static struct platform_driver mt79xx_afe_pcm_driver = { + .driver = { + .name = "mt79xx-audio", + .of_match_table = mt79xx_afe_pcm_dt_match, + .pm = &mt79xx_afe_pm_ops, + }, + .probe = mt79xx_afe_pcm_dev_probe, + .remove = mt79xx_afe_pcm_dev_remove, +}; + +module_platform_driver(mt79xx_afe_pcm_driver); + +MODULE_DESCRIPTION("Mediatek SoC AFE platform driver for ALSA MT79xx"); +MODULE_AUTHOR("Vic Wu vic.wu@mediatek.com"); +MODULE_LICENSE("GPL");
Il 12/06/23 12:52, Maso Hunag ha scritto:
From: Maso Huang maso.huang@mediatek.com
Add mt79xx platform driver.
Signed-off-by: Maso Huang maso.huang@mediatek.com
sound/soc/mediatek/Kconfig | 10 + sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/mt79xx/Makefile | 9 + sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c | 608 +++++++++++++++++++++ 4 files changed, 628 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/Makefile create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c
..snip..
diff --git a/sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c b/sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c new file mode 100644 index 000000000000..69c5f3f3f84b --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c @@ -0,0 +1,608 @@ +// SPDX-License-Identifier: GPL-2.0 +/*
- MediaTek ALSA SoC AFE platform driver for MT79xx
- Copyright (c) 2021 MediaTek Inc.
- Author: Vic Wu vic.wu@mediatek.com
Maso Huang <maso.huang@mediatek.com>
- */
+#include <linux/delay.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/pm_runtime.h>
+#include "mt79xx-afe-common.h" +#include "mt79xx-afe-clk.h" +#include "mt79xx-reg.h" +#include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-afe-fe-dai.h"
+enum {
- MTK_AFE_RATE_8K = 0,
- MTK_AFE_RATE_11K = 1,
- MTK_AFE_RATE_12K = 2,
- MTK_AFE_RATE_16K = 4,
- MTK_AFE_RATE_22K = 5,
- MTK_AFE_RATE_24K = 6,
- MTK_AFE_RATE_32K = 8,
- MTK_AFE_RATE_44K = 9,
- MTK_AFE_RATE_48K = 10,
- MTK_AFE_RATE_88K = 13,
- MTK_AFE_RATE_96K = 14,
- MTK_AFE_RATE_176K = 17,
- MTK_AFE_RATE_192K = 18,
+};
+unsigned int mt79xx_afe_rate_transform(struct device *dev,
unsigned int rate)
+{
- switch (rate) {
- case 8000:
return MTK_AFE_RATE_8K;
- case 11025:
return MTK_AFE_RATE_11K;
- case 12000:
return MTK_AFE_RATE_12K;
- case 16000:
return MTK_AFE_RATE_16K;
- case 22050:
return MTK_AFE_RATE_22K;
- case 24000:
return MTK_AFE_RATE_24K;
- case 32000:
return MTK_AFE_RATE_32K;
- case 44100:
return MTK_AFE_RATE_44K;
- case 48000:
return MTK_AFE_RATE_48K;
- case 88200:
return MTK_AFE_RATE_88K;
- case 96000:
return MTK_AFE_RATE_96K;
- case 176400:
return MTK_AFE_RATE_176K;
- case 192000:
return MTK_AFE_RATE_192K;
- default:
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
__func__, rate, MTK_AFE_RATE_48K);
return MTK_AFE_RATE_48K;
- }
+}
+static const struct snd_pcm_hardware mt79xx_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 = 256,
- .period_bytes_max = 4 * 48 * 1024,
- .periods_min = 2,
- .periods_max = 256,
- .buffer_bytes_max = 8 * 48 * 1024,
- .fifo_size = 0,
+};
+static int mt79xx_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);
Fits in one line.
- struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
- return mt79xx_afe_rate_transform(afe->dev, rate);
+}
+static int mt79xx_irq_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);
Fits in one line.
- struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component);
- return mt79xx_afe_rate_transform(afe->dev, rate);
+}
..snip..
+static irqreturn_t mt79xx_afe_irq_handler(int irq_id, void *dev) +{
- struct mtk_base_afe *afe = dev;
- struct mtk_base_afe_irq *irq;
- unsigned int status;
- unsigned int status_mcu;
- unsigned int mcu_en;
u32 mcu_en, status, status_mcu; int i, ret; irqreturn_t irq_ret = IRQ_HANDLED;
- int ret;
- int i;
- irqreturn_t irq_ret = IRQ_HANDLED;
- /* get irq that is sent to MCU */
- regmap_read(afe->regmap, AFE_IRQ_MCU_EN, &mcu_en);
- ret = regmap_read(afe->regmap, AFE_IRQ_MCU_STATUS, &status);
- /* only care IRQ which is sent to MCU */
- status_mcu = status & mcu_en & AFE_IRQ_STATUS_BITS;
- if (ret || status_mcu == 0) {
dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x,
mcu_en 0x%x\n", __func__, ret, status, mcu_en);
irq_ret = IRQ_NONE;
goto err_irq;
- }
- for (i = 0; i < MT79XX_MEMIF_NUM; i++) {
struct mtk_base_afe_memif *memif = &afe->memif[i];
if (!memif->substream)
continue;
if (memif->irq_usage < 0)
continue;
irq = &afe->irqs[memif->irq_usage];
if (status_mcu & (1 << irq->irq_data->irq_en_shift))
snd_pcm_period_elapsed(memif->substream);
- }
+err_irq:
- /* clear irq */
- regmap_write(afe->regmap, AFE_IRQ_MCU_CLR, status_mcu);
- return irq_ret;
+}
+static int mt79xx_afe_runtime_suspend(struct device *dev) +{
- struct mtk_base_afe *afe = dev_get_drvdata(dev);
- struct mt79xx_afe_private *afe_priv = afe->platform_priv;
- if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
goto skip_regmap;
- /* disable clk*/
- regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0x3fff);
- regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK,
0);
- regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK,
0);
Each regmap_update_bits() call fits in one line.
- /* make sure all irq status are cleared, twice intended */
- regmap_update_bits(afe->regmap, AFE_IRQ_MCU_CLR, 0xffff, 0xffff);
+skip_regmap:
- return mt79xx_afe_disable_clock(afe);
+}
+static int mt79xx_afe_runtime_resume(struct device *dev) +{
- struct mtk_base_afe *afe = dev_get_drvdata(dev);
- struct mt79xx_afe_private *afe_priv = afe->platform_priv;
- int ret;
- ret = mt79xx_afe_enable_clock(afe);
- if (ret)
return ret;
- if (!afe->regmap || afe_priv->pm_runtime_bypass_reg_ctl)
goto skip_regmap;
Just return 0 here instead of jumping.
- /* enable clk*/
- regmap_update_bits(afe->regmap, AUDIO_TOP_CON4, 0x3fff, 0);
- regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_APLL2_EN_MASK,
AUD_APLL2_EN);
- regmap_update_bits(afe->regmap, AUDIO_ENGEN_CON0, AUD_26M_EN_MASK,
AUD_26M_EN);
+skip_regmap:
- return 0;
+}
+static int mt79xx_afe_component_probe(struct snd_soc_component *component) +{
- return mtk_afe_add_sub_dai_control(component);
+}
+static const struct snd_soc_component_driver mt79xx_afe_component = {
- .name = AFE_PCM_NAME,
- .probe = mt79xx_afe_component_probe,
- .pointer = mtk_afe_pcm_pointer,
- .pcm_construct = mtk_afe_pcm_new,
+};
+static int mt79xx_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 = mt79xx_memif_dai_driver;
- dai->num_dai_drivers = ARRAY_SIZE(mt79xx_memif_dai_driver);
- dai->dapm_widgets = mt79xx_memif_widgets;
- dai->num_dapm_widgets = ARRAY_SIZE(mt79xx_memif_widgets);
- dai->dapm_routes = mt79xx_memif_routes;
- dai->num_dapm_routes = ARRAY_SIZE(mt79xx_memif_routes);
- return 0;
+}
+typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] = {
- mt79xx_dai_etdm_register,
- mt79xx_dai_memif_register,
+};
+static int mt79xx_afe_pcm_dev_probe(struct platform_device *pdev) +{
- struct mtk_base_afe *afe;
- struct mt79xx_afe_private *afe_priv;
- struct device *dev;
- int i, irq_id, ret;
- afe = devm_kzalloc(&pdev->dev, sizeof(*afe), GFP_KERNEL);
- if (!afe)
return -ENOMEM;
- platform_set_drvdata(pdev, afe);
- afe->platform_priv = devm_kzalloc(&pdev->dev, sizeof(*afe_priv),
GFP_KERNEL);
- if (!afe->platform_priv)
return -ENOMEM;
- afe_priv = afe->platform_priv;
- afe->dev = &pdev->dev;
- dev = afe->dev;
- afe->base_addr = devm_platform_ioremap_resource(pdev, 0);
- if (IS_ERR(afe->base_addr))
return PTR_ERR(afe->base_addr);
- /* initial audio related clock */
- ret = mt79xx_init_clock(afe);
- if (ret) {
dev_err(dev, "init clock error\n");
return ret;
return dev_err_probe(dev, ret, "Cannot initialize clocks\n");
- }
- pm_runtime_enable(dev);
ret = devm_pm_runtime_enable(dev); if (ret) return ret;
- /* enable clock for regcache get default value from hw */
- afe_priv->pm_runtime_bypass_reg_ctl = true;
- pm_runtime_get_sync(&pdev->dev);
- afe->regmap = devm_regmap_init_mmio(&pdev->dev, afe->base_addr,
&mt79xx_afe_regmap_config);
- if (IS_ERR(afe->regmap)) {
ret = PTR_ERR(afe->regmap);
goto err_pm_disable;
- }
- pm_runtime_put_sync(&pdev->dev);
- afe_priv->pm_runtime_bypass_reg_ctl = false;
- /* init memif */
- afe->memif_size = MT79XX_MEMIF_NUM;
- afe->memif = devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif),
GFP_KERNEL);
- if (!afe->memif)
goto err_pm_disable;
- for (i = 0; i < afe->memif_size; i++) {
afe->memif[i].data = &memif_data[i];
afe->memif[i].irq_usage = -1;
- }
- mutex_init(&afe->irq_alloc_lock);
- /* irq initialize */
- afe->irqs_size = MT79XX_IRQ_NUM;
- afe->irqs = devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs),
GFP_KERNEL);
- if (!afe->irqs)
goto err_pm_disable;
- for (i = 0; i < afe->irqs_size; i++)
afe->irqs[i].irq_data = &irq_data[i];
- /* request irq */
- irq_id = platform_get_irq(pdev, 0);
- if (!irq_id) {
dev_err(dev, "%pOFn no irq found\n", dev->of_node);
You're not setting any `ret` value to return an error: this will return 0!!!
goto err_pm_disable;
- }
- ret = devm_request_irq(dev, irq_id, mt79xx_afe_irq_handler,
IRQF_TRIGGER_NONE, "asys-isr", (void *)afe);
- if (ret) {
dev_err(dev, "could not request_irq for asys-isr\n");
goto err_pm_disable;
- }
- /* 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(afe->dev, "dai register i %d fail, ret %d\n",
i, ret);
Please change this dev_warn() to dev_err().
goto err_pm_disable;
}
- }
- /* init dai_driver and component_driver */
- ret = mtk_afe_combine_sub_dai(afe);
- if (ret) {
dev_warn(afe->dev, "mtk_afe_combine_sub_dai fail, ret %d\n",
ret);
dev_err()
goto err_pm_disable;
- }
- afe->mtk_afe_hardware = &mt79xx_afe_hardware;
- afe->memif_fs = mt79xx_memif_fs;
- afe->irq_fs = mt79xx_irq_fs;
- afe->runtime_resume = mt79xx_afe_runtime_resume;
- afe->runtime_suspend = mt79xx_afe_runtime_suspend;
- /* register component */
- ret = devm_snd_soc_register_component(&pdev->dev,
&mt79xx_afe_component,
NULL, 0);
- if (ret) {
dev_warn(dev, "err_platform\n");
goto err_pm_disable;
- }
- ret = devm_snd_soc_register_component(afe->dev,
&mt79xx_afe_pcm_dai_component,
afe->dai_drivers,
afe->num_dai_drivers);
- if (ret) {
dev_warn(dev, "err_dai_component\n");
goto err_pm_disable;
- }
- return ret;
+err_pm_disable:
- pm_runtime_put_sync(&pdev->dev);
- pm_runtime_disable(&pdev->dev);
- return ret;
+}
+static int mt79xx_afe_pcm_dev_remove(struct platform_device *pdev) +{
- pm_runtime_disable(&pdev->dev);
- if (!pm_runtime_status_suspended(&pdev->dev))
mt79xx_afe_runtime_suspend(&pdev->dev);
- return 0;
+}
+static const struct of_device_id mt79xx_afe_pcm_dt_match[] = {
- { .compatible = "mediatek,mt79xx-afe", },
- {},
Last entry is always { /* sentinel */ }
+}; +MODULE_DEVICE_TABLE(of, mt79xx_afe_pcm_dt_match);
+static const struct dev_pm_ops mt79xx_afe_pm_ops = {
- SET_RUNTIME_PM_OPS(mt79xx_afe_runtime_suspend,
mt79xx_afe_runtime_resume, NULL)
+};
+static struct platform_driver mt79xx_afe_pcm_driver = {
- .driver = {
.name = "mt79xx-audio",
.of_match_table = mt79xx_afe_pcm_dt_match,
.pm = &mt79xx_afe_pm_ops,
- },
- .probe = mt79xx_afe_pcm_dev_probe,
- .remove = mt79xx_afe_pcm_dev_remove,
+};
Remove this extra blank line.
+module_platform_driver(mt79xx_afe_pcm_driver);
+MODULE_DESCRIPTION("Mediatek SoC AFE platform driver for ALSA MT79xx"); +MODULE_AUTHOR("Vic Wu vic.wu@mediatek.com"); +MODULE_LICENSE("GPL");
Thanks, Angelo
Hi Maso,
kernel test robot noticed the following build errors:
[auto build test ERROR on broonie-sound/for-next] [also build test ERROR on tiwai-sound/for-next tiwai-sound/for-linus linus/master v6.4-rc6 next-20230614] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Maso-Hunag/ASoC-mediatek-mt79... base: https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git for-next patch link: https://lore.kernel.org/r/20230612105250.15441-4-maso.huang%40mediatek.com patch subject: [PATCH 3/7] ASoC: mediatek: mt79xx: add platform driver config: arm-allmodconfig (https://download.01.org/0day-ci/archive/20230614/202306142005.uUyPtOQT-lkp@i...) compiler: arm-linux-gnueabi-gcc (GCC) 12.3.0 reproduce (this is a W=1 build): mkdir -p ~/bin wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross git remote add broonie-sound https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git git fetch broonie-sound for-next git checkout broonie-sound/for-next b4 shazam https://lore.kernel.org/r/20230612105250.15441-4-maso.huang@mediatek.com # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.3.0 ~/bin/make.cross W=1 O=build_dir ARCH=arm olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.3.0 ~/bin/make.cross W=1 O=build_dir ARCH=arm SHELL=/bin/bash sound/soc/mediatek/mt79xx/
If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot lkp@intel.com | Closes: https://lore.kernel.org/oe-kbuild-all/202306142005.uUyPtOQT-lkp@intel.com/
All error/warnings (new ones prefixed by >>):
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c: In function 'mt79xx_afe_irq_handler':
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:35: warning: missing terminating " character
322 | dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, | ^ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:323:38: warning: missing terminating " character 323 | mcu_en 0x%x\n", __func__, ret, status, mcu_en); | ^
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:608:23: error: unterminated argument list invoking macro "dev_err"
608 | MODULE_LICENSE("GPL"); | ^
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:17: error: 'dev_err' undeclared (first use in this function); did you mean '_dev_err'?
322 | dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, | ^~~~~~~ | _dev_err sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:17: note: each undeclared identifier is reported only once for each function it appears in
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:24: error: expected ';' at end of input
322 | dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, | ^ | ; ......
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:17: error: expected declaration or statement at end of input
322 | dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:17: error: expected declaration or statement at end of input
sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:312:21: warning: unused variable 'irq_ret' [-Wunused-variable] 312 | irqreturn_t irq_ret = IRQ_HANDLED; | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:311:13: warning: unused variable 'i' [-Wunused-variable] 311 | int i; | ^ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:306:34: warning: unused variable 'irq' [-Wunused-variable] 306 | struct mtk_base_afe_irq *irq; | ^~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:322:17: error: no return statement in function returning non-void [-Werror=return-type] 322 | dev_err(afe->dev, "%s(), irq status err, ret %d, status 0x%x, | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c: At top level: sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:303:20: warning: 'mt79xx_afe_irq_handler' defined but not used [-Wunused-function] 303 | static irqreturn_t mt79xx_afe_irq_handler(int irq_id, void *dev) | ^~~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:294:35: warning: 'mt79xx_afe_regmap_config' defined but not used [-Wunused-const-variable=] 294 | static const struct regmap_config mt79xx_afe_regmap_config = { | ^~~~~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:232:39: warning: 'irq_data' defined but not used [-Wunused-const-variable=] 232 | static const struct mtk_base_irq_data irq_data[MT79XX_IRQ_NUM] = { | ^~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:183:41: warning: 'memif_data' defined but not used [-Wunused-const-variable=] 183 | static const struct mtk_base_memif_data memif_data[MT79XX_MEMIF_NUM] = { | ^~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:179:46: warning: 'mt79xx_afe_pcm_dai_component' defined but not used [-Wunused-const-variable=] 179 | static const struct snd_soc_component_driver mt79xx_afe_pcm_dai_component = { | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:170:40: warning: 'mt79xx_memif_routes' defined but not used [-Wunused-const-variable=] 170 | static const struct snd_soc_dapm_route mt79xx_memif_routes[] = { | ^~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:158:41: warning: 'mt79xx_memif_widgets' defined but not used [-Wunused-const-variable=] 158 | static const struct snd_soc_dapm_widget mt79xx_memif_widgets[] = { | ^~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:122:34: warning: 'mt79xx_memif_dai_driver' defined but not used [-Wunused-variable] 122 | static struct snd_soc_dai_driver mt79xx_memif_dai_driver[] = { | ^~~~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:101:12: warning: 'mt79xx_irq_fs' defined but not used [-Wunused-function] 101 | static int mt79xx_irq_fs(struct snd_pcm_substream *substream, | ^~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:90:12: warning: 'mt79xx_memif_fs' defined but not used [-Wunused-function] 90 | static int mt79xx_memif_fs(struct snd_pcm_substream *substream, | ^~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c:75:38: warning: 'mt79xx_afe_hardware' defined but not used [-Wunused-const-variable=] 75 | static const struct snd_pcm_hardware mt79xx_afe_hardware = { | ^~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors -- sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c: In function 'mt79xx_init_clock':
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:43: warning: missing terminating " character
46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:42: warning: missing terminating " character 47 | ret %ld\n", __func__, aud_clks[i], | ^ In file included from include/linux/kernel.h:30, from include/linux/clk.h:13, from sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:10:
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:43: error: missing terminating " character
46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:33: error: 'ret' undeclared (first use in this function); did you mean 'net'?
47 | ret %ld\n", __func__, aud_clks[i], | ^~~ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:33: note: each undeclared identifier is reported only once for each function it appears in 47 | ret %ld\n", __func__, aud_clks[i], | ^~~ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:40: error: stray '' in program
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:38: error: 'ld' undeclared (first use in this function)
47 | ret %ld\n", __func__, aud_clks[i], | ^~ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:41: error: expected ')' before 'n'
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ include/linux/printk.h:379:41: note: to match this '(' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^ include/linux/printk.h:422:9: note: in expansion of macro '__printk_index_emit' 422 | __printk_index_emit(fmt, level, subsys_fmt_prefix) | ^~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:42: error: missing terminating " character 47 | ret %ld\n", __func__, aud_clks[i], | ^~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/printk.h:379:42: note: in definition of macro '__printk_index_emit' 379 | if (__builtin_constant_p(_fmt) && __builtin_constant_p(_level)) { \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:43: error: missing terminating " character
46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/printk.h:388:61: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:40: error: stray '' in program
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/printk.h:388:61: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:41: error: expected ')' before 'n'
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/printk.h:388:61: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ include/linux/printk.h:388:60: note: to match this '(' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^ include/linux/printk.h:422:9: note: in expansion of macro '__printk_index_emit' 422 | __printk_index_emit(fmt, level, subsys_fmt_prefix) | ^~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:42: error: missing terminating " character 47 | ret %ld\n", __func__, aud_clks[i], | ^~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/printk.h:388:61: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:43: error: missing terminating " character
46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/printk.h:388:70: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:40: error: stray '' in program
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/printk.h:388:70: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:41: error: expected ')' before 'n'
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/printk.h:388:70: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ include/linux/printk.h:388:69: note: to match this '(' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^ include/linux/printk.h:422:9: note: in expansion of macro '__printk_index_emit' 422 | __printk_index_emit(fmt, level, subsys_fmt_prefix) | ^~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:42: error: missing terminating " character 47 | ret %ld\n", __func__, aud_clks[i], | ^~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/printk.h:388:70: note: in definition of macro '__printk_index_emit' 388 | .fmt = __builtin_constant_p(_fmt) ? (_fmt) : NULL, \ | ^~~~ include/linux/dev_printk.h:105:9: note: in expansion of macro 'printk_index_subsys_emit' 105 | printk_index_subsys_emit("%s %s: ", level, fmt) | ^~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:109:17: note: in expansion of macro 'dev_printk_index_emit' 109 | dev_printk_index_emit(level, fmt); \ | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ In file included from include/linux/device.h:15, from include/linux/platform_device.h:13, from include/sound/soc.h:14, from sound/soc/mediatek/mt79xx/mt79xx-afe-common.h:13, from sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:12:
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:43: error: missing terminating " character
46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:40: error: stray '' in program
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:41: error: expected ')' before 'n'
47 | ret %ld\n", __func__, aud_clks[i], | ^ include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ include/linux/dev_printk.h:110:24: note: to match this '(' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^ include/linux/dev_printk.h:144:9: note: in expansion of macro 'dev_printk_index_wrap' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~~~~~~~~~~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:47:42: error: missing terminating " character 47 | ret %ld\n", __func__, aud_clks[i], | ^~~~~~~~~~~~~~~~~~~~~~~~~ include/linux/dev_printk.h:110:30: note: in definition of macro 'dev_printk_index_wrap' 110 | _p_func(dev, fmt, ##__VA_ARGS__); \ | ^~~ include/linux/dev_printk.h:144:56: note: in expansion of macro 'dev_fmt' 144 | dev_printk_index_wrap(_dev_err, KERN_ERR, dev, dev_fmt(fmt), ##__VA_ARGS__) | ^~~~~~~ sound/soc/mediatek/mt79xx/mt79xx-afe-clk.c:46:25: note: in expansion of macro 'dev_err' 46 | dev_err(afe->dev, "%s(), devm_clk_get %s fail, | ^~~~~~~
vim +/dev_err +608 sound/soc/mediatek/mt79xx/mt79xx-afe-pcm.c
605 606 MODULE_DESCRIPTION("Mediatek SoC AFE platform driver for ALSA MT79xx"); 607 MODULE_AUTHOR("Vic Wu vic.wu@mediatek.com");
608 MODULE_LICENSE("GPL");
From: Maso Huang maso.huang@mediatek.com
Add mt79xx etdm dai driver support.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c | 421 ++++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c
diff --git a/sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c b/sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c new file mode 100644 index 000000000000..9a5cc7ce1eae --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-dai-etdm.c @@ -0,0 +1,421 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI eTDM Control + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#include <linux/bitops.h> +#include <linux/regmap.h> +#include <sound/pcm_params.h> +#include "mt79xx-afe-clk.h" +#include "mt79xx-afe-common.h" +#include "mt79xx-reg.h" + +enum { + HOPPING_CLK = 0, + APLL_CLK = 1, +}; + +enum { + MTK_DAI_ETDM_FORMAT_I2S = 0, + MTK_DAI_ETDM_FORMAT_DSPA = 4, + MTK_DAI_ETDM_FORMAT_DSPB = 5, +}; + +enum { + ETDM_IN5 = 2, + ETDM_OUT5 = 10, +}; + +enum { + MTK_ETDM_RATE_8K = 0, + MTK_ETDM_RATE_12K = 1, + MTK_ETDM_RATE_16K = 2, + MTK_ETDM_RATE_24K = 3, + MTK_ETDM_RATE_32K = 4, + MTK_ETDM_RATE_48K = 5, + MTK_ETDM_RATE_96K = 7, + MTK_ETDM_RATE_192K = 9, + MTK_ETDM_RATE_11K = 16, + MTK_ETDM_RATE_22K = 17, + MTK_ETDM_RATE_44K = 18, + MTK_ETDM_RATE_88K = 19, + MTK_ETDM_RATE_176K = 20, +}; + +struct mtk_dai_etdm_priv { + bool bck_inv; + bool lrck_inv; + bool slave_mode; + unsigned int format; +}; + +static unsigned int mt79xx_etdm_rate_transform(struct device *dev, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_ETDM_RATE_8K; + case 11025: + return MTK_ETDM_RATE_11K; + case 12000: + return MTK_ETDM_RATE_12K; + case 16000: + return MTK_ETDM_RATE_16K; + case 22050: + return MTK_ETDM_RATE_22K; + case 24000: + return MTK_ETDM_RATE_24K; + case 32000: + return MTK_ETDM_RATE_32K; + case 44100: + return MTK_ETDM_RATE_44K; + case 48000: + return MTK_ETDM_RATE_48K; + case 88200: + return MTK_ETDM_RATE_88K; + case 96000: + return MTK_ETDM_RATE_96K; + case 176400: + return MTK_ETDM_RATE_176K; + case 192000: + return MTK_ETDM_RATE_192K; + default: + dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n", + __func__, rate, MTK_ETDM_RATE_48K); + return MTK_ETDM_RATE_48K; + } +} + +static int get_etdm_wlen(unsigned int bitwidth) +{ + return bitwidth <= 16 ? 16 : 32; +} + +/* dai component */ +/* interconnection */ + +static const struct snd_kcontrol_new o124_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I032_Switch", AFE_CONN124_1, 0, 1, 0), +}; + +static const struct snd_kcontrol_new o125_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I033_Switch", AFE_CONN125_1, 1, 1, 0), +}; + +static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { + + /* DL */ + SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0), + /* UL */ + SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, + o124_mix, ARRAY_SIZE(o124_mix)), + SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, + o125_mix, ARRAY_SIZE(o125_mix)), +}; + +static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { + {"I150", NULL, "ETDM Capture"}, + {"I151", NULL, "ETDM Capture"}, + {"ETDM Playback", NULL, "O124"}, + {"ETDM Playback", NULL, "O125"}, + {"O124", "I032_Switch", "I032"}, + {"O125", "I033_Switch", "I033"}, +}; + +/* 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); + + mt79xx_afe_enable_clock(afe); + + regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK, + 0); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK, + 0); + + 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); + + regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_OUT5_PDN_MASK, + CLK_OUT5_PDN); + regmap_update_bits(afe->regmap, AUDIO_TOP_CON2, CLK_IN5_PDN_MASK, + CLK_IN5_PDN); + + mt79xx_afe_disable_clock(afe); +} + +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 mtk_dai_etdm_config(struct mtk_base_afe *afe, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, + int stream) +{ + struct mt79xx_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 etdm_rate = mt79xx_etdm_rate_transform(afe->dev, rate); + unsigned int afe_rate = mt79xx_afe_rate_transform(afe->dev, rate); + unsigned int channels = params_channels(params); + unsigned int bit_width = params_width(params); + unsigned int wlen = get_etdm_wlen(bit_width); + unsigned int val = 0; + unsigned int mask = 0; + + dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n", + __func__, stream, rate, bit_width); + + /* CON0 */ + mask |= ETDM_BIT_LEN_MASK; + val |= ETDM_BIT_LEN(bit_width); + mask |= ETDM_WRD_LEN_MASK; + val |= ETDM_WRD_LEN(wlen); + mask |= ETDM_FMT_MASK; + val |= ETDM_FMT(etdm_data->format); + mask |= ETDM_CH_NUM_MASK; + val |= ETDM_CH_NUM(get_etdm_ch_fixup(channels)); + mask |= RELATCH_SRC_MASK; + val |= RELATCH_SRC(APLL_CLK); + + switch (stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + /* set ETDM_OUT5_CON0 */ + regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, mask, val); + + /* set ETDM_OUT5_CON4 */ + regmap_update_bits(afe->regmap, ETDM_OUT5_CON4, + OUT_RELATCH_MASK, OUT_RELATCH(afe_rate)); + regmap_update_bits(afe->regmap, ETDM_OUT5_CON4, + OUT_CLK_SRC_MASK, OUT_CLK_SRC(APLL_CLK)); + regmap_update_bits(afe->regmap, ETDM_OUT5_CON4, + OUT_SEL_FS_MASK, OUT_SEL_FS(etdm_rate)); + + /* set ETDM_OUT5_CON5 */ + regmap_update_bits(afe->regmap, ETDM_OUT5_CON5, + ETDM_CLK_DIV_MASK, ETDM_CLK_DIV); + break; + case SNDRV_PCM_STREAM_CAPTURE: + /* set ETDM_IN5_CON0 */ + regmap_update_bits(afe->regmap, ETDM_IN5_CON0, mask, val); + regmap_update_bits(afe->regmap, ETDM_IN5_CON0, + ETDM_SYNC_MASK, ETDM_SYNC); + + /* set ETDM_IN5_CON2 */ + regmap_update_bits(afe->regmap, ETDM_IN5_CON2, + IN_CLK_SRC_MASK, IN_CLK_SRC(APLL_CLK)); + + /* set ETDM_IN5_CON3 */ + regmap_update_bits(afe->regmap, ETDM_IN5_CON3, + IN_SEL_FS_MASK, IN_SEL_FS(etdm_rate)); + + /* set ETDM_IN5_CON4 */ + regmap_update_bits(afe->regmap, ETDM_IN5_CON4, + IN_RELATCH_MASK, IN_RELATCH(afe_rate)); + break; + default: + break; + } + + 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) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_PLAYBACK); + mtk_dai_etdm_config(afe, params, dai, SNDRV_PCM_STREAM_CAPTURE); + + return 0; +} + +static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + + 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: + regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK, + ETDM_EN); + regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK, + ETDM_EN); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + regmap_update_bits(afe->regmap, ETDM_IN5_CON0, ETDM_EN_MASK, + 0); + regmap_update_bits(afe->regmap, ETDM_OUT5_CON0, ETDM_EN_MASK, + 0); + break; + default: + break; + } + + 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 mt79xx_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data; + void *priv_data; + + switch (dai->id) { + case MT79XX_DAI_ETDM: + break; + default: + dev_warn(afe->dev, "%s(), id %d not support\n", + __func__, dai->id); + return -EINVAL; + } + + priv_data = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv), + GFP_KERNEL); + if (!priv_data) + return -ENOMEM; + + afe_priv->dai_priv[dai->id] = priv_data; + 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_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 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_fmt = mtk_dai_etdm_set_fmt, +}; + +/* dai driver */ +#define MTK_ETDM_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_88200 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_176400 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_etdm_driver[] = { + { + .name = "ETDM", + .id = MT79XX_DAI_ETDM, + .capture = { + .stream_name = "ETDM Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .playback = { + .stream_name = "ETDM Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ETDM_RATES, + .formats = MTK_ETDM_FORMATS, + }, + .ops = &mtk_dai_etdm_ops, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, + }, +}; + +int mt79xx_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); + + return 0; +}
From: Maso Huang maso.huang@mediatek.com
Add support for mt79xx board with wm8960.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- sound/soc/mediatek/Kconfig | 10 ++ sound/soc/mediatek/mt79xx/Makefile | 1 + sound/soc/mediatek/mt79xx/mt79xx-wm8960.c | 185 ++++++++++++++++++++++ 3 files changed, 196 insertions(+) create mode 100644 sound/soc/mediatek/mt79xx/mt79xx-wm8960.c
diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 192546078d5e..bf641af72210 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -64,6 +64,16 @@ config SND_SOC_MT79XX Select Y if you have such device. If unsure select "N".
+config SND_SOC_MT79XX_WM8960 + tristate "ASoc Audio driver for MT79XX with WM8960 codec" + depends on SND_SOC_MT79XX && I2C + select SND_SOC_WM8960 + help + This adds support for ASoC machine driver for MediaTek MT79XX + boards with the WM8960 codecs. + Select Y if you have such device. + If unsure select "N". + config SND_SOC_MT8173 tristate "ASoC support for Mediatek MT8173 chip" depends on ARCH_MEDIATEK diff --git a/sound/soc/mediatek/mt79xx/Makefile b/sound/soc/mediatek/mt79xx/Makefile index 984b20ae8819..c910ee88d930 100644 --- a/sound/soc/mediatek/mt79xx/Makefile +++ b/sound/soc/mediatek/mt79xx/Makefile @@ -7,3 +7,4 @@ snd-soc-mt79xx-afe-objs := \ mt79xx-dai-etdm.o
obj-$(CONFIG_SND_SOC_MT79XX) += snd-soc-mt79xx-afe.o +obj-$(CONFIG_SND_SOC_MT79XX_WM8960) += mt79xx-wm8960.o diff --git a/sound/soc/mediatek/mt79xx/mt79xx-wm8960.c b/sound/soc/mediatek/mt79xx/mt79xx-wm8960.c new file mode 100644 index 000000000000..d1a01a2bb6ae --- /dev/null +++ b/sound/soc/mediatek/mt79xx/mt79xx-wm8960.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt79xx-wm8960.c -- MT79xx-WM8960 ALSA SoC machine driver + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Vic Wu vic.wu@mediatek.com + * Maso Huang maso.huang@mediatek.com + */ + +#include <linux/module.h> +#include <sound/soc.h> + +#include "mt79xx-afe-common.h" + +struct mt79xx_wm8960_priv { + struct device_node *platform_node; + struct device_node *codec_node; +}; + +static const struct snd_soc_dapm_widget mt79xx_wm8960_widgets[] = { + SND_SOC_DAPM_HP("Headphone", NULL), + SND_SOC_DAPM_MIC("AMIC", NULL), +}; + +static const struct snd_kcontrol_new mt79xx_wm8960_controls[] = { + SOC_DAPM_PIN_SWITCH("Headphone"), + SOC_DAPM_PIN_SWITCH("AMIC"), +}; + +SND_SOC_DAILINK_DEFS(playback, + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(capture, + DAILINK_COMP_ARRAY(COMP_CPU("UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(codec, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM")), + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static struct snd_soc_dai_link mt79xx_wm8960_dai_links[] = { + /* FE */ + { + .name = "wm8960-playback", + .stream_name = "wm8960-playback", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(playback), + }, + { + .name = "wm8960-capture", + .stream_name = "wm8960-capture", + .trigger = {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(capture), + }, + /* BE */ + { + .name = "wm8960-codec", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS | + SND_SOC_DAIFMT_GATED, + .dpcm_playback = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(codec), + }, +}; + +static struct snd_soc_card mt79xx_wm8960_card = { + .name = "mt79xx-wm8960", + .owner = THIS_MODULE, + .dai_link = mt79xx_wm8960_dai_links, + .num_links = ARRAY_SIZE(mt79xx_wm8960_dai_links), + .controls = mt79xx_wm8960_controls, + .num_controls = ARRAY_SIZE(mt79xx_wm8960_controls), + .dapm_widgets = mt79xx_wm8960_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt79xx_wm8960_widgets), +}; + +static int mt79xx_wm8960_machine_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &mt79xx_wm8960_card; + struct snd_soc_dai_link *dai_link; + struct mt79xx_wm8960_priv *priv; + int ret, i; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->platform_node = of_parse_phandle(pdev->dev.of_node, + "mediatek,platform", 0); + if (!priv->platform_node) { + dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + if (dai_link->platforms->name) + continue; + dai_link->platforms->of_node = priv->platform_node; + } + + card->dev = &pdev->dev; + + priv->codec_node = of_parse_phandle(pdev->dev.of_node, + "mediatek,audio-codec", 0); + if (!priv->codec_node) { + dev_err(&pdev->dev, + "Property 'audio-codec' missing or invalid\n"); + of_node_put(priv->platform_node); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + if (dai_link->codecs->name) + continue; + dai_link->codecs->of_node = priv->codec_node; + } + + ret = snd_soc_of_parse_audio_routing(card, "audio-routing"); + if (ret) { + dev_err(&pdev->dev, "failed to parse audio-routing: %d\n", ret); + goto err_of_node_put; + } + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", + __func__, ret); + goto err_of_node_put; + } + +err_of_node_put: + of_node_put(priv->codec_node); + of_node_put(priv->platform_node); + return ret; +} + +static int mt79xx_wm8960_machine_remove(struct platform_device *pdev) +{ + struct snd_soc_card *card = platform_get_drvdata(pdev); + struct mt79xx_wm8960_priv *priv = snd_soc_card_get_drvdata(card); + + of_node_put(priv->codec_node); + of_node_put(priv->platform_node); + + return 0; +} + +#ifdef CONFIG_OF +static const struct of_device_id mt79xx_wm8960_machine_dt_match[] = { + {.compatible = "mediatek,mt79xx-wm8960-machine",}, + {} +}; +#endif + +static struct platform_driver mt79xx_wm8960_machine = { + .driver = { + .name = "mt79xx-wm8960", +#ifdef CONFIG_OF + .of_match_table = mt79xx_wm8960_machine_dt_match, +#endif + }, + .probe = mt79xx_wm8960_machine_probe, + .remove = mt79xx_wm8960_machine_remove, +}; + +module_platform_driver(mt79xx_wm8960_machine); + +/* Module information */ +MODULE_DESCRIPTION("MT79xx WM8960 ALSA SoC machine driver"); +MODULE_AUTHOR("Vic Wu vic.wu@mediatek.com"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("mt79xx wm8960 soc card");
From: Maso Huang maso.huang@mediatek.com
Add document for mt79xx board with wm8960.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- .../sound/mediatek,mt79xx-wm8960.yaml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml new file mode 100644 index 000000000000..26b38bb629da --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt79xx-wm8960.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT79xx ASOC sound card with WM8960 codec + +maintainers: + - Maso Huang maso.huang@mediatek.com + +properties: + compatible: + const: mediatek,mt79xx-wm8960-machine + + mediatek,platform: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of MT79xx ASoC platform. + + audio-routing: + $ref: /schemas/types.yaml#/definitions/non-unique-string-array + description: + A list of the connections between audio components. Each entry is a + sink/source pair of strings. Valid names could be the input or output + widgets of audio components, power supplies, MicBias of codec and the + software switch. + + mediatek,audio-codec: + $ref: /schemas/types.yaml#/definitions/phandle + description: The phandle of wm8960 codec. + +additionalProperties: false + +required: + - compatible + - mediatek,platform + - audio-routing + - mediatek,audio-codec + +examples: + - | + sound { + compatible = "mediatek,mt79xx-wm8960-machine"; + mediatek,platform = <&afe>; + audio-routing = + "Headphone", "HP_L", + "Headphone", "HP_R", + "LINPUT1", "AMIC", + "RINPUT1", "AMIC"; + mediatek,audio-codec = <&wm8960>; + }; + +...
On 12/06/2023 12:52, Maso Hunag wrote:
From: Maso Huang maso.huang@mediatek.com
Add document for mt79xx board with wm8960.
Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.
Signed-off-by: Maso Huang maso.huang@mediatek.com
.../sound/mediatek,mt79xx-wm8960.yaml | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml new file mode 100644 index 000000000000..26b38bb629da --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-wm8960.yaml @@ -0,0 +1,53 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt79xx-wm8960.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml#
+title: MediaTek MT79xx ASOC sound card with WM8960 codec
What is a MT79xx ASOC? Is it some specific SoC name? What does "A" stands for in SoC? XX also looks odd, I thought Mediatek uses only numbers.
+maintainers:
- Maso Huang maso.huang@mediatek.com
+properties:
- compatible:
- const: mediatek,mt79xx-wm8960-machine
- mediatek,platform:
- $ref: /schemas/types.yaml#/definitions/phandle
- description: The phandle of MT79xx ASoC platform.
What is MT79xx ASoC platform?
Best regards, Krzysztof
From: Maso Huang maso.huang@mediatek.com
Add mt79xx audio afe document.
Signed-off-by: Maso Huang maso.huang@mediatek.com --- .../bindings/sound/mediatek,mt79xx-afe.yaml | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml new file mode 100644 index 000000000000..11ef1cfdf49b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt79xx-afe.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek AFE PCM controller for MT79xx + +maintainers: + - Maso Huang maso.huang@mediatek.com + +properties: + compatible: + oneOf: + - const: mediatek,mt79xx-afe + - items: + - enum: + - mediatek,mt7981-afe + - mediatek,mt7986-afe + - mediatek,mt7988-afe + - const: mediatek,mt79xx-afe + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 5 + items: + - description: audio bus clock + - description: audio 26M clock + - description: audio intbus clock + - description: audio hopping clock + - description: audio pll clock + - description: mux for pcm_mck + - description: audio i2s/pcm mck + + clock-names: + minItems: 5 + items: + - const: aud_bus_ck + - const: aud_26m_ck + - const: aud_l_ck + - const: aud_aud_ck + - const: aud_eg2_ck + - const: aud_sel + - const: aud_i2s_m + + assigned-clocks: + minItems: 3 + maxItems: 4 + + assigned-clock-parents: + minItems: 3 + maxItems: 4 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - assigned-clocks + - assigned-clock-parents + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/clock/mediatek,mt7981-clk.h> + + afe@11210000 { + compatible = "mediatek,mt7981-afe","mediatek,mt79xx-afe"; + reg = <0x11210000 0x9000>; + interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&infracfg_ao CLK_INFRA_AUD_BUS_CK>, + <&infracfg_ao CLK_INFRA_AUD_26M_CK>, + <&infracfg_ao CLK_INFRA_AUD_L_CK>, + <&infracfg_ao CLK_INFRA_AUD_AUD_CK>, + <&infracfg_ao CLK_INFRA_AUD_EG2_CK>, + <&topckgen CLK_TOP_AUD_SEL>; + clock-names = "aud_bus_ck", + "aud_26m_ck", + "aud_l_ck", + "aud_aud_ck", + "aud_eg2_ck", + "aud_sel"; + assigned-clocks = <&topckgen CLK_TOP_AUD_SEL>, + <&topckgen CLK_TOP_A1SYS_SEL>, + <&topckgen CLK_TOP_AUD_L_SEL>, + <&topckgen CLK_TOP_A_TUNER_SEL>; + assigned-clock-parents = <&topckgen CLK_TOP_CB_APLL2_196M>, + <&topckgen CLK_TOP_APLL2_D4>, + <&topckgen CLK_TOP_CB_APLL2_196M>, + <&topckgen CLK_TOP_APLL2_D4>; + }; + +...
On 12/06/2023 12:52, Maso Hunag wrote:
From: Maso Huang maso.huang@mediatek.com
Add mt79xx audio afe document.
Please use scripts/get_maintainers.pl to get a list of necessary people and lists to CC. It might happen, that command when run on an older kernel, gives you outdated entries. Therefore please be sure you base your patches on recent Linux kernel.
Signed-off-by: Maso Huang maso.huang@mediatek.com
.../bindings/sound/mediatek,mt79xx-afe.yaml | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml
diff --git a/Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml new file mode 100644 index 000000000000..11ef1cfdf49b --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mediatek,mt79xx-afe.yaml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mediatek,mt79xx-afe.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml#
+title: MediaTek AFE PCM controller for MT79xx
79XX sounds weird. Are you sure you are not using wildcards (which are not allowed)?
+maintainers:
- Maso Huang maso.huang@mediatek.com
+properties:
- compatible:
- oneOf:
- const: mediatek,mt79xx-afe
- items:
- enum:
- mediatek,mt7981-afe
- mediatek,mt7986-afe
- mediatek,mt7988-afe
- const: mediatek,mt79xx-afe
I already saw AFE, why it cannot be part of existing bindings?
This list is odd. 79xx, 7981? So it is wildcard?
- reg:
- maxItems: 1
- interrupts:
- maxItems: 1
- clocks:
- minItems: 5
- items:
- description: audio bus clock
- description: audio 26M clock
- description: audio intbus clock
- description: audio hopping clock
- description: audio pll clock
- description: mux for pcm_mck
- description: audio i2s/pcm mck
- clock-names:
- minItems: 5
- items:
- const: aud_bus_ck
- const: aud_26m_ck
- const: aud_l_ck
- const: aud_aud_ck
- const: aud_eg2_ck
- const: aud_sel
- const: aud_i2s_m
Why this is variable?
- assigned-clocks:
- minItems: 3
- maxItems: 4
Drop assigned-clocks
- assigned-clock-parents:
- minItems: 3
- maxItems: 4
Drop
Best regards, Krzysztof
participants (5)
-
AngeloGioacchino Del Regno
-
Claudiu.Beznea@microchip.com
-
kernel test robot
-
Krzysztof Kozlowski
-
Maso Hunag