[PATCH] ASoC: rt1308-sdw: get calibration params after power on
Pierre-Louis Bossart
pierre-louis.bossart at linux.intel.com
Tue Mar 15 16:03:31 CET 2022
On 3/15/22 04:37, shumingf at realtek.com wrote:
> From: Shuming Fan <shumingf at realtek.com>
>
> It will be safe when getting the calibration params after power-on.
> All powers are ready to read the calibration params from EFUSE.
>
> Signed-off-by: Shuming Fan <shumingf at realtek.com>
For more context, this patch solves 'cracking sound' on speakers and was
tested by the bug reporter on Dell XPS 17 9710 (SoundWire-based device)
BugLink: https://github.com/thesofproject/sof/issues/5436
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart at linux.intel.com>
> ---
> sound/soc/codecs/rt1308-sdw.c | 73 +++++++++++++++++++----------------
> 1 file changed, 40 insertions(+), 33 deletions(-)
>
> diff --git a/sound/soc/codecs/rt1308-sdw.c b/sound/soc/codecs/rt1308-sdw.c
> index 149a76075c76..1ef836a68a56 100644
> --- a/sound/soc/codecs/rt1308-sdw.c
> +++ b/sound/soc/codecs/rt1308-sdw.c
> @@ -50,6 +50,8 @@ static bool rt1308_volatile_register(struct device *dev, unsigned int reg)
> case 0x3008:
> case 0x300a:
> case 0xc000:
> + case 0xc860 ... 0xc863:
> + case 0xc870 ... 0xc873:
> return true;
> default:
> return false;
> @@ -159,12 +161,45 @@ static int rt1308_read_prop(struct sdw_slave *slave)
> return 0;
> }
>
> +static void rt1308_apply_calib_params(struct rt1308_sdw_priv *rt1308)
> +{
> + unsigned int efuse_m_btl_l, efuse_m_btl_r, tmp;
> + unsigned int efuse_c_btl_l, efuse_c_btl_r;
> +
> + /* read efuse to apply calibration parameters */
> + regmap_write(rt1308->regmap, 0xc7f0, 0x04);
> + regmap_write(rt1308->regmap, 0xc7f1, 0xfe);
> + msleep(100);
> + regmap_write(rt1308->regmap, 0xc7f0, 0x44);
> + msleep(20);
> + regmap_write(rt1308->regmap, 0xc240, 0x10);
> +
> + regmap_read(rt1308->regmap, 0xc861, &tmp);
> + efuse_m_btl_l = tmp;
> + regmap_read(rt1308->regmap, 0xc860, &tmp);
> + efuse_m_btl_l = efuse_m_btl_l | (tmp << 8);
> + regmap_read(rt1308->regmap, 0xc863, &tmp);
> + efuse_c_btl_l = tmp;
> + regmap_read(rt1308->regmap, 0xc862, &tmp);
> + efuse_c_btl_l = efuse_c_btl_l | (tmp << 8);
> + regmap_read(rt1308->regmap, 0xc871, &tmp);
> + efuse_m_btl_r = tmp;
> + regmap_read(rt1308->regmap, 0xc870, &tmp);
> + efuse_m_btl_r = efuse_m_btl_r | (tmp << 8);
> + regmap_read(rt1308->regmap, 0xc873, &tmp);
> + efuse_c_btl_r = tmp;
> + regmap_read(rt1308->regmap, 0xc872, &tmp);
> + efuse_c_btl_r = efuse_c_btl_r | (tmp << 8);
> + dev_dbg(&rt1308->sdw_slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__,
> + efuse_m_btl_l, efuse_m_btl_r);
> + dev_dbg(&rt1308->sdw_slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__,
> + efuse_c_btl_l, efuse_c_btl_r);
> +}
> +
> static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
> {
> struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
> int ret = 0;
> - unsigned int efuse_m_btl_l, efuse_m_btl_r, tmp;
> - unsigned int efuse_c_btl_l, efuse_c_btl_r;
>
> if (rt1308->hw_init)
> return 0;
> @@ -196,37 +231,6 @@ static int rt1308_io_init(struct device *dev, struct sdw_slave *slave)
> /* sw reset */
> regmap_write(rt1308->regmap, RT1308_SDW_RESET, 0);
>
> - /* read efuse */
> - regmap_write(rt1308->regmap, 0xc360, 0x01);
> - regmap_write(rt1308->regmap, 0xc361, 0x80);
> - regmap_write(rt1308->regmap, 0xc7f0, 0x04);
> - regmap_write(rt1308->regmap, 0xc7f1, 0xfe);
> - msleep(100);
> - regmap_write(rt1308->regmap, 0xc7f0, 0x44);
> - msleep(20);
> - regmap_write(rt1308->regmap, 0xc240, 0x10);
> -
> - regmap_read(rt1308->regmap, 0xc861, &tmp);
> - efuse_m_btl_l = tmp;
> - regmap_read(rt1308->regmap, 0xc860, &tmp);
> - efuse_m_btl_l = efuse_m_btl_l | (tmp << 8);
> - regmap_read(rt1308->regmap, 0xc863, &tmp);
> - efuse_c_btl_l = tmp;
> - regmap_read(rt1308->regmap, 0xc862, &tmp);
> - efuse_c_btl_l = efuse_c_btl_l | (tmp << 8);
> - regmap_read(rt1308->regmap, 0xc871, &tmp);
> - efuse_m_btl_r = tmp;
> - regmap_read(rt1308->regmap, 0xc870, &tmp);
> - efuse_m_btl_r = efuse_m_btl_r | (tmp << 8);
> - regmap_read(rt1308->regmap, 0xc873, &tmp);
> - efuse_c_btl_r = tmp;
> - regmap_read(rt1308->regmap, 0xc872, &tmp);
> - efuse_c_btl_r = efuse_c_btl_r | (tmp << 8);
> - dev_dbg(&slave->dev, "%s m_btl_l=0x%x, m_btl_r=0x%x\n", __func__,
> - efuse_m_btl_l, efuse_m_btl_r);
> - dev_dbg(&slave->dev, "%s c_btl_l=0x%x, c_btl_r=0x%x\n", __func__,
> - efuse_c_btl_l, efuse_c_btl_r);
> -
> /* initial settings */
> regmap_write(rt1308->regmap, 0xc103, 0xc0);
> regmap_write(rt1308->regmap, 0xc030, 0x17);
> @@ -323,6 +327,8 @@ static int rt1308_classd_event(struct snd_soc_dapm_widget *w,
> {
> struct snd_soc_component *component =
> snd_soc_dapm_to_component(w->dapm);
> + struct rt1308_sdw_priv *rt1308 =
> + snd_soc_component_get_drvdata(component);
>
> switch (event) {
> case SND_SOC_DAPM_POST_PMU:
> @@ -331,6 +337,7 @@ static int rt1308_classd_event(struct snd_soc_dapm_widget *w,
> RT1308_SDW_OFFSET | (RT1308_POWER_STATUS << 4),
> 0x3, 0x3);
> msleep(40);
> + rt1308_apply_calib_params(rt1308);
> break;
> case SND_SOC_DAPM_PRE_PMD:
> snd_soc_component_update_bits(component,
More information about the Alsa-devel
mailing list