diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c index f4a8fe7778fd..2667d9e32869 100644 --- a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c +++ b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c @@ -48,10 +48,14 @@ #define MSM_SDW_VERSION_1_0 0x0001 #define MSM_SDW_VERSION_ENTRY_SIZE 32 +/* + * 200 Milliseconds sufficient for DSP bring up in the modem + * after Sub System Restart + */ +#define ADSP_STATE_READY_TIMEOUT_MS 200 + static const DECLARE_TLV_DB_SCALE(digital_gain, 0, 1, 0); static struct snd_soc_dai_driver msm_sdw_dai[]; -static bool initial_boot = true; -static bool is_ssr_en; static bool skip_irq = true; static int msm_sdw_config_ear_spkr_gain(struct snd_soc_codec *codec, @@ -1636,6 +1640,8 @@ static int msm_sdw_notifier_service_cb(struct notifier_block *nb, struct msm_sdw_priv *msm_sdw = container_of(nb, struct msm_sdw_priv, service_nb); + bool adsp_ready = false; + unsigned long timeout; pr_debug("%s: Service opcode 0x%lx\n", __func__, opcode); @@ -1648,15 +1654,34 @@ static int msm_sdw_notifier_service_cb(struct notifier_block *nb, SWR_DEVICE_DOWN, NULL); break; case AUDIO_NOTIFIER_SERVICE_UP: - if (initial_boot) { - initial_boot = false; - break; + if (!q6core_is_adsp_ready()) { + dev_dbg(msm_sdw->dev, "ADSP isn't ready\n"); + timeout = jiffies + + msecs_to_jiffies(ADSP_STATE_READY_TIMEOUT_MS); + while (!time_after(jiffies, timeout)) { + if (!q6core_is_adsp_ready()) { + dev_dbg(msm_sdw->dev, + "ADSP isn't ready\n"); + } else { + dev_dbg(msm_sdw->dev, + "ADSP is ready\n"); + adsp_ready = true; + goto powerup; + } + } + } else { + adsp_ready = true; + dev_dbg(msm_sdw->dev, "%s: DSP is ready\n", __func__); + } +powerup: + if (adsp_ready) { + msm_sdw->dev_up = true; + msm_sdw_init_reg(msm_sdw->codec); + regcache_mark_dirty(msm_sdw->regmap); + regcache_sync(msm_sdw->regmap); + msm_sdw_set_spkr_mode(msm_sdw->codec, + msm_sdw->spkr_mode); } - msm_sdw->dev_up = true; - msm_sdw_init_reg(msm_sdw->codec); - regcache_mark_dirty(msm_sdw->regmap); - regcache_sync(msm_sdw->regmap); - msm_sdw_set_spkr_mode(msm_sdw->codec, msm_sdw->spkr_mode); break; default: break; @@ -1683,17 +1708,14 @@ static int msm_sdw_codec_probe(struct snd_soc_codec *codec) msm_sdw_init_reg(codec); msm_sdw->version = MSM_SDW_VERSION_1_0; - if (is_ssr_en) { - msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; - ret = audio_notifier_register("msm_sdw", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &msm_sdw->service_nb); - if (ret < 0) - dev_err(msm_sdw->dev, - "%s: Audio notifier register failed ret = %d\n", - __func__, ret); - } - + msm_sdw->service_nb.notifier_call = msm_sdw_notifier_service_cb; + ret = audio_notifier_register("msm_sdw", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &msm_sdw->service_nb); + if (ret < 0) + dev_err(msm_sdw->dev, + "%s: Audio notifier register failed ret = %d\n", + __func__, ret); return 0; } diff --git a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c index 5323c0465682..5ecd7870bb3b 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c @@ -93,8 +93,6 @@ static const DECLARE_TLV_DB_SCALE(analog_gain, 0, 25, 1); static struct snd_soc_dai_driver msm_anlg_cdc_i2s_dai[]; /* By default enable the internal speaker boost */ static bool spkr_boost_en = true; -static bool initial_boot = true; -static bool is_ssr_en; static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { "cdc-vdd-mic-bias", @@ -3777,7 +3775,6 @@ static int msm_anlg_cdc_device_down(struct snd_soc_codec *codec) snd_soc_write(codec, MSM89XX_PMIC_ANALOG_SPKR_DAC_CTL, 0x93); - msm_anlg_cdc_bringup(codec); atomic_set(&pdata->int_mclk0_enabled, false); msm_anlg_cdc_dig_notifier_call(codec, DIG_CDC_EVENT_SSR_DOWN); set_bit(BUS_DOWN, &sdm660_cdc_priv->status_mask); @@ -3799,14 +3796,6 @@ static int msm_anlg_cdc_device_up(struct snd_soc_codec *codec) /* delay is required to make sure sound card state updated */ usleep_range(5000, 5100); - msm_anlg_cdc_codec_init_reg(codec); - msm_anlg_cdc_update_reg_defaults(codec); - - regcache_mark_dirty(codec->component.regmap); - regcache_sync_region(codec->component.regmap, - MSM89XX_PMIC_DIGITAL_REVISION1, - MSM89XX_PMIC_CDC_MAX_REGISTER); - snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_INT_EN_SET, MSM89XX_PMIC_DIGITAL_INT_EN_SET__POR); snd_soc_write(codec, MSM89XX_PMIC_DIGITAL_INT_EN_CLR, @@ -3855,10 +3844,6 @@ static int sdm660_cdc_notifier_service_cb(struct notifier_block *nb, msm_anlg_cdc_device_down(codec); break; case AUDIO_NOTIFIER_SERVICE_UP: - if (initial_boot) { - initial_boot = false; - break; - } dev_dbg(codec->dev, "ADSP is about to power up. bring up codec\n"); @@ -4058,17 +4043,16 @@ int msm_anlg_codec_info_create_codec_entry(struct snd_info_entry *codec_root, return -ENOMEM; } sdm660_cdc_priv->version_entry = version_entry; - if (is_ssr_en) { - sdm660_cdc_priv->audio_ssr_nb.notifier_call = - sdm660_cdc_notifier_service_cb; - ret = audio_notifier_register("pmic_analog_cdc", - AUDIO_NOTIFIER_ADSP_DOMAIN, - &sdm660_cdc_priv->audio_ssr_nb); - if (ret < 0) { - pr_err("%s: Audio notifier register failed ret = %d\n", - __func__, ret); - return ret; - } + + sdm660_cdc_priv->audio_ssr_nb.notifier_call = + sdm660_cdc_notifier_service_cb; + ret = audio_notifier_register("pmic_analog_cdc", + AUDIO_NOTIFIER_ADSP_DOMAIN, + &sdm660_cdc_priv->audio_ssr_nb); + if (ret < 0) { + pr_err("%s: Audio notifier register failed ret = %d\n", + __func__, ret); + return ret; } return 0; } diff --git a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c index 5e078dba0448..f1c3b4050323 100644 --- a/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c +++ b/sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c @@ -74,6 +74,7 @@ static int msm_digcdc_clock_control(bool flag) pdata = snd_soc_card_get_drvdata(registered_digcodec->component.card); + mutex_lock(&pdata->cdc_int_mclk0_mutex); if (flag) { if (atomic_read(&pdata->int_mclk0_enabled) == false) { pdata->digital_cdc_core_clk.enable = 1; @@ -83,6 +84,7 @@ static int msm_digcdc_clock_control(bool flag) if (ret < 0) { pr_err("%s:failed to enable the MCLK\n", __func__); + mutex_unlock(&pdata->cdc_int_mclk0_mutex); return ret; } pr_debug("enabled digital codec core clk\n"); @@ -94,6 +96,7 @@ static int msm_digcdc_clock_control(bool flag) dev_dbg(registered_digcodec->dev, "disable MCLK, workq to disable set already\n"); } + mutex_unlock(&pdata->cdc_int_mclk0_mutex); return 0; }