Unverified Commit afb1a600 authored by Samuel Holland's avatar Samuel Holland Committed by Mark Brown
Browse files

ASoC: sun8i-codec: Support the TDM slot binding



Now that BCLK and LRCK rate calculations in the driver can handle any
hardware-supported slot width and number of slots, allow overriding
those parameters from the device tree.

Acked-by: default avatarMaxime Ripard <mripard@kernel.org>
Signed-off-by: default avatarSamuel Holland <samuel@sholland.org>
Link: https://lore.kernel.org/r/20201014061941.4306-8-samuel@sholland.org


Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 68a4f2ca
Loading
Loading
Loading
Loading
+26 −2
Original line number Diff line number Diff line
@@ -99,6 +99,11 @@ enum {
	SUN8I_CODEC_NAIFS
};

struct sun8i_codec_aif {
	unsigned int	slots;
	unsigned int	slot_width;
};

struct sun8i_codec_quirks {
	bool legacy_widgets	: 1;
	bool lrck_inversion	: 1;
@@ -108,6 +113,7 @@ struct sun8i_codec {
	struct regmap			*regmap;
	struct clk			*clk_module;
	const struct sun8i_codec_quirks	*quirks;
	struct sun8i_codec_aif		aifs[SUN8I_CODEC_NAIFS];
};

static int sun8i_codec_runtime_resume(struct device *dev)
@@ -261,6 +267,22 @@ static int sun8i_codec_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
	return 0;
}

static int sun8i_codec_set_tdm_slot(struct snd_soc_dai *dai,
				    unsigned int tx_mask, unsigned int rx_mask,
				    int slots, int slot_width)
{
	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];

	if (slot_width && !is_power_of_2(slot_width))
		return -EINVAL;

	aif->slots = slots;
	aif->slot_width = slot_width;

	return 0;
}

struct sun8i_codec_clk_div {
	u8	div;
	u8	val;
@@ -321,8 +343,9 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
				 struct snd_soc_dai *dai)
{
	struct sun8i_codec *scodec = snd_soc_dai_get_drvdata(dai);
	unsigned int slots = params_channels(params);
	unsigned int slot_width = params_width(params);
	struct sun8i_codec_aif *aif = &scodec->aifs[dai->id];
	unsigned int slots = aif->slots ?: params_channels(params);
	unsigned int slot_width = aif->slot_width ?: params_width(params);
	int lrck_div_order, sample_rate, word_size;
	u8 bclk_div;

@@ -376,6 +399,7 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,

static const struct snd_soc_dai_ops sun8i_codec_dai_ops = {
	.set_fmt	= sun8i_codec_set_fmt,
	.set_tdm_slot	= sun8i_codec_set_tdm_slot,
	.hw_params	= sun8i_codec_hw_params,
};