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 
9 /**
10   * \file include/sof/audio/component.h
11   * \brief Component API definition
12   * \author Liam Girdwood <liam.r.girdwood@linux.intel.com>
13   * \author Keyon Jie <yang.jie@linux.intel.com>
14   */
15 
16 #ifndef __SOF_AUDIO_COMPONENT_H__
17 #define __SOF_AUDIO_COMPONENT_H__
18 
19 #include <sof/audio/buffer.h>
20 #include <sof/audio/format.h>
21 #include <sof/audio/pipeline.h>
22 #include <sof/debug/panic.h>
23 #include <sof/drivers/idc.h>
24 #include <sof/list.h>
25 #include <sof/lib/alloc.h>
26 #include <sof/lib/cpu.h>
27 #include <sof/lib/dai.h>
28 #include <sof/lib/memory.h>
29 #include <sof/lib/perf_cnt.h>
30 #include <sof/math/numbers.h>
31 #include <sof/schedule/schedule.h>
32 #include <sof/sof.h>
33 #include <sof/trace/trace.h>
34 #include <ipc/control.h>
35 #include <ipc/stream.h>
36 #include <sof/ipc/topology.h>
37 #include <kernel/abi.h>
38 #include <user/trace.h>
39 
40 #include <errno.h>
41 #include <stdbool.h>
42 #include <stddef.h>
43 #include <stdint.h>
44 
45 struct comp_dev;
46 struct sof_ipc_stream_posn;
47 struct dai_hw_params;
48 struct timestamp_data;
49 
50 /** \addtogroup component_api Component API
51  *  @{
52  */
53 
54 /* NOTE: Keep the component state diagram up to date:
55  * sof-docs/developer_guides/firmware/components/images/comp-dev-states.pu
56  */
57 
58 /** \name Audio Component States
59  *  @{
60  */
61 #define COMP_STATE_INIT		0	/**< Component being initialised */
62 #define COMP_STATE_READY	1	/**< Component inactive, but ready */
63 #define COMP_STATE_SUSPEND	2	/**< Component suspended */
64 #define COMP_STATE_PREPARE	3	/**< Component prepared */
65 #define COMP_STATE_PAUSED	4	/**< Component paused */
66 #define COMP_STATE_ACTIVE	5	/**< Component active */
67 /** @}*/
68 
69 /** \name Standard Component Stream Commands
70  *  TODO: use IPC versions after 1.1
71  *  @{
72  */
73 #define COMP_TRIGGER_STOP	0	/**< Stop component stream */
74 #define COMP_TRIGGER_START	1	/**< Start component stream */
75 #define COMP_TRIGGER_PAUSE	2	/**< Pause the component stream */
76 #define COMP_TRIGGER_RELEASE	3	/**< Release paused component stream */
77 #define COMP_TRIGGER_SUSPEND	4	/**< Suspend component */
78 #define COMP_TRIGGER_RESUME	5	/**< Resume component */
79 #define COMP_TRIGGER_RESET	6	/**< Reset component */
80 #define COMP_TRIGGER_PREPARE	7	/**< Prepare component */
81 #define COMP_TRIGGER_XRUN	8	/**< XRUN component */
82 /** @}*/
83 
84 /** \name Standard Component Control Commands
85  *  "Value" commands are standard ones, known to the driver while
86  *  "Data" commands are opaque blobs transferred by the driver.
87  *
88  *  TODO: see also: ref to ipc data structures for commands.
89  *  @{
90  */
91 #define COMP_CMD_SET_VALUE	100	/**< Set value to component */
92 #define COMP_CMD_GET_VALUE	101     /**< Get value from component */
93 #define COMP_CMD_SET_DATA	102     /**< Set data to component */
94 #define COMP_CMD_GET_DATA	103     /**< Get data from component */
95 /** @}*/
96 
97 /** \name MMAP IPC status
98  *  @{
99  */
100 #define COMP_CMD_IPC_MMAP_RPOS	200	/**< Host read position */
101 #define COMP_CMD_IPC_MMAP_PPOS	201	/**< DAI presentation position */
102 
103 #define COMP_CMD_IPC_MMAP_VOL(chan)	(216 + chan)	/**< Volume */
104 /** @}*/
105 
106 /** \name Component status
107  *  @{
108  */
109 #define COMP_STATUS_STATE_ALREADY_SET	1	/**< Comp set state status */
110 /** @}*/
111 
112 /** \name Component attribute types
113  *  @{
114  */
115 #define COMP_ATTR_COPY_TYPE	0	/**< Comp copy type attribute */
116 #define COMP_ATTR_HOST_BUFFER	1	/**< Comp host buffer attribute */
117 #define COMP_ATTR_COPY_DIR	2	/**< Comp copy direction */
118 /** @}*/
119 
120 /** \name Trace macros
121  *  @{
122  */
123 
124 /** \brief Retrieves trace context from the component driver */
125 #define trace_comp_drv_get_tr_ctx(drv_p) ((drv_p)->tctx)
126 
127 /** \brief Retrieves id (-1 = undefined) from the component driver */
128 #define trace_comp_drv_get_id(drv_p) (-1)
129 
130 /** \brief Retrieves subid (-1 = undefined) from the component driver */
131 #define trace_comp_drv_get_subid(drv_p) (-1)
132 
133 /** \brief Retrieves trace context from the component device */
134 #define trace_comp_get_tr_ctx(comp_p) (&(comp_p)->tctx)
135 
136 /** \brief Retrieves id (pipe id) from the component device */
137 #define trace_comp_get_id(comp_p) ((comp_p)->ipc_config.pipeline_id)
138 
139 /** \brief Retrieves subid (comp id) from the component device */
140 #define trace_comp_get_subid(comp_p) ((comp_p)->ipc_config.id)
141 
142 /* class (driver) level (no device object) tracing */
143 
144 /** \brief Trace error message from component driver (no comp instance) */
145 #define comp_cl_err(drv_p, __e, ...)			\
146 	trace_dev_err(trace_comp_drv_get_tr_ctx,	\
147 		      trace_comp_drv_get_id,		\
148 		      trace_comp_drv_get_subid,		\
149 		      drv_p,				\
150 		      __e, ##__VA_ARGS__)
151 
152 /** \brief Trace warning message from component driver (no comp instance) */
153 #define comp_cl_warn(drv_p, __e, ...)			\
154 	trace_dev_warn(trace_comp_drv_get_tr_ctx,	\
155 		       trace_comp_drv_get_id,		\
156 		       trace_comp_drv_get_subid,	\
157 		       drv_p,				\
158 		       __e, ##__VA_ARGS__)
159 
160 /** \brief Trace info message from component driver (no comp instance) */
161 #define comp_cl_info(drv_p, __e, ...)			\
162 	trace_dev_info(trace_comp_drv_get_tr_ctx,	\
163 		       trace_comp_drv_get_id,		\
164 		       trace_comp_drv_get_subid,	\
165 		       drv_p,				\
166 		       __e, ##__VA_ARGS__)
167 
168 /** \brief Trace debug message from component driver (no comp instance) */
169 #define comp_cl_dbg(drv_p, __e, ...)			\
170 	trace_dev_dbg(trace_comp_drv_get_tr_ctx,	\
171 		      trace_comp_drv_get_id,		\
172 		      trace_comp_drv_get_subid,		\
173 		      drv_p,				\
174 		      __e, ##__VA_ARGS__)
175 
176 /* device tracing */
177 
178 /** \brief Trace error message from component device */
179 #define comp_err(comp_p, __e, ...)					\
180 	trace_dev_err(trace_comp_get_tr_ctx, trace_comp_get_id,		\
181 		      trace_comp_get_subid, comp_p, __e, ##__VA_ARGS__)
182 
183 /** \brief Trace warning message from component device */
184 #define comp_warn(comp_p, __e, ...)					\
185 	trace_dev_warn(trace_comp_get_tr_ctx, trace_comp_get_id,	\
186 		       trace_comp_get_subid, comp_p, __e, ##__VA_ARGS__)
187 
188 /** \brief Trace info message from component device */
189 #define comp_info(comp_p, __e, ...)					\
190 	trace_dev_info(trace_comp_get_tr_ctx, trace_comp_get_id,	\
191 		       trace_comp_get_subid, comp_p, __e, ##__VA_ARGS__)
192 
193 /** \brief Trace debug message from component device */
194 #define comp_dbg(comp_p, __e, ...)					\
195 	trace_dev_dbg(trace_comp_get_tr_ctx, trace_comp_get_id,		\
196 		      trace_comp_get_subid, comp_p, __e, ##__VA_ARGS__)
197 
198 #define comp_perf_info(pcd, comp_p)					\
199 	comp_info(comp_p, "perf comp_copy peak plat %d cpu %d",		\
200 		  (uint32_t)((pcd)->plat_delta_peak),			\
201 		  (uint32_t)((pcd)->cpu_delta_peak))
202 
203 /** @}*/
204 
205 /** \brief Type of endpoint this component is connected to in a pipeline */
206 enum comp_endpoint_type {
207 	COMP_ENDPOINT_HOST,	/**< Connected to host dma */
208 	COMP_ENDPOINT_DAI,	/**< Connected to dai dma */
209 	COMP_ENDPOINT_NODE	/**< No dma connection */
210 };
211 
212 /**
213  * \brief Type of next dma copy mode, changed on runtime.
214  *
215  * Supported by host as COMP_ATTR_COPY_TYPE parameter
216  * to comp_set_attribute().
217  */
218 enum comp_copy_type {
219 	COMP_COPY_INVALID = -1,	/**< Invalid */
220 	COMP_COPY_NORMAL = 0,	/**< Normal */
221 	COMP_COPY_BLOCKING,	/**< Blocking */
222 	COMP_COPY_ONE_SHOT,	/**< One-shot */
223 };
224 
225 struct comp_driver;
226 struct comp_ipc_config;
227 union ipc_config_specific;
228 
229 /**
230  * Audio component operations.
231  *
232  * All component operations must return 0 for success, negative values for
233  * errors and 1 to stop the pipeline walk operation unless specified otherwise
234  * in the operation documentation.
235  */
236 struct comp_ops {
237 	/**
238 	 * Creates a new component device.
239 	 * @param drv Parent component driver.
240 	 * @param comp Component parameters.
241 	 * @return Pointer to the new component device.
242 	 *
243 	 * All required data objects should be allocated from the run-time
244 	 * heap (SOF_MEM_ZONE_RUNTIME).
245 	 * Any component-specific private data is allocated separately and
246 	 * pointer is connected to the comp_dev::private by using
247 	 * comp_set_drvdata() and later retrieved by comp_get_drvdata().
248 	 *
249 	 * All parameters should be initialized to their default values.
250 	 */
251 	struct comp_dev *(*create)(const struct comp_driver *drv,
252 				   struct comp_ipc_config *ipc_config,
253 				   void *ipc_specific_config);
254 
255 	/**
256 	 * Called to delete the specified component device.
257 	 * @param dev Component device to be deleted.
258 	 *
259 	 * All data structures previously allocated on the run-time heap
260 	 * must be freed by the implementation of <code>free()</code>.
261 	 */
262 	void (*free)(struct comp_dev *dev);
263 
264 	/**
265 	 * Sets component audio stream parameters.
266 	 * @param dev Component device.
267 	 * @param params Audio (PCM) stream parameters to be set.
268 	 *
269 	 * Infrastructure calls comp_verify_params() if this handler is not
270 	 * defined, therefore it should be left NULL if no extra steps are
271 	 * required.
272 	 */
273 	int (*params)(struct comp_dev *dev,
274 		      struct sof_ipc_stream_params *params);
275 
276 	/**
277 	 * Fetches hardware stream parameters.
278 	 * @param dev Component device.
279 	 * @param params Receives copy of stream parameters retrieved from
280 	 *	DAI hw settings.
281 	 * @param dir Stream direction (see enum sof_ipc_stream_direction).
282 	 *
283 	 * Mandatory for components that allocate DAI.
284 	 */
285 	int (*dai_get_hw_params)(struct comp_dev *dev,
286 				 struct sof_ipc_stream_params *params, int dir);
287 
288 	/**
289 	 * Configures attached DAI.
290 	 * @param dev Component device.
291 	 * @param dai_config DAI configuration.
292 	 *
293 	 * Mandatory for components that allocate DAI.
294 	 */
295 	int (*dai_config)(struct comp_dev *dev, struct ipc_config_dai *dai_config,
296 			  void *dai_spec_config);
297 
298 	/**
299 	 * Used to pass standard and bespoke commands (with optional data).
300 	 * @param dev Component device.
301 	 * @param cmd Command.
302 	 * @param data Command data.
303 	 * @param max_data_size Max size of returned data acceptable by the
304 	 *	caller in case of 'get' commands.
305 	 */
306 	int (*cmd)(struct comp_dev *dev, int cmd, void *data,
307 		   int max_data_size);
308 
309 	/**
310 	 * Trigger, atomic - used to start/stop/pause stream operations.
311 	 * @param dev Component device.
312 	 * @param cmd Command, one of COMP_TRIGGER_...
313 	 */
314 	int (*trigger)(struct comp_dev *dev, int cmd);
315 
316 	/**
317 	 * Prepares component after params are set.
318 	 * @param dev Component device.
319 	 *
320 	 * Prepare should be used to get the component ready for starting
321 	 * processing after it's hw_params are known or after an XRUN.
322 	 */
323 	int (*prepare)(struct comp_dev *dev);
324 
325 	/**
326 	 * Resets component.
327 	 * @param dev Component device.
328 	 *
329 	 * Resets the component state and any hw_params to default component
330 	 * state. Should also free any resources acquired during hw_params.
331 	 * TODO: Some components are not compliant here wrt reset(). Fix this
332 	 * in v1.8.
333 	 */
334 	int (*reset)(struct comp_dev *dev);
335 
336 	/**
337 	 * Copy and process stream data from source to sink buffers.
338 	 * @param dev Component device.
339 	 * @return Number of copied frames.
340 	 */
341 	int (*copy)(struct comp_dev *dev);
342 
343 	/**
344 	 * Retrieves component rendering position.
345 	 * @param dev Component device.
346 	 * @param posn Receives reported position.
347 	 */
348 	int (*position)(struct comp_dev *dev,
349 		struct sof_ipc_stream_posn *posn);
350 
351 	/**
352 	 * Gets attribute in component.
353 	 * @param dev Component device.
354 	 * @param type Attribute type.
355 	 * @param value Attribute value.
356 	 * @return 0 if succeeded, error code otherwise.
357 	 */
358 	int (*get_attribute)(struct comp_dev *dev, uint32_t type,
359 			     void *value);
360 
361 	/**
362 	 * Sets attribute in component.
363 	 * @param dev Component device.
364 	 * @param type Attribute type.
365 	 * @param value Attribute value.
366 	 * @return 0 if succeeded, error code otherwise.
367 	 */
368 	int (*set_attribute)(struct comp_dev *dev, uint32_t type,
369 			     void *value);
370 
371 	/**
372 	 * Configures timestamping in attached DAI.
373 	 * @param dev Component device.
374 	 *
375 	 * Mandatory for components that allocate DAI.
376 	 */
377 	int (*dai_ts_config)(struct comp_dev *dev);
378 
379 	/**
380 	 * Starts timestamping.
381 	 * @param dev Component device.
382 	 *
383 	 * Mandatory for components that allocate DAI.
384 	 */
385 	int (*dai_ts_start)(struct comp_dev *dev);
386 
387 	/**
388 	 * Stops timestamping.
389 	 * @param dev Component device.
390 	 *
391 	 * Mandatory for components that allocate DAI.
392 	 */
393 	int (*dai_ts_stop)(struct comp_dev *dev);
394 
395 	/**
396 	 * Gets timestamp.
397 	 * @param dev Component device.
398 	 * @param tsd Receives timestamp data.
399 	 *
400 	 * Mandatory for components that allocate DAI.
401 	 */
402 	int (*dai_ts_get)(struct comp_dev *dev,
403 			  struct timestamp_data *tsd);
404 
405 	/**
406 	 * Bind, atomic - used to notify component of bind event.
407 	 * @param dev Component device.
408 	 * @param data Bind info
409 	 */
410 	int (*bind)(struct comp_dev *dev, void *data);
411 
412 	/**
413 	 * Unbind, atomic - used to notify component of unbind event.
414 	 * @param dev Component device.
415 	 * @param data unBind info
416 	 */
417 	int (*unbind)(struct comp_dev *dev, void *data);
418 };
419 
420 /**
421  * Audio component base driver "class"
422  * - used by all other component types.
423  */
424 struct comp_driver {
425 	uint32_t type;			/**< SOF_COMP_ for driver */
426 	const struct sof_uuid *uid;	/**< Address to UUID value */
427 	struct tr_ctx *tctx;		/**< Pointer to trace context */
428 	struct comp_ops ops;		/**< component operations */
429 };
430 
431 /** \brief Holds constant pointer to component driver */
432 struct comp_driver_info {
433 	const struct comp_driver *drv;	/**< pointer to component driver */
434 	struct list_item list;		/**< list of component drivers */
435 };
436 
437 /**
438  * Audio component base configuration from IPC at creation.
439  */
440 struct comp_ipc_config {
441 	uint32_t core;		/**< core we run on */
442 	uint32_t id;		/**< component id */
443 	uint32_t pipeline_id;	/**< component pipeline id */
444 	enum sof_comp_type type;	/**< component type */
445 	uint32_t periods_sink;	/**< 0 means variable */
446 	uint32_t periods_source;/**< 0 means variable */
447 	uint32_t frame_fmt;	/**< SOF_IPC_FRAME_ */
448 	uint32_t xrun_action;	/**< action we should take on XRUN */
449 };
450 
451 /**
452  * Audio component base device "class"
453  * - used by other component types.
454  */
455 struct comp_dev {
456 
457 	/* runtime */
458 	uint16_t state;		   /**< COMP_STATE_ */
459 	uint64_t position;	   /**< component rendering position */
460 	uint32_t frames;	   /**< number of frames we copy to sink */
461 	struct pipeline *pipeline; /**< pipeline we belong to */
462 
463 	uint32_t min_sink_bytes;   /**< min free sink buffer size measured in
464 				     *  bytes required to run component's
465 				     *  processing
466 				     */
467 	uint32_t min_source_bytes; /**< amount of data measured in bytes
468 				     *  available at source buffer required
469 				     *  to run component's processing
470 				     */
471 
472 	struct task *task;	/**< component's processing task used only
473 				  *  for components running on different core
474 				  *  than the rest of the pipeline
475 				  */
476 	uint32_t size;		/**< component's allocated size */
477 	uint32_t period;	/**< component's processing period */
478 	uint32_t priority;	/**< component's processing priority */
479 	bool is_shared;		/**< indicates whether component is shared
480 				  *  across cores
481 				  */
482 	struct comp_ipc_config ipc_config;	/**< Component IPC configuration */
483 	struct tr_ctx tctx;	/**< trace settings */
484 
485 	/* common runtime configuration for downstream/upstream */
486 	uint32_t direction;	/**< enum sof_ipc_stream_direction */
487 
488 	const struct comp_driver *drv;	/**< driver */
489 
490 	/* lists */
491 	struct list_item bsource_list;	/**< list of source buffers */
492 	struct list_item bsink_list;	/**< list of sink buffers */
493 
494 	/* private data - core does not touch this */
495 	void *priv_data;	/**< private data */
496 
497 #if CONFIG_PERFORMANCE_COUNTERS
498 	struct perf_cnt_data pcd;
499 #endif
500 };
501 
502 /** @}*/
503 
504 /* Common helper function used internally by the component implementations
505  * begin here.
506  */
507 
508 /** \addtogroup component_common_int Component's Common Helpers
509  *  @{
510  */
511 
512 /** \brief Struct for use with comp_get_copy_limits() function. */
513 struct comp_copy_limits {
514 	int frames;
515 	int source_bytes;
516 	int sink_bytes;
517 	int source_frame_bytes;
518 	int sink_frame_bytes;
519 };
520 
521 /**
522  * Retrieves Component id from device.
523  * @param dev Device.
524  * @return Component id.
525  */
dev_comp_id(const struct comp_dev * dev)526 static inline uint32_t dev_comp_id(const struct comp_dev *dev)
527 {
528 	return dev->ipc_config.id;
529 }
530 
531 /**
532  * Retrieves Component pipeline id from device.
533  * @param dev Device.
534  * @return Component pipeline id.
535  */
dev_comp_pipe_id(const struct comp_dev * dev)536 static inline uint32_t dev_comp_pipe_id(const struct comp_dev *dev)
537 {
538 	return dev->ipc_config.pipeline_id;
539 }
540 
541 /**
542  * Retrieves component type from device.
543  * @param dev Device.
544  * @return Component type.
545  */
dev_comp_type(const struct comp_dev * dev)546 static inline enum sof_comp_type dev_comp_type(const struct comp_dev *dev)
547 {
548 	return dev->ipc_config.type;
549 }
550 
551 /**
552  * Allocates memory for the component device and initializes common part.
553  * @param drv Parent component driver.
554  * @param bytes Size of the component device in bytes.
555  * @return Pointer to the component device.
556  */
comp_alloc(const struct comp_driver * drv,size_t bytes)557 static inline struct comp_dev *comp_alloc(const struct comp_driver *drv,
558 					  size_t bytes)
559 {
560 	struct comp_dev *dev = NULL;
561 
562 	dev = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, bytes);
563 	if (!dev)
564 		return NULL;
565 	dev->size = bytes;
566 	dev->drv = drv;
567 	dev->state = COMP_STATE_INIT;
568 	memcpy_s(&dev->tctx, sizeof(struct tr_ctx),
569 		 trace_comp_drv_get_tr_ctx(dev->drv), sizeof(struct tr_ctx));
570 
571 	return dev;
572 }
573 
574 /**
575  * \brief Assigns private data to component device.
576  * @param c Component device.
577  * @param data Private data.
578  */
579 #define comp_set_drvdata(c, data) \
580 	(c->priv_data = data)
581 
582 /**
583  * \brief Retrieves driver private data from component device.
584  * @param c Component device.
585  * @return Private data.
586  */
587 #define comp_get_drvdata(c) \
588 	c->priv_data
589 
590 #if defined UNIT_TEST || defined __ZEPHYR__
591 #define DECLARE_MODULE(init)
592 #elif CONFIG_LIBRARY
593 /* In case of shared libs components are initialised in dlopen */
594 #define DECLARE_MODULE(init) __attribute__((constructor)) \
595 	static void _module_init(void) { init(); }
596 #else
597 /** \brief Usage at the end of an independent module file:
598  *	DECLARE_MODULE(sys_*_init);
599  */
600 #define DECLARE_MODULE(init) __attribute__((__used__)) \
601 	__section(".module_init") static void(*f##init)(void) = init
602 #endif
603 
604 /** \name Component registration
605  *  @{
606  */
607 
608 /**
609  * Registers the component driver on the list of available components.
610  * @param drv Component driver to be registered.
611  * @return 0 if succeeded, error code otherwise.
612  */
613 int comp_register(struct comp_driver_info *drv);
614 
615 /**
616  * Unregisters the component driver from the list of available components.
617  * @param drv Component driver to be unregistered.
618  */
619 void comp_unregister(struct comp_driver_info *drv);
620 
621 /** @}*/
622 
623 /**
624  * Component state set.
625  * @param dev Component device.
626  * @param cmd Command, one of <i>COMP_TRIGGER_...</i>.
627  * @return 0 if succeeded, error code otherwise.
628  *
629  * This function should be called by a component implementation at the beginning
630  * of its state transition to verify whether the trigger is valid in the
631  * current state and abort the transition otherwise.
632  *
633  * Typically the COMP_STATE_READY as the initial state is set directly
634  * by the component's implementation of _new().
635  *
636  * COMP_TRIGGER_PREPARE is called from the component's prepare().
637  *
638  * COMP_TRIGGER_START/STOP is called from trigger().
639  *
640  * COMP_TRIGGER_RESET is called from reset().
641  */
642 int comp_set_state(struct comp_dev *dev, int cmd);
643 
644 /* \brief Set component period frames */
component_set_period_frames(struct comp_dev * current,uint32_t rate)645 static inline void component_set_period_frames(struct comp_dev *current,
646 					       uint32_t rate)
647 {
648 	/* Samplerate is in Hz and period in microseconds.
649 	 * As we don't have floats use scale divider 1000000.
650 	 * Also integer round up the result.
651 	 */
652 	current->frames = ceil_divide(rate * current->period, 1000000);
653 }
654 
655 /** \name XRUN handling.
656  *  @{
657  */
658 
659 /**
660  * Called by the component device when underrun is detected.
661  * @param dev Component device.
662  * @param source Source buffer.
663  * @param copy_bytes Requested size of data to be available.
664  */
comp_underrun(struct comp_dev * dev,struct comp_buffer * source,uint32_t copy_bytes)665 static inline void comp_underrun(struct comp_dev *dev,
666 				 struct comp_buffer *source,
667 				 uint32_t copy_bytes)
668 {
669 	int32_t bytes = (int32_t)audio_stream_get_avail_bytes(&source->stream) -
670 			copy_bytes;
671 
672 	comp_err(dev, "comp_underrun(): dev->comp.id = %u, source->avail = %u, copy_bytes = %u",
673 		 dev_comp_id(dev),
674 		 audio_stream_get_avail_bytes(&source->stream),
675 		 copy_bytes);
676 
677 	pipeline_xrun(dev->pipeline, dev, bytes);
678 }
679 
680 /**
681  * Called by component device when overrun is detected.
682  * @param dev Component device.
683  * @param sink Sink buffer.
684  * @param copy_bytes Requested size of free space to be available.
685  */
comp_overrun(struct comp_dev * dev,struct comp_buffer * sink,uint32_t copy_bytes)686 static inline void comp_overrun(struct comp_dev *dev, struct comp_buffer *sink,
687 				uint32_t copy_bytes)
688 {
689 	int32_t bytes = (int32_t)copy_bytes -
690 			audio_stream_get_free_bytes(&sink->stream);
691 
692 	comp_err(dev, "comp_overrun(): sink->free = %u, copy_bytes = %u",
693 		 audio_stream_get_free_bytes(&sink->stream), copy_bytes);
694 
695 	pipeline_xrun(dev->pipeline, dev, bytes);
696 }
697 
698 /** @}*/
699 
700 /**
701  * Computes source to sink copy operation boundaries including maximum number
702  * of frames that can be transferred (data available in source vs. free space
703  * available in sink).
704  *
705  * @param[in] source Source buffer.
706  * @param[in] sink Sink buffer.
707  * @param[out] cl Current copy limits.
708  */
709 void comp_get_copy_limits(struct comp_buffer *source, struct comp_buffer *sink,
710 			  struct comp_copy_limits *cl);
711 
712 /**
713  * Version of comp_get_copy_limits that locks both buffers to guarantee
714  * consistent state readings.
715  *
716  * @param[in] source Source buffer.
717  * @param[in] sink Sink buffer
718  * @param[out] cl Current copy limits.
719  */
720 static inline
comp_get_copy_limits_with_lock(struct comp_buffer * source,struct comp_buffer * sink,struct comp_copy_limits * cl)721 void comp_get_copy_limits_with_lock(struct comp_buffer *source,
722 				    struct comp_buffer *sink,
723 				    struct comp_copy_limits *cl)
724 {
725 	uint32_t source_flags = 0;
726 	uint32_t sink_flags = 0;
727 
728 	buffer_lock(source, &source_flags);
729 	buffer_lock(sink, &sink_flags);
730 
731 	comp_get_copy_limits(source, sink, cl);
732 
733 	buffer_unlock(sink, sink_flags);
734 	buffer_unlock(source, source_flags);
735 }
736 
737 /**
738  * Invalidates component to ensure current state and params readout.
739  * @param dev Component to invalidate
740  */
comp_invalidate(struct comp_dev * dev)741 static inline void comp_invalidate(struct comp_dev *dev)
742 {
743 	if (!dev->is_shared)
744 		dcache_invalidate_region(dev, sizeof(struct comp_dev));
745 }
746 
747 /**
748  * Writeback component to ensure current state and params readout.
749  * @param dev Component to writeback
750  */
comp_writeback(struct comp_dev * dev)751 static inline void comp_writeback(struct comp_dev *dev)
752 {
753 	if (!dev->is_shared)
754 		dcache_writeback_region(dev, sizeof(struct comp_dev));
755 }
756 
757 /**
758  * Get component state.
759  *
760  * @param req_dev Requesting component
761  * @param dev Component from which user wants to read status.
762  */
comp_get_state(struct comp_dev * req_dev,struct comp_dev * dev)763 static inline int comp_get_state(struct comp_dev *req_dev, struct comp_dev *dev)
764 {
765 	/* we should not invalidate data when components are on the same
766 	 * core, because we could invalidate data not previously writebacked
767 	 */
768 	if (req_dev->ipc_config.core != dev->ipc_config.core)
769 		comp_invalidate(dev);
770 
771 	return dev->state;
772 }
773 
774 struct comp_data_blob_handler;
775 
776 /**
777  * Returns data blob. In case when new data blob is available it returns new
778  * one. Function returns also data blob size in case when size pointer is given.
779  *
780  * @param blob_handler Data blob handler
781  * @param size Pointer to data blob size variable
782  * @param crc Pointer to data blolb crc value
783  */
784 void *comp_get_data_blob(struct comp_data_blob_handler *blob_handler,
785 			 size_t *size,  uint32_t *crc);
786 
787 /**
788  * Checks whether new data blob is available. Function allows to check (even
789  * during streaming - in copy() function) whether new config is available and
790  * if it is, component can perform reconfiguration.
791  *
792  * @param blob_handler Data blob handler
793  */
794 bool comp_is_new_data_blob_available(struct comp_data_blob_handler
795 					*blob_handler);
796 
797 /**
798  * Initilizes data blob with given value. If init_data is not specified,
799  * function will zero data blob.
800  *
801  * @param blob_handler Data blob handler
802  * @param size Data blob size
803  * @param init_data Initial data blob values
804  */
805 int comp_init_data_blob(struct comp_data_blob_handler *blob_handler,
806 			uint32_t size, void *init_data);
807 
808 /**
809  * Handles IPC set command.
810  *
811  * @param blob_handler Data blob handler
812  * @param cdata IPC ctrl data
813  */
814 int comp_data_blob_set_cmd(struct comp_data_blob_handler *blob_handler,
815 			   struct sof_ipc_ctrl_data *cdata);
816 /**
817  * Handles IPC get command.
818  *
819  * @param blob_handler Data blob handler
820  * @param cdata IPC ctrl data
821  * @param size Required size
822  */
823 int comp_data_blob_get_cmd(struct comp_data_blob_handler *blob_handler,
824 			   struct sof_ipc_ctrl_data *cdata, int size);
825 
826 /**
827  * Returns new data blob handler.
828  *
829  * @param dev Component device
830  */
831 struct comp_data_blob_handler *comp_data_blob_handler_new(struct comp_dev *dev);
832 
833 /**
834  * Free data blob handler.
835  *
836  * @param blob_handler Data blob handler
837  */
838 void comp_data_blob_handler_free(struct comp_data_blob_handler *blob_handler);
839 
840 /**
841  * Called by component in  params() function in order to set and update some of
842  * downstream (playback) or upstream (capture) buffer parameters with pcm
843  * parameters. There is a possibility to specify which of parameters won't be
844  * overwritten (e.g. SRC component should not overwrite rate parameter, because
845  * it is able to change it).
846  * @param dev Component device
847  * @param flag Specifies which parameter should not be updated
848  * @param params pcm params
849  */
850 int comp_verify_params(struct comp_dev *dev, uint32_t flag,
851 		       struct sof_ipc_stream_params *params);
852 
853 /** @}*/
854 
855 #endif /* __SOF_AUDIO_COMPONENT_H__ */
856