From 3217f9fa8ede15082d88ef61fc4da5d92f1fabaf Mon Sep 17 00:00:00 2001 From: Rander Wang Date: Sun, 30 Sep 2018 15:47:56 +0800 Subject: [PATCH] ASOC: SOF: add a workaround to detect HDA HDMI codecs The initialization process of HDA in SOF is: (1) init HDA to set up a context for i915 initialization then stop HDA bus. (2) init i915 to init HDMI codecs. (3) init HDA again to make everything ready On WHL, only HDA analog codec is detected in step (1). And after step (2) HDMI could be detected. But in function azx_reset for step(3), the detection code is: /* detect codecs */ if (!bus->codec_mask) { bus->codec_mask = snd_hdac_chip_readw(bus, STATESTS); dev_dbg(bus->dev, "codec_mask = 0x%lx\n", bus->codec_mask); } At step (3) codec_mask is not zero, so no more query would be triggered. This results to miss detecting HDMI codecs. Now set codec_mask to zero to query again For GLK, none codec is detected at step(1), so it is no problem at step(3) Signed-off-by: Rander Wang --- sound/soc/sof/intel/hda.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 2e724d4efb638b..aa06a1ee897c44 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -388,7 +388,10 @@ static int hda_init_caps(struct snd_sof_dev *sdev) struct hdac_ext_link *hlink = NULL; int ret = 0; - // FIXME: we do this a lot ! + /* The initialization process of HDA in SOF is: + * (1) init HDA to set up a context for i915 initialization + * then stop HDA bus. + */ hda_dsp_ctrl_init_chip(sdev, true); device_disable_async_suspend(bus->dev); @@ -402,14 +405,24 @@ static int hda_init_caps(struct snd_sof_dev *sdev) snd_hdac_bus_stop_chip(bus); - /* probe i915 and HDA codecs */ + /* (2) probe i915 and HDA codecs, HDMI codecs */ if (IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) { ret = hda_codec_i915_init(sdev); if (ret < 0) return ret; } - // FIXME: we do this a lot ! + /* only HDA analog codec is detected in step (1) and + * codec_mask would be set. At step(3) HDMI codec can't + * be detected because HDA framework only check codecs + * when codec_mask is zero. So now set codec_mask to zero + * to force HDA framework to check codecs again. + */ + bus->codec_mask = 0; + + /* (3) init HDA again to make everything ready so that all + * the codecs can be detected. + */ ret = hda_dsp_ctrl_init_chip(sdev, true); if (ret < 0) { dev_err(bus->dev, "Init chip failed with ret: %d\n", ret);