blob: 481dfe4ee2d046cc284ae5fccb6da6a846815382 [file] [log] [blame]
Liam Girdwoodc16211d2019-04-12 11:05:06 -05001/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
2/*
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.
5 *
6 * Copyright(c) 2018 Intel Corporation. All rights reserved.
7 *
8 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 */
10
11#ifndef __SOUND_SOC_SOF_PRIV_H
12#define __SOUND_SOC_SOF_PRIV_H
13
14#include <linux/device.h>
15
16#include <sound/hdaudio.h>
17#include <sound/soc.h>
Jaska Uimonen5d430012019-10-08 11:44:43 -050018#include <sound/control.h>
Liam Girdwoodc16211d2019-04-12 11:05:06 -050019
20#include <sound/sof.h>
21#include <sound/sof/stream.h> /* needs to be included before control.h */
22#include <sound/sof/control.h>
23#include <sound/sof/dai.h>
24#include <sound/sof/info.h>
25#include <sound/sof/pm.h>
26#include <sound/sof/topology.h>
27#include <sound/sof/trace.h>
28
29#include <uapi/sound/sof/fw.h>
30
31/* debug flags */
Pierre-Louis Bossart2ab4c502019-09-27 15:05:28 -050032#define SOF_DBG_ENABLE_TRACE BIT(0)
33#define SOF_DBG_REGS BIT(1)
34#define SOF_DBG_MBOX BIT(2)
35#define SOF_DBG_TEXT BIT(3)
36#define SOF_DBG_PCI BIT(4)
Liam Girdwood9a065082019-09-27 15:05:29 -050037#define SOF_DBG_RETAIN_CTX BIT(5) /* prevent DSP D3 on FW exception */
Pierre-Louis Bossart2ab4c502019-09-27 15:05:28 -050038
39/* global debug state set by SOF_DBG_ flags */
40extern int sof_core_debug;
Liam Girdwoodc16211d2019-04-12 11:05:06 -050041
42/* max BARs mmaped devices can use */
43#define SND_SOF_BARS 8
44
45/* time in ms for runtime suspend delay */
46#define SND_SOF_SUSPEND_DELAY_MS 2000
47
48/* DMA buffer size for trace */
49#define DMA_BUF_SIZE_FOR_TRACE (PAGE_SIZE * 16)
50
51/* max number of FE PCMs before BEs */
52#define SOF_BE_PCM_BASE 16
53
54#define SOF_IPC_DSP_REPLY 0
55#define SOF_IPC_HOST_REPLY 1
56
57/* convenience constructor for DAI driver streams */
58#define SOF_DAI_STREAM(sname, scmin, scmax, srates, sfmt) \
59 {.stream_name = sname, .channels_min = scmin, .channels_max = scmax, \
60 .rates = srates, .formats = sfmt}
61
62#define SOF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | \
63 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_FLOAT)
64
Ranjani Sridharan091c12e2019-06-03 11:18:20 -050065#define ENABLE_DEBUGFS_CACHEBUF \
66 (IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_ENABLE_DEBUGFS_CACHE) || \
67 IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_IPC_FLOOD_TEST))
68
Ranjani Sridharanbdf4ad3f2019-06-12 12:23:36 -050069#define DMA_CHAN_INVALID 0xFFFFFFFF
70
Keyon Jie4c190302019-10-25 17:40:57 -050071/* DSP D0ix sub-state */
72enum sof_d0_substate {
73 SOF_DSP_D0I0 = 0, /* DSP default D0 substate */
74 SOF_DSP_D0I3, /* DSP D0i3(low power) substate*/
75};
76
Liam Girdwoodc16211d2019-04-12 11:05:06 -050077struct snd_sof_dev;
78struct snd_sof_ipc_msg;
79struct snd_sof_ipc;
80struct snd_sof_debugfs_map;
81struct snd_soc_tplg_ops;
82struct snd_soc_component;
83struct snd_sof_pdata;
84
85/*
86 * SOF DSP HW abstraction operations.
87 * Used to abstract DSP HW architecture and any IO busses between host CPU
88 * and DSP device(s).
89 */
90struct snd_sof_dsp_ops {
91
92 /* probe and remove */
93 int (*probe)(struct snd_sof_dev *sof_dev); /* mandatory */
94 int (*remove)(struct snd_sof_dev *sof_dev); /* optional */
95
96 /* DSP core boot / reset */
97 int (*run)(struct snd_sof_dev *sof_dev); /* mandatory */
98 int (*stall)(struct snd_sof_dev *sof_dev); /* optional */
99 int (*reset)(struct snd_sof_dev *sof_dev); /* optional */
100 int (*core_power_up)(struct snd_sof_dev *sof_dev,
101 unsigned int core_mask); /* optional */
102 int (*core_power_down)(struct snd_sof_dev *sof_dev,
103 unsigned int core_mask); /* optional */
104
105 /*
106 * Register IO: only used by respective drivers themselves,
107 * TODO: consider removing these operations and calling respective
108 * implementations directly
109 */
110 void (*write)(struct snd_sof_dev *sof_dev, void __iomem *addr,
111 u32 value); /* optional */
112 u32 (*read)(struct snd_sof_dev *sof_dev,
113 void __iomem *addr); /* optional */
114 void (*write64)(struct snd_sof_dev *sof_dev, void __iomem *addr,
115 u64 value); /* optional */
116 u64 (*read64)(struct snd_sof_dev *sof_dev,
117 void __iomem *addr); /* optional */
118
119 /* memcpy IO */
120 void (*block_read)(struct snd_sof_dev *sof_dev, u32 bar,
121 u32 offset, void *dest,
122 size_t size); /* mandatory */
123 void (*block_write)(struct snd_sof_dev *sof_dev, u32 bar,
124 u32 offset, void *src,
125 size_t size); /* mandatory */
126
127 /* doorbell */
128 irqreturn_t (*irq_handler)(int irq, void *context); /* optional */
129 irqreturn_t (*irq_thread)(int irq, void *context); /* optional */
130
131 /* ipc */
132 int (*send_msg)(struct snd_sof_dev *sof_dev,
133 struct snd_sof_ipc_msg *msg); /* mandatory */
134
135 /* FW loading */
136 int (*load_firmware)(struct snd_sof_dev *sof_dev); /* mandatory */
137 int (*load_module)(struct snd_sof_dev *sof_dev,
138 struct snd_sof_mod_hdr *hdr); /* optional */
139 /*
140 * FW ready checks for ABI compatibility and creates
141 * memory windows at first boot
142 */
Ranjani Sridharan8692d492019-09-27 15:05:32 -0500143 int (*fw_ready)(struct snd_sof_dev *sdev, u32 msg_id); /* mandatory */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500144
145 /* connect pcm substream to a host stream */
146 int (*pcm_open)(struct snd_sof_dev *sdev,
147 struct snd_pcm_substream *substream); /* optional */
148 /* disconnect pcm substream to a host stream */
149 int (*pcm_close)(struct snd_sof_dev *sdev,
150 struct snd_pcm_substream *substream); /* optional */
151
152 /* host stream hw params */
153 int (*pcm_hw_params)(struct snd_sof_dev *sdev,
154 struct snd_pcm_substream *substream,
155 struct snd_pcm_hw_params *params,
156 struct sof_ipc_stream_params *ipc_params); /* optional */
157
Ranjani Sridharan93146bc2019-06-12 12:23:39 -0500158 /* host stream hw_free */
159 int (*pcm_hw_free)(struct snd_sof_dev *sdev,
160 struct snd_pcm_substream *substream); /* optional */
161
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500162 /* host stream trigger */
163 int (*pcm_trigger)(struct snd_sof_dev *sdev,
164 struct snd_pcm_substream *substream,
165 int cmd); /* optional */
166
167 /* host stream pointer */
168 snd_pcm_uframes_t (*pcm_pointer)(struct snd_sof_dev *sdev,
169 struct snd_pcm_substream *substream); /* optional */
170
171 /* host read DSP stream data */
172 void (*ipc_msg_data)(struct snd_sof_dev *sdev,
173 struct snd_pcm_substream *substream,
174 void *p, size_t sz); /* mandatory */
175
176 /* host configure DSP HW parameters */
177 int (*ipc_pcm_params)(struct snd_sof_dev *sdev,
178 struct snd_pcm_substream *substream,
179 const struct sof_ipc_pcm_params_reply *reply); /* mandatory */
180
181 /* pre/post firmware run */
182 int (*pre_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
183 int (*post_fw_run)(struct snd_sof_dev *sof_dev); /* optional */
184
185 /* DSP PM */
Fred Oh1c38c922019-07-22 09:13:50 -0500186 int (*suspend)(struct snd_sof_dev *sof_dev); /* optional */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500187 int (*resume)(struct snd_sof_dev *sof_dev); /* optional */
Fred Oh1c38c922019-07-22 09:13:50 -0500188 int (*runtime_suspend)(struct snd_sof_dev *sof_dev); /* optional */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500189 int (*runtime_resume)(struct snd_sof_dev *sof_dev); /* optional */
Kai Vehmanen62fde972019-07-02 16:24:27 +0300190 int (*runtime_idle)(struct snd_sof_dev *sof_dev); /* optional */
Ranjani Sridharan7077a072019-06-12 12:23:38 -0500191 int (*set_hw_params_upon_resume)(struct snd_sof_dev *sdev); /* optional */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500192
193 /* DSP clocking */
194 int (*set_clk)(struct snd_sof_dev *sof_dev, u32 freq); /* optional */
195
196 /* debug */
197 const struct snd_sof_debugfs_map *debug_map; /* optional */
198 int debug_map_count; /* optional */
199 void (*dbg_dump)(struct snd_sof_dev *sof_dev,
200 u32 flags); /* optional */
Pan Xiuli5e4a27f2019-04-30 18:09:32 -0500201 void (*ipc_dump)(struct snd_sof_dev *sof_dev); /* optional */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500202
203 /* host DMA trace initialization */
204 int (*trace_init)(struct snd_sof_dev *sdev,
205 u32 *stream_tag); /* optional */
206 int (*trace_release)(struct snd_sof_dev *sdev); /* optional */
207 int (*trace_trigger)(struct snd_sof_dev *sdev,
208 int cmd); /* optional */
209
Daniel Balutace8234a2019-07-22 09:13:47 -0500210 /* misc */
211 int (*get_bar_index)(struct snd_sof_dev *sdev,
212 u32 type); /* optional */
Daniel Balutabb9c93f2019-08-07 10:01:59 -0500213 int (*get_mailbox_offset)(struct snd_sof_dev *sdev);/* mandatory for common loader code */
Daniel Balutae17422c2019-08-07 10:02:00 -0500214 int (*get_window_offset)(struct snd_sof_dev *sdev,
215 u32 id);/* mandatory for common loader code */
Daniel Balutabb9c93f2019-08-07 10:01:59 -0500216
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500217 /* DAI ops */
218 struct snd_soc_dai_driver *drv;
219 int num_drv;
Pierre-Louis Bossart27e322f2019-10-24 16:03:17 -0500220
221 /* ALSA HW info flags, will be stored in snd_pcm_runtime.hw.info */
222 u32 hw_info;
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500223};
224
225/* DSP architecture specific callbacks for oops and stack dumps */
226struct sof_arch_ops {
227 void (*dsp_oops)(struct snd_sof_dev *sdev, void *oops);
228 void (*dsp_stack)(struct snd_sof_dev *sdev, void *oops,
229 u32 *stack, u32 stack_words);
230};
231
232#define sof_arch_ops(sdev) ((sdev)->pdata->desc->arch_ops)
233
234/* DSP device HW descriptor mapping between bus ID and ops */
235struct sof_ops_table {
236 const struct sof_dev_desc *desc;
237 const struct snd_sof_dsp_ops *ops;
238};
239
240enum sof_dfsentry_type {
241 SOF_DFSENTRY_TYPE_IOMEM = 0,
242 SOF_DFSENTRY_TYPE_BUF,
243};
244
245enum sof_debugfs_access_type {
246 SOF_DEBUGFS_ACCESS_ALWAYS = 0,
247 SOF_DEBUGFS_ACCESS_D0_ONLY,
248};
249
250/* FS entry for debug files that can expose DSP memories, registers */
251struct snd_sof_dfsentry {
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500252 size_t size;
253 enum sof_dfsentry_type type;
254 /*
255 * access_type specifies if the
256 * memory -> DSP resource (memory, register etc) is always accessible
257 * or if it is accessible only when the DSP is in D0.
258 */
259 enum sof_debugfs_access_type access_type;
Ranjani Sridharan091c12e2019-06-03 11:18:20 -0500260#if ENABLE_DEBUGFS_CACHEBUF
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500261 char *cache_buf; /* buffer to cache the contents of debugfs memory */
262#endif
263 struct snd_sof_dev *sdev;
264 struct list_head list; /* list in sdev dfsentry list */
265 union {
266 void __iomem *io_mem;
267 void *buf;
268 };
269};
270
271/* Debug mapping for any DSP memory or registers that can used for debug */
272struct snd_sof_debugfs_map {
273 const char *name;
274 u32 bar;
275 u32 offset;
276 u32 size;
277 /*
278 * access_type specifies if the memory is always accessible
279 * or if it is accessible only when the DSP is in D0.
280 */
281 enum sof_debugfs_access_type access_type;
282};
283
284/* mailbox descriptor, used for host <-> DSP IPC */
285struct snd_sof_mailbox {
286 u32 offset;
287 size_t size;
288};
289
290/* IPC message descriptor for host <-> DSP IO */
291struct snd_sof_ipc_msg {
292 /* message data */
293 u32 header;
294 void *msg_data;
295 void *reply_data;
296 size_t msg_size;
297 size_t reply_size;
298 int reply_error;
299
300 wait_queue_head_t waitq;
301 bool ipc_complete;
302};
303
304/* PCM stream, mapped to FW component */
305struct snd_sof_pcm_stream {
306 u32 comp_id;
307 struct snd_dma_buffer page_table;
308 struct sof_ipc_stream_posn posn;
309 struct snd_pcm_substream *substream;
Keyon Jiee2803e62019-04-30 18:09:25 -0500310 struct work_struct period_elapsed_work;
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500311};
312
313/* ALSA SOF PCM device */
314struct snd_sof_pcm {
315 struct snd_sof_dev *sdev;
316 struct snd_soc_tplg_pcm pcm;
317 struct snd_sof_pcm_stream stream[2];
318 struct list_head list; /* list in sdev pcm list */
319 struct snd_pcm_hw_params params[2];
Kai Vehmanen04c80272019-07-22 09:13:43 -0500320 bool prepared[2]; /* PCM_PARAMS set successfully */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500321};
322
Jaska Uimonen5d430012019-10-08 11:44:43 -0500323struct snd_sof_led_control {
324 unsigned int use_led;
325 unsigned int direction;
326 unsigned int led_value;
327};
328
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500329/* ALSA SOF Kcontrol device */
330struct snd_sof_control {
331 struct snd_sof_dev *sdev;
332 int comp_id;
Zhu Yingjiangaa66fd82019-06-12 12:01:45 -0500333 int min_volume_step; /* min volume step for volume_table */
334 int max_volume_step; /* max volume step for volume_table */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500335 int num_channels;
336 u32 readback_offset; /* offset to mmaped data if used */
337 struct sof_ipc_ctrl_data *control_data;
338 u32 size; /* cdata size */
339 enum sof_ipc_ctrl_cmd cmd;
340 u32 *volume_table; /* volume table computed from tlv data*/
341
342 struct list_head list; /* list in sdev control list */
Jaska Uimonen5d430012019-10-08 11:44:43 -0500343
344 struct snd_sof_led_control led_ctl;
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500345};
346
347/* ASoC SOF DAPM widget */
348struct snd_sof_widget {
349 struct snd_sof_dev *sdev;
350 int comp_id;
351 int pipeline_id;
352 int complete;
353 int id;
354
355 struct snd_soc_dapm_widget *widget;
356 struct list_head list; /* list in sdev widget list */
357
358 void *private; /* core does not touch this */
359};
360
361/* ASoC SOF DAPM route */
362struct snd_sof_route {
363 struct snd_sof_dev *sdev;
364
365 struct snd_soc_dapm_route *route;
366 struct list_head list; /* list in sdev route list */
367
368 void *private;
369};
370
371/* ASoC DAI device */
372struct snd_sof_dai {
373 struct snd_sof_dev *sdev;
374 const char *name;
Ranjani Sridharan1b7e1952019-06-12 12:23:35 -0500375 const char *cpu_dai_name;
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500376
377 struct sof_ipc_comp_dai comp_dai;
378 struct sof_ipc_dai_config *dai_config;
379 struct list_head list; /* list in sdev dai list */
380};
381
382/*
383 * SOF Device Level.
384 */
385struct snd_sof_dev {
386 struct device *dev;
387 spinlock_t ipc_lock; /* lock for IPC users */
388 spinlock_t hw_lock; /* lock for HW IO access */
389
390 /*
391 * ASoC components. plat_drv fields are set dynamically so
392 * can't use const
393 */
394 struct snd_soc_component_driver plat_drv;
395
Keyon Jie4c190302019-10-25 17:40:57 -0500396 /* power states related */
397 enum sof_d0_substate d0_substate;
398
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500399 /* DSP firmware boot */
400 wait_queue_head_t boot_wait;
401 u32 boot_complete;
402 u32 first_boot;
403
404 /* work queue in case the probe is implemented in two steps */
405 struct work_struct probe_work;
406
407 /* DSP HW differentiation */
408 struct snd_sof_pdata *pdata;
409
410 /* IPC */
411 struct snd_sof_ipc *ipc;
412 struct snd_sof_mailbox dsp_box; /* DSP initiated IPC */
413 struct snd_sof_mailbox host_box; /* Host initiated IPC */
414 struct snd_sof_mailbox stream_box; /* Stream position update */
415 struct snd_sof_ipc_msg *msg;
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500416 int ipc_irq;
417 u32 next_comp_id; /* monotonic - reset during S3 */
418
419 /* memory bases for mmaped DSPs - set by dsp_init() */
420 void __iomem *bar[SND_SOF_BARS]; /* DSP base address */
421 int mmio_bar;
422 int mailbox_bar;
423 size_t dsp_oops_offset;
424
425 /* debug */
426 struct dentry *debugfs_root;
427 struct list_head dfsentry_list;
428
429 /* firmware loader */
430 struct snd_dma_buffer dmab;
431 struct snd_dma_buffer dmab_bdl;
432 struct sof_ipc_fw_ready fw_ready;
433 struct sof_ipc_fw_version fw_version;
434
435 /* topology */
436 struct snd_soc_tplg_ops *tplg_ops;
437 struct list_head pcm_list;
438 struct list_head kcontrol_list;
439 struct list_head widget_list;
440 struct list_head dai_list;
441 struct list_head route_list;
442 struct snd_soc_component *component;
443 u32 enabled_cores_mask; /* keep track of enabled cores */
444
445 /* FW configuration */
446 struct sof_ipc_dma_buffer_data *info_buffer;
447 struct sof_ipc_window *info_window;
448
449 /* IPC timeouts in ms */
450 int ipc_timeout;
451 int boot_timeout;
452
453 /* Wait queue for code loading */
454 wait_queue_head_t waitq;
455 int code_loading;
456
457 /* DMA for Trace */
458 struct snd_dma_buffer dmatb;
459 struct snd_dma_buffer dmatp;
460 int dma_trace_pages;
461 wait_queue_head_t trace_sleep;
462 u32 host_offset;
Pierre-Louis Bossart2ab4c502019-09-27 15:05:28 -0500463 u32 dtrace_is_supported; /* set with Kconfig or module parameter */
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500464 u32 dtrace_is_enabled;
465 u32 dtrace_error;
Kai Vehmanenec9025e2019-05-24 14:23:06 -0500466 u32 dtrace_draining;
467
Guennadi Liakhovetski672ff5e2019-07-22 09:13:57 -0500468 bool msi_enabled;
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500469
470 void *private; /* core does not touch this */
471};
472
473/*
474 * Device Level.
475 */
476
477int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data);
478int snd_sof_device_remove(struct device *dev);
479
480int snd_sof_runtime_suspend(struct device *dev);
481int snd_sof_runtime_resume(struct device *dev);
Kai Vehmanen62fde972019-07-02 16:24:27 +0300482int snd_sof_runtime_idle(struct device *dev);
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500483int snd_sof_resume(struct device *dev);
484int snd_sof_suspend(struct device *dev);
485
486void snd_sof_new_platform_drv(struct snd_sof_dev *sdev);
487
488int snd_sof_create_page_table(struct snd_sof_dev *sdev,
489 struct snd_dma_buffer *dmab,
490 unsigned char *page_table, size_t size);
491
492/*
493 * Firmware loading.
494 */
495int snd_sof_load_firmware(struct snd_sof_dev *sdev);
496int snd_sof_load_firmware_raw(struct snd_sof_dev *sdev);
497int snd_sof_load_firmware_memcpy(struct snd_sof_dev *sdev);
498int snd_sof_run_firmware(struct snd_sof_dev *sdev);
499int snd_sof_parse_module_memcpy(struct snd_sof_dev *sdev,
500 struct snd_sof_mod_hdr *module);
501void snd_sof_fw_unload(struct snd_sof_dev *sdev);
502int snd_sof_fw_parse_ext_data(struct snd_sof_dev *sdev, u32 bar, u32 offset);
503
504/*
505 * IPC low level APIs.
506 */
507struct snd_sof_ipc *snd_sof_ipc_init(struct snd_sof_dev *sdev);
508void snd_sof_ipc_free(struct snd_sof_dev *sdev);
509int snd_sof_ipc_reply(struct snd_sof_dev *sdev, u32 msg_id);
510void snd_sof_ipc_msgs_rx(struct snd_sof_dev *sdev);
511int snd_sof_ipc_stream_pcm_params(struct snd_sof_dev *sdev,
512 struct sof_ipc_pcm_params *params);
513int snd_sof_dsp_mailbox_init(struct snd_sof_dev *sdev, u32 dspbox,
514 size_t dspbox_size, u32 hostbox,
515 size_t hostbox_size);
516int snd_sof_ipc_valid(struct snd_sof_dev *sdev);
517int sof_ipc_tx_message(struct snd_sof_ipc *ipc, u32 header,
518 void *msg_data, size_t msg_bytes, void *reply_data,
519 size_t reply_bytes);
520struct snd_sof_widget *snd_sof_find_swidget(struct snd_sof_dev *sdev,
521 const char *name);
522struct snd_sof_widget *snd_sof_find_swidget_sname(struct snd_sof_dev *sdev,
523 const char *pcm_name,
524 int dir);
525struct snd_sof_dai *snd_sof_find_dai(struct snd_sof_dev *sdev,
526 const char *name);
527
528static inline
529struct snd_sof_pcm *snd_sof_find_spcm_dai(struct snd_sof_dev *sdev,
530 struct snd_soc_pcm_runtime *rtd)
531{
532 struct snd_sof_pcm *spcm = NULL;
533
534 list_for_each_entry(spcm, &sdev->pcm_list, list) {
535 if (le32_to_cpu(spcm->pcm.dai_id) == rtd->dai_link->id)
536 return spcm;
537 }
538
539 return NULL;
540}
541
542struct snd_sof_pcm *snd_sof_find_spcm_name(struct snd_sof_dev *sdev,
543 const char *name);
544struct snd_sof_pcm *snd_sof_find_spcm_comp(struct snd_sof_dev *sdev,
545 unsigned int comp_id,
546 int *direction);
547struct snd_sof_pcm *snd_sof_find_spcm_pcm_id(struct snd_sof_dev *sdev,
548 unsigned int pcm_id);
Keyon Jiee2803e62019-04-30 18:09:25 -0500549void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream);
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500550
551/*
552 * Stream IPC
553 */
554int snd_sof_ipc_stream_posn(struct snd_sof_dev *sdev,
555 struct snd_sof_pcm *spcm, int direction,
556 struct sof_ipc_stream_posn *posn);
557
558/*
559 * Mixer IPC
560 */
561int snd_sof_ipc_set_get_comp_data(struct snd_sof_ipc *ipc,
562 struct snd_sof_control *scontrol, u32 ipc_cmd,
563 enum sof_ipc_ctrl_type ctrl_type,
564 enum sof_ipc_ctrl_cmd ctrl_cmd,
565 bool send);
566
567/*
568 * Topology.
569 * There is no snd_sof_free_topology since topology components will
570 * be freed by snd_soc_unregister_component,
571 */
572int snd_sof_init_topology(struct snd_sof_dev *sdev,
573 struct snd_soc_tplg_ops *ops);
574int snd_sof_load_topology(struct snd_sof_dev *sdev, const char *file);
575int snd_sof_complete_pipeline(struct snd_sof_dev *sdev,
576 struct snd_sof_widget *swidget);
577
578int sof_load_pipeline_ipc(struct snd_sof_dev *sdev,
579 struct sof_ipc_pipe_new *pipeline,
580 struct sof_ipc_comp_reply *r);
581
582/*
583 * Trace/debug
584 */
585int snd_sof_init_trace(struct snd_sof_dev *sdev);
586void snd_sof_release_trace(struct snd_sof_dev *sdev);
587void snd_sof_free_trace(struct snd_sof_dev *sdev);
588int snd_sof_dbg_init(struct snd_sof_dev *sdev);
589void snd_sof_free_debug(struct snd_sof_dev *sdev);
590int snd_sof_debugfs_io_item(struct snd_sof_dev *sdev,
591 void __iomem *base, size_t size,
592 const char *name,
593 enum sof_debugfs_access_type access_type);
594int snd_sof_debugfs_buf_item(struct snd_sof_dev *sdev,
595 void *base, size_t size,
Ranjani Sridharan5c9714f2019-06-03 11:18:18 -0500596 const char *name, mode_t mode);
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500597int snd_sof_trace_update_pos(struct snd_sof_dev *sdev,
598 struct sof_ipc_dma_trace_posn *posn);
599void snd_sof_trace_notify_for_error(struct snd_sof_dev *sdev);
600void snd_sof_get_status(struct snd_sof_dev *sdev, u32 panic_code,
601 u32 tracep_code, void *oops,
602 struct sof_ipc_panic_info *panic_info,
603 void *stack, size_t stack_words);
604int snd_sof_init_trace_ipc(struct snd_sof_dev *sdev);
Liam Girdwood9a065082019-09-27 15:05:29 -0500605void snd_sof_handle_fw_exception(struct snd_sof_dev *sdev);
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500606
607/*
608 * Platform specific ops.
609 */
610extern struct snd_compr_ops sof_compressed_ops;
611
612/*
613 * Kcontrols.
614 */
615
616int snd_sof_volume_get(struct snd_kcontrol *kcontrol,
617 struct snd_ctl_elem_value *ucontrol);
618int snd_sof_volume_put(struct snd_kcontrol *kcontrol,
619 struct snd_ctl_elem_value *ucontrol);
620int snd_sof_switch_get(struct snd_kcontrol *kcontrol,
621 struct snd_ctl_elem_value *ucontrol);
622int snd_sof_switch_put(struct snd_kcontrol *kcontrol,
623 struct snd_ctl_elem_value *ucontrol);
624int snd_sof_enum_get(struct snd_kcontrol *kcontrol,
625 struct snd_ctl_elem_value *ucontrol);
626int snd_sof_enum_put(struct snd_kcontrol *kcontrol,
627 struct snd_ctl_elem_value *ucontrol);
628int snd_sof_bytes_get(struct snd_kcontrol *kcontrol,
629 struct snd_ctl_elem_value *ucontrol);
630int snd_sof_bytes_put(struct snd_kcontrol *kcontrol,
631 struct snd_ctl_elem_value *ucontrol);
632int snd_sof_bytes_ext_put(struct snd_kcontrol *kcontrol,
633 const unsigned int __user *binary_data,
634 unsigned int size);
635int snd_sof_bytes_ext_get(struct snd_kcontrol *kcontrol,
636 unsigned int __user *binary_data,
637 unsigned int size);
638
639/*
640 * DSP Architectures.
641 */
642static inline void sof_stack(struct snd_sof_dev *sdev, void *oops, u32 *stack,
643 u32 stack_words)
644{
645 if (sof_arch_ops(sdev)->dsp_stack)
646 sof_arch_ops(sdev)->dsp_stack(sdev, oops, stack, stack_words);
647}
648
649static inline void sof_oops(struct snd_sof_dev *sdev, void *oops)
650{
651 if (sof_arch_ops(sdev)->dsp_oops)
652 sof_arch_ops(sdev)->dsp_oops(sdev, oops);
653}
654
655extern const struct sof_arch_ops sof_xtensa_arch_ops;
656
657/*
658 * Utilities
659 */
660void sof_io_write(struct snd_sof_dev *sdev, void __iomem *addr, u32 value);
661void sof_io_write64(struct snd_sof_dev *sdev, void __iomem *addr, u64 value);
662u32 sof_io_read(struct snd_sof_dev *sdev, void __iomem *addr);
663u64 sof_io_read64(struct snd_sof_dev *sdev, void __iomem *addr);
664void sof_mailbox_write(struct snd_sof_dev *sdev, u32 offset,
665 void *message, size_t bytes);
666void sof_mailbox_read(struct snd_sof_dev *sdev, u32 offset,
667 void *message, size_t bytes);
668void sof_block_write(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *src,
669 size_t size);
670void sof_block_read(struct snd_sof_dev *sdev, u32 bar, u32 offset, void *dest,
671 size_t size);
672
Daniel Baluta83ee7ab2019-08-07 10:02:01 -0500673int sof_fw_ready(struct snd_sof_dev *sdev, u32 msg_id);
674
Liam Girdwoodc16211d2019-04-12 11:05:06 -0500675void intel_ipc_msg_data(struct snd_sof_dev *sdev,
676 struct snd_pcm_substream *substream,
677 void *p, size_t sz);
678int intel_ipc_pcm_params(struct snd_sof_dev *sdev,
679 struct snd_pcm_substream *substream,
680 const struct sof_ipc_pcm_params_reply *reply);
681
682int intel_pcm_open(struct snd_sof_dev *sdev,
683 struct snd_pcm_substream *substream);
684int intel_pcm_close(struct snd_sof_dev *sdev,
685 struct snd_pcm_substream *substream);
686
687#endif