summaryrefslogtreecommitdiff
path: root/sound/soc/sof/intel
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/sof/intel')
-rw-r--r--sound/soc/sof/intel/Kconfig19
-rw-r--r--sound/soc/sof/intel/apl.c15
-rw-r--r--sound/soc/sof/intel/bdw.c2
-rw-r--r--sound/soc/sof/intel/byt.c4
-rw-r--r--sound/soc/sof/intel/cnl.c21
-rw-r--r--sound/soc/sof/intel/hda-dai.c204
-rw-r--r--sound/soc/sof/intel/hda-dsp.c20
-rw-r--r--sound/soc/sof/intel/hda-ipc.c18
-rw-r--r--sound/soc/sof/intel/hda-loader.c118
-rw-r--r--sound/soc/sof/intel/hda-pcm.c31
-rw-r--r--sound/soc/sof/intel/hda-probes.c104
-rw-r--r--sound/soc/sof/intel/hda-stream.c122
-rw-r--r--sound/soc/sof/intel/hda-trace.c23
-rw-r--r--sound/soc/sof/intel/hda.c307
-rw-r--r--sound/soc/sof/intel/hda.h90
-rw-r--r--sound/soc/sof/intel/icl.c15
-rw-r--r--sound/soc/sof/intel/pci-tgl.c2
-rw-r--r--sound/soc/sof/intel/pci-tng.c3
-rw-r--r--sound/soc/sof/intel/tgl.c15
19 files changed, 569 insertions, 564 deletions
diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 88b6176af021..b53f216d4ecc 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -215,6 +215,7 @@ config SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_PCI_DEV
select SND_INTEL_DSP_CONFIG
select SND_SOC_SOF_HDA_LINK_BASELINE
+ select SND_SOC_SOF_HDA_PROBES
help
This option is not user-selectable but automagically handled by
'select' statements at a higher level.
@@ -240,15 +241,6 @@ config SND_SOC_SOF_HDA_AUDIO_CODEC
Say Y if you want to enable HDAudio codecs with SOF.
If unsure select "N".
-config SND_SOC_SOF_HDA_PROBES
- bool "SOF enable probes over HDA"
- depends on SND_SOC_SOF_DEBUG_PROBES
- help
- This option enables the data probing for Intel(R)
- Skylake and newer platforms.
- Say Y if you want to enable probes.
- If unsure, select "N".
-
endif ## SND_SOC_SOF_HDA_COMMON
config SND_SOC_SOF_HDA_LINK_BASELINE
@@ -266,6 +258,15 @@ config SND_SOC_SOF_HDA
This option is not user-selectable but automagically handled by
'select' statements at a higher level.
+config SND_SOC_SOF_HDA_PROBES
+ bool
+ select SND_SOC_SOF_DEBUG_PROBES
+ help
+ The option enables the data probing for Intel(R) Skylake and newer
+ (HDA) platforms.
+ This option is not user-selectable but automagically handled by
+ 'select' statements at a higher level.
+
config SND_SOC_SOF_INTEL_SOUNDWIRE_LINK_BASELINE
tristate
select SOUNDWIRE_INTEL if SND_SOC_SOF_INTEL_SOUNDWIRE
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 810b8b6748a0..6721c8f95161 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -56,7 +56,7 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
.get_window_offset = hda_dsp_ipc_get_window_offset,
.ipc_msg_data = hda_ipc_msg_data,
- .ipc_pcm_params = hda_ipc_pcm_params,
+ .set_stream_data_offset = hda_set_stream_data_offset,
/* machine driver */
.machine_select = hda_machine_select,
@@ -80,15 +80,6 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
.pcm_pointer = hda_dsp_pcm_pointer,
.pcm_ack = hda_dsp_pcm_ack,
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
- /* probe callbacks */
- .probe_assign = hda_probe_compr_assign,
- .probe_free = hda_probe_compr_free,
- .probe_set_params = hda_probe_compr_set_params,
- .probe_trigger = hda_probe_compr_trigger,
- .probe_pointer = hda_probe_compr_pointer,
-#endif
-
/* firmware loading */
.load_firmware = snd_sof_load_firmware_raw,
@@ -110,6 +101,10 @@ const struct snd_sof_dsp_ops sof_apl_ops = {
.trace_release = hda_dsp_trace_release,
.trace_trigger = hda_dsp_trace_trigger,
+ /* client ops */
+ .register_ipc_clients = hda_register_clients,
+ .unregister_ipc_clients = hda_unregister_clients,
+
/* DAI drivers */
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
diff --git a/sound/soc/sof/intel/bdw.c b/sound/soc/sof/intel/bdw.c
index d627b7498d5e..fb9682b2fe32 100644
--- a/sound/soc/sof/intel/bdw.c
+++ b/sound/soc/sof/intel/bdw.c
@@ -596,7 +596,7 @@ static const struct snd_sof_dsp_ops sof_bdw_ops = {
.get_window_offset = bdw_get_window_offset,
.ipc_msg_data = sof_ipc_msg_data,
- .ipc_pcm_params = sof_ipc_pcm_params,
+ .set_stream_data_offset = sof_set_stream_data_offset,
/* machine driver */
.machine_select = bdw_machine_select,
diff --git a/sound/soc/sof/intel/byt.c b/sound/soc/sof/intel/byt.c
index dcfeaedb8fd5..bb84a4aa587a 100644
--- a/sound/soc/sof/intel/byt.c
+++ b/sound/soc/sof/intel/byt.c
@@ -250,7 +250,7 @@ static const struct snd_sof_dsp_ops sof_byt_ops = {
.get_window_offset = atom_get_window_offset,
.ipc_msg_data = sof_ipc_msg_data,
- .ipc_pcm_params = sof_ipc_pcm_params,
+ .set_stream_data_offset = sof_set_stream_data_offset,
/* machine driver */
.machine_select = atom_machine_select,
@@ -332,7 +332,7 @@ static const struct snd_sof_dsp_ops sof_cht_ops = {
.get_window_offset = atom_get_window_offset,
.ipc_msg_data = sof_ipc_msg_data,
- .ipc_pcm_params = sof_ipc_pcm_params,
+ .set_stream_data_offset = sof_set_stream_data_offset,
/* machine driver */
.machine_select = atom_machine_select,
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index e615125d575e..6a96470b967f 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -161,11 +161,9 @@ static void cnl_ipc_dsp_done(struct snd_sof_dev *sdev)
static bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg,
u32 *dr, u32 *dd)
{
- struct sof_ipc_pm_gate *pm_gate;
-
- if (msg->header == (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE)) {
- pm_gate = msg->msg_data;
+ struct sof_ipc_pm_gate *pm_gate = msg->msg_data;
+ if (pm_gate->hdr.cmd == (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE)) {
/* send the compact message via the primary register */
*dr = HDA_IPC_MSG_COMPACT | HDA_IPC_PM_GATE;
@@ -276,7 +274,7 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
.get_window_offset = hda_dsp_ipc_get_window_offset,
.ipc_msg_data = hda_ipc_msg_data,
- .ipc_pcm_params = hda_ipc_pcm_params,
+ .set_stream_data_offset = hda_set_stream_data_offset,
/* machine driver */
.machine_select = hda_machine_select,
@@ -300,15 +298,6 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
.pcm_pointer = hda_dsp_pcm_pointer,
.pcm_ack = hda_dsp_pcm_ack,
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
- /* probe callbacks */
- .probe_assign = hda_probe_compr_assign,
- .probe_free = hda_probe_compr_free,
- .probe_set_params = hda_probe_compr_set_params,
- .probe_trigger = hda_probe_compr_trigger,
- .probe_pointer = hda_probe_compr_pointer,
-#endif
-
/* firmware loading */
.load_firmware = snd_sof_load_firmware_raw,
@@ -330,6 +319,10 @@ const struct snd_sof_dsp_ops sof_cnl_ops = {
.trace_release = hda_dsp_trace_release,
.trace_trigger = hda_dsp_trace_trigger,
+ /* client ops */
+ .register_ipc_clients = hda_register_clients,
+ .unregister_ipc_clients = hda_unregister_clients,
+
/* DAI drivers */
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
diff --git a/sound/soc/sof/intel/hda-dai.c b/sound/soc/sof/intel/hda-dai.c
index cd12589355ef..f9cb9f1f0237 100644
--- a/sound/soc/sof/intel/hda-dai.c
+++ b/sound/soc/sof/intel/hda-dai.c
@@ -16,10 +16,6 @@
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
-#include "../sof-probes.h"
-#endif
-
struct hda_pipe_params {
u32 ch;
u32 s_freq;
@@ -59,8 +55,10 @@ static struct hdac_ext_stream *
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct sof_intel_hda_stream *hda_stream;
+ const struct sof_intel_dsp_desc *chip;
+ struct snd_sof_dev *sdev;
struct hdac_ext_stream *res = NULL;
- struct hdac_stream *stream = NULL;
+ struct hdac_stream *hstream = NULL;
int stream_dir = substream->stream;
@@ -70,28 +68,39 @@ static struct hdac_ext_stream *
}
spin_lock_irq(&bus->reg_lock);
- list_for_each_entry(stream, &bus->stream_list, list) {
- struct hdac_ext_stream *hstream =
- stream_to_hdac_ext_stream(stream);
- if (stream->direction != substream->stream)
+ list_for_each_entry(hstream, &bus->stream_list, list) {
+ struct hdac_ext_stream *hext_stream =
+ stream_to_hdac_ext_stream(hstream);
+ if (hstream->direction != substream->stream)
continue;
- hda_stream = hstream_to_sof_hda_stream(hstream);
+ hda_stream = hstream_to_sof_hda_stream(hext_stream);
+ sdev = hda_stream->sdev;
+ chip = get_chip_info(sdev->pdata);
/* check if link is available */
- if (!hstream->link_locked) {
- if (stream->opened) {
+ if (!hext_stream->link_locked) {
+ /*
+ * choose the first available link for platforms that do not have the
+ * PROCEN_FMT_QUIRK set.
+ */
+ if (!(chip->quirks & SOF_INTEL_PROCEN_FMT_QUIRK)) {
+ res = hext_stream;
+ break;
+ }
+
+ if (hstream->opened) {
/*
* check if the stream tag matches the stream
* tag of one of the connected FEs
*/
if (hda_check_fes(rtd, stream_dir,
- stream->stream_tag)) {
- res = hstream;
+ hstream->stream_tag)) {
+ res = hext_stream;
break;
}
} else {
- res = hstream;
+ res = hext_stream;
/*
* This must be a hostless stream.
@@ -119,17 +128,17 @@ static struct hdac_ext_stream *
return res;
}
-static int hda_link_dma_params(struct hdac_ext_stream *stream,
+static int hda_link_dma_params(struct hdac_ext_stream *hext_stream,
struct hda_pipe_params *params)
{
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
unsigned char stream_tag = hstream->stream_tag;
struct hdac_bus *bus = hstream->bus;
struct hdac_ext_link *link;
unsigned int format_val;
- snd_hdac_ext_stream_decouple(bus, stream, true);
- snd_hdac_ext_link_stream_reset(stream);
+ snd_hdac_ext_stream_decouple(bus, hext_stream, true);
+ snd_hdac_ext_link_stream_reset(hext_stream);
format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch,
params->format,
@@ -138,9 +147,9 @@ static int hda_link_dma_params(struct hdac_ext_stream *stream,
dev_dbg(bus->dev, "format_val=%d, rate=%d, ch=%d, format=%d\n",
format_val, params->s_freq, params->ch, params->format);
- snd_hdac_ext_link_stream_setup(stream, format_val);
+ snd_hdac_ext_link_stream_setup(hext_stream, format_val);
- if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) {
+ if (hext_stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) {
list_for_each_entry(link, &bus->hlink_list, list) {
if (link->index == params->link_index)
snd_hdac_ext_link_set_stream_id(link,
@@ -148,55 +157,24 @@ static int hda_link_dma_params(struct hdac_ext_stream *stream,
}
}
- stream->link_prepared = 1;
+ hext_stream->link_prepared = 1;
return 0;
}
-/* Update config for the DAI widget */
-static struct sof_ipc_dai_config *hda_dai_update_config(struct snd_soc_dapm_widget *w,
- int channel)
-{
- struct snd_sof_widget *swidget = w->dobj.private;
- struct sof_ipc_dai_config *config;
- struct snd_sof_dai *sof_dai;
-
- if (!swidget)
- return NULL;
-
- sof_dai = swidget->private;
-
- if (!sof_dai || !sof_dai->dai_config) {
- dev_err(swidget->scomp->dev, "error: No config for DAI %s\n", w->name);
- return NULL;
- }
-
- config = &sof_dai->dai_config[sof_dai->current_config];
-
- /* update config with stream tag */
- config->hda.link_dma_ch = channel;
-
- return config;
-}
-
static int hda_link_dai_widget_update(struct sof_intel_hda_stream *hda_stream,
struct snd_soc_dapm_widget *w,
int channel, bool widget_setup)
{
- struct snd_sof_dev *sdev = hda_stream->sdev;
- struct sof_ipc_dai_config *config;
+ struct snd_sof_dai_config_data data;
- config = hda_dai_update_config(w, channel);
- if (!config) {
- dev_err(sdev->dev, "error: no config for DAI %s\n", w->name);
- return -ENOENT;
- }
+ data.dai_data = channel;
/* set up/free DAI widget and send DAI_CONFIG IPC */
if (widget_setup)
- return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP);
+ return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_2_STEP_STOP, &data);
- return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
+ return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, &data);
}
static int hda_link_hw_params(struct snd_pcm_substream *substream,
@@ -205,7 +183,7 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
{
struct hdac_stream *hstream = substream->runtime->private_data;
struct hdac_bus *bus = hstream->bus;
- struct hdac_ext_stream *link_dev;
+ struct hdac_ext_stream *hext_stream;
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
struct sof_intel_hda_stream *hda_stream;
@@ -216,18 +194,18 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
int ret;
/* get stored dma data if resuming from system suspend */
- link_dev = snd_soc_dai_get_dma_data(dai, substream);
- if (!link_dev) {
- link_dev = hda_link_stream_assign(bus, substream);
- if (!link_dev)
+ hext_stream = snd_soc_dai_get_dma_data(dai, substream);
+ if (!hext_stream) {
+ hext_stream = hda_link_stream_assign(bus, substream);
+ if (!hext_stream)
return -EBUSY;
- snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev);
+ snd_soc_dai_set_dma_data(dai, substream, (void *)hext_stream);
}
- stream_tag = hdac_stream(link_dev)->stream_tag;
+ stream_tag = hdac_stream(hext_stream)->stream_tag;
- hda_stream = hstream_to_sof_hda_stream(link_dev);
+ hda_stream = hstream_to_sof_hda_stream(hext_stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
w = dai->playback_widget;
@@ -244,7 +222,7 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
return -EINVAL;
/* set the hdac_stream in the codec dai */
- snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream);
+ snd_soc_dai_set_stream(codec_dai, hdac_stream(hext_stream), substream->stream);
p_params.s_fmt = snd_pcm_format_width(params_format(params));
p_params.ch = params_channels(params);
@@ -258,20 +236,20 @@ static int hda_link_hw_params(struct snd_pcm_substream *substream,
else
p_params.link_bps = codec_dai->driver->capture.sig_bits;
- return hda_link_dma_params(link_dev, &p_params);
+ return hda_link_dma_params(hext_stream, &p_params);
}
static int hda_link_pcm_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- struct hdac_ext_stream *link_dev =
+ struct hdac_ext_stream *hext_stream =
snd_soc_dai_get_dma_data(dai, substream);
struct snd_sof_dev *sdev =
snd_soc_component_get_drvdata(dai->component);
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
int stream = substream->stream;
- if (link_dev->link_prepared)
+ if (hext_stream->link_prepared)
return 0;
dev_dbg(sdev->dev, "hda: prepare stream dir %d\n", substream->stream);
@@ -285,35 +263,23 @@ static int hda_link_dai_config_pause_push_ipc(struct snd_soc_dapm_widget *w)
struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct sof_ipc_dai_config *config;
- struct snd_sof_dai *sof_dai;
- struct sof_ipc_reply reply;
- int ret;
-
- sof_dai = swidget->private;
+ const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
+ int ret = 0;
- if (!sof_dai || !sof_dai->dai_config) {
- dev_err(sdev->dev, "No config for DAI %s\n", w->name);
- return -EINVAL;
+ if (tplg_ops->dai_config) {
+ ret = tplg_ops->dai_config(sdev, swidget, SOF_DAI_CONFIG_FLAGS_PAUSE, NULL);
+ if (ret < 0)
+ dev_err(sdev->dev, "%s: DAI config failed for widget %s\n", __func__,
+ w->name);
}
- config = &sof_dai->dai_config[sof_dai->current_config];
-
- /* set PAUSE command flag */
- config->flags = FIELD_PREP(SOF_DAI_CONFIG_FLAGS_CMD_MASK, SOF_DAI_CONFIG_FLAGS_PAUSE);
-
- ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
- &reply, sizeof(reply));
- if (ret < 0)
- dev_err(sdev->dev, "DAI config for %s failed during pause push\n", w->name);
-
return ret;
}
static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
int cmd, struct snd_soc_dai *dai)
{
- struct hdac_ext_stream *link_dev =
+ struct hdac_ext_stream *hext_stream =
snd_soc_dai_get_dma_data(dai, substream);
struct sof_intel_hda_stream *hda_stream;
struct snd_soc_pcm_runtime *rtd;
@@ -332,7 +298,7 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
if (!link)
return -EINVAL;
- hda_stream = hstream_to_sof_hda_stream(link_dev);
+ hda_stream = hstream_to_sof_hda_stream(hext_stream);
dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd);
@@ -341,11 +307,11 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- snd_hdac_ext_link_stream_start(link_dev);
+ snd_hdac_ext_link_stream_start(hext_stream);
break;
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_STOP:
- snd_hdac_ext_link_stream_clear(link_dev);
+ snd_hdac_ext_link_stream_clear(hext_stream);
/*
* free DAI widget during stop/suspend to keep widget use_count's balanced.
@@ -355,14 +321,14 @@ static int hda_link_pcm_trigger(struct snd_pcm_substream *substream,
return ret;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- stream_tag = hdac_stream(link_dev)->stream_tag;
+ stream_tag = hdac_stream(hext_stream)->stream_tag;
snd_hdac_ext_link_clear_stream_id(link, stream_tag);
}
- link_dev->link_prepared = 0;
+ hext_stream->link_prepared = 0;
break;
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- snd_hdac_ext_link_stream_clear(link_dev);
+ snd_hdac_ext_link_stream_clear(hext_stream);
ret = hda_link_dai_config_pause_push_ipc(w);
if (ret < 0)
@@ -383,22 +349,22 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
struct hdac_ext_link *link;
struct hdac_stream *hstream;
struct snd_soc_pcm_runtime *rtd;
- struct hdac_ext_stream *link_dev;
+ struct hdac_ext_stream *hext_stream;
struct snd_soc_dapm_widget *w;
int ret;
hstream = substream->runtime->private_data;
bus = hstream->bus;
rtd = asoc_substream_to_rtd(substream);
- link_dev = snd_soc_dai_get_dma_data(dai, substream);
+ hext_stream = snd_soc_dai_get_dma_data(dai, substream);
- if (!link_dev) {
+ if (!hext_stream) {
dev_dbg(dai->dev,
- "%s: link_dev is not assigned\n", __func__);
+ "%s: hext_stream is not assigned\n", __func__);
return -EINVAL;
}
- hda_stream = hstream_to_sof_hda_stream(link_dev);
+ hda_stream = hstream_to_sof_hda_stream(hext_stream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
w = dai->playback_widget;
@@ -415,13 +381,13 @@ static int hda_link_hw_free(struct snd_pcm_substream *substream,
return -EINVAL;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
- stream_tag = hdac_stream(link_dev)->stream_tag;
+ stream_tag = hdac_stream(hext_stream)->stream_tag;
snd_hdac_ext_link_clear_stream_id(link, stream_tag);
}
snd_soc_dai_set_dma_data(dai, substream, NULL);
- snd_hdac_ext_stream_release(link_dev, HDAC_EXT_STREAM_TYPE_LINK);
- link_dev->link_prepared = 0;
+ snd_hdac_ext_stream_release(hext_stream, HDAC_EXT_STREAM_TYPE_LINK);
+ hext_stream->link_prepared = 0;
/* free the host DMA channel reserved by hostless streams */
hda_stream->host_reserved = 0;
@@ -446,30 +412,17 @@ struct ssp_dai_dma_data {
static int ssp_dai_setup_or_free(struct snd_pcm_substream *substream, struct snd_soc_dai *dai,
bool setup)
{
- struct snd_soc_component *component;
- struct snd_sof_widget *swidget;
struct snd_soc_dapm_widget *w;
- struct sof_ipc_fw_version *v;
- struct snd_sof_dev *sdev;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
w = dai->playback_widget;
else
w = dai->capture_widget;
- swidget = w->dobj.private;
- component = swidget->scomp;
- sdev = snd_soc_component_get_drvdata(component);
- v = &sdev->fw_ready.version;
-
- /* DAI_CONFIG IPC during hw_params is not supported in older firmware */
- if (v->abi_version < SOF_ABI_VER(3, 18, 0))
- return 0;
-
if (setup)
- return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE);
+ return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE, NULL);
- return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
+ return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, NULL);
}
static int ssp_dai_startup(struct snd_pcm_substream *substream,
@@ -724,20 +677,5 @@ struct snd_soc_dai_driver skl_dai[] = {
.channels_max = 16,
},
},
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
-{
- .name = "Probe Extraction CPU DAI",
- .compress_new = snd_soc_new_compress,
- .cops = &sof_probe_compr_ops,
- .capture = {
- .stream_name = "Probe Extraction",
- .channels_min = 1,
- .channels_max = 8,
- .rates = SNDRV_PCM_RATE_48000,
- .rate_min = 48000,
- .rate_max = 48000,
- },
-},
-#endif
#endif
};
diff --git a/sound/soc/sof/intel/hda-dsp.c b/sound/soc/sof/intel/hda-dsp.c
index 916a257ea96b..8ddde60c56b3 100644
--- a/sound/soc/sof/intel/hda-dsp.c
+++ b/sound/soc/sof/intel/hda-dsp.c
@@ -498,15 +498,9 @@ static void hda_dsp_state_log(struct snd_sof_dev *sdev)
case SOF_DSP_PM_D2:
dev_dbg(sdev->dev, "Current DSP power state: D2\n");
break;
- case SOF_DSP_PM_D3_HOT:
- dev_dbg(sdev->dev, "Current DSP power state: D3_HOT\n");
- break;
case SOF_DSP_PM_D3:
dev_dbg(sdev->dev, "Current DSP power state: D3\n");
break;
- case SOF_DSP_PM_D3_COLD:
- dev_dbg(sdev->dev, "Current DSP power state: D3_COLD\n");
- break;
default:
dev_dbg(sdev->dev, "Unknown DSP power state: %d\n",
sdev->dsp_power_state.state);
@@ -904,7 +898,7 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
struct hdac_bus *bus = sof_to_bus(sdev);
struct snd_soc_pcm_runtime *rtd;
- struct hdac_ext_stream *stream;
+ struct hdac_ext_stream *hext_stream;
struct hdac_ext_link *link;
struct hdac_stream *s;
const char *name;
@@ -912,7 +906,7 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
/* set internal flag for BE */
list_for_each_entry(s, &bus->stream_list, list) {
- stream = stream_to_hdac_ext_stream(s);
+ hext_stream = stream_to_hdac_ext_stream(s);
/*
* clear stream. This should already be taken care for running
@@ -920,20 +914,20 @@ int hda_dsp_set_hw_params_upon_resume(struct snd_sof_dev *sdev)
* streams do not get suspended, so this needs to be done
* explicitly during suspend.
*/
- if (stream->link_substream) {
- rtd = asoc_substream_to_rtd(stream->link_substream);
+ if (hext_stream->link_substream) {
+ rtd = asoc_substream_to_rtd(hext_stream->link_substream);
name = asoc_rtd_to_codec(rtd, 0)->component->name;
link = snd_hdac_ext_bus_get_link(bus, name);
if (!link)
return -EINVAL;
- stream->link_prepared = 0;
+ hext_stream->link_prepared = 0;
- if (hdac_stream(stream)->direction ==
+ if (hdac_stream(hext_stream)->direction ==
SNDRV_PCM_STREAM_CAPTURE)
continue;
- stream_tag = hdac_stream(stream)->stream_tag;
+ stream_tag = hdac_stream(hext_stream)->stream_tag;
snd_hdac_ext_link_clear_stream_id(link, stream_tag);
}
}
diff --git a/sound/soc/sof/intel/hda-ipc.c b/sound/soc/sof/intel/hda-ipc.c
index f0cf8019d72d..0395638c43ae 100644
--- a/sound/soc/sof/intel/hda-ipc.c
+++ b/sound/soc/sof/intel/hda-ipc.c
@@ -255,39 +255,37 @@ int hda_ipc_msg_data(struct snd_sof_dev *sdev,
hda_stream = container_of(hstream,
struct sof_intel_hda_stream,
- hda_stream.hstream);
+ hext_stream.hstream);
/* The stream might already be closed */
if (!hstream)
return -ESTRPIPE;
- sof_mailbox_read(sdev, hda_stream->stream.posn_offset, p, sz);
+ sof_mailbox_read(sdev, hda_stream->sof_intel_stream.posn_offset, p, sz);
}
return 0;
}
-int hda_ipc_pcm_params(struct snd_sof_dev *sdev,
- struct snd_pcm_substream *substream,
- const struct sof_ipc_pcm_params_reply *reply)
+int hda_set_stream_data_offset(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ size_t posn_offset)
{
struct hdac_stream *hstream = substream->runtime->private_data;
struct sof_intel_hda_stream *hda_stream;
- /* validate offset */
- size_t posn_offset = reply->posn_offset;
hda_stream = container_of(hstream, struct sof_intel_hda_stream,
- hda_stream.hstream);
+ hext_stream.hstream);
/* check for unaligned offset or overflow */
if (posn_offset > sdev->stream_box.size ||
posn_offset % sizeof(struct sof_ipc_stream_posn) != 0)
return -EINVAL;
- hda_stream->stream.posn_offset = sdev->stream_box.offset + posn_offset;
+ hda_stream->sof_intel_stream.posn_offset = sdev->stream_box.offset + posn_offset;
dev_dbg(sdev->dev, "pcm: stream dir %d, posn mailbox offset is %zu",
- substream->stream, hda_stream->stream.posn_offset);
+ substream->stream, hda_stream->sof_intel_stream.posn_offset);
return 0;
}
diff --git a/sound/soc/sof/intel/hda-loader.c b/sound/soc/sof/intel/hda-loader.c
index 9bbfdab8009d..2ac5d9d0719b 100644
--- a/sound/soc/sof/intel/hda-loader.c
+++ b/sound/soc/sof/intel/hda-loader.c
@@ -21,26 +21,44 @@
#include <sound/sof.h>
#include "ext_manifest.h"
#include "../ops.h"
+#include "../sof-priv.h"
#include "hda.h"
#define HDA_CL_STREAM_FORMAT 0x40
+static void hda_ssp_set_cbp_cfp(struct snd_sof_dev *sdev)
+{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+ const struct sof_intel_dsp_desc *chip = hda->desc;
+ int i;
+
+ /* DSP is powered up, set all SSPs to clock consumer/codec provider mode */
+ for (i = 0; i < chip->ssp_count; i++) {
+ snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
+ chip->ssp_base_offset
+ + i * SSP_DEV_MEM_SIZE
+ + SSP_SSC1_OFFSET,
+ SSP_SET_CBP_CFP,
+ SSP_SET_CBP_CFP);
+ }
+}
+
static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsigned int format,
unsigned int size, struct snd_dma_buffer *dmab,
int direction)
{
- struct hdac_ext_stream *dsp_stream;
+ struct hdac_ext_stream *hext_stream;
struct hdac_stream *hstream;
struct pci_dev *pci = to_pci_dev(sdev->dev);
int ret;
- dsp_stream = hda_dsp_stream_get(sdev, direction, 0);
+ hext_stream = hda_dsp_stream_get(sdev, direction, 0);
- if (!dsp_stream) {
+ if (!hext_stream) {
dev_err(sdev->dev, "error: no stream available\n");
return ERR_PTR(-ENODEV);
}
- hstream = &dsp_stream->hstream;
+ hstream = &hext_stream->hstream;
hstream->substream = NULL;
/* allocate DMA buffer */
@@ -55,21 +73,21 @@ static struct hdac_ext_stream *cl_stream_prepare(struct snd_sof_dev *sdev, unsig
hstream->bufsize = size;
if (direction == SNDRV_PCM_STREAM_CAPTURE) {
- ret = hda_dsp_iccmax_stream_hw_params(sdev, dsp_stream, dmab, NULL);
+ ret = hda_dsp_iccmax_stream_hw_params(sdev, hext_stream, dmab, NULL);
if (ret < 0) {
dev_err(sdev->dev, "error: iccmax stream prepare failed: %d\n", ret);
goto out_free;
}
} else {
- ret = hda_dsp_stream_hw_params(sdev, dsp_stream, dmab, NULL);
+ ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
if (ret < 0) {
dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret);
goto out_free;
}
- hda_dsp_stream_spib_config(sdev, dsp_stream, HDA_DSP_SPIB_ENABLE, size);
+ hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_ENABLE, size);
}
- return dsp_stream;
+ return hext_stream;
out_free:
snd_dma_free_pages(dmab);
@@ -92,7 +110,6 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag)
char *dump_msg;
u32 flags, j;
int ret;
- int i;
/* step 1: power up corex */
ret = hda_dsp_enable_core(sdev, chip->host_managed_cores_mask);
@@ -102,15 +119,7 @@ static int cl_dsp_init(struct snd_sof_dev *sdev, int stream_tag)
goto err;
}
- /* DSP is powered up, set all SSPs to slave mode */
- for (i = 0; i < chip->ssp_count; i++) {
- snd_sof_dsp_update_bits_unlocked(sdev, HDA_DSP_BAR,
- chip->ssp_base_offset
- + i * SSP_DEV_MEM_SIZE
- + SSP_SSC1_OFFSET,
- SSP_SET_SLAVE,
- SSP_SET_SLAVE);
- }
+ hda_ssp_set_cbp_cfp(sdev);
/* step 2: purge FW request */
snd_sof_dsp_write(sdev, HDA_DSP_BAR, chip->ipc_req,
@@ -201,9 +210,9 @@ err:
}
static int cl_trigger(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream, int cmd)
+ struct hdac_ext_stream *hext_stream, int cmd)
{
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
/* code loader is special case that reuses stream ops */
@@ -223,19 +232,19 @@ static int cl_trigger(struct snd_sof_dev *sdev,
hstream->running = true;
return 0;
default:
- return hda_dsp_stream_trigger(sdev, stream, cmd);
+ return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
}
}
static int cl_cleanup(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab,
- struct hdac_ext_stream *stream)
+ struct hdac_ext_stream *hext_stream)
{
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
int ret = 0;
if (hstream->direction == SNDRV_PCM_STREAM_PLAYBACK)
- ret = hda_dsp_stream_spib_config(sdev, stream, HDA_DSP_SPIB_DISABLE, 0);
+ ret = hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
else
snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, sd_offset,
SOF_HDA_SD_CTL_DMA_START, 0);
@@ -259,12 +268,12 @@ static int cl_cleanup(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab,
return ret;
}
-static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream)
+static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream)
{
unsigned int reg;
int ret, status;
- ret = cl_trigger(sdev, stream, SNDRV_PCM_TRIGGER_START);
+ ret = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_START);
if (ret < 0) {
dev_err(sdev->dev, "error: DMA trigger start failed\n");
return ret;
@@ -288,7 +297,7 @@ static int cl_copy_fw(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream)
__func__);
}
- ret = cl_trigger(sdev, stream, SNDRV_PCM_TRIGGER_STOP);
+ ret = cl_trigger(sdev, hext_stream, SNDRV_PCM_TRIGGER_STOP);
if (ret < 0) {
dev_err(sdev->dev, "error: DMA trigger stop failed\n");
if (!status)
@@ -346,16 +355,55 @@ int hda_dsp_cl_boot_firmware_iccmax(struct snd_sof_dev *sdev)
return ret;
}
+static int hda_dsp_boot_imr(struct snd_sof_dev *sdev)
+{
+ struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
+ const struct sof_intel_dsp_desc *chip = hda->desc;
+ unsigned long mask;
+ u32 j;
+ int ret;
+
+ /* power up & unstall/run the cores to run the firmware */
+ ret = hda_dsp_enable_core(sdev, chip->init_core_mask);
+ if (ret < 0) {
+ dev_err(sdev->dev, "dsp core start failed %d\n", ret);
+ return -EIO;
+ }
+
+ /* set enabled cores mask and increment ref count for cores in init_core_mask */
+ sdev->enabled_cores_mask |= chip->init_core_mask;
+ mask = sdev->enabled_cores_mask;
+ for_each_set_bit(j, &mask, SOF_MAX_DSP_NUM_CORES)
+ sdev->dsp_core_ref_count[j]++;
+
+ hda_ssp_set_cbp_cfp(sdev);
+
+ /* enable IPC interrupts */
+ hda_dsp_ipc_int_enable(sdev);
+
+ /* process wakes */
+ hda_sdw_process_wakeen(sdev);
+
+ return ret;
+}
+
int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct snd_sof_pdata *plat_data = sdev->pdata;
const struct sof_dev_desc *desc = plat_data->desc;
const struct sof_intel_dsp_desc *chip_info;
- struct hdac_ext_stream *stream;
+ struct hdac_ext_stream *hext_stream;
struct firmware stripped_firmware;
int ret, ret1, i;
+ if ((sdev->fw_ready.flags & SOF_IPC_INFO_D3_PERSISTENT) &&
+ !(sof_debug_check_flag(SOF_DBG_IGNORE_D3_PERSISTENT)) &&
+ !sdev->first_boot) {
+ dev_dbg(sdev->dev, "IMR restore supported, booting from IMR directly\n");
+ return hda_dsp_boot_imr(sdev);
+ }
+
chip_info = desc->chip_info;
if (plat_data->fw->size <= plat_data->fw_offset) {
@@ -370,11 +418,11 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
init_waitqueue_head(&sdev->boot_wait);
/* prepare DMA for code loader stream */
- stream = cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
- &sdev->dmab, SNDRV_PCM_STREAM_PLAYBACK);
- if (IS_ERR(stream)) {
+ hext_stream = cl_stream_prepare(sdev, HDA_CL_STREAM_FORMAT, stripped_firmware.size,
+ &sdev->dmab, SNDRV_PCM_STREAM_PLAYBACK);
+ if (IS_ERR(hext_stream)) {
dev_err(sdev->dev, "error: dma prepare for fw loading failed\n");
- return PTR_ERR(stream);
+ return PTR_ERR(hext_stream);
}
memcpy(sdev->dmab.area, stripped_firmware.data,
@@ -386,7 +434,7 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
"Attempting iteration %d of Core En/ROM load...\n", i);
hda->boot_iteration = i + 1;
- ret = cl_dsp_init(sdev, stream->hstream.stream_tag);
+ ret = cl_dsp_init(sdev, hext_stream->hstream.stream_tag);
/* don't retry anymore if successful */
if (!ret)
@@ -425,7 +473,7 @@ int hda_dsp_cl_boot_firmware(struct snd_sof_dev *sdev)
* Continue with code loading and firmware boot
*/
hda->boot_iteration = HDA_FW_BOOT_ATTEMPTS;
- ret = cl_copy_fw(sdev, stream);
+ ret = cl_copy_fw(sdev, hext_stream);
if (!ret)
dev_dbg(sdev->dev, "Firmware download successful, booting...\n");
else
@@ -438,7 +486,7 @@ cleanup:
* This should be done even if firmware loading fails.
* If the cleanup also fails, we return the initial error
*/
- ret1 = cl_cleanup(sdev, &sdev->dmab, stream);
+ ret1 = cl_cleanup(sdev, &sdev->dmab, hext_stream);
if (ret1 < 0) {
dev_err(sdev->dev, "error: Code loader DSP cleanup failed\n");
diff --git a/sound/soc/sof/intel/hda-pcm.c b/sound/soc/sof/intel/hda-pcm.c
index d78aa5d8552d..dc1f743730c0 100644
--- a/sound/soc/sof/intel/hda-pcm.c
+++ b/sound/soc/sof/intel/hda-pcm.c
@@ -93,13 +93,12 @@ u32 hda_dsp_get_bits(struct snd_sof_dev *sdev, int sample_bits)
int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
- struct sof_ipc_stream_params *ipc_params)
+ struct snd_sof_platform_stream_params *platform_params)
{
struct hdac_stream *hstream = substream->runtime->private_data;
- struct hdac_ext_stream *stream = stream_to_hdac_ext_stream(hstream);
+ struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct snd_dma_buffer *dmab;
- struct sof_ipc_fw_version *v = &sdev->fw_ready.version;
int ret;
u32 size, rate, bits;
@@ -118,7 +117,7 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
(params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) &&
(params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP);
- ret = hda_dsp_stream_hw_params(sdev, stream, dmab, params);
+ ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, params);
if (ret < 0) {
dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret);
return ret;
@@ -126,23 +125,14 @@ int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
/* enable SPIB when rewinds are disabled */
if (hda_disable_rewinds)
- hda_dsp_stream_spib_config(sdev, stream, HDA_DSP_SPIB_ENABLE, 0);
+ hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_ENABLE, 0);
else
- hda_dsp_stream_spib_config(sdev, stream, HDA_DSP_SPIB_DISABLE, 0);
+ hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
- /* update no_stream_position flag for ipc params */
- if (hda && hda->no_ipc_position) {
- /* For older ABIs set host_period_bytes to zero to inform
- * FW we don't want position updates. Newer versions use
- * no_stream_position for this purpose.
- */
- if (v->abi_version < SOF_ABI_VER(3, 10, 0))
- ipc_params->host_period_bytes = 0;
- else
- ipc_params->no_stream_position = 1;
- }
+ if (hda)
+ platform_params->no_ipc_position = hda->no_ipc_position;
- ipc_params->stream_tag = hstream->stream_tag;
+ platform_params->stream_tag = hstream->stream_tag;
return 0;
}
@@ -174,9 +164,9 @@ int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream, int cmd)
{
struct hdac_stream *hstream = substream->runtime->private_data;
- struct hdac_ext_stream *stream = stream_to_hdac_ext_stream(hstream);
+ struct hdac_ext_stream *hext_stream = stream_to_hdac_ext_stream(hstream);
- return hda_dsp_stream_trigger(sdev, stream, cmd);
+ return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
}
snd_pcm_uframes_t hda_dsp_pcm_pointer(struct snd_sof_dev *sdev,
@@ -315,6 +305,7 @@ int hda_dsp_pcm_open(struct snd_sof_dev *sdev,
runtime->hw.info &= ~SNDRV_PCM_INFO_PAUSE;
if (hda_always_enable_dmi_l1 ||
+ direction == SNDRV_PCM_STREAM_PLAYBACK ||
spcm->stream[substream->stream].d0i3_compatible)
flags |= SOF_HDA_STREAM_DMI_L1_COMPATIBLE;
diff --git a/sound/soc/sof/intel/hda-probes.c b/sound/soc/sof/intel/hda-probes.c
index fe2f3f7d236b..31e85d4aae8c 100644
--- a/sound/soc/sof/intel/hda-probes.c
+++ b/sound/soc/sof/intel/hda-probes.c
@@ -3,14 +3,20 @@
// 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) 2019-2020 Intel Corporation. All rights reserved.
+// Copyright(c) 2019-2021 Intel Corporation. All rights reserved.
//
// Author: Cezary Rojewski <cezary.rojewski@intel.com>
+// Converted to SOF client:
+// Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
+// Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
//
+#include <linux/module.h>
#include <sound/hdaudio_ext.h>
#include <sound/soc.h>
#include "../sof-priv.h"
+#include "../sof-client-probes.h"
+#include "../sof-client.h"
#include "hda.h"
static inline struct hdac_ext_stream *
@@ -19,50 +25,55 @@ hda_compr_get_stream(struct snd_compr_stream *cstream)
return cstream->runtime->private_data;
}
-int hda_probe_compr_assign(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_soc_dai *dai)
+static int hda_probes_compr_assign(struct sof_client_dev *cdev,
+ struct snd_compr_stream *cstream,
+ struct snd_soc_dai *dai, u32 *stream_id)
{
- struct hdac_ext_stream *stream;
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+ struct hdac_ext_stream *hext_stream;
- stream = hda_dsp_stream_get(sdev, cstream->direction, 0);
- if (!stream)
+ hext_stream = hda_dsp_stream_get(sdev, cstream->direction, 0);
+ if (!hext_stream)
return -EBUSY;
- hdac_stream(stream)->curr_pos = 0;
- hdac_stream(stream)->cstream = cstream;
- cstream->runtime->private_data = stream;
+ hdac_stream(hext_stream)->curr_pos = 0;
+ hdac_stream(hext_stream)->cstream = cstream;
+ cstream->runtime->private_data = hext_stream;
- return hdac_stream(stream)->stream_tag;
+ *stream_id = hdac_stream(hext_stream)->stream_tag;
+
+ return 0;
}
-int hda_probe_compr_free(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_soc_dai *dai)
+static int hda_probes_compr_free(struct sof_client_dev *cdev,
+ struct snd_compr_stream *cstream,
+ struct snd_soc_dai *dai)
{
- struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+ struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
int ret;
ret = hda_dsp_stream_put(sdev, cstream->direction,
- hdac_stream(stream)->stream_tag);
+ hdac_stream(hext_stream)->stream_tag);
if (ret < 0) {
dev_dbg(sdev->dev, "stream put failed: %d\n", ret);
return ret;
}
- hdac_stream(stream)->cstream = NULL;
+ hdac_stream(hext_stream)->cstream = NULL;
cstream->runtime->private_data = NULL;
return 0;
}
-int hda_probe_compr_set_params(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_compr_params *params,
- struct snd_soc_dai *dai)
+static int hda_probes_compr_set_params(struct sof_client_dev *cdev,
+ struct snd_compr_stream *cstream,
+ struct snd_compr_params *params,
+ struct snd_soc_dai *dai)
{
- struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
- struct hdac_stream *hstream = hdac_stream(stream);
+ struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
+ struct hdac_stream *hstream = hdac_stream(hext_stream);
struct snd_dma_buffer *dmab;
u32 bits, rate;
int bps, ret;
@@ -80,7 +91,7 @@ int hda_probe_compr_set_params(struct snd_sof_dev *sdev,
hstream->period_bytes = cstream->runtime->fragment_size;
hstream->no_period_wakeup = 0;
- ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL);
+ ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
if (ret < 0) {
dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret);
return ret;
@@ -89,26 +100,49 @@ int hda_probe_compr_set_params(struct snd_sof_dev *sdev,
return 0;
}
-int hda_probe_compr_trigger(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream, int cmd,
- struct snd_soc_dai *dai)
+static int hda_probes_compr_trigger(struct sof_client_dev *cdev,
+ struct snd_compr_stream *cstream,
+ int cmd, struct snd_soc_dai *dai)
{
- struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+ struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);
+ struct snd_sof_dev *sdev = sof_client_dev_to_sof_dev(cdev);
- return hda_dsp_stream_trigger(sdev, stream, cmd);
+ return hda_dsp_stream_trigger(sdev, hext_stream, cmd);
}
-int hda_probe_compr_pointer(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp,
- struct snd_soc_dai *dai)
+static int hda_probes_compr_pointer(struct sof_client_dev *cdev,
+ struct snd_compr_stream *cstream,
+ struct snd_compr_tstamp *tstamp,
+ struct snd_soc_dai *dai)
{
- struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+ struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream);
struct snd_soc_pcm_stream *pstream;
pstream = &dai->driver->capture;
- tstamp->copied_total = hdac_stream(stream)->curr_pos;
+ tstamp->copied_total = hdac_stream(hext_stream)->curr_pos;
tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
return 0;
}
+
+/* SOF client implementation */
+static const struct sof_probes_host_ops hda_probes_ops = {
+ .assign = hda_probes_compr_assign,
+ .free = hda_probes_compr_free,
+ .set_params = hda_probes_compr_set_params,
+ .trigger = hda_probes_compr_trigger,
+ .pointer = hda_probes_compr_pointer,
+};
+
+int hda_probes_register(struct snd_sof_dev *sdev)
+{
+ return sof_client_dev_register(sdev, "hda-probes", 0, &hda_probes_ops,
+ sizeof(hda_probes_ops));
+}
+
+void hda_probes_unregister(struct snd_sof_dev *sdev)
+{
+ sof_client_dev_unregister(sdev, "hda-probes", 0);
+}
+
+MODULE_IMPORT_NS(SND_SOC_SOF_CLIENT);
diff --git a/sound/soc/sof/intel/hda-stream.c b/sound/soc/sof/intel/hda-stream.c
index ba60807fbd8f..daeb64c495e4 100644
--- a/sound/soc/sof/intel/hda-stream.c
+++ b/sound/soc/sof/intel/hda-stream.c
@@ -57,7 +57,7 @@ static char *hda_hstream_dbg_get_stream_info_str(struct hdac_stream *hstream)
*/
static int hda_setup_bdle(struct snd_sof_dev *sdev,
struct snd_dma_buffer *dmab,
- struct hdac_stream *stream,
+ struct hdac_stream *hstream,
struct sof_intel_dsp_bdl **bdlp,
int offset, int size, int ioc)
{
@@ -68,7 +68,7 @@ static int hda_setup_bdle(struct snd_sof_dev *sdev,
dma_addr_t addr;
int chunk;
- if (stream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
+ if (hstream->frags >= HDA_DSP_MAX_BDL_ENTRIES) {
dev_err(sdev->dev, "error: stream frags exceeded\n");
return -EINVAL;
}
@@ -91,11 +91,11 @@ static int hda_setup_bdle(struct snd_sof_dev *sdev,
size -= chunk;
bdl->ioc = (size || !ioc) ? 0 : cpu_to_le32(0x01);
bdl++;
- stream->frags++;
+ hstream->frags++;
offset += chunk;
dev_vdbg(sdev->dev, "bdl, frags:%d, chunk size:0x%x;\n",
- stream->frags, chunk);
+ hstream->frags, chunk);
}
*bdlp = bdl;
@@ -108,47 +108,47 @@ static int hda_setup_bdle(struct snd_sof_dev *sdev,
*/
int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
struct snd_dma_buffer *dmab,
- struct hdac_stream *stream)
+ struct hdac_stream *hstream)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
struct sof_intel_dsp_bdl *bdl;
int i, offset, period_bytes, periods;
int remain, ioc;
- period_bytes = stream->period_bytes;
+ period_bytes = hstream->period_bytes;
dev_dbg(sdev->dev, "%s: period_bytes:0x%x\n", __func__, period_bytes);
if (!period_bytes)
- period_bytes = stream->bufsize;
+ period_bytes = hstream->bufsize;
- periods = stream->bufsize / period_bytes;
+ periods = hstream->bufsize / period_bytes;
dev_dbg(sdev->dev, "%s: periods:%d\n", __func__, periods);
- remain = stream->bufsize % period_bytes;
+ remain = hstream->bufsize % period_bytes;
if (remain)
periods++;
/* program the initial BDL entries */
- bdl = (struct sof_intel_dsp_bdl *)stream->bdl.area;
+ bdl = (struct sof_intel_dsp_bdl *)hstream->bdl.area;
offset = 0;
- stream->frags = 0;
+ hstream->frags = 0;
/*
* set IOC if don't use position IPC
* and period_wakeup needed.
*/
ioc = hda->no_ipc_position ?
- !stream->no_period_wakeup : 0;
+ !hstream->no_period_wakeup : 0;
for (i = 0; i < periods; i++) {
if (i == (periods - 1) && remain)
/* set the last small entry */
offset = hda_setup_bdle(sdev, dmab,
- stream, &bdl, offset,
+ hstream, &bdl, offset,
remain, 0);
else
offset = hda_setup_bdle(sdev, dmab,
- stream, &bdl, offset,
+ hstream, &bdl, offset,
period_bytes, ioc);
}
@@ -156,10 +156,10 @@ int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
}
int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream,
+ struct hdac_ext_stream *hext_stream,
int enable, u32 size)
{
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
u32 mask;
if (!sdev->bar[HDA_DSP_SPIB_BAR]) {
@@ -175,7 +175,7 @@ int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
enable << hstream->index);
/* set the SPIB value */
- sof_io_write(sdev, stream->spib_addr, size);
+ sof_io_write(sdev, hext_stream->spib_addr, size);
return 0;
}
@@ -186,7 +186,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct sof_intel_hda_stream *hda_stream;
- struct hdac_ext_stream *stream = NULL;
+ struct hdac_ext_stream *hext_stream = NULL;
struct hdac_stream *s;
spin_lock_irq(&bus->reg_lock);
@@ -194,10 +194,10 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
/* get an unused stream */
list_for_each_entry(s, &bus->stream_list, list) {
if (s->direction == direction && !s->opened) {
- stream = stream_to_hdac_ext_stream(s);
- hda_stream = container_of(stream,
+ hext_stream = stream_to_hdac_ext_stream(s);
+ hda_stream = container_of(hext_stream,
struct sof_intel_hda_stream,
- hda_stream);
+ hext_stream);
/* check if the host DMA channel is reserved */
if (hda_stream->host_reserved)
continue;
@@ -210,11 +210,11 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
spin_unlock_irq(&bus->reg_lock);
/* stream found ? */
- if (!stream) {
+ if (!hext_stream) {
dev_err(sdev->dev, "error: no free %s streams\n",
direction == SNDRV_PCM_STREAM_PLAYBACK ?
"playback" : "capture");
- return stream;
+ return hext_stream;
}
hda_stream->flags = flags;
@@ -229,7 +229,7 @@ hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags)
HDA_VS_INTEL_EM2,
HDA_VS_INTEL_EM2_L1SEN, 0);
- return stream;
+ return hext_stream;
}
/* free a stream */
@@ -237,7 +237,7 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct sof_intel_hda_stream *hda_stream;
- struct hdac_ext_stream *stream;
+ struct hdac_ext_stream *hext_stream;
struct hdac_stream *s;
bool dmi_l1_enable = true;
bool found = false;
@@ -249,8 +249,8 @@ int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag)
* that are DMI L1 incompatible.
*/
list_for_each_entry(s, &bus->stream_list, list) {
- stream = stream_to_hdac_ext_stream(s);
- hda_stream = container_of(stream, struct sof_intel_hda_stream, hda_stream);
+ hext_stream = stream_to_hdac_ext_stream(s);
+ hda_stream = container_of(hext_stream, struct sof_intel_hda_stream, hext_stream);
if (!s->opened)
continue;
@@ -319,9 +319,9 @@ static int hda_dsp_stream_reset(struct snd_sof_dev *sdev, struct hdac_stream *hs
}
int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream, int cmd)
+ struct hdac_ext_stream *hext_stream, int cmd)
{
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
int ret = 0;
@@ -396,17 +396,17 @@ int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
}
/* minimal recommended programming for ICCMAX stream */
-int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
+int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *hext_stream,
struct snd_dma_buffer *dmab,
struct snd_pcm_hw_params *params)
{
struct hdac_bus *bus = sof_to_bus(sdev);
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
int ret;
u32 mask = 0x1 << hstream->index;
- if (!stream) {
+ if (!hext_stream) {
dev_err(sdev->dev, "error: no stream available\n");
return -ENODEV;
}
@@ -467,20 +467,20 @@ int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_st
* and normal stream.
*/
int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream,
+ struct hdac_ext_stream *hext_stream,
struct snd_dma_buffer *dmab,
struct snd_pcm_hw_params *params)
{
const struct sof_intel_dsp_desc *chip = get_chip_info(sdev->pdata);
struct hdac_bus *bus = sof_to_bus(sdev);
- struct hdac_stream *hstream = &stream->hstream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
int sd_offset = SOF_STREAM_SD_OFFSET(hstream);
int ret;
u32 dma_start = SOF_HDA_SD_CTL_DMA_START;
u32 mask;
u32 run;
- if (!stream) {
+ if (!hext_stream) {
dev_err(sdev->dev, "error: no stream available\n");
return -ENODEV;
}
@@ -659,28 +659,28 @@ int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream)
{
- struct hdac_stream *stream = substream->runtime->private_data;
- struct hdac_ext_stream *link_dev = container_of(stream,
- struct hdac_ext_stream,
- hstream);
+ struct hdac_stream *hstream = substream->runtime->private_data;
+ struct hdac_ext_stream *hext_stream = container_of(hstream,
+ struct hdac_ext_stream,
+ hstream);
struct hdac_bus *bus = sof_to_bus(sdev);
- u32 mask = 0x1 << stream->index;
+ u32 mask = 0x1 << hstream->index;
int ret;
- ret = hda_dsp_stream_reset(sdev, stream);
+ ret = hda_dsp_stream_reset(sdev, hstream);
if (ret < 0)
return ret;
spin_lock_irq(&bus->reg_lock);
/* couple host and link DMA if link DMA channel is idle */
- if (!link_dev->link_locked)
+ if (!hext_stream->link_locked)
snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR,
SOF_HDA_REG_PP_PPCTL, mask, 0);
spin_unlock_irq(&bus->reg_lock);
- hda_dsp_stream_spib_config(sdev, link_dev, HDA_DSP_SPIB_DISABLE, 0);
+ hda_dsp_stream_spib_config(sdev, hext_stream, HDA_DSP_SPIB_DISABLE, 0);
- stream->substream = NULL;
+ hstream->substream = NULL;
return 0;
}
@@ -808,7 +808,7 @@ irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context)
int hda_dsp_stream_init(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
- struct hdac_ext_stream *stream;
+ struct hdac_ext_stream *hext_stream;
struct hdac_stream *hstream;
struct pci_dev *pci = to_pci_dev(sdev->dev);
struct sof_intel_hda_dev *sof_hda = bus_to_sof_hda(bus);
@@ -872,27 +872,27 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
hda_stream->sdev = sdev;
- stream = &hda_stream->hda_stream;
+ hext_stream = &hda_stream->hext_stream;
- stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
+ hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
- stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
+ hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
SOF_HDA_PPLC_INTERVAL * i;
/* do we support SPIB */
if (sdev->bar[HDA_DSP_SPIB_BAR]) {
- stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
+ hext_stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
SOF_HDA_SPIB_SPIB;
- stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
+ hext_stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
SOF_HDA_SPIB_MAXFIFO;
}
- hstream = &stream->hstream;
+ hstream = &hext_stream->hstream;
hstream->bus = bus;
hstream->sd_int_sta_mask = 1 << i;
hstream->index = i;
@@ -927,28 +927,28 @@ int hda_dsp_stream_init(struct snd_sof_dev *sdev)
hda_stream->sdev = sdev;
- stream = &hda_stream->hda_stream;
+ hext_stream = &hda_stream->hext_stream;
/* we always have DSP support */
- stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
+ hext_stream->pphc_addr = sdev->bar[HDA_DSP_PP_BAR] +
SOF_HDA_PPHC_BASE + SOF_HDA_PPHC_INTERVAL * i;
- stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
+ hext_stream->pplc_addr = sdev->bar[HDA_DSP_PP_BAR] +
SOF_HDA_PPLC_BASE + SOF_HDA_PPLC_MULTI * num_total +
SOF_HDA_PPLC_INTERVAL * i;
/* do we support SPIB */
if (sdev->bar[HDA_DSP_SPIB_BAR]) {
- stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
+ hext_stream->spib_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
SOF_HDA_SPIB_SPIB;
- stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
+ hext_stream->fifo_addr = sdev->bar[HDA_DSP_SPIB_BAR] +
SOF_HDA_SPIB_BASE + SOF_HDA_SPIB_INTERVAL * i +
SOF_HDA_SPIB_MAXFIFO;
}
- hstream = &stream->hstream;
+ hstream = &hext_stream->hstream;
hstream->bus = bus;
hstream->sd_int_sta_mask = 1 << i;
hstream->index = i;
@@ -983,7 +983,7 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
struct hdac_stream *s, *_s;
- struct hdac_ext_stream *stream;
+ struct hdac_ext_stream *hext_stream;
struct sof_intel_hda_stream *hda_stream;
/* free position buffer */
@@ -1003,9 +1003,9 @@ void hda_dsp_stream_free(struct snd_sof_dev *sdev)
if (s->bdl.area)
snd_dma_free_pages(&s->bdl);
list_del(&s->list);
- stream = stream_to_hdac_ext_stream(s);
- hda_stream = container_of(stream, struct sof_intel_hda_stream,
- hda_stream);
+ hext_stream = stream_to_hdac_ext_stream(s);
+ hda_stream = container_of(hext_stream, struct sof_intel_hda_stream,
+ hext_stream);
devm_kfree(sdev->dev, hda_stream);
}
}
diff --git a/sound/soc/sof/intel/hda-trace.c b/sound/soc/sof/intel/hda-trace.c
index 29e3da3c63db..755ef1d835e0 100644
--- a/sound/soc/sof/intel/hda-trace.c
+++ b/sound/soc/sof/intel/hda-trace.c
@@ -19,25 +19,25 @@
#include "../ops.h"
#include "hda.h"
-static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev)
+static int hda_dsp_trace_prepare(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
- struct hdac_ext_stream *stream = hda->dtrace_stream;
- struct hdac_stream *hstream = &stream->hstream;
- struct snd_dma_buffer *dmab = &sdev->dmatb;
+ struct hdac_ext_stream *hext_stream = hda->dtrace_stream;
+ struct hdac_stream *hstream = &hext_stream->hstream;
int ret;
hstream->period_bytes = 0;/* initialize period_bytes */
- hstream->bufsize = sdev->dmatb.bytes;
+ hstream->bufsize = dmab->bytes;
- ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL);
+ ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL);
if (ret < 0)
dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret);
return ret;
}
-int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag)
+int hda_dsp_trace_init(struct snd_sof_dev *sdev,
+ struct sof_ipc_dma_trace_params_ext *dtrace_params)
{
struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
int ret;
@@ -51,18 +51,19 @@ int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag)
return -ENODEV;
}
- *stream_tag = hda->dtrace_stream->hstream.stream_tag;
+ dtrace_params->stream_tag = hda->dtrace_stream->hstream.stream_tag;
/*
* initialize capture stream, set BDL address and return corresponding
* stream tag which will be sent to the firmware by IPC message.
*/
- ret = hda_dsp_trace_prepare(sdev);
+ ret = hda_dsp_trace_prepare(sdev, &sdev->dmatb);
if (ret < 0) {
dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret);
- hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, *stream_tag);
+ hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE,
+ dtrace_params->stream_tag);
hda->dtrace_stream = NULL;
- *stream_tag = 0;
+ dtrace_params->stream_tag = 0;
}
return ret;
diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c
index 1385695d7745..9c97c80a7f48 100644
--- a/sound/soc/sof/intel/hda.c
+++ b/sound/soc/sof/intel/hda.c
@@ -41,100 +41,68 @@
#define EXCEPT_MAX_HDR_SIZE 0x400
#define HDA_EXT_ROM_STATUS_SIZE 8
-int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags)
+int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags,
+ struct snd_sof_dai_config_data *data)
{
struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct sof_ipc_dai_config *config;
- struct snd_sof_dai *sof_dai;
- struct sof_ipc_reply reply;
+ const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
+ struct snd_sof_dai *sof_dai = swidget->private;
int ret;
- sof_dai = swidget->private;
-
- if (!sof_dai || !sof_dai->dai_config) {
- dev_err(sdev->dev, "No config for DAI %s\n", w->name);
+ if (!sof_dai) {
+ dev_err(sdev->dev, "%s: No DAI for DAI widget %s\n", __func__, w->name);
return -EINVAL;
}
- /* DAI already configured, reset it before reconfiguring it */
- if (sof_dai->configured) {
- ret = hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
- if (ret < 0)
- return ret;
- }
+ if (tplg_ops->dai_config) {
+ unsigned int flags;
- config = &sof_dai->dai_config[sof_dai->current_config];
+ /* set HW_PARAMS flag along with quirks */
+ flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS |
+ quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT;
- /*
- * For static pipelines, the DAI widget would already be set up and calling
- * sof_widget_setup() simply returns without doing anything.
- * For dynamic pipelines, the DAI widget will be set up now.
- */
- ret = sof_widget_setup(sdev, swidget);
- if (ret < 0) {
- dev_err(sdev->dev, "error: failed setting up DAI widget %s\n", w->name);
- return ret;
- }
-
- /* set HW_PARAMS flag along with quirks */
- config->flags = SOF_DAI_CONFIG_FLAGS_HW_PARAMS |
- quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT;
-
-
- /* send DAI_CONFIG IPC */
- ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
- &reply, sizeof(reply));
- if (ret < 0) {
- dev_err(sdev->dev, "error: failed setting DAI config for %s\n", w->name);
- return ret;
+ ret = tplg_ops->dai_config(sdev, swidget, flags, data);
+ if (ret < 0) {
+ dev_err(sdev->dev, "%s: DAI config failed for widget %s\n", __func__,
+ w->name);
+ return ret;
+ }
}
- sof_dai->configured = true;
-
return 0;
}
-int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags)
+int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags,
+ struct snd_sof_dai_config_data *data)
{
struct snd_sof_widget *swidget = w->dobj.private;
struct snd_soc_component *component = swidget->scomp;
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
- struct sof_ipc_dai_config *config;
- struct snd_sof_dai *sof_dai;
- struct sof_ipc_reply reply;
- int ret;
-
- sof_dai = swidget->private;
+ const struct sof_ipc_tplg_ops *tplg_ops = sdev->ipc->ops->tplg;
+ struct snd_sof_dai *sof_dai = swidget->private;
- if (!sof_dai || !sof_dai->dai_config) {
- dev_err(sdev->dev, "error: No config to free DAI %s\n", w->name);
+ if (!sof_dai) {
+ dev_err(sdev->dev, "%s: No DAI for BE DAI widget %s\n", __func__, w->name);
return -EINVAL;
}
- /* nothing to do if hw_free() is called without restarting the stream after resume. */
- if (!sof_dai->configured)
- return 0;
-
- config = &sof_dai->dai_config[sof_dai->current_config];
-
- /* set HW_FREE flag along with any quirks */
- config->flags = SOF_DAI_CONFIG_FLAGS_HW_FREE |
- quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT;
+ if (tplg_ops->dai_config) {
+ unsigned int flags;
+ int ret;
- ret = sof_ipc_tx_message(sdev->ipc, config->hdr.cmd, config, config->hdr.size,
- &reply, sizeof(reply));
- if (ret < 0)
- dev_err(sdev->dev, "error: failed resetting DAI config for %s\n", w->name);
+ /* set HW_FREE flag along with any quirks */
+ flags = SOF_DAI_CONFIG_FLAGS_HW_FREE |
+ quirk_flags << SOF_DAI_CONFIG_FLAGS_QUIRK_SHIFT;
- /*
- * Reset the configured_flag and free the widget even if the IPC fails to keep
- * the widget use_count balanced
- */
- sof_dai->configured = false;
+ ret = tplg_ops->dai_config(sdev, swidget, flags, data);
+ if (ret < 0)
+ dev_err(sdev->dev, "%s: DAI config failed for widget '%s'\n", __func__,
+ w->name);
+ }
- return sof_widget_free(sdev, swidget);
+ return 0;
}
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
@@ -149,62 +117,34 @@ static int sdw_clock_stop_quirks = SDW_INTEL_CLK_STOP_BUS_RESET;
module_param(sdw_clock_stop_quirks, int, 0444);
MODULE_PARM_DESC(sdw_clock_stop_quirks, "SOF SoundWire clock stop quirks");
-static int sdw_dai_config_ipc(struct snd_sof_dev *sdev,
- struct snd_soc_dapm_widget *w,
- int link_id, int alh_stream_id, int dai_id, bool setup)
-{
- struct snd_sof_widget *swidget = w->dobj.private;
- struct sof_ipc_dai_config *config;
- struct snd_sof_dai *sof_dai;
-
- if (!swidget) {
- dev_err(sdev->dev, "error: No private data for widget %s\n", w->name);
- return -EINVAL;
- }
-
- sof_dai = swidget->private;
-
- if (!sof_dai || !sof_dai->dai_config) {
- dev_err(sdev->dev, "error: No config for DAI %s\n", w->name);
- return -EINVAL;
- }
-
- config = &sof_dai->dai_config[sof_dai->current_config];
-
- /* update config with link and stream ID */
- config->dai_index = (link_id << 8) | dai_id;
- config->alh.stream_id = alh_stream_id;
-
- if (setup)
- return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE);
-
- return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE);
-}
-
static int sdw_params_stream(struct device *dev,
struct sdw_intel_stream_params_data *params_data)
{
- struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_soc_dai *d = params_data->dai;
+ struct snd_sof_dai_config_data data;
struct snd_soc_dapm_widget *w;
w = snd_soc_dai_get_widget(d, params_data->stream);
+ data.dai_index = (params_data->link_id << 8) | d->id;
+ data.dai_data = params_data->alh_stream_id;
- return sdw_dai_config_ipc(sdev, w, params_data->link_id, params_data->alh_stream_id,
- d->id, true);
+ return hda_ctrl_dai_widget_setup(w, SOF_DAI_CONFIG_FLAGS_NONE, &data);
}
static int sdw_free_stream(struct device *dev,
struct sdw_intel_stream_free_data *free_data)
{
- struct snd_sof_dev *sdev = dev_get_drvdata(dev);
struct snd_soc_dai *d = free_data->dai;
+ struct snd_sof_dai_config_data data;
struct snd_soc_dapm_widget *w;
w = snd_soc_dai_get_widget(d, free_data->stream);
+ data.dai_index = (free_data->link_id << 8) | d->id;
/* send invalid stream_id */
- return sdw_dai_config_ipc(sdev, w, free_data->link_id, 0xFFFF, d->id, false);
+ data.dai_data = 0xFFFF;
+
+ return hda_ctrl_dai_widget_free(w, SOF_DAI_CONFIG_FLAGS_NONE, &data);
}
static const struct sdw_intel_ops sdw_callback = {
@@ -432,11 +372,9 @@ static char *hda_model;
module_param(hda_model, charp, 0444);
MODULE_PARM_DESC(hda_model, "Use the given HDA board model.");
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
-static int hda_dmic_num = -1;
-module_param_named(dmic_num, hda_dmic_num, int, 0444);
+static int dmic_num_override = -1;
+module_param_named(dmic_num, dmic_num_override, int, 0444);
MODULE_PARM_DESC(dmic_num, "SOF HDA DMIC number");
-#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
static bool hda_codec_use_common_hdmi = IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI);
@@ -534,7 +472,7 @@ static void hda_dsp_dump_ext_rom_status(struct snd_sof_dev *sdev, const char *le
void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
{
- char *level = flags & SOF_DBG_DUMP_OPTIONAL ? KERN_DEBUG : KERN_ERR;
+ char *level = (flags & SOF_DBG_DUMP_OPTIONAL) ? KERN_DEBUG : KERN_ERR;
struct sof_ipc_dsp_oops_xtensa xoops;
struct sof_ipc_panic_info panic_info;
u32 stack[HDA_DSP_STACK_DUMP_SIZE];
@@ -644,24 +582,54 @@ static int hda_init(struct snd_sof_dev *sdev)
return ret;
}
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
-
-static int check_nhlt_dmic(struct snd_sof_dev *sdev)
+static int check_dmic_num(struct snd_sof_dev *sdev)
{
struct nhlt_acpi_table *nhlt;
- int dmic_num;
+ int dmic_num = 0;
nhlt = intel_nhlt_init(sdev->dev);
if (nhlt) {
dmic_num = intel_nhlt_get_dmic_geo(sdev->dev, nhlt);
intel_nhlt_free(nhlt);
- if (dmic_num >= 1 && dmic_num <= 4)
- return dmic_num;
}
- return 0;
+ /* allow for module parameter override */
+ if (dmic_num_override != -1) {
+ dev_dbg(sdev->dev,
+ "overriding DMICs detected in NHLT tables %d by kernel param %d\n",
+ dmic_num, dmic_num_override);
+ dmic_num = dmic_num_override;
+ }
+
+ if (dmic_num < 0 || dmic_num > 4) {
+ dev_dbg(sdev->dev, "invalid dmic_number %d\n", dmic_num);
+ dmic_num = 0;
+ }
+
+ return dmic_num;
}
+static int check_nhlt_ssp_mask(struct snd_sof_dev *sdev)
+{
+ struct nhlt_acpi_table *nhlt;
+ int ssp_mask = 0;
+
+ nhlt = intel_nhlt_init(sdev->dev);
+ if (!nhlt)
+ return ssp_mask;
+
+ if (intel_nhlt_has_endpoint_type(nhlt, NHLT_LINK_SSP)) {
+ ssp_mask = intel_nhlt_ssp_endpoint_mask(nhlt, NHLT_DEVICE_I2S);
+ if (ssp_mask)
+ dev_info(sdev->dev, "NHLT_DEVICE_I2S detected, ssp_mask %#x\n", ssp_mask);
+ }
+ intel_nhlt_free(nhlt);
+
+ return ssp_mask;
+}
+
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) || IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
+
static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
const char *sof_tplg_filename,
const char *idisp_str,
@@ -697,16 +665,8 @@ static int dmic_topology_fixup(struct snd_sof_dev *sdev,
const char *dmic_str;
int dmic_num;
- /* first check NHLT for DMICs */
- dmic_num = check_nhlt_dmic(sdev);
-
- /* allow for module parameter override */
- if (hda_dmic_num != -1) {
- dev_dbg(sdev->dev,
- "overriding DMICs detected in NHLT tables %d by kernel param %d\n",
- dmic_num, hda_dmic_num);
- dmic_num = hda_dmic_num;
- }
+ /* first check for DMICs (using NHLT or module parameter) */
+ dmic_num = check_dmic_num(sdev);
switch (dmic_num) {
case 1:
@@ -1180,6 +1140,10 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev,
#endif
#if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE)
+
+#define SDW_CODEC_ADR_MASK(_adr) ((_adr) & (SDW_DISCO_LINK_ID_MASK | SDW_VERSION_MASK | \
+ SDW_MFG_ID_MASK | SDW_PART_ID_MASK))
+
/* Check if all Slaves defined on the link can be found */
static bool link_slaves_found(struct snd_sof_dev *sdev,
const struct snd_soc_acpi_link_adr *link,
@@ -1188,7 +1152,7 @@ static bool link_slaves_found(struct snd_sof_dev *sdev,
struct hdac_bus *bus = sof_to_bus(sdev);
struct sdw_intel_slave_id *ids = sdw->ids;
int num_slaves = sdw->num_slaves;
- unsigned int part_id, link_id, unique_id, mfg_id;
+ unsigned int part_id, link_id, unique_id, mfg_id, version;
int i, j, k;
for (i = 0; i < link->num_adr; i++) {
@@ -1198,12 +1162,14 @@ static bool link_slaves_found(struct snd_sof_dev *sdev,
mfg_id = SDW_MFG_ID(adr);
part_id = SDW_PART_ID(adr);
link_id = SDW_DISCO_LINK_ID(adr);
+ version = SDW_VERSION(adr);
for (j = 0; j < num_slaves; j++) {
/* find out how many identical parts were reported on that link */
if (ids[j].link_id == link_id &&
ids[j].id.part_id == part_id &&
- ids[j].id.mfg_id == mfg_id)
+ ids[j].id.mfg_id == mfg_id &&
+ ids[j].id.sdw_version == version)
reported_part_count++;
}
@@ -1212,21 +1178,15 @@ static bool link_slaves_found(struct snd_sof_dev *sdev,
if (ids[j].link_id != link_id ||
ids[j].id.part_id != part_id ||
- ids[j].id.mfg_id != mfg_id)
+ ids[j].id.mfg_id != mfg_id ||
+ ids[j].id.sdw_version != version)
continue;
/* find out how many identical parts are expected */
for (k = 0; k < link->num_adr; k++) {
u64 adr2 = link->adr_d[k].adr;
- unsigned int part_id2, link_id2, mfg_id2;
-
- mfg_id2 = SDW_MFG_ID(adr2);
- part_id2 = SDW_PART_ID(adr2);
- link_id2 = SDW_DISCO_LINK_ID(adr2);
- if (link_id2 == link_id &&
- part_id2 == part_id &&
- mfg_id2 == mfg_id)
+ if (SDW_CODEC_ADR_MASK(adr2) == SDW_CODEC_ADR_MASK(adr))
expected_part_count++;
}
@@ -1314,10 +1274,7 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
mach->mach_params.platform = dev_name(sdev->dev);
- if (mach->sof_fw_filename)
- pdata->fw_filename = mach->sof_fw_filename;
- else
- pdata->fw_filename = pdata->desc->default_fw_filename;
+ pdata->fw_filename = pdata->desc->default_fw_filename;
pdata->tplg_filename = mach->sof_tplg_filename;
/*
@@ -1377,9 +1334,12 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
struct snd_sof_pdata *sof_pdata = sdev->pdata;
const struct sof_dev_desc *desc = sof_pdata->desc;
struct snd_soc_acpi_mach *mach;
+ const char *tplg_filename;
mach = snd_soc_acpi_find_machine(desc->machines);
if (mach) {
+ bool add_extension = false;
+
/*
* If tplg file name is overridden, use it instead of
* the one set in mach table
@@ -1387,10 +1347,65 @@ struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev)
if (!sof_pdata->tplg_filename)
sof_pdata->tplg_filename = mach->sof_tplg_filename;
+ /* report to machine driver if any DMICs are found */
+ mach->mach_params.dmic_num = check_dmic_num(sdev);
+
+ if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_DMIC_NUMBER &&
+ mach->mach_params.dmic_num) {
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s%s%d%s",
+ sof_pdata->tplg_filename,
+ "-dmic",
+ mach->mach_params.dmic_num,
+ "ch");
+ if (!tplg_filename)
+ return NULL;
+
+ sof_pdata->tplg_filename = tplg_filename;
+ add_extension = true;
+ }
+
if (mach->link_mask) {
mach->mach_params.links = mach->links;
mach->mach_params.link_mask = mach->link_mask;
}
+
+ /* report SSP link mask to machine driver */
+ mach->mach_params.i2s_link_mask = check_nhlt_ssp_mask(sdev);
+
+ if (mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_NUMBER &&
+ mach->mach_params.i2s_link_mask) {
+ int ssp_num;
+
+ if (hweight_long(mach->mach_params.i2s_link_mask) > 1 &&
+ !(mach->tplg_quirk_mask & SND_SOC_ACPI_TPLG_INTEL_SSP_MSB))
+ dev_warn(sdev->dev, "More than one SSP exposed by NHLT, choosing MSB\n");
+
+ /* fls returns 1-based results, SSPs indices are 0-based */
+ ssp_num = fls(mach->mach_params.i2s_link_mask) - 1;
+
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s%s%d",
+ sof_pdata->tplg_filename,
+ "-ssp",
+ ssp_num);
+ if (!tplg_filename)
+ return NULL;
+
+ sof_pdata->tplg_filename = tplg_filename;
+ add_extension = true;
+ }
+
+ if (add_extension) {
+ tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
+ "%s%s",
+ sof_pdata->tplg_filename,
+ ".tplg");
+ if (!tplg_filename)
+ return NULL;
+
+ sof_pdata->tplg_filename = tplg_filename;
+ }
}
/*
@@ -1424,6 +1439,16 @@ int hda_pci_intel_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
}
EXPORT_SYMBOL_NS(hda_pci_intel_probe, SND_SOC_SOF_INTEL_HDA_COMMON);
+int hda_register_clients(struct snd_sof_dev *sdev)
+{
+ return hda_probes_register(sdev);
+}
+
+void hda_unregister_clients(struct snd_sof_dev *sdev)
+{
+ hda_probes_unregister(sdev);
+}
+
MODULE_LICENSE("Dual BSD/GPL");
MODULE_IMPORT_NS(SND_SOC_SOF_PCI_DEV);
MODULE_IMPORT_NS(SND_SOC_SOF_HDA_AUDIO_CODEC);
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index 03a6bb7a165c..05e5e158614a 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -16,6 +16,8 @@
#include <sound/compress_driver.h>
#include <sound/hda_codec.h>
#include <sound/hdaudio_ext.h>
+#include "../sof-client-probes.h"
+#include "../sof-audio.h"
#include "shim.h"
/* PCI registers */
@@ -351,13 +353,7 @@
/* Number of DAIs */
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
-
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
-#define SOF_SKL_NUM_DAIS 16
-#else
#define SOF_SKL_NUM_DAIS 15
-#endif
-
#else
#define SOF_SKL_NUM_DAIS 8
#endif
@@ -383,9 +379,9 @@
/* SSP Registers */
#define SSP_SSC1_OFFSET 0x4
-#define SSP_SET_SCLK_SLAVE BIT(25)
-#define SSP_SET_SFRM_SLAVE BIT(24)
-#define SSP_SET_SLAVE (SSP_SET_SCLK_SLAVE | SSP_SET_SFRM_SLAVE)
+#define SSP_SET_SCLK_CONSUMER BIT(25)
+#define SSP_SET_SFRM_CONSUMER BIT(24)
+#define SSP_SET_CBP_CFP (SSP_SET_SCLK_CONSUMER | SSP_SET_SFRM_CONSUMER)
#define HDA_IDISP_ADDR 2
#define HDA_IDISP_CODEC(x) ((x) & BIT(HDA_IDISP_ADDR))
@@ -471,14 +467,14 @@ static inline struct hda_bus *sof_to_hbus(struct snd_sof_dev *s)
struct sof_intel_hda_stream {
struct snd_sof_dev *sdev;
- struct hdac_ext_stream hda_stream;
- struct sof_intel_stream stream;
+ struct hdac_ext_stream hext_stream;
+ struct sof_intel_stream sof_intel_stream;
int host_reserved; /* reserve host DMA channel */
u32 flags;
};
#define hstream_to_sof_hda_stream(hstream) \
- container_of(hstream, struct sof_intel_hda_stream, hda_stream)
+ container_of(hstream, struct sof_intel_hda_stream, hext_stream)
#define bus_to_sof_hda(bus) \
container_of(bus, struct sof_intel_hda_dev, hbus.core)
@@ -529,7 +525,7 @@ int hda_dsp_pcm_close(struct snd_sof_dev *sdev,
int hda_dsp_pcm_hw_params(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params,
- struct sof_ipc_stream_params *ipc_params);
+ struct snd_sof_platform_stream_params *platform_params);
int hda_dsp_stream_hw_free(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream);
int hda_dsp_pcm_trigger(struct snd_sof_dev *sdev,
@@ -545,18 +541,19 @@ int hda_dsp_pcm_ack(struct snd_sof_dev *sdev, struct snd_pcm_substream *substrea
int hda_dsp_stream_init(struct snd_sof_dev *sdev);
void hda_dsp_stream_free(struct snd_sof_dev *sdev);
int hda_dsp_stream_hw_params(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream,
+ struct hdac_ext_stream *hext_stream,
struct snd_dma_buffer *dmab,
struct snd_pcm_hw_params *params);
-int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev, struct hdac_ext_stream *stream,
+int hda_dsp_iccmax_stream_hw_params(struct snd_sof_dev *sdev,
+ struct hdac_ext_stream *hext_stream,
struct snd_dma_buffer *dmab,
struct snd_pcm_hw_params *params);
int hda_dsp_stream_trigger(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream, int cmd);
+ struct hdac_ext_stream *hext_stream, int cmd);
irqreturn_t hda_dsp_stream_threaded_handler(int irq, void *context);
int hda_dsp_stream_setup_bdl(struct snd_sof_dev *sdev,
struct snd_dma_buffer *dmab,
- struct hdac_stream *stream);
+ struct hdac_stream *hstream);
bool hda_dsp_check_ipc_irq(struct snd_sof_dev *sdev);
bool hda_dsp_check_stream_irq(struct snd_sof_dev *sdev);
@@ -564,38 +561,15 @@ struct hdac_ext_stream *
hda_dsp_stream_get(struct snd_sof_dev *sdev, int direction, u32 flags);
int hda_dsp_stream_put(struct snd_sof_dev *sdev, int direction, int stream_tag);
int hda_dsp_stream_spib_config(struct snd_sof_dev *sdev,
- struct hdac_ext_stream *stream,
+ struct hdac_ext_stream *hext_stream,
int enable, u32 size);
int hda_ipc_msg_data(struct snd_sof_dev *sdev,
struct snd_pcm_substream *substream,
void *p, size_t sz);
-int hda_ipc_pcm_params(struct snd_sof_dev *sdev,
- struct snd_pcm_substream *substream,
- const struct sof_ipc_pcm_params_reply *reply);
-
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
-/*
- * Probe Compress Operations.
- */
-int hda_probe_compr_assign(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_soc_dai *dai);
-int hda_probe_compr_free(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_soc_dai *dai);
-int hda_probe_compr_set_params(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_compr_params *params,
- struct snd_soc_dai *dai);
-int hda_probe_compr_trigger(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream, int cmd,
- struct snd_soc_dai *dai);
-int hda_probe_compr_pointer(struct snd_sof_dev *sdev,
- struct snd_compr_stream *cstream,
- struct snd_compr_tstamp *tstamp,
- struct snd_soc_dai *dai);
-#endif
+int hda_set_stream_data_offset(struct snd_sof_dev *sdev,
+ struct snd_pcm_substream *substream,
+ size_t posn_offset);
/*
* DSP IPC Operations.
@@ -670,7 +644,8 @@ static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }
/*
* Trace Control.
*/
-int hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag);
+int hda_dsp_trace_init(struct snd_sof_dev *sdev,
+ struct sof_ipc_dma_trace_params_ext *dtrace_params);
int hda_dsp_trace_release(struct snd_sof_dev *sdev);
int hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd);
@@ -727,6 +702,25 @@ extern const struct sof_intel_dsp_desc ehl_chip_info;
extern const struct sof_intel_dsp_desc jsl_chip_info;
extern const struct sof_intel_dsp_desc adls_chip_info;
+/* Probes support */
+#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
+int hda_probes_register(struct snd_sof_dev *sdev);
+void hda_probes_unregister(struct snd_sof_dev *sdev);
+#else
+static inline int hda_probes_register(struct snd_sof_dev *sdev)
+{
+ return 0;
+}
+
+static inline void hda_probes_unregister(struct snd_sof_dev *sdev)
+{
+}
+#endif /* CONFIG_SND_SOC_SOF_HDA_PROBES */
+
+/* SOF client registration for HDA platforms */
+int hda_register_clients(struct snd_sof_dev *sdev);
+void hda_unregister_clients(struct snd_sof_dev *sdev);
+
/* machine driver select */
struct snd_soc_acpi_mach *hda_machine_select(struct snd_sof_dev *sdev);
void hda_set_mach_params(struct snd_soc_acpi_mach *mach,
@@ -737,8 +731,10 @@ int hda_pci_intel_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
struct snd_sof_dai;
struct sof_ipc_dai_config;
-int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags);
-int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags);
+int hda_ctrl_dai_widget_setup(struct snd_soc_dapm_widget *w, unsigned int quirk_flags,
+ struct snd_sof_dai_config_data *data);
+int hda_ctrl_dai_widget_free(struct snd_soc_dapm_widget *w, unsigned int quirk_flags,
+ struct snd_sof_dai_config_data *data);
#define SOF_HDA_POSITION_QUIRK_USE_SKYLAKE_LEGACY (0) /* previous implementation */
#define SOF_HDA_POSITION_QUIRK_USE_DPIB_REGISTERS (1) /* recommended if VC0 only */
diff --git a/sound/soc/sof/intel/icl.c b/sound/soc/sof/intel/icl.c
index f75e3983969f..b44a649bfc0b 100644
--- a/sound/soc/sof/intel/icl.c
+++ b/sound/soc/sof/intel/icl.c
@@ -118,7 +118,7 @@ const struct snd_sof_dsp_ops sof_icl_ops = {
.get_window_offset = hda_dsp_ipc_get_window_offset,
.ipc_msg_data = hda_ipc_msg_data,
- .ipc_pcm_params = hda_ipc_pcm_params,
+ .set_stream_data_offset = hda_set_stream_data_offset,
/* machine driver */
.machine_select = hda_machine_select,
@@ -142,15 +142,6 @@ const struct snd_sof_dsp_ops sof_icl_ops = {
.pcm_pointer = hda_dsp_pcm_pointer,
.pcm_ack = hda_dsp_pcm_ack,
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
- /* probe callbacks */
- .probe_assign = hda_probe_compr_assign,
- .probe_free = hda_probe_compr_free,
- .probe_set_params = hda_probe_compr_set_params,
- .probe_trigger = hda_probe_compr_trigger,
- .probe_pointer = hda_probe_compr_pointer,
-#endif
-
/* firmware loading */
.load_firmware = snd_sof_load_firmware_raw,
@@ -173,6 +164,10 @@ const struct snd_sof_dsp_ops sof_icl_ops = {
.trace_release = hda_dsp_trace_release,
.trace_trigger = hda_dsp_trace_trigger,
+ /* client ops */
+ .register_ipc_clients = hda_register_clients,
+ .unregister_ipc_clients = hda_unregister_clients,
+
/* DAI drivers */
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,
diff --git a/sound/soc/sof/intel/pci-tgl.c b/sound/soc/sof/intel/pci-tgl.c
index fd46210f1730..feaec251adc8 100644
--- a/sound/soc/sof/intel/pci-tgl.c
+++ b/sound/soc/sof/intel/pci-tgl.c
@@ -110,6 +110,8 @@ static const struct pci_device_id sof_pci_ids[] = {
.driver_data = (unsigned long)&ehl_desc},
{ PCI_DEVICE(0x8086, 0x7ad0), /* ADL-S */
.driver_data = (unsigned long)&adls_desc},
+ { PCI_DEVICE(0x8086, 0x7a50), /* RPL-S */
+ .driver_data = (unsigned long)&adls_desc},
{ PCI_DEVICE(0x8086, 0x51c8), /* ADL-P */
.driver_data = (unsigned long)&adl_desc},
{ PCI_DEVICE(0x8086, 0x51cd), /* ADL-P */
diff --git a/sound/soc/sof/intel/pci-tng.c b/sound/soc/sof/intel/pci-tng.c
index f8c841caa362..6efef225973f 100644
--- a/sound/soc/sof/intel/pci-tng.c
+++ b/sound/soc/sof/intel/pci-tng.c
@@ -25,7 +25,6 @@ static struct snd_soc_acpi_mach sof_tng_machines[] = {
{
.id = "INT343A",
.drv_name = "edison",
- .sof_fw_filename = "sof-byt.ri",
.sof_tplg_filename = "sof-byt.tplg",
},
{}
@@ -166,7 +165,7 @@ const struct snd_sof_dsp_ops sof_tng_ops = {
.get_window_offset = atom_get_window_offset,
.ipc_msg_data = sof_ipc_msg_data,
- .ipc_pcm_params = sof_ipc_pcm_params,
+ .set_stream_data_offset = sof_set_stream_data_offset,
/* machine driver */
.machine_select = atom_machine_select,
diff --git a/sound/soc/sof/intel/tgl.c b/sound/soc/sof/intel/tgl.c
index 7f7929c5cb88..cb1c319d5bee 100644
--- a/sound/soc/sof/intel/tgl.c
+++ b/sound/soc/sof/intel/tgl.c
@@ -91,7 +91,7 @@ const struct snd_sof_dsp_ops sof_tgl_ops = {
.get_window_offset = hda_dsp_ipc_get_window_offset,
.ipc_msg_data = hda_ipc_msg_data,
- .ipc_pcm_params = hda_ipc_pcm_params,
+ .set_stream_data_offset = hda_set_stream_data_offset,
/* machine driver */
.machine_select = hda_machine_select,
@@ -115,15 +115,6 @@ const struct snd_sof_dsp_ops sof_tgl_ops = {
.pcm_pointer = hda_dsp_pcm_pointer,
.pcm_ack = hda_dsp_pcm_ack,
-#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES)
- /* probe callbacks */
- .probe_assign = hda_probe_compr_assign,
- .probe_free = hda_probe_compr_free,
- .probe_set_params = hda_probe_compr_set_params,
- .probe_trigger = hda_probe_compr_trigger,
- .probe_pointer = hda_probe_compr_pointer,
-#endif
-
/* firmware loading */
.load_firmware = snd_sof_load_firmware_raw,
@@ -146,6 +137,10 @@ const struct snd_sof_dsp_ops sof_tgl_ops = {
.trace_release = hda_dsp_trace_release,
.trace_trigger = hda_dsp_trace_trigger,
+ /* client ops */
+ .register_ipc_clients = hda_register_clients,
+ .unregister_ipc_clients = hda_unregister_clients,
+
/* DAI drivers */
.drv = skl_dai,
.num_drv = SOF_SKL_NUM_DAIS,