[PATCH v2 2/9] ASoC: sun8i-codec: Don't hardcode BCLK / LRCK ratio

Vasily Khoruzhick
2018-10-13T16:53:22Z

BCLK / LRCK ratio should be sample size * channels, but it was
hardcoded to 32 (0x1 is 32 as per A33 and A64 datasheets).

Calculate it basing on sample size and number of channels.

Signed-off-by: Vasily Khoruzhick <anarsoul@gmail.com>
---
sound/soc/sunxi/sun8i-codec.c | 35 ++++++++++++++++++++++++++++++-----
1 file changed, 30 insertions(+), 5 deletions(-)

diff --git a/sound/soc/sunxi/sun8i-codec.c b/sound/soc/sunxi/sun8i-codec.c
index fb37dd927e33..e681e194ad4c 100644
--- a/sound/soc/sunxi/sun8i-codec.c
+++ b/sound/soc/sunxi/sun8i-codec.c
@@ -52,7 +52,6 @@
#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_INV 13
#define SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV 9
#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV 6
-#define SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16 (1 << 6)
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ 4
#define SUN8I_AIF1CLK_CTRL_AIF1_WORD_SIZ_16 (1 << 4)
#define SUN8I_AIF1CLK_CTRL_AIF1_DATA_FMT 2
@@ -257,8 +256,8 @@ static int sun8i_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
}

struct sun8i_codec_clk_div {
- u8 div;
- u8 val;
+ unsigned int div;
+ u8 val;
};

static const struct sun8i_codec_clk_div sun8i_codec_bclk_div[] = {
@@ -300,12 +299,33 @@ static u8 sun8i_codec_get_bclk_div(struct sun8i_codec *scodec,
return best_val;
}

+static const struct sun8i_codec_clk_div sun8i_codec_lrck_div[] = {
+ { .div = 16, .val = 0 },
+ { .div = 32, .val = 1 },
+ { .div = 64, .val = 2 },
+ { .div = 128, .val = 3 },
+ { .div = 256, .val = 4 },
+};
+
+static int sun8i_codec_get_lrck_div(unsigned int channels,
+ unsigned int word_size)
+{
+ unsigned int div = word_size * channels;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(sun8i_codec_lrck_div); i++)
+ if (sun8i_codec_lrck_div[i].div == div)
+ return sun8i_codec_lrck_div[i].val;
+
+ return -EINVAL;
+}
+
static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
struct snd_soc_dai *dai)
{
struct sun8i_codec *scodec = snd_soc_component_get_drvdata(dai->component);
- int sample_rate;
+ int sample_rate, lrck_div;
u8 bclk_div;

/*
@@ -321,9 +341,14 @@ static int sun8i_codec_hw_params(struct snd_pcm_substream *substream,
SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV_MASK,
bclk_div << SUN8I_AIF1CLK_CTRL_AIF1_BCLK_DIV);

+ lrck_div = sun8i_codec_get_lrck_div(params_channels(params),
+ params_physical_width(params));
+ if (lrck_div < 0)
+ return lrck_div;
+
regmap_update_bits(scodec->regmap, SUN8I_AIF1CLK_CTRL,
SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_MASK,
- SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV_16);
+ lrck_div << SUN8I_AIF1CLK_CTRL_AIF1_LRCK_DIV);

sample_rate = sun8i_codec_get_hw_rate(params);
if (sample_rate < 0)
--
2.19.0