[09/12] ASoC: SOF: Intel: Probe compress operations
diff mbox series

Message ID 20200124190413.18154-10-cezary.rojewski@intel.com
State New
Headers show
Series
  • ASoC: SOF: Data probing
Related show

Commit Message

Cezary Rojewski Jan. 24, 2020, 7:04 p.m. UTC
Add HDA handlers for soc_compr_ops and snd_compr_ops which cover probe
related operations. Implementation supports both connection purposes.
These merely define stream setups as core flow is covered by SOF
compress core.

Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
---
 sound/soc/sof/intel/Kconfig        |  10 +++
 sound/soc/sof/intel/Makefile       |   1 +
 sound/soc/sof/intel/apl.c          |   9 ++
 sound/soc/sof/intel/cnl.c          |   9 ++
 sound/soc/sof/intel/hda-compress.c | 132 +++++++++++++++++++++++++++++
 sound/soc/sof/intel/hda.h          |  24 ++++++
 6 files changed, 185 insertions(+)
 create mode 100644 sound/soc/sof/intel/hda-compress.c

Comments

Pierre-Louis Bossart Jan. 24, 2020, 8:07 p.m. UTC | #1
> diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
> index 8c2da6a2c9df..65058f5c808a 100644
> --- a/sound/soc/sof/intel/Kconfig
> +++ b/sound/soc/sof/intel/Kconfig
> @@ -328,6 +328,16 @@ 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_HDA_LINK

I think this dependency is incorrect? if we are only using the 
controller and host-side DMAs, it's not needed at all. There is no 
technical reason why we couldn't use probes with just I2S codecs, or 
even in nocodec mode.

maybe you meant HDA_COMMON so that it's only used on SKL+.

> +	depends on SND_SOC_SOF_DEBUG_PROBES
> +	help
> +	  This option enables the data probing for Intel(R).
> +		  HDAudio platforms.

HDAudio is misleading, this could mean the HDaudio controller (but 
that's only after SKL) or HDAudio codecs.

This should be "Intel(R) Skylake and newer platforms"?
Cezary Rojewski Jan. 27, 2020, 12:28 p.m. UTC | #2
On 2020-01-24 21:07, Pierre-Louis Bossart wrote:
>> diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
>> index 8c2da6a2c9df..65058f5c808a 100644
>> --- a/sound/soc/sof/intel/Kconfig
>> +++ b/sound/soc/sof/intel/Kconfig
>> @@ -328,6 +328,16 @@ 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_HDA_LINK
> 
> I think this dependency is incorrect? if we are only using the 
> controller and host-side DMAs, it's not needed at all. There is no 
> technical reason why we couldn't use probes with just I2S codecs, or 
> even in nocodec mode.
> 
> maybe you meant HDA_COMMON so that it's only used on SKL+.
> 

Addressed in v2, thanks.

>> +    depends on SND_SOC_SOF_DEBUG_PROBES
>> +    help
>> +      This option enables the data probing for Intel(R).
>> +          HDAudio platforms.
> 
> HDAudio is misleading, this could mean the HDaudio controller (but 
> that's only after SKL) or HDAudio codecs.
> 
> This should be "Intel(R) Skylake and newer platforms"?

Reworded in v2, thanks.

Patch
diff mbox series

diff --git a/sound/soc/sof/intel/Kconfig b/sound/soc/sof/intel/Kconfig
index 8c2da6a2c9df..65058f5c808a 100644
--- a/sound/soc/sof/intel/Kconfig
+++ b/sound/soc/sof/intel/Kconfig
@@ -328,6 +328,16 @@  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_HDA_LINK
+	depends on SND_SOC_SOF_DEBUG_PROBES
+	help
+	  This option enables the data probing for Intel(R).
+		  HDAudio platforms.
+	  Say Y if you want to enable probes.
+	  If unsure, select "N".
+
 config SND_SOC_SOF_HDA_ALWAYS_ENABLE_DMI_L1
 	bool "SOF enable DMI Link L1"
 	help
diff --git a/sound/soc/sof/intel/Makefile b/sound/soc/sof/intel/Makefile
index 587b91bb18b0..398f2e133919 100644
--- a/sound/soc/sof/intel/Makefile
+++ b/sound/soc/sof/intel/Makefile
@@ -11,6 +11,7 @@  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 \
 				 apl.o cnl.o
+snd-sof-intel-hda-common-$(CONFIG_SND_SOC_SOF_HDA_PROBES) += hda-compress.o
 
 snd-sof-intel-hda-objs := hda-codec.o
 
diff --git a/sound/soc/sof/intel/apl.c b/sound/soc/sof/intel/apl.c
index 2483b15699e7..02218d22e51f 100644
--- a/sound/soc/sof/intel/apl.c
+++ b/sound/soc/sof/intel/apl.c
@@ -73,6 +73,15 @@  const struct snd_sof_dsp_ops sof_apl_ops = {
 	.pcm_trigger	= hda_dsp_pcm_trigger,
 	.pcm_pointer	= hda_dsp_pcm_pointer,
 
+#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,
 
diff --git a/sound/soc/sof/intel/cnl.c b/sound/soc/sof/intel/cnl.c
index 8a59fec72919..05125cb0be6e 100644
--- a/sound/soc/sof/intel/cnl.c
+++ b/sound/soc/sof/intel/cnl.c
@@ -284,6 +284,15 @@  const struct snd_sof_dsp_ops sof_cnl_ops = {
 	.pcm_trigger	= hda_dsp_pcm_trigger,
 	.pcm_pointer	= hda_dsp_pcm_pointer,
 
+#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,
 
diff --git a/sound/soc/sof/intel/hda-compress.c b/sound/soc/sof/intel/hda-compress.c
new file mode 100644
index 000000000000..156da3437c6b
--- /dev/null
+++ b/sound/soc/sof/intel/hda-compress.c
@@ -0,0 +1,132 @@ 
+// SPDX-License-Identifier: (GPL-2.0 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) 2019 Intel Corporation. All rights reserved.
+//
+// Author: Cezary Rojewski <cezary.rojewski@intel.com>
+//
+
+#include <sound/hdaudio_ext.h>
+#include <sound/soc.h>
+#include "../sof-priv.h"
+#include "hda.h"
+
+static inline struct hdac_ext_stream *
+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)
+{
+	struct hdac_ext_stream *stream;
+	struct hdac_bus *bus = sof_to_bus(sdev);
+
+	stream = snd_hdac_ext_cstream_assign(bus, cstream);
+	if (!stream)
+		return -EBUSY;
+
+	hdac_stream(stream)->curr_pos = 0;
+	cstream->runtime->private_data = stream;
+
+	return hdac_stream(stream)->stream_tag;
+}
+
+int hda_probe_compr_free(struct snd_sof_dev *sdev,
+			 struct snd_compr_stream *cstream,
+			 struct snd_soc_dai *dai)
+{
+	struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+
+	snd_hdac_stream_cleanup(hdac_stream(stream));
+	hdac_stream(stream)->prepared = 0;
+	snd_hdac_ext_stream_release(stream, HDAC_EXT_STREAM_TYPE_HOST);
+
+	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)
+{
+	struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+	unsigned int format_val;
+	int bps, ret;
+	/* compr params do not store bit depth, default to S32_LE */
+	snd_pcm_format_t format = SNDRV_PCM_FORMAT_S32_LE;
+
+	hdac_stream(stream)->bufsize = 0;
+	hdac_stream(stream)->period_bytes = 0;
+	hdac_stream(stream)->format_val = 0;
+
+	bps = snd_pcm_format_physical_width(format);
+	if (bps < 0)
+		return bps;
+	format_val = snd_hdac_calc_stream_format(params->codec.sample_rate,
+			params->codec.ch_out, format, bps, 0);
+	ret = snd_hdac_stream_set_params(hdac_stream(stream), format_val);
+	if (ret < 0)
+		return ret;
+	ret = snd_hdac_stream_setup(hdac_stream(stream));
+	if (ret < 0)
+		return ret;
+
+	hdac_stream(stream)->prepared = 1;
+
+	return 0;
+}
+
+int hda_probe_compr_trigger(struct snd_sof_dev *sdev,
+			    struct snd_compr_stream *cstream, int cmd,
+			    struct snd_soc_dai *dai)
+{
+	struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+	struct hdac_bus *bus = sof_to_bus(sdev);
+	unsigned long cookie;
+
+	if (!hdac_stream(stream)->prepared)
+		return -EPIPE;
+
+	switch (cmd) {
+	case SNDRV_PCM_TRIGGER_START:
+	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
+	case SNDRV_PCM_TRIGGER_RESUME:
+		spin_lock_irqsave(&bus->reg_lock, cookie);
+		snd_hdac_stream_start(hdac_stream(stream), true);
+		spin_unlock_irqrestore(&bus->reg_lock, cookie);
+		break;
+
+	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
+	case SNDRV_PCM_TRIGGER_SUSPEND:
+	case SNDRV_PCM_TRIGGER_STOP:
+		spin_lock_irqsave(&bus->reg_lock, cookie);
+		snd_hdac_stream_stop(hdac_stream(stream));
+		spin_unlock_irqrestore(&bus->reg_lock, cookie);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+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)
+{
+	struct hdac_ext_stream *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->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates);
+
+	return 0;
+}
diff --git a/sound/soc/sof/intel/hda.h b/sound/soc/sof/intel/hda.h
index a49cc42c9f11..9eb86311a34c 100644
--- a/sound/soc/sof/intel/hda.h
+++ b/sound/soc/sof/intel/hda.h
@@ -13,6 +13,7 @@ 
 
 #include <linux/soundwire/sdw.h>
 #include <linux/soundwire/sdw_intel.h>
+#include <sound/compress_driver.h>
 #include <sound/hda_codec.h>
 #include <sound/hdaudio_ext.h>
 #include "shim.h"
@@ -561,6 +562,29 @@  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
+
 /*
  * DSP IPC Operations.
  */