Sound Open Firmware
Loading...
Searching...
No Matches
dai-legacy.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-3-Clause
2 *
3 * Copyright(c) 2016 Intel Corporation. All rights reserved.
4 *
5 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6 * Keyon Jie <yang.jie@linux.intel.com>
7 *
8 * Renamed from dai.h to dai-legacy.h because of Zephyr refactoring and
9 * the file content has not changed.
10 */
11
20
21#ifndef __SOF_LIB_DAI_LEGACY_H__
22#define __SOF_LIB_DAI_LEGACY_H__
23
24#include <platform/lib/dai.h>
25#include <rtos/bit.h>
26#include <sof/list.h>
27#include <sof/lib/io.h>
28#include <sof/lib/memory.h>
29#include <sof/lib/dma.h>
30#include <sof/list.h>
31#include <rtos/sof.h>
32#include <rtos/spinlock.h>
33#include <sof/trace/trace.h>
34#include <sof/ipc/topology.h>
37#include <errno.h>
38#include <stddef.h>
39#include <stdint.h>
40
41struct dai;
43
48
49#define DAI_CLOCK_IN 0
50#define DAI_CLOCK_OUT 1
51
52#define DAI_DIR_PLAYBACK 0
53#define DAI_DIR_CAPTURE 1
54
55#define DAI_NUM_SLOT_MAPS 8
56
57#define DAI_INFO_TYPE 0
58#define DAI_INFO_DMA_CAPS 1
59#define DAI_INFO_DMA_DEV 2
60
61/* DAI flags */
62
64#define DAI_FLAGS_IRQ_CB BIT(0)
65
66/* DAI get() flags */
67
69#define DAI_CREAT BIT(0)
70
81struct dai_ops {
82 int (*set_config)(struct dai *dai, struct ipc_config_dai *config,
83 const void *spec_config);
84 int (*trigger)(struct dai *dai, int cmd, int direction);
85 int (*get_hw_params)(struct dai *dai,
86 struct sof_ipc_stream_params *params, int dir);
87 int (*hw_params)(struct dai *dai, struct sof_ipc_stream_params *params);
88 int (*get_handshake)(struct dai *dai, int direction, int stream_id);
89 int (*get_fifo)(struct dai *dai, int direction, int stream_id);
90 int (*probe)(struct dai *dai);
91 int (*remove)(struct dai *dai);
92 uint32_t (*get_init_delay_ms)(struct dai *dai);
93 int (*get_fifo_depth)(struct dai *dai, int direction);
94 void (*copy)(struct dai *dai); /* Can be used by DAIs to prepare for data copying */
95};
96
97struct timestamp_cfg {
98 uint32_t walclk_rate; /* Rate in Hz, e.g. 19200000 */
99 int type; /* SSP, DMIC, HDA, etc. */
100 int direction; /* Playback, capture */
101 int index; /* For SSPx to select correct timestamp register */
102 int dma_id; /* GPDMA id*/
103 int dma_chan_index; /* Used GPDMA channel */
104 int dma_chan_count; /* Channels in single GPDMA */
105};
106
107struct timestamp_data {
108 uint64_t walclk; /* Wall clock */
109 uint64_t sample; /* Sample count */
110 uint32_t walclk_rate; /* Rate in Hz, e.g. 19200000 */
111};
112
113struct timestamp_ops {
114 int (*ts_config)(struct dai *dai, struct timestamp_cfg *cfg);
115 int (*ts_start)(struct dai *dai, struct timestamp_cfg *cfg);
116 int (*ts_stop)(struct dai *dai, struct timestamp_cfg *cfg);
117 int (*ts_get)(struct dai *dai, struct timestamp_cfg *cfg,
118 struct timestamp_data *tsd);
119};
120
121struct dai_driver {
122 uint32_t type;
123 const struct sof_uuid_entry *uid;
124 struct tr_ctx *tctx;
125 uint32_t dma_caps;
126 uint32_t dma_dev;
127 struct dai_ops ops;
128 struct timestamp_ops ts_ops;
129};
130
134struct dai_slot_map {
135 uint32_t channel;
136 uint32_t slot;
137};
138
139struct dai_plat_fifo_data {
140 uint32_t offset;
141 uint32_t width;
142 uint32_t depth;
143 uint32_t watermark;
144 uint32_t handshake;
145};
146
150struct dai_plat_data {
151 uint32_t base;
152 int irq;
153 const char *irq_name;
154 uint32_t flags;
155 struct dai_plat_fifo_data fifo[2];
156};
157
161struct llp_slot_info {
162 uint32_t node_id;
163 uint32_t reg_offset;
164};
165
166typedef int (*channel_copy_func)(const struct audio_stream *src, unsigned int src_channel,
167 struct audio_stream *dst, unsigned int dst_channel,
168 unsigned int frames);
169
173struct dai_data {
174 /* local DMA config */
175 struct dma_chan_data *chan;
176 uint32_t stream_id;
177 struct dma_sg_config config;
178 struct comp_dev *dai_dev;
179 struct comp_buffer *dma_buffer;
180 struct comp_buffer *local_buffer;
181 struct timestamp_cfg ts_config;
182 struct dai *dai;
183 struct dma *dma;
184 struct dai_group *group; /* NULL if no group assigned */
185 int xrun; /* true if we are doing xrun recovery */
186
187 pcm_converter_func process; /* processing function */
188 uint32_t chmap;
189 channel_copy_func channel_copy; /* channel copy func used by multi-endpoint
190 * gateway to mux/demux stream from/to multiple
191 * DMA buffers
192 */
193
194 uint32_t period_bytes; /* number of bytes per one period */
195 uint64_t total_data_processed;
196
197 struct ipc_config_dai ipc_config; /* generic common config */
198 void *dai_spec_config; /* dai specific config from the host */
199
200 uint64_t wallclock; /* wall clock at stream start */
201
202 /*
203 * flag indicating two-step stop/pause for DAI comp and DAI DMA.
204 * DAI stop occurs during STREAM_TRIG_STOP IPC and DMA stop during DAI_CONFIG IPC with
205 * the SOF_DAI_CONFIG_FLAGS_HW_FREE flag.
206 * DAI pause occurs during STREAM_TRIG_PAUSE IPC and DMA pause during DAI_CONFIG IPC with
207 * the SOF_DAI_CONFIG_FLAGS_PAUSE flag.
208 */
209 bool delayed_dma_stop;
210
211 /* llp slot info in memory windows */
212 struct llp_slot_info slot_info;
213
214 /* Copier gain params */
215 struct copier_gain_params *gain_data;
216};
217
218struct dai {
219 uint32_t index;
220 uint32_t type;
221 struct k_spinlock lock;
222 int sref;
223 struct dai_plat_data plat_data;
224 const struct dai_driver *drv;
225 const struct dai_data *dd;
226 void *priv_data;
227};
228
232struct dai_type_info {
233 uint32_t type;
234 struct dai *dai_array;
235 size_t num_dais;
236};
237
238/* dai tracing */
239#define trace_dai_drv_get_tr_ctx(drv_p) ((drv_p)->tctx)
240#define trace_dai_drv_get_id(drv_p) (-1)
241#define trace_dai_drv_get_subid(drv_p) (-1)
242
243#define trace_dai_get_tr_ctx(dai_p) ((dai_p)->drv->tctx)
244#define trace_dai_get_id(dai_p) ((dai_p)->drv->type)
245#define trace_dai_get_subid(dai_p) ((dai_p)->index)
246
247#if defined(__ZEPHYR__) && defined(CONFIG_ZEPHYR_LOG)
248/* driver level tracing */
249#define dai_cl_err(drv_p, __e, ...) LOG_ERR(__e, ##__VA_ARGS__)
250
251#define dai_cl_warn(drv_p, __e, ...) LOG_WRN(__e, ##__VA_ARGS__)
252
253#define dai_cl_info(drv_p, __e, ...) LOG_INF(__e, ##__VA_ARGS__)
254
255#define dai_cl_dbg(drv_p, __e, ...) LOG_DBG(__e, ##__VA_ARGS__)
256
257/* device level tracing */
258#define dai_err(dai_p, __e, ...) LOG_ERR(__e, ##__VA_ARGS__)
259
260#define dai_warn(dai_p, __e, ...) LOG_WRN(__e, ##__VA_ARGS__)
261
262#define dai_info(dai_p, __e, ...) LOG_INF(__e, ##__VA_ARGS__)
263
264#define dai_dbg(dai_p, __e, ...) LOG_DBG(__e, ##__VA_ARGS__)
265
266#else
267/* class (driver) level (no device object) tracing */
268
269#define dai_cl_err(drv_p, __e, ...) \
270 trace_dev_err(trace_dai_drv_get_tr_ctx, \
271 trace_dai_drv_get_id, \
272 trace_dai_drv_get_subid, \
273 drv_p, __e, ##__VA_ARGS__)
274
275#define dai_cl_warn(drv_p, __e, ...) \
276 trace_dev_warn(trace_dai_drv_get_tr_ctx,\
277 trace_dai_drv_get_id, \
278 trace_dai_drv_get_subid, \
279 drv_p, __e, ##__VA_ARGS__)
280
281#define dai_cl_info(drv_p, __e, ...) \
282 trace_dev_info(trace_dai_drv_get_tr_ctx,\
283 trace_dai_drv_get_id, \
284 trace_dai_drv_get_subid, \
285 drv_p, __e, ##__VA_ARGS__)
286
287#define dai_cl_dbg(drv_p, __e, ...) \
288 trace_dev_dbg(trace_dai_drv_get_tr_ctx, \
289 trace_dai_drv_get_id, \
290 trace_dai_drv_get_subid, \
291 drv_p, __e, ##__VA_ARGS__)
292
293/* device tracing */
294
295#define dai_err(dai_p, __e, ...) \
296 trace_dev_err(trace_dai_get_tr_ctx, \
297 trace_dai_get_id, \
298 trace_dai_get_subid, dai_p, __e, ##__VA_ARGS__)
299
300#define dai_warn(dai_p, __e, ...) \
301 trace_dev_warn(trace_dai_get_tr_ctx, \
302 trace_dai_get_id, \
303 trace_dai_get_subid, dai_p, __e, ##__VA_ARGS__)
304
305#define dai_info(dai_p, __e, ...) \
306 trace_dev_info(trace_dai_get_tr_ctx, \
307 trace_dai_get_id, \
308 trace_dai_get_subid, dai_p, __e, ##__VA_ARGS__)
309
310#define dai_dbg(dai_p, __e, ...) \
311 trace_dev_dbg(trace_dai_get_tr_ctx, \
312 trace_dai_get_id, \
313 trace_dai_get_subid, dai_p, __e, ##__VA_ARGS__)
314
315#endif /* #if defined(__ZEPHYR__) && defined(CONFIG_ZEPHYR_LOG) */
316
330struct dai_group *dai_group_get(uint32_t group_id, uint32_t flags);
331
339void dai_group_put(struct dai_group *group);
340
344struct dai_group {
348 uint32_t group_id;
349
353 uint32_t num_dais;
354
358 uint32_t trigger_counter;
359
363 int trigger_cmd;
364
368 int trigger_ret;
369
373 struct list_item list;
374};
375
379struct dai_info {
380 const struct dai_type_info *dai_type_array;
381 size_t num_dai_types;
382};
383
389int dai_init(struct sof *sof);
390
398struct dai *dai_get(uint32_t type, uint32_t index, uint32_t flags);
399
405void dai_put(struct dai *dai);
406
407#define dai_set_drvdata(dai, data) \
408 (dai->priv_data = data)
409#define dai_get_drvdata(dai) \
410 dai->priv_data
411#define dai_base(dai) \
412 dai->plat_data.base
413#define dai_irq(dai) \
414 dai->plat_data.irq
415#define dai_fifo(dai, direction) \
416 dai->plat_data.fifo[direction].offset
417
421static inline int dai_set_config(struct dai *dai, struct ipc_config_dai *config,
422 const void *spec_config, size_t size)
423{
424 return dai->drv->ops.set_config(dai, config, spec_config);
425}
426
430static inline int dai_trigger(struct dai *dai, int cmd, int direction)
431{
432 return dai->drv->ops.trigger(dai, cmd, direction);
433}
434
438static inline int dai_get_hw_params(struct dai *dai,
439 struct sof_ipc_stream_params *params,
440 int dir)
441{
442 return dai->drv->ops.get_hw_params(dai, params, dir);
443}
444
448static inline int dai_hw_params(struct dai *dai,
449 struct sof_ipc_stream_params *params)
450{
451 if (dai->drv->ops.hw_params)
452 return dai->drv->ops.hw_params(dai, params);
453
454 return 0;
455}
456
460static inline int dai_get_handshake(struct dai *dai, int direction,
461 int stream_id)
462{
463 return dai->drv->ops.get_handshake(dai, direction, stream_id);
464}
465
469static inline int dai_get_fifo(struct dai *dai, int direction,
470 int stream_id)
471{
472 return dai->drv->ops.get_fifo(dai, direction, stream_id);
473}
474
478static inline int dai_probe(struct dai *dai)
479{
480 return dai->drv->ops.probe(dai);
481}
482
486static inline int dai_remove(struct dai *dai)
487{
488 return dai->drv->ops.remove(dai);
489}
490
494static inline uint32_t dai_get_init_delay_ms(struct dai *dai)
495{
496 if (dai && dai->drv->ops.get_init_delay_ms)
497 return dai->drv->ops.get_init_delay_ms(dai);
498
499 return 0;
500}
501
502static inline int dai_get_fifo_depth(struct dai *dai, int direction)
503{
504 if (dai && dai->drv->ops.get_fifo_depth)
505 return dai->drv->ops.get_fifo_depth(dai, direction);
506
507 return 0;
508}
509
513static inline int dai_get_info(struct dai *dai, int info)
514{
515 int ret;
516
517 switch (info) {
518 case DAI_INFO_TYPE:
519 ret = dai->drv->type;
520 break;
521 case DAI_INFO_DMA_CAPS:
522 ret = dai->drv->dma_caps;
523 break;
524 case DAI_INFO_DMA_DEV:
525 ret = dai->drv->dma_dev;
526 break;
527 default:
528 ret = -EINVAL;
529 break;
530 }
531
532 return ret;
533}
534
535static inline void dai_write(struct dai *dai, uint32_t reg, uint32_t value)
536{
537 io_reg_write(dai_base(dai) + reg, value);
538}
539
540static inline uint32_t dai_read(struct dai *dai, uint32_t reg)
541{
542 return io_reg_read(dai_base(dai) + reg);
543}
544
545static inline void dai_update_bits(struct dai *dai, uint32_t reg,
546 uint32_t mask, uint32_t value)
547{
548 io_reg_update_bits(dai_base(dai) + reg, mask, value);
549}
550
551static inline const struct dai_info *dai_info_get(void)
552{
553 return sof_get()->dai_info;
554}
555
559int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void *config);
560
564void dai_set_link_hda_config(uint16_t *link_config,
565 struct ipc_config_dai *common_config,
566 const void *spec_config);
567
571void dai_dma_release(struct dai_data *dd, struct comp_dev *dev);
572
576int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai *common_config,
577 const void *spec_config);
578
582int dai_assign_group(struct dai_data *dd, struct comp_dev *dev, uint32_t group_id);
583
587int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn);
588
592void dai_dma_position_update(struct dai_data *dd, struct comp_dev *dev);
593
597void dai_release_llp_slot(struct dai_data *dd);
599
600#endif /* __SOF_LIB_DAI_LEGACY_H__ */
601
void dai_group_put(struct dai_group *group)
API to release DAI group.
int dai_get_fifo_depth(struct dai *dai, int direction)
Get Digital Audio interface fifo depth.
uint32_t dai_get_init_delay_ms(struct dai *dai)
Get DAI initial delay in milliseconds.
void dai_release_llp_slot(struct dai_data *dd)
release llp slot
int dai_config_dma_channel(struct dai_data *dd, struct comp_dev *dev, const void *config)
Configure DMA channel for DAI.
static uint32_t dai_read(struct dai *dai, uint32_t reg)
Definition dai-zephyr.h:181
int dai_config(struct dai_data *dd, struct comp_dev *dev, struct ipc_config_dai *common_cfg, const void *spec_cfg)
Configure DAI physical interface.
void dai_put(struct dai *dai)
API to release a platform DAI.
int(* channel_copy_func)(const struct audio_stream *src, unsigned int src_channel, struct audio_stream *dst, unsigned int dst_channel, unsigned int frames)
Definition dai-zephyr.h:112
static int dai_init(struct sof *sof)
API to initialize a platform DAI.
Definition dai-zephyr.h:220
void dai_set_link_hda_config(uint16_t *link_config, struct ipc_config_dai *common_config, const void *spec_config)
Configure HD Audio DMA params for DAI.
void dai_dma_position_update(struct dai_data *dd, struct comp_dev *dev)
update dai dma position for host driver.
int dai_assign_group(struct dai_data *dd, struct comp_dev *dev, uint32_t group_id)
Assign DAI to a group for simultaneous triggering.
int dai_get_handshake(struct dai *dai, int direction, int stream_id)
Get Digital Audio interface DMA Handshake.
struct dai * dai_get(uint32_t type, uint32_t index, uint32_t flags)
API to request a platform DAI.
void dai_dma_release(struct dai_data *dd, struct comp_dev *dev)
Reset DAI DMA config.
static void dai_write(struct dai *dai, uint32_t reg, uint32_t value)
Definition dai-zephyr.h:177
static void dai_update_bits(struct dai *dai, uint32_t reg, uint32_t mask, uint32_t value)
Definition dai-zephyr.h:186
struct dai_group * dai_group_get(uint32_t group_id, uint32_t flags)
API to request DAI group.
int dai_position(struct comp_dev *dev, struct sof_ipc_stream_posn *posn)
dai position for host driver.
int dai_set_config(struct dai *dai, struct ipc_config_dai *config, const void *spec_config, size_t size)
Digital Audio interface formatting.
static void io_reg_update_bits(uint32_t reg, uint32_t mask, uint32_t value)
Definition io.h:66
static uint32_t io_reg_read(uint32_t reg)
Definition io.h:56
static void io_reg_write(uint32_t reg, uint32_t val)
Definition io.h:61
#define list_item(item, type, member)
Definition list.h:80
PCM converter header file.
int(* pcm_converter_func)(const struct cir_buf_source *source, uint32_t src_channels, struct cir_buf_sink *sink, uint32_t sink_channels, size_t source_samples, uint32_t chmap)
PCM conversion function interface for data in circular buffer.
Definition pcm_converter.h:51
struct probe_pdata * probe
Definition sof.h:61
struct sof * sof_get(void)
const struct dai_info * dai_info
Definition sof.h:42
Audio stream is a circular buffer aware of audio format of the data in the buffer so provides API for...
Definition audio_stream.h:52
Audio component base device "class".
Definition component.h:645
DAI runtime data.
Definition dai-zephyr.h:119
struct sof_dma * dma
Definition dai-zephyr.h:130
struct comp_buffer * dma_buffer
Definition dai-zephyr.h:126
struct dai_group * group
Definition dai-zephyr.h:131
struct ipc_config_dai ipc_config
Definition dai-zephyr.h:145
bool delayed_dma_stop
Definition dai-zephyr.h:157
int xrun
Definition dai-zephyr.h:132
uint32_t stream_id
Definition dai-zephyr.h:122
struct dai * dai
Definition dai-zephyr.h:129
struct dma_sg_config config
Definition dai-zephyr.h:123
channel_copy_func channel_copy
Definition dai-zephyr.h:137
uint32_t chmap
Definition dai-zephyr.h:135
struct llp_slot_info slot_info
Definition dai-zephyr.h:160
pcm_converter_func process
Definition dai-zephyr.h:134
uint32_t period_bytes
Definition dai-zephyr.h:142
struct dai_ts_cfg ts_config
Definition dai-zephyr.h:128
struct comp_dev * dai_dev
Definition dai-zephyr.h:125
struct copier_gain_params * gain_data
Definition dai-zephyr.h:171
void * dai_spec_config
Definition dai-zephyr.h:146
uint64_t total_data_processed
Definition dai-zephyr.h:143
struct comp_buffer * local_buffer
Definition dai-zephyr.h:127
uint64_t wallclock
Definition dai-zephyr.h:148
DAI group information.
Definition dai-zephyr.h:72
int trigger_cmd
Trigger command to propagate.
Definition dai-zephyr.h:91
uint32_t trigger_counter
Number of DAIs to receive a trigger before processing begins.
Definition dai-zephyr.h:86
uint32_t num_dais
Number of DAIs in this group.
Definition dai-zephyr.h:81
struct list_item list
Group list.
Definition dai-zephyr.h:101
int trigger_ret
Last trigger error.
Definition dai-zephyr.h:96
uint32_t group_id
Group ID.
Definition dai-zephyr.h:76
Definition dai-zephyr.h:49
uint32_t index
Definition dai-zephyr.h:50
uint32_t dma_caps
Definition dai-zephyr.h:52
const struct dai_data * dd
Definition dai-zephyr.h:55
struct k_spinlock lock
Definition dai-zephyr.h:56
uint32_t dma_dev
Definition dai-zephyr.h:53
uint32_t type
Definition dai-zephyr.h:51
Definition ipc-config.h:65
llp slot info for memory window
Definition dai-zephyr.h:107
uint32_t reg_offset
Definition dai-zephyr.h:109
uint32_t node_id
Definition dai-zephyr.h:108
Definition stream.h:71
Definition stream.h:134
General firmware context.
Definition sof.h:44
const struct dai_info * dai_info
Definition sof.h:87
char value[]
Definition tlv.h:2
uint32_t type
Definition tlv.h:0