diff options
-rw-r--r-- | sound/soc/codecs/twl4030.c | 86 |
1 files changed, 51 insertions, 35 deletions
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index c667ca5a8a9e..45de2aad283c 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -1818,13 +1818,6 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1818 | return -EINVAL; | 1818 | return -EINVAL; |
1819 | } | 1819 | } |
1820 | 1820 | ||
1821 | if (mode != old_mode) { | ||
1822 | /* change rate and set CODECPDZ */ | ||
1823 | twl4030_codec_enable(codec, 0); | ||
1824 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | ||
1825 | twl4030_codec_enable(codec, 1); | ||
1826 | } | ||
1827 | |||
1828 | /* sample size */ | 1821 | /* sample size */ |
1829 | old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); | 1822 | old_format = twl4030_read_reg_cache(codec, TWL4030_REG_AUDIO_IF); |
1830 | format = old_format; | 1823 | format = old_format; |
@@ -1842,16 +1835,20 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, | |||
1842 | return -EINVAL; | 1835 | return -EINVAL; |
1843 | } | 1836 | } |
1844 | 1837 | ||
1845 | if (format != old_format) { | 1838 | if (format != old_format || mode != old_mode) { |
1846 | 1839 | if (twl4030->codec_powered) { | |
1847 | /* clear CODECPDZ before changing format (codec requirement) */ | 1840 | /* |
1848 | twl4030_codec_enable(codec, 0); | 1841 | * If the codec is powered, than we need to toggle the |
1849 | 1842 | * codec power. | |
1850 | /* change format */ | 1843 | */ |
1851 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | 1844 | twl4030_codec_enable(codec, 0); |
1852 | 1845 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | |
1853 | /* set CODECPDZ afterwards */ | 1846 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); |
1854 | twl4030_codec_enable(codec, 1); | 1847 | twl4030_codec_enable(codec, 1); |
1848 | } else { | ||
1849 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | ||
1850 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | ||
1851 | } | ||
1855 | } | 1852 | } |
1856 | 1853 | ||
1857 | /* Store the important parameters for the DAI configuration and set | 1854 | /* 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, | |||
1901 | unsigned int fmt) | 1898 | unsigned int fmt) |
1902 | { | 1899 | { |
1903 | struct snd_soc_codec *codec = codec_dai->codec; | 1900 | struct snd_soc_codec *codec = codec_dai->codec; |
1901 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
1904 | u8 old_format, format; | 1902 | u8 old_format, format; |
1905 | 1903 | ||
1906 | /* get format */ | 1904 | /* get format */ |
@@ -1935,15 +1933,17 @@ static int twl4030_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
1935 | } | 1933 | } |
1936 | 1934 | ||
1937 | if (format != old_format) { | 1935 | if (format != old_format) { |
1938 | 1936 | if (twl4030->codec_powered) { | |
1939 | /* clear CODECPDZ before changing format (codec requirement) */ | 1937 | /* |
1940 | twl4030_codec_enable(codec, 0); | 1938 | * If the codec is powered, than we need to toggle the |
1941 | 1939 | * codec power. | |
1942 | /* change format */ | 1940 | */ |
1943 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | 1941 | twl4030_codec_enable(codec, 0); |
1944 | 1942 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | |
1945 | /* set CODECPDZ afterwards */ | 1943 | twl4030_codec_enable(codec, 1); |
1946 | twl4030_codec_enable(codec, 1); | 1944 | } else { |
1945 | twl4030_write(codec, TWL4030_REG_AUDIO_IF, format); | ||
1946 | } | ||
1947 | } | 1947 | } |
1948 | 1948 | ||
1949 | return 0; | 1949 | return 0; |
@@ -2035,6 +2035,7 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | |||
2035 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 2035 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
2036 | struct snd_soc_device *socdev = rtd->socdev; | 2036 | struct snd_soc_device *socdev = rtd->socdev; |
2037 | struct snd_soc_codec *codec = socdev->card->codec; | 2037 | struct snd_soc_codec *codec = socdev->card->codec; |
2038 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
2038 | u8 old_mode, mode; | 2039 | u8 old_mode, mode; |
2039 | 2040 | ||
2040 | /* Enable voice digital filters */ | 2041 | /* Enable voice digital filters */ |
@@ -2059,10 +2060,17 @@ static int twl4030_voice_hw_params(struct snd_pcm_substream *substream, | |||
2059 | } | 2060 | } |
2060 | 2061 | ||
2061 | if (mode != old_mode) { | 2062 | if (mode != old_mode) { |
2062 | /* change rate and set CODECPDZ */ | 2063 | if (twl4030->codec_powered) { |
2063 | twl4030_codec_enable(codec, 0); | 2064 | /* |
2064 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | 2065 | * If the codec is powered, than we need to toggle the |
2065 | twl4030_codec_enable(codec, 1); | 2066 | * codec power. |
2067 | */ | ||
2068 | twl4030_codec_enable(codec, 0); | ||
2069 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | ||
2070 | twl4030_codec_enable(codec, 1); | ||
2071 | } else { | ||
2072 | twl4030_write(codec, TWL4030_REG_CODEC_MODE, mode); | ||
2073 | } | ||
2066 | } | 2074 | } |
2067 | 2075 | ||
2068 | return 0; | 2076 | return 0; |
@@ -2092,6 +2100,7 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
2092 | unsigned int fmt) | 2100 | unsigned int fmt) |
2093 | { | 2101 | { |
2094 | struct snd_soc_codec *codec = codec_dai->codec; | 2102 | struct snd_soc_codec *codec = codec_dai->codec; |
2103 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | ||
2095 | u8 old_format, format; | 2104 | u8 old_format, format; |
2096 | 2105 | ||
2097 | /* get format */ | 2106 | /* get format */ |
@@ -2123,10 +2132,17 @@ static int twl4030_voice_set_dai_fmt(struct snd_soc_dai *codec_dai, | |||
2123 | } | 2132 | } |
2124 | 2133 | ||
2125 | if (format != old_format) { | 2134 | if (format != old_format) { |
2126 | /* change format and set CODECPDZ */ | 2135 | if (twl4030->codec_powered) { |
2127 | twl4030_codec_enable(codec, 0); | 2136 | /* |
2128 | twl4030_write(codec, TWL4030_REG_VOICE_IF, format); | 2137 | * If the codec is powered, than we need to toggle the |
2129 | twl4030_codec_enable(codec, 1); | 2138 | * codec power. |
2139 | */ | ||
2140 | twl4030_codec_enable(codec, 0); | ||
2141 | twl4030_write(codec, TWL4030_REG_VOICE_IF, format); | ||
2142 | twl4030_codec_enable(codec, 1); | ||
2143 | } else { | ||
2144 | twl4030_write(codec, TWL4030_REG_VOICE_IF, format); | ||
2145 | } | ||
2130 | } | 2146 | } |
2131 | 2147 | ||
2132 | return 0; | 2148 | return 0; |
@@ -2235,7 +2251,6 @@ static int twl4030_soc_probe(struct platform_device *pdev) | |||
2235 | socdev->card->codec = codec; | 2251 | socdev->card->codec = codec; |
2236 | 2252 | ||
2237 | twl4030_init_chip(pdev); | 2253 | twl4030_init_chip(pdev); |
2238 | twl4030_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | ||
2239 | 2254 | ||
2240 | /* register pcms */ | 2255 | /* register pcms */ |
2241 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 2256 | 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) | |||
2296 | codec->read = twl4030_read_reg_cache; | 2311 | codec->read = twl4030_read_reg_cache; |
2297 | codec->write = twl4030_write; | 2312 | codec->write = twl4030_write; |
2298 | codec->set_bias_level = twl4030_set_bias_level; | 2313 | codec->set_bias_level = twl4030_set_bias_level; |
2314 | codec->idle_bias_off = 1; | ||
2299 | codec->dai = twl4030_dai; | 2315 | codec->dai = twl4030_dai; |
2300 | codec->num_dai = ARRAY_SIZE(twl4030_dai); | 2316 | codec->num_dai = ARRAY_SIZE(twl4030_dai); |
2301 | codec->reg_cache_size = sizeof(twl4030_reg); | 2317 | codec->reg_cache_size = sizeof(twl4030_reg); |