ASoC: wcd9335: Update HIFI mode sequence for headphones
Update HIFI mode register sequence for headphones on wcd9335 codec for better performance. Change-Id: I277a38847d02c4500cc3d2c77b00fbe4a63e2f83 Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
This commit is contained in:
parent
0307f3529b
commit
b7f1874102
2 changed files with 176 additions and 15 deletions
|
@ -335,6 +335,7 @@ enum {
|
|||
AIF4_SWITCH_VALUE,
|
||||
AUDIO_NOMINAL,
|
||||
CPE_NOMINAL,
|
||||
HPH_PA_DELAY,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -764,6 +765,8 @@ struct tasha_priv {
|
|||
struct hpf_work tx_hpf_work[TASHA_NUM_DECIMATORS];
|
||||
struct tx_mute_work tx_mute_dwork[TASHA_NUM_DECIMATORS];
|
||||
struct mutex codec_mutex;
|
||||
int hph_l_gain;
|
||||
int hph_r_gain;
|
||||
};
|
||||
|
||||
static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
|
||||
|
@ -3526,22 +3529,80 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void tasha_codec_hph_post_pa_config(struct tasha_priv *tasha,
|
||||
int mode, int event)
|
||||
{
|
||||
u8 scale_val = 0;
|
||||
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
return;
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
switch (mode) {
|
||||
case CLS_H_HIFI:
|
||||
scale_val = 0x3;
|
||||
break;
|
||||
case CLS_H_LOHIFI:
|
||||
scale_val = 0x1;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SND_SOC_DAPM_PRE_PMD:
|
||||
scale_val = 0x6;
|
||||
break;
|
||||
}
|
||||
|
||||
if (scale_val)
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_PA_CTL1, 0x0E,
|
||||
scale_val << 1);
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
if (tasha->comp_enabled[COMPANDER_1] ||
|
||||
tasha->comp_enabled[COMPANDER_2]) {
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN,
|
||||
0x20, 0x00);
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN,
|
||||
0x20, 0x00);
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP,
|
||||
0x20, 0x20);
|
||||
}
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_L_EN, 0x1F,
|
||||
tasha->hph_l_gain);
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_R_EN, 0x1F,
|
||||
tasha->hph_r_gain);
|
||||
}
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_update_bits(tasha->codec, WCD9335_HPH_AUTO_CHOP, 0x20,
|
||||
0x00);
|
||||
}
|
||||
}
|
||||
|
||||
static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
||||
struct snd_kcontrol *kcontrol,
|
||||
int event)
|
||||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
int hph_mode = tasha->hph_mode;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
set_bit(HPH_PA_DELAY, &tasha->status_mask);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* 5ms sleep is required after PA is enabled as per
|
||||
/*
|
||||
* 7ms sleep is required after PA is enabled as per
|
||||
* HW requirement
|
||||
*/
|
||||
usleep_range(5000, 5500);
|
||||
if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
|
||||
usleep_range(7000, 7100);
|
||||
clear_bit(HPH_PA_DELAY, &tasha->status_mask);
|
||||
}
|
||||
tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
|
||||
snd_soc_update_bits(codec, WCD9335_CDC_RX2_RX_PATH_CTL,
|
||||
0x10, 0x00);
|
||||
/* Remove mix path mute if it is enabled */
|
||||
|
@ -3555,6 +3616,7 @@ static int tasha_codec_enable_hphr_pa(struct snd_soc_dapm_widget *w,
|
|||
blocking_notifier_call_chain(&tasha->notifier,
|
||||
WCD_EVENT_PRE_HPHR_PA_OFF,
|
||||
&tasha->mbhc);
|
||||
tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* 5ms sleep is required after PA is disabled as per
|
||||
|
@ -3582,16 +3644,26 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
{
|
||||
struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
int hph_mode = tasha->hph_mode;
|
||||
int ret = 0;
|
||||
|
||||
dev_dbg(codec->dev, "%s %s %d\n", __func__, w->name, event);
|
||||
|
||||
switch (event) {
|
||||
case SND_SOC_DAPM_PRE_PMU:
|
||||
set_bit(HPH_PA_DELAY, &tasha->status_mask);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMU:
|
||||
/* 5ms sleep is required after PA is enabled as per
|
||||
/*
|
||||
* 7ms sleep is required after PA is enabled as per
|
||||
* HW requirement
|
||||
*/
|
||||
usleep_range(5000, 5500);
|
||||
if (test_bit(HPH_PA_DELAY, &tasha->status_mask)) {
|
||||
usleep_range(7000, 7100);
|
||||
clear_bit(HPH_PA_DELAY, &tasha->status_mask);
|
||||
}
|
||||
|
||||
tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
|
||||
snd_soc_update_bits(codec, WCD9335_CDC_RX1_RX_PATH_CTL,
|
||||
0x10, 0x00);
|
||||
/* Remove mix path mute if it is enabled */
|
||||
|
@ -3605,6 +3677,7 @@ static int tasha_codec_enable_hphl_pa(struct snd_soc_dapm_widget *w,
|
|||
blocking_notifier_call_chain(&tasha->notifier,
|
||||
WCD_EVENT_PRE_HPHL_PA_OFF,
|
||||
&tasha->mbhc);
|
||||
tasha_codec_hph_post_pa_config(tasha, hph_mode, event);
|
||||
break;
|
||||
case SND_SOC_DAPM_POST_PMD:
|
||||
/* 5ms sleep is required after PA is disabled as per
|
||||
|
@ -3734,8 +3807,43 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void tasha_codec_hph_mode_gain_opt(struct snd_soc_codec *codec,
|
||||
u8 gain)
|
||||
{
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
u8 hph_l_en, hph_r_en;
|
||||
u8 l_val, r_val;
|
||||
u8 hph_pa_status;
|
||||
bool is_hphl_pa, is_hphr_pa;
|
||||
|
||||
hph_pa_status = snd_soc_read(codec, WCD9335_ANA_HPH);
|
||||
is_hphl_pa = hph_pa_status >> 7;
|
||||
is_hphr_pa = (hph_pa_status & 0x40) >> 6;
|
||||
|
||||
hph_l_en = snd_soc_read(codec, WCD9335_HPH_L_EN);
|
||||
hph_r_en = snd_soc_read(codec, WCD9335_HPH_R_EN);
|
||||
|
||||
l_val = (hph_l_en & 0xC0) | 0x20 | gain;
|
||||
r_val = (hph_r_en & 0xC0) | 0x20 | gain;
|
||||
|
||||
/*
|
||||
* Set HPH_L & HPH_R gain source selection to REGISTER
|
||||
* for better click and pop only if corresponding PAs are
|
||||
* not enabled. Also cache the values of the HPHL/R
|
||||
* PA gains to be applied after PAs are enabled
|
||||
*/
|
||||
if ((l_val != hph_l_en) && !is_hphl_pa) {
|
||||
snd_soc_write(codec, WCD9335_HPH_L_EN, l_val);
|
||||
tasha->hph_l_gain = hph_l_en & 0x1F;
|
||||
}
|
||||
|
||||
if ((r_val != hph_r_en) && !is_hphr_pa) {
|
||||
snd_soc_write(codec, WCD9335_HPH_R_EN, r_val);
|
||||
tasha->hph_r_gain = hph_r_en & 0x1F;
|
||||
}
|
||||
}
|
||||
|
||||
static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec,
|
||||
struct tasha_priv *tasha,
|
||||
int event)
|
||||
{
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
|
@ -3755,7 +3863,6 @@ static void tasha_codec_hph_lohifi_config(struct snd_soc_codec *codec,
|
|||
}
|
||||
|
||||
static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec,
|
||||
struct tasha_priv *tasha,
|
||||
int event)
|
||||
{
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
|
@ -3785,6 +3892,22 @@ static void tasha_codec_hph_lp_config(struct snd_soc_codec *codec,
|
|||
}
|
||||
}
|
||||
|
||||
static void tasha_codec_hph_hifi_config(struct snd_soc_codec *codec,
|
||||
int event)
|
||||
{
|
||||
if (SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x03);
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
|
||||
tasha_codec_hph_mode_gain_opt(codec, 0x11);
|
||||
}
|
||||
|
||||
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
|
||||
snd_soc_update_bits(codec, WCD9335_HPH_CNP_WG_CTL, 0x07, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
|
||||
int event, int mode)
|
||||
{
|
||||
|
@ -3795,10 +3918,13 @@ static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
|
|||
|
||||
switch (mode) {
|
||||
case CLS_H_LP:
|
||||
tasha_codec_hph_lp_config(codec, tasha, event);
|
||||
tasha_codec_hph_lp_config(codec, event);
|
||||
break;
|
||||
case CLS_H_LOHIFI:
|
||||
tasha_codec_hph_lohifi_config(codec, tasha, event);
|
||||
tasha_codec_hph_lohifi_config(codec, event);
|
||||
break;
|
||||
case CLS_H_HIFI:
|
||||
tasha_codec_hph_hifi_config(codec, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -4146,6 +4272,38 @@ static u16 tasha_interp_get_primary_reg(u16 reg, u16 *ind)
|
|||
return prim_int_reg;
|
||||
}
|
||||
|
||||
static void tasha_codec_hd2_control(struct snd_soc_codec *codec,
|
||||
u16 prim_int_reg, int event)
|
||||
{
|
||||
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||
u16 hd2_scale_reg;
|
||||
u16 hd2_enable_reg = 0;
|
||||
|
||||
if (!TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||
return;
|
||||
|
||||
if (prim_int_reg == WCD9335_CDC_RX1_RX_PATH_CTL) {
|
||||
hd2_scale_reg = WCD9335_CDC_RX1_RX_PATH_SEC3;
|
||||
hd2_enable_reg = WCD9335_CDC_RX1_RX_PATH_CFG0;
|
||||
}
|
||||
if (prim_int_reg == WCD9335_CDC_RX2_RX_PATH_CTL) {
|
||||
hd2_scale_reg = WCD9335_CDC_RX2_RX_PATH_SEC3;
|
||||
hd2_enable_reg = WCD9335_CDC_RX2_RX_PATH_CFG0;
|
||||
}
|
||||
|
||||
if (hd2_enable_reg && SND_SOC_DAPM_EVENT_ON(event)) {
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x10);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x01);
|
||||
snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x04);
|
||||
}
|
||||
|
||||
if (hd2_enable_reg && SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||
snd_soc_update_bits(codec, hd2_enable_reg, 0x04, 0x00);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x03, 0x00);
|
||||
snd_soc_update_bits(codec, hd2_scale_reg, 0x3C, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
static int tasha_codec_enable_prim_interpolator(
|
||||
struct snd_soc_codec *codec,
|
||||
u16 reg, int event)
|
||||
|
@ -4162,6 +4320,7 @@ static int tasha_codec_enable_prim_interpolator(
|
|||
if (tasha->prim_int_users[ind] == 1) {
|
||||
snd_soc_update_bits(codec, prim_int_reg,
|
||||
0x10, 0x10);
|
||||
tasha_codec_hd2_control(codec, prim_int_reg, event);
|
||||
snd_soc_update_bits(codec, prim_int_reg,
|
||||
1 << 0x5, 1 << 0x5);
|
||||
}
|
||||
|
@ -4178,6 +4337,7 @@ static int tasha_codec_enable_prim_interpolator(
|
|||
0x40, 0x40);
|
||||
snd_soc_update_bits(codec, prim_int_reg,
|
||||
0x40, 0x00);
|
||||
tasha_codec_hd2_control(codec, prim_int_reg, event);
|
||||
}
|
||||
break;
|
||||
};
|
||||
|
@ -9782,11 +9942,11 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = {
|
|||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("ANC HPHL PA", WCD9335_ANA_HPH, 7, 0, NULL, 0,
|
||||
tasha_codec_enable_hphl_pa,
|
||||
SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("ANC HPHR PA", WCD9335_ANA_HPH, 6, 0, NULL, 0,
|
||||
tasha_codec_enable_hphr_pa,
|
||||
SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU |
|
||||
SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMD),
|
||||
SND_SOC_DAPM_PGA_E("ANC LINEOUT1 PA", WCD9335_ANA_LO_1_2,
|
||||
7, 0, NULL, 0,
|
||||
|
@ -10995,7 +11155,6 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
|
|||
{WCD9335_HPH_OCP_CTL, 0xFF, 0x5A},
|
||||
{WCD9335_HPH_L_TEST, 0x01, 0x01},
|
||||
{WCD9335_HPH_R_TEST, 0x01, 0x01},
|
||||
{WCD9335_FLYBACK_VNEG_DAC_CTRL_2, 0xE0, 0x20},
|
||||
{WCD9335_CDC_BOOST0_BOOST_CFG1, 0x3F, 0x12},
|
||||
{WCD9335_CDC_BOOST0_BOOST_CFG2, 0x1C, 0x08},
|
||||
{WCD9335_CDC_COMPANDER7_CTL7, 0x1E, 0x18},
|
||||
|
@ -11004,6 +11163,8 @@ static const struct tasha_reg_mask_val tasha_codec_reg_init_val_2_0[] = {
|
|||
{WCD9335_CDC_COMPANDER8_CTL7, 0x1E, 0x18},
|
||||
{WCD9335_CDC_TX0_TX_PATH_SEC7, 0xFF, 0x45},
|
||||
{WCD9335_CDC_RX0_RX_PATH_SEC0, 0xFC, 0xF4},
|
||||
{WCD9335_HPH_REFBUFF_LP_CTL, 0x08, 0x08},
|
||||
{WCD9335_HPH_REFBUFF_LP_CTL, 0x06, 0x02},
|
||||
};
|
||||
|
||||
static const struct tasha_reg_mask_val tasha_codec_reg_defaults[] = {
|
||||
|
|
|
@ -660,13 +660,13 @@ static void wcd_clsh_state_hph_r(struct snd_soc_codec *codec,
|
|||
0x40, 0x40);
|
||||
}
|
||||
wcd_clsh_set_buck_regulator_mode(codec, mode);
|
||||
wcd_clsh_set_buck_mode(codec, mode);
|
||||
wcd_clsh_set_flyback_mode(codec, mode);
|
||||
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
|
||||
wcd_clsh_set_flyback_current(codec, mode);
|
||||
wcd_clsh_set_buck_mode(codec, mode);
|
||||
wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
|
||||
wcd_clsh_set_gain_path(codec, mode);
|
||||
wcd_clsh_set_hph_mode(codec, mode);
|
||||
wcd_clsh_set_gain_path(codec, mode);
|
||||
} else {
|
||||
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
|
||||
|
||||
|
@ -714,13 +714,13 @@ static void wcd_clsh_state_hph_l(struct snd_soc_codec *codec,
|
|||
0x40, 0x40);
|
||||
}
|
||||
wcd_clsh_set_buck_regulator_mode(codec, mode);
|
||||
wcd_clsh_set_buck_mode(codec, mode);
|
||||
wcd_clsh_set_flyback_mode(codec, mode);
|
||||
wcd_clsh_flyback_ctrl(codec, clsh_d, mode, true);
|
||||
wcd_clsh_set_flyback_current(codec, mode);
|
||||
wcd_clsh_set_buck_mode(codec, mode);
|
||||
wcd_clsh_buck_ctrl(codec, clsh_d, mode, true);
|
||||
wcd_clsh_set_gain_path(codec, mode);
|
||||
wcd_clsh_set_hph_mode(codec, mode);
|
||||
wcd_clsh_set_gain_path(codec, mode);
|
||||
} else {
|
||||
wcd_clsh_set_hph_mode(codec, CLS_H_NORMAL);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue