ASoC: SOF: Intel: Probe compress operations
authorCezary Rojewski <cezary.rojewski@intel.com>
Tue, 18 Feb 2020 14:39:22 +0000 (15:39 +0100)
committerMark Brown <broonie@kernel.org>
Tue, 18 Feb 2020 21:52:09 +0000 (21:52 +0000)
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>
Acked-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20200218143924.10565-8-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
sound/soc/sof/intel/Kconfig
sound/soc/sof/intel/Makefile
sound/soc/sof/intel/apl.c
sound/soc/sof/intel/cnl.c
sound/soc/sof/intel/hda-compress.c [new file with mode: 0644]
sound/soc/sof/intel/hda.h

index 56a837d2cb95bb0dca2bba34097916ea046e3f29..3bc64dee7c39c37ea7e8ada91bc3df8a259da32a 100644 (file)
@@ -305,6 +305,15 @@ 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).
+                 Intel(R) Skylake and newer 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
index b8f58e006e29e5c809af5cf65b2cdc4194a8e5f8..cee02a2e00f402f7e3f63ffeb386c7c758a26f0d 100644 (file)
@@ -9,6 +9,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
 
index 2483b15699e73eaa094b29b2e6b2df04f1605e8f..02218d22e51f49777df1087a9b90bddc0695ba0b 100644 (file)
@@ -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,
 
index 8a59fec7291999619c77c84cb80c8350b49efe7b..05125cb0be6e28166933d0a46b3df8498ada7bb9 100644 (file)
@@ -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 (file)
index 0000000..38a1ebe
--- /dev/null
@@ -0,0 +1,114 @@
+// 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-2020 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;
+
+       stream = hda_dsp_stream_get(sdev, cstream->direction);
+       if (!stream)
+               return -EBUSY;
+
+       hdac_stream(stream)->curr_pos = 0;
+       hdac_stream(stream)->cstream = cstream;
+       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);
+       int ret;
+
+       ret = hda_dsp_stream_put(sdev, cstream->direction,
+                                hdac_stream(stream)->stream_tag);
+       if (ret < 0) {
+               dev_dbg(sdev->dev, "stream put failed: %d\n", ret);
+               return ret;
+       }
+
+       hdac_stream(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)
+{
+       struct hdac_ext_stream *stream = hda_compr_get_stream(cstream);
+       struct hdac_stream *hstream = hdac_stream(stream);
+       struct snd_dma_buffer *dmab;
+       u32 bits, rate;
+       int bps, ret;
+
+       dmab = cstream->runtime->dma_buffer_p;
+       /* compr params do not store bit depth, default to S32_LE */
+       bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE);
+       if (bps < 0)
+               return bps;
+       bits = hda_dsp_get_bits(sdev, bps);
+       rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate);
+
+       hstream->format_val = rate | bits | (params->codec.ch_out - 1);
+       hstream->bufsize = cstream->runtime->buffer_size;
+       hstream->period_bytes = cstream->runtime->fragment_size;
+       hstream->no_period_wakeup = 0;
+
+       ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL);
+       if (ret < 0) {
+               dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret);
+               return ret;
+       }
+
+       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);
+
+       return hda_dsp_stream_trigger(sdev, 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)
+{
+       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;
+}
index 2b5fde372790c6da1596ed213678971f11676c4d..ca44ecb765344875a3a368378ab6d426f9e38725 100644 (file)
@@ -11,6 +11,7 @@
 #ifndef __SOF_INTEL_HDA_H
 #define __SOF_INTEL_HDA_H
 
+#include <sound/compress_driver.h>
 #include <sound/hda_codec.h>
 #include <sound/hdaudio_ext.h>
 #include "shim.h"
@@ -552,6 +553,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.
  */