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: 13967994 Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) (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 6F7AC1F8BAA for ; Mon, 10 Feb 2025 15:01:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199701; cv=none; b=gclC2pX4ezOteejBPWT+wQ/iKUNgUmhyp4Wbm3/l9NYc+yc+9finSaSN9s/JOf4cZ2TuIPzPxoLOG2BtIj8JzDDeF10TEn1hthpj2onv2hmvMOInJRd90RAHBhUJt9muxC241bmb+B7BgCV3z3POh/V2VjFQIMXKveNn7s4wSg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199701; c=relaxed/simple; bh=QohpDMnGYyXpIbehK5ugOZmdwa7aGVXW0sC1wvKj0Bo=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=c7sphLa60hXTt778B+e6dEt01Ml5HahOEWLjZ8mZC/7/HcSYXIZTf7ep6yBSklw5A0nXFspzbK1rqG1uNRPBtMPOOR1BYQ/AtBrkub3x3vRekBDSLLRRVc64WZUa2kcqnDQzrXVhXYTdaBfUpq+gi9eDL7A0S2NQoEhPSsCrOYw= 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.44 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-f44.google.com with SMTP id a640c23a62f3a-aaf900cc7fbso756866766b.3 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=Yv61S4qWKhg7d8T5t0o10XcEOg1bOAb1Z64m03K5KdN+67WY5l6LSOdMuNlIPSXHJt a09DMs9zGQ8gl/MbJOyCYGcN+7rYN5yL3JjG43uvDBNumLdokq0NQfN2C/5g0WN1DhoC 1/WvL6usg/sx/icIi18SBfXzEKzvhvbcevCyxXyo4Veu39VnLpkX/g5A0OtViXGJ6IsH F8qWe4sBxLtbgsxADlWbEMYfAwKqRbOxPgj5sYouJq3AS4yzmFrtxa+Se6kmE1xB5OTN FFfGSM0VbqMRMMH4cHOA1Zk5T/NsfrJpfyVJNcudop0UhRxO55bBZ8CL+8BBqZ4VwzHG E0Zg== X-Forwarded-Encrypted: i=1; AJvYcCW4ExZlttInFbYO2HQq9u4jsbWFZeQN+FrVT25BtB231jTmPPpCVO8ae6eEqMAnWTPE0jLtnlhJlDVtkQ==@vger.kernel.org X-Gm-Message-State: AOJu0Yw8qhCZ/pUSkIpchhlhREVRCm3JEkRgupTEyg8my8jnze6n9AF1 wlsV8DlxIqNJQDZdNHkZAojKi6Zp0uC2vIEkc7D5wWOiXtd9KOFuarlhpC+M2qQ= X-Gm-Gg: ASbGncsPm0jQ4Xm0ze778RPQ3mSHkKNN5S2zXKcrSY8YCKbqH2/k5LaD44xs+9f2pzj +9cVBgxj3DO4BbW8YdEA1gp3ZFBD9XcKFJpJeFA6YPb5Av/9cbiuO68FHGKNX+twQVpUIRvbLJP r5cXxyFm7cNjsEqYYFdI4SDMM9cupuQ9HuaDQ9hRZnGSwOzBuVS0+yGbatNt3fxfRNN3AgWfZXi 2Y8ZihJZ3NGudIs9w1/997rPh4HftcATYAShZC2Ba4ES+sxO9Aexmgk1C9sFHXTUsfXsNudO7TO X6WcAY50ARcZsDrvM9GRLf0FkHbA 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-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC 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: 13967995 Received: from mail-ej1-f41.google.com (mail-ej1-f41.google.com [209.85.218.41]) (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 EA24A230998 for ; Mon, 10 Feb 2025 15:01:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199702; cv=none; b=mO0yGNagw9W0pYRQx6Wpo0uszcmsFPbKO/H69clNxVSzu07foTh8boZuCzm2e6RFxTj3jhx+t6zkM9I4pQpGLJuxKLQ1AVm48xqULW04XHWpFyudJO1jrwVWeiAqnZQ+moAaeG/KChFSMR9CkNAxucN+PPS2AWz2m6pZPzwXplE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199702; c=relaxed/simple; bh=1SUppZfGE8OGfuCWgDmwdGk734Gq/5yDZqUI2tQbkK8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aug0m99Y7XzCPa6+6GrckHXENz9OwLhSe9HCIlsDVXHkbuIB4lUczAAhpwxWAx7T/SGe9Mq1N4eEJ615KJZDc9iN2oB8JN0qCMKtMRwRIB9sGr8+yL18SoJOxDMaR2/5A7JgfxU6ruoz5B11eOK56HTeMfxMDKyj5FZv/DZllvo= 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.41 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-f41.google.com with SMTP id a640c23a62f3a-ab7d58aa674so47973366b.0 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=DWV69taZtVyyKSxyelK+deO82UcQMP81Zd8oNWx3ysJTLTwR5DpWDsCN2C1VYG0fJX 0a0n5isCM3MAIq3x4UyOiallR09GEcBuNHsBTp6wOVG7kElTOuvghxnSD0o/0cdvrs6t bJF6R1sss6fJAKDSz2cDiv6X2alhohY/rClNOTHOCzpcdIYPfLPyyUdsIYZR56OIbgDG 3sjwPcNJKOVeAxRwfKFSaHopo6D7XOA9n7WiswJ3Qpzx7IMKTrjCLbkIh9C2mwgcgrEn BR21s9xufdLVL9RW98QjmTgvw1uhQB9putmNoLH8AmdBttuNcmWl3HfPqLDMO9eLTtEQ xHPQ== X-Forwarded-Encrypted: i=1; AJvYcCXV5NQ2PyeJedAN/tm4H+bV5brOdBsGrIEnMUiU+bzvpQB9XPEejMrGvA5a7iNb+ryQXUkwF03P4lQikg==@vger.kernel.org X-Gm-Message-State: AOJu0YyVzzm8guaqhzfJrtc20XAcTvJXVp7+kI112+Ww66RJK42LvenF EdBX652PtV7WDUqzR0eQGpTiKygi2ddOO418fCZgPwts8/CoSeEQHUbmOmCI9DQ= X-Gm-Gg: ASbGncsorQFDqOtQsLRSGAKBSYSiibvkXNkbaxw3YLoNOZXjGE8IDHmyKmgLR4Ojhjk oOJ703JtR/rcqAVvC+yzF621YrDd3BgbqKz5vdmW/wYXld/nf4PUzbGJv0PsSg4io0gvbpdCJsz s+/+8DhE+ELD80lI4EQvZG4O5bk39QoCjMjh92n+zzkPgHRO9wCLkmsCv+OaDdIncqxRqrw2zGq cohgOZaXsdeVBPRU3zCKw/7djjsMR88db9JiHLepD5lG9GG6hvr9jBDv1o3LtGzA/Y4rksIjq95 VLRrSCRVLY+TCZnmSyJzktXHqlqm 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-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC 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: 13967996 Received: from mail-ed1-f43.google.com (mail-ed1-f43.google.com [209.85.208.43]) (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 A76D02397B0 for ; Mon, 10 Feb 2025 15:01:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199705; cv=none; b=A3hk8GFEPfyossbUuOS62jd0D02JMHFiseMJp8yVSiU9valkESaN+NCUijU+IzTYFX0wLRQ+ROXfrjVRIU60g9F53kQ2C/MDhsVa0rLOOSCyTLCw1DGLLiXTE7/9bAZq14h+HLJrXF5ws0htWUKZARsMXDM4rrQC0zWHejem6ng= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199705; c=relaxed/simple; bh=JHSdrOB1847/diwCu0IhOhb7TlH5udaxU1UYwzwnahw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=bWaKGCIZj/v++lJXcdU9agxKiAHEFWDlNlHosbHY15qP8SvNKvSDiatXqOzo8d4IrhOceNPhKTuQKNlU6KnyopgwNP04GlB7uQct1uKgp6JPbY86+EjCJy6TajvRCC0vc4tcmExkiKwuSkTrOnl4HkL9EH+nGL3QqhZf+UD5Y3I= 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=G9vgKr4i; arc=none smtp.client-ip=209.85.208.43 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="G9vgKr4i" Received: by mail-ed1-f43.google.com with SMTP id 4fb4d7f45d1cf-5de56ff9851so4800684a12.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=1739199699; x=1739804499; 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=G9vgKr4iGmN7ZSXF7U5R8RCNb1w6u6xqr/YLSOpBon6Pip8EOiHHsUpe4xQFVhnqwu J/LcHrdPwk0UaIlJJyfUGMXGbWF8Qj3+d8vbs09Uh9Lk8p2oKI58FkSjdnf18JMneog+ j+Yg3laxmNDEUzSHoIKJhVtTBYv+nggl7n7DtpvWRb9LkyPNSGcNr1oD9d2gYynaiGlE iO/U/KGeHGfCH8Mu/WsKiUhfIxw9TrTETSs44DO/pOuZYkgna8fVu8lafgfgT3gKNWfS jbIVEse2sNETup6MlEGWXfbXWfNoW4v3XLYJB6jrOmW3iLQ06Cq7cbOhKnE5cDEqKl3D Ed1w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1739199699; x=1739804499; 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=OXa/ryR4YxcAy+/ZLnnJSn8aBHOy9sNuC8kk4YDd3rGMXn4+hWLnLJh+qIl+AzgePg HZH5PtQ4KPY8+N5VM9yd8yd3HVY3sN13UR/KRuWo+GY2HqlPICXsiLRZkLKtqPSWkA2S AOdAojvJ3BVOJLvjuKvtODevbUKHYTjtj2hOl6VDQJfnWAQa6O6wUPmMnXy2/1zQqCdq Ghp497Q1yyQyz2QDTlX+c5072q+644MAOulN7MruMx48LWpwEMY3Np0iUuyU9Xp/6+id yFbxLiqaOUg7k/uaxKx0vHS6liWYuRK8CXsABNDUbTUsZQTubZhRtARUkNsqmXDmTB3+ fvCw== X-Forwarded-Encrypted: i=1; AJvYcCWUoiMyUAFBYXz5dc7PuzBeRBKnms7/ElQS2nLMjiNonAzs3Wbw0Gc+DcrJiC+7SPrQD/ARVwoVBNn8PA==@vger.kernel.org X-Gm-Message-State: AOJu0YwCMYNnxJ/DcnCgGQcpOkzXXSz06p3Ev01d/FZ9rUyld3hU9mpZ fXHKxTrB2K2+ptdkKZLT2SwBUhPXmVqHyxo+KSYwmVKDkbJmHYkAefPjvLSmDCM= X-Gm-Gg: ASbGnct4jK1P4Hj1hZoXhRTMu1Adye6lwKYWBgMXyj8y+tixFNZvx5h+H3vS+IYHrKg PmOt10GJ+0vbn4dVlYqSrRePYY5gYEkOETJaNKAAXhOKNQSu+wWAcmbreUW6fyNYZzISpyejK6e 1q2ukeMhZOfDicULSH9PfU/dYyawCYziOMZNljtQpfW0cYjlvVcriqB/dOCNJZUv3Q4FYQHqWcn +8WfPt7eq06nN7gYO4JXkyEZdJhqmIcgI5KhJ/0lYJSuXKG8lpATmK3qsfZ52xwqB9HUUL+tnTu T0h7Cg9hhWOArcNuf7RpQS59U9w4 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-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC 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: 13967999 Received: from mail-lj1-f174.google.com (mail-lj1-f174.google.com [209.85.208.174]) (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 3CA6C247DF0 for ; Mon, 10 Feb 2025 15:01:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199714; cv=none; b=KKmX8mPKE6020Sd6+56y1k7GW00VPovhQ/2ICd9O6yXZf1EvDN15kSe4L4SEAflquGy6x2771gN+0q7k79grd+ype4DzMM61FgNBKa5e1alTxEuw3ISknJEVbLwYw0VNsIAdH5i0Id+l8u7oNKrDK4fpbHXSe0OUosz1zIwBRLE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199714; c=relaxed/simple; bh=fRXm9P99TfVqw7/aWzdwF95S/kIUYPn5PkUQougaaW8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=MtAsgPjUbpjMpjLkj0xIF/8UMTU4BXM7ISKd4wU0Cw2IiXYPHLx3GeYVlB8STPhJMLl9QeJ8LpzO16WMsYgyxbt5KSKPqqJybvUeF8ZwVwMyC95g8DHEM0YSb2xFKgSJ1E2/kFuTGl7R4MbzVkU4Rjw3CqMQ1cA45nJFNzDBVjk= 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.174 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-f174.google.com with SMTP id 38308e7fff4ca-307d9a13782so39273651fa.2 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=wdH78HGh3NhksS6Q8PpE3MchtCNqxvrnVjMWUrd6tyZsR/MEejmhgZskSJHvfOAxox qtHdERc6HKw/dMpt704ks6ng/r2Vy/6q6DbN9/WYnE5yydl4B3tpPpTJFrEGFPOyrVMi uFqTMonb98TtbUD8pU1KZkYVyHkQVzu4HmP/ycdu89YgxvTdv6USOWl1I//6jg6YQGgi hcbjphWeKKLlxaQgEbWD2fbsHcZvA3RVyQSGXxtQ9nh4rUo9C10vT0X9brtTYpByM4tT hcl8L4R7Ei3QnIrVS58+pD5974BO/10Y5ObkNw4XhLm8g8vvfKV35m5kIwj66Msf5TIP JcIg== X-Forwarded-Encrypted: i=1; AJvYcCVofr9phW8OW462Pbf0lJjzLlbv8GmrH/Km6v6l07ACOR/rgPPcBVRhSAwt9s2xAOzkPgS+SGaNRY/6/Q==@vger.kernel.org X-Gm-Message-State: AOJu0Yw42oTJ/PHxt9iokxBtq9YrHBfDtWsYqGpSx0qvTRUq6UBxcQo0 YWS7w6WLkWqQYv4fvsmnPTgmE7/nLeHepdc6ClzM+i1NqpYQQIxsm2dEpx6apekf4i1M5yJDoVQ TqNR5mA== X-Gm-Gg: ASbGnctdArG3hya3pmP4q6sc6jE2XB2AO74XVcSTyDqOxt9ToCtbpbk1COcds647r53 DYPslcLg7Io25tzCLDSIJSMdAAl9FZntZxWvZQmgl7FB7GcMdCew7BcqCdvJG20akoQ1oV8miUA Gq9xY868dCeQ4zV+szwb1iS6sjftX5eU8jcE2NDFm7FSJ8bSoDbguvWcGxqTdEeCAOy40+xwxZs zt3tCBmRyuLh5T8JNO5VWSvCiNjhHOljARmCpqteRx+xH4O1bX91wBuFr4yz32QzKM1oSbDRVuf U6MVoMzp39/AHIR/eaBnOyYy+Dkh 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-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC 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: 13967998 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 7BA3923E24C for ; Mon, 10 Feb 2025 15:01:43 +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=1739199705; cv=none; b=suLFJ1ecLIOhpEM08IS5olaguadLl/GNQ2JO5h6mc/0/KgWmL21HQX2vIzLIXI24tePIl3G2gLJChftUp4PsKI+6KpfEd/pq+Q28rLO23LQcAzewWvyq00pGNBfoBb3TvEFzJk+CJVrY7T6Cgq87qLR35/RLq2AGottWBtBtVOM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199705; c=relaxed/simple; bh=KAhecjI26XiC6Rkzh5V+N4uCqMajbLT/16ybq2CB8AQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=q2gkwXpai6VCyWVgSucfFc7/wSZeb7EvEC9I6Od2lI3YX3UZ3IIsXGXyDnnAn9j75UJOGskcfVELgpkyJXhUloKobDgcFeBk7C06ub+tY2tt6kfoGvf+OMmkaF8/R09xNrMUrgFLdEUf3v0gwWBB8gqGZ21onZYdkSryGbA9uCg= 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.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="JzjZwR3J" Received: by mail-ej1-f52.google.com with SMTP id a640c23a62f3a-aaf0f1adef8so835911766b.3 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=m1xb50I3pC1HJvAi2raxhecVDP2078gy57PhGOrcsImaaLl3g3LHBkp5TAoY3q0fZn atcQjOWMfZTbty+409hthiskQKEHikKJhkeKGJgQGDR3MPFmk8mGZhxaI9a6K2tZeYLW 1th628ecK0/f4ot5aA1X/O3qJQX23xEZvlvEKwunRGaf9tOzAQ4Rcm2iZAiguaFabsOf hBncgfw7StcypzZWZnPsLRx/ZP4xbltwWVI8S6Rr2nuG0SsDw1ftU8hvlUzMnkdmObSP 8GM+LkiXGAXltsReApwbMuPjCyFhy7IM1GrqBcNd9Hinxtc6WG3Ng/vkdp+McUUv+gTx MLqg== X-Forwarded-Encrypted: i=1; AJvYcCVKsGUCR9eKeYbpXMEWJz1qELb915miouHdeIT5jnpvhVhvyv6jwQqO2VIA0OPHCyAzXzQzhoFKd4cOGw==@vger.kernel.org X-Gm-Message-State: AOJu0Yx0eQ6zD97nr7yid5mhLvH/x9YGcjMlNnddaDOjs3lssSMoGy9N YU36vr84Vd6u7fyXjWtNwlaDCKcNTOdCaHm0rGYXzSPLsDavvTRS9WZUL8soSrw= X-Gm-Gg: ASbGnctWwAmZRQ4/7Wfkuuh4ByyeljT4dKXZ059Zh0XNEYGejbUWi1E1Jzm1l9HcwhU ZBXblleF6jAiU4eRxHzk7OKpe2hLNQcdb8EcrNzRNrluz83umTKX8fkhN3es1PIW8FBX9sjIHdl rERgE+7ZpiwWVbVSP6GjEnPDF2d3SFKYeMXFkmZh/yCkEnYqKMaNNMnuP38txGBr9NVTdRvnfeS BhWnZYN3B8awn52LHv8XaZkxMRKIGQtTRg7tsY70X/2jabGeNwxikspaHdwlvxgLYCc/u+BQ72M wBHDKxCUF1TG8n3Hmhw89Mt3qe14 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-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC 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: 13967997 Received: from mail-ej1-f43.google.com (mail-ej1-f43.google.com [209.85.218.43]) (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 9424D23E250 for ; Mon, 10 Feb 2025 15:01:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199705; cv=none; b=jSXVT7bb/GPRptGYXdz5Yl8qbgrBbXwIBuuG4c7l5kzNTvQ6plhfpWLSIGbFWDWGzTmWXzf1B5FhodrtWfLnySWRvYBN8AoeOLy9V+pwIjlS+7V1Wcq1rIVX2K3Z64PMZ2J5cRDSqjpFi+CklUOQ9f1hk8q5WVh6hWUnWLRit2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1739199705; c=relaxed/simple; bh=ra186LwKS8pvRQ+ulkF1Ob/abglWAThWB5JzaYpqjE8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Ory7/YGgn5hw6BsOb6xF7yg4DZnNrIOy3PoBPaYmL1tHsI8foiNlmbK19cy99aLu1CXhNwzxMr3cXLf1TZ+tlxP5cQ3ad1Z23PflTMJiEJyKjayWVoRHnUHzC791kTut+isyxUzybiND2Vv7riOMwp3OKEB2PnB2uUm5HCa2wqU= 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.43 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-f43.google.com with SMTP id a640c23a62f3a-ab7c07e8b9bso184908166b.1 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=F/+8yzUQ8E/11zBLrNBlq3RCW++dgeG/BXFJCj7jHFPcFOnpJYQ3rtX+SK83ItA959 b5rTVwkdpM07l13UaiaDV6aT7wrrquW8qMgeaGonY3gU6P1K518wZb+SGKssO4SUNaKS 4qICxbwrATdVGZJWUECMk3S0oS28zP61Nkc5sugcw9bPJT8XhBsn79yjFMVvyTs+sz1e moQNebEwtMgT/DuLGxnCfi3XZFCPgaCoUkAclSzlHzkr46wyEuByaiTe55Urb8eGN3Bq ivCvaWUTVFurADyIUkV2ROGfV2ocApI2F9ZuH2Yt/d9fKFZv0GYZ5df/dT8B2Xh2lmNo 6WpA== X-Forwarded-Encrypted: i=1; AJvYcCW4etHJob4jzfpzg9e55UvPlFzoJkP8xSk//9FWWZG9rTvB4jrTl66jXmTDj2hjUXxzBP4rNUBGmtZv3g==@vger.kernel.org X-Gm-Message-State: AOJu0Yyh62t6HidWl41s2YfeVqPc1iKkvrUdK193Wm++DleC72fVFRIz mepUKP9auua8K/XLN4oikp5UCfEjg+jZA5TH2gNNtLiS/3WRU/vOlg1P0KCq674= X-Gm-Gg: ASbGncvDEDvvREUVwnhPRgcf72TUVTm6K7WsHZo2xBZdzVOgb72zxFn2luZjUwpsU35 lZk4bAiCQorhV/vK7Q+q4b0MzbMXDZU4mOnLsXS26yvvQp5KuJ+UlgvK6qn7Lrm+N1TJFIvD26i 5WTGPw+HaYNZzfFTv431GhlokZUZDgGbtaizp3qwqRys3/wLyR6ltUzucKmvD/W5p9O74p85AKP 1DEnjdBVWeDJ7ZYYFvOS/vR0iW3KRXPoqw1hpBpX0UdKfP1A04lBJTxE5wa6ASw0NdTpdyZmeLd uvzIetKZDVQYQ1poHSeSZy+Ue80V 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-sound@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Patchwork-State: RFC 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>;