xref: /OK3568_Linux_fs/kernel/sound/soc/sof/ops.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * This file is provided under a dual BSD/GPLv2 license.  When using or
4*4882a593Smuzhiyun  * redistributing this file, you may do so under either license.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright(c) 2018 Intel Corporation. All rights reserved.
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #ifndef __SOUND_SOC_SOF_IO_H
12*4882a593Smuzhiyun #define __SOUND_SOC_SOF_IO_H
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/device.h>
15*4882a593Smuzhiyun #include <linux/interrupt.h>
16*4882a593Smuzhiyun #include <linux/kernel.h>
17*4882a593Smuzhiyun #include <linux/types.h>
18*4882a593Smuzhiyun #include <sound/pcm.h>
19*4882a593Smuzhiyun #include "sof-priv.h"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun #define sof_ops(sdev) \
22*4882a593Smuzhiyun 	((sdev)->pdata->desc->ops)
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun /* Mandatory operations are verified during probing */
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun /* init */
snd_sof_probe(struct snd_sof_dev * sdev)27*4882a593Smuzhiyun static inline int snd_sof_probe(struct snd_sof_dev *sdev)
28*4882a593Smuzhiyun {
29*4882a593Smuzhiyun 	return sof_ops(sdev)->probe(sdev);
30*4882a593Smuzhiyun }
31*4882a593Smuzhiyun 
snd_sof_remove(struct snd_sof_dev * sdev)32*4882a593Smuzhiyun static inline int snd_sof_remove(struct snd_sof_dev *sdev)
33*4882a593Smuzhiyun {
34*4882a593Smuzhiyun 	if (sof_ops(sdev)->remove)
35*4882a593Smuzhiyun 		return sof_ops(sdev)->remove(sdev);
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun 	return 0;
38*4882a593Smuzhiyun }
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun /* control */
41*4882a593Smuzhiyun 
42*4882a593Smuzhiyun /*
43*4882a593Smuzhiyun  * snd_sof_dsp_run returns the core mask of the cores that are available
44*4882a593Smuzhiyun  * after successful fw boot
45*4882a593Smuzhiyun  */
snd_sof_dsp_run(struct snd_sof_dev * sdev)46*4882a593Smuzhiyun static inline int snd_sof_dsp_run(struct snd_sof_dev *sdev)
47*4882a593Smuzhiyun {
48*4882a593Smuzhiyun 	return sof_ops(sdev)->run(sdev);
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun 
snd_sof_dsp_stall(struct snd_sof_dev * sdev)51*4882a593Smuzhiyun static inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	if (sof_ops(sdev)->stall)
54*4882a593Smuzhiyun 		return sof_ops(sdev)->stall(sdev);
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	return 0;
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun 
snd_sof_dsp_reset(struct snd_sof_dev * sdev)59*4882a593Smuzhiyun static inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev)
60*4882a593Smuzhiyun {
61*4882a593Smuzhiyun 	if (sof_ops(sdev)->reset)
62*4882a593Smuzhiyun 		return sof_ops(sdev)->reset(sdev);
63*4882a593Smuzhiyun 
64*4882a593Smuzhiyun 	return 0;
65*4882a593Smuzhiyun }
66*4882a593Smuzhiyun 
67*4882a593Smuzhiyun /* dsp core power up/power down */
snd_sof_dsp_core_power_up(struct snd_sof_dev * sdev,unsigned int core_mask)68*4882a593Smuzhiyun static inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev,
69*4882a593Smuzhiyun 					    unsigned int core_mask)
70*4882a593Smuzhiyun {
71*4882a593Smuzhiyun 	if (sof_ops(sdev)->core_power_up)
72*4882a593Smuzhiyun 		return sof_ops(sdev)->core_power_up(sdev, core_mask);
73*4882a593Smuzhiyun 
74*4882a593Smuzhiyun 	return 0;
75*4882a593Smuzhiyun }
76*4882a593Smuzhiyun 
snd_sof_dsp_core_power_down(struct snd_sof_dev * sdev,unsigned int core_mask)77*4882a593Smuzhiyun static inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev,
78*4882a593Smuzhiyun 					      unsigned int core_mask)
79*4882a593Smuzhiyun {
80*4882a593Smuzhiyun 	if (sof_ops(sdev)->core_power_down)
81*4882a593Smuzhiyun 		return sof_ops(sdev)->core_power_down(sdev, core_mask);
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	return 0;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun /* pre/post fw load */
snd_sof_dsp_pre_fw_run(struct snd_sof_dev * sdev)87*4882a593Smuzhiyun static inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev)
88*4882a593Smuzhiyun {
89*4882a593Smuzhiyun 	if (sof_ops(sdev)->pre_fw_run)
90*4882a593Smuzhiyun 		return sof_ops(sdev)->pre_fw_run(sdev);
91*4882a593Smuzhiyun 
92*4882a593Smuzhiyun 	return 0;
93*4882a593Smuzhiyun }
94*4882a593Smuzhiyun 
snd_sof_dsp_post_fw_run(struct snd_sof_dev * sdev)95*4882a593Smuzhiyun static inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev)
96*4882a593Smuzhiyun {
97*4882a593Smuzhiyun 	if (sof_ops(sdev)->post_fw_run)
98*4882a593Smuzhiyun 		return sof_ops(sdev)->post_fw_run(sdev);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	return 0;
101*4882a593Smuzhiyun }
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun /* misc */
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun /**
106*4882a593Smuzhiyun  * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index
107*4882a593Smuzhiyun  *
108*4882a593Smuzhiyun  * @sdev: sof device
109*4882a593Smuzhiyun  * @type: section type as described by snd_sof_fw_blk_type
110*4882a593Smuzhiyun  *
111*4882a593Smuzhiyun  * Returns the corresponding BAR index (a positive integer) or -EINVAL
112*4882a593Smuzhiyun  * in case there is no mapping
113*4882a593Smuzhiyun  */
snd_sof_dsp_get_bar_index(struct snd_sof_dev * sdev,u32 type)114*4882a593Smuzhiyun static inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun 	if (sof_ops(sdev)->get_bar_index)
117*4882a593Smuzhiyun 		return sof_ops(sdev)->get_bar_index(sdev, type);
118*4882a593Smuzhiyun 
119*4882a593Smuzhiyun 	return sdev->mmio_bar;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun 
snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev * sdev)122*4882a593Smuzhiyun static inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
123*4882a593Smuzhiyun {
124*4882a593Smuzhiyun 	if (sof_ops(sdev)->get_mailbox_offset)
125*4882a593Smuzhiyun 		return sof_ops(sdev)->get_mailbox_offset(sdev);
126*4882a593Smuzhiyun 
127*4882a593Smuzhiyun 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
128*4882a593Smuzhiyun 	return -ENOTSUPP;
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
snd_sof_dsp_get_window_offset(struct snd_sof_dev * sdev,u32 id)131*4882a593Smuzhiyun static inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
132*4882a593Smuzhiyun 						u32 id)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	if (sof_ops(sdev)->get_window_offset)
135*4882a593Smuzhiyun 		return sof_ops(sdev)->get_window_offset(sdev, id);
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
138*4882a593Smuzhiyun 	return -ENOTSUPP;
139*4882a593Smuzhiyun }
140*4882a593Smuzhiyun /* power management */
snd_sof_dsp_resume(struct snd_sof_dev * sdev)141*4882a593Smuzhiyun static inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
142*4882a593Smuzhiyun {
143*4882a593Smuzhiyun 	if (sof_ops(sdev)->resume)
144*4882a593Smuzhiyun 		return sof_ops(sdev)->resume(sdev);
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun 	return 0;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun 
snd_sof_dsp_suspend(struct snd_sof_dev * sdev,u32 target_state)149*4882a593Smuzhiyun static inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev,
150*4882a593Smuzhiyun 				      u32 target_state)
151*4882a593Smuzhiyun {
152*4882a593Smuzhiyun 	if (sof_ops(sdev)->suspend)
153*4882a593Smuzhiyun 		return sof_ops(sdev)->suspend(sdev, target_state);
154*4882a593Smuzhiyun 
155*4882a593Smuzhiyun 	return 0;
156*4882a593Smuzhiyun }
157*4882a593Smuzhiyun 
snd_sof_dsp_runtime_resume(struct snd_sof_dev * sdev)158*4882a593Smuzhiyun static inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev)
159*4882a593Smuzhiyun {
160*4882a593Smuzhiyun 	if (sof_ops(sdev)->runtime_resume)
161*4882a593Smuzhiyun 		return sof_ops(sdev)->runtime_resume(sdev);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	return 0;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun 
snd_sof_dsp_runtime_suspend(struct snd_sof_dev * sdev)166*4882a593Smuzhiyun static inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun 	if (sof_ops(sdev)->runtime_suspend)
169*4882a593Smuzhiyun 		return sof_ops(sdev)->runtime_suspend(sdev);
170*4882a593Smuzhiyun 
171*4882a593Smuzhiyun 	return 0;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun 
snd_sof_dsp_runtime_idle(struct snd_sof_dev * sdev)174*4882a593Smuzhiyun static inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev)
175*4882a593Smuzhiyun {
176*4882a593Smuzhiyun 	if (sof_ops(sdev)->runtime_idle)
177*4882a593Smuzhiyun 		return sof_ops(sdev)->runtime_idle(sdev);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	return 0;
180*4882a593Smuzhiyun }
181*4882a593Smuzhiyun 
snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev * sdev)182*4882a593Smuzhiyun static inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev)
183*4882a593Smuzhiyun {
184*4882a593Smuzhiyun 	if (sof_ops(sdev)->set_hw_params_upon_resume)
185*4882a593Smuzhiyun 		return sof_ops(sdev)->set_hw_params_upon_resume(sdev);
186*4882a593Smuzhiyun 	return 0;
187*4882a593Smuzhiyun }
188*4882a593Smuzhiyun 
snd_sof_dsp_set_clk(struct snd_sof_dev * sdev,u32 freq)189*4882a593Smuzhiyun static inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq)
190*4882a593Smuzhiyun {
191*4882a593Smuzhiyun 	if (sof_ops(sdev)->set_clk)
192*4882a593Smuzhiyun 		return sof_ops(sdev)->set_clk(sdev, freq);
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	return 0;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun static inline int
snd_sof_dsp_set_power_state(struct snd_sof_dev * sdev,const struct sof_dsp_power_state * target_state)198*4882a593Smuzhiyun snd_sof_dsp_set_power_state(struct snd_sof_dev *sdev,
199*4882a593Smuzhiyun 			    const struct sof_dsp_power_state *target_state)
200*4882a593Smuzhiyun {
201*4882a593Smuzhiyun 	if (sof_ops(sdev)->set_power_state)
202*4882a593Smuzhiyun 		return sof_ops(sdev)->set_power_state(sdev, target_state);
203*4882a593Smuzhiyun 
204*4882a593Smuzhiyun 	/* D0 substate is not supported, do nothing here. */
205*4882a593Smuzhiyun 	return 0;
206*4882a593Smuzhiyun }
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun /* debug */
snd_sof_dsp_dbg_dump(struct snd_sof_dev * sdev,u32 flags)209*4882a593Smuzhiyun static inline void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags)
210*4882a593Smuzhiyun {
211*4882a593Smuzhiyun 	if (sof_ops(sdev)->dbg_dump)
212*4882a593Smuzhiyun 		return sof_ops(sdev)->dbg_dump(sdev, flags);
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun 
snd_sof_ipc_dump(struct snd_sof_dev * sdev)215*4882a593Smuzhiyun static inline void snd_sof_ipc_dump(struct snd_sof_dev *sdev)
216*4882a593Smuzhiyun {
217*4882a593Smuzhiyun 	if (sof_ops(sdev)->ipc_dump)
218*4882a593Smuzhiyun 		return sof_ops(sdev)->ipc_dump(sdev);
219*4882a593Smuzhiyun }
220*4882a593Smuzhiyun 
221*4882a593Smuzhiyun /* register IO */
snd_sof_dsp_write(struct snd_sof_dev * sdev,u32 bar,u32 offset,u32 value)222*4882a593Smuzhiyun static inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar,
223*4882a593Smuzhiyun 				     u32 offset, u32 value)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun 	if (sof_ops(sdev)->write) {
226*4882a593Smuzhiyun 		sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value);
227*4882a593Smuzhiyun 		return;
228*4882a593Smuzhiyun 	}
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun 
snd_sof_dsp_write64(struct snd_sof_dev * sdev,u32 bar,u32 offset,u64 value)233*4882a593Smuzhiyun static inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar,
234*4882a593Smuzhiyun 				       u32 offset, u64 value)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun 	if (sof_ops(sdev)->write64) {
237*4882a593Smuzhiyun 		sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value);
238*4882a593Smuzhiyun 		return;
239*4882a593Smuzhiyun 	}
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun 	dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__);
242*4882a593Smuzhiyun }
243*4882a593Smuzhiyun 
snd_sof_dsp_read(struct snd_sof_dev * sdev,u32 bar,u32 offset)244*4882a593Smuzhiyun static inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar,
245*4882a593Smuzhiyun 				   u32 offset)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun 	if (sof_ops(sdev)->read)
248*4882a593Smuzhiyun 		return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset);
249*4882a593Smuzhiyun 
250*4882a593Smuzhiyun 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
251*4882a593Smuzhiyun 	return -ENOTSUPP;
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun 
snd_sof_dsp_read64(struct snd_sof_dev * sdev,u32 bar,u32 offset)254*4882a593Smuzhiyun static inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar,
255*4882a593Smuzhiyun 				     u32 offset)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun 	if (sof_ops(sdev)->read64)
258*4882a593Smuzhiyun 		return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset);
259*4882a593Smuzhiyun 
260*4882a593Smuzhiyun 	dev_err(sdev->dev, "error: %s not defined\n", __func__);
261*4882a593Smuzhiyun 	return -ENOTSUPP;
262*4882a593Smuzhiyun }
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun /* block IO */
snd_sof_dsp_block_read(struct snd_sof_dev * sdev,u32 bar,u32 offset,void * dest,size_t bytes)265*4882a593Smuzhiyun static inline void snd_sof_dsp_block_read(struct snd_sof_dev *sdev, u32 bar,
266*4882a593Smuzhiyun 					  u32 offset, void *dest, size_t bytes)
267*4882a593Smuzhiyun {
268*4882a593Smuzhiyun 	sof_ops(sdev)->block_read(sdev, bar, offset, dest, bytes);
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun 
snd_sof_dsp_block_write(struct snd_sof_dev * sdev,u32 bar,u32 offset,void * src,size_t bytes)271*4882a593Smuzhiyun static inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar,
272*4882a593Smuzhiyun 					   u32 offset, void *src, size_t bytes)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun 	sof_ops(sdev)->block_write(sdev, bar, offset, src, bytes);
275*4882a593Smuzhiyun }
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun /* ipc */
snd_sof_dsp_send_msg(struct snd_sof_dev * sdev,struct snd_sof_ipc_msg * msg)278*4882a593Smuzhiyun static inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev,
279*4882a593Smuzhiyun 				       struct snd_sof_ipc_msg *msg)
280*4882a593Smuzhiyun {
281*4882a593Smuzhiyun 	return sof_ops(sdev)->send_msg(sdev, msg);
282*4882a593Smuzhiyun }
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun /* host DMA trace */
snd_sof_dma_trace_init(struct snd_sof_dev * sdev,u32 * stream_tag)285*4882a593Smuzhiyun static inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev,
286*4882a593Smuzhiyun 					 u32 *stream_tag)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun 	if (sof_ops(sdev)->trace_init)
289*4882a593Smuzhiyun 		return sof_ops(sdev)->trace_init(sdev, stream_tag);
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun 	return 0;
292*4882a593Smuzhiyun }
293*4882a593Smuzhiyun 
snd_sof_dma_trace_release(struct snd_sof_dev * sdev)294*4882a593Smuzhiyun static inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev)
295*4882a593Smuzhiyun {
296*4882a593Smuzhiyun 	if (sof_ops(sdev)->trace_release)
297*4882a593Smuzhiyun 		return sof_ops(sdev)->trace_release(sdev);
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun 	return 0;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun 
snd_sof_dma_trace_trigger(struct snd_sof_dev * sdev,int cmd)302*4882a593Smuzhiyun static inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	if (sof_ops(sdev)->trace_trigger)
305*4882a593Smuzhiyun 		return sof_ops(sdev)->trace_trigger(sdev, cmd);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	return 0;
308*4882a593Smuzhiyun }
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun /* host PCM ops */
311*4882a593Smuzhiyun static inline int
snd_sof_pcm_platform_open(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream)312*4882a593Smuzhiyun snd_sof_pcm_platform_open(struct snd_sof_dev *sdev,
313*4882a593Smuzhiyun 			  struct snd_pcm_substream *substream)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_open)
316*4882a593Smuzhiyun 		return sof_ops(sdev)->pcm_open(sdev, substream);
317*4882a593Smuzhiyun 
318*4882a593Smuzhiyun 	return 0;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun /* disconnect pcm substream to a host stream */
322*4882a593Smuzhiyun static inline int
snd_sof_pcm_platform_close(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream)323*4882a593Smuzhiyun snd_sof_pcm_platform_close(struct snd_sof_dev *sdev,
324*4882a593Smuzhiyun 			   struct snd_pcm_substream *substream)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_close)
327*4882a593Smuzhiyun 		return sof_ops(sdev)->pcm_close(sdev, substream);
328*4882a593Smuzhiyun 
329*4882a593Smuzhiyun 	return 0;
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun /* host stream hw params */
333*4882a593Smuzhiyun static inline int
snd_sof_pcm_platform_hw_params(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream,struct snd_pcm_hw_params * params,struct sof_ipc_stream_params * ipc_params)334*4882a593Smuzhiyun snd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
335*4882a593Smuzhiyun 			       struct snd_pcm_substream *substream,
336*4882a593Smuzhiyun 			       struct snd_pcm_hw_params *params,
337*4882a593Smuzhiyun 			       struct sof_ipc_stream_params *ipc_params)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params)
340*4882a593Smuzhiyun 		return sof_ops(sdev)->pcm_hw_params(sdev, substream,
341*4882a593Smuzhiyun 						    params, ipc_params);
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	return 0;
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun 
346*4882a593Smuzhiyun /* host stream hw free */
347*4882a593Smuzhiyun static inline int
snd_sof_pcm_platform_hw_free(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream)348*4882a593Smuzhiyun snd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,
349*4882a593Smuzhiyun 			     struct snd_pcm_substream *substream)
350*4882a593Smuzhiyun {
351*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free)
352*4882a593Smuzhiyun 		return sof_ops(sdev)->pcm_hw_free(sdev, substream);
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 	return 0;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun /* host stream trigger */
358*4882a593Smuzhiyun static inline int
snd_sof_pcm_platform_trigger(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream,int cmd)359*4882a593Smuzhiyun snd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev,
360*4882a593Smuzhiyun 			     struct snd_pcm_substream *substream, int cmd)
361*4882a593Smuzhiyun {
362*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger)
363*4882a593Smuzhiyun 		return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd);
364*4882a593Smuzhiyun 
365*4882a593Smuzhiyun 	return 0;
366*4882a593Smuzhiyun }
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun /* host DSP message data */
snd_sof_ipc_msg_data(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream,void * p,size_t sz)369*4882a593Smuzhiyun static inline void snd_sof_ipc_msg_data(struct snd_sof_dev *sdev,
370*4882a593Smuzhiyun 					struct snd_pcm_substream *substream,
371*4882a593Smuzhiyun 					void *p, size_t sz)
372*4882a593Smuzhiyun {
373*4882a593Smuzhiyun 	sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz);
374*4882a593Smuzhiyun }
375*4882a593Smuzhiyun 
376*4882a593Smuzhiyun /* host configure DSP HW parameters */
377*4882a593Smuzhiyun static inline int
snd_sof_ipc_pcm_params(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream,const struct sof_ipc_pcm_params_reply * reply)378*4882a593Smuzhiyun snd_sof_ipc_pcm_params(struct snd_sof_dev *sdev,
379*4882a593Smuzhiyun 		       struct snd_pcm_substream *substream,
380*4882a593Smuzhiyun 		       const struct sof_ipc_pcm_params_reply *reply)
381*4882a593Smuzhiyun {
382*4882a593Smuzhiyun 	return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply);
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun 
385*4882a593Smuzhiyun /* host stream pointer */
386*4882a593Smuzhiyun static inline snd_pcm_uframes_t
snd_sof_pcm_platform_pointer(struct snd_sof_dev * sdev,struct snd_pcm_substream * substream)387*4882a593Smuzhiyun snd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev,
388*4882a593Smuzhiyun 			     struct snd_pcm_substream *substream)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer)
391*4882a593Smuzhiyun 		return sof_ops(sdev)->pcm_pointer(sdev, substream);
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	return 0;
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES)
397*4882a593Smuzhiyun static inline int
snd_sof_probe_compr_assign(struct snd_sof_dev * sdev,struct snd_compr_stream * cstream,struct snd_soc_dai * dai)398*4882a593Smuzhiyun snd_sof_probe_compr_assign(struct snd_sof_dev *sdev,
399*4882a593Smuzhiyun 		struct snd_compr_stream *cstream, struct snd_soc_dai *dai)
400*4882a593Smuzhiyun {
401*4882a593Smuzhiyun 	return sof_ops(sdev)->probe_assign(sdev, cstream, dai);
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun static inline int
snd_sof_probe_compr_free(struct snd_sof_dev * sdev,struct snd_compr_stream * cstream,struct snd_soc_dai * dai)405*4882a593Smuzhiyun snd_sof_probe_compr_free(struct snd_sof_dev *sdev,
406*4882a593Smuzhiyun 		struct snd_compr_stream *cstream, struct snd_soc_dai *dai)
407*4882a593Smuzhiyun {
408*4882a593Smuzhiyun 	return sof_ops(sdev)->probe_free(sdev, cstream, dai);
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun 
411*4882a593Smuzhiyun static inline int
snd_sof_probe_compr_set_params(struct snd_sof_dev * sdev,struct snd_compr_stream * cstream,struct snd_compr_params * params,struct snd_soc_dai * dai)412*4882a593Smuzhiyun snd_sof_probe_compr_set_params(struct snd_sof_dev *sdev,
413*4882a593Smuzhiyun 		struct snd_compr_stream *cstream,
414*4882a593Smuzhiyun 		struct snd_compr_params *params, struct snd_soc_dai *dai)
415*4882a593Smuzhiyun {
416*4882a593Smuzhiyun 	return sof_ops(sdev)->probe_set_params(sdev, cstream, params, dai);
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun 
419*4882a593Smuzhiyun static inline int
snd_sof_probe_compr_trigger(struct snd_sof_dev * sdev,struct snd_compr_stream * cstream,int cmd,struct snd_soc_dai * dai)420*4882a593Smuzhiyun snd_sof_probe_compr_trigger(struct snd_sof_dev *sdev,
421*4882a593Smuzhiyun 		struct snd_compr_stream *cstream, int cmd,
422*4882a593Smuzhiyun 		struct snd_soc_dai *dai)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun 	return sof_ops(sdev)->probe_trigger(sdev, cstream, cmd, dai);
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun static inline int
snd_sof_probe_compr_pointer(struct snd_sof_dev * sdev,struct snd_compr_stream * cstream,struct snd_compr_tstamp * tstamp,struct snd_soc_dai * dai)428*4882a593Smuzhiyun snd_sof_probe_compr_pointer(struct snd_sof_dev *sdev,
429*4882a593Smuzhiyun 		struct snd_compr_stream *cstream,
430*4882a593Smuzhiyun 		struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai)
431*4882a593Smuzhiyun {
432*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->probe_pointer)
433*4882a593Smuzhiyun 		return sof_ops(sdev)->probe_pointer(sdev, cstream, tstamp, dai);
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 	return 0;
436*4882a593Smuzhiyun }
437*4882a593Smuzhiyun #endif
438*4882a593Smuzhiyun 
439*4882a593Smuzhiyun /* machine driver */
440*4882a593Smuzhiyun static inline int
snd_sof_machine_register(struct snd_sof_dev * sdev,void * pdata)441*4882a593Smuzhiyun snd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
442*4882a593Smuzhiyun {
443*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->machine_register)
444*4882a593Smuzhiyun 		return sof_ops(sdev)->machine_register(sdev, pdata);
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun 	return 0;
447*4882a593Smuzhiyun }
448*4882a593Smuzhiyun 
449*4882a593Smuzhiyun static inline void
snd_sof_machine_unregister(struct snd_sof_dev * sdev,void * pdata)450*4882a593Smuzhiyun snd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
451*4882a593Smuzhiyun {
452*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister)
453*4882a593Smuzhiyun 		sof_ops(sdev)->machine_unregister(sdev, pdata);
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun 
456*4882a593Smuzhiyun static inline void
snd_sof_machine_select(struct snd_sof_dev * sdev)457*4882a593Smuzhiyun snd_sof_machine_select(struct snd_sof_dev *sdev)
458*4882a593Smuzhiyun {
459*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->machine_select)
460*4882a593Smuzhiyun 		sof_ops(sdev)->machine_select(sdev);
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun static inline void
snd_sof_set_mach_params(const struct snd_soc_acpi_mach * mach,struct device * dev)464*4882a593Smuzhiyun snd_sof_set_mach_params(const struct snd_soc_acpi_mach *mach,
465*4882a593Smuzhiyun 			struct device *dev)
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun 	struct snd_sof_dev *sdev = dev_get_drvdata(dev);
468*4882a593Smuzhiyun 
469*4882a593Smuzhiyun 	if (sof_ops(sdev) && sof_ops(sdev)->set_mach_params)
470*4882a593Smuzhiyun 		sof_ops(sdev)->set_mach_params(mach, dev);
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun static inline const struct snd_sof_dsp_ops
sof_get_ops(const struct sof_dev_desc * d,const struct sof_ops_table mach_ops[],int asize)474*4882a593Smuzhiyun *sof_get_ops(const struct sof_dev_desc *d,
475*4882a593Smuzhiyun 	     const struct sof_ops_table mach_ops[], int asize)
476*4882a593Smuzhiyun {
477*4882a593Smuzhiyun 	int i;
478*4882a593Smuzhiyun 
479*4882a593Smuzhiyun 	for (i = 0; i < asize; i++) {
480*4882a593Smuzhiyun 		if (d == mach_ops[i].desc)
481*4882a593Smuzhiyun 			return mach_ops[i].ops;
482*4882a593Smuzhiyun 	}
483*4882a593Smuzhiyun 
484*4882a593Smuzhiyun 	/* not found */
485*4882a593Smuzhiyun 	return NULL;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun /**
489*4882a593Smuzhiyun  * snd_sof_dsp_register_poll_timeout - Periodically poll an address
490*4882a593Smuzhiyun  * until a condition is met or a timeout occurs
491*4882a593Smuzhiyun  * @op: accessor function (takes @addr as its only argument)
492*4882a593Smuzhiyun  * @addr: Address to poll
493*4882a593Smuzhiyun  * @val: Variable to read the value into
494*4882a593Smuzhiyun  * @cond: Break condition (usually involving @val)
495*4882a593Smuzhiyun  * @sleep_us: Maximum time to sleep between reads in us (0
496*4882a593Smuzhiyun  *            tight-loops).  Should be less than ~20ms since usleep_range
497*4882a593Smuzhiyun  *            is used (see Documentation/timers/timers-howto.rst).
498*4882a593Smuzhiyun  * @timeout_us: Timeout in us, 0 means never timeout
499*4882a593Smuzhiyun  *
500*4882a593Smuzhiyun  * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
501*4882a593Smuzhiyun  * case, the last read value at @addr is stored in @val. Must not
502*4882a593Smuzhiyun  * be called from atomic context if sleep_us or timeout_us are used.
503*4882a593Smuzhiyun  *
504*4882a593Smuzhiyun  * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
505*4882a593Smuzhiyun  */
506*4882a593Smuzhiyun #define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \
507*4882a593Smuzhiyun ({ \
508*4882a593Smuzhiyun 	u64 __timeout_us = (timeout_us); \
509*4882a593Smuzhiyun 	unsigned long __sleep_us = (sleep_us); \
510*4882a593Smuzhiyun 	ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
511*4882a593Smuzhiyun 	might_sleep_if((__sleep_us) != 0); \
512*4882a593Smuzhiyun 	for (;;) {							\
513*4882a593Smuzhiyun 		(val) = snd_sof_dsp_read(sdev, bar, offset);		\
514*4882a593Smuzhiyun 		if (cond) { \
515*4882a593Smuzhiyun 			dev_dbg(sdev->dev, \
516*4882a593Smuzhiyun 				"FW Poll Status: reg=%#x successful\n", (val)); \
517*4882a593Smuzhiyun 			break; \
518*4882a593Smuzhiyun 		} \
519*4882a593Smuzhiyun 		if (__timeout_us && \
520*4882a593Smuzhiyun 		    ktime_compare(ktime_get(), __timeout) > 0) { \
521*4882a593Smuzhiyun 			(val) = snd_sof_dsp_read(sdev, bar, offset); \
522*4882a593Smuzhiyun 			dev_dbg(sdev->dev, \
523*4882a593Smuzhiyun 				"FW Poll Status: reg=%#x timedout\n", (val)); \
524*4882a593Smuzhiyun 			break; \
525*4882a593Smuzhiyun 		} \
526*4882a593Smuzhiyun 		if (__sleep_us) \
527*4882a593Smuzhiyun 			usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
528*4882a593Smuzhiyun 	} \
529*4882a593Smuzhiyun 	(cond) ? 0 : -ETIMEDOUT; \
530*4882a593Smuzhiyun })
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun /* This is for registers bits with attribute RWC */
533*4882a593Smuzhiyun bool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset,
534*4882a593Smuzhiyun 			     u32 mask, u32 value);
535*4882a593Smuzhiyun 
536*4882a593Smuzhiyun bool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar,
537*4882a593Smuzhiyun 				      u32 offset, u32 mask, u32 value);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun bool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar,
540*4882a593Smuzhiyun 					u32 offset, u64 mask, u64 value);
541*4882a593Smuzhiyun 
542*4882a593Smuzhiyun bool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset,
543*4882a593Smuzhiyun 			     u32 mask, u32 value);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun bool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar,
546*4882a593Smuzhiyun 			       u32 offset, u64 mask, u64 value);
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun void snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
549*4882a593Smuzhiyun 				    u32 offset, u32 mask, u32 value);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun int snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
552*4882a593Smuzhiyun 			      u32 mask, u32 target, u32 timeout_ms,
553*4882a593Smuzhiyun 			      u32 interval_us);
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun void snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset);
556*4882a593Smuzhiyun #endif
557