From nobody Fri Dec 19 16:15:57 2025 Received: from mail-ej1-f51.google.com (mail-ej1-f51.google.com [209.85.218.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D7D07082E for ; Mon, 10 Feb 2025 15:01:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199702; cv=none; b=WT+N+DK4jXdjF2UWFeJaBG5DGeFoi3KlGHoe42TwvmH4Ug0Z9EyET89v2B2YaNFWoAh9EL4PjYinQ6AndjGEreu0yHz1RsoRLQnZ9uCzPbHE4sysC+i0V3kdL2AdGvVu5ufMKZMox7YCcV5Sb22MhurTtnt9imk78Au6zYflJac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199702; c=relaxed/simple; bh=QohpDMnGYyXpIbehK5ugOZmdwa7aGVXW0sC1wvKj0Bo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=oldXuHSJxOpuXEKKUjoTcTVxe5KVL6g1gbVjzKyT7pOlazRIRlaYbmKp/XfBvPj+1dQpo3EZF/bKqXHTbllDvoT9RNt6tk4/iWjlukk9LwvnFhqAV9gCfIbOBHs1zZaiKRWveXJgZl3x+nDsJqihgYQenfwaWT5tGVC9V2J3uWU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=IS9YF3IW; arc=none smtp.client-ip=209.85.218.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="IS9YF3IW" Received: by mail-ej1-f51.google.com with SMTP id a640c23a62f3a-aaeec07b705so705364866b.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=vger.kernel.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=IS9YF3IWtq+477poqmr72PeYcmhcGrO24Xdz6tl2zwge4srnt/jtDRCgnlCDljt2HD 0grRI2CTy1iCjejxYzFlpki9+6WbX/imk0nfWjGm7UDJBeXdPA+ZvTeCA3VQdm9pfGrd +WG/PZg7edlmm37/RLRrZ3dF10HxSXIebX5ZMFZX2Nv2WTIYTb/slKJ59Wqhu8/AE6Sw 6NiO8RUcfrOq3MOtCtvyPClLTppvdQpN7o5q23IRqEHhQdsHtklHDlOByM2dGchj9tgn ioz0BAvmBGpYBXRZA8keQgwDRr24tn1gyCFuBbF1GER0x5SXTC2B7L6UqAtEre4HU57G IQdQ== 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=i53wfyLTnL+VthfHy1JAZABE3qOEYs5HBEQixmu3rtbDB7ik1+7GXT0iyyPBzSvI90 8MWSU7RtBO8qewFBooqd20Cled7pjeZv1L0uYZhsHpFDeXtMSlzR5B9ENhVR7qhoH0Cx zDpz1iwhvBkY5SdjvhlY1/fPxEIeoRCA4+CaC0C3N5C1nAdsvIE/VhCgSCrrtvmwTjiq ZWIxPwtBekixJA7qWb/c7lwxlee721gj7zW++yCLMzwOZbhhWPmHAV2iINQxbSPdlOuL 9mFjZJ1f/QGyentKLNWW8mawTAgYlD9s5oV4RPqqSAFNje3fs/7ATxjU1jfDoItxO+nw Uygg== X-Gm-Message-State: AOJu0Yykjy8UkYA1CLDhMViuRbNggE3j7Yyh/lX/EJzuyRmhKf6JG8Gi IS9GtC+JiO9+zSFdrRyihzj+kOJV+5JKHMPmu0YL3CnDL4d/bjKDeYObEqsEdGU5jpSfe/kSj0C 7o2ogjA== X-Gm-Gg: ASbGncuXas9UFDLhV2H2WdYs8hhsfOSlQ1Y9d614VtCelVcSNGCu1NXuG0dYoN8cDDE 0ufB3yNZr1hthlxx7mCA8C7lGRffDNY9QmfCsrLf9Eze8ApIDeQZkyGoqSKeOf6kfhG1VlPrUfn 4Zut8A2t4mF+SsNzJUJam8LuW4aAfGO+ev0kaCmGdA5sZ/ibSIHnOtd2PWfBnuX2yURmMDmStxR lgkViOEL+FO/dKo/Vs6eUMzeK129nX2Uu6UJNSZK5+Z0i8JNv0M7R8y/wFPLaA2Zq1TKJkbfkZh xZFoFnfW1tEYQXNQSeepbl3PrsZG 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 =20 / { compatible =3D "amlogic,meson-gxbb"; @@ -62,6 +63,7 @@ usb1: usb@c9100000 { }; =20 &aiu { + #clock-cells =3D <1>; compatible =3D "amlogic,aiu-gxbb", "amlogic,aiu"; clocks =3D <&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 =3D "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 =3D <&reset RESET_AIU>; }; =20 diff --git a/include/dt-bindings/sound/meson-aiu.h b/include/dt-bindings/so= und/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 =20 +#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) =20 snd-soc-meson-aiu-y :=3D aiu.o +snd-soc-meson-aiu-y +=3D aiu-clocks.o snd-soc-meson-aiu-y +=3D aiu-acodec-ctrl.o snd-soc-meson-aiu-y +=3D aiu-codec-ctrl.o snd-soc-meson-aiu-y +=3D 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 =3D { + .data =3D &(struct clk_regmap_gate_data){ + .offset =3D AIU_CLK_CTRL, + .bit_idx =3D 0, + .flags =3D 0, + }, + .hw.init =3D &(struct clk_init_data){ + .name =3D "i2s_aoclk_div_gate", + .ops =3D &clk_regmap_gate_ops, + .parent_names =3D (const char *[]) { + "cts_amclk", + }, + .num_parents =3D 1, + .flags =3D 0, + }, +}; + +static struct clk_regmap i2s_aoclk_basic_divider =3D { + .data =3D &(struct clk_regmap_div_data){ + .offset =3D AIU_CLK_CTRL, + .shift =3D 2, + .width =3D 2, + .flags =3D CLK_DIVIDER_POWER_OF_TWO, + }, + .hw.init =3D &(struct clk_init_data){ + .name =3D "i2s_aoclk_basic_divider", + .ops =3D &clk_regmap_divider_ops, + .parent_names =3D (const char *[]) { + "i2s_aoclk_div_gate", + }, + .num_parents =3D 1, + .flags =3D CLK_DIVIDER_POWER_OF_TWO, + }, +}; + +static struct clk_regmap i2s_aoclk_more_divider =3D { + .data =3D &(struct clk_regmap_div_data){ + .offset =3D AIU_CLK_CTRL_MORE, + .shift =3D 0, + .width =3D 6, + .flags =3D 0, + }, + .hw.init =3D &(struct clk_init_data){ + .name =3D "i2s_aoclk_more_divider", + .ops =3D &clk_regmap_divider_ops, + .parent_names =3D (const char *[]) { + "i2s_aoclk_basic_divider", + }, + .num_parents =3D 1, + .flags =3D 0, + }, +}; + +static struct clk_regmap i2s_lrclk_divider =3D { + .data =3D &(struct clk_regmap_div_data){ + .offset =3D AIU_CODEC_DAC_LRCLK_CTRL, + .shift =3D 0, + .width =3D 12, + .flags =3D 0, + }, + .hw.init =3D &(struct clk_init_data){ + .name =3D "i2s_lrlk_divider", + .ops =3D &clk_regmap_divider_ops, + .parent_names =3D (const char *[]) { + "i2s_aoclk_more_divider", + }, + .num_parents =3D 1, + .flags =3D 0, + }, +}; + +struct clk_regmap *const aiu_clk_regmaps[] =3D { + &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 =3D clk_hw_data; + unsigned int idx =3D clkspec->args[0]; + + if (idx >=3D 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 =3D 0; i < ARRAY_SIZE(aiu_clk_regmaps); i++) { + aiu_clk_regmaps[i]->map =3D map; + ret =3D 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 =3D 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-encode= r-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) =20 #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 *compo= nent, - 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); -} =20 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_com= ponent *component, =20 static int aiu_encoder_i2s_set_legacy_div(struct snd_soc_component *compon= ent, struct snd_pcm_hw_params *params, - unsigned int bs) + unsigned long mclk_rate, + unsigned long aoclk_rate) { + struct aiu *aiu =3D snd_soc_component_get_drvdata(component); + unsigned long bs =3D 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_so= c_component *component, break; =20 default: - dev_err(component->dev, "Unsupported i2s divider: %u\n", bs); + dev_err(component->dev, "Unsupported i2s divider: %lu\n", bs); return -EINVAL; } =20 - 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 =3D 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; + } =20 - 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 =3D 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; + } =20 return 0; } =20 static int aiu_encoder_i2s_set_more_div(struct snd_soc_component *componen= t, struct snd_pcm_hw_params *params, - unsigned int bs) + unsigned long mclk_rate, + unsigned long aoclk_rate) { + struct aiu *aiu =3D snd_soc_component_get_drvdata(component); + unsigned long bs =3D 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_so= c_component *component, return -EINVAL; } bs +=3D bs / 2; + aoclk_rate =3D mclk_rate / bs; } =20 - /* 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 =3D 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; + } =20 - 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 =3D 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; + } =20 return 0; } =20 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 =3D snd_soc_component_get_drvdata(component); unsigned int srate =3D params_rate(params); - unsigned int fs, bs; + unsigned int fs; + unsigned long mclk_rate, aoclk_rate; int ret; =20 + mclk_rate =3D clk_get_rate(aiu->i2s.clks[MCLK].clk); + /* Get the oversampling factor */ - fs =3D DIV_ROUND_CLOSEST(clk_get_rate(aiu->i2s.clks[MCLK].clk), srate); + fs =3D DIV_ROUND_CLOSEST(mclk_rate, srate); =20 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); =20 - /* 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 =3D fs / 64; + /* aoclk rate is 64 times the sample rate */ + aoclk_rate =3D srate * 64; =20 if (aiu->platform->has_clk_ctrl_more_i2s_div) - ret =3D aiu_encoder_i2s_set_more_div(component, params, bs); + ret =3D aiu_encoder_i2s_set_more_div(component, params, + mclk_rate, aoclk_rate); else - ret =3D aiu_encoder_i2s_set_legacy_div(component, params, bs); + ret =3D aiu_encoder_i2s_set_legacy_div(component, params, + mclk_rate, aoclk_rate); =20 if (ret) return ret; =20 + /* lrclk rate is equal to the sample rate */ + ret =3D 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_s= ubstream *substream, struct snd_soc_dai *dai) { struct snd_soc_component *component =3D dai->component; + struct aiu *aiu =3D snd_soc_component_get_drvdata(dai->component); int ret; =20 /* 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); =20 ret =3D aiu_encoder_i2s_setup_desc(component, params); if (ret) { @@ -200,13 +219,17 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_s= ubstream *substream, return ret; } =20 - ret =3D aiu_encoder_i2s_set_clocks(component, params); + ret =3D aiu_encoder_i2s_set_clocks(component, params, dai); if (ret) { dev_err(dai->dev, "setting i2s clocks failed\n"); return ret; } =20 - aiu_encoder_i2s_divider_enable(component, true); + ret =3D 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; + } =20 return 0; } @@ -214,10 +237,10 @@ static int aiu_encoder_i2s_hw_params(struct snd_pcm_s= ubstream *substream, static int aiu_encoder_i2s_hw_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { - struct snd_soc_component *component =3D dai->component; - - aiu_encoder_i2s_divider_enable(component, false); + struct aiu *aiu =3D snd_soc_component_get_drvdata(dai->component); =20 + clk_disable_unprepare(aiu->i2s_extra.clks[AOCLK_DIV_GATE].clk); +=09 return 0; } =20 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 =20 @@ -203,6 +205,13 @@ static const char * const aiu_i2s_ids[] =3D { [MIXER] =3D "i2s_mixer", }; =20 +static const char * const aiu_i2s_extra_ids[] =3D { + [AOCLK_DIV_GATE] =3D "i2s_aoclk_div_gate", + [AOCLK_BASIC_DIV] =3D "i2s_aoclk_basic_div", + [AOCLK_MORE_DIV] =3D "i2s_aoclk_more_div", + [LRCLK_DIV] =3D "i2s_lrclk_div", +}; + static const char * const aiu_spdif_ids[] =3D { [PCLK] =3D "spdif_pclk", [AOCLK] =3D "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"); =20 + ret =3D 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 =3D 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; =20 + ret =3D aiu_register_clocks(dev, map); + if (ret) { + dev_err(dev, "Failed to register AIU clocks\n"); + return ret; + } + ret =3D 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 }; =20 +enum aiu_i2s_extra_clk_ids { + AOCLK_DIV_GATE =3D 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); =20 +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; --=20 2.39.5 From nobody Fri Dec 19 16:15:57 2025 Received: from mail-ej1-f47.google.com (mail-ej1-f47.google.com [209.85.218.47]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6F55204861 for ; Mon, 10 Feb 2025 15:01:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.47 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199701; cv=none; b=kWQ5tOyHU8sxVzv7wOZjkjueEWB78F8FrCZoMz/IHDUVSZ9vsLQoPqBOzYkK/qGIbJGbEjgvLwx99zjVBBdn3DIQPT08qMaPA/Y1/SlOU7PQ8fnwkBGhGHnoVY868od0t81Qxntmg3gcoWxgjWLyFGMOVkFGyrbKDwXD0p588p8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199701; c=relaxed/simple; bh=1SUppZfGE8OGfuCWgDmwdGk734Gq/5yDZqUI2tQbkK8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QbqQTUH/gksJkK2I3R/HywlcAwXJRJk8uXLako1rQ6Kmrr7hhb856BDXhbT4yhImdjckxX71nfE2phD0WvZLEgsxpeFp/UdsuatABpMNKy2zICGucEV020RJkeMzO+V3cNo3ak4hZID5a19Lm/hsj5ZvLwv4c+u+l0ZCfrxDaj8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=F3FzA+Wd; arc=none smtp.client-ip=209.85.218.47 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="F3FzA+Wd" Received: by mail-ej1-f47.google.com with SMTP id a640c23a62f3a-ab7c07e8b9bso184893366b.1 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=vger.kernel.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=F3FzA+WdcHy5M7f8MFqhWW68YvHoDYIw2nR9bM+k0pT2Urh1zNnbG/gkkinwLhcGNK nmUd3SIQ+43AFm5PVDQmGJ6DuCEuT19z7+qt/FO8uQZZZl1XLuRGc4D5RtZ7O0tlvIjb /+DAEDPd8yfgEnZqnGEU82XAsDTwDfU54LgUqLFHBUHJbTg3XleLzqDQe6ibtWAsHUAX ZKt5Gg9j6i1tyeP7NzFKVAcFu3qpUl59yC/LG3Xn6F2QT7Vi7LrC6+kDRGRay6UX4TuS v2LzJXVvdXMVWzojmUl5kV98+URPIazRrUmeTRfaIcr0XsvKrNkmWjQad0krRgzCJeTn yhBQ== 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=V28/G+KNQbpodpnLm+aywLU9NzWB4hl1twvRoAreJ3oTRoYgdPU/K2pBT2diSCzh5f Z+MHiKwNzola3R1h7tfeSsno6XVyvodCYy9fRIjAXDsAMt7r/01XEsAlbgyxMuv1RvoQ 9QnjE0ASINd9CqUs+YlEbXHBX6OgxbBLw+3VIrXQpt/GRKsFY1YvefVv7V8HkfXagJHP eq/CalS28wfjjYEoAXGadGlYVJUMXDeN1//gkh40KCzQRyJLBWaBPsuZHaHoSL1y4F4p LqddpANqoYYOVz4OLh8+UNAFXOt4pKBVy5uOfiXCBc3N+o1A3+5v9H2E4g1V7sErsXe+ CTgw== X-Gm-Message-State: AOJu0YwIkQZnNk+c4CtQKOwG/vXc26dTEpwRPI4GO3MfZyt4hjOGEI1U hjqz9U6PKOSJWqSXAb98NK/CKMXYFR8fwZnpUcEDBnVDDevu2OAtlCJm+Bv+K7I= X-Gm-Gg: ASbGncsJ1ZiIYArO20kSYw3bS5AJxZqZh48yDgz4rvC1iYOCx76pFNXYg2qTlzanQ1Q uQpydXU9lALodfusH7KUP43bDgFiAhM/R7Mga4snXy+t+LB5CjT4YKrDTMUB1CftE5xLf/G2ljR NxEcvkkcRsAL7u5K5Qgv0+wJjc3SVDI97WAl4Qz3kGXaE2qtU2lRfqj62avxWQPxbvacpkVssdp mlAYWR06vml6lEr5E/6HYG1HGN5O+V8Wh/A5jax0xOQ8WIEW9/vEwK10sPMZXRsML+OFB0enrKa XrrD2n7pGCUNEekaBjSBfBx9IX09 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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.y= aml create mode 100644 include/dt-bindings/sound/meson-audin.h diff --git a/Documentation/devicetree/bindings/sound/amlogic,audin.yaml b/D= ocumentation/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 =3D "amlogic,audin-gxbb", "amlogic,audin"; + #sound-dai-cells =3D <1>; + sound-name-prefix =3D "AUDIN"; + reg =3D <0x0 0xa000 0x0 0x308>; + clocks =3D <&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 =3D "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 =3D <&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 */ --=20 2.39.5 From nobody Fri Dec 19 16:15:57 2025 Received: from mail-ej1-f50.google.com (mail-ej1-f50.google.com [209.85.218.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A282B1DFD95 for ; Mon, 10 Feb 2025 15:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.50 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199704; cv=none; b=N9hxhEtMOpHjaYV5SBuDWQj2LusvlXEba4UrslLZe+llkZwVM/Yc8ftIqQngSNpnLRfKGw690WhRIxMiMhef2C8bsQ28gDUwMiSd1s80N97b31upa5OnoDA12X7uenEC9DQBzLu4N8ux03Lsmbv9c14NKK91O+WsFhrmsxKTFag= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199704; c=relaxed/simple; bh=JHSdrOB1847/diwCu0IhOhb7TlH5udaxU1UYwzwnahw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=PmG8VUAJBoF4+k/dKfbR77q5WjCQSrHbqKQmkzdBILVzAnJRK+XSHWU2WS92Y09myr1HeitBK3Kie3lpbnxYNjGTbO0WBSa+VFdLqD9bVepxoqqeuvqxsUcsP4aX9sFMUnbgSWdANUt/+hzIgOFGdi/P+Xf6rLLUQVh8zkfEAoo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=i309+eWr; arc=none smtp.client-ip=209.85.218.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="i309+eWr" Received: by mail-ej1-f50.google.com with SMTP id a640c23a62f3a-ab7c6fc35b3so149506466b.2 for ; Mon, 10 Feb 2025 07:01:40 -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=vger.kernel.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=i309+eWrVlHf3+vGEwcy9SmMAkPR6gdsOUMeoa6i+N+5TrECHz7avXBCUL1uFaiEWF CFFK+Nc2sJ+mSvPUT1jfjN/OIRkbibktz8e5DFEXWqwWkcoAZ6jlr5vDUx3pEKAaC4Oq 1P/c+9i8hGFeANHV1UaqyfPC7/2rn9bhX80AGU06nJA2h58iwiIjIfKVcffTiE5qiNvw S6PyhWzQ9H2AsMQHIhtBfbElNUEPx6Qht11umrgTbE+N78X8YsI7je3CRVuh3ciGWeiT 3HHvfjoULmEIGbsIXjdH1T/zvDFUFNm8l55CIb1rPtl7zCCWIWeb01cX1fUyU90dcuH+ 058A== 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=hRy7Ic2pasnX01HXt1xuvkyqrEWOKIi42QQJKbIWvtzCEn+ugYSInAfwz886S2CS8C 3u9alQ4AhobuOU6Ilpr4MI7lIa38psl+Uz+Aywv5GyUaAekwRYfmYOq7Jjc9LErUQnAQ qQZr69UYj0tVtCeCxe9WZOXO/x71TpqyrAoTiqH1yeIHMVU0iYX3SG0/yLxhNn89Qz12 dVlk4vG4CMHVbYh/nci+s9rj2EJ0FWqglem7fHnjgFLsIzCQhhGQssbN69uW5rEVf0UC cbs7JY2Z4eh7hueJhk/IOA70iSz4+cKC/347H0sDFslWxFHRgfO/EZVMfLwQT3depMpb 32kQ== X-Gm-Message-State: AOJu0YwCEtjOI2OR1EGogH0iad2+e3PsH9QezTSwZz/znrqYSHnLvb62 YByGqlIbRgpBlH4+MsvvK85qyoGPysp2G6ipkh3lRbBpy4ozbIf+mDJLb1DWOHo= X-Gm-Gg: ASbGncs95H3gGshqBP7JA8HODeyJPAS43MQRrt72uqx+cyHz5SUubPRGtCs7EmyJ3IJ VmXT4AyxfU7hQ+KmTajjRcPEHqf2owi31XuSwb4Z0LRCMGsf++ppecRFcK7CTN1Vuq/8O2zAFuS VsVdRanVkY85PSUVGoaNUVGROwN/Gl7NXog3GsJgGxjjeuZALCCAx5YbiaBJJ9h4i+7Zi9LUfaO /Y2ysEtxX/yH44TS3Sr6T5MRhgoO1SflrJ254El2qgHMP0uOb6ykaU49CbwoN5DamMJ1kFTAYYi 5HERxKu2tJPw83gufr29BkAo2Goe 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 =20 +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 +=3D aiu-encoder-spdif.o snd-soc-meson-aiu-y +=3D aiu-fifo.o snd-soc-meson-aiu-y +=3D aiu-fifo-i2s.o snd-soc-meson-aiu-y +=3D aiu-fifo-spdif.o +snd-soc-meson-audin-y :=3D audin.o +snd-soc-meson-audin-y +=3D audin-toddr.o +snd-soc-meson-audin-y +=3D audin-decoder-i2s.o snd-soc-meson-axg-fifo-y :=3D axg-fifo.o snd-soc-meson-axg-frddr-y :=3D axg-frddr.o snd-soc-meson-axg-toddr-y :=3D axg-toddr.o @@ -28,6 +31,7 @@ snd-soc-meson-g12a-tohdmitx-y :=3D g12a-tohdmitx.o snd-soc-meson-t9015-y :=3D t9015.o =20 obj-$(CONFIG_SND_MESON_AIU) +=3D snd-soc-meson-aiu.o +obj-$(CONFIG_SND_MESON_AUDIN) +=3D snd-soc-meson-audin.o obj-$(CONFIG_SND_MESON_AXG_FIFO) +=3D snd-soc-meson-axg-fifo.o obj-$(CONFIG_SND_MESON_AXG_FRDDR) +=3D snd-soc-meson-axg-frddr.o obj-$(CONFIG_SND_MESON_AXG_TODDR) +=3D snd-soc-meson-axg-toddr.o diff --git a/sound/soc/meson/aiu-encoder-i2s.c b/sound/soc/meson/aiu-encode= r-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_subst= ream *substream, struct aiu *aiu =3D snd_soc_component_get_drvdata(dai->component); =20 clk_disable_unprepare(aiu->i2s_extra.clks[AOCLK_DIV_GATE].clk); -=09 + return 0; } =20 diff --git a/sound/soc/meson/audin-decoder-i2s.c b/sound/soc/meson/audin-de= coder-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 =3D 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 =3D 3; + break; + default: + dev_err(dai->dev, "Error: wrong sample width %d", + params_physical_width(params)); + return -EINVAL; + } + val =3D 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 =3D 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 *componen= t, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct audin *audin =3D snd_soc_component_get_drvdata(component); + unsigned int sample_rate =3D params_rate(params); + unsigned long mclk; + int ret; + + mclk =3D 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 =3D 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 =3D 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 =3D 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 =3D dai->component; + struct audin *audin =3D snd_soc_component_get_drvdata(component); + int ret; + + ret =3D audin_decoder_i2s_setup_desc(params, dai); + if (ret) { + dev_err(dai->dev, "setting i2s desc failed\n"); + return ret; + } + + ret =3D audin_decoder_i2s_set_clocks(component, params, dai); + if (ret) { + dev_err(dai->dev, "setting i2s clocks failed\n"); + return ret; + } + + ret =3D 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 =3D 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 =3D dai->component; + unsigned int val =3D 0; + + /* Only CPU Master / Codec Slave supported ATM */ + if ((fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) !=3D 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 =3D 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 =3D AUDIN_I2SIN_CTRL_I2SIN_POS_SYNC; + break; + case SND_SOC_DAIFMT_NB_NF: + val =3D 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 =3D 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 =3D 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_i= d, + unsigned int freq, int dir) +{ + struct audin *audin =3D snd_soc_component_get_drvdata(dai->component); + int ret; + + if (WARN_ON(clk_id !=3D 0)) + return -EINVAL; + + if (dir =3D=3D SND_SOC_CLOCK_IN) + return 0; + + ret =3D 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 =3D snd_soc_component_get_drvdata(dai->component); + int ret; + + ret =3D 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 =3D 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 =3D { + .hw_params =3D audin_decoder_i2s_hw_params, + .hw_free =3D audin_decoder_i2s_hw_free, + .set_fmt =3D audin_decoder_i2s_set_fmt, + .set_sysclk =3D audin_decoder_i2s_set_sysclk, + .startup =3D audin_decoder_i2s_startup, + .shutdown =3D audin_decoder_i2s_shutdown, + .trigger =3D 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] =3D { + [0] =3D { + .start =3D AUDIN_FIFO0_START, + .end =3D AUDIN_FIFO0_END, + .ptr =3D AUDIN_FIFO0_PTR, + .intr =3D AUDIN_FIFO0_INTR, + .rdptr =3D AUDIN_FIFO0_RDPTR, + .ctrl =3D AUDIN_FIFO0_CTRL, + .ctrl1 =3D AUDIN_FIFO0_CTRL1, + .wrap =3D AUDIN_FIFO0_WRAP, + }, + [1] =3D { + .start =3D AUDIN_FIFO1_START, + .end =3D AUDIN_FIFO1_END, + .ptr =3D AUDIN_FIFO1_PTR, + .intr =3D AUDIN_FIFO1_INTR, + .rdptr =3D AUDIN_FIFO1_RDPTR, + .ctrl =3D AUDIN_FIFO1_CTRL, + .ctrl1 =3D AUDIN_FIFO1_CTRL1, + .wrap =3D AUDIN_FIFO1_WRAP, + }, + [2] =3D { + .start =3D AUDIN_FIFO2_START, + .end =3D AUDIN_FIFO2_END, + .ptr =3D AUDIN_FIFO2_PTR, + .intr =3D AUDIN_FIFO2_INTR, + .rdptr =3D AUDIN_FIFO2_RDPTR, + .ctrl =3D AUDIN_FIFO2_CTRL, + .ctrl1 =3D AUDIN_FIFO2_CTRL1, + .wrap =3D AUDIN_FIFO2_WRAP, + } +}; + +struct fifo_regs_bit_masks audin_fifo_regs_bit_masks[AUDIN_FIFO_COUNT] =3D= { + [0] =3D { + .overflow_en =3D AUDIN_INT_CTRL_FIFO0_OVERFLOW, + .addr_trigger_en =3D AUDIN_INT_CTRL_FIFO0_ADDR_TRIG, + .overflow_set =3D AUDIN_FIFO_INT_FIFO0_OVERFLOW, + .addr_trigger_set =3D AUDIN_FIFO_INT_FIFO0_ADDR_TRIG, + }, + [1] =3D { + .overflow_en =3D AUDIN_INT_CTRL_FIFO1_OVERFLOW, + .addr_trigger_en =3D AUDIN_INT_CTRL_FIFO1_ADDR_TRIG, + .overflow_set =3D AUDIN_FIFO_INT_FIFO1_OVERFLOW, + .addr_trigger_set =3D AUDIN_FIFO_INT_FIFO1_ADDR_TRIG, + }, + [2] =3D { + .overflow_en =3D AUDIN_INT_CTRL_FIFO2_OVERFLOW, + .addr_trigger_en =3D AUDIN_INT_CTRL_FIFO2_ADDR_TRIG, + .overflow_set =3D AUDIN_FIFO_INT_FIFO2_OVERFLOW, + .addr_trigger_set =3D 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 =3D { + .info =3D (SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE), + .formats =3D AUDIN_FORMATS, + .rate_min =3D 5512, + .rate_max =3D 192000, + .channels_min =3D 2, + .channels_max =3D 2, + .period_bytes_min =3D 2*AUDIN_FIFO_I2S_BLOCK, + .period_bytes_max =3D AUDIN_FIFO_I2S_BLOCK * USHRT_MAX, + .periods_min =3D 2, + .periods_max =3D UINT_MAX, + + /* No real justification for this */ + .buffer_bytes_max =3D 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 cm= d, + struct snd_soc_dai *dai) +{ + struct snd_soc_component *component =3D dai->component; + struct audin_fifo *fifo =3D 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 =3D dai->component; + struct audin_fifo *fifo =3D snd_soc_dai_dma_data_get_capture(dai); + struct snd_pcm_runtime *runtime =3D substream->runtime; + dma_addr_t dma_end =3D 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 =3D 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 =3D dai->component; + struct audin_fifo *fifo =3D 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 =3D 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 =3D 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 =3D 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 =3D FIELD_PREP(AUDIN_FIFO_CTRL_ENDIAN_MASK, 4); + snd_soc_component_update_bits(component, fifo->reg->ctrl, + AUDIN_FIFO_CTRL_ENDIAN_MASK, + val); + + val =3D 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 =3D 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 FIF= O. + */ + val =3D 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 =3D 1000000000 / params_rate(params) * + params_period_size(params); + + return 0; +} + +static enum hrtimer_restart timer_cb(struct hrtimer *timer) +{ + struct audin_fifo *fifo =3D 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 =3D snd_soc_dai_dma_data_get_capture(dai); + int ret; + + snd_soc_set_runtime_hwparams(substream, fifo->pcm_hw); + + /* Check runtime parameters */ + ret =3D 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 =3D 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 =3D 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 =3D 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 =3D 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 =3D substream->private_data; + struct snd_soc_dai *dai =3D snd_soc_rtd_to_cpu(rtd, 0); + struct audin_fifo *fifo =3D snd_soc_dai_dma_data_get_capture(dai); + struct snd_pcm_runtime *runtime =3D substream->runtime; + unsigned int start, ptr; + + start =3D snd_soc_component_read(component, fifo->reg->start); + ptr =3D 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 =3D snd_soc_component_get_drvdata(dai->component); + struct audin_fifo *fifo; + + fifo =3D kzalloc(sizeof(*fifo), GFP_KERNEL); + if (!fifo) + return -ENOMEM; + + if (dai->id >=3D AUDIN_FIFO_COUNT) { + dev_err(dai->dev, "Invalid DAI ID %d\n", dai->id); + kfree(fifo); + return -EINVAL; + } + + fifo->reg =3D &audin_fifo_regs[dai->id]; + fifo->reg_bit_masks =3D &audin_fifo_regs_bit_masks[dai->id]; + fifo->pcm_hw =3D &toddr_pcm_hw; + fifo->pclk =3D audin->bulk_clks[PCLK].clk; + hrtimer_init(&fifo->polling_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + fifo->polling_timer.function =3D 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 =3D rtd->card->snd_card; + struct audin_fifo *fifo =3D snd_soc_dai_dma_data_get_capture(dai); + size_t size =3D fifo->pcm_hw->buffer_bytes_max; + int ret; + + ret =3D 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 =3D 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 =3D { + .trigger =3D audin_toddr_trigger, + .prepare =3D audin_toddr_prepare, + .hw_params =3D audin_toddr_hw_params, + .startup =3D audin_toddr_startup, + .shutdown =3D audin_toddr_shutdown, + .pcm_new =3D audin_toddr_pcm_new, + .probe =3D audin_toddr_dai_probe, + .remove =3D 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[] =3D { + "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 =3D + 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 =3D + 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 =3D + SOC_DAPM_ENUM("FIFO2 SRC SEL", audin_fifo2_input_sel_enum); + +static const struct snd_soc_dapm_widget audin_cpu_dapm_widgets[] =3D { + 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[] =3D { + { "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 !=3D 1) { + dev_err(component->dev, "Wrong number of arguments %d\n", + args->args_count); + return -EINVAL; + } + + id =3D args->args[0]; + + if (id < 0 || id >=3D component->num_dai) { + dev_err(component->dev, "Invalid ID %d\n", id); + return -EINVAL; + } + + for_each_component_dais(component, dai) { + if (id =3D=3D 0) + break; + id--; + } + + *dai_name =3D dai->driver->name; + + return 0; +} + +static int audin_cpu_component_probe(struct snd_soc_component *component) +{ + struct audin *audin =3D 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 =3D snd_soc_component_get_drvdata(component); + + clk_disable_unprepare(audin->bulk_clks[INPUT].clk); +} + +static const struct snd_soc_component_driver audin_cpu_component =3D { + .name =3D "AUDIN CPU", + .dapm_widgets =3D audin_cpu_dapm_widgets, + .num_dapm_widgets =3D ARRAY_SIZE(audin_cpu_dapm_widgets), + .dapm_routes =3D audin_cpu_dapm_routes, + .num_dapm_routes =3D ARRAY_SIZE(audin_cpu_dapm_routes), + .of_xlate_dai_name =3D audin_cpu_of_xlate_dai_name, + .pointer =3D audin_toddr_pointer, + .probe =3D audin_cpu_component_probe, + .remove =3D audin_cpu_component_remove, +#ifdef CONFIG_DEBUG_FS + .debugfs_prefix =3D "audin-cpu", +#endif +}; + +static struct snd_soc_dai_driver audin_cpu_dai_drv[] =3D { + [CPU_AUDIN_TODDR_0] =3D { + .name =3D "TODDR 0", + .capture =3D { + .stream_name =3D "TODDR 0 Capture", + .channels_min =3D 2, + .channels_max =3D 2, + .rates =3D SNDRV_PCM_RATE_CONTINUOUS, + .rate_min =3D 5512, + .rate_max =3D 192000, + .formats =3D AUDIN_FORMATS, + }, + .ops =3D &audin_toddr_dai_ops, + }, + [CPU_AUDIN_TODDR_1] =3D { + .name =3D "TODDR 1", + .capture =3D { + .stream_name =3D "TODDR 1 Capture", + .channels_min =3D 2, + .channels_max =3D 2, + .rates =3D SNDRV_PCM_RATE_CONTINUOUS, + .rate_min =3D 5512, + .rate_max =3D 192000, + .formats =3D AUDIN_FORMATS, + }, + .ops =3D &audin_toddr_dai_ops, + }, + [CPU_AUDIN_TODDR_2] =3D { + .name =3D "TODDR 2", + .capture =3D { + .stream_name =3D "TODDR 2 Capture", + .channels_min =3D 2, + .channels_max =3D 2, + .rates =3D SNDRV_PCM_RATE_CONTINUOUS, + .rate_min =3D 5512, + .rate_max =3D 192000, + .formats =3D AUDIN_FORMATS, + }, + .ops =3D &audin_toddr_dai_ops, + }, + [CPU_I2S_DECODER] =3D { + .name =3D "I2S Decoder", + .capture =3D { + .stream_name =3D "I2S Decoder Capture", + .channels_min =3D 2, + .channels_max =3D 2, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .formats =3D AUDIN_FORMATS, + }, + .ops =3D &audin_decoder_i2s_dai_ops, + }, +}; + +static const struct regmap_config audin_regmap_cfg =3D { + .reg_bits =3D 32, + .val_bits =3D 32, + .reg_stride =3D 4, + .max_register =3D 0x308, +}; + +static const char * const clk_bulk_ids[] =3D { + "i2s_pclk", + "i2s_aoclk", + "i2s_mclk", + "i2s_mixer", + "i2s_input_clk", +}; + +static int audin_clk_single_get(struct device *dev, const unsigned char *i= d, + bool enable, struct clk **clk) +{ + *clk =3D 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 =3D dev_get_drvdata(dev); + struct clk *pclk; + int i, ret; + + ret =3D audin_clk_single_get(dev, "pclk", true, &pclk); + if (ret) + return ret; + + audin->bulk_clks_num =3D ARRAY_SIZE(clk_bulk_ids); + audin->bulk_clks =3D devm_kcalloc(dev, audin->bulk_clks_num, + sizeof(struct clk_bulk_data), + GFP_KERNEL); + if (!audin->bulk_clks) + return -ENOMEM; + + for (i =3D 0; i < ARRAY_SIZE(clk_bulk_ids); i++) + audin->bulk_clks[i].id =3D clk_bulk_ids[i]; + + ret =3D 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 =3D audin_clk_single_get(dev, "i2s_aoclk_div_gate", false, + &audin->aoclk_div_gate); + if (ret) + return ret; + + ret =3D audin_clk_single_get(dev, "i2s_aoclk_basic_div", false, + &audin->aoclk_basic_div); + if (ret) + return ret; + + ret =3D audin_clk_single_get(dev, "i2s_aoclk_more_div", false, + &audin->aoclk_more_div); + if (ret) + return ret; + + ret =3D 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 =3D &pdev->dev; + void __iomem *regs; + struct regmap *map; + struct audin *audin; + int ret; + + audin =3D devm_kzalloc(dev, sizeof(*audin), GFP_KERNEL); + if (!audin) + return -ENOMEM; + + platform_set_drvdata(pdev, audin); + + ret =3D device_reset(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to reset device\n"); + + regs =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(regs)) + return PTR_ERR(regs); + + map =3D 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 =3D audin_clk_get(dev); + if (ret) + return ret; + + ret =3D 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[] =3D { + { .compatible =3D "amlogic,audin-gxbb", .data =3D NULL }, + {} +}; +MODULE_DEVICE_TABLE(of, audin_of_match); + +static struct platform_driver audin_pdrv =3D { + .probe =3D audin_probe, + .remove =3D audin_remove, + .driver =3D { + .name =3D "meson-audin", + .of_match_table =3D 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 =3D 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 =3D 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 =3D 0x20 */ +#define AUDIN_FIFO0_END 0x084 /* Reg index =3D 0x21 */ +#define AUDIN_FIFO0_PTR 0x088 /* Reg index =3D 0x22 */ +#define AUDIN_FIFO0_INTR 0x08C /* Reg index =3D 0x23 */ +#define AUDIN_FIFO0_RDPTR 0x090 /* Reg index =3D 0x24 */ +#define AUDIN_FIFO0_WRAP 0x0C4 /* Reg index =3D 0x31 */ + +/* FIFO1 registers */ +#define AUDIN_FIFO1_START 0x0CC /* Reg index =3D 0x33 */ +#define AUDIN_FIFO1_END 0x0D0 /* Reg index =3D 0x34 */ +#define AUDIN_FIFO1_PTR 0x0D4 /* Reg index =3D 0x35 */ +#define AUDIN_FIFO1_INTR 0x0D8 /* Reg index =3D 0x36 */ +#define AUDIN_FIFO1_RDPTR 0x0DC /* Reg index =3D 0x37 */ +#define AUDIN_FIFO1_WRAP 0x110 /* Reg index =3D 0x44 */ + +/* FIFO2 registers */ +#define AUDIN_FIFO2_START 0x114 /* Reg index =3D 0x45 */ +#define AUDIN_FIFO2_END 0x118 /* Reg index =3D 0x46 */ +#define AUDIN_FIFO2_PTR 0x11C /* Reg index =3D 0x47 */ +#define AUDIN_FIFO2_INTR 0x120 /* Reg index =3D 0x48 */ +#define AUDIN_FIFO2_RDPTR 0x124 /* Reg index =3D 0x49 */ +#define AUDIN_FIFO2_WRAP 0x140 /* Reg index =3D 0x50 */ + +/* FIFOx CTRL registers and bits */ +#define AUDIN_FIFO0_CTRL 0x094 /* Reg index =3D 0x25 */ +#define AUDIN_FIFO1_CTRL 0x0E0 /* Reg index =3D 0x38 */ +#define AUDIN_FIFO2_CTRL 0x128 /* Reg index =3D 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 =3D 0x26 */ +#define AUDIN_FIFO1_CTRL1 0x0E4 /* Reg index =3D 0x39 */ +#define AUDIN_FIFO2_CTRL1 0x12C /* Reg index =3D 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 =3D 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 =3D 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 */ --=20 2.39.5 From nobody Fri Dec 19 16:15:57 2025 Received: from mail-lj1-f176.google.com (mail-lj1-f176.google.com [209.85.208.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E92F423ED6B for ; Mon, 10 Feb 2025 15:01:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.176 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199713; cv=none; b=mgNj2TXeS8lkJDmdNInCXlzi5Lbc/6s5iofu7d/7DWsRuBQSFQk2KtuBbkHpp4Be7O89oJGB1kBy5b5eEZfcnscLRqEQ0Yao7DwL9vGpfSA38wtP1B5rUpRwEVYSPKtTBkAY0I2I73UvAddpcKnPKmIMjx1YMSue4sHHFB7NdC0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199713; c=relaxed/simple; bh=fRXm9P99TfVqw7/aWzdwF95S/kIUYPn5PkUQougaaW8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=fNhqKboidlHpM3MyCkBU1hT162Uk+g7cxGEMra/CB3XuIq3gTsrsgWv3aaSAvVo3hHuAkOSnjoa+WQSchYPt5Lrx8EdSr17RZni+4m9cw9jwsSK2O7NXkr0nga2LuG5cCdiRvCuYvtIrsAexk8Mj3F0bB7R0iQcD4qFGvda3rO8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=KpWp80lN; arc=none smtp.client-ip=209.85.208.176 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="KpWp80lN" Received: by mail-lj1-f176.google.com with SMTP id 38308e7fff4ca-30795988ebeso44860671fa.3 for ; Mon, 10 Feb 2025 07:01:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20230601.gappssmtp.com; s=20230601; t=1739199710; x=1739804510; darn=vger.kernel.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=KpWp80lNEQDJq2ZktxgUIIQTTD3mHBjp+ovLSrUZduI6eHbXuqJy2pqfCBKl0JhR4i YrPtYhgIP26GHxD/kemZ6Z0xn8vz8Z6Z8AiNQ5EzS5EHJJgdEIdxl07U/Zndg8/uLHNA Qm1HCxmgXg7k6CiGOpPZe2xTQHzdiajQ9LOM7gGLlmbLRoVaOL4NgJzGIQVJmlrPkyLL iezdsoWBoyVFrOV8MOOOs1rQ5HzfVgV7jLlYBGFceLb1eBTseJfSjhc5nsmuFY42/jlH AQhqw4YiJuMyMP4Pw7VumCnshrU3kQbEK/utIdH9/3AWuyljYVsxLvwB8BxIJNsy/eDp uA/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199710; x=1739804510; 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=dkoj6X0viR/AlgiLw4qotnpEc9SbKxO91MUjq0IMldwcvkQ7XeM21mIvAfr7QrKIqt tEDXmANuyt+P5Q1kciF5XQjJ2objrmJw1ilcxtB3OYeItzJMwYTTctfuxs2qQUSf8lQm Z9WBwK4+6acIsS2nT/BGqTyX+vF3DLpv/tSDfXLYS4O/1Rf4Oc0yPxEZetLu3qMzIZqB eQsRreBVp8rLD7t2vOK0kjvxQHPeyrH2QpDsBylN6VabWAoCgn1DT258Z6bc549f0s5t i2y8Edsrno7GGO00i2xY+3A9Br0IHyBiV/yx2Ci6jOeTBgp1jgzuob2d1/iweoa9MEuU VpTQ== X-Gm-Message-State: AOJu0Yx5Oif5fcLBvLuhOLwlB0Gw9xsXUG2nyuEStzCx6xO3pbb1FR8Q w2KCIhNERgBtD+IiN9eEs5jOg6DwACCPzhOuNXGK1nGj0oGj+cXEZV6u/nVdXoWnxR0uxyvSitY fR6JR1w== X-Gm-Gg: ASbGnctER3y2csk11hRnY5a00AHvcxITv9ZDwZ0zLJ5iFwcTP2OyKEeBWczwRy4lxf+ FfhFx9p4C7hc3IbpXAFq4UoeoLzXzOKOq++To28nz3kRA+/uoicg/XCG8glpAFpJZIkrTd7lUBI +5mPVXqwPQGLlREUX3wkOe5TPE23cCRmOzV4bUKK6+UcfdVWKYzLOKnxUVQzv17IPzo6dk6LH0P fWF108tNeoAY+gze6Krf++ZKrLeZ/qTqoB3vn5uPiTwM7fUyrdFaXyNX7tKj4mhwdjcyWi55mzW pXSEuX0Jdjvn7sOLyHyOY8zvO645 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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, st= ruct device_node *np, =20 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); =20 ret =3D 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 =3D 1; } else { dai_link->no_pcm =3D 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 =3D gx_card_parse_i2s(card, np, index); } =20 --=20 2.39.5 From nobody Fri Dec 19 16:15:57 2025 Received: from mail-ej1-f49.google.com (mail-ej1-f49.google.com [209.85.218.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 78C2B244E98 for ; Mon, 10 Feb 2025 15:01:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199706; cv=none; b=CFYV4q9vEvQlAT0MC6RTA6OmGByoIguSjwr0GnOIacsfpt0oPUgPaFGe7GbEctlYtERlX1w0LkNOMi67cjno+1V9jqnYmnHcg/z30pQCWdbG6bAXiPdnzLRoL2RkOQ7paqEMY9rQUTUN1AdwkCSl9T5frnv4EFxGkYFPKPxcUbo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199706; c=relaxed/simple; bh=KAhecjI26XiC6Rkzh5V+N4uCqMajbLT/16ybq2CB8AQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=X3UxPaDQvWwoZZW3hJ1dMTl5lFRrDU8AT9H0etuOROr5oQyfXrIGsP0emFwf6IHZJoNzd7wPc85dzqBlKzq9XdnTR+D6RZ4buuisokDz8XH8RUVgU8H52duqaeos6J2O4knqSVJ7/eUsmPViRghS8mwg8RI3qHyZuQyHspG9dRY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=JzjZwR3J; arc=none smtp.client-ip=209.85.218.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="JzjZwR3J" Received: by mail-ej1-f49.google.com with SMTP id a640c23a62f3a-ab2b29dfc65so696573266b.1 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=vger.kernel.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=JzjZwR3JpvLBny2gBVPIvGEgJPzim6SWO6Ae/EgwBZfxleXmKrnIbvm0087KgJNltV GIc8i0wbKuUkOF128S5c9FzBmufDnl7YH+eYToZjDkR+t1vWv5d/1dLwPbAaJgUdPVPl 7e/xCsFYGVV/YrYn+QaVGmyL2uNrX2MCk4BeD1cBKPK1Guaj38lB4opJKX9KDE7mg8hF Ui9x86zBCxLZmmVnhhLfJ1s8RyZ2LfIzy3NtU4WwyUGfXBp8HlfEzizxfGFKIYmOy9kl nWtVnFJxcjCDH4XAmEi/feoKB2ntLveM+U5DbfdiDWY7BRrA4gMaV4XAcuRp1084AmoE ThSQ== 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=PHjpfWp2hYaAv861kpeN9kzpGkbtWgsrlUjsr5Bwziis8LPVpwFUVJHmTbS8JgQ7jt 8gUG7uTVW3NTNRtibAqDapT8LChmhk1tvr2QrNKGrQaRU3m90isUNc77kUiYnuv7CNIQ APJp93Zb5el7ozv6K8DfVoofi+Xo/f/ZutEsLZjKyWjVMF9+V/6T637nszi30cHo5LY9 xy0Ym1OpBtw16C3ubncRDAHqZyiN+X2sglEr4PBhrKB3IMaqbwiCorCDYE8UpWv8HGXc Sq1Pa9umSLKjdgJpdP8FdLbNhZ7GpCg26qi2NBLidVv6nRvI6aA6W0PCZecZ2zec4CRL zlow== X-Gm-Message-State: AOJu0YxuknvgVdoEEEFtEg1L5cSKnD3dil5J8q93eTJ9BMPVRX2POQ5u 9Rpc1GgUP/yNkjMzP5K6HlR6jazgUFG26EGHGrIF6H1G2Ngpuczv2KfbyrtNpTk= X-Gm-Gg: ASbGncuEQDASzXKmu8rA+KGMK3oejQNqOHZkwh3VV6k6cZ7aO9MrUpH3wx8uN0x9GmT wRZ+GW6eZY2TSY8oe/IV3YI16qibRfc+mkGSdnuFp4vm3aK+IlpLCf6P0qty7j7m6AjL4D057yy uAcYpVjNiJ8TAbhMNNurbBsgO1XxslnmUiXO0i7HQpwXc0QoEoMt3UsK/AABz9aIDPbGEl1qv/y EJR7j+CyV5fCCcu64J0DhGhM6E1ek40SevvQCvVL5YcaEMNYjG+PzAY0k9mXe4KXaAly8h+kNqy 0UxWxSIcvGcNWUtIY7grFgh6rHeQ 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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/dt= s/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 =3D "disabled"; }; =20 + audin: audio-input-controller@a000 { + compatible =3D "amlogic,audin"; + #sound-dai-cells =3D <1>; + sound-name-prefix =3D "AUDIN"; + reg =3D <0x0 0xa000 0x0 0x308>; + status =3D "disabled"; + }; + uart_A: serial@84c0 { compatible =3D "amlogic,meson-gx-uart"; reg =3D <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 =3D <&reset RESET_AIU>; }; =20 +&audin { + compatible =3D "amlogic,audin-gxbb", "amlogic,audin"; + clocks =3D <&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 =3D "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 =3D <&reset RESET_AIU>; +}; + &aobus { pinctrl_aobus: pinctrl@14 { compatible =3D "amlogic,meson-gxbb-aobus-pinctrl"; --=20 2.39.5 From nobody Fri Dec 19 16:15:57 2025 Received: from mail-ej1-f52.google.com (mail-ej1-f52.google.com [209.85.218.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AD82723E226 for ; Mon, 10 Feb 2025 15:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199704; cv=none; b=NI4vn0eZvaYufHCnjGbjvMyxc280MheCfRijF/5ORdKp+Q7t6zK2JSKaOiyjCBw3wPKB/9shwPnrSRW8e01nSmiFcvt11/uuN9jBBdVQSUzk6anUH+mubltmwdVwQWPVnkvF9vHB9jBFoWo6VEcU01P7C8G96klWvUQkDSaRlH8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199704; c=relaxed/simple; bh=ra186LwKS8pvRQ+ulkF1Ob/abglWAThWB5JzaYpqjE8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=M1OoD9ClrRnNgLWdeQUFQonNvd+pE0mylMQAFqnimwB97H9h40w/rqXoitlyuv3w8GQeCVVnLEGdOC7Vxvf2AJwrc+09TLexx8fO7nPsX8VYJIvEcABDoEiYv7iZz1Um809djH1Xtpt109zjtPExXLdZdAsyLyoa/dmBztrdcBE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com; spf=pass smtp.mailfrom=baylibre.com; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b=y2FluRXZ; arc=none smtp.client-ip=209.85.218.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=baylibre.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=baylibre.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=baylibre-com.20230601.gappssmtp.com header.i=@baylibre-com.20230601.gappssmtp.com header.b="y2FluRXZ" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-ab7d7f0a2cfso12946666b.3 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=vger.kernel.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=y2FluRXZpalIasDu37YaPRWxbZbxwoBOfegKmrERc6D/uS+n2GvH4Eok2Y8tO5qN1h e1F6mjDTbUzA6Xvu3qC1nzGTVCJHyJNcLRX8jxSGLZM5G7aH2HPXjFXPCrsuO7GcZO7L 4CtshYEf8I0kHP3Wgt0CMqBDU175aK1xz2Ipx1oMzAdu/2H8iqodr8KznJY4MNQrLKng rNEquzYJPlDNBJf9CPevWrU08ByTDc2kNIOkadqlJ/7j8act7OYFiFVCULaI4shvf0Lw uVKas3iYUBYxh0OpmRXwmiRnCU/EpkS9R1Rv9hysdhZDF/21JkYsyGJMHnU5Swc3DeCZ U36w== 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=VQd2jOMpqrJiksrL9m+ys9yT1tkawcZU0Am4FaBDkMKT2iMyAwJeabYKZF1zXgxU8D qyRdgNiz6a36Lr6KTO8vSo4tZUfqBytNczXn+7wGJZKsnDXGrR0gAiZY8p8AOVYXPOUA QxorwltDmE7uMyvWORjTi+r1bZW6R/u/lvWzCFkbZ5h46jfd16E/aVIEMudRKdWCwnr5 JgC5hmIXf4EVZib4SgbBR9409gW5uFvpCG3YWYYgoFO0FstL0i60z+n6BdVOyCYW/97S RHb6xbMej1oN16sGL1kyy3+nd5v0aBMEOTd2oWH3D/IOzIxNXnPH565jYJ1sV6/+9HSC /9dA== X-Gm-Message-State: AOJu0YwlostrWg3to5A8EUOhHDVDVybrSKkLaoB7fzB906bfIej6N+MK 6/k4ouuD97HgxzXE4ITccCcHeLCzhIxmTR8JvQUyViaqcXMIGojzUg0TZNwcIg0= X-Gm-Gg: ASbGncttSBaj+MgVw+mDvsEU1HNg9seYsI8WOnYqxohsbvje7LUizl1q5Wo+GukRxkW cP4hIiBmCBCDAwDlXR3TT/kY+KhYMYU7A0gMDoxFoCcIYESIPHZZUaRzjrNRqsHPUpi+F27nv3x YDK/ATXToX/sPJn2z0BPSubohzZyOB/ioAK04qk+9Dw45b4gAlgcUllr+S5g7TB1Xc7FW0RaDf1 zxliQx6Tv8BSf3Sr6X7TNzkEatXl5Q37XStocU5hmAZL7aebRs0uTTRwatSPUanaX+hGFnTXedt TlGMLVe9ddj5ROSpZFSjpWAoTYBM 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> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 =3D <&audin CPU_I2S_DECODER>; dai-format =3D "i2s"; mclk-fs =3D <256>; codec-0 { sound-dai =3D <&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/arm= 64/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 =20 / { compatible =3D "hardkernel,odroid-c2", "amlogic,meson-gxbb"; @@ -210,6 +211,10 @@ codec-0 { sound-dai =3D <&hdmi_tx>; }; }; + + dai-link-3 { + sound-dai =3D <&audin CPU_AUDIN_TODDR_0>; + }; }; }; =20 @@ -217,6 +222,10 @@ &aiu { status =3D "okay"; }; =20 +&audin { + status =3D "okay"; +}; + &cec_AO { status =3D "okay"; pinctrl-0 =3D <&ao_cec_pins>; --=20 2.39.5