From patchwork Thu Aug 19 08:41:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446615 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 61AD4C432BE for ; Thu, 19 Aug 2021 08:46:15 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 29D1F60E90 for ; Thu, 19 Aug 2021 08:46:15 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 29D1F60E90 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=3qZ+a2gPzJQWilHHF3rimj8zclWAYuRxgNoctly5yn4=; b=jOqA7+3rgMR3b2 sLW9cr9bCgIcW2PgMS0aHGhrxopbn1qH9V7/HTaYVF/QC4tnnSWgMQzdgMxUsire7draPhpOs6VH+ YR5ysZVf+Qdd6N+w/2Hc+wAM/pHj2iV9R4t4lJN5XZua2LWlmyYcKiGywjVsbJs5pGYrqgPtqcZAj VSH/iXkPs8XoN1g/62ck98Mq3DlWPNTq/0bCXLrCa84AM8IS3WzdJOmkjPoW2YcHgRLJmbcdjq1ct IXyB7YQLApYWLJGotaAdBh9dyxajDl/f4gakbvNZzclvoumjZebOsPYLUhvP6OKMbZXB75qj7RbtM Kje4tmKJeOBfZIU6fTTw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGde0-007iXn-A7; Thu, 19 Aug 2021 08:43:24 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGddt-007iUo-Qp; Thu, 19 Aug 2021 08:43:21 +0000 X-UUID: 65b1c4fa1b2f433f88364237e3e99a09-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=TEzVbA6H9OgqKrUI1gVwrs0AjxSfMMwErSeyQnhWNTI=; b=tVnoRDdwl81sl2VFSneN8vOQxEKCTZrhB831IF6skCrrC22VtnI+7avq3wytH69Y8kjs8iTXNaZwek36yfB4SoyXI+7Licv6xX0tXxy7uArkg3ZdCXHkd0VwU4fGIQqXJHR9bL/wAuPV0U/hu+AAsJ7QO8lNe4RUwtaKQ/RxG8U=; X-UUID: 65b1c4fa1b2f433f88364237e3e99a09-20210819 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1053516413; Thu, 19 Aug 2021 01:43:11 -0700 Received: from mtkmbs05n1.mediatek.inc (172.21.101.15) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:09 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n1.mediatek.inc (172.21.101.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:08 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:08 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 01/11] ASoC: mediatek: mt8195: update mediatek common driver Date: Thu, 19 Aug 2021 16:41:34 +0800 Message-ID: <20210819084144.18483-2-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014317_946497_3B631095 X-CRM114-Status: GOOD ( 14.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Update mediatek common driver to support MT8195 Signed-off-by: Trevor Wu Reported-by: kernel test robot --- sound/soc/mediatek/common/mtk-afe-fe-dai.c | 22 +++++++++++++++++++--- sound/soc/mediatek/common/mtk-base-afe.h | 10 ++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediatek/common/mtk-afe-fe-dai.c index 3cb2adf420bb..baaa5881b1d4 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c @@ -139,7 +139,7 @@ int mtk_afe_fe_hw_params(struct snd_pcm_substream *substream, substream->runtime->dma_area, substream->runtime->dma_bytes); - memset_io(substream->runtime->dma_area, 0, + memset_io((void __force __iomem *)substream->runtime->dma_area, 0, substream->runtime->dma_bytes); /* set addr */ @@ -433,11 +433,20 @@ int mtk_memif_set_addr(struct mtk_base_afe *afe, int id, phys_buf_addr_upper_32); } - /* set MSB to 33-bit */ - if (memif->data->msb_reg >= 0) + /* + * set MSB to 33-bit, for memif address + * only for memif base address, if msb_end_reg exists + */ + if (memif->data->msb_reg) mtk_regmap_update_bits(afe->regmap, memif->data->msb_reg, 1, msb_at_bit33, memif->data->msb_shift); + /* set MSB to 33-bit, for memif end address */ + if (memif->data->msb_end_reg) + mtk_regmap_update_bits(afe->regmap, memif->data->msb_end_reg, + 1, msb_at_bit33, + memif->data->msb_end_shift); + return 0; } EXPORT_SYMBOL_GPL(mtk_memif_set_addr); @@ -464,6 +473,13 @@ int mtk_memif_set_channel(struct mtk_base_afe *afe, else mono = (channel == 1) ? 1 : 0; + /* for specific configuration of memif mono mode */ + if (memif->data->int_odd_flag_reg) + mtk_regmap_update_bits(afe->regmap, + memif->data->int_odd_flag_reg, + 1, mono, + memif->data->int_odd_flag_shift); + return mtk_regmap_update_bits(afe->regmap, memif->data->mono_reg, 1, mono, memif->data->mono_shift); } diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/common/mtk-base-afe.h index a6f68c68581c..ef83e78c22a8 100644 --- a/sound/soc/mediatek/common/mtk-base-afe.h +++ b/sound/soc/mediatek/common/mtk-base-afe.h @@ -29,6 +29,8 @@ struct mtk_base_memif_data { int quad_ch_reg; int quad_ch_mask; int quad_ch_shift; + int int_odd_flag_reg; + int int_odd_flag_shift; int enable_reg; int enable_shift; int hd_reg; @@ -37,10 +39,13 @@ struct mtk_base_memif_data { int hd_align_mshift; int msb_reg; int msb_shift; - int msb2_reg; - int msb2_shift; + int msb_end_reg; + int msb_end_shift; int agent_disable_reg; int agent_disable_shift; + int ch_num_reg; + int ch_num_shift; + int ch_num_maskbit; /* playback memif only */ int pbuf_reg; int pbuf_mask; @@ -62,6 +67,7 @@ struct mtk_base_irq_data { int irq_en_shift; int irq_clr_reg; int irq_clr_shift; + int irq_status_shift; }; struct device; From patchwork Thu Aug 19 08:41:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446623 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 33CD7C4338F for ; Thu, 19 Aug 2021 08:47:15 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F1BBA60E90 for ; Thu, 19 Aug 2021 08:47:14 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F1BBA60E90 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=fd4ZsnkkUEAfGo3ucVN5oAw4hhLf3MJjRMQis30EI9U=; b=fp6ET/IvXmczay 3B7/FmqB2sYF31X+9A8fRKRg+ZnuCLCkZMeoB5+OXXZEYTYMbJrms9KmH1nuFO+gIigrHViZr12O3 QSsHN5tQR5R3j7L5YveIPO098K3Q7or84Gok9wN7fGAZHUGmQaIMk/IITV40/i+HHX9aEWGqMccPp 2eXVKHBKTHErdeLF1xgkmNfbNXRTyI9glzJtKTIztL7Pr4mmZJxTMdkXma550xprLtJynkHpEnW5n 5RwTFGNoj1g/ml29M2NmL8TmnJ8N43VvqfUU+rrMGqCqWDmYnzjivBWXARgfvKlf0LNUHgCpZ5tbI n+AjMg434q46fhuLnjXg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdft-007jPW-Oi; Thu, 19 Aug 2021 08:45:22 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGde1-007iVv-Mc; Thu, 19 Aug 2021 08:43:28 +0000 X-UUID: 26f18e638bde4310a6def9b9c61d556e-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=IXSmtchYV38Gja073mGHduofqeymDTyyl5YgCc1/tmk=; b=KMPMlD49y4kDNLOG/VRKuc8WeDdWeFi/JbLu3/fLKwdAthDZVDZ0+Yw0V+mPLBg3A4SIGxlvQ7OEmfpZ46MqFU3O224W5o+KsYHy1S+grm/zcYD+tJYdlUGYB2HW3g6aWorNpx/vIGsSQuCc0qwGOv/PnV3EdaOfBHsK/jjTatY=; X-UUID: 26f18e638bde4310a6def9b9c61d556e-20210819 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 163591647; Thu, 19 Aug 2021 01:43:11 -0700 Received: from mtkmbs05n2.mediatek.inc (172.21.101.140) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:10 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:08 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:08 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 02/11] ASoC: mediatek: mt8195: support audsys clock control Date: Thu, 19 Aug 2021 16:41:35 +0800 Message-ID: <20210819084144.18483-3-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014325_787750_895A89C6 X-CRM114-Status: GOOD ( 17.83 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds mt8195 audio cg control. Audio clock gates are registered to CCF for reference count and clock parent management. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-audsys-clk.c | 214 ++++++++++++++++++ sound/soc/mediatek/mt8195/mt8195-audsys-clk.h | 15 ++ .../soc/mediatek/mt8195/mt8195-audsys-clkid.h | 93 ++++++++ 3 files changed, 322 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.c create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clk.h create mode 100644 sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c new file mode 100644 index 000000000000..740aa6ddda0e --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.c @@ -0,0 +1,214 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * mt8195-audsys-clk.h -- Mediatek 8195 audsys clock control + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Trevor Wu + */ + +#include +#include +#include +#include "mt8195-afe-common.h" +#include "mt8195-audsys-clk.h" +#include "mt8195-audsys-clkid.h" +#include "mt8195-reg.h" + +struct afe_gate { + int id; + const char *name; + const char *parent_name; + int reg; + u8 bit; + const struct clk_ops *ops; + unsigned long flags; + u8 cg_flags; +}; + +#define GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, _flags, _cgflags) {\ + .id = _id, \ + .name = _name, \ + .parent_name = _parent, \ + .reg = _reg, \ + .bit = _bit, \ + .flags = _flags, \ + .cg_flags = _cgflags, \ + } + +#define GATE_AFE(_id, _name, _parent, _reg, _bit) \ + GATE_AFE_FLAGS(_id, _name, _parent, _reg, _bit, \ + CLK_SET_RATE_PARENT, CLK_GATE_SET_TO_DISABLE) + +#define GATE_AUD0(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON0, _bit) + +#define GATE_AUD1(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON1, _bit) + +#define GATE_AUD3(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON3, _bit) + +#define GATE_AUD4(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON4, _bit) + +#define GATE_AUD5(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON5, _bit) + +#define GATE_AUD6(_id, _name, _parent, _bit) \ + GATE_AFE(_id, _name, _parent, AUDIO_TOP_CON6, _bit) + +static const struct afe_gate aud_clks[CLK_AUD_NR_CLK] = { + /* AUD0 */ + GATE_AUD0(CLK_AUD_AFE, "aud_afe", "a1sys_hp_sel", 2), + GATE_AUD0(CLK_AUD_LRCK_CNT, "aud_lrck_cnt", "a1sys_hp_sel", 4), + GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_APLL, "aud_spdifin_tuner_apll", "apll4_sel", 10), + GATE_AUD0(CLK_AUD_SPDIFIN_TUNER_DBG, "aud_spdifin_tuner_dbg", "apll4_sel", 11), + GATE_AUD0(CLK_AUD_UL_TML, "aud_ul_tml", "a1sys_hp_sel", 18), + GATE_AUD0(CLK_AUD_APLL1_TUNER, "aud_apll1_tuner", "apll1_sel", 19), + GATE_AUD0(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "apll2_sel", 20), + GATE_AUD0(CLK_AUD_TOP0_SPDF, "aud_top0_spdf", "aud_iec_sel", 21), + GATE_AUD0(CLK_AUD_APLL, "aud_apll", "apll1_sel", 23), + GATE_AUD0(CLK_AUD_APLL2, "aud_apll2", "apll2_sel", 24), + GATE_AUD0(CLK_AUD_DAC, "aud_dac", "a1sys_hp_sel", 25), + GATE_AUD0(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "a1sys_hp_sel", 26), + GATE_AUD0(CLK_AUD_TML, "aud_tml", "a1sys_hp_sel", 27), + GATE_AUD0(CLK_AUD_ADC, "aud_adc", "a1sys_hp_sel", 28), + GATE_AUD0(CLK_AUD_DAC_HIRES, "aud_dac_hires", "audio_h_sel", 31), + + /* AUD1 */ + GATE_AUD1(CLK_AUD_A1SYS_HP, "aud_a1sys_hp", "a1sys_hp_sel", 2), + GATE_AUD1(CLK_AUD_AFE_DMIC1, "aud_afe_dmic1", "a1sys_hp_sel", 10), + GATE_AUD1(CLK_AUD_AFE_DMIC2, "aud_afe_dmic2", "a1sys_hp_sel", 11), + GATE_AUD1(CLK_AUD_AFE_DMIC3, "aud_afe_dmic3", "a1sys_hp_sel", 12), + GATE_AUD1(CLK_AUD_AFE_DMIC4, "aud_afe_dmic4", "a1sys_hp_sel", 13), + GATE_AUD1(CLK_AUD_AFE_26M_DMIC_TM, "aud_afe_26m_dmic_tm", "a1sys_hp_sel", 14), + GATE_AUD1(CLK_AUD_UL_TML_HIRES, "aud_ul_tml_hires", "audio_h_sel", 16), + GATE_AUD1(CLK_AUD_ADC_HIRES, "aud_adc_hires", "audio_h_sel", 17), + GATE_AUD1(CLK_AUD_ADDA6_ADC, "aud_adda6_adc", "a1sys_hp_sel", 18), + GATE_AUD1(CLK_AUD_ADDA6_ADC_HIRES, "aud_adda6_adc_hires", "audio_h_sel", 19), + + /* AUD3 */ + GATE_AUD3(CLK_AUD_LINEIN_TUNER, "aud_linein_tuner", "apll5_sel", 5), + GATE_AUD3(CLK_AUD_EARC_TUNER, "aud_earc_tuner", "apll3_sel", 7), + + /* AUD4 */ + GATE_AUD4(CLK_AUD_I2SIN, "aud_i2sin", "a1sys_hp_sel", 0), + GATE_AUD4(CLK_AUD_TDM_IN, "aud_tdm_in", "a1sys_hp_sel", 1), + GATE_AUD4(CLK_AUD_I2S_OUT, "aud_i2s_out", "a1sys_hp_sel", 6), + GATE_AUD4(CLK_AUD_TDM_OUT, "aud_tdm_out", "a1sys_hp_sel", 7), + GATE_AUD4(CLK_AUD_HDMI_OUT, "aud_hdmi_out", "a1sys_hp_sel", 8), + GATE_AUD4(CLK_AUD_ASRC11, "aud_asrc11", "a1sys_hp_sel", 16), + GATE_AUD4(CLK_AUD_ASRC12, "aud_asrc12", "a1sys_hp_sel", 17), + GATE_AUD4(CLK_AUD_MULTI_IN, "aud_multi_in", "mphone_slave_b", 19), + GATE_AUD4(CLK_AUD_INTDIR, "aud_intdir", "intdir_sel", 20), + GATE_AUD4(CLK_AUD_A1SYS, "aud_a1sys", "a1sys_hp_sel", 21), + GATE_AUD4(CLK_AUD_A2SYS, "aud_a2sys", "a2sys_sel", 22), + GATE_AUD4(CLK_AUD_PCMIF, "aud_pcmif", "a1sys_hp_sel", 24), + GATE_AUD4(CLK_AUD_A3SYS, "aud_a3sys", "a3sys_sel", 30), + GATE_AUD4(CLK_AUD_A4SYS, "aud_a4sys", "a4sys_sel", 31), + + /* AUD5 */ + GATE_AUD5(CLK_AUD_MEMIF_UL1, "aud_memif_ul1", "a1sys_hp_sel", 0), + GATE_AUD5(CLK_AUD_MEMIF_UL2, "aud_memif_ul2", "a1sys_hp_sel", 1), + GATE_AUD5(CLK_AUD_MEMIF_UL3, "aud_memif_ul3", "a1sys_hp_sel", 2), + GATE_AUD5(CLK_AUD_MEMIF_UL4, "aud_memif_ul4", "a1sys_hp_sel", 3), + GATE_AUD5(CLK_AUD_MEMIF_UL5, "aud_memif_ul5", "a1sys_hp_sel", 4), + GATE_AUD5(CLK_AUD_MEMIF_UL6, "aud_memif_ul6", "a1sys_hp_sel", 5), + GATE_AUD5(CLK_AUD_MEMIF_UL8, "aud_memif_ul8", "a1sys_hp_sel", 7), + GATE_AUD5(CLK_AUD_MEMIF_UL9, "aud_memif_ul9", "a1sys_hp_sel", 8), + GATE_AUD5(CLK_AUD_MEMIF_UL10, "aud_memif_ul10", "a1sys_hp_sel", 9), + GATE_AUD5(CLK_AUD_MEMIF_DL2, "aud_memif_dl2", "a1sys_hp_sel", 18), + GATE_AUD5(CLK_AUD_MEMIF_DL3, "aud_memif_dl3", "a1sys_hp_sel", 19), + GATE_AUD5(CLK_AUD_MEMIF_DL6, "aud_memif_dl6", "a1sys_hp_sel", 22), + GATE_AUD5(CLK_AUD_MEMIF_DL7, "aud_memif_dl7", "a1sys_hp_sel", 23), + GATE_AUD5(CLK_AUD_MEMIF_DL8, "aud_memif_dl8", "a1sys_hp_sel", 24), + GATE_AUD5(CLK_AUD_MEMIF_DL10, "aud_memif_dl10", "a1sys_hp_sel", 26), + GATE_AUD5(CLK_AUD_MEMIF_DL11, "aud_memif_dl11", "a1sys_hp_sel", 27), + + /* AUD6 */ + GATE_AUD6(CLK_AUD_GASRC0, "aud_gasrc0", "asm_h_sel", 0), + GATE_AUD6(CLK_AUD_GASRC1, "aud_gasrc1", "asm_h_sel", 1), + GATE_AUD6(CLK_AUD_GASRC2, "aud_gasrc2", "asm_h_sel", 2), + GATE_AUD6(CLK_AUD_GASRC3, "aud_gasrc3", "asm_h_sel", 3), + GATE_AUD6(CLK_AUD_GASRC4, "aud_gasrc4", "asm_h_sel", 4), + GATE_AUD6(CLK_AUD_GASRC5, "aud_gasrc5", "asm_h_sel", 5), + GATE_AUD6(CLK_AUD_GASRC6, "aud_gasrc6", "asm_h_sel", 6), + GATE_AUD6(CLK_AUD_GASRC7, "aud_gasrc7", "asm_h_sel", 7), + GATE_AUD6(CLK_AUD_GASRC8, "aud_gasrc8", "asm_h_sel", 8), + GATE_AUD6(CLK_AUD_GASRC9, "aud_gasrc9", "asm_h_sel", 9), + GATE_AUD6(CLK_AUD_GASRC10, "aud_gasrc10", "asm_h_sel", 10), + GATE_AUD6(CLK_AUD_GASRC11, "aud_gasrc11", "asm_h_sel", 11), + GATE_AUD6(CLK_AUD_GASRC12, "aud_gasrc12", "asm_h_sel", 12), + GATE_AUD6(CLK_AUD_GASRC13, "aud_gasrc13", "asm_h_sel", 13), + GATE_AUD6(CLK_AUD_GASRC14, "aud_gasrc14", "asm_h_sel", 14), + GATE_AUD6(CLK_AUD_GASRC15, "aud_gasrc15", "asm_h_sel", 15), + GATE_AUD6(CLK_AUD_GASRC16, "aud_gasrc16", "asm_h_sel", 16), + GATE_AUD6(CLK_AUD_GASRC17, "aud_gasrc17", "asm_h_sel", 17), + GATE_AUD6(CLK_AUD_GASRC18, "aud_gasrc18", "asm_h_sel", 18), + GATE_AUD6(CLK_AUD_GASRC19, "aud_gasrc19", "asm_h_sel", 19), +}; + +int mt8195_audsys_clk_register(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct clk *clk; + struct clk_lookup *cl; + int i; + + afe_priv->lookup = devm_kcalloc(afe->dev, CLK_AUD_NR_CLK, + sizeof(*afe_priv->lookup), + GFP_KERNEL); + + if (!afe_priv->lookup) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(aud_clks); i++) { + const struct afe_gate *gate = &aud_clks[i]; + + clk = clk_register_gate(afe->dev, gate->name, gate->parent_name, + gate->flags, afe->base_addr + gate->reg, + gate->bit, gate->cg_flags, NULL); + + if (IS_ERR(clk)) { + dev_err(afe->dev, "Failed to register clk %s: %ld\n", + gate->name, PTR_ERR(clk)); + continue; + } + + /* add clk_lookup for devm_clk_get(SND_SOC_DAPM_CLOCK_SUPPLY) */ + cl = kzalloc(sizeof(*cl), GFP_KERNEL); + if (!cl) + return -ENOMEM; + + cl->clk = clk; + cl->con_id = gate->name; + cl->dev_id = dev_name(afe->dev); + clkdev_add(cl); + + afe_priv->lookup[i] = cl; + } + + return 0; +} + +void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct clk *clk; + struct clk_lookup *cl; + int i; + + if (!afe_priv) + return; + + for (i = 0; i < CLK_AUD_NR_CLK; i++) { + cl = afe_priv->lookup[i]; + if (!cl) + continue; + + clk = cl->clk; + clk_unregister_gate(clk); + + clkdev_drop(cl); + } +} diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h new file mode 100644 index 000000000000..239d31016ba7 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clk.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-audsys-clk.h -- Mediatek 8195 audsys clock definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Trevor Wu + */ + +#ifndef _MT8195_AUDSYS_CLK_H_ +#define _MT8195_AUDSYS_CLK_H_ + +int mt8195_audsys_clk_register(struct mtk_base_afe *afe); +void mt8195_audsys_clk_unregister(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h new file mode 100644 index 000000000000..4dd0a5c8b8fa --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-audsys-clkid.h @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * mt8195-audsys-clkid.h -- Mediatek 8195 audsys clock id definition + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Trevor Wu + */ + +#ifndef _MT8195_AUDSYS_CLKID_H_ +#define _MT8195_AUDSYS_CLKID_H_ + +enum{ + CLK_AUD_AFE, + CLK_AUD_LRCK_CNT, + CLK_AUD_SPDIFIN_TUNER_APLL, + CLK_AUD_SPDIFIN_TUNER_DBG, + CLK_AUD_UL_TML, + CLK_AUD_APLL1_TUNER, + CLK_AUD_APLL2_TUNER, + CLK_AUD_TOP0_SPDF, + CLK_AUD_APLL, + CLK_AUD_APLL2, + CLK_AUD_DAC, + CLK_AUD_DAC_PREDIS, + CLK_AUD_TML, + CLK_AUD_ADC, + CLK_AUD_DAC_HIRES, + CLK_AUD_A1SYS_HP, + CLK_AUD_AFE_DMIC1, + CLK_AUD_AFE_DMIC2, + CLK_AUD_AFE_DMIC3, + CLK_AUD_AFE_DMIC4, + CLK_AUD_AFE_26M_DMIC_TM, + CLK_AUD_UL_TML_HIRES, + CLK_AUD_ADC_HIRES, + CLK_AUD_ADDA6_ADC, + CLK_AUD_ADDA6_ADC_HIRES, + CLK_AUD_LINEIN_TUNER, + CLK_AUD_EARC_TUNER, + CLK_AUD_I2SIN, + CLK_AUD_TDM_IN, + CLK_AUD_I2S_OUT, + CLK_AUD_TDM_OUT, + CLK_AUD_HDMI_OUT, + CLK_AUD_ASRC11, + CLK_AUD_ASRC12, + CLK_AUD_MULTI_IN, + CLK_AUD_INTDIR, + CLK_AUD_A1SYS, + CLK_AUD_A2SYS, + CLK_AUD_PCMIF, + CLK_AUD_A3SYS, + CLK_AUD_A4SYS, + CLK_AUD_MEMIF_UL1, + CLK_AUD_MEMIF_UL2, + CLK_AUD_MEMIF_UL3, + CLK_AUD_MEMIF_UL4, + CLK_AUD_MEMIF_UL5, + CLK_AUD_MEMIF_UL6, + CLK_AUD_MEMIF_UL8, + CLK_AUD_MEMIF_UL9, + CLK_AUD_MEMIF_UL10, + CLK_AUD_MEMIF_DL2, + CLK_AUD_MEMIF_DL3, + CLK_AUD_MEMIF_DL6, + CLK_AUD_MEMIF_DL7, + CLK_AUD_MEMIF_DL8, + CLK_AUD_MEMIF_DL10, + CLK_AUD_MEMIF_DL11, + CLK_AUD_GASRC0, + CLK_AUD_GASRC1, + CLK_AUD_GASRC2, + CLK_AUD_GASRC3, + CLK_AUD_GASRC4, + CLK_AUD_GASRC5, + CLK_AUD_GASRC6, + CLK_AUD_GASRC7, + CLK_AUD_GASRC8, + CLK_AUD_GASRC9, + CLK_AUD_GASRC10, + CLK_AUD_GASRC11, + CLK_AUD_GASRC12, + CLK_AUD_GASRC13, + CLK_AUD_GASRC14, + CLK_AUD_GASRC15, + CLK_AUD_GASRC16, + CLK_AUD_GASRC17, + CLK_AUD_GASRC18, + CLK_AUD_GASRC19, + CLK_AUD_NR_CLK, +}; + +#endif From patchwork Thu Aug 19 08:41:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446629 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 26591C4338F for ; Thu, 19 Aug 2021 08:49:23 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E2F0361106 for ; Thu, 19 Aug 2021 08:49:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org E2F0361106 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=fmNN8MitDmRYaC0lkp1fTdW0fkc0vD9o8ZjP5qDSz8I=; b=fpjUwIaLa937qW KGzuv4fRLbgciozPiPV3Z+N8YFXnp6TsD0w07tkUt6HmGySBsbH5quZKhEBNdUhJc/hDT8SKt+gRM JBx1/ycvs4eEJ8ua55aiBOmS106OR9xPQzqbxXVCee5XLfPHXy2pM6GLhl5ZcUl8FYcCsCc+ZXQBV 6f8kwZ6R34Z9kAX25vVlQb/NVgO1fp7KLg5BvhCECsDVEqmedBETRc5cnedbl/XqeYL0MZ8icjZbW xExbLPPEqoRe+kVpZqbVkwIg6003kDyT77kTTtnEDqBCmg3DnLEhAWumlLnmXox1KosvffcLLI2Es 6btudyBsiBvS/gCGoQhg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdhH-007kEw-GQ; Thu, 19 Aug 2021 08:46:47 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGde4-007iVH-LE; Thu, 19 Aug 2021 08:43:32 +0000 X-UUID: 3f1e15f94a0442258f809cc603fae240-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=V+MYQvssVLnX/IVH2qIySe1GnbQ9c8N3Cf6xUrSHTC4=; b=sIzIoHWRP/GtJMZ5GfigID0Q8R5pUNzxAj7qj2wdWaObqGVlfsGDK70xs4PfyrAqh58ppJyqsnq/VZ03RmdyjHz6FyGNcZeyQ8zc2+FETRctifU/hOAEqzZSVLrZCGkVGP1pceWBmO4smt90JQgWwyGFxARoVfiwjUspt6zFWxc=; X-UUID: 3f1e15f94a0442258f809cc603fae240-20210819 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 850943149; Thu, 19 Aug 2021 01:43:11 -0700 Received: from mtkmbs05n2.mediatek.inc (172.21.101.140) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:10 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:09 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:08 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 04/11] ASoC: mediatek: mt8195: support adda in platform driver Date: Thu, 19 Aug 2021 16:41:37 +0800 Message-ID: <20210819084144.18483-5-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014328_782452_D0FE815F X-CRM114-Status: GOOD ( 19.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds mt8195 adda dai driver. audio_h clock is used by ADSP bus and ADDA module. When ADDA requires audio_h clock, it is switched to APLL1, otherwise it is switched to Xtal_26m so that APLL1 can be turned off when audio feature is not used. ADSP bus only requires that the clock is on, so dynamic reparenting is used for the purpose of lowering power consumption. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-dai-adda.c | 830 ++++++++++++++++++++ 1 file changed, 830 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-adda.c diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-adda.c b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c new file mode 100644 index 000000000000..878dec0b69ed --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-dai-adda.c @@ -0,0 +1,830 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI ADDA Control + * + * Copyright (c) 2021 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include +#include +#include "mt8195-afe-clk.h" +#include "mt8195-afe-common.h" +#include "mt8195-reg.h" + +#define ADDA_DL_GAIN_LOOPBACK 0x1800 +#define ADDA_HIRES_THRES 48000 + +enum { + SUPPLY_SEQ_CLOCK_SEL, + SUPPLY_SEQ_CLOCK_ON, + SUPPLY_SEQ_ADDA_DL_ON, + SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SUPPLY_SEQ_ADDA_UL_ON, + SUPPLY_SEQ_ADDA_AFE_ON, +}; + +enum { + MTK_AFE_ADDA_DL_RATE_8K = 0, + MTK_AFE_ADDA_DL_RATE_11K = 1, + MTK_AFE_ADDA_DL_RATE_12K = 2, + MTK_AFE_ADDA_DL_RATE_16K = 3, + MTK_AFE_ADDA_DL_RATE_22K = 4, + MTK_AFE_ADDA_DL_RATE_24K = 5, + MTK_AFE_ADDA_DL_RATE_32K = 6, + MTK_AFE_ADDA_DL_RATE_44K = 7, + MTK_AFE_ADDA_DL_RATE_48K = 8, + MTK_AFE_ADDA_DL_RATE_96K = 9, + MTK_AFE_ADDA_DL_RATE_192K = 10, +}; + +enum { + MTK_AFE_ADDA_UL_RATE_8K = 0, + MTK_AFE_ADDA_UL_RATE_16K = 1, + MTK_AFE_ADDA_UL_RATE_32K = 2, + MTK_AFE_ADDA_UL_RATE_48K = 3, + MTK_AFE_ADDA_UL_RATE_96K = 4, + MTK_AFE_ADDA_UL_RATE_192K = 5, +}; + +enum { + DELAY_DATA_MISO1 = 0, + DELAY_DATA_MISO0 = 1, + DELAY_DATA_MISO2 = 1, +}; + +enum { + MTK_AFE_ADDA, + MTK_AFE_ADDA6, +}; + +struct mtk_dai_adda_priv { + bool hires_required; +}; + +static unsigned int afe_adda_dl_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_DL_RATE_8K; + case 11025: + return MTK_AFE_ADDA_DL_RATE_11K; + case 12000: + return MTK_AFE_ADDA_DL_RATE_12K; + case 16000: + return MTK_AFE_ADDA_DL_RATE_16K; + case 22050: + return MTK_AFE_ADDA_DL_RATE_22K; + case 24000: + return MTK_AFE_ADDA_DL_RATE_24K; + case 32000: + return MTK_AFE_ADDA_DL_RATE_32K; + case 44100: + return MTK_AFE_ADDA_DL_RATE_44K; + case 48000: + return MTK_AFE_ADDA_DL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_DL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_DL_RATE_192K; + default: + dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_DL_RATE_48K; + } +} + +static unsigned int afe_adda_ul_rate_transform(struct mtk_base_afe *afe, + unsigned int rate) +{ + switch (rate) { + case 8000: + return MTK_AFE_ADDA_UL_RATE_8K; + case 16000: + return MTK_AFE_ADDA_UL_RATE_16K; + case 32000: + return MTK_AFE_ADDA_UL_RATE_32K; + case 48000: + return MTK_AFE_ADDA_UL_RATE_48K; + case 96000: + return MTK_AFE_ADDA_UL_RATE_96K; + case 192000: + return MTK_AFE_ADDA_UL_RATE_192K; + default: + dev_info(afe->dev, "%s(), rate %d invalid, use 48kHz!!!\n", + __func__, rate); + return MTK_AFE_ADDA_UL_RATE_48K; + } +} + +static int mt8195_adda_mtkaif_init(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + int delay_data; + int delay_cycle; + unsigned int mask = 0; + unsigned int val = 0; + + /* set rx protocol 2 & mtkaif_rxif_clkinv_adc inverse */ + mask = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2); + val = (MTKAIF_RXIF_CLKINV_ADC | MTKAIF_RXIF_PROTOCOL2); + + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_CFG0, mask, val); + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_CFG0, mask, val); + + mask = RG_RX_PROTOCOL2; + val = RG_RX_PROTOCOL2; + regmap_update_bits(afe->regmap, AFE_AUD_PAD_TOP, mask, val); + + if (!param->mtkaif_calibration_ok) { + dev_info(afe->dev, "%s(), calibration fail\n", __func__); + return 0; + } + + /* set delay for ch1, ch2 */ + if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] >= + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]; + } else { + delay_data = DELAY_DATA_MISO0; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0]; + } + + val = 0; + mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK); + val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) & + MTKAIF_RXIF_DELAY_CYCLE_MASK; + val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT; + regmap_update_bits(afe->regmap, AFE_ADDA_MTKAIF_RX_CFG2, mask, val); + + /* set delay between ch3 and ch2 */ + if (param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] >= + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]) { + delay_data = DELAY_DATA_MISO1; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1]; + } else { + delay_data = DELAY_DATA_MISO2; + delay_cycle = + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] - + param->mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2]; + } + + val = 0; + mask = (MTKAIF_RXIF_DELAY_DATA | MTKAIF_RXIF_DELAY_CYCLE_MASK); + val |= MTKAIF_RXIF_DELAY_CYCLE(delay_cycle) & + MTKAIF_RXIF_DELAY_CYCLE_MASK; + val |= delay_data << MTKAIF_RXIF_DELAY_DATA_SHIFT; + regmap_update_bits(afe->regmap, AFE_ADDA6_MTKAIF_RX_CFG2, mask, val); + + return 0; +} + +static int mtk_adda_mtkaif_cfg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mt8195_adda_mtkaif_init(afe); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda_dl_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + break; + default: + break; + } + + return 0; +} + +static void mtk_adda_ul_mictype(struct mtk_base_afe *afe, int adda, bool dmic) +{ + unsigned int reg = 0; + unsigned int mask = 0; + unsigned int val = 0; + + switch (adda) { + case MTK_AFE_ADDA: + reg = AFE_ADDA_UL_SRC_CON0; + break; + case MTK_AFE_ADDA6: + reg = AFE_ADDA6_UL_SRC_CON0; + break; + default: + dev_info(afe->dev, "%s(), wrong parameter\n", __func__); + return; + } + + mask = (UL_SDM3_LEVEL_CTL | UL_MODE_3P25M_CH1_CTL | + UL_MODE_3P25M_CH2_CTL); + + /* turn on dmic, ch1, ch2 */ + if (dmic) + val = mask; + + regmap_update_bits(afe->regmap, reg, mask, val); +} + +static int mtk_adda_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mtk_adda_ul_mictype(afe, MTK_AFE_ADDA, param->mtkaif_dmic_on); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + break; + default: + break; + } + + return 0; +} + +static int mtk_adda6_ul_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + unsigned int val; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + mtk_adda_ul_mictype(afe, MTK_AFE_ADDA6, param->mtkaif_dmic_on); + + val = (param->mtkaif_adda6_only ? + ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE : 0); + + regmap_update_bits(afe->regmap, + AFE_ADDA_MTKAIF_SYNCWORD_CFG, + ADDA6_MTKAIF_RX_SYNC_WORD2_DISABLE, + val); + break; + case SND_SOC_DAPM_POST_PMD: + /* should delayed 1/fs(smallest is 8k) = 125us before afe off */ + usleep_range(125, 135); + break; + default: + break; + } + + return 0; +} + +static int mtk_audio_hires_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, + int event) +{ + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct clk *clk = afe_priv->clk[MT8195_CLK_TOP_AUDIO_H_SEL]; + struct clk *clk_parent; + + dev_dbg(afe->dev, "%s(), name %s, event 0x%x\n", + __func__, w->name, event); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + clk_parent = afe_priv->clk[MT8195_CLK_TOP_APLL1]; + break; + case SND_SOC_DAPM_POST_PMD: + clk_parent = afe_priv->clk[MT8195_CLK_XTAL_26M]; + break; + default: + return 0; + } + mt8195_afe_set_clk_parent(afe, clk, clk_parent); + + return 0; +} + +static struct mtk_dai_adda_priv *get_adda_priv_by_name(struct mtk_base_afe *afe, + const char *name) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + int dai_id; + + if (strstr(name, "aud_adc_hires")) + dai_id = MT8195_AFE_IO_UL_SRC1; + else if (strstr(name, "aud_adda6_adc_hires")) + dai_id = MT8195_AFE_IO_UL_SRC2; + else if (strstr(name, "aud_dac_hires")) + dai_id = MT8195_AFE_IO_DL_SRC; + else + return NULL; + + return afe_priv->dai_priv[dai_id]; +} + +static int mtk_afe_adda_hires_connect(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + struct snd_soc_dapm_widget *w = source; + struct snd_soc_component *cmpnt = snd_soc_dapm_to_component(w->dapm); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mtk_dai_adda_priv *adda_priv; + + adda_priv = get_adda_priv_by_name(afe, w->name); + + if (!adda_priv) { + dev_info(afe->dev, "adda_priv == NULL"); + return 0; + } + + return (adda_priv->hires_required) ? 1 : 0; +} + +static const struct snd_kcontrol_new mtk_dai_adda_o176_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN176, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I002 Switch", AFE_CONN176, 2, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I020 Switch", AFE_CONN176, 20, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I022 Switch", AFE_CONN176, 22, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN176_2, 6, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_adda_o177_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN177, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I003 Switch", AFE_CONN177, 3, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I021 Switch", AFE_CONN177, 21, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I023 Switch", AFE_CONN177, 23, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN177_2, 7, 1, 0), +}; + +static const char * const adda_dlgain_mux_map[] = { + "Bypass", "Connect", +}; + +static SOC_ENUM_SINGLE_DECL(adda_dlgain_mux_map_enum, + SND_SOC_NOPM, 0, + adda_dlgain_mux_map); + +static const struct snd_kcontrol_new adda_dlgain_mux_control = + SOC_DAPM_ENUM("DL_GAIN_MUX", adda_dlgain_mux_map_enum); + +static const struct snd_soc_dapm_widget mtk_dai_adda_widgets[] = { + SND_SOC_DAPM_MIXER("I168", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I169", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I170", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I171", SND_SOC_NOPM, 0, 0, NULL, 0), + + SND_SOC_DAPM_MIXER("O176", SND_SOC_NOPM, 0, 0, + mtk_dai_adda_o176_mix, + ARRAY_SIZE(mtk_dai_adda_o176_mix)), + SND_SOC_DAPM_MIXER("O177", SND_SOC_NOPM, 0, 0, + mtk_dai_adda_o177_mix, + ARRAY_SIZE(mtk_dai_adda_o177_mix)), + + SND_SOC_DAPM_SUPPLY_S("ADDA Enable", SUPPLY_SEQ_ADDA_AFE_ON, + AFE_ADDA_UL_DL_CON0, + ADDA_AFE_ON_SHIFT, 0, + NULL, + 0), + + SND_SOC_DAPM_SUPPLY_S("ADDA Playback Enable", SUPPLY_SEQ_ADDA_DL_ON, + AFE_ADDA_DL_SRC2_CON0, + DL_2_SRC_ON_TMP_CTRL_PRE_SHIFT, 0, + mtk_adda_dl_event, + SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SHIFT, 0, + mtk_adda_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA6 Capture Enable", SUPPLY_SEQ_ADDA_UL_ON, + AFE_ADDA6_UL_SRC_CON0, + UL_SRC_ON_TMP_CTL_SHIFT, 0, + mtk_adda6_ul_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("AUDIO_HIRES", SUPPLY_SEQ_CLOCK_SEL, + SND_SOC_NOPM, + 0, 0, + mtk_audio_hires_event, + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_SUPPLY_S("ADDA_MTKAIF_CFG", SUPPLY_SEQ_ADDA_MTKAIF_CFG, + SND_SOC_NOPM, + 0, 0, + mtk_adda_mtkaif_cfg_event, + SND_SOC_DAPM_PRE_PMU), + + SND_SOC_DAPM_MUX("DL_GAIN_MUX", SND_SOC_NOPM, 0, 0, + &adda_dlgain_mux_control), + + SND_SOC_DAPM_PGA("DL_GAIN", AFE_ADDA_DL_SRC2_CON0, + DL_2_GAIN_ON_CTL_PRE_SHIFT, 0, NULL, 0), + + SND_SOC_DAPM_INPUT("ADDA_INPUT"), + SND_SOC_DAPM_OUTPUT("ADDA_OUTPUT"), + + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_dac_hires"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adc_hires"), + SND_SOC_DAPM_CLOCK_SUPPLY("aud_adda6_adc_hires"), +}; + +static const struct snd_soc_dapm_route mtk_dai_adda_routes[] = { + {"ADDA Capture", NULL, "ADDA Enable"}, + {"ADDA Capture", NULL, "ADDA Capture Enable"}, + {"ADDA Capture", NULL, "ADDA_MTKAIF_CFG"}, + {"ADDA Capture", NULL, "aud_adc"}, + {"ADDA Capture", NULL, "aud_adc_hires", mtk_afe_adda_hires_connect}, + {"aud_adc_hires", NULL, "AUDIO_HIRES"}, + + {"ADDA6 Capture", NULL, "ADDA Enable"}, + {"ADDA6 Capture", NULL, "ADDA6 Capture Enable"}, + {"ADDA6 Capture", NULL, "ADDA_MTKAIF_CFG"}, + {"ADDA6 Capture", NULL, "aud_adda6_adc"}, + {"ADDA6 Capture", NULL, "aud_adda6_adc_hires", + mtk_afe_adda_hires_connect}, + {"aud_adda6_adc_hires", NULL, "AUDIO_HIRES"}, + + {"I168", NULL, "ADDA Capture"}, + {"I169", NULL, "ADDA Capture"}, + {"I170", NULL, "ADDA6 Capture"}, + {"I171", NULL, "ADDA6 Capture"}, + + {"ADDA Playback", NULL, "ADDA Enable"}, + {"ADDA Playback", NULL, "ADDA Playback Enable"}, + {"ADDA Playback", NULL, "aud_dac"}, + {"ADDA Playback", NULL, "aud_dac_hires", mtk_afe_adda_hires_connect}, + {"aud_dac_hires", NULL, "AUDIO_HIRES"}, + + {"DL_GAIN", NULL, "O176"}, + {"DL_GAIN", NULL, "O177"}, + + {"DL_GAIN_MUX", "Bypass", "O176"}, + {"DL_GAIN_MUX", "Bypass", "O177"}, + {"DL_GAIN_MUX", "Connect", "DL_GAIN"}, + + {"ADDA Playback", NULL, "DL_GAIN_MUX"}, + + {"O176", "I000 Switch", "I000"}, + {"O177", "I001 Switch", "I001"}, + + {"O176", "I002 Switch", "I002"}, + {"O177", "I003 Switch", "I003"}, + + {"O176", "I020 Switch", "I020"}, + {"O177", "I021 Switch", "I021"}, + + {"O176", "I022 Switch", "I022"}, + {"O177", "I023 Switch", "I023"}, + + {"O176", "I070 Switch", "I070"}, + {"O177", "I071 Switch", "I071"}, + + {"ADDA Capture", NULL, "ADDA_INPUT"}, + {"ADDA6 Capture", NULL, "ADDA_INPUT"}, + {"ADDA_OUTPUT", NULL, "ADDA Playback"}, +}; + +static int mt8195_adda_dl_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + unsigned int reg = AFE_ADDA_DL_SRC2_CON1; + unsigned int mask = DL_2_GAIN_CTL_PRE_MASK; + unsigned int value = (unsigned int)(ucontrol->value.integer.value[0]); + + regmap_update_bits(afe->regmap, reg, mask, DL_2_GAIN_CTL_PRE(value)); + return 0; +} + +static int mt8195_adda_dl_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(component); + unsigned int reg = AFE_ADDA_DL_SRC2_CON1; + unsigned int mask = DL_2_GAIN_CTL_PRE_MASK; + unsigned int value = 0; + + regmap_read(afe->regmap, reg, &value); + + ucontrol->value.integer.value[0] = ((value & mask) >> + DL_2_GAIN_CTL_PRE_SHIFT); + return 0; +} + +static int mt8195_adda6_only_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + + ucontrol->value.integer.value[0] = param->mtkaif_adda6_only; + return 0; +} + +static int mt8195_adda6_only_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + int mtkaif_adda6_only; + + mtkaif_adda6_only = ucontrol->value.integer.value[0]; + + dev_info(afe->dev, "%s(), kcontrol name %s, mtkaif_adda6_only %d\n", + __func__, kcontrol->id.name, mtkaif_adda6_only); + + param->mtkaif_adda6_only = mtkaif_adda6_only; + + return 0; +} + +static int mt8195_adda_dmic_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + + ucontrol->value.integer.value[0] = param->mtkaif_dmic_on; + return 0; +} + +static int mt8195_adda_dmic_set(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + int dmic_on; + + dmic_on = ucontrol->value.integer.value[0]; + + dev_dbg(afe->dev, "%s(), kcontrol name %s, dmic_on %d\n", + __func__, kcontrol->id.name, dmic_on); + + param->mtkaif_dmic_on = dmic_on; + return 0; +} + +static const struct snd_kcontrol_new mtk_dai_adda_controls[] = { + SOC_SINGLE_EXT("ADDA_DL_Gain", SND_SOC_NOPM, 0, 65535, 0, + mt8195_adda_dl_gain_get, mt8195_adda_dl_gain_put), + SOC_SINGLE_BOOL_EXT("MTKAIF_DMIC", 0, + mt8195_adda_dmic_get, mt8195_adda_dmic_set), + SOC_SINGLE_BOOL_EXT("MTKAIF_ADDA6_ONLY", 0, + mt8195_adda6_only_get, + mt8195_adda6_only_set), +}; + +static int mtk_dai_da_configure(struct mtk_base_afe *afe, + unsigned int rate, int id) +{ + unsigned int val = 0; + unsigned int mask = 0; + + /* set sampling rate */ + mask |= DL_2_INPUT_MODE_CTL_MASK; + val |= DL_2_INPUT_MODE_CTL(afe_adda_dl_rate_transform(afe, rate)); + + /* turn off saturation */ + mask |= DL_2_CH1_SATURATION_EN_CTL; + mask |= DL_2_CH2_SATURATION_EN_CTL; + + /* turn off mute function */ + mask |= DL_2_MUTE_CH1_OFF_CTL_PRE; + mask |= DL_2_MUTE_CH2_OFF_CTL_PRE; + val |= DL_2_MUTE_CH1_OFF_CTL_PRE; + val |= DL_2_MUTE_CH2_OFF_CTL_PRE; + + /* set voice input data if input sample rate is 8k or 16k */ + mask |= DL_2_VOICE_MODE_CTL_PRE; + if (rate == 8000 || rate == 16000) + val |= DL_2_VOICE_MODE_CTL_PRE; + + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SRC2_CON0, mask, val); + + mask = 0; + val = 0; + + /* new 2nd sdm */ + mask |= DL_USE_NEW_2ND_SDM; + val |= DL_USE_NEW_2ND_SDM; + regmap_update_bits(afe->regmap, AFE_ADDA_DL_SDM_DCCOMP_CON, mask, val); + + return 0; +} + +static int mtk_dai_ad_configure(struct mtk_base_afe *afe, + unsigned int rate, int id) +{ + unsigned int val = 0; + unsigned int mask = 0; + + mask |= UL_VOICE_MODE_CTL_MASK; + val |= UL_VOICE_MODE_CTL(afe_adda_ul_rate_transform(afe, rate)); + + switch (id) { + case MT8195_AFE_IO_UL_SRC1: + regmap_update_bits(afe->regmap, AFE_ADDA_UL_SRC_CON0, + mask, val); + break; + case MT8195_AFE_IO_UL_SRC2: + regmap_update_bits(afe->regmap, AFE_ADDA6_UL_SRC_CON0, + mask, val); + break; + default: + break; + } + return 0; +} + +static int mtk_dai_adda_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_adda_priv *adda_priv = afe_priv->dai_priv[dai->id]; + unsigned int rate = params_rate(params); + int id = dai->id; + int ret = 0; + + dev_dbg(afe->dev, "%s(), id %d, stream %d, rate %d\n", + __func__, id, substream->stream, rate); + + if (rate > ADDA_HIRES_THRES) + adda_priv->hires_required = 1; + else + adda_priv->hires_required = 0; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + ret = mtk_dai_da_configure(afe, rate, id); + else + ret = mtk_dai_ad_configure(afe, rate, id); + + return ret; +} + +static const struct snd_soc_dai_ops mtk_dai_adda_ops = { + .hw_params = mtk_dai_adda_hw_params, +}; + +/* dai driver */ +#define MTK_ADDA_PLAYBACK_RATES (SNDRV_PCM_RATE_8000_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_CAPTURE_RATES (SNDRV_PCM_RATE_8000 |\ + SNDRV_PCM_RATE_16000 |\ + SNDRV_PCM_RATE_32000 |\ + SNDRV_PCM_RATE_48000 |\ + SNDRV_PCM_RATE_96000 |\ + SNDRV_PCM_RATE_192000) + +#define MTK_ADDA_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_adda_driver[] = { + { + .name = "DL_SRC", + .id = MT8195_AFE_IO_DL_SRC, + .playback = { + .stream_name = "ADDA Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_PLAYBACK_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "UL_SRC1", + .id = MT8195_AFE_IO_UL_SRC1, + .capture = { + .stream_name = "ADDA Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, + { + .name = "UL_SRC2", + .id = MT8195_AFE_IO_UL_SRC2, + .capture = { + .stream_name = "ADDA6 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_ADDA_CAPTURE_RATES, + .formats = MTK_ADDA_FORMATS, + }, + .ops = &mtk_dai_adda_ops, + }, +}; + +static int init_adda_priv_data(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_adda_priv *adda_priv; + int adda_dai_list[] = { MT8195_AFE_IO_DL_SRC, + MT8195_AFE_IO_UL_SRC1, + MT8195_AFE_IO_UL_SRC2}; + int i; + + for (i = 0; i < ARRAY_SIZE(adda_dai_list); i++) { + adda_priv = devm_kzalloc(afe->dev, + sizeof(struct mtk_dai_adda_priv), + GFP_KERNEL); + if (!adda_priv) + return -ENOMEM; + + afe_priv->dai_priv[adda_dai_list[i]] = adda_priv; + } + + return 0; +} + +int mt8195_dai_adda_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_adda_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_adda_driver); + + dai->dapm_widgets = mtk_dai_adda_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_adda_widgets); + dai->dapm_routes = mtk_dai_adda_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_adda_routes); + dai->controls = mtk_dai_adda_controls; + dai->num_controls = ARRAY_SIZE(mtk_dai_adda_controls); + + return init_adda_priv_data(afe); +} From patchwork Thu Aug 19 08:41:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446619 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, UNWANTED_LANGUAGE_BODY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F79DC4338F for ; Thu, 19 Aug 2021 08:46:38 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F1EA960E90 for ; Thu, 19 Aug 2021 08:46:37 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F1EA960E90 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=DdeT6RzpOVab+/k7LxdE68LQ66vD9dVJP6ppX884Azg=; b=T1hFp9Hk/ZLseK M3fetDDQ9nnPpJHlUo1khET+lmF74KPmTXwksMpK+P6LANCIbJCqVy2Ivj6rBkeQ3sxZw9n4I1Ztf zqfXJqWy4c6bcz9mG64sxTGSQuHlXEKaEy5HvJGrOwW0TGUU50ssAC6JBXE7lGWY5+J1iQHzCBMCV tFLB2tQQkWkLhLZSqerUYxC6gm+pkTuNNzfSj6oF5qx2oVdzs5h1Ywev0LU9Rikm/Kj4mk+MryQaP KseDdVRGDbRk+wZLA4O5nJzYoZ5lT6mWpGnKVfpnteaYehb+Xoigu2gHD+zXP38rAGgVkZ2p2sTDG rNLj95IC3zWf/F8JkAAw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGded-007igo-EC; Thu, 19 Aug 2021 08:44:03 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGddv-007iVv-Rg; Thu, 19 Aug 2021 08:43:25 +0000 X-UUID: 61969db68f06468d9ff22e1ad3d135ca-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=QmasFQIt1wYNO5n09tMFTPYBlhs2leDScLRYtfODyPo=; b=eqCbaJ5CLF3CAv6ghvf5PV991Wr12aixNUJbsBTYtuRRm12GXlWgoqHHEl+K6VTZaV4afIpHJGpGkgGoTT+1mEAau8+Hdqqc5Y+G6MvwIKJopi6Nr41nBCsOZ4qK/TWmCXOoqwPIRqWpzXwF5KOkq1NX/yeQOSpZ1ixiBZWe5RU=; X-UUID: 61969db68f06468d9ff22e1ad3d135ca-20210819 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 622344340; Thu, 19 Aug 2021 01:43:13 -0700 Received: from mtkmbs05n1.mediatek.inc (172.21.101.15) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:11 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n1.mediatek.inc (172.21.101.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:08 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:08 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 05/11] ASoC: mediatek: mt8195: support pcm in platform driver Date: Thu, 19 Aug 2021 16:41:38 +0800 Message-ID: <20210819084144.18483-6-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014319_956698_740A353B X-CRM114-Status: GOOD ( 20.80 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds mt8195 pcm dai driver. Signed-off-by: Trevor Wu --- sound/soc/mediatek/mt8195/mt8195-dai-pcm.c | 389 +++++++++++++++++++++ 1 file changed, 389 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-dai-pcm.c diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c new file mode 100644 index 000000000000..5d10d2c4c991 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c @@ -0,0 +1,389 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * MediaTek ALSA SoC Audio DAI PCM I/F Control + * + * Copyright (c) 2020 MediaTek Inc. + * Author: Bicycle Tsai + * Trevor Wu + */ + +#include +#include +#include "mt8195-afe-clk.h" +#include "mt8195-afe-common.h" +#include "mt8195-reg.h" + +enum { + MTK_DAI_PCM_FMT_I2S, + MTK_DAI_PCM_FMT_EIAJ, + MTK_DAI_PCM_FMT_MODEA, + MTK_DAI_PCM_FMT_MODEB, +}; + +enum { + MTK_DAI_PCM_CLK_A1SYS, + MTK_DAI_PCM_CLK_A2SYS, + MTK_DAI_PCM_CLK_26M_48K, + MTK_DAI_PCM_CLK_26M_441K, +}; + +struct mtk_dai_pcm_rate { + unsigned int rate; + unsigned int reg_value; +}; + +struct mtk_dai_pcmif_priv { + unsigned int slave_mode; + unsigned int lrck_inv; + unsigned int bck_inv; + unsigned int format; +}; + +static const struct mtk_dai_pcm_rate mtk_dai_pcm_rates[] = { + { .rate = 8000, .reg_value = 0, }, + { .rate = 16000, .reg_value = 1, }, + { .rate = 32000, .reg_value = 2, }, + { .rate = 48000, .reg_value = 3, }, + { .rate = 11025, .reg_value = 1, }, + { .rate = 22050, .reg_value = 2, }, + { .rate = 44100, .reg_value = 3, }, +}; + +static int mtk_dai_pcm_mode(unsigned int rate) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(mtk_dai_pcm_rates); i++) + if (mtk_dai_pcm_rates[i].rate == rate) + return mtk_dai_pcm_rates[i].reg_value; + + return -EINVAL; +} + +static const struct snd_kcontrol_new mtk_dai_pcm_o000_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I000 Switch", AFE_CONN0, 0, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I070 Switch", AFE_CONN0_2, 6, 1, 0), +}; + +static const struct snd_kcontrol_new mtk_dai_pcm_o001_mix[] = { + SOC_DAPM_SINGLE_AUTODISABLE("I001 Switch", AFE_CONN1, 1, 1, 0), + SOC_DAPM_SINGLE_AUTODISABLE("I071 Switch", AFE_CONN1_2, 7, 1, 0), +}; + +static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = { + SND_SOC_DAPM_MIXER("I002", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I003", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("O000", SND_SOC_NOPM, 0, 0, + mtk_dai_pcm_o000_mix, + ARRAY_SIZE(mtk_dai_pcm_o000_mix)), + SND_SOC_DAPM_MIXER("O001", SND_SOC_NOPM, 0, 0, + mtk_dai_pcm_o001_mix, + ARRAY_SIZE(mtk_dai_pcm_o001_mix)), + + SND_SOC_DAPM_INPUT("PCM1_INPUT"), + SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"), +}; + +static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = { + {"I002", NULL, "PCM1 Capture"}, + {"I003", NULL, "PCM1 Capture"}, + + {"O000", "I000 Switch", "I000"}, + {"O001", "I001 Switch", "I001"}, + + {"O000", "I070 Switch", "I070"}, + {"O001", "I071 Switch", "I071"}, + + {"PCM1 Playback", NULL, "O000"}, + {"PCM1 Playback", NULL, "O001"}, + + {"PCM1_OUTPUT", NULL, "PCM1 Playback"}, + {"PCM1 Capture", NULL, "PCM1_INPUT"}, +}; + +static void mtk_dai_pcm_enable(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN); +} + +static void mtk_dai_pcm_disable(struct mtk_base_afe *afe) +{ + regmap_update_bits(afe->regmap, PCM_INTF_CON1, + PCM_INTF_CON1_PCM_EN, 0x0); +} + +static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_pcm_runtime * const runtime = substream->runtime; + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id]; + unsigned int slave_mode = pcmif_priv->slave_mode; + unsigned int lrck_inv = pcmif_priv->lrck_inv; + unsigned int bck_inv = pcmif_priv->bck_inv; + unsigned int fmt = pcmif_priv->format; + unsigned int bit_width = dai->sample_bits; + unsigned int val = 0; + unsigned int mask = 0; + int fs = 0; + int mode = 0; + + /* sync freq mode */ + fs = mt8195_afe_fs_timing(runtime->rate); + if (fs < 0) + return -EINVAL; + val |= PCM_INTF_CON2_SYNC_FREQ_MODE(fs); + mask |= PCM_INTF_CON2_SYNC_FREQ_MODE_MASK; + + /* clk domain sel */ + if (runtime->rate % 8000) + val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_441K); + else + val |= PCM_INTF_CON2_CLK_DOMAIN_SEL(MTK_DAI_PCM_CLK_26M_48K); + mask |= PCM_INTF_CON2_CLK_DOMAIN_SEL_MASK; + + regmap_update_bits(afe->regmap, PCM_INTF_CON2, mask, val); + + val = 0; + mask = 0; + + /* pcm mode */ + mode = mtk_dai_pcm_mode(runtime->rate); + if (mode < 0) + return -EINVAL; + val |= PCM_INTF_CON1_PCM_MODE(mode); + mask |= PCM_INTF_CON1_PCM_MODE_MASK; + + /* pcm format */ + val |= PCM_INTF_CON1_PCM_FMT(fmt); + mask |= PCM_INTF_CON1_PCM_FMT_MASK; + + /* pcm sync length */ + if (fmt == MTK_DAI_PCM_FMT_MODEA || + fmt == MTK_DAI_PCM_FMT_MODEB) + val |= PCM_INTF_CON1_SYNC_LENGTH(1); + else + val |= PCM_INTF_CON1_SYNC_LENGTH(bit_width); + mask |= PCM_INTF_CON1_SYNC_LENGTH_MASK; + + /* pcm bits, word length */ + if (bit_width > 16) { + val |= PCM_INTF_CON1_PCM_24BIT; + val |= PCM_INTF_CON1_PCM_WLEN_64BCK; + } else { + val |= PCM_INTF_CON1_PCM_16BIT; + val |= PCM_INTF_CON1_PCM_WLEN_32BCK; + } + mask |= PCM_INTF_CON1_PCM_BIT_MASK; + mask |= PCM_INTF_CON1_PCM_WLEN_MASK; + + /* master/slave */ + if (!slave_mode) { + val |= PCM_INTF_CON1_PCM_MASTER; + + if (lrck_inv) + val |= PCM_INTF_CON1_SYNC_OUT_INV; + if (bck_inv) + val |= PCM_INTF_CON1_BCLK_OUT_INV; + mask |= PCM_INTF_CON1_CLK_OUT_INV_MASK; + } else { + val |= PCM_INTF_CON1_PCM_SLAVE; + + if (lrck_inv) + val |= PCM_INTF_CON1_SYNC_IN_INV; + if (bck_inv) + val |= PCM_INTF_CON1_BCLK_IN_INV; + mask |= PCM_INTF_CON1_CLK_IN_INV_MASK; + + /* TODO: add asrc setting for slave mode */ + } + mask |= PCM_INTF_CON1_PCM_M_S_MASK; + + regmap_update_bits(afe->regmap, PCM_INTF_CON1, mask, val); + + return 0; +} + +/* dai ops */ +static int mtk_dai_pcm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + + if (dai->component->active) + return 0; + + mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]); + mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]); + mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]); + + return 0; +} + +static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + + if (dai->component->active) + return; + + mtk_dai_pcm_disable(afe); + + mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]); + mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]); + mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]); +} + +static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + int ret = 0; + + if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) && + snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) + return 0; + + ret = mtk_dai_pcm_configure(substream, dai); + if (ret) + return ret; + + mtk_dai_pcm_enable(afe); + + return 0; +} + +static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_pcmif_priv *pcmif_priv = afe_priv->dai_priv[dai->id]; + + dev_dbg(dai->dev, "%s fmt 0x%x\n", __func__, fmt); + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + pcmif_priv->format = MTK_DAI_PCM_FMT_I2S; + break; + case SND_SOC_DAIFMT_DSP_A: + pcmif_priv->format = MTK_DAI_PCM_FMT_MODEA; + break; + case SND_SOC_DAIFMT_DSP_B: + pcmif_priv->format = MTK_DAI_PCM_FMT_MODEB; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + pcmif_priv->bck_inv = 0; + pcmif_priv->lrck_inv = 0; + break; + case SND_SOC_DAIFMT_NB_IF: + pcmif_priv->bck_inv = 0; + pcmif_priv->lrck_inv = 1; + break; + case SND_SOC_DAIFMT_IB_NF: + pcmif_priv->bck_inv = 1; + pcmif_priv->lrck_inv = 0; + break; + case SND_SOC_DAIFMT_IB_IF: + pcmif_priv->bck_inv = 1; + pcmif_priv->lrck_inv = 1; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + pcmif_priv->slave_mode = 1; + break; + case SND_SOC_DAIFMT_CBS_CFS: + pcmif_priv->slave_mode = 0; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { + .startup = mtk_dai_pcm_startup, + .shutdown = mtk_dai_pcm_shutdown, + .prepare = mtk_dai_pcm_prepare, + .set_fmt = mtk_dai_pcm_set_fmt, +}; + +/* dai driver */ +#define MTK_PCM_RATES (SNDRV_PCM_RATE_8000_48000) + +#define MTK_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = { + { + .name = "PCM1", + .id = MT8195_AFE_IO_PCM, + .playback = { + .stream_name = "PCM1 Playback", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .capture = { + .stream_name = "PCM1 Capture", + .channels_min = 1, + .channels_max = 2, + .rates = MTK_PCM_RATES, + .formats = MTK_PCM_FORMATS, + }, + .ops = &mtk_dai_pcm_ops, + .symmetric_rate = 1, + .symmetric_sample_bits = 1, + }, +}; + +static int init_pcmif_priv_data(struct mtk_base_afe *afe) +{ + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtk_dai_pcmif_priv *pcmif_priv; + + pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mtk_dai_pcmif_priv), + GFP_KERNEL); + if (!pcmif_priv) + return -ENOMEM; + + afe_priv->dai_priv[MT8195_AFE_IO_PCM] = pcmif_priv; + return 0; +} + +int mt8195_dai_pcm_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers = mtk_dai_pcm_driver; + dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver); + + dai->dapm_widgets = mtk_dai_pcm_widgets; + dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets); + dai->dapm_routes = mtk_dai_pcm_routes; + dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes); + + return init_pcmif_priv_data(afe); +} From patchwork Thu Aug 19 08:41:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446625 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id EFCD4C4338F for ; Thu, 19 Aug 2021 08:47:19 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B413661106 for ; Thu, 19 Aug 2021 08:47:19 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org B413661106 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=+7IiRCnnqdHrMibbE1KPyabFXtNm5RGlE84Vom6/MN4=; b=O5YiZHs1TwilWq Yi8/mp4k8p5OxqHfGjTjgGghscSfFkSwWlr5v6wjfG827z9i6YzOXYmsyPY+C5zgSNXIfs2zNLw68 WxWw9eWOMXoRYWjXu3MucR3Msm/bruMzvsi73nY1ncVIcd+xB1GNzP0PxeYwbf1N3DWf/QQzE3Dq1 oAyobfhiVyjWaEDa6HnBfKxTakQUy77xDmfZb2sKCLobEKlPWJQImcIlFzYAKdepqQLQgZaZ1ARjA WP1/Ke2MRZOKkY7BEKhcFskZky5xlYwiTlVmUTBfPWJaAyakq9Z508pQgWVnWCAiB0azRKOxzwVQ7 bHjNjaY/0OdLRZ+/Q6Yg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdfO-007j25-JP; Thu, 19 Aug 2021 08:44:51 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGde1-007iVH-Jk; Thu, 19 Aug 2021 08:43:28 +0000 X-UUID: d14ed1583e02419ea5ff381124552a11-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=jAACT/u3ryxjbgKwnVyDlaI5Uq379l6+zwVkwtXSpQQ=; b=WyjQ6Sxy8V1RFUTbG/S3rW9Y0MAvbl987Co5sFFMyLXIxKRkzWTIgJIhY/gYJytotArqNl/0V0ZgpoC+Wp05/pg+hUx2mBs1OACsINq9EI89fKeSlZagM3E9NVUKSo2PxLdUdtxknwBKgpHycC/0Sqcl1vo1qRkrhkmgkmTAnsg=; X-UUID: d14ed1583e02419ea5ff381124552a11-20210819 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 316565339; Thu, 19 Aug 2021 01:43:13 -0700 Received: from mtkmbs05n1.mediatek.inc (172.21.101.15) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:12 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n1.mediatek.inc (172.21.101.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:09 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:09 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 07/11] dt-bindings: mediatek: mt8195: add audio afe document Date: Thu, 19 Aug 2021 16:41:40 +0800 Message-ID: <20210819084144.18483-8-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014325_712095_33B2DA9A X-CRM114-Status: GOOD ( 14.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds mt8195 audio afe document. In order to support dynamic clock reparenting for ADDA and ETDM, PLL and MUX clocks are requested even though they are not consumed by afe directly. Signed-off-by: Trevor Wu --- This patch depends on the following series that have not been accepted. [1] Mediatek MT8195 clock support https://patchwork.kernel.org/project/linux-mediatek/list/?series=501923 (dt-bindings/clock/mt8195-clk.h is included) [2] Mediatek MT8195 power domain support https://patchwork.kernel.org/project/linux-mediatek/list/?series=500709 (dt-bindings/power/mt8195-power.h is included) --- --- .../bindings/sound/mt8195-afe-pcm.yaml | 184 ++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml diff --git a/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml new file mode 100644 index 000000000000..53e9434a6d9d --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8195-afe-pcm.yaml @@ -0,0 +1,184 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mt8195-afe-pcm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek AFE PCM controller for mt8195 + +maintainers: + - Trevor Wu + +properties: + compatible: + const: mediatek,mt8195-audio + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + mediatek,topckgen: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of the mediatek topckgen controller + + power-domains: + maxItems: 1 + + clocks: + items: + - description: 26M clock + - description: audio pll1 clock + - description: audio pll2 clock + - description: clock divider for i2si1_mck + - description: clock divider for i2si2_mck + - description: clock divider for i2so1_mck + - description: clock divider for i2so2_mck + - description: clock divider for dptx_mck + - description: a1sys hoping clock + - description: audio intbus clock + - description: audio hires clock + - description: audio local bus clock + - description: mux for dptx_mck + - description: mux for i2so1_mck + - description: mux for i2so2_mck + - description: mux for i2si1_mck + - description: mux for i2si2_mck + - description: audio infra 26M clock + - description: infra bus clock + + clock-names: + items: + - const: clk26m + - const: apll1_ck + - const: apll2_ck + - const: apll12_div0 + - const: apll12_div1 + - const: apll12_div2 + - const: apll12_div3 + - const: apll12_div9 + - const: a1sys_hp_sel + - const: aud_intbus_sel + - const: audio_h_sel + - const: audio_local_bus_sel + - const: dptx_m_sel + - const: i2so1_m_sel + - const: i2so2_m_sel + - const: i2si1_m_sel + - const: i2si2_m_sel + - const: infra_ao_audio_26m_b + - const: scp_adsp_audiodsp + + mediatek,etdm-in1-chn-disabled: + $ref: /schemas/types.yaml#/definitions/uint8-array + maxItems: 24 + description: Specify which input channel should be disabled. + + mediatek,etdm-in2-chn-disabled: + $ref: /schemas/types.yaml#/definitions/uint8-array + maxItems: 16 + description: Specify which input channel should be disabled. + +patternProperties: + "^mediatek,etdm-in[1-2]-mclk-always-on-rate-hz$": + description: Specify etdm in mclk output rate for always on case. + + "^mediatek,etdm-out[1-3]-mclk-always-on-rate-hz$": + description: Specify etdm out mclk output rate for always on case. + + "^mediatek,etdm-in[1-2]-multi-pin-mode$": + type: boolean + description: if present, the etdm data mode is I2S. + + "^mediatek,etdm-out[1-3]-multi-pin-mode$": + type: boolean + description: if present, the etdm data mode is I2S. + + "^mediatek,etdm-in[1-2]-cowork-source$": + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + etdm modules can share the same external clock pin. Specify + which etdm clock source is required by this etdm in moudule. + enum: + - 0 # etdm1_in + - 1 # etdm2_in + - 2 # etdm1_out + - 3 # etdm2_out + + "^mediatek,etdm-out[1-2]-cowork-source$": + $ref: /schemas/types.yaml#/definitions/uint32 + description: | + etdm modules can share the same external clock pin. Specify + which etdm clock source is required by this etdm out moudule. + enum: + - 0 # etdm1_in + - 1 # etdm2_in + - 2 # etdm1_out + - 3 # etdm2_out + +required: + - compatible + - reg + - interrupts + - mediatek,topckgen + - power-domains + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include + #include + #include + #include + + afe: mt8195-afe-pcm@10890000 { + compatible = "mediatek,mt8195-audio"; + reg = <0x10890000 0x10000>; + interrupts = ; + mediatek,topckgen = <&topckgen>; + power-domains = <&spm MT8195_POWER_DOMAIN_AUDIO>; + clocks = <&clk26m>, + <&topckgen CLK_TOP_APLL1>, + <&topckgen CLK_TOP_APLL2>, + <&topckgen CLK_TOP_APLL12_DIV0>, + <&topckgen CLK_TOP_APLL12_DIV1>, + <&topckgen CLK_TOP_APLL12_DIV2>, + <&topckgen CLK_TOP_APLL12_DIV3>, + <&topckgen CLK_TOP_APLL12_DIV9>, + <&topckgen CLK_TOP_A1SYS_HP_SEL>, + <&topckgen CLK_TOP_AUD_INTBUS_SEL>, + <&topckgen CLK_TOP_AUDIO_H_SEL>, + <&topckgen CLK_TOP_AUDIO_LOCAL_BUS_SEL>, + <&topckgen CLK_TOP_DPTX_M_SEL>, + <&topckgen CLK_TOP_I2SO1_M_SEL>, + <&topckgen CLK_TOP_I2SO2_M_SEL>, + <&topckgen CLK_TOP_I2SI1_M_SEL>, + <&topckgen CLK_TOP_I2SI2_M_SEL>, + <&infracfg_ao CLK_INFRA_AO_AUDIO_26M_B>, + <&scp_adsp CLK_SCP_ADSP_AUDIODSP>; + clock-names = "clk26m", + "apll1_ck", + "apll2_ck", + "apll12_div0", + "apll12_div1", + "apll12_div2", + "apll12_div3", + "apll12_div9", + "a1sys_hp_sel", + "aud_intbus_sel", + "audio_h_sel", + "audio_local_bus_sel", + "dptx_m_sel", + "i2so1_m_sel", + "i2so2_m_sel", + "i2si1_m_sel", + "i2si2_m_sel", + "infra_ao_audio_26m_b", + "scp_adsp_audiodsp"; + }; + +... From patchwork Thu Aug 19 08:41:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446621 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78677C4338F for ; Thu, 19 Aug 2021 08:46:56 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 49B3061106 for ; Thu, 19 Aug 2021 08:46:56 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 49B3061106 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=EQKyQNHgZwaZLo5BYbc3MeEkjDYbLA6jYaWPK6C33/0=; b=NNpPT/En8EromW QquOX8k2s8BHKb8OimcXXUSJ9YVa4rXBoiSP0+uj50Ai1TtjmWeJD62fCLJeG6KbO3ZqFaF9oLrxH /XrDfns5Y2hUjvU3Nf5l0xMlbdmowDSpDq9tdkkW0RXEG6KE8mWA8cjXWXdiPpW2PJjzUbZ48niMN 9Vzj+i1RcFwMgItwLEr8fg6fhUBa/sINa2yj2ttc3Y9D+Rf+EMO78vloMC0fwcoqqHZzftNtHaUjX bpfzNDXwsNNA3VZZea6vCj6WYXWFiAX/oZx7ETGsv2lFlpDKYAuB0ZwV+N5ZesaaXSf2zkwPwFOdh EwJvlEtFriK3W8s4jo1A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdet-007inF-64; Thu, 19 Aug 2021 08:44:19 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGddx-007iUo-Pj; Thu, 19 Aug 2021 08:43:26 +0000 X-UUID: fc9b267607b340f9a1a4a4e386126c9f-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=sBM+ItGXC0KiMBV4F++E9pbPSuCspIHIqi1sTyyUDgA=; b=Xyg512kz6d9d7Z4RR6JYTIg/hFhwrq5erWsz2ajXfKlBP7upwhjrNcw1J0urEbJ4hbAGt/x1pAOGR4c7XfdZtlCJSBURi4deVHMkVIXSG548ipVRdRpb1naBUwCZ/Gvu36xsAB/a7koIxwfrH5u4mTVNx6X/BfDyhMnvt52duU0=; X-UUID: fc9b267607b340f9a1a4a4e386126c9f-20210819 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 542777017; Thu, 19 Aug 2021 01:43:13 -0700 Received: from mtkmbs05n2.mediatek.inc (172.21.101.140) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:12 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:09 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:09 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 08/11] ASoC: mediatek: mt8195: add machine driver with mt6359, rt1019 and rt5682 Date: Thu, 19 Aug 2021 16:41:41 +0800 Message-ID: <20210819084144.18483-9-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014321_891075_02DBF3C3 X-CRM114-Status: GOOD ( 24.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds support for mt8195 board with mt6359, rt1019 and rt5682. Signed-off-by: Trevor Wu Reported-by: kernel test robot --- sound/soc/mediatek/Kconfig | 14 + sound/soc/mediatek/mt8195/Makefile | 3 + .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 977 ++++++++++++++++++ 3 files changed, 994 insertions(+) create mode 100644 sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 3389f382be06..bfee954d0c7c 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -193,3 +193,17 @@ config SND_SOC_MT8195 that can be used with other codecs. Select Y if you have such device. If unsure select "N". + +config SND_SOC_MT8195_MT6359_RT1019_RT5682 + tristate "ASoC Audio driver for MT8195 with MT6359 RT1019 RT5682 codec" + depends on I2C + depends on SND_SOC_MT8195 + select SND_SOC_MT6359 + select SND_SOC_RT1015P + select SND_SOC_RT5682_I2C + select SND_SOC_DMIC + help + This adds ASoC driver for Mediatek MT8195 boards + with the MT6359 RT1019 RT5682 audio codec. + Select Y if you have such device. + If unsure select "N". diff --git a/sound/soc/mediatek/mt8195/Makefile b/sound/soc/mediatek/mt8195/Makefile index 6529dd5beb2b..44775f400b40 100644 --- a/sound/soc/mediatek/mt8195/Makefile +++ b/sound/soc/mediatek/mt8195/Makefile @@ -10,3 +10,6 @@ snd-soc-mt8195-afe-objs := \ mt8195-dai-pcm.o obj-$(CONFIG_SND_SOC_MT8195) += snd-soc-mt8195-afe.o + +# machine driver +obj-$(CONFIG_SND_SOC_MT8195_MT6359_RT1019_RT5682) += mt8195-mt6359-rt1019-rt5682.o diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c new file mode 100644 index 000000000000..39b33aecc1e9 --- /dev/null +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -0,0 +1,977 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// mt8195-mt6359-rt1019-rt5682.c -- +// MT8195-MT6359-RT1019-RT6358 ALSA SoC machine driver +// +// Copyright (c) 2021 MediaTek Inc. +// Author: Trevor Wu +// + +#include +#include +#include +#include +#include +#include +#include +#include "../../codecs/mt6359.h" +#include "../../codecs/rt5682.h" +#include "../common/mtk-afe-platform-driver.h" +#include "mt8195-afe-common.h" + +#define RT1019_CODEC_DAI "HiFi" +#define RT1019_DEV0_NAME "rt1019p" + +#define RT5682_CODEC_DAI "rt5682-aif1" +#define RT5682_DEV0_NAME "rt5682.2-001a" + +struct mt8195_mt6359_rt1019_rt5682_priv { + struct snd_soc_jack headset_jack; +}; + +static const struct snd_soc_dapm_widget + mt8195_mt6359_rt1019_rt5682_widgets[] = { + SND_SOC_DAPM_SPK("Speakers", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), +}; + +static const struct snd_soc_dapm_route mt8195_mt6359_rt1019_rt5682_routes[] = { + /* speaker */ + { "Speakers", NULL, "Speaker" }, + /* headset */ + { "Headphone Jack", NULL, "HPOL" }, + { "Headphone Jack", NULL, "HPOR" }, + { "IN1P", NULL, "Headset Mic" }, +}; + +static const struct snd_kcontrol_new mt8195_mt6359_rt1019_rt5682_controls[] = { + SOC_DAPM_PIN_SWITCH("Speakers"), + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), +}; + +static int mt8195_rt5682_etdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_card *card = rtd->card; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 128; + unsigned int mclk_fs = rate * mclk_fs_ratio; + int bitwidth; + int ret; + + bitwidth = snd_pcm_format_width(params_format(params)); + if (bitwidth < 0) { + dev_err(card->dev, "invalid bit width: %d\n", bitwidth); + return bitwidth; + } + + ret = snd_soc_dai_set_tdm_slot(codec_dai, 0x00, 0x0, 0x2, bitwidth); + if (ret) { + dev_err(card->dev, "failed to set tdm slot\n"); + return ret; + } + + ret = snd_soc_dai_set_pll(codec_dai, RT5682_PLL1, + RT5682_PLL1_S_BCLK1, + params_rate(params) * 64, + params_rate(params) * 512); + if (ret) { + dev_err(card->dev, "failed to set pll\n"); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, + RT5682_SCLK_S_PLL1, + params_rate(params) * 512, + SND_SOC_CLOCK_IN); + if (ret) { + dev_err(card->dev, "failed to set sysclk\n"); + return ret; + } + + return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, SND_SOC_CLOCK_OUT); +} + +static const struct snd_soc_ops mt8195_rt5682_etdm_ops = { + .hw_params = mt8195_rt5682_etdm_hw_params, +}; + +#define CKSYS_AUD_TOP_CFG 0x032c +#define CKSYS_AUD_TOP_MON 0x0330 + +static int mt8195_mt6359_mtkaif_calibration(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *cmpnt_afe = + snd_soc_rtdcom_lookup(rtd, AFE_PCM_NAME); + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + struct mtk_base_afe *afe = snd_soc_component_get_drvdata(cmpnt_afe); + struct mt8195_afe_private *afe_priv = afe->platform_priv; + struct mtkaif_param *param = &afe_priv->mtkaif_params; + int phase; + unsigned int monitor; + int mtkaif_calibration_num_phase; + int test_done_1, test_done_2, test_done_3; + int cycle_1, cycle_2, cycle_3; + int prev_cycle_1, prev_cycle_2, prev_cycle_3; + int chosen_phase_1, chosen_phase_2, chosen_phase_3; + int counter; + bool mtkaif_calibration_ok; + int mtkaif_chosen_phase[MT8195_MTKAIF_MISO_NUM]; + int mtkaif_phase_cycle[MT8195_MTKAIF_MISO_NUM]; + int i; + + dev_info(afe->dev, "%s(), start\n", __func__); + + param->mtkaif_calibration_ok = false; + for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) { + param->mtkaif_chosen_phase[i] = -1; + param->mtkaif_phase_cycle[i] = 0; + mtkaif_chosen_phase[i] = -1; + mtkaif_phase_cycle[i] = 0; + } + + if (IS_ERR(afe_priv->topckgen)) { + dev_info(afe->dev, "%s() Cannot find topckgen controller\n", + __func__); + return 0; + } + + pm_runtime_get_sync(afe->dev); + mt6359_mtkaif_calibration_enable(cmpnt_codec); + + /* set test type to synchronizer pulse */ + regmap_update_bits(afe_priv->topckgen, + CKSYS_AUD_TOP_CFG, 0xffff, 0x4); + mtkaif_calibration_num_phase = 42; /* mt6359: 0 ~ 42 */ + mtkaif_calibration_ok = true; + + for (phase = 0; + phase <= mtkaif_calibration_num_phase && mtkaif_calibration_ok; + phase++) { + mt6359_set_mtkaif_calibration_phase(cmpnt_codec, + phase, phase, phase); + + regmap_update_bits(afe_priv->topckgen, + CKSYS_AUD_TOP_CFG, 0x1, 0x1); + + test_done_1 = 0; + test_done_2 = 0; + test_done_3 = 0; + cycle_1 = -1; + cycle_2 = -1; + cycle_3 = -1; + counter = 0; + while (!(test_done_1 & test_done_2 & test_done_3)) { + regmap_read(afe_priv->topckgen, + CKSYS_AUD_TOP_MON, &monitor); + test_done_1 = (monitor >> 28) & 0x1; + test_done_2 = (monitor >> 29) & 0x1; + test_done_3 = (monitor >> 30) & 0x1; + if (test_done_1 == 1) + cycle_1 = monitor & 0xf; + + if (test_done_2 == 1) + cycle_2 = (monitor >> 4) & 0xf; + + if (test_done_3 == 1) + cycle_3 = (monitor >> 8) & 0xf; + + /* handle if never test done */ + if (++counter > 10000) { + dev_info(afe->dev, "%s(), test fail, cycle_1 %d, cycle_2 %d, cycle_3 %d, monitor 0x%x\n", + __func__, + cycle_1, cycle_2, cycle_3, monitor); + mtkaif_calibration_ok = false; + break; + } + } + + if (phase == 0) { + prev_cycle_1 = cycle_1; + prev_cycle_2 = cycle_2; + prev_cycle_3 = cycle_3; + } + + if (cycle_1 != prev_cycle_1 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = phase - 1; + mtkaif_phase_cycle[MT8195_MTKAIF_MISO_0] = prev_cycle_1; + } + + if (cycle_2 != prev_cycle_2 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = phase - 1; + mtkaif_phase_cycle[MT8195_MTKAIF_MISO_1] = prev_cycle_2; + } + + if (cycle_3 != prev_cycle_3 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = phase - 1; + mtkaif_phase_cycle[MT8195_MTKAIF_MISO_2] = prev_cycle_3; + } + + regmap_update_bits(afe_priv->topckgen, + CKSYS_AUD_TOP_CFG, 0x1, 0x0); + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] >= 0 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] >= 0 && + mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] >= 0) + break; + } + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] < 0) { + mtkaif_calibration_ok = false; + chosen_phase_1 = 0; + } else { + chosen_phase_1 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0]; + } + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] < 0) { + mtkaif_calibration_ok = false; + chosen_phase_2 = 0; + } else { + chosen_phase_2 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1]; + } + + if (mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] < 0) { + mtkaif_calibration_ok = false; + chosen_phase_3 = 0; + } else { + chosen_phase_3 = mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2]; + } + + mt6359_set_mtkaif_calibration_phase(cmpnt_codec, + chosen_phase_1, + chosen_phase_2, + chosen_phase_3); + + mt6359_mtkaif_calibration_disable(cmpnt_codec); + pm_runtime_put(afe->dev); + + param->mtkaif_calibration_ok = mtkaif_calibration_ok; + param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_0] = chosen_phase_1; + param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_1] = chosen_phase_2; + param->mtkaif_chosen_phase[MT8195_MTKAIF_MISO_2] = chosen_phase_3; + for (i = 0; i < MT8195_MTKAIF_MISO_NUM; i++) + param->mtkaif_phase_cycle[i] = mtkaif_phase_cycle[i]; + + dev_info(afe->dev, "%s(), end, calibration ok %d\n", + __func__, param->mtkaif_calibration_ok); + + return 0; +} + +static int mt8195_mt6359_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + + /* set mtkaif protocol */ + mt6359_set_mtkaif_protocol(cmpnt_codec, + MT6359_MTKAIF_PROTOCOL_2_CLK_P2); + + /* mtkaif calibration */ + mt8195_mt6359_mtkaif_calibration(rtd); + + return 0; +} + +static int mt8195_rt5682_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + struct mt8195_mt6359_rt1019_rt5682_priv *priv = + snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_jack *jack = &priv->headset_jack; + int ret; + + ret = snd_soc_card_jack_new(rtd->card, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_BTN_0 | + SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3, + jack, NULL, 0); + if (ret) { + dev_err(rtd->dev, "Headset Jack creation failed: %d\n", ret); + return ret; + } + + snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); + snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOICECOMMAND); + snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEUP); + snd_jack_set_key(jack->jack, SND_JACK_BTN_3, KEY_VOLUMEDOWN); + + ret = snd_soc_component_set_jack(cmpnt_codec, jack, NULL); + if (ret) { + dev_err(rtd->dev, "Headset Jack set failed: %d\n", ret); + return ret; + } + + return 0; +}; + +static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0); + unsigned int rate = params_rate(params); + unsigned int mclk_fs_ratio = 256; + unsigned int mclk_fs = rate * mclk_fs_ratio; + + return snd_soc_dai_set_sysclk(cpu_dai, 0, mclk_fs, + SND_SOC_CLOCK_OUT); +} + +static struct snd_soc_ops mt8195_dptx_ops = { + .hw_params = mt8195_dptx_hw_params, +}; + +static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) +{ + /* fix BE i2s format to 32bit, clean param mask first */ + snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), + 0, (__force unsigned int)SNDRV_PCM_FORMAT_LAST); + + params_set_format(params, SNDRV_PCM_FORMAT_S24_LE); + + return 0; +} + +static int mt8195_playback_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000 + }; + static const unsigned int channels[] = { + 2 + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); + return ret; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list channel failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_playback_ops = { + .startup = mt8195_playback_startup, +}; + +static int mt8195_capture_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000 + }; + static const unsigned int channels[] = { + 1, 2 + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); + return ret; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list channel failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_capture_ops = { + .startup = mt8195_capture_startup, +}; + +enum { + DAI_LINK_DL2_FE, + DAI_LINK_DL3_FE, + DAI_LINK_DL6_FE, + DAI_LINK_DL7_FE, + DAI_LINK_DL8_FE, + DAI_LINK_DL10_FE, + DAI_LINK_DL11_FE, + DAI_LINK_UL1_FE, + DAI_LINK_UL2_FE, + DAI_LINK_UL3_FE, + DAI_LINK_UL4_FE, + DAI_LINK_UL5_FE, + DAI_LINK_UL6_FE, + DAI_LINK_UL8_FE, + DAI_LINK_UL9_FE, + DAI_LINK_UL10_FE, + DAI_LINK_DL_SRC_BE, + DAI_LINK_DPTX_BE, + DAI_LINK_ETDM1_IN_BE, + DAI_LINK_ETDM2_IN_BE, + DAI_LINK_ETDM1_OUT_BE, + DAI_LINK_ETDM2_OUT_BE, + DAI_LINK_ETDM3_OUT_BE, + DAI_LINK_PCM1_BE, + DAI_LINK_UL_SRC1_BE, + DAI_LINK_UL_SRC2_BE, +}; + +/* FE */ +SND_SOC_DAILINK_DEFS(DL2_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL3_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL6_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL7_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL7")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL8_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL8")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL10_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL10")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DL11_FE, + DAILINK_COMP_ARRAY(COMP_CPU("DL11")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL1_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL2_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL2")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL3_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL3")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL4_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL4")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL5_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL5")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL6_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL6")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL8_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL8")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL9_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL9")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL10_FE, + DAILINK_COMP_ARRAY(COMP_CPU("UL10")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +/* BE */ +SND_SOC_DAILINK_DEFS(DL_SRC_BE, + DAILINK_COMP_ARRAY(COMP_CPU("DL_SRC")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", + "mt6359-snd-codec-aif1")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(DPTX_BE, + DAILINK_COMP_ARRAY(COMP_CPU("DPTX")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM1_IN_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_IN")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM2_IN_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_IN")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME, + RT5682_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM1_OUT_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM1_OUT")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT5682_DEV0_NAME, + RT5682_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM2_OUT_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM2_OUT")), + DAILINK_COMP_ARRAY(COMP_CODEC(RT1019_DEV0_NAME, + RT1019_CODEC_DAI)), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(ETDM3_OUT_BE, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM3_OUT")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(PCM1_BE, + DAILINK_COMP_ARRAY(COMP_CPU("PCM1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL_SRC1_BE, + DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC1")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", + "mt6359-snd-codec-aif1"), + COMP_CODEC("dmic-codec", + "dmic-hifi")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(UL_SRC2_BE, + DAILINK_COMP_ARRAY(COMP_CPU("UL_SRC2")), + DAILINK_COMP_ARRAY(COMP_CODEC("mt6359-sound", + "mt6359-snd-codec-aif2")), + DAILINK_COMP_ARRAY(COMP_EMPTY())); + +static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { + /* FE */ + [DAI_LINK_DL2_FE] = { + .name = "DL2_FE", + .stream_name = "DL2 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL2_FE), + }, + [DAI_LINK_DL3_FE] = { + .name = "DL3_FE", + .stream_name = "DL3 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL3_FE), + }, + [DAI_LINK_DL6_FE] = { + .name = "DL6_FE", + .stream_name = "DL6 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL6_FE), + }, + [DAI_LINK_DL7_FE] = { + .name = "DL7_FE", + .stream_name = "DL7 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE, + }, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(DL7_FE), + }, + [DAI_LINK_DL8_FE] = { + .name = "DL8_FE", + .stream_name = "DL8 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL8_FE), + }, + [DAI_LINK_DL10_FE] = { + .name = "DL10_FE", + .stream_name = "DL10 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(DL10_FE), + }, + [DAI_LINK_DL11_FE] = { + .name = "DL11_FE", + .stream_name = "DL11 Playback", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_playback = 1, + .ops = &mt8195_playback_ops, + SND_SOC_DAILINK_REG(DL11_FE), + }, + [DAI_LINK_UL1_FE] = { + .name = "UL1_FE", + .stream_name = "UL1 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE, + }, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(UL1_FE), + }, + [DAI_LINK_UL2_FE] = { + .name = "UL2_FE", + .stream_name = "UL2 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL2_FE), + }, + [DAI_LINK_UL3_FE] = { + .name = "UL3_FE", + .stream_name = "UL3 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL3_FE), + }, + [DAI_LINK_UL4_FE] = { + .name = "UL4_FE", + .stream_name = "UL4 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL4_FE), + }, + [DAI_LINK_UL5_FE] = { + .name = "UL5_FE", + .stream_name = "UL5 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL5_FE), + }, + [DAI_LINK_UL6_FE] = { + .name = "UL6_FE", + .stream_name = "UL6 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_PRE, + SND_SOC_DPCM_TRIGGER_PRE, + }, + .dynamic = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(UL6_FE), + }, + [DAI_LINK_UL8_FE] = { + .name = "UL8_FE", + .stream_name = "UL8 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL8_FE), + }, + [DAI_LINK_UL9_FE] = { + .name = "UL9_FE", + .stream_name = "UL9 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL9_FE), + }, + [DAI_LINK_UL10_FE] = { + .name = "UL10_FE", + .stream_name = "UL10 Capture", + .trigger = { + SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST, + }, + .dynamic = 1, + .dpcm_capture = 1, + .ops = &mt8195_capture_ops, + SND_SOC_DAILINK_REG(UL10_FE), + }, + /* BE */ + [DAI_LINK_DL_SRC_BE] = { + .name = "DL_SRC_BE", + .init = mt8195_mt6359_init, + .no_pcm = 1, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(DL_SRC_BE), + }, + [DAI_LINK_DPTX_BE] = { + .name = "DPTX_BE", + .no_pcm = 1, + .dpcm_playback = 1, + .ops = &mt8195_dptx_ops, + .be_hw_params_fixup = mt8195_dptx_hw_params_fixup, + SND_SOC_DAILINK_REG(DPTX_BE), + }, + [DAI_LINK_ETDM1_IN_BE] = { + .name = "ETDM1_IN_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(ETDM1_IN_BE), + }, + [DAI_LINK_ETDM2_IN_BE] = { + .name = "ETDM2_IN_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_capture = 1, + .init = mt8195_rt5682_init, + .ops = &mt8195_rt5682_etdm_ops, + .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, + SND_SOC_DAILINK_REG(ETDM2_IN_BE), + }, + [DAI_LINK_ETDM1_OUT_BE] = { + .name = "ETDM1_OUT_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_playback = 1, + .ops = &mt8195_rt5682_etdm_ops, + .be_hw_params_fixup = mt8195_etdm_hw_params_fixup, + SND_SOC_DAILINK_REG(ETDM1_OUT_BE), + }, + [DAI_LINK_ETDM2_OUT_BE] = { + .name = "ETDM2_OUT_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(ETDM2_OUT_BE), + }, + [DAI_LINK_ETDM3_OUT_BE] = { + .name = "ETDM3_OUT_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_playback = 1, + SND_SOC_DAILINK_REG(ETDM3_OUT_BE), + }, + [DAI_LINK_PCM1_BE] = { + .name = "PCM1_BE", + .no_pcm = 1, + .dai_fmt = SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(PCM1_BE), + }, + [DAI_LINK_UL_SRC1_BE] = { + .name = "UL_SRC1_BE", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(UL_SRC1_BE), + }, + [DAI_LINK_UL_SRC2_BE] = { + .name = "UL_SRC2_BE", + .no_pcm = 1, + .dpcm_capture = 1, + SND_SOC_DAILINK_REG(UL_SRC2_BE), + }, +}; + +static struct snd_soc_card mt8195_mt6359_rt1019_rt5682_soc_card = { + .name = "mt8195_r1019_5682", + .owner = THIS_MODULE, + .dai_link = mt8195_mt6359_rt1019_rt5682_dai_links, + .num_links = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_dai_links), + .controls = mt8195_mt6359_rt1019_rt5682_controls, + .num_controls = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_controls), + .dapm_widgets = mt8195_mt6359_rt1019_rt5682_widgets, + .num_dapm_widgets = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_widgets), + .dapm_routes = mt8195_mt6359_rt1019_rt5682_routes, + .num_dapm_routes = ARRAY_SIZE(mt8195_mt6359_rt1019_rt5682_routes), +}; + +static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) +{ + struct snd_soc_card *card = &mt8195_mt6359_rt1019_rt5682_soc_card; + struct device_node *platform_node; + struct snd_soc_dai_link *dai_link; + struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL; + + int ret, i; + + card->dev = &pdev->dev; + + platform_node = of_parse_phandle(pdev->dev.of_node, + "mediatek,platform", 0); + if (!platform_node) { + dev_dbg(&pdev->dev, "Property 'platform' missing or invalid\n"); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + if (!dai_link->platforms->name) + dai_link->platforms->of_node = platform_node; + } + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + snd_soc_card_set_drvdata(card, priv); + + ret = devm_snd_soc_register_card(&pdev->dev, card); + if (ret) + dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n", + __func__, ret); + return ret; +} + +#ifdef CONFIG_OF +static const struct of_device_id mt8195_mt6359_rt1019_rt5682_dt_match[] = { + {.compatible = "mediatek,mt8195_mt6359_rt1019_rt5682",}, + {} +}; +#endif + +static const struct dev_pm_ops mt8195_mt6359_rt1019_rt5682_pm_ops = { + .poweroff = snd_soc_poweroff, + .restore = snd_soc_resume, +}; + +static struct platform_driver mt8195_mt6359_rt1019_rt5682_driver = { + .driver = { + .name = "mt8195_mt6359_rt1019_rt5682", +#ifdef CONFIG_OF + .of_match_table = mt8195_mt6359_rt1019_rt5682_dt_match, +#endif + .pm = &mt8195_mt6359_rt1019_rt5682_pm_ops, + }, + .probe = mt8195_mt6359_rt1019_rt5682_dev_probe, +}; + +module_platform_driver(mt8195_mt6359_rt1019_rt5682_driver); + +/* Module information */ +MODULE_DESCRIPTION("MT8195-MT6359-RT1019-RT5682 ALSA SoC machine driver"); +MODULE_AUTHOR("Trevor Wu "); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("mt8195_mt6359_rt1019_rt5682 soc card"); From patchwork Thu Aug 19 08:41:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446631 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2E68BC4338F for ; Thu, 19 Aug 2021 08:49:52 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F1E6B61131 for ; Thu, 19 Aug 2021 08:49:51 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org F1E6B61131 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Ep0pI/hwsqQk2n43Zl2jM3srIcBVGh/l/VZiLoBlrMA=; b=wUnDaVo7DSdILR OHAmmMs1Zhm25mJcxXmWuBkW4gr5CiK0Lm4BUBNLMr9rfF8XFVci60MmkpXE+jXqzgonemBZceQZO LLElSjGyutYYmPnuVtVkvdn+K5UwqUXqiRo9L3VuMWcdvyPlXGv9uFyX8p7JZRNDTGcOUXdAA4wai kqX+m2CwonGP2XDFQ4kHs6xP1oPjaipDezmwJ+zlVDbghCc+NRIRoZxwdhUctvM68xJ2K6O6+1TCZ MdCZjddOtpg3Qjl40kjy7XzqUqT7Rxu1oBqzzy8qI1G0E/e2MNehhR6tkWzTrBvdj2bWtvEKmPVLF eluSWFVgGuiSVbr8l8TA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdi2-007khE-Os; Thu, 19 Aug 2021 08:47:35 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGde6-007iUi-6P; Thu, 19 Aug 2021 08:43:34 +0000 X-UUID: c6adf06d1cb442538b79e10f5320512a-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=6f63r2snCy7Qa12UdqnrRoQq1RQldZhgz6Z/W0fZ4Xc=; b=SRpvGekvpVh2zeOdAbLB96nRfHDuuZf9DiqxSr7bb7OzOHXLdhcB0U39Kgok538t38B9wh4bRd6jU5kax0NgE1ofjzoX+z+A5ejyKu2dPTo1TAdGEE7DKhbF1kEAQNfyGuaLosIIkOdGZ/9gXj43PZdFT8C84sXZHfNWQ6X+3gM=; X-UUID: c6adf06d1cb442538b79e10f5320512a-20210819 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1470318296; Thu, 19 Aug 2021 01:43:14 -0700 Received: from mtkmbs05n1.mediatek.inc (172.21.101.15) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:12 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n1.mediatek.inc (172.21.101.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:09 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:09 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 09/11] ASoC: mediatek: mt8195: add DPTX audio support Date: Thu, 19 Aug 2021 16:41:42 +0800 Message-ID: <20210819084144.18483-10-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014330_277100_0301EB2A X-CRM114-Status: GOOD ( 19.21 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds DPTX audio support on mt8195-mt6359-rt1019-rt5682 board. Signed-off-by: Trevor Wu --- sound/soc/mediatek/Kconfig | 1 + .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 88 +++++++++++++++++-- 2 files changed, 84 insertions(+), 5 deletions(-) diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index bfee954d0c7c..cf567a89f421 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -202,6 +202,7 @@ config SND_SOC_MT8195_MT6359_RT1019_RT5682 select SND_SOC_RT1015P select SND_SOC_RT5682_I2C select SND_SOC_DMIC + select SND_SOC_HDMI_CODEC help This adds ASoC driver for Mediatek MT8195 boards with the MT6359 RT1019 RT5682 audio codec. diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c index 39b33aecc1e9..d853bc445753 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -27,6 +27,7 @@ struct mt8195_mt6359_rt1019_rt5682_priv { struct snd_soc_jack headset_jack; + struct snd_soc_jack dp_jack; }; static const struct snd_soc_dapm_widget @@ -327,6 +328,52 @@ static int mt8195_etdm_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, return 0; } +static int mt8195_hdmitx_dptx_startup(struct snd_pcm_substream *substream) +{ + static const unsigned int rates[] = { + 48000 + }; + static const unsigned int channels[] = { + 2, 4, 6, 8 + }; + static const struct snd_pcm_hw_constraint_list constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, + }; + static const struct snd_pcm_hw_constraint_list constraints_channels = { + .count = ARRAY_SIZE(channels), + .list = channels, + .mask = 0, + }; + + struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); + struct snd_pcm_runtime *runtime = substream->runtime; + int ret; + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &constraints_rates); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list rate failed\n"); + return ret; + } + + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_CHANNELS, + &constraints_channels); + if (ret < 0) { + dev_err(rtd->dev, "hw_constraint_list channel failed\n"); + return ret; + } + + return 0; +} + +static const struct snd_soc_ops mt8195_hdmitx_dptx_playback_ops = { + .startup = mt8195_hdmitx_dptx_startup, +}; + static int mt8195_dptx_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { @@ -344,8 +391,25 @@ static struct snd_soc_ops mt8195_dptx_ops = { .hw_params = mt8195_dptx_hw_params, }; -static int mt8195_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, - struct snd_pcm_hw_params *params) +static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mt8195_mt6359_rt1019_rt5682_priv *priv = + snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + int ret = 0; + + ret = snd_soc_card_jack_new(rtd->card, "DP Jack", SND_JACK_LINEOUT, + &priv->dp_jack, NULL, 0); + if (ret) + return ret; + + return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL); +} + +static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, + struct snd_pcm_hw_params *params) + { /* fix BE i2s format to 32bit, clean param mask first */ snd_mask_reset_range(hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT), @@ -687,6 +751,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { }, .dynamic = 1, .dpcm_playback = 1, + .ops = &mt8195_hdmitx_dptx_playback_ops, SND_SOC_DAILINK_REG(DL10_FE), }, [DAI_LINK_DL11_FE] = { @@ -820,7 +885,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { .no_pcm = 1, .dpcm_playback = 1, .ops = &mt8195_dptx_ops, - .be_hw_params_fixup = mt8195_dptx_hw_params_fixup, + .be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup, SND_SOC_DAILINK_REG(DPTX_BE), }, [DAI_LINK_ETDM1_IN_BE] = { @@ -915,7 +980,6 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) struct device_node *platform_node; struct snd_soc_dai_link *dai_link; struct mt8195_mt6359_rt1019_rt5682_priv *priv = NULL; - int ret, i; card->dev = &pdev->dev; @@ -930,6 +994,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) for_each_card_prelinks(card, i, dai_link) { if (!dai_link->platforms->name) dai_link->platforms->of_node = platform_node; + + if (strcmp(dai_link->name, "DPTX_BE") == 0) { + dai_link->codecs->of_node = + of_parse_phandle(pdev->dev.of_node, + "mediatek,dptx-codec", 0); + if (!dai_link->codecs->of_node) { + dev_err(&pdev->dev, "Property 'dptx-codec' missing or invalid\n"); + return -EINVAL; + } + + dai_link->codecs->name = NULL; + dai_link->codecs->dai_name = "i2s-hifi"; + dai_link->init = mt8195_dptx_codec_init; + } } priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); @@ -940,7 +1018,7 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) ret = devm_snd_soc_register_card(&pdev->dev, card); if (ret) - dev_dbg(&pdev->dev, "%s snd_soc_register_card fail %d\n", + dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", __func__, ret); return ret; } From patchwork Thu Aug 19 08:41:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446627 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, UNWANTED_LANGUAGE_BODY,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 64E0FC4338F for ; Thu, 19 Aug 2021 08:48:25 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 2FB956023B for ; Thu, 19 Aug 2021 08:48:25 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 2FB956023B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=cnCHtlmcbxRuMMknTZBDCro+XrM9cbyQzcIz72CMKNg=; b=ytH4ju03jDBVQQ MsMJiTXRGiabnJxofFKgNnwOLFt7Ty0AVUu3WHRM8KfuDaLIsc7LJP30Doe59jylOc8zEqI4CyEg6 51p2gHqoppAxU44WrKOx00OVpBFslyKiw8neFc6Mob0m647Y3BojGDH1DHIMhJqiqYoqhJsvMewbq YnUJTHHOpliX387JX3cS4wVNDfEWPkW2ycFkTHPXJkeeAv9yQF/uB5ee2sUeY2pYd2bi5qwuWW8Aw fSpjioxvAzkqrAY6CzIqV4tfTGni9bmHz/GnISYRHsVwQ8CxYFce/gfzNtAQcudex0J21Xp3c7P0h DgNtHqXvTVZedLAbcURQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdgf-007jrV-2a; Thu, 19 Aug 2021 08:46:09 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGde4-007iUi-6a; Thu, 19 Aug 2021 08:43:30 +0000 X-UUID: 3dd94b70536b4b83998a1e115517099b-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=plK5QBi3Gl4C1jL3qgdzecZPoDWtmWlfLFuZcJWvuwI=; b=T9XayN/laUn+YjHU6sHY61O3dNssfotbcmlZoSnAlKGZX2uVWyCV3f0dgheG2k0hiT7SIzHGmgGMo6gWVIIoH1FsogYKkwM3CO4RGrrwWRmNWJ4Iov8nxEkBnp2AbHHWpj3ghCoob8Rw5Lfpt38ZyWhF5XjIkHyjycb1bZkr+2k=; X-UUID: 3dd94b70536b4b83998a1e115517099b-20210819 Received: from mtkcas67.mediatek.inc [(172.29.193.45)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 1940043806; Thu, 19 Aug 2021 01:43:14 -0700 Received: from mtkmbs05n1.mediatek.inc (172.21.101.15) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:13 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n1.mediatek.inc (172.21.101.15) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:09 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:09 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 10/11] ASoC: mediatek: mt8195: add HDMITX audio support Date: Thu, 19 Aug 2021 16:41:43 +0800 Message-ID: <20210819084144.18483-11-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014328_298013_2E2EC35E X-CRM114-Status: GOOD ( 14.46 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds HDMITX audio support on mt8195-mt6359-rt1019-rt5682 board. Signed-off-by: Trevor Wu --- .../mt8195/mt8195-mt6359-rt1019-rt5682.c | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c index d853bc445753..5dc217f59bd6 100644 --- a/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c +++ b/sound/soc/mediatek/mt8195/mt8195-mt6359-rt1019-rt5682.c @@ -28,6 +28,7 @@ struct mt8195_mt6359_rt1019_rt5682_priv { struct snd_soc_jack headset_jack; struct snd_soc_jack dp_jack; + struct snd_soc_jack hdmi_jack; }; static const struct snd_soc_dapm_widget @@ -407,6 +408,22 @@ static int mt8195_dptx_codec_init(struct snd_soc_pcm_runtime *rtd) return snd_soc_component_set_jack(cmpnt_codec, &priv->dp_jack, NULL); } +static int mt8195_hdmi_codec_init(struct snd_soc_pcm_runtime *rtd) +{ + struct mt8195_mt6359_rt1019_rt5682_priv *priv = + snd_soc_card_get_drvdata(rtd->card); + struct snd_soc_component *cmpnt_codec = + asoc_rtd_to_codec(rtd, 0)->component; + int ret = 0; + + ret = snd_soc_card_jack_new(rtd->card, "HDMI Jack", SND_JACK_LINEOUT, + &priv->hdmi_jack, NULL, 0); + if (ret) + return ret; + + return snd_soc_component_set_jack(cmpnt_codec, &priv->hdmi_jack, NULL); +} + static int mt8195_hdmitx_dptx_hw_params_fixup(struct snd_soc_pcm_runtime *rtd, struct snd_pcm_hw_params *params) @@ -936,6 +953,7 @@ static struct snd_soc_dai_link mt8195_mt6359_rt1019_rt5682_dai_links[] = { SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS, .dpcm_playback = 1, + .be_hw_params_fixup = mt8195_hdmitx_dptx_hw_params_fixup, SND_SOC_DAILINK_REG(ETDM3_OUT_BE), }, [DAI_LINK_PCM1_BE] = { @@ -1008,6 +1026,20 @@ static int mt8195_mt6359_rt1019_rt5682_dev_probe(struct platform_device *pdev) dai_link->codecs->dai_name = "i2s-hifi"; dai_link->init = mt8195_dptx_codec_init; } + + if (strcmp(dai_link->name, "ETDM3_OUT_BE") == 0) { + dai_link->codecs->of_node = + of_parse_phandle(pdev->dev.of_node, + "mediatek,hdmi-codec", 0); + if (!dai_link->codecs->of_node) { + dev_err(&pdev->dev, "Property 'hdmi-codec' missing or invalid\n"); + return -EINVAL; + } + + dai_link->codecs->name = NULL; + dai_link->codecs->dai_name = "i2s-hifi"; + dai_link->init = mt8195_hdmi_codec_init; + } } priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); From patchwork Thu Aug 19 08:41:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?b?VHJldm9yIFd1ICjlkLPmlofoia8p?= X-Patchwork-Id: 12446613 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 441F1C4338F for ; Thu, 19 Aug 2021 08:46:10 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1050260E90 for ; Thu, 19 Aug 2021 08:46:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.4.1 mail.kernel.org 1050260E90 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:CC:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/8tB0ISkOCMHpmrkULEpt1Di5VoDoxQ3iybRUl/IyMg=; b=UUOrnEboJ56WCH O1oPg/6mCzBGWDUBweCU8ZVkszXMNOH+BXitIeoaIyg8ErVoYHA/g12NItmB9JLtuCq4+bZz0Iz6p igU+AOl+fTjyn9I84O7HWo+KvCBPU/7nALTW43370BovTcH1aAufzWZc4B7hA9r9HxeNxGTQLAdmn 9evHLydDBM6hC7J7VCfsa2PXQNJSKthM6TQOBqPcrCKvK0cHHHvbk2RO6+mw6y40DbvsmnpDibi+O hE140Jaw0qhUdGKpEeIPcdaDMgOZKIVYkXfcfu9uOa6LQ0WyxSZwMX4mytkBOWP7LBsxgPXqa02LX rjSy7HLbas3j2pDE9+WQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGdeC-007ibH-RN; Thu, 19 Aug 2021 08:43:37 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1mGddt-007iUi-Qp; Thu, 19 Aug 2021 08:43:21 +0000 X-UUID: 4764241250f04c08ab3dbe351efa1c85-20210819 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=1Iy/LwAkCJ/Q6HXJlJdfxA8zdLgDs0wOAvqLvimjbCE=; b=RSbmNiSSfKddXUDazB4h+BiFQ40UPOIz1SLMefMTmDBWaUCA3tttLow6TEBwk3JjyQ64Ep1BBsK1hZOGiWZ+2UOntiPBkVZ9lgKS6TJ2qGYDy8Ycu9MJkCDlvHgqEX5j1GwiEMypfq1dRgu6rTp75orAaMVacK4ELoBb4Ecr9pg=; X-UUID: 4764241250f04c08ab3dbe351efa1c85-20210819 Received: from mtkcas68.mediatek.inc [(172.29.94.19)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-SHA384 256/256) with ESMTP id 959913457; Thu, 19 Aug 2021 01:43:13 -0700 Received: from mtkmbs05n2.mediatek.inc (172.21.101.140) by MTKMBS62N2.mediatek.inc (172.29.193.42) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 01:43:12 -0700 Received: from mtkcas07.mediatek.inc (172.21.101.84) by mtkmbs05n2.mediatek.inc (172.21.101.140) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Thu, 19 Aug 2021 16:43:10 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkcas07.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Thu, 19 Aug 2021 16:43:10 +0800 From: Trevor Wu To: , , , , CC: , , , , , , , , , , Subject: [PATCH v5 11/11] dt-bindings: mediatek: mt8195: add mt8195-mt6359-rt1019-rt5682 document Date: Thu, 19 Aug 2021 16:41:44 +0800 Message-ID: <20210819084144.18483-12-trevor.wu@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20210819084144.18483-1-trevor.wu@mediatek.com> References: <20210819084144.18483-1-trevor.wu@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210819_014317_909248_42409B7A X-CRM114-Status: GOOD ( 11.69 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org This patch adds document for mt8195 board with mt6359, rt1019 and rt5682 Signed-off-by: Trevor Wu --- .../sound/mt8195-mt6359-rt1019-rt5682.yaml | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml diff --git a/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml new file mode 100644 index 000000000000..20bc0ffd0e34 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/mt8195-mt6359-rt1019-rt5682.yaml @@ -0,0 +1,47 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/mt8195-mt6359-rt1019-rt5682.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Mediatek MT8195 with MT6359, RT1019 and RT5682 ASoC sound card driver + +maintainers: + - Trevor Wu + +description: + This binding describes the MT8195 sound card. + +properties: + compatible: + const: mediatek,mt8195_mt6359_rt1019_rt5682 + + mediatek,platform: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of MT8195 ASoC platform. + + mediatek,dptx-codec: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of MT8195 Display Port Tx codec node. + + mediatek,hdmi-codec: + $ref: "/schemas/types.yaml#/definitions/phandle" + description: The phandle of MT8195 HDMI codec node. + +additionalProperties: false + +required: + - compatible + - mediatek,platform + +examples: + - | + + sound: mt8195-sound { + compatible = "mediatek,mt8195_mt6359_rt1019_rt5682"; + mediatek,platform = <&afe>; + pinctrl-names = "default"; + pinctrl-0 = <&aud_pins_default>; + }; + +...