xref: /openbmc/linux/sound/soc/sof/intel/hda-probes.c (revision 7d88b9608142f95ccdd3dfb190da4a5faddb1cc7)
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