1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2020 Intel Corporation. All rights reserved.
4  *
5  * Author: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
6  */
7 
8 #ifndef __SOF_AUDIO_TDFB_CONFIG_H__
9 #define __SOF_AUDIO_TDFB_CONFIG_H__
10 
11 #include <sof/platform.h>
12 #include <sof/audio/audio_stream.h>
13 #include <sof/math/fir_generic.h>
14 #include <sof/math/fir_hifi2ep.h>
15 #include <sof/math/fir_hifi3.h>
16 #include <user/tdfb.h>
17 
18 /* Select optimized code variant when xt-xcc compiler is used */
19 #if defined __XCC__
20 #include <xtensa/config/core-isa.h>
21 #if XCHAL_HAVE_HIFI2EP == 1
22 #define TDFB_GENERIC	0
23 #define TDFB_HIFIEP	1
24 #define TDFB_HIFI3	0
25 #elif XCHAL_HAVE_HIFI3 == 1
26 #define TDFB_HIFI3	1
27 #define TDFB_HIFIEP	0
28 #define TDFB_GENERIC	0
29 #else
30 #error "No HIFIEP or HIFI3 found. Cannot build TDFB module."
31 #endif
32 #else
33 /* GCC */
34 #define TDFB_GENERIC	1
35 #define TDFB_HIFIEP	0
36 #define TDFB_HIFI3	0
37 #endif
38 
39 #define TDFB_IN_BUF_LENGTH (2 * PLATFORM_MAX_CHANNELS)
40 #define TDFB_OUT_BUF_LENGTH (2 * PLATFORM_MAX_CHANNELS)
41 
42 /* When set to one only one IPC is sent to host. There is not other requests
43  * triggered. If set to zero the IPC sent will be empty and the driver will
44  * issue an actual control get. In simple  case with known # of control channels
45  * including is more efficient.
46  */
47 #define TDFB_ADD_DIRECTION_TO_GET_CMD 1
48 
49 /* Allocate size is header plus single control value */
50 #define TDFB_GET_CTRL_DATA_SIZE (sizeof(struct sof_ipc_ctrl_data) + \
51 	sizeof(struct sof_ipc_ctrl_value_chan))
52 
53 /* TDFB component private data */
54 
55 struct tdfb_comp_data {
56 	struct fir_state_32x16 fir[SOF_TDFB_FIR_MAX_COUNT]; /**< FIR state */
57 	struct comp_data_blob_handler *model_handler;
58 	struct sof_tdfb_config *config;	    /**< pointer to setup blob */
59 	struct sof_tdfb_angle *filter_angles;
60 	struct sof_tdfb_mic_location *mic_locations;
61 	struct sof_ipc_ctrl_data *ctrl_data;
62 	struct ipc_msg *msg;
63 	int32_t in[TDFB_IN_BUF_LENGTH];	    /**< input samples buffer */
64 	int32_t out[TDFB_IN_BUF_LENGTH];    /**< output samples mix buffer */
65 	int32_t *fir_delay;		    /**< pointer to allocated RAM */
66 	int16_t *input_channel_select;	    /**< For each FIR define in ch */
67 	int16_t *output_channel_mix;	    /**< For each FIR define out ch */
68 	int16_t *output_stream_mix;         /**< for each FIR define stream */
69 	int16_t az_value;		    /**< beam steer azimuth as in control enum */
70 	int16_t az_value_estimate;	    /**< beam steer azimuth as in control enum */
71 	size_t fir_delay_size;              /**< allocated size */
72 	int direction_updates:1;	    /**< set true if direction angle control is updated */
73 	int direction_change:1;		    /**< set if direction value has significant change */
74 	int beam_on:1;			    /**< set true if beam is off */
75 	int update:1;			    /**< set true if control enum has been received */
76 	void (*tdfb_func)(struct tdfb_comp_data *cd,
77 			  const struct audio_stream *source,
78 			  struct audio_stream *sink,
79 			  int frames);
80 };
81 
82 #if CONFIG_FORMAT_S16LE
83 void tdfb_fir_s16(struct tdfb_comp_data *cd,
84 		  const struct audio_stream *source,
85 		  struct audio_stream *sink, int frames);
86 #endif
87 
88 #if CONFIG_FORMAT_S24LE
89 void tdfb_fir_s24(struct tdfb_comp_data *cd,
90 		  const struct audio_stream *source,
91 		  struct audio_stream *sink, int frames);
92 #endif
93 
94 #if CONFIG_FORMAT_S32LE
95 void tdfb_fir_s32(struct tdfb_comp_data *cd,
96 		  const struct audio_stream *source,
97 		  struct audio_stream *sink, int frames);
98 #endif
99 
100 #endif /* __SOF_AUDIO_EQ_FIR_FIR_CONFIG_H__ */
101