mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-03 00:54:09 +08:00
ASOC: codecs: ES8326: Add calibration support for version_b
Version_b requires a new way of calibrating headset offset. A new calibration function is added. Signed-off-by: Zhu Ning <zhuning0077@gmail.com> Link: https://lore.kernel.org/r/20230717033223.42506-4-zhuning0077@gmail.com Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
parent
ac20a73d76
commit
0663286e58
@ -388,6 +388,7 @@ 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);
|
||||
unsigned int offset_l, offset_r;
|
||||
|
||||
if (mute) {
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF);
|
||||
@ -398,10 +399,16 @@ static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction)
|
||||
if (!es8326->calibrated) {
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_FORCE_CAL);
|
||||
msleep(30);
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF);
|
||||
regmap_read(es8326->regmap, ES8326_HPL_OFFSET_INI, &offset_l);
|
||||
regmap_read(es8326->regmap, ES8326_HPR_OFFSET_INI, &offset_r);
|
||||
regmap_write(es8326->regmap, ES8326_HP_OFFSET_CAL, 0x8c);
|
||||
regmap_write(es8326->regmap, ES8326_HPL_OFFSET_INI, offset_l);
|
||||
regmap_write(es8326->regmap, ES8326_HPR_OFFSET_INI, offset_r);
|
||||
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_VOL, 0x80);
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON);
|
||||
regmap_update_bits(es8326->regmap, ES8326_DAC_MUTE,
|
||||
ES8326_MUTE_MASK, ~(ES8326_MUTE));
|
||||
@ -420,15 +427,17 @@ static int es8326_set_bias_level(struct snd_soc_component *codec,
|
||||
ret = clk_prepare_enable(es8326->mclk);
|
||||
if (ret)
|
||||
return ret;
|
||||
regmap_write(es8326->regmap, ES8326_RESET, ES8326_PWRUP_SEQ_EN);
|
||||
regmap_write(es8326->regmap, ES8326_INTOUT_IO, 0x45);
|
||||
|
||||
regmap_write(es8326->regmap, ES8326_RESET, 0x9f);
|
||||
msleep(20);
|
||||
regmap_update_bits(es8326->regmap, ES8326_DAC_DSM, 0x01, 0x00);
|
||||
regmap_write(es8326->regmap, ES8326_INTOUT_IO, es8326->interrupt_clk);
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT1_IO,
|
||||
(ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT));
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_RESAMPLE, 0x05);
|
||||
regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x02);
|
||||
regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x0E);
|
||||
regmap_write(es8326->regmap, ES8326_PGA_PDN, 0x40);
|
||||
regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0xAA);
|
||||
regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x00);
|
||||
regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x20);
|
||||
regmap_write(es8326->regmap, ES8326_RESET, ES8326_CSM_ON);
|
||||
break;
|
||||
case SND_SOC_BIAS_PREPARE:
|
||||
@ -437,15 +446,10 @@ static int es8326_set_bias_level(struct snd_soc_component *codec,
|
||||
break;
|
||||
case SND_SOC_BIAS_OFF:
|
||||
clk_disable_unprepare(es8326->mclk);
|
||||
regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0x11);
|
||||
regmap_write(es8326->regmap, ES8326_RESET, ES8326_CSM_OFF);
|
||||
regmap_write(es8326->regmap, ES8326_PGA_PDN, 0xF8);
|
||||
regmap_write(es8326->regmap, ES8326_ANA_PDN, 0x3b);
|
||||
regmap_write(es8326->regmap, ES8326_VMIDSEL, 0x00);
|
||||
regmap_write(es8326->regmap, ES8326_INT_SOURCE, 0x08);
|
||||
regmap_update_bits(es8326->regmap, ES8326_CLK_CTL, 0x20, 0x00);
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT);
|
||||
regmap_write(es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT);
|
||||
regmap_write(es8326->regmap, ES8326_RESET,
|
||||
ES8326_CODEC_RESET | ES8326_PWRUP_SEQ_EN);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -635,6 +639,54 @@ out:
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int es8326_calibrate(struct snd_soc_component *component)
|
||||
{
|
||||
struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
|
||||
unsigned int reg;
|
||||
unsigned int offset_l, offset_r;
|
||||
|
||||
regmap_read(es8326->regmap, ES8326_CHIP_VERSION, ®);
|
||||
es8326->version = reg;
|
||||
|
||||
if ((es8326->version == ES8326_VERSION_B) && (es8326->calibrated == false)) {
|
||||
dev_dbg(component->dev, "ES8326_VERSION_B, calibrating\n");
|
||||
regmap_write(es8326->regmap, ES8326_CLK_INV, 0xc0);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_DIV1, 0x01);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_DLL, 0x30);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_MUX, 0xed);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_TRI, 0xc1);
|
||||
regmap_write(es8326->regmap, ES8326_DAC_MUTE, 0x03);
|
||||
regmap_write(es8326->regmap, ES8326_ANA_VSEL, 0x7f);
|
||||
regmap_write(es8326->regmap, ES8326_VMIDLOW, 0x33);
|
||||
regmap_write(es8326->regmap, ES8326_DAC2HPMIX, 0x88);
|
||||
regmap_write(es8326->regmap, ES8326_HP_VOL, 0x80);
|
||||
regmap_write(es8326->regmap, ES8326_HP_OFFSET_CAL, 0x8c);
|
||||
regmap_write(es8326->regmap, ES8326_RESET, 0xc0);
|
||||
usleep_range(15000, 20000);
|
||||
|
||||
regmap_write(es8326->regmap, ES8326_HP_OFFSET_CAL, ES8326_HP_OFF);
|
||||
regmap_read(es8326->regmap, ES8326_CSM_MUTE_STA, ®);
|
||||
if ((reg & 0xf0) != 0x40)
|
||||
msleep(50);
|
||||
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, 0xd4);
|
||||
msleep(200);
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, 0x4d);
|
||||
msleep(200);
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF);
|
||||
regmap_read(es8326->regmap, ES8326_HPL_OFFSET_INI, &offset_l);
|
||||
regmap_read(es8326->regmap, ES8326_HPR_OFFSET_INI, &offset_r);
|
||||
regmap_write(es8326->regmap, ES8326_HP_OFFSET_CAL, 0x8c);
|
||||
regmap_write(es8326->regmap, ES8326_HPL_OFFSET_INI, offset_l);
|
||||
regmap_write(es8326->regmap, ES8326_HPR_OFFSET_INI, offset_r);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_INV, 0x00);
|
||||
|
||||
es8326->calibrated = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int es8326_resume(struct snd_soc_component *component)
|
||||
{
|
||||
struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
|
||||
@ -673,7 +725,8 @@ static int es8326_resume(struct snd_soc_component *component)
|
||||
regmap_write(es8326->regmap, ES8326_CLK_VMIDS1, 0xc4);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_VMIDS2, 0x81);
|
||||
regmap_write(es8326->regmap, ES8326_CLK_CAL_TIME, 0x00);
|
||||
|
||||
/* calibrate for B version */
|
||||
es8326_calibrate(component);
|
||||
/* turn off headphone out */
|
||||
regmap_write(es8326->regmap, ES8326_HP_CAL, 0x00);
|
||||
/* set ADC and DAC in low power mode */
|
||||
|
Loading…
Reference in New Issue
Block a user