1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2017 Intel Corporation. All rights reserved.
4 //
5 // Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
6 //         Liam Girdwood <liam.r.girdwood@linux.intel.com>
7 //         Keyon Jie <yang.jie@linux.intel.com>
8 
9 #include <sof/audio/component.h>
10 #include <sof/audio/buffer.h>
11 #include <sof/audio/eq_iir/eq_iir.h>
12 #include <sof/audio/eq_iir/iir.h>
13 #include <sof/audio/format.h>
14 #include <sof/audio/pipeline.h>
15 #include <sof/audio/ipc-config.h>
16 #include <sof/common.h>
17 #include <sof/debug/panic.h>
18 #include <sof/ipc/msg.h>
19 #include <sof/lib/alloc.h>
20 #include <sof/lib/memory.h>
21 #include <sof/lib/uuid.h>
22 #include <sof/list.h>
23 #include <sof/math/iir_df2t.h>
24 #include <sof/platform.h>
25 #include <sof/string.h>
26 #include <sof/ut.h>
27 #include <sof/trace/trace.h>
28 #include <ipc/control.h>
29 #include <ipc/stream.h>
30 #include <ipc/topology.h>
31 #include <user/eq.h>
32 #include <user/trace.h>
33 #include <errno.h>
34 #include <stddef.h>
35 #include <stdint.h>
36 
37 static const struct comp_driver comp_eq_iir;
38 
39 /* 5150c0e6-27f9-4ec8-8351-c705b642d12f */
40 DECLARE_SOF_RT_UUID("eq-iir", eq_iir_uuid, 0x5150c0e6, 0x27f9, 0x4ec8,
41 		 0x83, 0x51, 0xc7, 0x05, 0xb6, 0x42, 0xd1, 0x2f);
42 
43 DECLARE_TR_CTX(eq_iir_tr, SOF_UUID(eq_iir_uuid), LOG_LEVEL_INFO);
44 
45 /* IIR component private data */
46 struct comp_data {
47 	struct iir_state_df2t iir[PLATFORM_MAX_CHANNELS]; /**< filters state */
48 	struct comp_data_blob_handler *model_handler;
49 	struct sof_eq_iir_config *config;
50 	int64_t *iir_delay;			/**< pointer to allocated RAM */
51 	size_t iir_delay_size;			/**< allocated size */
52 	eq_iir_func eq_iir_func;		/**< processing function */
53 };
54 
55 #if CONFIG_FORMAT_S16LE
56 /*
57  * EQ IIR algorithm code
58  */
59 
eq_iir_s16_default(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)60 static void eq_iir_s16_default(const struct comp_dev *dev,
61 			       const struct audio_stream *source,
62 			       struct audio_stream *sink,
63 			       uint32_t frames)
64 
65 {
66 	struct comp_data *cd = comp_get_drvdata(dev);
67 	struct iir_state_df2t *filter;
68 	int16_t *x;
69 	int16_t *y;
70 	int32_t z;
71 	int ch;
72 	int i;
73 	int idx;
74 	int nch = source->channels;
75 
76 	for (ch = 0; ch < nch; ch++) {
77 		filter = &cd->iir[ch];
78 		idx = ch;
79 		for (i = 0; i < frames; i++) {
80 			x = audio_stream_read_frag_s16(source, idx);
81 			y = audio_stream_write_frag_s16(sink, idx);
82 			z = iir_df2t(filter, *x << 16);
83 			*y = sat_int16(Q_SHIFT_RND(z, 31, 15));
84 			idx += nch;
85 		}
86 	}
87 }
88 #endif /* CONFIG_FORMAT_S16LE */
89 
90 #if CONFIG_FORMAT_S24LE
eq_iir_s24_default(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)91 static void eq_iir_s24_default(const struct comp_dev *dev,
92 			       const struct audio_stream *source,
93 			       struct audio_stream *sink,
94 			       uint32_t frames)
95 
96 {
97 	struct comp_data *cd = comp_get_drvdata(dev);
98 	struct iir_state_df2t *filter;
99 	int32_t *x;
100 	int32_t *y;
101 	int32_t z;
102 	int idx;
103 	int ch;
104 	int i;
105 	int nch = source->channels;
106 
107 	for (ch = 0; ch < nch; ch++) {
108 		filter = &cd->iir[ch];
109 		idx = ch;
110 		for (i = 0; i < frames; i++) {
111 			x = audio_stream_read_frag_s32(source, idx);
112 			y = audio_stream_write_frag_s32(sink, idx);
113 			z = iir_df2t(filter, *x << 8);
114 			*y = sat_int24(Q_SHIFT_RND(z, 31, 23));
115 			idx += nch;
116 		}
117 	}
118 }
119 #endif /* CONFIG_FORMAT_S24LE */
120 
121 #if CONFIG_FORMAT_S32LE
eq_iir_s32_default(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)122 static void eq_iir_s32_default(const struct comp_dev *dev,
123 			       const struct audio_stream *source,
124 			       struct audio_stream *sink,
125 			       uint32_t frames)
126 
127 {
128 	struct comp_data *cd = comp_get_drvdata(dev);
129 	struct iir_state_df2t *filter;
130 	int32_t *x;
131 	int32_t *y;
132 	int idx;
133 	int ch;
134 	int i;
135 	int nch = source->channels;
136 
137 	for (ch = 0; ch < nch; ch++) {
138 		filter = &cd->iir[ch];
139 		idx = ch;
140 		for (i = 0; i < frames; i++) {
141 			x = audio_stream_read_frag_s32(source, idx);
142 			y = audio_stream_write_frag_s32(sink, idx);
143 			*y = iir_df2t(filter, *x);
144 			idx += nch;
145 		}
146 	}
147 }
148 #endif /* CONFIG_FORMAT_S32LE */
149 
150 #if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE
eq_iir_s32_16_default(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)151 static void eq_iir_s32_16_default(const struct comp_dev *dev,
152 				  const struct audio_stream *source,
153 				  struct audio_stream *sink,
154 				  uint32_t frames)
155 
156 {
157 	struct comp_data *cd = comp_get_drvdata(dev);
158 	struct iir_state_df2t *filter;
159 	int32_t *x;
160 	int16_t *y;
161 	int32_t z;
162 	int idx;
163 	int ch;
164 	int i;
165 	int nch = source->channels;
166 
167 	for (ch = 0; ch < nch; ch++) {
168 		filter = &cd->iir[ch];
169 		idx = ch;
170 		for (i = 0; i < frames; i++) {
171 			x = audio_stream_read_frag_s32(source, idx);
172 			y = audio_stream_write_frag_s16(sink, idx);
173 			z = iir_df2t(filter, *x);
174 			*y = sat_int16(Q_SHIFT_RND(z, 31, 15));
175 			idx += nch;
176 		}
177 	}
178 }
179 #endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S16LE */
180 
181 #if CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE
eq_iir_s32_24_default(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)182 static void eq_iir_s32_24_default(const struct comp_dev *dev,
183 				  const struct audio_stream *source,
184 				  struct audio_stream *sink,
185 				  uint32_t frames)
186 
187 {
188 	struct comp_data *cd = comp_get_drvdata(dev);
189 	struct iir_state_df2t *filter;
190 	int32_t *x;
191 	int32_t *y;
192 	int32_t z;
193 	int idx;
194 	int ch;
195 	int i;
196 	int nch = source->channels;
197 
198 	for (ch = 0; ch < nch; ch++) {
199 		filter = &cd->iir[ch];
200 		idx = ch;
201 		for (i = 0; i < frames; i++) {
202 			x = audio_stream_read_frag_s32(source, idx);
203 			y = audio_stream_write_frag_s32(sink, idx);
204 			z = iir_df2t(filter, *x);
205 			*y = sat_int24(Q_SHIFT_RND(z, 31, 23));
206 			idx += nch;
207 		}
208 	}
209 }
210 #endif /* CONFIG_FORMAT_S32LE && CONFIG_FORMAT_S24LE */
211 
eq_iir_pass(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)212 static void eq_iir_pass(const struct comp_dev *dev,
213 			const struct audio_stream *source,
214 			struct audio_stream *sink,
215 			uint32_t frames)
216 {
217 	audio_stream_copy(source, 0, sink, 0, frames * source->channels);
218 }
219 
220 #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE
eq_iir_s32_s16_pass(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)221 static void eq_iir_s32_s16_pass(const struct comp_dev *dev,
222 				const struct audio_stream *source,
223 				struct audio_stream *sink,
224 				uint32_t frames)
225 {
226 	int32_t *x;
227 	int16_t *y;
228 	int i;
229 	int n = frames * source->channels;
230 
231 	for (i = 0; i < n; i++) {
232 		x = audio_stream_read_frag_s32(source, i);
233 		y = audio_stream_write_frag_s16(sink, i);
234 		*y = sat_int16(Q_SHIFT_RND(*x, 31, 15));
235 	}
236 }
237 #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */
238 
239 #if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE
eq_iir_s32_s24_pass(const struct comp_dev * dev,const struct audio_stream * source,struct audio_stream * sink,uint32_t frames)240 static void eq_iir_s32_s24_pass(const struct comp_dev *dev,
241 				const struct audio_stream *source,
242 				struct audio_stream *sink,
243 				uint32_t frames)
244 {
245 	int32_t *x;
246 	int32_t *y;
247 	int i;
248 	int n = frames * source->channels;
249 
250 	for (i = 0; i < n; i++) {
251 		x = audio_stream_read_frag_s32(source, i);
252 		y = audio_stream_write_frag_s16(sink, i);
253 		*y = sat_int24(Q_SHIFT_RND(*x, 31, 23));
254 	}
255 }
256 #endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */
257 
258 const struct eq_iir_func_map fm_configured[] = {
259 #if CONFIG_FORMAT_S16LE
260 	{SOF_IPC_FRAME_S16_LE,  SOF_IPC_FRAME_S16_LE,  eq_iir_s16_default},
261 #endif /* CONFIG_FORMAT_S16LE */
262 #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE
263 	{SOF_IPC_FRAME_S16_LE,  SOF_IPC_FRAME_S24_4LE, NULL},
264 	{SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE,  NULL},
265 
266 #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE */
267 #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE
268 	{SOF_IPC_FRAME_S16_LE,  SOF_IPC_FRAME_S32_LE,  NULL},
269 	{SOF_IPC_FRAME_S32_LE,  SOF_IPC_FRAME_S16_LE,  eq_iir_s32_16_default},
270 #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE */
271 #if CONFIG_FORMAT_S24LE
272 	{SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, eq_iir_s24_default},
273 #endif /* CONFIG_FORMAT_S24LE */
274 #if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE
275 	{SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE,  NULL},
276 	{SOF_IPC_FRAME_S32_LE,  SOF_IPC_FRAME_S24_4LE, eq_iir_s32_24_default},
277 #endif /* CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE */
278 #if CONFIG_FORMAT_S32LE
279 	{SOF_IPC_FRAME_S32_LE,  SOF_IPC_FRAME_S32_LE,  eq_iir_s32_default},
280 #endif /* CONFIG_FORMAT_S32LE */
281 };
282 
283 const struct eq_iir_func_map fm_passthrough[] = {
284 #if CONFIG_FORMAT_S16LE
285 	{SOF_IPC_FRAME_S16_LE,  SOF_IPC_FRAME_S16_LE,  eq_iir_pass},
286 #endif /* CONFIG_FORMAT_S16LE */
287 #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE
288 	{SOF_IPC_FRAME_S16_LE,  SOF_IPC_FRAME_S24_4LE, NULL},
289 	{SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S16_LE,  NULL},
290 
291 #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S24LE*/
292 #if CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE
293 	{SOF_IPC_FRAME_S16_LE,  SOF_IPC_FRAME_S32_LE,  NULL},
294 	{SOF_IPC_FRAME_S32_LE,  SOF_IPC_FRAME_S16_LE,  eq_iir_s32_s16_pass},
295 #endif /* CONFIG_FORMAT_S16LE && CONFIG_FORMAT_S32LE*/
296 #if CONFIG_FORMAT_S24LE
297 	{SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S24_4LE, eq_iir_pass},
298 #endif /* CONFIG_FORMAT_S24LE */
299 #if CONFIG_FORMAT_S24LE && CONFIG_FORMAT_S32LE
300 	{SOF_IPC_FRAME_S24_4LE, SOF_IPC_FRAME_S32_LE,  NULL},
301 	{SOF_IPC_FRAME_S32_LE,  SOF_IPC_FRAME_S24_4LE, eq_iir_s32_s24_pass},
302 #endif /* CONFIG_FORMAT_S24LE */
303 #if CONFIG_FORMAT_S32LE
304 	{SOF_IPC_FRAME_S32_LE,  SOF_IPC_FRAME_S32_LE,  eq_iir_pass},
305 #endif /* CONFIG_FORMAT_S32LE */
306 };
307 
eq_iir_find_func(enum sof_ipc_frame source_format,enum sof_ipc_frame sink_format,const struct eq_iir_func_map * map,int n)308 static eq_iir_func eq_iir_find_func(enum sof_ipc_frame source_format,
309 				    enum sof_ipc_frame sink_format,
310 				    const struct eq_iir_func_map *map,
311 				    int n)
312 {
313 	int i;
314 
315 	/* Find suitable processing function from map. */
316 	for (i = 0; i < n; i++) {
317 		if ((uint8_t)source_format != map[i].source)
318 			continue;
319 		if ((uint8_t)sink_format != map[i].sink)
320 			continue;
321 
322 		return map[i].func;
323 	}
324 
325 	return NULL;
326 }
327 
eq_iir_free_delaylines(struct comp_data * cd)328 static void eq_iir_free_delaylines(struct comp_data *cd)
329 {
330 	struct iir_state_df2t *iir = cd->iir;
331 	int i = 0;
332 
333 	/* Free the common buffer for all EQs and point then
334 	 * each IIR channel delay line to NULL.
335 	 */
336 	rfree(cd->iir_delay);
337 	cd->iir_delay = NULL;
338 	cd->iir_delay_size = 0;
339 	for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
340 		iir[i].delay = NULL;
341 }
342 
eq_iir_init_coef(struct sof_eq_iir_config * config,struct iir_state_df2t * iir,int nch)343 static int eq_iir_init_coef(struct sof_eq_iir_config *config,
344 			    struct iir_state_df2t *iir, int nch)
345 {
346 	struct sof_eq_iir_header_df2t *lookup[SOF_EQ_IIR_MAX_RESPONSES];
347 	struct sof_eq_iir_header_df2t *eq;
348 	int32_t *assign_response;
349 	int32_t *coef_data;
350 	int size_sum = 0;
351 	int resp = 0;
352 	int i;
353 	int j;
354 	int s;
355 
356 	comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), response assign for %u channels, %u responses",
357 		     config->channels_in_config,
358 		     config->number_of_responses);
359 
360 	/* Sanity checks */
361 	if (nch > PLATFORM_MAX_CHANNELS ||
362 	    config->channels_in_config > PLATFORM_MAX_CHANNELS ||
363 	    !config->channels_in_config) {
364 		comp_cl_err(&comp_eq_iir, "eq_iir_init_coef(), invalid channels count");
365 		return -EINVAL;
366 	}
367 	if (config->number_of_responses > SOF_EQ_IIR_MAX_RESPONSES) {
368 		comp_cl_err(&comp_eq_iir, "eq_iir_init_coef(), # of resp exceeds max");
369 		return -EINVAL;
370 	}
371 
372 	/* Collect index of response start positions in all_coefficients[]  */
373 	j = 0;
374 	assign_response = ASSUME_ALIGNED(&config->data[0], 4);
375 	coef_data = ASSUME_ALIGNED(&config->data[config->channels_in_config],
376 				   4);
377 	for (i = 0; i < SOF_EQ_IIR_MAX_RESPONSES; i++) {
378 		if (i < config->number_of_responses) {
379 			eq = (struct sof_eq_iir_header_df2t *)&coef_data[j];
380 			lookup[i] = eq;
381 			j += SOF_EQ_IIR_NHEADER_DF2T
382 				+ SOF_EQ_IIR_NBIQUAD_DF2T * eq->num_sections;
383 		} else {
384 			lookup[i] = NULL;
385 		}
386 	}
387 
388 	/* Initialize 1st phase */
389 	for (i = 0; i < nch; i++) {
390 		/* Check for not reading past blob response to channel assign
391 		 * map. The previous channel response is assigned for any
392 		 * additional channels in the stream. It allows to use single
393 		 * channel configuration to setup multi channel equalization
394 		 * with the same response.
395 		 */
396 		if (i < config->channels_in_config)
397 			resp = assign_response[i];
398 
399 		if (resp < 0) {
400 			/* Initialize EQ channel to bypass and continue with
401 			 * next channel response.
402 			 */
403 			comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), ch %d is set to bypass",
404 				     i);
405 			iir_reset_df2t(&iir[i]);
406 			continue;
407 		}
408 
409 		if (resp >= config->number_of_responses) {
410 			comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), requested response %d exceeds defined",
411 				     resp);
412 			return -EINVAL;
413 		}
414 
415 		/* Initialize EQ coefficients */
416 		eq = lookup[resp];
417 		s = iir_delay_size_df2t(eq);
418 		if (s > 0) {
419 			size_sum += s;
420 		} else {
421 			comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), sections count %d exceeds max",
422 				     eq->num_sections);
423 			return -EINVAL;
424 		}
425 
426 		iir_init_coef_df2t(&iir[i], eq);
427 		comp_cl_info(&comp_eq_iir, "eq_iir_init_coef(), ch %d is set to response %d",
428 			     i, resp);
429 	}
430 
431 	return size_sum;
432 }
433 
eq_iir_init_delay(struct iir_state_df2t * iir,int64_t * delay_start,int nch)434 static void eq_iir_init_delay(struct iir_state_df2t *iir,
435 			      int64_t *delay_start, int nch)
436 {
437 	int64_t *delay = delay_start;
438 	int i;
439 
440 	/* Initialize second phase to set EQ delay lines pointers. A
441 	 * bypass mode filter is indicated by biquads count of zero.
442 	 */
443 	for (i = 0; i < nch; i++) {
444 		if (iir[i].biquads > 0)
445 			iir_init_delay_df2t(&iir[i], &delay);
446 	}
447 }
448 
eq_iir_setup(struct comp_data * cd,int nch)449 static int eq_iir_setup(struct comp_data *cd, int nch)
450 {
451 	int delay_size;
452 
453 	/* Free existing IIR channels data if it was allocated */
454 	eq_iir_free_delaylines(cd);
455 
456 	/* Set coefficients for each channel EQ from coefficient blob */
457 	delay_size = eq_iir_init_coef(cd->config, cd->iir, nch);
458 	if (delay_size < 0)
459 		return delay_size; /* Contains error code */
460 
461 	/* If all channels were set to bypass there's no need to
462 	 * allocate delay. Just return with success.
463 	 */
464 	if (!delay_size)
465 		return 0;
466 
467 	/* Allocate all IIR channels data in a big chunk and clear it */
468 	cd->iir_delay = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM,
469 				delay_size);
470 	if (!cd->iir_delay) {
471 		comp_cl_err(&comp_eq_iir, "eq_iir_setup(), delay allocation fail");
472 		return -ENOMEM;
473 	}
474 
475 	memset(cd->iir_delay, 0, delay_size);
476 	cd->iir_delay_size = delay_size;
477 
478 	/* Assign delay line to each channel EQ */
479 	eq_iir_init_delay(cd->iir, cd->iir_delay, nch);
480 	return 0;
481 }
482 
483 /*
484  * End of EQ setup code. Next the standard component methods.
485  */
486 
eq_iir_new(const struct comp_driver * drv,struct comp_ipc_config * config,void * spec)487 static struct comp_dev *eq_iir_new(const struct comp_driver *drv,
488 				   struct comp_ipc_config *config,
489 				   void *spec)
490 {
491 	struct comp_dev *dev = NULL;
492 	struct comp_data *cd = NULL;
493 	struct ipc_config_process *ipc_iir = spec;
494 	size_t bs = ipc_iir->size;
495 	int i;
496 	int ret;
497 
498 	comp_cl_info(&comp_eq_iir, "eq_iir_new()");
499 
500 	/* Check first before proceeding with dev and cd that coefficients
501 	 * blob size is sane.
502 	 */
503 	if (bs > SOF_EQ_IIR_MAX_SIZE) {
504 		comp_cl_err(&comp_eq_iir, "eq_iir_new(), coefficients blob size %u exceeds maximum",
505 			    bs);
506 		return NULL;
507 	}
508 
509 	dev = comp_alloc(drv, sizeof(*dev));
510 	if (!dev)
511 		return NULL;
512 	dev->ipc_config = *config;
513 
514 	cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
515 	if (!cd)
516 		goto fail;
517 
518 	comp_set_drvdata(dev, cd);
519 
520 	cd->eq_iir_func = NULL;
521 	cd->iir_delay = NULL;
522 	cd->iir_delay_size = 0;
523 
524 	/* component model data handler */
525 	cd->model_handler = comp_data_blob_handler_new(dev);
526 	if (!cd->model_handler) {
527 		comp_cl_err(&comp_eq_iir, "eq_iir_new(): comp_data_blob_handler_new() failed.");
528 		goto cd_fail;
529 	}
530 
531 	/* Allocate and make a copy of the coefficients blob and reset IIR. If
532 	 * the EQ is configured later in run-time the size is zero.
533 	 */
534 	ret = comp_init_data_blob(cd->model_handler, bs, ipc_iir->data);
535 	if (ret < 0) {
536 		comp_cl_err(&comp_eq_iir, "eq_iir_new(): comp_init_data_blob() failed.");
537 		goto cd_fail;
538 	}
539 
540 	for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
541 		iir_reset_df2t(&cd->iir[i]);
542 
543 	dev->state = COMP_STATE_READY;
544 	return dev;
545 
546 cd_fail:
547 	comp_data_blob_handler_free(cd->model_handler);
548 	rfree(cd);
549 fail:
550 	rfree(dev);
551 	return NULL;
552 }
553 
eq_iir_free(struct comp_dev * dev)554 static void eq_iir_free(struct comp_dev *dev)
555 {
556 	struct comp_data *cd = comp_get_drvdata(dev);
557 
558 	comp_info(dev, "eq_iir_free()");
559 
560 	eq_iir_free_delaylines(cd);
561 	comp_data_blob_handler_free(cd->model_handler);
562 
563 	rfree(cd);
564 	rfree(dev);
565 }
566 
eq_iir_verify_params(struct comp_dev * dev,struct sof_ipc_stream_params * params)567 static int eq_iir_verify_params(struct comp_dev *dev,
568 				struct sof_ipc_stream_params *params)
569 {
570 	struct comp_buffer *sourceb;
571 	struct comp_buffer *sinkb;
572 	uint32_t buffer_flag;
573 	int ret;
574 
575 	comp_dbg(dev, "eq_iir_verify_params()");
576 
577 	/* EQ component will only ever have 1 source and 1 sink buffer */
578 	sourceb = list_first_item(&dev->bsource_list, struct comp_buffer,
579 				  sink_list);
580 	sinkb = list_first_item(&dev->bsink_list, struct comp_buffer,
581 				source_list);
582 
583 	/* we check whether we can support frame_fmt conversion (whether we have
584 	 * such conversion function) due to source and sink buffer frame_fmt's.
585 	 * If not, we will overwrite sink (playback) and source (capture) with
586 	 * pcm frame_fmt and will not make any conversion (sink and source
587 	 * frame_fmt will be equal).
588 	 */
589 	buffer_flag = eq_iir_find_func(sourceb->stream.frame_fmt,
590 				       sinkb->stream.frame_fmt, fm_configured,
591 				       ARRAY_SIZE(fm_configured)) ?
592 				       BUFF_PARAMS_FRAME_FMT : 0;
593 
594 	ret = comp_verify_params(dev, buffer_flag, params);
595 	if (ret < 0) {
596 		comp_err(dev, "eq_iir_verify_params(): comp_verify_params() failed.");
597 		return ret;
598 	}
599 
600 	return 0;
601 }
602 
603 /* set component audio stream parameters */
eq_iir_params(struct comp_dev * dev,struct sof_ipc_stream_params * params)604 static int eq_iir_params(struct comp_dev *dev,
605 			 struct sof_ipc_stream_params *params)
606 {
607 	int err;
608 
609 	comp_info(dev, "eq_iir_params()");
610 
611 	err = eq_iir_verify_params(dev, params);
612 	if (err < 0) {
613 		comp_err(dev, "eq_iir_params(): pcm params verification failed.");
614 		return -EINVAL;
615 	}
616 
617 	/* All configuration work is postponed to prepare(). */
618 	return 0;
619 }
620 
iir_cmd_get_data(struct comp_dev * dev,struct sof_ipc_ctrl_data * cdata,int max_size)621 static int iir_cmd_get_data(struct comp_dev *dev,
622 			    struct sof_ipc_ctrl_data *cdata, int max_size)
623 {
624 	struct comp_data *cd = comp_get_drvdata(dev);
625 	int ret = 0;
626 
627 	switch (cdata->cmd) {
628 	case SOF_CTRL_CMD_BINARY:
629 		comp_info(dev, "iir_cmd_get_data(), SOF_CTRL_CMD_BINARY");
630 		ret = comp_data_blob_get_cmd(cd->model_handler, cdata,
631 					     max_size);
632 		break;
633 	default:
634 		comp_err(dev, "iir_cmd_get_data(), invalid command");
635 		ret = -EINVAL;
636 		break;
637 	}
638 	return ret;
639 }
640 
iir_cmd_set_data(struct comp_dev * dev,struct sof_ipc_ctrl_data * cdata)641 static int iir_cmd_set_data(struct comp_dev *dev,
642 			    struct sof_ipc_ctrl_data *cdata)
643 {
644 	struct comp_data *cd = comp_get_drvdata(dev);
645 	int ret = 0;
646 
647 	switch (cdata->cmd) {
648 	case SOF_CTRL_CMD_BINARY:
649 		comp_info(dev, "iir_cmd_set_data(), SOF_CTRL_CMD_BINARY");
650 		ret = comp_data_blob_set_cmd(cd->model_handler, cdata);
651 		break;
652 	default:
653 		comp_err(dev, "iir_cmd_set_data(), invalid command");
654 		ret = -EINVAL;
655 		break;
656 	}
657 
658 	return ret;
659 }
660 
661 /* used to pass standard and bespoke commands (with data) to component */
eq_iir_cmd(struct comp_dev * dev,int cmd,void * data,int max_data_size)662 static int eq_iir_cmd(struct comp_dev *dev, int cmd, void *data,
663 		      int max_data_size)
664 {
665 	struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4);
666 	int ret = 0;
667 
668 	comp_info(dev, "eq_iir_cmd()");
669 
670 	switch (cmd) {
671 	case COMP_CMD_SET_DATA:
672 		ret = iir_cmd_set_data(dev, cdata);
673 		break;
674 	case COMP_CMD_GET_DATA:
675 		ret = iir_cmd_get_data(dev, cdata, max_data_size);
676 		break;
677 	default:
678 		comp_err(dev, "eq_iir_cmd(), invalid command");
679 		ret = -EINVAL;
680 	}
681 
682 	return ret;
683 }
684 
eq_iir_trigger(struct comp_dev * dev,int cmd)685 static int eq_iir_trigger(struct comp_dev *dev, int cmd)
686 {
687 	struct comp_data *cd = comp_get_drvdata(dev);
688 
689 	comp_info(dev, "eq_iir_trigger()");
690 
691 	if (cmd == COMP_TRIGGER_START || cmd == COMP_TRIGGER_RELEASE)
692 		assert(cd->eq_iir_func);
693 
694 	return comp_set_state(dev, cmd);
695 }
696 
eq_iir_process(struct comp_dev * dev,struct comp_buffer * source,struct comp_buffer * sink,int frames,uint32_t source_bytes,uint32_t sink_bytes)697 static void eq_iir_process(struct comp_dev *dev, struct comp_buffer *source,
698 			   struct comp_buffer *sink, int frames,
699 			   uint32_t source_bytes, uint32_t sink_bytes)
700 {
701 	struct comp_data *cd = comp_get_drvdata(dev);
702 
703 	buffer_invalidate(source, source_bytes);
704 
705 	cd->eq_iir_func(dev, &source->stream, &sink->stream, frames);
706 
707 	buffer_writeback(sink, sink_bytes);
708 
709 	/* calc new free and available */
710 	comp_update_buffer_consume(source, source_bytes);
711 	comp_update_buffer_produce(sink, sink_bytes);
712 }
713 
714 /* copy and process stream data from source to sink buffers */
eq_iir_copy(struct comp_dev * dev)715 static int eq_iir_copy(struct comp_dev *dev)
716 {
717 	struct comp_copy_limits cl;
718 	struct comp_data *cd = comp_get_drvdata(dev);
719 	struct comp_buffer *sourceb;
720 	struct comp_buffer *sinkb;
721 	int ret;
722 
723 	comp_dbg(dev, "eq_iir_copy()");
724 
725 	sourceb = list_first_item(&dev->bsource_list, struct comp_buffer,
726 				  sink_list);
727 
728 	/* Check for changed configuration */
729 	if (comp_is_new_data_blob_available(cd->model_handler)) {
730 		cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL);
731 		ret = eq_iir_setup(cd, sourceb->stream.channels);
732 		if (ret < 0) {
733 			comp_err(dev, "eq_iir_copy(), failed IIR setup");
734 			return ret;
735 		}
736 	}
737 
738 	sinkb = list_first_item(&dev->bsink_list, struct comp_buffer,
739 				source_list);
740 
741 	/* Get source, sink, number of frames etc. to process. */
742 	comp_get_copy_limits_with_lock(sourceb, sinkb, &cl);
743 
744 	/* Run EQ function */
745 	eq_iir_process(dev, sourceb, sinkb, cl.frames, cl.source_bytes,
746 		       cl.sink_bytes);
747 
748 	return 0;
749 }
750 
eq_iir_prepare(struct comp_dev * dev)751 static int eq_iir_prepare(struct comp_dev *dev)
752 {
753 	struct comp_data *cd = comp_get_drvdata(dev);
754 	struct comp_buffer *sourceb;
755 	struct comp_buffer *sinkb;
756 	enum sof_ipc_frame source_format;
757 	enum sof_ipc_frame sink_format;
758 	uint32_t sink_period_bytes;
759 	int ret;
760 
761 	comp_info(dev, "eq_iir_prepare()");
762 
763 	ret = comp_set_state(dev, COMP_TRIGGER_PREPARE);
764 	if (ret < 0)
765 		return ret;
766 
767 	if (ret == COMP_STATUS_STATE_ALREADY_SET)
768 		return PPL_STATUS_PATH_STOP;
769 
770 	/* EQ component will only ever have 1 source and 1 sink buffer */
771 	sourceb = list_first_item(&dev->bsource_list,
772 				  struct comp_buffer, sink_list);
773 	sinkb = list_first_item(&dev->bsink_list,
774 				struct comp_buffer, source_list);
775 
776 	/* get source data format */
777 	source_format = sourceb->stream.frame_fmt;
778 
779 	/* get sink data format and period bytes */
780 	sink_format = sinkb->stream.frame_fmt;
781 	sink_period_bytes = audio_stream_period_bytes(&sinkb->stream,
782 						      dev->frames);
783 
784 	if (sinkb->stream.size < sink_period_bytes) {
785 		comp_err(dev, "eq_iir_prepare(): sink buffer size %d is insufficient < %d",
786 			 sinkb->stream.size, sink_period_bytes);
787 		ret = -ENOMEM;
788 		goto err;
789 	}
790 
791 	cd->config = comp_get_data_blob(cd->model_handler, NULL, NULL);
792 
793 	/* Initialize EQ */
794 	comp_info(dev, "eq_iir_prepare(), source_format=%d, sink_format=%d",
795 		  source_format, sink_format);
796 	if (cd->config) {
797 		ret = eq_iir_setup(cd, sourceb->stream.channels);
798 		if (ret < 0) {
799 			comp_err(dev, "eq_iir_prepare(), setup failed.");
800 			goto err;
801 		}
802 		cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_configured,
803 						   ARRAY_SIZE(fm_configured));
804 		if (!cd->eq_iir_func) {
805 			comp_err(dev, "eq_iir_prepare(), No proc func");
806 			ret = -EINVAL;
807 			goto err;
808 		}
809 		comp_info(dev, "eq_iir_prepare(), IIR is configured.");
810 	} else {
811 		cd->eq_iir_func = eq_iir_find_func(source_format, sink_format, fm_passthrough,
812 						   ARRAY_SIZE(fm_passthrough));
813 		if (!cd->eq_iir_func) {
814 			comp_err(dev, "eq_iir_prepare(), No pass func");
815 			ret = -EINVAL;
816 			goto err;
817 		}
818 		comp_info(dev, "eq_iir_prepare(), pass-through mode.");
819 	}
820 	return 0;
821 
822 err:
823 	comp_set_state(dev, COMP_TRIGGER_RESET);
824 	return ret;
825 }
826 
eq_iir_reset(struct comp_dev * dev)827 static int eq_iir_reset(struct comp_dev *dev)
828 {
829 	int i;
830 	struct comp_data *cd = comp_get_drvdata(dev);
831 
832 	comp_info(dev, "eq_iir_reset()");
833 
834 	eq_iir_free_delaylines(cd);
835 
836 	cd->eq_iir_func = NULL;
837 	for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
838 		iir_reset_df2t(&cd->iir[i]);
839 
840 	comp_set_state(dev, COMP_TRIGGER_RESET);
841 	return 0;
842 }
843 
844 static const struct comp_driver comp_eq_iir = {
845 	.type = SOF_COMP_EQ_IIR,
846 	.uid = SOF_RT_UUID(eq_iir_uuid),
847 	.tctx = &eq_iir_tr,
848 	.ops = {
849 		.create = eq_iir_new,
850 		.free = eq_iir_free,
851 		.params = eq_iir_params,
852 		.cmd = eq_iir_cmd,
853 		.trigger = eq_iir_trigger,
854 		.copy = eq_iir_copy,
855 		.prepare = eq_iir_prepare,
856 		.reset = eq_iir_reset,
857 	},
858 };
859 
860 static SHARED_DATA struct comp_driver_info comp_eq_iir_info = {
861 	.drv = &comp_eq_iir,
862 };
863 
sys_comp_eq_iir_init(void)864 UT_STATIC void sys_comp_eq_iir_init(void)
865 {
866 	comp_register(platform_shared_get(&comp_eq_iir_info,
867 					  sizeof(comp_eq_iir_info)));
868 }
869 
870 DECLARE_MODULE(sys_comp_eq_iir_init);
871