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