ASoC: mediatek: mt8192: add platform driver
This patch adds mt8192 platform and affiliated drivers. Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com> Link: https://lore.kernel.org/r/1604390378-23993-3-git-send-email-jiaxin.yu@mediatek.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
682c5a72a2
commit
125ab5d588
|
@ -158,3 +158,13 @@ config SND_SOC_MTK_BTCVSD
|
|||
BT encoded data to/from BT firmware.
|
||||
Select Y if you have such device.
|
||||
If unsure select "N".
|
||||
|
||||
config SND_SOC_MT8192
|
||||
tristate "ASoC support for Mediatek MT8192 chip"
|
||||
depends on ARCH_MEDIATEK
|
||||
select SND_SOC_MEDIATEK
|
||||
help
|
||||
This adds ASoC platform driver support for Mediatek MT8192 chip
|
||||
that can be used with other codecs.
|
||||
Select Y if you have such device.
|
||||
If unsure select "N".
|
||||
|
|
|
@ -4,3 +4,4 @@ obj-$(CONFIG_SND_SOC_MT2701) += mt2701/
|
|||
obj-$(CONFIG_SND_SOC_MT6797) += mt6797/
|
||||
obj-$(CONFIG_SND_SOC_MT8173) += mt8173/
|
||||
obj-$(CONFIG_SND_SOC_MT8183) += mt8183/
|
||||
obj-$(CONFIG_SND_SOC_MT8192) += mt8192/
|
||||
|
|
|
@ -542,8 +542,13 @@ int mtk_memif_set_format(struct mtk_base_afe *afe,
|
|||
break;
|
||||
case SNDRV_PCM_FORMAT_S32_LE:
|
||||
case SNDRV_PCM_FORMAT_U32_LE:
|
||||
hd_audio = 1;
|
||||
hd_align = 1;
|
||||
if (afe->memif_32bit_supported) {
|
||||
hd_audio = 2;
|
||||
hd_align = 0;
|
||||
} else {
|
||||
hd_audio = 1;
|
||||
hd_align = 1;
|
||||
}
|
||||
break;
|
||||
case SNDRV_PCM_FORMAT_S24_LE:
|
||||
case SNDRV_PCM_FORMAT_U24_LE:
|
||||
|
@ -556,10 +561,10 @@ int mtk_memif_set_format(struct mtk_base_afe *afe,
|
|||
}
|
||||
|
||||
mtk_regmap_update_bits(afe->regmap, memif->data->hd_reg,
|
||||
1, hd_audio, memif->data->hd_shift);
|
||||
0x3, hd_audio, memif->data->hd_shift);
|
||||
|
||||
mtk_regmap_update_bits(afe->regmap, memif->data->hd_align_reg,
|
||||
1, hd_align, memif->data->hd_align_mshift);
|
||||
0x1, hd_align, memif->data->hd_align_mshift);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ struct mtk_base_afe {
|
|||
int memif_size;
|
||||
struct mtk_base_afe_irq *irqs;
|
||||
int irqs_size;
|
||||
int memif_32bit_supported;
|
||||
|
||||
struct list_head sub_dais;
|
||||
struct snd_soc_dai_driver *dai_drivers;
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# platform driver
|
||||
snd-soc-mt8192-afe-objs := \
|
||||
mt8192-afe-pcm.o \
|
||||
mt8192-afe-clk.o \
|
||||
mt8192-afe-gpio.o \
|
||||
mt8192-dai-adda.o \
|
||||
mt8192-afe-control.o \
|
||||
mt8192-dai-i2s.o \
|
||||
mt8192-dai-pcm.o \
|
||||
mt8192-dai-tdm.o
|
||||
|
||||
obj-$(CONFIG_SND_SOC_MT8192) += snd-soc-mt8192-afe.o
|
|
@ -0,0 +1,669 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// mt8192-afe-clk.c -- Mediatek 8192 afe clock ctrl
|
||||
//
|
||||
// Copyright (c) 2020 MediaTek Inc.
|
||||
// Author: Shane Chien <shane.chien@mediatek.com>
|
||||
//
|
||||
|
||||
#include <linux/arm-smccc.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include "mt8192-afe-clk.h"
|
||||
#include "mt8192-afe-common.h"
|
||||
|
||||
static const char *aud_clks[CLK_NUM] = {
|
||||
[CLK_AFE] = "aud_afe_clk",
|
||||
[CLK_TML] = "aud_tml_clk",
|
||||
[CLK_APLL22M] = "aud_apll22m_clk",
|
||||
[CLK_APLL24M] = "aud_apll24m_clk",
|
||||
[CLK_APLL1_TUNER] = "aud_apll1_tuner_clk",
|
||||
[CLK_APLL2_TUNER] = "aud_apll2_tuner_clk",
|
||||
[CLK_NLE] = "aud_nle",
|
||||
[CLK_INFRA_SYS_AUDIO] = "aud_infra_clk",
|
||||
[CLK_INFRA_AUDIO_26M] = "aud_infra_26m_clk",
|
||||
[CLK_MUX_AUDIO] = "top_mux_audio",
|
||||
[CLK_MUX_AUDIOINTBUS] = "top_mux_audio_int",
|
||||
[CLK_TOP_MAINPLL_D4_D4] = "top_mainpll_d4_d4",
|
||||
[CLK_TOP_MUX_AUD_1] = "top_mux_aud_1",
|
||||
[CLK_TOP_APLL1_CK] = "top_apll1_ck",
|
||||
[CLK_TOP_MUX_AUD_2] = "top_mux_aud_2",
|
||||
[CLK_TOP_APLL2_CK] = "top_apll2_ck",
|
||||
[CLK_TOP_MUX_AUD_ENG1] = "top_mux_aud_eng1",
|
||||
[CLK_TOP_APLL1_D4] = "top_apll1_d4",
|
||||
[CLK_TOP_MUX_AUD_ENG2] = "top_mux_aud_eng2",
|
||||
[CLK_TOP_APLL2_D4] = "top_apll2_d4",
|
||||
[CLK_TOP_MUX_AUDIO_H] = "top_mux_audio_h",
|
||||
[CLK_TOP_I2S0_M_SEL] = "top_i2s0_m_sel",
|
||||
[CLK_TOP_I2S1_M_SEL] = "top_i2s1_m_sel",
|
||||
[CLK_TOP_I2S2_M_SEL] = "top_i2s2_m_sel",
|
||||
[CLK_TOP_I2S3_M_SEL] = "top_i2s3_m_sel",
|
||||
[CLK_TOP_I2S4_M_SEL] = "top_i2s4_m_sel",
|
||||
[CLK_TOP_I2S5_M_SEL] = "top_i2s5_m_sel",
|
||||
[CLK_TOP_I2S6_M_SEL] = "top_i2s6_m_sel",
|
||||
[CLK_TOP_I2S7_M_SEL] = "top_i2s7_m_sel",
|
||||
[CLK_TOP_I2S8_M_SEL] = "top_i2s8_m_sel",
|
||||
[CLK_TOP_I2S9_M_SEL] = "top_i2s9_m_sel",
|
||||
[CLK_TOP_APLL12_DIV0] = "top_apll12_div0",
|
||||
[CLK_TOP_APLL12_DIV1] = "top_apll12_div1",
|
||||
[CLK_TOP_APLL12_DIV2] = "top_apll12_div2",
|
||||
[CLK_TOP_APLL12_DIV3] = "top_apll12_div3",
|
||||
[CLK_TOP_APLL12_DIV4] = "top_apll12_div4",
|
||||
[CLK_TOP_APLL12_DIVB] = "top_apll12_divb",
|
||||
[CLK_TOP_APLL12_DIV5] = "top_apll12_div5",
|
||||
[CLK_TOP_APLL12_DIV6] = "top_apll12_div6",
|
||||
[CLK_TOP_APLL12_DIV7] = "top_apll12_div7",
|
||||
[CLK_TOP_APLL12_DIV8] = "top_apll12_div8",
|
||||
[CLK_TOP_APLL12_DIV9] = "top_apll12_div9",
|
||||
[CLK_CLK26M] = "top_clk26m_clk",
|
||||
};
|
||||
|
||||
int mt8192_set_audio_int_bus_parent(struct mtk_base_afe *afe,
|
||||
int clk_id)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int ret;
|
||||
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIOINTBUS],
|
||||
afe_priv->clk[clk_id]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_MUX_AUDIOINTBUS],
|
||||
aud_clks[clk_id], ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int apll1_mux_setting(struct mtk_base_afe *afe, bool enable)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_1], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
|
||||
afe_priv->clk[CLK_TOP_APLL1_CK]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_1],
|
||||
aud_clks[CLK_TOP_APLL1_CK], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
/* 180.6336 / 4 = 45.1584MHz */
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_ENG1], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
|
||||
afe_priv->clk[CLK_TOP_APLL1_D4]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],
|
||||
aud_clks[CLK_TOP_APLL1_D4], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
} else {
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1],
|
||||
afe_priv->clk[CLK_CLK26M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_ENG1],
|
||||
aud_clks[CLK_CLK26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG1]);
|
||||
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_1],
|
||||
afe_priv->clk[CLK_CLK26M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_1],
|
||||
aud_clks[CLK_CLK26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_1]);
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int apll2_mux_setting(struct mtk_base_afe *afe, bool enable)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int ret;
|
||||
|
||||
if (enable) {
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_2], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
|
||||
afe_priv->clk[CLK_TOP_APLL2_CK]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_2],
|
||||
aud_clks[CLK_TOP_APLL2_CK], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
/* 196.608 / 4 = 49.152MHz */
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_ENG2], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
|
||||
afe_priv->clk[CLK_TOP_APLL2_D4]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],
|
||||
aud_clks[CLK_TOP_APLL2_D4], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
} else {
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2],
|
||||
afe_priv->clk[CLK_CLK26M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_ENG2],
|
||||
aud_clks[CLK_CLK26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_ENG2]);
|
||||
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUD_2],
|
||||
afe_priv->clk[CLK_CLK26M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUD_2],
|
||||
aud_clks[CLK_CLK26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_TOP_MUX_AUD_2]);
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mt8192_afe_enable_clock(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int ret;
|
||||
|
||||
dev_info(afe->dev, "%s()\n", __func__);
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_INFRA_SYS_AUDIO], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_INFRA_AUDIO_26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIO]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_MUX_AUDIO], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_MUX_AUDIO],
|
||||
afe_priv->clk[CLK_CLK26M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_MUX_AUDIO],
|
||||
aud_clks[CLK_CLK26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_MUX_AUDIOINTBUS], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = mt8192_set_audio_int_bus_parent(afe, CLK_CLK26M);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_MUX_AUDIOINTBUS],
|
||||
aud_clks[CLK_CLK26M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_set_parent(afe_priv->clk[CLK_TOP_MUX_AUDIO_H],
|
||||
afe_priv->clk[CLK_TOP_APLL2_CK]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[CLK_TOP_MUX_AUDIO_H],
|
||||
aud_clks[CLK_TOP_APLL2_CK], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_AFE]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_AFE], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mt8192_afe_disable_clock(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
dev_info(afe->dev, "%s()\n", __func__);
|
||||
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_AFE]);
|
||||
mt8192_set_audio_int_bus_parent(afe, CLK_CLK26M);
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIOINTBUS]);
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_MUX_AUDIO]);
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_INFRA_AUDIO_26M]);
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_INFRA_SYS_AUDIO]);
|
||||
}
|
||||
|
||||
int mt8192_apll1_enable(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int ret;
|
||||
|
||||
/* setting for APLL */
|
||||
apll1_mux_setting(afe, true);
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_APLL22M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_APLL22M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_APLL1_TUNER]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_APLL1_TUNER], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG,
|
||||
0x0000FFF7, 0x00000832);
|
||||
regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x1);
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_22M_ON_MASK_SFT,
|
||||
0x1 << AFE_22M_ON_SFT);
|
||||
|
||||
EXIT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mt8192_apll1_disable(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_22M_ON_MASK_SFT,
|
||||
0x0 << AFE_22M_ON_SFT);
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_APLL1_TUNER_CFG, 0x1, 0x0);
|
||||
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_APLL1_TUNER]);
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_APLL22M]);
|
||||
|
||||
apll1_mux_setting(afe, false);
|
||||
}
|
||||
|
||||
int mt8192_apll2_enable(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int ret;
|
||||
|
||||
/* setting for APLL */
|
||||
apll2_mux_setting(afe, true);
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_APLL24M]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_APLL24M], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
ret = clk_prepare_enable(afe_priv->clk[CLK_APLL2_TUNER]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[CLK_APLL2_TUNER], ret);
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG,
|
||||
0x0000FFF7, 0x00000634);
|
||||
regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x1);
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_24M_ON_MASK_SFT,
|
||||
0x1 << AFE_24M_ON_SFT);
|
||||
|
||||
EXIT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mt8192_apll2_disable(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_HD_ENGEN_ENABLE,
|
||||
AFE_24M_ON_MASK_SFT,
|
||||
0x0 << AFE_24M_ON_SFT);
|
||||
|
||||
regmap_update_bits(afe->regmap, AFE_APLL2_TUNER_CFG, 0x1, 0x0);
|
||||
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_APLL2_TUNER]);
|
||||
clk_disable_unprepare(afe_priv->clk[CLK_APLL24M]);
|
||||
|
||||
apll2_mux_setting(afe, false);
|
||||
}
|
||||
|
||||
int mt8192_get_apll_rate(struct mtk_base_afe *afe, int apll)
|
||||
{
|
||||
return (apll == MT8192_APLL1) ? 180633600 : 196608000;
|
||||
}
|
||||
|
||||
int mt8192_get_apll_by_rate(struct mtk_base_afe *afe, int rate)
|
||||
{
|
||||
return ((rate % 8000) == 0) ? MT8192_APLL2 : MT8192_APLL1;
|
||||
}
|
||||
|
||||
int mt8192_get_apll_by_name(struct mtk_base_afe *afe, const char *name)
|
||||
{
|
||||
if (strcmp(name, APLL1_W_NAME) == 0)
|
||||
return MT8192_APLL1;
|
||||
else
|
||||
return MT8192_APLL2;
|
||||
}
|
||||
|
||||
/* mck */
|
||||
struct mt8192_mck_div {
|
||||
int m_sel_id;
|
||||
int div_clk_id;
|
||||
/* below will be deprecated */
|
||||
int div_pdn_reg;
|
||||
int div_pdn_mask_sft;
|
||||
int div_reg;
|
||||
int div_mask_sft;
|
||||
int div_mask;
|
||||
int div_sft;
|
||||
int div_apll_sel_reg;
|
||||
int div_apll_sel_mask_sft;
|
||||
int div_apll_sel_sft;
|
||||
};
|
||||
|
||||
static const struct mt8192_mck_div mck_div[MT8192_MCK_NUM] = {
|
||||
[MT8192_I2S0_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S0_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV0,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV0_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_2,
|
||||
.div_mask_sft = APLL12_CK_DIV0_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV0_MASK,
|
||||
.div_sft = APLL12_CK_DIV0_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S0_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S0_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S1_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S1_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV1,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV1_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_2,
|
||||
.div_mask_sft = APLL12_CK_DIV1_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV1_MASK,
|
||||
.div_sft = APLL12_CK_DIV1_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S1_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S1_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S2_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S2_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV2,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV2_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_2,
|
||||
.div_mask_sft = APLL12_CK_DIV2_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV2_MASK,
|
||||
.div_sft = APLL12_CK_DIV2_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S2_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S2_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S3_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S3_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV3,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV3_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_2,
|
||||
.div_mask_sft = APLL12_CK_DIV3_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV3_MASK,
|
||||
.div_sft = APLL12_CK_DIV3_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S3_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S3_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S4_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S4_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV4,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV4_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_3,
|
||||
.div_mask_sft = APLL12_CK_DIV4_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV4_MASK,
|
||||
.div_sft = APLL12_CK_DIV4_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S4_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S4_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S4_BCK] = {
|
||||
.m_sel_id = -1,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIVB,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIVB_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_2,
|
||||
.div_mask_sft = APLL12_CK_DIVB_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIVB_MASK,
|
||||
.div_sft = APLL12_CK_DIVB_SFT,
|
||||
},
|
||||
[MT8192_I2S5_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S5_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV5,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV5_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_3,
|
||||
.div_mask_sft = APLL12_CK_DIV5_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV5_MASK,
|
||||
.div_sft = APLL12_CK_DIV5_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S5_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S5_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S6_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S6_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV6,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV6_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_3,
|
||||
.div_mask_sft = APLL12_CK_DIV6_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV6_MASK,
|
||||
.div_sft = APLL12_CK_DIV6_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S6_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S6_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S7_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S7_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV7,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV7_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_4,
|
||||
.div_mask_sft = APLL12_CK_DIV7_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV7_MASK,
|
||||
.div_sft = APLL12_CK_DIV7_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S7_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S7_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S8_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S8_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV8,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV8_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_4,
|
||||
.div_mask_sft = APLL12_CK_DIV8_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV8_MASK,
|
||||
.div_sft = APLL12_CK_DIV8_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S8_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S8_MCK_SEL_SFT,
|
||||
},
|
||||
[MT8192_I2S9_MCK] = {
|
||||
.m_sel_id = CLK_TOP_I2S9_M_SEL,
|
||||
.div_clk_id = CLK_TOP_APLL12_DIV9,
|
||||
.div_pdn_reg = CLK_AUDDIV_0,
|
||||
.div_pdn_mask_sft = APLL12_DIV9_PDN_MASK_SFT,
|
||||
.div_reg = CLK_AUDDIV_4,
|
||||
.div_mask_sft = APLL12_CK_DIV9_MASK_SFT,
|
||||
.div_mask = APLL12_CK_DIV9_MASK,
|
||||
.div_sft = APLL12_CK_DIV9_SFT,
|
||||
.div_apll_sel_reg = CLK_AUDDIV_0,
|
||||
.div_apll_sel_mask_sft = APLL_I2S9_MCK_SEL_MASK_SFT,
|
||||
.div_apll_sel_sft = APLL_I2S9_MCK_SEL_SFT,
|
||||
},
|
||||
};
|
||||
|
||||
int mt8192_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int apll = mt8192_get_apll_by_rate(afe, rate);
|
||||
int apll_clk_id = apll == MT8192_APLL1 ?
|
||||
CLK_TOP_MUX_AUD_1 : CLK_TOP_MUX_AUD_2;
|
||||
int m_sel_id = mck_div[mck_id].m_sel_id;
|
||||
int div_clk_id = mck_div[mck_id].div_clk_id;
|
||||
int ret;
|
||||
|
||||
/* select apll */
|
||||
if (m_sel_id >= 0) {
|
||||
ret = clk_prepare_enable(afe_priv->clk[m_sel_id]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[m_sel_id], ret);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_set_parent(afe_priv->clk[m_sel_id],
|
||||
afe_priv->clk[apll_clk_id]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s(), clk_set_parent %s-%s fail %d\n",
|
||||
__func__, aud_clks[m_sel_id],
|
||||
aud_clks[apll_clk_id], ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* enable div, set rate */
|
||||
ret = clk_prepare_enable(afe_priv->clk[div_clk_id]);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s(), clk_prepare_enable %s fail %d\n",
|
||||
__func__, aud_clks[div_clk_id], ret);
|
||||
return ret;
|
||||
}
|
||||
ret = clk_set_rate(afe_priv->clk[div_clk_id], rate);
|
||||
if (ret) {
|
||||
dev_err(afe->dev, "%s(), clk_set_rate %s, rate %d, fail %d\n",
|
||||
__func__, aud_clks[div_clk_id],
|
||||
rate, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mt8192_mck_disable(struct mtk_base_afe *afe, int mck_id)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
int m_sel_id = mck_div[mck_id].m_sel_id;
|
||||
int div_clk_id = mck_div[mck_id].div_clk_id;
|
||||
|
||||
clk_disable_unprepare(afe_priv->clk[div_clk_id]);
|
||||
if (m_sel_id >= 0)
|
||||
clk_disable_unprepare(afe_priv->clk[m_sel_id]);
|
||||
}
|
||||
|
||||
int mt8192_init_clock(struct mtk_base_afe *afe)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
struct device_node *of_node = afe->dev->of_node;
|
||||
int i = 0;
|
||||
|
||||
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_warn(afe->dev, "%s devm_clk_get %s fail, ret %ld\n",
|
||||
__func__,
|
||||
aud_clks[i], PTR_ERR(afe_priv->clk[i]));
|
||||
afe_priv->clk[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
afe_priv->apmixedsys = syscon_regmap_lookup_by_phandle(of_node,
|
||||
"mediatek,apmixedsys");
|
||||
if (IS_ERR(afe_priv->apmixedsys)) {
|
||||
dev_err(afe->dev, "%s() Cannot find apmixedsys controller: %ld\n",
|
||||
__func__, PTR_ERR(afe_priv->apmixedsys));
|
||||
return PTR_ERR(afe_priv->apmixedsys);
|
||||
}
|
||||
|
||||
afe_priv->topckgen = syscon_regmap_lookup_by_phandle(of_node,
|
||||
"mediatek,topckgen");
|
||||
if (IS_ERR(afe_priv->topckgen)) {
|
||||
dev_err(afe->dev, "%s() Cannot find topckgen controller: %ld\n",
|
||||
__func__, PTR_ERR(afe_priv->topckgen));
|
||||
return PTR_ERR(afe_priv->topckgen);
|
||||
}
|
||||
|
||||
afe_priv->infracfg = syscon_regmap_lookup_by_phandle(of_node,
|
||||
"mediatek,infracfg");
|
||||
if (IS_ERR(afe_priv->infracfg)) {
|
||||
dev_err(afe->dev, "%s() Cannot find infracfg: %ld\n",
|
||||
__func__, PTR_ERR(afe_priv->infracfg));
|
||||
return PTR_ERR(afe_priv->infracfg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,244 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* mt8192-afe-clk.h -- Mediatek 8192 afe clock ctrl definition
|
||||
*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Shane Chien <shane.chien@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT8192_AFE_CLOCK_CTRL_H_
|
||||
#define _MT8192_AFE_CLOCK_CTRL_H_
|
||||
|
||||
#define AP_PLL_CON3 0x0014
|
||||
#define APLL1_CON0 0x0318
|
||||
#define APLL1_CON1 0x031c
|
||||
#define APLL1_CON2 0x0320
|
||||
#define APLL1_CON4 0x0328
|
||||
#define APLL1_TUNER_CON0 0x0040
|
||||
|
||||
#define APLL2_CON0 0x032c
|
||||
#define APLL2_CON1 0x0330
|
||||
#define APLL2_CON2 0x0334
|
||||
#define APLL2_CON4 0x033c
|
||||
#define APLL2_TUNER_CON0 0x0044
|
||||
|
||||
#define CLK_CFG_7 0x0080
|
||||
#define CLK_CFG_8 0x0090
|
||||
#define CLK_CFG_11 0x00c0
|
||||
#define CLK_CFG_12 0x00d0
|
||||
#define CLK_CFG_13 0x00e0
|
||||
#define CLK_CFG_15 0x0100
|
||||
|
||||
#define CLK_AUDDIV_0 0x0320
|
||||
#define CLK_AUDDIV_2 0x0328
|
||||
#define CLK_AUDDIV_3 0x0334
|
||||
#define CLK_AUDDIV_4 0x0338
|
||||
#define CKSYS_AUD_TOP_CFG 0x032c
|
||||
#define CKSYS_AUD_TOP_MON 0x0330
|
||||
|
||||
#define PERI_BUS_DCM_CTRL 0x0074
|
||||
#define MODULE_SW_CG_1_STA 0x0094
|
||||
#define MODULE_SW_CG_2_STA 0x00ac
|
||||
|
||||
/* CLK_AUDDIV_0 */
|
||||
#define APLL12_DIV0_PDN_SFT 0
|
||||
#define APLL12_DIV0_PDN_MASK 0x1
|
||||
#define APLL12_DIV0_PDN_MASK_SFT (0x1 << 0)
|
||||
#define APLL12_DIV1_PDN_SFT 1
|
||||
#define APLL12_DIV1_PDN_MASK 0x1
|
||||
#define APLL12_DIV1_PDN_MASK_SFT (0x1 << 1)
|
||||
#define APLL12_DIV2_PDN_SFT 2
|
||||
#define APLL12_DIV2_PDN_MASK 0x1
|
||||
#define APLL12_DIV2_PDN_MASK_SFT (0x1 << 2)
|
||||
#define APLL12_DIV3_PDN_SFT 3
|
||||
#define APLL12_DIV3_PDN_MASK 0x1
|
||||
#define APLL12_DIV3_PDN_MASK_SFT (0x1 << 3)
|
||||
#define APLL12_DIV4_PDN_SFT 4
|
||||
#define APLL12_DIV4_PDN_MASK 0x1
|
||||
#define APLL12_DIV4_PDN_MASK_SFT (0x1 << 4)
|
||||
#define APLL12_DIVB_PDN_SFT 5
|
||||
#define APLL12_DIVB_PDN_MASK 0x1
|
||||
#define APLL12_DIVB_PDN_MASK_SFT (0x1 << 5)
|
||||
#define APLL12_DIV5_PDN_SFT 6
|
||||
#define APLL12_DIV5_PDN_MASK 0x1
|
||||
#define APLL12_DIV5_PDN_MASK_SFT (0x1 << 6)
|
||||
#define APLL12_DIV6_PDN_SFT 7
|
||||
#define APLL12_DIV6_PDN_MASK 0x1
|
||||
#define APLL12_DIV6_PDN_MASK_SFT (0x1 << 7)
|
||||
#define APLL12_DIV7_PDN_SFT 8
|
||||
#define APLL12_DIV7_PDN_MASK 0x1
|
||||
#define APLL12_DIV7_PDN_MASK_SFT (0x1 << 8)
|
||||
#define APLL12_DIV8_PDN_SFT 9
|
||||
#define APLL12_DIV8_PDN_MASK 0x1
|
||||
#define APLL12_DIV8_PDN_MASK_SFT (0x1 << 9)
|
||||
#define APLL12_DIV9_PDN_SFT 10
|
||||
#define APLL12_DIV9_PDN_MASK 0x1
|
||||
#define APLL12_DIV9_PDN_MASK_SFT (0x1 << 10)
|
||||
#define APLL_I2S0_MCK_SEL_SFT 16
|
||||
#define APLL_I2S0_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S0_MCK_SEL_MASK_SFT (0x1 << 16)
|
||||
#define APLL_I2S1_MCK_SEL_SFT 17
|
||||
#define APLL_I2S1_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S1_MCK_SEL_MASK_SFT (0x1 << 17)
|
||||
#define APLL_I2S2_MCK_SEL_SFT 18
|
||||
#define APLL_I2S2_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S2_MCK_SEL_MASK_SFT (0x1 << 18)
|
||||
#define APLL_I2S3_MCK_SEL_SFT 19
|
||||
#define APLL_I2S3_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S3_MCK_SEL_MASK_SFT (0x1 << 19)
|
||||
#define APLL_I2S4_MCK_SEL_SFT 20
|
||||
#define APLL_I2S4_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S4_MCK_SEL_MASK_SFT (0x1 << 20)
|
||||
#define APLL_I2S5_MCK_SEL_SFT 21
|
||||
#define APLL_I2S5_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S5_MCK_SEL_MASK_SFT (0x1 << 21)
|
||||
#define APLL_I2S6_MCK_SEL_SFT 22
|
||||
#define APLL_I2S6_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S6_MCK_SEL_MASK_SFT (0x1 << 22)
|
||||
#define APLL_I2S7_MCK_SEL_SFT 23
|
||||
#define APLL_I2S7_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S7_MCK_SEL_MASK_SFT (0x1 << 23)
|
||||
#define APLL_I2S8_MCK_SEL_SFT 24
|
||||
#define APLL_I2S8_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S8_MCK_SEL_MASK_SFT (0x1 << 24)
|
||||
#define APLL_I2S9_MCK_SEL_SFT 25
|
||||
#define APLL_I2S9_MCK_SEL_MASK 0x1
|
||||
#define APLL_I2S9_MCK_SEL_MASK_SFT (0x1 << 25)
|
||||
|
||||
/* CLK_AUDDIV_2 */
|
||||
#define APLL12_CK_DIV0_SFT 0
|
||||
#define APLL12_CK_DIV0_MASK 0xff
|
||||
#define APLL12_CK_DIV0_MASK_SFT (0xff << 0)
|
||||
#define APLL12_CK_DIV1_SFT 8
|
||||
#define APLL12_CK_DIV1_MASK 0xff
|
||||
#define APLL12_CK_DIV1_MASK_SFT (0xff << 8)
|
||||
#define APLL12_CK_DIV2_SFT 16
|
||||
#define APLL12_CK_DIV2_MASK 0xff
|
||||
#define APLL12_CK_DIV2_MASK_SFT (0xff << 16)
|
||||
#define APLL12_CK_DIV3_SFT 24
|
||||
#define APLL12_CK_DIV3_MASK 0xff
|
||||
#define APLL12_CK_DIV3_MASK_SFT (0xff << 24)
|
||||
|
||||
/* CLK_AUDDIV_3 */
|
||||
#define APLL12_CK_DIV4_SFT 0
|
||||
#define APLL12_CK_DIV4_MASK 0xff
|
||||
#define APLL12_CK_DIV4_MASK_SFT (0xff << 0)
|
||||
#define APLL12_CK_DIVB_SFT 8
|
||||
#define APLL12_CK_DIVB_MASK 0xff
|
||||
#define APLL12_CK_DIVB_MASK_SFT (0xff << 8)
|
||||
#define APLL12_CK_DIV5_SFT 16
|
||||
#define APLL12_CK_DIV5_MASK 0xff
|
||||
#define APLL12_CK_DIV5_MASK_SFT (0xff << 16)
|
||||
#define APLL12_CK_DIV6_SFT 24
|
||||
#define APLL12_CK_DIV6_MASK 0xff
|
||||
#define APLL12_CK_DIV6_MASK_SFT (0xff << 24)
|
||||
|
||||
/* CLK_AUDDIV_4 */
|
||||
#define APLL12_CK_DIV7_SFT 0
|
||||
#define APLL12_CK_DIV7_MASK 0xff
|
||||
#define APLL12_CK_DIV7_MASK_SFT (0xff << 0)
|
||||
#define APLL12_CK_DIV8_SFT 8
|
||||
#define APLL12_CK_DIV8_MASK 0xff
|
||||
#define APLL12_CK_DIV8_MASK_SFT (0xff << 0)
|
||||
#define APLL12_CK_DIV9_SFT 16
|
||||
#define APLL12_CK_DIV9_MASK 0xff
|
||||
#define APLL12_CK_DIV9_MASK_SFT (0xff << 0)
|
||||
|
||||
/* AUD_TOP_CFG */
|
||||
#define AUD_TOP_CFG_SFT 0
|
||||
#define AUD_TOP_CFG_MASK 0xffffffff
|
||||
#define AUD_TOP_CFG_MASK_SFT (0xffffffff << 0)
|
||||
|
||||
/* AUD_TOP_MON */
|
||||
#define AUD_TOP_MON_SFT 0
|
||||
#define AUD_TOP_MON_MASK 0xffffffff
|
||||
#define AUD_TOP_MON_MASK_SFT (0xffffffff << 0)
|
||||
|
||||
/* CLK_AUDDIV_3 */
|
||||
#define APLL12_CK_DIV5_MSB_SFT 0
|
||||
#define APLL12_CK_DIV5_MSB_MASK 0xf
|
||||
#define APLL12_CK_DIV5_MSB_MASK_SFT (0xf << 0)
|
||||
#define RESERVED0_SFT 4
|
||||
#define RESERVED0_MASK 0xfffffff
|
||||
#define RESERVED0_MASK_SFT (0xfffffff << 4)
|
||||
|
||||
/* APLL */
|
||||
#define APLL1_W_NAME "APLL1"
|
||||
#define APLL2_W_NAME "APLL2"
|
||||
enum {
|
||||
MT8192_APLL1 = 0,
|
||||
MT8192_APLL2,
|
||||
};
|
||||
|
||||
enum {
|
||||
CLK_AFE = 0,
|
||||
CLK_TML,
|
||||
CLK_APLL22M,
|
||||
CLK_APLL24M,
|
||||
CLK_APLL1_TUNER,
|
||||
CLK_APLL2_TUNER,
|
||||
CLK_NLE,
|
||||
CLK_INFRA_SYS_AUDIO,
|
||||
CLK_INFRA_AUDIO_26M,
|
||||
CLK_MUX_AUDIO,
|
||||
CLK_MUX_AUDIOINTBUS,
|
||||
CLK_TOP_MAINPLL_D4_D4,
|
||||
/* apll related mux */
|
||||
CLK_TOP_MUX_AUD_1,
|
||||
CLK_TOP_APLL1_CK,
|
||||
CLK_TOP_MUX_AUD_2,
|
||||
CLK_TOP_APLL2_CK,
|
||||
CLK_TOP_MUX_AUD_ENG1,
|
||||
CLK_TOP_APLL1_D4,
|
||||
CLK_TOP_MUX_AUD_ENG2,
|
||||
CLK_TOP_APLL2_D4,
|
||||
CLK_TOP_MUX_AUDIO_H,
|
||||
CLK_TOP_I2S0_M_SEL,
|
||||
CLK_TOP_I2S1_M_SEL,
|
||||
CLK_TOP_I2S2_M_SEL,
|
||||
CLK_TOP_I2S3_M_SEL,
|
||||
CLK_TOP_I2S4_M_SEL,
|
||||
CLK_TOP_I2S5_M_SEL,
|
||||
CLK_TOP_I2S6_M_SEL,
|
||||
CLK_TOP_I2S7_M_SEL,
|
||||
CLK_TOP_I2S8_M_SEL,
|
||||
CLK_TOP_I2S9_M_SEL,
|
||||
CLK_TOP_APLL12_DIV0,
|
||||
CLK_TOP_APLL12_DIV1,
|
||||
CLK_TOP_APLL12_DIV2,
|
||||
CLK_TOP_APLL12_DIV3,
|
||||
CLK_TOP_APLL12_DIV4,
|
||||
CLK_TOP_APLL12_DIVB,
|
||||
CLK_TOP_APLL12_DIV5,
|
||||
CLK_TOP_APLL12_DIV6,
|
||||
CLK_TOP_APLL12_DIV7,
|
||||
CLK_TOP_APLL12_DIV8,
|
||||
CLK_TOP_APLL12_DIV9,
|
||||
CLK_CLK26M,
|
||||
CLK_NUM
|
||||
};
|
||||
|
||||
struct mtk_base_afe;
|
||||
|
||||
int mt8192_init_clock(struct mtk_base_afe *afe);
|
||||
int mt8192_afe_enable_clock(struct mtk_base_afe *afe);
|
||||
void mt8192_afe_disable_clock(struct mtk_base_afe *afe);
|
||||
|
||||
int mt8192_apll1_enable(struct mtk_base_afe *afe);
|
||||
void mt8192_apll1_disable(struct mtk_base_afe *afe);
|
||||
|
||||
int mt8192_apll2_enable(struct mtk_base_afe *afe);
|
||||
void mt8192_apll2_disable(struct mtk_base_afe *afe);
|
||||
|
||||
int mt8192_get_apll_rate(struct mtk_base_afe *afe, int apll);
|
||||
int mt8192_get_apll_by_rate(struct mtk_base_afe *afe, int rate);
|
||||
int mt8192_get_apll_by_name(struct mtk_base_afe *afe, const char *name);
|
||||
|
||||
/* these will be replaced by using CCF */
|
||||
int mt8192_mck_enable(struct mtk_base_afe *afe, int mck_id, int rate);
|
||||
void mt8192_mck_disable(struct mtk_base_afe *afe, int mck_id);
|
||||
|
||||
int mt8192_set_audio_int_bus_parent(struct mtk_base_afe *afe,
|
||||
int clk_id);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,170 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* mt8192-afe-common.h -- Mediatek 8192 audio driver definitions
|
||||
*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Shane Chien <shane.chien@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT_8192_AFE_COMMON_H_
|
||||
#define _MT_8192_AFE_COMMON_H_
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <sound/soc.h>
|
||||
|
||||
#include "../common/mtk-base-afe.h"
|
||||
#include "mt8192-reg.h"
|
||||
|
||||
enum {
|
||||
MT8192_MEMIF_DL1,
|
||||
MT8192_MEMIF_DL12,
|
||||
MT8192_MEMIF_DL2,
|
||||
MT8192_MEMIF_DL3,
|
||||
MT8192_MEMIF_DL4,
|
||||
MT8192_MEMIF_DL5,
|
||||
MT8192_MEMIF_DL6,
|
||||
MT8192_MEMIF_DL7,
|
||||
MT8192_MEMIF_DL8,
|
||||
MT8192_MEMIF_DL9,
|
||||
MT8192_MEMIF_DAI,
|
||||
MT8192_MEMIF_DAI2,
|
||||
MT8192_MEMIF_MOD_DAI,
|
||||
MT8192_MEMIF_VUL12,
|
||||
MT8192_MEMIF_VUL2,
|
||||
MT8192_MEMIF_VUL3,
|
||||
MT8192_MEMIF_VUL4,
|
||||
MT8192_MEMIF_VUL5,
|
||||
MT8192_MEMIF_VUL6,
|
||||
MT8192_MEMIF_AWB,
|
||||
MT8192_MEMIF_AWB2,
|
||||
MT8192_MEMIF_HDMI,
|
||||
MT8192_MEMIF_NUM,
|
||||
MT8192_DAI_ADDA = MT8192_MEMIF_NUM,
|
||||
MT8192_DAI_ADDA_CH34,
|
||||
MT8192_DAI_AP_DMIC,
|
||||
MT8192_DAI_AP_DMIC_CH34,
|
||||
MT8192_DAI_VOW,
|
||||
MT8192_DAI_CONNSYS_I2S,
|
||||
MT8192_DAI_I2S_0,
|
||||
MT8192_DAI_I2S_1,
|
||||
MT8192_DAI_I2S_2,
|
||||
MT8192_DAI_I2S_3,
|
||||
MT8192_DAI_I2S_5,
|
||||
MT8192_DAI_I2S_6,
|
||||
MT8192_DAI_I2S_7,
|
||||
MT8192_DAI_I2S_8,
|
||||
MT8192_DAI_I2S_9,
|
||||
MT8192_DAI_HW_GAIN_1,
|
||||
MT8192_DAI_HW_GAIN_2,
|
||||
MT8192_DAI_SRC_1,
|
||||
MT8192_DAI_SRC_2,
|
||||
MT8192_DAI_PCM_1,
|
||||
MT8192_DAI_PCM_2,
|
||||
MT8192_DAI_TDM,
|
||||
MT8192_DAI_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
MT8192_IRQ_0,
|
||||
MT8192_IRQ_1,
|
||||
MT8192_IRQ_2,
|
||||
MT8192_IRQ_3,
|
||||
MT8192_IRQ_4,
|
||||
MT8192_IRQ_5,
|
||||
MT8192_IRQ_6,
|
||||
MT8192_IRQ_7,
|
||||
MT8192_IRQ_8,
|
||||
MT8192_IRQ_9,
|
||||
MT8192_IRQ_10,
|
||||
MT8192_IRQ_11,
|
||||
MT8192_IRQ_12,
|
||||
MT8192_IRQ_13,
|
||||
MT8192_IRQ_14,
|
||||
MT8192_IRQ_15,
|
||||
MT8192_IRQ_16,
|
||||
MT8192_IRQ_17,
|
||||
MT8192_IRQ_18,
|
||||
MT8192_IRQ_19,
|
||||
MT8192_IRQ_20,
|
||||
MT8192_IRQ_21,
|
||||
MT8192_IRQ_22,
|
||||
MT8192_IRQ_23,
|
||||
MT8192_IRQ_24,
|
||||
MT8192_IRQ_25,
|
||||
MT8192_IRQ_26,
|
||||
MT8192_IRQ_31, /* used only for TDM */
|
||||
MT8192_IRQ_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
MTKAIF_PROTOCOL_1 = 0,
|
||||
MTKAIF_PROTOCOL_2,
|
||||
MTKAIF_PROTOCOL_2_CLK_P2,
|
||||
};
|
||||
|
||||
enum {
|
||||
MTK_AFE_ADDA_DL_GAIN_MUTE = 0,
|
||||
MTK_AFE_ADDA_DL_GAIN_NORMAL = 0xf74f,
|
||||
/* SA suggest apply -0.3db to audio/speech path */
|
||||
};
|
||||
|
||||
/* MCLK */
|
||||
enum {
|
||||
MT8192_I2S0_MCK = 0,
|
||||
MT8192_I2S1_MCK,
|
||||
MT8192_I2S2_MCK,
|
||||
MT8192_I2S3_MCK,
|
||||
MT8192_I2S4_MCK,
|
||||
MT8192_I2S4_BCK,
|
||||
MT8192_I2S5_MCK,
|
||||
MT8192_I2S6_MCK,
|
||||
MT8192_I2S7_MCK,
|
||||
MT8192_I2S8_MCK,
|
||||
MT8192_I2S9_MCK,
|
||||
MT8192_MCK_NUM,
|
||||
};
|
||||
|
||||
struct clk;
|
||||
|
||||
struct mt8192_afe_private {
|
||||
struct clk **clk;
|
||||
struct regmap *topckgen;
|
||||
struct regmap *apmixedsys;
|
||||
struct regmap *infracfg;
|
||||
int stf_positive_gain_db;
|
||||
int pm_runtime_bypass_reg_ctl;
|
||||
|
||||
/* dai */
|
||||
bool dai_on[MT8192_DAI_NUM];
|
||||
void *dai_priv[MT8192_DAI_NUM];
|
||||
|
||||
/* adda */
|
||||
int mtkaif_protocol;
|
||||
int mtkaif_chosen_phase[4];
|
||||
int mtkaif_phase_cycle[4];
|
||||
int mtkaif_calibration_num_phase;
|
||||
int mtkaif_dmic;
|
||||
int mtkaif_dmic_ch34;
|
||||
int mtkaif_adda6_only;
|
||||
|
||||
/* mck */
|
||||
int mck_rate[MT8192_MCK_NUM];
|
||||
};
|
||||
|
||||
int mt8192_dai_adda_register(struct mtk_base_afe *afe);
|
||||
int mt8192_dai_i2s_register(struct mtk_base_afe *afe);
|
||||
int mt8192_dai_hw_gain_register(struct mtk_base_afe *afe);
|
||||
int mt8192_dai_src_register(struct mtk_base_afe *afe);
|
||||
int mt8192_dai_pcm_register(struct mtk_base_afe *afe);
|
||||
int mt8192_dai_tdm_register(struct mtk_base_afe *afe);
|
||||
|
||||
unsigned int mt8192_general_rate_transform(struct device *dev,
|
||||
unsigned int rate);
|
||||
unsigned int mt8192_rate_transform(struct device *dev,
|
||||
unsigned int rate, int aud_blk);
|
||||
|
||||
int mt8192_dai_set_priv(struct mtk_base_afe *afe, int id,
|
||||
int priv_size, const void *priv_data);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,163 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// MediaTek ALSA SoC Audio Control
|
||||
//
|
||||
// Copyright (c) 2020 MediaTek Inc.
|
||||
// Author: Shane Chien <shane.chien@mediatek.com>
|
||||
//
|
||||
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include "mt8192-afe-common.h"
|
||||
|
||||
enum {
|
||||
MTK_AFE_RATE_8K = 0,
|
||||
MTK_AFE_RATE_11K = 1,
|
||||
MTK_AFE_RATE_12K = 2,
|
||||
MTK_AFE_RATE_384K = 3,
|
||||
MTK_AFE_RATE_16K = 4,
|
||||
MTK_AFE_RATE_22K = 5,
|
||||
MTK_AFE_RATE_24K = 6,
|
||||
MTK_AFE_RATE_352K = 7,
|
||||
MTK_AFE_RATE_32K = 8,
|
||||
MTK_AFE_RATE_44K = 9,
|
||||
MTK_AFE_RATE_48K = 10,
|
||||
MTK_AFE_RATE_88K = 11,
|
||||
MTK_AFE_RATE_96K = 12,
|
||||
MTK_AFE_RATE_176K = 13,
|
||||
MTK_AFE_RATE_192K = 14,
|
||||
MTK_AFE_RATE_260K = 15,
|
||||
};
|
||||
|
||||
enum {
|
||||
MTK_AFE_DAI_MEMIF_RATE_8K = 0,
|
||||
MTK_AFE_DAI_MEMIF_RATE_16K = 1,
|
||||
MTK_AFE_DAI_MEMIF_RATE_32K = 2,
|
||||
MTK_AFE_DAI_MEMIF_RATE_48K = 3,
|
||||
};
|
||||
|
||||
enum {
|
||||
MTK_AFE_PCM_RATE_8K = 0,
|
||||
MTK_AFE_PCM_RATE_16K = 1,
|
||||
MTK_AFE_PCM_RATE_32K = 2,
|
||||
MTK_AFE_PCM_RATE_48K = 3,
|
||||
};
|
||||
|
||||
unsigned int mt8192_general_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;
|
||||
case 260000:
|
||||
return MTK_AFE_RATE_260K;
|
||||
case 352800:
|
||||
return MTK_AFE_RATE_352K;
|
||||
case 384000:
|
||||
return MTK_AFE_RATE_384K;
|
||||
default:
|
||||
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
|
||||
__func__,
|
||||
rate, MTK_AFE_RATE_48K);
|
||||
return MTK_AFE_RATE_48K;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int dai_memif_rate_transform(struct device *dev,
|
||||
unsigned int rate)
|
||||
{
|
||||
switch (rate) {
|
||||
case 8000:
|
||||
return MTK_AFE_DAI_MEMIF_RATE_8K;
|
||||
case 16000:
|
||||
return MTK_AFE_DAI_MEMIF_RATE_16K;
|
||||
case 32000:
|
||||
return MTK_AFE_DAI_MEMIF_RATE_32K;
|
||||
case 48000:
|
||||
return MTK_AFE_DAI_MEMIF_RATE_48K;
|
||||
default:
|
||||
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
|
||||
__func__,
|
||||
rate, MTK_AFE_DAI_MEMIF_RATE_16K);
|
||||
return MTK_AFE_DAI_MEMIF_RATE_16K;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned int pcm_rate_transform(struct device *dev,
|
||||
unsigned int rate)
|
||||
{
|
||||
switch (rate) {
|
||||
case 8000:
|
||||
return MTK_AFE_PCM_RATE_8K;
|
||||
case 16000:
|
||||
return MTK_AFE_PCM_RATE_16K;
|
||||
case 32000:
|
||||
return MTK_AFE_PCM_RATE_32K;
|
||||
case 48000:
|
||||
return MTK_AFE_PCM_RATE_48K;
|
||||
default:
|
||||
dev_warn(dev, "%s(), rate %u invalid, use %d!!!\n",
|
||||
__func__,
|
||||
rate, MTK_AFE_PCM_RATE_32K);
|
||||
return MTK_AFE_PCM_RATE_32K;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int mt8192_rate_transform(struct device *dev,
|
||||
unsigned int rate, int aud_blk)
|
||||
{
|
||||
switch (aud_blk) {
|
||||
case MT8192_MEMIF_DAI:
|
||||
case MT8192_MEMIF_MOD_DAI:
|
||||
return dai_memif_rate_transform(dev, rate);
|
||||
case MT8192_DAI_PCM_1:
|
||||
case MT8192_DAI_PCM_2:
|
||||
return pcm_rate_transform(dev, rate);
|
||||
default:
|
||||
return mt8192_general_rate_transform(dev, rate);
|
||||
}
|
||||
}
|
||||
|
||||
int mt8192_dai_set_priv(struct mtk_base_afe *afe, int id,
|
||||
int priv_size, const void *priv_data)
|
||||
{
|
||||
struct mt8192_afe_private *afe_priv = afe->platform_priv;
|
||||
void *temp_data;
|
||||
|
||||
temp_data = devm_kzalloc(afe->dev,
|
||||
priv_size,
|
||||
GFP_KERNEL);
|
||||
if (!temp_data)
|
||||
return -ENOMEM;
|
||||
|
||||
if (priv_data)
|
||||
memcpy(temp_data, priv_data, priv_size);
|
||||
|
||||
afe_priv->dai_priv[id] = temp_data;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,306 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
//
|
||||
// mt8192-afe-gpio.c -- Mediatek 8192 afe gpio ctrl
|
||||
//
|
||||
// Copyright (c) 2020 MediaTek Inc.
|
||||
// Author: Shane Chien <shane.chien@mediatek.com>
|
||||
//
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
|
||||
#include "mt8192-afe-common.h"
|
||||
#include "mt8192-afe-gpio.h"
|
||||
|
||||
struct pinctrl *aud_pinctrl;
|
||||
|
||||
enum mt8192_afe_gpio {
|
||||
MT8192_AFE_GPIO_DAT_MISO_OFF,
|
||||
MT8192_AFE_GPIO_DAT_MISO_ON,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_OFF,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_ON,
|
||||
MT8192_AFE_GPIO_DAT_MISO_CH34_OFF,
|
||||
MT8192_AFE_GPIO_DAT_MISO_CH34_ON,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_CH34_ON,
|
||||
MT8192_AFE_GPIO_I2S0_OFF,
|
||||
MT8192_AFE_GPIO_I2S0_ON,
|
||||
MT8192_AFE_GPIO_I2S1_OFF,
|
||||
MT8192_AFE_GPIO_I2S1_ON,
|
||||
MT8192_AFE_GPIO_I2S2_OFF,
|
||||
MT8192_AFE_GPIO_I2S2_ON,
|
||||
MT8192_AFE_GPIO_I2S3_OFF,
|
||||
MT8192_AFE_GPIO_I2S3_ON,
|
||||
MT8192_AFE_GPIO_I2S5_OFF,
|
||||
MT8192_AFE_GPIO_I2S5_ON,
|
||||
MT8192_AFE_GPIO_I2S6_OFF,
|
||||
MT8192_AFE_GPIO_I2S6_ON,
|
||||
MT8192_AFE_GPIO_I2S7_OFF,
|
||||
MT8192_AFE_GPIO_I2S7_ON,
|
||||
MT8192_AFE_GPIO_I2S8_OFF,
|
||||
MT8192_AFE_GPIO_I2S8_ON,
|
||||
MT8192_AFE_GPIO_I2S9_OFF,
|
||||
MT8192_AFE_GPIO_I2S9_ON,
|
||||
MT8192_AFE_GPIO_VOW_DAT_OFF,
|
||||
MT8192_AFE_GPIO_VOW_DAT_ON,
|
||||
MT8192_AFE_GPIO_VOW_CLK_OFF,
|
||||
MT8192_AFE_GPIO_VOW_CLK_ON,
|
||||
MT8192_AFE_GPIO_CLK_MOSI_OFF,
|
||||
MT8192_AFE_GPIO_CLK_MOSI_ON,
|
||||
MT8192_AFE_GPIO_TDM_OFF,
|
||||
MT8192_AFE_GPIO_TDM_ON,
|
||||
MT8192_AFE_GPIO_GPIO_NUM
|
||||
};
|
||||
|
||||
struct audio_gpio_attr {
|
||||
const char *name;
|
||||
bool gpio_prepare;
|
||||
struct pinctrl_state *gpioctrl;
|
||||
};
|
||||
|
||||
static struct audio_gpio_attr aud_gpios[MT8192_AFE_GPIO_GPIO_NUM] = {
|
||||
[MT8192_AFE_GPIO_DAT_MISO_OFF] = {"aud_dat_miso_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MISO_ON] = {"aud_dat_miso_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MOSI_OFF] = {"aud_dat_mosi_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MOSI_ON] = {"aud_dat_mosi_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S0_OFF] = {"aud_gpio_i2s0_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S0_ON] = {"aud_gpio_i2s0_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S1_OFF] = {"aud_gpio_i2s1_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S1_ON] = {"aud_gpio_i2s1_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S2_OFF] = {"aud_gpio_i2s2_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S2_ON] = {"aud_gpio_i2s2_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S3_OFF] = {"aud_gpio_i2s3_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S3_ON] = {"aud_gpio_i2s3_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S5_OFF] = {"aud_gpio_i2s5_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S5_ON] = {"aud_gpio_i2s5_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S6_OFF] = {"aud_gpio_i2s6_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S6_ON] = {"aud_gpio_i2s6_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S7_OFF] = {"aud_gpio_i2s7_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S7_ON] = {"aud_gpio_i2s7_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S8_OFF] = {"aud_gpio_i2s8_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S8_ON] = {"aud_gpio_i2s8_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S9_OFF] = {"aud_gpio_i2s9_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_I2S9_ON] = {"aud_gpio_i2s9_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_TDM_OFF] = {"aud_gpio_tdm_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_TDM_ON] = {"aud_gpio_tdm_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_VOW_DAT_OFF] = {"vow_dat_miso_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_VOW_DAT_ON] = {"vow_dat_miso_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_VOW_CLK_OFF] = {"vow_clk_miso_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_VOW_CLK_ON] = {"vow_clk_miso_on", false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MISO_CH34_OFF] = {"aud_dat_miso_ch34_off",
|
||||
false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MISO_CH34_ON] = {"aud_dat_miso_ch34_on",
|
||||
false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF] = {"aud_dat_mosi_ch34_off",
|
||||
false, NULL},
|
||||
[MT8192_AFE_GPIO_DAT_MOSI_CH34_ON] = {"aud_dat_mosi_ch34_on",
|
||||
false, NULL},
|
||||
[MT8192_AFE_GPIO_CLK_MOSI_OFF] = {"aud_clk_mosi_off", false, NULL},
|
||||
[MT8192_AFE_GPIO_CLK_MOSI_ON] = {"aud_clk_mosi_on", false, NULL},
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(gpio_request_mutex);
|
||||
|
||||
static int mt8192_afe_gpio_select(struct device *dev,
|
||||
enum mt8192_afe_gpio type)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (type < 0 || type >= MT8192_AFE_GPIO_GPIO_NUM) {
|
||||
dev_err(dev, "%s(), error, invalid gpio type %d\n",
|
||||
__func__, type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!aud_gpios[type].gpio_prepare) {
|
||||
dev_warn(dev, "%s(), error, gpio type %d not prepared\n",
|
||||
__func__, type);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = pinctrl_select_state(aud_pinctrl,
|
||||
aud_gpios[type].gpioctrl);
|
||||
if (ret) {
|
||||
dev_dbg(dev, "%s(), error, can not set gpio type %d\n",
|
||||
__func__, type);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int mt8192_afe_gpio_init(struct device *dev)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
aud_pinctrl = devm_pinctrl_get(dev);
|
||||
if (IS_ERR(aud_pinctrl)) {
|
||||
ret = PTR_ERR(aud_pinctrl);
|
||||
dev_err(dev, "%s(), ret %d, cannot get aud_pinctrl!\n",
|
||||
__func__, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(aud_gpios); i++) {
|
||||
aud_gpios[i].gpioctrl = pinctrl_lookup_state(aud_pinctrl,
|
||||
aud_gpios[i].name);
|
||||
if (IS_ERR(aud_gpios[i].gpioctrl)) {
|
||||
ret = PTR_ERR(aud_gpios[i].gpioctrl);
|
||||
dev_dbg(dev, "%s(), pinctrl_lookup_state %s fail, ret %d\n",
|
||||
__func__, aud_gpios[i].name, ret);
|
||||
} else {
|
||||
aud_gpios[i].gpio_prepare = true;
|
||||
}
|
||||
}
|
||||
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_CLK_MOSI_ON);
|
||||
|
||||
/* gpio status init */
|
||||
mt8192_afe_gpio_request(dev, false, MT8192_DAI_ADDA, 0);
|
||||
mt8192_afe_gpio_request(dev, false, MT8192_DAI_ADDA, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mt8192_afe_gpio_adda_dl(struct device *dev, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_ON);
|
||||
} else {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
static int mt8192_afe_gpio_adda_ul(struct device *dev, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MISO_ON);
|
||||
} else {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MISO_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
static int mt8192_afe_gpio_adda_ch34_dl(struct device *dev, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_CH34_ON);
|
||||
} else {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MOSI_CH34_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
static int mt8192_afe_gpio_adda_ch34_ul(struct device *dev, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MISO_CH34_ON);
|
||||
} else {
|
||||
return mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_DAT_MISO_CH34_OFF);
|
||||
}
|
||||
}
|
||||
|
||||
int mt8192_afe_gpio_request(struct device *dev, bool enable,
|
||||
int dai, int uplink)
|
||||
{
|
||||
mutex_lock(&gpio_request_mutex);
|
||||
switch (dai) {
|
||||
case MT8192_DAI_ADDA:
|
||||
if (uplink)
|
||||
mt8192_afe_gpio_adda_ul(dev, enable);
|
||||
else
|
||||
mt8192_afe_gpio_adda_dl(dev, enable);
|
||||
break;
|
||||
case MT8192_DAI_ADDA_CH34:
|
||||
if (uplink)
|
||||
mt8192_afe_gpio_adda_ch34_ul(dev, enable);
|
||||
else
|
||||
mt8192_afe_gpio_adda_ch34_dl(dev, enable);
|
||||
break;
|
||||
case MT8192_DAI_I2S_0:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S0_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S0_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_1:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S1_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S1_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_2:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S2_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S2_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_3:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S3_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S3_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_5:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S5_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S5_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_6:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S6_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S6_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_7:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S7_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S7_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_8:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S8_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S8_OFF);
|
||||
break;
|
||||
case MT8192_DAI_I2S_9:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S9_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_I2S9_OFF);
|
||||
break;
|
||||
case MT8192_DAI_TDM:
|
||||
if (enable)
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_TDM_ON);
|
||||
else
|
||||
mt8192_afe_gpio_select(dev, MT8192_AFE_GPIO_TDM_OFF);
|
||||
break;
|
||||
case MT8192_DAI_VOW:
|
||||
if (enable) {
|
||||
mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_VOW_CLK_ON);
|
||||
mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_VOW_DAT_ON);
|
||||
} else {
|
||||
mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_VOW_CLK_OFF);
|
||||
mt8192_afe_gpio_select(dev,
|
||||
MT8192_AFE_GPIO_VOW_DAT_OFF);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
mutex_unlock(&gpio_request_mutex);
|
||||
dev_warn(dev, "%s(), invalid dai %d\n", __func__, dai);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_unlock(&gpio_request_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* mt8192-afe-gpio.h -- Mediatek 8192 afe gpio ctrl definition
|
||||
*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Shane Chien <shane.chien@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT8192_AFE_GPIO_H_
|
||||
#define _MT8192_AFE_GPIO_H_
|
||||
|
||||
struct device;
|
||||
|
||||
int mt8192_afe_gpio_init(struct device *dev);
|
||||
|
||||
int mt8192_afe_gpio_request(struct device *dev, bool enable,
|
||||
int dai, int uplink);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,65 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Mediatek MT8192 audio driver interconnection definition
|
||||
*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Author: Shane Chien <shane.chien@mediatek.com>
|
||||
*/
|
||||
|
||||
#ifndef _MT8192_INTERCONNECTION_H_
|
||||
#define _MT8192_INTERCONNECTION_H_
|
||||
|
||||
/* in port define */
|
||||
#define I_I2S0_CH1 0
|
||||
#define I_I2S0_CH2 1
|
||||
#define I_ADDA_UL_CH1 3
|
||||
#define I_ADDA_UL_CH2 4
|
||||
#define I_DL1_CH1 5
|
||||
#define I_DL1_CH2 6
|
||||
#define I_DL2_CH1 7
|
||||
#define I_DL2_CH2 8
|
||||
#define I_PCM_1_CAP_CH1 9
|
||||
#define I_GAIN1_OUT_CH1 10
|
||||
#define I_GAIN1_OUT_CH2 11
|
||||
#define I_GAIN2_OUT_CH1 12
|
||||
#define I_GAIN2_OUT_CH2 13
|
||||
#define I_PCM_2_CAP_CH1 14
|
||||
#define I_ADDA_UL_CH3 17
|
||||
#define I_ADDA_UL_CH4 18
|
||||
#define I_DL12_CH1 19
|
||||
#define I_DL12_CH2 20
|
||||
#define I_PCM_2_CAP_CH2 21
|
||||
#define I_PCM_1_CAP_CH2 22
|
||||
#define I_DL3_CH1 23
|
||||
#define I_DL3_CH2 24
|
||||
#define I_I2S2_CH1 25
|
||||
#define I_I2S2_CH2 26
|
||||
#define I_I2S2_CH3 27
|
||||
#define I_I2S2_CH4 28
|
||||
|
||||
/* in port define >= 32 */
|
||||
#define I_32_OFFSET 32
|
||||
#define I_CONNSYS_I2S_CH1 (34 - I_32_OFFSET)
|
||||
#define I_CONNSYS_I2S_CH2 (35 - I_32_OFFSET)
|
||||
#define I_SRC_1_OUT_CH1 (36 - I_32_OFFSET)
|
||||
#define I_SRC_1_OUT_CH2 (37 - I_32_OFFSET)
|
||||
#define I_SRC_2_OUT_CH1 (38 - I_32_OFFSET)
|
||||
#define I_SRC_2_OUT_CH2 (39 - I_32_OFFSET)
|
||||
#define I_DL4_CH1 (40 - I_32_OFFSET)
|
||||
#define I_DL4_CH2 (41 - I_32_OFFSET)
|
||||
#define I_DL5_CH1 (42 - I_32_OFFSET)
|
||||
#define I_DL5_CH2 (43 - I_32_OFFSET)
|
||||
#define I_DL6_CH1 (44 - I_32_OFFSET)
|
||||
#define I_DL6_CH2 (45 - I_32_OFFSET)
|
||||
#define I_DL7_CH1 (46 - I_32_OFFSET)
|
||||
#define I_DL7_CH2 (47 - I_32_OFFSET)
|
||||
#define I_DL8_CH1 (48 - I_32_OFFSET)
|
||||
#define I_DL8_CH2 (49 - I_32_OFFSET)
|
||||
#define I_DL9_CH1 (50 - I_32_OFFSET)
|
||||
#define I_DL9_CH2 (51 - I_32_OFFSET)
|
||||
#define I_I2S6_CH1 (52 - I_32_OFFSET)
|
||||
#define I_I2S6_CH2 (53 - I_32_OFFSET)
|
||||
#define I_I2S8_CH1 (54 - I_32_OFFSET)
|
||||
#define I_I2S8_CH2 (55 - I_32_OFFSET)
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue