1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2019-2021 Intel Corporation
8 // Author: Cezary Rojewski <cezary.rojewski@intel.com>
9 // Converted to SOF client:
10 // Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
11 // Peter Ujfalusi <peter.ujfalusi@linux.intel.com>
14 #include <linux/module.h>
15 #include <sound/hdaudio_ext.h>
16 #include <sound/soc.h>
17 #include "../sof-priv.h"
18 #include "../sof-client-probes.h"
19 #include "../sof-client.h"
22 static inline struct hdac_ext_stream
*
23 hda_compr_get_stream(struct snd_compr_stream
*cstream
)
25 return cstream
->runtime
->private_data
;
28 static int hda_probes_compr_startup(struct sof_client_dev
*cdev
,
29 struct snd_compr_stream
*cstream
,
30 struct snd_soc_dai
*dai
, u32
*stream_id
)
32 struct snd_sof_dev
*sdev
= sof_client_dev_to_sof_dev(cdev
);
33 struct hdac_ext_stream
*hext_stream
;
35 hext_stream
= hda_dsp_stream_get(sdev
, cstream
->direction
, 0);
39 hdac_stream(hext_stream
)->curr_pos
= 0;
40 hdac_stream(hext_stream
)->cstream
= cstream
;
41 cstream
->runtime
->private_data
= hext_stream
;
43 *stream_id
= hdac_stream(hext_stream
)->stream_tag
;
48 static int hda_probes_compr_shutdown(struct sof_client_dev
*cdev
,
49 struct snd_compr_stream
*cstream
,
50 struct snd_soc_dai
*dai
)
52 struct hdac_ext_stream
*hext_stream
= hda_compr_get_stream(cstream
);
53 struct snd_sof_dev
*sdev
= sof_client_dev_to_sof_dev(cdev
);
56 ret
= hda_dsp_stream_put(sdev
, cstream
->direction
,
57 hdac_stream(hext_stream
)->stream_tag
);
59 dev_dbg(sdev
->dev
, "stream put failed: %d\n", ret
);
63 hdac_stream(hext_stream
)->cstream
= NULL
;
64 cstream
->runtime
->private_data
= NULL
;
69 static int hda_probes_compr_set_params(struct sof_client_dev
*cdev
,
70 struct snd_compr_stream
*cstream
,
71 struct snd_compr_params
*params
,
72 struct snd_soc_dai
*dai
)
74 struct hdac_ext_stream
*hext_stream
= hda_compr_get_stream(cstream
);
75 struct snd_sof_dev
*sdev
= sof_client_dev_to_sof_dev(cdev
);
76 struct hdac_stream
*hstream
= hdac_stream(hext_stream
);
77 struct snd_dma_buffer
*dmab
;
81 dmab
= cstream
->runtime
->dma_buffer_p
;
82 /* compr params do not store bit depth, default to S32_LE */
83 bps
= snd_pcm_format_physical_width(SNDRV_PCM_FORMAT_S32_LE
);
86 bits
= hda_dsp_get_bits(sdev
, bps
);
87 rate
= hda_dsp_get_mult_div(sdev
, params
->codec
.sample_rate
);
89 hstream
->format_val
= rate
| bits
| (params
->codec
.ch_out
- 1);
90 hstream
->bufsize
= cstream
->runtime
->buffer_size
;
91 hstream
->period_bytes
= cstream
->runtime
->fragment_size
;
92 hstream
->no_period_wakeup
= 0;
94 ret
= hda_dsp_stream_hw_params(sdev
, hext_stream
, dmab
, NULL
);
96 dev_err(sdev
->dev
, "error: hdac prepare failed: %d\n", ret
);
103 static int hda_probes_compr_trigger(struct sof_client_dev
*cdev
,
104 struct snd_compr_stream
*cstream
,
105 int cmd
, struct snd_soc_dai
*dai
)
107 struct hdac_ext_stream
*hext_stream
= hda_compr_get_stream(cstream
);
108 struct snd_sof_dev
*sdev
= sof_client_dev_to_sof_dev(cdev
);
110 return hda_dsp_stream_trigger(sdev
, hext_stream
, cmd
);
113 static int hda_probes_compr_pointer(struct sof_client_dev
*cdev
,
114 struct snd_compr_stream
*cstream
,
115 struct snd_compr_tstamp
*tstamp
,
116 struct snd_soc_dai
*dai
)
118 struct hdac_ext_stream
*hext_stream
= hda_compr_get_stream(cstream
);
119 struct snd_soc_pcm_stream
*pstream
;
121 pstream
= &dai
->driver
->capture
;
122 tstamp
->copied_total
= hdac_stream(hext_stream
)->curr_pos
;
123 tstamp
->sampling_rate
= snd_pcm_rate_bit_to_rate(pstream
->rates
);
128 /* SOF client implementation */
129 static const struct sof_probes_host_ops hda_probes_ops
= {
130 .startup
= hda_probes_compr_startup
,
131 .shutdown
= hda_probes_compr_shutdown
,
132 .set_params
= hda_probes_compr_set_params
,
133 .trigger
= hda_probes_compr_trigger
,
134 .pointer
= hda_probes_compr_pointer
,
137 int hda_probes_register(struct snd_sof_dev
*sdev
)
139 return sof_client_dev_register(sdev
, "hda-probes", 0, &hda_probes_ops
,
140 sizeof(hda_probes_ops
));
142 EXPORT_SYMBOL_NS(hda_probes_register
, "SND_SOC_SOF_INTEL_HDA_COMMON");
144 void hda_probes_unregister(struct snd_sof_dev
*sdev
)
146 sof_client_dev_unregister(sdev
, "hda-probes", 0);
148 EXPORT_SYMBOL_NS(hda_probes_unregister
, "SND_SOC_SOF_INTEL_HDA_COMMON");
150 MODULE_IMPORT_NS("SND_SOC_SOF_CLIENT");