From patchwork Mon Feb 10 15:01:24 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerio Setti X-Patchwork-Id: 13968073 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 69E87C02198 for ; Mon, 10 Feb 2025 15:02:50 +0000 (UTC) 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=NR1og2ijAnc1mgRfMUfiF0UyNGW5Vj9fiyqX1o7phKI=; b=jgdQJoFid9uZJ8 /J2d3JoIBj7GsNrN8m44BL2+1uPij0+Pfr1F+l7JPuiO5kDC0QZvfhPlTI+aTQoZKvMG8WLfYnMcK b542SbglDWfP9hO5J2LM5lY0ObT1sKayfACpVl8C70mAuvqStI1uyLs3qs05Qw+Nbhy0/+n1y69bt 3Mo8eCvXky9A2QSKaXPa787kghn15izLq75b2o40V3UqlLQWvetlpI8d+al131ipMwMUgE7uzhPqt f/ktDSUMvDJjU8Kc5BjJcTRXbBtEqgjdHKISPCISvxTi+uWD5YzSl9dcDeQzV4sOrSolCScRvcNGg 5x/Me5qG/g0t6VqMBO/g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1thVJ8-00000000EG5-0JBU; Mon, 10 Feb 2025 15:02:46 +0000 Received: from mail-ej1-x630.google.com ([2a00:1450:4864:20::630]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1thVI3-00000000Duj-0INs for linux-amlogic@lists.infradead.org; Mon, 10 Feb 2025 15:01:41 +0000 Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-ab7cc0c1a37so126400066b.0 for ; Mon, 10 Feb 2025 07:01:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199697; x=1739804497; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GoW4ElKxbzHPd1HAYMzIAS62vLOcPOeAwiyP6knEeRE=; b=kr1RffrAjep3wRNmcBiYN0zDU5LCqrJVaiy9jRHk+4oOzLiglccby33pCZcNJI18uw pLBdKKLvgcQtnJ19zr+2h4eKghGdpqZjVCMgAIoYxyCjnPwpG7frJzvvoVtEkeoMSmBV +d53umBoRuzGj3WlksI8u2nq6P5n+BfNpP6XU8aciW72UkZm2717Nm+dMH9cBBqgSG3K gogic+kPPylM2iXQmvvgUq16tECOm/i0xQYFaQHgk15pGMIOJaAATCHC13Ww8b00bvLU wKHHbyW4xfKawgMwt9CUUn96OiXzFme/Lg13VzF8cmqaTl/u1qyl+rUm9MhiE9sSIRuZ AGKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199697; x=1739804497; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GoW4ElKxbzHPd1HAYMzIAS62vLOcPOeAwiyP6knEeRE=; b=JoQmn/1B1f2RtMItwbH72JeUV+Uvc4SdD7RtiWS5iSan/HOsV+UiVZ6tRqcPgE3IyL mhnKYe6NlOkRZ02asPXP3PKhFZIu2JGjS/iszrucTE3pCS+o1/tbuiJLrM3Lec9wQIkq dOnGw6UrsDQjSMboAT6s5/xNwjTDyeT79+7jEixkgE+hTEy2yik/Y/QPB7zm3b4H5c8w qV0nw6uI5tJGoUfobMIIB6z2LghUzNTjhn7mCesu+2O0X0saj5TsJABX+9uyh6ahSqjY 6lJD2ZF24flmA9FsE9gkOW74ul5ohHwbtmjUMVsgNfV9Q3WPvwux3hr+nOETXmd1dUzk CdqQ== X-Forwarded-Encrypted: i=1; AJvYcCUtb7FESC3MgzxGjz8C28rjLRUvRSSs4uIvUIXKIkFGPsiCMi+W5FBvReuwGRFLGCpEMc2Bm4qbkgnu4F92@lists.infradead.org X-Gm-Message-State: AOJu0YwZ5+Azs4Er5Bsz7/ZzVoKLsKT3GGF+Wr57aByBakfjQx+CNnkW ULmyH/CjbnotOMRu+6FAnO0EjPMJFAYRhgzttDMHC9jwNstXlpoYaUmDgAK/AX0= X-Gm-Gg: ASbGncun/EvgEjO+LaEp7CyyexriBbnAy/4F28WXu1KcXxf/5k9YC89EaspGdrgCe+d PowQXdiqZ4wkaJTNdv4HgLAtSdb0KJfA8VcFsUr2rRsNbeKjTuIY3a84vucLrGKbhZU6O9TTBIJ hJV8d6NUxFiTB/j/F2yXIhWSvrYlVciMNaEc86NyY5G+A5zDC1kl4FgOuBl0l6EM1lkNYgAS3u5 Hx83jDTfYa2+PWXQAWSNpeiAIvcUvf3dKS3zDp+kH7HRfb0fafzw75HFHzB5vRvrFDM2NZiDCWk ZVckYYTT/h8iCq0qrBNYiLlW9TcX X-Google-Smtp-Source: AGHT+IFSb4PN0v3r+wCwmVC4SXfkndG2iRcZotOXajDb40L/GlsWSOnpyQvs1PhoQNE6v2oFkgxGPA== X-Received: by 2002:a17:907:3fa5:b0:aab:c78c:a7ed with SMTP id a640c23a62f3a-ab789c2d7aemr1556998866b.49.1739199696088; Mon, 10 Feb 2025 07:01:36 -0800 (PST) Received: from localhost.localdomain ([151.41.218.186]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7bec717f7sm250400466b.81.2025.02.10.07.01.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 07:01:35 -0800 (PST) From: Valerio Setti To: jbrunet@baylibre.com, neil.armstrong@linaro.org, khilman@baylibre.com, martin.blumenstingl@googlemail.com, linux-amlogic@lists.infradead.org, linux-sound@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Valerio Setti Subject: [PATCH RFC 1/6] ASoC: meson: [HACK] let AIU export its clocks through clk-regmap Date: Mon, 10 Feb 2025 16:01:24 +0100 Message-Id: <20250210150129.40248-2-vsetti@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210150129.40248-1-vsetti@baylibre.com> References: <20250210150129.40248-1-vsetti@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250210_070139_115833_2BD526AA X-CRM114-Status: GOOD ( 28.48 ) X-BeenThere: linux-amlogic@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-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Make AIU export its clocks gates and dividers through the clk-regmap interface. The advantage is that other periperals, such as AUDIN (audio input) which requires some clocks owned by AIU, can easily use them. Since clk-regmap interface is not public yet, this commit is marked as HACK, but it is necessary to build and test the following commits that introduce support for AUDIN driver. Being an HACK commit, I took the liberty to condense all the changes (driver, dt-bindings, DT) in a single commit. Once clk-regmap interace will be public, I can rework this by splitting it into a proper commit sequence. Signed-off-by: Valerio Setti --- arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 14 ++- include/dt-bindings/sound/meson-aiu.h | 5 + sound/soc/meson/Makefile | 1 + sound/soc/meson/aiu-clocks.c | 123 ++++++++++++++++++++ sound/soc/meson/aiu-encoder-i2s.c | 121 +++++++++++-------- sound/soc/meson/aiu.c | 22 ++++ sound/soc/meson/aiu.h | 10 ++ 7 files changed, 245 insertions(+), 51 deletions(-) create mode 100644 sound/soc/meson/aiu-clocks.c diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index ed00e67e6923..e2026b7aa03f 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -10,6 +10,7 @@ #include #include #include +#include / { compatible = "amlogic,meson-gxbb"; @@ -62,6 +63,7 @@ usb1: usb@c9100000 { }; &aiu { + #clock-cells = <1>; compatible = "amlogic,aiu-gxbb", "amlogic,aiu"; clocks = <&clkc CLKID_AIU_GLUE>, <&clkc CLKID_I2S_OUT>, @@ -71,7 +73,11 @@ &aiu { <&clkc CLKID_IEC958>, <&clkc CLKID_IEC958_GATE>, <&clkc CLKID_CTS_MCLK_I958>, - <&clkc CLKID_CTS_I958>; + <&clkc CLKID_CTS_I958>, + <&aiu AIU_AOCLK_DIV_GATE>, + <&aiu AIU_AOCLK_BASIC_DIV>, + <&aiu AIU_AOCLK_MORE_DIV>, + <&aiu AIU_LRCLK_DIV>; clock-names = "pclk", "i2s_pclk", "i2s_aoclk", @@ -80,7 +86,11 @@ &aiu { "spdif_pclk", "spdif_aoclk", "spdif_mclk", - "spdif_mclk_sel"; + "spdif_mclk_sel", + "i2s_aoclk_div_gate", + "i2s_aoclk_basic_div", + "i2s_aoclk_more_div", + "i2s_lrclk_div"; resets = <&reset RESET_AIU>; }; diff --git a/include/dt-bindings/sound/meson-aiu.h b/include/dt-bindings/sound/meson-aiu.h index 1051b8af298b..8e8834273fe6 100644 --- a/include/dt-bindings/sound/meson-aiu.h +++ b/include/dt-bindings/sound/meson-aiu.h @@ -15,4 +15,9 @@ #define CTRL_PCM 1 #define CTRL_OUT 2 +#define AIU_AOCLK_DIV_GATE 0 +#define AIU_AOCLK_BASIC_DIV 1 +#define AIU_AOCLK_MORE_DIV 2 +#define AIU_LRCLK_DIV 3 + #endif /* __DT_MESON_AIU_H */ diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile index 24078e4396b0..af75f386feda 100644 --- a/sound/soc/meson/Makefile +++ b/sound/soc/meson/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: (GPL-2.0 OR MIT) snd-soc-meson-aiu-y := aiu.o +snd-soc-meson-aiu-y += aiu-clocks.o snd-soc-meson-aiu-y += aiu-acodec-ctrl.o snd-soc-meson-aiu-y += aiu-codec-ctrl.o snd-soc-meson-aiu-y += aiu-encoder-i2s.o diff --git a/sound/soc/meson/aiu-clocks.c b/sound/soc/meson/aiu-clocks.c new file mode 100644 index 000000000000..ec4b4846b0de --- /dev/null +++ b/sound/soc/meson/aiu-clocks.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include +#include "../../../drivers/clk/meson/clk-regmap.h" +#include +#include + +#include +#include "aiu.h" + +static struct clk_regmap i2s_aoclk_div_gate = { + .data = &(struct clk_regmap_gate_data){ + .offset = AIU_CLK_CTRL, + .bit_idx = 0, + .flags = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "i2s_aoclk_div_gate", + .ops = &clk_regmap_gate_ops, + .parent_names = (const char *[]) { + "cts_amclk", + }, + .num_parents = 1, + .flags = 0, + }, +}; + +static struct clk_regmap i2s_aoclk_basic_divider = { + .data = &(struct clk_regmap_div_data){ + .offset = AIU_CLK_CTRL, + .shift = 2, + .width = 2, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init = &(struct clk_init_data){ + .name = "i2s_aoclk_basic_divider", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]) { + "i2s_aoclk_div_gate", + }, + .num_parents = 1, + .flags = CLK_DIVIDER_POWER_OF_TWO, + }, +}; + +static struct clk_regmap i2s_aoclk_more_divider = { + .data = &(struct clk_regmap_div_data){ + .offset = AIU_CLK_CTRL_MORE, + .shift = 0, + .width = 6, + .flags = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "i2s_aoclk_more_divider", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]) { + "i2s_aoclk_basic_divider", + }, + .num_parents = 1, + .flags = 0, + }, +}; + +static struct clk_regmap i2s_lrclk_divider = { + .data = &(struct clk_regmap_div_data){ + .offset = AIU_CODEC_DAC_LRCLK_CTRL, + .shift = 0, + .width = 12, + .flags = 0, + }, + .hw.init = &(struct clk_init_data){ + .name = "i2s_lrlk_divider", + .ops = &clk_regmap_divider_ops, + .parent_names = (const char *[]) { + "i2s_aoclk_more_divider", + }, + .num_parents = 1, + .flags = 0, + }, +}; + +struct clk_regmap *const aiu_clk_regmaps[] = { + &i2s_aoclk_div_gate, + &i2s_aoclk_basic_divider, + &i2s_aoclk_more_divider, + &i2s_lrclk_divider, +}; + +static struct clk_hw *aiu_clk_hw_get(struct of_phandle_args *clkspec, void *clk_hw_data) +{ + struct clk_regmap **const aiu_clk_regmaps_ptr = clk_hw_data; + unsigned int idx = clkspec->args[0]; + + if (idx >= ARRAY_SIZE(aiu_clk_regmaps)) { + pr_err("%s: invalid index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + return &(aiu_clk_regmaps_ptr[idx]->hw); +} + +int aiu_register_clocks(struct device *dev, struct regmap *map) +{ + int i, ret; + + for (i = 0; i < ARRAY_SIZE(aiu_clk_regmaps); i++) { + aiu_clk_regmaps[i]->map = map; + ret = devm_clk_hw_register(dev, &(aiu_clk_regmaps[i]->hw)); + if (ret) { + dev_err(dev, "Failed to register AIU clock %d\n", i); + return ret; + } + } + + ret = devm_of_clk_add_hw_provider(dev, aiu_clk_hw_get, (void *)&aiu_clk_regmaps); + if (ret) { + dev_err(dev, "devm_of_clk_add_hw_provider failed\n"); + return ret; + } + + return 0; +} diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encoder-i2s.c index a0dd914c8ed1..d469ff429177 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -18,22 +18,10 @@ #define AIU_RST_SOFT_I2S_FAST BIT(0) #define AIU_I2S_DAC_CFG_MSB_FIRST BIT(2) -#define AIU_CLK_CTRL_I2S_DIV_EN BIT(0) -#define AIU_CLK_CTRL_I2S_DIV GENMASK(3, 2) #define AIU_CLK_CTRL_AOCLK_INVERT BIT(6) #define AIU_CLK_CTRL_LRCLK_INVERT BIT(7) #define AIU_CLK_CTRL_LRCLK_SKEW GENMASK(9, 8) #define AIU_CLK_CTRL_MORE_HDMI_AMCLK BIT(6) -#define AIU_CLK_CTRL_MORE_I2S_DIV GENMASK(5, 0) -#define AIU_CODEC_DAC_LRCLK_CTRL_DIV GENMASK(11, 0) - -static void aiu_encoder_i2s_divider_enable(struct snd_soc_component *component, - bool enable) -{ - snd_soc_component_update_bits(component, AIU_CLK_CTRL, - AIU_CLK_CTRL_I2S_DIV_EN, - enable ? AIU_CLK_CTRL_I2S_DIV_EN : 0); -} static int aiu_encoder_i2s_setup_desc(struct snd_soc_component *component, struct snd_pcm_hw_params *params) @@ -80,8 +68,13 @@ static int aiu_encoder_i2s_setup_desc(struct snd_soc_component *component, static int aiu_encoder_i2s_set_legacy_div(struct snd_soc_component *component, struct snd_pcm_hw_params *params, - unsigned int bs) + unsigned long mclk_rate, + unsigned long aoclk_rate) { + struct aiu *aiu = snd_soc_component_get_drvdata(component); + unsigned long bs = mclk_rate / aoclk_rate; + int ret; + switch (bs) { case 1: case 2: @@ -91,27 +84,38 @@ static int aiu_encoder_i2s_set_legacy_div(struct snd_soc_component *component, break; default: - dev_err(component->dev, "Unsupported i2s divider: %u\n", bs); + dev_err(component->dev, "Unsupported i2s divider: %lu\n", bs); return -EINVAL; } - snd_soc_component_update_bits(component, AIU_CLK_CTRL, - AIU_CLK_CTRL_I2S_DIV, - FIELD_PREP(AIU_CLK_CTRL_I2S_DIV, - __ffs(bs))); + /* Use AOCLK_BASIC divider, i.e. set AOCLK_MORE to the same rate as + * its parent so that it acts as a passthrough. + */ + ret = clk_set_rate(aiu->i2s_extra.clks[AOCLK_BASIC_DIV].clk, + aoclk_rate); + if (ret) { + dev_err(component->dev, "failed to set AOCLK_BASIC_DIV\n"); + return ret; + } - snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE, - AIU_CLK_CTRL_MORE_I2S_DIV, - FIELD_PREP(AIU_CLK_CTRL_MORE_I2S_DIV, - 0)); + ret = clk_set_rate(aiu->i2s_extra.clks[AOCLK_MORE_DIV].clk, aoclk_rate); + if (ret) { + dev_err(component->dev, "failed to set AOCLK_MORE_DIV\n"); + return ret; + } return 0; } static int aiu_encoder_i2s_set_more_div(struct snd_soc_component *component, struct snd_pcm_hw_params *params, - unsigned int bs) + unsigned long mclk_rate, + unsigned long aoclk_rate) { + struct aiu *aiu = snd_soc_component_get_drvdata(component); + unsigned long bs = mclk_rate / aoclk_rate; + int ret; + /* * NOTE: this HW is odd. * In most configuration, the i2s divider is 'mclk / blck'. @@ -126,31 +130,41 @@ static int aiu_encoder_i2s_set_more_div(struct snd_soc_component *component, return -EINVAL; } bs += bs / 2; + aoclk_rate = mclk_rate / bs; } - /* Use CLK_MORE for mclk to bclk divider */ - snd_soc_component_update_bits(component, AIU_CLK_CTRL, - AIU_CLK_CTRL_I2S_DIV, - FIELD_PREP(AIU_CLK_CTRL_I2S_DIV, 0)); + /* Use AOCLK_MORE divider, i.e. set AOCLK_BASIC to the same rate as + * its parent so that it acts as a passthough. + */ + ret = clk_set_rate(aiu->i2s_extra.clks[AOCLK_BASIC_DIV].clk, mclk_rate); + if (ret) { + dev_err(component->dev, "failed to set AOCLK_BASIC_DIV\n"); + return ret; + } - snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE, - AIU_CLK_CTRL_MORE_I2S_DIV, - FIELD_PREP(AIU_CLK_CTRL_MORE_I2S_DIV, - bs - 1)); + ret = clk_set_rate(aiu->i2s_extra.clks[AOCLK_MORE_DIV].clk, aoclk_rate); + if (ret) { + dev_err(component->dev, "failed to set AOCLK_MORE_DIV\n"); + return ret; + } return 0; } static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component, - struct snd_pcm_hw_params *params) + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) { struct aiu *aiu = snd_soc_component_get_drvdata(component); unsigned int srate = params_rate(params); - unsigned int fs, bs; + unsigned int fs; + unsigned long mclk_rate, aoclk_rate; int ret; + mclk_rate = clk_get_rate(aiu->i2s.clks[MCLK].clk); + /* Get the oversampling factor */ - fs = DIV_ROUND_CLOSEST(clk_get_rate(aiu->i2s.clks[MCLK].clk), srate); + fs = DIV_ROUND_CLOSEST(mclk_rate, srate); if (fs % 64) return -EINVAL; @@ -160,22 +174,26 @@ static int aiu_encoder_i2s_set_clocks(struct snd_soc_component *component, AIU_I2S_DAC_CFG_MSB_FIRST, AIU_I2S_DAC_CFG_MSB_FIRST); - /* Set bclk to lrlck ratio */ - snd_soc_component_update_bits(component, AIU_CODEC_DAC_LRCLK_CTRL, - AIU_CODEC_DAC_LRCLK_CTRL_DIV, - FIELD_PREP(AIU_CODEC_DAC_LRCLK_CTRL_DIV, - 64 - 1)); - - bs = fs / 64; + /* aoclk rate is 64 times the sample rate */ + aoclk_rate = srate * 64; if (aiu->platform->has_clk_ctrl_more_i2s_div) - ret = aiu_encoder_i2s_set_more_div(component, params, bs); + ret = aiu_encoder_i2s_set_more_div(component, params, + mclk_rate, aoclk_rate); else - ret = aiu_encoder_i2s_set_legacy_div(component, params, bs); + ret = aiu_encoder_i2s_set_legacy_div(component, params, + mclk_rate, aoclk_rate); if (ret) return ret; + /* lrclk rate is equal to the sample rate */ + ret = clk_set_rate(aiu->i2s_extra.clks[LRCLK_DIV].clk, srate); + if (ret) { + dev_err(dai->dev, "failed to set LRCLK_DIV\n"); + return ret; + } + /* Make sure amclk is used for HDMI i2s as well */ snd_soc_component_update_bits(component, AIU_CLK_CTRL_MORE, AIU_CLK_CTRL_MORE_HDMI_AMCLK, @@ -189,10 +207,11 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component = dai->component; + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); int ret; /* Disable the clock while changing the settings */ - aiu_encoder_i2s_divider_enable(component, false); + // clk_disable_unprepare(aiu->i2s_extra.clks[AOCLK_DIV_GATE].clk); ret = aiu_encoder_i2s_setup_desc(component, params); if (ret) { @@ -200,13 +219,17 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream, return ret; } - ret = aiu_encoder_i2s_set_clocks(component, params); + ret = aiu_encoder_i2s_set_clocks(component, params, dai); if (ret) { dev_err(dai->dev, "setting i2s clocks failed\n"); return ret; } - aiu_encoder_i2s_divider_enable(component, true); + ret = clk_prepare_enable(aiu->i2s_extra.clks[AOCLK_DIV_GATE].clk); + if (ret) { + dev_err(dai->dev, "failed to enable AOCLK_DIV_GATE\n"); + return ret; + } return 0; } @@ -214,10 +237,10 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_substream *substream, static int aiu_encoder_i2s_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_component *component = dai->component; - - aiu_encoder_i2s_divider_enable(component, false); + struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); + clk_disable_unprepare(aiu->i2s_extra.clks[AOCLK_DIV_GATE].clk); + return 0; } diff --git a/sound/soc/meson/aiu.c b/sound/soc/meson/aiu.c index f2890111c1d2..ef3365348aa1 100644 --- a/sound/soc/meson/aiu.c +++ b/sound/soc/meson/aiu.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include "../../../drivers/clk/meson/clk-regmap.h" #include #include @@ -203,6 +205,13 @@ static const char * const aiu_i2s_ids[] = { [MIXER] = "i2s_mixer", }; +static const char * const aiu_i2s_extra_ids[] = { + [AOCLK_DIV_GATE] = "i2s_aoclk_div_gate", + [AOCLK_BASIC_DIV] = "i2s_aoclk_basic_div", + [AOCLK_MORE_DIV] = "i2s_aoclk_more_div", + [LRCLK_DIV] = "i2s_lrclk_div", +}; + static const char * const aiu_spdif_ids[] = { [PCLK] = "spdif_pclk", [AOCLK] = "spdif_aoclk", @@ -229,6 +238,13 @@ static int aiu_clk_get(struct device *dev) if (ret) return dev_err_probe(dev, ret, "Can't get the i2s clocks\n"); + ret = aiu_clk_bulk_get(dev, aiu_i2s_extra_ids, + ARRAY_SIZE(aiu_i2s_extra_ids), + &aiu->i2s_extra); + if (ret) + return dev_err_probe(dev, ret, + "Can't get the i2s extra clocks\n"); + ret = aiu_clk_bulk_get(dev, aiu_spdif_ids, ARRAY_SIZE(aiu_spdif_ids), &aiu->spdif); if (ret) @@ -278,6 +294,12 @@ static int aiu_probe(struct platform_device *pdev) if (aiu->spdif.irq < 0) return aiu->spdif.irq; + ret = aiu_register_clocks(dev, map); + if (ret) { + dev_err(dev, "Failed to register AIU clocks\n"); + return ret; + } + ret = aiu_clk_get(dev); if (ret) return ret; diff --git a/sound/soc/meson/aiu.h b/sound/soc/meson/aiu.h index 0f94c8bf6081..847466c02408 100644 --- a/sound/soc/meson/aiu.h +++ b/sound/soc/meson/aiu.h @@ -21,6 +21,13 @@ enum aiu_clk_ids { MIXER }; +enum aiu_i2s_extra_clk_ids { + AOCLK_DIV_GATE = 0, + AOCLK_BASIC_DIV, + AOCLK_MORE_DIV, + LRCLK_DIV, +}; + struct aiu_interface { struct clk_bulk_data *clks; unsigned int clk_num; @@ -35,6 +42,7 @@ struct aiu_platform_data { struct aiu { struct clk *spdif_mclk; struct aiu_interface i2s; + struct aiu_interface i2s_extra; struct aiu_interface spdif; const struct aiu_platform_data *platform; }; @@ -54,6 +62,8 @@ int aiu_acodec_ctrl_register_component(struct device *dev); int aiu_fifo_i2s_dai_probe(struct snd_soc_dai *dai); int aiu_fifo_spdif_dai_probe(struct snd_soc_dai *dai); +int aiu_register_clocks(struct device *dev, struct regmap *map); + extern const struct snd_soc_dai_ops aiu_fifo_i2s_dai_ops; extern const struct snd_soc_dai_ops aiu_fifo_spdif_dai_ops; extern const struct snd_soc_dai_ops aiu_encoder_i2s_dai_ops; From patchwork Mon Feb 10 15:01:25 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerio Setti X-Patchwork-Id: 13968076 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 7917EC021A1 for ; Mon, 10 Feb 2025 15:02:51 +0000 (UTC) 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=MtT4K32ROx4ygkre3GR37wrVEaZHeT7vZUJfrO1z8eQ=; b=1rgJxWhwacTMsh cni659P4RVZG9hSkEJuxiMpSCO2IiCnuo9TvxerEIOmFzkrAXQJEOyp387Q3mGndjfbPHmcvHdIgY HQ9zKcokAuG73N3/zFqZKHRdaecjFT8FgP3rfEZztYlxefBkyecRcyJ+q5kvw6SpENWz/j5F0IiK6 1n1c6ydyj2SIFAOOWSSJA+wetyPr1M8+SpaAhBJ+emn11HxQd7QONBTvxJPJ8S590xnq4VUt6C7jp 1Cn9xcM6VYzZBOvCIUPOtLvn4zfEyC6sxhFNrCWuS26cTNu6Fifh8pn/5tfvrt8En9KxE7/2bYcW+ EH7HU0mO7IM++rxvVGbw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1thVJ8-00000000EGA-1pPy; Mon, 10 Feb 2025 15:02:46 +0000 Received: from mail-ed1-x52d.google.com ([2a00:1450:4864:20::52d]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1thVI2-00000000Dus-42eq for linux-amlogic@lists.infradead.org; Mon, 10 Feb 2025 15:01:41 +0000 Received: by mail-ed1-x52d.google.com with SMTP id 4fb4d7f45d1cf-5de594e2555so4427314a12.2 for ; Mon, 10 Feb 2025 07:01:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199697; x=1739804497; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=BadoGFdbWi+RxOS2TPc6oRzGweQOUnlp92mI5rcILo8=; b=NEfW1GjD+7oH9jvq9Y0gA9j3huX+ItZSVLmPzWTrOtoMZpvX2cXTgbiPQNRAeh2l+I z8Gpq6tzXG6xi5RVhrCUfJU+qFOXaG1sz8AYZYXGvarJjLc8gYFBusrMMnJUQYi+0kge mqo+Xd2FFZN4FPyPrciZv24qqVkEiUXRlJj7OJaGHeuvSnuf0caBfgoK/gG3ygfqUr5w /BFXyxLacp7AIetLUWrdIG4yFyDteGuABCIQwLUGR1HaEUpBDJo3vPUIzy9yhC5lNDhq 0Ndgp9SnbCvdlYjMHfDaQ1cOTowH7lXXKgZ8K7oj/V2gLp1OH8kxcVVkeU7XaEJpDSAF acbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199697; x=1739804497; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=BadoGFdbWi+RxOS2TPc6oRzGweQOUnlp92mI5rcILo8=; b=jpI2Ft1o30HTM3N8Mx1VrVNTeaJmEfMdthQiMpL6RBc3gsxdcGUTlA75ajGRZBQIj5 dVotJlJ23FpS5/Hr0WudL9311lQz2HFDqJ1W/rVNyEhzK5z5qUEK7o2bpy7LLRVPo+tF OVwDDWbiGC04NAWdNxHumUgbXDpzFVz2NdVSdKbaX+cfrNk/1LFLT55+hzJNk+A2JaaJ EpqTnEvN8sIrimzQT5r3kUaEnBbPx3UpXJpFstEkKCNOvkY2skXg3IhSc1BAxBBE+OTU 5VLF9hdQJLk1bg9rKfI28uqDho9eJwGtUFQ36hmCxLuwzmJdhiT70lV2OtkeklYaDrBv kYSQ== X-Forwarded-Encrypted: i=1; AJvYcCWIJhXU96PDLVlOIfxkaCYxFY2Ci2A8P6CJPRdoiwfwb2UooiBu2BrACVdQoPirylpkZ9zR59CcNUGDuPS7@lists.infradead.org X-Gm-Message-State: AOJu0YxgS2eMHNP1/tj6GKTW+MvU/DfN5/ec4nb3+P7GEXy+1ohlOPJ3 ilf4hFIM4YnLXA11y44Eu/BtffPIKvkqFvSyCCNsbrVVyirv4cQH/7quBB/pcHI= X-Gm-Gg: ASbGnctZWLq6dL2ptNXolATJGWarxZAStq+DlrvKgJ98bRYEjcf5pBRJYmpjdUr+4/A VsTMHQ8nRmVD3RCKoIcgbXDiNHh6LJBu38PDz/59GOZ7DYh4qAGJM3tu7xwYz/8uFC/fD1tgxBX uttC+ZruxMsNnoVv030N2PgTWft/8wor/j0Qq6ZCJpND9n+bw8V/PYKdBuN81jX8uzxtQLOdwl/ +pcOEAqryVaD0o+PaU0cwMHtTQDcsIJyCQzsrfuOAGUm7XvSlw+5q12JSmByk23E5YG5VlrlMBo KfZeQ/ZH3aaCDyp2A+9mpWScX3Hj X-Google-Smtp-Source: AGHT+IGpVqycyZR2YnxbLB+0FPSVnyS2AxVJJQJRRoHf/8da6EsHjXh4Mti5AGi9XDwh+En5MO0W0w== X-Received: by 2002:a17:907:960f:b0:ab6:dbe0:d658 with SMTP id a640c23a62f3a-ab789b20e6amr1580540166b.31.1739199696978; Mon, 10 Feb 2025 07:01:36 -0800 (PST) Received: from localhost.localdomain ([151.41.218.186]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7bec717f7sm250400466b.81.2025.02.10.07.01.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 07:01:36 -0800 (PST) From: Valerio Setti To: jbrunet@baylibre.com, neil.armstrong@linaro.org, khilman@baylibre.com, martin.blumenstingl@googlemail.com, linux-amlogic@lists.infradead.org, linux-sound@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Valerio Setti Subject: [PATCH RFC 2/6] ASoC: meson: audin: add audio input dt-bindings Date: Mon, 10 Feb 2025 16:01:25 +0100 Message-Id: <20250210150129.40248-3-vsetti@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210150129.40248-1-vsetti@baylibre.com> References: <20250210150129.40248-1-vsetti@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250210_070139_015624_63DFDB81 X-CRM114-Status: GOOD ( 13.09 ) X-BeenThere: linux-amlogic@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-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Add the dt-bindings and documentation of the AUDIN audio controller. This component provides most audio input found on the Amlogic GXBB SoC family. Signed-off-by: Valerio Setti --- .../bindings/sound/amlogic,audin.yaml | 104 ++++++++++++++++++ include/dt-bindings/sound/meson-audin.h | 10 ++ 2 files changed, 114 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/amlogic,audin.yaml create mode 100644 include/dt-bindings/sound/meson-audin.h diff --git a/Documentation/devicetree/bindings/sound/amlogic,audin.yaml b/Documentation/devicetree/bindings/sound/amlogic,audin.yaml new file mode 100644 index 000000000000..7fb231a8d5a7 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/amlogic,audin.yaml @@ -0,0 +1,104 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/amlogic,audin.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic AUDIN audio output controller + +maintainers: + - Valerio Setti + +allOf: + - $ref: dai-common.yaml# + +properties: + $nodename: + pattern: "^audio-input-controller@.*" + + "#sound-dai-cells": + const: 1 + + compatible: + items: + - enum: + - amlogic,audin-gxbb + - const: amlogic,audin + + clocks: + items: + - description: AIU peripheral clock + - description: I2S peripheral clock + - description: I2S output clock + - description: I2S master clock + - description: I2S mixer clock + - description: AUDIN peripheral clock + - description: I2S bit clock gate + - description: I2S bit clock basic divider + - description: I2S bit clock more divider + - description: I2S L/R clock divider + + clock-names: + items: + - const: pclk + - const: i2s_pclk + - const: i2s_aoclk + - const: i2s_mclk + - const: i2s_mixer + - const: i2s_input_clk + - const: i2s_aoclk_div_gate + - const: i2s_aoclk_basic_div + - const: i2s_aoclk_more_div + - const: i2s_lrclk_div + + reg: + maxItems: 1 + + resets: + maxItems: 1 + + sound-name-prefix: true + +required: + - "#sound-dai-cells" + - compatible + - clocks + - clock-names + - reg + - resets + +additionalProperties: false + +examples: + - | + #include + #include + #include + + audin: audio-input-controller@a000 { + compatible = "amlogic,audin-gxbb", "amlogic,audin"; + #sound-dai-cells = <1>; + sound-name-prefix = "AUDIN"; + reg = <0x0 0xa000 0x0 0x308>; + clocks = <&clkc CLKID_AIU_GLUE>, + <&clkc CLKID_I2S_OUT>, + <&clkc CLKID_AOCLK_GATE>, + <&clkc CLKID_CTS_AMCLK>, + <&clkc CLKID_MIXER_IFACE>, + <&clkc CLKID_I2S_SPDIF>, + <&aiu AIU_AOCLK_DIV_GATE>, + <&aiu AIU_AOCLK_BASIC_DIV>, + <&aiu AIU_AOCLK_MORE_DIV>, + <&aiu AIU_LRCLK_DIV>; + clock-names = "pclk", + "i2s_pclk", + "i2s_aoclk", + "i2s_mclk", + "i2s_mixer", + "i2s_input_clk", + "i2s_aoclk_div_gate", + "i2s_aoclk_basic_div", + "i2s_aoclk_more_div", + "i2s_lrclk_div"; + resets = <&reset RESET_AIU>; + }; diff --git a/include/dt-bindings/sound/meson-audin.h b/include/dt-bindings/sound/meson-audin.h new file mode 100644 index 000000000000..30c2fe218ab4 --- /dev/null +++ b/include/dt-bindings/sound/meson-audin.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __DT_MESON_AUDIN_H +#define __DT_MESON_AUDIN_H + +#define CPU_AUDIN_TODDR_0 0 +#define CPU_AUDIN_TODDR_1 1 +#define CPU_AUDIN_TODDR_2 2 +#define CPU_I2S_DECODER 3 + +#endif /* __DT_MESON_AUDIN_H */ From patchwork Mon Feb 10 15:01:26 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerio Setti X-Patchwork-Id: 13968078 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id E0E5FC0219B for ; Mon, 10 Feb 2025 15:02:50 +0000 (UTC) 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=QfIoXtVDMUOgWpSxuCVDKwNJ/icUXlg9L0+9PnUiTwg=; b=mDRs0S/1098NLw lyhFS/JnL0w911JT43ZLY/82MioiKXTjTVCBnaKwyHHF5vw97t0xwvw+zL+SD7Crf1jj+i1vv1jcP eHD4CI8dZhcbDYBy0KQpZ29Y67hdsIvbBLhFJEUtgxikj0VJZE6iN+Q4ioQ48aRXS2sjBcr8ZBshp MzOvBwBUsDxI16BJAtQ64//HAsr4nht294z8XmedQ1WD2LxzeQbXs4QBFRIsGrPe7Z+eOD+eDL1mo gESLhFMT5gx3WtWZVkYDL7Js1lEnF4IN/q1CheErHK0HhrhnAahViMcejZdE+g3tRL57cA29DF/OU 2PxixmE9ryMOLy7g/Q1w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1thVJ8-00000000EGT-3LQ6; Mon, 10 Feb 2025 15:02:46 +0000 Received: from mail-ed1-x52c.google.com ([2a00:1450:4864:20::52c]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1thVI4-00000000DwB-1JPj for linux-amlogic@lists.infradead.org; Mon, 10 Feb 2025 15:01:42 +0000 Received: by mail-ed1-x52c.google.com with SMTP id 4fb4d7f45d1cf-5de5e3729ecso4007159a12.0 for ; Mon, 10 Feb 2025 07:01:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199698; x=1739804498; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IVD5Ahyv/b3Ko22+0ZGNasjR9VpgBzuxVGD+jcQGn9E=; b=FFQ9exivlk6t/WqyDlPeHoZ4lAeGpk3FH8Z/W6y2gEBMKaT3HnHHh4JYqFR2rSDWab 6rXjGwTz0IwSAjo6JaAbwv84db1a85L0Rb3gI+Gh+bJw9TTB5TDrLPwPy65KFe+N11vT sPO4s4rd9fi6GL9WJ2ydWOQTwfXW1iSzfMEBZte8D0gRDOhWqugcfHs0B0QZRVHXXUBB emm8VMCl15pIlEzTLj7mVVQIMlDIJ2Hb1bo8EsWHiOYy4NMgD5Jb4EllW16jk12NEqot jiZJWrE7h1bjI2DugqzHSZrsknXkfPT6mKGpDeiTJTHnr2MTbSgeXOtpHpG1oZTq4deu xeGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199698; x=1739804498; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=IVD5Ahyv/b3Ko22+0ZGNasjR9VpgBzuxVGD+jcQGn9E=; b=TZGiJ5zYQY3d0RH0QLBY4AibXg+r3Xdh7aios8KuqqLy6C0orvEJPtrVQYVsG5Q5tJ XMdeWeVyieL0sXtPhdJRQjTCxACSWaAor/njLOgsh/RiJ3zRdv59ofDK2CVjn1/8+8cj /gDNpXkYq/GEB/q5WDpYRi6EqBch7olSKQAvq2JVDBZKrQMrxvalin29pVMcn8ocOHer dMSaJx3vj8naOEIhH4okmUi6mzIj0NztgO0TEgXhPBvZIErc7ZFSg+MOuws+RVBqoy9T //rbFJwG7nZbXnYLnmtEfAKwTCq8pr+UKJOxKA3XWazRBQ5oP7l7PkIn8S+db8dHbOvm CqdQ== X-Forwarded-Encrypted: i=1; AJvYcCVgw/9TcWZqn3/TvAcwgQrP99H899pWrqGKaJRWtoSKYoiIHNk9/AgaF7tncX4Dcw7dEXt6a9vGg6g3C4tb@lists.infradead.org X-Gm-Message-State: AOJu0YxCqFRweRNQuxqKTY+xV3SkIC0DQMH2FC8zGbDsmfAFzO1dKzGY 5J+3G2QYb3HRaZZ1Tg8dPhttVZO8gBHVMdvkTdnoCBHCr6HGKkeDpf8374XhVqs= X-Gm-Gg: ASbGncvX43izCKcCXaReUgGGDRIJOMYC4soYJ7WlLN32bcdnuAwUcanuSaVBT6003q3 ofe2ML1KvFXIFN4ckUJFReqdcsYAwAPlBuD5lIdRMnZBjgBBf3xroMFRc4uSq0jbnLW4jiYpm3+ +hXis2hooShYexD2wK32KgtZyORSIvCe3kRwqDpPNIOeSPh0F/KkRro+rPRnQ03upcS4LEpuiSo 7mtCHUGa+N4qu903WpWSKjkuT80zB80D4y6klOYt8cFJH47mL/9AEN0k6+mrHYyUYyFVETExiyZ GW33lLRkSUCVA1Ee4aJ1SJKaNy1M X-Google-Smtp-Source: AGHT+IFOHn3m4ICp9bqFmWrQqHtCVAGtZ0JqR6Zgx3LJqCU/fvhBcOVOBrgQkgqRXXGPCL413lvStg== X-Received: by 2002:a17:907:1c9c:b0:aab:ee4a:6788 with SMTP id a640c23a62f3a-ab789c52c06mr1656549266b.57.1739199697949; Mon, 10 Feb 2025 07:01:37 -0800 (PST) Received: from localhost.localdomain ([151.41.218.186]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7bec717f7sm250400466b.81.2025.02.10.07.01.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 07:01:37 -0800 (PST) From: Valerio Setti To: jbrunet@baylibre.com, neil.armstrong@linaro.org, khilman@baylibre.com, martin.blumenstingl@googlemail.com, linux-amlogic@lists.infradead.org, linux-sound@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Valerio Setti Subject: [PATCH RFC 3/6] ASoC: meson: add AUDIN driver Date: Mon, 10 Feb 2025 16:01:26 +0100 Message-Id: <20250210150129.40248-4-vsetti@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210150129.40248-1-vsetti@baylibre.com> References: <20250210150129.40248-1-vsetti@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250210_070140_390444_F2353687 X-CRM114-Status: GOOD ( 27.24 ) X-BeenThere: linux-amlogic@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-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Add support for the AUDIN driver which provides audio input capabilities to the Amlogic GXBB platform. As of now it is composed by: - I2S decoder which receives I2S audio samples from some external codec; - toddr module which transfers collected audio samples to an internal FIFO first and then to RAM. I2S is the only supported audio source as of now, but others are possible and can be added in the future. Signed-off-by: Valerio Setti --- sound/soc/meson/Kconfig | 6 + sound/soc/meson/Makefile | 4 + sound/soc/meson/aiu-encoder-i2s.c | 2 +- sound/soc/meson/audin-decoder-i2s.c | 247 +++++++++++++++++ sound/soc/meson/audin-toddr.c | 403 ++++++++++++++++++++++++++++ sound/soc/meson/audin.c | 321 ++++++++++++++++++++++ sound/soc/meson/audin.h | 119 ++++++++ 7 files changed, 1101 insertions(+), 1 deletion(-) create mode 100644 sound/soc/meson/audin-decoder-i2s.c create mode 100644 sound/soc/meson/audin-toddr.c create mode 100644 sound/soc/meson/audin.c create mode 100644 sound/soc/meson/audin.h diff --git a/sound/soc/meson/Kconfig b/sound/soc/meson/Kconfig index 6458d5dc4902..3a86c6be08aa 100644 --- a/sound/soc/meson/Kconfig +++ b/sound/soc/meson/Kconfig @@ -12,6 +12,12 @@ config SND_MESON_AIU Select Y or M to add support for the Audio output subsystem found in the Amlogic Meson8, Meson8b and GX SoC families +config SND_MESON_AUDIN + tristate "Amlogic AUDIN" + help + Select Y or M to add support for the Audio input subsystem found + in the Amlogic GXBB SoC family. + config SND_MESON_AXG_FIFO tristate select REGMAP_MMIO diff --git a/sound/soc/meson/Makefile b/sound/soc/meson/Makefile index af75f386feda..e4869af72811 100644 --- a/sound/soc/meson/Makefile +++ b/sound/soc/meson/Makefile @@ -9,6 +9,9 @@ snd-soc-meson-aiu-y += aiu-encoder-spdif.o snd-soc-meson-aiu-y += aiu-fifo.o snd-soc-meson-aiu-y += aiu-fifo-i2s.o snd-soc-meson-aiu-y += aiu-fifo-spdif.o +snd-soc-meson-audin-y := audin.o +snd-soc-meson-audin-y += audin-toddr.o +snd-soc-meson-audin-y += audin-decoder-i2s.o snd-soc-meson-axg-fifo-y := axg-fifo.o snd-soc-meson-axg-frddr-y := axg-frddr.o snd-soc-meson-axg-toddr-y := axg-toddr.o @@ -28,6 +31,7 @@ snd-soc-meson-g12a-tohdmitx-y := g12a-tohdmitx.o snd-soc-meson-t9015-y := t9015.o obj-$(CONFIG_SND_MESON_AIU) += snd-soc-meson-aiu.o +obj-$(CONFIG_SND_MESON_AUDIN) += snd-soc-meson-audin.o obj-$(CONFIG_SND_MESON_AXG_FIFO) += snd-soc-meson-axg-fifo.o obj-$(CONFIG_SND_MESON_AXG_FRDDR) += snd-soc-meson-axg-frddr.o obj-$(CONFIG_SND_MESON_AXG_TODDR) += snd-soc-meson-axg-toddr.o diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encoder-i2s.c index d469ff429177..b4d5311eb3c5 100644 --- a/sound/soc/meson/aiu-encoder-i2s.c +++ b/sound/soc/meson/aiu-encoder-i2s.c @@ -240,7 +240,7 @@ static int aiu_encoder_i2s_hw_free(struct snd_pcm_substream *substream, struct aiu *aiu = snd_soc_component_get_drvdata(dai->component); clk_disable_unprepare(aiu->i2s_extra.clks[AOCLK_DIV_GATE].clk); - + return 0; } diff --git a/sound/soc/meson/audin-decoder-i2s.c b/sound/soc/meson/audin-decoder-i2s.c new file mode 100644 index 000000000000..a6c01399af0c --- /dev/null +++ b/sound/soc/meson/audin-decoder-i2s.c @@ -0,0 +1,247 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2025 BayLibre, SAS. +// Author: Valerio Setti + +#include +#include +#include +#include +#include + +#include "audin.h" + +static int audin_decoder_i2s_setup_desc(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + int val; + + /* I2S decoder always outputs 24bits to the FIFO according to the + * manual. The only thing we can do is mask some bits as follows: + * - 0: 16 bit + * - 1: 18 bits (not exposed as supported format) + * - 2: 20 bits (not exposed as supported format) + * - 3: 24 bits + * + * We force 24 bit output here and filter unnecessary ones at the FIFO + * stage. + * Note: data is left-justified, so in case of 16 bits samples, this + * means that the LSB is to be discarded at FIFO level and the + * relevant part is in bits [23:8]. + */ + switch (params_width(params)) { + case 16: + case 24: + val = 3; + break; + default: + dev_err(dai->dev, "Error: wrong sample width %d", + params_physical_width(params)); + return -EINVAL; + } + val = FIELD_PREP(AUDIN_I2SIN_CTRL_I2SIN_SIZE_MASK, val); + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, + AUDIN_I2SIN_CTRL_I2SIN_SIZE_MASK, val); + + /* The manual claims that this platform supports up to 4 streams + * (8 channels), but only 1 stream (2 channels) is supported ATM. + */ + val = FIELD_PREP(AUDIN_I2SIN_CTRL_I2SIN_CHAN_EN_MASK, 1); + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, + AUDIN_I2SIN_CTRL_I2SIN_CHAN_EN_MASK, val); + + return 0; +} + +static int audin_decoder_i2s_set_clocks(struct snd_soc_component *component, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct audin *audin = snd_soc_component_get_drvdata(component); + unsigned int sample_rate = params_rate(params); + unsigned long mclk; + int ret; + + mclk = clk_get_rate(audin->bulk_clks[MCLK].clk); + + /* Set mclk to bclk ratio. + * We're going to use the new/finer clock divider (BCLK_MORE_DIV) for + * this, so let's keep the legacy one (BCLK_DIV) as passthrough. + */ + ret = clk_set_rate(audin->aoclk_basic_div, mclk); + if (ret) { + dev_err(dai->dev, "Failed to set aoclk_basic_div %d\n", ret); + return ret; + } + + /* We're going for a fixed bclk to lrclk ratio of 64. */ + ret = clk_set_rate(audin->aoclk_more_div, sample_rate * 64UL); + if (ret) { + dev_err(dai->dev, "Failed to set aoclk_more_div %d\n", ret); + return ret; + } + + ret = clk_set_rate(audin->lrclk_div, sample_rate); + if (ret) { + dev_err(dai->dev, "Failed to set lrclk_div %d\n", ret); + return ret; + } + + return 0; +} + +static int audin_decoder_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct audin *audin = snd_soc_component_get_drvdata(component); + int ret; + + ret = audin_decoder_i2s_setup_desc(params, dai); + if (ret) { + dev_err(dai->dev, "setting i2s desc failed\n"); + return ret; + } + + ret = audin_decoder_i2s_set_clocks(component, params, dai); + if (ret) { + dev_err(dai->dev, "setting i2s clocks failed\n"); + return ret; + } + + ret = clk_prepare_enable(audin->aoclk_div_gate); + if (ret) + return ret; + + return 0; +} + +static int audin_decoder_i2s_hw_free(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct audin *audin = snd_soc_component_get_drvdata(dai->component); + + clk_disable_unprepare(audin->aoclk_div_gate); + + return 0; +} + +static int audin_decoder_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_component *component = dai->component; + unsigned int val = 0; + + /* Only CPU Master / Codec Slave supported ATM */ + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) != SND_SOC_DAIFMT_BP_FP) + return -EINVAL; + + /* Use clocks from AIU and not from the pads since we only want to + * support master mode. + */ + val = AUDIN_I2SIN_CTRL_I2SIN_CLK_SEL | + AUDIN_I2SIN_CTRL_I2SIN_LRCLK_SEL | + AUDIN_I2SIN_CTRL_I2SIN_DIR; + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, val, val); + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_IB_NF: + val = AUDIN_I2SIN_CTRL_I2SIN_POS_SYNC; + break; + case SND_SOC_DAIFMT_NB_NF: + val = 0; + break; + default: + dev_err(dai->dev, "Error: unsupported format %x", fmt); + return -EINVAL; + } + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, + AUDIN_I2SIN_CTRL_I2SIN_POS_SYNC, val); + + /* MSB data starts 1 clock cycle after LRCLK transition, as per I2S + * specs. + */ + val = FIELD_PREP(AUDIN_I2SIN_CTRL_I2SIN_LRCLK_SKEW_MASK, 1); + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, + AUDIN_I2SIN_CTRL_I2SIN_LRCLK_INV | + AUDIN_I2SIN_CTRL_I2SIN_LRCLK_SKEW_MASK, + val); + + return 0; +} + +static int audin_decoder_i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, + AUDIN_I2SIN_CTRL_I2SIN_EN, + AUDIN_I2SIN_CTRL_I2SIN_EN); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_STOP: + snd_soc_component_update_bits(component, AUDIN_I2SIN_CTRL, + AUDIN_I2SIN_CTRL_I2SIN_EN, 0); + break; + default: + return -EINVAL; + } + return 0; +} + +static int audin_decoder_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id, + unsigned int freq, int dir) +{ + struct audin *audin = snd_soc_component_get_drvdata(dai->component); + int ret; + + if (WARN_ON(clk_id != 0)) + return -EINVAL; + + if (dir == SND_SOC_CLOCK_IN) + return 0; + + ret = clk_set_rate(audin->bulk_clks[MCLK].clk, freq); + if (ret) + dev_err(dai->dev, "Failed to set sysclk %d", ret); + + return ret; +} + +static int audin_decoder_i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct audin *audin = snd_soc_component_get_drvdata(dai->component); + int ret; + + ret = clk_bulk_prepare_enable(audin->bulk_clks_num, audin->bulk_clks); + if (ret) + dev_err(dai->dev, "Failed to enable bulk clocks %d\n", ret); + + return ret; +} + +static void audin_decoder_i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct audin *audin = snd_soc_component_get_drvdata(dai->component); + + clk_bulk_disable_unprepare(audin->bulk_clks_num, audin->bulk_clks); +} + +const struct snd_soc_dai_ops audin_decoder_i2s_dai_ops = { + .hw_params = audin_decoder_i2s_hw_params, + .hw_free = audin_decoder_i2s_hw_free, + .set_fmt = audin_decoder_i2s_set_fmt, + .set_sysclk = audin_decoder_i2s_set_sysclk, + .startup = audin_decoder_i2s_startup, + .shutdown = audin_decoder_i2s_shutdown, + .trigger = audin_decoder_i2s_trigger, +}; diff --git a/sound/soc/meson/audin-toddr.c b/sound/soc/meson/audin-toddr.c new file mode 100644 index 000000000000..14db8b9587e8 --- /dev/null +++ b/sound/soc/meson/audin-toddr.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2025 BayLibre, SAS. +// Author: Valerio Setti + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "audin.h" + +struct fifo_regs { + unsigned int start; + unsigned int end; + unsigned int ptr; + unsigned int intr; + unsigned int rdptr; + unsigned int ctrl; + unsigned int ctrl1; + unsigned int wrap; +}; + +struct fifo_regs_bit_masks { + unsigned int overflow_en; + unsigned int addr_trigger_en; + unsigned int overflow_set; + unsigned int addr_trigger_set; +}; + +#define AUDIN_FIFO_COUNT 3 + +struct fifo_regs audin_fifo_regs[AUDIN_FIFO_COUNT] = { + [0] = { + .start = AUDIN_FIFO0_START, + .end = AUDIN_FIFO0_END, + .ptr = AUDIN_FIFO0_PTR, + .intr = AUDIN_FIFO0_INTR, + .rdptr = AUDIN_FIFO0_RDPTR, + .ctrl = AUDIN_FIFO0_CTRL, + .ctrl1 = AUDIN_FIFO0_CTRL1, + .wrap = AUDIN_FIFO0_WRAP, + }, + [1] = { + .start = AUDIN_FIFO1_START, + .end = AUDIN_FIFO1_END, + .ptr = AUDIN_FIFO1_PTR, + .intr = AUDIN_FIFO1_INTR, + .rdptr = AUDIN_FIFO1_RDPTR, + .ctrl = AUDIN_FIFO1_CTRL, + .ctrl1 = AUDIN_FIFO1_CTRL1, + .wrap = AUDIN_FIFO1_WRAP, + }, + [2] = { + .start = AUDIN_FIFO2_START, + .end = AUDIN_FIFO2_END, + .ptr = AUDIN_FIFO2_PTR, + .intr = AUDIN_FIFO2_INTR, + .rdptr = AUDIN_FIFO2_RDPTR, + .ctrl = AUDIN_FIFO2_CTRL, + .ctrl1 = AUDIN_FIFO2_CTRL1, + .wrap = AUDIN_FIFO2_WRAP, + } +}; + +struct fifo_regs_bit_masks audin_fifo_regs_bit_masks[AUDIN_FIFO_COUNT] = { + [0] = { + .overflow_en = AUDIN_INT_CTRL_FIFO0_OVERFLOW, + .addr_trigger_en = AUDIN_INT_CTRL_FIFO0_ADDR_TRIG, + .overflow_set = AUDIN_FIFO_INT_FIFO0_OVERFLOW, + .addr_trigger_set = AUDIN_FIFO_INT_FIFO0_ADDR_TRIG, + }, + [1] = { + .overflow_en = AUDIN_INT_CTRL_FIFO1_OVERFLOW, + .addr_trigger_en = AUDIN_INT_CTRL_FIFO1_ADDR_TRIG, + .overflow_set = AUDIN_FIFO_INT_FIFO1_OVERFLOW, + .addr_trigger_set = AUDIN_FIFO_INT_FIFO1_ADDR_TRIG, + }, + [2] = { + .overflow_en = AUDIN_INT_CTRL_FIFO2_OVERFLOW, + .addr_trigger_en = AUDIN_INT_CTRL_FIFO2_ADDR_TRIG, + .overflow_set = AUDIN_FIFO_INT_FIFO2_OVERFLOW, + .addr_trigger_set = AUDIN_FIFO_INT_FIFO2_ADDR_TRIG, + }, + +}; + +/* This is the size of the FIFO (i.e. 64*64 bytes). */ +#define AUDIN_FIFO_I2S_BLOCK 4096 + +static struct snd_pcm_hardware toddr_pcm_hw = { + .info = (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE), + .formats = AUDIN_FORMATS, + .rate_min = 5512, + .rate_max = 192000, + .channels_min = 2, + .channels_max = 2, + .period_bytes_min = 2*AUDIN_FIFO_I2S_BLOCK, + .period_bytes_max = AUDIN_FIFO_I2S_BLOCK * USHRT_MAX, + .periods_min = 2, + .periods_max = UINT_MAX, + + /* No real justification for this */ + .buffer_bytes_max = 1 * 1024 * 1024, +}; + +struct audin_fifo { + const struct fifo_regs *reg; + const struct fifo_regs_bit_masks *reg_bit_masks; + struct snd_pcm_hardware *pcm_hw; + struct clk *pclk; + + /* The AUDIN peripheral has an IRQ to signal when data is received, but + * it cannot grant a periodic behavior. The reason is that the register + * which holds the address which triggers the IRQ must be updated + * continuously. Therefore we use a periodic timer. + */ + struct hrtimer polling_timer; + int poll_time_ns; + struct snd_pcm_substream *substream; +}; + +static int audin_toddr_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + snd_soc_component_update_bits(component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_EN, + AUDIN_FIFO_CTRL_EN); + break; + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + case SNDRV_PCM_TRIGGER_STOP: + snd_soc_component_update_bits(component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_EN, 0); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int audin_toddr_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + dma_addr_t dma_end = runtime->dma_addr + runtime->dma_bytes - 8; + unsigned int val; + + /* Setup memory boundaries */ + snd_soc_component_write(component, fifo->reg->start, runtime->dma_addr); + snd_soc_component_write(component, fifo->reg->ptr, runtime->dma_addr); + snd_soc_component_write(component, fifo->reg->end, dma_end); + + /* Load new addresses */ + val = AUDIN_FIFO_CTRL_LOAD | AUDIN_FIFO_CTRL_UG; + snd_soc_component_update_bits(component, fifo->reg->ctrl, val, val); + + /* Reset */ + snd_soc_component_update_bits(dai->component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_RST, + AUDIN_FIFO_CTRL_RST); + + return 0; +} + +static int audin_toddr_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component = dai->component; + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + unsigned int val; + + switch (params_width(params)) { + case 16: + /* FIFO is filled line by line and each of them is 8 bytes. The + * problem is that each line is filled starting from the end, + * so we need to properly reorder them before moving to the + * RAM. This is the value required to properly re-order 16 bits + * samples. + */ + val = FIELD_PREP(AUDIN_FIFO_CTRL_ENDIAN_MASK, 6); + snd_soc_component_update_bits(component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_ENDIAN_MASK, val); + + /* The I2S input decoder passed 24 bits of left-justified data + * but samples were 16 bits. Therefore we drop the LSB. + */ + val = FIELD_PREP(AUDIN_FIFO_CTRL1_DIN_POS_01_MASK, 1); + snd_soc_component_update_bits(component, fifo->reg->ctrl1, + AUDIN_FIFO_CTRL1_DIN_POS_01_MASK, + val); + + /* Set sample size to 2 bytes (16 bit) */ + val = FIELD_PREP(AUDIN_FIFO_CTRL1_DIN_BYTE_NUM_MASK, 1); + snd_soc_component_update_bits(component, fifo->reg->ctrl1, + AUDIN_FIFO_CTRL1_DIN_BYTE_NUM_MASK, + val); + break; + case 24: + /* The same as above but in this case we need to reorder 32 bits + * samples (because 24 bits samples are stored as 32 bits). + */ + val = FIELD_PREP(AUDIN_FIFO_CTRL_ENDIAN_MASK, 4); + snd_soc_component_update_bits(component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_ENDIAN_MASK, + val); + + val = FIELD_PREP(AUDIN_FIFO_CTRL1_DIN_POS_01_MASK, 0); + snd_soc_component_update_bits(component, fifo->reg->ctrl1, + AUDIN_FIFO_CTRL1_DIN_POS_01_MASK, + val); + + /* Set sample size to 3 bytes (24 bit) */ + val = FIELD_PREP(AUDIN_FIFO_CTRL1_DIN_BYTE_NUM_MASK, 2); + snd_soc_component_update_bits(component, fifo->reg->ctrl1, + AUDIN_FIFO_CTRL1_DIN_BYTE_NUM_MASK, + val); + break; + default: + dev_err(dai->dev, "Unsupported physical width %u\n", + params_physical_width(params)); + return -EINVAL; + } + + /* This is a bit counterintuitive. Even though the platform has a single pin + * for I2S input which would mean that we can only support 2 channels, + * doing so would cause samples to be stored in a weird way into the FIFO: + * all the samples from the 1st channel on the 1st half of the FIFO, then + * samples from the 2nd channel in the other half. Of course extra work + * would be required to properly interleave them before returning to the + * userspace. + * Setting a single channel mode instead solves the problem: samples from + * 1st and 2nd channel are stored interleaved and sequentially in the FIFO. + */ + val = FIELD_PREP(AUDIN_FIFO_CTRL_CHAN_MASK, 1); + snd_soc_component_update_bits(component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_CHAN_MASK, val); + + /* Setup the period for the polling timer. */ + fifo->poll_time_ns = 1000000000 / params_rate(params) * + params_period_size(params); + + return 0; +} + +static enum hrtimer_restart timer_cb(struct hrtimer *timer) +{ + struct audin_fifo *fifo = container_of(timer, struct audin_fifo, + polling_timer); + snd_pcm_period_elapsed(fifo->substream); + hrtimer_forward_now(timer, fifo->poll_time_ns); + return HRTIMER_RESTART; +} + +static int audin_toddr_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + int ret; + + snd_soc_set_runtime_hwparams(substream, fifo->pcm_hw); + + /* Check runtime parameters */ + ret = snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + AUDIN_FIFO_I2S_BLOCK); + if (ret) { + dev_err(dai->dev, "Failed to set runtime constraint %d\n", ret); + return ret; + } + + ret = snd_pcm_hw_constraint_step(substream->runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + AUDIN_FIFO_I2S_BLOCK); + if (ret) { + dev_err(dai->dev, "Failed to set runtime constraint %d\n", ret); + return ret; + } + + ret = clk_prepare_enable(fifo->pclk); + if (ret) { + dev_err(dai->dev, "Failed to enable PCLK %d\n", ret); + return ret; + } + + /* Start the reporting timer */ + fifo->substream = substream; + hrtimer_start(&fifo->polling_timer, fifo->poll_time_ns, + HRTIMER_MODE_REL); + + return ret; +} + +static void audin_toddr_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + + hrtimer_cancel(&fifo->polling_timer); + clk_disable_unprepare(fifo->pclk); +} + +snd_pcm_uframes_t audin_toddr_pointer(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *dai = snd_soc_rtd_to_cpu(rtd, 0); + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + struct snd_pcm_runtime *runtime = substream->runtime; + unsigned int start, ptr; + + start = snd_soc_component_read(component, fifo->reg->start); + ptr = snd_soc_component_read(component, fifo->reg->ptr); + + return bytes_to_frames(runtime, ptr - start); +} + +static int audin_toddr_dai_probe(struct snd_soc_dai *dai) +{ + struct audin *audin = snd_soc_component_get_drvdata(dai->component); + struct audin_fifo *fifo; + + fifo = kzalloc(sizeof(*fifo), GFP_KERNEL); + if (!fifo) + return -ENOMEM; + + if (dai->id >= AUDIN_FIFO_COUNT) { + dev_err(dai->dev, "Invalid DAI ID %d\n", dai->id); + kfree(fifo); + return -EINVAL; + } + + fifo->reg = &audin_fifo_regs[dai->id]; + fifo->reg_bit_masks = &audin_fifo_regs_bit_masks[dai->id]; + fifo->pcm_hw = &toddr_pcm_hw; + fifo->pclk = audin->bulk_clks[PCLK].clk; + hrtimer_init(&fifo->polling_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + fifo->polling_timer.function = timer_cb; + + snd_soc_dai_dma_data_set_capture(dai, fifo); + + return 0; +} + +static int audin_toddr_dai_remove(struct snd_soc_dai *dai) +{ + kfree(snd_soc_dai_dma_data_get_capture(dai)); + + return 0; +} + +static int audin_toddr_pcm_new(struct snd_soc_pcm_runtime *rtd, + struct snd_soc_dai *dai) +{ + struct snd_card *card = rtd->card->snd_card; + struct audin_fifo *fifo = snd_soc_dai_dma_data_get_capture(dai); + size_t size = fifo->pcm_hw->buffer_bytes_max; + int ret; + + ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(dai->dev, "Failed to set DMA mask %d\n", ret); + return ret; + } + + ret = snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, + card->dev, size, size); + if (ret) { + dev_err(dai->dev, "Failed to set PCM managed buffer %d\n", ret); + return ret; + } + + return 0; +} + +const struct snd_soc_dai_ops audin_toddr_dai_ops = { + .trigger = audin_toddr_trigger, + .prepare = audin_toddr_prepare, + .hw_params = audin_toddr_hw_params, + .startup = audin_toddr_startup, + .shutdown = audin_toddr_shutdown, + .pcm_new = audin_toddr_pcm_new, + .probe = audin_toddr_dai_probe, + .remove = audin_toddr_dai_remove, +}; diff --git a/sound/soc/meson/audin.c b/sound/soc/meson/audin.c new file mode 100644 index 000000000000..254d646260f1 --- /dev/null +++ b/sound/soc/meson/audin.c @@ -0,0 +1,321 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Copyright (c) 2025 BayLibre, SAS. +// Author: Valerio Setti + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "audin.h" + +static const char * const audin_fifo_input_sel_texts[] = { + "SPDIF", "I2S", "PCM", "HDMI", "Demodulator" +}; + +static SOC_ENUM_SINGLE_DECL(audin_fifo0_input_sel_enum, AUDIN_FIFO0_CTRL, + AUDIN_FIFO_CTRL_DIN_SEL_OFF, + audin_fifo_input_sel_texts); + +static const struct snd_kcontrol_new audin_fifo0_input_sel_mux = + SOC_DAPM_ENUM("FIFO0 SRC SEL", audin_fifo0_input_sel_enum); + +static SOC_ENUM_SINGLE_DECL(audin_fifo1_input_sel_enum, AUDIN_FIFO1_CTRL, + AUDIN_FIFO_CTRL_DIN_SEL_OFF, + audin_fifo_input_sel_texts); + +static const struct snd_kcontrol_new audin_fifo1_input_sel_mux = + SOC_DAPM_ENUM("FIFO1 SRC SEL", audin_fifo1_input_sel_enum); + +static SOC_ENUM_SINGLE_DECL(audin_fifo2_input_sel_enum, AUDIN_FIFO2_CTRL, + AUDIN_FIFO_CTRL_DIN_SEL_OFF, + audin_fifo_input_sel_texts); + +static const struct snd_kcontrol_new audin_fifo2_input_sel_mux = + SOC_DAPM_ENUM("FIFO2 SRC SEL", audin_fifo2_input_sel_enum); + +static const struct snd_soc_dapm_widget audin_cpu_dapm_widgets[] = { + SND_SOC_DAPM_MUX("FIFO0 SRC SEL", SND_SOC_NOPM, 0, 0, + &audin_fifo0_input_sel_mux), + SND_SOC_DAPM_MUX("FIFO1 SRC SEL", SND_SOC_NOPM, 0, 0, + &audin_fifo1_input_sel_mux), + SND_SOC_DAPM_MUX("FIFO2 SRC SEL", SND_SOC_NOPM, 0, 0, + &audin_fifo2_input_sel_mux), +}; + +static const struct snd_soc_dapm_route audin_cpu_dapm_routes[] = { + { "FIFO0 SRC SEL", "I2S", "I2S Decoder Capture" }, + { "FIFO1 SRC SEL", "I2S", "I2S Decoder Capture" }, + { "FIFO2 SRC SEL", "I2S", "I2S Decoder Capture" }, + { "TODDR 0 Capture", NULL, "FIFO0 SRC SEL" }, + { "TODDR 1 Capture", NULL, "FIFO1 SRC SEL" }, + { "TODDR 2 Capture", NULL, "FIFO2 SRC SEL" }, +}; + +static int audin_cpu_of_xlate_dai_name(struct snd_soc_component *component, + const struct of_phandle_args *args, + const char **dai_name) +{ + struct snd_soc_dai *dai; + int id; + + if (args->args_count != 1) { + dev_err(component->dev, "Wrong number of arguments %d\n", + args->args_count); + return -EINVAL; + } + + id = args->args[0]; + + if (id < 0 || id >= component->num_dai) { + dev_err(component->dev, "Invalid ID %d\n", id); + return -EINVAL; + } + + for_each_component_dais(component, dai) { + if (id == 0) + break; + id--; + } + + *dai_name = dai->driver->name; + + return 0; +} + +static int audin_cpu_component_probe(struct snd_soc_component *component) +{ + struct audin *audin = snd_soc_component_get_drvdata(component); + + /* Required for the FIFO Source control operation */ + return clk_prepare_enable(audin->bulk_clks[INPUT].clk); +} + +static void audin_cpu_component_remove(struct snd_soc_component *component) +{ + struct audin *audin = snd_soc_component_get_drvdata(component); + + clk_disable_unprepare(audin->bulk_clks[INPUT].clk); +} + +static const struct snd_soc_component_driver audin_cpu_component = { + .name = "AUDIN CPU", + .dapm_widgets = audin_cpu_dapm_widgets, + .num_dapm_widgets = ARRAY_SIZE(audin_cpu_dapm_widgets), + .dapm_routes = audin_cpu_dapm_routes, + .num_dapm_routes = ARRAY_SIZE(audin_cpu_dapm_routes), + .of_xlate_dai_name = audin_cpu_of_xlate_dai_name, + .pointer = audin_toddr_pointer, + .probe = audin_cpu_component_probe, + .remove = audin_cpu_component_remove, +#ifdef CONFIG_DEBUG_FS + .debugfs_prefix = "audin-cpu", +#endif +}; + +static struct snd_soc_dai_driver audin_cpu_dai_drv[] = { + [CPU_AUDIN_TODDR_0] = { + .name = "TODDR 0", + .capture = { + .stream_name = "TODDR 0 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 192000, + .formats = AUDIN_FORMATS, + }, + .ops = &audin_toddr_dai_ops, + }, + [CPU_AUDIN_TODDR_1] = { + .name = "TODDR 1", + .capture = { + .stream_name = "TODDR 1 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 192000, + .formats = AUDIN_FORMATS, + }, + .ops = &audin_toddr_dai_ops, + }, + [CPU_AUDIN_TODDR_2] = { + .name = "TODDR 2", + .capture = { + .stream_name = "TODDR 2 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_CONTINUOUS, + .rate_min = 5512, + .rate_max = 192000, + .formats = AUDIN_FORMATS, + }, + .ops = &audin_toddr_dai_ops, + }, + [CPU_I2S_DECODER] = { + .name = "I2S Decoder", + .capture = { + .stream_name = "I2S Decoder Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = AUDIN_FORMATS, + }, + .ops = &audin_decoder_i2s_dai_ops, + }, +}; + +static const struct regmap_config audin_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .max_register = 0x308, +}; + +static const char * const clk_bulk_ids[] = { + "i2s_pclk", + "i2s_aoclk", + "i2s_mclk", + "i2s_mixer", + "i2s_input_clk", +}; + +static int audin_clk_single_get(struct device *dev, const unsigned char *id, + bool enable, struct clk **clk) +{ + *clk = devm_clk_get(dev, id); + if (IS_ERR(*clk)) { + dev_err(dev, "Failed to get %s clock %ld\n", id, PTR_ERR(*clk)); + return PTR_ERR(*clk); + } + + if (enable) + return clk_prepare_enable(*clk); + + return 0; +} + +static int audin_clk_get(struct device *dev) +{ + struct audin *audin = dev_get_drvdata(dev); + struct clk *pclk; + int i, ret; + + ret = audin_clk_single_get(dev, "pclk", true, &pclk); + if (ret) + return ret; + + audin->bulk_clks_num = ARRAY_SIZE(clk_bulk_ids); + audin->bulk_clks = devm_kcalloc(dev, audin->bulk_clks_num, + sizeof(struct clk_bulk_data), + GFP_KERNEL); + if (!audin->bulk_clks) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(clk_bulk_ids); i++) + audin->bulk_clks[i].id = clk_bulk_ids[i]; + + ret = devm_clk_bulk_get(dev, ARRAY_SIZE(clk_bulk_ids), + audin->bulk_clks); + if (ret) { + dev_err(dev, "Failed to get bulk clocks %d\n", ret); + return ret; + } + + ret = audin_clk_single_get(dev, "i2s_aoclk_div_gate", false, + &audin->aoclk_div_gate); + if (ret) + return ret; + + ret = audin_clk_single_get(dev, "i2s_aoclk_basic_div", false, + &audin->aoclk_basic_div); + if (ret) + return ret; + + ret = audin_clk_single_get(dev, "i2s_aoclk_more_div", false, + &audin->aoclk_more_div); + if (ret) + return ret; + + ret = audin_clk_single_get(dev, "i2s_lrclk_div", false, + &audin->lrclk_div); + if (ret) + return ret; + + return 0; +} + +static int audin_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + void __iomem *regs; + struct regmap *map; + struct audin *audin; + int ret; + + audin = devm_kzalloc(dev, sizeof(*audin), GFP_KERNEL); + if (!audin) + return -ENOMEM; + + platform_set_drvdata(pdev, audin); + + ret = device_reset(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to reset device\n"); + + regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + map = devm_regmap_init_mmio(dev, regs, &audin_regmap_cfg); + if (IS_ERR(map)) { + dev_err(dev, "failed to init regmap: %ld\n", + PTR_ERR(map)); + return PTR_ERR(map); + } + + ret = audin_clk_get(dev); + if (ret) + return ret; + + ret = snd_soc_register_component(dev, &audin_cpu_component, + audin_cpu_dai_drv, + ARRAY_SIZE(audin_cpu_dai_drv)); + if (ret) { + dev_err(dev, "Failed to register cpu component\n"); + return ret; + } + + return 0; +} + +static void audin_remove(struct platform_device *pdev) +{ + snd_soc_unregister_component(&pdev->dev); +} + +static const struct of_device_id audin_of_match[] = { + { .compatible = "amlogic,audin-gxbb", .data = NULL }, + {} +}; +MODULE_DEVICE_TABLE(of, audin_of_match); + +static struct platform_driver audin_pdrv = { + .probe = audin_probe, + .remove = audin_remove, + .driver = { + .name = "meson-audin", + .of_match_table = audin_of_match, + }, +}; +module_platform_driver(audin_pdrv); + +MODULE_DESCRIPTION("Meson AUDIN Driver"); +MODULE_AUTHOR("Valerio Setti "); +MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/meson/audin.h b/sound/soc/meson/audin.h new file mode 100644 index 000000000000..eb1dbbaeabcc --- /dev/null +++ b/sound/soc/meson/audin.h @@ -0,0 +1,119 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Copyright (c) 2025 BayLibre, SAS. + * Author: Valerio Setti + */ + +#ifndef _MESON_AUDIN_H +#define _MESON_AUDIN_H + +struct clk; +struct clk_bulk_data; +struct device; +struct of_phandle_args; +struct snd_soc_dai; +struct snd_soc_dai_ops; + +enum audin_bulk_clks_id { + PCLK = 0, + AOCLK, + MCLK, + MIXER, + INPUT, +}; + +struct audin { + struct clk_bulk_data *bulk_clks; + unsigned int bulk_clks_num; + struct clk *aoclk_div_gate; + struct clk *aoclk_basic_div; + struct clk *aoclk_more_div; + struct clk *lrclk_div; +}; + +/* I2SIN_CTRL register and bits */ +#define AUDIN_I2SIN_CTRL 0x040 /* Reg index = 0x10 */ + #define AUDIN_I2SIN_CTRL_I2SIN_DIR BIT(0) + #define AUDIN_I2SIN_CTRL_I2SIN_CLK_SEL BIT(1) + #define AUDIN_I2SIN_CTRL_I2SIN_LRCLK_SEL BIT(2) + #define AUDIN_I2SIN_CTRL_I2SIN_POS_SYNC BIT(3) + #define AUDIN_I2SIN_CTRL_I2SIN_LRCLK_SKEW_MASK GENMASK(6, 4) + #define AUDIN_I2SIN_CTRL_I2SIN_LRCLK_INV BIT(7) + #define AUDIN_I2SIN_CTRL_I2SIN_SIZE_MASK GENMASK(9, 8) + #define AUDIN_I2SIN_CTRL_I2SIN_CHAN_EN_MASK GENMASK(13, 10) + #define AUDIN_I2SIN_CTRL_I2SIN_EN BIT(15) + +/* FIFO0 registers */ +#define AUDIN_FIFO0_START 0x080 /* Reg index = 0x20 */ +#define AUDIN_FIFO0_END 0x084 /* Reg index = 0x21 */ +#define AUDIN_FIFO0_PTR 0x088 /* Reg index = 0x22 */ +#define AUDIN_FIFO0_INTR 0x08C /* Reg index = 0x23 */ +#define AUDIN_FIFO0_RDPTR 0x090 /* Reg index = 0x24 */ +#define AUDIN_FIFO0_WRAP 0x0C4 /* Reg index = 0x31 */ + +/* FIFO1 registers */ +#define AUDIN_FIFO1_START 0x0CC /* Reg index = 0x33 */ +#define AUDIN_FIFO1_END 0x0D0 /* Reg index = 0x34 */ +#define AUDIN_FIFO1_PTR 0x0D4 /* Reg index = 0x35 */ +#define AUDIN_FIFO1_INTR 0x0D8 /* Reg index = 0x36 */ +#define AUDIN_FIFO1_RDPTR 0x0DC /* Reg index = 0x37 */ +#define AUDIN_FIFO1_WRAP 0x110 /* Reg index = 0x44 */ + +/* FIFO2 registers */ +#define AUDIN_FIFO2_START 0x114 /* Reg index = 0x45 */ +#define AUDIN_FIFO2_END 0x118 /* Reg index = 0x46 */ +#define AUDIN_FIFO2_PTR 0x11C /* Reg index = 0x47 */ +#define AUDIN_FIFO2_INTR 0x120 /* Reg index = 0x48 */ +#define AUDIN_FIFO2_RDPTR 0x124 /* Reg index = 0x49 */ +#define AUDIN_FIFO2_WRAP 0x140 /* Reg index = 0x50 */ + +/* FIFOx CTRL registers and bits */ +#define AUDIN_FIFO0_CTRL 0x094 /* Reg index = 0x25 */ +#define AUDIN_FIFO1_CTRL 0x0E0 /* Reg index = 0x38 */ +#define AUDIN_FIFO2_CTRL 0x128 /* Reg index = 0x4a */ + #define AUDIN_FIFO_CTRL_EN BIT(0) + #define AUDIN_FIFO_CTRL_RST BIT(1) + #define AUDIN_FIFO_CTRL_LOAD BIT(2) + #define AUDIN_FIFO_CTRL_DIN_SEL_OFF 3 + #define AUDIN_FIFO_CTRL_DIN_SEL_MASK GENMASK(5, 3) + #define AUDIN_FIFO_CTRL_ENDIAN_MASK GENMASK(10, 8) + #define AUDIN_FIFO_CTRL_CHAN_MASK GENMASK(14, 11) + #define AUDIN_FIFO_CTRL_UG BIT(15) + +/* FIFOx_CTRL1 registers and bits */ +#define AUDIN_FIFO0_CTRL1 0x098 /* Reg index = 0x26 */ +#define AUDIN_FIFO1_CTRL1 0x0E4 /* Reg index = 0x39 */ +#define AUDIN_FIFO2_CTRL1 0x12C /* Reg index = 0x4b */ + #define AUDIN_FIFO_CTRL1_DIN_POS_2 BIT(7) + #define AUDIN_FIFO_CTRL1_DIN_BYTE_NUM_MASK GENMASK(3, 2) + #define AUDIN_FIFO_CTRL1_DIN_POS_01_MASK GENMASK(1, 0) + +/* INT_CTRL register and bits */ +#define AUDIN_INT_CTRL 0x144 /* Reg index = 0x51 */ + #define AUDIN_INT_CTRL_FIFO0_OVERFLOW BIT(0) + #define AUDIN_INT_CTRL_FIFO0_ADDR_TRIG BIT(1) + #define AUDIN_INT_CTRL_FIFO1_OVERFLOW BIT(2) + #define AUDIN_INT_CTRL_FIFO1_ADDR_TRIG BIT(3) + #define AUDIN_INT_CTRL_FIFO2_OVERFLOW BIT(11) + #define AUDIN_INT_CTRL_FIFO2_ADDR_TRIG BIT(12) + +/* FIFO_INT register and bits */ +#define AUDIN_FIFO_INT 0x148 /* Reg index = 0x52 */ + #define AUDIN_FIFO_INT_FIFO0_OVERFLOW BIT(0) + #define AUDIN_FIFO_INT_FIFO0_ADDR_TRIG BIT(1) + #define AUDIN_FIFO_INT_FIFO1_OVERFLOW BIT(2) + #define AUDIN_FIFO_INT_FIFO1_ADDR_TRIG BIT(3) + #define AUDIN_FIFO_INT_FIFO2_OVERFLOW BIT(11) + #define AUDIN_FIFO_INT_FIFO2_ADDR_TRIG BIT(12) + +#define AUDIN_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +extern const struct snd_soc_dai_ops audin_toddr_dai_ops; +extern const struct snd_soc_dai_ops audin_decoder_i2s_dai_ops; +extern struct device_attribute dev_attr_dump_regs; + +snd_pcm_uframes_t audin_toddr_pointer(struct snd_soc_component *component, + struct snd_pcm_substream *substream); + +#endif /* _MESON_AUDIN_H */ From patchwork Mon Feb 10 15:01:27 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerio Setti X-Patchwork-Id: 13968072 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 7CC5BC0219E for ; Mon, 10 Feb 2025 15:02:50 +0000 (UTC) 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=ObXXfoJwEZxAv50qWTc/zQnx88aZKByAVESS99av8o0=; b=aLqTxrSgTCd5uS tL+rsuQZbj5wAMIuJZMDhFzKTOOcEY62Hlq4I4JlrW3Zy56QNkylZzBVSX6Vd1J0F8D9DIX9EpBUq MFNdsz7a+IOFTOqs69vLnANj4Vs7nI2mE2yq+8cnS/HiGTnpsyXvJtr9NW37n9qypSEBvaIjV0LEq O/TcE9EW6caOAQ9VTmcS/Y/xb7gnIDlvEv37gicohLTvUgNZDQViKAL7Y5a5t16FPDd+6g3GP+3+A Lcjg/ljOtF0x2j1PdKaMmJ+ZbkGYRYdb/exygQuNBllt9GAR9RvkgrN2HlLnGj4jWEwekRmSjnneC G78GKgkedOZEU9Y+2mjQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1thVJ9-00000000EHc-3psh; Mon, 10 Feb 2025 15:02:47 +0000 Received: from mail-ej1-x630.google.com ([2a00:1450:4864:20::630]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1thVI9-00000000Dyk-1dKt for linux-amlogic@lists.infradead.org; Mon, 10 Feb 2025 15:01:46 +0000 Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-ab7a342ef4eso428536166b.0 for ; Mon, 10 Feb 2025 07:01:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199704; x=1739804504; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GWn8LoEHwMNZQ9TBj9gyzvn+gEM+LQNUFBCn0O8RbT0=; b=TuCPoZmrZdSKH0Mo8FeR7yyTACZDaYS/lo0OHNyAM1aA3fO76sKIC+yTMVrBrHeGx8 ySBWCZXspPjb5x3ShM74Ylq3xLu4HYXePHURI2Rhu+9Qf8Rz5GE8DySRnH6mgvTdglPa 2PXW4/cjt4D/lF60nh8ROPW1D+X1FbmHVyl5pfyJSjvjbB1dU16/5YSi05b49umYvSot 4bpbHumlUtJ+B41V+xy58EjdA4S5oKUPOr8eswxbYKpYPWsBCbCOh+ys51dEDamVu2x5 HMBFjIlpdi/BV/Pbm9jjPoAaCaNneeJ18YEiKEfMBiksjb6qopLs6DGaTmsIJCNTmvpS dKYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199704; x=1739804504; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=GWn8LoEHwMNZQ9TBj9gyzvn+gEM+LQNUFBCn0O8RbT0=; b=QwZV/BjOYXMxgF7eyHEP6tjDf52JTAjuMS59NbALsHc6RZ7BtP5T4y25pk6ytrK4dU KJu112yyF8IiXzJANV6kcaJBbpvP9w+6XRxGnH2Pr0OxNBUbBkb+V9mpV3BkGQD0ljA7 vJebxShZaq8EurMxryCvI1oBYZdgnf+sL0PA8RcGrCYVDDjxzkecCx9nOU3+ozKT66or zqPEOTJJe4Ms2KeY8k0xEFk1UoCaNaO0feMcMskjUAtU5JT7UuXb/sg35ZFLXk3fzr5w guXSfIbCIra/gtjziFyirGJKLKzFFDPzn0yCaKJXBMtfa9A2wzlM3bPB9oK/1d2TGNn4 Y4NQ== X-Forwarded-Encrypted: i=1; AJvYcCV2nFBKDVcpqnPPPNL5jW+Cgt3XbMTDl13P9GDF7CIt+JiFPMdwMdupnD4NSMI+T/D7K9Wy8dGS5Pq9qB78@lists.infradead.org X-Gm-Message-State: AOJu0Yxz/2Jn3T6D7qQ3X3OjuHVUhLbdgkKh9acx1j/lhT4/hw2/GjFy tOCPCq5T3rVymWL5qMl5RIezA/dZQ/90LMnadn1yGHVFlhZ3rBZZpfCKGevUXKgVT4ItCOAI7Ph tt1fIFw== X-Gm-Gg: ASbGncs/C/LT0aeVqAafjDqB579/8c2T8kyEKJ5CwYbJa8TUcP22Ng7Vp6J+Ez0NGaD wzjkEsUKt8tN6kazIc0vUVEGytjlWv3oCLpBquBaCGVyJgcFw8oAaSK0GoHVp/+OGGibfsN5hL3 ZzKbf2U8Ofr1boqQEJG7oxFXqVGyAvBsFCTyRId4/68rI7QcNs5cPE0o5OBkHGsYjS84H68h83b AZ62JTz/PalhuW2Cy+7xRp5qEYe8mI5dJdjDDQJIpIAHXtWNXvjuvqhrc/Z5c9xwQxT8I0AFUtf glDLMcF4XZNvquaiqr05Zw9zgSvw X-Google-Smtp-Source: AGHT+IEIeHQTJ8/QtRwBWcSl9TO92kHxG7avnOm8/eWBRmULID8JOaosNQ6nHBBvafmVZG0xlTQNtg== X-Received: by 2002:a17:907:6eac:b0:aa6:5910:49af with SMTP id a640c23a62f3a-ab789b1f93cmr1478824566b.24.1739199698834; Mon, 10 Feb 2025 07:01:38 -0800 (PST) Received: from localhost.localdomain ([151.41.218.186]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7bec717f7sm250400466b.81.2025.02.10.07.01.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 07:01:38 -0800 (PST) From: Valerio Setti To: jbrunet@baylibre.com, neil.armstrong@linaro.org, khilman@baylibre.com, martin.blumenstingl@googlemail.com, linux-amlogic@lists.infradead.org, linux-sound@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Valerio Setti Subject: [PATCH RFC 4/6] ASoC: meson: add support for AUDIN in gx-card Date: Mon, 10 Feb 2025 16:01:27 +0100 Message-Id: <20250210150129.40248-5-vsetti@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210150129.40248-1-vsetti@baylibre.com> References: <20250210150129.40248-1-vsetti@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250210_070145_433932_7C4F5866 X-CRM114-Status: GOOD ( 13.04 ) X-BeenThere: linux-amlogic@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-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Extend the gx-card module in order to support the audio input capabilities provided by AUDIN driver. Signed-off-by: Valerio Setti --- sound/soc/meson/gx-card.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sound/soc/meson/gx-card.c b/sound/soc/meson/gx-card.c index b408cc2bbc91..c59bb18b0951 100644 --- a/sound/soc/meson/gx-card.c +++ b/sound/soc/meson/gx-card.c @@ -67,7 +67,8 @@ static int gx_card_parse_i2s(struct snd_soc_card *card, static int gx_card_cpu_identify(struct snd_soc_dai_link_component *c, char *match) { - if (of_device_is_compatible(c->of_node, DT_PREFIX "aiu")) { + if ((of_device_is_compatible(c->of_node, DT_PREFIX "aiu")) || + (of_device_is_compatible(c->of_node, DT_PREFIX "audin"))) { if (strstr(c->dai_name, match)) return 1; } @@ -96,6 +97,8 @@ static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np, if (gx_card_cpu_identify(dai_link->cpus, "FIFO")) return meson_card_set_fe_link(card, dai_link, np, true); + else if (gx_card_cpu_identify(dai_link->cpus, "TODDR")) + return meson_card_set_fe_link(card, dai_link, np, false); ret = meson_card_set_be_link(card, dai_link, np); if (ret) @@ -107,8 +110,11 @@ static int gx_card_add_link(struct snd_soc_card *card, struct device_node *np, dai_link->num_c2c_params = 1; } else { dai_link->no_pcm = 1; - /* Check if the cpu is the i2s encoder and parse i2s data */ - if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder")) + /* Check if the cpu is the i2s encoder|decoder and parse + * i2s data + */ + if (gx_card_cpu_identify(dai_link->cpus, "I2S Encoder") || + gx_card_cpu_identify(dai_link->cpus, "I2S Decoder")) ret = gx_card_parse_i2s(card, np, index); } From patchwork Mon Feb 10 15:01:28 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerio Setti X-Patchwork-Id: 13968074 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 79218C021A4 for ; Mon, 10 Feb 2025 15:02:51 +0000 (UTC) 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=n+1Keq1zplp3CXx7tTqoAswse49cDDDjSCGPE0sT5QY=; b=Kc4kdmQbzAdM+Z JD0BFErVR643d86Rq8ED9toQXHCFgswxb8TOjWGsrKjYQrn06xwQVdj/JI0AMQk88mqgsCPGGZy0i 09/j0xP3wZZKmqRSnSfh3OFKDOB9fkk6BaqQ9hcKNHQCGLubCYchkCtLf0h9B+rppU1xBK68Vohuv pHmllMzmbo3q8lXHOK3FaB7icXVY6L8mNk3HE3tPULPCzFsinelFDkKobLie8e9ycLMoRw9UOs7lY OzPJk9oJgWoUQWKXbMdl+qtLjobGjCWAn6jEBurePYGOkXRf7H0Vib19xRi7MT4VaZN64l2S0kr7W Ccbnb/5JSNzHWHYHD0SQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1thVJ9-00000000EGl-2AXI; Mon, 10 Feb 2025 15:02:47 +0000 Received: from mail-ej1-x632.google.com ([2a00:1450:4864:20::632]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1thVI7-00000000Dxf-2Efn for linux-amlogic@lists.infradead.org; Mon, 10 Feb 2025 15:01:44 +0000 Received: by mail-ej1-x632.google.com with SMTP id a640c23a62f3a-aaec111762bso1083304166b.2 for ; Mon, 10 Feb 2025 07:01:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199702; x=1739804502; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=3Zy3IZpzQXEf48BiX24sRog0zkDKc85etGewBmE/vSM=; b=W1aKcmokUpJfMkQUAtDZKl/5q9bz0WASBrv0kwxdIqFXdbtOFszSYtzFq8VQvoxuo1 GcceGULsrJtFjQNDJtmtn9+9y5iE9tFVWRNTmudZopkcpStpJHUD58rxguwtZzeMSsUY vu0xhGQj38VWsTxOTKwc4tFtvWKHXDIv6Q4KLKXRkCsISi4pKN/1LGBvcEytsaK7mCjH WhY8tgHqfwfVM6OPH6ZnMdUGoJHX4ZQkJOK5pBZkH+wVRCq+vD92PDjvf2lDkbO3GCB2 14UIVyPv0SBtGYu7u5Y1k/WneUoeG9qNInF+Dj8uDc7GVpPkNOXxAN2WUyX2gNu1XHXX 8zhw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199702; x=1739804502; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3Zy3IZpzQXEf48BiX24sRog0zkDKc85etGewBmE/vSM=; b=oblDW+o3kWJOEgpjAMuVtq+GY1/rl0jeNr1OLlAHEK11WkmPM0wokUkye7B14lJMv7 6oR8TXhENX60Ez45GgmmVYKrKURpDb+EjJL9rgUkg59H+aBIN6Hh0UpH2A+ZnYme4hhA xFPuzpxp2eYLaqkGkDn2/an36fYcQ4v459IwC5PlIHoek9D5q4PfQ3gpGIKLNxo9Qs7V WMxtGvNEUyx8+F4TzFmIBVotzR8Rwv/Q61lYr4SnrohwCQdu7LeK4GJxmd2591zinhFI BeAUBIGL5SS/fsjXpCSWRqdQLNI9IWdEZfJ6fOOoAZtWe7ut/dOMYgfNdUrajJKm6kND 3/Ww== X-Forwarded-Encrypted: i=1; AJvYcCU1dCjKFS5M6iESW1u7a6GWdm1bVyJvldRxpiRGywiUNUnTuJ7l9zgq6vsYuhDAfThmuALsAnDTyxKUMC5h@lists.infradead.org X-Gm-Message-State: AOJu0YzegGgHYPqSzrsMNaE0PseZuhK5Zsy1p1idBbaCAsdk8vTUKE21 QEX+zwNSnk86qM9Md028wc4sNn5oYdukn+LYZgINmwiVMtofUSWeqRlP6c529AM= X-Gm-Gg: ASbGncuUF5qkLAozPLRkPHZeE0bofmIbunxZQGwM57gnvTDsfVlmpKNUgAs6yZBngRB JcgkarpfNeeDZUram8Ci4AWDCSn4U81EhHQRJHtEGqjiNFXnDUOGT311nctiXgeJV0QHwKyOczZ UllBgVN1aK+0aHHpq0fBgU3ZTOfik35HC/ZIfotBGcGSaqzL2nhQW59ZiB9WzhXXo8JOU0gaMtS YpATaASmXNHhDSf+D6M2ReMNh4qAKqAVdGrTg7KiZ9VbDdP8PLujJX2ZtbfKJGRlPtwvDqumWlY pYbuaWNlsFist3XJj2S/JLvAFj20 X-Google-Smtp-Source: AGHT+IEbHPd1oSXP7eD15imjc/jvWXdr6BpOIe7NB5TG+hcbBq9WIktQHOMG5ONOKZqK3lCo6o+VLA== X-Received: by 2002:a17:906:110c:b0:ab7:c3c9:2ab1 with SMTP id a640c23a62f3a-ab7c3c92cd1mr373031766b.50.1739199699671; Mon, 10 Feb 2025 07:01:39 -0800 (PST) Received: from localhost.localdomain ([151.41.218.186]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7bec717f7sm250400466b.81.2025.02.10.07.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 07:01:39 -0800 (PST) From: Valerio Setti To: jbrunet@baylibre.com, neil.armstrong@linaro.org, khilman@baylibre.com, martin.blumenstingl@googlemail.com, linux-amlogic@lists.infradead.org, linux-sound@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Valerio Setti Subject: [PATCH RFC 5/6] arm64: dts: meson-gx: add audin support Date: Mon, 10 Feb 2025 16:01:28 +0100 Message-Id: <20250210150129.40248-6-vsetti@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210150129.40248-1-vsetti@baylibre.com> References: <20250210150129.40248-1-vsetti@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250210_070143_580925_7440DDCA X-CRM114-Status: UNSURE ( 8.46 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-amlogic@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-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org Add the AUDIN audio device to the Amlogic GX SoC family DT. Signed-off-by: Valerio Setti --- arch/arm64/boot/dts/amlogic/meson-gx.dtsi | 8 +++++++ arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi | 25 +++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi index 2673f0dbafe7..594d7de606ec 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gx.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gx.dtsi @@ -304,6 +304,14 @@ aiu: audio-controller@5400 { status = "disabled"; }; + audin: audio-input-controller@a000 { + compatible = "amlogic,audin"; + #sound-dai-cells = <1>; + sound-name-prefix = "AUDIN"; + reg = <0x0 0xa000 0x0 0x308>; + status = "disabled"; + }; + uart_A: serial@84c0 { compatible = "amlogic,meson-gx-uart"; reg = <0x0 0x84c0 0x0 0x18>; diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index e2026b7aa03f..2db6916684fc 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi @@ -94,6 +94,31 @@ &aiu { resets = <&reset RESET_AIU>; }; +&audin { + compatible = "amlogic,audin-gxbb", "amlogic,audin"; + clocks = <&clkc CLKID_AIU_GLUE>, + <&clkc CLKID_I2S_OUT>, + <&clkc CLKID_AOCLK_GATE>, + <&clkc CLKID_CTS_AMCLK>, + <&clkc CLKID_MIXER_IFACE>, + <&clkc CLKID_I2S_SPDIF>, + <&aiu AIU_AOCLK_DIV_GATE>, + <&aiu AIU_AOCLK_BASIC_DIV>, + <&aiu AIU_AOCLK_MORE_DIV>, + <&aiu AIU_LRCLK_DIV>; + clock-names = "pclk", + "i2s_pclk", + "i2s_aoclk", + "i2s_mclk", + "i2s_mixer", + "i2s_input_clk", + "i2s_aoclk_div_gate", + "i2s_aoclk_basic_div", + "i2s_aoclk_more_div", + "i2s_lrclk_div"; + resets = <&reset RESET_AIU>; +}; + &aobus { pinctrl_aobus: pinctrl@14 { compatible = "amlogic,meson-gxbb-aobus-pinctrl"; From patchwork Mon Feb 10 15:01:29 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Valerio Setti X-Patchwork-Id: 13968075 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from 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 smtp.lore.kernel.org (Postfix) with ESMTPS id 20A3BC021A3 for ; Mon, 10 Feb 2025 15:02:52 +0000 (UTC) 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=NMHkxmbwQEZie0ESO29vqheoOb5bhemPFFMafvojK9o=; b=Nqh9Mu1fxEeKwj RPMpdmYUEkTcPH5pR4DucVV5jRa8KF495dX/Aw7Y4Gq7akN1IfkZJA/qdMtz2n3G+gU7x+BXzOvqT fSQ0jJZsD0+4EWk+5tvmRB1zMC6hojcEbIiabQAP65Ow76/dY8PMTjUsuWhWFibG9wHfTcCtX8gp2 kEW9Wz8OAZh/7CUQgezauxG6GVWrBsVkyUDw0bfY8Lk+cUMoUQTs/K5ksFbA6p2l/W6C760wzejQw JIPTMEXcEBXNwRqYKMUK+c9PuI9lxpC1avjNpMHdBAF8+h0NT0igYNJelsymUCzVcG0XWWp7EtRof N3xLeCkT6rL7+1/PbOiQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1thVJ9-00000000EGf-0gic; Mon, 10 Feb 2025 15:02:47 +0000 Received: from mail-ej1-x62c.google.com ([2a00:1450:4864:20::62c]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1thVI6-00000000DxQ-304g for linux-amlogic@lists.infradead.org; Mon, 10 Feb 2025 15:01:43 +0000 Received: by mail-ej1-x62c.google.com with SMTP id a640c23a62f3a-ab7d58aa674so47983966b.0 for ; Mon, 10 Feb 2025 07:01:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199701; x=1739804501; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XDwysfrxYdnvpIdJT7USDkw1h39r5hFh2YykRChg6Kc=; b=MrK8qURzSBnd4Bz8NuoLzSJD4WS4zlHP7ymoNJ8uX1lNSLQBuAa+f1ypCqAFUnZMwU sIZwXGijk6zIPseN/H/cVkAgu1yCNA/6W+8HgC/p9cHQBsnJihOqdgi9K18EYhYSHesk PfuTH2h8ecv9jIYn1VT3PaCT/c78K1HCWZTQyWdEceeyPh0hD55PfG6B5RDA6U3APdJ2 byNEiTR1T+415/CCnYTLImX2QB8TcWoIM8m7vmpsM/dkwFfk2AJ08riUbjGf4bWtUbNa R49Hu7NDK7rpMcut1RwZq5aZP69knHvb2+qspucI58FooMlbHIP385bz5ZbosXsScQq6 i9Sw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199701; x=1739804501; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XDwysfrxYdnvpIdJT7USDkw1h39r5hFh2YykRChg6Kc=; b=Gejhzu9rSF82+wxVDGRHbEh4LwoxiQB1nFebiWCBuCb7IzbSD7XUxAjBviKeFiIlkg 4U1X3hKQt7G7ArG9/SP9yud37p90OaD8ECAbbLnQtw+07+4UCgGtkmTg2YOrSBf7n8fX CqSE1puO7tHgONs8HXT+TkVDNAfj9T7i7vqiKfEmh8Mk46o0ZcCe1L1gR6tsoDRVigTA ITTaodMau/MLVv+ap56AWVuTjed8MfBV2iwLbTR8RzvYjfUy6DrR3Tqs75aRd0e+nknr b8g6/qE6JVERx9md2yBAC50TzpLLXvAXP2XhrvjGwzade7tjivEIT0HS+i3hOM3aSmU2 b6bw== X-Forwarded-Encrypted: i=1; AJvYcCWdxBDdNVp5ZybLzQ5afMAQIaOS0wiPiVAYbGoK38n+4s4ai704HYdycOBJQm+61zgQtID0JtxF3Wl5YggK@lists.infradead.org X-Gm-Message-State: AOJu0Yxu0U18AR1WFj7RrqLTe/6fM3uWoqMhA3pjmfZBcMDjKQY8M31q c17jt8PNdwKQ6uPCOzoetb6nRDnDYNKkwTA144N40BS75Si+5ow0S6Z8elbvFSo= X-Gm-Gg: ASbGncvIZ2mhHp0JZk7Tggh2kRGr5nv8Euk2dAfgydNKjSwIe0xrquB8diRjx3mi5Vz 8Cn3sDSRm6NfHE+mDjE4cfmIPlHemGeT4l/opPX4s+x3reH5+gShOsPa0BEkeDGQz0olqd+itM8 6uJ/szVFl+oUyWXZeOrGePWHERjWkk4SA9InMqBLq/RVCJSL+eJs54pjKt6pLsMUn7YpkNKPjaP CHQrardp2Vh9KmqVC9VUuaYicAVorUf3q3In9U7OVBYN91XAi1N+pKFVf1RLIQk5VLYmhtpujz+ 0xWBZkz8VS47fmJumm72mgbZpswN X-Google-Smtp-Source: AGHT+IGGApn1+B5eCaOcf/7nnDOcbipSWzqajWhFXoUzR2omWufSb2FAoBNmw4R/1Cmqf9KlenerKQ== X-Received: by 2002:a17:907:9411:b0:ab7:b84c:361 with SMTP id a640c23a62f3a-ab7b84c05e6mr572978266b.25.1739199700513; Mon, 10 Feb 2025 07:01:40 -0800 (PST) Received: from localhost.localdomain ([151.41.218.186]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ab7bec717f7sm250400466b.81.2025.02.10.07.01.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2025 07:01:40 -0800 (PST) From: Valerio Setti To: jbrunet@baylibre.com, neil.armstrong@linaro.org, khilman@baylibre.com, martin.blumenstingl@googlemail.com, linux-amlogic@lists.infradead.org, linux-sound@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Valerio Setti Subject: [PATCH RFC 6/6] arm64: dts: meson-gx: enable audin on odroidc2 platform Date: Mon, 10 Feb 2025 16:01:29 +0100 Message-Id: <20250210150129.40248-7-vsetti@baylibre.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250210150129.40248-1-vsetti@baylibre.com> References: <20250210150129.40248-1-vsetti@baylibre.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20250210_070142_752105_8851C776 X-CRM114-Status: GOOD ( 10.66 ) X-BeenThere: linux-amlogic@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-amlogic" Errors-To: linux-amlogic-bounces+linux-amlogic=archiver.kernel.org@lists.infradead.org This commit adds the TODDR #0 module to the Odroid-C2 platform. Note: this not enough to be able to start recording data. An addiditional dai-link node should be added with a reference to the external codec being used. For example here's what should be added when an NXP SGTL5000 is used: dai-link-4 { sound-dai = <&audin CPU_I2S_DECODER>; dai-format = "i2s"; mclk-fs = <256>; codec-0 { sound-dai = <&sgtl5000>; }; }; Signed-off-by: Valerio Setti --- arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts index 959bd8d77a82..a83373739019 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-odroidc2.dts @@ -10,6 +10,7 @@ #include "meson-gxbb.dtsi" #include #include +#include / { compatible = "hardkernel,odroid-c2", "amlogic,meson-gxbb"; @@ -210,6 +211,10 @@ codec-0 { sound-dai = <&hdmi_tx>; }; }; + + dai-link-3 { + sound-dai = <&audin CPU_AUDIN_TODDR_0>; + }; }; }; @@ -217,6 +222,10 @@ &aiu { status = "okay"; }; +&audin { + status = "okay"; +}; + &cec_AO { status = "okay"; pinctrl-0 = <&ao_cec_pins>;