.info = snd_soc_info_volsw_range, .get = snd_soc_get_volsw_range, \
        .put = snd_soc_put_volsw_range, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
-               {.reg = xreg, .shift = xshift, .min = xmin,\
-                .max = xmax, .platform_max = xmax, .invert = xinvert} }
+               {.reg = xreg, .rreg = xreg, .shift = xshift, \
+                .rshift = xshift,  .min = xmin, .max = xmax, \
+                .platform_max = xmax, .invert = xinvert} }
 #define SOC_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
        .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
        .info = snd_soc_info_volsw_range, \
        .get = snd_soc_get_volsw_range, .put = snd_soc_put_volsw_range, \
        .private_value = (unsigned long)&(struct soc_mixer_control) \
-               {.reg = xreg, .shift = xshift, .min = xmin,\
-                .max = xmax, .platform_max = xmax, .invert = xinvert} }
+               {.reg = xreg, .rreg = xreg, .shift = xshift, \
+                .rshift = xshift, .min = xmin, .max = xmax, \
+                .platform_max = xmax, .invert = xinvert} }
 #define SOC_DOUBLE(xname, reg, shift_left, shift_right, max, invert) \
 {      .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\
        .info = snd_soc_info_volsw, .get = snd_soc_get_volsw, \
 
        platform_max = mc->platform_max;
 
        uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
-       uinfo->count = 1;
+       uinfo->count = snd_soc_volsw_is_stereo(mc) ? 2 : 1;
        uinfo->value.integer.min = 0;
        uinfo->value.integer.max = platform_max - min;
 
                (struct soc_mixer_control *)kcontrol->private_value;
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        unsigned int reg = mc->reg;
+       unsigned int rreg = mc->rreg;
        unsigned int shift = mc->shift;
        int min = mc->min;
        int max = mc->max;
        unsigned int mask = (1 << fls(max)) - 1;
        unsigned int invert = mc->invert;
        unsigned int val, val_mask;
+       int ret;
 
        val = ((ucontrol->value.integer.value[0] + min) & mask);
        if (invert)
        val_mask = mask << shift;
        val = val << shift;
 
-       return snd_soc_update_bits_locked(codec, reg, val_mask, val);
+       ret = snd_soc_update_bits_locked(codec, reg, val_mask, val);
+       if (ret != 0)
+               return ret;
+
+       if (snd_soc_volsw_is_stereo(mc)) {
+               val = ((ucontrol->value.integer.value[1] + min) & mask);
+               if (invert)
+                       val = max - val;
+               val_mask = mask << shift;
+               val = val << shift;
+
+               ret = snd_soc_update_bits_locked(codec, rreg, val_mask, val);
+       }
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(snd_soc_put_volsw_range);
 
                (struct soc_mixer_control *)kcontrol->private_value;
        struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
        unsigned int reg = mc->reg;
+       unsigned int rreg = mc->rreg;
        unsigned int shift = mc->shift;
        int min = mc->min;
        int max = mc->max;
        unsigned int mask = (1 << fls(max)) - 1;
        unsigned int invert = mc->invert;
+       int ret;
 
        ucontrol->value.integer.value[0] =
                (snd_soc_read(codec, reg) >> shift) & mask;
        ucontrol->value.integer.value[0] =
                ucontrol->value.integer.value[0] - min;
 
+       if (snd_soc_volsw_is_stereo(mc)) {
+               ucontrol->value.integer.value[1] =
+                       (snd_soc_read(codec, rreg) >> shift) & mask;
+               if (invert)
+                       ucontrol->value.integer.value[1] =
+                               max - ucontrol->value.integer.value[1];
+               ucontrol->value.integer.value[1] =
+                       ucontrol->value.integer.value[1] - min;
+       }
+
        return 0;
 }
 EXPORT_SYMBOL_GPL(snd_soc_get_volsw_range);