@@ -63,20 +63,124 @@ struct comp_data {
6363 uint32_t period_bytes ;
6464 int32_t * fir_delay ;
6565 size_t fir_delay_size ;
66+ void (* eq_fir_func_even )(struct fir_state_32x16 fir [],
67+ struct comp_buffer * source ,
68+ struct comp_buffer * sink ,
69+ int frames , int nch );
6670 void (* eq_fir_func )(struct fir_state_32x16 fir [],
6771 struct comp_buffer * source ,
6872 struct comp_buffer * sink ,
6973 int frames , int nch );
70- void (* eq_fir_func_odd )(struct fir_state_32x16 fir [],
71- struct comp_buffer * source ,
72- struct comp_buffer * sink ,
73- int frames , int nch );
7474};
7575
76- static void eq_fir_passthrough (struct fir_state_32x16 fir [],
77- struct comp_buffer * source ,
78- struct comp_buffer * sink ,
79- int frames , int nch )
76+ /* The optimized FIR functions variants need to be updated into function
77+ * set_fir_func. The cd->eq_fir_func is a function that can process any
78+ * number of samples. The cd->eq_fir_func_even is for optimized version
79+ * that is guaranteed to be called with even samples number.
80+ */
81+
82+ #if FIR_HIFI3
83+ static inline void set_s16_fir (struct comp_data * cd )
84+ {
85+ cd -> eq_fir_func_even = eq_fir_2x_s16_hifi3 ;
86+ cd -> eq_fir_func = eq_fir_s16_hifi3 ;
87+ }
88+
89+ static inline void set_s24_fir (struct comp_data * cd )
90+ {
91+ cd -> eq_fir_func_even = eq_fir_2x_s24_hifi3 ;
92+ cd -> eq_fir_func = eq_fir_s24_hifi3 ;
93+ }
94+
95+ static inline void set_s32_fir (struct comp_data * cd )
96+ {
97+ cd -> eq_fir_func_even = eq_fir_2x_s32_hifi3 ;
98+ cd -> eq_fir_func = eq_fir_s32_hifi3 ;
99+ }
100+ #elif FIR_HIFIEP
101+ static inline void set_s16_fir (struct comp_data * cd )
102+ {
103+ cd -> eq_fir_func_even = eq_fir_2x_s16_hifiep ;
104+ cd -> eq_fir_func = eq_fir_s16_hifiep ;
105+ }
106+
107+ static inline void set_s24_fir (struct comp_data * cd )
108+ {
109+ cd -> eq_fir_func_even = eq_fir_2x_s24_hifiep ;
110+ cd -> eq_fir_func = eq_fir_s24_hifiep ;
111+ }
112+
113+ static inline void set_s32_fir (struct comp_data * cd )
114+ {
115+ cd -> eq_fir_func_even = eq_fir_2x_s32_hifiep ;
116+ cd -> eq_fir_func = eq_fir_s32_hifiep ;
117+ }
118+ #else
119+ /* FIR_GENERIC */
120+ static inline void set_s16_fir (struct comp_data * cd )
121+ {
122+ cd -> eq_fir_func_even = eq_fir_s16 ;
123+ cd -> eq_fir_func = eq_fir_s16 ;
124+ }
125+
126+ static inline void set_s24_fir (struct comp_data * cd )
127+ {
128+ cd -> eq_fir_func_even = eq_fir_s24 ;
129+ cd -> eq_fir_func = eq_fir_s24 ;
130+ }
131+
132+ static inline void set_s32_fir (struct comp_data * cd )
133+ {
134+ cd -> eq_fir_func_even = eq_fir_s32 ;
135+ cd -> eq_fir_func = eq_fir_s32 ;
136+ }
137+ #endif
138+
139+ static inline int set_fir_func (struct comp_dev * dev )
140+ {
141+ struct comp_data * cd = comp_get_drvdata (dev );
142+ struct sof_ipc_comp_config * config = COMP_GET_CONFIG (dev );
143+
144+ switch (config -> frame_fmt ) {
145+ case SOF_IPC_FRAME_S16_LE :
146+ trace_eq ("f16" );
147+ set_s16_fir (cd );
148+ break ;
149+ case SOF_IPC_FRAME_S24_4LE :
150+ trace_eq ("f24" );
151+ set_s24_fir (cd );
152+ break ;
153+ case SOF_IPC_FRAME_S32_LE :
154+ trace_eq ("f32" );
155+ set_s32_fir (cd );
156+ break ;
157+ default :
158+ trace_eq_error ("eef" );
159+ return - EINVAL ;
160+ }
161+ return 0 ;
162+ }
163+
164+ /* Pass-trough functions to replace FIR core while not configured for
165+ * response.
166+ */
167+
168+ static void eq_fir_s16_passthrough (struct fir_state_32x16 fir [],
169+ struct comp_buffer * source ,
170+ struct comp_buffer * sink ,
171+ int frames , int nch )
172+ {
173+ int16_t * src = (int16_t * )source -> r_ptr ;
174+ int16_t * dest = (int16_t * )sink -> w_ptr ;
175+ int n = frames * nch ;
176+
177+ memcpy (dest , src , n * sizeof (int16_t ));
178+ }
179+
180+ static void eq_fir_s32_passthrough (struct fir_state_32x16 fir [],
181+ struct comp_buffer * source ,
182+ struct comp_buffer * sink ,
183+ int frames , int nch )
80184{
81185 int32_t * src = (int32_t * )source -> r_ptr ;
82186 int32_t * dest = (int32_t * )sink -> w_ptr ;
@@ -85,6 +189,32 @@ static void eq_fir_passthrough(struct fir_state_32x16 fir[],
85189 memcpy (dest , src , n * sizeof (int32_t ));
86190}
87191
192+ /* Function to select pass-trough depending on PCM format */
193+
194+ static inline int set_pass_func (struct comp_dev * dev )
195+ {
196+ struct comp_data * cd = comp_get_drvdata (dev );
197+ struct sof_ipc_comp_config * config = COMP_GET_CONFIG (dev );
198+
199+ switch (config -> frame_fmt ) {
200+ case SOF_IPC_FRAME_S16_LE :
201+ trace_eq ("p16" );
202+ cd -> eq_fir_func_even = eq_fir_s16_passthrough ;
203+ cd -> eq_fir_func = eq_fir_s16_passthrough ;
204+ break ;
205+ case SOF_IPC_FRAME_S24_4LE :
206+ case SOF_IPC_FRAME_S32_LE :
207+ trace_eq ("p32" );
208+ cd -> eq_fir_func_even = eq_fir_s32_passthrough ;
209+ cd -> eq_fir_func = eq_fir_s32_passthrough ;
210+ break ;
211+ default :
212+ trace_eq_error ("epf" );
213+ return - EINVAL ;
214+ }
215+ return 0 ;
216+ }
217+
88218/*
89219 * EQ control code is next. The processing is in fir_ C modules.
90220 */
@@ -276,8 +406,8 @@ static struct comp_dev *eq_fir_new(struct sof_ipc_comp *comp)
276406
277407 comp_set_drvdata (dev , cd );
278408
279- cd -> eq_fir_func = eq_fir_passthrough ;
280- cd -> eq_fir_func_odd = eq_fir_passthrough ;
409+ cd -> eq_fir_func_even = eq_fir_s32_passthrough ;
410+ cd -> eq_fir_func = eq_fir_s32_passthrough ;
281411 cd -> config = NULL ;
282412
283413 /* Allocate and make a copy of the coefficients blob and reset FIR. If
@@ -340,10 +470,6 @@ static int eq_fir_params(struct comp_dev *dev)
340470 return err ;
341471 }
342472
343- /* EQ supports only S32_LE PCM format */
344- if (config -> frame_fmt != SOF_IPC_FRAME_S32_LE )
345- return - EINVAL ;
346-
347473 return 0 ;
348474}
349475
@@ -531,9 +657,9 @@ static int eq_fir_copy(struct comp_dev *dev)
531657 }
532658
533659 if (dev -> frames & 1 )
534- sd -> eq_fir_func_odd (fir , source , sink , dev -> frames , nch );
535- else
536660 sd -> eq_fir_func (fir , source , sink , dev -> frames , nch );
661+ else
662+ sd -> eq_fir_func_even (fir , source , sink , dev -> frames , nch );
537663
538664 /* calc new free and available */
539665 comp_update_buffer_consume (source , sd -> period_bytes );
@@ -554,31 +680,19 @@ static int eq_fir_prepare(struct comp_dev *dev)
554680 return ret ;
555681
556682 /* Initialize EQ */
557- cd -> eq_fir_func = eq_fir_passthrough ;
558683 if (cd -> config ) {
559684 ret = eq_fir_setup (cd , dev -> params .channels );
560685 if (ret < 0 ) {
561686 comp_set_state (dev , COMP_TRIGGER_RESET );
562687 return ret ;
563688 }
564- #if FIR_GENERIC
565- cd -> eq_fir_func = eq_fir_s32 ;
566- cd -> eq_fir_func_odd = eq_fir_s32 ;
567- #endif
568- #if FIR_HIFIEP
569- cd -> eq_fir_func = eq_fir_2x_s32_hifiep ;
570- cd -> eq_fir_func_odd = eq_fir_s32_hifiep ;
571- #endif
572- #if FIR_HIFI3
573- cd -> eq_fir_func = eq_fir_2x_s32_hifi3 ;
574- cd -> eq_fir_func_odd = eq_fir_s32_hifi3 ;
575- #endif
689+
690+ ret = set_fir_func (dev );
691+ return ret ;
576692 }
577- trace_eq ("len" );
578- trace_value (cd -> fir [0 ].length );
579- trace_value (cd -> fir [1 ].length );
580693
581- return 0 ;
694+ ret = set_pass_func (dev );
695+ return ret ;
582696}
583697
584698static int eq_fir_reset (struct comp_dev * dev )
@@ -590,8 +704,8 @@ static int eq_fir_reset(struct comp_dev *dev)
590704
591705 eq_fir_free_delaylines (cd );
592706
593- cd -> eq_fir_func = eq_fir_passthrough ;
594- cd -> eq_fir_func_odd = eq_fir_passthrough ;
707+ cd -> eq_fir_func_even = eq_fir_s32_passthrough ;
708+ cd -> eq_fir_func = eq_fir_s32_passthrough ;
595709 for (i = 0 ; i < PLATFORM_MAX_CHANNELS ; i ++ )
596710 fir_reset (& cd -> fir [i ]);
597711
0 commit comments