OSDN Git Service

ASoC: rt1308-sdw: get calibration params after power on
authorShuming Fan <shumingf@realtek.com>
Tue, 15 Mar 2022 09:37:40 +0000 (17:37 +0800)
committerMark Brown <broonie@kernel.org>
Wed, 16 Mar 2022 16:39:23 +0000 (16:39 +0000)
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@realtek.com>
Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20220315093740.12008-1-shumingf@realtek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/codecs/rt1308-sdw.c

index 149a760..1ef836a 100644 (file)
@@ -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,