1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2016 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/buffer.h>
10 #include <sof/audio/component.h>
11 #include <sof/audio/format.h>
12 #include <sof/audio/pipeline.h>
13 #include <sof/audio/ipc-config.h>
14 #include <sof/common.h>
15 #include <rtos/panic.h>
16 #include <sof/ipc/msg.h>
17 #include <rtos/alloc.h>
18 #include <rtos/init.h>
19 #include <sof/lib/memory.h>
20 #include <sof/lib/uuid.h>
21 #include <sof/list.h>
22 #include <sof/math/trig.h>
23 #include <sof/platform.h>
24 #include <rtos/string.h>
25 #include <sof/trace/trace.h>
26 #include <sof/ut.h>
27 #include <ipc/control.h>
28 #include <ipc/stream.h>
29 #include <ipc/topology.h>
30 #include <user/tone.h>
31 #include <user/trace.h>
32 #include <errno.h>
33 #include <stdbool.h>
34 #include <stddef.h>
35 #include <stdint.h>
36 
37 /* Convert float frequency in Hz to Q16.16 fractional format */
38 #define TONE_FREQ(f) Q_CONVERT_FLOAT(f, 16)
39 
40 /* Convert float gain to Q1.31 fractional format */
41 #define TONE_GAIN(v) Q_CONVERT_FLOAT(v, 31)
42 
43 /* Set default tone amplitude and frequency */
44 #define TONE_AMPLITUDE_DEFAULT TONE_GAIN(0.1)      /*  -20 dB  */
45 #define TONE_FREQUENCY_DEFAULT TONE_FREQ(997.0)
46 #define TONE_NUM_FS            13       /* Table size for 8-192 kHz range */
47 
48 static const struct comp_driver comp_tone;
49 
50 LOG_MODULE_REGISTER(tone, CONFIG_SOF_LOG_LEVEL);
51 
52 /* 04e3f894-2c5c-4f2e-8dc1-694eeaab53fa */
53 DECLARE_SOF_RT_UUID("tone", tone_uuid, 0x04e3f894, 0x2c5c, 0x4f2e,
54 		 0x8d, 0xc1, 0x69, 0x4e, 0xea, 0xab, 0x53, 0xfa);
55 
56 DECLARE_TR_CTX(tone_tr, SOF_UUID(tone_uuid), LOG_LEVEL_INFO);
57 
58 /* 2*pi/Fs lookup tables in Q1.31 for each Fs */
59 static const int32_t tone_fs_list[TONE_NUM_FS] = {
60 	8000, 11025, 16000, 22050, 24000, 32000, 44100, 48000,
61 	64000, 88200, 96000, 176400, 192000
62 };
63 
64 static const int32_t tone_pi2_div_fs[TONE_NUM_FS] = {
65 	1686630, 1223858, 843315, 611929, 562210, 421657, 305965,
66 	281105, 210829, 152982, 140552, 76491, 70276
67 };
68 
69 /* tone component private data */
70 
71 struct tone_state {
72 	int mute;
73 	int32_t a; /* Current amplitude Q1.31 */
74 	int32_t a_target; /* Target amplitude Q1.31 */
75 	int32_t ampl_coef; /* Amplitude multiplier Q2.30 */
76 	int32_t c; /* Coefficient 2*pi/Fs Q1.31 */
77 	int32_t f; /* Frequency Q16.16 */
78 	int32_t freq_coef; /* Frequency multiplier Q2.30 */
79 	int32_t fs; /* Sample rate in Hertz Q32.0 */
80 	int32_t ramp_step; /* Amplitude ramp step Q1.31 */
81 	int32_t w; /* Angle radians Q4.28 */
82 	int32_t w_step; /* Angle step Q4.28 */
83 	uint32_t block_count;
84 	uint32_t repeat_count;
85 	uint32_t repeats; /* Number of repeats for tone (sweep steps) */
86 	uint32_t sample_count;
87 	uint32_t samples_in_block; /* Samples in 125 us block */
88 	uint32_t tone_length; /* Active length in 125 us blocks */
89 	uint32_t tone_period; /* Active + idle time in 125 us blocks */
90 };
91 
92 struct comp_data {
93 	uint32_t period_bytes;
94 	uint32_t channels;
95 	uint32_t frame_bytes;
96 	uint32_t rate;
97 	struct tone_state sg[PLATFORM_MAX_CHANNELS];
98 	void (*tone_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink,
99 			  uint32_t frames);
100 };
101 
102 static int32_t tonegen(struct tone_state *sg);
103 static void tonegen_control(struct tone_state *sg);
104 static void tonegen_update_f(struct tone_state *sg, int32_t f);
105 
106 /*
107  * Tone generator algorithm code
108  */
109 
tone_circ_inc_wrap(int32_t ** ptr,int32_t * end,size_t size)110 static inline void tone_circ_inc_wrap(int32_t **ptr, int32_t *end, size_t size)
111 {
112 	if (*ptr >= end)
113 		*ptr = (int32_t *)((size_t)*ptr - size);
114 }
115 
tone_s32_default(struct comp_dev * dev,struct audio_stream __sparse_cache * sink,uint32_t frames)116 static void tone_s32_default(struct comp_dev *dev, struct audio_stream __sparse_cache *sink,
117 			     uint32_t frames)
118 {
119 	struct comp_data *cd = comp_get_drvdata(dev);
120 	int32_t *dest = (int32_t *)sink->w_ptr;
121 	int i;
122 	int n;
123 	int n_wrap_dest;
124 	int n_min;
125 	int nch = cd->channels;
126 
127 	n = frames * nch;
128 	while (n > 0) {
129 		n_wrap_dest = (int32_t *)sink->end_addr - dest;
130 		n_min = (n < n_wrap_dest) ? n : n_wrap_dest;
131 		/* Process until wrap or completed n */
132 		while (n_min > 0) {
133 			n -= nch;
134 			n_min -= nch;
135 			for (i = 0; i < nch; i++) {
136 				tonegen_control(&cd->sg[i]);
137 				*dest = tonegen(&cd->sg[i]);
138 				dest++;
139 			}
140 		}
141 		tone_circ_inc_wrap(&dest, sink->end_addr, sink->size);
142 	}
143 }
144 
tonegen(struct tone_state * sg)145 static int32_t tonegen(struct tone_state *sg)
146 {
147 	int64_t sine;
148 	int64_t w;
149 	/* sg->w is angle in Q4.28 radians format, sin() returns Q1.31 */
150 	/* sg->a is amplitude as Q1.31 */
151 	sine =
152 		q_mults_32x32(sin_fixed_32b(sg->w), sg->a,
153 			      Q_SHIFT_BITS_64(31, 31, 31));
154 
155 	/* Next point */
156 	w = (int64_t)sg->w + sg->w_step;
157 	sg->w = (w > PI_MUL2_Q4_28)
158 		? (int32_t)(w - PI_MUL2_Q4_28) : (int32_t)w;
159 
160 	if (sg->mute)
161 		return 0;
162 	else
163 		return (int32_t)sine; /* Q1.31 no saturation need */
164 }
165 
tonegen_control(struct tone_state * sg)166 static void tonegen_control(struct tone_state *sg)
167 {
168 	int64_t a;
169 	int64_t p;
170 
171 	/* Count samples, 125 us blocks */
172 	sg->sample_count++;
173 	if (sg->sample_count < sg->samples_in_block)
174 		return;
175 
176 	sg->sample_count = 0;
177 	if (sg->block_count < INT32_MAX)
178 		sg->block_count++;
179 
180 	/* Fade-in ramp during tone */
181 	if (sg->block_count < sg->tone_length) {
182 		if (sg->a == 0)
183 			sg->w = 0; /* Reset phase to have less clicky ramp */
184 
185 		if (sg->a > sg->a_target) {
186 			a = (int64_t)sg->a - sg->ramp_step;
187 			if (a < sg->a_target)
188 				a = sg->a_target;
189 
190 		} else {
191 			a = (int64_t)sg->a + sg->ramp_step;
192 			if (a > sg->a_target)
193 				a = sg->a_target;
194 		}
195 		sg->a = (int32_t)a;
196 	}
197 
198 	/* Fade-out ramp after tone*/
199 	if (sg->block_count > sg->tone_length) {
200 		a = (int64_t)sg->a - sg->ramp_step;
201 		if (a < 0)
202 			a = 0;
203 
204 		sg->a = (int32_t)a;
205 	}
206 
207 	/* New repeated tone, update for frequency or amplitude sweep */
208 	if ((sg->block_count > sg->tone_period) &&
209 	    (sg->repeat_count + 1 < sg->repeats)) {
210 		sg->block_count = 0;
211 		if (sg->ampl_coef > 0) {
212 			sg->a_target =
213 				sat_int32(q_multsr_32x32(sg->a_target,
214 				sg->ampl_coef, Q_SHIFT_BITS_64(31, 30, 31)));
215 			sg->a = (sg->ramp_step > sg->a_target)
216 				? sg->a_target : sg->ramp_step;
217 		}
218 		if (sg->freq_coef > 0) {
219 			/* f is Q16.16, freq_coef is Q2.30 */
220 			p = q_multsr_32x32(sg->f, sg->freq_coef,
221 				Q_SHIFT_BITS_64(16, 30, 16));
222 			tonegen_update_f(sg, (int32_t)p); /* No saturation */
223 		}
224 		sg->repeat_count++;
225 	}
226 }
227 
228 /* Set sine amplitude */
tonegen_set_a(struct tone_state * sg,int32_t a)229 static inline void tonegen_set_a(struct tone_state *sg, int32_t a)
230 {
231 	sg->a_target = a;
232 }
233 
234 /* Repeated number of beeps */
tonegen_set_repeats(struct tone_state * sg,uint32_t r)235 static void tonegen_set_repeats(struct tone_state *sg, uint32_t r)
236 {
237 	sg->repeats = r;
238 }
239 
240 /* The next functions support zero as shortcut for defaults to get
241  * make a nicer API without need to remember the neutral steady
242  * non-swept tone settings.
243  */
244 
245 /* Multiplication factor for frequency as Q2.30 for logarithmic change */
tonegen_set_freq_mult(struct tone_state * sg,int32_t fm)246 static void tonegen_set_freq_mult(struct tone_state *sg, int32_t fm)
247 {
248 	sg->freq_coef = (fm > 0) ? fm : ONE_Q2_30; /* Set freq mult to 1.0 */
249 }
250 
251 /* Multiplication factor for amplitude as Q2.30 for logarithmic change */
tonegen_set_ampl_mult(struct tone_state * sg,int32_t am)252 static void tonegen_set_ampl_mult(struct tone_state *sg, int32_t am)
253 {
254 	sg->ampl_coef = (am > 0) ? am : ONE_Q2_30; /* Set ampl mult to 1.0 */
255 }
256 
257 /* Tone length in samples, this is the active length of tone */
tonegen_set_length(struct tone_state * sg,uint32_t tl)258 static void tonegen_set_length(struct tone_state *sg, uint32_t tl)
259 {
260 	sg->tone_length = (tl > 0) ? tl : INT32_MAX; /* Count rate 125 us */
261 }
262 
263 /* Tone period in samples, this is the length including the pause after beep */
tonegen_set_period(struct tone_state * sg,uint32_t tp)264 static void tonegen_set_period(struct tone_state *sg, uint32_t tp)
265 {
266 	sg->tone_period = (tp > 0) ? tp : INT32_MAX; /* Count rate 125 us */
267 }
268 
269 /* Tone ramp parameters:
270  * step - Value that is added or subtracted to amplitude. A zero or negative
271  *        number disables the ramp and amplitude is immediately modified to
272  *        final value.
273  */
274 
tonegen_set_linramp(struct tone_state * sg,int32_t step)275 static inline void tonegen_set_linramp(struct tone_state *sg, int32_t step)
276 {
277 	sg->ramp_step = (step > 0) ? step : INT32_MAX;
278 }
279 
tonegen_get_f(struct tone_state * sg)280 static inline int32_t tonegen_get_f(struct tone_state *sg)
281 {
282 	return sg->f;
283 }
284 
tonegen_get_a(struct tone_state * sg)285 static inline int32_t tonegen_get_a(struct tone_state *sg)
286 {
287 	return sg->a_target;
288 }
289 
tonegen_mute(struct tone_state * sg)290 static inline void tonegen_mute(struct tone_state *sg)
291 {
292 	sg->mute = 1;
293 }
294 
tonegen_unmute(struct tone_state * sg)295 static inline void tonegen_unmute(struct tone_state *sg)
296 {
297 	sg->mute = 0;
298 }
299 
tonegen_update_f(struct tone_state * sg,int32_t f)300 static void tonegen_update_f(struct tone_state *sg, int32_t f)
301 {
302 	int64_t w_tmp;
303 	int64_t f_max;
304 
305 	/* Calculate Fs/2, fs is Q32.0, f is Q16.16 */
306 	f_max = Q_SHIFT_LEFT((int64_t)sg->fs, 0, 16 - 1);
307 	f_max = (f_max > INT32_MAX) ? INT32_MAX : f_max;
308 	sg->f = (f > f_max) ? f_max : f;
309 	/* Q16 x Q31 -> Q28 */
310 	w_tmp = q_multsr_32x32(sg->f, sg->c, Q_SHIFT_BITS_64(16, 31, 28));
311 	w_tmp = (w_tmp > PI_Q4_28) ? PI_Q4_28 : w_tmp; /* Limit to pi Q4.28 */
312 	sg->w_step = (int32_t)w_tmp;
313 }
314 
tonegen_reset(struct tone_state * sg)315 static void tonegen_reset(struct tone_state *sg)
316 {
317 	sg->mute = 1;
318 	sg->a = 0;
319 	sg->a_target = TONE_AMPLITUDE_DEFAULT;
320 	sg->c = 0;
321 	sg->f = TONE_FREQUENCY_DEFAULT;
322 	sg->w = 0;
323 	sg->w_step = 0;
324 
325 	sg->block_count = 0;
326 	sg->repeat_count = 0;
327 	sg->repeats = 0;
328 	sg->sample_count = 0;
329 	sg->samples_in_block = 0;
330 
331 	/* Continuous tone */
332 	sg->freq_coef = ONE_Q2_30; /* Set freq multiplier to 1.0 */
333 	sg->ampl_coef = ONE_Q2_30; /* Set ampl multiplier to 1.0 */
334 	sg->tone_length = INT32_MAX;
335 	sg->tone_period = INT32_MAX;
336 	sg->ramp_step = ONE_Q1_31; /* Set lin ramp modification to max */
337 }
338 
tonegen_init(struct tone_state * sg,int32_t fs,int32_t f,int32_t a)339 static int tonegen_init(struct tone_state *sg, int32_t fs, int32_t f, int32_t a)
340 {
341 	int idx;
342 	int i;
343 
344 	sg->a_target = a;
345 	sg->a = (sg->ramp_step > sg->a_target) ? sg->a_target : sg->ramp_step;
346 
347 	idx = -1;
348 	sg->mute = 1;
349 	sg->fs = 0;
350 
351 	/* Find index of current sample rate and then get from lookup table the
352 	 * corresponding 2*pi/Fs value.
353 	 */
354 	for (i = 0; i < TONE_NUM_FS; i++) {
355 		if (fs == tone_fs_list[i])
356 			idx = i;
357 	}
358 
359 	if (idx < 0) {
360 		sg->w_step = 0;
361 		return -EINVAL;
362 	}
363 
364 	sg->fs = fs;
365 	sg->c = tone_pi2_div_fs[idx]; /* Store 2*pi/Fs */
366 	sg->mute = 0;
367 	tonegen_update_f(sg, f);
368 
369 	/* 125us as Q1.31 is 268435, calculate fs * 125e-6 in Q31.0  */
370 	sg->samples_in_block =
371 		(int32_t) q_multsr_32x32(fs, 268435, Q_SHIFT_BITS_64(0, 31, 0));
372 
373 	return 0;
374 }
375 
376 /*
377  * End of algorithm code. Next the standard component methods.
378  */
379 
tone_new(const struct comp_driver * drv,const struct comp_ipc_config * config,const void * spec)380 static struct comp_dev *tone_new(const struct comp_driver *drv,
381 				 const struct comp_ipc_config *config,
382 				 const void *spec)
383 {
384 	struct comp_dev *dev;
385 	const struct ipc_config_tone *ipc_tone = spec;
386 	struct comp_data *cd;
387 	int i;
388 
389 	comp_cl_info(&comp_tone, "tone_new()");
390 
391 	dev = comp_alloc(drv, sizeof(*dev));
392 	if (!dev)
393 		return NULL;
394 	dev->ipc_config = *config;
395 
396 	cd = rzalloc(SOF_MEM_ZONE_RUNTIME, 0, SOF_MEM_CAPS_RAM, sizeof(*cd));
397 	if (!cd) {
398 		rfree(dev);
399 		return NULL;
400 	}
401 
402 	comp_set_drvdata(dev, cd);
403 	cd->tone_func = tone_s32_default;
404 
405 	cd->rate = ipc_tone->sample_rate;
406 
407 	/* Reset tone generator and set channels volumes to default */
408 	for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
409 		tonegen_reset(&cd->sg[i]);
410 
411 	dev->state = COMP_STATE_READY;
412 	return dev;
413 }
414 
tone_free(struct comp_dev * dev)415 static void tone_free(struct comp_dev *dev)
416 {
417 	struct tone_data *td = comp_get_drvdata(dev);
418 
419 	comp_info(dev, "tone_free()");
420 
421 	rfree(td);
422 	rfree(dev);
423 }
424 
425 /* set component audio stream parameters */
tone_params(struct comp_dev * dev,struct sof_ipc_stream_params * params)426 static int tone_params(struct comp_dev *dev,
427 		       struct sof_ipc_stream_params *params)
428 {
429 	struct comp_data *cd = comp_get_drvdata(dev);
430 	struct comp_buffer *sourceb, *sinkb;
431 	struct comp_buffer __sparse_cache *source_c, *sink_c;
432 
433 	sourceb = list_first_item(&dev->bsource_list, struct comp_buffer,
434 				  sink_list);
435 
436 	sinkb = list_first_item(&dev->bsink_list, struct comp_buffer,
437 				source_list);
438 
439 	comp_info(dev, "tone_params(), config->frame_fmt = %u",
440 		  dev->ipc_config.frame_fmt);
441 
442 	/* Tone supports only S32_LE PCM format atm */
443 	if (dev->ipc_config.frame_fmt != SOF_IPC_FRAME_S32_LE)
444 		return -EINVAL;
445 
446 	source_c = buffer_acquire(sourceb);
447 	sink_c = buffer_acquire(sinkb);
448 
449 	source_c->stream.frame_fmt = dev->ipc_config.frame_fmt;
450 	sink_c->stream.frame_fmt = dev->ipc_config.frame_fmt;
451 
452 	/* calculate period size based on config */
453 	cd->period_bytes = dev->frames *
454 			   audio_stream_frame_bytes(&source_c->stream);
455 
456 	buffer_release(sink_c);
457 	buffer_release(source_c);
458 
459 	return 0;
460 }
461 
tone_cmd_get_value(struct comp_dev * dev,struct sof_ipc_ctrl_data * cdata,int max_size)462 static int tone_cmd_get_value(struct comp_dev *dev,
463 			      struct sof_ipc_ctrl_data *cdata, int max_size)
464 {
465 	struct comp_data *cd = comp_get_drvdata(dev);
466 	int j;
467 
468 	comp_info(dev, "tone_cmd_get_value()");
469 
470 	if (cdata->type != SOF_CTRL_TYPE_VALUE_CHAN_GET) {
471 		comp_err(dev, "tone_cmd_get_value(): wrong cdata->type: %u",
472 			 cdata->type);
473 		return -EINVAL;
474 	}
475 
476 	if (cdata->cmd == SOF_CTRL_CMD_SWITCH) {
477 		for (j = 0; j < cdata->num_elems; j++) {
478 			cdata->chanv[j].channel = j;
479 			cdata->chanv[j].value = !cd->sg[j].mute;
480 			comp_info(dev, "tone_cmd_get_value(), j = %u, cd->sg[j].mute = %u",
481 				  j, cd->sg[j].mute);
482 		}
483 	}
484 	return 0;
485 }
486 
tone_cmd_set_value(struct comp_dev * dev,struct sof_ipc_ctrl_data * cdata)487 static int tone_cmd_set_value(struct comp_dev *dev,
488 			      struct sof_ipc_ctrl_data *cdata)
489 {
490 	struct comp_data *cd = comp_get_drvdata(dev);
491 	int j;
492 	uint32_t ch;
493 	bool val;
494 
495 	if (cdata->type != SOF_CTRL_TYPE_VALUE_CHAN_SET) {
496 		comp_err(dev, "tone_cmd_set_value(): wrong cdata->type: %u",
497 			 cdata->type);
498 		return -EINVAL;
499 	}
500 
501 	if (cdata->cmd == SOF_CTRL_CMD_SWITCH) {
502 		comp_info(dev, "tone_cmd_set_value(), SOF_CTRL_CMD_SWITCH");
503 		for (j = 0; j < cdata->num_elems; j++) {
504 			ch = cdata->chanv[j].channel;
505 			val = cdata->chanv[j].value;
506 			comp_info(dev, "tone_cmd_set_value(), SOF_CTRL_CMD_SWITCH, ch = %u, val = %u",
507 				  ch, val);
508 			if (ch >= PLATFORM_MAX_CHANNELS) {
509 				comp_err(dev, "tone_cmd_set_value(): ch >= PLATFORM_MAX_CHANNELS");
510 				return -EINVAL;
511 			}
512 
513 			if (val)
514 				tonegen_unmute(&cd->sg[ch]);
515 			else
516 				tonegen_mute(&cd->sg[ch]);
517 		}
518 	} else {
519 		comp_err(dev, "tone_cmd_set_value(): invalid cdata->cmd");
520 		return -EINVAL;
521 	}
522 
523 	return 0;
524 }
525 
tone_cmd_set_data(struct comp_dev * dev,struct sof_ipc_ctrl_data * cdata)526 static int tone_cmd_set_data(struct comp_dev *dev,
527 			     struct sof_ipc_ctrl_data *cdata)
528 {
529 	struct comp_data *cd = comp_get_drvdata(dev);
530 	struct sof_ipc_ctrl_value_comp *compv;
531 	int i;
532 	uint32_t ch;
533 	uint32_t val;
534 
535 	comp_info(dev, "tone_cmd_set_data()");
536 
537 	if (cdata->type != SOF_CTRL_TYPE_VALUE_COMP_SET) {
538 		comp_err(dev, "tone_cmd_set_data(): wrong cdata->type: %u",
539 			 cdata->type);
540 		return -EINVAL;
541 	}
542 
543 	switch (cdata->cmd) {
544 	case SOF_CTRL_CMD_ENUM:
545 		comp_info(dev, "tone_cmd_set_data(), SOF_CTRL_CMD_ENUM, cdata->index = %u",
546 			  cdata->index);
547 		compv = (struct sof_ipc_ctrl_value_comp *)ASSUME_ALIGNED(&cdata->data->data, 4);
548 
549 		for (i = 0; i < (int)cdata->num_elems; i++) {
550 			ch = compv[i].index;
551 			val = compv[i].svalue;
552 			comp_info(dev, "tone_cmd_set_data(), SOF_CTRL_CMD_ENUM, ch = %u, val = %u",
553 				  ch, val);
554 			switch (cdata->index) {
555 			case SOF_TONE_IDX_FREQUENCY:
556 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_FREQUENCY");
557 				tonegen_update_f(&cd->sg[ch], val);
558 				break;
559 			case SOF_TONE_IDX_AMPLITUDE:
560 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_AMPLITUDE");
561 				tonegen_set_a(&cd->sg[ch], val);
562 				break;
563 			case SOF_TONE_IDX_FREQ_MULT:
564 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_FREQ_MULT");
565 				tonegen_set_freq_mult(&cd->sg[ch], val);
566 				break;
567 			case SOF_TONE_IDX_AMPL_MULT:
568 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_AMPL_MULT");
569 				tonegen_set_ampl_mult(&cd->sg[ch], val);
570 				break;
571 			case SOF_TONE_IDX_LENGTH:
572 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_LENGTH");
573 				tonegen_set_length(&cd->sg[ch], val);
574 				break;
575 			case SOF_TONE_IDX_PERIOD:
576 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_PERIOD");
577 				tonegen_set_period(&cd->sg[ch], val);
578 				break;
579 			case SOF_TONE_IDX_REPEATS:
580 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_REPEATS");
581 				tonegen_set_repeats(&cd->sg[ch], val);
582 				break;
583 			case SOF_TONE_IDX_LIN_RAMP_STEP:
584 				comp_info(dev, "tone_cmd_set_data(), SOF_TONE_IDX_LIN_RAMP_STEP");
585 				tonegen_set_linramp(&cd->sg[ch], val);
586 				break;
587 			default:
588 				comp_err(dev, "tone_cmd_set_data(): invalid cdata->index");
589 				return -EINVAL;
590 			}
591 		}
592 		break;
593 	default:
594 		comp_err(dev, "tone_cmd_set_data(): invalid cdata->cmd");
595 		return -EINVAL;
596 	}
597 
598 	return 0;
599 }
600 
601 /* used to pass standard and bespoke commands (with data) to component */
tone_cmd(struct comp_dev * dev,int cmd,void * data,int max_data_size)602 static int tone_cmd(struct comp_dev *dev, int cmd, void *data,
603 		    int max_data_size)
604 {
605 	struct sof_ipc_ctrl_data *cdata = ASSUME_ALIGNED(data, 4);
606 	int ret = 0;
607 
608 	comp_info(dev, "tone_cmd()");
609 
610 	switch (cmd) {
611 	case COMP_CMD_SET_DATA:
612 		ret = tone_cmd_set_data(dev, cdata);
613 		break;
614 	case COMP_CMD_SET_VALUE:
615 		ret = tone_cmd_set_value(dev, cdata);
616 		break;
617 	case COMP_CMD_GET_VALUE:
618 		ret = tone_cmd_get_value(dev, cdata, max_data_size);
619 		break;
620 	}
621 
622 	return ret;
623 }
624 
tone_trigger(struct comp_dev * dev,int cmd)625 static int tone_trigger(struct comp_dev *dev, int cmd)
626 {
627 	comp_info(dev, "tone_trigger()");
628 
629 	return comp_set_state(dev, cmd);
630 }
631 
632 /* copy and process stream data from source to sink buffers */
tone_copy(struct comp_dev * dev)633 static int tone_copy(struct comp_dev *dev)
634 {
635 	struct comp_buffer *sink;
636 	struct comp_buffer __sparse_cache *sink_c;
637 	struct comp_data *cd = comp_get_drvdata(dev);
638 	uint32_t free;
639 	int ret = 0;
640 
641 	comp_dbg(dev, "tone_copy()");
642 
643 	/* tone component sink buffer */
644 	sink = list_first_item(&dev->bsink_list, struct comp_buffer,
645 			       source_list);
646 
647 	sink_c = buffer_acquire(sink);
648 	free = audio_stream_get_free_bytes(&sink_c->stream);
649 
650 	/* Test that sink has enough free frames. Then run once to maintain
651 	 * low latency and steady load for tones.
652 	 */
653 	if (free >= cd->period_bytes) {
654 		/* create tone */
655 		cd->tone_func(dev, &sink_c->stream, dev->frames);
656 		buffer_stream_writeback(sink_c, cd->period_bytes);
657 
658 		/* calc new free and available */
659 		comp_update_buffer_produce(sink_c, cd->period_bytes);
660 
661 		ret = dev->frames;
662 	}
663 
664 	buffer_release(sink_c);
665 
666 	return ret;
667 }
668 
tone_prepare(struct comp_dev * dev)669 static int tone_prepare(struct comp_dev *dev)
670 {
671 	struct comp_data *cd = comp_get_drvdata(dev);
672 	struct comp_buffer *sourceb;
673 	int32_t f;
674 	int32_t a;
675 	int ret;
676 	int i;
677 
678 	comp_info(dev, "tone_prepare()");
679 
680 	ret = comp_set_state(dev, COMP_TRIGGER_PREPARE);
681 	if (ret < 0)
682 		return ret;
683 
684 	if (ret == COMP_STATUS_STATE_ALREADY_SET)
685 		return PPL_STATUS_PATH_STOP;
686 
687 	sourceb = list_first_item(&dev->bsource_list, struct comp_buffer,
688 				  sink_list);
689 
690 	cd->channels = sourceb->stream.channels;
691 	comp_info(dev, "tone_prepare(), cd->channels = %u, cd->rate = %u",
692 		  cd->channels, cd->rate);
693 
694 	for (i = 0; i < cd->channels; i++) {
695 		f = tonegen_get_f(&cd->sg[i]);
696 		a = tonegen_get_a(&cd->sg[i]);
697 		if (tonegen_init(&cd->sg[i], cd->rate, f, a) < 0) {
698 			comp_set_state(dev, COMP_TRIGGER_RESET);
699 			return -EINVAL;
700 		}
701 	}
702 
703 	return 0;
704 }
705 
tone_reset(struct comp_dev * dev)706 static int tone_reset(struct comp_dev *dev)
707 {
708 	struct comp_data *cd = comp_get_drvdata(dev);
709 	int i;
710 
711 	comp_info(dev, "tone_reset()");
712 
713 	/* Initialize with the defaults */
714 	for (i = 0; i < PLATFORM_MAX_CHANNELS; i++)
715 		tonegen_reset(&cd->sg[i]);
716 
717 	comp_set_state(dev, COMP_TRIGGER_RESET);
718 
719 	return 0;
720 }
721 
722 static const struct comp_driver comp_tone = {
723 	.type = SOF_COMP_TONE,
724 	.uid = SOF_RT_UUID(tone_uuid),
725 	.tctx = &tone_tr,
726 	.ops = {
727 		.create = tone_new,
728 		.free = tone_free,
729 		.params = tone_params,
730 		.cmd = tone_cmd,
731 		.trigger = tone_trigger,
732 		.copy = tone_copy,
733 		.prepare = tone_prepare,
734 		.reset = tone_reset,
735 	},
736 };
737 
738 static SHARED_DATA struct comp_driver_info comp_tone_info = {
739 	.drv = &comp_tone,
740 };
741 
sys_comp_tone_init(void)742 UT_STATIC void sys_comp_tone_init(void)
743 {
744 	comp_register(platform_shared_get(&comp_tone_info,
745 					  sizeof(comp_tone_info)));
746 }
747 
748 DECLARE_MODULE(sys_comp_tone_init);
749 SOF_MODULE_INIT(tone, sys_comp_tone_init);
750