Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions sound/soc/intel/boards/skl_hda_dsp_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ static inline int skl_hda_hdmi_build_controls(struct snd_soc_card *card)
struct snd_soc_component *component;
struct skl_hda_hdmi_pcm *pcm;

/* HDMI disabled, do not create controls */
if (list_empty(&ctx->hdmi_pcm_list))
return 0;

pcm = list_first_entry(&ctx->hdmi_pcm_list, struct skl_hda_hdmi_pcm,
head);
component = pcm->codec_dai->component;
Expand Down
25 changes: 20 additions & 5 deletions sound/soc/intel/boards/skl_hda_dsp_generic.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ static const struct snd_soc_dapm_route skl_hda_map[] = {
{ "Alt Analog CPU Capture", NULL, "Alt Analog Codec Capture" },
};

SND_SOC_DAILINK_DEF(dummy_codec,
DAILINK_COMP_ARRAY(COMP_CODEC("snd-soc-dummy", "snd-soc-dummy-dai")));

static int skl_hda_card_late_probe(struct snd_soc_card *card)
{
return skl_hda_hdmi_jack_init(card);
Expand Down Expand Up @@ -114,13 +117,19 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
{
struct snd_soc_card *card = &hda_soc_card;
struct snd_soc_dai_link *dai_link;
u32 codec_count, codec_mask;
u32 codec_count, codec_mask, idisp_mask;
int i, num_links, num_route;

codec_mask = mach_params->codec_mask;
codec_count = hweight_long(codec_mask);
idisp_mask = codec_mask & IDISP_CODEC_MASK;

if (!codec_count || codec_count > 2 ||
(codec_count == 2 && !idisp_mask))
return -EINVAL;

if (codec_count == 1 && codec_mask & IDISP_CODEC_MASK) {
if (codec_mask == idisp_mask) {
/* topology with iDisp as the only HDA codec */
num_links = IDISP_DAI_COUNT + DMIC_DAI_COUNT;
num_route = IDISP_ROUTE_COUNT;

Expand All @@ -135,13 +144,19 @@ static int skl_hda_fill_card_info(struct snd_soc_acpi_mach_params *mach_params)
skl_hda_be_dai_links[IDISP_DAI_COUNT +
HDAC_DAI_COUNT + i];
}
} else if (codec_count == 2 && codec_mask & IDISP_CODEC_MASK) {
} else {
/* topology with external and iDisp HDA codecs */
num_links = ARRAY_SIZE(skl_hda_be_dai_links);
num_route = ARRAY_SIZE(skl_hda_map);
card->dapm_widgets = skl_hda_widgets;
card->num_dapm_widgets = ARRAY_SIZE(skl_hda_widgets);
} else {
return -EINVAL;
if (!idisp_mask) {
Comment thread
kv2019i marked this conversation as resolved.
Resolved
for (i = 0; i < IDISP_DAI_COUNT; i++) {
skl_hda_be_dai_links[i].codecs = dummy_codec;
Comment thread
kv2019i marked this conversation as resolved.
Resolved
skl_hda_be_dai_links[i].num_codecs =
ARRAY_SIZE(dummy_codec);
Comment thread
kv2019i marked this conversation as resolved.
Resolved
}
}
Comment thread
kv2019i marked this conversation as resolved.
Resolved
Comment thread
kv2019i marked this conversation as resolved.
Resolved
}

card->num_links = num_links;
Expand Down
11 changes: 10 additions & 1 deletion sound/soc/sof/intel/hda-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,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 (!hdev->bus->audio_component) {
dev_dbg(sdev->dev,
"iDisp hw present but no driver\n");
return -ENOENT;

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing I wondered about is should the device be unregistered here immediately in the error case. But I ended up not doing that. snd_hdac_ext_bus_device_remove() will clean up this device as well.

}
hda_priv->need_display_power = true;
}

/*
* if common HDMI codec driver is not used, codec load
Expand Down Expand Up @@ -203,6 +209,9 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev)
struct hdac_bus *bus = sof_to_bus(sdev);
int ret;

if (!bus->audio_component)
return 0;

/* power down unconditionally */
snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);

Expand Down
22 changes: 8 additions & 14 deletions sound/soc/sof/intel/hda.c
Original file line number Diff line number Diff line change
Expand Up @@ -520,10 +520,8 @@ static int hda_init(struct snd_sof_dev *sdev)

/* 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 < 0)
dev_warn(sdev->dev, "init of i915 and HDMI codec failed\n");

/* get controller capabilities */
ret = hda_dsp_ctrl_get_caps(sdev);
Expand Down Expand Up @@ -600,9 +598,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
if (ret < 0) {
dev_err(bus->dev, "error: init chip failed with ret: %d\n",
ret);
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
hda_codec_i915_exit(sdev);
#endif
return ret;
}

Expand Down Expand Up @@ -642,7 +637,7 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);

if (!HDA_IDISP_CODEC(bus->codec_mask))
hda_codec_i915_exit(sdev);
hda_codec_i915_display_power(sdev, false);

/*
* we are done probing so decrement link counts
Expand Down Expand Up @@ -971,12 +966,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 @@ -986,7 +980,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))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor again, not following here why codec count is important. previous author should have commented this.

idisp_str = "-idisp";
else
idisp_str = "";
Expand Down