Unverified Commit 59c6a3a4 authored by Jerome Brunet's avatar Jerome Brunet Committed by Mark Brown
Browse files

ASoC: meson: axg-tdm-interface: add frame rate constraint



According to Amlogic datasheets for the SoCs supported by this driver, the
maximum bit clock rate is 100MHz.

The tdm interface allows the rates listed by the DAI driver, regardless of
the number slots or their width. However, these will impact the bit clock
rate.

Hitting the 100MHz limit is very unlikely for most use cases but it is
possible.

For example with 32 slots / 32 bits wide, the maximum rate is no longer
384kHz but ~96kHz.

Add the constraint accordingly if the component is not already active.
If it is active, the rate is already constrained by the first stream rate.

Fixes: d60e4f1e ("ASoC: meson: add tdm interface driver")
Signed-off-by: default avatarJerome Brunet <jbrunet@baylibre.com>
Link: https://msgid.link/r/20240223175116.2005407-3-jbrunet@baylibre.com


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent e3741a8d
Loading
Loading
Loading
Loading
+18 −7
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@

#include "axg-tdm.h"

/* Maximum bit clock frequency according the datasheets */
#define MAX_SCLK 100000000 /* Hz */

enum {
	TDM_IFACE_PAD,
	TDM_IFACE_LOOPBACK,
@@ -153,19 +156,27 @@ static int axg_tdm_iface_startup(struct snd_pcm_substream *substream,
		return -EINVAL;
	}

	/* Apply component wide rate symmetry */
	if (snd_soc_component_active(dai->component)) {
		/* Apply component wide rate symmetry */
		ret = snd_pcm_hw_constraint_single(substream->runtime,
						   SNDRV_PCM_HW_PARAM_RATE,
						   iface->rate);
		if (ret < 0) {
			dev_err(dai->dev,
				"can't set iface rate constraint\n");
			return ret;
		}

	} else {
		/* Limit rate according to the slot number and width */
		unsigned int max_rate =
			MAX_SCLK / (iface->slots * iface->slot_width);
		ret = snd_pcm_hw_constraint_minmax(substream->runtime,
						   SNDRV_PCM_HW_PARAM_RATE,
						   0, max_rate);
	}

	return 0;
	if (ret < 0)
		dev_err(dai->dev, "can't set iface rate constraint\n");
	else
		ret = 0;

	return ret;
}

static int axg_tdm_iface_set_stream(struct snd_pcm_substream *substream,