Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/* SPDX-License-Identifier: ((GPL-2.0 WITH Linux-syscall-note) OR BSD-3-Clause) */
2/*
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * Copyright(c) 2018 Intel Corporation. All rights reserved.
7 */
8
9#ifndef __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__
10#define __INCLUDE_UAPI_SOUND_SOF_USER_EQ_H__
11
12/* FIR EQ type */
13
14#define SOF_EQ_FIR_IDX_SWITCH 0
15
16#define SOF_EQ_FIR_MAX_SIZE 4096 /* Max size allowed for coef data in bytes */
17
18#define SOF_EQ_FIR_MAX_LENGTH 192 /* Max length for individual filter */
19
20#define SOF_EQ_FIR_MAX_RESPONSES 8 /* A blob can define max 8 FIR EQs */
21
22/*
23 * eq_fir_configuration data structure contains this information
24 * uint32_t size
25 * This is the number of bytes need to store the received EQ
26 * configuration.
27 * uint16_t channels_in_config
28 * This describes the number of channels in this EQ config data. It
29 * can be different from PLATFORM_MAX_CHANNELS.
30 * uint16_t number_of_responses
31 * 0=no responses, 1=one response defined, 2=two responses defined, etc.
32 * int16_t data[]
33 * assign_response[channels_in_config]
34 * 0 = use first response, 1 = use 2nd response, etc.
35 * E.g. {0, 0, 0, 0, 1, 1, 1, 1} would apply to channels 0-3 the
36 * same first defined response and for to channels 4-7 the second.
37 * coef_data[]
38 * Repeated data
39 * { filter_length, output_shift, h[] }
40 * for every EQ response defined where vector h has filter_length
41 * number of coefficients. Coefficients in h[] are in Q1.15 format.
42 * E.g. 16384 (Q1.15) = 0.5. The shifts are number of right shifts.
43 *
44 * NOTE: The channels_in_config must be even to have coef_data aligned to
45 * 32 bit word in RAM. Therefore a mono EQ assign must be duplicated to 2ch
46 * even if it would never used. Similarly a 5ch EQ assign must be increased
47 * to 6ch. EQ init will return an error if this is not met.
48 *
49 * NOTE: The filter_length must be multiple of four. Therefore the filter must
50 * be padded from the end with zeros have this condition met.
51 */
52
53struct sof_eq_fir_config {
54 uint32_t size;
55 uint16_t channels_in_config;
56 uint16_t number_of_responses;
57
58 /* reserved */
59 uint32_t reserved[4];
60
61 int16_t data[];
62} __packed;
63
64struct sof_eq_fir_coef_data {
65 int16_t length; /* Number of FIR taps */
66 int16_t out_shift; /* Amount of right shifts at output */
67
68 /* reserved */
69 uint32_t reserved[4];
70
71 int16_t coef[]; /* FIR coefficients */
72} __packed;
73
74/* In the struct above there's two 16 bit words (length, shift) and four
75 * reserved 32 bit words before the actual FIR coefficients. This information
76 * is used in parsing of the configuration blob.
77 */
78#define SOF_EQ_FIR_COEF_NHEADER \
79 (sizeof(struct sof_eq_fir_coef_data) / sizeof(int16_t))
80
81/* IIR EQ type */
82
83#define SOF_EQ_IIR_IDX_SWITCH 0
84
85#define SOF_EQ_IIR_MAX_SIZE 1024 /* Max size allowed for coef data in bytes */
86
87#define SOF_EQ_IIR_MAX_RESPONSES 8 /* A blob can define max 8 IIR EQs */
88
89/* eq_iir_configuration
90 * uint32_t channels_in_config
91 * This describes the number of channels in this EQ config data. It
92 * can be different from PLATFORM_MAX_CHANNELS.
93 * uint32_t number_of_responses_defined
94 * 0=no responses, 1=one response defined, 2=two responses defined, etc.
95 * int32_t data[]
96 * Data consist of two parts. First is the response assign vector that
97 * has length of channels_in_config. The latter part is coefficient
98 * data.
99 * uint32_t assign_response[channels_in_config]
100 * -1 = not defined, 0 = use first response, 1 = use 2nd, etc.
101 * E.g. {0, 0, 0, 0, -1, -1, -1, -1} would apply to channels 0-3 the
102 * same first defined response and leave channels 4-7 unequalized.
103 * coefficient_data[]
104 * <1st EQ>
105 * uint32_t num_biquads
106 * uint32_t num_biquads_in_series
107 * <1st biquad>
108 * int32_t coef_a2 Q2.30 format
109 * int32_t coef_a1 Q2.30 format
110 * int32_t coef_b2 Q2.30 format
111 * int32_t coef_b1 Q2.30 format
112 * int32_t coef_b0 Q2.30 format
113 * int32_t output_shift number of shifts right, shift left is negative
114 * int32_t output_gain Q2.14 format
115 * <2nd biquad>
116 * ...
117 * <2nd EQ>
118 *
119 * Note: A flat response biquad can be made with a section set to
120 * b0 = 1.0, gain = 1.0, and other parameters set to 0
121 * {0, 0, 0, 0, 1073741824, 0, 16484}
122 */
123
124struct sof_eq_iir_config {
125 uint32_t size;
126 uint32_t channels_in_config;
127 uint32_t number_of_responses;
128
129 /* reserved */
130 uint32_t reserved[4];
131
132 int32_t data[]; /* eq_assign[channels], eq 0, eq 1, ... */
133} __packed;
134
135struct sof_eq_iir_header_df2t {
136 uint32_t num_sections;
137 uint32_t num_sections_in_series;
138
139 /* reserved */
140 uint32_t reserved[4];
141
142 int32_t biquads[]; /* Repeated biquad coefficients */
143} __packed;
144
145struct sof_eq_iir_biquad_df2t {
146 int32_t a2; /* Q2.30 */
147 int32_t a1; /* Q2.30 */
148 int32_t b2; /* Q2.30 */
149 int32_t b1; /* Q2.30 */
150 int32_t b0; /* Q2.30 */
151 int32_t output_shift; /* Number of right shifts */
152 int32_t output_gain; /* Q2.14 */
153} __packed;
154
155/* A full 22th order equalizer with 11 biquads cover octave bands 1-11 in
156 * in the 0 - 20 kHz bandwidth.
157 */
158#define SOF_EQ_IIR_DF2T_BIQUADS_MAX 11
159
160/* The number of int32_t words in sof_eq_iir_header_df2t:
161 * num_sections, num_sections_in_series, reserved[4]
162 */
163#define SOF_EQ_IIR_NHEADER_DF2T \
164 (sizeof(struct sof_eq_iir_header_df2t) / sizeof(int32_t))
165
166/* The number of int32_t words in sof_eq_iir_biquad_df2t:
167 * a2, a1, b2, b1, b0, output_shift, output_gain
168 */
169#define SOF_EQ_IIR_NBIQUAD_DF2T \
170 (sizeof(struct sof_eq_iir_biquad_df2t) / sizeof(int32_t))
171
172#endif