blob: 032617b7ffcdf409e3db9db4294e8719b47a5d56 [file] [log] [blame]
Quinn Male2e883752019-03-22 11:28:54 -07001/* sound_trigger_platform.c
2 *
3 * This file contains the platform specific functionality.
4 *
Zhou Songba4ac3b2021-03-04 00:30:00 +08005 * Copyright (c) 2013-2021, The Linux Foundation. All rights reserved.
Quinn Male2e883752019-03-22 11:28:54 -07006 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following
14 * disclaimer in the documentation and/or other materials provided
15 * with the distribution.
16 * * Neither the name of The Linux Foundation nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
21 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
27 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
29 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
30 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * Not a Contribution.
33 *
34 * Copyright (C) 2014 The Android Open Source Project
35 *
36 * Licensed under the Apache License, Version 2.0 (the "License");
37 * you may not use this file except in compliance with the License.
38 * You may obtain a copy of the License at
39 *
40 * http://www.apache.org/licenses/LICENSE-2.0
41 *
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 * See the License for the specific language governing permissions and
46 * limitations under the License.
47 */
48#define LOG_TAG "sound_trigger_platform"
49#define ATRACE_TAG (ATRACE_TAG_HAL)
50/* #define LOG_NDEBUG 0 */
51#define LOG_NDDEBUG 0
52#ifdef LINUX_ENABLED
53/*temporay change since defination is not found for msmcal-hwdep.h*/
54typedef unsigned int __u32;
55typedef unsigned char __u8;
56#endif
57
58#include <cutils/log.h>
59#include <cutils/str_parms.h>
60#include <cutils/properties.h>
61#include <cutils/trace.h>
62#include <dlfcn.h>
63#include <expat.h>
64#include <errno.h>
65#include <fcntl.h>
66#include <sys/ioctl.h>
Meng Wang78b97242020-05-08 14:24:51 +080067#include <sound/asound.h>
Quinn Male2e883752019-03-22 11:28:54 -070068#include <sound/msmcal-hwdep.h>
69#include <linux/msm_audio_calibration.h> /* for AUDIO_CORE_METAINFO_CAL_TYPE; audio_cal_info_metainfo */
70#include <sound/lsm_params.h>
71#include "sound_trigger_platform.h"
72#include "sound_trigger_hw.h"
73#include "st_hw_session_gcs.h" /* for gcs_init/deinit */
74#include "st_hw_session_pcm.h" /* for pcm_init/deinit */
75#include "st_second_stage.h"
76
77/* platform info keys */
78#define ST_PARAM_KEY_MAX_CPE_SESSIONS "max_cpe_sessions"
79#define ST_PARAM_KEY_MAX_APE_SESSIONS "max_ape_sessions"
80#define ST_PARAM_KEY_MAX_WDSP_SESSIONS "max_wdsp_sessions"
81#define ST_PARAM_KEY_SW_MAD "sw_mad"
82#define ST_PARAM_KEY_BG_KWD "bg_kwd"
83#define ST_PARAM_KEY_ENABLE_FAILURE_DETECTION "enable_failure_detection"
Quinn Male2e883752019-03-22 11:28:54 -070084#define ST_PARAM_KEY_RX_CONCURRENCY_DISABLED "rx_concurrency_disabled"
85#define ST_PARAM_KEY_RX_MAX_CONC_SESSIONS "rx_conc_max_st_ses"
86#define ST_PARAM_KEY_CONCURRENT_CAPTURE "concurrent_capture"
87#define ST_PARAM_KEY_CONCURRENT_VOICE_CALL "concurrent_voice_call"
88#define ST_PARAM_KEY_CONCURRENT_VOIP_CALL "concurrent_voip_call"
89
90
91#define ST_PARAM_KEY_FIRMWARE_IMAGE "firmware_image"
92#define ST_PARAM_KEY_SM_VENDOR_UUID "vendor_uuid"
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -070093#define ST_PARAM_KEY_MERGE_FIRST_STAGE_SOUNDMODELS "merge_first_stage_sound_models"
Quinn Male2e883752019-03-22 11:28:54 -070094#define ST_PARAM_KEY_APP_TYPE "app_type"
Quinn Male58749452020-03-26 17:14:56 -070095#define ST_PARAM_KEY_PDK5_APP_TYPE "pdk5_app_type"
Quinn Male2e883752019-03-22 11:28:54 -070096#define ST_PARAM_KEY_MAX_CPE_PHRASES "max_cpe_phrases"
97#define ST_PARAM_KEY_MAX_APE_USERS "max_ape_users"
98#define ST_PARAM_KEY_MAX_APE_PHRASES "max_ape_phrases"
99#define ST_PARAM_KEY_MAX_CPE_USERS "max_cpe_users"
100#define ST_PARAM_KEY_SAMPLE_RATE "sample_rate"
101#define ST_PARAM_KEY_BIT_WIDTH "bit_width"
102#define ST_PARAM_KEY_CHANNEL_COUNT "channel_count"
103#define ST_PARAM_KEY_IN_CHANNELS "in_channels"
Quinn Male3d7d9d42019-05-20 13:35:01 -0700104#define ST_PARAM_KEY_IN_CHANNELS_LPI "in_channels_lpi"
Quinn Male23026702019-07-19 10:51:16 -0700105#define ST_PARAM_KEY_LPI_MODE "lpi_mode"
Quinn Male2e883752019-03-22 11:28:54 -0700106#define ST_PARAM_KEY_OUT_CHANNELS "out_channels"
107#define ST_PARAM_KEY_ADM_CFG_PROFILE "adm_cfg_profile"
108#define ST_PARAM_KEY_CAPTURE_DEVICE "capture_device"
Quinn Male58749452020-03-26 17:14:56 -0700109#define ST_PARAM_KEY_MODULE_TYPE "module_type"
Quinn Male2e883752019-03-22 11:28:54 -0700110#define ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS "load_sound_model_ids"
111#define ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS "unload_sound_model_ids"
112#define ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS "confidence_levels_ids"
113#define ST_PARAM_KEY_OPERATION_MODE_IDS "operation_mode_ids"
114#define ST_PARAM_KEY_POLLING_ENABLE_IDS "polling_enable_ids"
115#define ST_PARAM_KEY_CUSTOM_CONFIG_IDS "custom_config_ids"
116#define ST_PARAM_KEY_DET_EVENT_TYPE_IDS "det_event_type_ids"
117#define ST_PARAM_KEY_DETECTION_EVENT_IDS "detection_event_ids"
118#define ST_PARAM_KEY_READ_REQ_IDS "read_cmd_ids"
119#define ST_PARAM_KEY_READ_RSP_IDS "read_rsp_ids"
120#define ST_PARAM_KEY_START_ENGINE_IDS "start_engine_ids"
121#define ST_PARAM_KEY_RESTART_ENGINE_IDS "restart_engine_ids"
122#define ST_PARAM_KEY_REQUEST_DETECTION_IDS "request_detection_ids"
Quinn Male3d7d9d42019-05-20 13:35:01 -0700123#define ST_PARAM_KEY_LAB_DAM_CFG_IDS "lab_dam_cfg_ids"
Quinn Male2e883752019-03-22 11:28:54 -0700124#define ST_PARAM_KEY_UID "uid"
125#define ST_PARAM_KEY_ACDB_DEVICES "acdb_devices"
126#define ST_PARAM_KEY_CAPTURE_KEYWORD "capture_keyword"
127#define ST_PARAM_KEY_CLIENT_CAPTURE_READ_DELAY "client_capture_read_delay"
128#define ST_PARAM_KEY_KW_START_TOLERANCE "kw_start_tolerance"
129#define ST_PARAM_KEY_KW_END_TOLERANCE "kw_end_tolerance"
130#define ST_PARAM_KEY_EXECUTION_TYPE "execution_type"
Shalini Manjunatha47c34c82021-05-10 16:46:43 +0530131#define ST_PARAM_KEY_SECOND_STAGE_SUPPORTED "second_stage_supported"
Quinn Male2e883752019-03-22 11:28:54 -0700132#define ST_PARAM_KEY_EVENT_TIMESTAMP_MODE "event_timestamp_mode"
133#define ST_PARAM_KEY_BACKEND_PORT_NAME "backend_port_name"
134#define ST_PARAM_KEY_BACKEND_DAI_NAME "backend_dai_name"
135#define ST_PARAM_KEY_SND_CARD_NAME "snd_card_name"
136#define ST_PARAM_KEY_FLUENCE_TYPE "fluence_type"
137#define ST_PARAM_KEY_WDSP_FLUENCE_TYPE "wdsp_fluence_type"
138#define ST_PARAM_KEY_SUPPORT_DEVICE_SWITCH "support_device_switch"
139#define ST_PARAM_KEY_EXECUTION_MODE "execution_mode"
140#define ST_PARAM_KEY_TRANSIT_TO_ADSP_ON_PLAYBACK "transit_to_adsp_on_playback"
141#define ST_PARAM_KEY_TRANSIT_TO_ADSP_ON_BATTERY_CHARGING \
142 "transit_to_adsp_on_battery_charging"
143#define ST_PARAM_KEY_TRANSIT_TO_NON_LPI_ON_BATTERY_CHARGING \
144 "transit_to_non_lpi_on_battery_charging"
Quinn Male3d7d9d42019-05-20 13:35:01 -0700145#define ST_PARAM_KEY_PLATFORM_LPI_ENABLE "platform_lpi_enable"
Quinn Malecc1affd2019-07-18 16:13:31 -0700146#define ST_PARAM_KEY_SUPPORT_BARGE_IN_MODE \
147 "support_non_lpi_without_ec"
Quinn Male2e883752019-03-22 11:28:54 -0700148#define ST_PARAM_KEY_TRANSIT_WAIT_TIME "transit_wait_time"
149#define ST_PARAM_KEY_SPLIT_EC_REF_DATA "split_ec_ref_data"
150#define ST_PARAM_KEY_EC_REF_CHANNEL_COUNT "ec_ref_channel_count"
151#define ST_PARAM_KEY_IMPLEMENTER_UUID "implementer_uuid"
152#define ST_PARAM_KEY_IMPLEMENTER_VERSION "implementer_version"
153#define ST_PARAM_KEY_BB_IDS "bridge_buffer_ids"
154#define ST_PARAM_KEY_LAB_CONTROL_IDS "lab_control_ids"
155#define ST_PARAM_KEY_LPI_ENABLE "lpi_enable"
156#define ST_PARAM_KEY_VAD_ENABLE "vad_enable"
157#define ST_PARAM_KEY_DEDICATED_SVA_PATH "dedicated_sva_path"
Zhou Songd18c6712019-06-10 11:20:10 +0800158#define ST_PARAM_KEY_DEDICATED_HEADSET_PATH "dedicated_headset_path"
Quinn Maleaba13db2019-07-11 15:52:14 -0700159#define ST_PARAM_KEY_ENABLE_DEBUG_DUMPS "enable_debug_dumps"
Quinn Male3d7d9d42019-05-20 13:35:01 -0700160#define ST_PARAM_KEY_DAM_TOKEN_ID "dam_token_id"
Harshal Ahire89337992020-07-13 02:38:14 +0530161#define ST_PARAM_KEY_GET_MODULE_VERSION "get_module_version"
162#define ST_PARAM_KEY_VERSION_ID "version_ids"
Quinn Male2e883752019-03-22 11:28:54 -0700163
164#ifndef Q6AFE_HWDEP_NODE
165#define Q6AFE_HWDEP_NODE -1
166#endif
167
168#define ST_PARAM_KEY_DEVICE_HANDSET_APE "DEVICE_HANDSET_MIC_APE"
169#define ST_PARAM_KEY_DEVICE_HANDSET_CPE "DEVICE_HANDSET_MIC_CPE"
170#define ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP "DEVICE_HANDSET_MIC_ECPP_CPE"
171#define ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE "DEVICE_HANDSET_DMIC_CPE"
172#define ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE "DEVICE_HANDSET_TMIC_CPE"
173#define ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE "DEVICE_HANDSET_QMIC_CPE"
174#define ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE "DEVICE_HANDSET_DMIC_APE"
175#define ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE "DEVICE_HANDSET_TMIC_APE"
176#define ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE "DEVICE_HANDSET_QMIC_APE"
177#define ST_PARAM_KEY_DEVICE_HANDSET_6MIC_APE "DEVICE_HANDSET_6MIC_APE"
178#define ST_PARAM_KEY_DEVICE_HANDSET_8MIC_APE "DEVICE_HANDSET_8MIC_APE"
179#define ST_PARAM_KEY_DEVICE_HEADSET_CPE "DEVICE_HEADSET_MIC_CPE"
180#define ST_PARAM_KEY_DEVICE_HEADSET_APE "DEVICE_HEADSET_MIC_APE"
181#define ST_PARAM_KEY_DEVICE_HANDSET_APE_PP "DEVICE_HANDSET_MIC_PP_APE"
182#define ST_PARAM_KEY_DEVICE_HANDSET_QMIC_ARM "DEVICE_HANDSET_QMIC_ARM"
183#define ST_PARAM_KEY_DEVICE_HANDSET_6MIC_ARM "DEVICE_HANDSET_6MIC_ARM"
184#define ST_PARAM_KEY_DEVICE_HANDSET_8MIC_ARM "DEVICE_HANDSET_8MIC_ARM"
185#define ST_PARAM_KEY_DEVICE_HANDSET_DMIC_LPI_APE "DEVICE_HANDSET_DMIC_LPI_APE"
186#define ST_PARAM_KEY_DEVICE_HANDSET_TMIC_LPI_APE "DEVICE_HANDSET_TMIC_LPI_APE"
187#define ST_PARAM_KEY_DEVICE_HANDSET_QMIC_LPI_APE "DEVICE_HANDSET_QMIC_LPI_APE"
188#define ST_PARAM_KEY_DEVICE_HANDSET_6MIC_LPI_APE "DEVICE_HANDSET_6MIC_LPI_APE"
189#define ST_PARAM_KEY_DEVICE_HANDSET_8MIC_LPI_APE "DEVICE_HANDSET_8MIC_LPI_APE"
Quinn Male3d7d9d42019-05-20 13:35:01 -0700190#define ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE "DEVICE_HEADSET_MIC_APE_LPI"
Quinn Male2e883752019-03-22 11:28:54 -0700191
192#define ST_PARAM_KEY_SS_SM_TYPE "sm_detection_type"
193#define ST_PARAM_KEY_SS_SM_ID "sm_id"
194#define ST_PARAM_KEY_SS_LIB "module_lib"
Zhou Songebe8a932020-02-10 12:18:31 +0800195#define ST_PARAM_KEY_SS_DATA_BEFORE_KW_START "data_before_kw_start"
Quinn Male2e883752019-03-22 11:28:54 -0700196#define ST_PARAM_KEY_SS_DATA_AFTER_KW_END "data_after_kw_end"
197
198#define ST_BACKEND_PORT_NAME_MAX_SIZE 25
199#define ST_MAX_LENGTH_MIXER_CONTROL 128
200#define ST_MAX_NUM_CHANNELS 4
201#define ST_MAX_SND_CARD_NAME_LENGTH 100
202#define ST_MAX_STRING_PARAM_SIZE 128
203
204typedef int (*acdb_loader_init_v2_t)(const char *, const char *, int);
205typedef void (*acdb_loader_deallocate_t)(void);
206typedef void (*acdb_loader_send_listen_device_cal_t)(int, int, int, int);
207typedef void (*acdb_loader_send_listen_device_cal_v1_t)(int, int, int, int, int);
208typedef int (*acdb_loader_send_listen_lsm_cal_t)(int, int, int, int);
209typedef int (*acdb_loader_send_listen_lsm_cal_v1_t)(int, int, int, int, int);
210typedef int (*acdb_loader_get_calibration_t)(char *, int, void *);
211typedef int (*acdb_loader_get_audio_cal_t) (void *, void *, unsigned int*);
212typedef int (*acdb_loader_send_common_custom_topology_t)();
213
214struct st_device_index
215st_device_name_idx[ST_EXEC_MODE_MAX][ST_DEVICE_MAX] = {
216 {
217 {"DEVICE_HANDSET_MIC_APE", ST_DEVICE_HANDSET_MIC},
218 {"DEVICE_HANDSET_DMIC_APE", ST_DEVICE_HANDSET_DMIC},
219 {"DEVICE_HANDSET_TMIC_APE", ST_DEVICE_HANDSET_TMIC},
220 {"DEVICE_HANDSET_QMIC_APE", ST_DEVICE_HANDSET_QMIC},
221 {"DEVICE_HANDSET_6MIC_APE", ST_DEVICE_HANDSET_6MIC},
222 {"DEVICE_HANDSET_8MIC_APE", ST_DEVICE_HANDSET_8MIC},
223 {"DEVICE_HANDSET_MIC_PP_APE", ST_DEVICE_HANDSET_MIC_PP},
224 {"DEVICE_HANDSET_DMIC_LPI_APE", ST_DEVICE_HANDSET_DMIC_LPI},
225 {"DEVICE_HANDSET_TMIC_LPI_APE", ST_DEVICE_HANDSET_TMIC_LPI},
226 {"DEVICE_HANDSET_QMIC_LPI_APE", ST_DEVICE_HANDSET_QMIC_LPI},
227 {"DEVICE_HANDSET_6MIC_LPI_APE", ST_DEVICE_HANDSET_6MIC_LPI},
228 {"DEVICE_HANDSET_8MIC_LPI_APE", ST_DEVICE_HANDSET_8MIC_LPI},
229 {"DEVICE_HEADSET_MIC_APE", ST_DEVICE_HEADSET_MIC},
Quinn Male3d7d9d42019-05-20 13:35:01 -0700230 {"DEVICE_HEADSET_MIC_APE_LPI", ST_DEVICE_HEADSET_MIC_LPI},
Quinn Male2e883752019-03-22 11:28:54 -0700231 },
232 {
233 {"DEVICE_HANDSET_MIC_CPE", ST_DEVICE_HANDSET_MIC},
234 {"DEVICE_HANDSET_MIC_ECPP_CPE", ST_DEVICE_HANDSET_MIC_ECPP},
235 {"DEVICE_HANDSET_DMIC_CPE", ST_DEVICE_HANDSET_DMIC},
236 {"DEVICE_HANDSET_TMIC_CPE", ST_DEVICE_HANDSET_TMIC},
237 {"DEVICE_HANDSET_QMIC_CPE", ST_DEVICE_HANDSET_QMIC},
238 {"DEVICE_HEADSET_MIC_CPE", ST_DEVICE_HEADSET_MIC},
239 },
240 {
241 {"DEVICE_HANDSET_QMIC_ARM", ST_DEVICE_HANDSET_QMIC},
242 {"DEVICE_HANDSET_6MIC_ARM", ST_DEVICE_HANDSET_6MIC},
243 {"DEVICE_HANDSET_8MIC_ARM", ST_DEVICE_HANDSET_8MIC},
244 },
245};
246
247static const char * const
248st_device_table[ST_EXEC_MODE_MAX][ST_DEVICE_MAX] = {
249 {
250 /* ADSP SVA devices */
251 [ST_DEVICE_NONE] = "none",
252 [ST_DEVICE_HANDSET_MIC] = "listen-ape-handset-mic",
253 [ST_DEVICE_HANDSET_DMIC] = "listen-ape-handset-dmic",
254 [ST_DEVICE_HANDSET_TMIC] = "listen-ape-handset-tmic",
255 [ST_DEVICE_HANDSET_QMIC] = "listen-ape-handset-qmic",
256 [ST_DEVICE_HANDSET_6MIC] = "listen-ape-handset-6mic",
257 [ST_DEVICE_HANDSET_8MIC] = "listen-ape-handset-8mic",
258 [ST_DEVICE_HANDSET_MIC_PP] = "listen-ape-handset-mic-preproc",
259 [ST_DEVICE_HANDSET_DMIC_LPI] = "listen-ape-handset-dmic",
260 [ST_DEVICE_HANDSET_TMIC_LPI] = "listen-ape-handset-tmic",
261 [ST_DEVICE_HANDSET_QMIC_LPI] = "listen-ape-handset-qmic",
262 [ST_DEVICE_HANDSET_6MIC_LPI] = "listen-ape-handset-6mic",
263 [ST_DEVICE_HANDSET_8MIC_LPI] = "listen-ape-handset-8mic",
264 [ST_DEVICE_HEADSET_MIC] = "listen-ape-headset-mic",
Quinn Male3d7d9d42019-05-20 13:35:01 -0700265 [ST_DEVICE_HEADSET_MIC_LPI] = "listen-ape-headset-mic",
Quinn Male2e883752019-03-22 11:28:54 -0700266 },
267 {
268 /* CPE SVA devices */
269 [ST_DEVICE_NONE] = "none",
270 [ST_DEVICE_HANDSET_MIC] = "listen-cpe-handset-mic",
271 [ST_DEVICE_HANDSET_MIC_ECPP] = "listen-cpe-handset-mic-ecpp",
272 [ST_DEVICE_HANDSET_DMIC] = "listen-cpe-handset-dmic",
273 [ST_DEVICE_HANDSET_TMIC] = "listen-cpe-handset-tmic",
274 [ST_DEVICE_HANDSET_QMIC] = "listen-cpe-handset-qmic",
275 [ST_DEVICE_HEADSET_MIC] = "listen-cpe-headset-mic",
276 },
277 {
278 /* ARM SVA devices */
279 [ST_DEVICE_NONE] = "none",
280 [ST_DEVICE_HANDSET_QMIC] = "listen-handset-qmic",
281 [ST_DEVICE_HANDSET_6MIC] = "listen-handset-6mic",
282 [ST_DEVICE_HANDSET_8MIC] = "listen-handset-8mic",
283 },
284};
285
286/* ACDB IDs for each device for both CDSP and ADSP */
287static int acdb_device_table[ST_EXEC_MODE_MAX][ST_DEVICE_MAX] = {
288 {
289 [ST_DEVICE_NONE] = -1,
290 [ST_DEVICE_HANDSET_MIC] = DEVICE_HANDSET_APE_ACDB_ID,
291 [ST_DEVICE_HANDSET_DMIC] = DEVICE_HANDSET_APE_ACDB_ID,
292 [ST_DEVICE_HANDSET_TMIC] = DEVICE_HANDSET_APE_ACDB_ID,
293 [ST_DEVICE_HANDSET_QMIC] = DEVICE_HANDSET_APE_ACDB_ID,
294 [ST_DEVICE_HANDSET_6MIC] = DEVICE_HANDSET_APE_ACDB_ID,
295 [ST_DEVICE_HANDSET_8MIC] = DEVICE_HANDSET_APE_ACDB_ID,
296 [ST_DEVICE_HANDSET_MIC_PP] = DEVICE_HANDSET_APE_ACDB_ID,
297 [ST_DEVICE_HANDSET_DMIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
298 [ST_DEVICE_HANDSET_TMIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
299 [ST_DEVICE_HANDSET_QMIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
300 [ST_DEVICE_HANDSET_6MIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
301 [ST_DEVICE_HANDSET_8MIC_LPI] = DEVICE_HANDSET_APE_ACDB_ID,
302 [ST_DEVICE_HEADSET_MIC] = DEVICE_HEADSET_APE_ACDB_ID,
Quinn Male3d7d9d42019-05-20 13:35:01 -0700303 [ST_DEVICE_HEADSET_MIC_LPI] = DEVICE_HEADSET_APE_ACDB_ID,
Quinn Male2e883752019-03-22 11:28:54 -0700304 },
305 {
306 [ST_DEVICE_NONE] = -1,
307 [ST_DEVICE_HANDSET_MIC] = DEVICE_HANDSET_CPE_ACDB_ID,
308 [ST_DEVICE_HANDSET_MIC_ECPP] = DEVICE_HANDSET_CPE_ACDB_ID,
309 [ST_DEVICE_HANDSET_DMIC] = DEVICE_HANDSET_CPE_ACDB_ID,
310 [ST_DEVICE_HANDSET_TMIC] = DEVICE_HANDSET_CPE_ACDB_ID,
311 [ST_DEVICE_HANDSET_QMIC] = DEVICE_HANDSET_CPE_ACDB_ID,
312 [ST_DEVICE_HEADSET_MIC] = DEVICE_HEADSET_CPE_ACDB_ID,
313 },
314 {
315 [ST_DEVICE_NONE] = -1,
316 [ST_DEVICE_HANDSET_QMIC] = DEVICE_HANDSET_ARM_ACDB_ID,
317 [ST_DEVICE_HANDSET_6MIC] = DEVICE_HANDSET_ARM_ACDB_ID,
318 [ST_DEVICE_HANDSET_8MIC] = DEVICE_HANDSET_ARM_ACDB_ID,
319 },
320};
321
322/*
323 * backend type for each device for both ADSP and CPE.
324 * The backend type is used to determine whether two st_devices
325 * share common backend or not.
326 */
327static char *st_device_backend_table[ST_EXEC_MODE_MAX][ST_DEVICE_MAX];
328
329/* Qualcomm Technologies Inc. vendorUuid */
330static const sound_trigger_uuid_t qcva_uuid =
331 { 0x68ab2d40, 0xe860, 0x11e3, 0x95ef, { 0x00, 0x02, 0xa5, 0xd5, 0xc5, 0x1b } };
332
333/* QTI Music Detection vendorUuid */
334static const sound_trigger_uuid_t qcmd_uuid =
335 { 0x876c1b46, 0x9d4d, 0x40cc, 0xa4fd, { 0x4d, 0x5e, 0xc7, 0xa8, 0x0e, 0x47 } };
336
337/* Platform xml tags */
338typedef enum {
339 TAG_ROOT,
340 TAG_COMMON,
341 TAG_ACDB,
342 TAG_BACKEND_TYPE,
343 TAG_SOUND_MODEL,
344 TAG_ARM_SS_USECASE,
345 TAG_GCS_USECASE,
346 TAG_LSM_USECASE,
347 TAG_ADM_CFG,
348 TAG_LPMA_CONFIG,
349 TAG_ACDB_METAINFO_KEY,
Quinn Male58749452020-03-26 17:14:56 -0700350 TAG_LSM_SS_USECASE,
351 TAG_MODULE_PARAMS
Quinn Male2e883752019-03-22 11:28:54 -0700352} st_xml_tags_t;
353
354typedef void (*st_xml_process_fn)(void *platform, const XML_Char **attr);
355static void platform_stdev_process_kv_params(void *platform, const XML_Char **attr);
356static void process_stdev_acdb_metainfo_key(void *platform, const XML_Char **attr);
357
358/* function pointers for xml tag info parsing */
359static st_xml_process_fn process_table[] = {
360 [TAG_ROOT] = NULL,
361 [TAG_COMMON] = platform_stdev_process_kv_params,
362 [TAG_ACDB] = platform_stdev_process_kv_params,
363 [TAG_BACKEND_TYPE] = platform_stdev_process_kv_params,
364 [TAG_SOUND_MODEL] = platform_stdev_process_kv_params,
365 [TAG_ARM_SS_USECASE] = platform_stdev_process_kv_params,
366 [TAG_GCS_USECASE] = platform_stdev_process_kv_params,
367 [TAG_LSM_USECASE] = platform_stdev_process_kv_params,
368 [TAG_ADM_CFG] = platform_stdev_process_kv_params,
369 [TAG_LPMA_CONFIG] = platform_stdev_process_kv_params,
370 [TAG_ACDB_METAINFO_KEY] = process_stdev_acdb_metainfo_key,
371 [TAG_LSM_SS_USECASE] = platform_stdev_process_kv_params,
Quinn Male58749452020-03-26 17:14:56 -0700372 [TAG_MODULE_PARAMS] = platform_stdev_process_kv_params,
Quinn Male2e883752019-03-22 11:28:54 -0700373};
374
375#define ST_ACDB_METAINFO_KEY_MODULE_NAME_LEN (100)
376
377struct meta_key_list {
378 struct listnode list;
379 struct audio_cal_info_metainfo cal_info;
380 char name[ST_ACDB_METAINFO_KEY_MODULE_NAME_LEN];
381};
382
383struct platform_data {
384 int hwdep_fd;
385 int prev_acdb_id;
386 int vad_hwdep_fd;
387 sound_trigger_device_t *stdev;
388 void *acdb_handle;
389 acdb_loader_send_listen_device_cal_t acdb_send_device_cal;
390 acdb_loader_send_listen_device_cal_v1_t acdb_send_device_cal_v1;
391 acdb_loader_send_listen_lsm_cal_t acdb_send_lsm_cal;
392 acdb_loader_send_listen_lsm_cal_v1_t acdb_send_lsm_cal_v1;
393 acdb_loader_get_calibration_t acdb_get_cal;
394 acdb_loader_get_audio_cal_t acdb_get_audio_cal;
395 acdb_loader_init_v2_t acdb_init;
396 acdb_loader_send_common_custom_topology_t acdb_send_common_custom_topology;
397
398 audio_hw_open_snd_mixer_t audio_hw_open_snd_mixer;
399 audio_hw_close_snd_mixer_t audio_hw_close_snd_mixer;
400 audio_hw_acdb_init_t audio_hw_acdb_init;
401 audio_hw_acdb_init_v2_t audio_hw_acdb_init_v2;
402 acdb_loader_deallocate_t acdb_deinit;
403
404 int xml_version;
405 st_xml_tags_t st_xml_tag;
406 struct str_parms *kvpairs;
407
Quinn Male2e883752019-03-22 11:28:54 -0700408 char codec_version[15];
409
410 char backend_port[ST_BACKEND_PORT_NAME_MAX_SIZE];
411 st_codec_backend_cfg_t codec_backend_cfg;
Quinn Male2e883752019-03-22 11:28:54 -0700412 char ec_ref_mixer_path[ST_MAX_LENGTH_MIXER_CONTROL];
413 int bad_mic_channel_index;
414
415 int max_be_dai_names;
416 struct st_be_dai_name_table *be_dai_name_table;
417 char backend_dai_name[ST_BE_DAI_NAME_MAX_LENGTH];
418 char snd_card_name[ST_SND_CARD_NAME_MAX_LENGTH];
419
420 struct st_lpma_config lpma_cfg;
421 struct listnode acdb_meta_key_list;
Saurav Kumar5e2957e2020-06-03 18:22:51 +0530422
423 char vendor_config_path[MIXER_PATH_MAX_LENGTH];
424 char xml_file_path[MIXER_PATH_MAX_LENGTH];
Quinn Male2e883752019-03-22 11:28:54 -0700425};
426
Saurav Kumar5e2957e2020-06-03 18:22:51 +0530427
428/*
429 * Function to retrieve vendor configs path
430 *
431 * If 'ro.boot.product.vendor.sku' is not set,files would be loaded from
432 * /vendor/etc/. If the property is set, files would be loaded from
433 * /vendor/etc/audio/sku_{ro.boot.product.vendor.sku}.
434 * 'ro.boot.product.vendor.sku' would be set to SoC/SKU at boot up in vendor.
435*/
436static void platform_stdev_get_vendor_config_path(char* config_file_path, int path_size)
437{
438 char vendor_sku[PROPERTY_VALUE_MAX] = {'\0'};
439
440 if (property_get("ro.boot.product.vendor.sku", vendor_sku, "") <= 0) {
441#ifdef LINUX_ENABLED
442 /* Audio configs are stored in /etc */
443 snprintf(config_file_path, path_size, "%s", "/etc");
444#else
445 /* Audio configs are stored in /vendor/etc */
446 snprintf(config_file_path, path_size, "%s", "/vendor/etc");
447#endif
448 } else {
449 /* Audio configs are stored in /vendor/etc/audio/sku_${vendor_sku} */
450 snprintf(config_file_path, path_size,"%s%s", "/vendor/etc/audio/sku_", vendor_sku);
451 }
452}
453
454static void get_xml_file_path(char* path, const char* file_name, const char* vendor_path)
455{
456 snprintf(path, MIXER_PATH_MAX_LENGTH, "%s/%s", vendor_path, file_name);
457}
458
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700459static int load_soundmodel_lib(sound_trigger_device_t *stdev)
Quinn Male2e883752019-03-22 11:28:54 -0700460{
461 int status = 0;
462
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700463 stdev->smlib_handle = dlopen(LIB_SVA_SOUNDMODEL, RTLD_NOW);
464 if (!stdev->smlib_handle) {
Quinn Male2e883752019-03-22 11:28:54 -0700465 ALOGE("%s: ERROR. %s", __func__, dlerror());
466 return -ENODEV;
467 }
468
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700469 DLSYM(stdev->smlib_handle, stdev->smlib_getSoundModelHeader,
470 getSoundModelHeader, status);
Quinn Male2e883752019-03-22 11:28:54 -0700471 if (status)
472 goto cleanup;
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700473
474 DLSYM(stdev->smlib_handle, stdev->smlib_releaseSoundModelHeader,
475 releaseSoundModelHeader, status);
Quinn Male2e883752019-03-22 11:28:54 -0700476 if (status)
477 goto cleanup;
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700478
479 DLSYM(stdev->smlib_handle, stdev->smlib_getKeywordPhrases,
480 getKeywordPhrases, status);
Quinn Male2e883752019-03-22 11:28:54 -0700481 if (status)
482 goto cleanup;
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700483
484 DLSYM(stdev->smlib_handle, stdev->smlib_getUserNames,
485 getUserNames, status);
Quinn Male2e883752019-03-22 11:28:54 -0700486 if (status)
487 goto cleanup;
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700488
489 DLSYM(stdev->smlib_handle, stdev->smlib_getMergedModelSize,
490 getMergedModelSize, status);
491 if (status)
492 goto cleanup;
493
494 DLSYM(stdev->smlib_handle, stdev->smlib_mergeModels,
495 mergeModels, status);
496 if (status)
497 goto cleanup;
498
499 DLSYM(stdev->smlib_handle, stdev->smlib_getSizeAfterDeleting,
500 getSizeAfterDeleting, status);
501 if (status)
502 goto cleanup;
503
504 DLSYM(stdev->smlib_handle, stdev->smlib_deleteFromModel,
505 deleteFromModel, status);
506 if (status)
507 goto cleanup;
Quinn Male2e883752019-03-22 11:28:54 -0700508
509 return 0;
510
511cleanup:
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -0700512 if (stdev->smlib_handle) {
513 dlclose(stdev->smlib_handle);
514 stdev->smlib_handle = NULL;
Quinn Male2e883752019-03-22 11:28:54 -0700515 }
516 return status;
517}
518
519static int load_acdb(struct platform_data *my_data)
520{
521 int status = 0;
522
523 my_data->acdb_handle = dlopen(LIB_ACDB_LOADER, RTLD_NOW);
524 if (!my_data->acdb_handle) {
525 ALOGE("%s: ERROR. %s", __func__, dlerror());
526 return -ENODEV;
527 }
528
529 DLSYM(my_data->stdev->audio_hal_handle, my_data->audio_hw_acdb_init_v2,
530 acdb_init_v2, status);
531 if (status) {
532 status = 0;
533 DLSYM(my_data->stdev->audio_hal_handle, my_data->audio_hw_acdb_init,
534 acdb_init, status);
535 if (status) {
536 status = 0;
537 DLSYM(my_data->acdb_handle, my_data->acdb_init,
538 acdb_loader_init_v2, status);
539 if (status)
540 goto cleanup;
541 }
542 }
543
544 DLSYM(my_data->acdb_handle, my_data->acdb_deinit,
545 acdb_loader_deallocate_ACDB, status);
546 if (status)
547 goto cleanup;
548
549 DLSYM(my_data->acdb_handle, my_data->acdb_send_device_cal_v1,
550 acdb_loader_send_listen_device_cal_v1,
551 status);
552 if (status) {
553 DLSYM(my_data->acdb_handle, my_data->acdb_send_device_cal,
554 acdb_loader_send_listen_device_cal,
555 status);
556 if (status)
557 goto cleanup;
558 }
559
560 DLSYM(my_data->acdb_handle, my_data->acdb_send_lsm_cal_v1,
561 acdb_loader_send_listen_lsm_cal_v1, status);
562 if (status) {
563 DLSYM(my_data->acdb_handle, my_data->acdb_send_lsm_cal,
564 acdb_loader_send_listen_lsm_cal, status);
565 if (status)
566 goto cleanup;
567 }
568
569 DLSYM(my_data->acdb_handle, my_data->acdb_get_cal,
570 acdb_loader_get_calibration, status);
571 if (status)
572 goto cleanup;
573 DLSYM(my_data->acdb_handle, my_data->acdb_get_audio_cal,
574 acdb_loader_get_audio_cal_v2, status);
575 if (status)
576 goto cleanup;
577 DLSYM(my_data->acdb_handle, my_data->acdb_send_common_custom_topology,
578 acdb_loader_send_common_custom_topology, status);
579 if (status)
580 goto cleanup;
581
582 return 0;
583
584cleanup:
585 if (my_data->acdb_handle) {
586 dlclose(my_data->acdb_handle);
587 my_data->acdb_handle = NULL;
588 }
589 return status;
590}
591
592static int load_mulaw_decoder(sound_trigger_device_t *stdev)
593{
594 int status = 0;
595
596 stdev->mulaw_dec_lib_handle = dlopen(LIB_MULAW_DECODER, RTLD_NOW);
597 if (!stdev->mulaw_dec_lib_handle) {
598 ALOGE("%s: ERROR. %s", __func__, dlerror());
599 return -ENODEV;
600 }
601
602 DLSYM(stdev->mulaw_dec_lib_handle, stdev->mulaw_dec_process,
603 mulaw_dec_process, status);
604 if (status) {
605 dlclose(stdev->mulaw_dec_lib_handle);
606 stdev->mulaw_dec_lib_handle = NULL;
607 }
608 return status;
609}
610
Quinn Male2e883752019-03-22 11:28:54 -0700611static int platform_stdev_set_acdb_id(void *userdata __unused, const char* device, int acdb_id)
612{
613 int i, j;
614 int ret = 0;
615 int dev_idx = ST_DEVICE_NONE;
616
617 if (device == NULL) {
618 ALOGE("%s: device name is NULL", __func__);
619 ret = -ENODEV;
620 goto done;
621 }
622
623 for (i = 0; i < ST_EXEC_MODE_MAX; i++) {
624 for (j = 0; j < ST_DEVICE_MAX; j++) {
625 if (strcmp(st_device_name_idx[i][j].name, device) == 0) {
626 dev_idx = st_device_name_idx[i][j].index;
627 break;
628 }
629 }
630 if (dev_idx != ST_DEVICE_NONE)
631 break;
632 }
633 if (dev_idx == ST_DEVICE_NONE) {
634 ALOGE("%s: Could not find index for device name = %s",
635 __func__, device);
636 ret = -ENODEV;
637 goto done;
638 }
639
640 acdb_device_table[i][dev_idx] = acdb_id;
641
642done:
643 return ret;
644
645}
646
647static const char *get_snd_card_name_for_acdb_loader(const char *snd_card_name)
648{
649 const char *acdb_card_name = NULL;
650 char *substring = NULL;
651 char string[ST_MAX_SND_CARD_NAME_LENGTH] = {0};
652 int length = 0;
653
654 if (snd_card_name == NULL)
655 return NULL;
656
657 /* Both tasha & tasha-lite uses tasha ACDB files
658 simulate sound card name for tasha lite, so that
659 ACDB module loads tasha ACDB files for tasha lite */
660 if ((substring = strstr(snd_card_name, "tashalite"))) {
661 ALOGD("%s: using tasha ACDB files for tasha-lite", __func__);
662 length = substring - snd_card_name + 1;
663 snprintf(string, length, "%s", snd_card_name);
664 strlcat(string, "tasha-snd-card", sizeof(string));
665 acdb_card_name = strdup(string);
666 return acdb_card_name;
667 }
668 acdb_card_name = strdup(snd_card_name);
669 return acdb_card_name;
670}
671
672static void set_default_backend_type()
673{
674 int i, j;
675
676 /* backend type can be overridden from platform XML file */
677 for (i = 0; i < ST_EXEC_MODE_MAX; i++) {
678 for (j = 0; j < ST_DEVICE_MAX; j++) {
679 if (j == ST_DEVICE_NONE)
680 st_device_backend_table[i][j] = strdup("NONE");
681 else
682 st_device_backend_table[i][j] = strdup("BACKEND_DEFAULT");
683 }
684 }
685};
686
687static int set_backend_type(void *userdata __unused, const char* device, char *type)
688{
689 int i, j;
690 int ret = 0;
691 int dev_idx = ST_DEVICE_NONE;
692
693 if (device == NULL) {
694 ALOGE("%s: device name is NULL", __func__);
695 ret = -ENODEV;
696 goto done;
697 }
698
699 for (i = 0; i < ST_EXEC_MODE_MAX; i++) {
700 for (j = 0; j < ST_DEVICE_MAX; j++) {
701 if (strcmp(st_device_name_idx[i][j].name, device) == 0) {
702 dev_idx = st_device_name_idx[i][j].index;
703 break;
704 }
705 }
706 if (dev_idx != ST_DEVICE_NONE)
707 break;
708 }
709 if (dev_idx == ST_DEVICE_NONE) {
710 ALOGE("%s: Could not find index for device name = %s",
711 __func__, device);
712 ret = -ENODEV;
713 goto done;
714 }
715
716 if (st_device_backend_table[i][dev_idx])
717 free(st_device_backend_table[i][dev_idx]);
718
719 st_device_backend_table[i][dev_idx] = strdup(type);
720
721done:
722 return ret;
723}
724
725static void platform_stdev_set_default_config(struct platform_data *platform)
726{
727 sound_trigger_device_t *stdev = platform->stdev;
728
729 stdev->max_ape_sessions = 1;
730 stdev->avail_ape_phrases = 0;
731 stdev->avail_ape_users = 0;
732 stdev->max_cpe_sessions = 1;
733 stdev->max_wdsp_sessions = 1;
734 stdev->avail_cpe_phrases = 0;
735 stdev->avail_cpe_users = 0;
736 stdev->max_arm_sessions = 1;
737 stdev->bg_kwd = false;
738 stdev->rx_conc_max_st_ses = UINT_MAX;
739 stdev->support_dev_switch = false;
740 stdev->transit_to_adsp_on_playback = false;
741 stdev->transit_to_adsp_on_battery_charging = false;
742 stdev->transit_to_non_lpi_on_battery_charging = false;
743 stdev->transit_wait_time = DEFAULT_TRANSIT_WAIT_TIME_SEC;
744 stdev->ssr_offline_received = false;
745 stdev->conc_capture_supported = false;
746 stdev->conc_voice_call_supported = false;
747 stdev->conc_voip_call_supported = false;
748 stdev->dedicated_sva_path = false;
Zhou Songd18c6712019-06-10 11:20:10 +0800749 stdev->dedicated_headset_path = true;
Quinn Male2e883752019-03-22 11:28:54 -0700750 stdev->disable_hwmad = false;
Quinn Male3d7d9d42019-05-20 13:35:01 -0700751 stdev->platform_lpi_enable = ST_PLATFORM_LPI_NONE;
Quinn Malecc1affd2019-07-18 16:13:31 -0700752 stdev->screen_off = true;
753 stdev->support_dynamic_ec_update = true;
Zhou Songea5a0b42020-01-06 18:16:29 +0800754 stdev->ec_reset_pending_cnt = 0;
Quinn Male2e883752019-03-22 11:28:54 -0700755
Quinn Male2e883752019-03-22 11:28:54 -0700756 platform->bad_mic_channel_index = 0;
Quinn Male2e883752019-03-22 11:28:54 -0700757 platform->be_dai_name_table = NULL;
758 platform->max_be_dai_names = 0;
759 platform->lpma_cfg.num_bb_ids = 0;
760
761 set_default_backend_type();
762}
763
764static int string_to_uuid(const char *str, sound_trigger_uuid_t *uuid)
765{
766 int tmp[10];
767
768 if (str == NULL || uuid == NULL) {
769 return -EINVAL;
770 }
771
772 if (sscanf(str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
773 tmp, tmp + 1, tmp + 2, tmp + 3, tmp + 4, tmp + 5, tmp + 6,
774 tmp + 7, tmp+ 8, tmp+ 9) < 10) {
775 return -EINVAL;
776 }
777 uuid->timeLow = (uint32_t)tmp[0];
778 uuid->timeMid = (uint16_t)tmp[1];
779 uuid->timeHiAndVersion = (uint16_t)tmp[2];
780 uuid->clockSeq = (uint16_t)tmp[3];
781 uuid->node[0] = (uint8_t)tmp[4];
782 uuid->node[1] = (uint8_t)tmp[5];
783 uuid->node[2] = (uint8_t)tmp[6];
784 uuid->node[3] = (uint8_t)tmp[7];
785 uuid->node[4] = (uint8_t)tmp[8];
786 uuid->node[5] = (uint8_t)tmp[9];
787
788 return 0;
789}
790
791static int platform_stdev_set_module_param_ids
792(
793 struct st_module_param_info *mp_info,
794 char *value,
795 bool legacy_params
796)
797{
798 char *id, *test_r;
799 int ret = 0;
800
801 id = strtok_r(value, ", ", &test_r);
802 if (!id) {
803 ALOGE("%s: incorrect module id", __func__);
804 ret = -EINVAL;
805 goto error_exit;
806 }
807 mp_info->module_id = strtoul(id, NULL, 16);
808
809 id = strtok_r(NULL, ", ", &test_r);
810 if (!id) {
811 ALOGE("%s: incorrect %s", __func__,
812 legacy_params ? "param id" : "instance id");
813 ret = -EINVAL;
814 goto error_exit;
815 }
816 if (legacy_params) {
817 mp_info->instance_id = 0;
818 mp_info->param_id = strtoul(id, NULL, 16);
819 } else {
820 mp_info->instance_id = strtoul(id, NULL, 16);
821
822 id = strtok_r(NULL, ", ", &test_r);
823 if (!id) {
824 ALOGE("%s: incorrect param id", __func__);
825 ret = -EINVAL;
826 goto error_exit;
827 }
828 mp_info->param_id = strtoul(id, NULL, 16);
829 }
830 return 0;
831
832error_exit:
833 return ret;
834}
835
836static int acdb_device_to_id(const char* device)
837{
838 int i, j;
839 int ret = 0;
840 int dev_idx = ST_DEVICE_NONE;
841
842 if (device == NULL) {
843 ALOGE("%s: device name is NULL", __func__);
844 ret = -ENODEV;
845 goto done;
846 }
847
848 for (i = 0; i < ST_EXEC_MODE_MAX; i++) {
849 for (j = 0; j < ST_DEVICE_MAX; j++) {
850 if (strcmp(st_device_name_idx[i][j].name, device) == 0) {
851 dev_idx = st_device_name_idx[i][j].index;
852 break;
853 }
854 }
855 if (dev_idx != ST_DEVICE_NONE)
856 break;
857 }
858 if (dev_idx == ST_DEVICE_NONE) {
859 ALOGE("%s: Could not find index for device name = %s",
860 __func__, device);
861 ret = -ENODEV;
862 goto done;
863 }
864
865 ret = acdb_device_table[i][dev_idx];
866
867done:
868 return ret;
869}
870
871static int platform_stdev_set_gcs_usecase_acdb_ids
872(
873 unsigned int *acdb_ids,
874 char *value
875)
876{
877 char *device, *test_r = value;
878 int ret = 0, num_ids = 0;
879
880 while ((device = strtok_r(test_r, ", ", &test_r))) {
881 if (num_ids < MAX_GCS_USECASE_ACDB_IDS) {
882 acdb_ids[num_ids] = acdb_device_to_id(device);
883 num_ids++;
884 } else {
885 ALOGE("%s: Exceeded max number of acdb ids", __func__);
886 ret = -EINVAL;
887 }
888 }
889 if (!num_ids) {
890 ALOGE("%s: No valid acdb_ids", __func__);
891 ret = -EINVAL;
892 }
893
894 return ret;
895}
896
897static int platform_stdev_set_capture_keyword_config
898(
899 struct st_vendor_info *sm_info,
900 char *value
901)
902{
903 char *id, *test_r;
904 int ret = 0;
905
906 id = strtok_r(value, ", ", &test_r);
907 if (!id) {
908 ALOGE("%s: Incorrect capture format", __func__);
909 ret = -EINVAL;
910 goto error_exit;
911 }
Quinn Male9a345522020-03-12 17:49:25 -0700912 if (!strcmp(id, "MULAW_raw")) {
Quinn Male2e883752019-03-22 11:28:54 -0700913 sm_info->kw_capture_format |= MULAW_RAW;
914 } else if (!strcmp(id, "PCM_packet")) {
915 sm_info->kw_capture_format |= PCM_CUSTOM_PACKET;
916 } else if (!strcmp(id, "PCM_raw")) {
917 sm_info->kw_capture_format |= PCM_RAW;
918 } else {
919 ALOGE("%s: Unknown catpure format", __func__);
920 ret = -EINVAL;
921 goto error_exit;
922 }
923
924 id = strtok_r(NULL, ", ", &test_r);
925 if (!id) {
926 ALOGE("%s: Incorrect capture mode", __func__);
927 ret = -EINVAL;
928 goto error_exit;
929 }
930 if (!strcmp(id, "FTRT")) {
931 sm_info->kw_transfer_mode = FTRT_TRANSFER_MODE;
932 }
933 else if (!strcmp(id, "RT")) {
934 sm_info->kw_transfer_mode = RT_TRANSFER_MODE;
935 }
936 else {
937 ALOGE("%s: Unknown catpure mode", __func__);
938 ret = -EINVAL;
939 goto error_exit;
940 }
941
942 id = strtok_r(NULL, ", ", &test_r);
943 if (id)
944 sm_info->kw_duration = atoi(id);
945
946 return 0;
947
948error_exit:
949 return ret;
950}
951
952static int platform_set_common_config
953(
954 void *platform,
955 struct str_parms *parms
956)
957{
958 struct platform_data *my_data = (struct platform_data *)platform;
959 sound_trigger_device_t *stdev = my_data->stdev;
960 char str_value[ST_MAX_STRING_PARAM_SIZE];
961 int value, err;
962
963 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_CPE_SESSIONS, &value);
964 if (err >= 0) {
965 str_parms_del(parms, ST_PARAM_KEY_MAX_CPE_SESSIONS);
966 stdev->max_cpe_sessions = value;
967 }
968
969 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_APE_SESSIONS, &value);
970 if (err >= 0) {
971 str_parms_del(parms, ST_PARAM_KEY_MAX_APE_SESSIONS);
972 stdev->max_ape_sessions = value;
973 }
974
975 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_WDSP_SESSIONS, &value);
976 if (err >= 0) {
977 str_parms_del(parms, ST_PARAM_KEY_MAX_WDSP_SESSIONS);
978 stdev->max_wdsp_sessions = value;
979 }
980
981 err = str_parms_get_str(parms, ST_PARAM_KEY_SW_MAD,
982 str_value, sizeof(str_value));
983 if (err >= 0) {
984 str_parms_del(parms, ST_PARAM_KEY_SW_MAD);
985 stdev->sw_mad = !strncasecmp(str_value, "true", 4) ? true : false;
986 }
987
988 err = str_parms_get_str(parms, ST_PARAM_KEY_BG_KWD,
989 str_value, sizeof(str_value));
990 if (err >= 0) {
991 str_parms_del(parms, ST_PARAM_KEY_BG_KWD);
992 stdev->bg_kwd = !strncasecmp(str_value, "true", 4) ? true : false;
993 }
994
995 err = str_parms_get_str(parms, ST_PARAM_KEY_ENABLE_FAILURE_DETECTION,
996 str_value, sizeof(str_value));
997 if (err >= 0) {
998 str_parms_del(parms, ST_PARAM_KEY_ENABLE_FAILURE_DETECTION);
999 stdev->detect_failure =
1000 !strncasecmp(str_value, "true", 4) ? true : false;
1001 }
1002
Quinn Male2e883752019-03-22 11:28:54 -07001003 err = str_parms_get_str(parms, ST_PARAM_KEY_RX_CONCURRENCY_DISABLED,
1004 str_value, sizeof(str_value));
1005 if (err >= 0) {
1006 str_parms_del(parms, ST_PARAM_KEY_RX_CONCURRENCY_DISABLED);
1007 stdev->rx_concurrency_disabled =
1008 !strncasecmp(str_value, "true", 4) ? true : false;
1009 }
1010
1011 err = str_parms_get_int(parms, ST_PARAM_KEY_RX_MAX_CONC_SESSIONS, &value);
1012 if (err >= 0) {
1013 str_parms_del(parms, ST_PARAM_KEY_RX_MAX_CONC_SESSIONS);
1014 stdev->rx_conc_max_st_ses = value;
1015 }
1016
1017 err = str_parms_get_str(parms, ST_PARAM_KEY_SUPPORT_DEVICE_SWITCH,
1018 str_value, sizeof(str_value));
1019 if (err >= 0) {
1020 str_parms_del(parms, ST_PARAM_KEY_SUPPORT_DEVICE_SWITCH);
1021 stdev->support_dev_switch =
1022 !strncasecmp(str_value, "true", 4) ? true : false;
1023 }
1024
1025 err = str_parms_get_str(parms, ST_PARAM_KEY_TRANSIT_TO_ADSP_ON_PLAYBACK,
1026 str_value, sizeof(str_value));
1027 if (err >= 0) {
1028 str_parms_del(parms, ST_PARAM_KEY_TRANSIT_TO_ADSP_ON_PLAYBACK);
1029 stdev->transit_to_adsp_on_playback =
1030 !strncasecmp(str_value, "true", 4) ? true : false;
1031 }
1032
1033 err = str_parms_get_str(parms,
1034 ST_PARAM_KEY_TRANSIT_TO_ADSP_ON_BATTERY_CHARGING,
1035 str_value, sizeof(str_value));
1036 if (err >= 0) {
1037 str_parms_del(parms, ST_PARAM_KEY_TRANSIT_TO_ADSP_ON_BATTERY_CHARGING);
1038 stdev->transit_to_adsp_on_battery_charging =
1039 !strncasecmp(str_value, "true", 4) ? true : false;
1040 }
1041
1042 err = str_parms_get_str(parms,
1043 ST_PARAM_KEY_TRANSIT_TO_NON_LPI_ON_BATTERY_CHARGING,
1044 str_value, sizeof(str_value));
1045 if (err >= 0) {
1046 str_parms_del(parms,
1047 ST_PARAM_KEY_TRANSIT_TO_NON_LPI_ON_BATTERY_CHARGING);
1048 stdev->transit_to_non_lpi_on_battery_charging =
1049 !strncasecmp(str_value, "true", 4) ? true : false;
1050 }
1051
Quinn Male3d7d9d42019-05-20 13:35:01 -07001052 err = str_parms_get_str(parms, ST_PARAM_KEY_PLATFORM_LPI_ENABLE, str_value,
1053 sizeof(str_value));
1054 if (err >= 0) {
1055 str_parms_del(parms, ST_PARAM_KEY_PLATFORM_LPI_ENABLE);
1056 stdev->platform_lpi_enable =
1057 !strncasecmp(str_value, "true", 4) ? ST_PLATFORM_LPI_ENABLE :
1058 ST_PLATFORM_LPI_DISABLE;
1059 }
1060
Quinn Malecc1affd2019-07-18 16:13:31 -07001061 err = str_parms_get_str(parms, ST_PARAM_KEY_SUPPORT_BARGE_IN_MODE,
1062 str_value, sizeof(str_value));
1063 if (err >= 0) {
1064 str_parms_del(parms, ST_PARAM_KEY_SUPPORT_BARGE_IN_MODE);
1065 stdev->support_barge_in_mode =
1066 !strncasecmp(str_value, "true", 4) ? true : false;
1067 }
1068
Quinn Male2e883752019-03-22 11:28:54 -07001069 err = str_parms_get_int(parms, ST_PARAM_KEY_TRANSIT_WAIT_TIME, &value);
1070 if (err >= 0) {
1071 str_parms_del(parms, ST_PARAM_KEY_TRANSIT_WAIT_TIME);
1072 stdev->transit_wait_time = value;
1073 }
1074
1075 err = str_parms_get_str(parms, ST_PARAM_KEY_BACKEND_PORT_NAME,
1076 str_value, sizeof(str_value));
1077 if (err >= 0) {
1078 str_parms_del(parms, ST_PARAM_KEY_BACKEND_PORT_NAME);
1079 strlcpy(my_data->backend_port,
1080 str_value, sizeof(my_data->backend_port));
1081 }
1082
1083 err = str_parms_get_str(parms, ST_PARAM_KEY_BACKEND_DAI_NAME,
1084 str_value, sizeof(str_value));
1085 if (err >= 0) {
1086 str_parms_del(parms, ST_PARAM_KEY_BACKEND_DAI_NAME);
1087 strlcpy(my_data->backend_dai_name,
1088 str_value, sizeof(my_data->backend_dai_name));
1089 }
1090
1091 err = str_parms_get_str(parms, ST_PARAM_KEY_IMPLEMENTER_UUID,
1092 str_value, sizeof(str_value));
1093 if (err >= 0) {
1094 str_parms_del(parms, ST_PARAM_KEY_IMPLEMENTER_UUID);
1095 if (string_to_uuid(str_value, &stdev->hw_properties->uuid) < 0) {
1096 ALOGE("%s: string_to_uuid failed", __func__);
1097 return -EINVAL;
1098 }
1099 }
1100
1101 err = str_parms_get_str(parms, ST_PARAM_KEY_IMPLEMENTER_VERSION,
1102 str_value, sizeof(str_value));
1103 if (err >= 0) {
1104 str_parms_del(parms, ST_PARAM_KEY_IMPLEMENTER_VERSION);
1105 stdev->hw_properties->version = strtoul(str_value, NULL, 16);
1106 }
1107
1108 err = str_parms_get_str(parms, ST_PARAM_KEY_SND_CARD_NAME,
1109 str_value, sizeof(str_value));
1110 if (err >= 0) {
1111 str_parms_del(parms, ST_PARAM_KEY_SND_CARD_NAME);
1112 strlcpy(my_data->snd_card_name,
1113 str_value, sizeof(my_data->snd_card_name));
1114 }
1115
1116 err = str_parms_get_str(parms, ST_PARAM_KEY_CONCURRENT_CAPTURE,
1117 str_value, sizeof(str_value));
1118 if (err >= 0) {
1119 str_parms_del(parms, ST_PARAM_KEY_CONCURRENT_CAPTURE);
1120 stdev->conc_capture_supported =
1121 !strncasecmp(str_value, "true", 4) ? true : false;
1122 }
1123
1124 if (stdev->conc_capture_supported) {
1125 err = str_parms_get_str(parms, ST_PARAM_KEY_CONCURRENT_VOICE_CALL,
1126 str_value, sizeof(str_value));
1127 if (err >= 0) {
1128 str_parms_del(parms, ST_PARAM_KEY_CONCURRENT_VOICE_CALL);
1129 stdev->conc_voice_call_supported =
1130 !strncasecmp(str_value, "true", 4) ? true : false;
1131 }
1132
1133 err = str_parms_get_str(parms, ST_PARAM_KEY_CONCURRENT_VOIP_CALL,
1134 str_value, sizeof(str_value));
1135 if (err >= 0) {
1136 str_parms_del(parms, ST_PARAM_KEY_CONCURRENT_VOIP_CALL);
1137 stdev->conc_voip_call_supported =
1138 !strncasecmp(str_value, "true", 4) ? true : false;
1139 }
1140 }
1141
1142 err = str_parms_get_str(parms, ST_PARAM_KEY_DEDICATED_SVA_PATH,
1143 str_value, sizeof(str_value));
1144 if (err >= 0) {
1145 str_parms_del(parms, ST_PARAM_KEY_DEDICATED_SVA_PATH);
1146 stdev->dedicated_sva_path =
1147 !strncasecmp(str_value, "true", 4) ? true : false;
1148 }
1149
Zhou Songd18c6712019-06-10 11:20:10 +08001150 err = str_parms_get_str(parms, ST_PARAM_KEY_DEDICATED_HEADSET_PATH,
1151 str_value, sizeof(str_value));
1152 if (err >= 0) {
1153 str_parms_del(parms, ST_PARAM_KEY_DEDICATED_HEADSET_PATH);
1154 stdev->dedicated_headset_path =
1155 !strncasecmp(str_value, "true", 4) ? true : false;
1156 }
1157
Quinn Maleaba13db2019-07-11 15:52:14 -07001158 err = str_parms_get_str(parms, ST_PARAM_KEY_ENABLE_DEBUG_DUMPS,
1159 str_value, sizeof(str_value));
1160 if (err >= 0) {
1161 str_parms_del(parms, ST_PARAM_KEY_ENABLE_DEBUG_DUMPS);
1162 stdev->enable_debug_dumps =
1163 !strncasecmp(str_value, "true", 4) ? true : false;
1164 }
1165
Quinn Male2e883752019-03-22 11:28:54 -07001166 return 0;
1167}
1168
1169static int platform_set_acdb_ids
1170(
1171 void *platform,
1172 struct str_parms *parms
1173)
1174{
1175 int ret = 0, value, err;
1176
1177 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE, &value);
1178 if (err >= 0) {
1179 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE);
1180 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_CPE, value);
1181 if (ret)
1182 goto exit;
1183 }
1184
1185 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP, &value);
1186 if (err >= 0) {
1187 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP);
1188 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP, value);
1189 if (ret)
1190 goto exit;
1191 }
1192
1193 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE, &value);
1194 if (err >= 0) {
1195 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE);
1196 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE, value);
1197 if (ret)
1198 goto exit;
1199 }
1200
1201 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE, &value);
1202 if (err >= 0) {
1203 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE);
1204 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE, value);
1205 if (ret)
1206 goto exit;
1207 }
1208
1209 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE, &value);
1210 if (err >= 0) {
1211 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE);
1212 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE, value);
1213 if (ret)
1214 goto exit;
1215 }
1216
1217 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_APE, &value);
1218 if (err >= 0) {
1219 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_APE);
1220 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_APE, value);
1221 if (ret)
1222 goto exit;
1223 }
1224
1225 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HEADSET_APE, &value);
1226 if (err >= 0) {
1227 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HEADSET_APE);
1228 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HEADSET_APE, value);
1229 if (ret)
1230 goto exit;
1231 }
1232
1233 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE, &value);
1234 if (err >= 0) {
1235 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE);
1236 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE, value);
1237 if (ret)
1238 goto exit;
1239 }
1240
1241 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE, &value);
1242 if (err >= 0) {
1243 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE);
1244 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE, value);
1245 if (ret)
1246 goto exit;
1247 }
1248
1249 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE, &value);
1250 if (err >= 0) {
1251 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE);
1252 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE, value);
1253 if (ret)
1254 goto exit;
1255 }
1256
1257 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_APE, &value);
1258 if (err >= 0) {
1259 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_APE);
1260 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_APE, value);
1261 if (ret)
1262 goto exit;
1263 }
1264
1265 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_APE, &value);
1266 if (err >= 0) {
1267 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_APE);
1268 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_APE, value);
1269 if (ret)
1270 goto exit;
1271 }
1272
1273 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HEADSET_CPE, &value);
1274 if (err >= 0) {
1275 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HEADSET_CPE);
1276 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HEADSET_CPE, value);
1277 if (ret)
1278 goto exit;
1279 }
1280
1281 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_APE_PP, &value);
1282 if (err >= 0) {
1283 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_APE_PP);
1284 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_APE_PP, value);
1285 if (ret)
1286 goto exit;
1287 }
1288
1289 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_ARM, &value);
1290 if (err >= 0) {
1291 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_ARM);
1292 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_ARM, value);
1293 if (ret)
1294 goto exit;
1295 }
1296
1297 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_ARM, &value);
1298 if (err >= 0) {
1299 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_ARM);
1300 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_ARM, value);
1301 if (ret)
1302 goto exit;
1303 }
1304
1305 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_ARM, &value);
1306 if (err >= 0) {
1307 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_ARM);
1308 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_ARM, value);
1309 if (ret)
1310 goto exit;
1311 }
1312
1313 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_LPI_APE, &value);
1314 if (err >= 0) {
1315 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_LPI_APE);
1316 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_LPI_APE, value);
1317 if (ret)
1318 goto exit;
1319 }
1320
1321 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_LPI_APE, &value);
1322 if (err >= 0) {
1323 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_LPI_APE);
1324 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_LPI_APE, value);
1325 if (ret)
1326 goto exit;
1327 }
1328
1329 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_LPI_APE, &value);
1330 if (err >= 0) {
1331 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_LPI_APE);
1332 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_LPI_APE, value);
1333 if (ret)
1334 goto exit;
1335 }
1336
1337 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_LPI_APE, &value);
1338 if (err >= 0) {
1339 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_LPI_APE);
1340 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_6MIC_LPI_APE, value);
1341 if (ret)
1342 goto exit;
1343 }
1344
1345 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_LPI_APE, &value);
1346 if (err >= 0) {
1347 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_LPI_APE);
1348 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HANDSET_8MIC_LPI_APE, value);
1349 if (ret)
1350 goto exit;
1351 }
1352
Quinn Male3d7d9d42019-05-20 13:35:01 -07001353 err = str_parms_get_int(parms, ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE, &value);
1354 if (err >= 0) {
1355 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE);
1356 ret = platform_stdev_set_acdb_id(platform, ST_PARAM_KEY_DEVICE_HEADSET_LPI_APE, value);
1357 if (ret)
1358 goto exit;
1359 }
1360
Quinn Male2e883752019-03-22 11:28:54 -07001361exit:
1362 return ret;
1363}
1364
1365static int platform_stdev_process_backend_type
1366(
1367 void *platform,
1368 struct str_parms *parms
1369)
1370{
1371 int ret = 0, err;
1372 char *kv_pairs = str_parms_to_str(parms);
1373 char str_value[ST_MAX_STRING_PARAM_SIZE];
1374
1375 if (!kv_pairs) {
1376 ALOGE("%s: key-value pair is NULL",__func__);
1377 return -EINVAL;
1378 }
1379
1380 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE,
1381 str_value, sizeof(str_value));
1382 if (err >= 0) {
1383 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE);
1384 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_CPE, str_value);
1385 if (ret)
1386 goto exit;
1387 }
1388
1389 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP,
1390 str_value, sizeof(str_value));
1391 if (err >= 0) {
1392 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP);
1393 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_CPE_ECPP, str_value);
1394 if (ret)
1395 goto exit;
1396 }
1397
1398 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE,
1399 str_value, sizeof(str_value));
1400 if (err >= 0) {
1401 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE);
1402 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_CPE, str_value);
1403 if (ret)
1404 goto exit;
1405 }
1406
1407 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE,
1408 str_value, sizeof(str_value));
1409 if (err >= 0) {
1410 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE);
1411 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_CPE, str_value);
1412 if (ret)
1413 goto exit;
1414 }
1415
1416 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE,
1417 str_value, sizeof(str_value));
1418 if (err >= 0) {
1419 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE);
1420 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_CPE, str_value);
1421 if (ret)
1422 goto exit;
1423 }
1424
1425 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_APE,
1426 str_value, sizeof(str_value));
1427 if (err >= 0) {
1428 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_APE);
1429 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_APE, str_value);
1430 if (ret)
1431 goto exit;
1432 }
1433
1434 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HEADSET_APE,
1435 str_value, sizeof(str_value));
1436 if (err >= 0) {
1437 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HEADSET_APE);
1438 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HEADSET_APE, str_value);
1439 if (ret)
1440 goto exit;
1441 }
1442
1443 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE,
1444 str_value, sizeof(str_value));
1445 if (err >= 0) {
1446 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE);
1447 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_DMIC_APE, str_value);
1448 if (ret)
1449 goto exit;
1450 }
1451
1452 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE,
1453 str_value, sizeof(str_value));
1454 if (err >= 0) {
1455 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE);
1456 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_TMIC_APE, str_value);
1457 if (ret)
1458 goto exit;
1459 }
1460
1461 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE,
1462 str_value, sizeof(str_value));
1463 if (err >= 0) {
1464 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE);
1465 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HANDSET_QMIC_APE, str_value);
1466 if (ret)
1467 goto exit;
1468 }
1469
1470 err = str_parms_get_str(parms, ST_PARAM_KEY_DEVICE_HEADSET_CPE,
1471 str_value, sizeof(str_value));
1472 if (err >= 0) {
1473 str_parms_del(parms, ST_PARAM_KEY_DEVICE_HEADSET_CPE);
1474 ret = set_backend_type(platform, ST_PARAM_KEY_DEVICE_HEADSET_CPE, str_value);
1475 if (ret)
1476 goto exit;
1477 }
1478
1479exit:
1480 free(kv_pairs);
1481 return ret;
1482}
1483
1484static int string_to_profile_type(const char *str, st_profile_type_t *type)
1485{
1486 int ret = 0;
1487
1488 if (!strncmp(str, "NONE", sizeof("NONE"))) {
1489 *type = ST_PROFILE_TYPE_NONE;
1490 } else if (!strncmp(str, "DEFAULT", sizeof("DEFAULT"))) {
1491 *type = ST_PROFILE_TYPE_DEFAULT;
1492 } else if (!strncmp(str, "EC", sizeof("EC"))) {
1493 *type = ST_PROFILE_TYPE_EC;
1494 } else if (!strncmp(str, "UNPROCESSED", sizeof("UNPROCESSED"))) {
1495 *type = ST_PROFILE_TYPE_UNPROCESSED;
1496 } else if (!strncmp(str, "FLUENCE", sizeof("FLUENCE"))) {
1497 *type = ST_PROFILE_TYPE_FLUENCE;
1498 } else if (!strncmp(str, "FLUENCE_STEREO", sizeof("FLUENCE_STEREO"))) {
1499 *type = ST_PROFILE_TYPE_FLUENCE_STEREO;
1500 } else if (!strncmp(str, "FFECNS", sizeof("FFECNS"))) {
1501 *type = ST_PROFILE_TYPE_FFECNS;
1502 } else {
1503 ALOGE("unknown profile string %s", str);
1504 ret = -EINVAL;
1505 }
1506
1507 return ret;
1508}
1509
1510static audio_devices_t string_to_capture_device
1511(
1512 const char *str,
1513 audio_devices_t *device
1514)
1515{
1516 int ret = 0;
1517
1518 if (!strncmp(str, "HANDSET", sizeof("HANDSET"))) {
1519 *device = AUDIO_DEVICE_IN_BUILTIN_MIC;
1520 } else if (!strncmp(str, "HEADSET", sizeof("HEADSET"))) {
1521 *device = AUDIO_DEVICE_IN_WIRED_HEADSET;
1522 } else {
1523 ALOGE("unknown capture device %s", str);
1524 ret = -EINVAL;
1525 }
1526
1527 return ret;
1528}
1529
1530static int string_to_fluence_type(const char *str, st_fluence_type_t *type)
1531{
1532 int ret = 0;
1533
1534 if (!strncmp(str, "NONE", sizeof("NONE"))) {
1535 *type = ST_FLUENCE_TYPE_NONE;
1536 } else if (!strncmp(str, "FLUENCE", sizeof("FLUENCE")) ||
1537 !strncmp(str, "FLUENCE_MIC", sizeof("FLUENCE_MIC"))) {
1538 *type = ST_FLUENCE_TYPE_MONO;
1539 } else if (!strncmp(str, "FLUENCE_DMIC", sizeof("FLUENCE_DMIC"))) {
1540 *type = ST_FLUENCE_TYPE_DMIC;
1541 } else if (!strncmp(str, "FLUENCE_TMIC", sizeof("FLUENCE_TMIC"))) {
1542 *type = ST_FLUENCE_TYPE_TMIC;
1543 } else if (!strncmp(str, "FLUENCE_QMIC", sizeof("FLUENCE_QMIC"))) {
1544 *type = ST_FLUENCE_TYPE_QMIC;
1545 } else if (!strncmp(str, "FLUENCE_6MIC", sizeof("FLUENCE_6MIC"))) {
1546 *type = ST_FLUENCE_TYPE_6MIC;
1547 } else if (!strncmp(str, "FLUENCE_8MIC", sizeof("FLUENCE_8MIC"))) {
1548 *type = ST_FLUENCE_TYPE_8MIC;
1549 } else {
1550 ALOGE("unknown fluence string %s", str);
1551 ret = -EINVAL;
1552 }
1553
1554 return ret;
1555}
1556
1557static int get_channel_cnt_from_fluence_type(st_fluence_type_t type)
1558{
1559 int channel_cnt = 0;
1560
1561 switch (type) {
1562 case ST_FLUENCE_TYPE_NONE:
1563 case ST_FLUENCE_TYPE_MONO:
1564 channel_cnt = 1;
1565 break;
1566 case ST_FLUENCE_TYPE_DMIC:
1567 channel_cnt = 2;
1568 break;
1569 case ST_FLUENCE_TYPE_TMIC:
1570 channel_cnt = 3;
1571 break;
1572 case ST_FLUENCE_TYPE_QMIC:
1573 channel_cnt = 4;
1574 break;
1575 case ST_FLUENCE_TYPE_6MIC:
1576 channel_cnt = 6;
1577 break;
1578 case ST_FLUENCE_TYPE_8MIC:
1579 channel_cnt = 8;
1580 break;
1581 default:
1582 ALOGE("%s: Invalid fluence type", __func__);
1583 }
1584
1585 return channel_cnt;
1586}
1587
1588static int platform_stdev_set_ss_params
1589(
1590 void *platform,
1591 struct str_parms *parms
1592)
1593{
1594 struct platform_data *my_data = (struct platform_data *)platform;
1595 struct st_arm_ss_params *arm_params = NULL;
1596 struct st_lsm_ss_params *lsm_params = NULL;
1597 struct st_second_stage_info *common_params = NULL;
1598 char str_value[128];
1599 char *kv_pairs = str_parms_to_str(parms);
1600 int ret = 0, err, value;
1601 struct listnode *sm_info_node = NULL;
1602 struct st_vendor_info *sm_info = NULL;
1603
1604 if (kv_pairs == NULL) {
1605 ALOGE("%s: key-value pair is NULL", __func__);
1606 return -EINVAL;
1607 }
1608 ALOGV("%s: %s", __func__, kv_pairs);
1609
1610 if (my_data->st_xml_tag == TAG_ARM_SS_USECASE) {
1611 arm_params = calloc(1, sizeof(*arm_params));
1612 if (!arm_params) {
1613 ALOGE("%s: arm_params allocation failed", __func__);
1614 ret = -ENOMEM;
1615 goto err_exit;
1616 }
1617 common_params = &arm_params->common_params;
1618 } else if (my_data->st_xml_tag == TAG_LSM_SS_USECASE) {
1619 lsm_params = calloc(1, sizeof(*lsm_params));
1620 if (!lsm_params) {
1621 ALOGE("%s: lsm_params allocation failed", __func__);
1622 ret = -ENOMEM;
1623 goto err_exit;
1624 }
1625 common_params = &lsm_params->common_params;
1626 } else {
1627 ALOGE("%s: Unexpected XML Tag, exiting", __func__);
1628 ret = -EINVAL;
1629 goto err_exit;
1630 }
1631
1632 err = str_parms_get_str(parms, ST_PARAM_KEY_SS_SM_TYPE,
1633 str_value, sizeof(str_value));
1634 if (err >= 0) {
1635 str_parms_del(parms, ST_PARAM_KEY_SS_SM_TYPE);
1636 if (!strncmp(str_value, "KEYWORD_DETECTION", sizeof("KEYWORD_DETECTION"))) {
1637 common_params->sm_detection_type = ST_SM_TYPE_KEYWORD_DETECTION;
1638 } else if (!strncmp(str_value, "USER_VERIFICATION", sizeof("USER_VERIFICATION"))) {
1639 common_params->sm_detection_type = ST_SM_TYPE_USER_VERIFICATION;
1640 } else if (!strncmp(str_value, "CUSTOM_DETECTION", sizeof("CUSTOM_DETECTION"))) {
1641 common_params->sm_detection_type = ST_SM_TYPE_CUSTOM_DETECTION;
1642 } else {
1643 ALOGE("%s: invalid sm type: %s", __func__, str_value);
1644 }
1645 }
1646
1647 err = str_parms_get_str(parms, ST_PARAM_KEY_SS_SM_ID,
1648 str_value, sizeof(str_value));
1649 if (err >= 0) {
1650 str_parms_del(parms, ST_PARAM_KEY_SS_SM_ID);
1651 common_params->sm_id = strtoul(str_value, NULL, 16);
1652 }
1653
1654 err = str_parms_get_str(parms, ST_PARAM_KEY_SS_LIB,
1655 str_value, sizeof(str_value));
1656 if (err >= 0) {
1657 str_parms_del(parms, ST_PARAM_KEY_SS_LIB);
1658 strlcpy(common_params->lib_name, str_value, sizeof(common_params->lib_name));
1659 }
1660
1661 err = str_parms_get_int(parms, ST_PARAM_KEY_SAMPLE_RATE, &value);
1662 if (err >= 0) {
1663 str_parms_del(parms, ST_PARAM_KEY_SAMPLE_RATE);
1664 common_params->sample_rate = value;
1665 }
1666
1667 err = str_parms_get_int(parms, ST_PARAM_KEY_BIT_WIDTH, &value);
1668 if (err >= 0) {
1669 str_parms_del(parms, ST_PARAM_KEY_BIT_WIDTH);
1670 common_params->bit_width = value;
1671 }
1672
1673 err = str_parms_get_int(parms, ST_PARAM_KEY_CHANNEL_COUNT, &value);
1674 if (err >= 0) {
1675 str_parms_del(parms, ST_PARAM_KEY_CHANNEL_COUNT);
1676 common_params->channel_count = value;
1677 }
1678
Zhou Songebe8a932020-02-10 12:18:31 +08001679 err = str_parms_get_int(parms, ST_PARAM_KEY_SS_DATA_BEFORE_KW_START, &value);
1680 if (err >= 0) {
1681 str_parms_del(parms, ST_PARAM_KEY_SS_DATA_BEFORE_KW_START);
1682 common_params->data_before_kw_start = value;
1683 } else {
1684 common_params->data_before_kw_start = VOP_DATA_BEFORE_TRUE_KW_START_MS;
1685 }
1686
Quinn Male2e883752019-03-22 11:28:54 -07001687 err = str_parms_get_int(parms, ST_PARAM_KEY_SS_DATA_AFTER_KW_END, &value);
1688 if (err >= 0) {
1689 str_parms_del(parms, ST_PARAM_KEY_SS_DATA_AFTER_KW_END);
1690 common_params->data_after_kw_end = value;
1691 } else {
1692 common_params->data_after_kw_end = CNN_DATA_AFTER_TRUE_KW_END_MS;
1693 }
1694
1695 if (my_data->st_xml_tag == TAG_LSM_SS_USECASE) {
1696 err = str_parms_get_str(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS,
1697 str_value, sizeof(str_value));
1698 if (err >= 0) {
1699 str_parms_del(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS);
1700 ret = platform_stdev_set_module_param_ids(&lsm_params->params[LOAD_SOUND_MODEL],
1701 str_value, false);
1702 if (ret)
1703 goto err_exit;
1704 lsm_params->param_tag_tracker |= PARAM_LOAD_SOUND_MODEL_BIT;
1705 }
1706
1707 err = str_parms_get_str(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS,
1708 str_value, sizeof(str_value));
1709 if (err >= 0) {
1710 str_parms_del(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS);
1711 ret = platform_stdev_set_module_param_ids(&lsm_params->params[UNLOAD_SOUND_MODEL],
1712 str_value, false);
1713 if (ret)
1714 goto err_exit;
1715 lsm_params->param_tag_tracker |= PARAM_UNLOAD_SOUND_MODEL_BIT;
1716 }
1717
1718 err = str_parms_get_str(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS,
1719 str_value, sizeof(str_value));
1720 if (err >= 0) {
1721 str_parms_del(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS);
1722 ret = platform_stdev_set_module_param_ids(&lsm_params->params[CONFIDENCE_LEVELS],
1723 str_value, false);
1724 if (ret)
1725 goto err_exit;
1726 lsm_params->param_tag_tracker |= PARAM_CONFIDENCE_LEVELS_BIT;;
1727 }
1728
1729 err = str_parms_get_str(parms, ST_PARAM_KEY_OPERATION_MODE_IDS,
1730 str_value, sizeof(str_value));
1731 if (err >= 0) {
1732 str_parms_del(parms, ST_PARAM_KEY_OPERATION_MODE_IDS);
1733 ret = platform_stdev_set_module_param_ids(&lsm_params->params[OPERATION_MODE],
1734 str_value, false);
1735 if (ret)
1736 goto err_exit;
1737 lsm_params->param_tag_tracker |= PARAM_OPERATION_MODE_BIT;
1738 }
1739
1740 err = str_parms_get_str(parms, ST_PARAM_KEY_POLLING_ENABLE_IDS,
1741 str_value, sizeof(str_value));
1742 if (err >= 0) {
1743 str_parms_del(parms, ST_PARAM_KEY_POLLING_ENABLE_IDS);
1744 ret = platform_stdev_set_module_param_ids(&lsm_params->params[POLLING_ENABLE],
1745 str_value, false);
1746 if (ret)
1747 goto err_exit;
1748 lsm_params->param_tag_tracker |= PARAM_POLLING_ENABLE_BIT;
1749 }
1750
1751 err = str_parms_get_str(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS,
1752 str_value, sizeof(str_value));
1753 if (err >= 0) {
1754 str_parms_del(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS);
1755 ret = platform_stdev_set_module_param_ids(&lsm_params->params[CUSTOM_CONFIG],
1756 str_value, false);
1757 if (ret)
1758 goto err_exit;
1759 lsm_params->param_tag_tracker |= PARAM_CUSTOM_CONFIG_BIT;
1760 }
1761
1762 err = str_parms_get_str(parms, ST_PARAM_KEY_DETECTION_EVENT_IDS,
1763 str_value, sizeof(str_value));
1764 if (err >= 0) {
1765 str_parms_del(parms, ST_PARAM_KEY_DETECTION_EVENT_IDS);
1766 ret = platform_stdev_set_module_param_ids(&lsm_params->params[DETECTION_EVENT],
1767 str_value, false);
1768 if (ret)
1769 goto err_exit;
1770 }
1771
1772 err = str_parms_get_str(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS,
1773 str_value, sizeof(str_value));
1774 if (err >= 0) {
1775 str_parms_del(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS);
1776 ret = platform_stdev_set_module_param_ids(&lsm_params->params[DET_EVENT_TYPE],
1777 str_value, false);
1778 if (ret)
1779 goto err_exit;
1780 lsm_params->param_tag_tracker |= PARAM_DET_EVENT_TYPE_BIT;
1781 }
1782
1783 err = str_parms_get_str(parms, ST_PARAM_KEY_LAB_CONTROL_IDS,
1784 str_value, sizeof(str_value));
1785 if (err >= 0) {
1786 str_parms_del(parms, ST_PARAM_KEY_LAB_CONTROL_IDS);
1787 ret = platform_stdev_set_module_param_ids(&lsm_params->params[LAB_CONTROL],
1788 str_value, false);
1789 if (ret)
1790 goto err_exit;
1791 lsm_params->param_tag_tracker |= PARAM_LAB_CONTROL_BIT;
1792 }
1793
1794 err = str_parms_get_str(parms, ST_PARAM_KEY_APP_TYPE,
1795 str_value, sizeof(str_value));
1796 if (err >= 0) {
1797 str_parms_del(parms, ST_PARAM_KEY_APP_TYPE);
1798 lsm_params->app_type = strtoul(str_value, NULL, 16);
1799 }
1800 }
1801
1802 /* store in vendor_info */
1803 sm_info_node = list_tail(&my_data->stdev->vendor_uuid_list);
1804 if (sm_info_node) {
1805 sm_info = node_to_item(sm_info_node, struct st_vendor_info, list_node);
1806 if (my_data->st_xml_tag == TAG_ARM_SS_USECASE)
1807 list_add_tail(&sm_info->arm_ss_usecase_list, &arm_params->list_node);
1808 else if (my_data->st_xml_tag == TAG_LSM_SS_USECASE)
1809 list_add_tail(&sm_info->lsm_ss_usecase_list, &lsm_params->list_node);
1810 } else {
1811 ALOGE("%s: found NULL sm_info", __func__);
1812 ret = -EINVAL;
1813 goto err_exit;
1814 }
1815
1816 free(kv_pairs);
1817 return 0;
1818
1819err_exit:
1820 if (arm_params)
1821 free(arm_params);
1822 if (lsm_params)
1823 free(lsm_params);
1824 free(kv_pairs);
1825 return ret;
1826}
1827
1828static int platform_stdev_set_gcs_params
1829(
1830 void *platform,
1831 struct str_parms *parms
1832)
1833{
1834 struct platform_data *my_data = (struct platform_data *)platform;
1835 struct st_gcs_params *gcs_params;
1836 char str_value[ST_MAX_STRING_PARAM_SIZE];
1837 char *kv_pairs = str_parms_to_str(parms);
1838 int ret = 0, err;
1839 struct listnode *sm_info_node = NULL;
1840 struct st_vendor_info *sm_info = NULL;
1841
1842 if (kv_pairs == NULL) {
1843 ALOGE("%s: key-value pair is NULL", __func__);
1844 return -EINVAL;
1845 }
1846
1847 gcs_params = calloc(1, sizeof(*gcs_params));
1848 if (!gcs_params) {
1849 ALOGE("%s: new_params allcoation failed", __func__);
1850 ret = -ENOMEM;
1851 goto err_exit;
1852 }
1853
1854 /* populate new params */
1855 err = str_parms_get_str(parms, ST_PARAM_KEY_UID,
1856 str_value, sizeof(str_value));
1857 if (err >= 0) {
1858 str_parms_del(parms, ST_PARAM_KEY_UID);
1859 gcs_params->uid = strtoul(str_value, NULL, 16);
1860 }
1861
1862 err = str_parms_get_str(parms, ST_PARAM_KEY_ACDB_DEVICES,
1863 str_value, sizeof(str_value));
1864 if (err >= 0) {
1865 str_parms_del(parms, ST_PARAM_KEY_ACDB_DEVICES);
1866 ret = platform_stdev_set_gcs_usecase_acdb_ids(gcs_params->acdb_ids, str_value);
1867 if (ret)
1868 goto err_exit;
1869 }
1870
1871 err = str_parms_get_str(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS,
1872 str_value, sizeof(str_value));
1873 if (err >= 0) {
1874 str_parms_del(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS);
1875 ret = platform_stdev_set_module_param_ids(&gcs_params->params[LOAD_SOUND_MODEL],
1876 str_value, false);
1877 if (ret)
1878 goto err_exit;
1879 }
1880
1881 err = str_parms_get_str(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS,
1882 str_value, sizeof(str_value));
1883 if (err >= 0) {
1884 str_parms_del(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS);
1885 ret = platform_stdev_set_module_param_ids(&gcs_params->params[UNLOAD_SOUND_MODEL],
1886 str_value, false);
1887 if (ret)
1888 goto err_exit;
1889 }
1890
1891 err = str_parms_get_str(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS,
1892 str_value, sizeof(str_value));
1893 if (err >= 0) {
1894 str_parms_del(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS);
1895 ret = platform_stdev_set_module_param_ids(&gcs_params->params[CONFIDENCE_LEVELS],
1896 str_value, false);
1897 if (ret)
1898 goto err_exit;
1899 }
1900
1901 err = str_parms_get_str(parms, ST_PARAM_KEY_OPERATION_MODE_IDS,
1902 str_value, sizeof(str_value));
1903 if (err >= 0) {
1904 str_parms_del(parms, ST_PARAM_KEY_OPERATION_MODE_IDS);
1905 ret = platform_stdev_set_module_param_ids(&gcs_params->params[OPERATION_MODE],
1906 str_value, false);
1907 if (ret)
1908 goto err_exit;
1909 }
1910
1911 err = str_parms_get_str(parms, ST_PARAM_KEY_DETECTION_EVENT_IDS,
1912 str_value, sizeof(str_value));
1913 if (err >= 0) {
1914 str_parms_del(parms, ST_PARAM_KEY_DETECTION_EVENT_IDS);
1915 ret = platform_stdev_set_module_param_ids(&gcs_params->params[DETECTION_EVENT],
1916 str_value, false);
1917 if (ret)
1918 goto err_exit;
1919 }
1920
1921 err = str_parms_get_str(parms, ST_PARAM_KEY_READ_REQ_IDS,
1922 str_value, sizeof(str_value));
1923 if (err >= 0) {
1924 str_parms_del(parms, ST_PARAM_KEY_READ_REQ_IDS);
1925 ret = platform_stdev_set_module_param_ids(&gcs_params->params[READ_REQ],
1926 str_value, false);
1927 if (ret)
1928 goto err_exit;
1929 }
1930
1931 err = str_parms_get_str(parms, ST_PARAM_KEY_READ_RSP_IDS,
1932 str_value, sizeof(str_value));
1933 if (err >= 0) {
1934 str_parms_del(parms, ST_PARAM_KEY_READ_RSP_IDS);
1935 ret = platform_stdev_set_module_param_ids(&gcs_params->params[READ_RSP],
1936 str_value, false);
1937 if (ret)
1938 goto err_exit;
1939 }
1940
1941 err = str_parms_get_str(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS,
1942 str_value, sizeof(str_value));
1943 if (err >= 0) {
1944 str_parms_del(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS);
1945 ret = platform_stdev_set_module_param_ids(&gcs_params->params[CUSTOM_CONFIG],
1946 str_value, false);
1947 if (ret)
1948 goto err_exit;
1949 }
1950
1951 err = str_parms_get_str(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS,
1952 str_value, sizeof(str_value));
1953 if (err >= 0) {
1954 str_parms_del(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS);
1955 ret = platform_stdev_set_module_param_ids(&gcs_params->params[DET_EVENT_TYPE],
1956 str_value, false);
1957 if (ret)
1958 goto err_exit;
1959 }
1960
1961 err = str_parms_get_str(parms, ST_PARAM_KEY_START_ENGINE_IDS,
1962 str_value, sizeof(str_value));
1963 if (err >= 0) {
1964 str_parms_del(parms, ST_PARAM_KEY_START_ENGINE_IDS);
1965 ret = platform_stdev_set_module_param_ids(&gcs_params->params[START_ENGINE],
1966 str_value, false);
1967 if (ret)
1968 goto err_exit;
1969 }
1970
1971 err = str_parms_get_str(parms, ST_PARAM_KEY_RESTART_ENGINE_IDS,
1972 str_value, sizeof(str_value));
1973 if (err >= 0) {
1974 str_parms_del(parms, ST_PARAM_KEY_RESTART_ENGINE_IDS);
1975 ret = platform_stdev_set_module_param_ids(&gcs_params->params[RESTART_ENGINE],
1976 str_value, false);
1977 if (ret)
1978 goto err_exit;
1979 }
1980
1981 err = str_parms_get_str(parms, ST_PARAM_KEY_REQUEST_DETECTION_IDS,
1982 str_value, sizeof(str_value));
1983 if (err >= 0) {
1984 str_parms_del(parms, ST_PARAM_KEY_REQUEST_DETECTION_IDS);
1985 ret = platform_stdev_set_module_param_ids(&gcs_params->params[REQUEST_DETECTION],
1986 str_value, false);
1987 if (ret)
1988 goto err_exit;
1989 }
1990
1991 /* store in vendor_info */
1992 sm_info_node = list_tail(&my_data->stdev->vendor_uuid_list);
1993 if (sm_info_node) {
1994 sm_info = node_to_item(sm_info_node, struct st_vendor_info, list_node);
1995 list_add_tail(&sm_info->gcs_usecase_list, &gcs_params->list_node);
1996 } else {
1997 ALOGE("%s: found NULL sm_info", __func__);
1998 ret = -EINVAL;
1999 goto err_exit;
2000 }
2001 free(kv_pairs);
2002 return 0;
2003
2004err_exit:
2005 if (gcs_params)
2006 free(gcs_params);
2007 free(kv_pairs);
2008 return ret;
2009}
2010
Quinn Male58749452020-03-26 17:14:56 -07002011static int platform_stdev_set_module_params
2012(
2013 void *platform,
2014 struct str_parms *parms
2015)
2016{
2017 struct platform_data *my_data = (struct platform_data *)platform;
2018 char str_value[ST_MAX_STRING_PARAM_SIZE];
2019 char *kv_pairs = str_parms_to_str(parms);
2020 int ret = 0, err = 0;
2021 struct listnode *sm_info_node = NULL, *lsm_params_node = NULL;
2022 struct st_vendor_info *sm_info = NULL;
2023 struct st_lsm_params *lsm_params = NULL;
2024 struct st_module_params *module_params = NULL;
2025
2026 if (kv_pairs == NULL) {
2027 ALOGE("%s: key-value pair is NULL", __func__);
2028 return -EINVAL;
2029 }
2030 ALOGV("%s: %s", __func__, kv_pairs);
2031
2032 if (my_data->xml_version < PLATFORM_XML_VERSION_0x0106) {
2033 ALOGE("%s: Unexpected platform xml version 0x%x, exiting", __func__,
2034 my_data->xml_version);
2035 return -EINVAL;
2036 }
2037
2038 /* Get the last added vendor_info node */
2039 sm_info_node = list_tail(&my_data->stdev->vendor_uuid_list);
2040 if (sm_info_node) {
2041 sm_info = node_to_item(sm_info_node, struct st_vendor_info, list_node);
2042 } else {
2043 ALOGE("%s: found NULL sm_info", __func__);
2044 ret = -EINVAL;
2045 goto err_exit;
2046 }
2047
2048 /* Get the last added lsm_params node */
2049 lsm_params_node = list_tail(&sm_info->lsm_usecase_list);
2050 if (lsm_params_node) {
2051 lsm_params = node_to_item(lsm_params_node, struct st_lsm_params,
2052 list_node);
2053 } else {
2054 ALOGE("%s: found NULL lsm_params", __func__);
2055 ret = -EINVAL;
2056 goto err_exit;
2057 }
2058
2059 module_params = calloc(1, sizeof(struct st_module_params));
2060 if (!module_params) {
2061 ALOGE("%s: module_params allocation failed", __func__);
2062 ret = -ENOMEM;
2063 goto err_exit;
2064 }
2065
2066 err = str_parms_get_str(parms, ST_PARAM_KEY_MODULE_TYPE,
2067 str_value, sizeof(str_value));
2068 if (err >= 0) {
2069 str_parms_del(parms, ST_PARAM_KEY_MODULE_TYPE);
2070 if (!strncmp(str_value, "GMM", sizeof("GMM")))
2071 module_params->type = ST_MODULE_TYPE_GMM;
2072 else if (!strncmp(str_value, "PDK5", sizeof("PDK5")))
2073 module_params->type = ST_MODULE_TYPE_PDK5;
2074 else {
2075 ALOGE("%s: Unknown module type, exiting", __func__);
2076 ret = -EINVAL;
2077 goto err_exit;
2078 }
2079 } else {
2080 module_params->type = ST_MODULE_TYPE_GMM;
2081 }
2082
2083 err = str_parms_get_str(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS,
2084 str_value, sizeof(str_value));
2085 if (err >= 0) {
2086 str_parms_del(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS);
2087 ret = platform_stdev_set_module_param_ids(
2088 &module_params->params[LOAD_SOUND_MODEL], str_value, false);
2089 if (ret)
2090 goto err_exit;
2091 module_params->param_tag_tracker |= PARAM_LOAD_SOUND_MODEL_BIT;
2092 }
2093
2094 err = str_parms_get_str(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS,
2095 str_value, sizeof(str_value));
2096 if (err >= 0) {
2097 str_parms_del(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS);
2098 ret = platform_stdev_set_module_param_ids(
2099 &module_params->params[UNLOAD_SOUND_MODEL], str_value, false);
2100 if (ret)
2101 goto err_exit;
2102 module_params->param_tag_tracker |= PARAM_UNLOAD_SOUND_MODEL_BIT;
2103 }
2104
2105 err = str_parms_get_str(parms, ST_PARAM_KEY_REQUEST_DETECTION_IDS,
2106 str_value, sizeof(str_value));
2107 if (err >= 0) {
2108 str_parms_del(parms, ST_PARAM_KEY_REQUEST_DETECTION_IDS);
2109 ret = platform_stdev_set_module_param_ids(
2110 &module_params->params[REQUEST_DETECTION], str_value, false);
2111 if (ret)
2112 goto err_exit;
2113 module_params->param_tag_tracker |= PARAM_REQUEST_DETECTION_BIT;
2114 }
2115
2116 err = str_parms_get_str(parms, ST_PARAM_KEY_LAB_DAM_CFG_IDS,
2117 str_value, sizeof(str_value));
2118 if (err >= 0) {
2119 str_parms_del(parms, ST_PARAM_KEY_LAB_DAM_CFG_IDS);
2120 ret = platform_stdev_set_module_param_ids(
2121 &module_params->params[LAB_DAM_CFG], str_value, false);
2122 if (ret)
2123 goto err_exit;
2124 module_params->param_tag_tracker |= PARAM_LAB_DAM_CFG_BIT;
2125 }
2126
2127 err = str_parms_get_str(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS,
2128 str_value, sizeof(str_value));
2129 if (err >= 0) {
2130 str_parms_del(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS);
2131 ret = platform_stdev_set_module_param_ids(
2132 &module_params->params[CONFIDENCE_LEVELS], str_value, false);
2133 if (ret)
2134 goto err_exit;
2135 module_params->param_tag_tracker |= PARAM_CONFIDENCE_LEVELS_BIT;
2136 }
2137
2138 err = str_parms_get_str(parms, ST_PARAM_KEY_OPERATION_MODE_IDS,
2139 str_value, sizeof(str_value));
2140 if (err >= 0) {
2141 str_parms_del(parms, ST_PARAM_KEY_OPERATION_MODE_IDS);
2142 ret = platform_stdev_set_module_param_ids(
2143 &module_params->params[OPERATION_MODE], str_value, false);
2144 if (ret)
2145 goto err_exit;
2146 module_params->param_tag_tracker |= PARAM_OPERATION_MODE_BIT;
2147 }
2148
2149 err = str_parms_get_str(parms, ST_PARAM_KEY_POLLING_ENABLE_IDS,
2150 str_value, sizeof(str_value));
2151 if (err >= 0) {
2152 str_parms_del(parms, ST_PARAM_KEY_POLLING_ENABLE_IDS);
2153 ret = platform_stdev_set_module_param_ids(
2154 &module_params->params[POLLING_ENABLE], str_value, false);
2155 if (ret)
2156 goto err_exit;
2157 module_params->param_tag_tracker |= PARAM_POLLING_ENABLE_BIT;
2158 }
2159
2160 err = str_parms_get_str(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS,
2161 str_value, sizeof(str_value));
2162 if (err >= 0) {
2163 str_parms_del(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS);
2164 ret = platform_stdev_set_module_param_ids(
2165 &module_params->params[CUSTOM_CONFIG], str_value, false);
2166 if (ret)
2167 goto err_exit;
2168 module_params->param_tag_tracker |= PARAM_CUSTOM_CONFIG_BIT;
2169 }
2170
2171 err = str_parms_get_str(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS,
2172 str_value, sizeof(str_value));
2173 if (err >= 0) {
2174 str_parms_del(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS);
2175 ret = platform_stdev_set_module_param_ids(
2176 &module_params->params[DET_EVENT_TYPE], str_value, false);
2177 if (ret)
2178 goto err_exit;
2179 module_params->param_tag_tracker |= PARAM_DET_EVENT_TYPE_BIT;
2180 }
2181
2182 err = str_parms_get_str(parms, ST_PARAM_KEY_LAB_CONTROL_IDS,
2183 str_value, sizeof(str_value));
2184 if (err >= 0) {
2185 str_parms_del(parms, ST_PARAM_KEY_LAB_CONTROL_IDS);
2186 ret = platform_stdev_set_module_param_ids(
2187 &module_params->params[LAB_CONTROL], str_value, false);
2188 if (ret)
2189 goto err_exit;
2190 module_params->param_tag_tracker |= PARAM_LAB_CONTROL_BIT;
2191 }
2192
Harshal Ahire89337992020-07-13 02:38:14 +05302193 err = str_parms_get_str(parms, ST_PARAM_KEY_VERSION_ID,
2194 str_value, sizeof(str_value));
2195 if (err >= 0) {
2196 str_parms_del(parms, ST_PARAM_KEY_VERSION_ID);
2197 ret = platform_stdev_set_module_param_ids(
2198 &module_params->params[VERSION_ID], str_value, false);
2199 if (ret)
2200 goto err_exit;
2201 }
2202
Quinn Male58749452020-03-26 17:14:56 -07002203 list_add_tail(&lsm_params->module_params_list,
2204 &module_params->list_node);
2205 free(kv_pairs);
2206 return 0;
2207
2208err_exit:
2209 if (module_params)
2210 free(module_params);
2211 free(kv_pairs);
2212 return ret;
2213}
2214
Quinn Male2e883752019-03-22 11:28:54 -07002215static int platform_stdev_set_lsm_params
2216(
2217 void *platform,
2218 struct str_parms *parms
2219)
2220{
2221 struct platform_data *my_data = (struct platform_data *)platform;
2222 char str_value[ST_MAX_STRING_PARAM_SIZE];
2223 char *kv_pairs = str_parms_to_str(parms);
2224 int ret = 0, err = 0, value = 0;
Quinn Male58749452020-03-26 17:14:56 -07002225 struct listnode *sm_info_node = NULL, *module_node = NULL;
2226 struct listnode *tmp_node = NULL, *lsm_params_node = NULL;
Quinn Male2e883752019-03-22 11:28:54 -07002227 struct st_vendor_info *sm_info = NULL;
2228 struct st_lsm_params *lsm_params = NULL;
Quinn Male58749452020-03-26 17:14:56 -07002229 struct st_module_params *module_params = NULL;
Quinn Male2e883752019-03-22 11:28:54 -07002230 st_exec_mode_t exec_mode = ST_EXEC_MODE_NONE;
2231 bool is_legacy_params = true;
2232 bool is_legacy_version = true;
2233
2234 if (kv_pairs == NULL) {
2235 ALOGE("%s: key-value pair is NULL", __func__);
2236 return -EINVAL;
2237 }
2238 ALOGV("%s: %s", __func__, kv_pairs);
2239
2240 /* Get the last added vendor_info node */
2241 sm_info_node = list_tail(&my_data->stdev->vendor_uuid_list);
Quinn Malea8019d12020-06-22 13:36:41 -07002242 if (sm_info_node)
Quinn Male2e883752019-03-22 11:28:54 -07002243 sm_info = node_to_item(sm_info_node, struct st_vendor_info, list_node);
Quinn Malea8019d12020-06-22 13:36:41 -07002244
2245 if (!sm_info) {
Quinn Male2e883752019-03-22 11:28:54 -07002246 ALOGE("%s: found NULL sm_info", __func__);
Quinn Malea8019d12020-06-22 13:36:41 -07002247 free(kv_pairs);
2248 return -EINVAL;
Quinn Male2e883752019-03-22 11:28:54 -07002249 }
2250
Quinn Male58749452020-03-26 17:14:56 -07002251 /* Get the last added lsm_params node */
2252 lsm_params_node = list_tail(&sm_info->lsm_usecase_list);
Quinn Malea8019d12020-06-22 13:36:41 -07002253 if (lsm_params_node)
Quinn Male58749452020-03-26 17:14:56 -07002254 lsm_params = node_to_item(lsm_params_node, struct st_lsm_params, list_node);
Quinn Malea8019d12020-06-22 13:36:41 -07002255
2256 if (!lsm_params) {
Quinn Male58749452020-03-26 17:14:56 -07002257 ALOGE("%s: found NULL lsm_params", __func__);
Quinn Malea8019d12020-06-22 13:36:41 -07002258 free(kv_pairs);
2259 return -EINVAL;
Quinn Male2e883752019-03-22 11:28:54 -07002260 }
2261
2262 err = str_parms_get_str(parms, ST_PARAM_KEY_EXECUTION_MODE,
2263 str_value, sizeof(str_value));
2264 if (err >= 0) {
2265 str_parms_del(parms, ST_PARAM_KEY_EXECUTION_MODE);
2266 if (!strcmp(str_value, "WDSP"))
2267 exec_mode = ST_EXEC_MODE_CPE;
2268 else if (!strcmp(str_value, "ADSP"))
2269 exec_mode = ST_EXEC_MODE_ADSP;
2270 else
2271 ALOGE("%s: Invalid execution mode set %s", __func__, str_value);
2272 }
2273
2274 if ((exec_mode <= ST_EXEC_MODE_NONE) ||
2275 (exec_mode >= ST_EXEC_MODE_MAX)) {
2276 ALOGE("%s: Invalid execution mode %x", __func__, exec_mode);
2277 goto err_exit;
2278 }
2279
2280 lsm_params->exec_mode = exec_mode;
2281 /* xml version 0x0104 onwards is having instance id support for LSM usecase as well */
2282 if (my_data->xml_version > PLATFORM_XML_VERSION_0x0103)
2283 is_legacy_params = false;
2284 if (my_data->xml_version > PLATFORM_XML_VERSION_0x0102)
2285 is_legacy_version = false;
2286
2287 ALOGV("%s: Process params for exec mode %x", __func__, exec_mode);
2288
Quinn Male58749452020-03-26 17:14:56 -07002289 if (my_data->xml_version <= PLATFORM_XML_VERSION_0x0105) {
2290 err = str_parms_get_str(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS,
2291 str_value, sizeof(str_value));
2292 if (err >= 0) {
2293 str_parms_del(parms, ST_PARAM_KEY_LOAD_SOUND_MODEL_IDS);
2294 ret = platform_stdev_set_module_param_ids(
2295 &lsm_params->params[LOAD_SOUND_MODEL], str_value, is_legacy_params);
2296 if (ret)
2297 goto err_exit;
2298 lsm_params->param_tag_tracker |= PARAM_LOAD_SOUND_MODEL_BIT;
2299 }
Quinn Male2e883752019-03-22 11:28:54 -07002300
Quinn Male58749452020-03-26 17:14:56 -07002301 err = str_parms_get_str(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS,
2302 str_value, sizeof(str_value));
2303 if (err >= 0) {
2304 str_parms_del(parms, ST_PARAM_KEY_UNLOAD_SOUND_MODEL_IDS);
2305 ret = platform_stdev_set_module_param_ids(
2306 &lsm_params->params[UNLOAD_SOUND_MODEL], str_value, is_legacy_params);
2307 if (ret)
2308 goto err_exit;
2309 lsm_params->param_tag_tracker |= PARAM_UNLOAD_SOUND_MODEL_BIT;
2310 }
Quinn Male2e883752019-03-22 11:28:54 -07002311
Quinn Male58749452020-03-26 17:14:56 -07002312 err = str_parms_get_str(parms, ST_PARAM_KEY_REQUEST_DETECTION_IDS,
2313 str_value, sizeof(str_value));
2314 if (err >= 0) {
2315 str_parms_del(parms, ST_PARAM_KEY_REQUEST_DETECTION_IDS);
2316 ret = platform_stdev_set_module_param_ids(
2317 &lsm_params->params[REQUEST_DETECTION], str_value, is_legacy_params);
2318 if (ret)
2319 goto err_exit;
2320 lsm_params->param_tag_tracker |= PARAM_REQUEST_DETECTION_BIT;
2321 }
Quinn Male2e883752019-03-22 11:28:54 -07002322
Quinn Male58749452020-03-26 17:14:56 -07002323 err = str_parms_get_str(parms, ST_PARAM_KEY_LAB_DAM_CFG_IDS,
2324 str_value, sizeof(str_value));
2325 if (err >= 0) {
2326 str_parms_del(parms, ST_PARAM_KEY_LAB_DAM_CFG_IDS);
2327 ret = platform_stdev_set_module_param_ids(
2328 &lsm_params->params[LAB_DAM_CFG], str_value, is_legacy_params);
2329 if (ret)
2330 goto err_exit;
2331 lsm_params->param_tag_tracker |= PARAM_LAB_DAM_CFG_BIT;
2332 }
Quinn Male3d7d9d42019-05-20 13:35:01 -07002333
Quinn Male58749452020-03-26 17:14:56 -07002334 err = str_parms_get_str(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS,
2335 str_value, sizeof(str_value));
2336 if (err >= 0) {
2337 str_parms_del(parms, ST_PARAM_KEY_CONFIDENCE_LEVELS_IDS);
2338 ret = platform_stdev_set_module_param_ids(
2339 &lsm_params->params[CONFIDENCE_LEVELS], str_value, is_legacy_params);
2340 if (ret)
2341 goto err_exit;
2342 lsm_params->param_tag_tracker |= PARAM_CONFIDENCE_LEVELS_BIT;
2343 }
Quinn Male2e883752019-03-22 11:28:54 -07002344
Quinn Male58749452020-03-26 17:14:56 -07002345 err = str_parms_get_str(parms, ST_PARAM_KEY_OPERATION_MODE_IDS,
2346 str_value, sizeof(str_value));
2347 if (err >= 0) {
2348 str_parms_del(parms, ST_PARAM_KEY_OPERATION_MODE_IDS);
2349 ret = platform_stdev_set_module_param_ids(
2350 &lsm_params->params[OPERATION_MODE], str_value, is_legacy_params);
2351 if (ret)
2352 goto err_exit;
2353 lsm_params->param_tag_tracker |= PARAM_OPERATION_MODE_BIT;
2354 }
Quinn Male2e883752019-03-22 11:28:54 -07002355
Quinn Male58749452020-03-26 17:14:56 -07002356 err = str_parms_get_str(parms, ST_PARAM_KEY_POLLING_ENABLE_IDS,
2357 str_value, sizeof(str_value));
2358 if (err >= 0) {
2359 str_parms_del(parms, ST_PARAM_KEY_POLLING_ENABLE_IDS);
2360 ret = platform_stdev_set_module_param_ids(
2361 &lsm_params->params[POLLING_ENABLE], str_value, is_legacy_params);
2362 if (ret)
2363 goto err_exit;
2364 lsm_params->param_tag_tracker |= PARAM_POLLING_ENABLE_BIT;
2365 }
Quinn Male2e883752019-03-22 11:28:54 -07002366
Quinn Male58749452020-03-26 17:14:56 -07002367 err = str_parms_get_str(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS,
2368 str_value, sizeof(str_value));
2369 if (err >= 0) {
2370 str_parms_del(parms, ST_PARAM_KEY_CUSTOM_CONFIG_IDS);
2371 ret = platform_stdev_set_module_param_ids(
2372 &lsm_params->params[CUSTOM_CONFIG], str_value, is_legacy_params);
2373 if (ret)
2374 goto err_exit;
2375 lsm_params->param_tag_tracker |= PARAM_CUSTOM_CONFIG_BIT;
2376 }
Quinn Male2e883752019-03-22 11:28:54 -07002377
Quinn Male58749452020-03-26 17:14:56 -07002378 err = str_parms_get_str(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS,
2379 str_value, sizeof(str_value));
2380 if (err >= 0) {
2381 str_parms_del(parms, ST_PARAM_KEY_DET_EVENT_TYPE_IDS);
2382 ret = platform_stdev_set_module_param_ids(
2383 &lsm_params->params[DET_EVENT_TYPE], str_value, is_legacy_params);
2384 if (ret)
2385 goto err_exit;
2386 lsm_params->param_tag_tracker |= PARAM_DET_EVENT_TYPE_BIT;
2387 }
Quinn Male2e883752019-03-22 11:28:54 -07002388
Quinn Male58749452020-03-26 17:14:56 -07002389 err = str_parms_get_str(parms, ST_PARAM_KEY_LAB_CONTROL_IDS,
2390 str_value, sizeof(str_value));
2391 if (err >= 0) {
2392 str_parms_del(parms, ST_PARAM_KEY_LAB_CONTROL_IDS);
2393 ret = platform_stdev_set_module_param_ids(
2394 &lsm_params->params[LAB_CONTROL], str_value, is_legacy_params);
2395 if (ret)
2396 goto err_exit;
2397 lsm_params->param_tag_tracker |= PARAM_LAB_CONTROL_BIT;
2398 }
Harshal Ahire89337992020-07-13 02:38:14 +05302399
2400 err = str_parms_get_str(parms, ST_PARAM_KEY_VERSION_ID,
2401 str_value, sizeof(str_value));
2402 if (err >= 0) {
2403 str_parms_del(parms, ST_PARAM_KEY_VERSION_ID);
2404 ret = platform_stdev_set_module_param_ids(
2405 &lsm_params->params[VERSION_ID], str_value, is_legacy_params);
2406 if (ret)
2407 goto err_exit;
2408 }
Quinn Male58749452020-03-26 17:14:56 -07002409 } else {
2410 err = str_parms_get_str(parms, ST_PARAM_KEY_PDK5_APP_TYPE,
Quinn Male2e883752019-03-22 11:28:54 -07002411 str_value, sizeof(str_value));
Quinn Male58749452020-03-26 17:14:56 -07002412 if (err >= 0) {
2413 str_parms_del(parms, ST_PARAM_KEY_PDK5_APP_TYPE);
2414 lsm_params->pdk5_app_type = strtoul(str_value, NULL, 16);
2415 }
Quinn Male2e883752019-03-22 11:28:54 -07002416 }
2417
2418 if (is_legacy_version == false) {
2419 err = str_parms_get_str(parms, ST_PARAM_KEY_APP_TYPE,
2420 str_value, sizeof(str_value));
2421 if (err >= 0) {
2422 str_parms_del(parms, ST_PARAM_KEY_APP_TYPE);
2423 lsm_params->app_type = strtoul(str_value, NULL, 16);
2424 }
2425 }
2426
2427 lsm_params->in_channels = SOUND_TRIGGER_CHANNEL_MODE_MONO; /* default */
2428 err = str_parms_get_int(parms, ST_PARAM_KEY_IN_CHANNELS, &value);
2429 if (err >= 0) {
2430 str_parms_del(parms, ST_PARAM_KEY_IN_CHANNELS);
2431 lsm_params->in_channels = value;
2432 }
2433
Quinn Male3d7d9d42019-05-20 13:35:01 -07002434 lsm_params->in_channels_lpi = lsm_params->in_channels;
2435 err = str_parms_get_int(parms, ST_PARAM_KEY_IN_CHANNELS_LPI, &value);
2436 if (err >= 0) {
2437 str_parms_del(parms, ST_PARAM_KEY_IN_CHANNELS_LPI);
2438 lsm_params->in_channels_lpi = value;
2439 }
2440
Quinn Male2e883752019-03-22 11:28:54 -07002441 if (my_data->xml_version >= PLATFORM_XML_VERSION_0x0105) {
2442 err = str_parms_get_str(parms, ST_PARAM_KEY_ADM_CFG_PROFILE,
2443 str_value, sizeof(str_value));
2444 if (err >= 0) {
2445 str_parms_del(parms, ST_PARAM_KEY_ADM_CFG_PROFILE);
2446 ret = string_to_profile_type(
2447 str_value, &(lsm_params->adm_cfg_profile));
2448 if (ret) {
2449 goto err_exit;
2450 }
2451 }
2452
2453 err = str_parms_get_str(parms, ST_PARAM_KEY_CAPTURE_DEVICE,
2454 str_value, sizeof(str_value));
2455 if (err >= 0) {
2456 str_parms_del(parms, ST_PARAM_KEY_CAPTURE_DEVICE);
2457 ret = string_to_capture_device(
2458 str_value, &(lsm_params->capture_device));
2459 if (ret) {
2460 goto err_exit;
2461 }
2462 }
2463
2464 err = str_parms_get_str(parms, ST_PARAM_KEY_FLUENCE_TYPE,
2465 str_value, sizeof(str_value));
2466 if (err >= 0) {
2467 str_parms_del(parms, ST_PARAM_KEY_FLUENCE_TYPE);
2468 ret = string_to_fluence_type(
2469 str_value, &(lsm_params->fluence_type));
2470 if (ret) {
2471 goto err_exit;
2472 }
2473 }
Quinn Male23026702019-07-19 10:51:16 -07002474
2475 lsm_params->lpi_enable = ST_PLATFORM_LPI_NONE;
2476 err = str_parms_get_str(parms, ST_PARAM_KEY_LPI_MODE,
2477 str_value, sizeof(str_value));
2478 if (err >= 0) {
2479 str_parms_del(parms, ST_PARAM_KEY_LPI_MODE);
Quinn Malecc1affd2019-07-18 16:13:31 -07002480 /*
2481 * The default setting will have 2 lsm_usecases in the xml -
2482 * lpi_mode LPI and NON_LPI_BARGE_IN. With this configuration,
2483 * dynamic EC updates are supported when barge_in_mode is enabled
2484 * or disabled. If a third lsm_usecase is present in the xml with
2485 * lpi_mode NON_LPI, then transitions will occur when barge_in_mode
2486 * is enabled or disabled. This allows for different number of MICs
2487 * between non-LPI with barge-in and non-LPI without barge-in.
2488 */
2489 if (!strncasecmp(str_value, "NON_LPI",
2490 sizeof("NON_LPI"))) {
Quinn Male23026702019-07-19 10:51:16 -07002491 lsm_params->lpi_enable = ST_PLATFORM_LPI_DISABLE;
Quinn Malecc1affd2019-07-18 16:13:31 -07002492 my_data->stdev->support_dynamic_ec_update = false;
2493 } else if (!strncasecmp(str_value, "NON_LPI_BARGE_IN",
2494 sizeof("NON_LPI_BARGE_IN"))) {
2495 lsm_params->lpi_enable = ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN;
2496 } else if (!strncasecmp(str_value, "LPI", sizeof("LPI"))) {
Quinn Male23026702019-07-19 10:51:16 -07002497 lsm_params->lpi_enable = ST_PLATFORM_LPI_ENABLE;
Quinn Malecc1affd2019-07-18 16:13:31 -07002498 } else {
Quinn Male23026702019-07-19 10:51:16 -07002499 ALOGE("%s: invalid lpi_mode set: %s", __func__, str_value);
Quinn Malecc1affd2019-07-18 16:13:31 -07002500 goto err_exit;
2501 }
Quinn Male23026702019-07-19 10:51:16 -07002502 }
Quinn Male2e883752019-03-22 11:28:54 -07002503 }
2504
Quinn Male2e883752019-03-22 11:28:54 -07002505 free(kv_pairs);
2506 return 0;
2507
2508err_exit:
Quinn Male58749452020-03-26 17:14:56 -07002509 list_for_each_safe(module_node, tmp_node,
2510 &lsm_params->module_params_list) {
2511 module_params = node_to_item(module_node, struct st_module_params,
2512 list_node);
2513 list_remove(module_node);
2514 free(module_params);
2515 }
Quinn Malea8019d12020-06-22 13:36:41 -07002516 free(lsm_params);
Quinn Male2e883752019-03-22 11:28:54 -07002517 free(kv_pairs);
2518 return ret;
2519}
2520
Quinn Male58749452020-03-26 17:14:56 -07002521static int platform_stdev_create_lsm_params
2522(
2523 void *platform
2524)
2525{
2526 struct platform_data *my_data = (struct platform_data *)platform;
2527 struct st_vendor_info *sm_info = NULL;
2528 struct st_lsm_params *lsm_params = NULL;
2529 struct listnode *sm_info_node = NULL;
2530
2531 sm_info_node = list_tail(&my_data->stdev->vendor_uuid_list);
2532 if (sm_info_node) {
2533 sm_info = node_to_item(sm_info_node, struct st_vendor_info, list_node);
2534 } else {
2535 ALOGE("%s: found NULL sm_info", __func__);
2536 return -EINVAL;
2537 }
2538
2539 lsm_params = calloc(1, sizeof(struct st_lsm_params));
2540 if (!lsm_params) {
2541 ALOGE("%s: lsm_params allcoation failed", __func__);
2542 return -ENOMEM;
2543 }
2544
2545 if (my_data->xml_version > PLATFORM_XML_VERSION_0x0105)
2546 list_init(&lsm_params->module_params_list);
2547
2548 list_add_tail(&sm_info->lsm_usecase_list, &lsm_params->list_node);
2549
2550 return 0;
2551}
2552
Quinn Male2e883752019-03-22 11:28:54 -07002553static int platform_stdev_create_sm_config_params
2554(
2555 void *platform
2556)
2557{
2558 struct platform_data *my_data = (struct platform_data *)platform;
2559 struct st_vendor_info *sm_info;
2560
2561 /*
2562 * Allocate the vendor sound model config. Set default values to
2563 * config params. Push this sound model config to list.
2564 */
2565 sm_info = calloc(1, sizeof(*sm_info));
2566 if (!sm_info) {
2567 ALOGE("%s: sm_info allcoation failed", __func__);
2568 return -ENOMEM;
2569 }
2570 /* initialize to deault config */
2571 sm_info->kw_transfer_mode = RT_TRANSFER_MODE;
2572 sm_info->kw_capture_format = PCM_RAW;
2573 sm_info->kw_duration = DEFAULT_MAX_KEYWORD_DURATION_MS;
2574 sm_info->client_capture_read_delay = DEFAULT_MAX_CLIENT_LAB_READ_DELAY_MS;
2575 sm_info->sample_rate = SOUND_TRIGGER_SAMPLING_RATE_16000;
2576 sm_info->format = PCM_FORMAT_S16_LE;
2577 sm_info->in_channels = SOUND_TRIGGER_CHANNEL_MODE_MONO;
2578 sm_info->out_channels = SOUND_TRIGGER_CHANNEL_MODE_MONO;
2579 sm_info->profile_type = ST_PROFILE_TYPE_NONE;
2580 sm_info->fwk_mode = SOUND_TRIGGER_EVENT_NON_TIME_STAMP_MODE;
2581 sm_info->fluence_type = ST_FLUENCE_TYPE_NONE;
2582 sm_info->wdsp_fluence_type = ST_FLUENCE_TYPE_NONE;
2583 sm_info->split_ec_ref_data = false;
2584 sm_info->ec_ref_channel_cnt = SOUND_TRIGGER_CHANNEL_MODE_MONO;
2585
2586 list_init(&sm_info->gcs_usecase_list);
2587 list_init(&sm_info->lsm_usecase_list);
2588 list_init(&sm_info->arm_ss_usecase_list);
2589 list_init(&sm_info->lsm_ss_usecase_list);
2590
2591 list_add_tail(&my_data->stdev->vendor_uuid_list,
2592 &sm_info->list_node);
2593
2594 return 0;
2595}
2596
2597static int platform_stdev_set_sm_config_params
2598(
2599 void *platform,
2600 struct str_parms *parms
2601)
2602{
2603 struct platform_data *my_data = (struct platform_data *)platform;
2604 sound_trigger_device_t *stdev = my_data->stdev;
Quinn Male58749452020-03-26 17:14:56 -07002605 struct listnode *sm_info_node = NULL, *gcs_node = NULL;
2606 struct listnode *arm_node = NULL, *lsm_node = NULL, *module_node = NULL;
2607 struct listnode *tmp_node = NULL, *tmp_node1 = NULL;
Quinn Male2e883752019-03-22 11:28:54 -07002608 struct st_vendor_info *sm_info = NULL;
2609 char str_value[ST_MAX_STRING_PARAM_SIZE];
2610 char *kv_pairs = str_parms_to_str(parms);
Quinn Male58749452020-03-26 17:14:56 -07002611 int ret = 0, err = 0, value = 0;
2612 struct st_gcs_params *gcs_params = NULL;
2613 struct st_arm_ss_params *arm_params = NULL;
2614 struct st_lsm_ss_params *lsm_ss_params = NULL;
2615 struct st_lsm_params *lsm_params = NULL;
2616 struct st_module_params *module_params = NULL;
Quinn Male2e883752019-03-22 11:28:54 -07002617
2618 ALOGV("%s: enter: %s", __func__, kv_pairs);
2619 if (kv_pairs == NULL) {
2620 ALOGE("%s: key-value pair is NULL", __func__);
2621 return -EINVAL;
2622 }
2623
2624 sm_info_node = list_tail(&my_data->stdev->vendor_uuid_list);
2625 if (!sm_info_node) {
2626 ALOGE("%s: found NULL sm_info_node", __func__);
2627 ret = -ENOMEM;
2628 goto error_exit;
2629 }
2630
2631 sm_info = node_to_item(sm_info_node, struct st_vendor_info, list_node);
2632
2633 /* Set the platform configured params */
2634 err = str_parms_get_str(parms, ST_PARAM_KEY_SM_VENDOR_UUID,
2635 str_value, sizeof(str_value));
2636 if (err >= 0) {
2637 str_parms_del(parms, ST_PARAM_KEY_SM_VENDOR_UUID);
2638 if (string_to_uuid(str_value, &sm_info->uuid) < 0) {
2639 ALOGE("%s: string_to_uuid failed", __func__);
2640 ret = -EINVAL;
2641 goto error_exit;
2642 }
2643 }
2644
2645 err = str_parms_get_str(parms, ST_PARAM_KEY_EXECUTION_TYPE,
2646 str_value, sizeof(str_value));
2647 if (err >= 0) {
2648 str_parms_del(parms, ST_PARAM_KEY_EXECUTION_TYPE);
2649 if (!strcmp(str_value, "WDSP")) {
2650 sm_info->exec_mode_cfg = EXEC_MODE_CFG_CPE;
2651 } else if (!strcmp(str_value, "ADSP")) {
2652 sm_info->exec_mode_cfg = EXEC_MODE_CFG_APE;
2653 } else if (!strcmp(str_value, "DYNAMIC")) {
2654 sm_info->exec_mode_cfg = EXEC_MODE_CFG_DYNAMIC;
2655 } else if (!strcmp(str_value, "ARM")) {
2656 sm_info->exec_mode_cfg = EXEC_MODE_CFG_ARM;
2657 } else {
2658 ALOGE("%s: invalid exec type set: %s", __func__, str_value);
2659 }
2660 }
2661
Shalini Manjunatha47c34c82021-05-10 16:46:43 +05302662 err = str_parms_get_str(parms, ST_PARAM_KEY_SECOND_STAGE_SUPPORTED,
2663 str_value, sizeof(str_value));
2664 //By default set to true
2665 sm_info->second_stage_supported = true;
2666 if (err >= 0) {
2667 str_parms_del(parms, ST_PARAM_KEY_SECOND_STAGE_SUPPORTED);
2668 if (!strcmp(str_value, "true")) {
2669 sm_info->second_stage_supported = true;
2670 } else if (!strcmp(str_value, "false")) {
2671 sm_info->second_stage_supported = false;
2672 } else {
2673 ALOGE("%s: invalid second stage support value set: %s", __func__, str_value);
2674 }
2675 }
2676
Quinn Male2e883752019-03-22 11:28:54 -07002677 err = str_parms_get_str(parms, ST_PARAM_KEY_APP_TYPE,
2678 str_value, sizeof(str_value));
2679 if (err >= 0) {
2680 str_parms_del(parms, ST_PARAM_KEY_APP_TYPE);
2681 sm_info->app_type = strtoul(str_value, NULL, 16);
2682 }
2683
Quinn Male2e883752019-03-22 11:28:54 -07002684 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_CPE_PHRASES, &value);
2685 if (err >= 0) {
2686 str_parms_del(parms, ST_PARAM_KEY_MAX_CPE_PHRASES);
2687 sm_info->avail_cpe_phrases = value;
2688 }
2689
2690 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_CPE_USERS, &value);
2691 if (err >= 0) {
2692 str_parms_del(parms, ST_PARAM_KEY_MAX_CPE_USERS);
2693 sm_info->avail_cpe_users = value;
2694 }
2695
2696 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_APE_PHRASES, &value);
2697 if (err >= 0) {
2698 str_parms_del(parms, ST_PARAM_KEY_MAX_APE_PHRASES);
2699 sm_info->avail_ape_phrases = value;
2700 }
2701
2702 err = str_parms_get_int(parms, ST_PARAM_KEY_MAX_APE_USERS, &value);
2703 if (err >= 0) {
2704 str_parms_del(parms, ST_PARAM_KEY_MAX_APE_USERS);
2705 sm_info->avail_ape_users = value;
2706 }
2707
2708 err = str_parms_get_int(parms, ST_PARAM_KEY_CLIENT_CAPTURE_READ_DELAY, &value);
2709 if (err >= 0) {
2710 str_parms_del(parms, ST_PARAM_KEY_CLIENT_CAPTURE_READ_DELAY);
2711 sm_info->client_capture_read_delay = value;
2712 }
2713
2714 err = str_parms_get_int(parms, ST_PARAM_KEY_KW_START_TOLERANCE, &value);
2715 if (err >= 0) {
2716 str_parms_del(parms, ST_PARAM_KEY_KW_START_TOLERANCE);
2717 sm_info->kw_start_tolerance = value;
2718 } else {
2719 sm_info->kw_start_tolerance = FIRST_STAGE_KW_START_TOLERANCE_MS;
2720 }
2721
2722 err = str_parms_get_int(parms, ST_PARAM_KEY_KW_END_TOLERANCE, &value);
2723 if (err >= 0) {
2724 str_parms_del(parms, ST_PARAM_KEY_KW_END_TOLERANCE);
2725 sm_info->kw_end_tolerance = value;
2726 } else {
2727 sm_info->kw_end_tolerance = FIRST_STAGE_KW_END_TOLERANCE_MS;
2728 }
2729
2730 err = str_parms_get_str(parms, ST_PARAM_KEY_CAPTURE_KEYWORD,
2731 str_value, sizeof(str_value));
2732 if (err >= 0) {
2733 str_parms_del(parms, ST_PARAM_KEY_CAPTURE_KEYWORD);
2734 ret = platform_stdev_set_capture_keyword_config(sm_info, str_value);
2735 if (ret)
2736 goto error_exit;
2737
2738 }
2739
2740 err = str_parms_get_str(parms, ST_PARAM_KEY_FIRMWARE_IMAGE,
2741 str_value, sizeof(str_value));
2742 if (err >= 0) {
2743 str_parms_del(parms, ST_PARAM_KEY_FIRMWARE_IMAGE);
2744 strlcpy(sm_info->cpe_firmware_image,
2745 str_value, sizeof(sm_info->cpe_firmware_image));
2746 }
2747
2748 err = str_parms_get_str(parms, ST_PARAM_KEY_EVENT_TIMESTAMP_MODE,
2749 str_value, sizeof(str_value));
2750 if (err >= 0) {
2751 str_parms_del(parms, ST_PARAM_KEY_EVENT_TIMESTAMP_MODE);
2752 if (!strncasecmp(str_value, "true", 4))
2753 sm_info->fwk_mode = SOUND_TRIGGER_EVENT_TIME_STAMP_MODE;
2754 }
2755
2756 err = str_parms_get_int(parms, ST_PARAM_KEY_SAMPLE_RATE, &value);
2757 if (err >= 0) {
2758 str_parms_del(parms, ST_PARAM_KEY_SAMPLE_RATE);
2759 sm_info->sample_rate = value;
2760 }
2761
2762 err = str_parms_get_int(parms, ST_PARAM_KEY_BIT_WIDTH, &value);
2763 if (err >= 0) {
2764 str_parms_del(parms, ST_PARAM_KEY_BIT_WIDTH);
2765 if (value == 16) {
2766 sm_info->format = PCM_FORMAT_S16_LE;
2767 } else if (value == 24) {
2768 sm_info->format = PCM_FORMAT_S24_LE;
2769 } else {
2770 ALOGE("%s: invalid bit width for profile", __func__);
2771 ret = -EINVAL;
2772 goto error_exit;
2773 }
2774 }
2775
2776 err = str_parms_get_int(parms, ST_PARAM_KEY_OUT_CHANNELS, &value);
2777 if (err >= 0) {
2778 str_parms_del(parms, ST_PARAM_KEY_OUT_CHANNELS);
2779 } else {
2780 /* Backward compatibility with old XML */
2781 err = str_parms_get_int(parms, ST_PARAM_KEY_CHANNEL_COUNT, &value);
2782 if (err >= 0) {
2783 str_parms_del(parms, ST_PARAM_KEY_CHANNEL_COUNT);
2784 }
2785 }
2786 if (err >= 0) {
2787 sm_info->out_channels = value;
2788 /* Backward compatibility where in_channels is not in lsm_usecase */
2789 if (my_data->xml_version <= PLATFORM_XML_VERSION_0x0102)
2790 sm_info->in_channels = sm_info->out_channels;
2791 }
2792
2793 err = str_parms_get_str(parms, ST_PARAM_KEY_ADM_CFG_PROFILE,
2794 str_value, sizeof(str_value));
2795 if (err >= 0) {
2796 str_parms_del(parms, ST_PARAM_KEY_ADM_CFG_PROFILE);
2797 if (string_to_profile_type(str_value, &sm_info->profile_type) < 0) {
2798 ALOGE("%s: string_to_profile_type failed", __func__);
2799 ret = -EINVAL;
2800 goto error_exit;
2801 }
2802 }
2803
2804 err = str_parms_get_str(parms, ST_PARAM_KEY_FLUENCE_TYPE,
2805 str_value, sizeof(str_value));
2806 if (err >= 0) {
2807 str_parms_del(parms, ST_PARAM_KEY_FLUENCE_TYPE);
2808 if (string_to_fluence_type(str_value, &sm_info->fluence_type) < 0) {
2809 ALOGE("%s: string_to_fluence_type failed", __func__);
2810 ret = -EINVAL;
2811 goto error_exit;
2812 }
2813 }
2814
2815 err = str_parms_get_str(parms, ST_PARAM_KEY_WDSP_FLUENCE_TYPE,
2816 str_value, sizeof(str_value));
2817 if (err >= 0) {
2818 str_parms_del(parms, ST_PARAM_KEY_WDSP_FLUENCE_TYPE);
2819 if (string_to_fluence_type(str_value, &sm_info->wdsp_fluence_type) < 0) {
2820 ALOGE("%s: string_to_fluence_type failed", __func__);
2821 ret = -EINVAL;
2822 goto error_exit;
2823 }
2824 }
2825
2826 err = str_parms_get_str(parms, ST_PARAM_KEY_SPLIT_EC_REF_DATA,
2827 str_value, sizeof(str_value));
2828 if (err >= 0) {
2829 str_parms_del(parms, ST_PARAM_KEY_SPLIT_EC_REF_DATA);
2830 sm_info->split_ec_ref_data =
2831 !strncasecmp(str_value, "true", 4) ? true : false;
2832 }
2833
2834 err = str_parms_get_int(parms, ST_PARAM_KEY_EC_REF_CHANNEL_COUNT, &value);
2835 if (err >= 0) {
2836 str_parms_del(parms, ST_PARAM_KEY_EC_REF_CHANNEL_COUNT);
2837 sm_info->ec_ref_channel_cnt = value;
2838 }
2839
2840 err = str_parms_get_str(parms, ST_PARAM_KEY_LPI_ENABLE,
2841 str_value, sizeof(str_value));
2842 if (err >= 0) {
2843 str_parms_del(parms, ST_PARAM_KEY_LPI_ENABLE);
2844 sm_info->lpi_enable = !strncasecmp(str_value, "true", 4) ? true : false;
2845 }
2846
2847 err = str_parms_get_str(parms, ST_PARAM_KEY_VAD_ENABLE,
2848 str_value, sizeof(str_value));
2849 if (err >= 0) {
2850 str_parms_del(parms, ST_PARAM_KEY_VAD_ENABLE);
2851 sm_info->vad_enable = !strncasecmp(str_value, "true", 4) ? true : false;
2852 }
2853
Quinn Male3d7d9d42019-05-20 13:35:01 -07002854 err = str_parms_get_int(parms, ST_PARAM_KEY_DAM_TOKEN_ID, &value);
2855 if (err >= 0) {
2856 str_parms_del(parms, ST_PARAM_KEY_DAM_TOKEN_ID);
2857 sm_info->lab_dam_cfg_payload.token_id = value;
2858 }
2859
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -07002860 err = str_parms_get_str(parms, ST_PARAM_KEY_MERGE_FIRST_STAGE_SOUNDMODELS,
2861 str_value, sizeof(str_value));
2862 if (err >= 0) {
2863 str_parms_del(parms, ST_PARAM_KEY_MERGE_FIRST_STAGE_SOUNDMODELS);
2864 sm_info->merge_fs_soundmodels =
2865 !strncasecmp(str_value, "true", 4) ? true : false;
2866 }
2867
Harshal Ahire89337992020-07-13 02:38:14 +05302868 err = str_parms_get_str(parms, ST_PARAM_KEY_GET_MODULE_VERSION,
2869 str_value, sizeof(str_value));
2870 if (err >= 0) {
2871 str_parms_del(parms, ST_PARAM_KEY_GET_MODULE_VERSION);
2872 sm_info->get_module_version =
2873 !strncasecmp(str_value, "true", 4) ? true : false;
2874 }
2875
Quinn Male2e883752019-03-22 11:28:54 -07002876 sm_info->avail_transit_ape_phrases = sm_info->avail_ape_phrases;
2877 sm_info->avail_transit_ape_users = sm_info->avail_ape_users;
2878 sm_info->avail_transit_cpe_phrases = sm_info->avail_cpe_phrases;
2879 sm_info->avail_transit_cpe_users = sm_info->avail_cpe_users;
2880
2881 /* store combined keyphrases/users of all engines */
2882 stdev->avail_ape_phrases += sm_info->avail_ape_phrases;
2883 stdev->avail_ape_users += sm_info->avail_ape_users;
2884 stdev->avail_cpe_phrases += sm_info->avail_cpe_phrases;
2885 stdev->avail_cpe_users += sm_info->avail_cpe_users;
2886
2887 free(kv_pairs);
2888 ALOGV("%s: exit", __func__);
2889 return 0;
2890
2891error_exit:
2892 if (sm_info) {
2893 /* remove and free the param structs */
2894 list_for_each_safe(arm_node, tmp_node, &sm_info->arm_ss_usecase_list) {
2895 arm_params = node_to_item(arm_node, struct st_arm_ss_params, list_node);
2896 list_remove(arm_node);
2897 free(arm_params);
2898 }
2899 list_for_each_safe(lsm_node, tmp_node, &sm_info->lsm_ss_usecase_list) {
2900 lsm_ss_params = node_to_item(lsm_node, struct st_lsm_ss_params, list_node);
2901 list_remove(lsm_node);
2902 free(lsm_ss_params);
2903 }
2904 list_for_each_safe(gcs_node, tmp_node, &sm_info->gcs_usecase_list) {
2905 gcs_params = node_to_item(gcs_node, struct st_gcs_params, list_node);
2906 list_remove(gcs_node);
2907 free(gcs_params);
2908 }
2909 list_for_each_safe(lsm_node, tmp_node, &sm_info->lsm_usecase_list) {
2910 lsm_params = node_to_item(lsm_node, struct st_lsm_params, list_node);
2911 list_remove(lsm_node);
Quinn Male58749452020-03-26 17:14:56 -07002912 list_for_each_safe(module_node, tmp_node1,
2913 &lsm_params->module_params_list) {
2914 module_params = node_to_item(module_node, struct st_module_params,
2915 list_node);
2916 list_remove(module_node);
2917 free(module_params);
2918 }
Quinn Male2e883752019-03-22 11:28:54 -07002919 free(lsm_params);
2920 }
2921 list_remove(sm_info_node);
2922 free(sm_info);
2923 }
2924 free(kv_pairs);
2925 return ret;
2926}
2927
2928static int platform_stdev_set_adm_cfg_params
2929(
2930 void *platform,
2931 struct str_parms *parms
2932)
2933{
2934 struct platform_data *my_data = (struct platform_data *)platform;
2935 struct adm_cfg_info *cfg_info;
2936 char str_value[ST_MAX_STRING_PARAM_SIZE];
2937 char *kv_pairs = str_parms_to_str(parms);
2938 int ret = 0, err, value;
2939
2940 ALOGV("%s: enter: %s", __func__, kv_pairs);
2941 if (kv_pairs == NULL) {
2942 ALOGE("%s: key-value pair is NULL", __func__);
2943 return -EINVAL;
2944 }
2945
2946 /* Allocate the app type profile info
2947 * Set the platform configured profile params.
2948 * Push this profile to platform data.
2949 */
2950 cfg_info = calloc(1, sizeof(*cfg_info));
2951 if (!cfg_info) {
2952 ALOGE("%s: cfg info allcoation failed", __func__);
2953 ret = -ENOMEM;
2954 goto error_exit;
2955 }
2956
2957 /* initialize to deault config */
2958 cfg_info->profile_type = ST_PROFILE_TYPE_DEFAULT;
2959 cfg_info->app_type = SOUND_TRIGGER_DEVICE_DEFAULT_APP_TYPE;
2960 cfg_info->sample_rate = SOUND_TRIGGER_SAMPLING_RATE_16000;
2961 cfg_info->bit_width = SOUND_TRIGGER_BIT_WIDTH;
2962
2963 /* Set the platform configured params */
2964 err = str_parms_get_str(parms, ST_PARAM_KEY_ADM_CFG_PROFILE,
2965 str_value, sizeof(str_value));
2966 if (err >= 0) {
2967 str_parms_del(parms, ST_PARAM_KEY_ADM_CFG_PROFILE);
2968 if (string_to_profile_type(str_value, &cfg_info->profile_type) < 0) {
2969 ALOGE("%s: string_to_profile_type failed", __func__);
2970 ret = -EINVAL;
2971 goto error_exit;
2972 }
2973 } else {
2974 ALOGE("%s: Error: adm cfg defined without profile", __func__);
2975 ret = -EINVAL;
2976 goto error_exit;
2977 }
2978
2979 err = str_parms_get_int(parms, ST_PARAM_KEY_APP_TYPE, &value);
2980 if (err >= 0) {
2981 str_parms_del(parms, ST_PARAM_KEY_APP_TYPE);
2982 cfg_info->app_type = value;
2983 }
2984
2985 err = str_parms_get_int(parms, ST_PARAM_KEY_SAMPLE_RATE, &value);
2986 if (err >= 0) {
2987 str_parms_del(parms, ST_PARAM_KEY_SAMPLE_RATE);
2988 cfg_info->sample_rate = value;
2989 }
2990
2991 err = str_parms_get_int(parms, ST_PARAM_KEY_BIT_WIDTH, &value);
2992 if (err >= 0) {
2993 str_parms_del(parms, ST_PARAM_KEY_BIT_WIDTH);
2994 cfg_info->bit_width = value;
2995 }
2996
2997 err = str_parms_get_int(parms, ST_PARAM_KEY_OUT_CHANNELS, &value);
2998 if (err >= 0) {
2999 str_parms_del(parms, ST_PARAM_KEY_OUT_CHANNELS);
3000 cfg_info->out_channels = value;
3001 }
3002
3003 list_add_tail(&my_data->stdev->adm_cfg_list,
3004 &cfg_info->list_node);
3005 free(kv_pairs);
3006 return 0;
3007
3008error_exit:
3009 if (cfg_info)
3010 free(cfg_info);
3011 free(kv_pairs);
3012 return ret;
3013}
3014
3015
3016static int platform_stdev_set_lpma_config
3017(
3018 void *platform,
3019 struct str_parms *parms
3020)
3021{
3022 struct platform_data *my_data = (struct platform_data *)platform;
3023 char str_value[ST_MAX_STRING_PARAM_SIZE];
3024 char *kv_pairs = str_parms_to_str(parms);
3025 int ret = 0, err;
3026
3027 if (kv_pairs == NULL) {
3028 ALOGE("%s: key-value pair is NULL", __func__);
3029 return -EINVAL;
3030 }
3031
3032 err = str_parms_get_str(parms, ST_PARAM_KEY_UID,
3033 str_value, sizeof(str_value));
3034 if (err >= 0) {
3035 str_parms_del(parms, ST_PARAM_KEY_UID);
3036 my_data->lpma_cfg.uid = strtoul(str_value, NULL, 16);
3037 }
3038
3039 err = str_parms_get_str(parms, ST_PARAM_KEY_BB_IDS,
3040 str_value, sizeof(str_value));
3041 if (err >= 0) {
3042 str_parms_del(parms, ST_PARAM_KEY_BB_IDS);
3043 if (my_data->lpma_cfg.num_bb_ids < MAX_LPMA_BB_IDS) {
3044 ret = platform_stdev_set_module_param_ids(
3045 &my_data->lpma_cfg.bb_params[my_data->lpma_cfg.num_bb_ids++],
3046 str_value, false);
3047 } else {
3048 ALOGE("%s: max lpma_bb_ids %d exceeded", __func__, MAX_LPMA_BB_IDS);
3049 }
3050 }
3051
3052 free(kv_pairs);
3053 return ret;
3054}
3055
3056int platform_stdev_set_parameters
3057(
3058 void *platform,
3059 struct str_parms *parms
3060)
3061{
3062 char *kv_pairs = str_parms_to_str(parms);
3063
3064 ALOGV("%s: enter with key-value pair: %s", __func__, kv_pairs);
3065 if (!kv_pairs) {
3066 ALOGE("%s: key-value pair is NULL",__func__);
3067 return -EINVAL;
3068 }
3069
3070 platform_set_common_config(platform, parms);
3071 platform_set_acdb_ids(platform, parms);
3072 free(kv_pairs);
3073
3074 return 0;
3075}
3076
3077static void platform_stdev_process_kv_params
3078(
3079 void *platform,
3080 const XML_Char **attr
3081)
3082{
3083 struct platform_data *my_data = (struct platform_data *)platform;
3084
3085 ALOGV("%s: %s:%s ", __func__, attr[0],attr[1]);
3086 str_parms_add_str(my_data->kvpairs, (char*)attr[0], (char*)attr[1]);
3087 return;
3088}
3089
3090static void platform_stdev_process_versioned_xml_data
3091(
3092 struct platform_data *my_data,
3093 const XML_Char *tag_name,
3094 const XML_Char **attr
3095)
3096{
3097 st_xml_process_fn fn_ptr;
3098
3099 if (!strcmp(tag_name, "common_config")) {
3100 my_data->st_xml_tag = TAG_COMMON;
3101 } else if (!strcmp(tag_name, "acdb_ids")) {
3102 my_data->st_xml_tag = TAG_ACDB;
3103 } else if (!strcmp(tag_name, "sound_model_config")) {
3104 my_data->st_xml_tag = TAG_SOUND_MODEL;
3105 /* create an entry for storing sound_model_config */
3106 platform_stdev_create_sm_config_params(my_data);
3107 } else if (!strcmp(tag_name, "arm_ss_usecase")) {
3108 my_data->st_xml_tag = TAG_ARM_SS_USECASE;
3109 } else if (!strcmp(tag_name, "gcs_usecase")) {
3110 my_data->st_xml_tag = TAG_GCS_USECASE;
3111 } else if (!strcmp(tag_name, "lsm_usecase")) {
3112 my_data->st_xml_tag = TAG_LSM_USECASE;
Quinn Male58749452020-03-26 17:14:56 -07003113 platform_stdev_create_lsm_params(my_data);
Quinn Male2e883752019-03-22 11:28:54 -07003114 } else if (!strcmp(tag_name, "lsm_ss_usecase")) {
3115 my_data->st_xml_tag = TAG_LSM_SS_USECASE;
Quinn Male58749452020-03-26 17:14:56 -07003116 } else if (!strcmp(tag_name, "module_params")) {
3117 my_data->st_xml_tag = TAG_MODULE_PARAMS;
Quinn Male2e883752019-03-22 11:28:54 -07003118 } else if (!strcmp(tag_name, "adm_config")) {
3119 my_data->st_xml_tag = TAG_ADM_CFG;
3120 } else if (!strcmp(tag_name, "backend_type")) {
3121 my_data->st_xml_tag = TAG_BACKEND_TYPE;
3122 } else if (!strcmp(tag_name, "lpma_config")) {
3123 my_data->st_xml_tag = TAG_LPMA_CONFIG;
3124 } else if(!strcmp(tag_name, "acdb_metainfo_key")) {
3125 my_data->st_xml_tag = TAG_ACDB_METAINFO_KEY;
3126 } else if (!strcmp(tag_name, "param")) {
3127 if ((my_data->st_xml_tag != TAG_ROOT) && (my_data->st_xml_tag != TAG_COMMON) &&
3128 (my_data->st_xml_tag != TAG_ACDB) && (my_data->st_xml_tag != TAG_SOUND_MODEL) &&
3129 (my_data->st_xml_tag != TAG_ARM_SS_USECASE) &&
3130 (my_data->st_xml_tag != TAG_GCS_USECASE) &&
3131 (my_data->st_xml_tag != TAG_LSM_USECASE) &&
3132 (my_data->st_xml_tag != TAG_LSM_SS_USECASE) &&
Quinn Male58749452020-03-26 17:14:56 -07003133 (my_data->st_xml_tag != TAG_MODULE_PARAMS) &&
Quinn Male2e883752019-03-22 11:28:54 -07003134 (my_data->st_xml_tag != TAG_ADM_CFG) &&
3135 (my_data->st_xml_tag != TAG_BACKEND_TYPE) &&
3136 (my_data->st_xml_tag != TAG_LPMA_CONFIG) &&
3137 (my_data->st_xml_tag != TAG_ACDB_METAINFO_KEY)) {
3138 ALOGE("%s: param under unknown tag", __func__);
3139 return;
3140 }
3141 fn_ptr = process_table[my_data->st_xml_tag];
3142 if (fn_ptr)
3143 fn_ptr(my_data, attr);
3144 }
3145}
3146
3147static void start_tag(void *userdata, const XML_Char *tag_name,
3148 const XML_Char **attr)
3149{
3150 struct platform_data *platform = (void *)userdata;
3151
3152 if (!platform || !tag_name || !attr) {
3153 ALOGE("%s: NULL platform/tag_name/attr", __func__);
3154 return;
3155 }
3156
3157 if ((platform->st_xml_tag == TAG_ROOT) &&
3158 !strcmp(tag_name, "param") && !strcmp(attr[0], "version") ) {
3159 /* This must be the first param for versioned XML file */
3160 platform->xml_version = strtoul(attr[1], NULL, 16);
3161 ALOGV("%s: xml_version 0x%04x", __func__, platform->xml_version);
3162 } else if (platform->xml_version) {
3163 platform_stdev_process_versioned_xml_data(platform, tag_name, attr);
3164 } else if (platform->st_xml_tag != TAG_ROOT) {
3165 ALOGE("%s: Unsupported platform xml. Upgrade to latest", __func__);
3166 }
3167 return;
3168}
3169
3170static void end_tag(void *userdata, const XML_Char *tag_name)
3171{
3172 struct platform_data *platform = userdata;
3173
3174 if (!platform || !tag_name) {
3175 ALOGE("%s: NULL tag or platform", __func__);
3176 return;
3177 }
3178
3179 if (!strcmp(tag_name, "common_config") || (!strcmp(tag_name, "acdb_ids"))) {
3180 platform->st_xml_tag = TAG_ROOT;
3181 platform_stdev_set_parameters(platform, platform->kvpairs);
3182 } else if (!strcmp(tag_name, "arm_ss_usecase")) {
3183 platform->st_xml_tag = TAG_ARM_SS_USECASE;
3184 platform_stdev_set_ss_params(platform, platform->kvpairs);
3185 platform->st_xml_tag = TAG_SOUND_MODEL;
3186 } else if (!strcmp(tag_name, "gcs_usecase")) {
3187 platform->st_xml_tag = TAG_SOUND_MODEL;
3188 platform_stdev_set_gcs_params(platform, platform->kvpairs);
3189 } else if (!strcmp(tag_name, "lsm_usecase")) {
3190 platform->st_xml_tag = TAG_SOUND_MODEL;
3191 platform_stdev_set_lsm_params(platform, platform->kvpairs);
Quinn Male58749452020-03-26 17:14:56 -07003192 } else if (!strcmp(tag_name, "module_params")) {
3193 platform->st_xml_tag = TAG_LSM_USECASE;
3194 platform_stdev_set_module_params(platform, platform->kvpairs);
Quinn Male2e883752019-03-22 11:28:54 -07003195 } else if (!strcmp(tag_name, "sound_model_config")) {
3196 platform->st_xml_tag = TAG_ROOT;
3197 platform_stdev_set_sm_config_params(platform, platform->kvpairs);
3198 } else if (!strcmp(tag_name, "adm_config")) {
3199 platform->st_xml_tag = TAG_ROOT;
3200 platform_stdev_set_adm_cfg_params(platform, platform->kvpairs);
3201 } else if (!strcmp(tag_name, "backend_type")) {
3202 platform->st_xml_tag = TAG_ROOT;
3203 platform_stdev_process_backend_type(platform, platform->kvpairs);
3204 } else if (!strcmp(tag_name, "lpma_config")) {
3205 platform->st_xml_tag = TAG_ROOT;
3206 platform_stdev_set_lpma_config(platform, platform->kvpairs);
3207 } else if (!strcmp(tag_name, "acdb_metainfo_key")) {
3208 platform->st_xml_tag = TAG_ROOT;
3209 } else if (!strcmp(tag_name, "lsm_ss_usecase")) {
3210 platform->st_xml_tag = TAG_LSM_SS_USECASE;
3211 platform_stdev_set_ss_params(platform, platform->kvpairs);
3212 platform->st_xml_tag = TAG_LSM_USECASE;
3213 }
3214}
3215
3216static int platform_parse_info(struct platform_data *platform, const char *filename)
3217{
3218 XML_Parser parser;
3219 FILE *file;
3220 int ret = 0;
3221 int bytes_read;
3222 void *buf;
3223
3224 file = fopen(filename, "r");
3225 if (!file) {
3226 ALOGD("%s: Failed to open %s, using defaults", __func__, filename);
3227 ret = -ENODEV;
3228 goto done;
3229 }
3230 platform->st_xml_tag = TAG_ROOT;
3231 platform->kvpairs = str_parms_create();
3232
3233 parser = XML_ParserCreate(NULL);
3234 if (!parser) {
3235 ALOGE("%s: Failed to create XML parser!", __func__);
3236 ret = -ENODEV;
3237 goto err_close_file;
3238 }
3239
3240 XML_SetUserData(parser, platform);
3241
3242 XML_SetElementHandler(parser, start_tag, end_tag);
3243
3244 while (1) {
3245 buf = XML_GetBuffer(parser, BUF_SIZE);
3246 if (buf == NULL) {
3247 ALOGE("%s: XML_GetBuffer failed", __func__);
3248 ret = -ENOMEM;
3249 goto err_free_parser;
3250 }
3251
3252 bytes_read = fread(buf, 1, BUF_SIZE, file);
3253 if (bytes_read < 0) {
3254 ALOGE("%s: fread failed, bytes read = %d", __func__, bytes_read);
3255 ret = bytes_read;
3256 goto err_free_parser;
3257 }
3258
3259 if (XML_ParseBuffer(parser, bytes_read,
3260 bytes_read == 0) == XML_STATUS_ERROR) {
3261 ALOGE("%s: XML_ParseBuffer failed, for %s",
3262 __func__, filename);
3263 ret = -EINVAL;
3264 goto err_free_parser;
3265 }
3266
3267 if (bytes_read == 0)
3268 break;
3269 }
3270
3271err_free_parser:
3272 XML_ParserFree(parser);
3273err_close_file:
3274 fclose(file);
3275done:
3276 return ret;
3277}
3278
3279static int get_codec_version(struct platform_data *my_data,
3280 const char *snd_card_name,
3281 int card_num)
3282{
3283 char procfs_path[50];
3284 FILE *fp;
3285
3286 /* query the codec type to handle FTRT based on codec capability
3287 currently applicable to tasha codec versions */
3288 if (strstr(snd_card_name, "tasha")) {
3289 snprintf(procfs_path, sizeof(procfs_path),
3290 "/proc/asound/card%d/codecs/tasha/version", card_num);
3291 if ((fp = fopen(procfs_path, "r")) != NULL) {
3292 fgets(my_data->codec_version, sizeof(my_data->codec_version), fp);
3293 fclose(fp);
3294 } else {
3295 ALOGE("%s: ERROR. cannot open %s", __func__, procfs_path);
3296 return -ENOENT;
3297 }
3298 }
3299 ALOGD("%s: codec version %s", __func__, my_data->codec_version);
3300
3301 return 0;
3302}
3303
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303304static void query_stdev_platform(struct platform_data *my_data,
Quinn Male2e883752019-03-22 11:28:54 -07003305 const char *snd_card_name,
3306 char *mixer_path_xml)
3307{
3308 if (strstr(snd_card_name, "msm8939-tapan")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303309 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_WCD9306,
3310 my_data->vendor_config_path);
3311 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Quinn Male2e883752019-03-22 11:28:54 -07003312 } else if (strstr(snd_card_name, "msm8952-tomtom")||
3313 strstr(snd_card_name, "msm8996-tomtom")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303314 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_WCD9330,
3315 my_data->vendor_config_path);
3316 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Quinn Male2e883752019-03-22 11:28:54 -07003317 } else if (strstr(snd_card_name, "sdm670-skuw")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303318 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_SKUW,
3319 my_data->vendor_config_path);
3320 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Quinn Male2e883752019-03-22 11:28:54 -07003321 } else if (strstr(snd_card_name, "msm8976-tasha")||
3322 strstr(snd_card_name, "msm8952-tasha") ||
3323 strstr(snd_card_name, "msm8953-tasha") ||
3324 strstr(snd_card_name, "msm8953-sku3-tasha") ||
3325 strstr(snd_card_name, "msm8937-tasha") ||
3326 strstr(snd_card_name, "sdm660-tasha") ||
3327 strstr(snd_card_name, "sdm670-tasha") ||
3328 strstr(snd_card_name, "apq8009-tashalite")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303329 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_WCD9335,
3330 my_data->vendor_config_path);
3331 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Quinn Male2e883752019-03-22 11:28:54 -07003332 } else if (strstr(snd_card_name, "tavil")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303333 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_WCD9340,
3334 my_data->vendor_config_path);
3335 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
3336 my_data->stdev->is_gcs = true;
Quinn Male2e883752019-03-22 11:28:54 -07003337 } else if (strstr(snd_card_name, "bg")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303338 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_BG,
3339 my_data->vendor_config_path);
3340 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
3341 my_data->stdev->is_gcs = true;
Quinn Male2e883752019-03-22 11:28:54 -07003342 } else if (strstr(snd_card_name, "qcs405-tdm")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303343 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME_TDM,
3344 my_data->vendor_config_path);
3345 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Quinn Male2e883752019-03-22 11:28:54 -07003346 } else {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303347 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME,
3348 my_data->vendor_config_path);
3349 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Quinn Male2e883752019-03-22 11:28:54 -07003350 }
Manisha Agarwaldf979312019-10-24 16:53:32 +05303351 /* create mixer path file name from sound card name
3352 and attach cdp/qrd if sound card name has cdp/qrd */
3353 char *tmp = NULL;
3354 char *snd_internal_name = NULL;
3355 char temp_path[MIXER_PATH_MAX_LENGTH];
Quinn Male3d7d9d42019-05-20 13:35:01 -07003356
Manisha Agarwaldf979312019-10-24 16:53:32 +05303357 strlcpy(temp_path, mixer_path_xml, MIXER_PATH_MAX_LENGTH);
Zhou Songd18c6712019-06-10 11:20:10 +08003358
Manisha Agarwaldf979312019-10-24 16:53:32 +05303359 char *snd_card_name_t = strdup(snd_card_name);
3360 if (snd_card_name_t != NULL) {
3361 snd_internal_name = strtok_r(snd_card_name_t, "-", &tmp);
3362 while (snd_internal_name != NULL) {
3363 snd_internal_name = strtok_r(NULL, "-", &tmp);
3364 if (snd_internal_name != NULL) {
3365 strlcat(temp_path, "_", MIXER_PATH_MAX_LENGTH);
3366 strlcat(temp_path, snd_internal_name, MIXER_PATH_MAX_LENGTH);
3367 strlcat(temp_path, MIXER_FILE_EXT, MIXER_PATH_MAX_LENGTH);
3368 if (access(temp_path, R_OK) == 0) {
3369 strlcat(mixer_path_xml, "_", MIXER_PATH_MAX_LENGTH);
3370 strlcat(mixer_path_xml, snd_internal_name, MIXER_PATH_MAX_LENGTH);
3371 break;
3372 }
3373 strlcpy(temp_path, mixer_path_xml, MIXER_PATH_MAX_LENGTH);
3374 }
Quinn Male2e883752019-03-22 11:28:54 -07003375 }
Zhou Songd18c6712019-06-10 11:20:10 +08003376 strlcpy(temp_path, mixer_path_xml, MIXER_PATH_MAX_LENGTH);
Manisha Agarwaldf979312019-10-24 16:53:32 +05303377 if (strstr(snd_card_name, "qrd")) {
3378 strlcat(temp_path, "_qrd", MIXER_PATH_MAX_LENGTH);
3379 strlcat(temp_path, MIXER_FILE_EXT, MIXER_PATH_MAX_LENGTH);
3380 if (access(temp_path, R_OK) == 0)
3381 strlcat(mixer_path_xml, "_qrd", MIXER_PATH_MAX_LENGTH);
3382 }
3383 else if (strstr(snd_card_name, "cdp")) {
3384 strlcat(temp_path, "_cdp", MIXER_PATH_MAX_LENGTH);
3385 strlcat(temp_path, MIXER_FILE_EXT, MIXER_PATH_MAX_LENGTH);
3386 if (access(temp_path, R_OK) == 0)
3387 strlcat(mixer_path_xml, "_cdp", MIXER_PATH_MAX_LENGTH);
3388 }
3389 free(snd_card_name_t);
Quinn Male2e883752019-03-22 11:28:54 -07003390 }
Manisha Agarwaldf979312019-10-24 16:53:32 +05303391 if (!strncmp(snd_card_name, "sm6150-wcd9375qrd-snd-card",
3392 sizeof("sm6150-wcd9375qrd-snd-card"))) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303393 get_xml_file_path(my_data->xml_file_path, MIXER_PATH_FILE_NAME,
3394 my_data->vendor_config_path);
3395 strlcpy(mixer_path_xml, my_data->xml_file_path, MIXER_PATH_MAX_LENGTH);
Manisha Agarwaldf979312019-10-24 16:53:32 +05303396 }
3397
Quinn Male2e883752019-03-22 11:28:54 -07003398 strlcat(mixer_path_xml, MIXER_FILE_EXT, MIXER_PATH_MAX_LENGTH);
3399
3400 /* Default sw_mad value will be overwritten if it
3401 is defined in platform info file
3402 */
3403 if ((strstr(snd_card_name, "msm8939") ||
3404 strstr(snd_card_name, "msm8909") ||
3405 strstr(snd_card_name, "apq8009") ||
3406 strstr(snd_card_name, "msm8952") ||
3407 strstr(snd_card_name, "sdm439") ||
3408 strstr(snd_card_name, "msm8976") ||
3409 strstr(snd_card_name, "msm8953") ||
3410 strstr(snd_card_name, "msm8937") ||
3411 strstr(snd_card_name, "sdm660") ||
3412 strstr(snd_card_name, "sdm670") ||
3413 strstr(snd_card_name, "sm6150") ||
3414 strstr(snd_card_name, "qcs605-lc") ||
3415 strstr(snd_card_name, "msm8x16")) &&
3416 !strstr(snd_card_name, "msm8976-tasha") &&
3417 !strstr(snd_card_name, "msm8952-tasha") &&
3418 !strstr(snd_card_name, "msm8953-tasha") &&
3419 !strstr(snd_card_name, "msm8953-sku3-tasha") &&
3420 !strstr(snd_card_name, "msm8937-tasha") &&
3421 !strstr(snd_card_name, "msm8952-tomtom") &&
3422 !strstr(snd_card_name, "sdm660-tasha") &&
3423 !strstr(snd_card_name, "sdm660-tavil") &&
3424 !strstr(snd_card_name, "sdm670-tasha") &&
3425 !strstr(snd_card_name, "sdm670-tavil") &&
3426 !strstr(snd_card_name, "sm6150-tavil") &&
3427 !strstr(snd_card_name, "apq8009-tasha") &&
3428 !strstr(snd_card_name, "msm8939-tomtom")) {
Saurav Kumar5e2957e2020-06-03 18:22:51 +05303429 my_data->stdev->sw_mad = true;
Quinn Male2e883752019-03-22 11:28:54 -07003430 }
3431}
3432
3433static void init_codec_backend_cfg_mixer_ctl(struct platform_data *my_data)
3434{
3435 char mixer_ctl[ST_MAX_STRING_PARAM_SIZE];
3436
3437 if (strcmp(my_data->backend_port, "")) {
3438 snprintf(mixer_ctl, sizeof(mixer_ctl),
3439 "%s SampleRate", my_data->backend_port);
3440 my_data->codec_backend_cfg.samplerate_mixer_ctl = strdup(mixer_ctl);
3441
3442 snprintf(mixer_ctl, sizeof(mixer_ctl),
3443 "%s Format", my_data->backend_port);
3444 my_data->codec_backend_cfg.format_mixer_ctl = strdup(mixer_ctl);
3445
3446 snprintf(mixer_ctl, sizeof(mixer_ctl),
3447 "%s Channels", my_data->backend_port);
3448 my_data->codec_backend_cfg.channelcount_mixer_ctl = strdup(mixer_ctl);
3449
3450 snprintf(mixer_ctl, sizeof(mixer_ctl), "VAD CFG");
3451 my_data->codec_backend_cfg.vad_mixer_ctl = strdup(mixer_ctl);
3452
3453 snprintf(mixer_ctl, sizeof(mixer_ctl),
3454 "%s TX island", my_data->backend_port);
3455 my_data->codec_backend_cfg.lpi_mixer_ctl = strdup(mixer_ctl);
3456 }
3457}
3458
Quinn Maled409e412019-12-09 14:50:48 -08003459/* ---------------- device list APIs --------------- */
3460static int list_length(struct listnode *list)
3461{
3462 struct listnode *node;
3463 int length = 0;
3464
3465 if (list == NULL)
3466 goto done;
3467
3468 for (node = list->next; node != list; node = node->next)
3469 ++length;
3470done:
3471 return length;
3472}
3473
3474/*
3475 * Clear device list
3476 * Operation: devices = {};
3477 */
3478static int clear_devices(struct listnode *devices)
3479{
Samyak Jainad14a972020-04-13 09:46:42 +05303480 struct listnode *node = NULL, *temp = NULL;
Quinn Maled409e412019-12-09 14:50:48 -08003481 struct audio_device_info *item = NULL;
3482
3483 if (devices == NULL)
3484 return 0;
3485
Samyak Jainad14a972020-04-13 09:46:42 +05303486 list_for_each_safe (node, temp, devices) {
Quinn Maled409e412019-12-09 14:50:48 -08003487 item = node_to_item(node, struct audio_device_info, list);
3488 if (item != NULL) {
3489 list_remove(&item->list);
3490 free(item);
3491 }
3492 }
3493
3494 return 0;
3495}
3496
3497/*
3498 * Returns true if A2DP output device is found in passed devices list
3499 */
3500bool platform_stdev_is_a2dp_out_device_type(struct listnode *devices)
3501{
3502 if (devices == NULL)
3503 return false;
3504
3505 if (platform_stdev_compare_device_type(devices,
3506 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP) ||
3507 platform_stdev_compare_device_type(devices,
3508 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES) ||
3509 platform_stdev_compare_device_type(devices,
3510 AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER))
3511 return true;
3512 else
3513 return false;
3514}
3515
3516/*
3517 * Check if a device with given type is present in devices list
3518 */
3519bool platform_stdev_compare_device_type(struct listnode *devices,
3520 audio_devices_t device_type)
3521{
3522 struct listnode *node = NULL;
3523 struct audio_device_info *item = NULL;
3524
3525 if (devices == NULL)
3526 return false;
3527
3528 list_for_each (node, devices) {
3529 item = node_to_item(node, struct audio_device_info, list);
3530 if (item != NULL && (item->type == device_type)) {
3531 ALOGV("%s: device types %d match", __func__, device_type);
3532 return true;
3533 }
3534 }
3535 return false;
3536}
3537
3538/*
3539 * Returns true if lists are equal in terms of device type
3540 * TODO: Check if device addresses are also equal in the future
3541 */
3542bool platform_stdev_compare_devices(struct listnode *d1, struct listnode *d2)
3543{
3544 struct listnode *node = NULL;
3545 struct audio_device_info *item = NULL;
3546
3547 if (d1 == NULL && d2 == NULL)
3548 return true;
3549
3550 if (d1 == NULL || d2 == NULL ||
3551 (list_length(d1) != list_length(d2)))
3552 return false;
3553
3554 list_for_each (node, d1) {
3555 item = node_to_item(node, struct audio_device_info, list);
3556 if (item != NULL &&
3557 !platform_stdev_compare_device_type(d2, item->type))
3558 return false;
3559 }
3560 return true;
3561}
3562
3563/*
3564 * Add or remove device from list denoted by head
3565 */
3566int platform_stdev_update_device_list(audio_devices_t type, char* address,
3567 struct listnode *head, bool add_device)
3568{
3569 struct listnode *node = NULL;
3570 struct audio_device_info *item = NULL;
3571 struct audio_device_info *device = NULL;
3572 int ret = 0;
3573
3574 if (head == NULL)
3575 goto done;
3576
3577 if (type == AUDIO_DEVICE_NONE) {
3578 ALOGE("%s: Invalid device: %#x", __func__, type);
3579 ret = -EINVAL;
3580 goto done;
3581 }
3582
3583 list_for_each (node, head) {
3584 item = node_to_item(node, struct audio_device_info, list);
3585 if (item != NULL && (item->type == type)) {
3586 device = item;
3587 break;
3588 }
3589 }
3590
3591 if (add_device) {
3592 if (device == NULL) {
3593 device = (struct audio_device_info *)
3594 calloc (1, sizeof(struct audio_device_info));
3595 if (!device) {
3596 ALOGE("%s: Cannot allocate memory for device_info", __func__);
3597 ret = -ENOMEM;
3598 goto done;
3599 }
3600 device->type = type;
3601 list_add_tail(head, &device->list);
3602 }
3603 /*
3604 * TODO: Use address in future if required. Currently NULL string used.
3605 */
3606 strlcpy(device->address, address, AUDIO_DEVICE_MAX_ADDRESS_LEN);
3607 ALOGV("%s: Added device type %#x, address %s", __func__, type,
3608 address);
3609 } else {
3610 if (device != NULL) {
3611 list_remove(&device->list);
3612 free(device);
3613 ALOGV("%s: Removed device type %#x, address %s", __func__, type,
3614 address);
3615 }
3616 }
3617done:
3618 return ret;
3619}
3620
3621/*
3622 * Assign source device list to destination device list
3623 * Operation: dest list = source list
3624 */
3625int platform_stdev_assign_devices(struct listnode *dest,
3626 const struct listnode *source)
3627{
3628 struct listnode *node;
3629 struct audio_device_info *item = NULL;
3630 int ret = 0;
3631
3632 if (source == NULL || dest == NULL)
3633 return ret;
3634
3635 if (!list_empty(dest))
3636 clear_devices(dest);
3637
3638 list_for_each (node, source) {
3639 item = node_to_item(node, struct audio_device_info, list);
3640 if (item != NULL)
3641 ret = platform_stdev_update_device_list(item->type, item->address,
3642 dest, true);
3643 }
3644 return ret;
3645}
3646
Quinn Male2e883752019-03-22 11:28:54 -07003647#if (SNDRV_LSM_VERSION >= SNDRV_PROTOCOL_VERSION(0, 3, 0))
3648static void platform_stdev_send_adm_app_type_cfg(void *platform)
3649{
3650 struct platform_data *my_data = (struct platform_data *)platform;
3651 sound_trigger_device_t *stdev = my_data->stdev;
3652 const char *mixer_ctl_name = "Listen App Type Config V2";
3653 struct mixer_ctl *ctl;
3654 struct listnode *p_node, *temp_node;
3655 struct adm_cfg_info *cfg_info;;
3656 int app_type_cfg[ST_MAX_LENGTH_MIXER_CONTROL] = {-1};
3657 int i, len = 0, num_app_types = 0;
3658 bool update;
3659
3660 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
3661 if (!ctl) {
3662 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
3663 __func__, mixer_ctl_name);
3664 return;
3665 }
3666
3667 /*
3668 * The first entry should define number of app type cfgs being sent
3669 * following which each app type cfg is populated in below order:
3670 * - app type
3671 * - sample rate
3672 * - bit width
3673 * - out_channels
3674 * ex for 2 app type cfgs being sent:
3675 * 2, 69938, 16000, 16, 1, 69939, 48000, 24, 3
3676 *
3677 * Number of app types is determined at the end before setting mixer control
3678 * after avoiding duplicate app_type entries
3679 */
3680 app_type_cfg[len++] = num_app_types;
3681 list_for_each_safe(p_node, temp_node, &stdev->adm_cfg_list) {
3682 cfg_info = node_to_item(p_node, struct adm_cfg_info, list_node);
3683 update = true;
3684 for (i = 0; i < len; i = i + 4) {
3685 /* avoid updating duplicate app types */
3686 if (app_type_cfg[i + 1] == -1) {
3687 break;
3688 } else if (app_type_cfg[i + 1] == cfg_info->app_type) {
3689 update = false;
3690 break;
3691 }
3692 }
3693
3694 if (update && ((len + 4) <= ST_MAX_LENGTH_MIXER_CONTROL)) {
3695 num_app_types += 1;
3696 app_type_cfg[len++] = cfg_info->app_type;
3697 app_type_cfg[len++] = cfg_info->sample_rate;
3698 app_type_cfg[len++] = cfg_info->bit_width;
3699 app_type_cfg[len++] = cfg_info->out_channels;
3700 }
3701 }
3702
3703 ALOGV("%s: num_app_types_v2 %d", __func__, num_app_types);
3704 if (num_app_types) {
3705 app_type_cfg[0] = num_app_types;
3706 mixer_ctl_set_array(ctl, app_type_cfg, len);
3707 }
3708}
3709#else
3710static void platform_stdev_send_adm_app_type_cfg(void *platform)
3711{
3712 struct platform_data *my_data = (struct platform_data *)platform;
3713 sound_trigger_device_t *stdev = my_data->stdev;
3714 const char *mixer_ctl_name = "Listen App Type Config";
3715 struct mixer_ctl *ctl;
3716 struct listnode *p_node, *temp_node;
3717 struct adm_cfg_info *cfg_info;;
3718 int app_type_cfg[ST_MAX_LENGTH_MIXER_CONTROL] = {-1};
3719 int i, len = 0, num_app_types = 0;
3720 bool update;
3721
3722 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
3723 if (!ctl) {
3724 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
3725 __func__, mixer_ctl_name);
3726 return;
3727 }
3728
3729 /*
3730 * The first entry should define number of app type cfgs being sent
3731 * following which each app type cfg is populated in below order:
3732 * - app type
3733 * - sample rate
3734 * - bit width
3735 * ex for 2 app type cfgs being sent:
3736 * 2, 69938, 16000, 16, 69939, 48000, 24
3737 *
3738 * Number of app types is determined at the end before setting mixer control
3739 * after avoiding duplicate app_type entries
3740 */
3741 app_type_cfg[len++] = num_app_types;
3742 list_for_each_safe(p_node, temp_node, &stdev->adm_cfg_list) {
3743 cfg_info = node_to_item(p_node, struct adm_cfg_info, list_node);
3744 update = true;
3745 for (i = 0; i < len; i = i+3) {
3746 /* avoid updating duplicate app types */
3747 if (app_type_cfg[i+1] == -1) {
3748 break;
3749 } else if (app_type_cfg[i+1] == cfg_info->app_type) {
3750 update = false;
3751 break;
3752 }
3753 }
3754
3755 if (update && ((len + 3) <= ST_MAX_LENGTH_MIXER_CONTROL)) {
3756 num_app_types += 1;
3757 app_type_cfg[len++] = cfg_info->app_type;
3758 app_type_cfg[len++] = cfg_info->sample_rate;
3759 app_type_cfg[len++] = cfg_info->bit_width;
3760 }
3761 }
3762
3763 ALOGV("%s: num_app_types: %d", __func__, num_app_types);
3764 if (num_app_types) {
3765 app_type_cfg[0] = num_app_types;
3766 mixer_ctl_set_array(ctl, app_type_cfg, len);
3767 }
3768}
3769#endif
3770
3771bool platform_stdev_is_hwmad_backend
3772(
3773 void *platform,
3774 st_device_t st_device,
3775 st_exec_mode_t exec_mode
3776)
3777{
3778 struct platform_data *my_data = (struct platform_data *)platform;
3779 sound_trigger_device_t *stdev = my_data->stdev;
3780 /*
3781 * HWMAD backend is NOT used for following usecases:
3782 * 1. SWMAD solution. ex: internal codecs
3783 * 2. BlackGhost(BG) wearable platform using WDSP but not HWMAD.
3784 * 3. WDSP: Multimic DMA backend. But single mic handset and
3785 * headset backends still use HWMAD path.
3786 * 4. ADSP: Handset backends other than single mic.
3787 * 5. ARM detection mode alone. ex: FFV.
3788 */
3789 return !stdev->disable_hwmad &&
3790 !stdev->sw_mad &&
3791 !stdev->bg_kwd &&
3792 ((exec_mode != ST_EXEC_MODE_ARM &&
3793 st_device == ST_DEVICE_HANDSET_MIC) ||
3794 (exec_mode == ST_EXEC_MODE_CPE &&
3795 st_device == ST_DEVICE_HEADSET_MIC));
3796}
3797
Zhou Songd18c6712019-06-10 11:20:10 +08003798bool platform_stdev_is_dedicated_sva_path
3799(
3800 void *platform
3801)
3802{
3803 struct platform_data *my_data = (struct platform_data *)platform;
3804 sound_trigger_device_t *stdev = my_data->stdev;
3805 audio_devices_t cur_device =
3806 platform_stdev_get_capture_device(stdev->platform);
3807
3808 if (!stdev->dedicated_sva_path ||
3809 (cur_device == AUDIO_DEVICE_IN_WIRED_HEADSET &&
3810 !stdev->dedicated_headset_path))
3811 return false;
3812
3813 return true;
3814}
3815
Quinn Male893c4742020-09-21 14:32:10 -07003816bool platform_stdev_backend_reset_allowed
3817(
3818 void *platform
3819)
3820{
3821 struct platform_data *my_data = (struct platform_data *)platform;
3822 sound_trigger_device_t *stdev = my_data->stdev;
3823
3824 if (stdev->conc_capture_supported &&
3825 stdev->tx_concurrency_active > 0 &&
3826 !platform_stdev_is_dedicated_sva_path(platform))
3827 return false;
3828 else
3829 return true;
3830}
3831
Quinn Male2e883752019-03-22 11:28:54 -07003832static int platform_stdev_get_device_sample_rate
3833(
3834 struct platform_data *my_data,
3835 st_profile_type_t profile_type
3836)
3837{
3838 sound_trigger_device_t *stdev = my_data->stdev;
3839 struct listnode *p_node, *temp_node;
3840 struct adm_cfg_info *cfg_info;;
3841 /* default device sampling rate in acdb */
Dallas Delaneyab3e0932019-10-25 13:38:03 -07003842 int sample_rate = SOUND_TRIGGER_SAMPLING_RATE_16000;
Quinn Male2e883752019-03-22 11:28:54 -07003843
3844 list_for_each_safe(p_node, temp_node, &stdev->adm_cfg_list) {
3845 cfg_info = node_to_item(p_node, struct adm_cfg_info, list_node);
3846 if (cfg_info->profile_type == profile_type) {
3847 sample_rate = cfg_info->sample_rate;
3848 break;
3849 }
3850 }
3851 ALOGD("%s: sample rate %d", __func__, sample_rate);
3852
3853 return sample_rate;
3854}
3855
3856static bool is_ec_profile(st_profile_type_t profile_type)
3857{
3858 bool ec_profile = false;
3859
3860 switch (profile_type) {
3861 case ST_PROFILE_TYPE_EC:
3862 case ST_PROFILE_TYPE_FLUENCE:
3863 case ST_PROFILE_TYPE_FLUENCE_STEREO:
3864 case ST_PROFILE_TYPE_FFECNS:
3865 ec_profile = true;
3866 break;
3867 default:
3868 break;
3869 }
3870
3871 return ec_profile;
3872}
3873
3874static int init_be_dai_name_table(struct platform_data *my_data)
3875{
3876 sound_trigger_device_t *stdev = my_data->stdev;
3877 const char *mixer_ctl_name = "Backend DAI Name Table";
3878 struct mixer_ctl *ctl;
3879 int ret, size;
3880
3881 /*
3882 * Retrieves the be_dai_name_table from kernel to enable a mapping
3883 * between sound device hw interfaces and backend IDs.
3884 * This allows HAL to specify the backend a specific calibration
3885 * is needed for.
3886 */
3887
3888 if (!strcmp(my_data->backend_dai_name, "")) {
3889 ALOGE("%s: No backend dai name set\n", __func__);
3890 ret = -EINVAL;
3891 goto error;
3892 }
3893
3894 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
3895 if (!ctl) {
3896 ALOGE("%s: Could not get ctl for mixer name %s\n",
3897 __func__, mixer_ctl_name);
3898 ret = -EINVAL;
3899 goto error;
3900 }
3901
3902 mixer_ctl_update(ctl);
3903
3904 size = mixer_ctl_get_num_values(ctl);
3905 if (size <= 0) {
3906 ALOGE("%s: Failed to get %s size %d\n",
3907 __func__, mixer_ctl_name, size);
3908 ret = -EFAULT;
3909 goto error;
3910 }
3911
3912 my_data->be_dai_name_table = (struct st_be_dai_name_table *)calloc(1, size);
3913 if (my_data->be_dai_name_table == NULL) {
3914 ALOGE("%s: Failed to allocate memory for %s\n",
3915 __func__, mixer_ctl_name);
3916 ret = -ENOMEM;
3917 goto error;
3918 }
3919
3920 ret = mixer_ctl_get_array(ctl, (void *)my_data->be_dai_name_table, size);
3921 if (ret) {
3922 ALOGE("%s: Failed to get %s, ret %d\n",
3923 __func__, mixer_ctl_name, ret);
3924 ret = -EFAULT;
3925 goto error;
3926 }
3927
3928 my_data->max_be_dai_names = size / sizeof(struct st_be_dai_name_table);
3929 ALOGV("%s: Successfully got %s, number of be dais is %d\n",
3930 __func__, mixer_ctl_name, my_data->max_be_dai_names);
3931 return 0;
3932
3933error:
3934 if (my_data->be_dai_name_table) {
3935 free((void *)my_data->be_dai_name_table);
3936 my_data->be_dai_name_table = NULL;
3937 }
3938 return ret;
3939}
3940
3941int get_st_device_backend_index
3942(
3943 struct platform_data *my_data,
3944 st_device_t st_device
3945)
3946{
3947 int i;
3948 int be_dai_id = -EINVAL;
3949
3950 if ((st_device < ST_DEVICE_MIN) || (st_device >= ST_DEVICE_MAX)) {
3951 ALOGE("%s: Invalid st_device = %d", __func__, st_device);
3952 return be_dai_id;
3953 }
3954
3955 /* Check if be dai name table was retrieved successfully */
3956 if (my_data->be_dai_name_table == NULL) {
3957 ALOGE("%s: BE DAI Name Table is not present\n", __func__);
3958 return be_dai_id;
3959 }
3960
3961 /*
3962 * Get backend ID for device specified
3963 * Note:
3964 * Backend port is currently same for all supported sound trigger devices
3965 * and hence part of platform data.
3966 * To support different backend ports, a global interface table per st_device
3967 * to store backend backend port names is to be defined and override these
3968 * values from platform info xml values if required.
3969 */
3970
3971 for (i = 0; i < my_data->max_be_dai_names; i++) {
3972 if (strcmp(my_data->backend_dai_name,
3973 my_data->be_dai_name_table[i].be_name) == 0) {
3974 be_dai_id = my_data->be_dai_name_table[i].be_id;
3975 break;
3976 }
3977 }
3978 if (i == my_data->max_be_dai_names)
3979 ALOGE("%s: no interface matching name %s\n",
3980 __func__, my_data->backend_dai_name);
3981
3982 ALOGV("%s: return backend dai id %d", __func__, be_dai_id);
3983 return be_dai_id;
3984}
3985
3986static int get_snd_card_num(struct platform_data *my_data)
3987{
3988 struct mixer *mixer = NULL;
3989 int retry_num = 0, retry_limit = 0, snd_card_num = 0;
3990 const char* snd_card_name = NULL;
3991 bool card_verifed[MAX_SND_CARD] = {false};
3992 char value[PROPERTY_VALUE_MAX];
3993 char *default_value = "10";
3994
3995 property_get("vendor.audio.snd_card.open.retries",
3996 value, default_value);
3997 retry_limit = atoi(value);
3998
3999 for (;;) {
4000 if (snd_card_num >= MAX_SND_CARD) {
4001 if (retry_num++ >= retry_limit) {
4002 ALOGE("%s: primary sound card not found", __func__);
4003 break;
4004 }
4005 snd_card_num = 0;
4006 usleep(RETRY_US);
4007 continue;
4008 }
4009 if (card_verifed[snd_card_num]) {
4010 snd_card_num++;
4011 continue;
4012 }
4013
4014 mixer = mixer_open(snd_card_num);
4015 if (!mixer) {
4016 ALOGE("%s: Unable to open the mixer card %d",
4017 __func__, snd_card_num);
4018 snd_card_num++;
4019 continue;
4020 }
4021
4022 snd_card_name = mixer_get_name(mixer);
4023 if (!strcmp(my_data->snd_card_name, "")) {
4024 if (strstr(snd_card_name, "msm") || strstr(snd_card_name, "sdm") ||
4025 strstr(snd_card_name, "apq"))
4026 break;
4027 } else {
4028 if (!strncmp(snd_card_name, my_data->snd_card_name,
4029 sizeof(my_data->snd_card_name)))
4030 break;
4031 }
4032
4033 ALOGD("%s: sound card %s is not primary, skipping",
4034 __func__, snd_card_name);
4035 mixer_close(mixer);
4036 mixer = NULL;
4037 card_verifed[snd_card_num] = true;
4038 snd_card_num++;
4039 }
4040 if (mixer)
4041 mixer_close(mixer);
4042
4043 return snd_card_num;
4044}
4045
4046void *platform_stdev_init(sound_trigger_device_t *stdev)
4047{
4048 int ret = 0, retry_num = 0, snd_card_num = 0;
4049 struct platform_data *my_data = NULL;
4050 struct mixer_ctl *ctl = NULL;
4051 const char *hwmad_ctl_name = "MAD_SEL MUX";
4052 const char *snd_card_name = NULL;
4053 const char *acdb_card_name = NULL;
4054 audio_hw_get_snd_card_num_t audio_hw_get_snd_card_num = NULL;
4055 char mixer_path_xml[MIXER_PATH_MAX_LENGTH];
4056 struct listnode *v_node, *temp_node;
4057 struct st_vendor_info* v_info;
4058 char dev_name[256];
4059
4060 ALOGI("%s: Enter", __func__);
4061 my_data = calloc(1, sizeof(struct platform_data));
4062
4063 if (!my_data || !stdev) {
4064 ALOGE("%s: ERROR. NULL param", __func__);
4065 if (my_data)
4066 free(my_data);
4067 return NULL;
4068 }
4069 my_data->stdev = stdev;
4070 list_init(&stdev->vendor_uuid_list);
4071 list_init(&stdev->adm_cfg_list);
4072 list_init(&my_data->acdb_meta_key_list);
4073
Saurav Kumar5e2957e2020-06-03 18:22:51 +05304074 platform_stdev_get_vendor_config_path(my_data->vendor_config_path,
4075 sizeof(my_data->vendor_config_path));
Quinn Male2e883752019-03-22 11:28:54 -07004076 platform_stdev_set_default_config(my_data);
Saurav Kumar5e2957e2020-06-03 18:22:51 +05304077 get_xml_file_path(my_data->xml_file_path, PLATFORM_PATH_XML,
4078 my_data->vendor_config_path);
4079 platform_parse_info(my_data, my_data->xml_file_path);
Quinn Male2e883752019-03-22 11:28:54 -07004080
4081 my_data->hwdep_fd = -1;
4082 my_data->vad_hwdep_fd = -1;
4083
4084 my_data->audio_hw_open_snd_mixer =
4085 (audio_hw_open_snd_mixer_t)dlsym(stdev->audio_hal_handle,
4086 "audio_extn_utils_open_snd_mixer");
4087 if (my_data->audio_hw_open_snd_mixer) {
4088 snd_card_num = my_data->audio_hw_open_snd_mixer(&stdev->mixer);
4089 if (snd_card_num < 0) {
4090 ALOGE("%s: ERROR. Unable to get sound card num", __func__);
4091 goto cleanup;
4092 }
4093 my_data->audio_hw_close_snd_mixer =
4094 (audio_hw_close_snd_mixer_t)dlsym(stdev->audio_hal_handle,
4095 "audio_extn_utils_close_snd_mixer");
4096 } else {
4097 ALOGE("%s: ERROR. dlsym error %s for audio_extn_utils_open_snd_mixer",
4098 __func__, dlerror());
4099 audio_hw_get_snd_card_num =
4100 (audio_hw_get_snd_card_num_t)dlsym(stdev->audio_hal_handle,
4101 "audio_extn_utils_get_snd_card_num");
4102 if (audio_hw_get_snd_card_num) {
4103 snd_card_num = audio_hw_get_snd_card_num();
4104 if (snd_card_num < 0) {
4105 ALOGE("%s: ERROR. Unable to get sound card num", __func__);
4106 goto cleanup;
4107 }
4108 } else {
4109 ALOGE("%s: ERROR. dlsym error %s for audio_extn_utils_get_snd_card_num",
4110 __func__, dlerror());
4111 snd_card_num = get_snd_card_num(my_data);
4112 if (snd_card_num < 0) {
4113 ALOGE("%s: ERROR. Unable to get sound card num", __func__);
4114 goto cleanup;
4115 }
4116 }
4117 stdev->mixer = mixer_open(snd_card_num);
4118 while (!stdev->mixer && retry_num < MIXER_OPEN_MAX_NUM_RETRY) {
4119 usleep(RETRY_US);
4120 stdev->mixer = mixer_open(snd_card_num);
4121 retry_num++;
4122 }
4123 }
4124
4125 if (!stdev->mixer) {
4126 ALOGE("%s: ERROR. Unable to open the mixer, aborting", __func__);
4127 goto cleanup;
4128 }
4129
4130 snd_card_name = mixer_get_name(stdev->mixer);
4131
Saurav Kumar5e2957e2020-06-03 18:22:51 +05304132 query_stdev_platform(my_data, snd_card_name, mixer_path_xml);
Quinn Male2e883752019-03-22 11:28:54 -07004133 stdev->audio_route = audio_route_init(snd_card_num, mixer_path_xml);
4134 if (!stdev->audio_route) {
4135 ALOGE("%s: ERROR. Failed to init audio route controls, aborting.",
4136 __func__);
4137 goto cleanup;
4138 }
4139 stdev->snd_card = snd_card_num;
4140
4141 ret = load_acdb(my_data);
4142 if (ret)
4143 goto cleanup;
4144
4145 if (my_data->audio_hw_acdb_init_v2) {
4146 ret = my_data->audio_hw_acdb_init_v2(stdev->mixer);
4147 if (ret) {
4148 ALOGE("%s: ERROR. audio_hw_acdb_init_v2 failed status %d", __func__, ret);
Vikram Pandurangad2f8fa02019-10-03 16:32:57 -07004149 my_data->acdb_deinit();
Quinn Male2e883752019-03-22 11:28:54 -07004150 goto cleanup;
4151 }
4152 } else if (my_data->audio_hw_acdb_init) {
4153 ret = my_data->audio_hw_acdb_init(snd_card_num);
4154 if (ret) {
4155 ALOGE("%s: ERROR. audio_hw_acdb_init failed status %d", __func__, ret);
Vikram Pandurangad2f8fa02019-10-03 16:32:57 -07004156 my_data->acdb_deinit();
Quinn Male2e883752019-03-22 11:28:54 -07004157 goto cleanup;
4158 }
4159 } else {
4160 acdb_card_name = get_snd_card_name_for_acdb_loader(snd_card_name);
4161 ALOGI("%s: acdb_init: %s", __func__, acdb_card_name);
4162 ret = my_data->acdb_init(acdb_card_name, NULL, 0);
4163 if (acdb_card_name) {
4164 free((void*)acdb_card_name);
4165 acdb_card_name = NULL;
4166 }
4167 if (ret) {
4168 ALOGE("%s: ERROR. acdb_loader_init_v2 failed status %d", __func__, ret);
4169 goto cleanup;
4170 }
4171 }
4172
4173 ctl = mixer_get_ctl_by_name(stdev->mixer, hwmad_ctl_name);
4174 if (!ctl) {
4175 ALOGV("%s: Could not get ctl for MAD_SEL MUX, disabling hwmad",
4176 __func__);
4177 stdev->disable_hwmad = true;
4178 }
4179
4180 if (!stdev->bg_kwd && !stdev->sw_mad && !stdev->disable_hwmad) {
4181 snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
4182 snd_card_num, WCD9XXX_CODEC_HWDEP_NODE);
4183 ALOGD("%s: Opening device %s", __func__, dev_name);
4184 my_data->hwdep_fd = open(dev_name, O_WRONLY);
4185 if (my_data->hwdep_fd < 0) {
4186 ALOGE("%s: cannot open device '%s'", __func__, dev_name);
4187 my_data->acdb_deinit();
4188 goto cleanup;
4189 }
4190 }
4191
4192 my_data->prev_acdb_id = -1;
4193
4194 if (Q6AFE_HWDEP_NODE >= 0) {
4195 snprintf(dev_name, sizeof(dev_name), "/dev/snd/hwC%uD%u",
4196 snd_card_num, Q6AFE_HWDEP_NODE);
4197
4198 ALOGD("%s Opening device %s for vad hwdep config", __func__, dev_name);
4199 my_data->vad_hwdep_fd = open(dev_name, O_WRONLY);
4200
4201 /*
4202 * VAD support might not be available on some platform,
4203 * hence not treating as fatal error.
4204 */
4205 if (my_data->vad_hwdep_fd < 0)
4206 ALOGD("%s: cannot open device '%s', error:%s",
4207 __func__, dev_name, strerror(errno));
4208 }
4209
4210 ret = get_codec_version(my_data, snd_card_name, snd_card_num);
4211 if (ret)
4212 goto cleanup;
4213
4214 list_for_each(v_node, &stdev->vendor_uuid_list) {
4215 v_info = node_to_item(v_node, struct st_vendor_info, list_node);
4216 if (!memcmp(&v_info->uuid, &qcva_uuid, sizeof(sound_trigger_uuid_t))) {
4217 v_info->is_qcva_uuid = true;
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -07004218 if (!stdev->smlib_handle && v_info->merge_fs_soundmodels) {
4219 ret = load_soundmodel_lib(stdev);
4220 if (ret) {
4221 v_info->merge_fs_soundmodels = false;
4222 ret = 0;
4223 }
4224 }
Quinn Male2e883752019-03-22 11:28:54 -07004225 } else if (!memcmp(&v_info->uuid, &qcmd_uuid, sizeof(sound_trigger_uuid_t))) {
4226 v_info->is_qcmd_uuid = true;
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -07004227 v_info->merge_fs_soundmodels = false;
Quinn Male2e883752019-03-22 11:28:54 -07004228 } else {
Venkatesh Mangalappalie4f17532019-06-04 16:30:28 -07004229 v_info->merge_fs_soundmodels = false;
Quinn Male2e883752019-03-22 11:28:54 -07004230 ALOGV("%s: ISV uuid present", __func__);
4231 }
Quinn Male2e883752019-03-22 11:28:54 -07004232 if (!stdev->mulaw_dec_lib_handle &&
4233 (v_info->kw_capture_format & MULAW)) {
4234 ret = load_mulaw_decoder(stdev);
4235 if (ret)
4236 goto cleanup;
4237 }
4238 ALOGV("%s: vendor config: kcf=%d, ktm=%d, ckw=%d, cu=%d, akw=%d, au=%d",
4239 __func__, v_info->kw_capture_format, v_info->kw_transfer_mode,
4240 v_info->avail_cpe_phrases, v_info->avail_cpe_users,
4241 v_info->avail_ape_phrases, v_info->avail_ape_users);
4242 }
4243
4244 /* gcs init must happen after acdb inititlization as gcs client has
4245 dependency on acdb inititialization */
4246 if (stdev->is_gcs) {
4247 ret = st_hw_gcs_init();
4248 if (ret)
4249 goto cleanup;
4250 }
4251 ret = st_hw_pcm_init();
4252 if (ret)
4253 goto cleanup_2;
4254
4255 init_codec_backend_cfg_mixer_ctl(my_data);
4256
4257 platform_stdev_send_adm_app_type_cfg(my_data);
4258
4259 init_be_dai_name_table(my_data);
4260
Quinn Male3d7d9d42019-05-20 13:35:01 -07004261 platform_stdev_reset_backend_cfg(my_data);
4262
Quinn Male2e883752019-03-22 11:28:54 -07004263 return my_data;
4264
4265cleanup_2:
4266 if (stdev->is_gcs)
4267 st_hw_gcs_deinit();
4268
4269cleanup:
4270 if (stdev->mulaw_dec_lib_handle)
4271 dlclose(stdev->mulaw_dec_lib_handle);
4272
Quinn Male2e883752019-03-22 11:28:54 -07004273 if (my_data->acdb_handle)
4274 dlclose(my_data->acdb_handle);
4275
4276 if (stdev->smlib_handle)
4277 dlclose(stdev->smlib_handle);
4278
4279 if (stdev->audio_route)
4280 audio_route_free(stdev->audio_route);
4281
4282 if (stdev->mixer) {
4283 if (my_data->audio_hw_close_snd_mixer)
4284 my_data->audio_hw_close_snd_mixer(stdev->mixer);
4285 else
4286 mixer_close(stdev->mixer);
4287 }
4288 list_for_each_safe(v_node, temp_node, &stdev->vendor_uuid_list) {
4289 v_info = node_to_item(v_node, struct st_vendor_info, list_node);
Quinn Male2e883752019-03-22 11:28:54 -07004290 list_remove(v_node);
4291 free(v_info);
4292 }
4293 if (my_data->hwdep_fd >= 0) {
4294 close(my_data->hwdep_fd);
4295 }
4296 if (my_data->vad_hwdep_fd >= 0) {
4297 close(my_data->vad_hwdep_fd);
4298 }
4299 if (my_data->kvpairs)
4300 str_parms_destroy(my_data->kvpairs);
4301
4302 free(my_data);
4303 return NULL;
4304}
4305
4306void platform_stdev_deinit(void *platform)
4307{
4308 struct platform_data *my_data = (struct platform_data *)platform;
Quinn Male58749452020-03-26 17:14:56 -07004309 struct listnode *v_node = NULL, *temp_node = NULL, *gcs_node = NULL;
4310 struct listnode *temp_node1 = NULL, *temp_node2 = NULL, *module_node = NULL;
4311 struct listnode *arm_node = NULL, *lsm_node = NULL, *mk_node = NULL;
4312 struct st_vendor_info* v_info = NULL;
4313 struct st_gcs_params *gcs_info = NULL;
4314 struct meta_key_list *key_info = NULL;
4315 struct st_arm_ss_params *arm_info = NULL;
4316 struct st_lsm_ss_params *lsm_ss_info = NULL;
4317 struct st_lsm_params *lsm_info = NULL;
4318 struct st_module_params *module_info = NULL;
Quinn Male2e883752019-03-22 11:28:54 -07004319
4320 ALOGI("%s: Enter", __func__);
4321 if (my_data) {
4322 list_for_each_safe(v_node, temp_node, &my_data->stdev->vendor_uuid_list) {
4323 v_info = node_to_item(v_node, struct st_vendor_info, list_node);
4324
4325 /* remove and free the param structs */
4326 list_for_each_safe(arm_node, temp_node1, &v_info->arm_ss_usecase_list) {
4327 arm_info = node_to_item(arm_node, struct st_arm_ss_params, list_node);
4328 list_remove(arm_node);
4329 free(arm_info);
4330 }
4331 list_for_each_safe(lsm_node, temp_node1, &v_info->lsm_ss_usecase_list) {
4332 lsm_ss_info = node_to_item(lsm_node, struct st_lsm_ss_params, list_node);
4333 list_remove(lsm_node);
4334 free(lsm_ss_info);
4335 }
4336 list_for_each_safe(gcs_node, temp_node1, &v_info->gcs_usecase_list) {
4337 gcs_info = node_to_item(gcs_node, struct st_gcs_params, list_node);
4338 list_remove(gcs_node);
4339 free(gcs_info);
4340 }
4341 list_for_each_safe(lsm_node, temp_node1, &v_info->lsm_usecase_list) {
4342 lsm_info = node_to_item(lsm_node, struct st_lsm_params, list_node);
4343 list_remove(lsm_node);
Quinn Male58749452020-03-26 17:14:56 -07004344 list_for_each_safe(module_node, temp_node2,
4345 &lsm_info->module_params_list) {
4346 module_info = node_to_item(module_node, struct st_module_params,
4347 list_node);
4348 list_remove(module_node);
4349 free(module_info);
4350 }
Quinn Male2e883752019-03-22 11:28:54 -07004351 free(lsm_info);
4352 }
4353
Quinn Male2e883752019-03-22 11:28:54 -07004354 list_remove(v_node);
4355 free(v_info);
4356 }
4357
4358 list_for_each_safe(mk_node, temp_node, &my_data->acdb_meta_key_list) {
4359 key_info = node_to_item(mk_node, struct meta_key_list, list);
4360 list_remove(mk_node);
4361 free(key_info);
4362 }
4363
4364 my_data->acdb_deinit();
4365 dlclose(my_data->acdb_handle);
4366 if (my_data->stdev->smlib_handle)
4367 dlclose(my_data->stdev->smlib_handle);
Quinn Male2e883752019-03-22 11:28:54 -07004368 if (my_data->stdev->mulaw_dec_lib_handle)
4369 dlclose(my_data->stdev->mulaw_dec_lib_handle);
4370 audio_route_free(my_data->stdev->audio_route);
4371 if (my_data->audio_hw_close_snd_mixer)
4372 my_data->audio_hw_close_snd_mixer(my_data->stdev->mixer);
4373 else
4374 mixer_close(my_data->stdev->mixer);
4375 if (my_data->hwdep_fd >= 0) {
4376 close(my_data->hwdep_fd);
4377 my_data->hwdep_fd = -1;
4378 }
4379 if (my_data->vad_hwdep_fd >= 0) {
4380 close(my_data->vad_hwdep_fd);
4381 my_data->vad_hwdep_fd = -1;
4382 }
4383 if (my_data->kvpairs)
4384 str_parms_destroy(my_data->kvpairs);
4385
4386 if (my_data->stdev->is_gcs) {
4387 st_hw_gcs_deinit();
4388 }
4389 st_hw_pcm_deinit();
4390
4391 if (my_data->be_dai_name_table)
4392 free((void *)my_data->be_dai_name_table);
4393
4394 free(my_data);
4395 }
4396}
4397
4398struct st_vendor_info* platform_stdev_get_vendor_info
4399(
4400 void *platform,
4401 sound_trigger_uuid_t *vendor_uuid
4402)
4403{
4404 struct listnode *v_node;
4405 struct st_vendor_info *v_info = NULL, *vendor_info = NULL;
4406 struct platform_data *my_data;
4407 sound_trigger_device_t *stdev;
4408
4409 if (!platform || !vendor_uuid) {
4410 ALOGE("%s: NULL inputs", __func__);
4411 return NULL;
4412 }
4413 my_data = (struct platform_data *)platform;
4414 if (!my_data->stdev) {
4415 ALOGE("%s: platform stdev data is NULL", __func__);
4416 return NULL;
4417 }
4418 stdev = my_data->stdev;
4419
4420 list_for_each(v_node, &stdev->vendor_uuid_list) {
4421 v_info = node_to_item(v_node, struct st_vendor_info, list_node);
4422 if (!memcmp(&v_info->uuid, vendor_uuid, sizeof(sound_trigger_uuid_t))) {
4423 ALOGV("%s: Matched uuid", __func__);
4424 vendor_info = v_info;
4425 break;
4426 }
4427 }
4428
4429 return vendor_info;
4430}
4431
4432static void check_and_append_device_name
4433(
4434 struct platform_data *my_data,
4435 char *device_name
4436)
4437{
4438 int alt_mixer_control_value = 0;
4439 char device_name_suffix[10];
4440
4441 /* Alternate configuration is supported for quad mic currently.
4442 * Do not add suffix if bad mic channel index is not set.
4443 */
4444 if ((my_data->codec_backend_cfg.channel_count != SOUND_TRIGGER_CHANNEL_MODE_QUAD) ||
4445 (my_data->bad_mic_channel_index == 0)) {
4446 ALOGV("%s: No requirement to add suffix to device name", __func__);
4447 return;
4448 }
4449
4450 switch (my_data->bad_mic_channel_index) {
4451 case BAD_MIC_CH_INDEX_0:
4452 alt_mixer_control_value = 1;
4453 break;
4454 case BAD_MIC_CH_INDEX_1:
4455 alt_mixer_control_value = 2;
4456 break;
4457 case BAD_MIC_CH_INDEX_2:
4458 alt_mixer_control_value = 3;
4459 break;
4460 case BAD_MIC_CH_INDEX_3:
4461 default:
4462 break;
4463 }
4464
4465 if (alt_mixer_control_value) {
4466 snprintf(device_name_suffix, sizeof(device_name_suffix), "-alt%d",
4467 alt_mixer_control_value);
4468 strlcat(device_name, device_name_suffix, DEVICE_NAME_MAX_SIZE);
4469 ALOGV("%s: appended device name %s", __func__, device_name);
4470 }
4471}
4472
4473int platform_stdev_get_device_name
4474(
4475 void *platform,
4476 st_exec_mode_t exec_mode,
4477 st_device_t st_device,
4478 char *device_name
4479)
4480{
4481 struct platform_data *my_data = (struct platform_data *)platform;
4482
4483 if ((st_device >= ST_DEVICE_MIN && st_device < ST_DEVICE_MAX) &&
4484 (exec_mode > ST_EXEC_MODE_NONE && exec_mode < ST_EXEC_MODE_MAX)) {
4485 strlcpy(device_name, st_device_table[exec_mode][st_device], DEVICE_NAME_MAX_SIZE);
4486
4487 if ((strstr(my_data->codec_version, "WCD9335_1_0") ||
4488 strstr(my_data->codec_version, "WCD9335_1_1")) &&
4489 (exec_mode == ST_EXEC_MODE_CPE)) {
4490 strlcat(device_name, " low-speed-intf", DEVICE_NAME_MAX_SIZE);
4491 } else if (exec_mode == ST_EXEC_MODE_ADSP) {
4492 check_and_append_device_name(my_data, device_name);
4493 }
4494 } else {
4495 strlcpy(device_name, "", DEVICE_NAME_MAX_SIZE);
4496 return -EINVAL;
4497 }
4498 return 0;
4499}
4500
4501static int get_st_device
4502(
4503 void *platform,
4504 struct st_vendor_info* v_info,
4505 audio_devices_t device,
4506 enum st_exec_mode exec_mode,
4507 bool for_cal
4508)
4509{
4510 struct platform_data *my_data = (struct platform_data *)platform;
4511 st_device_t st_device = ST_DEVICE_NONE;
4512 int channel_count = 0;
4513
4514 switch (device) {
4515 case AUDIO_DEVICE_IN_WIRED_HEADSET:
4516 if ((ST_EXEC_MODE_CPE == exec_mode) ||
4517 (ST_EXEC_MODE_ADSP == exec_mode)) {
Quinn Male1c764fd2019-10-18 13:29:40 -07004518 if (my_data->stdev->lpi_enable)
Quinn Male3d7d9d42019-05-20 13:35:01 -07004519 st_device = ST_DEVICE_HEADSET_MIC_LPI;
4520 else
4521 st_device = ST_DEVICE_HEADSET_MIC;
Quinn Male2e883752019-03-22 11:28:54 -07004522 break;
4523 }
4524 case AUDIO_DEVICE_IN_BUILTIN_MIC:
4525 if (ST_EXEC_MODE_CPE == exec_mode) {
4526 channel_count =
4527 get_channel_cnt_from_fluence_type(v_info->wdsp_fluence_type);
4528
4529 if (v_info->sample_rate == SOUND_TRIGGER_SAMPLING_RATE_48000)
4530 st_device = ST_DEVICE_HANDSET_MIC_ECPP;
4531 else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_QUAD)
4532 st_device = ST_DEVICE_HANDSET_QMIC;
4533 else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_TRI)
4534 st_device = ST_DEVICE_HANDSET_TMIC;
4535 else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_STEREO)
4536 st_device = ST_DEVICE_HANDSET_DMIC;
4537 else
4538 st_device = ST_DEVICE_HANDSET_MIC;
4539 } else {
4540 /* ADSP/ARM mode */
4541 /* Though the same highest backend device is used for all concurrent
4542 * VA sessions, the calibration must be retrieved from
4543 * corresponding acdb device id the VA engine originally
4544 * configured for. For ex: SVA with QMIC acdb_id Vs Hotword
4545 * with DMIC acdb_id, where the calibration is kept in the
4546 * corresponding acdb_id.
4547 */
4548 if (for_cal) {
4549 if ((v_info->profile_type == ST_PROFILE_TYPE_FLUENCE) ||
4550 (v_info->profile_type == ST_PROFILE_TYPE_FLUENCE_STEREO) ||
4551 (v_info->profile_type == ST_PROFILE_TYPE_FFECNS)) {
4552 channel_count =
4553 get_channel_cnt_from_fluence_type(v_info->fluence_type);
4554 } else {
4555 channel_count = v_info->in_channels;
4556 }
4557 } else {
4558 channel_count = my_data->codec_backend_cfg.channel_count;
4559 }
4560 if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_OCT) {
Quinn Male23026702019-07-19 10:51:16 -07004561 if (my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07004562 st_device = ST_DEVICE_HANDSET_8MIC_LPI;
4563 else
4564 st_device = ST_DEVICE_HANDSET_8MIC;
4565 } else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_HEX) {
Quinn Male23026702019-07-19 10:51:16 -07004566 if (my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07004567 st_device = ST_DEVICE_HANDSET_6MIC_LPI;
4568 else
4569 st_device = ST_DEVICE_HANDSET_6MIC;
4570 } else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_QUAD) {
Quinn Male23026702019-07-19 10:51:16 -07004571 if (my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07004572 st_device = ST_DEVICE_HANDSET_QMIC_LPI;
4573 else
4574 st_device = ST_DEVICE_HANDSET_QMIC;
4575 } else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_TRI) {
Quinn Male23026702019-07-19 10:51:16 -07004576 if (my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07004577 st_device = ST_DEVICE_HANDSET_TMIC_LPI;
4578 else
4579 st_device = ST_DEVICE_HANDSET_TMIC;
4580 } else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_STEREO) {
Quinn Male23026702019-07-19 10:51:16 -07004581 if (my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07004582 st_device = ST_DEVICE_HANDSET_DMIC_LPI;
4583 else
4584 st_device = ST_DEVICE_HANDSET_DMIC;
4585 } else if (channel_count == SOUND_TRIGGER_CHANNEL_MODE_MONO) {
Quinn Male1c764fd2019-10-18 13:29:40 -07004586 if (my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07004587 st_device = ST_DEVICE_HANDSET_MIC;
Quinn Male1c764fd2019-10-18 13:29:40 -07004588 else
4589 st_device = ST_DEVICE_HANDSET_MIC_PP;
Quinn Male2e883752019-03-22 11:28:54 -07004590 } else {
4591 ALOGE("%s: Invalid channel count %d", __func__, channel_count);
4592 }
4593 }
4594 break;
4595 default:
4596 ALOGD("%s: returing handset mic device", __func__);
4597 st_device = ST_DEVICE_HANDSET_MIC;
4598 break;
4599 }
4600
4601 ALOGV("%s: sample_rate=%d st_device %d", __func__,
4602 v_info->sample_rate, st_device);
4603 return st_device;
4604}
4605
4606int platform_stdev_get_device
4607(
4608 void *platform,
4609 struct st_vendor_info* v_info,
4610 audio_devices_t device,
4611 enum st_exec_mode exec_mode
4612)
4613{
4614 return get_st_device(platform, v_info, device, exec_mode, false);
4615}
4616
Zhou Songba4ac3b2021-03-04 00:30:00 +08004617int platform_stdev_get_device_for_cal
4618(
4619 void *platform,
4620 struct st_vendor_info* v_info,
4621 audio_devices_t device,
4622 enum st_exec_mode exec_mode
4623)
4624{
4625 return get_st_device(platform, v_info, device, exec_mode, true);
4626}
4627
Quinn Male2e883752019-03-22 11:28:54 -07004628audio_devices_t platform_stdev_get_capture_device
4629(
4630 void *platform
4631)
4632{
4633 struct platform_data *my_data = (struct platform_data *)platform;
4634 sound_trigger_device_t *stdev = my_data->stdev;
4635 audio_devices_t device = AUDIO_DEVICE_NONE;
Quinn Maled409e412019-12-09 14:50:48 -08004636 struct audio_device_info *item = NULL;
4637 struct listnode *node = NULL;
Quinn Male2e883752019-03-22 11:28:54 -07004638
Quinn Maled409e412019-12-09 14:50:48 -08004639 if (platform_stdev_compare_device_type(&stdev->available_devices,
4640 AUDIO_DEVICE_IN_WIRED_HEADSET)) {
Quinn Male2e883752019-03-22 11:28:54 -07004641 device = AUDIO_DEVICE_IN_WIRED_HEADSET;
Quinn Maled409e412019-12-09 14:50:48 -08004642 } else if (platform_stdev_compare_device_type(&stdev->available_devices,
4643 AUDIO_DEVICE_IN_BUILTIN_MIC)) {
Quinn Male2e883752019-03-22 11:28:54 -07004644 device = AUDIO_DEVICE_IN_BUILTIN_MIC;
Quinn Maled409e412019-12-09 14:50:48 -08004645 }
Quinn Male2e883752019-03-22 11:28:54 -07004646
Quinn Maled409e412019-12-09 14:50:48 -08004647 ALOGD("%s: Device = 0x%x", __func__, device);
4648 list_for_each (node, &stdev->available_devices) {
4649 item = node_to_item(node, struct audio_device_info, list);
4650 ALOGD("%s: Available device = 0x%x", __func__, item->type);
4651 }
4652
Quinn Male2e883752019-03-22 11:28:54 -07004653 return device;
4654}
4655
Quinn Male2e883752019-03-22 11:28:54 -07004656static int get_backend_index_from_name
4657(
4658 struct platform_data *my_data,
4659 const char *dai_name
4660)
4661{
4662 int backend_id = -1, i;
4663
4664 if ((my_data->be_dai_name_table != NULL) &&
4665 (dai_name[0] != '\0')) {
4666 for (i = 0; i < my_data->max_be_dai_names; i++) {
4667 if (!strcmp(dai_name, my_data->be_dai_name_table[i].be_name)) {
4668 backend_id = my_data->be_dai_name_table[i].be_id;
4669 break;
4670 }
4671 }
4672 }
4673 return backend_id;
4674}
4675
4676void platform_stdev_reset_backend_cfg(void *platform)
4677{
4678 struct platform_data *my_data = (struct platform_data *)platform;
4679 sound_trigger_device_t *stdev = my_data->stdev;
4680 struct mixer_ctl *ctl;
4681 int backend_id;
4682 int vad_cfg[3] = {0};
4683
4684 my_data->codec_backend_cfg.sample_rate = SOUND_TRIGGER_SAMPLING_RATE_48000;
4685 my_data->codec_backend_cfg.format = PCM_FORMAT_S16_LE;
4686 my_data->codec_backend_cfg.channel_count = SOUND_TRIGGER_CHANNEL_MODE_MONO;
4687
4688 my_data->codec_backend_cfg.lpi_enable = false;
4689 ctl = mixer_get_ctl_by_name(stdev->mixer,
4690 my_data->codec_backend_cfg.lpi_mixer_ctl);
Quinn Male24daf422019-05-29 16:12:55 -07004691 if (!ctl) {
Quinn Male2e883752019-03-22 11:28:54 -07004692 ALOGV("%s: Could not get ctl for mixer command - %s",
Quinn Male24daf422019-05-29 16:12:55 -07004693 __func__, my_data->codec_backend_cfg.lpi_mixer_ctl);
4694 } else {
4695 ALOGD("%s: Setting %s to false",
4696 __func__, my_data->codec_backend_cfg.lpi_mixer_ctl);
Quinn Male2e883752019-03-22 11:28:54 -07004697 mixer_ctl_set_value(ctl, 0, (int)false);
Quinn Male24daf422019-05-29 16:12:55 -07004698 }
Quinn Male2e883752019-03-22 11:28:54 -07004699
4700 my_data->codec_backend_cfg.vad_enable = false;
4701 my_data->codec_backend_cfg.vad_preroll = 0;
4702 backend_id = get_backend_index_from_name(my_data, my_data->backend_dai_name);
4703 if (backend_id >= 0) {
4704 ctl = mixer_get_ctl_by_name(stdev->mixer,
4705 my_data->codec_backend_cfg.vad_mixer_ctl);
4706 if (ctl) {
4707 vad_cfg[0] = my_data->codec_backend_cfg.vad_enable;
4708 vad_cfg[1] = my_data->codec_backend_cfg.vad_preroll;
4709 vad_cfg[2] = backend_id;
4710 mixer_ctl_set_array(ctl, vad_cfg, sizeof(vad_cfg)/sizeof(vad_cfg[0]));
4711 } else {
4712 ALOGV("%s: Could not get ctl for mixer command - %s",
4713 __func__, my_data->codec_backend_cfg.vad_mixer_ctl);
4714 }
4715 } else {
4716 ALOGE("%s: Could not get valid backend id(%d) to reset vad controls",
4717 __func__, backend_id);
4718 }
4719}
4720
4721bool platform_get_lpi_mode(void *platform)
4722{
4723 struct platform_data *my_data = (struct platform_data *) platform;
4724
4725 return my_data->codec_backend_cfg.lpi_enable;
4726}
4727
Quinn Maledd105082019-11-07 18:36:02 -08004728int platform_get_lpi_st_device(int st_device)
4729{
4730 int lpi_device = st_device;
4731
4732 switch (st_device) {
4733 case ST_DEVICE_HANDSET_DMIC:
4734 lpi_device = ST_DEVICE_HANDSET_DMIC_LPI;
4735 break;
4736 case ST_DEVICE_HANDSET_TMIC:
4737 lpi_device = ST_DEVICE_HANDSET_TMIC_LPI;
4738 break;
4739 case ST_DEVICE_HANDSET_QMIC:
4740 lpi_device = ST_DEVICE_HANDSET_QMIC_LPI;
4741 break;
4742 case ST_DEVICE_HEADSET_MIC:
4743 lpi_device = ST_DEVICE_HEADSET_MIC_LPI;
4744 break;
4745 default:
4746 ALOGV("%s: No need to convert device %d", __func__, st_device);
4747 }
4748
4749 return lpi_device;
4750}
4751
Quinn Male2e883752019-03-22 11:28:54 -07004752#ifdef SNDRV_IOCTL_HWDEP_VAD_CAL_TYPE
4753static int platform_stdev_send_hwvad_cal
4754(
4755 struct platform_data *my_data,
4756 int acdb_id
4757)
4758{
4759 int ret = 0;
4760 struct q6afecal_ioctl_buffer ioctl_buffer;
4761 struct hwdep_cal_param_data calib;
4762 char dev_name[50] = {0};
4763 int hwdep_fd = my_data->vad_hwdep_fd;
4764
4765 if (hwdep_fd < 0) {
4766 ALOGE("%s: invalid fd for vad device '%s', cannot send cal", __func__, dev_name);
4767 return -1;
4768 }
4769
4770 ATRACE_BEGIN("sthal: send_hwvad_cal");
4771 calib.acdb_id = acdb_id;
4772 calib.get_size = 1;
4773 ret = my_data->acdb_get_cal("vad_cal", sizeof(struct hwdep_cal_param_data),
4774 &calib);
4775 if (ret < 0) {
4776 ATRACE_END();
4777 ALOGE("%s: get_calibration to get size failed", __func__);
4778 return ret;
4779 }
4780
4781 calib.get_size = 0;
4782 calib.buff = malloc(calib.buff_size);
4783 if (!calib.buff) {
4784 ATRACE_END();
4785 ALOGE("%s: malloc calib of buff size %d failed",
4786 __func__, calib.buff_size);
4787 return -ENOMEM;
4788 }
4789
4790 ret = my_data->acdb_get_cal("vad_cal", sizeof(struct hwdep_cal_param_data),
4791 &calib);
4792 if (ret < 0) {
4793 ATRACE_END();
4794 ALOGE("%s: get_calibration to get size failed", __func__);
4795 free(calib.buff);
4796 return ret;
4797 }
4798
4799 ioctl_buffer.buffer = calib.buff;
4800 ioctl_buffer.size = calib.data_size;
4801 ioctl_buffer.cal_type = Q6AFE_VAD_CORE_CAL;
4802 ret = ioctl(hwdep_fd, SNDRV_IOCTL_HWDEP_VAD_CAL_TYPE, &ioctl_buffer);
4803 if (ret < 0) {
4804 ALOGE("%s: failed to call ioctl err=%d",__func__, errno);
4805 } else {
4806 ALOGD("%s hwvad cal sent for acdb_id (%d)", __func__, acdb_id);
4807 }
4808
4809 free(calib.buff);
4810 ATRACE_END();
4811 return ret;
4812}
4813#else
4814static int platform_stdev_send_hwvad_cal
4815(
4816 struct platform_data *my_data __unused,
4817 int acdb_id __unused
4818)
4819{
4820 return -ENOSYS;
4821}
4822#endif
4823
4824static int platform_stdev_send_hwmad_cal
4825(
4826 struct platform_data *my_data,
4827 int acdb_id
4828)
4829{
4830 int ret = 0;
4831 struct wcdcal_ioctl_buffer codec_buffer;
4832 struct hwdep_cal_param_data calib;
4833 int hwdep_fd = my_data->hwdep_fd;
4834
4835 if (my_data->prev_acdb_id == acdb_id) {
4836 ALOGD("%s: previous acdb_id %d matches new acdb_id %d return",
4837 __func__, my_data->prev_acdb_id, acdb_id);
4838 return 0;
4839 }
4840
4841 ATRACE_BEGIN("sthal: send_hwmad_cal");
4842 calib.acdb_id = acdb_id;
4843 calib.get_size = 1;
4844 ret = my_data->acdb_get_cal("mad_cal", sizeof(struct hwdep_cal_param_data),
4845 &calib);
4846 if (ret < 0) {
4847 ATRACE_END();
4848 ALOGE("%s: get_calibration to get size failed", __func__);
4849 return ret;
4850 }
4851
4852 calib.get_size = 0;
4853 calib.buff = malloc(calib.buff_size);
4854 if (!calib.buff) {
4855 ATRACE_END();
4856 ALOGE("%s: malloc calib of buff size %d failed",
4857 __func__, calib.buff_size);
4858 return -ENOMEM;
4859 }
4860
4861 ret = my_data->acdb_get_cal("mad_cal", sizeof(struct hwdep_cal_param_data),
4862 &calib);
4863 if (ret < 0) {
4864 ATRACE_END();
4865 ALOGE("%s: get_calibration to get size failed", __func__);
4866 free(calib.buff);
4867 return ret;
4868 }
4869
4870 codec_buffer.buffer = calib.buff;
4871 codec_buffer.size = calib.data_size;
4872 codec_buffer.cal_type = WCD9XXX_MAD_CAL;
4873 ret = ioctl(hwdep_fd, SNDRV_CTL_IOCTL_HWDEP_CAL_TYPE, &codec_buffer);
4874 if (ret < 0) {
4875 ALOGE("%s: failed to call ioctl err=%d",__func__, errno);
4876 } else {
4877 my_data->prev_acdb_id = acdb_id;
4878 ALOGD("%s hwmad cal sent for acdb_id (%d)", __func__, acdb_id);
4879 }
4880
4881 free(calib.buff);
4882 ATRACE_END();
4883 return ret;
4884}
4885
4886int platform_stdev_get_acdb_id
4887(
4888 st_device_t st_device,
4889 st_exec_mode_t exec_mode
4890)
4891{
4892 int acdb_id;
4893
4894 acdb_id = acdb_device_table[exec_mode][st_device];
4895 if (acdb_id < 0) {
4896 ALOGE("%s: Could not find acdb id for device(%d)",
4897 __func__, st_device);
4898 return -EINVAL;
4899 }
4900
4901 return acdb_id;
4902}
4903
4904int platform_stdev_send_common_topology(void *platform)
4905{
4906 struct platform_data *my_data = (struct platform_data*)platform;
4907
4908 return my_data->acdb_send_common_custom_topology();
4909}
4910
4911int platform_stdev_send_calibration
4912(
4913 void *platform,
4914 audio_devices_t device,
4915 st_exec_mode_t exec_mode,
4916 struct st_vendor_info *v_info,
4917 int app_id,
4918 bool use_topology,
4919 st_cal_type type
4920)
4921{
4922 return platform_stdev_send_calibration_v2(platform, device, exec_mode,
4923 v_info, app_id, use_topology,
4924 type, ST_CAL_INDEX_0);
4925}
4926
4927int platform_stdev_send_calibration_v2
4928(
4929 void *platform,
4930 audio_devices_t device,
4931 st_exec_mode_t exec_mode,
4932 struct st_vendor_info *v_info,
4933 int app_id,
4934 bool use_topology,
4935 st_cal_type type,
4936 int cal_index
4937)
4938{
4939 struct platform_data *my_data = (struct platform_data *)platform;
4940 int acdb_id;
4941 st_device_t st_device;
4942 int status = 0;
4943 int hw_type, cal_mode, sample_rate;
4944
4945 st_device = get_st_device(my_data, v_info, device, exec_mode, true);
4946 if (st_device == ST_DEVICE_NONE) {
4947 ALOGE("%s: Could not find valid device",__func__);
4948 return -EINVAL;
4949 }
4950
4951 acdb_id = acdb_device_table[exec_mode][st_device];
4952 if (acdb_id < 0) {
4953 ALOGE("%s: Could not find acdb id for device(%d)",
4954 __func__, st_device);
4955 return -EINVAL;
4956 }
4957 hw_type = (exec_mode == ST_EXEC_MODE_CPE) ? 0 : 1;
4958
4959 switch (type) {
4960 case ST_SESSION_CAL:
4961 if (my_data->acdb_send_lsm_cal_v1) {
4962 ALOGD("%s: sending lsm cal for device(%d) acdb_id(%d) index(%d) app_id(%d)",
4963 __func__, st_device, acdb_id, cal_index, app_id);
4964 /* ACDB modes: topology=1, non-topology=0 */
4965 ATRACE_BEGIN("sthal: acdb_send_lsm_cal_v1");
4966 status = my_data->acdb_send_lsm_cal_v1(acdb_id, app_id,
4967 (use_topology == true),
4968 hw_type, cal_index);
4969 ATRACE_END();
4970 } else {
4971 if (cal_index != ST_CAL_INDEX_0) {
4972 ALOGE("%s: no api to send cal with index(%d) for device(%d) acdbid(%d) app_id(%d)",
4973 __func__, cal_index, st_device, acdb_id, app_id);
4974 return -EINVAL;
4975 }
4976 ALOGD("%s: sending lsm calibration for device(%d) acdb_id(%d) app_id(%d)",
4977 __func__, st_device, acdb_id, app_id);
4978 /* ACDB modes: topology=1, non-topology=0 */
4979 ATRACE_BEGIN("sthal: acdb_send_lsm_cal");
4980 status = my_data->acdb_send_lsm_cal(acdb_id, app_id,
4981 (use_topology == true),
4982 hw_type);
4983 ATRACE_END();
4984 }
4985 break;
4986
4987 case ST_DEVICE_CAL:
4988 sample_rate = platform_stdev_get_device_sample_rate(my_data,
4989 v_info->profile_type);
4990
4991 if (platform_stdev_is_hwmad_backend(platform, st_device, exec_mode)) {
4992 if (platform_stdev_send_hwmad_cal(platform, acdb_id))
4993 return -EINVAL;
4994 } else if (my_data->codec_backend_cfg.vad_enable == true) {
4995 if (platform_stdev_send_hwvad_cal(platform, acdb_id))
4996 return -EINVAL;
4997 }
4998
4999 if (my_data->acdb_send_device_cal_v1) {
5000 /* 0: non-persistent, 1: persistent */
5001 cal_mode = (v_info->profile_type == ST_PROFILE_TYPE_FFECNS) ? 1 : 0;
5002 ALOGD("%s: send dev cal for device(%d) acdb_id(%d) cal_mode(%d) app_id(%d)",
5003 __func__, st_device, acdb_id, cal_mode, app_id);
5004 ATRACE_BEGIN("sthal: acdb_send_device_cal_v1");
5005 my_data->acdb_send_device_cal_v1(acdb_id, hw_type, app_id,
5006 sample_rate, cal_mode);
5007 ATRACE_END();
5008 } else if (my_data->acdb_send_device_cal) {
5009 ALOGD("%s: sending device calibration for device(%d) acdb_id(%d) app_id %d",
5010 __func__, st_device, acdb_id, app_id);
5011 ATRACE_BEGIN("sthal: acdb_send_device_cal");
5012 my_data->acdb_send_device_cal(acdb_id, hw_type, app_id, sample_rate);
5013 ATRACE_END();
5014 }
5015 break;
5016
5017 default:
5018 ALOGE("%s: invalid cal type %d",__func__,type);
5019 return -EINVAL;
5020 }
5021
5022 return status;
5023}
5024
5025bool platform_stdev_check_and_update_concurrency
5026(
5027 void *platform,
5028 audio_event_type_t event_type,
5029 audio_event_info_t* config,
5030 unsigned int num_sessions
5031)
5032{
5033 struct platform_data *my_data;
5034 sound_trigger_device_t *stdev;
Zhou Song6ab4d642020-03-12 16:16:50 +08005035 bool concurrency_ses_allowed = true;
Quinn Male2e883752019-03-22 11:28:54 -07005036
5037 if (!platform) {
5038 ALOGE("%s: NULL platform", __func__);
5039 return false;
5040 }
5041 my_data = (struct platform_data *)platform;
5042 if (!my_data->stdev) {
5043 ALOGE("%s: platform stdev data is NULL", __func__);
5044 return false;
5045 }
5046 stdev = my_data->stdev;
5047
Quinn Maled21521c2020-05-19 10:58:26 -07005048 if (event_type == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
5049 event_type == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
5050 /* handle CAPTURE_DEVICE events */
Quinn Male893c4742020-09-21 14:32:10 -07005051 ALOGI("%s: Received DEVICE event, event type %d, usecase type %d",
5052 __func__, event_type, config->u.usecase.type);
Quinn Maled21521c2020-05-19 10:58:26 -07005053 /*
5054 * for device status events, if:
5055 * 1. conc audio disabled - return with false to disable VA sessions
5056 * 2. conc audio enabled - due to use case type unknown, return with
5057 * current decision
5058 */
5059 switch (event_type) {
5060 case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
5061 stdev->tx_concurrency_active++;
Quinn Male893c4742020-09-21 14:32:10 -07005062 switch (config->u.usecase.type) {
5063 case USECASE_TYPE_VOICE_CALL:
5064 stdev->conc_voice_active = true;
5065 break;
5066 case USECASE_TYPE_VOIP_CALL:
5067 stdev->conc_voip_active = true;
5068 break;
5069 default:
5070 break;
5071 }
Quinn Maled21521c2020-05-19 10:58:26 -07005072 break;
5073 case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
5074 if (stdev->tx_concurrency_active > 0)
5075 stdev->tx_concurrency_active--;
Quinn Male893c4742020-09-21 14:32:10 -07005076 switch (config->u.usecase.type) {
5077 case USECASE_TYPE_VOICE_CALL:
5078 stdev->conc_voice_active = false;
5079 break;
5080 case USECASE_TYPE_VOIP_CALL:
5081 stdev->conc_voip_active = false;
5082 break;
5083 default:
5084 break;
5085 }
Quinn Maled21521c2020-05-19 10:58:26 -07005086 break;
5087 default:
5088 break;
5089 }
5090 if (stdev->conc_capture_supported)
5091 concurrency_ses_allowed = stdev->session_allowed;
5092 else if (stdev->tx_concurrency_active > 0)
5093 concurrency_ses_allowed = false;
5094 } else {
5095 /* handle CAPTURE_STREAM events */
Quinn Male2e883752019-03-22 11:28:54 -07005096 ALOGI("%s: Received STREAM event, event type %d, usecase type %d",
5097 __func__, event_type, config->u.usecase.type);
5098 switch (event_type) {
Quinn Male893c4742020-09-21 14:32:10 -07005099 case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
5100 stdev->rx_concurrency_active++;
5101 break;
5102 case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
5103 if (stdev->rx_concurrency_active > 0)
5104 stdev->rx_concurrency_active--;
5105 break;
5106 default:
5107 break;
Quinn Male2e883752019-03-22 11:28:54 -07005108 }
5109 if (event_type == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE ||
5110 event_type == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
Quinn Male2e883752019-03-22 11:28:54 -07005111 if (stdev->rx_concurrency_disabled &&
5112 stdev->rx_concurrency_active > 0 &&
5113 num_sessions > stdev->rx_conc_max_st_ses)
5114 concurrency_ses_allowed = false;
Zhou Song6ab4d642020-03-12 16:16:50 +08005115 }
Zhou Song3575d182020-04-19 15:54:02 +08005116 if (concurrency_ses_allowed) {
5117 if ((!stdev->conc_capture_supported &&
5118 stdev->tx_concurrency_active > 0) ||
5119 (stdev->conc_capture_supported &&
5120 ((!stdev->conc_voice_call_supported && stdev->conc_voice_active) ||
5121 (!stdev->conc_voip_call_supported && stdev->conc_voip_active))))
Quinn Male2e883752019-03-22 11:28:54 -07005122 concurrency_ses_allowed = false;
5123 }
Quinn Male2e883752019-03-22 11:28:54 -07005124 }
5125
5126 /*
Quinn Male893c4742020-09-21 14:32:10 -07005127 * This disablement of VOIP/Voice flags is needed for the following usecase:
5128 *
5129 * 1. VOIP/Voice and AR active.
5130 * 2. VOIP/Voice stops - AHAL sends stream inactive events for each stream,
5131 * followed by the shared device inactive and device active events which
5132 * both have VOIP/voice usecase, followed by one stream active event for AR.
5133 * 3. AR stops - stream and device inactive events with pcm capture usecase.
5134 *
5135 * In this usecase the VOIP/voice flags get stuck set to true, so reset them here.
Quinn Male2e883752019-03-22 11:28:54 -07005136 */
Quinn Male893c4742020-09-21 14:32:10 -07005137 if (stdev->tx_concurrency_active == 0) {
5138 stdev->conc_voice_active = false;
5139 stdev->conc_voip_active = false;
5140 }
Quinn Male2e883752019-03-22 11:28:54 -07005141
5142 ALOGD("%s: dedicated path %d, reset backend %d, tx %d, rx %d,"
Quinn Malee90f4722019-06-14 15:01:15 -07005143 " concurrency session%s allowed",
5144 __func__, platform_stdev_is_dedicated_sva_path(stdev->platform),
5145 stdev->reset_backend, stdev->tx_concurrency_active,
5146 stdev->rx_concurrency_active, concurrency_ses_allowed? "" : " not");
Quinn Male2e883752019-03-22 11:28:54 -07005147
5148 return concurrency_ses_allowed;
5149}
5150
5151void platform_stdev_check_and_update_pcm_config
5152(
Quinn Male2e883752019-03-22 11:28:54 -07005153 struct pcm_config *config,
Quinn Male9a345522020-03-12 17:49:25 -07005154 struct st_vendor_info *v_info
Quinn Male2e883752019-03-22 11:28:54 -07005155)
5156{
Quinn Male2e883752019-03-22 11:28:54 -07005157 /* Update config with params in vendor info */
5158 config->rate = v_info->sample_rate;
5159 config->format = v_info->format;
5160 config->channels = v_info->out_channels;
Quinn Male2e883752019-03-22 11:28:54 -07005161}
5162
5163int platform_stdev_connect_mad
5164(
5165 void *platform,
5166 st_exec_mode_t mode,
5167 st_profile_type_t profile_type
5168)
5169{
5170 /* This mixer control is only valid for CPE supported codec */
5171 struct platform_data *my_data = (struct platform_data *)platform;
5172 sound_trigger_device_t *stdev = my_data->stdev;
5173 int status = 0;
5174 struct mixer_ctl *ctl = NULL;
5175 const char *mixer_ctl_name = "MAD_SEL MUX";
5176
5177 if (stdev->disable_hwmad || stdev->sw_mad ||
5178 (mode == ST_EXEC_MODE_NONE) || (mode == ST_EXEC_MODE_ARM) ||
5179 ((mode == ST_EXEC_MODE_ADSP) &&
5180 (profile_type != ST_PROFILE_TYPE_NONE)))
5181 return 0;
5182
5183 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
5184 if (!ctl) {
5185 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
5186 __func__, mixer_ctl_name);
5187 return -EINVAL;
5188 }
5189 if (mode == ST_EXEC_MODE_ADSP)
5190 status = mixer_ctl_set_enum_by_string(ctl, "MSM");
5191 else
5192 status = mixer_ctl_set_enum_by_string(ctl, "SPE");
5193
5194 if (status)
5195 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
5196
5197 return status;
5198}
5199
5200int platform_stdev_get_hw_type(void *platform)
5201{
5202 struct platform_data *my_data = (struct platform_data *)platform;
5203 sound_trigger_device_t *stdev = my_data->stdev;
5204
5205 int dev_id;
5206 unsigned int i = 0, j = 0, k = 0;
5207 char comp_string[USECASE_STRING_SIZE];
5208 char *line = NULL;
5209 size_t len = 0;
5210 FILE *fp;
5211
5212 fp = fopen(PCM_DEVICE_FILE, "r");
5213
5214 if (!fp) {
5215 ALOGE("%s: ERROR. %s file open failed", __func__, PCM_DEVICE_FILE);
5216 return -ENODEV;
5217 }
5218 snprintf(comp_string, USECASE_STRING_SIZE, "Listen %d Audio Service", i+1);
5219
5220 while(getline(&line, &len, fp) != -1) {
5221 if (strstr(line, comp_string) && (i < stdev->max_ape_sessions)) {
5222 stdev->hw_type |= ST_DEVICE_HW_APE;
5223 snprintf(stdev->ape_pcm_use_cases[i].use_case,
5224 USECASE_STRING_SIZE, "listen-voice-wakeup-%d", i+1);
5225
5226 if (sscanf(&line[3], "%d", &dev_id) == 1)
5227 stdev->ape_pcm_use_cases[i++].pcm_id = dev_id;
5228 else
5229 ALOGE("%s: ERROR. adsp pcm dev_id parse failed", __func__);
5230
5231 snprintf(comp_string, USECASE_STRING_SIZE, "Listen %d Audio Service", i+1);
Quinn Male2e883752019-03-22 11:28:54 -07005232 } else if (strstr(line, CAPTURE_PCM_USECASE_STRING)) {
5233 stdev->hw_type |= ST_DEVICE_HW_ARM;
5234 if (sscanf(&line[3], "%d", &dev_id) == 1)
5235 stdev->arm_pcm_use_cases[CAPTURE_PCM_USECASE_INDEX].pcm_id = dev_id;
5236 else
5237 ALOGE("%s: ERROR. arm pcm dev_id parse failed", __func__);
5238
5239 strlcpy(stdev->arm_pcm_use_cases[CAPTURE_PCM_USECASE_INDEX].use_case,
5240 CAPTURE_PCM_USECASE_PATH, USECASE_STRING_SIZE);
5241 k++;
5242 } else if (strstr(line, CAPTURE_EC_REF_USECASE_STRING)) {
5243 if (sscanf(&line[3], "%d", &dev_id) == 1)
5244 stdev->arm_pcm_use_cases[CAPTURE_EC_REF_USECASE_INDEX].pcm_id = dev_id;
5245 else
5246 ALOGE("%s: ERROR. arm pcm dev_id parse failed", __func__);
5247
5248 strlcpy(stdev->arm_pcm_use_cases[CAPTURE_EC_REF_USECASE_INDEX].use_case,
5249 CAPTURE_EC_REF_USECASE_PATH, USECASE_STRING_SIZE);
5250 }
5251 }
5252
5253 free(line);
5254 fclose(fp);
5255
5256 if (!CHECK_BIT(stdev->hw_type,
5257 ST_DEVICE_HW_APE|ST_DEVICE_HW_CPE|ST_DEVICE_HW_ARM)) {
5258 ALOGE("%s: ERROR. No Listen device present", __func__);
5259 return -ENODEV;
5260 }
5261
5262 if (stdev->max_ape_sessions > i) {
5263 ALOGW("%s: max_ape_sessions platform configured=%d > driver supported=%d",
5264 __func__, stdev->max_ape_sessions, i);
5265 stdev->max_ape_sessions = i;
5266 }
5267 if (stdev->max_cpe_sessions > j) {
5268 ALOGW("%s: max_cpe_sessions platform configured=%d > driver supported=%d",
5269 __func__, stdev->max_cpe_sessions, j);
5270 stdev->max_cpe_sessions = j;
5271 }
5272 if (stdev->max_arm_sessions > k) {
5273 ALOGW("%s: max_arm_sessions platform configured=%d > driver supported=%d",
5274 __func__, stdev->max_arm_sessions, k);
5275 stdev->max_arm_sessions = k;
5276 }
5277
5278 return 0;
5279}
5280
Quinn Male2e883752019-03-22 11:28:54 -07005281int platform_ape_get_pcm_device_id
5282(
5283 void *platform,
5284 unsigned int* use_case_idx
5285)
5286{
5287 struct platform_data *my_data = (struct platform_data *)platform;
5288 sound_trigger_device_t *stdev = my_data->stdev;
5289 unsigned int i;
5290 int ret = -1;
5291
5292 for (i = 0; i < stdev->max_ape_sessions; i++) {
5293 if (!stdev->ape_pcm_use_cases[i].active) {
5294 stdev->ape_pcm_use_cases[i].active = true;
5295 ret = stdev->ape_pcm_use_cases[i].pcm_id;
5296 *use_case_idx = i;
5297 break;
5298 }
5299 }
5300 if (ret < 0)
5301 ALOGE("%s: ERROR. no free pcm device available", __func__);
5302
5303 return ret;
5304}
5305
5306void platform_ape_free_pcm_device_id
5307(
5308 void *platform,
5309 int pcm_id
5310)
5311{
5312 struct platform_data *my_data = (struct platform_data *)platform;
5313 sound_trigger_device_t *stdev = my_data->stdev;
5314 unsigned int i;
5315
5316 for (i = 0; i < stdev->max_ape_sessions; i++) {
5317 if (stdev->ape_pcm_use_cases[i].pcm_id == pcm_id) {
5318 stdev->ape_pcm_use_cases[i].active = false;
5319 break;
5320 }
5321 }
5322}
5323
Quinn Male2e883752019-03-22 11:28:54 -07005324int platform_arm_get_pcm_device_id
5325(
5326 void *platform,
5327 unsigned int* use_case_idx,
5328 bool ec_ref_dev
5329)
5330{
5331 struct platform_data *my_data = (struct platform_data *)platform;
5332 sound_trigger_device_t *stdev = my_data->stdev;
5333 unsigned int i = CAPTURE_PCM_USECASE_INDEX;
5334 int ret = -1;
5335
5336 if (ec_ref_dev)
5337 i = CAPTURE_EC_REF_USECASE_INDEX;
5338
5339 if (!stdev->arm_pcm_use_cases[i].active) {
5340 stdev->arm_pcm_use_cases[i].active = true;
5341 ret = stdev->arm_pcm_use_cases[i].pcm_id;
5342 *use_case_idx = i;
5343 }
5344 if (ret < 0)
5345 ALOGE("%s: ERROR. no free pcm device available", __func__);
5346
5347 return ret;
5348}
5349
5350void platform_arm_free_pcm_device_id
5351(
5352 void *platform,
5353 int pcm_id,
5354 bool ec_ref_dev
5355)
5356{
5357 struct platform_data *my_data = (struct platform_data *)platform;
5358 sound_trigger_device_t *stdev = my_data->stdev;
5359 unsigned int i = CAPTURE_PCM_USECASE_INDEX;
5360
5361 if (ec_ref_dev)
5362 i = CAPTURE_EC_REF_USECASE_INDEX;
5363
5364 if (stdev->arm_pcm_use_cases[i].pcm_id == pcm_id)
5365 stdev->arm_pcm_use_cases[i].active = false;
5366}
5367
5368struct st_ss_usecase platform_get_ss_usecase
5369(
5370 struct st_vendor_info *v_info,
5371 listen_model_indicator_enum sm_id
5372)
5373{
5374 struct st_ss_usecase usecase;
5375 struct listnode *node, *temp;
5376
5377 ALOGV("%s: Enter", __func__);
5378
5379 usecase.type = ST_SS_USECASE_TYPE_NONE;
5380 if (!v_info) {
5381 ALOGE("%s: received null params", __func__);
5382 return usecase;
5383 }
5384
5385 if (!list_empty(&v_info->arm_ss_usecase_list)) {
5386 list_for_each_safe(node, temp, &v_info->arm_ss_usecase_list) {
5387 usecase.arm = node_to_item(node, struct st_arm_ss_params, list_node);
5388 if (usecase.arm->common_params.sm_id == sm_id) {
5389 usecase.type = ST_SS_USECASE_TYPE_ARM;
5390 return usecase;
5391 }
5392 }
5393 }
5394
5395 if (!list_empty(&v_info->lsm_ss_usecase_list)) {
5396 list_for_each_safe(node, temp, &v_info->lsm_ss_usecase_list) {
5397 usecase.lsm = node_to_item(node, struct st_lsm_ss_params, list_node);
5398 if (usecase.lsm->common_params.sm_id == sm_id) {
5399 usecase.type = ST_SS_USECASE_TYPE_LSM;
5400 return usecase;
5401 }
5402 }
5403 }
5404
5405 ALOGE("%s: Found no matching second stage session type", __func__);
5406 return usecase;
5407}
5408
5409void platform_alloc_gcs_usecase
5410(
5411 void *platform,
5412 struct st_vendor_info *v_info,
5413 struct st_gcs_params **gcs_usecase,
5414 unsigned int acdb_id
5415)
5416{
5417 struct platform_data *my_data = (struct platform_data *)platform;
5418 struct st_gcs_params *usecase = NULL;
5419 struct listnode *gcs_node, *node;
5420 int i;
5421
5422 ALOGV("%s: enter", __func__);
5423
5424 if (!v_info || !gcs_usecase) {
5425 ALOGE("%s: received null params", __func__);
5426 return;
5427 }
5428
5429 if (list_empty(&v_info->gcs_usecase_list)) {
5430 *gcs_usecase = NULL;
5431 ALOGE("%s: gcs usecase not available", __func__);
5432 return;
5433 }
5434
5435 if (my_data->xml_version >= PLATFORM_XML_VERSION_0x0102) {
5436 list_for_each_safe(gcs_node, node, &v_info->gcs_usecase_list) {
5437 usecase = node_to_item(gcs_node, struct st_gcs_params, list_node);
5438 i = 0;
5439 while ((i < MAX_GCS_USECASE_ACDB_IDS) && usecase->acdb_ids[i]) {
5440 if (usecase->acdb_ids[i] == acdb_id) {
5441 *gcs_usecase = usecase;
5442 list_remove(gcs_node);
5443 return;
5444 }
5445 i++;
5446 }
5447 }
5448 ALOGE("%s: Found no matching acdb id", __func__);
5449 *gcs_usecase = NULL;
5450 } else {
5451 gcs_node = list_head(&v_info->gcs_usecase_list);
5452 *gcs_usecase = node_to_item(gcs_node, struct st_gcs_params, list_node);
5453 list_remove(gcs_node);
5454 }
5455}
5456
5457void platform_free_gcs_usecase
5458(
5459 struct st_vendor_info *v_info,
5460 struct st_gcs_params *gcs_usecase
5461)
5462{
5463 ALOGV("%s: enter", __func__);
5464
5465 if (!v_info || !gcs_usecase) {
5466 ALOGE("%s: received null params", __func__);
5467 return;
5468 }
5469
5470 list_add_head(&v_info->gcs_usecase_list, &gcs_usecase->list_node);
5471}
5472
Quinn Male3d7d9d42019-05-20 13:35:01 -07005473static int get_shared_buf_fmt
5474(
5475 st_profile_type_t profile
5476)
5477{
5478 int ret = ST_SHARED_BUF_RAW;
5479
5480 switch (profile) {
5481 case ST_PROFILE_TYPE_FLUENCE:
5482 case ST_PROFILE_TYPE_FLUENCE_STEREO:
5483 case ST_PROFILE_TYPE_FFECNS:
5484 ret = ST_SHARED_BUF_PROCESSED;
5485 break;
5486 default:
5487 ret = ST_SHARED_BUF_RAW;
5488 }
5489
5490 return ret;
5491}
5492
Quinn Male8b2cb792020-07-13 14:41:32 -07005493static int platform_get_module_params_for_lsm_usecase
Quinn Male58749452020-03-26 17:14:56 -07005494(
5495 struct st_lsm_params *usecase,
5496 st_module_type_t sm_version
5497)
5498{
5499 struct listnode *module_node = NULL, *tmp_node = NULL;
5500 struct st_module_params *module_info = NULL;
5501
5502 list_for_each_safe(module_node, tmp_node, &usecase->module_params_list) {
5503 module_info = node_to_item(module_node, struct st_module_params,
5504 list_node);
5505 if (module_info->type == sm_version) {
5506 memcpy((uint8_t *)usecase->params, (uint8_t *)module_info->params,
5507 sizeof(struct st_module_param_info) * MAX_PARAM_IDS);
5508 usecase->param_tag_tracker = module_info->param_tag_tracker;
Quinn Male8b2cb792020-07-13 14:41:32 -07005509 return 0;
Quinn Male58749452020-03-26 17:14:56 -07005510 }
5511 }
5512
Quinn Male8b2cb792020-07-13 14:41:32 -07005513 return -EINVAL;
Quinn Male58749452020-03-26 17:14:56 -07005514}
5515
Quinn Male8b2cb792020-07-13 14:41:32 -07005516int platform_get_lsm_usecase
Quinn Male2e883752019-03-22 11:28:54 -07005517(
5518 void* platform,
5519 struct st_vendor_info* v_info,
Quinn Male8b2cb792020-07-13 14:41:32 -07005520 struct st_lsm_params* lsm_usecase,
Quinn Male23026702019-07-19 10:51:16 -07005521 st_exec_mode_t exec_mode,
Quinn Male58749452020-03-26 17:14:56 -07005522 bool lpi_enable,
5523 st_module_type_t sm_version
Quinn Male2e883752019-03-22 11:28:54 -07005524)
5525{
5526 struct st_lsm_params *usecase = NULL;
5527 struct listnode *lsm_node = NULL, *node = NULL;
5528 struct platform_data *my_data = (struct platform_data *)platform;
5529 audio_devices_t capture_device =
5530 platform_stdev_get_capture_device(platform);
Quinn Malecc1affd2019-07-18 16:13:31 -07005531 sound_trigger_device_t *stdev = my_data->stdev;
Quinn Male8b2cb792020-07-13 14:41:32 -07005532 int status = 0;
Quinn Male2e883752019-03-22 11:28:54 -07005533
5534 ALOGV("%s: Enter", __func__);
5535
5536 if (!v_info || !lsm_usecase) {
5537 ALOGE("%s: received null params", __func__);
Quinn Male8b2cb792020-07-13 14:41:32 -07005538 return -EINVAL;
Quinn Male2e883752019-03-22 11:28:54 -07005539 }
5540
5541 if (list_empty(&v_info->lsm_usecase_list)) {
Quinn Male2e883752019-03-22 11:28:54 -07005542 ALOGE("%s: lsm usecase not available", __func__);
Quinn Male8b2cb792020-07-13 14:41:32 -07005543 return -EINVAL;
Quinn Male2e883752019-03-22 11:28:54 -07005544 }
5545
5546 list_for_each_safe(lsm_node, node, &v_info->lsm_usecase_list) {
5547 usecase = node_to_item(lsm_node, struct st_lsm_params, list_node);
5548 if (usecase->exec_mode == exec_mode) {
5549 if (my_data->xml_version >= PLATFORM_XML_VERSION_0x0105) {
Quinn Malecc1affd2019-07-18 16:13:31 -07005550 /*
5551 * When the capture device matches, the lsm_usecase with the
5552 * following lpi_mode will be selected:
5553 *
5554 * ST_PLATFORM_LPI_NONE, when no lpi_mode is present.
5555 *
5556 * ST_PLATFORM_LPI_ENABLE, when lpi_enable is true.
5557 *
5558 * ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN, when lpi_enable is
5559 * false and either no lsm_usecase with ST_PLATFORM_LPI_DISABLE
5560 * is present or barge_in_mode is active.
5561 *
5562 * ST_PLATFORM_LPI_DISABLE, when lpi_enable is false and an
5563 * lsm_usecase with this lpi_mode is present and barge_in_mode
5564 * is inactive.
5565 */
Quinn Male23026702019-07-19 10:51:16 -07005566 if (capture_device == usecase->capture_device &&
5567 (usecase->lpi_enable == ST_PLATFORM_LPI_NONE ||
Quinn Malecc1affd2019-07-18 16:13:31 -07005568 (usecase->lpi_enable == ST_PLATFORM_LPI_ENABLE &&
5569 lpi_enable) ||
5570 (usecase->lpi_enable ==
5571 ST_PLATFORM_LPI_DISABLE_AND_BARGE_IN && !lpi_enable &&
5572 (stdev->support_dynamic_ec_update ||
5573 stdev->barge_in_mode)) ||
5574 (usecase->lpi_enable == ST_PLATFORM_LPI_DISABLE &&
5575 !lpi_enable && !stdev->barge_in_mode))) {
Quinn Male58749452020-03-26 17:14:56 -07005576 if (my_data->xml_version == PLATFORM_XML_VERSION_0x0106) {
Quinn Male8b2cb792020-07-13 14:41:32 -07005577 status = platform_get_module_params_for_lsm_usecase(usecase,
5578 sm_version);
5579 if (status) {
Quinn Male58749452020-03-26 17:14:56 -07005580 ALOGE("%s: Error. No matching module info params.",
5581 __func__);
Quinn Male8b2cb792020-07-13 14:41:32 -07005582 return status;
Quinn Male58749452020-03-26 17:14:56 -07005583 }
5584 }
Quinn Male8b2cb792020-07-13 14:41:32 -07005585 memcpy((uint8_t *)lsm_usecase, (uint8_t *)usecase,
5586 sizeof(struct st_lsm_params));
Quinn Male2e883752019-03-22 11:28:54 -07005587 v_info->in_channels = usecase->in_channels;
5588 v_info->fluence_type = usecase->fluence_type;
5589 v_info->profile_type = usecase->adm_cfg_profile;
Quinn Male3d7d9d42019-05-20 13:35:01 -07005590 v_info->shared_buf_fmt =
5591 get_shared_buf_fmt(v_info->profile_type);
Quinn Male8b2cb792020-07-13 14:41:32 -07005592 if (sm_version == ST_MODULE_TYPE_PDK5)
Quinn Male58749452020-03-26 17:14:56 -07005593 v_info->app_type = usecase->pdk5_app_type;
Quinn Male8b2cb792020-07-13 14:41:32 -07005594 else
Quinn Male58749452020-03-26 17:14:56 -07005595 v_info->app_type = usecase->app_type;
Quinn Male8b2cb792020-07-13 14:41:32 -07005596 return status;
Quinn Male2e883752019-03-22 11:28:54 -07005597 }
5598 } else {
Quinn Male8b2cb792020-07-13 14:41:32 -07005599 /* Same lsm usecase will be used for multiple sessions */
5600 memcpy((uint8_t *)lsm_usecase, (uint8_t *)usecase,
5601 sizeof(struct st_lsm_params));
5602 v_info->in_channels = usecase->in_channels;
5603 return status;
Quinn Male2e883752019-03-22 11:28:54 -07005604 }
5605 }
5606 }
5607 ALOGE("%s: No lsm usecase found for exec_mode %d", __func__, exec_mode);
Quinn Male8b2cb792020-07-13 14:41:32 -07005608 return -EINVAL;
Quinn Male2e883752019-03-22 11:28:54 -07005609}
5610
5611int platform_stdev_get_backend_channel_count
5612(
5613 void *platform __unused,
5614 const struct st_vendor_info *v_info
5615)
5616{
5617 /*
5618 * Channel count for backend is determined from configuration of
5619 * lsm session except in case of fluence profile.
5620 * In case of fluence, backend configuration is obtained from
5621 * fluence type set.
5622 */
5623 if ((v_info->profile_type == ST_PROFILE_TYPE_FLUENCE) ||
5624 (v_info->profile_type == ST_PROFILE_TYPE_FLUENCE_STEREO) ||
5625 (v_info->profile_type == ST_PROFILE_TYPE_FFECNS))
5626 return get_channel_cnt_from_fluence_type(v_info->fluence_type);
5627
5628 return v_info->in_channels;
5629}
5630
5631static int check_and_set_codec_backend_cfg
5632(
5633 void *platform,
5634 struct st_vendor_info *v_info,
5635 bool *backend_cfg_change,
5636 bool force,
5637 bool lpi_enable,
5638 bool vad_enable,
5639 int vad_preroll
5640)
5641{
5642 struct platform_data *my_data = (struct platform_data *)platform;
5643 sound_trigger_device_t *stdev = my_data->stdev;
5644 struct mixer_ctl *ctl;
5645 int channel_count;
5646 char *sample_rate = "KHZ_16";
5647 bool set_sample_rate = false;
5648
5649 if (!backend_cfg_change) {
5650 ALOGE("%s: NULL backend", __func__);
5651 return -EINVAL;
5652 }
5653
5654 *backend_cfg_change = false;
5655
5656 if (!v_info)
5657 return 0;
5658
5659 if (force || (v_info->format != my_data->codec_backend_cfg.format)) {
5660 if (my_data->codec_backend_cfg.format_mixer_ctl &&
5661 (force || (my_data->codec_backend_cfg.format != PCM_FORMAT_S24_LE))) {
5662 ctl = mixer_get_ctl_by_name(stdev->mixer,
5663 my_data->codec_backend_cfg.format_mixer_ctl);
5664 if (!ctl) {
5665 ALOGE("%s: Could not get ctl for mixer command - %s",
5666 __func__, my_data->codec_backend_cfg.format_mixer_ctl);
5667 return -EINVAL;
5668 }
5669
5670 if (v_info->format == PCM_FORMAT_S24_LE) {
5671 mixer_ctl_set_enum_by_string(ctl, "S24_LE");
5672 } else if (v_info->format == PCM_FORMAT_S16_LE) {
5673 mixer_ctl_set_enum_by_string(ctl, "S16_LE");
5674 } else {
5675 ALOGE("%s: Invalid format %d", __func__, v_info->format);
5676 return -EINVAL;
5677 }
5678 *backend_cfg_change = true;
5679 my_data->codec_backend_cfg.format = v_info->format;
5680 }
5681 }
5682
5683 channel_count = platform_stdev_get_backend_channel_count(platform, v_info);
5684 ALOGV("%s: check new ch count %d against backend ch count %d",
5685 __func__, channel_count, my_data->codec_backend_cfg.channel_count);
5686 if (force || (channel_count > my_data->codec_backend_cfg.channel_count)) {
5687 *backend_cfg_change = true;
5688 my_data->codec_backend_cfg.channel_count = channel_count;
5689 }
5690
5691 ALOGV("%s: check new lpi_state %d against backend lpi_state %d",
5692 __func__, lpi_enable, my_data->codec_backend_cfg.lpi_enable);
5693 if (my_data->codec_backend_cfg.lpi_enable != lpi_enable) {
5694 my_data->codec_backend_cfg.lpi_enable = lpi_enable;
5695 ctl = mixer_get_ctl_by_name(stdev->mixer,
5696 my_data->codec_backend_cfg.lpi_mixer_ctl);
5697 if (ctl) {
Quinn Male24daf422019-05-29 16:12:55 -07005698 ALOGD("%s: Setting %s to %s",
5699 __func__, my_data->codec_backend_cfg.lpi_mixer_ctl,
5700 lpi_enable ? "true" : "false");
Quinn Male2e883752019-03-22 11:28:54 -07005701 mixer_ctl_set_value(ctl, 0, (int)lpi_enable);
5702 *backend_cfg_change = true;
5703 set_sample_rate = my_data->codec_backend_cfg.lpi_enable;
5704 } else {
5705 ALOGV("%s: Could not get ctl for mixer command - %s",
5706 __func__, my_data->codec_backend_cfg.lpi_mixer_ctl);
5707 }
5708 }
5709
5710 ALOGV("%s: check (proposed/current) state: vad(%d/%d) preroll(%d/%d), forced(%d)",
5711 __func__, vad_enable, my_data->codec_backend_cfg.vad_enable,
5712 vad_preroll, my_data->codec_backend_cfg.vad_preroll, force);
5713 if (force || my_data->codec_backend_cfg.vad_enable != vad_enable ||
5714 (vad_enable && (my_data->codec_backend_cfg.vad_preroll < vad_preroll))) {
5715 int backend_id;
5716 int vad_cfg[3] = {0};
5717
5718 backend_id = get_backend_index_from_name(my_data, my_data->backend_dai_name);
5719 if (backend_id < 0) {
5720 ALOGE("%s: Could not get valid backend id(%d)", __func__, backend_id);
5721 return -EINVAL;
5722 }
5723
5724 ctl = mixer_get_ctl_by_name(stdev->mixer,
5725 my_data->codec_backend_cfg.vad_mixer_ctl);
5726 if (ctl) {
5727 my_data->codec_backend_cfg.vad_enable = vad_enable;
5728 if (force || my_data->codec_backend_cfg.vad_preroll < vad_preroll)
5729 my_data->codec_backend_cfg.vad_preroll = vad_preroll;
5730
5731 vad_cfg[0] = my_data->codec_backend_cfg.vad_enable;
5732 vad_cfg[1] = my_data->codec_backend_cfg.vad_preroll;
5733 vad_cfg[2] = backend_id;
5734 mixer_ctl_set_array(ctl, vad_cfg,
5735 sizeof(vad_cfg)/sizeof(vad_cfg[0]));
5736 *backend_cfg_change = true;
5737 set_sample_rate = (set_sample_rate ||
5738 my_data->codec_backend_cfg.vad_enable);
5739 } else {
5740 ALOGV("%s: Could not get ctl for mixer command - %s",
5741 __func__, my_data->codec_backend_cfg.vad_mixer_ctl);
5742 }
5743 }
5744
5745 /*
5746 * LPI and VAD both mandate AFE sample rate to be 16 KHz.
5747 * TODO: make it generic enough to handle concurrency with audio hal.
5748 */
5749 if (set_sample_rate) {
5750 ctl = mixer_get_ctl_by_name(stdev->mixer,
5751 my_data->codec_backend_cfg.samplerate_mixer_ctl);
5752 if (ctl) {
5753 mixer_ctl_set_enum_by_string(ctl, sample_rate);
5754 } else {
5755 ALOGE("%s: Could not get ctl for mixer command - %s",
5756 __func__,
5757 my_data->codec_backend_cfg.samplerate_mixer_ctl);
5758 return -EINVAL;
5759 }
5760 }
5761 return 0;
5762}
5763
5764int platform_stdev_check_and_set_codec_backend_cfg
5765(
5766 void *platform,
5767 struct st_vendor_info *v_info,
5768 bool *backend_cfg_change,
5769 bool lpi_enable,
5770 bool vad_enable,
5771 int vad_preroll
5772)
5773{
5774 return check_and_set_codec_backend_cfg(platform, v_info,
5775 backend_cfg_change,
5776 false, /* force */
5777 lpi_enable, vad_enable, vad_preroll);
5778}
5779
5780int platform_stdev_set_codec_backend_cfg
5781(
5782 void *platform,
5783 struct st_vendor_info *v_info,
5784 bool lpi_enable,
5785 bool vad_enable,
5786 int vad_preroll
5787)
5788{
5789 bool backend_cfg_change;
5790
5791 return check_and_set_codec_backend_cfg(platform, v_info,
5792 &backend_cfg_change,
5793 true, /* force */
5794 lpi_enable, vad_enable, vad_preroll);
5795}
5796
Quinn Male3d7d9d42019-05-20 13:35:01 -07005797int platform_stdev_set_shared_buf_fmt
5798(
5799 void *platform,
5800 int pcm_id,
5801 int shared_buf_fmt
5802)
5803{
5804 struct platform_data *my_data = (struct platform_data *)platform;
5805 sound_trigger_device_t *stdev = my_data->stdev;
5806 char mixer_ctl_name[ST_MAX_LENGTH_MIXER_CONTROL];
5807 struct mixer_ctl *ctl = NULL;
5808
5809 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
5810 "Listen Stream %d Unprocessed Data", pcm_id);
5811 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
5812 if (!ctl) {
5813 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
5814 __func__, mixer_ctl_name);
5815 return -EINVAL;
5816 }
5817
5818 mixer_ctl_set_value(ctl, 0, shared_buf_fmt);
5819
5820 return 0;
5821}
5822
Quinn Male2e883752019-03-22 11:28:54 -07005823int platform_stdev_send_stream_app_type_cfg
5824(
5825 void *platform,
5826 int pcm_id,
5827 st_device_t st_device,
5828 st_exec_mode_t exec_mode,
5829 st_profile_type_t profile_type
5830)
5831{
5832 struct platform_data *my_data = (struct platform_data *)platform;
5833 sound_trigger_device_t *stdev = my_data->stdev;
5834 char mixer_ctl_name[ST_MAX_LENGTH_MIXER_CONTROL];
5835 int app_type_cfg[ST_MAX_LENGTH_MIXER_CONTROL] = {0};
5836 int len = 0;
5837 struct mixer_ctl *ctl;
5838 int status = 0, acdb_id;
5839 struct listnode *p_node, *temp_node;
5840 struct adm_cfg_info *cfg_info;
5841 bool found_profile = false;
5842 int st_device_be_idx = -EINVAL;
5843
Venkatesh Mangalappali86e4b972019-10-14 17:07:49 -07005844 if (!stdev->lpi_enable && (profile_type == ST_PROFILE_TYPE_NONE)) {
Quinn Male2e883752019-03-22 11:28:54 -07005845 ALOGV("%s: Profile set to None, ignore sending app type cfg",__func__);
5846 goto exit;
5847 }
5848
5849 if (st_device == ST_DEVICE_NONE) {
5850 ALOGE("%s: Invalid device sent",__func__);
5851 status = -EINVAL;
5852 goto exit;
5853 }
5854
5855 acdb_id = acdb_device_table[exec_mode][st_device];
5856 if (acdb_id < 0) {
5857 ALOGE("%s: Could not find acdb id for device(%d)",
5858 __func__, st_device);
5859 status = -EINVAL;
5860 goto exit;
5861 }
5862
5863 st_device_be_idx = get_st_device_backend_index(my_data, st_device);
5864 if (st_device_be_idx < 0)
5865 ALOGE("%s: Couldn't get backend index for device %d ret = %d",
5866 __func__, st_device, st_device_be_idx);
5867
5868 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
5869 "Listen Stream %d App Type Cfg", pcm_id);
5870 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
5871 if (!ctl) {
5872 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
5873 __func__, mixer_ctl_name);
5874 status = -EINVAL;
5875 goto exit;
5876 }
5877
Venkatesh Mangalappali86e4b972019-10-14 17:07:49 -07005878 if (stdev->lpi_enable) {
5879 /*
5880 * Though app_type_cfg is for ADM connection, driver needs atleast LPI
5881 * acdb id to avoid sending a cached non-lpi acdb stale topology of any
5882 * concurrent audio use case for SVA LPI use case.
5883 */
5884 ALOGD("%s: send Stream App Type Cfg for LPI",__func__);
5885 found_profile = true;
5886 app_type_cfg[len++] = 0;
5887 app_type_cfg[len++] = acdb_id;
5888 app_type_cfg[len++] = SOUND_TRIGGER_SAMPLING_RATE_16000;
5889 if (st_device_be_idx >= 0)
5890 app_type_cfg[len++] = st_device_be_idx;
5891 } else {
5892 list_for_each_safe(p_node, temp_node, &stdev->adm_cfg_list) {
5893 cfg_info = node_to_item(p_node, struct adm_cfg_info, list_node);
5894 if (cfg_info->profile_type == profile_type) {
5895 found_profile = true;
5896 app_type_cfg[len++] = cfg_info->app_type;
5897 app_type_cfg[len++] = acdb_id;
5898 app_type_cfg[len++] = cfg_info->sample_rate;
5899 if (st_device_be_idx >= 0)
5900 app_type_cfg[len++] = st_device_be_idx;
5901 break;
5902 }
Quinn Male2e883752019-03-22 11:28:54 -07005903 }
5904 }
5905
5906 if (found_profile) {
5907 status = mixer_ctl_set_array(ctl, app_type_cfg, len);
5908 if (status)
5909 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
5910 }
5911
5912exit:
5913 return status;
5914}
5915
5916int platform_stdev_get_device_app_type
5917(
5918 void *platform,
5919 st_profile_type_t profile_type
5920)
5921{
5922 struct platform_data *my_data = (struct platform_data *)platform;
5923 sound_trigger_device_t *stdev = my_data->stdev;
5924 struct listnode *p_node, *temp_node;
5925 struct adm_cfg_info *cfg_info;
5926 int app_type = 0;
5927
5928 list_for_each_safe(p_node, temp_node, &stdev->adm_cfg_list) {
5929 cfg_info = node_to_item(p_node, struct adm_cfg_info, list_node);
5930 if (cfg_info->profile_type == profile_type) {
5931 app_type = cfg_info->app_type;
5932 break;
5933 }
5934 }
5935
5936 ALOGV("%s: app type %d for profile %d", __func__, app_type, profile_type);
5937 return app_type;
5938}
5939
Quinn Male893c4742020-09-21 14:32:10 -07005940void platform_stdev_disable_stale_devices
5941(
5942 void *platform
5943)
5944{
5945 struct platform_data *my_data = (struct platform_data *)platform;
5946 sound_trigger_device_t *stdev = my_data->stdev;
5947 char st_device_name[DEVICE_NAME_MAX_SIZE] = {0};
5948
5949 /*
5950 * There can be stale devices while exec_mode is NONE with the
5951 * below usecase:
5952 *
5953 * 1. SVA is active in non-dedicated path mode.
5954 * 2. Tx starts, transitioning SVA to NLPI.
5955 * 3. SVA stops and unloads, but cannot disable the BE device.
5956 * 4. Tx stops - this function will get called with exec_mode NONE.
5957 */
5958 if (stdev->exec_mode == ST_EXEC_MODE_ADSP ||
5959 (stdev->exec_mode == ST_EXEC_MODE_NONE &&
5960 !stdev->is_gcs)) {
5961 pthread_mutex_lock(&stdev->ref_cnt_lock);
5962 for (int i = ST_DEVICE_MIN; i < ST_DEVICE_MAX; i++) {
5963 if (0 < stdev->dev_enable_cnt[i]) {
5964 platform_stdev_get_device_name(stdev->platform,
5965 ST_EXEC_MODE_ADSP, i, st_device_name);
5966 ALOGD("%s: disable device (%x) = %s", __func__, i,
5967 st_device_name);
5968 ATRACE_BEGIN("sthal: audio_route_reset_and_update_path");
5969 audio_route_reset_and_update_path(stdev->audio_route,
5970 st_device_name);
5971 ATRACE_END();
5972 --(stdev->dev_enable_cnt[i]);
5973 }
5974 }
5975 pthread_mutex_unlock(&stdev->ref_cnt_lock);
5976 }
5977}
5978
Quinn Male2e883752019-03-22 11:28:54 -07005979static void check_and_append_ec_ref_device_name
5980(
5981 void *platform,
Quinn Maled409e412019-12-09 14:50:48 -08005982 char *ec_ref_mixer_path
Quinn Male2e883752019-03-22 11:28:54 -07005983)
5984{
5985 audio_devices_t capture_device = 0;
Quinn Maled409e412019-12-09 14:50:48 -08005986 struct platform_data *my_data = (struct platform_data *)platform;
Quinn Male2e883752019-03-22 11:28:54 -07005987
5988 capture_device = platform_stdev_get_capture_device(platform);
Quinn Maled409e412019-12-09 14:50:48 -08005989 if (capture_device == AUDIO_DEVICE_IN_WIRED_HEADSET) {
Quinn Male2e883752019-03-22 11:28:54 -07005990 strlcat(ec_ref_mixer_path, " headset", DEVICE_NAME_MAX_SIZE);
Quinn Maled409e412019-12-09 14:50:48 -08005991 } else if (platform_stdev_is_a2dp_out_device_type(
5992 &my_data->stdev->active_rx_dev_list)) {
Quinn Male2e883752019-03-22 11:28:54 -07005993 strlcat(ec_ref_mixer_path, " a2dp", DEVICE_NAME_MAX_SIZE);
Quinn Maled409e412019-12-09 14:50:48 -08005994 } else if (platform_stdev_compare_device_type(
5995 &my_data->stdev->active_rx_dev_list,
5996 AUDIO_DEVICE_OUT_LINE)) {
Quinn Male2e883752019-03-22 11:28:54 -07005997 strlcat(ec_ref_mixer_path, " line", DEVICE_NAME_MAX_SIZE);
Quinn Maled409e412019-12-09 14:50:48 -08005998 }
Quinn Male2e883752019-03-22 11:28:54 -07005999}
6000
Quinn Malecc1affd2019-07-18 16:13:31 -07006001int platform_stdev_update_ec_effect
6002(
6003 void *platform,
6004 bool enable_ec
6005)
6006{
6007 struct platform_data *my_data = (struct platform_data *)platform;
6008 sound_trigger_device_t *stdev = my_data->stdev;
6009 struct mixer_ctl *ctl = NULL;
6010 const char *mixer_ctl_name = "FFECNS Effect";
6011 int status = 0;
6012
6013 ALOGD("%s: Turning %s EC effect", __func__, enable_ec ? "on" : "off");
6014
6015 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
6016 if (!ctl) {
6017 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
6018 __func__, mixer_ctl_name);
6019 return -EINVAL;
6020 }
6021
6022 if (enable_ec)
6023 status = mixer_ctl_set_enum_by_string(ctl, "ECNS");
6024 else
6025 status = mixer_ctl_set_enum_by_string(ctl, "NS_ONLY");
6026
6027 if (status)
6028 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
6029
6030 return status;
6031}
6032
Quinn Male2e883752019-03-22 11:28:54 -07006033void platform_stdev_send_ec_ref_cfg
6034(
6035 void *platform,
6036 st_profile_type_t profile_type,
6037 bool enable
6038)
6039{
6040 struct platform_data *my_data = (struct platform_data *)platform;
6041 sound_trigger_device_t *stdev = my_data->stdev;
Quinn Male82d41662019-08-28 15:43:23 -07006042 struct sound_trigger_event_info event_info = {{0}, 0};
Quinn Male2e883752019-03-22 11:28:54 -07006043
6044 if (is_ec_profile(profile_type)) {
6045 event_info.st_ec_ref_enabled = enable;
Zhou Songea5a0b42020-01-06 18:16:29 +08006046 // reset the pending active EC mixer ctls first
Zhou Songc5134f32020-03-12 17:06:28 +08006047 if (!stdev->audio_ec_enabled) {
6048 while (stdev->ec_reset_pending_cnt > 0) {
Zhou Songea5a0b42020-01-06 18:16:29 +08006049 audio_route_reset_and_update_path(stdev->audio_route,
6050 my_data->ec_ref_mixer_path);
Zhou Songc5134f32020-03-12 17:06:28 +08006051 stdev->ec_reset_pending_cnt--;
6052 }
Zhou Songea5a0b42020-01-06 18:16:29 +08006053 }
Quinn Male2e883752019-03-22 11:28:54 -07006054 if (enable) {
6055 stdev->audio_hal_cb(ST_EVENT_UPDATE_ECHO_REF, &event_info);
Quinn Male2e883752019-03-22 11:28:54 -07006056 strlcpy(my_data->ec_ref_mixer_path, "echo-reference",
6057 sizeof(my_data->ec_ref_mixer_path));
6058
6059 check_and_append_ec_ref_device_name(platform,
Quinn Maled409e412019-12-09 14:50:48 -08006060 my_data->ec_ref_mixer_path);
Quinn Male2e883752019-03-22 11:28:54 -07006061
6062 audio_route_apply_and_update_path(stdev->audio_route,
6063 my_data->ec_ref_mixer_path);
6064 ALOGD("%s: set echo ref %s", __func__, my_data->ec_ref_mixer_path);
6065 } else {
6066 stdev->audio_hal_cb(ST_EVENT_UPDATE_ECHO_REF, &event_info);
6067 /* avoid disabling echo if audio hal has enabled echo ref */
6068 if (!stdev->audio_ec_enabled) {
Quinn Male82d41662019-08-28 15:43:23 -07006069 ALOGD("%s: reset echo ref %s", __func__,
6070 my_data->ec_ref_mixer_path);
6071 audio_route_reset_and_update_path(stdev->audio_route,
6072 my_data->ec_ref_mixer_path);
Quinn Male2e883752019-03-22 11:28:54 -07006073 } else {
Zhou Songea5a0b42020-01-06 18:16:29 +08006074 stdev->ec_reset_pending_cnt++;
Quinn Male2e883752019-03-22 11:28:54 -07006075 ALOGD("%s: audio hal has already enabled EC", __func__);
6076 }
6077 }
6078 } else {
6079 ALOGV("%s: Non-EC Profile, ignore sending ec ref cfg",__func__);
6080 }
6081}
6082
6083int platform_stdev_send_custom_channel_mixing_coefficients
6084(
6085 void *platform,
6086 struct st_vendor_info *v_info,
6087 int pcm_id,
6088 char *str
6089)
6090{
6091 struct platform_data *my_data = (struct platform_data *)platform;
6092 sound_trigger_device_t *stdev = my_data->stdev;
6093 char mixer_ctl_name[ST_MAX_LENGTH_MIXER_CONTROL];
6094 int cust_ch_mixer_cfg[ST_MAX_LENGTH_MIXER_CONTROL], len = 0;
6095 struct mixer_ctl *ctl;
6096 char *test_r = NULL;
6097 int err = -EINVAL;
6098 int ip_channel_cnt, op_channel_cnt, i;
6099 char *params;
6100 int select_channel;
6101 int ch_weightage_coeff[ST_MAX_NUM_CHANNELS][ST_MAX_NUM_CHANNELS];
6102
6103 if (!v_info)
6104 return 0;
6105
6106 if (str == NULL) {
6107 ALOGE("%s: Invalid string passed", __func__);
6108 goto exit;
6109 }
6110
6111 ip_channel_cnt = my_data->codec_backend_cfg.channel_count;
6112 op_channel_cnt = v_info->in_channels;
6113 ALOGD("%s: i/p channel count %d, o/p channel count %d", __func__,
6114 ip_channel_cnt, op_channel_cnt);
6115 if (ip_channel_cnt > ST_MAX_NUM_CHANNELS ||
6116 op_channel_cnt > ST_MAX_NUM_CHANNELS) {
6117 ALOGE("%s: ERROR: Channel count out of bounds", __func__);
6118 goto exit;
6119 }
6120
6121 snprintf(mixer_ctl_name, sizeof(mixer_ctl_name),
6122 "Listen Stream %d Channel Mix Cfg", pcm_id);
6123 ctl = mixer_get_ctl_by_name(stdev->mixer, mixer_ctl_name);
6124 if (!ctl) {
6125 ALOGE("%s: ERROR. Could not get ctl for mixer cmd - %s",
6126 __func__, mixer_ctl_name);
6127 goto exit;
6128 }
6129
6130 /* Input channel count corresponds to backend configuration channels.
6131 * Output channel count corresponds to LSM session channels.
6132 * Set params is called with channels that need to be selected from
6133 * input to generate output.
6134 * ex: "1,4" to downmix from 4 to 2 i.e. to downmix from 4 to 2,
6135 * select channels 1 and 4 from input to generate output.
6136 *
6137 * This mixer control takes values in the following sequence:
6138 * - input channel count(m)
6139 * - output channel count(n)
6140 * - weight coeff for [out ch#1, in ch#1]
6141 * ....
6142 * - weight coeff for [out ch#1, in ch#m]
6143 *
6144 * - weight coeff for [out ch#2, in ch#1]
6145 * ....
6146 * - weight coeff for [out ch#2, in ch#m]
6147 *
6148 * - weight coeff for [out ch#n, in ch#1]
6149 * ....
6150 * - weight coeff for [out ch#n, in ch#m]
6151 *
6152 * weightage coeff is set to Unity for channels that are passed as part
6153 * of set params string.
6154 * In case of upmixing, coefficients is set to 0 for all output channels
6155 * which are greater than input channel count.
6156 * This is in sync with ADM Matrix mixer.
6157 */
6158 cust_ch_mixer_cfg[len++] = ip_channel_cnt;
6159 cust_ch_mixer_cfg[len++] = op_channel_cnt;
6160 for (i = 0; i < op_channel_cnt; i++) {
6161 memset(ch_weightage_coeff[i], 0, sizeof(*ch_weightage_coeff[i]));
6162
6163 if (i >= ip_channel_cnt) {
6164 ALOGD("%s: Upmixing case. Ignore select channel", __func__);
6165 } else {
6166 if (i == 0)
6167 params = strtok_r(str, ",", &test_r);
6168 else
6169 params = strtok_r(NULL, ",", &test_r);
6170
6171 if (params == NULL) {
6172 ALOGE("%s: incorrect channel mixing options\n", __func__);
6173 break;
6174 }
6175
6176 select_channel = atoi(params);
6177 if ((select_channel > 0) && (select_channel <= ip_channel_cnt)) {
6178 ALOGD("%s: o/p [%d] select channel from i/p [%d]", __func__,
6179 i+1, select_channel);
6180 ch_weightage_coeff[i][select_channel - 1] = 1;
6181 } else {
6182 ALOGE("%s: Invalid o/p channel count entered", __func__);
6183 break;
6184 }
6185 }
6186
6187 if (len > ST_MAX_LENGTH_MIXER_CONTROL) {
6188 ALOGE("%s: ERROR: Mixer control length out of bounds", __func__);
6189 goto exit;
6190 }
6191
6192 memcpy(&cust_ch_mixer_cfg[len], &ch_weightage_coeff[i][0],
6193 ip_channel_cnt);
6194 len += ip_channel_cnt;
6195 }
6196
6197 if (i != op_channel_cnt)
6198 goto exit;
6199
6200 err = mixer_ctl_set_array(ctl, cust_ch_mixer_cfg, len);
6201 if (err)
6202 ALOGE("%s: ERROR. Mixer ctl set failed", __func__);
6203
6204exit:
6205 return err;
6206}
6207
6208int platform_stdev_update_bad_mic_channel_index
6209(
6210 void *platform,
6211 int bad_mic_channel_index,
6212 bool *backend_cfg_change
6213)
6214{
6215 struct platform_data *my_data = (struct platform_data *)platform;
6216 int ret = 0;
6217
6218 *backend_cfg_change = false;
6219
6220 if (!(bad_mic_channel_index & BAD_MIC_CH_SUPPORTED_INDICES)) {
6221 ALOGE("%s: Invalid bad mic channel index 0x%x",
6222 __func__, bad_mic_channel_index);
6223 ret = -EINVAL;
6224 return ret;
6225 }
6226
6227 /* Currently bad mic index can be set once and
6228 * to only one of the supported bad indices.
6229 *
6230 * Determine if backend config change is required depending on current
6231 * channel configuration -
6232 * 4 channels - always reconfigure backend
6233 * 2 channels - reconfigure backend if index 0 or 1 goes bad
6234 * 1 channel - reconfigure backend if index 0 goes bad
6235 */
6236
6237 if (my_data->bad_mic_channel_index) {
6238 ALOGE("%s: bad mic channel index already set to 0x%x",
6239 __func__, my_data->bad_mic_channel_index);
6240 ret = -EINVAL;
6241 return ret;
6242 }
6243
6244 if (popcount(bad_mic_channel_index) > 1) {
6245 ALOGE("%s: bad mic channel index popcount more than one 0x%x",
6246 __func__, bad_mic_channel_index);
6247 ret = -EINVAL;
6248 return ret;
6249 }
6250
6251 switch (my_data->codec_backend_cfg.channel_count) {
6252 case SOUND_TRIGGER_CHANNEL_MODE_QUAD:
6253 case SOUND_TRIGGER_CHANNEL_MODE_TRI:
6254 *backend_cfg_change = true;
6255 break;
6256 case SOUND_TRIGGER_CHANNEL_MODE_STEREO:
6257 if ((bad_mic_channel_index == BAD_MIC_CH_INDEX_0) ||
6258 (bad_mic_channel_index == BAD_MIC_CH_INDEX_1))
6259 *backend_cfg_change = true;
6260 break;
6261 case SOUND_TRIGGER_CHANNEL_MODE_MONO:
6262 if (bad_mic_channel_index == BAD_MIC_CH_INDEX_0)
6263 *backend_cfg_change = true;
6264 break;
6265 default:
6266 break;
6267 }
6268
6269 my_data->bad_mic_channel_index = bad_mic_channel_index;
6270 ALOGV("%s: Bad mic channel index set to 0x%x, backend cfg change %d",
6271 __func__, my_data->bad_mic_channel_index, *backend_cfg_change);
6272 return ret;
6273}
6274
6275bool platform_stdev_check_backends_match
6276(
6277 void *platform __unused,
6278 st_exec_mode_t exec_mode1,
6279 st_device_t st_device1,
6280 st_exec_mode_t exec_mode2,
6281 st_device_t st_device2
6282)
6283{
6284 bool match = false;
6285
6286 if ((st_device1 < ST_DEVICE_MIN) || (st_device1 >= ST_DEVICE_MAX)) {
6287 ALOGE("%s: Invalid st_device1 = %d", __func__, st_device1);
6288 return match;
6289 }
6290
6291 if ((st_device2 < ST_DEVICE_MIN) || (st_device2 >= ST_DEVICE_MAX)) {
6292 ALOGE("%s: Invalid st_device2 = %d", __func__, st_device2);
6293 return match;
6294 }
6295
6296 char *be_itf1 = st_device_backend_table[exec_mode1][st_device1];
6297 char *be_itf2 = st_device_backend_table[exec_mode2][st_device2];
6298
6299 if ((NULL != be_itf1) && (NULL != be_itf2)) {
6300 if (!strcmp(be_itf1, be_itf2))
6301 match = true;
6302 }
6303 ALOGV("%s: be_itf1 %s, be_itf2 %s match %d", __func__, be_itf1, be_itf2, match);
6304
6305 return match;
6306}
6307
6308void platform_stdev_check_and_append_usecase
6309(
Quinn Male1c764fd2019-10-18 13:29:40 -07006310 void *platform,
6311 char *use_case
Quinn Male2e883752019-03-22 11:28:54 -07006312)
6313{
Quinn Male1c764fd2019-10-18 13:29:40 -07006314 struct platform_data *my_data = (struct platform_data *)platform;
6315
6316 if (!my_data->stdev->lpi_enable)
Quinn Male2e883752019-03-22 11:28:54 -07006317 strlcat(use_case, " preproc", USECASE_STRING_SIZE);
6318
6319 ALOGV("%s: return usecase %s", __func__, use_case);
6320}
6321
6322void platform_stdev_check_and_update_ec_ref_config
6323(
6324 void *platform __unused,
6325 struct st_vendor_info *v_info,
6326 struct pcm_config *config
6327)
6328{
6329 /* Update channels with ec ref channel count in vendor info */
6330 if (v_info)
6331 config->channels = v_info->ec_ref_channel_cnt;
6332}
6333
6334void platform_stdev_get_lpma_config
6335(
6336 void *platform,
6337 struct st_lpma_config **lpma_cfg
6338)
6339{
6340 if (lpma_cfg != NULL)
6341 *lpma_cfg = &((struct platform_data *)platform)->lpma_cfg;
6342}
6343static int platform_stdev_get_meta_info_key
6344(
6345 void *platform,
6346 char *mod_name
6347)
6348{
6349 struct listnode *node;
6350 struct meta_key_list *key_info;
6351 struct platform_data *pdata = (struct platform_data *)platform;
6352 int key = 0;
6353
6354 ALOGV("%s: for module %s", __func__, mod_name);
6355
6356 list_for_each(node, &pdata->acdb_meta_key_list) {
6357 key_info = node_to_item(node, struct meta_key_list, list);
6358 if (strcmp(key_info->name, mod_name) == 0) {
6359 key = key_info->cal_info.nKey;
6360 ALOGD("%s: Found key %d for module %s", __func__, key, mod_name);
6361 break;
6362 }
6363 }
6364 return key;
6365}
6366
6367int platform_stdev_get_license_by_product
6368(
6369 void *platform,
6370 const char* product_name,
6371 int *product_id,
6372 char* product_license
6373)
6374{
6375 int ret = 0;
6376 int id = 0;
6377 acdb_audio_cal_cfg_t cal;
6378 uint32_t param_len = ST_LICENSE_STR_MAX_LENGTH;
6379
6380 struct platform_data *my_data = (struct platform_data *)platform;
6381 if (NULL == platform || NULL == product_name || NULL == product_id) {
6382 ALOGE("%s: Invalid input parameters %d ",__func__, __LINE__);
6383 ret = -EINVAL;
6384 goto on_error;
6385 }
6386
6387 *product_id = 0;
6388 id = platform_stdev_get_meta_info_key(platform, (char*)product_name);
6389 if(0 == id) {
6390 ALOGE("%s:Id not found for %s", __func__, product_name);
6391 ret = -EINVAL;
6392 goto on_error;
6393 }
6394
6395 ALOGD("%s: Found Id[%d] for %s", __func__, id, product_name);
6396 if(NULL == my_data->acdb_get_audio_cal) {
6397 ALOGE("%s: acdb_get_audio_cal is NULL.",__func__);
6398 ret = -ENOSYS;
6399 goto on_error;
6400 }
6401
6402 memset(&cal, 0, sizeof(cal));
6403 cal.persist = 1;
6404 cal.cal_type = AUDIO_CORE_METAINFO_CAL_TYPE;
6405 cal.acdb_dev_id = (uint32_t)id;
6406 ret = my_data->acdb_get_audio_cal((void*)&cal, (void*)product_license, &param_len);
6407 if (ret) {
6408 ALOGE("%s: License not found for %s", __func__, product_name);
6409 ret = -EINVAL;
6410 goto on_error;
6411 }
6412
6413 ALOGD("%s: Got Length[%d] License[%s]", __func__, param_len, product_license );
6414 *product_id = id;
6415 return 0;
6416
6417on_error:
6418
6419 return ret;
6420
6421}
6422
6423int platform_stdev_set_acdb_metainfo_key
6424(
6425 void *platform,
6426 char *name,
6427 int key
6428)
6429{
6430 struct meta_key_list *key_info;
6431 struct platform_data *pdata = (struct platform_data *)platform;
6432
6433 key_info = (struct meta_key_list *)calloc(1, sizeof(struct meta_key_list));
6434 if (!key_info) {
6435 ALOGE("%s: Could not allocate memory for key %d", __func__, key);
6436 return -ENOMEM;
6437 }
6438
6439 key_info->cal_info.nKey = key;
6440 strlcpy(key_info->name, name, sizeof(key_info->name));
6441 list_add_tail(&pdata->acdb_meta_key_list, &key_info->list);
6442 ALOGD("%s: successfully added module %s and key %d to the list", __func__,
6443 key_info->name, key_info->cal_info.nKey);
6444 return 0;
6445}
6446
6447/* process acdb meta info key value */
6448static void process_stdev_acdb_metainfo_key
6449(
6450 void *platform,
6451 const XML_Char **attr
6452)
6453{
6454 if (strcmp(attr[0], "name") != 0) {
6455 ALOGE("%s: 'name' not found", __func__);
6456 goto on_error;
6457 }
6458
6459 if (strcmp(attr[2], "value") != 0) {
6460 ALOGE("%s: 'value' not found", __func__);
6461 goto on_error;
6462 }
6463
6464 int key = atoi((char *)attr[3]);
6465
6466 if (platform_stdev_set_acdb_metainfo_key(platform, (char*)attr[1], key) < 0) {
6467 ALOGE("%s: key %d was not set!", __func__, key);
6468 goto on_error;
6469 }
6470on_error:
6471 return;
6472}
6473
6474inline int platform_stdev_get_xml_version(void *platform)
6475{
6476 struct platform_data *my_data = (struct platform_data *)platform;
6477
6478 return my_data->xml_version;
6479}
6480
6481int platform_stdev_derive_mixer_ctl_from_backend
6482(
6483 void *platform,
6484 char *mixer_ctl_name
6485)
6486{
6487 struct platform_data *my_data = (struct platform_data *)platform;
6488
6489 if (mixer_ctl_name == NULL) {
6490 ALOGE("%s: ERROR. mixer_ctl_name is NULL", __func__);
6491 return -EINVAL;
6492 }
6493
6494 if (!strcmp(my_data->backend_dai_name, "")) {
6495 ALOGE("%s: ERROR. No backend dai name set", __func__);
6496 return -EINVAL;
6497 }
6498
6499 strlcat(mixer_ctl_name, " ", MIXER_PATH_MAX_LENGTH);
6500 strlcat(mixer_ctl_name, my_data->backend_dai_name, MIXER_PATH_MAX_LENGTH);
6501
6502 return 0;
6503}