Skip to content

Commit

Permalink
ASoC: SOF: Intel: hda: allow operation without i915 gfx
Browse files Browse the repository at this point in the history
Add support to configure the HDA controller with an external HDA
codec even if iDisp codec in i915 is not available.

This can happen for multiple reasons:
 - internal graphics is disabled on the system
 - i915 driver is not enabled in kernel or it fails to init
 - i915 codec reports error in HDA codec probe
 - HDA codec driver probe fails

Address all these scenarios, but keep using the existing topology.
In case failures occur, HDMI PCM nodes are created, but they will
report error if application tries to use them. No ALSA mixer controls
are created. If the external HDA codec init fails as well, SOF probe
will return error as before.

Signed-off-by: Kai Vehmanen <kai.vehmanen@linux.intel.com>
  • Loading branch information
kv2019i committed Jan 22, 2020
1 parent c5dcc8a commit a6da130
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 13 deletions.
9 changes: 8 additions & 1 deletion sound/soc/sof/intel/hda-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
bool hda_codec_use_common_hdmi)
{
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hdac_hda_priv *hda_priv;
#endif
struct hda_bus *hbus = sof_to_hbus(sdev);
Expand Down Expand Up @@ -113,8 +114,14 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address,
if (ret < 0)
return ret;

if ((resp & 0xFFFF0000) == IDISP_VID_INTEL)
if ((resp & 0xFFFF0000) == IDISP_VID_INTEL) {
if (!hda->i915_codec_enabled) {
dev_dbg(sdev->dev,
"iDisp hw present but no driver\n");
return -ENOENT;
}
hda_priv->need_display_power = true;
}

/*
* if common HDMI codec driver is not used, codec load
Expand Down
26 changes: 14 additions & 12 deletions sound/soc/sof/intel/hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,6 +574,7 @@ static const char *fixup_tplg_name(struct snd_sof_dev *sdev,

static int hda_init_caps(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct hdac_bus *bus = sof_to_bus(sdev);
struct snd_sof_pdata *pdata = sdev->pdata;
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
Expand All @@ -592,10 +593,10 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/* init i915 and HDMI codecs */
ret = hda_codec_i915_init(sdev);
if (ret < 0) {
dev_err(sdev->dev, "error: init i915 and HDMI codec failed\n");
return ret;
}
if (!ret)
hda->i915_codec_enabled = true;
else
dev_warn(sdev->dev, "init of i915 and HDMI codec failed\n");
#endif

/* Init HDA controller after i915 init */
Expand Down Expand Up @@ -644,7 +645,8 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
/* create codec instances */
hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);

hda_codec_i915_put(sdev);
if (!HDA_IDISP_CODEC(bus->codec_mask))
hda_codec_i915_put(sdev);

/*
* we are done probing so decrement link counts
Expand Down Expand Up @@ -938,7 +940,8 @@ int hda_dsp_remove(struct snd_sof_dev *sdev)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
snd_hdac_ext_bus_exit(bus);
#endif
hda_codec_i915_exit(sdev);
if (hda->i915_codec_enabled)
hda_codec_i915_exit(sdev);

return 0;
}
Expand Down Expand Up @@ -972,12 +975,11 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev)
/*
* If no machine driver is found, then:
*
* hda machine driver is used if :
* 1. there is one HDMI codec and one external HDAudio codec
* 2. only HDMI codec
* generic hda machine driver can handle:
* - one HDMI codec, and/or
* - one external HDAudio codec
*/
if (!pdata->machine && codec_num <= 2 &&
HDA_IDISP_CODEC(bus->codec_mask)) {
if (!pdata->machine && codec_num <= 2) {
hda_mach = snd_soc_acpi_intel_hda_machines;

/* topology: use the info from hda_machines */
Expand All @@ -987,7 +989,7 @@ static int hda_generic_machine_select(struct snd_sof_dev *sdev)
dev_info(bus->dev, "using HDA machine driver %s now\n",
hda_mach->drv_name);

if (codec_num == 1)
if (codec_num == 1 && HDA_IDISP_CODEC(bus->codec_mask))
idisp_str = "-idisp";
else
idisp_str = "";
Expand Down
3 changes: 3 additions & 0 deletions sound/soc/sof/intel/hda.h
Original file line number Diff line number Diff line change
Expand Up @@ -430,6 +430,9 @@ struct sof_intel_hda_dev {
/* PM related */
bool l1_support_changed;/* during suspend, is L1SEN changed or not */

/* is connection to i915 display driver enabled */
bool i915_codec_enabled;

/* DMIC device */
struct platform_device *dmic_dev;

Expand Down

0 comments on commit a6da130

Please sign in to comment.