Merge branch 'for-5.6' of https://git.kernel.org/pub/scm/linux/kernel/git/broonie...
[linux-2.6-microblaze.git] / sound / soc / codecs / wm_adsp.c
index 9e5b6c4..ffb9836 100644 (file)
@@ -1030,8 +1030,8 @@ static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl,
        return -ETIMEDOUT;
 }
 
-static int wm_coeff_write_control(struct wm_coeff_ctl *ctl,
-                                 const void *buf, size_t len)
+static int wm_coeff_write_ctrl_raw(struct wm_coeff_ctl *ctl,
+                                  const void *buf, size_t len)
 {
        struct wm_adsp *dsp = ctl->dsp;
        void *scratch;
@@ -1061,6 +1061,23 @@ static int wm_coeff_write_control(struct wm_coeff_ctl *ctl,
        return 0;
 }
 
+static int wm_coeff_write_ctrl(struct wm_coeff_ctl *ctl,
+                              const void *buf, size_t len)
+{
+       int ret = 0;
+
+       if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
+               ret = -EPERM;
+       else if (buf != ctl->cache)
+               memcpy(ctl->cache, buf, len);
+
+       ctl->set = 1;
+       if (ctl->enabled && ctl->dsp->running)
+               ret = wm_coeff_write_ctrl_raw(ctl, buf, len);
+
+       return ret;
+}
+
 static int wm_coeff_put(struct snd_kcontrol *kctl,
                        struct snd_ctl_elem_value *ucontrol)
 {
@@ -1071,16 +1088,7 @@ static int wm_coeff_put(struct snd_kcontrol *kctl,
        int ret = 0;
 
        mutex_lock(&ctl->dsp->pwr_lock);
-
-       if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
-               ret = -EPERM;
-       else
-               memcpy(ctl->cache, p, ctl->len);
-
-       ctl->set = 1;
-       if (ctl->enabled && ctl->dsp->running)
-               ret = wm_coeff_write_control(ctl, p, ctl->len);
-
+       ret = wm_coeff_write_ctrl(ctl, p, ctl->len);
        mutex_unlock(&ctl->dsp->pwr_lock);
 
        return ret;
@@ -1096,15 +1104,10 @@ static int wm_coeff_tlv_put(struct snd_kcontrol *kctl,
 
        mutex_lock(&ctl->dsp->pwr_lock);
 
-       if (copy_from_user(ctl->cache, bytes, size)) {
+       if (copy_from_user(ctl->cache, bytes, size))
                ret = -EFAULT;
-       } else {
-               ctl->set = 1;
-               if (ctl->enabled && ctl->dsp->running)
-                       ret = wm_coeff_write_control(ctl, ctl->cache, size);
-               else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE)
-                       ret = -EPERM;
-       }
+       else
+               ret = wm_coeff_write_ctrl(ctl, ctl->cache, size);
 
        mutex_unlock(&ctl->dsp->pwr_lock);
 
@@ -1135,8 +1138,8 @@ static int wm_coeff_put_acked(struct snd_kcontrol *kctl,
        return ret;
 }
 
-static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
-                                void *buf, size_t len)
+static int wm_coeff_read_ctrl_raw(struct wm_coeff_ctl *ctl,
+                                 void *buf, size_t len)
 {
        struct wm_adsp *dsp = ctl->dsp;
        void *scratch;
@@ -1166,29 +1169,37 @@ static int wm_coeff_read_control(struct wm_coeff_ctl *ctl,
        return 0;
 }
 
-static int wm_coeff_get(struct snd_kcontrol *kctl,
-                       struct snd_ctl_elem_value *ucontrol)
+static int wm_coeff_read_ctrl(struct wm_coeff_ctl *ctl, void *buf, size_t len)
 {
-       struct soc_bytes_ext *bytes_ext =
-               (struct soc_bytes_ext *)kctl->private_value;
-       struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
-       char *p = ucontrol->value.bytes.data;
        int ret = 0;
 
-       mutex_lock(&ctl->dsp->pwr_lock);
-
        if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
                if (ctl->enabled && ctl->dsp->running)
-                       ret = wm_coeff_read_control(ctl, p, ctl->len);
+                       return wm_coeff_read_ctrl_raw(ctl, buf, len);
                else
-                       ret = -EPERM;
+                       return -EPERM;
        } else {
                if (!ctl->flags && ctl->enabled && ctl->dsp->running)
-                       ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
+                       ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len);
 
-               memcpy(p, ctl->cache, ctl->len);
+               if (buf != ctl->cache)
+                       memcpy(buf, ctl->cache, len);
        }
 
+       return ret;
+}
+
+static int wm_coeff_get(struct snd_kcontrol *kctl,
+                       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_bytes_ext *bytes_ext =
+               (struct soc_bytes_ext *)kctl->private_value;
+       struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext);
+       char *p = ucontrol->value.bytes.data;
+       int ret;
+
+       mutex_lock(&ctl->dsp->pwr_lock);
+       ret = wm_coeff_read_ctrl(ctl, p, ctl->len);
        mutex_unlock(&ctl->dsp->pwr_lock);
 
        return ret;
@@ -1204,15 +1215,7 @@ static int wm_coeff_tlv_get(struct snd_kcontrol *kctl,
 
        mutex_lock(&ctl->dsp->pwr_lock);
 
-       if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) {
-               if (ctl->enabled && ctl->dsp->running)
-                       ret = wm_coeff_read_control(ctl, ctl->cache, size);
-               else
-                       ret = -EPERM;
-       } else {
-               if (!ctl->flags && ctl->enabled && ctl->dsp->running)
-                       ret = wm_coeff_read_control(ctl, ctl->cache, size);
-       }
+       ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, size);
 
        if (!ret && copy_to_user(bytes, ctl->cache, size))
                ret = -EFAULT;
@@ -1340,7 +1343,7 @@ static int wm_coeff_init_control_caches(struct wm_adsp *dsp)
                 * created so we don't need to do anything.
                 */
                if (!ctl->flags || (ctl->flags & WMFW_CTL_FLAG_READABLE)) {
-                       ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len);
+                       ret = wm_coeff_read_ctrl_raw(ctl, ctl->cache, ctl->len);
                        if (ret < 0)
                                return ret;
                }
@@ -1358,7 +1361,8 @@ static int wm_coeff_sync_controls(struct wm_adsp *dsp)
                if (!ctl->enabled)
                        continue;
                if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) {
-                       ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len);
+                       ret = wm_coeff_write_ctrl_raw(ctl, ctl->cache,
+                                                     ctl->len);
                        if (ret < 0)
                                return ret;
                }
@@ -2048,7 +2052,7 @@ int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
        if (len > ctl->len)
                return -EINVAL;
 
-       ret = wm_coeff_write_control(ctl, buf, len);
+       ret = wm_coeff_write_ctrl(ctl, buf, len);
 
        kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl->name);
        snd_ctl_notify(dsp->component->card->snd_card,
@@ -2070,7 +2074,7 @@ int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
        if (len > ctl->len)
                return -EINVAL;
 
-       return wm_coeff_read_control(ctl, buf, len);
+       return wm_coeff_read_ctrl(ctl, buf, len);
 }
 EXPORT_SYMBOL_GPL(wm_adsp_read_ctl);