diff --git a/sound/soc/codecs/wcd9335.c b/sound/soc/codecs/wcd9335.c index 8b3fb4912e44..ea16bdf05baf 100755 --- a/sound/soc/codecs/wcd9335.c +++ b/sound/soc/codecs/wcd9335.c @@ -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) diff --git a/sound/soc/codecs/wcd9335.h b/sound/soc/codecs/wcd9335.h index 67280c583b2a..8d38399ba92f 100644 --- a/sound/soc/codecs/wcd9335.h +++ b/sound/soc/codecs/wcd9335.h @@ -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);