1 // SPDX-License-Identifier: BSD-3-Clause
2 //
3 // Copyright(c) 2020 Maxim Integrated All rights reserved.
4 //
5 // Author: Ryan Lee <ryans.lee@maximintegrated.com>
6
7 #include <stdint.h>
8 #include <sof/audio/component.h>
9 #include <sof/audio/format.h>
10 #include <sof/audio/smart_amp/smart_amp.h>
11
12 #ifdef CONFIG_GENERIC
13
smart_amp_ff_generic(int32_t x)14 static int32_t smart_amp_ff_generic(int32_t x)
15 {
16 /* Add speaker protection feed forward process here */
17 return x;
18 }
19
smart_amp_fb_generic(int32_t x)20 static void smart_amp_fb_generic(int32_t x)
21 {
22 /* Add speaker protection feedback process here */
23 }
24
25 #if CONFIG_FORMAT_S16LE
smart_amp_s16_ff_default(const struct comp_dev * dev,const struct audio_stream __sparse_cache * source,const struct audio_stream __sparse_cache * sink,const struct audio_stream __sparse_cache * feedback,uint32_t frames)26 static void smart_amp_s16_ff_default(const struct comp_dev *dev,
27 const struct audio_stream __sparse_cache *source,
28 const struct audio_stream __sparse_cache *sink,
29 const struct audio_stream __sparse_cache *feedback,
30 uint32_t frames)
31 {
32 int16_t *x;
33 int16_t *y;
34 int32_t tmp;
35 int idx;
36 int ch;
37 int i;
38 int nch = source->channels;
39
40 for (ch = 0; ch < nch; ch++) {
41 idx = ch;
42 for (i = 0; i < frames; i++) {
43 x = audio_stream_read_frag_s16(source, idx);
44 y = audio_stream_read_frag_s16(sink, idx);
45 tmp = smart_amp_ff_generic(*x << 16);
46 *y = sat_int16(Q_SHIFT_RND(tmp, 31, 15));
47 idx += nch;
48 }
49 }
50 }
51 #endif /* CONFIG_FORMAT_S16LE */
52
53 #if CONFIG_FORMAT_S24LE
smart_amp_s24_ff_default(const struct comp_dev * dev,const struct audio_stream __sparse_cache * source,const struct audio_stream __sparse_cache * sink,const struct audio_stream __sparse_cache * feedback,uint32_t frames)54 static void smart_amp_s24_ff_default(const struct comp_dev *dev,
55 const struct audio_stream __sparse_cache *source,
56 const struct audio_stream __sparse_cache *sink,
57 const struct audio_stream __sparse_cache *feedback,
58 uint32_t frames)
59 {
60 int32_t *x;
61 int32_t *y;
62 int32_t tmp;
63 int idx;
64 int ch;
65 int i;
66 int nch = source->channels;
67
68 for (ch = 0; ch < nch; ch++) {
69 idx = ch;
70 for (i = 0; i < frames; i++) {
71 x = audio_stream_read_frag_s32(source, idx);
72 y = audio_stream_read_frag_s32(sink, idx);
73 tmp = smart_amp_ff_generic(*x << 8);
74 *y = sat_int24(Q_SHIFT_RND(tmp, 31, 23));
75 idx += nch;
76 }
77 }
78 }
79 #endif /* CONFIG_FORMAT_S24LE */
80
81 #if CONFIG_FORMAT_S32LE
smart_amp_s32_ff_default(const struct comp_dev * dev,const struct audio_stream __sparse_cache * source,const struct audio_stream __sparse_cache * sink,const struct audio_stream __sparse_cache * feedback,uint32_t frames)82 static void smart_amp_s32_ff_default(const struct comp_dev *dev,
83 const struct audio_stream __sparse_cache *source,
84 const struct audio_stream __sparse_cache *sink,
85 const struct audio_stream __sparse_cache *feedback,
86 uint32_t frames)
87 {
88 int32_t *x;
89 int32_t *y;
90 int idx;
91 int ch;
92 int i;
93 int nch = source->channels;
94
95 for (ch = 0; ch < nch; ch++) {
96 idx = ch;
97 for (i = 0; i < frames; i++) {
98 x = audio_stream_read_frag_s32(source, idx);
99 y = audio_stream_read_frag_s32(sink, idx);
100 *y = smart_amp_ff_generic(*x);
101 idx += nch;
102 }
103 }
104 }
105 #endif /* CONFIG_FORMAT_S32LE */
106
107 #if CONFIG_FORMAT_S16LE
smart_amp_s16_fb_default(const struct comp_dev * dev,const struct audio_stream __sparse_cache * source,const struct audio_stream __sparse_cache * sink,const struct audio_stream __sparse_cache * feedback,uint32_t frames)108 static void smart_amp_s16_fb_default(const struct comp_dev *dev,
109 const struct audio_stream __sparse_cache *source,
110 const struct audio_stream __sparse_cache *sink,
111 const struct audio_stream __sparse_cache *feedback,
112 uint32_t frames)
113 {
114 int16_t *x;
115 int idx;
116 int ch;
117 int i;
118 int nch = source->channels;
119
120 for (ch = 0; ch < nch; ch++) {
121 idx = ch;
122 for (i = 0; i < frames; i++) {
123 x = audio_stream_read_frag_s16(feedback, idx);
124 smart_amp_fb_generic(*x << 16);
125 idx += nch;
126 }
127 }
128 }
129 #endif /* CONFIG_FORMAT_S16LE */
130
131 #if CONFIG_FORMAT_S24LE
smart_amp_s24_fb_default(const struct comp_dev * dev,const struct audio_stream __sparse_cache * source,const struct audio_stream __sparse_cache * sink,const struct audio_stream __sparse_cache * feedback,uint32_t frames)132 static void smart_amp_s24_fb_default(const struct comp_dev *dev,
133 const struct audio_stream __sparse_cache *source,
134 const struct audio_stream __sparse_cache *sink,
135 const struct audio_stream __sparse_cache *feedback,
136 uint32_t frames)
137 {
138 int32_t *x;
139 int idx;
140 int ch;
141 int i;
142 int nch = source->channels;
143
144 for (ch = 0; ch < nch; ch++) {
145 idx = ch;
146 for (i = 0; i < frames; i++) {
147 x = audio_stream_read_frag_s32(feedback, idx);
148 smart_amp_fb_generic(*x << 8);
149 idx += nch;
150 }
151 }
152 }
153 #endif /* CONFIG_FORMAT_S24LE */
154
155 #if CONFIG_FORMAT_S32LE
smart_amp_s32_fb_default(const struct comp_dev * dev,const struct audio_stream __sparse_cache * source,const struct audio_stream __sparse_cache * sink,const struct audio_stream __sparse_cache * feedback,uint32_t frames)156 static void smart_amp_s32_fb_default(const struct comp_dev *dev,
157 const struct audio_stream __sparse_cache *source,
158 const struct audio_stream __sparse_cache *sink,
159 const struct audio_stream __sparse_cache *feedback,
160 uint32_t frames)
161 {
162 int32_t *x;
163 int idx;
164 int ch;
165 int i;
166 int nch = source->channels;
167
168 for (ch = 0; ch < nch; ch++) {
169 idx = ch;
170 for (i = 0; i < frames; i++) {
171 x = audio_stream_read_frag_s32(feedback, idx);
172 smart_amp_ff_generic(*x);
173 idx += nch;
174 }
175 }
176 }
177 #endif /* CONFIG_FORMAT_S32LE */
178
179 const struct smart_amp_func_map smart_amp_function_map[] = {
180 /* { SOURCE_FORMAT , PROCESSING FUNCTION } */
181 #if CONFIG_FORMAT_S16LE
182 { SOF_IPC_FRAME_S16_LE, smart_amp_s16_ff_default },
183 #endif /* CONFIG_FORMAT_S16LE */
184 #if CONFIG_FORMAT_S24LE
185 { SOF_IPC_FRAME_S24_4LE, smart_amp_s24_ff_default },
186 #endif /* CONFIG_FORMAT_S24LE */
187 #if CONFIG_FORMAT_S32LE
188 { SOF_IPC_FRAME_S32_LE, smart_amp_s32_ff_default },
189 #endif /* CONFIG_FORMAT_S32LE */
190 #if CONFIG_FORMAT_S16LE
191 { SOF_IPC_FRAME_S16_LE, smart_amp_s16_fb_default },
192 #endif /* CONFIG_FORMAT_S16LE */
193 #if CONFIG_FORMAT_S24LE
194 { SOF_IPC_FRAME_S24_4LE, smart_amp_s24_fb_default },
195 #endif /* CONFIG_FORMAT_S24LE */
196 #if CONFIG_FORMAT_S32LE
197 { SOF_IPC_FRAME_S32_LE, smart_amp_s32_fb_default },
198 #endif /* CONFIG_FORMAT_S32LE */
199 };
200
201 const size_t smart_amp_func_count = ARRAY_SIZE(smart_amp_function_map);
202 #endif
203