Merge branch 'for-3.1' into for-3.2
[pandora-kernel.git] / sound / soc / codecs / wm_hubs.c
index 4cc2d56..017522e 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/pm.h>
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
+#include <linux/mfd/wm8994/registers.h>
 #include <sound/core.h>
 #include <sound/pcm.h>
 #include <sound/pcm_params.h>
@@ -116,14 +117,23 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
 {
        struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec);
        s8 offset;
-       u16 reg, reg_l, reg_r, dcs_cfg;
+       u16 reg, reg_l, reg_r, dcs_cfg, dcs_reg;
+
+       switch (hubs->dcs_readback_mode) {
+       case 2:
+               dcs_reg = WM8994_DC_SERVO_4E;
+               break;
+       default:
+               dcs_reg = WM8993_DC_SERVO_3;
+               break;
+       }
 
        /* If we're using a digital only path and have a previously
         * callibrated DC servo offset stored then use that. */
        if (hubs->class_w && hubs->class_w_dcs) {
                dev_dbg(codec->dev, "Using cached DC servo offset %x\n",
                        hubs->class_w_dcs);
-               snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs);
+               snd_soc_write(codec, dcs_reg, hubs->class_w_dcs);
                wait_for_dc_servo(codec,
                                  WM8993_DCS_TRIG_DAC_WR_0 |
                                  WM8993_DCS_TRIG_DAC_WR_1);
@@ -154,8 +164,9 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
                reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
                        & WM8993_DCS_INTEG_CHAN_1_MASK;
                break;
+       case 2:
        case 1:
-               reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
+               reg = snd_soc_read(codec, dcs_reg);
                reg_r = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
                        >> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
                reg_l = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
@@ -168,24 +179,25 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec)
        dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r);
 
        /* Apply correction to DC servo result */
-       if (hubs->dcs_codes) {
-               dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
-                       hubs->dcs_codes);
+       if (hubs->dcs_codes_l || hubs->dcs_codes_r) {
+               dev_dbg(codec->dev,
+                       "Applying %d/%d code DC servo correction\n",
+                       hubs->dcs_codes_l, hubs->dcs_codes_r);
 
                /* HPOUT1R */
                offset = reg_r;
-               offset += hubs->dcs_codes;
+               offset += hubs->dcs_codes_r;
                dcs_cfg = (u8)offset << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
 
                /* HPOUT1L */
                offset = reg_l;
-               offset += hubs->dcs_codes;
+               offset += hubs->dcs_codes_l;
                dcs_cfg |= (u8)offset;
 
                dev_dbg(codec->dev, "DCS result: %x\n", dcs_cfg);
 
                /* Do it */
-               snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
+               snd_soc_write(codec, dcs_reg, dcs_cfg);
                wait_for_dc_servo(codec,
                                  WM8993_DCS_TRIG_DAC_WR_0 |
                                  WM8993_DCS_TRIG_DAC_WR_1);
@@ -217,7 +229,7 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
 
        /* If we're applying an offset correction then updating the
         * callibration would be likely to introduce further offsets. */
-       if (hubs->dcs_codes || hubs->no_series_update)
+       if (hubs->dcs_codes_l || hubs->dcs_codes_r || hubs->no_series_update)
                return ret;
 
        /* Only need to do this if the outputs are active */
@@ -440,9 +452,8 @@ static int hp_event(struct snd_soc_dapm_widget *w,
                reg |= WM8993_HPOUT1L_DLY | WM8993_HPOUT1R_DLY;
                snd_soc_write(codec, WM8993_ANALOGUE_HP_0, reg);
 
-               /* Smallest supported update interval */
                snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
-                                   WM8993_DCS_TIMER_PERIOD_01_MASK, 1);
+                                   WM8993_DCS_TIMER_PERIOD_01_MASK, 0);
 
                calibrate_dc_servo(codec);