diff --git a/asoc/codecs/wcd938x/wcd938x.c b/asoc/codecs/wcd938x/wcd938x.c index ae88d7ce5386..3db8fc5a9733 100644 --- a/asoc/codecs/wcd938x/wcd938x.c +++ b/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);