u8 jack_pol;
        u8 interrupt_src;
        u8 interrupt_clk;
+       u8 hpl_vol;
+       u8 hpr_vol;
        bool jd_inverted;
        unsigned int sysclk;
 
        return 0;
 }
 
+static int es8326_hplvol_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
+
+       ucontrol->value.integer.value[0] = es8326->hpl_vol;
+
+       return 0;
+}
+
+static int es8326_hplvol_set(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
+       unsigned int hp_vol;
+
+       hp_vol = ucontrol->value.integer.value[0];
+       if (hp_vol > 5)
+               return -EINVAL;
+       if (es8326->hpl_vol != hp_vol) {
+               es8326->hpl_vol = hp_vol;
+               if (hp_vol >= 3)
+                       hp_vol++;
+               regmap_update_bits(es8326->regmap, ES8326_HP_VOL,
+                               0x70, (hp_vol << 4));
+               return 1;
+       }
+
+       return 0;
+}
+
+static int es8326_hprvol_get(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
+
+       ucontrol->value.integer.value[0] = es8326->hpr_vol;
+
+       return 0;
+}
+
+static int es8326_hprvol_set(struct snd_kcontrol *kcontrol,
+               struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+       struct es8326_priv *es8326 = snd_soc_component_get_drvdata(component);
+       unsigned int hp_vol;
+
+       hp_vol = ucontrol->value.integer.value[0];
+       if (hp_vol > 5)
+               return -EINVAL;
+       if (es8326->hpr_vol != hp_vol) {
+               es8326->hpr_vol = hp_vol;
+               if (hp_vol >= 3)
+                       hp_vol++;
+               regmap_update_bits(es8326->regmap, ES8326_HP_VOL,
+                               0x07, hp_vol);
+               return 1;
+       }
+
+       return 0;
+}
+
 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9550, 50, 0);
 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9550, 50, 0);
 static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_analog_pga_tlv, 0, 300, 0);
 static const char *const dacpol_txt[] =        {
        "Normal", "R Invert", "L Invert", "L + R Invert" };
 
+static const char *const hp_spkvol_switch[] = {
+       "HPVOL: HPL+HPL, SPKVOL: HPL+HPL",
+       "HPVOL: HPL+HPR, SPKVOL: HPL+HPR",
+       "HPVOL: HPL+HPL, SPKVOL: SPKL+SPKR",
+       "HPVOL: HPL+HPR, SPKVOL: SPKL+SPKR",
+};
+
 static const struct soc_enum dacpol =
        SOC_ENUM_SINGLE(ES8326_DAC_DSM, 4, 4, dacpol_txt);
 static const struct soc_enum alc_winsize =
        SOC_ENUM_SINGLE(ES8326_ADC_RAMPRATE, 4, 16, winsize);
 static const struct soc_enum drc_winsize =
        SOC_ENUM_SINGLE(ES8326_DRC_WINSIZE, 4, 16, winsize);
+static const struct soc_enum hpvol_spkvol_switch =
+       SOC_ENUM_SINGLE(ES8326_HP_MISC, 6, 4, hp_spkvol_switch);
 
 static const struct snd_kcontrol_new es8326_snd_controls[] = {
-       SOC_SINGLE_TLV("DAC Playback Volume", ES8326_DAC_VOL, 0, 0xbf, 0, dac_vol_tlv),
+       SOC_SINGLE_TLV("DAC Playback Volume", ES8326_DACL_VOL, 0, 0xbf, 0, dac_vol_tlv),
        SOC_ENUM("Playback Polarity", dacpol),
        SOC_SINGLE_TLV("DAC Ramp Rate", ES8326_DAC_RAMPRATE, 0, 0x0f, 0, softramp_rate),
        SOC_SINGLE_TLV("DRC Recovery Level", ES8326_DRC_RECOVERY, 0, 4, 0, drc_recovery_tlv),
                        es8326_crosstalk1_get, es8326_crosstalk1_set),
        SOC_SINGLE_EXT("CROSSTALK2", SND_SOC_NOPM, 0, 31, 0,
                        es8326_crosstalk2_get, es8326_crosstalk2_set),
+       SOC_SINGLE_EXT("HPL Volume", SND_SOC_NOPM, 0, 5, 0,
+                       es8326_hplvol_get, es8326_hplvol_set),
+       SOC_SINGLE_EXT("HPR Volume", SND_SOC_NOPM, 0, 5, 0,
+                       es8326_hprvol_get, es8326_hprvol_set),
+
+       SOC_SINGLE_TLV("HPL Playback Volume", ES8326_DACL_VOL, 0, 0xbf, 0, dac_vol_tlv),
+       SOC_SINGLE_TLV("HPR Playback Volume", ES8326_DACR_VOL, 0, 0xbf, 0, dac_vol_tlv),
+       SOC_SINGLE_TLV("SPKL Playback Volume", ES8326_SPKL_VOL, 0, 0xbf, 0, dac_vol_tlv),
+       SOC_SINGLE_TLV("SPKR Playback Volume", ES8326_SPKR_VOL, 0, 0xbf, 0, dac_vol_tlv),
+
+       SOC_ENUM("HPVol SPKVol Switch", hpvol_spkvol_switch),
 };
 
 static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = {
 
        es8326->jack_remove_retry = 0;
        es8326->hp = 0;
+       es8326->hpl_vol = 0x03;
+       es8326->hpr_vol = 0x03;
        return 0;
 }