1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2020 Google LLC. All rights reserved.
4  *
5  * Author: Sebastiano Carlucci <scarlucci@google.com>
6  */
7 
8 #ifndef __USER_CROSSOVER_H__
9 #define __USER_CROSSOVER_H__
10 
11 #include <stdint.h>
12 #include <user/eq.h>
13 
14 /* Maximum Number of sinks allowed in config */
15 #define SOF_CROSSOVER_MAX_STREAMS 4
16 
17 /* Maximum number allowed in configuration blob */
18 #define SOF_CROSSOVER_MAX_SIZE 1024
19 
20  /* crossover_configuration
21   *     uint32_t number_of_sinks <= 4
22   *         1=passthrough, n=n-way cossover.
23   *     uint32_t assign_sinks[SOF_CROSSOVER_MAX_STREAMS]
24   *         Mapping between sink positions and the sink's pipeline id. To assign
25   *         output j to sink i, set: assign_sinks[j] = i. Refer to the diagrams
26   *         below for more information on the sink outputs.
27   *
28   *		4-way:
29   *                                 o---- LR4 LP0 --> LOW assign_sink[0]
30   *                                 |
31   *                  o--- LR4 LP1 --o
32   *                  |              |
33   *                  |              o---- LR4 HP0 --> MID_LOW assign_sink[1]
34   *         x(n) --- o
35   *                  |              o---- LR4 LP2 --> MID_HIGH assign_sink[2]
36   *                  |              |
37   *                  o--- LR4 HP1 --o
38   *                                 |
39   *                                 o---- LR4 HP2 --> HIGH assign_sink[3]
40   *
41   *             Merging is necessary for 3way to adjsut the phase of the
42   *             outputs.
43   *		3-way:
44   *                                 o---- LR4 LP1 --o
45   *                                 |                |
46   *                  o--- LR4 LP0 --o                +-> LOW assign_sink[0]
47   *                  |              |                |
48   *                  |              o---- LR4 HP1 --o
49   *         x(n) --- o
50   *                  |              o---- LR4 LP2 -----> MID assign_sink[1]
51   *                  |              |
52   *                  o--- LR4 HP0 --o
53   *                                 |
54   *                                 o---- LR4 HP2 -----> HIGH assign_sink[2]
55   *
56   *		2-way:
57   *                  o--- LR4 LP0 ---> LOW assign_sink[0]
58   *                  |
59   *         x(n) --- o
60   *                  |
61   *                  o--- LR4 HP0 ---> HIGH assign_sink[1]
62   *
63   *         struct sof_eq_iir_biquad_df2t coef[(num_sinks - 1)*2]
64   *             The coefficients data for the LR4s. Depending on many
65   *             sinks are set, the number entries of this field can vary.
66   *             Each entry of the array defines the coefficients for one biquad
67   *             of the LR4 filter. The order the coefficients are assigned is:
68   *             [LR4 LP0, LR4 HP0, LR4 LP1, LR4 HP1, LR4 LP2, LR4 HP2].
69   *             coef[0] = coefficients of LR4 LP0...
70   *             coef[1] = coefficients of LR4 HP0...
71   *             ...
72   *
73   *             Since an LR4 is two biquads in series with same coefficients,
74   *             the config takes the coefficients for one biquad and
75   *             assigns it to both biquads of the LR4.
76   *
77   *             <1st Low Pass LR4>
78   *             int32_t coef_a2       Q2.30 format
79   *             int32_t coef_a1       Q2.30 format
80   *             int32_t coef_b2       Q2.30 format
81   *             int32_t coef_b1       Q2.30 format
82   *             int32_t coef_b0       Q2.30 format
83   *             int32_t output_shift  number of right shift (nve for left)
84   *             int32_t output_gain   Q2.14 format
85   *             <1nd High Pass LR4>
86   *             ...
87   *             <2nd Low Pass LR4>
88   *             <2nd High Pass LR4>
89   *             ...
90   *             ... At most 3 Low Pass LR4s and 3 High Pass LR4s ...
91   *
92   */
93 struct sof_crossover_config {
94 	uint32_t size;
95 	uint32_t num_sinks;
96 
97 	/* reserved */
98 	uint32_t reserved[4];
99 
100 	uint32_t assign_sink[SOF_CROSSOVER_MAX_STREAMS];
101 	struct sof_eq_iir_biquad_df2t coef[];
102 };
103 
104 #endif // __USER_CROSSOVER_H__
105