From patchwork Wed May 10 03:55:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Wu X-Patchwork-Id: 680735 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39100C77B7C for ; Wed, 10 May 2023 03:56:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236044AbjEJD4n (ORCPT ); Tue, 9 May 2023 23:56:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53980 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235284AbjEJDzl (ORCPT ); Tue, 9 May 2023 23:55:41 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 82454271B; Tue, 9 May 2023 20:55:35 -0700 (PDT) X-UUID: 81325ef6eee611ed9cb5633481061a41-20230510 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=zTnxtp6hN8hNECyGyeAIWXn7uB5lZFLas1G7S96mRtQ=; b=FIotXXZKi5/G4W5oSbmmgO+dc0wGt2uJTd+YzSTW024E424+mOyxiv3agFJQrkBHPxQ6wJ/vi9+qntDTkl5cuw2BC0rwUr6CY3EvXUoDae72+U045hPkzET6f/tkuP8DV4neSRsT7s4JwwZ5hB5RzM2ZTmJD5uuVtMpOGZ1qNJQ=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.24, REQID:403d5798-bd0c-466a-acf3-65270ca59aa5, IP:0, U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:95,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:95 X-CID-INFO: VERSION:1.1.24, REQID:403d5798-bd0c-466a-acf3-65270ca59aa5, IP:0, URL :0,TC:0,Content:0,EDM:0,RT:0,SF:95,FILE:0,BULK:0,RULE:Spam_GS981B3D,ACTION :quarantine,TS:95 X-CID-META: VersionHash:178d4d4, CLOUDID:7b1d516b-2f20-4998-991c-3b78627e4938, B ulkID:2305101155320X735M76,BulkQuantity:0,Recheck:0,SF:38|29|28|17|19|48,T C:nil,Content:0,EDM:-3,IP:nil,URL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0 ,OSI:0,OSA:0,AV:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-UUID: 81325ef6eee611ed9cb5633481061a41-20230510 Received: from mtkmbs13n1.mediatek.inc [(172.21.101.193)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 475702234; Wed, 10 May 2023 11:55:29 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs11n2.mediatek.inc (172.21.101.187) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 10 May 2023 11:55:28 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 10 May 2023 11:55:28 +0800 From: Trevor Wu To: , , , , , , , CC: , , , , , Subject: [PATCH v4 2/9] ASoC: mediatek: mt8188: complete set_tdm_slot function Date: Wed, 10 May 2023 11:55:19 +0800 Message-ID: <20230510035526.18137-3-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230510035526.18137-1-trevor.wu@mediatek.com> References: <20230510035526.18137-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org User can configures slot number of TDM mode via set_tdm_slot callback. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c index 7a37752d4244..fddecf5bf7c6 100644 --- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c +++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c @@ -1909,6 +1909,10 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, if (!is_valid_etdm_dai(mst_dai_id)) return -EINVAL; + mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; + if (mst_etdm_data->slots) + channels = mst_etdm_data->slots; + ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id); if (ret) return ret; @@ -1918,7 +1922,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, if (ret) return ret; - mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { slv_dai_id = mst_etdm_data->cowork_slv_id[i]; ret = mtk_dai_etdm_configure(afe, rate, channels, @@ -1931,6 +1934,12 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, return ret; } } else { + if (!is_valid_etdm_dai(dai->id)) + return -EINVAL; + mst_etdm_data = afe_priv->dai_priv[dai->id]; + if (mst_etdm_data->slots) + channels = mst_etdm_data->slots; + ret = mtk_dai_etdm_mclk_configure(afe, dai->id); if (ret) return ret; @@ -2073,10 +2082,16 @@ static int mtk_dai_etdm_set_tdm_slot(struct snd_soc_dai *dai, struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); struct mt8188_afe_private *afe_priv = afe->platform_priv; struct mtk_dai_etdm_priv *etdm_data; + int dai_id; - if (!is_valid_etdm_dai(dai->id)) + if (is_cowork_mode(dai)) + dai_id = get_etdm_cowork_master_id(dai); + else + dai_id = dai->id; + + if (!is_valid_etdm_dai(dai_id)) return -EINVAL; - etdm_data = afe_priv->dai_priv[dai->id]; + etdm_data = afe_priv->dai_priv[dai_id]; dev_dbg(dai->dev, "%s id %d slot_width %d\n", __func__, dai->id, slot_width); From patchwork Wed May 10 03:55:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Wu X-Patchwork-Id: 680734 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2B8F1C7EE22 for ; Wed, 10 May 2023 03:56:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235795AbjEJD4s (ORCPT ); Tue, 9 May 2023 23:56:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53986 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235698AbjEJDzm (ORCPT ); Tue, 9 May 2023 23:55:42 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8224D2704; Tue, 9 May 2023 20:55:33 -0700 (PDT) X-UUID: 80c5b4cceee611ed9cb5633481061a41-20230510 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=OtJ9snYBPwTd6TY4IdhDZZ1O11Zn0fRC/iBjODxKKHQ=; b=Xg0YJ2GWZhR0pIYcfhsbdecUIUEX7dS60Mh0xWq5ObF6acnILuXykNSJpgsFpitx0zNTzhaimYELeCIJpfkhJAKS13Ws1kLKiujjNx6s6RJ1iWLOnVuQzYTjC7JIuUjCwp4DB2Wpptd3WVnItkUHmfKu/BXp22IzedxQK47pFXk=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.24, REQID:868842b5-0b70-40d2-822e-4ecae3b31015, IP:0, U RL:0,TC:0,Content:-5,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-5 X-CID-META: VersionHash:178d4d4, CLOUDID:0b1d516b-2f20-4998-991c-3b78627e4938, B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-UUID: 80c5b4cceee611ed9cb5633481061a41-20230510 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 694992188; Wed, 10 May 2023 11:55:28 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs13n2.mediatek.inc (172.21.101.108) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 10 May 2023 11:55:28 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 10 May 2023 11:55:28 +0800 From: Trevor Wu To: , , , , , , , CC: , , , , , Subject: [PATCH v4 3/9] ASoC: mediatek: mt8188: revise ETDM control flow Date: Wed, 10 May 2023 11:55:20 +0800 Message-ID: <20230510035526.18137-4-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230510035526.18137-1-trevor.wu@mediatek.com> References: <20230510035526.18137-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Replace register controls in snd_soc_dai_ops with snd_soc_dapm_widgets. startup, shutdown and trigger ops are removed, and create DAPM_SUPPLY to handle mclk, clock gating and etdm enabling. Additionally, mclk setup sequence is also updated because of new supply enabling sequence. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 790 ++++++++++---------- sound/soc/mediatek/mt8188/mt8188-reg.h | 2 + 2 files changed, 406 insertions(+), 386 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c index fddecf5bf7c6..fd6e39a1e4c1 100644 --- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c +++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c @@ -21,6 +21,13 @@ #define ETDM_TO_DAI_ID(x) ((x) + MT8188_AFE_IO_ETDM_START) #define ENUM_TO_STR(x) #x +enum { + SUPPLY_SEQ_ETDM_MCLK, + SUPPLY_SEQ_ETDM_CG, + SUPPLY_SEQ_DPTX_EN, + SUPPLY_SEQ_ETDM_EN, +}; + enum { MTK_DAI_ETDM_FORMAT_I2S = 0, MTK_DAI_ETDM_FORMAT_LJ, @@ -84,7 +91,6 @@ struct mtk_dai_etdm_rate { }; struct mtk_dai_etdm_priv { - unsigned int clock_mode; unsigned int data_mode; bool slave_mode; bool lrck_inv; @@ -100,8 +106,6 @@ struct mtk_dai_etdm_priv { unsigned int cowork_slv_count; int cowork_slv_id[MT8188_AFE_IO_ETDM_NUM - 1]; //dai_id bool in_disable_ch[MT8188_ETDM_MAX_CHANNELS]; - unsigned int en_ref_cnt; - bool is_prepared; }; static const struct mtk_dai_etdm_rate mt8188_etdm_rates[] = { @@ -345,14 +349,82 @@ static int mtk_dai_etdm_get_clkdiv_id_by_dai_id(int dai_id) } } +static int get_etdm_id_by_name(struct mtk_base_afe *afe, + const char *name) +{ + if (!strncmp(name, "ETDM1_IN", strlen("ETDM1_IN"))) + return MT8188_AFE_IO_ETDM1_IN; + else if (!strncmp(name, "ETDM2_IN", strlen("ETDM2_IN"))) + return MT8188_AFE_IO_ETDM2_IN; + else if (!strncmp(name, "ETDM1_OUT", strlen("ETDM1_OUT"))) + return MT8188_AFE_IO_ETDM1_OUT; + else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT"))) + return MT8188_AFE_IO_ETDM2_OUT; + else + return -EINVAL; +} + +static struct mtk_dai_etdm_priv *get_etdm_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8188_afe_private *afe_priv = afe->platform_priv; + int dai_id = get_etdm_id_by_name(afe, name); + + if (dai_id < MT8188_AFE_IO_ETDM_START || + dai_id >= MT8188_AFE_IO_ETDM_END) + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id) { struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data; + struct etdm_con_reg etdm_reg; + unsigned int val = 0; + unsigned int mask; + int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id); int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id); + int apll_clk_id; + int apll; + int ret; + + if (!is_valid_etdm_dai(dai_id)) + return -EINVAL; + etdm_data = afe_priv->dai_priv[dai_id]; - if (clkdiv_id < 0) + apll = etdm_data->mclk_apll; + apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll); + + if (clkmux_id < 0 || clkdiv_id < 0) return -EINVAL; + if (apll_clk_id < 0) + return apll_clk_id; + + ret = get_etdm_reg(dai_id, &etdm_reg); + if (ret < 0) + return ret; + + mask = ETDM_CON1_MCLK_OUTPUT; + if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT) + val = ETDM_CON1_MCLK_OUTPUT; + regmap_update_bits(afe->regmap, etdm_reg.con1, mask, val); + + /* enable parent clock before select apll*/ + mt8188_afe_enable_clk(afe, afe_priv->clk[clkmux_id]); + + /* select apll */ + ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clkmux_id], + afe_priv->clk[apll_clk_id]); + if (ret) + return ret; + + /* set rate */ + ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id], + etdm_data->mclk_freq); + mt8188_afe_enable_clk(afe, afe_priv->clk[clkdiv_id]); return 0; @@ -361,12 +433,207 @@ static int mtk_dai_etdm_enable_mclk(struct mtk_base_afe *afe, int dai_id) static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id) { struct mt8188_afe_private *afe_priv = afe->platform_priv; + int clkmux_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id); int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id); - if (clkdiv_id < 0) + if (clkmux_id < 0 || clkdiv_id < 0) return -EINVAL; mt8188_afe_disable_clk(afe, afe_priv->clk[clkdiv_id]); + mt8188_afe_disable_clk(afe, afe_priv->clk[clkmux_id]); + + return 0; +} + +static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_priv; + int mclk_id; + + mclk_id = get_etdm_id_by_name(afe, source->name); + if (mclk_id < 0) { + dev_dbg(afe->dev, "mclk_id < 0\n"); + return 0; + } + + etdm_priv = get_etdm_priv_by_name(afe, w->name); + if (!etdm_priv) { + dev_dbg(afe->dev, "etdm_priv == NULL\n"); + return 0; + } + + if (get_etdm_id_by_name(afe, sink->name) == mclk_id) + return !!(etdm_priv->mclk_freq > 0); + + if (etdm_priv->cowork_source_id == mclk_id) { + etdm_priv = afe_priv->dai_priv[mclk_id]; + return !!(etdm_priv->mclk_freq > 0); + } + + return 0; +} + +static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_priv; + int source_id; + int i; + + source_id = get_etdm_id_by_name(afe, source->name); + if (source_id < 0) { + dev_dbg(afe->dev, "%s() source_id < 0\n", __func__); + return 0; + } + + etdm_priv = get_etdm_priv_by_name(afe, w->name); + if (!etdm_priv) { + dev_dbg(afe->dev, "%s() etdm_priv == NULL\n", __func__); + return 0; + } + + if (etdm_priv->cowork_source_id != COWORK_ETDM_NONE) { + if (etdm_priv->cowork_source_id == source_id) + return 1; + + etdm_priv = afe_priv->dai_priv[etdm_priv->cowork_source_id]; + for (i = 0; i < etdm_priv->cowork_slv_count; i++) { + if (etdm_priv->cowork_slv_id[i] == source_id) + return 1; + } + } else { + for (i = 0; i < etdm_priv->cowork_slv_count; i++) { + if (etdm_priv->cowork_slv_id[i] == source_id) + return 1; + } + } + + return 0; +} + +static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + int mclk_id = get_etdm_id_by_name(afe, w->name); + + if (mclk_id < 0) { + dev_dbg(afe->dev, "%s() mclk_id < 0\n", __func__); + return 0; + } + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mtk_dai_etdm_enable_mclk(afe, mclk_id); + break; + case SND_SOC_DAPM_POST_PMD: + mtk_dai_etdm_disable_mclk(afe, mclk_id); + break; + default: + break; + } + + return 0; +} + +static int mtk_dptx_mclk_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mtk_dai_etdm_enable_mclk(afe, MT8188_AFE_IO_DPTX); + break; + case SND_SOC_DAPM_POST_PMD: + mtk_dai_etdm_disable_mclk(afe, MT8188_AFE_IO_DPTX); + break; + default: + break; + } + + return 0; +} + +static int mtk_etdm_cg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + int etdm_id; + int cg_id; + + etdm_id = get_etdm_id_by_name(afe, w->name); + if (etdm_id < 0) { + dev_dbg(afe->dev, "%s() etdm_id < 0\n", __func__); + return 0; + } + + cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(etdm_id); + if (cg_id < 0) { + dev_dbg(afe->dev, "%s() cg_id < 0\n", __func__); + return 0; + } + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); + break; + case SND_SOC_DAPM_POST_PMD: + mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); + break; + default: + break; + } + + return 0; +} + +static int mtk_etdm3_cg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]); + break; + case SND_SOC_DAPM_POST_PMD: + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_HDMI_OUT]); + break; + default: + break; + } return 0; } @@ -906,11 +1173,141 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { SND_SOC_DAPM_MUX("HDMI_CH7_MUX", SND_SOC_NOPM, 0, 0, &hdmi_ch7_mux_control), + /* mclk en */ + SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK, + SND_SOC_NOPM, 0, 0, + mtk_etdm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_MCLK", SUPPLY_SEQ_ETDM_MCLK, + SND_SOC_NOPM, 0, 0, + mtk_etdm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK, + SND_SOC_NOPM, 0, 0, + mtk_etdm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_MCLK", SUPPLY_SEQ_ETDM_MCLK, + SND_SOC_NOPM, 0, 0, + mtk_etdm_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("DPTX_MCLK", SUPPLY_SEQ_ETDM_MCLK, + SND_SOC_NOPM, 0, 0, + mtk_dptx_mclk_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* cg */ + SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_CG", SUPPLY_SEQ_ETDM_CG, + SND_SOC_NOPM, 0, 0, + mtk_etdm_cg_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_CG", SUPPLY_SEQ_ETDM_CG, + SND_SOC_NOPM, 0, 0, + mtk_etdm_cg_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_CG", SUPPLY_SEQ_ETDM_CG, + SND_SOC_NOPM, 0, 0, + mtk_etdm_cg_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_CG", SUPPLY_SEQ_ETDM_CG, + SND_SOC_NOPM, 0, 0, + mtk_etdm_cg_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_CG", SUPPLY_SEQ_ETDM_CG, + SND_SOC_NOPM, 0, 0, + mtk_etdm3_cg_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + /* en */ + SND_SOC_DAPM_SUPPLY_S("ETDM1_IN_EN", SUPPLY_SEQ_ETDM_EN, + ETDM_IN1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ETDM2_IN_EN", SUPPLY_SEQ_ETDM_EN, + ETDM_IN2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ETDM1_OUT_EN", SUPPLY_SEQ_ETDM_EN, + ETDM_OUT1_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ETDM2_OUT_EN", SUPPLY_SEQ_ETDM_EN, + ETDM_OUT2_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("ETDM3_OUT_EN", SUPPLY_SEQ_ETDM_EN, + ETDM_OUT3_CON0, ETDM_CON0_EN_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN, + AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0), + SND_SOC_DAPM_INPUT("ETDM_INPUT"), SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"), }; static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { + /* mclk */ + {"ETDM1_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM1_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM1_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect}, + {"ETDM1_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect}, + + {"ETDM2_IN", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM2_IN", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM2_IN", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect}, + {"ETDM2_IN", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect}, + + {"ETDM1_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM1_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM1_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect}, + {"ETDM1_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect}, + + {"ETDM2_OUT", NULL, "ETDM1_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM2_OUT", NULL, "ETDM2_IN_MCLK", mtk_etdm_mclk_connect}, + {"ETDM2_OUT", NULL, "ETDM1_OUT_MCLK", mtk_etdm_mclk_connect}, + {"ETDM2_OUT", NULL, "ETDM2_OUT_MCLK", mtk_etdm_mclk_connect}, + + {"DPTX", NULL, "DPTX_MCLK"}, + + /* cg */ + {"ETDM1_IN", NULL, "ETDM1_IN_CG"}, + {"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect}, + {"ETDM1_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect}, + {"ETDM1_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect}, + + {"ETDM2_IN", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect}, + {"ETDM2_IN", NULL, "ETDM2_IN_CG"}, + {"ETDM2_IN", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect}, + {"ETDM2_IN", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect}, + + {"ETDM1_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect}, + {"ETDM1_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect}, + {"ETDM1_OUT", NULL, "ETDM1_OUT_CG"}, + {"ETDM1_OUT", NULL, "ETDM2_OUT_CG", mtk_etdm_cowork_connect}, + + {"ETDM2_OUT", NULL, "ETDM1_IN_CG", mtk_etdm_cowork_connect}, + {"ETDM2_OUT", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect}, + {"ETDM2_OUT", NULL, "ETDM1_OUT_CG", mtk_etdm_cowork_connect}, + {"ETDM2_OUT", NULL, "ETDM2_OUT_CG"}, + + {"ETDM3_OUT", NULL, "ETDM3_OUT_CG"}, + {"DPTX", NULL, "ETDM3_OUT_CG"}, + + /* en */ + {"ETDM1_IN", NULL, "ETDM1_IN_EN"}, + {"ETDM1_IN", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect}, + {"ETDM1_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect}, + {"ETDM1_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect}, + + {"ETDM2_IN", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect}, + {"ETDM2_IN", NULL, "ETDM2_IN_EN"}, + {"ETDM2_IN", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect}, + {"ETDM2_IN", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect}, + + {"ETDM1_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect}, + {"ETDM1_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect}, + {"ETDM1_OUT", NULL, "ETDM1_OUT_EN"}, + {"ETDM1_OUT", NULL, "ETDM2_OUT_EN", mtk_etdm_cowork_connect}, + + {"ETDM2_OUT", NULL, "ETDM1_IN_EN", mtk_etdm_cowork_connect}, + {"ETDM2_OUT", NULL, "ETDM2_IN_EN", mtk_etdm_cowork_connect}, + {"ETDM2_OUT", NULL, "ETDM1_OUT_EN", mtk_etdm_cowork_connect}, + {"ETDM2_OUT", NULL, "ETDM2_OUT_EN"}, + + {"ETDM3_OUT", NULL, "ETDM3_OUT_EN"}, + {"DPTX", NULL, "ETDM3_OUT_EN"}, + {"DPTX", NULL, "DPTX_EN"}, + {"I012", NULL, "ETDM2_IN"}, {"I013", NULL, "ETDM2_IN"}, {"I014", NULL, "ETDM2_IN"}, @@ -1163,64 +1560,6 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { {"ETDM2_IN", NULL, "ETDM_INPUT"}, }; -static int mt8188_afe_enable_etdm(struct mtk_base_afe *afe, int dai_id) -{ - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *etdm_data; - struct etdm_con_reg etdm_reg; - unsigned long flags; - int ret = 0; - - if (!is_valid_etdm_dai(dai_id)) - return -EINVAL; - etdm_data = afe_priv->dai_priv[dai_id]; - - dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt); - spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); - etdm_data->en_ref_cnt++; - if (etdm_data->en_ref_cnt == 1) { - ret = get_etdm_reg(dai_id, &etdm_reg); - if (ret < 0) - goto out; - - regmap_set_bits(afe->regmap, etdm_reg.con0, ETDM_CON0_EN); - } - -out: - spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); - return ret; -} - -static int mt8188_afe_disable_etdm(struct mtk_base_afe *afe, int dai_id) -{ - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *etdm_data; - struct etdm_con_reg etdm_reg; - unsigned long flags; - int ret = 0; - - if (!is_valid_etdm_dai(dai_id)) - return -EINVAL; - etdm_data = afe_priv->dai_priv[dai_id]; - - dev_dbg(afe->dev, "%s [%d]%d\n", __func__, dai_id, etdm_data->en_ref_cnt); - spin_lock_irqsave(&afe_priv->afe_ctrl_lock, flags); - if (etdm_data->en_ref_cnt > 0) { - etdm_data->en_ref_cnt--; - if (etdm_data->en_ref_cnt == 0) { - ret = get_etdm_reg(dai_id, &etdm_reg); - if (ret < 0) - goto out; - regmap_clear_bits(afe->regmap, etdm_reg.con0, - ETDM_CON0_EN); - } - } - -out: - spin_unlock_irqrestore(&afe_priv->afe_ctrl_lock, flags); - return ret; -} - static int etdm_cowork_slv_sel(int id, int slave_mode) { if (slave_mode) { @@ -1408,121 +1747,6 @@ static int mt8188_etdm_sync_mode_configure(struct mtk_base_afe *afe, int dai_id) } /* dai ops */ -static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *mst_etdm_data; - int mst_dai_id; - int slv_dai_id; - int cg_id; - int i; - - if (is_cowork_mode(dai)) { - mst_dai_id = get_etdm_cowork_master_id(dai); - if (!is_valid_etdm_dai(mst_dai_id)) - return -EINVAL; - mtk_dai_etdm_enable_mclk(afe, mst_dai_id); - - cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id); - if (cg_id >= 0) - mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); - - mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; - - for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { - slv_dai_id = mst_etdm_data->cowork_slv_id[i]; - cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id); - if (cg_id >= 0) - mt8188_afe_enable_clk(afe, - afe_priv->clk[cg_id]); - } - } else { - mtk_dai_etdm_enable_mclk(afe, dai->id); - - cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); - if (cg_id >= 0) - mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); - } - - return 0; -} - -static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *mst_etdm_data; - int mst_dai_id; - int slv_dai_id; - int cg_id; - int ret; - int i; - - if (!is_valid_etdm_dai(dai->id)) - return; - mst_etdm_data = afe_priv->dai_priv[dai->id]; - - dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id, - mst_etdm_data->is_prepared); - - if (mst_etdm_data->is_prepared) { - mst_etdm_data->is_prepared = false; - - if (is_cowork_mode(dai)) { - mst_dai_id = get_etdm_cowork_master_id(dai); - if (!is_valid_etdm_dai(mst_dai_id)) - return; - mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; - - ret = mt8188_afe_disable_etdm(afe, mst_dai_id); - if (ret) - dev_dbg(afe->dev, "%s disable %d failed\n", - __func__, mst_dai_id); - - for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { - slv_dai_id = mst_etdm_data->cowork_slv_id[i]; - ret = mt8188_afe_disable_etdm(afe, slv_dai_id); - if (ret) - dev_dbg(afe->dev, "%s disable %d failed\n", - __func__, slv_dai_id); - } - } else { - ret = mt8188_afe_disable_etdm(afe, dai->id); - if (ret) - dev_dbg(afe->dev, "%s disable %d failed\n", - __func__, dai->id); - } - } - - if (is_cowork_mode(dai)) { - mst_dai_id = get_etdm_cowork_master_id(dai); - if (!is_valid_etdm_dai(mst_dai_id)) - return; - cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(mst_dai_id); - if (cg_id >= 0) - mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); - - mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; - for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { - slv_dai_id = mst_etdm_data->cowork_slv_id[i]; - cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(slv_dai_id); - if (cg_id >= 0) - mt8188_afe_disable_clk(afe, - afe_priv->clk[cg_id]); - } - mtk_dai_etdm_disable_mclk(afe, mst_dai_id); - } else { - cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); - if (cg_id >= 0) - mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); - - mtk_dai_etdm_disable_mclk(afe, dai->id); - } -} - static int mtk_dai_etdm_fifo_mode(struct mtk_base_afe *afe, int dai_id, unsigned int rate) { @@ -1759,60 +1983,6 @@ static int mtk_dai_etdm_out_configure(struct mtk_base_afe *afe, return 0; } -static int mtk_dai_etdm_mclk_configure(struct mtk_base_afe *afe, int dai_id) -{ - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *etdm_data; - struct etdm_con_reg etdm_reg; - int clk_id = mtk_dai_etdm_get_clk_id_by_dai_id(dai_id); - int clkdiv_id = mtk_dai_etdm_get_clkdiv_id_by_dai_id(dai_id); - int apll_clk_id; - int apll; - int ret; - - if (clk_id < 0 || clkdiv_id < 0) - return -EINVAL; - - if (!is_valid_etdm_dai(dai_id)) - return -EINVAL; - etdm_data = afe_priv->dai_priv[dai_id]; - - ret = get_etdm_reg(dai_id, &etdm_reg); - if (ret < 0) - return ret; - - if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT) - regmap_set_bits(afe->regmap, etdm_reg.con1, - ETDM_CON1_MCLK_OUTPUT); - else - regmap_clear_bits(afe->regmap, etdm_reg.con1, - ETDM_CON1_MCLK_OUTPUT); - - if (etdm_data->mclk_freq) { - apll = etdm_data->mclk_apll; - apll_clk_id = mt8188_afe_get_mclk_source_clk_id(apll); - if (apll_clk_id < 0) - return apll_clk_id; - - /* select apll */ - ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[clk_id], - afe_priv->clk[apll_clk_id]); - if (ret) - return ret; - - /* set rate */ - ret = mt8188_afe_set_clk_rate(afe, afe_priv->clk[clkdiv_id], - etdm_data->mclk_freq); - if (ret) - return ret; - } else { - if (etdm_data->mclk_dir == SND_SOC_CLOCK_OUT) - dev_dbg(afe->dev, "%s mclk freq = 0\n", __func__); - } - - return 0; -} - static int mtk_dai_etdm_configure(struct mtk_base_afe *afe, unsigned int rate, unsigned int channels, @@ -1839,10 +2009,10 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe, if (ret < 0) return ret; - dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, clock %u slv %u\n", + dev_dbg(afe->dev, "%s fmt %u data %u lrck %d-%u bck %d, slv %u\n", __func__, etdm_data->format, etdm_data->data_mode, etdm_data->lrck_inv, etdm_data->lrck_width, etdm_data->bck_inv, - etdm_data->clock_mode, etdm_data->slave_mode); + etdm_data->slave_mode); dev_dbg(afe->dev, "%s rate %u channels %u bitwidth %u, id %d\n", __func__, rate, channels, bit_width, dai_id); @@ -1913,10 +2083,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, if (mst_etdm_data->slots) channels = mst_etdm_data->slots; - ret = mtk_dai_etdm_mclk_configure(afe, mst_dai_id); - if (ret) - return ret; - ret = mtk_dai_etdm_configure(afe, rate, channels, bit_width, mst_dai_id); if (ret) @@ -1940,10 +2106,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, if (mst_etdm_data->slots) channels = mst_etdm_data->slots; - ret = mtk_dai_etdm_mclk_configure(afe, dai->id); - if (ret) - return ret; - ret = mtk_dai_etdm_configure(afe, rate, channels, bit_width, dai->id); if (ret) @@ -1953,66 +2115,6 @@ static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, return 0; } -static int mtk_dai_etdm_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *mst_etdm_data; - int mst_dai_id; - int slv_dai_id; - int ret; - int i; - - if (!is_valid_etdm_dai(dai->id)) - return -EINVAL; - mst_etdm_data = afe_priv->dai_priv[dai->id]; - - dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id, - mst_etdm_data->is_prepared); - - if (mst_etdm_data->is_prepared) - return 0; - - mst_etdm_data->is_prepared = true; - - if (is_cowork_mode(dai)) { - mst_dai_id = get_etdm_cowork_master_id(dai); - if (!is_valid_etdm_dai(mst_dai_id)) - return -EINVAL; - mst_etdm_data = afe_priv->dai_priv[mst_dai_id]; - - for (i = 0; i < mst_etdm_data->cowork_slv_count; i++) { - slv_dai_id = mst_etdm_data->cowork_slv_id[i]; - ret = mt8188_afe_enable_etdm(afe, slv_dai_id); - if (ret) { - dev_dbg(afe->dev, "%s enable %d failed\n", - __func__, slv_dai_id); - - return ret; - } - } - - ret = mt8188_afe_enable_etdm(afe, mst_dai_id); - if (ret) { - dev_dbg(afe->dev, "%s enable %d failed\n", - __func__, mst_dai_id); - - return ret; - } - } else { - ret = mt8188_afe_enable_etdm(afe, dai->id); - if (ret) { - dev_dbg(afe->dev, "%s enable %d failed\n", - __func__, dai->id); - - return ret; - } - } - - return 0; -} - static int mtk_dai_etdm_cal_mclk(struct mtk_base_afe *afe, int freq, int dai_id) { struct mt8188_afe_private *afe_priv = afe->platform_priv; @@ -2166,53 +2268,6 @@ static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) return 0; } -static int mtk_dai_hdmitx_dptx_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - struct mt8188_afe_private *afe_priv = afe->platform_priv; - int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); - - if (cg_id >= 0) - mt8188_afe_enable_clk(afe, afe_priv->clk[cg_id]); - - mtk_dai_etdm_enable_mclk(afe, dai->id); - - return 0; -} - -static void mtk_dai_hdmitx_dptx_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - struct mt8188_afe_private *afe_priv = afe->platform_priv; - int cg_id = mtk_dai_etdm_get_cg_id_by_dai_id(dai->id); - struct mtk_dai_etdm_priv *etdm_data; - int ret; - - if (!is_valid_etdm_dai(dai->id)) - return; - etdm_data = afe_priv->dai_priv[dai->id]; - - if (etdm_data->is_prepared) { - etdm_data->is_prepared = false; - /* disable etdm_out3 */ - ret = mt8188_afe_disable_etdm(afe, dai->id); - if (ret) - dev_dbg(afe->dev, "%s disable failed\n", __func__); - - /* disable dptx interface */ - if (dai->id == MT8188_AFE_IO_DPTX) - regmap_clear_bits(afe->regmap, AFE_DPTX_CON, - AFE_DPTX_CON_ON); - } - - mtk_dai_etdm_disable_mclk(afe, dai->id); - - if (cg_id >= 0) - mt8188_afe_disable_clk(afe, afe_priv->clk[cg_id]); -} - static unsigned int mtk_dai_get_dptx_ch_en(unsigned int channel) { switch (channel) { @@ -2280,42 +2335,11 @@ static int mtk_dai_hdmitx_dptx_hw_params(struct snd_pcm_substream *substream, etdm_data->data_mode = MTK_DAI_ETDM_DATA_MULTI_PIN; } - ret = mtk_dai_etdm_mclk_configure(afe, dai->id); - if (ret) - return ret; - ret = mtk_dai_etdm_configure(afe, rate, channels, width, dai->id); return ret; } -static int mtk_dai_hdmitx_dptx_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); - struct mt8188_afe_private *afe_priv = afe->platform_priv; - struct mtk_dai_etdm_priv *etdm_data; - - if (!is_valid_etdm_dai(dai->id)) - return -EINVAL; - etdm_data = afe_priv->dai_priv[dai->id]; - - dev_dbg(afe->dev, "%s(), dai id %d, prepared %d\n", __func__, dai->id, - etdm_data->is_prepared); - - if (etdm_data->is_prepared) - return 0; - - etdm_data->is_prepared = true; - - /* enable dptx interface */ - if (dai->id == MT8188_AFE_IO_DPTX) - regmap_set_bits(afe->regmap, AFE_DPTX_CON, AFE_DPTX_CON_ON); - - /* enable etdm_out3 */ - return mt8188_afe_enable_etdm(afe, dai->id); -} - static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai, int clk_id, unsigned int freq, @@ -2337,20 +2361,14 @@ static int mtk_dai_hdmitx_dptx_set_sysclk(struct snd_soc_dai *dai, } static const struct snd_soc_dai_ops mtk_dai_etdm_ops = { - .startup = mtk_dai_etdm_startup, - .shutdown = mtk_dai_etdm_shutdown, .hw_params = mtk_dai_etdm_hw_params, - .prepare = mtk_dai_etdm_prepare, .set_sysclk = mtk_dai_etdm_set_sysclk, .set_fmt = mtk_dai_etdm_set_fmt, .set_tdm_slot = mtk_dai_etdm_set_tdm_slot, }; static const struct snd_soc_dai_ops mtk_dai_hdmitx_dptx_ops = { - .startup = mtk_dai_hdmitx_dptx_startup, - .shutdown = mtk_dai_hdmitx_dptx_shutdown, .hw_params = mtk_dai_hdmitx_dptx_hw_params, - .prepare = mtk_dai_hdmitx_dptx_prepare, .set_sysclk = mtk_dai_hdmitx_dptx_set_sysclk, .set_fmt = mtk_dai_etdm_set_fmt, }; diff --git a/sound/soc/mediatek/mt8188/mt8188-reg.h b/sound/soc/mediatek/mt8188/mt8188-reg.h index 51cd1a83dd9d..bdd885419ff3 100644 --- a/sound/soc/mediatek/mt8188/mt8188-reg.h +++ b/sound/soc/mediatek/mt8188/mt8188-reg.h @@ -3007,6 +3007,7 @@ #define ETDM_CON0_SLAVE_MODE BIT(5) #define ETDM_CON0_SYNC_MODE BIT(1) #define ETDM_CON0_EN BIT(0) +#define ETDM_CON0_EN_SHIFT 0 #define ETDM_OUT_CON0_RELATCH_DOMAIN_MASK GENMASK(29, 28) @@ -3108,6 +3109,7 @@ #define AFE_DPTX_CON_CH_NUM_8CH (0x1 << 1) #define AFE_DPTX_CON_CH_NUM_MASK BIT(1) #define AFE_DPTX_CON_ON BIT(0) +#define AFE_DPTX_CON_ON_SHIFT 0 /* AFE_ADDA_DL_SRC2_CON0 */ #define DL_2_INPUT_MODE_CTL_MASK GENMASK(31, 28) From patchwork Wed May 10 03:55:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Wu X-Patchwork-Id: 680731 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 869FCC7EE22 for ; Wed, 10 May 2023 03:57:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236085AbjEJD5G (ORCPT ); Tue, 9 May 2023 23:57:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53486 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235312AbjEJDzq (ORCPT ); Tue, 9 May 2023 23:55:46 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 817C940F7; Tue, 9 May 2023 20:55:41 -0700 (PDT) X-UUID: 8161b980eee611ed9cb5633481061a41-20230510 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=F/Yw6OHKAu10IOjEUM87CTc8nWP90wVs74g53jQNKRU=; b=NiVWeG0tb3OzyIu0HjQvXNRi6m3K+rp0GpPxNfcR/fmUx5D/Ay541IaCha2ZlHlKyMIaVN7n6d2vOSL5OxmHFsRFU14qF3dy6Drxxm9zldeGwlVkCmLCYFC3mHG8iz1mqsi0GOgO0IP/t9bfETi4+wf1djU0EkkT/DFIdMaSafk=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.24, REQID:ddb9c9e5-cf8e-455b-893a-5ed937ad05d6, IP:0, U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:0 X-CID-META: VersionHash:178d4d4, CLOUDID:ae6758c0-e32c-4c97-918d-fbb3fc224d4e, B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-UUID: 8161b980eee611ed9cb5633481061a41-20230510 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 889967141; Wed, 10 May 2023 11:55:29 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs13n1.mediatek.inc (172.21.101.193) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 10 May 2023 11:55:28 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 10 May 2023 11:55:28 +0800 From: Trevor Wu To: , , , , , , , CC: , , , , , Subject: [PATCH v4 4/9] ASoC: mediatek: mt8188: refine APLL control Date: Wed, 10 May 2023 11:55:21 +0800 Message-ID: <20230510035526.18137-5-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230510035526.18137-1-trevor.wu@mediatek.com> References: <20230510035526.18137-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Currently, APLL is only used in ETDM module, so APLL and APLL tuner don't need to be enabled when AFE is used. Integrate APLL control into ETDM DAPM routes, so that APLL can be enabled when it is really required. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8188/mt8188-afe-clk.c | 138 ++++++++++++++++---- sound/soc/mediatek/mt8188/mt8188-afe-clk.h | 11 ++ sound/soc/mediatek/mt8188/mt8188-dai-etdm.c | 115 ++++++++++++++++ 3 files changed, 241 insertions(+), 23 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c index 743d6a162cb9..02411be93900 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.c @@ -24,6 +24,7 @@ static const char *aud_clks[MT8188_CLK_NUM] = { [MT8188_CLK_APMIXED_APLL2] = "apll2", /* divider */ + [MT8188_CLK_TOP_APLL1_D4] = "apll1_d4", [MT8188_CLK_TOP_APLL12_DIV0] = "apll12_div0", [MT8188_CLK_TOP_APLL12_DIV1] = "apll12_div1", [MT8188_CLK_TOP_APLL12_DIV2] = "apll12_div2", @@ -378,6 +379,19 @@ int mt8188_afe_get_default_mclk_source_by_rate(int rate) MT8188_MCK_SEL_APLL1 : MT8188_MCK_SEL_APLL2; } +int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate) +{ + return ((rate % 8000) == 0) ? MT8188_AUD_PLL1 : MT8188_AUD_PLL2; +} + +int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name) +{ + if (strcmp(name, APLL1_W_NAME) == 0) + return MT8188_AUD_PLL1; + + return MT8188_AUD_PLL2; +} + int mt8188_afe_init_clock(struct mtk_base_afe *afe) { struct mt8188_afe_private *afe_priv = afe->platform_priv; @@ -477,8 +491,8 @@ int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, if (clk && parent) { ret = clk_set_parent(clk, parent); if (ret) { - dev_dbg(afe->dev, "%s(), failed to set clk parent\n", - __func__); + dev_dbg(afe->dev, "%s(), failed to set clk parent %d\n", + __func__, ret); return ret; } } @@ -605,54 +619,132 @@ static int mt8188_afe_disable_afe_on(struct mtk_base_afe *afe) return 0; } -static int mt8188_afe_enable_timing_sys(struct mtk_base_afe *afe) +static int mt8188_afe_enable_a1sys(struct mtk_base_afe *afe) { struct mt8188_afe_private *afe_priv = afe->platform_priv; + int ret; - mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]); - mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]); + ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]); + if (ret) + return ret; - mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING); - mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING); - mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING); + return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING); +} + +static int mt8188_afe_disable_a1sys(struct mtk_base_afe *afe) +{ + struct mt8188_afe_private *afe_priv = afe->platform_priv; + mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]); return 0; } -static int mt8188_afe_disable_timing_sys(struct mtk_base_afe *afe) +static int mt8188_afe_enable_a2sys(struct mtk_base_afe *afe) { struct mt8188_afe_private *afe_priv = afe->platform_priv; + int ret; - mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A1SYS]); - mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]); + ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]); + if (ret) + return ret; - mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING); - mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING); - mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A1SYS_TIMING); + return mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING); +} + +static int mt8188_afe_disable_a2sys(struct mtk_base_afe *afe) +{ + struct mt8188_afe_private *afe_priv = afe->platform_priv; + mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_A2SYS_TIMING); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_AUD_A2SYS]); return 0; } -int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe) +int mt8188_apll1_enable(struct mtk_base_afe *afe) { - mt8188_afe_enable_timing_sys(afe); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + int ret; - mt8188_afe_enable_afe_on(afe); + ret = mt8188_afe_enable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]); + if (ret) + return ret; + + ret = mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL], + afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]); + if (ret) + goto err_clk_parent; - mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1); - mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2); + ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL1); + if (ret) + goto err_apll_tuner; + + ret = mt8188_afe_enable_a1sys(afe); + if (ret) + goto err_a1sys; return 0; + +err_a1sys: + mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1); +err_apll_tuner: + mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL], + afe_priv->clk[MT8188_CLK_XTAL_26M]); +err_clk_parent: + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]); + + return ret; } -int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe) +int mt8188_apll1_disable(struct mtk_base_afe *afe) { - mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2); + struct mt8188_afe_private *afe_priv = afe->platform_priv; + + mt8188_afe_disable_a1sys(afe); mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL1); + mt8188_afe_set_clk_parent(afe, afe_priv->clk[MT8188_CLK_TOP_A1SYS_HP_SEL], + afe_priv->clk[MT8188_CLK_XTAL_26M]); + mt8188_afe_disable_clk(afe, afe_priv->clk[MT8188_CLK_TOP_APLL1_D4]); - mt8188_afe_disable_afe_on(afe); + return 0; +} + +int mt8188_apll2_enable(struct mtk_base_afe *afe) +{ + int ret; - mt8188_afe_disable_timing_sys(afe); + ret = mt8188_afe_enable_apll_tuner(afe, MT8188_AUD_PLL2); + if (ret) + return ret; + ret = mt8188_afe_enable_a2sys(afe); + if (ret) + goto err_a2sys; + + return 0; +err_a2sys: + mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2); + + return ret; +} + +int mt8188_apll2_disable(struct mtk_base_afe *afe) +{ + mt8188_afe_disable_a2sys(afe); + mt8188_afe_disable_apll_tuner(afe, MT8188_AUD_PLL2); + return 0; +} + +int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe) +{ + mt8188_afe_enable_top_cg(afe, MT8188_TOP_CG_26M_TIMING); + mt8188_afe_enable_afe_on(afe); + return 0; +} + +int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe) +{ + mt8188_afe_disable_afe_on(afe); + mt8188_afe_disable_top_cg(afe, MT8188_TOP_CG_26M_TIMING); return 0; } diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h index 084fdfb1d877..04cb476f0bcb 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-clk.h +++ b/sound/soc/mediatek/mt8188/mt8188-afe-clk.h @@ -11,6 +11,10 @@ #ifndef _MT8188_AFE_CLK_H_ #define _MT8188_AFE_CLK_H_ +/* APLL */ +#define APLL1_W_NAME "APLL1" +#define APLL2_W_NAME "APLL2" + enum { /* xtal */ MT8188_CLK_XTAL_26M, @@ -18,6 +22,7 @@ enum { MT8188_CLK_APMIXED_APLL1, MT8188_CLK_APMIXED_APLL2, /* divider */ + MT8188_CLK_TOP_APLL1_D4, MT8188_CLK_TOP_APLL12_DIV0, MT8188_CLK_TOP_APLL12_DIV1, MT8188_CLK_TOP_APLL12_DIV2, @@ -99,6 +104,8 @@ struct mtk_base_afe; int mt8188_afe_get_mclk_source_clk_id(int sel); int mt8188_afe_get_mclk_source_rate(struct mtk_base_afe *afe, int apll); int mt8188_afe_get_default_mclk_source_by_rate(int rate); +int mt8188_get_apll_by_rate(struct mtk_base_afe *afe, int rate); +int mt8188_get_apll_by_name(struct mtk_base_afe *afe, const char *name); int mt8188_afe_init_clock(struct mtk_base_afe *afe); void mt8188_afe_deinit_clock(void *priv); int mt8188_afe_enable_clk(struct mtk_base_afe *afe, struct clk *clk); @@ -107,6 +114,10 @@ int mt8188_afe_set_clk_rate(struct mtk_base_afe *afe, struct clk *clk, unsigned int rate); int mt8188_afe_set_clk_parent(struct mtk_base_afe *afe, struct clk *clk, struct clk *parent); +int mt8188_apll1_enable(struct mtk_base_afe *afe); +int mt8188_apll1_disable(struct mtk_base_afe *afe); +int mt8188_apll2_enable(struct mtk_base_afe *afe); +int mt8188_apll2_disable(struct mtk_base_afe *afe); int mt8188_afe_enable_main_clock(struct mtk_base_afe *afe); int mt8188_afe_disable_main_clock(struct mtk_base_afe *afe); int mt8188_afe_enable_reg_rw_clk(struct mtk_base_afe *afe); diff --git a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c index fd6e39a1e4c1..16440dd0a89c 100644 --- a/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c +++ b/sound/soc/mediatek/mt8188/mt8188-dai-etdm.c @@ -22,6 +22,7 @@ #define ENUM_TO_STR(x) #x enum { + SUPPLY_SEQ_APLL, SUPPLY_SEQ_ETDM_MCLK, SUPPLY_SEQ_ETDM_CG, SUPPLY_SEQ_DPTX_EN, @@ -95,6 +96,7 @@ struct mtk_dai_etdm_priv { bool slave_mode; bool lrck_inv; bool bck_inv; + unsigned int rate; unsigned int format; unsigned int slots; unsigned int lrck_width; @@ -360,6 +362,10 @@ static int get_etdm_id_by_name(struct mtk_base_afe *afe, return MT8188_AFE_IO_ETDM1_OUT; else if (!strncmp(name, "ETDM2_OUT", strlen("ETDM2_OUT"))) return MT8188_AFE_IO_ETDM2_OUT; + else if (!strncmp(name, "ETDM3_OUT", strlen("ETDM3_OUT"))) + return MT8188_AFE_IO_ETDM3_OUT; + else if (!strncmp(name, "DPTX", strlen("DPTX"))) + return MT8188_AFE_IO_ETDM3_OUT; else return -EINVAL; } @@ -445,6 +451,44 @@ static int mtk_dai_etdm_disable_mclk(struct mtk_base_afe *afe, int dai_id) return 0; } +static int mtk_afe_etdm_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_dai_etdm_priv *etdm_priv; + int cur_apll; + int need_apll; + + etdm_priv = get_etdm_priv_by_name(afe, w->name); + if (!etdm_priv) { + dev_dbg(afe->dev, "etdm_priv == NULL\n"); + return 0; + } + + cur_apll = mt8188_get_apll_by_name(afe, source->name); + need_apll = mt8188_get_apll_by_rate(afe, etdm_priv->rate); + + return (need_apll == cur_apll) ? 1 : 0; +} + +static int mtk_afe_mclk_apll_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = sink; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_dai_etdm_priv *etdm_priv; + int cur_apll; + + etdm_priv = get_etdm_priv_by_name(afe, w->name); + + cur_apll = mt8188_get_apll_by_name(afe, source->name); + + return (etdm_priv->mclk_apll == cur_apll) ? 1 : 0; +} + static int mtk_etdm_mclk_connect(struct snd_soc_dapm_widget *source, struct snd_soc_dapm_widget *sink) { @@ -520,6 +564,36 @@ static int mtk_etdm_cowork_connect(struct snd_soc_dapm_widget *source, return 0; } +static int mtk_apll_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(cmpnt->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8188_apll1_enable(afe); + else + mt8188_apll2_enable(afe); + break; + case SND_SOC_DAPM_POST_PMD: + if (strcmp(w->name, APLL1_W_NAME) == 0) + mt8188_apll1_disable(afe); + else + mt8188_apll2_disable(afe); + break; + default: + break; + } + + return 0; +} + static int mtk_etdm_mclk_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) @@ -1231,6 +1305,16 @@ static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] = { SND_SOC_DAPM_SUPPLY_S("DPTX_EN", SUPPLY_SEQ_DPTX_EN, AFE_DPTX_CON, AFE_DPTX_CON_ON_SHIFT, 0, NULL, 0), + /* apll */ + SND_SOC_DAPM_SUPPLY_S(APLL1_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY_S(APLL2_W_NAME, SUPPLY_SEQ_APLL, + SND_SOC_NOPM, 0, 0, + mtk_apll_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_INPUT("ETDM_INPUT"), SND_SOC_DAPM_OUTPUT("ETDM_OUTPUT"), }; @@ -1259,6 +1343,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { {"DPTX", NULL, "DPTX_MCLK"}, + {"ETDM1_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {"ETDM1_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + {"ETDM2_IN_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {"ETDM2_IN_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + {"ETDM1_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {"ETDM1_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + {"ETDM2_OUT_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {"ETDM2_OUT_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + + {"DPTX_MCLK", NULL, APLL1_W_NAME, mtk_afe_mclk_apll_connect}, + {"DPTX_MCLK", NULL, APLL2_W_NAME, mtk_afe_mclk_apll_connect}, + /* cg */ {"ETDM1_IN", NULL, "ETDM1_IN_CG"}, {"ETDM1_IN", NULL, "ETDM2_IN_CG", mtk_etdm_cowork_connect}, @@ -1308,6 +1407,21 @@ static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] = { {"DPTX", NULL, "ETDM3_OUT_EN"}, {"DPTX", NULL, "DPTX_EN"}, + {"ETDM1_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect}, + {"ETDM1_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect}, + + {"ETDM2_IN_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect}, + {"ETDM2_IN_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect}, + + {"ETDM1_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect}, + {"ETDM1_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect}, + + {"ETDM2_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect}, + {"ETDM2_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect}, + + {"ETDM3_OUT_EN", NULL, APLL1_W_NAME, mtk_afe_etdm_apll_connect}, + {"ETDM3_OUT_EN", NULL, APLL2_W_NAME, mtk_afe_etdm_apll_connect}, + {"I012", NULL, "ETDM2_IN"}, {"I013", NULL, "ETDM2_IN"}, {"I014", NULL, "ETDM2_IN"}, @@ -2004,6 +2118,7 @@ static int mtk_dai_etdm_configure(struct mtk_base_afe *afe, return -EINVAL; etdm_data = afe_priv->dai_priv[dai_id]; slave_mode = etdm_data->slave_mode; + etdm_data->rate = rate; ret = get_etdm_reg(dai_id, &etdm_reg); if (ret < 0) From patchwork Wed May 10 03:55:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Wu X-Patchwork-Id: 680733 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D87F3C7EE26 for ; Wed, 10 May 2023 03:56:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236055AbjEJD4v (ORCPT ); Tue, 9 May 2023 23:56:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53438 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235728AbjEJDzn (ORCPT ); Tue, 9 May 2023 23:55:43 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B17D40F4; Tue, 9 May 2023 20:55:37 -0700 (PDT) X-UUID: 8172b0beeee611ed9cb5633481061a41-20230510 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=iQxj2f8v6Hq2mM43K9p34deiZ+cOeCScETZMUSLPaL4=; b=hdbRCgfhW2JZxzEkeqodgJ5IPBIlHzOdVnsWFsisVl+AA0q6rfbQujIQjEtBZVu9IoDrv0izqkByD6U9TL/WtjXqomJKJCfdv0jnZoUAcXV9VyfINo36Fj0bVL4tDfWiBFBrG/YTPfJDSTkFMVXlmGk1jYAJIWrxMOAuYdegzb4=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.24, REQID:6acb1ce6-a0e7-4efd-a9e9-0ef1c84326bf, IP:0, U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:178d4d4, CLOUDID:ac6758c0-e32c-4c97-918d-fbb3fc224d4e, B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-UUID: 8172b0beeee611ed9cb5633481061a41-20230510 Received: from mtkmbs13n2.mediatek.inc [(172.21.101.108)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1120389062; Wed, 10 May 2023 11:55:30 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs11n1.mediatek.inc (172.21.101.185) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 10 May 2023 11:55:28 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 10 May 2023 11:55:28 +0800 From: Trevor Wu To: , , , , , , , CC: , , , , , Subject: [PATCH v4 5/9] ASoC: mediatek: mt8188: combine afe component registration Date: Wed, 10 May 2023 11:55:22 +0800 Message-ID: <20230510035526.18137-6-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230510035526.18137-1-trevor.wu@mediatek.com> References: <20230510035526.18137-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org There is no benefit to separate two components for AFE, so DAI driver registration is moved to dev_snd_soc_register_component to merge these two components. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 37 ++-------------------- 1 file changed, 2 insertions(+), 35 deletions(-) diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c index e5f9373bed56..fecc891f892d 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c @@ -1898,10 +1898,6 @@ static const struct snd_kcontrol_new mt8188_memif_controls[] = { MT8188_AFE_MEMIF_UL10), }; -static const struct snd_soc_component_driver mt8188_afe_pcm_dai_component = { - .name = "mt8188-afe-pcm-dai", -}; - static const struct mtk_base_memif_data memif_data[MT8188_AFE_MEMIF_NUM] = { [MT8188_AFE_MEMIF_DL2] = { .name = "DL2", @@ -3142,9 +3138,8 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev) struct mtk_base_afe *afe; struct mt8188_afe_private *afe_priv; struct device *dev; - int i, irq_id, ret; - struct snd_soc_component *component; struct reset_control *rstc; + int i, irq_id, ret; ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); if (ret) @@ -3280,34 +3275,12 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev) /* register component */ ret = devm_snd_soc_register_component(dev, &mt8188_afe_component, - NULL, 0); + afe->dai_drivers, afe->num_dai_drivers); if (ret) { dev_warn(dev, "err_platform\n"); goto err_pm_put; } - component = devm_kzalloc(&pdev->dev, sizeof(*component), GFP_KERNEL); - if (!component) { - ret = -ENOMEM; - goto err_pm_put; - } - - ret = snd_soc_component_initialize(component, - &mt8188_afe_pcm_dai_component, - &pdev->dev); - if (ret) - goto err_pm_put; -#ifdef CONFIG_DEBUG_FS - component->debugfs_prefix = "pcm"; -#endif - ret = snd_soc_add_component(component, - afe->dai_drivers, - afe->num_dai_drivers); - if (ret) { - dev_warn(dev, "err_add_component\n"); - goto err_pm_put; - } - mt8188_afe_init_registers(afe); pm_runtime_put_sync(&pdev->dev); @@ -3323,11 +3296,6 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev) return ret; } -static void mt8188_afe_pcm_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_component(&pdev->dev); -} - static const struct of_device_id mt8188_afe_pcm_dt_match[] = { { .compatible = "mediatek,mt8188-afe", }, {}, @@ -3346,7 +3314,6 @@ static struct platform_driver mt8188_afe_pcm_driver = { .pm = &mt8188_afe_pm_ops, }, .probe = mt8188_afe_pcm_dev_probe, - .remove_new = mt8188_afe_pcm_dev_remove, }; module_platform_driver(mt8188_afe_pcm_driver); From patchwork Wed May 10 03:55:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trevor Wu X-Patchwork-Id: 680732 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7C4F3C77B7C for ; Wed, 10 May 2023 03:56:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236062AbjEJD44 (ORCPT ); Tue, 9 May 2023 23:56:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235979AbjEJDzo (ORCPT ); Tue, 9 May 2023 23:55:44 -0400 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8786726BD; Tue, 9 May 2023 20:55:39 -0700 (PDT) X-UUID: 81146b44eee611ed9cb5633481061a41-20230510 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=RVqtcIPzTn3ljgLNBGF6OLNjNa9bEk34VJBl1FNNCT0=; b=b9eW2EXphONo1Uoy14RVJKM4NcF9d6BaZcfjr50MT8yn/xQA0D3quuf0OvYVfNxdrp+p3jaHOjRRe7Nl0ORqU8QEufVjLWFZjKSuR3ztcM8fboskxfwULf7rKup8tqRD4p0F0YMtnoyULXT3XwoEbxyCCPbJihpWgSRyfyExwKY=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.24, REQID:7517cf65-c52e-4f94-8bc5-547949a24eee, IP:0, U RL:0,TC:0,Content:0,EDM:0,RT:0,SF:95,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:95 X-CID-INFO: VERSION:1.1.24, REQID:7517cf65-c52e-4f94-8bc5-547949a24eee, IP:0, URL :0,TC:0,Content:0,EDM:0,RT:0,SF:95,FILE:0,BULK:0,RULE:Spam_GS981B3D,ACTION :quarantine,TS:95 X-CID-META: VersionHash:178d4d4, CLOUDID:7a1d516b-2f20-4998-991c-3b78627e4938, B ulkID:230510115532FJG4VNBW,BulkQuantity:0,Recheck:0,SF:29|28|17|19|48|38,T C:nil,Content:0,EDM:-3,IP:nil,URL:0,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0 ,OSI:0,OSA:0,AV:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-UUID: 81146b44eee611ed9cb5633481061a41-20230510 Received: from mtkmbs13n1.mediatek.inc [(172.21.101.193)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 831875863; Wed, 10 May 2023 11:55:29 +0800 Received: from mtkmbs13n2.mediatek.inc (172.21.101.108) by mtkmbs10n2.mediatek.inc (172.21.101.183) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 10 May 2023 11:55:28 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n2.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 10 May 2023 11:55:28 +0800 From: Trevor Wu To: , , , , , , , CC: , , , , , Subject: [PATCH v4 6/9] ASoC: mediatek: mt8188: add bus protection Date: Wed, 10 May 2023 11:55:23 +0800 Message-ID: <20230510035526.18137-7-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20230510035526.18137-1-trevor.wu@mediatek.com> References: <20230510035526.18137-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Add bus protection for reset controller. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8188/mt8188-afe-pcm.c | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c index fecc891f892d..c3fd32764da0 100644 --- a/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c +++ b/sound/soc/mediatek/mt8188/mt8188-afe-pcm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include "mt8188-afe-common.h" @@ -3133,12 +3134,68 @@ static int mt8188_afe_parse_of(struct mtk_base_afe *afe, return 0; } +#define MT8188_DELAY_US 10 +#define MT8188_TIMEOUT_US USEC_PER_SEC + +static int bus_protect_enable(struct regmap *regmap) +{ + int ret; + u32 val; + u32 mask; + + val = 0; + mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1; + regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask); + + ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA, + val, (val & mask) == mask, + MT8188_DELAY_US, MT8188_TIMEOUT_US); + if (ret) + return ret; + + val = 0; + mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2; + regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_SET, mask); + + ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA, + val, (val & mask) == mask, + MT8188_DELAY_US, MT8188_TIMEOUT_US); + return ret; +} + +static int bus_protect_disable(struct regmap *regmap) +{ + int ret; + u32 val; + u32 mask; + + val = 0; + mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP2; + regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask); + + ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA, + val, !(val & mask), + MT8188_DELAY_US, MT8188_TIMEOUT_US); + if (ret) + return ret; + + val = 0; + mask = MT8188_TOP_AXI_PROT_EN_2_AUDIO_STEP1; + regmap_write(regmap, MT8188_TOP_AXI_PROT_EN_2_CLR, mask); + + ret = regmap_read_poll_timeout(regmap, MT8188_TOP_AXI_PROT_EN_2_STA, + val, !(val & mask), + MT8188_DELAY_US, MT8188_TIMEOUT_US); + return ret; +} + static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev) { struct mtk_base_afe *afe; struct mt8188_afe_private *afe_priv; struct device *dev; struct reset_control *rstc; + struct regmap *infra_ao; int i, irq_id, ret; ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(33)); @@ -3163,18 +3220,37 @@ static int mt8188_afe_pcm_dev_probe(struct platform_device *pdev) return dev_err_probe(dev, PTR_ERR(afe->base_addr), "AFE base_addr not found\n"); + infra_ao = syscon_regmap_lookup_by_phandle(dev->of_node, + "mediatek,infracfg"); + if (IS_ERR(infra_ao)) + return dev_err_probe(dev, PTR_ERR(infra_ao), + "%s() Cannot find infra_ao controller\n", + __func__); + /* reset controller to reset audio regs before regmap cache */ rstc = devm_reset_control_get_exclusive(dev, "audiosys"); if (IS_ERR(rstc)) return dev_err_probe(dev, PTR_ERR(rstc), "could not get audiosys reset\n"); + ret = bus_protect_enable(infra_ao); + if (ret) { + dev_err(dev, "bus_protect_enable failed\n"); + return ret; + } + ret = reset_control_reset(rstc); if (ret) { dev_err(dev, "failed to trigger audio reset:%d\n", ret); return ret; } + ret = bus_protect_disable(infra_ao); + if (ret) { + dev_err(dev, "bus_protect_disable failed\n"); + return ret; + } + /* initial audio related clock */ ret = mt8188_afe_init_clock(afe); if (ret)