Merge "ASoC: wcd9335: Add support for various headphone modes"

This commit is contained in:
Linux Build Service Account 2015-10-20 04:37:33 -07:00 committed by Gerrit - the friendly Code Review server
commit 21b9d82b5d
3 changed files with 103 additions and 7 deletions

View file

@ -3311,6 +3311,75 @@ static int tasha_codec_enable_ear_pa(struct snd_soc_dapm_widget *w,
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,
struct snd_kcontrol *kcontrol,
int event)
@ -3333,7 +3402,7 @@ static int tasha_codec_hphr_dac_event(struct snd_soc_dapm_widget *w,
/* Read DEM INP Select */
dem_inp = snd_soc_read(codec, WCD9335_CDC_RX2_RX_PATH_SEC0) &
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)) {
dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
__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_EVENT_PRE_DAC,
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)
snd_soc_update_bits(codec,
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:
/* 1000us required as per HW requirement */
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_EVENT_POST_PA,
WCD_CLSH_STATE_HPHR,
hph_mode);
((hph_mode == CLS_H_LOHIFI) ?
CLS_H_HIFI : hph_mode));
break;
};
@ -3399,7 +3478,7 @@ static int tasha_codec_hphl_dac_event(struct snd_soc_dapm_widget *w,
/* Read DEM INP Select */
dem_inp = snd_soc_read(codec, WCD9335_CDC_RX1_RX_PATH_SEC0) &
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)) {
dev_err(codec->dev, "%s: DEM Input not set correctly, hph_mode: %d\n",
__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_EVENT_PRE_DAC,
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)
snd_soc_update_bits(codec,
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:
/* 1000us required as per HW requirement */
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_EVENT_POST_PA,
WCD_CLSH_STATE_HPHL,
hph_mode);
((hph_mode == CLS_H_LOHIFI) ?
CLS_H_HIFI : hph_mode));
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[] = {
"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 =

View file

@ -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)
{
int i;

View file

@ -62,6 +62,7 @@ enum {
CLS_H_HIFI, /* Class-H HiFi */
CLS_H_LP, /* Class-H Low Power */
CLS_AB, /* Class-AB */
CLS_H_LOHIFI, /* LoHIFI */
CLS_NONE, /* None of the above modes */
};
@ -141,6 +142,7 @@ extern void wcd_clsh_fsm(struct snd_soc_codec *codec,
int int_mode);
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 {
RESERVED = 0,