1f95b4152SPeter Ujfalusi // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 2f95b4152SPeter Ujfalusi // 3f95b4152SPeter Ujfalusi // This file is provided under a dual BSD/GPLv2 license. When using or 4f95b4152SPeter Ujfalusi // redistributing this file, you may do so under either license. 5f95b4152SPeter Ujfalusi // 6f95b4152SPeter Ujfalusi // Copyright(c) 2019-2020 Intel Corporation. All rights reserved. 7f95b4152SPeter Ujfalusi // 8f95b4152SPeter Ujfalusi // Author: Cezary Rojewski <cezary.rojewski@intel.com> 9f95b4152SPeter Ujfalusi // 10f95b4152SPeter Ujfalusi 11f95b4152SPeter Ujfalusi #include <sound/hdaudio_ext.h> 12f95b4152SPeter Ujfalusi #include <sound/soc.h> 13f95b4152SPeter Ujfalusi #include "../sof-priv.h" 14f95b4152SPeter Ujfalusi #include "hda.h" 15f95b4152SPeter Ujfalusi 16f95b4152SPeter Ujfalusi static inline struct hdac_ext_stream * 17f95b4152SPeter Ujfalusi hda_compr_get_stream(struct snd_compr_stream *cstream) 18f95b4152SPeter Ujfalusi { 19f95b4152SPeter Ujfalusi return cstream->runtime->private_data; 20f95b4152SPeter Ujfalusi } 21f95b4152SPeter Ujfalusi 22f95b4152SPeter Ujfalusi int hda_probe_compr_assign(struct snd_sof_dev *sdev, 23f95b4152SPeter Ujfalusi struct snd_compr_stream *cstream, 24f95b4152SPeter Ujfalusi struct snd_soc_dai *dai) 25f95b4152SPeter Ujfalusi { 26*7d88b960SPierre-Louis Bossart struct hdac_ext_stream *hext_stream; 27f95b4152SPeter Ujfalusi 28*7d88b960SPierre-Louis Bossart hext_stream = hda_dsp_stream_get(sdev, cstream->direction, 0); 29*7d88b960SPierre-Louis Bossart if (!hext_stream) 30f95b4152SPeter Ujfalusi return -EBUSY; 31f95b4152SPeter Ujfalusi 32*7d88b960SPierre-Louis Bossart hdac_stream(hext_stream)->curr_pos = 0; 33*7d88b960SPierre-Louis Bossart hdac_stream(hext_stream)->cstream = cstream; 34*7d88b960SPierre-Louis Bossart cstream->runtime->private_data = hext_stream; 35f95b4152SPeter Ujfalusi 36*7d88b960SPierre-Louis Bossart return hdac_stream(hext_stream)->stream_tag; 37f95b4152SPeter Ujfalusi } 38f95b4152SPeter Ujfalusi 39f95b4152SPeter Ujfalusi int hda_probe_compr_free(struct snd_sof_dev *sdev, 40f95b4152SPeter Ujfalusi struct snd_compr_stream *cstream, 41f95b4152SPeter Ujfalusi struct snd_soc_dai *dai) 42f95b4152SPeter Ujfalusi { 43*7d88b960SPierre-Louis Bossart struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream); 44f95b4152SPeter Ujfalusi int ret; 45f95b4152SPeter Ujfalusi 46f95b4152SPeter Ujfalusi ret = hda_dsp_stream_put(sdev, cstream->direction, 47*7d88b960SPierre-Louis Bossart hdac_stream(hext_stream)->stream_tag); 48f95b4152SPeter Ujfalusi if (ret < 0) { 49f95b4152SPeter Ujfalusi dev_dbg(sdev->dev, "stream put failed: %d\n", ret); 50f95b4152SPeter Ujfalusi return ret; 51f95b4152SPeter Ujfalusi } 52f95b4152SPeter Ujfalusi 53*7d88b960SPierre-Louis Bossart hdac_stream(hext_stream)->cstream = NULL; 54f95b4152SPeter Ujfalusi cstream->runtime->private_data = NULL; 55f95b4152SPeter Ujfalusi 56f95b4152SPeter Ujfalusi return 0; 57f95b4152SPeter Ujfalusi } 58f95b4152SPeter Ujfalusi 59f95b4152SPeter Ujfalusi int hda_probe_compr_set_params(struct snd_sof_dev *sdev, 60f95b4152SPeter Ujfalusi struct snd_compr_stream *cstream, 61f95b4152SPeter Ujfalusi struct snd_compr_params *params, 62f95b4152SPeter Ujfalusi struct snd_soc_dai *dai) 63f95b4152SPeter Ujfalusi { 64*7d88b960SPierre-Louis Bossart struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream); 65*7d88b960SPierre-Louis Bossart struct hdac_stream *hstream = hdac_stream(hext_stream); 66f95b4152SPeter Ujfalusi struct snd_dma_buffer *dmab; 67f95b4152SPeter Ujfalusi u32 bits, rate; 68f95b4152SPeter Ujfalusi int bps, ret; 69f95b4152SPeter Ujfalusi 70f95b4152SPeter Ujfalusi dmab = cstream->runtime->dma_buffer_p; 71f95b4152SPeter Ujfalusi /* compr params do not store bit depth, default to S32_LE */ 72f95b4152SPeter Ujfalusi bps = snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE); 73f95b4152SPeter Ujfalusi if (bps < 0) 74f95b4152SPeter Ujfalusi return bps; 75f95b4152SPeter Ujfalusi bits = hda_dsp_get_bits(sdev, bps); 76f95b4152SPeter Ujfalusi rate = hda_dsp_get_mult_div(sdev, params->codec.sample_rate); 77f95b4152SPeter Ujfalusi 78f95b4152SPeter Ujfalusi hstream->format_val = rate | bits | (params->codec.ch_out - 1); 79f95b4152SPeter Ujfalusi hstream->bufsize = cstream->runtime->buffer_size; 80f95b4152SPeter Ujfalusi hstream->period_bytes = cstream->runtime->fragment_size; 81f95b4152SPeter Ujfalusi hstream->no_period_wakeup = 0; 82f95b4152SPeter Ujfalusi 83*7d88b960SPierre-Louis Bossart ret = hda_dsp_stream_hw_params(sdev, hext_stream, dmab, NULL); 84f95b4152SPeter Ujfalusi if (ret < 0) { 85f95b4152SPeter Ujfalusi dev_err(sdev->dev, "error: hdac prepare failed: %d\n", ret); 86f95b4152SPeter Ujfalusi return ret; 87f95b4152SPeter Ujfalusi } 88f95b4152SPeter Ujfalusi 89f95b4152SPeter Ujfalusi return 0; 90f95b4152SPeter Ujfalusi } 91f95b4152SPeter Ujfalusi 92f95b4152SPeter Ujfalusi int hda_probe_compr_trigger(struct snd_sof_dev *sdev, 93f95b4152SPeter Ujfalusi struct snd_compr_stream *cstream, int cmd, 94f95b4152SPeter Ujfalusi struct snd_soc_dai *dai) 95f95b4152SPeter Ujfalusi { 96*7d88b960SPierre-Louis Bossart struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream); 97f95b4152SPeter Ujfalusi 98*7d88b960SPierre-Louis Bossart return hda_dsp_stream_trigger(sdev, hext_stream, cmd); 99f95b4152SPeter Ujfalusi } 100f95b4152SPeter Ujfalusi 101f95b4152SPeter Ujfalusi int hda_probe_compr_pointer(struct snd_sof_dev *sdev, 102f95b4152SPeter Ujfalusi struct snd_compr_stream *cstream, 103f95b4152SPeter Ujfalusi struct snd_compr_tstamp *tstamp, 104f95b4152SPeter Ujfalusi struct snd_soc_dai *dai) 105f95b4152SPeter Ujfalusi { 106*7d88b960SPierre-Louis Bossart struct hdac_ext_stream *hext_stream = hda_compr_get_stream(cstream); 107f95b4152SPeter Ujfalusi struct snd_soc_pcm_stream *pstream; 108f95b4152SPeter Ujfalusi 109f95b4152SPeter Ujfalusi pstream = &dai->driver->capture; 110*7d88b960SPierre-Louis Bossart tstamp->copied_total = hdac_stream(hext_stream)->curr_pos; 111f95b4152SPeter Ujfalusi tstamp->sampling_rate = snd_pcm_rate_bit_to_rate(pstream->rates); 112f95b4152SPeter Ujfalusi 113f95b4152SPeter Ujfalusi return 0; 114f95b4152SPeter Ujfalusi } 115