mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 05:48:40 +00:00
ALSA: HDA: Conexant auto: Handle multiple connections to ADC node
Conexant 20641 has several inputs to its ADC node, with one selector and individual amps for all inputs. This patch adds support in the Conexant auto parser to handle that case. It also means that the pin node's volume is being renamed to "Boost" to avoid name clash with the new volume controls on the ADC node. BugLink: http://bugs.launchpad.net/bugs/719524 Signed-off-by: David Henningsson <david.henningsson@canonical.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
b540afc2b3
commit
983345e51e
1 changed files with 48 additions and 13 deletions
|
@ -3729,9 +3729,9 @@ static int cx_auto_init(struct hda_codec *codec)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
|
||||
static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename,
|
||||
const char *dir, int cidx,
|
||||
hda_nid_t nid, int hda_dir)
|
||||
hda_nid_t nid, int hda_dir, int amp_idx)
|
||||
{
|
||||
static char name[32];
|
||||
static struct snd_kcontrol_new knew[] = {
|
||||
|
@ -3743,7 +3743,8 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
|
|||
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct snd_kcontrol *kctl;
|
||||
knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, hda_dir);
|
||||
knew[i].private_value = HDA_COMPOSE_AMP_VAL(nid, 3, amp_idx,
|
||||
hda_dir);
|
||||
knew[i].subdevice = HDA_SUBDEV_AMP_FLAG;
|
||||
knew[i].index = cidx;
|
||||
snprintf(name, sizeof(name), "%s%s %s", basename, dir, sfx[i]);
|
||||
|
@ -3759,6 +3760,9 @@ static int cx_auto_add_volume(struct hda_codec *codec, const char *basename,
|
|||
return 0;
|
||||
}
|
||||
|
||||
#define cx_auto_add_volume(codec, str, dir, cidx, nid, hda_dir) \
|
||||
cx_auto_add_volume_idx(codec, str, dir, cidx, nid, hda_dir, 0)
|
||||
|
||||
#define cx_auto_add_pb_volume(codec, nid, str, idx) \
|
||||
cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT)
|
||||
|
||||
|
@ -3808,29 +3812,60 @@ static int cx_auto_build_input_controls(struct hda_codec *codec)
|
|||
struct conexant_spec *spec = codec->spec;
|
||||
struct auto_pin_cfg *cfg = &spec->autocfg;
|
||||
static const char *prev_label;
|
||||
int i, err, cidx;
|
||||
int i, err, cidx, conn_len;
|
||||
hda_nid_t conn[HDA_MAX_CONNECTIONS];
|
||||
|
||||
int multi_adc_volume = 0; /* If the ADC nid has several input volumes */
|
||||
int adc_nid = spec->adc_nids[0];
|
||||
|
||||
conn_len = snd_hda_get_connections(codec, adc_nid, conn,
|
||||
HDA_MAX_CONNECTIONS);
|
||||
if (conn_len < 0)
|
||||
return conn_len;
|
||||
|
||||
multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1;
|
||||
if (!multi_adc_volume) {
|
||||
err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid,
|
||||
HDA_INPUT);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
err = cx_auto_add_volume(codec, "Capture", "", 0, spec->adc_nids[0],
|
||||
HDA_INPUT);
|
||||
if (err < 0)
|
||||
return err;
|
||||
prev_label = NULL;
|
||||
cidx = 0;
|
||||
for (i = 0; i < cfg->num_inputs; i++) {
|
||||
hda_nid_t nid = cfg->inputs[i].pin;
|
||||
const char *label;
|
||||
if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP))
|
||||
int j;
|
||||
int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP;
|
||||
if (!pin_amp && !multi_adc_volume)
|
||||
continue;
|
||||
|
||||
label = hda_get_autocfg_input_label(codec, cfg, i);
|
||||
if (label == prev_label)
|
||||
cidx++;
|
||||
else
|
||||
cidx = 0;
|
||||
prev_label = label;
|
||||
err = cx_auto_add_volume(codec, label, " Capture", cidx,
|
||||
nid, HDA_INPUT);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (pin_amp) {
|
||||
err = cx_auto_add_volume(codec, label, " Boost", cidx,
|
||||
nid, HDA_INPUT);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
|
||||
if (!multi_adc_volume)
|
||||
continue;
|
||||
for (j = 0; j < conn_len; j++) {
|
||||
if (conn[j] == nid) {
|
||||
err = cx_auto_add_volume_idx(codec, label,
|
||||
" Capture", cidx, adc_nid, HDA_INPUT, j);
|
||||
if (err < 0)
|
||||
return err;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue