blob: db3bd87ebc0e237101a9b89141bf3c0116d8bfbe [file] [log] [blame]
Meng Wang43bbb872018-12-10 12:32:05 +08001// SPDX-License-Identifier: GPL-2.0-only
Aditya Bavanari53fbc922019-04-26 14:38:29 +05302/* Copyright (c) 2013-2019, The Linux Foundation. All rights reserved.
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05303 */
4
5#include <linux/slab.h>
Aditya Bavanari53fbc922019-04-26 14:38:29 +05306#include <linux/ratelimit.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05307#include <sound/compress_params.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05308#include <sound/devdep_params.h>
Laxminath Kasam605b42f2017-08-01 22:02:15 +05309#include <dsp/apr_audio-v2.h>
10#include <dsp/q6asm-v2.h>
11#include <dsp/msm-audio-effects-q6-v2.h>
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -080012#include <dsp/q6common.h>
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053013
14#define MAX_ENABLE_CMD_SIZE 32
15
16#define GET_NEXT(ptr, upper_limit, rc) \
17({ \
18 if (((ptr) + 1) > (upper_limit)) { \
Aditya Bavanari53fbc922019-04-26 14:38:29 +053019 pr_err_ratelimited("%s: param list out of boundary\n", \
20 __func__); \
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053021 (rc) = -EINVAL; \
22 } \
23 ((rc) == 0) ? *(ptr)++ : -EINVAL; \
24})
25
26#define CHECK_PARAM_LEN(len, max_len, tag, rc) \
27do { \
28 if ((len) > (max_len)) { \
Aditya Bavanari53fbc922019-04-26 14:38:29 +053029 pr_err_ratelimited("%s: params length overflows\n", \
30 (tag)); \
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053031 (rc) = -EINVAL; \
32 } \
33} while (0)
34
35
Laxminath Kasam8b1366a2017-10-05 01:44:16 +053036/**
37 * msm_audio_effects_is_effmodule_supp_in_top -
38 * Checks if given topology and module in effects
39 *
40 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053041bool msm_audio_effects_is_effmodule_supp_in_top(int effect_module,
42 int topology)
43{
44 switch (effect_module) {
45 case VIRTUALIZER_MODULE:
46 case REVERB_MODULE:
47 case BASS_BOOST_MODULE:
48 case PBE_MODULE:
49 case EQ_MODULE:
50 switch (topology) {
51 case ASM_STREAM_POSTPROC_TOPO_ID_SA_PLUS:
52 return true;
53 default:
54 return false;
55 }
56 default:
57 return false;
58 }
59}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +053060EXPORT_SYMBOL(msm_audio_effects_is_effmodule_supp_in_top);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053061
62int msm_audio_effects_enable_extn(struct audio_client *ac,
63 struct msm_nt_eff_all_config *effects,
64 bool flag)
65{
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -080066 u32 flag_param = flag ? 1 : 0;
67 struct param_hdr_v3 param_hdr;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053068 int rc = 0;
69
70 pr_debug("%s\n", __func__);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -080071 memset(&param_hdr, 0, sizeof(param_hdr));
72 param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER;
73 param_hdr.instance_id = INSTANCE_ID_0;
74 param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
75 param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053076 if (effects->virtualizer.enable_flag)
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -080077 rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr,
78 (u8 *) &flag_param);
79
80 param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST;
81 param_hdr.instance_id = INSTANCE_ID_0;
82 param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
83 param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053084 if (effects->bass_boost.enable_flag)
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -080085 rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr,
86 (u8 *) &flag_param);
87
88 param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
89 param_hdr.instance_id = INSTANCE_ID_0;
90 param_hdr.param_id = AUDPROC_PARAM_ID_ENABLE;
91 param_hdr.param_size = EQ_ENABLE_PARAM_SZ;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053092 if (effects->equalizer.enable_flag)
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -080093 rc = q6asm_pack_and_set_pp_param_in_band(ac, param_hdr,
94 (u8 *) &flag_param);
95
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +053096 return rc;
97}
98
Laxminath Kasam8b1366a2017-10-05 01:44:16 +053099/**
100 * msm_audio_effects_virtualizer_handler -
101 * Audio effects handler for virtualizer
102 *
103 * @ac: audio client handle
104 * @pbe: virtualizer params
105 * @values: values to be updated
106 *
107 * Return 0 on success or error on failure
108 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530109int msm_audio_effects_virtualizer_handler(struct audio_client *ac,
110 struct virtualizer_params *virtualizer,
111 long *values)
112{
113 long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
114 char *params = NULL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800115 u8 *updt_params;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530116 int rc = 0;
117 int devices = GET_NEXT(values, param_max_offset, rc);
118 int num_commands = GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800119 int i, prev_enable_flag;
120 uint32_t max_params_length = 0;
121 uint32_t params_length = 0;
122 struct param_hdr_v3 param_hdr;
123 u8 *param_data = NULL;
124 u32 packed_data_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530125
126 pr_debug("%s\n", __func__);
127 if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
128 pr_err("%s: cannot set audio effects\n", __func__);
129 return -EINVAL;
130 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800131 params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
132 if (!params) {
133 pr_err("%s, params memory alloc failed\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530134 return -ENOMEM;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800135 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530136 pr_debug("%s: device: %d\n", __func__, devices);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800137 updt_params = (u8 *) params;
138 /* Set MID and IID once at top and only update param specific fields*/
Karthikeyan Mani4183e322018-11-09 17:48:17 -0800139 memset(&param_hdr, 0, sizeof(param_hdr));
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800140 param_hdr.module_id = AUDPROC_MODULE_ID_VIRTUALIZER;
141 param_hdr.instance_id = INSTANCE_ID_0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530142 for (i = 0; i < num_commands; i++) {
143 uint32_t command_id =
144 GET_NEXT(values, param_max_offset, rc);
145 uint32_t command_config_state =
146 GET_NEXT(values, param_max_offset, rc);
147 uint32_t index_offset =
148 GET_NEXT(values, param_max_offset, rc);
149 uint32_t length =
150 GET_NEXT(values, param_max_offset, rc);
151 switch (command_id) {
152 case VIRTUALIZER_ENABLE:
153 if (length != 1 || index_offset != 0) {
154 pr_err("VIRT ENABLE:invalid params\n");
155 rc = -EINVAL;
156 goto invalid_config;
157 }
158 prev_enable_flag = virtualizer->enable_flag;
159 virtualizer->enable_flag =
160 GET_NEXT(values, param_max_offset, rc);
161 pr_debug("%s:VIRT ENABLE prev:%d, new:%d\n", __func__,
162 prev_enable_flag, virtualizer->enable_flag);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800163 if (prev_enable_flag == virtualizer->enable_flag)
Weiyin Jiang431b1c52019-06-25 23:05:14 +0800164 continue;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800165 max_params_length = params_length +
166 COMMAND_IID_PAYLOAD_SZ +
167 VIRTUALIZER_ENABLE_PARAM_SZ;
168 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
169 "VIRT ENABLE", rc);
170 if (rc != 0)
171 break;
172 param_hdr.param_id =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530173 AUDPROC_PARAM_ID_VIRTUALIZER_ENABLE;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800174 param_hdr.param_size = VIRTUALIZER_ENABLE_PARAM_SZ;
175 param_data = (u8 *) &virtualizer->enable_flag;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530176 break;
177 case VIRTUALIZER_STRENGTH:
178 if (length != 1 || index_offset != 0) {
179 pr_err("VIRT STRENGTH:invalid params\n");
180 rc = -EINVAL;
181 goto invalid_config;
182 }
183 virtualizer->strength =
184 GET_NEXT(values, param_max_offset, rc);
185 pr_debug("%s: VIRT STRENGTH val: %d\n",
186 __func__, virtualizer->strength);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800187 if (command_config_state != CONFIG_SET)
188 break;
189 max_params_length = params_length +
190 COMMAND_IID_PAYLOAD_SZ +
191 VIRTUALIZER_STRENGTH_PARAM_SZ;
192 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
193 "VIRT STRENGTH", rc);
194 if (rc != 0)
195 break;
196 param_hdr.param_id =
197 AUDPROC_PARAM_ID_VIRTUALIZER_STRENGTH;
198 param_hdr.param_size = VIRTUALIZER_STRENGTH_PARAM_SZ;
199 param_data = (u8 *) &virtualizer->strength;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530200 break;
201 case VIRTUALIZER_OUT_TYPE:
202 if (length != 1 || index_offset != 0) {
203 pr_err("VIRT OUT_TYPE:invalid params\n");
204 rc = -EINVAL;
205 goto invalid_config;
206 }
207 virtualizer->out_type =
208 GET_NEXT(values, param_max_offset, rc);
209 pr_debug("%s: VIRT OUT_TYPE val:%d\n",
210 __func__, virtualizer->out_type);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800211 if (command_config_state != CONFIG_SET)
212 break;
213 max_params_length = params_length +
214 COMMAND_IID_PAYLOAD_SZ +
215 VIRTUALIZER_OUT_TYPE_PARAM_SZ;
216 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
217 "VIRT OUT_TYPE", rc);
218 if (rc != 0)
219 break;
220 param_hdr.param_id =
221 AUDPROC_PARAM_ID_VIRTUALIZER_OUT_TYPE;
222 param_hdr.param_size = VIRTUALIZER_OUT_TYPE_PARAM_SZ;
223 param_data = (u8 *) &virtualizer->out_type;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530224 break;
225 case VIRTUALIZER_GAIN_ADJUST:
226 if (length != 1 || index_offset != 0) {
227 pr_err("VIRT GAIN_ADJUST: invalid params\n");
228 rc = -EINVAL;
229 goto invalid_config;
230 }
231 virtualizer->gain_adjust =
232 GET_NEXT(values, param_max_offset, rc);
233 pr_debug("%s: VIRT GAIN_ADJUST val:%d\n",
234 __func__, virtualizer->gain_adjust);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800235 if (command_config_state != CONFIG_SET)
236 break;
237 max_params_length = params_length +
238 COMMAND_IID_PAYLOAD_SZ +
239 VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
240 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
241 "VIRT GAIN_ADJUST", rc);
242 if (rc != 0)
243 break;
244 param_hdr.param_id =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530245 AUDPROC_PARAM_ID_VIRTUALIZER_GAIN_ADJUST;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800246 param_hdr.param_size = VIRTUALIZER_GAIN_ADJUST_PARAM_SZ;
247 param_data = (u8 *) &virtualizer->gain_adjust;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530248 break;
249 default:
Aditya Bavanari53fbc922019-04-26 14:38:29 +0530250 pr_err_ratelimited("%s: Invalid command to set config\n",
251 __func__);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800252 continue;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530253 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800254 if (rc)
255 goto invalid_config;
256
257 rc = q6common_pack_pp_params(updt_params, &param_hdr,
258 param_data, &packed_data_size);
259 if (rc) {
260 pr_err("%s: Failed to pack params, error %d\n",
261 __func__, rc);
262 goto invalid_config;
263 }
264
265 updt_params += packed_data_size;
266 params_length += packed_data_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530267 }
268 if (params_length && (rc == 0))
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800269 q6asm_set_pp_params(ac, NULL, params, params_length);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530270 else
271 pr_debug("%s: did not send pp params\n", __func__);
272invalid_config:
273 kfree(params);
274 return rc;
275}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530276EXPORT_SYMBOL(msm_audio_effects_virtualizer_handler);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530277
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530278/**
279 * msm_audio_effects_reverb_handler -
280 * Audio effects handler for reverb
281 *
282 * @ac: audio client handle
283 * @pbe: reverb params
284 * @values: values to be updated
285 *
286 * Return 0 on success or error on failure
287 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530288int msm_audio_effects_reverb_handler(struct audio_client *ac,
289 struct reverb_params *reverb,
290 long *values)
291{
292 long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
293 char *params = NULL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800294 u8 *updt_params;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530295 int rc = 0;
296 int devices = GET_NEXT(values, param_max_offset, rc);
297 int num_commands = GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800298 int i, prev_enable_flag;
299 uint32_t max_params_length = 0;
300 uint32_t params_length = 0;
301 struct param_hdr_v3 param_hdr;
302 u8 *param_data = NULL;
303 u32 packed_data_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530304
305 pr_debug("%s\n", __func__);
306 if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
307 pr_err("%s: cannot set audio effects\n", __func__);
308 return -EINVAL;
309 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800310 params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
311 if (!params) {
312 pr_err("%s, params memory alloc failed\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530313 return -ENOMEM;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800314 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530315 pr_debug("%s: device: %d\n", __func__, devices);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800316 updt_params = (u8 *) params;
317 /* Set MID and IID once at top and only update param specific fields*/
318 memset(&param_hdr, 0, sizeof(param_hdr));
319 param_hdr.module_id = AUDPROC_MODULE_ID_REVERB;
320 param_hdr.instance_id = INSTANCE_ID_0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530321 for (i = 0; i < num_commands; i++) {
322 uint32_t command_id =
323 GET_NEXT(values, param_max_offset, rc);
324 uint32_t command_config_state =
325 GET_NEXT(values, param_max_offset, rc);
326 uint32_t index_offset =
327 GET_NEXT(values, param_max_offset, rc);
328 uint32_t length =
329 GET_NEXT(values, param_max_offset, rc);
330 switch (command_id) {
331 case REVERB_ENABLE:
332 if (length != 1 || index_offset != 0) {
333 pr_err("REVERB_ENABLE:invalid params\n");
334 rc = -EINVAL;
335 goto invalid_config;
336 }
337 prev_enable_flag = reverb->enable_flag;
338 reverb->enable_flag =
339 GET_NEXT(values, param_max_offset, rc);
340 pr_debug("%s:REVERB_ENABLE prev:%d,new:%d\n", __func__,
341 prev_enable_flag, reverb->enable_flag);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800342 if (prev_enable_flag == reverb->enable_flag)
Weiyin Jiang431b1c52019-06-25 23:05:14 +0800343 continue;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800344 max_params_length = params_length +
345 COMMAND_IID_PAYLOAD_SZ +
346 REVERB_ENABLE_PARAM_SZ;
347 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
348 "REVERB_ENABLE", rc);
349 if (rc != 0)
350 break;
351 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ENABLE;
352 param_hdr.param_size = REVERB_ENABLE_PARAM_SZ;
353 param_data = (u8 *) &reverb->enable_flag;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530354 break;
355 case REVERB_MODE:
356 if (length != 1 || index_offset != 0) {
357 pr_err("REVERB_MODE:invalid params\n");
358 rc = -EINVAL;
359 goto invalid_config;
360 }
361 reverb->mode =
362 GET_NEXT(values, param_max_offset, rc);
363 pr_debug("%s: REVERB_MODE val:%d\n",
364 __func__, reverb->mode);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800365 if (command_config_state != CONFIG_SET)
366 break;
367 max_params_length = params_length +
368 COMMAND_IID_PAYLOAD_SZ +
369 REVERB_MODE_PARAM_SZ;
370 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
371 "REVERB_MODE", rc);
372 if (rc != 0)
373 break;
374 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_MODE;
375 param_hdr.param_size = REVERB_MODE_PARAM_SZ;
376 param_data = (u8 *) &reverb->mode;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530377 break;
378 case REVERB_PRESET:
379 if (length != 1 || index_offset != 0) {
380 pr_err("REVERB_PRESET:invalid params\n");
381 rc = -EINVAL;
382 goto invalid_config;
383 }
384 reverb->preset =
385 GET_NEXT(values, param_max_offset, rc);
386 pr_debug("%s: REVERB_PRESET val:%d\n",
387 __func__, reverb->preset);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800388 if (command_config_state != CONFIG_SET)
389 break;
390 max_params_length = params_length +
391 COMMAND_IID_PAYLOAD_SZ +
392 REVERB_PRESET_PARAM_SZ;
393 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
394 "REVERB_PRESET", rc);
395 if (rc != 0)
396 break;
397 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_PRESET;
398 param_hdr.param_size = REVERB_PRESET_PARAM_SZ;
399 param_data = (u8 *) &reverb->preset;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530400 break;
401 case REVERB_WET_MIX:
402 if (length != 1 || index_offset != 0) {
403 pr_err("REVERB_WET_MIX:invalid params\n");
404 rc = -EINVAL;
405 goto invalid_config;
406 }
407 reverb->wet_mix =
408 GET_NEXT(values, param_max_offset, rc);
409 pr_debug("%s: REVERB_WET_MIX val:%d\n",
410 __func__, reverb->wet_mix);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800411 if (command_config_state != CONFIG_SET)
412 break;
413 max_params_length = params_length +
414 COMMAND_IID_PAYLOAD_SZ +
415 REVERB_WET_MIX_PARAM_SZ;
416 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
417 "REVERB_WET_MIX", rc);
418 if (rc != 0)
419 break;
420 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_WET_MIX;
421 param_hdr.param_size = REVERB_WET_MIX_PARAM_SZ;
422 param_data = (u8 *) &reverb->wet_mix;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530423 break;
424 case REVERB_GAIN_ADJUST:
425 if (length != 1 || index_offset != 0) {
426 pr_err("REVERB_GAIN_ADJUST:invalid params\n");
427 rc = -EINVAL;
428 goto invalid_config;
429 }
430 reverb->gain_adjust =
431 GET_NEXT(values, param_max_offset, rc);
432 pr_debug("%s: REVERB_GAIN_ADJUST val:%d\n",
433 __func__, reverb->gain_adjust);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800434 if (command_config_state != CONFIG_SET)
435 break;
436 max_params_length = params_length +
437 COMMAND_IID_PAYLOAD_SZ +
438 REVERB_GAIN_ADJUST_PARAM_SZ;
439 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
440 "REVERB_GAIN_ADJUST", rc);
441 if (rc != 0)
442 break;
443 param_hdr.param_id =
444 AUDPROC_PARAM_ID_REVERB_GAIN_ADJUST;
445 param_hdr.param_size = REVERB_GAIN_ADJUST_PARAM_SZ;
446 param_data = (u8 *) &reverb->gain_adjust;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530447 break;
448 case REVERB_ROOM_LEVEL:
449 if (length != 1 || index_offset != 0) {
450 pr_err("REVERB_ROOM_LEVEL:invalid params\n");
451 rc = -EINVAL;
452 goto invalid_config;
453 }
454 reverb->room_level =
455 GET_NEXT(values, param_max_offset, rc);
456 pr_debug("%s: REVERB_ROOM_LEVEL val:%d\n",
457 __func__, reverb->room_level);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800458 if (command_config_state != CONFIG_SET)
459 break;
460 max_params_length = params_length +
461 COMMAND_IID_PAYLOAD_SZ +
462 REVERB_ROOM_LEVEL_PARAM_SZ;
463 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
464 "REVERB_ROOM_LEVEL", rc);
465 if (rc != 0)
466 break;
467 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_ROOM_LEVEL;
468 param_hdr.param_size = REVERB_ROOM_LEVEL_PARAM_SZ;
469 param_data = (u8 *) &reverb->room_level;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530470 break;
471 case REVERB_ROOM_HF_LEVEL:
472 if (length != 1 || index_offset != 0) {
473 pr_err("REVERB_ROOM_HF_LEVEL:invalid params\n");
474 rc = -EINVAL;
475 goto invalid_config;
476 }
477 reverb->room_hf_level =
478 GET_NEXT(values, param_max_offset, rc);
479 pr_debug("%s: REVERB_ROOM_HF_LEVEL val%d\n",
480 __func__, reverb->room_hf_level);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800481 if (command_config_state != CONFIG_SET)
482 break;
483 max_params_length = params_length +
484 COMMAND_IID_PAYLOAD_SZ +
485 REVERB_ROOM_HF_LEVEL_PARAM_SZ;
486 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
487 "REVERB_ROOM_HF_LEVEL", rc);
488 if (rc != 0)
489 break;
490 param_hdr.param_id =
491 AUDPROC_PARAM_ID_REVERB_ROOM_HF_LEVEL;
492 param_hdr.param_size = REVERB_ROOM_HF_LEVEL_PARAM_SZ;
493 param_data = (u8 *) &reverb->room_hf_level;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530494 break;
495 case REVERB_DECAY_TIME:
496 if (length != 1 || index_offset != 0) {
497 pr_err("REVERB_DECAY_TIME:invalid params\n");
498 rc = -EINVAL;
499 goto invalid_config;
500 }
501 reverb->decay_time =
502 GET_NEXT(values, param_max_offset, rc);
503 pr_debug("%s: REVERB_DECAY_TIME val:%d\n",
504 __func__, reverb->decay_time);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800505 if (command_config_state != CONFIG_SET)
506 break;
507 max_params_length = params_length +
508 COMMAND_IID_PAYLOAD_SZ +
509 REVERB_DECAY_TIME_PARAM_SZ;
510 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
511 "REVERB_DECAY_TIME", rc);
512 if (rc != 0)
513 break;
514 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DECAY_TIME;
515 param_hdr.param_size = REVERB_DECAY_TIME_PARAM_SZ;
516 param_data = (u8 *) &reverb->decay_time;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530517 break;
518 case REVERB_DECAY_HF_RATIO:
519 if (length != 1 || index_offset != 0) {
520 pr_err("REVERB_DECAY_HF_RATIOinvalid params\n");
521 rc = -EINVAL;
522 goto invalid_config;
523 }
524 reverb->decay_hf_ratio =
525 GET_NEXT(values, param_max_offset, rc);
526 pr_debug("%s: REVERB_DECAY_HF_RATIO val%d\n",
527 __func__, reverb->decay_hf_ratio);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800528 if (command_config_state != CONFIG_SET)
529 break;
530 max_params_length = params_length +
531 COMMAND_IID_PAYLOAD_SZ +
532 REVERB_DECAY_HF_RATIO_PARAM_SZ;
533 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
534 "REVERB_DECAY_HF_RATIO", rc);
535 if (rc != 0)
536 break;
537 param_hdr.param_id =
538 AUDPROC_PARAM_ID_REVERB_DECAY_HF_RATIO;
539 param_hdr.param_size = REVERB_DECAY_HF_RATIO_PARAM_SZ;
540 param_data = (u8 *) &reverb->decay_hf_ratio;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530541 break;
542 case REVERB_REFLECTIONS_LEVEL:
543 if (length != 1 || index_offset != 0) {
544 pr_err("REVERB_REFLECTION_LVLinvalid params\n");
545 rc = -EINVAL;
546 goto invalid_config;
547 }
548 reverb->reflections_level =
549 GET_NEXT(values, param_max_offset, rc);
550 pr_debug("%s: REVERB_REFLECTIONS_LEVEL val:%d\n",
551 __func__, reverb->reflections_level);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800552 if (command_config_state != CONFIG_SET)
553 break;
554 max_params_length = params_length +
555 COMMAND_IID_PAYLOAD_SZ +
556 REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
557 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
558 "REVERB_REFLECTIONS_LEVEL", rc);
559 if (rc != 0)
560 break;
561 param_hdr.param_id =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530562 AUDPROC_PARAM_ID_REVERB_REFLECTIONS_LEVEL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800563 param_hdr.param_size =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530564 REVERB_REFLECTIONS_LEVEL_PARAM_SZ;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800565 param_data = (u8 *) &reverb->reflections_level;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530566 break;
567 case REVERB_REFLECTIONS_DELAY:
568 if (length != 1 || index_offset != 0) {
569 pr_err("REVERB_REFLECTION_DLYinvalid params\n");
570 rc = -EINVAL;
571 goto invalid_config;
572 }
573 reverb->reflections_delay =
574 GET_NEXT(values, param_max_offset, rc);
575 pr_debug("%s: REVERB_REFLECTIONS_DELAY val:%d\n",
576 __func__, reverb->reflections_delay);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800577 if (command_config_state != CONFIG_SET)
578 break;
579 max_params_length = params_length +
580 COMMAND_IID_PAYLOAD_SZ +
581 REVERB_REFLECTIONS_DELAY_PARAM_SZ;
582 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
583 "REVERB_REFLECTIONS_DELAY", rc);
584 if (rc != 0)
585 break;
586 param_hdr.param_id =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530587 AUDPROC_PARAM_ID_REVERB_REFLECTIONS_DELAY;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800588 param_hdr.param_size =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530589 REVERB_REFLECTIONS_DELAY_PARAM_SZ;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800590 param_data = (u8 *) &reverb->reflections_delay;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530591 break;
592 case REVERB_LEVEL:
593 if (length != 1 || index_offset != 0) {
594 pr_err("REVERB_LEVEL:invalid params\n");
595 rc = -EINVAL;
596 goto invalid_config;
597 }
598 reverb->level =
599 GET_NEXT(values, param_max_offset, rc);
600 pr_debug("%s: REVERB_LEVEL val:%d\n",
601 __func__, reverb->level);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800602 if (command_config_state != CONFIG_SET)
603 break;
604 max_params_length = params_length +
605 COMMAND_IID_PAYLOAD_SZ +
606 REVERB_LEVEL_PARAM_SZ;
607 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
608 "REVERB_LEVEL", rc);
609 if (rc != 0)
610 break;
611 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_LEVEL;
612 param_hdr.param_size = REVERB_LEVEL_PARAM_SZ;
613 param_data = (u8 *) &reverb->level;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530614 break;
615 case REVERB_DELAY:
616 if (length != 1 || index_offset != 0) {
617 pr_err("REVERB_DELAY:invalid params\n");
618 rc = -EINVAL;
619 goto invalid_config;
620 }
621 reverb->delay =
622 GET_NEXT(values, param_max_offset, rc);
623 pr_debug("%s:REVERB_DELAY val:%d\n",
624 __func__, reverb->delay);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800625 if (command_config_state != CONFIG_SET)
626 break;
627 max_params_length = params_length +
628 COMMAND_IID_PAYLOAD_SZ +
629 REVERB_DELAY_PARAM_SZ;
630 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
631 "REVERB_DELAY", rc);
632 if (rc != 0)
633 break;
634 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DELAY;
635 param_hdr.param_size = REVERB_DELAY_PARAM_SZ;
636 param_data = (u8 *) &reverb->delay;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530637 break;
638 case REVERB_DIFFUSION:
639 if (length != 1 || index_offset != 0) {
640 pr_err("REVERB_DIFFUSION:invalid params\n");
641 rc = -EINVAL;
642 goto invalid_config;
643 }
644 reverb->diffusion =
645 GET_NEXT(values, param_max_offset, rc);
646 pr_debug("%s: REVERB_DIFFUSION val:%d\n",
647 __func__, reverb->diffusion);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800648 if (command_config_state != CONFIG_SET)
649 break;
650 max_params_length = params_length +
651 COMMAND_IID_PAYLOAD_SZ +
652 REVERB_DIFFUSION_PARAM_SZ;
653 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
654 "REVERB_DIFFUSION", rc);
655 if (rc != 0)
656 break;
657 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DIFFUSION;
658 param_hdr.param_size = REVERB_DIFFUSION_PARAM_SZ;
659 param_data = (u8 *) &reverb->diffusion;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530660 break;
661 case REVERB_DENSITY:
662 if (length != 1 || index_offset != 0) {
663 pr_err("REVERB_DENSITY:invalid params\n");
664 rc = -EINVAL;
665 goto invalid_config;
666 }
667 reverb->density =
668 GET_NEXT(values, param_max_offset, rc);
669 pr_debug("%s: REVERB_DENSITY val:%d\n",
670 __func__, reverb->density);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800671 if (command_config_state != CONFIG_SET)
672 break;
673 max_params_length = params_length +
674 COMMAND_IID_PAYLOAD_SZ +
675 REVERB_DENSITY_PARAM_SZ;
676 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
677 "REVERB_DENSITY", rc);
678 if (rc != 0)
679 break;
680 param_hdr.param_id = AUDPROC_PARAM_ID_REVERB_DENSITY;
681 param_hdr.param_size = REVERB_DENSITY_PARAM_SZ;
682 param_data = (u8 *) &reverb->density;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530683 break;
684 default:
Aditya Bavanari53fbc922019-04-26 14:38:29 +0530685 pr_err_ratelimited("%s: Invalid command to set config\n",
686 __func__);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800687 continue;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530688 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800689 if (rc)
690 goto invalid_config;
691
692 rc = q6common_pack_pp_params(updt_params, &param_hdr,
693 param_data, &packed_data_size);
694 if (rc) {
695 pr_err("%s: Failed to pack params, error %d\n",
696 __func__, rc);
697 goto invalid_config;
698 }
699
700 updt_params += packed_data_size;
701 params_length += packed_data_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530702 }
703 if (params_length && (rc == 0))
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800704 q6asm_set_pp_params(ac, NULL, params, params_length);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530705 else
706 pr_debug("%s: did not send pp params\n", __func__);
707invalid_config:
708 kfree(params);
709 return rc;
710}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530711EXPORT_SYMBOL(msm_audio_effects_reverb_handler);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530712
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530713/**
714 * msm_audio_effects_bass_boost_handler -
715 * Audio effects handler for bass_boost
716 *
717 * @ac: audio client handle
718 * @bass_boost: bass_boost params
719 * @values: values to be updated
720 *
721 * Return 0 on success or error on failure
722 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530723int msm_audio_effects_bass_boost_handler(struct audio_client *ac,
724 struct bass_boost_params *bass_boost,
725 long *values)
726{
727 long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
728 char *params = NULL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800729 u8 *updt_params;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530730 int rc = 0;
731 int devices = GET_NEXT(values, param_max_offset, rc);
732 int num_commands = GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800733 int i, prev_enable_flag;
734 uint32_t max_params_length = 0;
735 uint32_t params_length = 0;
736 struct param_hdr_v3 param_hdr;
737 u8 *param_data = NULL;
738 u32 packed_data_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530739
740 pr_debug("%s\n", __func__);
741 if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
742 pr_err("%s: cannot set audio effects\n", __func__);
743 return -EINVAL;
744 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800745 params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
746 if (!params) {
747 pr_err("%s, params memory alloc failed\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530748 return -ENOMEM;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800749 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530750 pr_debug("%s: device: %d\n", __func__, devices);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800751 updt_params = (u8 *) params;
752 /* Set MID and IID once at top and only update param specific fields*/
753 memset(&param_hdr, 0, sizeof(param_hdr));
754 param_hdr.module_id = AUDPROC_MODULE_ID_BASS_BOOST;
755 param_hdr.instance_id = INSTANCE_ID_0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530756 for (i = 0; i < num_commands; i++) {
757 uint32_t command_id =
758 GET_NEXT(values, param_max_offset, rc);
759 uint32_t command_config_state =
760 GET_NEXT(values, param_max_offset, rc);
761 uint32_t index_offset =
762 GET_NEXT(values, param_max_offset, rc);
763 uint32_t length =
764 GET_NEXT(values, param_max_offset, rc);
765 switch (command_id) {
766 case BASS_BOOST_ENABLE:
767 if (length != 1 || index_offset != 0) {
768 pr_err("BASS_BOOST_ENABLE:invalid params\n");
769 rc = -EINVAL;
770 goto invalid_config;
771 }
772 prev_enable_flag = bass_boost->enable_flag;
773 bass_boost->enable_flag =
774 GET_NEXT(values, param_max_offset, rc);
775 pr_debug("%s: BASS_BOOST_ENABLE prev:%d new:%d\n",
776 __func__, prev_enable_flag,
777 bass_boost->enable_flag);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800778 if (prev_enable_flag == bass_boost->enable_flag)
Weiyin Jiang431b1c52019-06-25 23:05:14 +0800779 continue;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800780 max_params_length = params_length +
781 COMMAND_IID_PAYLOAD_SZ +
782 BASS_BOOST_ENABLE_PARAM_SZ;
783 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
784 "BASS_BOOST_ENABLE", rc);
785 if (rc != 0)
786 break;
787 param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_ENABLE;
788 param_hdr.param_size = BASS_BOOST_ENABLE_PARAM_SZ;
789 param_data = (u8 *) &bass_boost->enable_flag;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530790 break;
791 case BASS_BOOST_MODE:
792 if (length != 1 || index_offset != 0) {
793 pr_err("BASS_BOOST_MODE:invalid params\n");
794 rc = -EINVAL;
795 goto invalid_config;
796 }
797 bass_boost->mode =
798 GET_NEXT(values, param_max_offset, rc);
799 pr_debug("%s: BASS_BOOST_MODE val:%d\n",
800 __func__, bass_boost->mode);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800801 if (command_config_state != CONFIG_SET)
802 break;
803 max_params_length = params_length +
804 COMMAND_IID_PAYLOAD_SZ +
805 BASS_BOOST_MODE_PARAM_SZ;
806 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
807 "BASS_BOOST_MODE", rc);
808 if (rc != 0)
809 break;
810 param_hdr.param_id = AUDPROC_PARAM_ID_BASS_BOOST_MODE;
811 param_hdr.param_size = BASS_BOOST_MODE_PARAM_SZ;
812 param_data = (u8 *) &bass_boost->mode;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530813 break;
814 case BASS_BOOST_STRENGTH:
815 if (length != 1 || index_offset != 0) {
816 pr_err("BASS_BOOST_STRENGTH:invalid params\n");
817 rc = -EINVAL;
818 goto invalid_config;
819 }
820 bass_boost->strength =
821 GET_NEXT(values, param_max_offset, rc);
822 pr_debug("%s: BASS_BOOST_STRENGTH val:%d\n",
823 __func__, bass_boost->strength);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800824 if (command_config_state != CONFIG_SET)
825 break;
826 max_params_length = params_length +
827 COMMAND_IID_PAYLOAD_SZ +
828 BASS_BOOST_STRENGTH_PARAM_SZ;
829 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
830 "BASS_BOOST_STRENGTH", rc);
831 if (rc != 0)
832 break;
833 param_hdr.param_id =
834 AUDPROC_PARAM_ID_BASS_BOOST_STRENGTH;
835 param_hdr.param_size = BASS_BOOST_STRENGTH_PARAM_SZ;
836 param_data = (u8 *) &bass_boost->strength;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530837 break;
838 default:
Aditya Bavanari53fbc922019-04-26 14:38:29 +0530839 pr_err_ratelimited("%s: Invalid command to set config\n",
840 __func__);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800841 continue;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530842 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800843 if (rc)
844 goto invalid_config;
845
846 rc = q6common_pack_pp_params(updt_params, &param_hdr,
847 param_data, &packed_data_size);
848 if (rc) {
849 pr_err("%s: Failed to pack params, error %d\n",
850 __func__, rc);
851 goto invalid_config;
852 }
853
854 updt_params += packed_data_size;
855 params_length += packed_data_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530856 }
857 if (params_length && (rc == 0))
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800858 q6asm_set_pp_params(ac, NULL, params, params_length);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530859 else
860 pr_debug("%s: did not send pp params\n", __func__);
861invalid_config:
862 kfree(params);
863 return rc;
864}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530865EXPORT_SYMBOL(msm_audio_effects_bass_boost_handler);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530866
Laxminath Kasam8b1366a2017-10-05 01:44:16 +0530867/**
868 * msm_audio_effects_pbe_handler -
869 * Audio effects handler for pbe
870 *
871 * @ac: audio client handle
872 * @pbe: pbe params
873 * @values: values to be updated
874 *
875 * Return 0 on success or error on failure
876 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530877int msm_audio_effects_pbe_handler(struct audio_client *ac,
878 struct pbe_params *pbe,
879 long *values)
880{
881 long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
882 char *params = NULL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800883 u8 *updt_params;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530884 int rc = 0;
885 int devices = GET_NEXT(values, param_max_offset, rc);
886 int num_commands = GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800887 int i, prev_enable_flag;
888 uint32_t max_params_length = 0;
889 uint32_t params_length = 0;
890 struct param_hdr_v3 param_hdr;
891 u8 *param_data = NULL;
892 u32 packed_data_size = 0;
Weiyin Jiangfce04f72019-05-23 02:07:35 +0800893 int32_t *p_coeffs = NULL;
894 uint32_t lpf_len = 0, hpf_len = 0, bpf_len = 0;
895 uint32_t bsf_len = 0, tsf_len = 0, total_coeffs_len = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530896
897 pr_debug("%s\n", __func__);
898 if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
899 pr_err("%s: cannot set audio effects\n", __func__);
900 return -EINVAL;
901 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800902 params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
903 if (!params) {
904 pr_err("%s, params memory alloc failed\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530905 return -ENOMEM;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800906 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530907 pr_debug("%s: device: %d\n", __func__, devices);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800908 updt_params = (u8 *) params;
909 /* Set MID and IID once at top and only update param specific fields*/
910 memset(&param_hdr, 0, sizeof(param_hdr));
911 param_hdr.module_id = AUDPROC_MODULE_ID_PBE;
912 param_hdr.instance_id = INSTANCE_ID_0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530913 for (i = 0; i < num_commands; i++) {
914 uint32_t command_id =
915 GET_NEXT(values, param_max_offset, rc);
916 uint32_t command_config_state =
917 GET_NEXT(values, param_max_offset, rc);
918 uint32_t index_offset =
919 GET_NEXT(values, param_max_offset, rc);
920 uint32_t length =
921 GET_NEXT(values, param_max_offset, rc);
922 switch (command_id) {
923 case PBE_ENABLE:
924 pr_debug("%s: PBE_ENABLE\n", __func__);
925 if (length != 1 || index_offset != 0) {
926 pr_err("no valid params\n");
927 rc = -EINVAL;
928 goto invalid_config;
929 }
930 prev_enable_flag = pbe->enable_flag;
931 pbe->enable_flag =
932 GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800933 if (prev_enable_flag == pbe->enable_flag)
Weiyin Jiang431b1c52019-06-25 23:05:14 +0800934 continue;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -0800935 max_params_length = params_length +
936 COMMAND_IID_PAYLOAD_SZ +
937 PBE_ENABLE_PARAM_SZ;
938 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
939 "PBE_ENABLE", rc);
940 if (rc != 0)
941 break;
942 param_hdr.param_id = AUDPROC_PARAM_ID_PBE_ENABLE;
943 param_hdr.param_size = PBE_ENABLE_PARAM_SZ;
944 param_data = (u8 *) &pbe->enable_flag;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +0530945 break;
946 case PBE_CONFIG:
947 pr_debug("%s: PBE_PARAM length %u\n", __func__, length);
948 if (length > sizeof(struct pbe_config_t) ||
949 length < PBE_CONFIG_PARAM_LEN ||
950 index_offset != 0) {
951 pr_err("no valid params, len %d\n", length);
952 rc = -EINVAL;
953 goto invalid_config;
954 }
Weiyin Jiangfce04f72019-05-23 02:07:35 +0800955
956 pbe->config.real_bass_mix =
957 GET_NEXT(values, param_max_offset, rc);
958 pbe->config.bass_color_control =
959 GET_NEXT(values, param_max_offset, rc);
960 pbe->config.main_chain_delay =
961 GET_NEXT(values, param_max_offset, rc);
962 pbe->config.xover_filter_order =
963 GET_NEXT(values, param_max_offset, rc);
964 pbe->config.bandpass_filter_order =
965 GET_NEXT(values, param_max_offset, rc);
966 pbe->config.drc_delay =
967 GET_NEXT(values, param_max_offset, rc);
968 pbe->config.rms_tav =
969 GET_NEXT(values, param_max_offset, rc);
970 pbe->config.exp_threshold =
971 GET_NEXT(values, param_max_offset, rc);
972 pbe->config.exp_slope =
973 GET_NEXT(values, param_max_offset, rc);
974 pbe->config.comp_threshold =
975 GET_NEXT(values, param_max_offset, rc);
976 pbe->config.comp_slope =
977 GET_NEXT(values, param_max_offset, rc);
978 pbe->config.makeup_gain =
979 GET_NEXT(values, param_max_offset, rc);
980 pbe->config.comp_attack =
981 GET_NEXT(values, param_max_offset, rc);
982 pbe->config.comp_release =
983 GET_NEXT(values, param_max_offset, rc);
984 pbe->config.exp_attack =
985 GET_NEXT(values, param_max_offset, rc);
986 pbe->config.exp_release =
987 GET_NEXT(values, param_max_offset, rc);
988 pbe->config.limiter_bass_threshold =
989 GET_NEXT(values, param_max_offset, rc);
990 pbe->config.limiter_high_threshold =
991 GET_NEXT(values, param_max_offset, rc);
992 pbe->config.limiter_bass_makeup_gain =
993 GET_NEXT(values, param_max_offset, rc);
994 pbe->config.limiter_high_makeup_gain =
995 GET_NEXT(values, param_max_offset, rc);
996 pbe->config.limiter_bass_gc =
997 GET_NEXT(values, param_max_offset, rc);
998 pbe->config.limiter_high_gc =
999 GET_NEXT(values, param_max_offset, rc);
1000 pbe->config.limiter_delay =
1001 GET_NEXT(values, param_max_offset, rc);
1002 pbe->config.reserved =
1003 GET_NEXT(values, param_max_offset, rc);
1004
1005 p_coeffs = &pbe->config.p1LowPassCoeffs[0];
1006 lpf_len = (pbe->config.xover_filter_order == 3) ? 10 : 5;
1007 hpf_len = (pbe->config.xover_filter_order == 3) ? 10 : 5;
1008 bpf_len = pbe->config.bandpass_filter_order * 5;
1009 bsf_len = 5;
1010 tsf_len = 5;
1011 total_coeffs_len = lpf_len + hpf_len + bpf_len + bsf_len + tsf_len;
1012
1013 for (i = 0; i < total_coeffs_len; i++) {
1014 *p_coeffs++ = GET_NEXT(values, param_max_offset, rc);
1015 }
1016
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001017 if (command_config_state != CONFIG_SET)
1018 break;
Weiyin Jiangfce04f72019-05-23 02:07:35 +08001019
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001020 max_params_length =
1021 params_length + COMMAND_IID_PAYLOAD_SZ + length;
1022 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1023 "PBE_PARAM", rc);
1024 if (rc != 0)
1025 break;
1026 param_hdr.param_id = AUDPROC_PARAM_ID_PBE_PARAM_CONFIG;
1027 param_hdr.param_size = length;
Weiyin Jiangfce04f72019-05-23 02:07:35 +08001028 param_data = (u8 *) &pbe->config;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301029 break;
1030 default:
Aditya Bavanari53fbc922019-04-26 14:38:29 +05301031 pr_err_ratelimited("%s: Invalid command to set config\n",
1032 __func__);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001033 continue;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301034 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001035 if (rc)
1036 goto invalid_config;
1037
1038 rc = q6common_pack_pp_params(updt_params, &param_hdr,
1039 param_data, &packed_data_size);
1040 if (rc) {
1041 pr_err("%s: Failed to pack params, error %d\n",
1042 __func__, rc);
1043 goto invalid_config;
1044 }
1045
1046 updt_params += packed_data_size;
1047 params_length += packed_data_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301048 }
1049 if (params_length && (rc == 0))
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001050 q6asm_set_pp_params(ac, NULL, params, params_length);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301051invalid_config:
1052 kfree(params);
1053 return rc;
1054}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301055EXPORT_SYMBOL(msm_audio_effects_pbe_handler);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301056
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301057/**
1058 * msm_audio_effects_popless_eq_handler -
1059 * Audio effects handler for popless equalizer
1060 *
1061 * @ac: audio client handle
1062 * @eq: equalizer params
1063 * @values: values to be updated
1064 *
1065 * Return 0 on success or error on failure
1066 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301067int msm_audio_effects_popless_eq_handler(struct audio_client *ac,
1068 struct eq_params *eq,
1069 long *values)
1070{
1071 long *param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
1072 char *params = NULL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001073 u8 *updt_params = NULL;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301074 int rc = 0;
1075 int devices = GET_NEXT(values, param_max_offset, rc);
1076 int num_commands = GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001077 int i, prev_enable_flag;
1078 uint32_t max_params_length = 0;
1079 uint32_t params_length = 0;
1080 struct param_hdr_v3 param_hdr;
1081 u8 *param_data = NULL;
1082 u32 packed_data_size = 0;
1083 u8 *eq_config_data = NULL;
1084 u32 *updt_config_data = NULL;
1085 int config_param_length;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301086
1087 pr_debug("%s\n", __func__);
1088 if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
1089 pr_err("%s: cannot set audio effects\n", __func__);
1090 return -EINVAL;
1091 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001092 params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
1093 if (!params) {
1094 pr_err("%s, params memory alloc failed\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301095 return -ENOMEM;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001096 }
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301097 pr_debug("%s: device: %d\n", __func__, devices);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001098 updt_params = (u8 *) params;
1099 /* Set MID and IID once at top and only update param specific fields*/
1100 memset(&param_hdr, 0, sizeof(param_hdr));
1101 param_hdr.module_id = AUDPROC_MODULE_ID_POPLESS_EQUALIZER;
1102 param_hdr.instance_id = INSTANCE_ID_0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301103 for (i = 0; i < num_commands; i++) {
1104 uint32_t command_id =
1105 GET_NEXT(values, param_max_offset, rc);
1106 uint32_t command_config_state =
1107 GET_NEXT(values, param_max_offset, rc);
1108 uint32_t index_offset =
1109 GET_NEXT(values, param_max_offset, rc);
1110 uint32_t length =
1111 GET_NEXT(values, param_max_offset, rc);
1112 uint32_t idx;
1113 int j;
1114
1115 switch (command_id) {
1116 case EQ_ENABLE:
1117 if (length != 1 || index_offset != 0) {
1118 pr_err("EQ_ENABLE:invalid params\n");
1119 rc = -EINVAL;
1120 goto invalid_config;
1121 }
1122 prev_enable_flag = eq->enable_flag;
1123 eq->enable_flag =
1124 GET_NEXT(values, param_max_offset, rc);
1125 pr_debug("%s: EQ_ENABLE prev:%d new:%d\n", __func__,
1126 prev_enable_flag, eq->enable_flag);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001127 if (prev_enable_flag == eq->enable_flag)
Weiyin Jiang431b1c52019-06-25 23:05:14 +08001128 continue;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001129 max_params_length = params_length +
1130 COMMAND_IID_PAYLOAD_SZ +
1131 EQ_ENABLE_PARAM_SZ;
1132 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1133 "EQ_ENABLE", rc);
1134 if (rc != 0)
1135 break;
1136 param_hdr.param_id = AUDPROC_PARAM_ID_EQ_ENABLE;
1137 param_hdr.param_size = EQ_ENABLE_PARAM_SZ;
1138 param_data = (u8 *) &eq->enable_flag;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301139 break;
1140 case EQ_CONFIG:
1141 if (length < EQ_CONFIG_PARAM_LEN || index_offset != 0) {
1142 pr_err("EQ_CONFIG:invalid params\n");
1143 rc = -EINVAL;
1144 goto invalid_config;
1145 }
1146 pr_debug("%s: EQ_CONFIG bands:%d, pgain:%d, pset:%d\n",
1147 __func__, eq->config.num_bands,
1148 eq->config.eq_pregain, eq->config.preset_id);
1149 for (idx = 0; idx < MAX_EQ_BANDS; idx++)
1150 eq->per_band_cfg[idx].band_idx = -1;
1151 eq->config.eq_pregain =
1152 GET_NEXT(values, param_max_offset, rc);
1153 eq->config.preset_id =
1154 GET_NEXT(values, param_max_offset, rc);
1155 eq->config.num_bands =
1156 GET_NEXT(values, param_max_offset, rc);
1157 if (eq->config.num_bands > MAX_EQ_BANDS) {
1158 pr_err("EQ_CONFIG:invalid num of bands\n");
1159 rc = -EINVAL;
1160 goto invalid_config;
1161 }
1162 if (eq->config.num_bands &&
1163 (((length - EQ_CONFIG_PARAM_LEN)/
1164 EQ_CONFIG_PER_BAND_PARAM_LEN)
1165 != eq->config.num_bands)) {
1166 pr_err("EQ_CONFIG:invalid length per band\n");
1167 rc = -EINVAL;
1168 goto invalid_config;
1169 }
1170 for (j = 0; j < eq->config.num_bands; j++) {
1171 idx = GET_NEXT(values, param_max_offset, rc);
1172 if (idx >= MAX_EQ_BANDS) {
1173 pr_err("EQ_CONFIG:invalid band index\n");
1174 rc = -EINVAL;
1175 goto invalid_config;
1176 }
1177 eq->per_band_cfg[idx].band_idx = idx;
1178 eq->per_band_cfg[idx].filter_type =
1179 GET_NEXT(values, param_max_offset, rc);
1180 eq->per_band_cfg[idx].freq_millihertz =
1181 GET_NEXT(values, param_max_offset, rc);
1182 eq->per_band_cfg[idx].gain_millibels =
1183 GET_NEXT(values, param_max_offset, rc);
1184 eq->per_band_cfg[idx].quality_factor =
1185 GET_NEXT(values, param_max_offset, rc);
1186 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001187 if (command_config_state != CONFIG_SET)
1188 break;
1189 config_param_length = EQ_CONFIG_PARAM_SZ +
1190 (EQ_CONFIG_PER_BAND_PARAM_SZ *
1191 eq->config.num_bands);
1192 max_params_length = params_length +
1193 COMMAND_IID_PAYLOAD_SZ +
1194 config_param_length;
1195 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1196 "EQ_CONFIG", rc);
1197 if (rc != 0)
1198 break;
1199 param_hdr.param_id = AUDPROC_PARAM_ID_EQ_CONFIG;
1200 param_hdr.param_size = config_param_length;
1201
1202 if (!eq_config_data)
1203 eq_config_data = kzalloc(config_param_length,
1204 GFP_KERNEL);
1205 else
1206 memset(eq_config_data, 0, config_param_length);
1207 if (!eq_config_data) {
1208 pr_err("%s, EQ_CONFIG:memory alloc failed\n",
1209 __func__);
1210 rc = -ENOMEM;
1211 goto invalid_config;
1212 }
1213 param_data = eq_config_data;
1214 updt_config_data = (u32 *) eq_config_data;
1215 *updt_config_data++ = eq->config.eq_pregain;
1216 *updt_config_data++ = eq->config.preset_id;
1217 *updt_config_data++ = eq->config.num_bands;
1218 for (idx = 0; idx < MAX_EQ_BANDS; idx++) {
1219 if (eq->per_band_cfg[idx].band_idx < 0)
1220 continue;
1221 *updt_config_data++ =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301222 eq->per_band_cfg[idx].filter_type;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001223 *updt_config_data++ =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301224 eq->per_band_cfg[idx].freq_millihertz;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001225 *updt_config_data++ =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301226 eq->per_band_cfg[idx].gain_millibels;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001227 *updt_config_data++ =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301228 eq->per_band_cfg[idx].quality_factor;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001229 *updt_config_data++ =
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301230 eq->per_band_cfg[idx].band_idx;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301231 }
1232 break;
1233 case EQ_BAND_INDEX:
1234 if (length != 1 || index_offset != 0) {
1235 pr_err("EQ_BAND_INDEX:invalid params\n");
1236 rc = -EINVAL;
1237 goto invalid_config;
1238 }
1239 idx = GET_NEXT(values, param_max_offset, rc);
1240 if (idx > MAX_EQ_BANDS) {
1241 pr_err("EQ_BAND_INDEX:invalid band index\n");
1242 rc = -EINVAL;
1243 goto invalid_config;
1244 }
1245 eq->band_index = idx;
1246 pr_debug("%s: EQ_BAND_INDEX val:%d\n",
1247 __func__, eq->band_index);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001248 if (command_config_state != CONFIG_SET)
1249 break;
1250 max_params_length = params_length +
1251 COMMAND_IID_PAYLOAD_SZ +
1252 EQ_BAND_INDEX_PARAM_SZ;
1253 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1254 "EQ_BAND_INDEX", rc);
1255 if (rc != 0)
1256 break;
1257 param_hdr.param_id = AUDPROC_PARAM_ID_EQ_BAND_INDEX;
1258 param_hdr.param_size = EQ_BAND_INDEX_PARAM_SZ;
1259 param_data = (u8 *) &eq->band_index;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301260 break;
1261 case EQ_SINGLE_BAND_FREQ:
1262 if (length != 1 || index_offset != 0) {
1263 pr_err("EQ_SINGLE_BAND_FREQ:invalid params\n");
1264 rc = -EINVAL;
1265 goto invalid_config;
1266 }
1267 if (eq->band_index > MAX_EQ_BANDS) {
1268 pr_err("EQ_SINGLE_BAND_FREQ:invalid index\n");
1269 break;
1270 }
1271 eq->freq_millihertz =
1272 GET_NEXT(values, param_max_offset, rc);
1273 pr_debug("%s: EQ_SINGLE_BAND_FREQ idx:%d, val:%d\n",
1274 __func__, eq->band_index, eq->freq_millihertz);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001275 if (command_config_state != CONFIG_SET)
1276 break;
1277 max_params_length = params_length +
1278 COMMAND_IID_PAYLOAD_SZ +
1279 EQ_SINGLE_BAND_FREQ_PARAM_SZ;
1280 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1281 "EQ_SINGLE_BAND_FREQ", rc);
1282 if (rc != 0)
1283 break;
1284 param_hdr.param_id =
1285 AUDPROC_PARAM_ID_EQ_SINGLE_BAND_FREQ;
1286 param_hdr.param_size = EQ_SINGLE_BAND_FREQ_PARAM_SZ;
1287 param_data = (u8 *) &eq->freq_millihertz;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301288 break;
1289 default:
Aditya Bavanari53fbc922019-04-26 14:38:29 +05301290 pr_err_ratelimited("%s: Invalid command to set config\n",
1291 __func__);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001292 continue;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301293 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001294 if (rc)
1295 goto invalid_config;
1296
1297 rc = q6common_pack_pp_params(updt_params, &param_hdr,
1298 param_data, &packed_data_size);
1299 if (rc) {
1300 pr_err("%s: Failed to pack params, error %d\n",
1301 __func__, rc);
1302 goto invalid_config;
1303 }
1304
1305 updt_params += packed_data_size;
1306 params_length += packed_data_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301307 }
1308 if (params_length && (rc == 0))
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001309 q6asm_set_pp_params(ac, NULL, params, params_length);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301310 else
1311 pr_debug("%s: did not send pp params\n", __func__);
1312invalid_config:
1313 kfree(params);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001314 kfree(eq_config_data);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301315 return rc;
1316}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301317EXPORT_SYMBOL(msm_audio_effects_popless_eq_handler);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301318
1319static int __msm_audio_effects_volume_handler(struct audio_client *ac,
1320 struct soft_volume_params *vol,
1321 long *values,
1322 int instance)
1323{
1324 int devices;
1325 int num_commands;
1326 char *params = NULL;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001327 u8 *updt_params;
1328 int i;
1329 uint32_t vol_gain_2ch = 0;
1330 uint32_t max_params_length = 0;
1331 uint32_t params_length = 0;
1332 struct param_hdr_v3 param_hdr;
1333 u32 packed_data_size = 0;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301334 long *param_max_offset;
1335 int rc = 0;
1336
1337 pr_debug("%s: instance: %d\n", __func__, instance);
1338 if (!values) {
1339 pr_err("%s: set audio effects failed, no valid data\n",
1340 __func__);
1341 return -EINVAL;
1342 }
1343 param_max_offset = values + MAX_PP_PARAMS_SZ - 1;
1344 devices = GET_NEXT(values, param_max_offset, rc);
1345 num_commands = GET_NEXT(values, param_max_offset, rc);
1346 if (!ac || (devices == -EINVAL) || (num_commands == -EINVAL)) {
1347 pr_err("%s: cannot set audio effects\n", __func__);
1348 return -EINVAL;
1349 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001350 params = kzalloc(MAX_INBAND_PARAM_SZ, GFP_KERNEL);
1351 if (!params) {
1352 pr_err("%s, params memory alloc failed\n", __func__);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301353 return -ENOMEM;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001354 }
1355 updt_params = (u8 *) params;
1356 /* Set MID and IID once at top and only update param specific fields*/
1357 memset(&param_hdr, 0, sizeof(param_hdr));
1358 q6asm_set_soft_volume_module_instance_ids(instance, &param_hdr);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301359 for (i = 0; i < num_commands; i++) {
1360 uint32_t command_id =
1361 GET_NEXT(values, param_max_offset, rc);
1362 uint32_t command_config_state =
1363 GET_NEXT(values, param_max_offset, rc);
1364 uint32_t index_offset =
1365 GET_NEXT(values, param_max_offset, rc);
1366 uint32_t length =
1367 GET_NEXT(values, param_max_offset, rc);
1368 switch (command_id) {
1369 case SOFT_VOLUME_GAIN_2CH:
1370 case SOFT_VOLUME2_GAIN_2CH:
1371 if (length != 2 || index_offset != 0) {
1372 pr_err("VOLUME_GAIN_2CH: invalid params\n");
1373 rc = -EINVAL;
1374 goto invalid_config;
1375 }
1376 vol->left_gain = GET_NEXT(values, param_max_offset, rc);
1377 vol->right_gain =
1378 GET_NEXT(values, param_max_offset, rc);
1379 vol->master_gain = 0x2000;
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001380 if (command_config_state != CONFIG_SET)
1381 break;
1382 max_params_length = params_length +
1383 COMMAND_IID_PAYLOAD_SZ +
1384 SOFT_VOLUME_GAIN_2CH_PARAM_SZ +
1385 COMMAND_IID_PAYLOAD_SZ +
1386 SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
1387 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1388 "VOLUME/VOLUME2_GAIN_2CH", rc);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301389 break;
1390 case SOFT_VOLUME_GAIN_MASTER:
1391 case SOFT_VOLUME2_GAIN_MASTER:
1392 if (length != 1 || index_offset != 0) {
1393 pr_err("VOLUME_GAIN_MASTER: invalid params\n");
1394 rc = -EINVAL;
1395 goto invalid_config;
1396 }
1397 vol->left_gain = 0x2000;
1398 vol->right_gain = 0x2000;
1399 vol->master_gain =
1400 GET_NEXT(values, param_max_offset, rc);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001401 if (command_config_state != CONFIG_SET)
1402 break;
1403 max_params_length = params_length +
1404 COMMAND_IID_PAYLOAD_SZ +
1405 SOFT_VOLUME_GAIN_2CH_PARAM_SZ +
1406 COMMAND_IID_PAYLOAD_SZ +
1407 SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
1408 CHECK_PARAM_LEN(max_params_length, MAX_INBAND_PARAM_SZ,
1409 "VOLUME/VOLUME2_GAIN_MASTER", rc);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301410 break;
1411 default:
Aditya Bavanari53fbc922019-04-26 14:38:29 +05301412 pr_err_ratelimited("%s: Invalid command id: %d to set config\n",
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301413 __func__, command_id);
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001414 continue;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301415 }
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001416 if (rc)
1417 continue;
1418
1419 /* Set Volume Control for Left/Right */
1420 param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_LR_CHANNEL_GAIN;
1421 param_hdr.param_size = SOFT_VOLUME_GAIN_2CH_PARAM_SZ;
1422 vol_gain_2ch = (vol->left_gain << 16) | vol->right_gain;
1423 rc = q6common_pack_pp_params(updt_params, &param_hdr,
1424 (u8 *) &vol_gain_2ch,
1425 &packed_data_size);
1426 if (rc) {
1427 pr_err("%s: Failed to pack params, error %d\n",
1428 __func__, rc);
1429 goto invalid_config;
1430 }
1431
1432 updt_params += packed_data_size;
1433 params_length += packed_data_size;
1434
1435 /* Set Master Volume Control */
1436 param_hdr.param_id = ASM_PARAM_ID_VOL_CTRL_MASTER_GAIN;
1437 param_hdr.param_size = SOFT_VOLUME_GAIN_MASTER_PARAM_SZ;
1438 rc = q6common_pack_pp_params(updt_params, &param_hdr,
1439 (u8 *) &vol->master_gain,
1440 &packed_data_size);
1441 if (rc) {
1442 pr_err("%s: Failed to pack params, error %d\n",
1443 __func__, rc);
1444 goto invalid_config;
1445 }
1446
1447 updt_params += packed_data_size;
1448 params_length += packed_data_size;
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301449 }
1450 if (params_length && (rc == 0))
Vignesh Kulothunganfa497d22018-01-29 17:21:19 -08001451 q6asm_set_pp_params(ac, NULL, params, params_length);
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301452invalid_config:
1453 kfree(params);
1454 return rc;
1455}
1456
1457int msm_audio_effects_volume_handler(struct audio_client *ac,
1458 struct soft_volume_params *vol,
1459 long *values)
1460{
1461 return __msm_audio_effects_volume_handler(ac, vol, values,
1462 SOFT_VOLUME_INSTANCE_1);
1463}
1464
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301465/**
1466 * msm_audio_effects_volume_handler_v2 -
1467 * Audio effects handler for volume
1468 *
1469 * @ac: audio client handle
1470 * @vol: volume params
1471 * @values: values to be updated
1472 * @instance: instance to update
1473 *
1474 * Return 0 on success or error on failure
1475 */
Asish Bhattacharya8e2277f2017-07-20 18:31:55 +05301476int msm_audio_effects_volume_handler_v2(struct audio_client *ac,
1477 struct soft_volume_params *vol,
1478 long *values, int instance)
1479{
1480 return __msm_audio_effects_volume_handler(ac, vol, values, instance);
1481}
Laxminath Kasam8b1366a2017-10-05 01:44:16 +05301482EXPORT_SYMBOL(msm_audio_effects_volume_handler_v2);