diff --git a/apps/lang/english.lang b/apps/lang/english.lang
index 653a0be..7955915 100644
--- a/apps/lang/english.lang
+++ b/apps/lang/english.lang
@@ -10510,14 +10510,23 @@
   <source>
     *: none
     ipodvideo: "Bass Cutoff"
+    mpiohd200: "Bass Cutoff"
+    gigabeatfx: "Bass Cutoff"
+    mrobe100: "Bass Cutoff"
   </source>
   <dest>
     *: none
     ipodvideo: "Bass Cutoff"
+    mpiohd200: "Bass Cutoff"
+    gigabeatfx: "Bass Cutoff"
+    mrobe100: "Bass Cutoff"
   </dest>
   <voice>
     *: none
     ipodvideo: "Bass Cutoff"
+    mpiohd200: "Bass Cutoff"
+    gigabeatfx: "Bass Cutoff"
+    mrobe100: "Bass Cutoff"
   </voice>
 </phrase>
 <phrase>
@@ -10527,14 +10536,23 @@
   <source>
     *: none
     ipodvideo: "Treble Cutoff"
+    mpiohd200: "Treble Cutoff"
+    gigabeatfx: "Treble Cutoff"
+    mrobe100: "Treble Cutoff"
   </source>
   <dest>
     *: none
     ipodvideo: "Treble Cutoff"
+    mpiohd200: "Treble Cutoff"
+    gigabeatfx: "Treble Cutoff"
+    mrobe100: "Treble Cutoff"
   </dest>
   <voice>
     *: none
     ipodvideo: "Treble Cutoff"
+    mpiohd200: "Treble Cutoff"
+    gigabeatfx: "Treble Cutoff"
+    mrobe100: "Treble Cutoff"
   </voice>
 </phrase>
 <phrase>
@@ -12471,14 +12489,17 @@
   <source>
     *: none
     gigabeats: "3-D Enhancement"
+    mpiohd200: "3-D Enhancement"
   </source>
   <dest>
     *: none
     gigabeats: "3-D Enhancement"
+    mpiohd200: "3-D Enhancement"
   </dest>
   <voice>
     *: none
     gigabeats: "3-D Enhancement"
+    mpiohd200: "3-D Enhancement"
   </voice>
 </phrase>
 <phrase>
diff --git a/firmware/drivers/audio/wm8751.c b/firmware/drivers/audio/wm8751.c
index 5eb90b0..8a40aa1 100644
--- a/firmware/drivers/audio/wm8751.c
+++ b/firmware/drivers/audio/wm8751.c
@@ -42,34 +42,96 @@ const struct sound_settings_info audiohw_settings[] = {
     [SOUND_BALANCE]       = {"%",  0,  1,-100, 100,   0},
     [SOUND_CHANNELS]      = {"",   0,  1,   0,   5,   0},
     [SOUND_STEREO_WIDTH]  = {"%",  0,  5,   0, 250, 100},
-#ifdef AUDIOHW_HAVE_DEPTH_3D
-    [SOUND_DEPTH_3D]      = {"",   0,  1,   0,  15,   0},
-#endif
 #ifdef HAVE_RECORDING
-    [SOUND_LEFT_GAIN]     = {"dB", 1,  1,-172, 300,   0},
-    [SOUND_RIGHT_GAIN]    = {"dB", 1,  1,-172, 300,   0},
-    [SOUND_MIC_GAIN]      = {"dB", 1,  1,-172, 300,   0},
+    [SOUND_LEFT_GAIN]     = {"dB", 1, 50,-970, 300,   0},
+    [SOUND_RIGHT_GAIN]    = {"dB", 1, 50,-970, 300,   0},
+    [SOUND_MIC_GAIN]      = {"dB", 1, 50,-970, 300,   0},
+#endif
+#ifdef AUDIOHW_HAVE_BASS_CUTOFF
+    [SOUND_BASS_CUTOFF]   = {"Hz", 0, 70, 130, 200, 200},
+#endif
+#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
+    [SOUND_TREBLE_CUTOFF] = {"kHz",0,  4,   4,   8,   4},
+#endif
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+    [SOUND_DEPTH_3D]      = {"",   0,  1,   -1,  15,   -1},
 #endif
 };
 
-/* Flags used in combination with settings */
-
-/* use zero crossing to reduce clicks during volume changes */
-#define LOUT1_BITS      (LOUT1_LO1ZC)
-/* latch left volume first then update left+right together */
-#define ROUT1_BITS      (ROUT1_RO1ZC | ROUT1_RO1VU)
-#define LOUT2_BITS      (LOUT2_LO2ZC)
-#define ROUT2_BITS      (ROUT2_RO2ZC | ROUT2_RO2VU)
-/* We use linear bass control with 200 Hz cutoff */
-#ifdef USE_ADAPTIVE_BASE
-#define BASSCTRL_BITS   (BASSCTRL_BC | BASSCTRL_BB)
-#else
-#define BASSCTRL_BITS   (BASSCTRL_BC)
+static int prescaler = 0;
+
+static uint16_t wmcodec_regs[WM_NUM_REGS] =
+{
+    [0 ... WM_NUM_REGS-1] = 0x200, /* set invalid data in gaps */
+#ifdef HAVE_WM8750
+    [LINVOL]              = 0x097,
+    [RINVOL]              = 0x097,
+#endif
+    [LOUT1]               = 0x079,
+    [ROUT1]               = 0x079,
+    [DACCTRL]             = 0x008,
+    [AINTFCE]             = 0x00a,
+    [CLOCKING]            = 0x000,
+    [LEFTGAIN]            = 0x0ff,
+    [RIGHTGAIN]           = 0x0ff,
+    [BASSCTRL]            = 0x00f,
+    [TREBCTRL]            = 0x00f,
+/*  [RESET] */
+#ifdef HAVE_WM8750
+    [ENHANCE_3D]          = 0x000,
+    [ALC1]                = 0x07b,
+    [ALC2]                = 0x000,
+    [ALC3]                = 0x032,
+    [NGAT]                = 0x000,
+    [LADCVOL]             = 0x0c3,
+    [RADCVOL]             = 0x0c3,
+#endif
+    [ADDITIONAL1]         = 0x0c0,
+    [ADDITIONAL2]         = 0x000,
+    [PWRMGMT1]            = 0x000,
+    [PWRMGMT2]            = 0x000,
+    [ADDITIONAL3]         = 0x000,
+#ifdef HAVE_WM8750
+    [ADCIM]               = 0x000,
+    [ADCL]                = 0x000,
+    [ADCR]                = 0x000,
 #endif
-/* We use linear treble control with 4 kHz cutoff */
-#define TREBCTRL_BITS   (TREBCTRL_TC)
+    [LEFTMIX1]            = 0x050,
+    [LEFTMIX2]            = 0x050,
+    [RIGHTMIX1]           = 0x050,
+    [RIGHTMIX2]           = 0x050,
+    [MONOMIX1]            = 0x050,
+    [MONOMIX2]            = 0x050,
+    [LOUT2]               = 0x079,
+    [ROUT2]               = 0x079,
+    [MONOOUT]             = 0x079
+};
 
-static int prescaler = 0;
+static void wmcodec_set_reg(unsigned int reg, unsigned int val)
+{
+    if (reg >= WM_NUM_REGS || (wmcodec_regs[reg] & 0x200))
+        /* invalid register */
+        return;
+
+    wmcodec_regs[reg] = val & 0x1ff;
+    wmcodec_write(reg, wmcodec_regs[reg]);
+}
+
+static void wmcodec_set_bits(unsigned int reg, unsigned int bits)
+{
+    wmcodec_set_reg(reg, wmcodec_regs[reg] | bits);
+}
+
+static void wmcodec_clear_bits(unsigned int reg, unsigned int bits)
+{
+    wmcodec_set_reg(reg, wmcodec_regs[reg] & ~bits);
+}
+
+static void wmcodec_set_masked(unsigned int reg, unsigned int val, 
+                          unsigned int mask )
+{
+    wmcodec_set_reg(reg, (wmcodec_regs[reg] & ~mask) | val);
+}
 
 /* convert tenth of dB volume (-730..60) to master volume register value */
 int tenthdb2master(int db)
@@ -98,51 +160,6 @@ static int tone_tenthdb2hw(int value)
     return value;
 }
 
-#if 0
-static int alc_tenthdb2hw(int value)
-{
-   /* -28.5dB - -6dB step 1.5dB - translate -285 - -60 step 15
-      to 0 - 15 step 1
-    */
-
-    value = 15 - (value + 60)/15;
-}
-
-
-static int alc_hldus2hw(unsigned int value)
-{
-    /* 0000 -        0us
-     * 0001 -     2670us
-     * 0010 -     5330us
-     *
-     * 1111 - 43691000us
-     */
-    return 0;
-}
-
-static int alc_dcyms2hw(int value)
-{
-    /* 0000 - 24ms
-     * 0001 - 48ms
-     * 0010 - 96ms
-     *
-     * 1010 or higher 24580ms
-     */
-    return 0;  
-}
-
-static int alc_atkms2hw(int value)
-{
-    /* 0000 -  6ms
-     * 0001 - 12ms
-     * 0010 - 24ms
-     *
-     * 1010 or higher 6140ms
-     */
-    return 0;
-}
-#endif
-
 #ifdef USE_ADAPTIVE_BASS
 static int adaptivebass2hw(int value)
 {
@@ -153,31 +170,44 @@ static int adaptivebass2hw(int value)
 }
 #endif
 
-#if defined(HAVE_WM8750)
-#if 0
-static int ngath_tenthdb2hw(int value)
+#ifdef AUDIOHW_HAVE_BASS_CUTOFF
+void audiohw_set_bass_cutoff(int val)
 {
-    /* -76.5dB - -30dB in 1.5db steps   -765 - -300 in 15 steps */
-    value = 31 - (value + 300)/15;
-    return value;
+     if ( val == 130 )
+         wmcodec_clear_bits(BASSCTRL, BASSCTRL_BC);
+     else
+         wmcodec_set_bits(BASSCTRL, BASSCTRL_BC);
+
+}
+#endif
+
+#ifdef AUDIOHW_HAVE_TREBLE_CUTOFF
+void audiohw_set_treble_cutoff(int val)
+{
+    if ( val == 8 )
+        wmcodec_clear_bits(TREBCTRL, TREBCTRL_TC);
+    else
+        wmcodec_set_bits(TREBCTRL, TREBCTRL_TC); 
 }
 #endif
+
+#if defined(HAVE_WM8750) && defined(HAVE_RECORDING)
 static int recvol2hw(int value)
 {
-/* convert tenth of dB of input volume (-172...300) to input register value */
-    /* +30dB to -17.25 0.75dB step 6 bits */
-    /* 111111 == +30dB  (0x3f)            */
-    /* 010111 ==   0dB  (0x17)            */
-    /* 000000 == -17.25dB                 */
+   /* -970...300 to input register value */
 
-    return ((4*(value))/30 + 0x17);
+   return ((2*value)/10 + 0xc3);
 }
 #endif
+
 static void audiohw_mute(bool mute)
 {
     /* Mute:   Set DACMU = 1 to soft-mute the audio DACs. */
     /* Unmute: Set DACMU = 0 to soft-un-mute the audio DACs. */
-    wmcodec_write(DACCTRL, mute ? DACCTRL_DACMU : 0);
+    if (mute)
+        wmcodec_set_bits(DACCTRL,DACCTRL_DACMU);
+    else
+        wmcodec_clear_bits(DACCTRL,DACCTRL_DACMU);
 }
 
 /* Reset and power up the WM8751 */
@@ -201,14 +231,14 @@ void audiohw_preinit(void)
     wmcodec_write(RESET, RESET_RESET);    /*Reset*/
 
      /* 2. Enable Vmid and VREF. */
-    wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_5K);
+    wmcodec_set_bits(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_5K);
 
 #ifdef CODEC_SLAVE
-    wmcodec_write(AINTFCE,AINTFCE_WL_16|AINTFCE_FORMAT_I2S);
+    wmcodec_set_bits(AINTFCE,AINTFCE_WL_16|AINTFCE_FORMAT_I2S);
 #else
     /* BCLKINV=0(Dont invert BCLK) MS=1(Enable Master) LRSWAP=0 LRP=0 */
     /* IWL=00(16 bit) FORMAT=10(I2S format) */
-    wmcodec_write(AINTFCE, AINTFCE_MS | AINTFCE_WL_16 |
+    wmcodec_set_bits(AINTFCE, AINTFCE_MS | AINTFCE_WL_16 |
                   AINTFCE_FORMAT_I2S);
 #endif
     /* Set default samplerate */
@@ -222,50 +252,62 @@ void audiohw_postinit(void)
     /* From app notes: allow Vref to stabilize to reduce clicks */
     sleep(HZ);
 
+
+#ifdef AUDIOHW_HAVE_DEPTH_3D
+    wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK);
+#endif
+
+#ifdef USE_ADAPTIVE_BASS
+    wmcodec_set_bits(BASSCTRL, BASSCTRL_BB);
+#endif
+
      /* 3. Enable DACs as required. */
-    wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR);
+    wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR);
 
      /* 4. Enable line and / or headphone output buffers as required. */
 #if defined(MROBE_100) || defined(MPIO_HD200)
-    /* fix for high pitch noise after power-up on HD200
-     * it is *NOT* required step according to the
-     * Datasheet for WM8750L but real life is different :-)
-     */
-    wmcodec_write(LOUT1, LOUT1_BITS);
-    wmcodec_write(ROUT1, ROUT1_BITS);
-
-    /* power-up output stage */
-    wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                  PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+     /* power-up output stage */
+    wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
 #else
-    wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                  PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | PWRMGMT2_LOUT2 |
-                  PWRMGMT2_ROUT2);
+    wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 | 
+                     PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2);
 #endif
 
     /* Full -0dB on the DACS */
-    wmcodec_write(LEFTGAIN, 0xff);
-    wmcodec_write(RIGHTGAIN, RIGHTGAIN_RDVU | 0xff);
+    wmcodec_set_bits(LEFTGAIN, 0xff);
+    wmcodec_set_bits(RIGHTGAIN, RIGHTGAIN_RDVU | 0xff);
 
-    wmcodec_write(ADDITIONAL1, ADDITIONAL1_TSDEN | ADDITIONAL1_TOEN |
+    /* Enable Thermal shutdown, Timeout when zero-crossing in use,
+     * set analog bias for 3.3V, monomix to DACR
+     */
+    wmcodec_set_reg(ADDITIONAL1, ADDITIONAL1_TSDEN | ADDITIONAL1_TOEN |
                     ADDITIONAL1_DMONOMIX_LLRR | ADDITIONAL1_VSEL_DEFAULT);
 
-    wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO | LEFTMIX1_LI2LO_DEFAULT);
-    wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO | RIGHTMIX2_RI2RO_DEFAULT);
+
+    /* Enable zero-crossing in out stage */
+    wmcodec_set_bits(LOUT1, LOUT1_LO1ZC);
+    wmcodec_set_bits(ROUT1, ROUT1_RO1ZC);
+    wmcodec_set_bits(LOUT2, LOUT2_LO2ZC);
+    wmcodec_set_bits(ROUT2, ROUT2_RO2ZC);
+
+    /* route signal from DAC to mixers */
+    wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
+    wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
 
 #ifdef TOSHIBA_GIGABEAT_F
 #ifdef HAVE_HARDWARE_BEEP
     /* Single-ended mono input */
-    wmcodec_write(MONOMIX1, 0);
+    wmcodec_set_reg(MONOMIX1, 0x00);
 
     /* Route mono input to both outputs at 0dB */
-    wmcodec_write(LEFTMIX2, LEFTMIX2_MI2LO | LEFTMIX2_MI2LOVOL(2));
-    wmcodec_write(RIGHTMIX1, RIGHTMIX1_MI2RO | RIGHTMIX1_MI2ROVOL(2));
+    wmcodec_set_reg(LEFTMIX2, LEFTMIX2_MI2LO | LEFTMIX2_MI2LOVOL(2));
+    wmcodec_set_reg(RIGHTMIX1, RIGHTMIX1_MI2RO | RIGHTMIX1_MI2ROVOL(2));
 #endif
 #endif
 
     /* lower power consumption */
-    wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
+    wmcodec_set_masked(PWRMGMT1, PWRMGMT1_VMIDSEL_50K,
+                       PWRMGMT1_VMIDSEL_MASK);
 
     audiohw_mute(false);
 
@@ -274,6 +316,11 @@ void audiohw_postinit(void)
     GPIOL_OUTPUT_VAL &= ~0x10;
     GPIOL_OUTPUT_EN  |=  0x10;
 #endif
+
+#ifdef MPIO_HD200
+   /* enable headphone output */
+   or_l((1<<25),&GPIO1_OUT);
+#endif
 }
 
 void audiohw_set_master_vol(int vol_l, int vol_r)
@@ -284,41 +331,45 @@ void audiohw_set_master_vol(int vol_l, int vol_r)
     /* 0110000 == -73dB                                    */
     /* 0101111 == mute (0x2f)                              */
 
-    wmcodec_write(LOUT1, LOUT1_BITS | LOUT1_LOUT1VOL(vol_l));
-    wmcodec_write(ROUT1, ROUT1_BITS | ROUT1_ROUT1VOL(vol_r));
+    wmcodec_set_masked(LOUT1, LOUT1_LOUT1VOL(vol_l),
+                       LOUT1_LOUT1VOL_MASK);
+    wmcodec_set_masked(ROUT1, ROUT1_RO1VU | ROUT1_ROUT1VOL(vol_r),
+                       ROUT1_ROUT1VOL_MASK);
 }
 
-#ifndef MROBE_100
+#ifdef TOSHIBA_GIGABEAT_F
 void audiohw_set_lineout_vol(int vol_l, int vol_r)
 {
-    wmcodec_write(LOUT2, LOUT2_BITS | LOUT2_LOUT2VOL(vol_l));
-    wmcodec_write(ROUT2, ROUT2_BITS | ROUT2_ROUT2VOL(vol_r));
+    wmcodec_set_masked(LOUT2, LOUT2_LOUT2VOL(vol_l),
+                       LOUT2_LOUT2VOL_MASK);
+    wmcodec_set_masked(ROUT2, ROUT2_RO2VU | ROUT2_ROUT2VOL(vol_r),
+                       ROUT2_ROUT2VOL_MASK);
 }
 #endif
 
 void audiohw_set_bass(int value)
 {
-    wmcodec_write(BASSCTRL, BASSCTRL_BITS |
+    wmcodec_set_masked(BASSCTRL,
 
 #ifdef USE_ADAPTIVE_BASS
-        BASSCTRL_BASS(adaptivebass2hw(value)));
+        BASSCTRL_BASS(adaptivebass2hw(value)),BASSCTRL_BASS_MASK);
 #else
-        BASSCTRL_BASS(tone_tenthdb2hw(value)));
+        BASSCTRL_BASS(tone_tenthdb2hw(value)),BASSCTRL_BASS_MASK);
 #endif
 }
 
 void audiohw_set_treble(int value)
 {
-    wmcodec_write(TREBCTRL, TREBCTRL_BITS |
-        TREBCTRL_TREB(tone_tenthdb2hw(value)));
+    wmcodec_set_masked(TREBCTRL, TREBCTRL_TREB(tone_tenthdb2hw(value)),
+                       TREBCTRL_TREB_MASK);
 }
 
 void audiohw_set_prescaler(int value)
 {
     prescaler = 3 * value / 15;
-    wmcodec_write(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL));
-    wmcodec_write(RIGHTGAIN, RIGHTGAIN_RDVU |
-                  (0xff - (prescaler & RIGHTGAIN_RDACVOL)));
+    wmcodec_set_reg(LEFTGAIN, 0xff - (prescaler & LEFTGAIN_LDACVOL));
+    wmcodec_set_reg(RIGHTGAIN, RIGHTGAIN_RDVU | 
+                    (0xff - (prescaler & RIGHTGAIN_RDACVOL)));
 }
 
 /* Nice shutdown of WM8751 codec */
@@ -327,11 +378,16 @@ void audiohw_close(void)
     /* 1. Set DACMU = 1 to soft-mute the audio DACs. */
     audiohw_mute(true);
 
+#ifdef MPIO_HD200
+    /* disable headphone out */
+    and_l(~(1<<25), &GPIO1_OUT);
+#endif
+
     /* 2. Disable all output buffers. */
-    wmcodec_write(PWRMGMT2, 0x0);
+    wmcodec_set_reg(PWRMGMT2, 0x00);
 
     /* 3. Switch off the power supplies. */
-    wmcodec_write(PWRMGMT1, 0x0);
+    wmcodec_set_reg(PWRMGMT1, 0x00);
 }
 
 /* According to datasheet of WM8750
@@ -351,26 +407,31 @@ void audiohw_set_frequency(int fsel)
     if ((unsigned)fsel >= HW_NUM_FREQ)
         fsel = HW_FREQ_DEFAULT;
 
-    wmcodec_write(CLOCKING, srctrl_table[fsel]);
+    wmcodec_set_reg(CLOCKING, srctrl_table[fsel]);
 }
 
-#if defined(HAVE_WM8750)
+#ifdef HAVE_WM8750
 #ifdef AUDIOHW_HAVE_DEPTH_3D
 /* Set the depth of the 3D effect */
 void audiohw_set_depth_3d(int val)
 {
-    if (val)
-        wmcodec_write(ENHANCE_3D,
-                      ENHANCE_3D_MODE3D_PLAYBACK | ENHANCE_3D_DEPTH(val) |
-                      ENHANCE_3D_3DEN);
+    if (val >= 0)
+    {
+        if ( !(wmcodec_regs[ENHANCE_3D] & ENHANCE_3D_3DEN) )
+            wmcodec_set_bits(ENHANCE_3D, ENHANCE_3D_3DEN);
+
+        wmcodec_set_masked(ENHANCE_3D, ENHANCE_3D_DEPTH(val),
+                           ENHANCE_3D_DEPTH_MASK);
+    }
     else
-        wmcodec_write(ENHANCE_3D,ENHANCE_3D_MODE3D_PLAYBACK);
+    {
+        wmcodec_clear_bits(ENHANCE_3D, ENHANCE_3D_3DEN);
+    }
 }
 #endif
 
 #ifdef HAVE_RECORDING
-#if 0
-void audiohw_set_ngath(int ngath, int type, bool enable)
+static void audiohw_set_ngat(int ngath, int type, bool enable)
 {
     /* This function controls Noise gate function
      * of the codec. This can only run in conjunction
@@ -378,63 +439,33 @@ void audiohw_set_ngath(int ngath, int type, bool enable)
      */
 
     if(enable)
-        wmcodec_write(NGAT, NGAT_NGG(type)|NGAT_NGTH(ngath)|NGAT_NGAT);
+        wmcodec_set_reg(NGAT, NGAT_NGG(type) |
+                        NGAT_NGTH(ngath) | NGAT_NGAT);
     else
-        wmcodec_write(NGAT, NGAT_NGG(type)|NGAT_NGTH(ngath_tenthdb2hw(ngath)));
+        wmcodec_clear_bits(NGAT, NGAT_NGAT);
 }
 
 
-void audiohw_set_alc(int level, unsigned int hold, int decay, int attack, bool enable)
+static void audiohw_set_alc(unsigned char level,  /* signal level at ADC */
+                            bool zc,              /* zero cross detection */
+                            unsigned char hold,   /* hold time */
+                            unsigned char decay,  /* decay time */
+                            unsigned char attack, /* attack time */
+                            bool enable)          /* hw function on/off */
 {
-    /* level in thenth of dB -28.5dB - -6dB in 1.5dB steps
-     * hold time in us 0us - 43691000us
-     * decay time in ms 24ms - 24580ms
-     * attack time in ms 6ms - 6140ms
-     */
-
-    if(enable)
-    {
-        wmcodec_write(ALC1, ALC1_ALCSEL_STEREO|ALC1_MAXGAIN(0x07)|
-                      ALC1_ALCL(alc_tenthdb2hw(level)));
-        wmcodec_write(ALC2, ALC2_ALCZ|ALC2_HLD(alc_hldus2hw(hold)));
-        wmcodec_write(ALC3, ALC3_DCY(alc_dcyms2hw(decay))|
-                      ALC3_ATK(alc_atkms2hw(attack)));
-    }
-    else
-    {
-        wmcodec_write(ALC1, ALC1_ALCSEL_DISABLED|ALC1_MAXGAIN(0x07)|ALC1_ALCL(alc_tenthdb2hw(level)));
-    }
-}
-
-void audiohw_set_alc(int level, unsigned int hold, int decay, int attack, bool enable)
-{
-    /* level in thenth of dB -28.5dB - -6dB in 1.5dB steps
-     * hold time in 15 steps 0ms,2.67ms,5.33ms,...,43691ms
-     * decay time in 10 steps 24ms,48ms,96ms,...,24580ms
-     * attack time in 10 steps 6ms,12ms,24ms,...,6140ms
-     */
-
     if(enable)
     {
-        wmcodec_write(ALC1, ALC1_ALCSEL_STEREO|ALC1_MAXGAIN(0x07)|
-                      ALC1_ALCL(alc_tenthdb2hw(level)));
-        wmcodec_write(ALC2, ALC2_ALCZ|ALC2_HLD(hold));
-        wmcodec_write(ALC3, ALC3_DCY(decay)|
-                      ALC3_ATK(attack));
+        wmcodec_set_reg(ALC1, ALC1_ALCSEL_STEREO | ALC1_MAXGAIN(0x07) |
+                        ALC1_ALCL(level));
+        wmcodec_set_reg(ALC2, zc?ALC2_ALCZC:0 | ALC2_HLD(hold));
+        wmcodec_set_reg(ALC3, ALC3_DCY(decay) | ALC3_ATK(attack));
     }
     else
     {
-        wmcodec_write(ALC1, ALC1_ALCSEL_DISABLED|ALC1_MAXGAIN(0x07)|
-                      ALC1_ALCL(alc_tenthdb2hw(level)));
+        wmcodec_set_masked(ALC1, ALC1_ALCSEL_DISABLED, ALC1_ALCSEL_MASK);
     }
 }
 
-void audiohw_set_alc_level(int level)
-{
-    wmcodec_write(ALC1, ALC1_ALCSEL_STEREO|ALC1_MAXGAIN(0x07)|
-                  ALC1_ALCL(alc_tenthdb2hw(level)));
-}
-#endif
 void audiohw_set_recsrc(int source, bool recording)
 {
     /* INPUT1 - FM radio
@@ -453,29 +484,20 @@ void audiohw_set_recsrc(int source, bool recording)
     switch(source)
     {
     case AUDIO_SRC_PLAYBACK:
-        /* turn off DAC and ADC in order to setup Enchance 3D function
-         * for playback. This does not turn on enchancement but
-         * the switch between playback/record has to be done with
-         * DAC and ADC off
-         */
-#ifdef AUDIOHW_HAVE_DEPTH_3D
-        wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
-        wmcodec_write(PWRMGMT2, 0x00);
-        wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_PLAYBACK);
-#endif
-        /* mute PGA, disable all audio paths but DAC and output stage*/
-        wmcodec_write(LINVOL, LINVOL_LINMUTE | LINVOL_LINVOL(0x17)); /* 0dB */
-        wmcodec_write(RINVOL, RINVOL_RINMUTE | RINVOL_RINVOL(0x17)); /* 0dB */
+        audiohw_mute(true);
 
-        wmcodec_write(LOUT1, LOUT1_BITS);
-        wmcodec_write(ROUT1, ROUT1_BITS);
+        /* mute PGA, disable all audio paths but DAC and output stage*/
+        wmcodec_set_bits(LINVOL, LINVOL_LINMUTE); /* Mute */
+        wmcodec_set_bits(RINVOL, RINVOL_RINMUTE); /* Mute */
 
-        wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                      PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+        wmcodec_clear_bits(PWRMGMT2, PWRMGMT2_OUT3 | PWRMGMT2_MOUT |
+                           PWRMGMT2_ROUT2 | PWRMGMT2_LOUT2);
 
-        /* route DAC signal to output mixer */
-        wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
-        wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
+        /* route DAC signal to output mixer, disable INPUT routing */
+        wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
+        wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
+        wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
+        wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
 
         /* unmute DAC */
         audiohw_mute(false);
@@ -484,31 +506,22 @@ void audiohw_set_recsrc(int source, bool recording)
     case AUDIO_SRC_FMRADIO:
         if(recording)
         {
-            /* turn off DAC and ADC in order to setup Enchance 3D function
-             * for playback. This does not turn on enchancement but
-             * the switch between playback/record has to be done with
-             * DAC and ADC off
-             */
-#ifdef AUDIOHW_HAVE_DEPTH_3D
-              wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
-              wmcodec_write(PWRMGMT2, 0x00);
-              wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_RECORD);
-#endif
-
+            audiohw_mute(true);
             /* Turn on PGA and ADC */
-            wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K |
-                          PWRMGMT1_AINL | PWRMGMT1_AINR | 
-                          PWRMGMT1_ADCL | PWRMGMT1_ADCR);
+            wmcodec_set_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR | 
+                             PWRMGMT1_ADCL | PWRMGMT1_ADCR);
 
             /* Set input volume to PGA 0dB*/
-            wmcodec_write(LINVOL, LINVOL_LIVU|LINVOL_LINVOL(0x17));
-            wmcodec_write(RINVOL, RINVOL_RIVU|RINVOL_RINVOL(0x17));
+            wmcodec_set_reg(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(0x17));
+            wmcodec_set_reg(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(0x17));
 
-            /* Setup input source for PGA as INPUT1 
-             * MICBOOST disabled
-             */
-            wmcodec_write(ADCL, ADCL_LINSEL_LINPUT1 | ADCL_LMICBOOST_DISABLED);
-            wmcodec_write(ADCR, ADCR_RINSEL_RINPUT1 | ADCR_RMICBOOST_DISABLED);
+            /* Setup input source for PGA as INPUT1 */
+            wmcodec_set_masked(ADCL, ADCL_LINSEL_LINPUT1, ADCL_LINSEL_MASK);
+            wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT1, ADCR_RINSEL_MASK);
+
+           /* turn off ALC and NGAT as OF do */
+           audiohw_set_alc(0x00, false, 0x00, 0x00, 0x00, false);
+           audiohw_set_ngat(0x00, 0x00, false);
 
             /* setup output digital data
              * default is LADC -> LDATA, RADC -> RDATA
@@ -516,115 +529,131 @@ void audiohw_set_recsrc(int source, bool recording)
              */
 
             /* power up DAC and output stage */
-            wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                          PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+            /* skip as DAC and output stage is never powered down 
+            wmcodec_set_bits(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
+                             PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+            */
 
-            /* route DAC signal to output mixer */
-            wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
-            wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
+            /* route DAC signal to output mixer, disable INPUT routing */
+            wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
+            wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
+            wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
+            wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
+            
+            audiohw_mute(false);
         }
         else
         {
+            audiohw_mute(true);
             /* turn off ADC, PGA */
-            wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
-
-            wmcodec_write(LOUT1, LOUT1_BITS);
-            wmcodec_write(ROUT1, ROUT1_BITS);
-
-           /* turn on DAC and output stage */
-            wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                          PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+            wmcodec_clear_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
+                               PWRMGMT1_ADCL | PWRMGMT1_ADCR);
 
            /* setup monitor mode by routing input signal to outmix 
             * at 0dB volume
             */
-            wmcodec_write(LEFTMIX1, LEFTMIX1_LI2LO | LEFTMIX1_LMIXSEL_LINPUT1 |
-                          LEFTMIX1_LI2LOVOL(0x20) | LEFTMIX1_LD2LO);
-            wmcodec_write(RIGHTMIX1, RIGHTMIX1_RMIXSEL_RINPUT1);
-            wmcodec_write(RIGHTMIX2, RIGHTMIX2_RI2RO |
-                          RIGHTMIX2_RI2ROVOL(0x20) | RIGHTMIX2_RD2RO);
+            wmcodec_set_masked(LEFTMIX1, LEFTMIX1_LI2LOVOL(0x20),
+                               LEFTMIX1_LI2LOVOL_MASK);
+
+            wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LI2LO | 
+                             LEFTMIX1_LMIXSEL_LINPUT1 |
+                             LEFTMIX1_LD2LO);
+
+            wmcodec_set_masked(RIGHTMIX2, RIGHTMIX2_RI2ROVOL(0x20),
+                               RIGHTMIX2_RI2ROVOL_MASK);
+            wmcodec_set_bits(RIGHTMIX1, RIGHTMIX1_RMIXSEL_RINPUT1);
+            wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RI2RO |
+                             RIGHTMIX2_RD2RO);
+
+            audiohw_mute(false);
         }
         break;
 
     case AUDIO_SRC_LINEIN:
-#ifdef AUDIOHW_HAVE_DEPTH_3D
-        wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
-        wmcodec_write(PWRMGMT2, 0x00);
-        wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_RECORD);
-#endif
-
-        /* Set input volume to PGA */
-        wmcodec_write(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(23));
-        wmcodec_write(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(23));
+        audiohw_mute(true);
 
-        /* Turn on PGA, ADC */
-        wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K |
-                      PWRMGMT1_AINL | PWRMGMT1_AINR | 
-                      PWRMGMT1_ADCL | PWRMGMT1_ADCR);
+        /* Turn on PGA and ADC */
+        wmcodec_set_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
+                         PWRMGMT1_ADCL | PWRMGMT1_ADCR);
 
-        /* turn on DAC and output stage */
-        wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                      PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+        /* Set input volume to PGA 0dB*/
+        wmcodec_set_reg(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(0x17));
+        wmcodec_set_reg(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(0x17));
 
         /* Setup input source for PGA as INPUT2 
          * MICBOOST disabled
          */
-        wmcodec_write(ADCL, ADCL_LINSEL_LINPUT2 | ADCL_LMICBOOST_DISABLED);
-        wmcodec_write(ADCR, ADCR_RINSEL_RINPUT2 | ADCR_RMICBOOST_DISABLED);
+        wmcodec_set_masked(ADCL, ADCL_LINSEL_LINPUT2, ADCL_LINSEL_MASK);
+        wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT2, ADCR_RINSEL_MASK);
+
+        /* setup ALC and NGAT as OF do */
+        /* level, zc, hold, decay, attack, enable */
+        audiohw_set_alc(0x0b, true, 0x00, 0x03, 0x02, true);
+        /* ngath, type, enable */
+        audiohw_set_ngat(0x08, 0x02, true);
 
         /* setup output digital data
          * default is LADC -> LDATA, RADC -> RDATA
          * so we don't touch this
          */
-        /* route DAC signal to output mixer */
-        wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
-        wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
+        /* route DAC signal to output mixer, disable INPUT routing */
+        wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
+        wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
+        wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
+        wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
+
+        audiohw_mute(false);
         break;
 
     case AUDIO_SRC_MIC:
-#ifdef AUDIOHW_HAVE_DEPTH_3D
-          wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K);
-          wmcodec_write(PWRMGMT2, 0x00);
-          wmcodec_write(ENHANCE_3D, ENHANCE_3D_MODE3D_RECORD);
-#endif
-
-        /* Set input volume to PGA */
-        wmcodec_write(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(23));
-        wmcodec_write(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(23));
+        audiohw_mute(true);
 
-        /* Turn on PGA and ADC, turn off DAC */
-        wmcodec_write(PWRMGMT1, PWRMGMT1_VREF | PWRMGMT1_VMIDSEL_50K |
-                      PWRMGMT1_AINL | PWRMGMT1_AINR | 
-                      PWRMGMT1_ADCL | PWRMGMT1_ADCR);
+        /* Turn on PGA and ADC */
+        wmcodec_set_bits(PWRMGMT1, PWRMGMT1_AINL | PWRMGMT1_AINR |
+                         PWRMGMT1_ADCL | PWRMGMT1_ADCR);
 
-        /* turn on DAC and output stage */
-        wmcodec_write(PWRMGMT2, PWRMGMT2_DACL | PWRMGMT2_DACR |
-                      PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
+        /* Set input volume to PGA 0dB*/
+        wmcodec_set_reg(LINVOL, LINVOL_LIVU | LINVOL_LINVOL(0x17));
+        wmcodec_set_reg(RINVOL, RINVOL_RIVU | RINVOL_RINVOL(0x17));
 
-        /* Setup input source for PGA as INPUT3 
+        /* Setup input source for PGA as INPUT2 
          * MICBOOST disabled
          */
-        wmcodec_write(ADCL, ADCL_LINSEL_LINPUT3 | ADCL_LMICBOOST_DISABLED);
-        wmcodec_write(ADCR, ADCR_RINSEL_RINPUT3 | ADCR_RMICBOOST_DISABLED);
+        wmcodec_set_masked(ADCL, ADCL_LINSEL_LINPUT3, ADCL_LINSEL_MASK);
+        wmcodec_set_masked(ADCR, ADCR_RINSEL_RINPUT3, ADCR_RINSEL_MASK);
+
+        /* setup ALC and NGAT as OF do */
+        /* level, zc, hold, decay, attack, enable */
+        audiohw_set_alc(0x0f, false, 0x00, 0x05, 0x02, true);
+        /* ngath, type, enable */
+        audiohw_set_ngat(0x1f, 0x00, true);
 
         /* setup output digital data
          * default is LADC -> LDATA, RADC -> RDATA
          * so we don't touch this
          */
+        /* route DAC signal to output mixer, disable INPUT routing */
+        wmcodec_clear_bits(LEFTMIX1, LEFTMIX1_LI2LO);
+        wmcodec_set_bits(LEFTMIX1, LEFTMIX1_LD2LO);
+        wmcodec_clear_bits(RIGHTMIX2, RIGHTMIX2_RI2RO);
+        wmcodec_set_bits(RIGHTMIX2, RIGHTMIX2_RD2RO);
 
-        /* route DAC signal to output mixer */
-        wmcodec_write(LEFTMIX1, LEFTMIX1_LD2LO);
-        wmcodec_write(RIGHTMIX2, RIGHTMIX2_RD2RO);
-
+        audiohw_mute(false);
     } /* switch(source) */
 }
 
-/* Setup PGA gain */
+/* Setup digital gain */
 void audiohw_set_recvol(int vol_l, int vol_r, int type)
 {
     (void)type;
-    wmcodec_write(LINVOL, LINVOL_LIZC|LINVOL_LINVOL(recvol2hw(vol_l)));
-    wmcodec_write(RINVOL, RINVOL_RIZC|RINVOL_RIVU|RINVOL_RINVOL(recvol2hw(vol_r)));
+    wmcodec_set_reg(LADCVOL, LADCVOL_LADCVOL(recvol2hw(vol_l)));
+
+    if (type == AUDIO_GAIN_MIC)
+        wmcodec_set_reg(RADCVOL, RADCVOL_RAVU | 
+                        RADCVOL_RADCVOL(recvol2hw(vol_l)));
+    else
+        wmcodec_set_reg(RADCVOL, RADCVOL_RAVU | 
+                        RADCVOL_RADCVOL(recvol2hw(vol_r)));
 }
 #endif /* HAVE_RECORDING */
 #endif /* HAVE_WM8750 */
diff --git a/firmware/export/wm8751.h b/firmware/export/wm8751.h
index a7c28a9..3bbf744 100644
--- a/firmware/export/wm8751.h
+++ b/firmware/export/wm8751.h
@@ -25,13 +25,15 @@
 #define VOLUME_MIN -730
 #define VOLUME_MAX  60
 
-/* turn off 3D Enchance feature of WM8750 for now
 #if defined(HAVE_WM8750)
-#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | DEPTH_3D_CAP)
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \
+                      BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP | \
+                      DEPTH_3D_CAP)
 #else
-*/
-#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP)
-/* #endif */
+
+#define AUDIOHW_CAPS (BASS_CAP | TREBLE_CAP | PRESCALER_CAP | \
+                      BASS_CUTOFF_CAP | TREBLE_CUTOFF_CAP)
+#endif
 
 extern int tenthdb2master(int db);
 
@@ -60,12 +62,13 @@ void audiohw_set_recsrc(int source, bool recording);
 #endif
 
 #define LOUT1                       0x02
-#define LOUT1_LOUT1VOL_MASK         (0x07f << 0)
+#define LOUT1_LOUT1VOL_MASK         0x07f
 #define LOUT1_LOUT1VOL(x)           ((x) & 0x7f)
 #define LOUT1_LO1ZC                 (1 << 7)
 #define LOUT1_LO1VU                 (1 << 8)
 
 #define ROUT1                       0x03
+#define ROUT1_ROUT1VOL_MASK         0x17f
 #define ROUT1_ROUT1VOL(x)           ((x) & 0x7f)
 #define ROUT1_RO1ZC                 (1 << 7)
 #define ROUT1_RO1VU                 (1 << 8)
@@ -110,11 +113,13 @@ void audiohw_set_recsrc(int source, bool recording);
 #define RIGHTGAIN_RDVU              (1 << 8)
 
 #define BASSCTRL                    0x0c
+#define BASSCTRL_BASS_MASK          0x0f
 #define BASSCTRL_BASS(x)            ((x) & 0xf)
 #define BASSCTRL_BC                 (1 << 6)
 #define BASSCTRL_BB                 (1 << 7)
 
 #define TREBCTRL                    0x0d
+#define TREBCTRL_TREB_MASK          0x0f
 #define TREBCTRL_TREB(x)            ((x) & 0xf)
 #define TREBCTRL_TC                 (1 << 6)
 
@@ -125,6 +130,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #define ENHANCE_3D                  0x10
 #define ENHANCE_3D_3DEN             (1 << 0)
 #define ENHANCE_3D_DEPTH(x)         (((x) & 0xf) << 1)
+#define ENHANCE_3D_DEPTH_MASK       (0x0f << 1)
 #define ENHANCE_3D_3DLC             (1 << 5)
 #define ENHANCE_3D_3DUC             (1 << 6)
 #define ENHANCE_3D_MODE3D_PLAYBACK  (1 << 7)
@@ -137,6 +143,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #define ALC1_ALCSEL_RIGHT           (1 << 7)
 #define ALC1_ALCSEL_LEFT            (2 << 7)
 #define ALC1_ALCSEL_STEREO          (3 << 7)
+#define ALC1_ALCSEL_MASK            (3 << 7)
 
 #define ALC2                        0x12
 #define ALC2_HLD(x)                 ((x) & 0x0f)
@@ -152,6 +159,14 @@ void audiohw_set_recsrc(int source, bool recording);
 #define NGAT_NGG_MUTEADC            (1 << 1)
 #define NGAT_NGG(x)                 (((x) & 0x3) << 1)
 #define NGAT_NGTH(x)                (((x) & 0x1f) << 3)
+
+#define LADCVOL                     0x15
+#define LADCVOL_LADCVOL(x)          ((x) & 0xff)
+#define LADCVOL_LAVU                (1 << 8)
+
+#define RADCVOL                     0x16
+#define RADCVOL_RADCVOL(x)          ((x) & 0xff)
+#define RADCVOL_RAVU                (1 << 8)
 #endif
 
 #define ADDITIONAL1                 0x17
@@ -167,6 +182,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #define ADDITIONAL1_VSEL_DEFAULT2   (2 << 6)
 #define ADDITIONAL1_VSEL_DEFAULT    (3 << 6)
 #define ADDITIONAL1_VSEL(x)         ((x) & (0x3 << 6))
+#define ADDITIONAL1_VSEL_MASK       (3 << 6)
 #define ADDITIONAL1_TSDEN           (1 << 8)
 
 #define ADDITIONAL2                 0x18
@@ -196,6 +212,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #define PWRMGMT1_VMIDSEL_500K       (2 << 7)
 #define PWRMGMT1_VMIDSEL_5K         (3 << 7)
 #define PWRMGMT1_VMIDSEL(x)         ((x) & (0x3 << 7))
+#define PWRMGMT1_VMIDSEL_MASK       ((1<<8)|(1<<7))
 
 #define PWRMGMT2                    0x1a
 #define PWRMGMT2_OUT3               (1 << 1)
@@ -232,7 +249,8 @@ void audiohw_set_recsrc(int source, bool recording);
 #define ADCL_LINSEL_LINPUT1         (0 << 6)
 #define ADCL_LINSEL_LINPUT2         (1 << 6)
 #define ADCL_LINSEL_LINPUT3         (2 << 6)
-#define ADCL_LINSEL_DIFF            (3 << 6)         
+#define ADCL_LINSEL_DIFF            (3 << 6)        
+#define ADCL_LINSEL_MASK            (3 << 6) 
 
 #define ADCR                        0x21
 #define ADCR_RMICBOOST_DISABLED     (0 << 4)
@@ -244,6 +262,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #define ADCR_RINSEL_RINPUT2         (1 << 6)
 #define ADCR_RINSEL_RINPUT3         (2 << 6)
 #define ADCR_RINSEL_DIFF            (3 << 6)
+#define ADCR_RINSEL_MASK            (3 << 6)
 #endif
 
 #define LEFTMIX1                    0x22
@@ -256,6 +275,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #endif
 #define LEFTMIX1_LI2LO_DEFAULT      (5 << 4)
 #define LEFTMIX1_LI2LOVOL(x)        ((x) & (0x7 << 4))
+#define LEFTMIX1_LI2LOVOL_MASK      (0x7 << 4)
 #define LEFTMIX1_LI2LO              (1 << 7)
 #define LEFTMIX1_LD2LO              (1 << 8)
 
@@ -297,6 +317,7 @@ void audiohw_set_recsrc(int source, bool recording);
 #endif
 #define RIGHTMIX2_RI2RO_DEFAULT     (5 << 4)
 #define RIGHTMIX2_RI2ROVOL(x)       ((x) & (0x7 << 4))
+#define RIGHTMIX2_RI2ROVOL_MASK     (0x7 << 4)
 #define RIGHTMIX2_RI2RO             (1 << 7)
 #define RIGHTMIX2_RD2RO             (1 << 8)
 
@@ -312,11 +333,13 @@ void audiohw_set_recsrc(int source, bool recording);
 #define MONOMIX2_RD2MO              (1 << 8)
 
 #define LOUT2                       0x28
+#define LOUT2_LOUT2VOL_MASK         0x7f
 #define LOUT2_LOUT2VOL(x)           ((x) & 0x7f)
 #define LOUT2_LO2ZC                 (1 << 7)
 #define LOUT2_LO2VU                 (1 << 8)
 
 #define ROUT2                       0x29
+#define ROUT2_ROUT2VOL_MASK         0x17f
 #define ROUT2_ROUT2VOL(x)           ((x) & 0x7f)
 #define ROUT2_RO2ZC                 (1 << 7)
 #define ROUT2_RO2VU                 (1 << 8)
@@ -324,4 +347,5 @@ void audiohw_set_recsrc(int source, bool recording);
 #define MONOOUT                     0x2a
 #define MONOOUT_MOZC                (1 << 7)
 
+#define WM_NUM_REGS                 0x2b
 #endif /* _WM8751_H */
