diff options
author | Samuel Holland <samuel@sholland.org> | 2020-10-14 01:19:31 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2020-10-26 14:56:57 +0000 |
commit | afb1a6006299a8b6b5ad04363fd74aa66a6ac79b (patch) | |
tree | 2e01acfb3a44c5b60d0aeba2ef87ef954e83278b /sound/soc/sunxi | |
parent | 68a4f2caaa17ce62890c51ef957dd008c2e42aae (diff) | |
download | lwn-afb1a6006299a8b6b5ad04363fd74aa66a6ac79b.tar.gz lwn-afb1a6006299a8b6b5ad04363fd74aa66a6ac79b.zip |
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: Maxime Ripard <mripard@kernel.org>
Signed-off-by: Samuel Holland <samuel@sholland.org>
Link: https://lore.kernel.org/r/20201014061941.4306-8-samuel@sholland.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound/soc/sunxi')
-rw-r--r-- | sound/soc/sunxi/sun8i-codec.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c index ae885774c877..49e763d1891b 100644 --- a/sound/soc/sunxi/sun8i-codec.c +++ b/sound/soc/sunxi/sun8i-codec.c @@ -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, }; |