diff --git a/asoc/codecs/wcd938x/internal.h b/asoc/codecs/wcd938x/internal.h index 8c2ff0df61..098a60dac8 100644 --- a/asoc/codecs/wcd938x/internal.h +++ b/asoc/codecs/wcd938x/internal.h @@ -99,6 +99,7 @@ struct wcd938x_priv { struct snd_info_entry *variant_entry; int flyback_cur_det_disable; int ear_rx_path; + bool dev_up; }; struct wcd938x_micbias_setting { diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index 4bd37c33f0..2980c3766d 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/asoc/codecs/wcd938x/wcd938x.c @@ -1650,6 +1650,7 @@ int wcd938x_micbias_control(struct snd_soc_component *component, int pre_off_event = 0, post_off_event = 0; int post_on_event = 0, post_dapm_off = 0; int post_dapm_on = 0; + int ret = 0; if ((micb_index < 0) || (micb_index > WCD938X_MAX_MICBIAS - 1)) { dev_err(component->dev, @@ -1691,6 +1692,12 @@ int wcd938x_micbias_control(struct snd_soc_component *component, switch (req) { case MICB_PULLUP_ENABLE: + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } wcd938x->pullup_ref[micb_index]++; if ((wcd938x->pullup_ref[micb_index] == 1) && (wcd938x->micb_ref[micb_index] == 0)) @@ -1700,12 +1707,24 @@ int wcd938x_micbias_control(struct snd_soc_component *component, case MICB_PULLUP_DISABLE: if (wcd938x->pullup_ref[micb_index] > 0) wcd938x->pullup_ref[micb_index]--; + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } if ((wcd938x->pullup_ref[micb_index] == 0) && (wcd938x->micb_ref[micb_index] == 0)) snd_soc_component_update_bits(component, micb_reg, 0xC0, 0x00); break; case MICB_ENABLE: + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } wcd938x->micb_ref[micb_index]++; if (wcd938x->micb_ref[micb_index] == 1) { snd_soc_component_update_bits(component, @@ -1738,6 +1757,12 @@ int wcd938x_micbias_control(struct snd_soc_component *component, case MICB_DISABLE: if (wcd938x->micb_ref[micb_index] > 0) wcd938x->micb_ref[micb_index]--; + if (!wcd938x->dev_up) { + dev_dbg(component->dev, "%s: enable req %d wcd device down\n", + __func__, req); + ret = -ENODEV; + goto done; + } if ((wcd938x->micb_ref[micb_index] == 0) && (wcd938x->pullup_ref[micb_index] > 0)) snd_soc_component_update_bits(component, micb_reg, @@ -1768,9 +1793,10 @@ int wcd938x_micbias_control(struct snd_soc_component *component, "%s: micb_num:%d, micb_ref: %d, pullup_ref: %d\n", __func__, micb_num, wcd938x->micb_ref[micb_index], wcd938x->pullup_ref[micb_index]); - mutex_unlock(&wcd938x->micb_lock); - return 0; +done: + mutex_unlock(&wcd938x->micb_lock); + return ret; } EXPORT_SYMBOL(wcd938x_micbias_control); @@ -1833,6 +1859,7 @@ static int wcd938x_event_notify(struct notifier_block *block, 0x80, 0x00); break; case BOLERO_WCD_EVT_SSR_DOWN: + wcd938x->dev_up = false; mbhc = &wcd938x->mbhc->wcd_mbhc; wcd938x_mbhc_ssr_down(wcd938x->mbhc, component); wcd938x_reset_low(wcd938x->dev); @@ -1853,6 +1880,7 @@ static int wcd938x_event_notify(struct notifier_block *block, } else { wcd938x_mbhc_hs_detect(component, mbhc->mbhc_cfg); } + wcd938x->dev_up = true; break; case BOLERO_WCD_EVT_CLK_NOTIFY: snd_soc_component_update_bits(component, @@ -3008,6 +3036,7 @@ static int wcd938x_soc_codec_probe(struct snd_soc_component *component) return ret; } } + wcd938x->dev_up = true; return ret; err_hwdep: