ASoC: TWL4030: Use BIAS_OFF instead of BIAS_STANDBY, when not in use
authorPeter Ujfalusi <peter.ujfalusi@nokia.com>
Wed, 26 May 2010 08:38:20 +0000 (11:38 +0300)
committerLiam Girdwood <lrg@slimlogic.co.uk>
Mon, 31 May 2010 10:08:58 +0000 (11:08 +0100)
Restructure the codec power code in order to be able to hit
off when the codec is not in use.

Since the audio registers are accessible while the codec is powered
down, there is no need for additional safety mechanism.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@nokia.com>
Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Signed-off-by: Liam Girdwood <lrg@slimlogic.co.uk>
sound/soc/codecs/twl4030.c

index c667ca5a8a9e16225321b0d7ee3cc4df16345715..45de2aad283c3a731bc6b332ec6a43e242884e23 100644 (file)
@@ -1818,13 +1818,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       if (mode != old_mode) {
-               /* change rate and set CODECPDZ */
-               twl4030_codec_enable(codec, 0);
-               twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-               twl4030_codec_enable(codec, 1);
-       }
-
        /* sample size */
        old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF);
        format = old_format;
@@ -1842,16 +1835,20 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream,
                return -EINVAL;
        }
 
-       if (format != old_format) {
-
-               /* clear CODECPDZ before changing format (codec requirement) */
-               twl4030_codec_enable(codec, 0);
-
-               /* change format */
-               twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
-
-               /* set CODECPDZ afterwards */
-               twl4030_codec_enable(codec, 1);
+       if (format != old_format || mode != old_mode) {
+               if (twl4030->codec_powered) {
+                       /*
+                        * If the codec is powered, than we need to toggle the
+                        * codec power.
+                        */
+                       twl4030_codec_enable(codec, 0);
+                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+                       twl4030_codec_enable(codec, 1);
+               } else {
+                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+               }
        }
 
        /* Store the important parameters for the DAI configuration and set
@@ -1901,6 +1898,7 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
                             unsigned int fmt)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
+       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
        u8 old_format, format;
 
        /* get format */
@@ -1935,15 +1933,17 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai,
        }
 
        if (format != old_format) {
-
-               /* clear CODECPDZ before changing format (codec requirement) */
-               twl4030_codec_enable(codec, 0);
-
-               /* change format */
-               twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
-
-               /* set CODECPDZ afterwards */
-               twl4030_codec_enable(codec, 1);
+               if (twl4030->codec_powered) {
+                       /*
+                        * If the codec is powered, than we need to toggle the
+                        * codec power.
+                        */
+                       twl4030_codec_enable(codec, 0);
+                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+                       twl4030_codec_enable(codec, 1);
+               } else {
+                       twl4030_write(codec, TWL4030_REG_AUDIO_IF, format);
+               }
        }
 
        return 0;
@@ -2035,6 +2035,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
        struct snd_soc_pcm_runtime *rtd = substream->private_data;
        struct snd_soc_device *socdev = rtd->socdev;
        struct snd_soc_codec *codec = socdev->card->codec;
+       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
        u8 old_mode, mode;
 
        /* Enable voice digital filters */
@@ -2059,10 +2060,17 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream,
        }
 
        if (mode != old_mode) {
-               /* change rate and set CODECPDZ */
-               twl4030_codec_enable(codec, 0);
-               twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
-               twl4030_codec_enable(codec, 1);
+               if (twl4030->codec_powered) {
+                       /*
+                        * If the codec is powered, than we need to toggle the
+                        * codec power.
+                        */
+                       twl4030_codec_enable(codec, 0);
+                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+                       twl4030_codec_enable(codec, 1);
+               } else {
+                       twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode);
+               }
        }
 
        return 0;
@@ -2092,6 +2100,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
                unsigned int fmt)
 {
        struct snd_soc_codec *codec = codec_dai->codec;
+       struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec);
        u8 old_format, format;
 
        /* get format */
@@ -2123,10 +2132,17 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai,
        }
 
        if (format != old_format) {
-               /* change format and set CODECPDZ */
-               twl4030_codec_enable(codec, 0);
-               twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
-               twl4030_codec_enable(codec, 1);
+               if (twl4030->codec_powered) {
+                       /*
+                        * If the codec is powered, than we need to toggle the
+                        * codec power.
+                        */
+                       twl4030_codec_enable(codec, 0);
+                       twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
+                       twl4030_codec_enable(codec, 1);
+               } else {
+                       twl4030_write(codec, TWL4030_REG_VOICE_IF, format);
+               }
        }
 
        return 0;
@@ -2235,7 +2251,6 @@ static int twl4030_soc_probe(struct platform_device *pdev)
        socdev->card->codec = codec;
 
        twl4030_init_chip(pdev);
-       twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
        /* register pcms */
        ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
@@ -2296,6 +2311,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev)
        codec->read = twl4030_read_reg_cache;
        codec->write = twl4030_write;
        codec->set_bias_level = twl4030_set_bias_level;
+       codec->idle_bias_off = 1;
        codec->dai = twl4030_dai;
        codec->num_dai = ARRAY_SIZE(twl4030_dai);
        codec->reg_cache_size = sizeof(twl4030_reg);