public inbox for linux-mediatek@lists.infradead.org
 help / color / mirror / Atom feed
From: Alexandre Mergnat <amergnat@baylibre.com>
To: "Liam Girdwood" <lgirdwood@gmail.com>,
	"Mark Brown" <broonie@kernel.org>,
	"Rob Herring" <robh+dt@kernel.org>,
	"Krzysztof Kozlowski" <krzysztof.kozlowski+dt@linaro.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Matthias Brugger" <matthias.bgg@gmail.com>,
	"AngeloGioacchino Del Regno"
	<angelogioacchino.delregno@collabora.com>,
	"Lee Jones" <lee@kernel.org>, "Flora Fu" <flora.fu@mediatek.com>,
	"Jaroslav Kysela" <perex@perex.cz>,
	"Takashi Iwai" <tiwai@suse.com>,
	"Sumit Semwal" <sumit.semwal@linaro.org>,
	"Christian König" <christian.koenig@amd.com>,
	"Catalin Marinas" <catalin.marinas@arm.com>,
	"Will Deacon" <will@kernel.org>
Cc: linux-sound@vger.kernel.org, devicetree@vger.kernel.org,
	 linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	 linux-mediatek@lists.infradead.org, linux-media@vger.kernel.org,
	 dri-devel@lists.freedesktop.org, linaro-mm-sig@lists.linaro.org,
	 Alexandre Mergnat <amergnat@baylibre.com>
Subject: [PATCH 09/18] ASoC: mediatek: mt8365: Add PCM DAI support
Date: Mon, 26 Feb 2024 15:01:47 +0100	[thread overview]
Message-ID: <20240226-audio-i350-v1-9-4fa1cea1667f@baylibre.com> (raw)
In-Reply-To: <20240226-audio-i350-v1-0-4fa1cea1667f@baylibre.com>

Add Pulse Code Modulation Device Audio Interface support for MT8365 SoC.

Signed-off-by: Alexandre Mergnat <amergnat@baylibre.com>
---
 sound/soc/mediatek/mt8365/mt8365-dai-pcm.c | 298 +++++++++++++++++++++++++++++
 1 file changed, 298 insertions(+)

diff --git a/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c
new file mode 100644
index 000000000000..02ee81663e50
--- /dev/null
+++ b/sound/soc/mediatek/mt8365/mt8365-dai-pcm.c
@@ -0,0 +1,298 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8365 ALSA SoC Audio DAI PCM Control
+ *
+ * Copyright (c) 2024 MediaTek Inc.
+ * Authors: Jia Zeng <jia.zeng@mediatek.com>
+ *          Alexandre Mergnat <amergnat@baylibre.com>
+ */
+
+#include <linux/bitops.h>
+#include <linux/regmap.h>
+#include <sound/pcm_params.h>
+#include "mt8365-afe-clk.h"
+#include "mt8365-afe-common.h"
+
+struct mt8365_pcm_intf_data {
+	bool slave_mode;
+	bool lrck_inv;
+	bool bck_inv;
+	unsigned int format;
+};
+
+/* DAI Drivers */
+
+static void mt8365_dai_enable_pcm1(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_EN, PCM_INTF_CON1_EN);
+}
+
+static void mt8365_dai_disable_pcm1(struct mtk_base_afe *afe)
+{
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_EN, 0x0);
+}
+
+static int mt8365_dai_configure_pcm1(struct snd_pcm_substream *substream,
+	struct snd_soc_dai *dai)
+{
+	struct snd_pcm_runtime * const runtime = substream->runtime;
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8365_afe_private *afe_priv = afe->platform_priv;
+	struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1];
+	bool slave_mode = pcm_priv->slave_mode;
+	bool lrck_inv = pcm_priv->lrck_inv;
+	bool bck_inv = pcm_priv->bck_inv;
+	unsigned int fmt = pcm_priv->format;
+	unsigned int bit_width = dai->sample_bits;
+	unsigned int val = 0;
+
+	if (!slave_mode) {
+		val |= PCM_INTF_CON1_MASTER_MODE |
+		       PCM_INTF_CON1_BYPASS_ASRC;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_OUT_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_OUT_INV;
+	} else {
+		val |= PCM_INTF_CON1_SLAVE_MODE;
+
+		if (lrck_inv)
+			val |= PCM_INTF_CON1_SYNC_IN_INV;
+		if (bck_inv)
+			val |= PCM_INTF_CON1_BCLK_IN_INV;
+
+		// TODO: add asrc setting
+	}
+
+	val |= FIELD_PREP(PCM_INTF_CON1_FORMAT_MASK, fmt);
+
+	if (fmt == MT8365_PCM_FORMAT_PCMA ||
+	    fmt == MT8365_PCM_FORMAT_PCMB)
+		val |= PCM_INTF_CON1_SYNC_LEN(1);
+	else
+		val |= PCM_INTF_CON1_SYNC_LEN(bit_width);
+
+	switch (runtime->rate) {
+	case 48000:
+		val |= PCM_INTF_CON1_FS_48K;
+		break;
+	case 32000:
+		val |= PCM_INTF_CON1_FS_32K;
+		break;
+	case 16000:
+		val |= PCM_INTF_CON1_FS_16K;
+		break;
+	case 8000:
+		val |= PCM_INTF_CON1_FS_8K;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	if (bit_width > 16)
+		val |= PCM_INTF_CON1_24BIT | PCM_INTF_CON1_64BCK;
+	else
+		val |= PCM_INTF_CON1_16BIT | PCM_INTF_CON1_32BCK;
+
+	val |= PCM_INTF_CON1_EXT_MODEM;
+
+	regmap_update_bits(afe->regmap, PCM_INTF_CON1,
+			   PCM_INTF_CON1_CONFIG_MASK, val);
+
+	return 0;
+}
+
+static int mt8365_dai_pcm1_startup(struct snd_pcm_substream *substream,
+	struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+
+	if (snd_soc_dai_active(dai))
+		return 0;
+
+	mt8365_afe_enable_main_clk(afe);
+
+	return 0;
+}
+
+static void mt8365_dai_pcm1_shutdown(struct snd_pcm_substream *substream,
+	struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+
+	if (snd_soc_dai_active(dai))
+		return;
+
+	mt8365_dai_disable_pcm1(afe);
+	mt8365_afe_disable_main_clk(afe);
+}
+
+static int mt8365_dai_pcm1_prepare(struct snd_pcm_substream *substream,
+	struct snd_soc_dai *dai)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	int ret;
+
+	if ((snd_soc_dai_stream_active_playback(dai) + snd_soc_dai_stream_active_capture(dai))
+		> 1) {
+		dev_info(afe->dev, "%s '%s' active(%u-%u) already\n",
+			 __func__, snd_pcm_stream_str(substream),
+			 snd_soc_dai_stream_active_playback(dai),
+			 snd_soc_dai_stream_active_capture(dai));
+		return 0;
+	}
+
+	ret = mt8365_dai_configure_pcm1(substream, dai);
+	if (ret)
+		return ret;
+
+	mt8365_dai_enable_pcm1(afe);
+
+	return 0;
+}
+
+static int mt8365_dai_pcm1_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
+{
+	struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai);
+	struct mt8365_afe_private *afe_priv = afe->platform_priv;
+	struct mt8365_pcm_intf_data *pcm_priv = afe_priv->dai_priv[MT8365_AFE_IO_PCM1];
+
+	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
+	case SND_SOC_DAIFMT_I2S:
+		pcm_priv->format = MT8365_PCM_FORMAT_I2S;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
+	case SND_SOC_DAIFMT_NB_NF:
+		pcm_priv->bck_inv = false;
+		pcm_priv->lrck_inv = false;
+		break;
+	case SND_SOC_DAIFMT_NB_IF:
+		pcm_priv->bck_inv = false;
+		pcm_priv->lrck_inv = true;
+		break;
+	case SND_SOC_DAIFMT_IB_NF:
+		pcm_priv->bck_inv = true;
+		pcm_priv->lrck_inv = false;
+		break;
+	case SND_SOC_DAIFMT_IB_IF:
+		pcm_priv->bck_inv = true;
+		pcm_priv->lrck_inv = true;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
+	case SND_SOC_DAIFMT_CBM_CFM:
+		pcm_priv->slave_mode = true;
+		break;
+	case SND_SOC_DAIFMT_CBS_CFS:
+		pcm_priv->slave_mode = false;
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static const struct snd_soc_dai_ops mt8365_dai_pcm1_ops = {
+	.startup	= mt8365_dai_pcm1_startup,
+	.shutdown	= mt8365_dai_pcm1_shutdown,
+	.prepare	= mt8365_dai_pcm1_prepare,
+	.set_fmt	= mt8365_dai_pcm1_set_fmt,
+};
+
+static struct snd_soc_dai_driver mtk_dai_pcm_driver[] = {
+	{
+		.name = "PCM1",
+		.id = MT8365_AFE_IO_PCM1,
+		.playback = {
+			.stream_name = "PCM1 Playback",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000 |
+				 SNDRV_PCM_RATE_16000 |
+				 SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.capture = {
+			.stream_name = "PCM1 Capture",
+			.channels_min = 1,
+			.channels_max = 2,
+			.rates = SNDRV_PCM_RATE_8000 |
+				 SNDRV_PCM_RATE_16000 |
+				 SNDRV_PCM_RATE_32000 |
+				 SNDRV_PCM_RATE_48000,
+			.formats = SNDRV_PCM_FMTBIT_S16_LE |
+				   SNDRV_PCM_FMTBIT_S32_LE,
+		},
+		.ops = &mt8365_dai_pcm1_ops,
+		.symmetric_rate = 1,
+		.symmetric_sample_bits = 1,
+	}
+};
+
+/* DAI widget */
+
+static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = {
+	SND_SOC_DAPM_OUTPUT("PCM1 Out"),
+	SND_SOC_DAPM_INPUT("PCM1 In"),
+};
+
+/* DAI route */
+
+static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = {
+	{"PCM1 Playback", NULL, "O07"},
+	{"PCM1 Playback", NULL, "O08"},
+	{"PCM1 Out", NULL, "PCM1 Playback"},
+
+	{"I09", NULL, "PCM1 Capture"},
+	{"I22", NULL, "PCM1 Capture"},
+	{"PCM1 Capture", NULL, "PCM1 In"},
+};
+
+static int init_pcmif_priv_data(struct mtk_base_afe *afe)
+{
+	struct mt8365_afe_private *afe_priv = afe->platform_priv;
+	struct mt8365_pcm_intf_data *pcmif_priv;
+
+	pcmif_priv = devm_kzalloc(afe->dev, sizeof(struct mt8365_pcm_intf_data),
+				  GFP_KERNEL);
+	if (!pcmif_priv)
+		return -ENOMEM;
+
+	afe_priv->dai_priv[MT8365_AFE_IO_PCM1] = pcmif_priv;
+	return 0;
+}
+
+int mt8365_dai_pcm_register(struct mtk_base_afe *afe)
+{
+	struct mtk_base_afe_dai *dai;
+
+	dev_dbg(afe->dev, "%s()\n", __func__);
+
+	dai = devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL);
+	if (!dai)
+		return -ENOMEM;
+
+	list_add(&dai->list, &afe->sub_dais);
+
+	dai->dai_drivers = mtk_dai_pcm_driver;
+	dai->num_dai_drivers = ARRAY_SIZE(mtk_dai_pcm_driver);
+	dai->dapm_widgets = mtk_dai_pcm_widgets;
+	dai->num_dapm_widgets = ARRAY_SIZE(mtk_dai_pcm_widgets);
+	dai->dapm_routes = mtk_dai_pcm_routes;
+	dai->num_dapm_routes = ARRAY_SIZE(mtk_dai_pcm_routes);
+
+	return init_pcmif_priv_data(afe);
+}

-- 
2.25.1



  parent reply	other threads:[~2024-02-26 14:04 UTC|newest]

Thread overview: 59+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-26 14:01 [PATCH 00/18] Add audio support for the MediaTek Genio 350-evk board Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 01/18] ASoC: dt-bindings: mediatek,mt8365-afe: Add audio afe document Alexandre Mergnat
2024-02-27  9:01   ` Krzysztof Kozlowski
2024-02-27 15:18     ` Alexandre Mergnat
2024-02-28  7:28       ` Krzysztof Kozlowski
2024-02-28  9:57         ` Alexandre Mergnat
2024-02-28 10:25           ` AngeloGioacchino Del Regno
2024-02-28 11:48             ` Alexandre Mergnat
2024-02-28 12:09             ` Krzysztof Kozlowski
2024-02-26 14:01 ` [PATCH 02/18] ASoC: dt-bindings: mediatek,mt8365-mt6357: Add audio sound card document Alexandre Mergnat
2024-02-26 15:30   ` AngeloGioacchino Del Regno
2024-02-27 10:23     ` Alexandre Mergnat
2024-02-27 10:31       ` Krzysztof Kozlowski
2024-02-27 12:38       ` AngeloGioacchino Del Regno
2024-02-28  9:18         ` Alexandre Mergnat
2024-02-27  9:06   ` Krzysztof Kozlowski
2024-02-26 14:01 ` [PATCH 03/18] dt-bindings: mfd: mediatek: Add codec property for MT6357 PMIC Alexandre Mergnat
2024-02-27  9:08   ` Krzysztof Kozlowski
2024-02-26 14:01 ` [PATCH 04/18] ASoC: mediatek: mt8365: Add common header Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 05/18] SoC: mediatek: mt8365: support audio clock control Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 06/18] ASoC: mediatek: mt8365: Add I2S DAI support Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 07/18] ASoC: mediatek: mt8365: Add ADDA " Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 08/18] ASoC: mediatek: mt8365: Add DMIC " Alexandre Mergnat
2024-02-27  9:10   ` Krzysztof Kozlowski
2024-02-26 14:01 ` Alexandre Mergnat [this message]
2024-02-26 14:01 ` [PATCH 10/18] ASoc: mediatek: mt8365: Add a specific soundcard for EVK amergnat
2024-02-26 15:10   ` AngeloGioacchino Del Regno
2024-02-27  8:43   ` Krzysztof Kozlowski
2024-02-26 14:01 ` [PATCH 11/18] ASoC: mediatek: mt8365: Add platform driver Alexandre Mergnat
2024-02-27  8:50   ` Krzysztof Kozlowski
2024-02-26 14:01 ` [PATCH 12/18] ASoC: codecs: mt6357: add MT6357 codec amergnat
2024-02-26 15:25   ` AngeloGioacchino Del Regno
2024-03-12 14:50     ` Alexandre Mergnat
2024-03-12 14:54       ` AngeloGioacchino Del Regno
2024-02-26 16:09   ` Mark Brown
2024-03-12 18:03     ` Alexandre Mergnat
2024-03-13 17:23       ` Mark Brown
2024-03-15 11:01         ` Alexandre Mergnat
2024-03-15 14:30           ` Mark Brown
2024-03-15 15:05             ` Alexandre Mergnat
2024-03-15 15:15               ` Mark Brown
2024-03-15 17:36                 ` Alexandre Mergnat
2024-03-15 18:09                   ` Mark Brown
2024-03-13 17:11     ` Alexandre Mergnat
2024-03-13 17:24       ` Mark Brown
2024-02-26 14:01 ` [PATCH 13/18] mfd: mt6397-core: register mt6357 sound codec amergnat
2024-02-26 15:26   ` AngeloGioacchino Del Regno
2024-02-29 17:45   ` (subset) " Lee Jones
2024-02-26 14:01 ` [PATCH 14/18] ASoC: mediatek: Add MT8365 support Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 15/18] arm64: defconfig: enable mt8365 sound Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 16/18] arm64: dts: mediatek: add mt6357 audio codec support Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 17/18] arm64: dts: mediatek: add afe support for mt8365 SoC Alexandre Mergnat
2024-02-26 14:01 ` [PATCH 18/18] arm64: dts: mediatek: add audio support for mt8365-evk Alexandre Mergnat
2024-02-26 14:54 ` [PATCH 00/18] Add audio support for the MediaTek Genio 350-evk board AngeloGioacchino Del Regno
2024-03-28 10:09   ` Alexandre Mergnat
2024-02-27 15:06 ` Mark Brown
2024-03-12  8:58   ` Alexandre Mergnat
2024-03-15 14:38     ` Mark Brown
2024-03-15 15:28       ` Alexandre Mergnat

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240226-audio-i350-v1-9-4fa1cea1667f@baylibre.com \
    --to=amergnat@baylibre.com \
    --cc=angelogioacchino.delregno@collabora.com \
    --cc=broonie@kernel.org \
    --cc=catalin.marinas@arm.com \
    --cc=christian.koenig@amd.com \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=flora.fu@mediatek.com \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=lee@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linaro-mm-sig@lists.linaro.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-mediatek@lists.infradead.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=matthias.bgg@gmail.com \
    --cc=perex@perex.cz \
    --cc=robh+dt@kernel.org \
    --cc=sumit.semwal@linaro.org \
    --cc=tiwai@suse.com \
    --cc=will@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox