[alsa-devel] [PATCH 0/3] HDMI HBR(High Bit Rate) Feature bug fix for Intel's Chips
Please Note This patchset has not been tested yet on any Hardware platform. i could only confirm there's no compile error. :) I test previous single patch on the Yamaha A/V receiver which works well, the test results was also confirmed by some guys from XBMC forum.
The idea of this patch comes from Anssi, Big credit to him at first!
Any comments are appreciated!
Changelog: * do not touch channel_allocation priority order, use new api to get correct channels number * use spdif->status to check audio type, pcm or non-pcm * create new non_pcm_mapping[] for non_pcm audio in seperate block * add non_pcm hdmi_spec_per_cvt to remember previous audio type, used to determine whether need a channel mapping update during the pcm/non-pcm stream switch with same channel number.
Wang Xingchao (3): ALSA: hdmi - fix channel_allocation array wrong order ALSA: HDMI - Enable HBR feature on Intel chips ALSA: HDMI - Setup channel mapping for non_pcm audio
sound/pci/hda/patch_hdmi.c | 56 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)
The array channel_allocations[] is an ordered list, add function to get correct order by ca_index.
Signed-off-by: Wang Xingchao xingchao.wang@intel.com --- sound/pci/hda/patch_hdmi.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d9439c5..6ac21d4 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -469,6 +469,17 @@ static void init_channel_allocations(void) } }
+static int get_channel_allocation_order(int ca) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { + if (channel_allocations[i].ca_index == ca) + break; + } + return i; +} + /* * The transformation takes two steps: * @@ -541,9 +552,11 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec, { int i; int err; + int order;
+ order = get_channel_allocation_order(ca); if (hdmi_channel_mapping[ca][1] == 0) { - for (i = 0; i < channel_allocations[ca].channels; i++) + for (i = 0; i < channel_allocations[order].channels; i++) hdmi_channel_mapping[ca][i] = i | (i << 4); for (; i < 8; i++) hdmi_channel_mapping[ca][i] = 0xf | (i << 4);
HDMI channel remapping apparently effects HBR packets on Intel's chips. For compressed non-PCM audio, use "straight-through" channel mapping. For uncompressed multi-channel pcm audio, use normal channel mapping.
Signed-off-by: Wang Xingchao xingchao.wang@intel.com --- sound/pci/hda/patch_hdmi.c | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 6ac21d4..a87f8b2 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -34,6 +34,7 @@ #include <linux/module.h> #include <sound/core.h> #include <sound/jack.h> +#include <sound/asoundef.h> #include "hda_codec.h" #include "hda_local.h" #include "hda_jack.h" @@ -60,6 +61,7 @@ struct hdmi_spec_per_cvt { u32 rates; u64 formats; unsigned int maxbps; + bool non_pcm; };
struct hdmi_spec_per_pin { @@ -548,13 +550,17 @@ static void hdmi_debug_channel_mapping(struct hda_codec *codec,
static void hdmi_setup_channel_mapping(struct hda_codec *codec, hda_nid_t pin_nid, + hda_nid_t cvt_nid, + bool non_pcm, int ca) { int i; int err; int order; + int non_pcm_mapping[8];
order = get_channel_allocation_order(ca); + if (hdmi_channel_mapping[ca][1] == 0) { for (i = 0; i < channel_allocations[order].channels; i++) hdmi_channel_mapping[ca][i] = i | (i << 4); @@ -562,10 +568,17 @@ static void hdmi_setup_channel_mapping(struct hda_codec *codec, hdmi_channel_mapping[ca][i] = 0xf | (i << 4); }
+ if (non_pcm) { + for (i = 0; i < channel_allocations[order].channels; i++) + non_pcm_mapping[i] = i | (i << 4); + for (; i < 8; i++) + non_pcm_mapping[i] = 0xf | (i << 4); + } + for (i = 0; i < 8; i++) { err = snd_hda_codec_write(codec, pin_nid, 0, AC_VERB_SET_HDMI_CHAN_SLOT, - hdmi_channel_mapping[ca][i]); + non_pcm ? non_pcm_mapping[i] : hdmi_channel_mapping[ca][i]); if (err) { snd_printdd(KERN_NOTICE "HDMI: channel mapping failed\n"); @@ -699,15 +712,27 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid, }
static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, - struct snd_pcm_substream *substream) + hda_nid_t cvt_nid, struct snd_pcm_substream *substream) { struct hdmi_spec *spec = codec->spec; struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; + struct hdmi_spec_per_cvt *per_cvt; + struct hda_spdif_out *spdif; hda_nid_t pin_nid = per_pin->pin_nid; int channels = substream->runtime->channels; struct hdmi_eld *eld; int ca; + int cvt_idx; union audio_infoframe ai; + bool non_pcm = false; + + cvt_idx = cvt_nid_to_cvt_index(spec, cvt_nid); + per_cvt = &spec->cvts[cvt_idx]; + + mutex_lock(&codec->spdif_mutex); + spdif = snd_hda_spdif_out_of_nid(codec, cvt_nid); + non_pcm = !!(spdif->status & IEC958_AES0_NONAUDIO); + mutex_unlock(&codec->spdif_mutex);
eld = &spec->pins[pin_idx].sink_eld; if (!eld->monitor_present) @@ -750,12 +775,14 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, "pin=%d channels=%d\n", pin_nid, channels); - hdmi_setup_channel_mapping(codec, pin_nid, ca); + hdmi_setup_channel_mapping(codec, pin_nid, cvt_nid, non_pcm, ca); hdmi_stop_infoframe_trans(codec, pin_nid); hdmi_fill_audio_infoframe(codec, pin_nid, ai.bytes, sizeof(ai)); hdmi_start_infoframe_trans(codec, pin_nid); } + + per_cvt->non_pcm = non_pcm; }
@@ -1077,6 +1104,7 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
per_cvt->cvt_nid = cvt_nid; per_cvt->channels_min = 2; + per_cvt->non_pcm = false; if (chans <= 16) per_cvt->channels_max = chans;
@@ -1164,7 +1192,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
- hdmi_setup_audio_infoframe(codec, pin_idx, substream); + hdmi_setup_audio_infoframe(codec, pin_idx, cvt_nid, substream);
pinctl = snd_hda_codec_read(codec, pin_nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
For HBR stream test, use straight channel mapping way. when switched back to "speaker-test -c8", even the audio infoframe is up-to-date, there should be correct channel mapping setup.
Signed-off-by: Wang Xingchao xingchao.wang@intel.com --- sound/pci/hda/patch_hdmi.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index a87f8b2..bcb0939 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -780,6 +780,11 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, hdmi_fill_audio_infoframe(codec, pin_nid, ai.bytes, sizeof(ai)); hdmi_start_infoframe_trans(codec, pin_nid); + } else { + /* For non-pcm audio switch, setup new channel mapping + * accordingly */ + if (per_cvt->non_pcm != non_pcm) + hdmi_setup_channel_mapping(codec, pin_nid, cvt_nid, non_pcm, ca); }
per_cvt->non_pcm = non_pcm;
At Wed, 5 Sep 2012 13:58:35 +0800, Wang Xingchao wrote:
Please Note This patchset has not been tested yet on any Hardware platform. i could only confirm there's no compile error. :) I test previous single patch on the Yamaha A/V receiver which works well, the test results was also confirmed by some guys from XBMC forum.
The idea of this patch comes from Anssi, Big credit to him at first!
Any comments are appreciated!
Changelog:
- do not touch channel_allocation priority order, use new api to get
correct channels number
- use spdif->status to check audio type, pcm or non-pcm
- create new non_pcm_mapping[] for non_pcm audio in seperate block
- add non_pcm hdmi_spec_per_cvt to remember previous audio type, used to determine whether need a channel mapping update during the pcm/non-pcm stream switch with same channel number.
Wang Xingchao (3): ALSA: hdmi - fix channel_allocation array wrong order ALSA: HDMI - Enable HBR feature on Intel chips ALSA: HDMI - Setup channel mapping for non_pcm audio
The patches look good to me. Maybe you can unify the subject line prefix (either lower or upper case), though :)
thanks,
Takashi
sound/pci/hda/patch_hdmi.c | 56 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)
-- 1.7.9.5
2012/9/5 Takashi Iwai tiwai@suse.de:
At Wed, 5 Sep 2012 13:58:35 +0800, Wang Xingchao wrote:
Please Note This patchset has not been tested yet on any Hardware platform. i could only confirm there's no compile error. :) I test previous single patch on the Yamaha A/V receiver which works well, the test results was also confirmed by some guys from XBMC forum.
The idea of this patch comes from Anssi, Big credit to him at first!
Any comments are appreciated!
Changelog:
- do not touch channel_allocation priority order, use new api to get
correct channels number
- use spdif->status to check audio type, pcm or non-pcm
- create new non_pcm_mapping[] for non_pcm audio in seperate block
- add non_pcm hdmi_spec_per_cvt to remember previous audio type, used to determine whether need a channel mapping update during the pcm/non-pcm stream switch with same channel number.
Wang Xingchao (3): ALSA: hdmi - fix channel_allocation array wrong order ALSA: HDMI - Enable HBR feature on Intel chips ALSA: HDMI - Setup channel mapping for non_pcm audio
The patches look good to me. Maybe you can unify the subject line prefix (either lower or upper case), though :)
Okay. And I will let you know after the patches are tested, this may take some time. :(
thanks --xingchao
thanks,
Takashi
sound/pci/hda/patch_hdmi.c | 56 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 51 insertions(+), 5 deletions(-)
-- 1.7.9.5
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
participants (3)
-
Takashi Iwai
-
Wang Xingchao
-
Wang Xingchao