]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - sound/soc/codecs/wm8904.c
ASoC: codecs: wm8904: Fix register cache incoherency
[mv-sheeva.git] / sound / soc / codecs / wm8904.c
index 33be84e506ea7d4e2927a4e44a06e49ab648f156..1ec12eff06205f9023b57c5da7b836d6e81a1f4b 100644 (file)
@@ -50,8 +50,6 @@ static const char *wm8904_supply_names[WM8904_NUM_SUPPLIES] = {
 /* codec private data */
 struct wm8904_priv {
 
-       u16 reg_cache[WM8904_MAX_REGISTER + 1];
-
        enum wm8904_type devtype;
        void *control_data;
 
@@ -818,7 +816,8 @@ static int wm8904_get_deemph(struct snd_kcontrol *kcontrol,
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
 
-       return wm8904->deemph;
+       ucontrol->value.enumerated.item[0] = wm8904->deemph;
+       return 0;
 }
 
 static int wm8904_put_deemph(struct snd_kcontrol *kcontrol,
@@ -2093,7 +2092,7 @@ static int wm8904_digital_mute(struct snd_soc_dai *codec_dai, int mute)
 
 static void wm8904_sync_cache(struct snd_soc_codec *codec)
 {
-       struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
+       u16 *reg_cache = codec->reg_cache;
        int i;
 
        if (!codec->cache_sync)
@@ -2104,14 +2103,14 @@ static void wm8904_sync_cache(struct snd_soc_codec *codec)
        /* Sync back cached values if they're different from the
         * hardware default.
         */
-       for (i = 1; i < ARRAY_SIZE(wm8904->reg_cache); i++) {
+       for (i = 1; i < codec->driver->reg_cache_size; i++) {
                if (!wm8904_access[i].writable)
                        continue;
 
-               if (wm8904->reg_cache[i] == wm8904_reg[i])
+               if (reg_cache[i] == wm8904_reg[i])
                        continue;
 
-               snd_soc_write(codec, i, wm8904->reg_cache[i]);
+               snd_soc_write(codec, i, reg_cache[i]);
        }
 
        codec->cache_sync = 0;
@@ -2370,6 +2369,7 @@ static int wm8904_probe(struct snd_soc_codec *codec)
 {
        struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec);
        struct wm8904_pdata *pdata = wm8904->pdata;
+       u16 *reg_cache = codec->reg_cache;
        int ret, i;
 
        codec->cache_sync = 1;
@@ -2436,19 +2436,19 @@ static int wm8904_probe(struct snd_soc_codec *codec)
        }
 
        /* Change some default settings - latch VU and enable ZC */
-       wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
-       wm8904->reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
-       wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
-       wm8904->reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
-       wm8904->reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
+       reg_cache[WM8904_ADC_DIGITAL_VOLUME_LEFT] |= WM8904_ADC_VU;
+       reg_cache[WM8904_ADC_DIGITAL_VOLUME_RIGHT] |= WM8904_ADC_VU;
+       reg_cache[WM8904_DAC_DIGITAL_VOLUME_LEFT] |= WM8904_DAC_VU;
+       reg_cache[WM8904_DAC_DIGITAL_VOLUME_RIGHT] |= WM8904_DAC_VU;
+       reg_cache[WM8904_ANALOGUE_OUT1_LEFT] |= WM8904_HPOUT_VU |
                WM8904_HPOUTLZC;
-       wm8904->reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
+       reg_cache[WM8904_ANALOGUE_OUT1_RIGHT] |= WM8904_HPOUT_VU |
                WM8904_HPOUTRZC;
-       wm8904->reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
+       reg_cache[WM8904_ANALOGUE_OUT2_LEFT] |= WM8904_LINEOUT_VU |
                WM8904_LINEOUTLZC;
-       wm8904->reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
+       reg_cache[WM8904_ANALOGUE_OUT2_RIGHT] |= WM8904_LINEOUT_VU |
                WM8904_LINEOUTRZC;
-       wm8904->reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
+       reg_cache[WM8904_CLOCK_RATES_0] &= ~WM8904_SR_MODE;
 
        /* Apply configuration from the platform data. */
        if (wm8904->pdata) {
@@ -2456,23 +2456,23 @@ static int wm8904_probe(struct snd_soc_codec *codec)
                        if (!pdata->gpio_cfg[i])
                                continue;
 
-                       wm8904->reg_cache[WM8904_GPIO_CONTROL_1 + i]
+                       reg_cache[WM8904_GPIO_CONTROL_1 + i]
                                = pdata->gpio_cfg[i] & 0xffff;
                }
 
                /* Zero is the default value for these anyway */
                for (i = 0; i < WM8904_MIC_REGS; i++)
-                       wm8904->reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
+                       reg_cache[WM8904_MIC_BIAS_CONTROL_0 + i]
                                = pdata->mic_cfg[i];
        }
 
        /* Set Class W by default - this will be managed by the Class
         * G widget at runtime where bypass paths are available.
         */
-       wm8904->reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
+       reg_cache[WM8904_CLASS_W_0] |= WM8904_CP_DYN_PWR;
 
        /* Use normal bias source */
-       wm8904->reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
+       reg_cache[WM8904_BIAS_CONTROL_0] &= ~WM8904_POBCTRL;
 
        wm8904_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
 
@@ -2498,6 +2498,8 @@ static int wm8904_remove(struct snd_soc_codec *codec)
 
        wm8904_set_bias_level(codec, SND_SOC_BIAS_OFF);
        regulator_bulk_free(ARRAY_SIZE(wm8904->supplies), wm8904->supplies);
+       kfree(wm8904->retune_mobile_texts);
+       kfree(wm8904->drc_texts);
 
        return 0;
 }