Explorar el Código

asoc: wcd938x: Fix swr get logical addr fail during SSR

During SSR, sometimes swr get logical addr fails.
Add sufficient delay after reset and retry logic
for get logical addr.

Change-Id: I2a932e99896e0055f3b35f9b251008612f43b79f
Signed-off-by: Laxminath Kasam <[email protected]>
Laxminath Kasam hace 5 años
padre
commit
9a37b81cd4
Se han modificado 1 ficheros con 17 adiciones y 8 borrados
  1. 17 8
      asoc/codecs/wcd938x/wcd938x.c

+ 17 - 8
asoc/codecs/wcd938x/wcd938x.c

@@ -41,6 +41,8 @@
 #define ADC_MODE_VAL_ULP1     0x09
 #define ADC_MODE_VAL_ULP2     0x0B
 
+#define NUM_ATTEMPTS 5
+
 enum {
 	CODEC_TX = 0,
 	CODEC_RX,
@@ -1842,15 +1844,18 @@ static int wcd938x_get_logical_addr(struct swr_device *swr_dev)
 {
 	int ret = 0;
 	uint8_t devnum = 0;
+	int num_retry = NUM_ATTEMPTS;
 
-	ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
-	if (ret) {
-		dev_err(&swr_dev->dev,
-			"%s get devnum %d for dev addr %lx failed\n",
-			__func__, devnum, swr_dev->addr);
-		swr_remove_device(swr_dev);
-		return ret;
-	}
+	do {
+		ret = swr_get_logical_dev_num(swr_dev, swr_dev->addr, &devnum);
+		if (ret) {
+			dev_err(&swr_dev->dev,
+				"%s get devnum %d for dev addr %lx failed\n",
+				__func__, devnum, swr_dev->addr);
+			/* retry after 1ms */
+			usleep_range(1000, 1010);
+		}
+	} while (ret && --num_retry);
 	swr_dev->dev_num = devnum;
 	return 0;
 }
@@ -1904,8 +1909,12 @@ static int wcd938x_event_notify(struct notifier_block *block,
 		break;
 	case BOLERO_WCD_EVT_SSR_UP:
 		wcd938x_reset(wcd938x->dev);
+		/* allow reset to take effect */
+		usleep_range(10000, 10010);
+
 		wcd938x_get_logical_addr(wcd938x->tx_swr_dev);
 		wcd938x_get_logical_addr(wcd938x->rx_swr_dev);
+
 		wcd938x_init_reg(component);
 		regcache_mark_dirty(wcd938x->regmap);
 		regcache_sync(wcd938x->regmap);