diff options
author | Takashi Iwai <tiwai@suse.de> | 2022-12-22 11:11:48 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-12-22 11:11:48 +0300 |
commit | 2d78eb0342dd2c9c5cde9ae9ada1d33f189a858b (patch) | |
tree | f711bc9cab45f4963e4883ef15ff4c54a6cbc12e /sound/soc/sof/intel/hda-mlink.c | |
parent | b47068b4aa53a57552398e3f60d0ed1918700c2b (diff) | |
parent | ee0b089d660021792e4ab4dda191b097ce1e964f (diff) | |
download | linux-2d78eb0342dd2c9c5cde9ae9ada1d33f189a858b.tar.xz |
Merge branch 'for-next' into for-linus
Diffstat (limited to 'sound/soc/sof/intel/hda-mlink.c')
-rw-r--r-- | sound/soc/sof/intel/hda-mlink.c | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/sound/soc/sof/intel/hda-mlink.c b/sound/soc/sof/intel/hda-mlink.c new file mode 100644 index 000000000000..76ab9a2e7bb3 --- /dev/null +++ b/sound/soc/sof/intel/hda-mlink.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +// +// This file is provided under a dual BSD/GPLv2 license. When using or +// redistributing this file, you may do so under either license. +// +// Copyright(c) 2022 Intel Corporation. All rights reserved. +// + +/* + * Management of HDaudio multi-link (capabilities, power, coupling) + */ + +#include <sound/hdaudio_ext.h> +#include <sound/hda_register.h> + +#include <linux/acpi.h> +#include <linux/module.h> +#include <linux/soundwire/sdw.h> +#include <linux/soundwire/sdw_intel.h> +#include <sound/intel-dsp-config.h> +#include <sound/intel-nhlt.h> +#include <sound/sof.h> +#include <sound/sof/xtensa.h> +#include "../sof-audio.h" +#include "../sof-pci-dev.h" +#include "../ops.h" +#include "hda.h" + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + +void hda_bus_ml_get_capabilities(struct hdac_bus *bus) +{ + if (bus->mlcap) + snd_hdac_ext_bus_get_ml_capabilities(bus); +} + +void hda_bus_ml_free(struct hdac_bus *bus) +{ + struct hdac_ext_link *hlink; + + if (!bus->mlcap) + return; + + while (!list_empty(&bus->hlink_list)) { + hlink = list_first_entry(&bus->hlink_list, struct hdac_ext_link, list); + list_del(&hlink->list); + kfree(hlink); + } +} + +void hda_bus_ml_put_all(struct hdac_bus *bus) +{ + struct hdac_ext_link *hlink; + + list_for_each_entry(hlink, &bus->hlink_list, list) + snd_hdac_ext_bus_link_put(bus, hlink); +} + +void hda_bus_ml_reset_losidv(struct hdac_bus *bus) +{ + struct hdac_ext_link *hlink; + + /* Reset stream-to-link mapping */ + list_for_each_entry(hlink, &bus->hlink_list, list) + writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); +} + +int hda_bus_ml_resume(struct hdac_bus *bus) +{ + struct hdac_ext_link *hlink; + int ret; + + /* power up links that were active before suspend */ + list_for_each_entry(hlink, &bus->hlink_list, list) { + if (hlink->ref_count) { + ret = snd_hdac_ext_bus_link_power_up(hlink); + if (ret < 0) + return ret; + } + } + return 0; +} + +int hda_bus_ml_suspend(struct hdac_bus *bus) +{ + return snd_hdac_ext_bus_link_power_down_all(bus); +} + +#endif |