Skip to content

Commit

Permalink
ASoC: codecs: ES8326: Add es8326_mute function
Browse files Browse the repository at this point in the history
The internal analog power and hp Vref of es8326 should always be on to
reduce pop noise. The HP_VOL and HP_CAL are moved to es8326_mute function
so they are turned on at last and turned off at first.

Also, the calibration should be done manually once during start-up
to reduce DC offset on headphone.

Signed-off-by: Zhu Ning <zhuning0077@gmail.com>
Link: https://lore.kernel.org/r/20230714032453.3334-1-zhuning0077@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Zhu Ning authored and Mark Brown committed Jul 14, 2023
1 parent 2edd641 commit 083912c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 47 deletions.
75 changes: 31 additions & 44 deletions sound/soc/codecs/es8326.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ struct es8326_priv {
u8 interrupt_clk;
bool jd_inverted;
unsigned int sysclk;

bool calibrated;
int version;
};

static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9550, 50, 0);
Expand Down Expand Up @@ -121,33 +124,12 @@ static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = {
/* Analog Power Supply*/
SND_SOC_DAPM_DAC("Right DAC", NULL, ES8326_ANA_PDN, 0, 1),
SND_SOC_DAPM_DAC("Left DAC", NULL, ES8326_ANA_PDN, 1, 1),
SND_SOC_DAPM_SUPPLY("Analog Power", ES8326_ANA_PDN, 7, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("IBias Power", ES8326_ANA_PDN, 6, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("ADC Vref", ES8326_ANA_PDN, 5, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("DAC Vref", ES8326_ANA_PDN, 4, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("Vref Power", ES8326_ANA_PDN, 3, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("MICBIAS1", ES8326_ANA_MICBIAS, 2, 0, NULL, 0),
SND_SOC_DAPM_SUPPLY("MICBIAS2", ES8326_ANA_MICBIAS, 3, 0, NULL, 0),

SND_SOC_DAPM_PGA("LHPMIX", ES8326_DAC2HPMIX, 7, 0, NULL, 0),
SND_SOC_DAPM_PGA("RHPMIX", ES8326_DAC2HPMIX, 3, 0, NULL, 0),

/* Headphone Charge Pump and Output */
SND_SOC_DAPM_SUPPLY("HPOR Cal", ES8326_HP_CAL, 7, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("HPOL Cal", ES8326_HP_CAL, 3, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("Headphone Charge Pump", ES8326_HP_DRIVER,
3, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("Headphone Driver Bias", ES8326_HP_DRIVER,
2, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("Headphone LDO", ES8326_HP_DRIVER,
1, 1, NULL, 0),
SND_SOC_DAPM_SUPPLY("Headphone Reference", ES8326_HP_DRIVER,
0, 1, NULL, 0),
SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOR Supply", ES8326_HP_CAL,
ES8326_HPOR_SHIFT, 7, 7, 0),
SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOL Supply", ES8326_HP_CAL,
0, 7, 7, 0),

SND_SOC_DAPM_OUTPUT("HPOL"),
SND_SOC_DAPM_OUTPUT("HPOR"),
};
Expand All @@ -166,34 +148,12 @@ static const struct snd_soc_dapm_route es8326_dapm_routes[] = {
{"I2S OUT", NULL, "ADC L"},
{"I2S OUT", NULL, "ADC R"},

{"I2S OUT", NULL, "Analog Power"},
{"I2S OUT", NULL, "ADC Vref"},
{"I2S OUT", NULL, "Vref Power"},
{"I2S OUT", NULL, "IBias Power"},
{"I2S IN", NULL, "Analog Power"},
{"I2S IN", NULL, "DAC Vref"},
{"I2S IN", NULL, "Vref Power"},
{"I2S IN", NULL, "IBias Power"},

{"Right DAC", NULL, "I2S IN"},
{"Left DAC", NULL, "I2S IN"},

{"LHPMIX", NULL, "Left DAC"},
{"RHPMIX", NULL, "Right DAC"},

{"HPOR", NULL, "HPOR Cal"},
{"HPOL", NULL, "HPOL Cal"},
{"HPOR", NULL, "HPOR Supply"},
{"HPOL", NULL, "HPOL Supply"},
{"HPOL", NULL, "Headphone Charge Pump"},
{"HPOR", NULL, "Headphone Charge Pump"},
{"HPOL", NULL, "Headphone Driver Bias"},
{"HPOR", NULL, "Headphone Driver Bias"},
{"HPOL", NULL, "Headphone LDO"},
{"HPOR", NULL, "Headphone LDO"},
{"HPOL", NULL, "Headphone Reference"},
{"HPOR", NULL, "Headphone Reference"},

{"HPOL", NULL, "LHPMIX"},
{"HPOR", NULL, "RHPMIX"},
};
Expand Down Expand Up @@ -419,6 +379,31 @@ static int es8326_pcm_hw_params(struct snd_pcm_substream *substream,
return 0;
}

static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
{
struct snd_soc_component *component = dai->component;
struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);

if (mute) {
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF);
regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE,
ES8326_MUTE_MASK, ES8326_MUTE);
regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xf0);
} else {
if (!es8326->calibrated) {
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_FORCE_CAL);
msleep(30);
es8326->calibrated = true;
}
regmap_write(es8326->regmap, ES8326_HP_DRIVER, 0xa0);
regmap_write(es8326->regmap, ES8326_HP_VOL, 0x00);
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON);
regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE,
ES8326_MUTE_MASK, ~(ES8326_MUTE));
}
return 0;
}

static int es8326_set_bias_level(struct snd_soc_component *codec,
enum snd_soc_bias_level level)
{
Expand Down Expand Up @@ -469,6 +454,8 @@ static const struct snd_soc_dai_ops es8326_ops = {
.hw_params = es8326_pcm_hw_params,
.set_fmt = es8326_set_dai_fmt,
.set_sysclk = es8326_set_dai_sysclk,
.mute_stream = es8326_mute,
.no_capture_mute = 1,
};

static struct snd_soc_dai_driver es8326_dai = {
Expand Down Expand Up @@ -691,7 +678,7 @@ static int es8326_suspend(struct snd_soc_component *component)

cancel_delayed_work_sync(&es8326->jack_detect_work);
es8326_disable_micbias(component);

es8326->calibrated = false;
regmap_write(es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_OFF);
regcache_cache_only(es8326->regmap, true);
regcache_mark_dirty(es8326->regmap);
Expand Down
9 changes: 6 additions & 3 deletions sound/soc/codecs/es8326.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#ifndef _ES8326_H
#define _ES8326_H

#define CONFIG_HHTECH_MINIPMP 1

/* ES8326 register space */
#define ES8326_RESET 0x00
#define ES8326_CLK_CTL 0x01
Expand Down Expand Up @@ -94,6 +92,8 @@
#define ES8326_PWRUP_SEQ_EN (1 << 5)
#define ES8326_CODEC_RESET (0x0f << 0)
#define ES8326_CSM_OFF (0 << 7)
#define ES8326_MUTE_MASK (3 << 0)
#define ES8326_MUTE (3 << 0)

/* ES8326_CLK_CTL */
#define ES8326_CLK_ON (0x7f << 0)
Expand Down Expand Up @@ -122,7 +122,9 @@
#define ES8326_MIC2_SEL (1 << 5)

/* ES8326_HP_CAL */
#define ES8326_HPOR_SHIFT 4
#define ES8326_HP_OFF 0
#define ES8326_HP_FORCE_CAL ((1 << 7) | (1 << 3))
#define ES8326_HP_ON ((7 << 4) | (7 << 0))

/* ES8326_ADC1_SRC */
#define ES8326_ADC1_SHIFT 0
Expand Down Expand Up @@ -180,3 +182,4 @@
#define ES8326_VERSION_B (1 << 0)

#endif

0 comments on commit 083912c

Please sign in to comment.