Commit 47fd830a authored by Takashi Iwai's avatar Takashi Iwai Committed by Jaroslav Kysela

[ALSA] hda-codec - add snd_hda_codec_stereo() function

Added snd_hda_codec_amp_stereo() function that changes both of stereo
channels with the same mask and value bits.  It simplifies most of
amp-handling codes.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarJaroslav Kysela <perex@suse.cz>
parent 82beb8fd
......@@ -842,6 +842,19 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
return 1;
}
/*
* update the AMP stereo with the same mask and value
*/
int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
int direction, int idx, int mask, int val)
{
int ch, ret = 0;
for (ch = 0; ch < 2; ch++)
ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
idx, mask, val);
return ret;
}
#ifdef CONFIG_PM
/* resume the all amp commands from the cache */
void snd_hda_codec_resume_amp(struct hda_codec *codec)
......@@ -913,9 +926,11 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
long *valp = ucontrol->value.integer.value;
if (chs & 1)
*valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x7f;
*valp++ = snd_hda_codec_amp_read(codec, nid, 0, dir, idx)
& HDA_AMP_VOLMASK;
if (chs & 2)
*valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x7f;
*valp = snd_hda_codec_amp_read(codec, nid, 1, dir, idx)
& HDA_AMP_VOLMASK;
return 0;
}
......@@ -992,10 +1007,10 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
if (chs & 1)
*valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
0x80) ? 0 : 1;
HDA_AMP_MUTE) ? 0 : 1;
if (chs & 2)
*valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
0x80) ? 0 : 1;
HDA_AMP_MUTE) ? 0 : 1;
return 0;
}
......@@ -1012,12 +1027,14 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
if (chs & 1) {
change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
0x80, *valp ? 0 : 0x80);
HDA_AMP_MUTE,
*valp ? 0 : HDA_AMP_MUTE);
valp++;
}
if (chs & 2)
change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
0x80, *valp ? 0 : 0x80);
HDA_AMP_MUTE,
*valp ? 0 : HDA_AMP_MUTE);
return change;
}
......@@ -1318,12 +1335,9 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
val & 0xff);
/* unmute amp switch (if any) */
if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
(val & AC_DIG1_ENABLE)) {
snd_hda_codec_amp_update(codec, nid, 0, HDA_OUTPUT, 0,
0x80, 0x00);
snd_hda_codec_amp_update(codec, nid, 1, HDA_OUTPUT, 0,
0x80, 0x00);
}
(val & AC_DIG1_ENABLE))
snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
HDA_AMP_MUTE, 0);
}
mutex_unlock(&codec->spdif_mutex);
return change;
......
......@@ -218,8 +218,7 @@ static int unmute_output(struct hda_codec *codec, struct hda_gnode *node)
ofs = (node->amp_out_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
if (val >= ofs)
val -= ofs;
snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 0, 0xff, val);
snd_hda_codec_amp_update(codec, node->nid, 0, HDA_OUTPUT, 1, 0xff, val);
snd_hda_codec_amp_stereo(codec, node->nid, HDA_OUTPUT, 0, 0xff, val);
return 0;
}
......@@ -234,10 +233,7 @@ static int unmute_input(struct hda_codec *codec, struct hda_gnode *node, unsigne
ofs = (node->amp_in_caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
if (val >= ofs)
val -= ofs;
snd_hda_codec_amp_update(codec, node->nid, 0, HDA_INPUT, index,
0xff, val);
snd_hda_codec_amp_update(codec, node->nid, 1, HDA_INPUT, index,
0xff, val);
snd_hda_codec_amp_stereo(codec, node->nid, HDA_INPUT, index, 0xff, val);
return 0;
}
......
......@@ -84,10 +84,17 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int index);
int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
int direction, int idx, int mask, int val);
int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
int dir, int idx, int mask, int val);
#ifdef CONFIG_PM
void snd_hda_codec_resume_amp(struct hda_codec *codec);
#endif
/* amp value bits */
#define HDA_AMP_MUTE 0x80
#define HDA_AMP_UNMUTE 0x00
#define HDA_AMP_VOLMASK 0x7f
/* mono switch binding multiple inputs */
#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
......
......@@ -1120,10 +1120,9 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
return 0;
/* toggle HP mute appropriately */
snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
0x80, spec->cur_eapd ? 0 : 0x80);
snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
0x80, spec->cur_eapd ? 0 : 0x80);
snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
HDA_AMP_MUTE,
spec->cur_eapd ? 0 : HDA_AMP_MUTE);
return 1;
}
......@@ -1136,13 +1135,13 @@ static int ad1981_hp_master_vol_put(struct snd_kcontrol *kcontrol,
int change;
change = snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
change |= snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
snd_hda_codec_amp_update(codec, 0x06, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
snd_hda_codec_amp_update(codec, 0x06, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
return change;
}
......@@ -1153,10 +1152,8 @@ static void ad1981_hp_automute(struct hda_codec *codec)
present = snd_hda_codec_read(codec, 0x06, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
0x80, present ? 0x80 : 0);
snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
0x80, present ? 0x80 : 0);
snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
}
/* toggle input of built-in and mic jack appropriately */
......
......@@ -472,13 +472,13 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol,
/* toggle internal speakers mute depending of presence of
* the headphone jack
*/
bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
bits = spec->cur_eapd ? 0 : 0x80;
snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
snd_hda_codec_amp_stereo(codec, 0x11, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
return 1;
}
......@@ -491,13 +491,13 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol,
int change;
change = snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
change |= snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
return change;
}
......@@ -534,9 +534,9 @@ static void cxt5045_hp_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x11, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x10, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
/* unsolicited event for HP jack sensing */
......@@ -887,12 +887,12 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol,
/* toggle internal speakers mute depending of presence of
* the headphone jack
*/
bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80;
snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = spec->cur_eapd ? 0 : 0x80;
snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE;
snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE;
snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
return 1;
}
......@@ -905,13 +905,13 @@ static int cxt5047_hp_master_vol_put(struct snd_kcontrol *kcontrol,
int change;
change = snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
change |= snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
snd_hda_codec_amp_update(codec, 0x13, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
snd_hda_codec_amp_update(codec, 0x13, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
return change;
}
......@@ -924,12 +924,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
/* Mute/Unmute PCM 2 for good measure - some systems need this */
snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
/* mute internal speaker if HP is plugged */
......@@ -941,12 +941,12 @@ static void cxt5047_hp2_automute(struct hda_codec *codec)
spec->hp_present = snd_hda_codec_read(codec, 0x13, 0,
AC_VERB_GET_PIN_SENSE, 0) & 0x80000000;
bits = spec->hp_present ? 0x80 : 0;
snd_hda_codec_amp_update(codec, 0x1d, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x1d, 1, HDA_OUTPUT, 0, 0x80, bits);
bits = spec->hp_present ? HDA_AMP_MUTE : 0;
snd_hda_codec_amp_stereo(codec, 0x1d, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
/* Mute/Unmute PCM 2 for good measure - some systems need this */
snd_hda_codec_amp_update(codec, 0x1c, 0, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_update(codec, 0x1c, 1, HDA_OUTPUT, 0, 0x80, bits);
snd_hda_codec_amp_stereo(codec, 0x1c, HDA_OUTPUT, 0,
HDA_AMP_MUTE, bits);
}
/* toggle input of built-in and mic jack appropriately */
......
This diff is collapsed.
......@@ -2408,13 +2408,13 @@ static int vaio_master_vol_put(struct snd_kcontrol *kcontrol,
int change;
change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
0x7f, valp[0] & 0x7f);
HDA_AMP_VOLMASK, valp[0]);
snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
0x7f, valp[1] & 0x7f);
HDA_AMP_VOLMASK, valp[1]);
return change;
}
......@@ -2427,13 +2427,15 @@ static int vaio_master_sw_put(struct snd_kcontrol *kcontrol,
int change;
change = snd_hda_codec_amp_update(codec, 0x02, 0, HDA_OUTPUT, 0,
0x80, (valp[0] ? 0 : 0x80));
HDA_AMP_MUTE,
(valp[0] ? 0 : HDA_AMP_MUTE));
change |= snd_hda_codec_amp_update(codec, 0x02, 1, HDA_OUTPUT, 0,
0x80, (valp[1] ? 0 : 0x80));
HDA_AMP_MUTE,
(valp[1] ? 0 : HDA_AMP_MUTE));
snd_hda_codec_amp_update(codec, 0x05, 0, HDA_OUTPUT, 0,
0x80, (valp[0] ? 0 : 0x80));
HDA_AMP_MUTE, (valp[0] ? 0 : HDA_AMP_MUTE));
snd_hda_codec_amp_update(codec, 0x05, 1, HDA_OUTPUT, 0,
0x80, (valp[1] ? 0 : 0x80));
HDA_AMP_MUTE, (valp[1] ? 0 : HDA_AMP_MUTE));
return change;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment