From 00d512dc535201b88821dbd54a319a8f2cf3f3c3 Mon Sep 17 00:00:00 2001 From: Laxminath Kasam Date: Mon, 13 Feb 2017 19:36:27 +0530 Subject: ASoC: codecs: Enable SSR for internal codec and WSA For internal codec SSR, remove regcache sync as regcache operations over SPMI is not supported. Enable SSR for both internal codec and WSA codec. CRs-Fixed: 2001499 Change-Id: I98c363c45973d50654af231d5a7772ba059fccac Signed-off-by: Laxminath Kasam --- sound/soc/codecs/msm_sdw/msm_sdw_cdc.c | 64 ++++++++++++++++++--------- sound/soc/codecs/sdm660_cdc/msm-analog-cdc.c | 36 +++++---------- sound/soc/codecs/sdm660_cdc/msm-digital-cdc.c | 3 ++ 3 files changed, 56 insertions(+), 47 deletions(-) (limited to 'sound/soc') diff --git a/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c b/sound/soc/codecs/msm_sdw/msm_sdw_cdc.c index 850238764d87..4e808dfa0311 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, @@ -1629,6 +1633,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); @@ -1641,15 +1647,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; @@ -1676,17 +1701,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 8f7db4d13378..358a0d905d88 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", @@ -3772,7 +3770,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); @@ -3794,14 +3791,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, @@ -3850,10 +3839,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"); @@ -4053,17 +4038,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; } -- cgit v1.2.3