OSDN Git Service

ASoC: wcd9335: Add support to enable low power mode on codec
authorSudheer Papothi <spapothi@codeaurora.org>
Thu, 12 May 2016 18:46:56 +0000 (00:16 +0530)
committerGerrit - the friendly Code Review server <code-review@localhost>
Wed, 3 Aug 2016 05:41:41 +0000 (22:41 -0700)
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>
sound/soc/codecs/wcd9335.c
sound/soc/codecs/wcd9335.h

index 8b3fb49..ea16bdf 100755 (executable)
@@ -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)
index 67280c5..8d38399 100644 (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);