[PATCH v1] ASoC: codecs: ntp8918: calculate bclk using tdm params
From: Ilias Izmaylov
Date: Wed Feb 18 2026 - 07:46:18 EST
Use a function snd_soc_tdm_params_to_bclk instead of snd_soc_params_to_bclk
to calculate bclk frequency correctly using frame size, channel period
and a number of channels
Since in NTP8918 the word clock and bit clock frequencies are both 64
bits per period and given that the device has only 2 channels it means
that the period per channel is equal to 32 bits. Thus to calculate bit
clock frequency the only other non-constant value that we need is frame
size (or sample rate)
Also implemented a set_tdm_slot dai ops callback for ntp8918 codec that will
ensure that tdm slot width and slot num are set to 32 and 2
respectively because ntp8918 can only operate in that configuration
Signed-off-by: Ilias Izmaylov <ikizmaylov@xxxxxxxxxxxxxxxxx>
---
sound/soc/codecs/ntp8918.c | 43 +++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/sound/soc/codecs/ntp8918.c b/sound/soc/codecs/ntp8918.c
index cc672fd93def4..c37bd5b53ed8a 100644
--- a/sound/soc/codecs/ntp8918.c
+++ b/sound/soc/codecs/ntp8918.c
@@ -32,6 +32,15 @@
SNDRV_PCM_FMTBIT_S24_LE | \
SNDRV_PCM_FMTBIT_S32_LE)
+/*
+ * The NTP8918 word clock (WCK) period is fixed at 64 bits,
+ * and the bit clock (BCK) period is equal to the word clock period.
+ * The interface has only 2 channels, meaning the number of ticks
+ * for both word and bit clocks per channel is 64 / 2 = 32.
+ */
+#define NTP8918_BCK_CHANNEL_PERIOD 32
+#define NTP8918_NR_CHANNELS 2
+
#define NTP8918_INPUT_FMT 0x0
#define NTP8918_INPUT_FMT_MASTER_MODE BIT(0)
#define NTP8918_INPUT_FMT_GSA_MODE BIT(1)
@@ -215,7 +224,17 @@ static int ntp8918_hw_params(struct snd_pcm_substream *substream,
int bclk;
int ret;
- bclk = snd_soc_params_to_bclk(params);
+ /*
+ * When calculating bit clock frequency the only non-constant
+ * input that's needed is sample rate which then needs to be
+ * multiplied by constant values of BCK channel period and
+ * number of channels.
+ */
+ bclk = snd_soc_tdm_params_to_bclk(params,
+ NTP8918_BCK_CHANNEL_PERIOD,
+ NTP8918_NR_CHANNELS,
+ 0);
+
switch (bclk) {
case 3072000:
case 2822400:
@@ -313,10 +332,32 @@ static int ntp8918_digital_mute(struct snd_soc_dai *dai, int mute, int stream)
return ret < 0 ? ret : 0;
}
+static int ntp8918_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask,
+ unsigned int rx_mask, int slots,
+ int slot_width)
+{
+ if (slots != NTP8918_NR_CHANNELS) {
+ dev_err(dai->component->dev,
+ "Unsupported number of TDM slots %d, should be %d\n",
+ slots, NTP8918_NR_CHANNELS);
+ return -EINVAL;
+ }
+
+ if (slot_width != NTP8918_BCK_CHANNEL_PERIOD) {
+ dev_err(dai->component->dev,
+ "Unsupported TDM slot width %d, should be %d\n",
+ slot_width, NTP8918_BCK_CHANNEL_PERIOD);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops ntp8918_dai_ops = {
.hw_params = ntp8918_hw_params,
.set_fmt = ntp8918_set_fmt,
.mute_stream = ntp8918_digital_mute,
+ .set_tdm_slot = ntp8918_set_tdm_slot,
};
static struct snd_soc_dai_driver ntp8918_dai = {
--
2.47.3