ASoC: Convert WM8962 register access map to modern style
[deliverable/linux.git] / sound / soc / codecs / cx20442.c
index ae55e31bfc721172c7210cc48b2c6706fc0d9831..d5fd00a64748097ad1794ed9cc45178c513c6b68 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/tty.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/regulator/consumer.h>
 
 #include <sound/core.h>
 #include <sound/initval.h>
@@ -25,8 +26,8 @@
 
 
 struct cx20442_priv {
-       enum snd_soc_control_type control_type;
        void *control_data;
+       struct regulator *por;
 };
 
 #define CX20442_PM             0x0
@@ -324,6 +325,38 @@ static struct snd_soc_dai_driver cx20442_dai = {
        },
 };
 
+static int cx20442_set_bias_level(struct snd_soc_codec *codec,
+               enum snd_soc_bias_level level)
+{
+       struct cx20442_priv *cx20442 = snd_soc_codec_get_drvdata(codec);
+       int err = 0;
+
+       switch (level) {
+       case SND_SOC_BIAS_PREPARE:
+               if (codec->dapm.bias_level != SND_SOC_BIAS_STANDBY)
+                       break;
+               if (IS_ERR(cx20442->por))
+                       err = PTR_ERR(cx20442->por);
+               else
+                       err = regulator_enable(cx20442->por);
+               break;
+       case SND_SOC_BIAS_STANDBY:
+               if (codec->dapm.bias_level != SND_SOC_BIAS_PREPARE)
+                       break;
+               if (IS_ERR(cx20442->por))
+                       err = PTR_ERR(cx20442->por);
+               else
+                       err = regulator_disable(cx20442->por);
+               break;
+       default:
+               break;
+       }
+       if (!err)
+               codec->dapm.bias_level = level;
+
+       return err;
+}
+
 static int cx20442_codec_probe(struct snd_soc_codec *codec)
 {
        struct cx20442_priv *cx20442;
@@ -331,9 +364,13 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec)
        cx20442 = kzalloc(sizeof(struct cx20442_priv), GFP_KERNEL);
        if (cx20442 == NULL)
                return -ENOMEM;
-       snd_soc_codec_set_drvdata(codec, cx20442);
 
+       cx20442->por = regulator_get(codec->dev, "POR");
+       if (IS_ERR(cx20442->por))
+               dev_warn(codec->dev, "failed to get the regulator");
        cx20442->control_data = NULL;
+
+       snd_soc_codec_set_drvdata(codec, cx20442);
        codec->hw_write = NULL;
        codec->card->pop_time = 0;
 
@@ -350,6 +387,12 @@ static int cx20442_codec_remove(struct snd_soc_codec *codec)
                        tty_hangup(tty);
        }
 
+       if (!IS_ERR(cx20442->por)) {
+               /* should be already in STANDBY, hence disabled */
+               regulator_put(cx20442->por);
+       }
+
+       snd_soc_codec_set_drvdata(codec, NULL);
        kfree(cx20442);
        return 0;
 }
@@ -359,6 +402,7 @@ static const u8 cx20442_reg;
 static struct snd_soc_codec_driver cx20442_codec_dev = {
        .probe =        cx20442_codec_probe,
        .remove =       cx20442_codec_remove,
+       .set_bias_level = cx20442_set_bias_level,
        .reg_cache_default = &cx20442_reg,
        .reg_cache_size = 1,
        .reg_word_size = sizeof(u8),
This page took 0.02606 seconds and 5 git commands to generate.