162306a36Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 262306a36Sopenharmony_ci// 362306a36Sopenharmony_ci// This file is provided under a dual BSD/GPLv2 license. When using or 462306a36Sopenharmony_ci// redistributing this file, you may do so under either license. 562306a36Sopenharmony_ci// 662306a36Sopenharmony_ci// Copyright(c) 2018 Intel Corporation. All rights reserved. 762306a36Sopenharmony_ci// 862306a36Sopenharmony_ci// Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com> 962306a36Sopenharmony_ci// Ranjani Sridharan <ranjani.sridharan@linux.intel.com> 1062306a36Sopenharmony_ci// Rander Wang <rander.wang@intel.com> 1162306a36Sopenharmony_ci// Keyon Jie <yang.jie@linux.intel.com> 1262306a36Sopenharmony_ci// 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci/* 1562306a36Sopenharmony_ci * Hardware interface for generic Intel audio DSP HDA IP 1662306a36Sopenharmony_ci */ 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_ci#include <sound/hdaudio_ext.h> 1962306a36Sopenharmony_ci#include "../ops.h" 2062306a36Sopenharmony_ci#include "hda.h" 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_cistatic int hda_dsp_trace_prepare(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab) 2362306a36Sopenharmony_ci{ 2462306a36Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 2562306a36Sopenharmony_ci struct hdac_ext_stream *hext_stream = hda->dtrace_stream; 2662306a36Sopenharmony_ci struct hdac_stream *hstream = &hext_stream->hstream; 2762306a36Sopenharmony_ci int ret; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci hstream->period_bytes = 0;/* initialize period_bytes */ 3062306a36Sopenharmony_ci hstream->bufsize = dmab->bytes; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL); 3362306a36Sopenharmony_ci if (ret < 0) 3462306a36Sopenharmony_ci dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci return ret; 3762306a36Sopenharmony_ci} 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ciint hda_dsp_trace_init(struct snd_sof_dev *sdev, struct snd_dma_buffer *dmab, 4062306a36Sopenharmony_ci struct sof_ipc_dma_trace_params_ext *dtrace_params) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 4362306a36Sopenharmony_ci int ret; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci hda->dtrace_stream = hda_dsp_stream_get(sdev, SNDRV_PCM_STREAM_CAPTURE, 4662306a36Sopenharmony_ci SOF_HDA_STREAM_DMI_L1_COMPATIBLE); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci if (!hda->dtrace_stream) { 4962306a36Sopenharmony_ci dev_err(sdev->dev, 5062306a36Sopenharmony_ci "error: no available capture stream for DMA trace\n"); 5162306a36Sopenharmony_ci return -ENODEV; 5262306a36Sopenharmony_ci } 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci dtrace_params->stream_tag = hda->dtrace_stream->hstream.stream_tag; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci /* 5762306a36Sopenharmony_ci * initialize capture stream, set BDL address and return corresponding 5862306a36Sopenharmony_ci * stream tag which will be sent to the firmware by IPC message. 5962306a36Sopenharmony_ci */ 6062306a36Sopenharmony_ci ret = hda_dsp_trace_prepare(sdev, dmab); 6162306a36Sopenharmony_ci if (ret < 0) { 6262306a36Sopenharmony_ci dev_err(sdev->dev, "error: hdac trace init failed: %d\n", ret); 6362306a36Sopenharmony_ci hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, 6462306a36Sopenharmony_ci dtrace_params->stream_tag); 6562306a36Sopenharmony_ci hda->dtrace_stream = NULL; 6662306a36Sopenharmony_ci dtrace_params->stream_tag = 0; 6762306a36Sopenharmony_ci } 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci return ret; 7062306a36Sopenharmony_ci} 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ciint hda_dsp_trace_release(struct snd_sof_dev *sdev) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 7562306a36Sopenharmony_ci struct hdac_stream *hstream; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (hda->dtrace_stream) { 7862306a36Sopenharmony_ci hstream = &hda->dtrace_stream->hstream; 7962306a36Sopenharmony_ci hda_dsp_stream_put(sdev, 8062306a36Sopenharmony_ci SNDRV_PCM_STREAM_CAPTURE, 8162306a36Sopenharmony_ci hstream->stream_tag); 8262306a36Sopenharmony_ci hda->dtrace_stream = NULL; 8362306a36Sopenharmony_ci return 0; 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci dev_dbg(sdev->dev, "DMA trace stream is not opened!\n"); 8762306a36Sopenharmony_ci return -ENODEV; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ciint hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd) 9162306a36Sopenharmony_ci{ 9262306a36Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci return hda_dsp_stream_trigger(sdev, hda->dtrace_stream, cmd); 9562306a36Sopenharmony_ci} 96