ASoC: cros_ec_codec: Support setting bclk ratio
authorYu-Hsuan Hsu <yuhsuan@chromium.org>
Sat, 25 Jan 2020 16:29:17 +0000 (00:29 +0800)
committerMark Brown <broonie@kernel.org>
Tue, 11 Feb 2020 11:20:23 +0000 (11:20 +0000)
Support setting bclk ratio from machine drivers.

Signed-off-by: Yu-Hsuan Hsu <yuhsuan@chromium.org>
Reviewed-by: Tzung-Bi Shih <tzungbi@google.com>
Link: https://lore.kernel.org/r/20200125162917.247485-1-yuhsuan@chromium.org
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/cros_ec_codec.c

index 6a24f57..d3dc42a 100644 (file)
@@ -45,6 +45,9 @@ struct cros_ec_codec_priv {
        /* DMIC */
        atomic_t dmic_probed;
 
+       /* I2S_RX */
+       uint32_t i2s_rx_bclk_ratio;
+
        /* WoV */
        bool wov_enabled;
        uint8_t *wov_audio_shm_p;
@@ -259,6 +262,7 @@ static int i2s_rx_hw_params(struct snd_pcm_substream *substream,
                snd_soc_component_get_drvdata(component);
        struct ec_param_ec_codec_i2s_rx p;
        enum ec_codec_i2s_rx_sample_depth depth;
+       uint32_t bclk;
        int ret;
 
        if (params_rate(params) != 48000)
@@ -284,15 +288,29 @@ static int i2s_rx_hw_params(struct snd_pcm_substream *substream,
        if (ret < 0)
                return ret;
 
-       dev_dbg(component->dev, "set bclk to %u\n",
-               snd_soc_params_to_bclk(params));
+       if (priv->i2s_rx_bclk_ratio)
+               bclk = params_rate(params) * priv->i2s_rx_bclk_ratio;
+       else
+               bclk = snd_soc_params_to_bclk(params);
+
+       dev_dbg(component->dev, "set bclk to %u\n", bclk);
 
        p.cmd = EC_CODEC_I2S_RX_SET_BCLK;
-       p.set_bclk_param.bclk = snd_soc_params_to_bclk(params);
+       p.set_bclk_param.bclk = bclk;
        return send_ec_host_command(priv->ec_device, EC_CMD_EC_CODEC_I2S_RX,
                                    (uint8_t *)&p, sizeof(p), NULL, 0);
 }
 
+static int i2s_rx_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio)
+{
+       struct snd_soc_component *component = dai->component;
+       struct cros_ec_codec_priv *priv =
+               snd_soc_component_get_drvdata(component);
+
+       priv->i2s_rx_bclk_ratio = ratio;
+       return 0;
+}
+
 static int i2s_rx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 {
        struct snd_soc_component *component = dai->component;
@@ -340,6 +358,7 @@ static int i2s_rx_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 static const struct snd_soc_dai_ops i2s_rx_dai_ops = {
        .hw_params = i2s_rx_hw_params,
        .set_fmt = i2s_rx_set_fmt,
+       .set_bclk_ratio = i2s_rx_set_bclk_ratio,
 };
 
 static int i2s_rx_event(struct snd_soc_dapm_widget *w,