Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2d24386 authored by Divya Ojha's avatar Divya Ojha Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: codecs: Add PM suspend routines for digital codec



Digital codec soc suspend enables mclk, preventing XO shutdown.
So implement digital codec pm suspend to disable mclk. Add ignore
suspend property to new widgets to resolve powering up and down
during suspend.

Change-Id: I2a773cdfe25d408d95f1c07be71fd4be740e8bf0
Signed-off-by: default avatarDivya Ojha <dojha@codeaurora.org>
parent fc0f6a78
Loading
Loading
Loading
Loading
+4 −14
Original line number Diff line number Diff line
@@ -4046,6 +4046,7 @@ EXPORT_SYMBOL(msm_anlg_codec_info_create_codec_entry);
static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec)
{
	struct sdm660_cdc_priv *sdm660_cdc;
	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
	int ret;

	sdm660_cdc = dev_get_drvdata(codec->dev);
@@ -4154,6 +4155,9 @@ static int msm_anlg_cdc_soc_probe(struct snd_soc_codec *codec)
	/* Set initial cap mode */
	msm_anlg_cdc_configure_cap(codec, false, false);

	snd_soc_dapm_ignore_suspend(dapm, "PDM Playback");
	snd_soc_dapm_ignore_suspend(dapm, "PDM Capture");

	return 0;
}

@@ -4229,24 +4233,10 @@ static int msm_anlg_cdc_disable_static_supplies_to_optimum(

static int msm_anlg_cdc_suspend(struct snd_soc_codec *codec)
{
	struct msm_asoc_mach_data *pdata = NULL;
	struct sdm660_cdc_priv *sdm660_cdc = snd_soc_codec_get_drvdata(codec);
	struct sdm660_cdc_pdata *sdm660_cdc_pdata =
					sdm660_cdc->dev->platform_data;

	pdata = snd_soc_card_get_drvdata(codec->component.card);
	pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n",
		  __func__, atomic_read(&pdata->int_mclk0_rsc_ref),
	atomic_read(&pdata->int_mclk0_enabled));
	if (atomic_read(&pdata->int_mclk0_enabled) == true) {
		cancel_delayed_work_sync(&pdata->disable_int_mclk0_work);
		mutex_lock(&pdata->cdc_int_mclk0_mutex);
		pdata->digital_cdc_core_clk.enable = 0;
		afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX,
				       &pdata->digital_cdc_core_clk);
		atomic_set(&pdata->int_mclk0_enabled, false);
		mutex_unlock(&pdata->cdc_int_mclk0_mutex);
	}
	msm_anlg_cdc_disable_static_supplies_to_optimum(sdm660_cdc,
							sdm660_cdc_pdata);
	return 0;
+70 −1
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ static int msm_digcdc_clock_control(bool flag)
		if (atomic_read(&pdata->int_mclk0_enabled) == false) {
			pdata->digital_cdc_core_clk.enable = 1;
			ret = afe_set_lpass_clock_v2(
						AFE_PORT_ID_PRIMARY_MI2S_RX,
						AFE_PORT_ID_INT0_MI2S_RX,
						&pdata->digital_cdc_core_clk);
			if (ret < 0) {
				pr_err("%s:failed to enable the MCLK\n",
@@ -1166,6 +1166,7 @@ EXPORT_SYMBOL(msm_dig_codec_info_create_codec_entry);
static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
{
	struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);
	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
	int i, ret;

	msm_dig_cdc->codec = codec;
@@ -1197,6 +1198,15 @@ static int msm_dig_cdc_soc_probe(struct snd_soc_codec *codec)
	}
	registered_digcodec = codec;

	snd_soc_dapm_ignore_suspend(dapm, "AIF1 Playback");
	snd_soc_dapm_ignore_suspend(dapm, "AIF1 Capture");
	snd_soc_dapm_ignore_suspend(dapm, "ADC1_IN");
	snd_soc_dapm_ignore_suspend(dapm, "ADC2_IN");
	snd_soc_dapm_ignore_suspend(dapm, "ADC3_IN");
	snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX1");
	snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX2");
	snd_soc_dapm_ignore_suspend(dapm, "PDM_OUT_RX3");

	return 0;
}

@@ -1969,9 +1979,27 @@ static struct regmap *msm_digital_get_regmap(struct device *dev)
	return msm_dig_cdc->regmap;
}

static int msm_dig_cdc_suspend(struct snd_soc_codec *codec)
{
	struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);

	msm_dig_cdc->dapm_bias_off = 1;
	return 0;
}

static int msm_dig_cdc_resume(struct snd_soc_codec *codec)
{
	struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(codec->dev);

	msm_dig_cdc->dapm_bias_off = 0;
	return 0;
}

static struct snd_soc_codec_driver soc_msm_dig_codec = {
	.probe  = msm_dig_cdc_soc_probe,
	.remove = msm_dig_cdc_soc_remove,
	.suspend = msm_dig_cdc_suspend,
	.resume = msm_dig_cdc_resume,
	.controls = msm_dig_snd_controls,
	.num_controls = ARRAY_SIZE(msm_dig_snd_controls),
	.dapm_widgets = msm_dig_dapm_widgets,
@@ -2054,6 +2082,44 @@ static int msm_dig_cdc_remove(struct platform_device *pdev)
	return 0;
}

#ifdef CONFIG_PM
static int msm_dig_suspend(struct device *dev)
{
	struct msm_asoc_mach_data *pdata =
	snd_soc_card_get_drvdata(registered_digcodec->component.card);
	struct msm_dig_priv *msm_dig_cdc = dev_get_drvdata(dev);

	if (msm_dig_cdc->dapm_bias_off) {
		pr_debug("%s: mclk cnt = %d, mclk_enabled = %d\n",
			__func__, atomic_read(&pdata->int_mclk0_rsc_ref),
			atomic_read(&pdata->int_mclk0_enabled));

		if (atomic_read(&pdata->int_mclk0_enabled) == true) {
			cancel_delayed_work_sync(
				&pdata->disable_int_mclk0_work);
			mutex_lock(&pdata->cdc_int_mclk0_mutex);
			pdata->digital_cdc_core_clk.enable = 0;
			afe_set_lpass_clock_v2(AFE_PORT_ID_INT0_MI2S_RX,
						&pdata->digital_cdc_core_clk);
			atomic_set(&pdata->int_mclk0_enabled, false);
			mutex_unlock(&pdata->cdc_int_mclk0_mutex);
		}
	}

	return 0;
}

static int msm_dig_resume(struct device *dev)
{
	return 0;
}

static const struct dev_pm_ops msm_dig_pm_ops = {
	.suspend = msm_dig_suspend,
	.resume = msm_dig_resume,
};
#endif

static const struct of_device_id msm_dig_cdc_of_match[] = {
	{.compatible = "qcom,msm-digital-codec"},
	{},
@@ -2064,6 +2130,9 @@ static struct platform_driver msm_digcodec_driver = {
		.owner          = THIS_MODULE,
		.name           = DRV_NAME,
		.of_match_table = msm_dig_cdc_of_match,
#ifdef CONFIG_PM
	.pm = &msm_dig_pm_ops,
#endif
	},
	.probe                  = msm_dig_cdc_probe,
	.remove                 = msm_dig_cdc_remove,
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ struct msm_dig_priv {
	struct regmap *regmap;
	struct notifier_block nblock;
	u32 mute_mask;
	int dapm_bias_off;
	void *handle;
	void (*update_clkdiv)(void *handle, int val);
	int (*get_cdc_version)(void *handle);