Loading sound/soc/codecs/wcd9335.c +140 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,12 @@ MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode"); #define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) #define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { "cdc-vdd-mic-bias", }; enum { POWER_COLLAPSE, POWER_RESUME, Loading Loading @@ -772,6 +778,8 @@ struct tasha_priv { struct snd_info_entry *version_entry; int power_active_ref; struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; int (*machine_codec_event_cb)(struct snd_soc_codec *codec, enum wcd9335_codec_event); int spkr_gain_offset; Loading Loading @@ -1280,6 +1288,53 @@ static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, 0xC0, 0x40); } static int tasha_enable_ext_mb_source(struct snd_soc_codec *codec, bool turn_on) { struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); int ret = 0; struct on_demand_supply *supply; if (!tasha) return -EINVAL; supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS]; if (!supply->supply) { dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", __func__, "onDemand Micbias"); return ret; } dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, supply->ondemand_supply_count); if (turn_on) { if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS_REGULATOR"); snd_soc_dapm_sync(&codec->dapm); } supply->ondemand_supply_count++; } else { if (supply->ondemand_supply_count > 0) supply->ondemand_supply_count--; if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS_REGULATOR"); snd_soc_dapm_sync(&codec->dapm); } } if (ret) dev_err(codec->dev, "%s: Failed to %s external micbias source\n", __func__, turn_on ? "enable" : "disabled"); else dev_dbg(codec->dev, "%s: %s external micbias source\n", __func__, turn_on ? "Enabled" : "Disabled"); return ret; } static int tasha_micbias_control(struct snd_soc_codec *codec, int micb_num, int req, bool is_dapm) Loading Loading @@ -1902,6 +1957,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .free_irq = tasha_mbhc_free_irq, .clk_setup = tasha_mbhc_clk_setup, .map_btn_code_to_num = tasha_mbhc_btn_to_num, .enable_mb_source = tasha_enable_ext_mb_source, .mbhc_bias = tasha_mbhc_mbhc_bias_control, .set_btn_thr = tasha_mbhc_program_btn_thr, .lock_sleep = tasha_mbhc_lock_sleep, Loading Loading @@ -4930,6 +4986,57 @@ static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w, return 0; } static int tasha_codec_enable_on_demand_supply( struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { int ret = 0; struct snd_soc_codec *codec = w->codec; struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); struct on_demand_supply *supply; if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { dev_err(codec->dev, "%s: error index > MAX Demand supplies", __func__); ret = -EINVAL; goto out; } dev_dbg(codec->dev, "%s: supply: %s event: %d\n", __func__, on_demand_supply_name[w->shift], event); supply = &tasha->on_demand_list[w->shift]; WARN_ONCE(!supply->supply, "%s isn't defined\n", on_demand_supply_name[w->shift]); if (!supply->supply) { dev_err(codec->dev, "%s: err supply not present ond for %d", __func__, w->shift); goto out; } switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = regulator_enable(supply->supply); if (ret) dev_err(codec->dev, "%s: Failed to enable %s\n", __func__, on_demand_supply_name[w->shift]); break; case SND_SOC_DAPM_POST_PMD: ret = regulator_disable(supply->supply); if (ret) dev_err(codec->dev, "%s: Failed to disable %s\n", __func__, on_demand_supply_name[w->shift]); break; default: break; }; out: return ret; } static int tasha_codec_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n) { Loading Loading @@ -9994,6 +10101,10 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("LINEOUT4"), SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"), SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"), SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM, ON_DEMAND_MICBIAS, 0, tasha_codec_enable_on_demand_supply, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0, 0, &adc_us_mux0_switch), Loading Loading @@ -12206,6 +12317,26 @@ err: return ret; } static struct regulator *tasha_codec_find_ondemand_regulator( struct snd_soc_codec *codec, const char *name) { int i; struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { if (pdata->regulator[i].ondemand && wcd9xxx->supplies[i].supply && !strcmp(wcd9xxx->supplies[i].supply, name)) return wcd9xxx->supplies[i].consumer; } dev_dbg(tasha->dev, "Warning: regulator not found:%s\n", name); return NULL; } static int tasha_codec_probe(struct snd_soc_codec *codec) { struct wcd9xxx *control; Loading @@ -12214,6 +12345,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) struct snd_soc_dapm_context *dapm = &codec->dapm; int i, ret; void *ptr = NULL; struct regulator *supply; control = dev_get_drvdata(codec->dev->parent); Loading Loading @@ -12264,6 +12396,14 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) goto err; } supply = tasha_codec_find_ondemand_regulator(codec, on_demand_supply_name[ON_DEMAND_MICBIAS]); if (supply) { tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply; tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count = 0; } tasha->fw_data = devm_kzalloc(codec->dev, sizeof(*(tasha->fw_data)), GFP_KERNEL); if (!tasha->fw_data) { Loading sound/soc/codecs/wcd9335.h +14 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,20 @@ enum wcd9335_codec_event { WCD9335_CODEC_EVENT_CODEC_UP = 0, }; enum tasha_on_demand_supply { ON_DEMAND_MICBIAS = 0, ON_DEMAND_SUPPLIES_MAX, }; /* structure used to put the defined * ondemand supply for codec * and count being used. */ struct on_demand_supply { struct regulator *supply; int ondemand_supply_count; }; /* Dai data structure holds the * dai specific info like rate, * channel number etc. Loading Loading
sound/soc/codecs/wcd9335.c +140 −0 Original line number Diff line number Diff line Loading @@ -142,6 +142,12 @@ MODULE_PARM_DESC(cpe_debug_mode, "boot cpe in debug mode"); #define TASHA_DIG_CORE_COLLAPSE_TIMER_MS (5 * 1000) #define MAX_ON_DEMAND_SUPPLY_NAME_LENGTH 64 static char on_demand_supply_name[][MAX_ON_DEMAND_SUPPLY_NAME_LENGTH] = { "cdc-vdd-mic-bias", }; enum { POWER_COLLAPSE, POWER_RESUME, Loading Loading @@ -772,6 +778,8 @@ struct tasha_priv { struct snd_info_entry *version_entry; int power_active_ref; struct on_demand_supply on_demand_list[ON_DEMAND_SUPPLIES_MAX]; int (*machine_codec_event_cb)(struct snd_soc_codec *codec, enum wcd9335_codec_event); int spkr_gain_offset; Loading Loading @@ -1280,6 +1288,53 @@ static void tasha_mbhc_hph_l_pull_up_control(struct snd_soc_codec *codec, 0xC0, 0x40); } static int tasha_enable_ext_mb_source(struct snd_soc_codec *codec, bool turn_on) { struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); int ret = 0; struct on_demand_supply *supply; if (!tasha) return -EINVAL; supply = &tasha->on_demand_list[ON_DEMAND_MICBIAS]; if (!supply->supply) { dev_dbg(codec->dev, "%s: warning supply not present ond for %s\n", __func__, "onDemand Micbias"); return ret; } dev_dbg(codec->dev, "%s turn_on: %d count: %d\n", __func__, turn_on, supply->ondemand_supply_count); if (turn_on) { if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS_REGULATOR"); snd_soc_dapm_sync(&codec->dapm); } supply->ondemand_supply_count++; } else { if (supply->ondemand_supply_count > 0) supply->ondemand_supply_count--; if (!(supply->ondemand_supply_count)) { ret = snd_soc_dapm_disable_pin(&codec->dapm, "MICBIAS_REGULATOR"); snd_soc_dapm_sync(&codec->dapm); } } if (ret) dev_err(codec->dev, "%s: Failed to %s external micbias source\n", __func__, turn_on ? "enable" : "disabled"); else dev_dbg(codec->dev, "%s: %s external micbias source\n", __func__, turn_on ? "Enabled" : "Disabled"); return ret; } static int tasha_micbias_control(struct snd_soc_codec *codec, int micb_num, int req, bool is_dapm) Loading Loading @@ -1902,6 +1957,7 @@ static const struct wcd_mbhc_cb mbhc_cb = { .free_irq = tasha_mbhc_free_irq, .clk_setup = tasha_mbhc_clk_setup, .map_btn_code_to_num = tasha_mbhc_btn_to_num, .enable_mb_source = tasha_enable_ext_mb_source, .mbhc_bias = tasha_mbhc_mbhc_bias_control, .set_btn_thr = tasha_mbhc_program_btn_thr, .lock_sleep = tasha_mbhc_lock_sleep, Loading Loading @@ -4930,6 +4986,57 @@ static int tasha_codec_set_iir_gain(struct snd_soc_dapm_widget *w, return 0; } static int tasha_codec_enable_on_demand_supply( struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { int ret = 0; struct snd_soc_codec *codec = w->codec; struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); struct on_demand_supply *supply; if (w->shift >= ON_DEMAND_SUPPLIES_MAX) { dev_err(codec->dev, "%s: error index > MAX Demand supplies", __func__); ret = -EINVAL; goto out; } dev_dbg(codec->dev, "%s: supply: %s event: %d\n", __func__, on_demand_supply_name[w->shift], event); supply = &tasha->on_demand_list[w->shift]; WARN_ONCE(!supply->supply, "%s isn't defined\n", on_demand_supply_name[w->shift]); if (!supply->supply) { dev_err(codec->dev, "%s: err supply not present ond for %d", __func__, w->shift); goto out; } switch (event) { case SND_SOC_DAPM_PRE_PMU: ret = regulator_enable(supply->supply); if (ret) dev_err(codec->dev, "%s: Failed to enable %s\n", __func__, on_demand_supply_name[w->shift]); break; case SND_SOC_DAPM_POST_PMD: ret = regulator_disable(supply->supply); if (ret) dev_err(codec->dev, "%s: Failed to disable %s\n", __func__, on_demand_supply_name[w->shift]); break; default: break; }; out: return ret; } static int tasha_codec_find_amic_input(struct snd_soc_codec *codec, int adc_mux_n) { Loading Loading @@ -9994,6 +10101,10 @@ static const struct snd_soc_dapm_widget tasha_dapm_widgets[] = { SND_SOC_DAPM_OUTPUT("LINEOUT4"), SND_SOC_DAPM_OUTPUT("ANC LINEOUT1"), SND_SOC_DAPM_OUTPUT("ANC LINEOUT2"), SND_SOC_DAPM_SUPPLY("MICBIAS_REGULATOR", SND_SOC_NOPM, ON_DEMAND_MICBIAS, 0, tasha_codec_enable_on_demand_supply, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SWITCH("ADC US MUX0", WCD9335_CDC_TX0_TX_PATH_192_CTL, 0, 0, &adc_us_mux0_switch), Loading Loading @@ -12206,6 +12317,26 @@ err: return ret; } static struct regulator *tasha_codec_find_ondemand_regulator( struct snd_soc_codec *codec, const char *name) { int i; struct tasha_priv *tasha = snd_soc_codec_get_drvdata(codec); struct wcd9xxx *wcd9xxx = tasha->wcd9xxx; struct wcd9xxx_pdata *pdata = dev_get_platdata(codec->dev->parent); for (i = 0; i < wcd9xxx->num_of_supplies; ++i) { if (pdata->regulator[i].ondemand && wcd9xxx->supplies[i].supply && !strcmp(wcd9xxx->supplies[i].supply, name)) return wcd9xxx->supplies[i].consumer; } dev_dbg(tasha->dev, "Warning: regulator not found:%s\n", name); return NULL; } static int tasha_codec_probe(struct snd_soc_codec *codec) { struct wcd9xxx *control; Loading @@ -12214,6 +12345,7 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) struct snd_soc_dapm_context *dapm = &codec->dapm; int i, ret; void *ptr = NULL; struct regulator *supply; control = dev_get_drvdata(codec->dev->parent); Loading Loading @@ -12264,6 +12396,14 @@ static int tasha_codec_probe(struct snd_soc_codec *codec) goto err; } supply = tasha_codec_find_ondemand_regulator(codec, on_demand_supply_name[ON_DEMAND_MICBIAS]); if (supply) { tasha->on_demand_list[ON_DEMAND_MICBIAS].supply = supply; tasha->on_demand_list[ON_DEMAND_MICBIAS].ondemand_supply_count = 0; } tasha->fw_data = devm_kzalloc(codec->dev, sizeof(*(tasha->fw_data)), GFP_KERNEL); if (!tasha->fw_data) { Loading
sound/soc/codecs/wcd9335.h +14 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,20 @@ enum wcd9335_codec_event { WCD9335_CODEC_EVENT_CODEC_UP = 0, }; enum tasha_on_demand_supply { ON_DEMAND_MICBIAS = 0, ON_DEMAND_SUPPLIES_MAX, }; /* structure used to put the defined * ondemand supply for codec * and count being used. */ struct on_demand_supply { struct regulator *supply; int ondemand_supply_count; }; /* Dai data structure holds the * dai specific info like rate, * channel number etc. Loading