From: Marcus Cooper <[email protected]>
Some codecs require a different amount of a bit clocks per frame than
what is calculated by the sample width. Use the tdm slot bindings to
provide this mechanism.
Signed-off-by: Marcus Cooper <[email protected]>
---
sound/soc/sunxi/sun4i-i2s.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
index 329883750d6f..bca73b3c0d74 100644
--- a/sound/soc/sunxi/sun4i-i2s.c
+++ b/sound/soc/sunxi/sun4i-i2s.c
@@ -186,6 +186,9 @@ struct sun4i_i2s {
struct regmap_field *field_rxchansel;
const struct sun4i_i2s_quirks *variant;
+
+ unsigned int tdm_slots;
+ unsigned int slot_width;
};
struct sun4i_i2s_clk_div {
@@ -337,7 +340,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
if (i2s->variant->is_h3_i2s_based)
regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
- SUN8I_I2S_FMT0_LRCK_PERIOD(32));
+ SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
/* Set sign extension to pad out LSB with 0 */
regmap_field_write(i2s->field_fmt_sext, 0);
@@ -414,7 +417,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
sr + i2s->variant->fmt_offset);
return sun4i_i2s_set_clk_rate(dai, params_rate(params),
- params_width(params));
+ i2s->tdm_slots ?
+ i2s->slot_width : params_width(params));
}
static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
@@ -657,11 +661,25 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
return 0;
}
+static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
+ unsigned int tx_mask, unsigned int rx_mask,
+ int slots, int width)
+{
+ struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
+
+ i2s->tdm_slots = slots;
+
+ i2s->slot_width = width;
+
+ return 0;
+}
+
static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
.hw_params = sun4i_i2s_hw_params,
.set_fmt = sun4i_i2s_set_fmt,
.set_sysclk = sun4i_i2s_set_sysclk,
.trigger = sun4i_i2s_trigger,
+ .set_tdm_slot = sun4i_i2s_set_dai_tdm_slot,
};
static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
--
2.21.0
On Mon, Jun 03, 2019 at 07:47:31PM +0200, [email protected] wrote:
> From: Marcus Cooper <[email protected]>
>
> Some codecs require a different amount of a bit clocks per frame than
Which codec? And what are the actual requirements?
> what is calculated by the sample width. Use the tdm slot bindings to
> provide this mechanism.
>
> Signed-off-by: Marcus Cooper <[email protected]>
> ---
> sound/soc/sunxi/sun4i-i2s.c | 22 ++++++++++++++++++++--
> 1 file changed, 20 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index 329883750d6f..bca73b3c0d74 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -186,6 +186,9 @@ struct sun4i_i2s {
> struct regmap_field *field_rxchansel;
>
> const struct sun4i_i2s_quirks *variant;
> +
> + unsigned int tdm_slots;
> + unsigned int slot_width;
> };
>
> struct sun4i_i2s_clk_div {
> @@ -337,7 +340,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
> if (i2s->variant->is_h3_i2s_based)
> regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
> SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
> - SUN8I_I2S_FMT0_LRCK_PERIOD(32));
> + SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
This is an unrelated change, it should be in a separate patch.
>
> /* Set sign extension to pad out LSB with 0 */
> regmap_field_write(i2s->field_fmt_sext, 0);
> @@ -414,7 +417,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream *substream,
> sr + i2s->variant->fmt_offset);
>
> return sun4i_i2s_set_clk_rate(dai, params_rate(params),
> - params_width(params));
> + i2s->tdm_slots ?
> + i2s->slot_width : params_width(params));
> }
>
> static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> @@ -657,11 +661,25 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, int clk_id,
> return 0;
> }
>
> +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
> + unsigned int tx_mask, unsigned int rx_mask,
> + int slots, int width)
The alignment after the wraping should be at the opening parenthesis.
> +{
> + struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +
> + i2s->tdm_slots = slots;
> +
> + i2s->slot_width = width;
> +
> + return 0;
> +}
> +
> static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
> .hw_params = sun4i_i2s_hw_params,
> .set_fmt = sun4i_i2s_set_fmt,
> .set_sysclk = sun4i_i2s_set_sysclk,
> .trigger = sun4i_i2s_trigger,
> + .set_tdm_slot = sun4i_i2s_set_dai_tdm_slot,
Please sort them by alphabetical order.
Thanks!
Maxime
--
Maxime Ripard, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com