diff options
-rw-r--r-- | sound/soc/sof/Kconfig | 18 | ||||
-rw-r--r-- | sound/soc/sof/intel/Kconfig | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/Makefile | 2 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-bus.c | 23 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-codec.c | 252 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-ctrl.c | 63 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-dai.c | 10 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-dsp.c | 44 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-mlink.c | 89 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda-stream.c | 30 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.c | 62 | ||||
-rw-r--r-- | sound/soc/sof/intel/hda.h | 63 | ||||
-rw-r--r-- | sound/soc/sof/sof-audio.c | 5 | ||||
-rw-r--r-- | sound/soc/sof/sof-priv.h | 3 |
14 files changed, 438 insertions, 228 deletions
diff --git a/sound/soc/sof/Kconfig b/sound/soc/sof/Kconfig index 37f7df5fde17..0b9beb74b0f6 100644 --- a/sound/soc/sof/Kconfig +++ b/sound/soc/sof/Kconfig @@ -97,13 +97,13 @@ config SND_SOC_SOF_NOCODEC tristate config SND_SOC_SOF_NOCODEC_SUPPORT - bool "SOF nocodec mode support" + bool "SOF nocodec static mode support" help This adds support for a dummy/nocodec machine driver fallback option if no known codec is detected. This is typically only enabled for developers or devices where the sound card is controlled externally. - This option is mutually exclusive with the Intel HDAudio support. + This option is mutually exclusive at build time with the Intel HDAudio support. Selecting it may have negative impacts and prevent e.g. microphone functionality from being enabled on Intel CoffeeLake and later platforms. @@ -136,6 +136,19 @@ config SND_SOC_SOF_DEBUG if SND_SOC_SOF_DEBUG +config SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT + bool "SOF nocodec debug mode support" + depends on !SND_SOC_SOF_NOCODEC_SUPPORT + help + This adds support for a dummy/nocodec machine driver fallback + option. + Unlike the SND_SOC_SOF_NOCODEC_SUPPORT, this option is NOT + mutually exclusive at build with the Intel HDAudio support. The + selection will be done depending on command line or modprobe.d settings + Distributions should not select this option! + Say Y if you need this nocodec debug fallback option. + If unsure select "N". + config SND_SOC_SOF_FORCE_NOCODEC_MODE bool "SOF force nocodec Mode" depends on SND_SOC_SOF_NOCODEC_SUPPORT @@ -239,6 +252,7 @@ config SND_SOC_SOF tristate select SND_SOC_TOPOLOGY select SND_SOC_SOF_NOCODEC if SND_SOC_SOF_NOCODEC_SUPPORT + select SND_SOC_SOF_NOCODEC if SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT help This option is not user-selectable but automagically handled by 'select' statements at a higher level. diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig index 7af495fb6125..36a0e2bf30ff 100644 --- a/sound/soc/sof/intel/Kconfig +++ b/sound/soc/sof/intel/Kconfig @@ -277,7 +277,7 @@ if SND_SOC_SOF_HDA_COMMON config SND_SOC_SOF_HDA_LINK bool "SOF support for HDA Links(HDA/HDMI)" - depends on SND_SOC_SOF_NOCODEC=n + depends on SND_SOC_SOF_NOCODEC_SUPPORT=n select SND_SOC_SOF_PROBE_WORK_QUEUE help This adds support for HDA links(HDA/HDMI) with Sound Open Firmware diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile index 8b8ea0361785..8201cbdd654c 100644 --- a/sound/soc/sof/intel/Makefile +++ b/sound/soc/sof/intel/Makefile @@ -5,7 +5,7 @@ snd-sof-acpi-intel-bdw-objs := bdw.o snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \ hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \ - hda-dai.o hda-bus.o \ + hda-dai.o hda-bus.o hda-mlink.o \ skl.o hda-loader-skl.o \ apl.o cnl.o tgl.o icl.o mtl.o hda-common-ops.o diff --git a/sound/soc/sof/intel/hda-bus.c b/sound/soc/sof/intel/hda-bus.c index 0862ff8b6627..acb4b85868d0 100644 --- a/sound/soc/sof/intel/hda-bus.c +++ b/sound/soc/sof/intel/hda-bus.c @@ -18,11 +18,7 @@ #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) #include "../../codecs/hdac_hda.h" #define sof_hda_ext_ops snd_soc_hdac_hda_get_ops() -#else -#define sof_hda_ext_ops NULL -#endif -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) static void update_codec_wake_enable(struct hdac_bus *bus, unsigned int addr, bool link_power) { unsigned int mask = snd_hdac_chip_readw(bus, WAKEEN); @@ -70,11 +66,13 @@ static const struct hdac_bus_ops bus_core_ops = { /* * This can be used for both with/without hda link support. */ -void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev) +void sof_hda_bus_init(struct snd_sof_dev *sdev, struct device *dev) { -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + struct hdac_bus *bus = sof_to_bus(sdev); + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) snd_hdac_ext_bus_init(bus, dev, &bus_core_ops, sof_hda_ext_ops); -#else /* CONFIG_SND_SOC_SOF_HDA */ +#else /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ memset(bus, 0, sizeof(*bus)); bus->dev = dev; @@ -89,5 +87,14 @@ void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev) bus->idx = 0; spin_lock_init(&bus->reg_lock); -#endif /* CONFIG_SND_SOC_SOF_HDA */ +#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ +} + +void sof_hda_bus_exit(struct snd_sof_dev *sdev) +{ +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) + struct hdac_bus *bus = sof_to_bus(sdev); + + snd_hdac_ext_bus_exit(bus); +#endif } diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c index 1e9afc48394c..1882b9ac3c3b 100644 --- a/sound/soc/sof/intel/hda-codec.c +++ b/sound/soc/sof/intel/hda-codec.c @@ -1,7 +1,4 @@ -// 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. +// SPDX-License-Identifier: GPL-2.0-only // // Copyright(c) 2018 Intel Corporation. All rights reserved. // @@ -16,15 +13,18 @@ #include <sound/sof.h> #include "../ops.h" #include "hda.h" + #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) #include "../../codecs/hdac_hda.h" -#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ #define CODEC_PROBE_RETRIES 3 -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) #define IDISP_VID_INTEL 0x80860000 +static int hda_codec_mask = -1; +module_param_named(codec_mask, hda_codec_mask, int, 0444); +MODULE_PARM_DESC(codec_mask, "SOF HDA codec mask for probing"); + /* load the legacy HDA codec driver */ static int request_codec_module(struct hda_codec *codec) { @@ -72,6 +72,10 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) struct hda_codec *codec; unsigned int mask = 0; + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + if (enable) { list_for_each_codec(codec, hbus) if (codec->jacktbl.used) @@ -80,6 +84,7 @@ void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) snd_hdac_chip_updatew(bus, WAKEEN, STATESTS_INT_MASK, mask); } +EXPORT_SYMBOL_NS_GPL(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC); /* check jack status after resuming from suspend mode */ void hda_codec_jack_check(struct snd_sof_dev *sdev) @@ -87,6 +92,10 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev) struct hda_bus *hbus = sof_to_hbus(sdev); struct hda_codec *codec; + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + list_for_each_codec(codec, hbus) /* * Wake up all jack-detecting codecs regardless whether an event @@ -95,12 +104,7 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev) if (codec->jacktbl.used) pm_request_resume(&codec->core.dev); } -#else -void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) {} -void hda_codec_jack_check(struct snd_sof_dev *sdev) {} -#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ -EXPORT_SYMBOL_NS(hda_codec_jack_wake_enable, SND_SOC_SOF_HDA_AUDIO_CODEC); -EXPORT_SYMBOL_NS(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_jack_check, SND_SOC_SOF_HDA_AUDIO_CODEC); #if IS_ENABLED(CONFIG_SND_HDA_GENERIC) #define is_generic_config(bus) \ @@ -139,13 +143,9 @@ static struct hda_codec *hda_codec_device_init(struct hdac_bus *bus, int addr, i } /* probe individual codec */ -static int hda_codec_probe(struct snd_sof_dev *sdev, int address, - bool hda_codec_use_common_hdmi) +static int hda_codec_probe(struct snd_sof_dev *sdev, int address) { -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) struct hdac_hda_priv *hda_priv; - int type = HDA_DEV_LEGACY; -#endif struct hda_bus *hbus = sof_to_hbus(sdev); struct hda_codec *codec; u32 hda_cmd = (address << 28) | (AC_NODE_ROOT << 20) | @@ -165,16 +165,11 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address, dev_dbg(sdev->dev, "HDA codec #%d probed OK: response: %x\n", address, resp); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) hda_priv = devm_kzalloc(sdev->dev, sizeof(*hda_priv), GFP_KERNEL); if (!hda_priv) return -ENOMEM; - /* only probe ASoC codec drivers for HDAC-HDMI */ - if (!hda_codec_use_common_hdmi && (resp & 0xFFFF0000) == IDISP_VID_INTEL) - type = HDA_DEV_ASOC; - - codec = hda_codec_device_init(&hbus->core, address, type); + codec = hda_codec_device_init(&hbus->core, address, HDA_DEV_LEGACY); ret = PTR_ERR_OR_ZERO(codec); if (ret < 0) return ret; @@ -197,43 +192,40 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int address, else codec->probe_id = 0; - if (type == HDA_DEV_LEGACY) { - ret = hda_codec_load_module(codec); - /* - * handle ret==0 (no driver bound) as an error, but pass - * other return codes without modification - */ - if (ret == 0) - ret = -ENOENT; - } + ret = hda_codec_load_module(codec); + /* + * handle ret==0 (no driver bound) as an error, but pass + * other return codes without modification + */ + if (ret == 0) + ret = -ENOENT; out: if (ret < 0) { snd_hdac_device_unregister(&codec->core); put_device(&codec->core.dev); } -#else - codec = hda_codec_device_init(&hbus->core, address, HDA_DEV_ASOC); - ret = PTR_ERR_OR_ZERO(codec); -#endif return ret; } /* Codec initialization */ -void hda_codec_probe_bus(struct snd_sof_dev *sdev, - bool hda_codec_use_common_hdmi) +void hda_codec_probe_bus(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); int i, ret; + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + /* probe codecs in avail slots */ for (i = 0; i < HDA_MAX_CODECS; i++) { if (!(bus->codec_mask & (1 << i))) continue; - ret = hda_codec_probe(sdev, i, hda_codec_use_common_hdmi); + ret = hda_codec_probe(sdev, i); if (ret < 0) { dev_warn(bus->dev, "codec #%d probe error, ret: %d\n", i, ret); @@ -241,27 +233,193 @@ void hda_codec_probe_bus(struct snd_sof_dev *sdev, } } } -EXPORT_SYMBOL_NS(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC); +EXPORT_SYMBOL_NS_GPL(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_check_for_state_change(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + unsigned int codec_mask; + + codec_mask = snd_hdac_chip_readw(bus, STATESTS); + if (codec_mask) { + hda_codec_jack_check(sdev); + snd_hdac_chip_writew(bus, STATESTS, codec_mask); + } +} +EXPORT_SYMBOL_NS_GPL(hda_codec_check_for_state_change, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_detect_mask(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* Accept unsolicited responses */ + snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL); + + /* 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); + } + + if (hda_codec_mask != -1) { + bus->codec_mask &= hda_codec_mask; + dev_dbg(bus->dev, "filtered codec_mask = 0x%lx\n", + bus->codec_mask); + } +} +EXPORT_SYMBOL_NS_GPL(hda_codec_detect_mask, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_init_cmd_io(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* initialize the codec command I/O */ + snd_hdac_bus_init_cmd_io(bus); +} +EXPORT_SYMBOL_NS_GPL(hda_codec_init_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_resume_cmd_io(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* set up CORB/RIRB buffers if was on before suspend */ + if (bus->cmd_dma_state) + snd_hdac_bus_init_cmd_io(bus); +} +EXPORT_SYMBOL_NS_GPL(hda_codec_resume_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_stop_cmd_io(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* initialize the codec command I/O */ + snd_hdac_bus_stop_cmd_io(bus); +} +EXPORT_SYMBOL_NS_GPL(hda_codec_stop_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_suspend_cmd_io(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* stop the CORB/RIRB DMA if it is On */ + if (bus->cmd_dma_state) + snd_hdac_bus_stop_cmd_io(bus); + +} +EXPORT_SYMBOL_NS_GPL(hda_codec_suspend_cmd_io, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_rirb_status_clear(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* clear rirb status */ + snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK); +} +EXPORT_SYMBOL_NS_GPL(hda_codec_rirb_status_clear, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_set_codec_wakeup(struct snd_sof_dev *sdev, bool status) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + snd_hdac_set_codec_wakeup(bus, status); +} +EXPORT_SYMBOL_NS_GPL(hda_codec_set_codec_wakeup, SND_SOC_SOF_HDA_AUDIO_CODEC); + +bool hda_codec_check_rirb_status(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + bool active = false; + u32 rirb_status; + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return false; + + rirb_status = snd_hdac_chip_readb(bus, RIRBSTS); + if (rirb_status & RIRB_INT_MASK) { + /* + * Clearing the interrupt status here ensures + * that no interrupt gets masked after the RIRB + * wp is read in snd_hdac_bus_update_rirb. + */ + snd_hdac_chip_writeb(bus, RIRBSTS, + RIRB_INT_MASK); + active = true; + if (rirb_status & RIRB_INT_RESPONSE) + snd_hdac_bus_update_rirb(bus); + } + return active; +} +EXPORT_SYMBOL_NS_GPL(hda_codec_check_rirb_status, SND_SOC_SOF_HDA_AUDIO_CODEC); + +void hda_codec_device_remove(struct snd_sof_dev *sdev) +{ + struct hdac_bus *bus = sof_to_bus(sdev); + + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + + /* codec removal, invoke bus_device_remove */ + snd_hdac_ext_bus_device_remove(bus); +} +EXPORT_SYMBOL_NS_GPL(hda_codec_device_remove, SND_SOC_SOF_HDA_AUDIO_CODEC); + +#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ -#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \ - IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) && IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable) { struct hdac_bus *bus = sof_to_bus(sdev); + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return; + if (HDA_IDISP_CODEC(bus->codec_mask)) { dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable); snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable); } } -EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +EXPORT_SYMBOL_NS_GPL(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); int hda_codec_i915_init(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); int ret; + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return 0; + /* i915 exposes a HDA codec for HDMI audio */ ret = snd_hdac_i915_init(bus); if (ret < 0) @@ -272,12 +430,16 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev) return 0; } -EXPORT_SYMBOL_NS(hda_codec_i915_init, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +EXPORT_SYMBOL_NS_GPL(hda_codec_i915_init, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); int hda_codec_i915_exit(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + return 0; + if (!bus->audio_component) return 0; @@ -286,7 +448,7 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev) return snd_hdac_i915_exit(bus); } -EXPORT_SYMBOL_NS(hda_codec_i915_exit, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); +EXPORT_SYMBOL_NS_GPL(hda_codec_i915_exit, SND_SOC_SOF_HDA_AUDIO_CODEC_I915); #endif diff --git a/sound/soc/sof/intel/hda-ctrl.c b/sound/soc/sof/intel/hda-ctrl.c index 12900965ca5f..3aea36c077c9 100644 --- a/sound/soc/sof/intel/hda-ctrl.c +++ b/sound/soc/sof/intel/hda-ctrl.c @@ -22,12 +22,6 @@ #include "../ops.h" #include "hda.h" -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) -static int hda_codec_mask = -1; -module_param_named(codec_mask, hda_codec_mask, int, 0444); -MODULE_PARM_DESC(codec_mask, "SOF HDA codec mask for probing"); -#endif - /* * HDA Operations. */ @@ -185,18 +179,14 @@ int hda_dsp_ctrl_clock_power_gating(struct snd_sof_dev *sdev, bool enable) int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_ext_link *hlink; -#endif struct hdac_stream *stream; int sd_offset, ret = 0; if (bus->chip_init) return 0; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_set_codec_wakeup(bus, true); -#endif + hda_codec_set_codec_wakeup(sdev, true); + hda_dsp_ctrl_misc_clock_gating(sdev, false); /* reset HDA controller */ @@ -213,22 +203,7 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev) goto err; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* Accept unsolicited responses */ - snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL); - - /* 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); - } - - if (hda_codec_mask != -1) { - bus->codec_mask &= hda_codec_mask; - dev_dbg(bus->dev, "filtered codec_mask = 0x%lx\n", - bus->codec_mask); - } -#endif + hda_codec_detect_mask(sdev); /* clear stream status */ list_for_each_entry(stream, &bus->stream_list, list) { @@ -242,19 +217,13 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS, SOF_HDA_WAKESTS_INT_MASK); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* clear rirb status */ - snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK); -#endif + hda_codec_rirb_status_clear(sdev); /* clear interrupt status register */ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS, SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* initialize the codec command I/O */ - snd_hdac_bus_init_cmd_io(bus); -#endif + hda_codec_init_cmd_io(sdev); /* enable CIE and GIE interrupts */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, @@ -269,19 +238,14 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev) upper_32_bits(bus->posbuf.addr)); } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* Reset stream-to-link mapping */ - list_for_each_entry(hlink, &bus->hlink_list, list) - writel(0, hlink->ml_addr + AZX_REG_ML_LOSIDV); -#endif + hda_bus_ml_reset_losidv(bus); bus->chip_init = true; err: hda_dsp_ctrl_misc_clock_gating(sdev, true); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_set_codec_wakeup(bus, false); -#endif + + hda_codec_set_codec_wakeup(sdev, false); return ret; } @@ -326,19 +290,14 @@ void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev) snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS, SOF_HDA_WAKESTS_INT_MASK); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* clear rirb status */ - snd_hdac_chip_writeb(bus, RIRBSTS, RIRB_INT_MASK); -#endif + hda_codec_rirb_status_clear(sdev); /* clear interrupt status register */ snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS, SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* disable CORB/RIRB */ - snd_hdac_bus_stop_cmd_io(bus); -#endif + hda_codec_stop_cmd_io(sdev); + /* disable position buffer */ if (bus->use_posbuf && bus->posbuf.addr) { snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c index 6e368974abd1..0cb7af719c66 100644 --- a/sound/soc/sof/intel/hda-dai.c +++ b/sound/soc/sof/intel/hda-dai.c @@ -27,7 +27,7 @@ static bool hda_use_tplg_nhlt; module_param_named(sof_use_tplg_nhlt, hda_use_tplg_nhlt, bool, 0444); MODULE_PARM_DESC(sof_use_tplg_nhlt, "SOF topology nhlt override"); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) struct hda_pipe_params { u32 ch; @@ -772,7 +772,7 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) ops->drv[i].ops = &ipc3_ssp_dai_ops; continue; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) if (strstr(ops->drv[i].name, "iDisp") || strstr(ops->drv[i].name, "Analog") || strstr(ops->drv[i].name, "Digital")) @@ -793,7 +793,7 @@ void hda_set_dai_drv_ops(struct snd_sof_dev *sdev, struct snd_sof_dsp_ops *ops) ops->drv[i].ops = &ipc4_ssp_dai_ops; continue; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) if (strstr(ops->drv[i].name, "iDisp") || strstr(ops->drv[i].name, "Analog") || strstr(ops->drv[i].name, "Digital")) @@ -911,7 +911,7 @@ struct snd_soc_dai_driver skl_dai[] = { .channels_max = 4, }, }, -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) { .name = "iDisp1 Pin", .playback = { @@ -984,7 +984,7 @@ int hda_dsp_dais_suspend(struct snd_sof_dev *sdev) * Since the component suspend is called last, we can trap this corner case * and force the DAIs to release their resources. */ -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) int ret; ret = hda_dai_suspend(sof_to_bus(sdev)); diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c index 6d896ea31680..c61bab1a5719 100644 --- a/sound/soc/sof/intel/hda-dsp.c +++ b/sound/soc/sof/intel/hda-dsp.c @@ -614,9 +614,7 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; const struct sof_intel_dsp_desc *chip = hda->desc; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) struct hdac_bus *bus = sof_to_bus(sdev); -#endif int ret, j; /* @@ -635,12 +633,10 @@ static int hda_suspend(struct snd_sof_dev *sdev, bool runtime_suspend) if (ret < 0) return ret; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) hda_codec_jack_wake_enable(sdev, runtime_suspend); - /* power down all hda link */ - snd_hdac_ext_bus_link_power_down_all(bus); -#endif + /* power down all hda links */ + hda_bus_ml_suspend(bus); ret = chip->power_down_dsp(sdev); if (ret < 0) { @@ -698,14 +694,12 @@ static int hda_resume(struct snd_sof_dev *sdev, bool runtime_resume) goto cleanup; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) /* check jack status */ if (runtime_resume) { hda_codec_jack_wake_enable(sdev, false); if (sdev->system_suspend_target == SOF_SUSPEND_NONE) hda_codec_jack_check(sdev); } -#endif /* enable ppcap interrupt */ hda_dsp_ctrl_ppcap_enable(sdev, true); @@ -721,37 +715,26 @@ cleanup: int hda_dsp_resume(struct snd_sof_dev *sdev) { struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; + struct hdac_bus *bus = sof_to_bus(sdev); struct pci_dev *pci = to_pci_dev(sdev->dev); const struct sof_dsp_power_state target_state = { .state = SOF_DSP_PM_D0, .substate = SOF_HDA_DSP_PM_D0I0, }; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_bus *bus = sof_to_bus(sdev); - struct hdac_ext_link *hlink = NULL; -#endif int ret; /* resume from D0I3 */ if (sdev->dsp_power_state.state == SOF_DSP_PM_D0) { -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* 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) { - dev_err(sdev->dev, - "error %d in %s: failed to power up links", - ret, __func__); - return ret; - } - } + ret = hda_bus_ml_resume(bus); + if (ret < 0) { + dev_err(sdev->dev, + "error %d in %s: failed to power up links", + ret, __func__); + return ret; } /* set up CORB/RIRB buffers if was on before suspend */ - if (bus->cmd_dma_state) - snd_hdac_bus_init_cmd_io(bus); -#endif + hda_codec_resume_cmd_io(sdev); /* Set DSP power state */ ret = snd_sof_dsp_set_power_state(sdev, &target_state); @@ -860,20 +843,17 @@ int hda_dsp_suspend(struct snd_sof_dev *sdev, u32 target_state) HDA_VS_INTEL_EM2_L1SEN, HDA_VS_INTEL_EM2_L1SEN); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) /* stop the CORB/RIRB DMA if it is On */ - if (bus->cmd_dma_state) - snd_hdac_bus_stop_cmd_io(bus); + hda_codec_suspend_cmd_io(sdev); /* no link can be powered in s0ix state */ - ret = snd_hdac_ext_bus_link_power_down_all(bus); + ret = hda_bus_ml_suspend(bus); if (ret < 0) { dev_err(sdev->dev, "error %d in %s: failed to power down links", ret, __func__); return ret; } -#endif /* enable the system waking up via IPC IRQ */ enable_irq_wake(pci->irq); 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 diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c index c858f30c08f9..8e3f05857632 100644 --- a/sound/soc/sof/intel/hda-stream.c +++ b/sound/soc/sof/intel/hda-stream.c @@ -765,9 +765,6 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context) { struct snd_sof_dev *sdev = context; struct hdac_bus *bus = sof_to_bus(sdev); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - u32 rirb_status; -#endif bool active; u32 status; int i; @@ -785,23 +782,9 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context) active = hda_dsp_stream_check(bus, status); /* check and clear RIRB interrupt */ -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) if (status & AZX_INT_CTRL_EN) { - rirb_status = snd_hdac_chip_readb(bus, RIRBSTS); - if (rirb_status & RIRB_INT_MASK) { - /* - * Clearing the interrupt status here ensures - * that no interrupt gets masked after the RIRB - * wp is read in snd_hdac_bus_update_rirb. - */ - snd_hdac_chip_writeb(bus, RIRBSTS, - RIRB_INT_MASK); - active = true; - if (rirb_status & RIRB_INT_RESPONSE) - snd_hdac_bus_update_rirb(bus); - } + active |= hda_codec_check_rirb_status(sdev); } -#endif spin_unlock_irq(&bus->reg_lock); } @@ -854,15 +837,16 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev) return -ENOMEM; } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* mem alloc for the CORB/RIRB ringbuffers */ + /* + * mem alloc for the CORB/RIRB ringbuffers - this will be used only for + * HDAudio codecs + */ ret = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, &pci->dev, PAGE_SIZE, &bus->rb); if (ret < 0) { dev_err(sdev->dev, "error: RB alloc failed\n"); return -ENOMEM; } -#endif /* create capture streams */ for (i = 0; i < num_capture; i++) { @@ -995,11 +979,9 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev) if (bus->posbuf.area) snd_dma_free_pages(&bus->posbuf); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* free position buffer */ + /* free CORB/RIRB buffer - only used for HDaudio codecs */ if (bus->rb.area) snd_dma_free_pages(&bus->rb); -#endif list_for_each_entry_safe(s, _s, &bus->stream_list, list) { /* TODO: decouple */ diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 79c32d948b2d..99be5ef78324 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -383,12 +383,6 @@ static int mclk_id_override = -1; module_param_named(mclk_id, mclk_id_override, int, 0444); MODULE_PARM_DESC(mclk_id, "SOF SSP mclk_id"); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) -static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI); -module_param_named(use_common_hdmi, hda_codec_use_common_hdmi, bool, 0444); -MODULE_PARM_DESC(use_common_hdmi, "SOF HDA use common HDMI codec driver"); -#endif - static const struct hda_dsp_msg_code hda_dsp_rom_fw_error_texts[] = { {HDA_DSP_ROM_CSE_ERROR, "error: cse error"}, {HDA_DSP_ROM_CSE_WRONG_RESPONSE, "error: cse wrong response"}, @@ -702,7 +696,7 @@ static int hda_init(struct snd_sof_dev *sdev) bus = sof_to_bus(sdev); /* HDA bus init */ - sof_hda_bus_init(bus, &pci->dev); + sof_hda_bus_init(sdev, &pci->dev); if (sof_hda_position_quirk == SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS) bus->use_posbuf = 0; @@ -797,7 +791,7 @@ static int check_nhlt_ssp_mclk_mask(struct snd_sof_dev *sdev, int ssp_num) return intel_nhlt_ssp_mclk_mask(nhlt, ssp_num); } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) static const char *fixup_tplg_name(struct snd_sof_dev *sdev, const char *sof_tplg_filename, @@ -877,9 +871,6 @@ static int hda_init_caps(struct snd_sof_dev *sdev) { struct hdac_bus *bus = sof_to_bus(sdev); struct snd_sof_pdata *pdata = sdev->pdata; -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_ext_link *hlink; -#endif struct sof_intel_hda_dev *hdev = pdata->hw_pdata; u32 link_mask; int ret = 0; @@ -924,37 +915,17 @@ static int hda_init_caps(struct snd_sof_dev *sdev) skip_soundwire: -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - if (bus->mlcap) - snd_hdac_ext_bus_get_ml_capabilities(bus); + hda_bus_ml_get_capabilities(bus); /* create codec instances */ - hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi); + hda_codec_probe_bus(sdev); if (!HDA_IDISP_CODEC(bus->codec_mask)) hda_codec_i915_display_power(sdev, false); - /* - * we are done probing so decrement link counts - */ - list_for_each_entry(hlink, &bus->hlink_list, list) - snd_hdac_ext_bus_link_put(bus, hlink); -#endif - return 0; -} + hda_bus_ml_put_all(bus); -static void hda_check_for_state_change(struct snd_sof_dev *sdev) -{ -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - struct hdac_bus *bus = sof_to_bus(sdev); - unsigned int codec_mask; - - codec_mask = snd_hdac_chip_readw(bus, STATESTS); - if (codec_mask) { - hda_codec_jack_check(sdev); - snd_hdac_chip_writew(bus, STATESTS, codec_mask); - } -#endif + return 0; } static irqreturn_t hda_dsp_interrupt_handler(int irq, void *context) @@ -1006,7 +977,7 @@ static irqreturn_t hda_dsp_interrupt_thread(int irq, void *context) hda_sdw_process_wakeen(sdev); } - hda_check_for_state_change(sdev); + hda_codec_check_for_state_change(sdev); /* enable GIE interrupt */ snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, @@ -1202,10 +1173,7 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) /* cancel any attempt for DSP D0I3 */ cancel_delayed_work_sync(&hda->d0i3_work); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - /* codec removal, invoke bus_device_remove */ - snd_hdac_ext_bus_device_remove(bus); -#endif + hda_codec_device_remove(sdev); hda_sdw_exit(sdev); @@ -1233,16 +1201,14 @@ int hda_dsp_remove(struct snd_sof_dev *sdev) pci_free_irq_vectors(pci); hda_dsp_stream_free(sdev); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_ext_link_free_all(bus); -#endif + + hda_bus_ml_free(sof_to_bus(sdev)); iounmap(sdev->bar[HDA_DSP_BAR]); iounmap(bus->remap_addr); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) - snd_hdac_ext_bus_exit(bus); -#endif + sof_hda_bus_exit(sdev); + hda_codec_i915_exit(sdev); return 0; @@ -1256,7 +1222,7 @@ int hda_power_down_dsp(struct snd_sof_dev *sdev) return hda_dsp_core_reset_power_down(sdev, chip->host_managed_cores_mask); } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) static void hda_generic_machine_select(struct snd_sof_dev *sdev, struct snd_soc_acpi_mach **mach) { @@ -1335,7 +1301,7 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, if (*mach) { mach_params = &(*mach)->mach_params; mach_params->codec_mask = bus->codec_mask; - mach_params->common_hdmi_codec_drv = hda_codec_use_common_hdmi; + mach_params->common_hdmi_codec_drv = true; } } #else diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h index 17ed7e60cae8..ea73fd17ae28 100644 --- a/sound/soc/sof/intel/hda.h +++ b/sound/soc/sof/intel/hda.h @@ -708,22 +708,46 @@ void hda_dsp_ctrl_stop_chip(struct snd_sof_dev *sdev); /* * HDA bus operations. */ -void sof_hda_bus_init(struct hdac_bus *bus, struct device *dev); +void sof_hda_bus_init(struct snd_sof_dev *sdev, struct device *dev); +void sof_hda_bus_exit(struct snd_sof_dev *sdev); -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) /* * HDA Codec operations. */ -void hda_codec_probe_bus(struct snd_sof_dev *sdev, - bool hda_codec_use_common_hdmi); +void hda_codec_probe_bus(struct snd_sof_dev *sdev); void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable); void hda_codec_jack_check(struct snd_sof_dev *sdev); +void hda_codec_check_for_state_change(struct snd_sof_dev *sdev); +void hda_codec_init_cmd_io(struct snd_sof_dev *sdev); +void hda_codec_resume_cmd_io(struct snd_sof_dev *sdev); +void hda_codec_stop_cmd_io(struct snd_sof_dev *sdev); +void hda_codec_suspend_cmd_io(struct snd_sof_dev *sdev); +void hda_codec_detect_mask(struct snd_sof_dev *sdev); +void hda_codec_rirb_status_clear(struct snd_sof_dev *sdev); +bool hda_codec_check_rirb_status(struct snd_sof_dev *sdev); +void hda_codec_set_codec_wakeup(struct snd_sof_dev *sdev, bool status); +void hda_codec_device_remove(struct snd_sof_dev *sdev); -#endif /* CONFIG_SND_SOC_SOF_HDA */ +#else + +static inline void hda_codec_probe_bus(struct snd_sof_dev *sdev) { } +static inline void hda_codec_jack_wake_enable(struct snd_sof_dev *sdev, bool enable) { } +static inline void hda_codec_jack_check(struct snd_sof_dev *sdev) { } +static inline void hda_codec_check_for_state_change(struct snd_sof_dev *sdev) { } +static inline void hda_codec_init_cmd_io(struct snd_sof_dev *sdev) { } +static inline void hda_codec_resume_cmd_io(struct snd_sof_dev *sdev) { } +static inline void hda_codec_stop_cmd_io(struct snd_sof_dev *sdev) { } +static inline void hda_codec_suspend_cmd_io(struct snd_sof_dev *sdev) { } +static inline void hda_codec_detect_mask(struct snd_sof_dev *sdev) { } +static inline void hda_codec_rirb_status_clear(struct snd_sof_dev *sdev) { } +static inline bool hda_codec_check_rirb_status(struct snd_sof_dev *sdev) { return false; } +static inline void hda_codec_set_codec_wakeup(struct snd_sof_dev *sdev, bool status) { } +static inline void hda_codec_device_remove(struct snd_sof_dev *sdev) { } -#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) && \ - (IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \ - IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)) +#endif /* CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC */ + +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) && IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable); int hda_codec_i915_init(struct snd_sof_dev *sdev); @@ -731,13 +755,32 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev); #else -static inline void hda_codec_i915_display_power(struct snd_sof_dev *sdev, - bool enable) { } +static inline void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable) { } static inline int hda_codec_i915_init(struct snd_sof_dev *sdev) { return 0; } static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; } #endif +#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) + +void hda_bus_ml_get_capabilities(struct hdac_bus *bus); +void hda_bus_ml_free(struct hdac_bus *bus); +void hda_bus_ml_put_all(struct hdac_bus *bus); +void hda_bus_ml_reset_losidv(struct hdac_bus *bus); +int hda_bus_ml_resume(struct hdac_bus *bus); +int hda_bus_ml_suspend(struct hdac_bus *bus); + +#else + +static inline void hda_bus_ml_get_capabilities(struct hdac_bus *bus) { } +static inline void hda_bus_ml_free(struct hdac_bus *bus) { } +static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { } +static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { } +static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; } +static inline int hda_bus_ml_suspend(struct hdac_bus *bus) { return 0; } + +#endif /* CONFIG_SND_SOC_SOF_HDA */ + /* * Trace Control. */ diff --git a/sound/soc/sof/sof-audio.c b/sound/soc/sof/sof-audio.c index 62092e2d609c..7306a2649857 100644 --- a/sound/soc/sof/sof-audio.c +++ b/sound/soc/sof/sof-audio.c @@ -826,6 +826,10 @@ int sof_machine_check(struct snd_sof_dev *sdev) if (!IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE)) { const struct snd_sof_of_mach *of_mach; + if (IS_ENABLED(CONFIG_SND_SOC_SOF_NOCODEC_DEBUG_SUPPORT) && + sof_debug_check_flag(SOF_DBG_FORCE_NOCODEC)) + goto nocodec; + /* find machine */ mach = snd_sof_machine_select(sdev); if (mach) { @@ -848,6 +852,7 @@ int sof_machine_check(struct snd_sof_dev *sdev) dev_warn(sdev->dev, "Force to use nocodec mode\n"); } +nocodec: /* select nocodec mode */ dev_warn(sdev->dev, "Using nocodec machine driver\n"); mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index d3ede97b6759..876e6fdbef4f 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -43,6 +43,9 @@ #define SOF_DBG_PRINT_IPC_SUCCESS_LOGS BIT(9) /* print IPC success * in dmesg logs */ +#define SOF_DBG_FORCE_NOCODEC BIT(10) /* ignore all codec-related + * configurations + */ /* Flag definitions used for controlling the DSP dump behavior */ #define SOF_DBG_DUMP_REGS BIT(0) |