diff options
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index b83b14fa1d29..22b50899b151 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -67,6 +67,8 @@ struct hdmi_spec_per_pin { | |||
67 | struct delayed_work work; | 67 | struct delayed_work work; |
68 | struct snd_kcontrol *eld_ctl; | 68 | struct snd_kcontrol *eld_ctl; |
69 | int repoll_count; | 69 | int repoll_count; |
70 | bool setup; /* the stream has been set up by prepare callback */ | ||
71 | int channels; /* current number of channels */ | ||
70 | bool non_pcm; | 72 | bool non_pcm; |
71 | bool chmap_set; /* channel-map override by ALSA API? */ | 73 | bool chmap_set; /* channel-map override by ALSA API? */ |
72 | unsigned char chmap[8]; /* ALSA API channel-map */ | 74 | unsigned char chmap[8]; /* ALSA API channel-map */ |
@@ -879,18 +881,19 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, | |||
879 | return true; | 881 | return true; |
880 | } | 882 | } |
881 | 883 | ||
882 | static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | 884 | static void hdmi_setup_audio_infoframe(struct hda_codec *codec, |
883 | bool non_pcm, | 885 | struct hdmi_spec_per_pin *per_pin, |
884 | struct snd_pcm_substream *substream) | 886 | bool non_pcm) |
885 | { | 887 | { |
886 | struct hdmi_spec *spec = codec->spec; | ||
887 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); | ||
888 | hda_nid_t pin_nid = per_pin->pin_nid; | 888 | hda_nid_t pin_nid = per_pin->pin_nid; |
889 | int channels = substream->runtime->channels; | 889 | int channels = per_pin->channels; |
890 | struct hdmi_eld *eld; | 890 | struct hdmi_eld *eld; |
891 | int ca; | 891 | int ca; |
892 | union audio_infoframe ai; | 892 | union audio_infoframe ai; |
893 | 893 | ||
894 | if (!channels) | ||
895 | return; | ||
896 | |||
894 | eld = &per_pin->sink_eld; | 897 | eld = &per_pin->sink_eld; |
895 | if (!eld->monitor_present) | 898 | if (!eld->monitor_present) |
896 | return; | 899 | return; |
@@ -1341,6 +1344,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
1341 | eld_changed = true; | 1344 | eld_changed = true; |
1342 | } | 1345 | } |
1343 | if (update_eld) { | 1346 | if (update_eld) { |
1347 | bool old_eld_valid = pin_eld->eld_valid; | ||
1344 | pin_eld->eld_valid = eld->eld_valid; | 1348 | pin_eld->eld_valid = eld->eld_valid; |
1345 | eld_changed = pin_eld->eld_size != eld->eld_size || | 1349 | eld_changed = pin_eld->eld_size != eld->eld_size || |
1346 | memcmp(pin_eld->eld_buffer, eld->eld_buffer, | 1350 | memcmp(pin_eld->eld_buffer, eld->eld_buffer, |
@@ -1350,6 +1354,18 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) | |||
1350 | eld->eld_size); | 1354 | eld->eld_size); |
1351 | pin_eld->eld_size = eld->eld_size; | 1355 | pin_eld->eld_size = eld->eld_size; |
1352 | pin_eld->info = eld->info; | 1356 | pin_eld->info = eld->info; |
1357 | |||
1358 | /* Haswell-specific workaround: re-setup when the transcoder is | ||
1359 | * changed during the stream playback | ||
1360 | */ | ||
1361 | if (codec->vendor_id == 0x80862807 && | ||
1362 | eld->eld_valid && !old_eld_valid && per_pin->setup) { | ||
1363 | snd_hda_codec_write(codec, pin_nid, 0, | ||
1364 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
1365 | AMP_OUT_UNMUTE); | ||
1366 | hdmi_setup_audio_infoframe(codec, per_pin, | ||
1367 | per_pin->non_pcm); | ||
1368 | } | ||
1353 | } | 1369 | } |
1354 | mutex_unlock(&pin_eld->lock); | 1370 | mutex_unlock(&pin_eld->lock); |
1355 | 1371 | ||
@@ -1522,14 +1538,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1522 | hda_nid_t cvt_nid = hinfo->nid; | 1538 | hda_nid_t cvt_nid = hinfo->nid; |
1523 | struct hdmi_spec *spec = codec->spec; | 1539 | struct hdmi_spec *spec = codec->spec; |
1524 | int pin_idx = hinfo_to_pin_index(spec, hinfo); | 1540 | int pin_idx = hinfo_to_pin_index(spec, hinfo); |
1525 | hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid; | 1541 | struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx); |
1542 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
1526 | bool non_pcm; | 1543 | bool non_pcm; |
1527 | 1544 | ||
1528 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); | 1545 | non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); |
1546 | per_pin->channels = substream->runtime->channels; | ||
1547 | per_pin->setup = true; | ||
1529 | 1548 | ||
1530 | hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); | 1549 | hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); |
1531 | 1550 | ||
1532 | hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream); | 1551 | hdmi_setup_audio_infoframe(codec, per_pin, non_pcm); |
1533 | 1552 | ||
1534 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); | 1553 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); |
1535 | } | 1554 | } |
@@ -1569,6 +1588,9 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | |||
1569 | snd_hda_spdif_ctls_unassign(codec, pin_idx); | 1588 | snd_hda_spdif_ctls_unassign(codec, pin_idx); |
1570 | per_pin->chmap_set = false; | 1589 | per_pin->chmap_set = false; |
1571 | memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); | 1590 | memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); |
1591 | |||
1592 | per_pin->setup = false; | ||
1593 | per_pin->channels = 0; | ||
1572 | } | 1594 | } |
1573 | 1595 | ||
1574 | return 0; | 1596 | return 0; |
@@ -1704,8 +1726,7 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol, | |||
1704 | per_pin->chmap_set = true; | 1726 | per_pin->chmap_set = true; |
1705 | memcpy(per_pin->chmap, chmap, sizeof(chmap)); | 1727 | memcpy(per_pin->chmap, chmap, sizeof(chmap)); |
1706 | if (prepared) | 1728 | if (prepared) |
1707 | hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm, | 1729 | hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm); |
1708 | substream); | ||
1709 | 1730 | ||
1710 | return 0; | 1731 | return 0; |
1711 | } | 1732 | } |