Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
[safe/jmp/linux-2.6] / sound / soc / soc-core.c
index 025c5a7..ad7f952 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/bitops.h>
 #include <linux/debugfs.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <sound/ac97_codec.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
@@ -80,6 +81,196 @@ static int run_delayed_work(struct delayed_work *dwork)
        return ret;
 }
 
+/* codec register dump */
+static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
+{
+       int i, step = 1, count = 0;
+
+       if (!codec->reg_cache_size)
+               return 0;
+
+       if (codec->reg_cache_step)
+               step = codec->reg_cache_step;
+
+       count += sprintf(buf, "%s registers\n", codec->name);
+       for (i = 0; i < codec->reg_cache_size; i += step) {
+               if (codec->readable_register && !codec->readable_register(i))
+                       continue;
+
+               count += sprintf(buf + count, "%2x: ", i);
+               if (count >= PAGE_SIZE - 1)
+                       break;
+
+               if (codec->display_register)
+                       count += codec->display_register(codec, buf + count,
+                                                        PAGE_SIZE - count, i);
+               else
+                       count += snprintf(buf + count, PAGE_SIZE - count,
+                                         "%4x", codec->read(codec, i));
+
+               if (count >= PAGE_SIZE - 1)
+                       break;
+
+               count += snprintf(buf + count, PAGE_SIZE - count, "\n");
+               if (count >= PAGE_SIZE - 1)
+                       break;
+       }
+
+       /* Truncate count; min() would cause a warning */
+       if (count >= PAGE_SIZE)
+               count = PAGE_SIZE - 1;
+
+       return count;
+}
+static ssize_t codec_reg_show(struct device *dev,
+       struct device_attribute *attr, char *buf)
+{
+       struct snd_soc_device *devdata = dev_get_drvdata(dev);
+       return soc_codec_reg_show(devdata->card->codec, buf);
+}
+
+static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
+
+static ssize_t pmdown_time_show(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct snd_soc_device *socdev = dev_get_drvdata(dev);
+       struct snd_soc_card *card = socdev->card;
+
+       return sprintf(buf, "%ld\n", card->pmdown_time);
+}
+
+static ssize_t pmdown_time_set(struct device *dev,
+                              struct device_attribute *attr,
+                              const char *buf, size_t count)
+{
+       struct snd_soc_device *socdev = dev_get_drvdata(dev);
+       struct snd_soc_card *card = socdev->card;
+
+       strict_strtol(buf, 10, &card->pmdown_time);
+
+       return count;
+}
+
+static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
+
+#ifdef CONFIG_DEBUG_FS
+static int codec_reg_open_file(struct inode *inode, struct file *file)
+{
+       file->private_data = inode->i_private;
+       return 0;
+}
+
+static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
+                              size_t count, loff_t *ppos)
+{
+       ssize_t ret;
+       struct snd_soc_codec *codec = file->private_data;
+       char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+       ret = soc_codec_reg_show(codec, buf);
+       if (ret >= 0)
+               ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
+       kfree(buf);
+       return ret;
+}
+
+static ssize_t codec_reg_write_file(struct file *file,
+               const char __user *user_buf, size_t count, loff_t *ppos)
+{
+       char buf[32];
+       int buf_size;
+       char *start = buf;
+       unsigned long reg, value;
+       int step = 1;
+       struct snd_soc_codec *codec = file->private_data;
+
+       buf_size = min(count, (sizeof(buf)-1));
+       if (copy_from_user(buf, user_buf, buf_size))
+               return -EFAULT;
+       buf[buf_size] = 0;
+
+       if (codec->reg_cache_step)
+               step = codec->reg_cache_step;
+
+       while (*start == ' ')
+               start++;
+       reg = simple_strtoul(start, &start, 16);
+       if ((reg >= codec->reg_cache_size) || (reg % step))
+               return -EINVAL;
+       while (*start == ' ')
+               start++;
+       if (strict_strtoul(start, 16, &value))
+               return -EINVAL;
+       codec->write(codec, reg, value);
+       return buf_size;
+}
+
+static const struct file_operations codec_reg_fops = {
+       .open = codec_reg_open_file,
+       .read = codec_reg_read_file,
+       .write = codec_reg_write_file,
+};
+
+static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
+{
+       char codec_root[128];
+
+       if (codec->dev)
+               snprintf(codec_root, sizeof(codec_root),
+                       "%s.%s", codec->name, dev_name(codec->dev));
+       else
+               snprintf(codec_root, sizeof(codec_root),
+                       "%s", codec->name);
+
+       codec->debugfs_codec_root = debugfs_create_dir(codec_root,
+                                                      debugfs_root);
+       if (!codec->debugfs_codec_root) {
+               printk(KERN_WARNING
+                      "ASoC: Failed to create codec debugfs directory\n");
+               return;
+       }
+
+       codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
+                                                codec->debugfs_codec_root,
+                                                codec, &codec_reg_fops);
+       if (!codec->debugfs_reg)
+               printk(KERN_WARNING
+                      "ASoC: Failed to create codec register debugfs file\n");
+
+       codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
+                                                    codec->debugfs_codec_root,
+                                                    &codec->pop_time);
+       if (!codec->debugfs_pop_time)
+               printk(KERN_WARNING
+                      "Failed to create pop time debugfs file\n");
+
+       codec->debugfs_dapm = debugfs_create_dir("dapm",
+                                                codec->debugfs_codec_root);
+       if (!codec->debugfs_dapm)
+               printk(KERN_WARNING
+                      "Failed to create DAPM debugfs directory\n");
+
+       snd_soc_dapm_debugfs_init(codec);
+}
+
+static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
+{
+       debugfs_remove_recursive(codec->debugfs_codec_root);
+}
+
+#else
+
+static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
+{
+}
+
+static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
+{
+}
+#endif
+
 #ifdef CONFIG_SND_SOC_AC97_BUS
 /* unregister ac97 codec */
 static int soc_ac97_dev_unregister(struct snd_soc_codec *codec)
@@ -237,24 +428,24 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
        if (!runtime->hw.rates) {
                printk(KERN_ERR "asoc: %s <-> %s No matching rates\n",
                        codec_dai->name, cpu_dai->name);
-               goto machine_err;
+               goto config_err;
        }
        if (!runtime->hw.formats) {
                printk(KERN_ERR "asoc: %s <-> %s No matching formats\n",
                        codec_dai->name, cpu_dai->name);
-               goto machine_err;
+               goto config_err;
        }
        if (!runtime->hw.channels_min || !runtime->hw.channels_max) {
                printk(KERN_ERR "asoc: %s <-> %s No matching channels\n",
                        codec_dai->name, cpu_dai->name);
-               goto machine_err;
+               goto config_err;
        }
 
        /* Symmetry only applies if we've already got an active stream. */
        if (cpu_dai->active || codec_dai->active) {
                ret = soc_pcm_apply_symmetry(substream);
                if (ret != 0)
-                       goto machine_err;
+                       goto config_err;
        }
 
        pr_debug("asoc: %s <-> %s info:\n", codec_dai->name, cpu_dai->name);
@@ -274,10 +465,14 @@ static int soc_pcm_open(struct snd_pcm_substream *substream)
        mutex_unlock(&pcm_mutex);
        return 0;
 
-machine_err:
+config_err:
        if (machine->ops && machine->ops->shutdown)
                machine->ops->shutdown(substream);
 
+machine_err:
+       if (codec_dai->ops->shutdown)
+               codec_dai->ops->shutdown(substream, codec_dai);
+
 codec_dai_err:
        if (platform->pcm_ops->close)
                platform->pcm_ops->close(substream);
@@ -375,7 +570,7 @@ static int soc_codec_close(struct snd_pcm_substream *substream)
                /* start delayed pop wq here for playback streams */
                codec_dai->pop_wait = 1;
                schedule_delayed_work(&card->delayed_work,
-                       msecs_to_jiffies(pmdown_time));
+                       msecs_to_jiffies(card->pmdown_time));
        } else {
                /* capture streams can be powered down now */
                snd_soc_dapm_stream_event(codec,
@@ -773,6 +968,12 @@ static int soc_resume(struct device *dev)
        struct snd_soc_card *card = socdev->card;
        struct snd_soc_dai *cpu_dai = card->dai_link[0].cpu_dai;
 
+       /* If the initialization of this soc device failed, there is no codec
+        * associated with it. Just bail out in this case.
+        */
+       if (!card->codec)
+               return 0;
+
        /* AC97 devices might have other drivers hanging off them so
         * need to resume immediately.  Other drivers don't have that
         * problem and may take a substantial amount of time to resume
@@ -803,6 +1004,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
                                                    struct platform_device,
                                                    dev);
        struct snd_soc_codec_device *codec_dev = card->socdev->codec_dev;
+       struct snd_soc_codec *codec;
        struct snd_soc_platform *platform;
        struct snd_soc_dai *dai;
        int i, found, ret, ac97;
@@ -871,6 +1073,8 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
        dev_dbg(card->dev, "All components present, instantiating\n");
 
        /* Found everything, bring it up */
+       card->pmdown_time = pmdown_time;
+
        if (card->probe) {
                ret = card->probe(pdev);
                if (ret < 0)
@@ -891,6 +1095,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
                if (ret < 0)
                        goto cpu_dai_err;
        }
+       codec = card->codec;
 
        if (platform->probe) {
                ret = platform->probe(pdev);
@@ -905,10 +1110,73 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card)
        INIT_WORK(&card->deferred_resume_work, soc_resume_deferred);
 #endif
 
+       for (i = 0; i < card->num_links; i++) {
+               if (card->dai_link[i].init) {
+                       ret = card->dai_link[i].init(codec);
+                       if (ret < 0) {
+                               printk(KERN_ERR "asoc: failed to init %s\n",
+                                       card->dai_link[i].stream_name);
+                               continue;
+                       }
+               }
+               if (card->dai_link[i].codec_dai->ac97_control)
+                       ac97 = 1;
+       }
+
+       snprintf(codec->card->shortname, sizeof(codec->card->shortname),
+                "%s",  card->name);
+       snprintf(codec->card->longname, sizeof(codec->card->longname),
+                "%s (%s)", card->name, codec->name);
+
+       /* Make sure all DAPM widgets are instantiated */
+       snd_soc_dapm_new_widgets(codec);
+
+       ret = snd_card_register(codec->card);
+       if (ret < 0) {
+               printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
+                               codec->name);
+               goto card_err;
+       }
+
+       mutex_lock(&codec->mutex);
+#ifdef CONFIG_SND_SOC_AC97_BUS
+       /* Only instantiate AC97 if not already done by the adaptor
+        * for the generic AC97 subsystem.
+        */
+       if (ac97 && strcmp(codec->name, "AC97") != 0) {
+               ret = soc_ac97_dev_register(codec);
+               if (ret < 0) {
+                       printk(KERN_ERR "asoc: AC97 device register failed\n");
+                       snd_card_free(codec->card);
+                       mutex_unlock(&codec->mutex);
+                       goto card_err;
+               }
+       }
+#endif
+
+       ret = snd_soc_dapm_sys_add(card->socdev->dev);
+       if (ret < 0)
+               printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
+
+       ret = device_create_file(card->socdev->dev, &dev_attr_pmdown_time);
+       if (ret < 0)
+               printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n");
+
+       ret = device_create_file(card->socdev->dev, &dev_attr_codec_reg);
+       if (ret < 0)
+               printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
+
+       soc_init_codec_debugfs(codec);
+       mutex_unlock(&codec->mutex);
+
        card->instantiated = 1;
 
        return;
 
+card_err:
+       if (platform->remove)
+               platform->remove(pdev);
+
 platform_err:
        if (codec_dev->remove)
                codec_dev->remove(pdev);
@@ -1008,7 +1276,7 @@ static int soc_poweroff(struct device *dev)
        return 0;
 }
 
-static struct dev_pm_ops soc_pm_ops = {
+static const struct dev_pm_ops soc_pm_ops = {
        .suspend = soc_suspend,
        .resume = soc_resume,
        .poweroff = soc_poweroff,
@@ -1048,8 +1316,8 @@ static int soc_new_pcm(struct snd_soc_device *socdev,
        codec_dai->codec = card->codec;
 
        /* check client and interface hw capabilities */
-       sprintf(new_name, "%s %s-%d", dai_link->stream_name, codec_dai->name,
-               num);
+       snprintf(new_name, sizeof(new_name), "%s %s-%d",
+                dai_link->stream_name, codec_dai->name, num);
 
        if (codec_dai->playback.channels_min)
                playback = 1;
@@ -1111,173 +1379,6 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg)
 }
 EXPORT_SYMBOL_GPL(snd_soc_codec_volatile_register);
 
-/* codec register dump */
-static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf)
-{
-       int i, step = 1, count = 0;
-
-       if (!codec->reg_cache_size)
-               return 0;
-
-       if (codec->reg_cache_step)
-               step = codec->reg_cache_step;
-
-       count += sprintf(buf, "%s registers\n", codec->name);
-       for (i = 0; i < codec->reg_cache_size; i += step) {
-               if (codec->readable_register && !codec->readable_register(i))
-                       continue;
-
-               count += sprintf(buf + count, "%2x: ", i);
-               if (count >= PAGE_SIZE - 1)
-                       break;
-
-               if (codec->display_register)
-                       count += codec->display_register(codec, buf + count,
-                                                        PAGE_SIZE - count, i);
-               else
-                       count += snprintf(buf + count, PAGE_SIZE - count,
-                                         "%4x", codec->read(codec, i));
-
-               if (count >= PAGE_SIZE - 1)
-                       break;
-
-               count += snprintf(buf + count, PAGE_SIZE - count, "\n");
-               if (count >= PAGE_SIZE - 1)
-                       break;
-       }
-
-       /* Truncate count; min() would cause a warning */
-       if (count >= PAGE_SIZE)
-               count = PAGE_SIZE - 1;
-
-       return count;
-}
-static ssize_t codec_reg_show(struct device *dev,
-       struct device_attribute *attr, char *buf)
-{
-       struct snd_soc_device *devdata = dev_get_drvdata(dev);
-       return soc_codec_reg_show(devdata->card->codec, buf);
-}
-
-static DEVICE_ATTR(codec_reg, 0444, codec_reg_show, NULL);
-
-#ifdef CONFIG_DEBUG_FS
-static int codec_reg_open_file(struct inode *inode, struct file *file)
-{
-       file->private_data = inode->i_private;
-       return 0;
-}
-
-static ssize_t codec_reg_read_file(struct file *file, char __user *user_buf,
-                              size_t count, loff_t *ppos)
-{
-       ssize_t ret;
-       struct snd_soc_codec *codec = file->private_data;
-       char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if (!buf)
-               return -ENOMEM;
-       ret = soc_codec_reg_show(codec, buf);
-       if (ret >= 0)
-               ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret);
-       kfree(buf);
-       return ret;
-}
-
-static ssize_t codec_reg_write_file(struct file *file,
-               const char __user *user_buf, size_t count, loff_t *ppos)
-{
-       char buf[32];
-       int buf_size;
-       char *start = buf;
-       unsigned long reg, value;
-       int step = 1;
-       struct snd_soc_codec *codec = file->private_data;
-
-       buf_size = min(count, (sizeof(buf)-1));
-       if (copy_from_user(buf, user_buf, buf_size))
-               return -EFAULT;
-       buf[buf_size] = 0;
-
-       if (codec->reg_cache_step)
-               step = codec->reg_cache_step;
-
-       while (*start == ' ')
-               start++;
-       reg = simple_strtoul(start, &start, 16);
-       if ((reg >= codec->reg_cache_size) || (reg % step))
-               return -EINVAL;
-       while (*start == ' ')
-               start++;
-       if (strict_strtoul(start, 16, &value))
-               return -EINVAL;
-       codec->write(codec, reg, value);
-       return buf_size;
-}
-
-static const struct file_operations codec_reg_fops = {
-       .open = codec_reg_open_file,
-       .read = codec_reg_read_file,
-       .write = codec_reg_write_file,
-};
-
-static void soc_init_codec_debugfs(struct snd_soc_codec *codec)
-{
-       char codec_root[128];
-
-       if (codec->dev)
-               snprintf(codec_root, sizeof(codec_root),
-                       "%s.%s", codec->name, dev_name(codec->dev));
-       else
-               snprintf(codec_root, sizeof(codec_root),
-                       "%s", codec->name);
-
-       codec->debugfs_codec_root = debugfs_create_dir(codec_root,
-                                                      debugfs_root);
-       if (!codec->debugfs_codec_root) {
-               printk(KERN_WARNING
-                      "ASoC: Failed to create codec debugfs directory\n");
-               return;
-       }
-
-       codec->debugfs_reg = debugfs_create_file("codec_reg", 0644,
-                                                codec->debugfs_codec_root,
-                                                codec, &codec_reg_fops);
-       if (!codec->debugfs_reg)
-               printk(KERN_WARNING
-                      "ASoC: Failed to create codec register debugfs file\n");
-
-       codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0744,
-                                                    codec->debugfs_codec_root,
-                                                    &codec->pop_time);
-       if (!codec->debugfs_pop_time)
-               printk(KERN_WARNING
-                      "Failed to create pop time debugfs file\n");
-
-       codec->debugfs_dapm = debugfs_create_dir("dapm",
-                                                codec->debugfs_codec_root);
-       if (!codec->debugfs_dapm)
-               printk(KERN_WARNING
-                      "Failed to create DAPM debugfs directory\n");
-
-       snd_soc_dapm_debugfs_init(codec);
-}
-
-static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
-{
-       debugfs_remove_recursive(codec->debugfs_codec_root);
-}
-
-#else
-
-static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec)
-{
-}
-
-static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec)
-{
-}
-#endif
-
 /**
  * snd_soc_new_ac97_codec - initailise AC97 device
  * @codec: audio codec
@@ -1307,6 +1408,7 @@ int snd_soc_new_ac97_codec(struct snd_soc_codec *codec,
 
        codec->ac97->bus->ops = ops;
        codec->ac97->num = num;
+       codec->dev = &codec->ac97->dev;
        mutex_unlock(&codec->mutex);
        return 0;
 }
@@ -1356,6 +1458,31 @@ int snd_soc_update_bits(struct snd_soc_codec *codec, unsigned short reg,
 EXPORT_SYMBOL_GPL(snd_soc_update_bits);
 
 /**
+ * snd_soc_update_bits_locked - update codec register bits
+ * @codec: audio codec
+ * @reg: codec register
+ * @mask: register mask
+ * @value: new value
+ *
+ * Writes new register value, and takes the codec mutex.
+ *
+ * Returns 1 for change else 0.
+ */
+int snd_soc_update_bits_locked(struct snd_soc_codec *codec,
+                              unsigned short reg, unsigned int mask,
+                              unsigned int value)
+{
+       int change;
+
+       mutex_lock(&codec->mutex);
+       change = snd_soc_update_bits(codec, reg, mask, value);
+       mutex_unlock(&codec->mutex);
+
+       return change;
+}
+EXPORT_SYMBOL_GPL(snd_soc_update_bits_locked);
+
+/**
  * snd_soc_test_bits - test register for change
  * @codec: audio codec
  * @reg: codec register
@@ -1422,89 +1549,17 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
                        mutex_unlock(&codec->mutex);
                        return ret;
                }
-       }
-
-       mutex_unlock(&codec->mutex);
-       return ret;
-}
-EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
-
-/**
- * snd_soc_init_card - register sound card
- * @socdev: the SoC audio device
- *
- * Register a SoC sound card. Also registers an AC97 device if the
- * codec is AC97 for ad hoc devices.
- *
- * Returns 0 for success, else error.
- */
-int snd_soc_init_card(struct snd_soc_device *socdev)
-{
-       struct snd_soc_card *card = socdev->card;
-       struct snd_soc_codec *codec = card->codec;
-       int ret = 0, i, ac97 = 0, err = 0;
-
-       for (i = 0; i < card->num_links; i++) {
-               if (card->dai_link[i].init) {
-                       err = card->dai_link[i].init(codec);
-                       if (err < 0) {
-                               printk(KERN_ERR "asoc: failed to init %s\n",
-                                       card->dai_link[i].stream_name);
-                               continue;
-                       }
-               }
-               if (card->dai_link[i].codec_dai->ac97_control) {
-                       ac97 = 1;
+               /* Check for codec->ac97 to handle the ac97.c fun */
+               if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
                        snd_ac97_dev_add_pdata(codec->ac97,
                                card->dai_link[i].cpu_dai->ac97_pdata);
                }
        }
-       snprintf(codec->card->shortname, sizeof(codec->card->shortname),
-                "%s",  card->name);
-       snprintf(codec->card->longname, sizeof(codec->card->longname),
-                "%s (%s)", card->name, codec->name);
 
-       /* Make sure all DAPM widgets are instantiated */
-       snd_soc_dapm_new_widgets(codec);
-
-       ret = snd_card_register(codec->card);
-       if (ret < 0) {
-               printk(KERN_ERR "asoc: failed to register soundcard for %s\n",
-                               codec->name);
-               goto out;
-       }
-
-       mutex_lock(&codec->mutex);
-#ifdef CONFIG_SND_SOC_AC97_BUS
-       /* Only instantiate AC97 if not already done by the adaptor
-        * for the generic AC97 subsystem.
-        */
-       if (ac97 && strcmp(codec->name, "AC97") != 0) {
-               ret = soc_ac97_dev_register(codec);
-               if (ret < 0) {
-                       printk(KERN_ERR "asoc: AC97 device register failed\n");
-                       snd_card_free(codec->card);
-                       mutex_unlock(&codec->mutex);
-                       goto out;
-               }
-       }
-#endif
-
-       err = snd_soc_dapm_sys_add(socdev->dev);
-       if (err < 0)
-               printk(KERN_WARNING "asoc: failed to add dapm sysfs entries\n");
-
-       err = device_create_file(socdev->dev, &dev_attr_codec_reg);
-       if (err < 0)
-               printk(KERN_WARNING "asoc: failed to add codec sysfs files\n");
-
-       soc_init_codec_debugfs(codec);
        mutex_unlock(&codec->mutex);
-
-out:
        return ret;
 }
-EXPORT_SYMBOL_GPL(snd_soc_init_card);
+EXPORT_SYMBOL_GPL(snd_soc_new_pcms);
 
 /**
  * snd_soc_free_pcms - free sound card and pcms
@@ -1706,7 +1761,7 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
                mask |= (bitmask - 1) << e->shift_r;
        }
 
-       return snd_soc_update_bits(codec, e->reg, mask, val);
+       return snd_soc_update_bits_locked(codec, e->reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
 
@@ -1780,7 +1835,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
                mask |= e->mask << e->shift_r;
        }
 
-       return snd_soc_update_bits(codec, e->reg, mask, val);
+       return snd_soc_update_bits_locked(codec, e->reg, mask, val);
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_value_enum_double);
 
@@ -1941,7 +1996,7 @@ int snd_soc_put_volsw(struct snd_kcontrol *kcontrol,
                val_mask |= mask << rshift;
                val |= val2 << rshift;
        }
-       return snd_soc_update_bits(codec, reg, val_mask, val);
+       return snd_soc_update_bits_locked(codec, reg, val_mask, val);
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_volsw);
 
@@ -2047,11 +2102,11 @@ int snd_soc_put_volsw_2r(struct snd_kcontrol *kcontrol,
        val = val << shift;
        val2 = val2 << shift;
 
-       err = snd_soc_update_bits(codec, reg, val_mask, val);
+       err = snd_soc_update_bits_locked(codec, reg, val_mask, val);
        if (err < 0)
                return err;
 
-       err = snd_soc_update_bits(codec, reg2, val_mask, val2);
+       err = snd_soc_update_bits_locked(codec, reg2, val_mask, val2);
        return err;
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_volsw_2r);
@@ -2130,7 +2185,7 @@ int snd_soc_put_volsw_s8(struct snd_kcontrol *kcontrol,
        val = (ucontrol->value.integer.value[0]+min) & 0xff;
        val |= ((ucontrol->value.integer.value[1]+min) & 0xff) << 8;
 
-       return snd_soc_update_bits(codec, reg, 0xffff, val);
+       return snd_soc_update_bits_locked(codec, reg, 0xffff, val);
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_volsw_s8);