Commit 40585391 authored by Adam Thomson's avatar Adam Thomson Committed by Mark Brown

ASoC: da7219: Make more efficient use of MCLK within driver

Currently, if the driver has control of MCLK then it remains
enabled as long as the codec is in STANDBY or above. The MCLK is
only really required in STANDBY when a 3-pole jack is inserted
and the HP detect procedure is required to run.

This patch updates the code to enable/disable the MCLK when moving
between the STANDBY and PREPARE bias level, and when a 3-pole jack
is inserted and HP detection is required, thus saving power at all
other times.
Signed-off-by: default avatarAdam Thomson <Adam.Thomson.Opensource@diasemi.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 29b4817d
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/property.h> #include <linux/property.h>
#include <linux/pm_wakeirq.h> #include <linux/pm_wakeirq.h>
...@@ -115,12 +116,23 @@ static void da7219_aad_hptest_work(struct work_struct *work) ...@@ -115,12 +116,23 @@ static void da7219_aad_hptest_work(struct work_struct *work)
u16 tonegen_freq_hptest; u16 tonegen_freq_hptest;
u8 accdet_cfg8; u8 accdet_cfg8;
int report = 0; int report = 0, ret = 0;
/* Lock DAPM and any Kcontrols that are affected by this test */ /* Lock DAPM and any Kcontrols that are affected by this test */
snd_soc_dapm_mutex_lock(dapm); snd_soc_dapm_mutex_lock(dapm);
mutex_lock(&da7219->lock); mutex_lock(&da7219->lock);
/* Ensure MCLK is available for HP test procedure */
if (da7219->mclk) {
ret = clk_prepare_enable(da7219->mclk);
if (ret) {
dev_err(codec->dev, "Failed to enable mclk - %d\n", ret);
mutex_unlock(&da7219->lock);
snd_soc_dapm_mutex_unlock(dapm);
return;
}
}
/* Bypass cache so it saves current settings */ /* Bypass cache so it saves current settings */
regcache_cache_bypass(da7219->regmap, true); regcache_cache_bypass(da7219->regmap, true);
...@@ -250,6 +262,10 @@ static void da7219_aad_hptest_work(struct work_struct *work) ...@@ -250,6 +262,10 @@ static void da7219_aad_hptest_work(struct work_struct *work)
snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK, snd_soc_update_bits(codec, DA7219_HP_R_CTRL, DA7219_HP_R_AMP_OE_MASK,
DA7219_HP_R_AMP_OE_MASK); DA7219_HP_R_AMP_OE_MASK);
/* Remove MCLK, if previously enabled */
if (da7219->mclk)
clk_disable_unprepare(da7219->mclk);
mutex_unlock(&da7219->lock); mutex_unlock(&da7219->lock);
snd_soc_dapm_mutex_unlock(dapm); snd_soc_dapm_mutex_unlock(dapm);
......
...@@ -1508,11 +1508,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, ...@@ -1508,11 +1508,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
switch (level) { switch (level) {
case SND_SOC_BIAS_ON: case SND_SOC_BIAS_ON:
case SND_SOC_BIAS_PREPARE:
break; break;
case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_PREPARE:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { /* Enable MCLK for transition to ON state */
/* MCLK */ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
if (da7219->mclk) { if (da7219->mclk) {
ret = clk_prepare_enable(da7219->mclk); ret = clk_prepare_enable(da7219->mclk);
if (ret) { if (ret) {
...@@ -1521,11 +1520,19 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, ...@@ -1521,11 +1520,19 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
return ret; return ret;
} }
} }
}
break;
case SND_SOC_BIAS_STANDBY:
if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Master bias */ /* Master bias */
snd_soc_update_bits(codec, DA7219_REFERENCES, snd_soc_update_bits(codec, DA7219_REFERENCES,
DA7219_BIAS_EN_MASK, DA7219_BIAS_EN_MASK,
DA7219_BIAS_EN_MASK); DA7219_BIAS_EN_MASK);
} else {
/* Remove MCLK */
if (da7219->mclk)
clk_disable_unprepare(da7219->mclk);
} }
break; break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
...@@ -1534,9 +1541,6 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec, ...@@ -1534,9 +1541,6 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, DA7219_REFERENCES, snd_soc_update_bits(codec, DA7219_REFERENCES,
DA7219_BIAS_EN_MASK, 0); DA7219_BIAS_EN_MASK, 0);
/* MCLK */
if (da7219->mclk)
clk_disable_unprepare(da7219->mclk);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment