ASoC: wcd9335: Add support to enable low power mode on codec

Codec is in digital core power collapse when there is no
audio usecase but low power audio usecases needs codec to
be out of power collapse. Changes bring codec out of
digital core power collapse for low power audio usecases
without enabling master clock.

CRs-fixed: 1022917
Change-Id: I762fc1dc6b6527608e73ac5144215ee141570aac
Signed-off-by: Sudheer Papothi <spapothi@codeaurora.org>
Signed-off-by: Vidyakumar Athota <vathota@codeaurora.org>
This commit is contained in:
Sudheer Papothi 2016-05-13 00:16:56 +05:30 committed by Gerrit - the friendly Code Review server
parent b435be5346
commit b9b48e3ff3
2 changed files with 74 additions and 0 deletions

View file

@ -588,6 +588,8 @@ static int wcd9335_get_micb_vout_ctl_val(u32 micb_mv);
static int tasha_config_compander(struct snd_soc_codec *, int, int);
static void tasha_codec_set_tx_hold(struct snd_soc_codec *, u16, bool);
static int tasha_codec_internal_rco_ctrl(struct snd_soc_codec *codec,
bool enable);
/* Hold instance to soundwire platform device */
struct tasha_swr_ctrl_data {
@ -841,6 +843,8 @@ struct tasha_priv {
int hph_r_gain;
int rx_7_count;
int rx_8_count;
bool clk_mode;
bool clk_internal;
};
static int tasha_codec_vote_max_bw(struct snd_soc_codec *codec,
@ -2290,6 +2294,30 @@ static int tasha_put_anc_func(struct snd_kcontrol *kcontrol,
return 0;
}
static int tasha_get_clkmode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
ucontrol->value.enumerated.item[0] = tasha->clk_mode;
dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
return 0;
}
static int tasha_put_clkmode(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol);
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
tasha->clk_mode = ucontrol->value.enumerated.item[0];
dev_dbg(codec->dev, "%s: clk_mode: %d\n", __func__, tasha->clk_mode);
return 0;
}
static int tasha_get_iir_enable_audio_mixer(
struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
@ -6083,6 +6111,9 @@ static const char *const tasha_anc_func_text[] = {"OFF", "ON"};
static const struct soc_enum tasha_anc_func_enum =
SOC_ENUM_SINGLE_EXT(2, tasha_anc_func_text);
static const char *const tasha_clkmode_text[] = {"EXTERNAL", "INTERNAL"};
static SOC_ENUM_SINGLE_EXT_DECL(tasha_clkmode_enum, tasha_clkmode_text);
/* Cutoff frequency for high pass filter */
static const char * const cf_text[] = {
"CF_NEG_3DB_4HZ", "CF_NEG_3DB_75HZ", "CF_NEG_3DB_150HZ"
@ -8211,6 +8242,9 @@ static const struct snd_kcontrol_new tasha_snd_controls[] = {
SOC_ENUM_EXT("ANC Function", tasha_anc_func_enum, tasha_get_anc_func,
tasha_put_anc_func),
SOC_ENUM_EXT("CLK MODE", tasha_clkmode_enum, tasha_get_clkmode,
tasha_put_clkmode),
SOC_ENUM("TX0 HPF cut off", cf_dec0_enum),
SOC_ENUM("TX1 HPF cut off", cf_dec1_enum),
SOC_ENUM("TX2 HPF cut off", cf_dec2_enum),
@ -11749,6 +11783,44 @@ int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable, bool dapm)
}
EXPORT_SYMBOL(tasha_cdc_mclk_enable);
int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable, bool dapm)
{
struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec);
int ret = 0;
dev_dbg(tasha->dev, "%s: clk_mode: %d, enable: %d, clk_internal: %d\n",
__func__, tasha->clk_mode, enable, tasha->clk_internal);
if (tasha->clk_mode || tasha->clk_internal) {
if (enable) {
tasha_cdc_sido_ccl_enable(tasha, true);
wcd_resmgr_enable_master_bias(tasha->resmgr);
tasha_dig_core_power_collapse(tasha, POWER_RESUME);
snd_soc_update_bits(codec,
WCD9335_CDC_CLK_RST_CTRL_FS_CNT_CONTROL,
0x01, 0x01);
snd_soc_update_bits(codec,
WCD9335_CDC_CLK_RST_CTRL_MCLK_CONTROL,
0x01, 0x01);
set_bit(CPE_NOMINAL, &tasha->status_mask);
tasha_codec_update_sido_voltage(tasha,
SIDO_VOLTAGE_NOMINAL_MV);
tasha->clk_internal = true;
} else {
tasha->clk_internal = false;
clear_bit(CPE_NOMINAL, &tasha->status_mask);
tasha_codec_update_sido_voltage(tasha,
sido_buck_svs_voltage);
tasha_dig_core_power_collapse(tasha, POWER_COLLAPSE);
wcd_resmgr_disable_master_bias(tasha->resmgr);
tasha_cdc_sido_ccl_enable(tasha, false);
}
} else {
ret = __tasha_cdc_mclk_enable(tasha, enable);
}
return ret;
}
EXPORT_SYMBOL(tasha_cdc_mclk_tx_enable);
static ssize_t tasha_codec_version_read(struct snd_info_entry *entry,
void *file_private_data, struct file *file,
char __user *buf, size_t count, loff_t pos)

View file

@ -179,6 +179,8 @@ extern void *tasha_get_afe_config(struct snd_soc_codec *codec,
enum afe_config_type config_type);
extern int tasha_cdc_mclk_enable(struct snd_soc_codec *codec, int enable,
bool dapm);
extern int tasha_cdc_mclk_tx_enable(struct snd_soc_codec *codec, int enable,
bool dapm);
extern int tasha_enable_efuse_sensing(struct snd_soc_codec *codec);
extern int tasha_mbhc_hs_detect(struct snd_soc_codec *codec,
struct wcd_mbhc_config *mbhc_cfg);