diff options
Diffstat (limited to 'sound/soc')
-rw-r--r-- | sound/soc/soc-dapm.c | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 9273216f22fc..1dbc5f8cdc98 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c | |||
@@ -409,6 +409,12 @@ static inline void soc_widget_unlock(struct snd_soc_dapm_widget *w) | |||
409 | mutex_unlock(&w->platform->mutex); | 409 | mutex_unlock(&w->platform->mutex); |
410 | } | 410 | } |
411 | 411 | ||
412 | static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm) | ||
413 | { | ||
414 | if (dapm->codec && dapm->codec->using_regmap) | ||
415 | regmap_async_complete(dapm->codec->control_data); | ||
416 | } | ||
417 | |||
412 | static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, | 418 | static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, |
413 | unsigned short reg, unsigned int mask, unsigned int value) | 419 | unsigned short reg, unsigned int mask, unsigned int value) |
414 | { | 420 | { |
@@ -417,8 +423,9 @@ static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w, | |||
417 | int ret; | 423 | int ret; |
418 | 424 | ||
419 | if (w->codec && w->codec->using_regmap) { | 425 | if (w->codec && w->codec->using_regmap) { |
420 | ret = regmap_update_bits_check(w->codec->control_data, | 426 | ret = regmap_update_bits_check_async(w->codec->control_data, |
421 | reg, mask, value, &change); | 427 | reg, mask, value, |
428 | &change); | ||
422 | if (ret != 0) | 429 | if (ret != 0) |
423 | return ret; | 430 | return ret; |
424 | } else { | 431 | } else { |
@@ -1201,6 +1208,8 @@ int dapm_regulator_event(struct snd_soc_dapm_widget *w, | |||
1201 | { | 1208 | { |
1202 | int ret; | 1209 | int ret; |
1203 | 1210 | ||
1211 | soc_dapm_async_complete(w->dapm); | ||
1212 | |||
1204 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 1213 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
1205 | if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { | 1214 | if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) { |
1206 | ret = regulator_allow_bypass(w->regulator, false); | 1215 | ret = regulator_allow_bypass(w->regulator, false); |
@@ -1234,6 +1243,8 @@ int dapm_clock_event(struct snd_soc_dapm_widget *w, | |||
1234 | if (!w->clk) | 1243 | if (!w->clk) |
1235 | return -EIO; | 1244 | return -EIO; |
1236 | 1245 | ||
1246 | soc_dapm_async_complete(w->dapm); | ||
1247 | |||
1237 | #ifdef CONFIG_HAVE_CLK | 1248 | #ifdef CONFIG_HAVE_CLK |
1238 | if (SND_SOC_DAPM_EVENT_ON(event)) { | 1249 | if (SND_SOC_DAPM_EVENT_ON(event)) { |
1239 | return clk_prepare_enable(w->clk); | 1250 | return clk_prepare_enable(w->clk); |
@@ -1426,6 +1437,7 @@ static void dapm_seq_check_event(struct snd_soc_card *card, | |||
1426 | if (w->event && (w->event_flags & event)) { | 1437 | if (w->event && (w->event_flags & event)) { |
1427 | pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n", | 1438 | pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n", |
1428 | w->name, ev_name); | 1439 | w->name, ev_name); |
1440 | soc_dapm_async_complete(w->dapm); | ||
1429 | trace_snd_soc_dapm_widget_event_start(w, event); | 1441 | trace_snd_soc_dapm_widget_event_start(w, event); |
1430 | ret = w->event(w, NULL, event); | 1442 | ret = w->event(w, NULL, event); |
1431 | trace_snd_soc_dapm_widget_event_done(w, event); | 1443 | trace_snd_soc_dapm_widget_event_done(w, event); |
@@ -1498,6 +1510,7 @@ static void dapm_seq_run(struct snd_soc_card *card, | |||
1498 | struct list_head *list, int event, bool power_up) | 1510 | struct list_head *list, int event, bool power_up) |
1499 | { | 1511 | { |
1500 | struct snd_soc_dapm_widget *w, *n; | 1512 | struct snd_soc_dapm_widget *w, *n; |
1513 | struct snd_soc_dapm_context *d; | ||
1501 | LIST_HEAD(pending); | 1514 | LIST_HEAD(pending); |
1502 | int cur_sort = -1; | 1515 | int cur_sort = -1; |
1503 | int cur_subseq = -1; | 1516 | int cur_subseq = -1; |
@@ -1528,6 +1541,9 @@ static void dapm_seq_run(struct snd_soc_card *card, | |||
1528 | cur_subseq); | 1541 | cur_subseq); |
1529 | } | 1542 | } |
1530 | 1543 | ||
1544 | if (cur_dapm && w->dapm != cur_dapm) | ||
1545 | soc_dapm_async_complete(cur_dapm); | ||
1546 | |||
1531 | INIT_LIST_HEAD(&pending); | 1547 | INIT_LIST_HEAD(&pending); |
1532 | cur_sort = -1; | 1548 | cur_sort = -1; |
1533 | cur_subseq = INT_MIN; | 1549 | cur_subseq = INT_MIN; |
@@ -1586,6 +1602,10 @@ static void dapm_seq_run(struct snd_soc_card *card, | |||
1586 | cur_dapm->seq_notifier(cur_dapm, | 1602 | cur_dapm->seq_notifier(cur_dapm, |
1587 | i, cur_subseq); | 1603 | i, cur_subseq); |
1588 | } | 1604 | } |
1605 | |||
1606 | list_for_each_entry(d, &card->dapm_list, list) { | ||
1607 | soc_dapm_async_complete(d); | ||
1608 | } | ||
1589 | } | 1609 | } |
1590 | 1610 | ||
1591 | static void dapm_widget_update(struct snd_soc_card *card) | 1611 | static void dapm_widget_update(struct snd_soc_card *card) |