summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sound/soc/codecs/da7219-aad.c52
-rw-r--r--sound/soc/codecs/da7219-aad.h6
-rw-r--r--sound/soc/codecs/da7219.c18
-rw-r--r--sound/soc/codecs/da7219.h2
4 files changed, 66 insertions, 12 deletions
diff --git a/sound/soc/codecs/da7219-aad.c b/sound/soc/codecs/da7219-aad.c
index f0057cd..fc27dab 100644
--- a/sound/soc/codecs/da7219-aad.c
+++ b/sound/soc/codecs/da7219-aad.c
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
+#include <linux/clk.h>
#include <linux/i2c.h>
#include <linux/property.h>
#include <linux/pm_wakeirq.h>
@@ -114,13 +115,38 @@ static void da7219_aad_hptest_work(struct work_struct *work)
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
u16 tonegen_freq_hptest;
- u8 accdet_cfg8;
- int report = 0;
+ u8 pll_srm_sts, gain_ramp_ctrl, accdet_cfg8;
+ int report = 0, ret = 0;
/* Lock DAPM and any Kcontrols that are affected by this test */
snd_soc_dapm_mutex_lock(dapm);
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;
+ }
+ }
+
+ /*
+ * If MCLK not present, then we're using the internal oscillator and
+ * require different frequency settings to achieve the same result.
+ */
+ pll_srm_sts = snd_soc_read(codec, DA7219_PLL_SRM_STS);
+ if (pll_srm_sts & DA7219_PLL_SRM_STS_MCLK)
+ tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
+ else
+ tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC);
+
+ /* Ensure gain ramping at fastest rate */
+ gain_ramp_ctrl = snd_soc_read(codec, DA7219_GAIN_RAMP_CTRL);
+ snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, DA7219_GAIN_RAMP_RATE_X8);
+
/* Bypass cache so it saves current settings */
regcache_cache_bypass(da7219->regmap, true);
@@ -183,9 +209,15 @@ static void da7219_aad_hptest_work(struct work_struct *work)
snd_soc_write(codec, DA7219_HP_R_CTRL,
DA7219_HP_R_AMP_OE_MASK | DA7219_HP_R_AMP_EN_MASK);
+ /*
+ * If we're running from the internal oscillator then give audio paths
+ * time to settle before running test.
+ */
+ if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
+ msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
+
/* Configure & start Tone Generator */
snd_soc_write(codec, DA7219_TONE_GEN_ON_PER, DA7219_BEEP_ON_PER_MASK);
- tonegen_freq_hptest = cpu_to_le16(DA7219_AAD_HPTEST_RAMP_FREQ);
regmap_raw_write(da7219->regmap, DA7219_TONE_GEN_FREQ1_L,
&tonegen_freq_hptest, sizeof(tonegen_freq_hptest));
snd_soc_update_bits(codec, DA7219_TONE_GEN_CFG2,
@@ -244,12 +276,26 @@ static void da7219_aad_hptest_work(struct work_struct *work)
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_8,
DA7219_HPTEST_EN_MASK, 0);
+ /*
+ * If we're running from the internal oscillator then give audio paths
+ * time to settle before allowing headphones to be driven as required.
+ */
+ if (!(pll_srm_sts & DA7219_PLL_SRM_STS_MCLK))
+ msleep(DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY);
+
+ /* Restore gain ramping rate */
+ snd_soc_write(codec, DA7219_GAIN_RAMP_CTRL, gain_ramp_ctrl);
+
/* Drive Headphones/lineout */
snd_soc_update_bits(codec, DA7219_HP_L_CTRL, DA7219_HP_L_AMP_OE_MASK,
DA7219_HP_L_AMP_OE_MASK);
snd_soc_update_bits(codec, DA7219_HP_R_CTRL, 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);
snd_soc_dapm_mutex_unlock(dapm);
diff --git a/sound/soc/codecs/da7219-aad.h b/sound/soc/codecs/da7219-aad.h
index 4fccf67..a34be48 100644
--- a/sound/soc/codecs/da7219-aad.h
+++ b/sound/soc/codecs/da7219-aad.h
@@ -176,8 +176,10 @@
#define DA7219_AAD_MICBIAS_CHK_DELAY 10
#define DA7219_AAD_MICBIAS_CHK_RETRIES 5
-#define DA7219_AAD_HPTEST_RAMP_FREQ 0x28
-#define DA7219_AAD_HPTEST_PERIOD 65
+#define DA7219_AAD_HPTEST_RAMP_FREQ 0x28
+#define DA7219_AAD_HPTEST_RAMP_FREQ_INT_OSC 0x4D
+#define DA7219_AAD_HPTEST_PERIOD 65
+#define DA7219_AAD_HPTEST_INT_OSC_PATH_DELAY 20
enum da7219_aad_event_regs {
DA7219_AAD_IRQ_REG_A = 0,
diff --git a/sound/soc/codecs/da7219.c b/sound/soc/codecs/da7219.c
index 30f35e8..9d08c11 100644
--- a/sound/soc/codecs/da7219.c
+++ b/sound/soc/codecs/da7219.c
@@ -1508,11 +1508,10 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
switch (level) {
case SND_SOC_BIAS_ON:
- case SND_SOC_BIAS_PREPARE:
break;
- case SND_SOC_BIAS_STANDBY:
- if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
- /* MCLK */
+ case SND_SOC_BIAS_PREPARE:
+ /* Enable MCLK for transition to ON state */
+ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_STANDBY) {
if (da7219->mclk) {
ret = clk_prepare_enable(da7219->mclk);
if (ret) {
@@ -1521,11 +1520,19 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
return ret;
}
}
+ }
+ break;
+ case SND_SOC_BIAS_STANDBY:
+ if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) {
/* Master bias */
snd_soc_update_bits(codec, DA7219_REFERENCES,
DA7219_BIAS_EN_MASK,
DA7219_BIAS_EN_MASK);
+ } else {
+ /* Remove MCLK */
+ if (da7219->mclk)
+ clk_disable_unprepare(da7219->mclk);
}
break;
case SND_SOC_BIAS_OFF:
@@ -1534,9 +1541,6 @@ static int da7219_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, DA7219_REFERENCES,
DA7219_BIAS_EN_MASK, 0);
- /* MCLK */
- if (da7219->mclk)
- clk_disable_unprepare(da7219->mclk);
break;
}
diff --git a/sound/soc/codecs/da7219.h b/sound/soc/codecs/da7219.h
index ff2a2f0..545576d 100644
--- a/sound/soc/codecs/da7219.h
+++ b/sound/soc/codecs/da7219.h
@@ -224,6 +224,7 @@
#define DA7219_PLL_SRM_STATE_MASK (0xF << 0)
#define DA7219_PLL_SRM_STATUS_SHIFT 4
#define DA7219_PLL_SRM_STATUS_MASK (0xF << 4)
+#define DA7219_PLL_SRM_STS_MCLK (0x1 << 4)
#define DA7219_PLL_SRM_STS_SRM_LOCK (0x1 << 7)
/* DA7219_DIG_ROUTING_DAI = 0x2A */
@@ -576,6 +577,7 @@
/* DA7219_GAIN_RAMP_CTRL = 0x92 */
#define DA7219_GAIN_RAMP_RATE_SHIFT 0
#define DA7219_GAIN_RAMP_RATE_MASK (0x3 << 0)
+#define DA7219_GAIN_RAMP_RATE_X8 (0x0 << 0)
#define DA7219_GAIN_RAMP_RATE_MAX 4
/* DA7219_PC_COUNT = 0x94 */