Browse Source

asoc: codecs: wcd938x: check for device up before writes

During SSR, codec device will be down and wait till
receiving up notification before doing any register
reads or writes.

Change-Id: I0e2967990bfc9d0d780d4c7e666a4c31159e70ce
Signed-off-by: Karthikeyan Mani <[email protected]>
Karthikeyan Mani 5 years ago
parent
commit
7af16b8364
2 changed files with 32 additions and 2 deletions
  1. 1 0
      asoc/codecs/wcd938x/internal.h
  2. 31 2
      asoc/codecs/wcd938x/wcd938x.c

+ 1 - 0
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 {

+ 31 - 2
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: