mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-10-31 18:09:19 +00:00
ASoC: wcd9335: Add support for various headphone modes
WCD9335 codec version 2.0 supports multiple headphone modes namely LOHIFI, LOWPWR for audio playback. Add support to configure codec registers for these modes in version 2.0. Change-Id: I62eb409868795ea3913f6e967429b76f45cde2f9 Signed-off-by: Phani Kumar Uppalapati <phaniu@codeaurora.org>
This commit is contained in:
parent
0dcd2def74
commit
97cc2dc6d0
3 changed files with 103 additions and 7 deletions
|
@ -3311,6 +3311,75 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x02);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x06);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2,
|
||||||
|
0xF0, 0x40);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||||
|
snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDACBUFF_CNP2, 0x8A);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_PA, 0x0F, 0x0A);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x06);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)) {
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x0C);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x08);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x04);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x20);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x07,
|
||||||
|
0x01);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x70,
|
||||||
|
0x10);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
|
||||||
|
0x0F, 0x01);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO,
|
||||||
|
0xF0, 0x10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SND_SOC_DAPM_EVENT_OFF(event)) {
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_R_EN, 0xC0, 0x80);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_L_EN, 0xC0, 0x80);
|
||||||
|
snd_soc_write(codec, WCD9335_RX_BIAS_HPH_RDAC_LDO, 0x88);
|
||||||
|
snd_soc_write(codec, WCD9335_HPH_RDAC_LDO_CTL, 0x33);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x20, 0x00);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x04, 0x00);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL2, 0x08, 0x00);
|
||||||
|
snd_soc_update_bits(codec, WCD9335_HPH_PA_CTL1, 0x0E, 0x06);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tasha_codec_hph_mode_config(struct snd_soc_codec *codec,
|
||||||
|
int event, int mode)
|
||||||
|
{
|
||||||
|
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
|
||||||
|
|
||||||
|
if (!TASHA_IS_2_0(tasha->wcd9xxx->version))
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case CLS_H_LP:
|
||||||
|
tasha_codec_hph_lp_config(codec, tasha, event);
|
||||||
|
break;
|
||||||
|
case CLS_H_LOHIFI:
|
||||||
|
tasha_codec_hph_lohifi_config(codec, tasha, event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
struct snd_kcontrol *kcontrol,
|
struct snd_kcontrol *kcontrol,
|
||||||
int event)
|
int event)
|
||||||
|
@ -3333,7 +3402,7 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
/* Read DEM INP Select */
|
/* Read DEM INP Select */
|
||||||
dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) &
|
dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) &
|
||||||
0x03;
|
0x03;
|
||||||
if (((hph_mode == CLS_H_HIFI) ||
|
if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
|
||||||
(hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
|
(hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
|
||||||
dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
|
dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
|
||||||
__func__, hph_mode);
|
__func__, hph_mode);
|
||||||
|
@ -3342,7 +3411,11 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
||||||
WCD_CLSH_EVENT_PRE_DAC,
|
WCD_CLSH_EVENT_PRE_DAC,
|
||||||
WCD_CLSH_STATE_HPHR,
|
WCD_CLSH_STATE_HPHR,
|
||||||
hph_mode);
|
((hph_mode == CLS_H_LOHIFI) ?
|
||||||
|
CLS_H_HIFI : hph_mode));
|
||||||
|
|
||||||
|
tasha_codec_hph_mode_config(codec, event, hph_mode);
|
||||||
|
|
||||||
if (tasha->anc_func)
|
if (tasha->anc_func)
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_update_bits(codec,
|
||||||
WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10);
|
WCD9335_CDC_RX2_RX_PATH_CFG0, 0x10, 0x10);
|
||||||
|
@ -3367,10 +3440,16 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
/* 1000us required as per HW requirement */
|
/* 1000us required as per HW requirement */
|
||||||
usleep_range(1000, 1100);
|
usleep_range(1000, 1100);
|
||||||
|
|
||||||
|
if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
|
||||||
|
WCD_CLSH_STATE_HPHL))
|
||||||
|
tasha_codec_hph_mode_config(codec, event, hph_mode);
|
||||||
|
|
||||||
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
||||||
WCD_CLSH_EVENT_POST_PA,
|
WCD_CLSH_EVENT_POST_PA,
|
||||||
WCD_CLSH_STATE_HPHR,
|
WCD_CLSH_STATE_HPHR,
|
||||||
hph_mode);
|
((hph_mode == CLS_H_LOHIFI) ?
|
||||||
|
CLS_H_HIFI : hph_mode));
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -3399,7 +3478,7 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
/* Read DEM INP Select */
|
/* Read DEM INP Select */
|
||||||
dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) &
|
dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) &
|
||||||
0x03;
|
0x03;
|
||||||
if (((hph_mode == CLS_H_HIFI) ||
|
if (((hph_mode == CLS_H_HIFI) || (hph_mode == CLS_H_LOHIFI) ||
|
||||||
(hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
|
(hph_mode == CLS_H_LP)) && (dem_inp != 0x01)) {
|
||||||
dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
|
dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
|
||||||
__func__, hph_mode);
|
__func__, hph_mode);
|
||||||
|
@ -3408,7 +3487,11 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
||||||
WCD_CLSH_EVENT_PRE_DAC,
|
WCD_CLSH_EVENT_PRE_DAC,
|
||||||
WCD_CLSH_STATE_HPHL,
|
WCD_CLSH_STATE_HPHL,
|
||||||
hph_mode);
|
((hph_mode == CLS_H_LOHIFI) ?
|
||||||
|
CLS_H_HIFI : hph_mode));
|
||||||
|
|
||||||
|
tasha_codec_hph_mode_config(codec, event, hph_mode);
|
||||||
|
|
||||||
if (tasha->anc_func)
|
if (tasha->anc_func)
|
||||||
snd_soc_update_bits(codec,
|
snd_soc_update_bits(codec,
|
||||||
WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
|
WCD9335_CDC_RX1_RX_PATH_CFG0, 0x10, 0x10);
|
||||||
|
@ -3433,10 +3516,15 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
|
||||||
case SND_SOC_DAPM_POST_PMD:
|
case SND_SOC_DAPM_POST_PMD:
|
||||||
/* 1000us required as per HW requirement */
|
/* 1000us required as per HW requirement */
|
||||||
usleep_range(1000, 1100);
|
usleep_range(1000, 1100);
|
||||||
|
|
||||||
|
if (!(wcd_clsh_get_clsh_state(&tasha->clsh_d) &
|
||||||
|
WCD_CLSH_STATE_HPHR))
|
||||||
|
tasha_codec_hph_mode_config(codec, event, hph_mode);
|
||||||
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
wcd_clsh_fsm(codec, &tasha->clsh_d,
|
||||||
WCD_CLSH_EVENT_POST_PA,
|
WCD_CLSH_EVENT_POST_PA,
|
||||||
WCD_CLSH_STATE_HPHL,
|
WCD_CLSH_STATE_HPHL,
|
||||||
hph_mode);
|
((hph_mode == CLS_H_LOHIFI) ?
|
||||||
|
CLS_H_HIFI : hph_mode));
|
||||||
break;
|
break;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6448,7 +6536,7 @@ static int tasha_codec_vbat_enable_event(struct snd_soc_dapm_widget *w,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const rx_hph_mode_mux_text[] = {
|
static const char * const rx_hph_mode_mux_text[] = {
|
||||||
"CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB"
|
"CLS_H_INVALID", "CLS_H_HIFI", "CLS_H_LP", "CLS_AB", "CLS_H_LOHIFI"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct soc_enum rx_hph_mode_mux_enum =
|
static const struct soc_enum rx_hph_mode_mux_enum =
|
||||||
|
|
|
@ -847,6 +847,12 @@ void wcd_clsh_fsm(struct snd_soc_codec *codec,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh)
|
||||||
|
{
|
||||||
|
return clsh->state;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(wcd_clsh_get_clsh_state);
|
||||||
|
|
||||||
void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh)
|
void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
|
@ -62,6 +62,7 @@ enum {
|
||||||
CLS_H_HIFI, /* Class-H HiFi */
|
CLS_H_HIFI, /* Class-H HiFi */
|
||||||
CLS_H_LP, /* Class-H Low Power */
|
CLS_H_LP, /* Class-H Low Power */
|
||||||
CLS_AB, /* Class-AB */
|
CLS_AB, /* Class-AB */
|
||||||
|
CLS_H_LOHIFI, /* LoHIFI */
|
||||||
CLS_NONE, /* None of the above modes */
|
CLS_NONE, /* None of the above modes */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -141,6 +142,7 @@ extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
|
||||||
int int_mode);
|
int int_mode);
|
||||||
|
|
||||||
extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh);
|
extern void wcd_clsh_init(struct wcd_clsh_cdc_data *clsh);
|
||||||
|
extern int wcd_clsh_get_clsh_state(struct wcd_clsh_cdc_data *clsh);
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
RESERVED = 0,
|
RESERVED = 0,
|
||||||
|
|
Loading…
Reference in a new issue