Merge remote-tracking branch 'asoc/fix/arizona' into asoc-linus
authorMark Brown <broonie@linaro.org>
Fri, 15 Nov 2013 10:20:00 +0000 (10:20 +0000)
committerMark Brown <broonie@linaro.org>
Fri, 15 Nov 2013 10:20:00 +0000 (10:20 +0000)
1  2 
sound/soc/soc-dapm.c

diff --combined sound/soc/soc-dapm.c
index b2949aed1ac2e9bfd374dff8b0a2483ecf19ddf4,2fb0b72d8a3c00c7d6266df72b68487a06f31877..cc36caaf6443619cd2ea8b71eee706cf72ec5f68
@@@ -59,31 -59,31 +59,31 @@@ snd_soc_dapm_new_control(struct snd_soc
  /* dapm power sequences - make this per codec in the future */
  static int dapm_up_seq[] = {
        [snd_soc_dapm_pre] = 0,
-       [snd_soc_dapm_supply] = 1,
        [snd_soc_dapm_regulator_supply] = 1,
        [snd_soc_dapm_clock_supply] = 1,
-       [snd_soc_dapm_micbias] = 2,
+       [snd_soc_dapm_supply] = 2,
+       [snd_soc_dapm_micbias] = 3,
        [snd_soc_dapm_dai_link] = 2,
-       [snd_soc_dapm_dai_in] = 3,
-       [snd_soc_dapm_dai_out] = 3,
-       [snd_soc_dapm_aif_in] = 3,
-       [snd_soc_dapm_aif_out] = 3,
-       [snd_soc_dapm_mic] = 4,
-       [snd_soc_dapm_mux] = 5,
-       [snd_soc_dapm_virt_mux] = 5,
-       [snd_soc_dapm_value_mux] = 5,
-       [snd_soc_dapm_dac] = 6,
-       [snd_soc_dapm_switch] = 7,
-       [snd_soc_dapm_mixer] = 7,
-       [snd_soc_dapm_mixer_named_ctl] = 7,
-       [snd_soc_dapm_pga] = 8,
-       [snd_soc_dapm_adc] = 9,
-       [snd_soc_dapm_out_drv] = 10,
-       [snd_soc_dapm_hp] = 10,
-       [snd_soc_dapm_spk] = 10,
-       [snd_soc_dapm_line] = 10,
-       [snd_soc_dapm_kcontrol] = 11,
-       [snd_soc_dapm_post] = 12,
+       [snd_soc_dapm_dai_in] = 4,
+       [snd_soc_dapm_dai_out] = 4,
+       [snd_soc_dapm_aif_in] = 4,
+       [snd_soc_dapm_aif_out] = 4,
+       [snd_soc_dapm_mic] = 5,
+       [snd_soc_dapm_mux] = 6,
+       [snd_soc_dapm_virt_mux] = 6,
+       [snd_soc_dapm_value_mux] = 6,
+       [snd_soc_dapm_dac] = 7,
+       [snd_soc_dapm_switch] = 8,
+       [snd_soc_dapm_mixer] = 8,
+       [snd_soc_dapm_mixer_named_ctl] = 8,
+       [snd_soc_dapm_pga] = 9,
+       [snd_soc_dapm_adc] = 10,
+       [snd_soc_dapm_out_drv] = 11,
+       [snd_soc_dapm_hp] = 11,
+       [snd_soc_dapm_spk] = 11,
+       [snd_soc_dapm_line] = 11,
+       [snd_soc_dapm_kcontrol] = 12,
+       [snd_soc_dapm_post] = 13,
  };
  
  static int dapm_down_seq[] = {
        [snd_soc_dapm_dai_in] = 10,
        [snd_soc_dapm_dai_out] = 10,
        [snd_soc_dapm_dai_link] = 11,
-       [snd_soc_dapm_clock_supply] = 12,
-       [snd_soc_dapm_regulator_supply] = 12,
        [snd_soc_dapm_supply] = 12,
-       [snd_soc_dapm_post] = 13,
+       [snd_soc_dapm_clock_supply] = 13,
+       [snd_soc_dapm_regulator_supply] = 13,
+       [snd_soc_dapm_post] = 14,
  };
  
  static void pop_wait(u32 pop_time)
@@@ -409,6 -409,12 +409,12 @@@ static inline void soc_widget_unlock(st
                mutex_unlock(&w->platform->mutex);
  }
  
+ static void soc_dapm_async_complete(struct snd_soc_dapm_context *dapm)
+ {
+       if (dapm->codec && dapm->codec->using_regmap)
+               regmap_async_complete(dapm->codec->control_data);
+ }
  static int soc_widget_update_bits_locked(struct snd_soc_dapm_widget *w,
        unsigned short reg, unsigned int mask, unsigned int value)
  {
        int ret;
  
        if (w->codec && w->codec->using_regmap) {
-               ret = regmap_update_bits_check(w->codec->control_data,
-                                              reg, mask, value, &change);
+               ret = regmap_update_bits_check_async(w->codec->control_data,
+                                                    reg, mask, value,
+                                                    &change);
                if (ret != 0)
                        return ret;
        } else {
@@@ -499,18 -506,22 +506,22 @@@ static void dapm_set_path_status(struc
                int val;
                struct soc_mixer_control *mc = (struct soc_mixer_control *)
                        w->kcontrol_news[i].private_value;
-               unsigned int reg = mc->reg;
+               int reg = mc->reg;
                unsigned int shift = mc->shift;
                int max = mc->max;
                unsigned int mask = (1 << fls(max)) - 1;
                unsigned int invert = mc->invert;
  
-               val = soc_widget_read(w, reg);
-               val = (val >> shift) & mask;
-               if (invert)
-                       val = max - val;
+               if (reg != SND_SOC_NOPM) {
+                       val = soc_widget_read(w, reg);
+                       val = (val >> shift) & mask;
+                       if (invert)
+                               val = max - val;
+                       p->connect = !!val;
+               } else {
+                       p->connect = 0;
+               }
  
-               p->connect = !!val;
        }
        break;
        case snd_soc_dapm_mux: {
@@@ -1197,6 -1208,8 +1208,8 @@@ int dapm_regulator_event(struct snd_soc
  {
        int ret;
  
+       soc_dapm_async_complete(w->dapm);
        if (SND_SOC_DAPM_EVENT_ON(event)) {
                if (w->on_val & SND_SOC_DAPM_REGULATOR_BYPASS) {
                        ret = regulator_allow_bypass(w->regulator, false);
@@@ -1230,6 -1243,8 +1243,8 @@@ int dapm_clock_event(struct snd_soc_dap
        if (!w->clk)
                return -EIO;
  
+       soc_dapm_async_complete(w->dapm);
  #ifdef CONFIG_HAVE_CLK
        if (SND_SOC_DAPM_EVENT_ON(event)) {
                return clk_prepare_enable(w->clk);
@@@ -1422,6 -1437,7 +1437,7 @@@ static void dapm_seq_check_event(struc
        if (w->event && (w->event_flags & event)) {
                pop_dbg(w->dapm->dev, card->pop_time, "pop test : %s %s\n",
                        w->name, ev_name);
+               soc_dapm_async_complete(w->dapm);
                trace_snd_soc_dapm_widget_event_start(w, event);
                ret = w->event(w, NULL, event);
                trace_snd_soc_dapm_widget_event_done(w, event);
@@@ -1494,6 -1510,7 +1510,7 @@@ static void dapm_seq_run(struct snd_soc
        struct list_head *list, int event, bool power_up)
  {
        struct snd_soc_dapm_widget *w, *n;
+       struct snd_soc_dapm_context *d;
        LIST_HEAD(pending);
        int cur_sort = -1;
        int cur_subseq = -1;
                                                                       cur_subseq);
                        }
  
+                       if (cur_dapm && w->dapm != cur_dapm)
+                               soc_dapm_async_complete(cur_dapm);
                        INIT_LIST_HEAD(&pending);
                        cur_sort = -1;
                        cur_subseq = INT_MIN;
                                cur_dapm->seq_notifier(cur_dapm,
                                                       i, cur_subseq);
        }
+       list_for_each_entry(d, &card->dapm_list, list) {
+               soc_dapm_async_complete(d);
+       }
  }
  
  static void dapm_widget_update(struct snd_soc_card *card)
@@@ -1840,6 -1864,7 +1864,7 @@@ static int dapm_power_widgets(struct sn
                         */
                        switch (w->id) {
                        case snd_soc_dapm_siggen:
+                       case snd_soc_dapm_vmid:
                                break;
                        case snd_soc_dapm_supply:
                        case snd_soc_dapm_regulator_supply:
@@@ -1949,7 -1974,7 +1974,7 @@@ static ssize_t dapm_widget_power_read_f
                                w->active ? "active" : "inactive");
  
        list_for_each_entry(p, &w->sources, list_sink) {
 -              if (p->connected && !p->connected(w, p->sink))
 +              if (p->connected && !p->connected(w, p->source))
                        continue;
  
                if (p->connect)
@@@ -2791,7 -2816,7 +2816,7 @@@ int snd_soc_dapm_get_volsw(struct snd_k
        struct snd_soc_card *card = codec->card;
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       unsigned int reg = mc->reg;
+       int reg = mc->reg;
        unsigned int shift = mc->shift;
        int max = mc->max;
        unsigned int mask = (1 << fls(max)) - 1;
                         kcontrol->id.name);
  
        mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
-       if (dapm_kcontrol_is_powered(kcontrol))
+       if (dapm_kcontrol_is_powered(kcontrol) && reg != SND_SOC_NOPM)
                val = (snd_soc_read(codec, reg) >> shift) & mask;
        else
                val = dapm_kcontrol_get_value(kcontrol);
@@@ -2835,7 -2860,7 +2860,7 @@@ int snd_soc_dapm_put_volsw(struct snd_k
        struct snd_soc_card *card = codec->card;
        struct soc_mixer_control *mc =
                (struct soc_mixer_control *)kcontrol->private_value;
-       unsigned int reg = mc->reg;
+       int reg = mc->reg;
        unsigned int shift = mc->shift;
        int max = mc->max;
        unsigned int mask = (1 << fls(max)) - 1;
  
        mutex_lock_nested(&card->dapm_mutex, SND_SOC_DAPM_CLASS_RUNTIME);
  
-       dapm_kcontrol_set_value(kcontrol, val);
+       change = dapm_kcontrol_set_value(kcontrol, val);
+       if (reg != SND_SOC_NOPM) {
+               mask = mask << shift;
+               val = val << shift;
  
-       mask = mask << shift;
-       val = val << shift;
+               change = snd_soc_test_bits(codec, reg, mask, val);
+       }
  
-       change = snd_soc_test_bits(codec, reg, mask, val);
        if (change) {
-               update.kcontrol = kcontrol;
-               update.reg = reg;
-               update.mask = mask;
-               update.val = val;
+               if (reg != SND_SOC_NOPM) {
+                       update.kcontrol = kcontrol;
+                       update.reg = reg;
+                       update.mask = mask;
+                       update.val = val;
  
-               card->update = &update;
+                       card->update = &update;
+               }
  
                soc_dapm_mixer_update_power(card, kcontrol, connect);
  
@@@ -3495,7 -3525,6 +3525,7 @@@ int snd_soc_dapm_new_dai_widgets(struc
                if (!w) {
                        dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
                                dai->driver->playback.stream_name);
 +                      return -ENOMEM;
                }
  
                w->priv = dai;
                if (!w) {
                        dev_err(dapm->dev, "ASoC: Failed to create %s widget\n",
                                dai->driver->capture.stream_name);
 +                      return -ENOMEM;
                }
  
                w->priv = dai;