Skip to content

Commit

Permalink
Merge remote-tracking branches 'asoc/topic/da7218', 'asoc/topic/da721…
Browse files Browse the repository at this point in the history
…9' and 'asoc/topic/dpcm' into asoc-next
  • Loading branch information
broonie committed Sep 29, 2016
4 parents acf6470 + 72dce36 + a56a569 + 94d215c commit 480d060
Show file tree
Hide file tree
Showing 8 changed files with 201 additions and 53 deletions.
2 changes: 2 additions & 0 deletions include/sound/da7219.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ enum da7219_mic_amp_in_sel {
struct da7219_aad_pdata;

struct da7219_pdata {
bool wakeup_source;

/* Mic */
enum da7219_micbias_voltage micbias_lvl;
enum da7219_mic_amp_in_sel mic_amp_in_sel;
Expand Down
34 changes: 15 additions & 19 deletions sound/soc/codecs/da7218.c
Original file line number Diff line number Diff line change
Expand Up @@ -1819,7 +1819,7 @@ static int da7218_set_dai_sysclk(struct snd_soc_dai *codec_dai,
if (da7218->mclk_rate == freq)
return 0;

if (((freq < 2000000) && (freq != 32768)) || (freq > 54000000)) {
if ((freq < 2000000) || (freq > 54000000)) {
dev_err(codec_dai->dev, "Unsupported MCLK value %d\n",
freq);
return -EINVAL;
Expand Down Expand Up @@ -1866,11 +1866,8 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
u32 freq_ref;
u64 frac_div;

/* Verify 32KHz, 2MHz - 54MHz MCLK provided, and set input divider */
if (da7218->mclk_rate == 32768) {
indiv_bits = DA7218_PLL_INDIV_9_TO_18_MHZ;
indiv = DA7218_PLL_INDIV_9_TO_18_MHZ_VAL;
} else if (da7218->mclk_rate < 2000000) {
/* Verify 2MHz - 54MHz MCLK provided, and set input divider */
if (da7218->mclk_rate < 2000000) {
dev_err(codec->dev, "PLL input clock %d below valid range\n",
da7218->mclk_rate);
return -EINVAL;
Expand Down Expand Up @@ -1911,9 +1908,6 @@ static int da7218_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
case DA7218_SYSCLK_PLL_SRM:
pll_ctrl |= DA7218_PLL_MODE_SRM;
break;
case DA7218_SYSCLK_PLL_32KHZ:
pll_ctrl |= DA7218_PLL_MODE_32KHZ;
break;
default:
dev_err(codec->dev, "Invalid PLL config\n");
return -EINVAL;
Expand Down Expand Up @@ -2589,20 +2583,22 @@ static int da7218_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 (da7218->mclk) {
ret = clk_prepare_enable(da7218->mclk);
if (ret) {
dev_err(codec->dev,
"Failed to enable mclk\n");
dev_err(codec->dev, "Failed to enable mclk\n");
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, DA7218_REFERENCES,
DA7218_BIAS_EN_MASK,
Expand All @@ -2612,6 +2608,10 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, DA7218_LDO_CTRL,
DA7218_LDO_EN_MASK,
DA7218_LDO_EN_MASK);
} else {
/* Remove MCLK */
if (da7218->mclk)
clk_disable_unprepare(da7218->mclk);
}
break;
case SND_SOC_BIAS_OFF:
Expand All @@ -2625,10 +2625,6 @@ static int da7218_set_bias_level(struct snd_soc_codec *codec,
snd_soc_update_bits(codec, DA7218_REFERENCES,
DA7218_BIAS_EN_MASK, 0);
}

/* MCLK */
if (da7218->mclk)
clk_disable_unprepare(da7218->mclk);
break;
}

Expand Down
2 changes: 0 additions & 2 deletions sound/soc/codecs/da7218.h
Original file line number Diff line number Diff line change
Expand Up @@ -888,7 +888,6 @@
#define DA7218_PLL_MODE_BYPASS (0x0 << 6)
#define DA7218_PLL_MODE_NORMAL (0x1 << 6)
#define DA7218_PLL_MODE_SRM (0x2 << 6)
#define DA7218_PLL_MODE_32KHZ (0x3 << 6)

/* DA7218_PLL_FRAC_TOP = 0x92 */
#define DA7218_PLL_FBDIV_FRAC_TOP_SHIFT 0
Expand Down Expand Up @@ -1371,7 +1370,6 @@ enum da7218_sys_clk {
DA7218_SYSCLK_MCLK = 0,
DA7218_SYSCLK_PLL,
DA7218_SYSCLK_PLL_SRM,
DA7218_SYSCLK_PLL_32KHZ
};

enum da7218_dev_id {
Expand Down
108 changes: 105 additions & 3 deletions sound/soc/codecs/da7219-aad.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -750,6 +796,62 @@ static void da7219_aad_handle_pdata(struct snd_soc_codec *codec)
}


/*
* Suspend/Resume
*/

void da7219_aad_suspend(struct snd_soc_codec *codec)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_aad_priv *da7219_aad = da7219->aad;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
u8 micbias_ctrl;

if (da7219_aad->jack) {
/* Disable jack detection during suspend */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
DA7219_ACCDET_EN_MASK, 0);

/*
* If we have a 4-pole jack inserted, then micbias will be
* enabled. We can disable micbias here, and keep a note to
* re-enable it on resume. If jack removal occurred during
* suspend then this will be dealt with through the IRQ handler.
*/
if (da7219_aad->jack_inserted) {
micbias_ctrl = snd_soc_read(codec, DA7219_MICBIAS_CTRL);
if (micbias_ctrl & DA7219_MICBIAS1_EN_MASK) {
snd_soc_dapm_disable_pin(dapm, "Mic Bias");
snd_soc_dapm_sync(dapm);
da7219_aad->micbias_resume_enable = true;
}
}
}
}

void da7219_aad_resume(struct snd_soc_codec *codec)
{
struct da7219_priv *da7219 = snd_soc_codec_get_drvdata(codec);
struct da7219_aad_priv *da7219_aad = da7219->aad;
struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);

if (da7219_aad->jack) {
/* Re-enable micbias if previously enabled for 4-pole jack */
if (da7219_aad->jack_inserted &&
da7219_aad->micbias_resume_enable) {
snd_soc_dapm_force_enable_pin(dapm, "Mic Bias");
snd_soc_dapm_sync(dapm);
da7219_aad->micbias_resume_enable = false;
}

/* Re-enable jack detection */
snd_soc_update_bits(codec, DA7219_ACCDET_CONFIG_1,
DA7219_ACCDET_EN_MASK,
DA7219_ACCDET_EN_MASK);
}
}


/*
* Init/Exit
*/
Expand Down
11 changes: 9 additions & 2 deletions sound/soc/codecs/da7219-aad.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -199,12 +201,17 @@ struct da7219_aad_priv {
struct work_struct hptest_work;

struct snd_soc_jack *jack;
bool micbias_resume_enable;
bool jack_inserted;
};

/* AAD control */
void da7219_aad_jack_det(struct snd_soc_codec *codec, struct snd_soc_jack *jack);

/* Suspend/Resume */
void da7219_aad_suspend(struct snd_soc_codec *codec);
void da7219_aad_resume(struct snd_soc_codec *codec);

/* Init/Exit */
int da7219_aad_init(struct snd_soc_codec *codec);
void da7219_aad_exit(struct snd_soc_codec *codec);
Expand Down
Loading

0 comments on commit 480d060

Please sign in to comment.