18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// This file is provided under a dual BSD/GPLv2 license. When using or 48c2ecf20Sopenharmony_ci// redistributing this file, you may do so under either license. 58c2ecf20Sopenharmony_ci// 68c2ecf20Sopenharmony_ci// Copyright(c) 2018 Intel Corporation. All rights reserved. 78c2ecf20Sopenharmony_ci// 88c2ecf20Sopenharmony_ci// Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com> 98c2ecf20Sopenharmony_ci// Ranjani Sridharan <ranjani.sridharan@linux.intel.com> 108c2ecf20Sopenharmony_ci// Rander Wang <rander.wang@intel.com> 118c2ecf20Sopenharmony_ci// Keyon Jie <yang.jie@linux.intel.com> 128c2ecf20Sopenharmony_ci// 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * Hardware interface for generic Intel audio DSP HDA IP 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include <sound/hdaudio_ext.h> 198c2ecf20Sopenharmony_ci#include "../ops.h" 208c2ecf20Sopenharmony_ci#include "hda.h" 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic int hda_dsp_trace_prepare(struct snd_sof_dev *sdev) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 258c2ecf20Sopenharmony_ci struct hdac_ext_stream *stream = hda->dtrace_stream; 268c2ecf20Sopenharmony_ci struct hdac_stream *hstream = &stream->hstream; 278c2ecf20Sopenharmony_ci struct snd_dma_buffer *dmab = &sdev->dmatb; 288c2ecf20Sopenharmony_ci int ret; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci hstream->period_bytes = 0;/* initialize period_bytes */ 318c2ecf20Sopenharmony_ci hstream->bufsize = sdev->dmatb.bytes; 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci ret = hda_dsp_stream_hw_params(sdev, stream, dmab, NULL); 348c2ecf20Sopenharmony_ci if (ret < 0) 358c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: hdac prepare failed: %x\n", ret); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci return ret; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciint hda_dsp_trace_init(struct snd_sof_dev *sdev, u32 *stream_tag) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 438c2ecf20Sopenharmony_ci int ret; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci hda->dtrace_stream = hda_dsp_stream_get(sdev, 468c2ecf20Sopenharmony_ci SNDRV_PCM_STREAM_CAPTURE); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci if (!hda->dtrace_stream) { 498c2ecf20Sopenharmony_ci dev_err(sdev->dev, 508c2ecf20Sopenharmony_ci "error: no available capture stream for DMA trace\n"); 518c2ecf20Sopenharmony_ci return -ENODEV; 528c2ecf20Sopenharmony_ci } 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci *stream_tag = hda->dtrace_stream->hstream.stream_tag; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci /* 578c2ecf20Sopenharmony_ci * initialize capture stream, set BDL address and return corresponding 588c2ecf20Sopenharmony_ci * stream tag which will be sent to the firmware by IPC message. 598c2ecf20Sopenharmony_ci */ 608c2ecf20Sopenharmony_ci ret = hda_dsp_trace_prepare(sdev); 618c2ecf20Sopenharmony_ci if (ret < 0) { 628c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: hdac trace init failed: %x\n", ret); 638c2ecf20Sopenharmony_ci hda_dsp_stream_put(sdev, SNDRV_PCM_STREAM_CAPTURE, *stream_tag); 648c2ecf20Sopenharmony_ci hda->dtrace_stream = NULL; 658c2ecf20Sopenharmony_ci *stream_tag = 0; 668c2ecf20Sopenharmony_ci } 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci return ret; 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciint hda_dsp_trace_release(struct snd_sof_dev *sdev) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 748c2ecf20Sopenharmony_ci struct hdac_stream *hstream; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci if (hda->dtrace_stream) { 778c2ecf20Sopenharmony_ci hstream = &hda->dtrace_stream->hstream; 788c2ecf20Sopenharmony_ci hda_dsp_stream_put(sdev, 798c2ecf20Sopenharmony_ci SNDRV_PCM_STREAM_CAPTURE, 808c2ecf20Sopenharmony_ci hstream->stream_tag); 818c2ecf20Sopenharmony_ci hda->dtrace_stream = NULL; 828c2ecf20Sopenharmony_ci return 0; 838c2ecf20Sopenharmony_ci } 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "DMA trace stream is not opened!\n"); 868c2ecf20Sopenharmony_ci return -ENODEV; 878c2ecf20Sopenharmony_ci} 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ciint hda_dsp_trace_trigger(struct snd_sof_dev *sdev, int cmd) 908c2ecf20Sopenharmony_ci{ 918c2ecf20Sopenharmony_ci struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci return hda_dsp_stream_trigger(sdev, hda->dtrace_stream, cmd); 948c2ecf20Sopenharmony_ci} 95