Commit 5fa9b151 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'fix/hda' into topic/hda

Conflicts:
	sound/pci/hda/patch_realtek.c
parents 188cd2b5 1f015f5f
...@@ -1073,10 +1073,10 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev) ...@@ -1073,10 +1073,10 @@ static int aoa_fabric_layout_probe(struct soundbus_dev *sdev)
sdev->pcmid = -1; sdev->pcmid = -1;
list_del(&ldev->list); list_del(&ldev->list);
layouts_list_items--; layouts_list_items--;
kfree(ldev);
outnodev: outnodev:
of_node_put(sound); of_node_put(sound);
layout_device = NULL; layout_device = NULL;
kfree(ldev);
return -ENODEV; return -ENODEV;
} }
......
...@@ -144,25 +144,17 @@ static int cea_sampling_frequencies[8] = { ...@@ -144,25 +144,17 @@ static int cea_sampling_frequencies[8] = {
SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ SNDRV_PCM_RATE_192000, /* 7: 192000Hz */
}; };
static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid, static unsigned int hdmi_get_eld_data(struct hda_codec *codec, hda_nid_t nid,
int byte_index) int byte_index)
{ {
unsigned int val; unsigned int val;
val = snd_hda_codec_read(codec, nid, 0, val = snd_hda_codec_read(codec, nid, 0,
AC_VERB_GET_HDMI_ELDD, byte_index); AC_VERB_GET_HDMI_ELDD, byte_index);
#ifdef BE_PARANOID #ifdef BE_PARANOID
printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val); printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val);
#endif #endif
return val;
if ((val & AC_ELDD_ELD_VALID) == 0) {
snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n",
byte_index);
val = 0;
}
return val & AC_ELDD_ELD_DATA;
} }
#define GRAB_BITS(buf, byte, lowbit, bits) \ #define GRAB_BITS(buf, byte, lowbit, bits) \
...@@ -344,11 +336,26 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, ...@@ -344,11 +336,26 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld,
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < size; i++) for (i = 0; i < size; i++) {
buf[i] = hdmi_get_eld_byte(codec, nid, i); unsigned int val = hdmi_get_eld_data(codec, nid, i);
if (!(val & AC_ELDD_ELD_VALID)) {
if (!i) {
snd_printd(KERN_INFO
"HDMI: invalid ELD data\n");
ret = -EINVAL;
goto error;
}
snd_printd(KERN_INFO
"HDMI: invalid ELD data byte %d\n", i);
val = 0;
} else
val &= AC_ELDD_ELD_DATA;
buf[i] = val;
}
ret = hdmi_update_eld(eld, buf, size); ret = hdmi_update_eld(eld, buf, size);
error:
kfree(buf); kfree(buf);
return ret; return ret;
} }
......
...@@ -375,7 +375,7 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx) ...@@ -375,7 +375,7 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx)
static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
unsigned int *idxp) unsigned int *idxp)
{ {
int i; int i, idx;
hda_nid_t nid; hda_nid_t nid;
nid = codec->start_nid; nid = codec->start_nid;
...@@ -384,9 +384,11 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, ...@@ -384,9 +384,11 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin,
type = get_wcaps_type(get_wcaps(codec, nid)); type = get_wcaps_type(get_wcaps(codec, nid));
if (type != AC_WID_AUD_IN) if (type != AC_WID_AUD_IN)
continue; continue;
*idxp = snd_hda_get_conn_index(codec, nid, pin, false); idx = snd_hda_get_conn_index(codec, nid, pin, false);
if (*idxp >= 0) if (idx >= 0) {
*idxp = idx;
return nid; return nid;
}
} }
return 0; return 0;
} }
......
...@@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin, ...@@ -3348,6 +3348,8 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t pin,
#define MAX_AUTO_DACS 5 #define MAX_AUTO_DACS 5
#define DAC_SLAVE_FLAG 0x8000 /* filled dac is a slave */
/* fill analog DAC list from the widget tree */ /* fill analog DAC list from the widget tree */
static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs) static int fill_cx_auto_dacs(struct hda_codec *codec, hda_nid_t *dacs)
{ {
...@@ -3379,6 +3381,8 @@ static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins, ...@@ -3379,6 +3381,8 @@ static int fill_dacs_for_pins(struct hda_codec *codec, hda_nid_t *pins,
filled[nums].pin = pins[i]; filled[nums].pin = pins[i];
filled[nums].type = type; filled[nums].type = type;
filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest); filled[nums].dac = get_unassigned_dac(codec, pins[i], dacs, rest);
if (!filled[nums].dac && i > 0 && filled[0].dac)
filled[nums].dac = filled[0].dac | DAC_SLAVE_FLAG;
nums++; nums++;
} }
return nums; return nums;
...@@ -3407,7 +3411,7 @@ static void cx_auto_parse_output(struct hda_codec *codec) ...@@ -3407,7 +3411,7 @@ static void cx_auto_parse_output(struct hda_codec *codec)
/* fill multiout struct */ /* fill multiout struct */
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
hda_nid_t dac = spec->dac_info[i].dac; hda_nid_t dac = spec->dac_info[i].dac;
if (!dac) if (!dac || (dac & DAC_SLAVE_FLAG))
continue; continue;
switch (spec->dac_info[i].type) { switch (spec->dac_info[i].type) {
case AUTO_PIN_LINE_OUT: case AUTO_PIN_LINE_OUT:
...@@ -4035,6 +4039,8 @@ static void cx_auto_init_output(struct hda_codec *codec) ...@@ -4035,6 +4039,8 @@ static void cx_auto_init_output(struct hda_codec *codec)
nid = spec->dac_info[i].dac; nid = spec->dac_info[i].dac;
if (!nid) if (!nid)
nid = spec->multiout.dac_nids[0]; nid = spec->multiout.dac_nids[0];
else if (nid & DAC_SLAVE_FLAG)
nid &= ~DAC_SLAVE_FLAG;
select_connection(codec, spec->dac_info[i].pin, nid); select_connection(codec, spec->dac_info[i].pin, nid);
} }
if (spec->auto_mute) { if (spec->auto_mute) {
...@@ -4191,7 +4197,8 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) ...@@ -4191,7 +4197,8 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
for (i = 0; i < spec->dac_info_filled; i++) { for (i = 0; i < spec->dac_info_filled; i++) {
const char *label; const char *label;
int idx, type; int idx, type;
if (!spec->dac_info[i].dac) hda_nid_t dac = spec->dac_info[i].dac;
if (!dac || (dac & DAC_SLAVE_FLAG))
continue; continue;
type = spec->dac_info[i].type; type = spec->dac_info[i].type;
if (type == AUTO_PIN_LINE_OUT) if (type == AUTO_PIN_LINE_OUT)
...@@ -4211,7 +4218,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) ...@@ -4211,7 +4218,7 @@ static int cx_auto_build_output_controls(struct hda_codec *codec)
idx = num_spk++; idx = num_spk++;
break; break;
} }
err = try_add_pb_volume(codec, spec->dac_info[i].dac, err = try_add_pb_volume(codec, dac,
spec->dac_info[i].pin, spec->dac_info[i].pin,
label, idx); label, idx);
if (err < 0) if (err < 0)
......
...@@ -578,11 +578,11 @@ static void alc_hp_automute(struct hda_codec *codec) ...@@ -578,11 +578,11 @@ static void alc_hp_automute(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
if (!spec->automute)
return;
spec->jack_present = spec->jack_present =
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
spec->autocfg.hp_pins); spec->autocfg.hp_pins);
if (!spec->automute)
return;
call_update_speakers(codec); call_update_speakers(codec);
} }
...@@ -591,11 +591,11 @@ static void alc_line_automute(struct hda_codec *codec) ...@@ -591,11 +591,11 @@ static void alc_line_automute(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
if (!spec->automute || !spec->detect_line)
return;
spec->line_jack_present = spec->line_jack_present =
detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
spec->autocfg.line_out_pins); spec->autocfg.line_out_pins);
if (!spec->automute || !spec->detect_line)
return;
call_update_speakers(codec); call_update_speakers(codec);
} }
...@@ -1797,6 +1797,7 @@ static const char * const alc_slave_vols[] = { ...@@ -1797,6 +1797,7 @@ static const char * const alc_slave_vols[] = {
"Speaker Playback Volume", "Speaker Playback Volume",
"Mono Playback Volume", "Mono Playback Volume",
"Line-Out Playback Volume", "Line-Out Playback Volume",
"PCM Playback Volume",
NULL, NULL,
}; };
...@@ -1811,6 +1812,7 @@ static const char * const alc_slave_sws[] = { ...@@ -1811,6 +1812,7 @@ static const char * const alc_slave_sws[] = {
"Mono Playback Switch", "Mono Playback Switch",
"IEC958 Playback Switch", "IEC958 Playback Switch",
"Line-Out Playback Switch", "Line-Out Playback Switch",
"PCM Playback Switch",
NULL, NULL,
}; };
...@@ -3221,16 +3223,22 @@ static void alc_auto_init_multi_out(struct hda_codec *codec) ...@@ -3221,16 +3223,22 @@ static void alc_auto_init_multi_out(struct hda_codec *codec)
static void alc_auto_init_extra_out(struct hda_codec *codec) static void alc_auto_init_extra_out(struct hda_codec *codec)
{ {
struct alc_spec *spec = codec->spec; struct alc_spec *spec = codec->spec;
hda_nid_t pin; hda_nid_t pin, dac;
pin = spec->autocfg.hp_pins[0]; pin = spec->autocfg.hp_pins[0];
if (pin) if (pin) {
alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac = spec->multiout.hp_nid;
spec->multiout.hp_nid); if (!dac)
dac = spec->multiout.dac_nids[0];
alc_auto_set_output_and_unmute(codec, pin, PIN_HP, dac);
}
pin = spec->autocfg.speaker_pins[0]; pin = spec->autocfg.speaker_pins[0];
if (pin) if (pin) {
alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac = spec->multiout.extra_out_nid[0];
spec->multiout.extra_out_nid[0]); if (!dac)
dac = spec->multiout.dac_nids[0];
alc_auto_set_output_and_unmute(codec, pin, PIN_OUT, dac);
}
} }
/* /*
......
...@@ -152,6 +152,7 @@ static inline void check_mapped_dB(const struct usbmix_name_map *p, ...@@ -152,6 +152,7 @@ static inline void check_mapped_dB(const struct usbmix_name_map *p,
if (p && p->dB) { if (p && p->dB) {
cval->dBmin = p->dB->min; cval->dBmin = p->dB->min;
cval->dBmax = p->dB->max; cval->dBmax = p->dB->max;
cval->initialized = 1;
} }
} }
...@@ -1092,7 +1093,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, ...@@ -1092,7 +1093,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc,
" Switch" : " Volume"); " Switch" : " Volume");
if (control == UAC_FU_VOLUME) { if (control == UAC_FU_VOLUME) {
check_mapped_dB(map, cval); check_mapped_dB(map, cval);
if (cval->dBmin < cval->dBmax) { if (cval->dBmin < cval->dBmax || !cval->initialized) {
kctl->tlv.c = mixer_vol_tlv; kctl->tlv.c = mixer_vol_tlv;
kctl->vd[0].access |= kctl->vd[0].access |=
SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_TLV_READ |
......
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