blob: f8a0b56db1b6b8111dce483bc648891a56e908a6 [file] [log] [blame]
Dhanalakshmi Siddani0f1dfd52019-01-09 12:38:13 +05301/* Copyright (c) 2013-2014, 2016-2019 The Linux Foundation. All rights reserved.
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -07002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29#define LOG_TAG "soundtrigger"
30/* #define LOG_NDEBUG 0 */
31#define LOG_NDDEBUG 0
32
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -070033#include <errno.h>
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -070034#include <stdbool.h>
35#include <stdlib.h>
36#include <dlfcn.h>
Jiyong Parke69fc722017-06-29 15:15:58 +090037#include <pthread.h>
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -070038#include <cutils/log.h>
Vinay Vermaaddfa4a2018-04-29 14:03:38 +053039#include <unistd.h>
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -070040#include "audio_hw.h"
41#include "audio_extn.h"
42#include "platform.h"
43#include "platform_api.h"
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053044
45/*-------------------- Begin: AHAL-STHAL Interface ---------------------------*/
46/*
47 * Maintain the proprietary interface between AHAL and STHAL locally to avoid
48 * the compilation dependency of interface header file from STHAL.
49 */
50
51#define MAKE_HAL_VERSION(maj, min) ((((maj) & 0xff) << 8) | ((min) & 0xff))
52#define MAJOR_VERSION(ver) (((ver) & 0xff00) >> 8)
53#define MINOR_VERSION(ver) ((ver) & 0x00ff)
54
55/* Proprietary interface version used for compatibility with STHAL */
56#define STHAL_PROP_API_VERSION_1_0 MAKE_HAL_VERSION(1, 0)
kunleizef40adb2018-12-28 17:50:23 +080057#define STHAL_PROP_API_VERSION_1_1 MAKE_HAL_VERSION(1, 1)
58#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_1
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053059
60#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
61#define ST_DEVICE_HANDSET_MIC 1
62
63typedef enum {
64 ST_EVENT_SESSION_REGISTER,
65 ST_EVENT_SESSION_DEREGISTER,
66 ST_EVENT_START_KEEP_ALIVE,
67 ST_EVENT_STOP_KEEP_ALIVE,
kunleizef40adb2018-12-28 17:50:23 +080068 ST_EVENT_UPDATE_ECHO_REF
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053069} sound_trigger_event_type_t;
70
71typedef enum {
72 AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
73 AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
74 AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE,
75 AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE,
76 AUDIO_EVENT_STOP_LAB,
77 AUDIO_EVENT_SSR,
78 AUDIO_EVENT_NUM_ST_SESSIONS,
79 AUDIO_EVENT_READ_SAMPLES,
80 AUDIO_EVENT_DEVICE_CONNECT,
81 AUDIO_EVENT_DEVICE_DISCONNECT,
82 AUDIO_EVENT_SVA_EXEC_MODE,
83 AUDIO_EVENT_SVA_EXEC_MODE_STATUS,
84 AUDIO_EVENT_CAPTURE_STREAM_INACTIVE,
85 AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
Zhou Songc1088ea2018-06-12 00:17:29 +080086 AUDIO_EVENT_BATTERY_STATUS_CHANGED,
kunleizef40adb2018-12-28 17:50:23 +080087 AUDIO_EVENT_GET_PARAM,
88 AUDIO_EVENT_UPDATE_ECHO_REF
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053089} audio_event_type_t;
90
91typedef enum {
92 USECASE_TYPE_PCM_PLAYBACK,
93 USECASE_TYPE_PCM_CAPTURE,
94 USECASE_TYPE_VOICE_CALL,
95 USECASE_TYPE_VOIP_CALL,
96} audio_stream_usecase_type_t;
97
98typedef enum {
99 SND_CARD_STATUS_OFFLINE,
100 SND_CARD_STATUS_ONLINE,
101 CPE_STATUS_OFFLINE,
102 CPE_STATUS_ONLINE
103} ssr_event_status_t;
104
105struct sound_trigger_session_info {
106 void* p_ses; /* opaque pointer to st_session obj */
107 int capture_handle;
108 struct pcm *pcm;
109 struct pcm_config config;
110};
111
112struct audio_read_samples_info {
113 struct sound_trigger_session_info *ses_info;
114 void *buf;
115 size_t num_bytes;
116};
117
118struct audio_hal_usecase {
119 audio_stream_usecase_type_t type;
120};
121
122struct sound_trigger_event_info {
123 struct sound_trigger_session_info st_ses;
kunleizef40adb2018-12-28 17:50:23 +0800124 bool st_ec_ref_enabled;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530125};
126typedef struct sound_trigger_event_info sound_trigger_event_info_t;
127
128struct sound_trigger_device_info {
129 int device;
130};
131
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530132struct sound_trigger_get_param_data {
133 char *param;
134 int sm_handle;
135 struct str_parms *reply;
136};
137
138
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530139struct audio_event_info {
140 union {
141 ssr_event_status_t status;
142 int value;
143 struct sound_trigger_session_info ses_info;
144 struct audio_read_samples_info aud_info;
145 char str_value[ST_EVENT_CONFIG_MAX_STR_VALUE];
146 struct audio_hal_usecase usecase;
kunleizef40adb2018-12-28 17:50:23 +0800147 bool audio_ec_ref_enabled;
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530148 struct sound_trigger_get_param_data st_get_param_data;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530149 } u;
150 struct sound_trigger_device_info device_info;
151};
152typedef struct audio_event_info audio_event_info_t;
153/* STHAL callback which is called by AHAL */
154typedef int (*sound_trigger_hw_call_back_t)(audio_event_type_t,
155 struct audio_event_info*);
156
157/*---------------- End: AHAL-STHAL Interface ----------------------------------*/
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700158
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +0530159#ifdef DYNAMIC_LOG_ENABLED
160#include <log_xml_parser.h>
161#define LOG_MASK HAL_MOD_FILE_SND_TRIGGER
162#include <log_utils.h>
163#endif
164
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700165#define XSTR(x) STR(x)
166#define STR(x) #x
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530167#define MAX_LIBRARY_PATH 100
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700168
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530169#define DLSYM(handle, ptr, symbol, err) \
170do {\
Venkatesh Mangalappalibcc684c2018-04-06 14:58:44 -0700171 ptr = dlsym(handle, #symbol); \
172 if (ptr == NULL) {\
173 ALOGW("%s: %s not found. %s", __func__, #symbol, dlerror());\
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530174 err = -ENODEV;\
175 }\
176} while(0)
177
178#ifdef __LP64__
179#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib64/hw/sound_trigger.primary.%s.so"
180#else
181#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib/hw/sound_trigger.primary.%s.so"
182#endif
183
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530184#define SVA_PARAM_DIRECTION_OF_ARRIVAL "st_direction_of_arrival"
185#define SVA_PARAM_CHANNEL_INDEX "st_channel_index"
186
187#define MAX_STR_LENGTH_FFV_PARAMS 30
188#define MAX_FFV_SESSION_ID 100
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530189/*
190 * Current proprietary API version used by AHAL. Queried by STHAL
191 * for compatibility check with AHAL
192 */
193const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;
194
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700195struct sound_trigger_info {
196 struct sound_trigger_session_info st_ses;
197 bool lab_stopped;
198 struct listnode list;
199};
200
201struct sound_trigger_audio_device {
202 void *lib_handle;
203 struct audio_device *adev;
204 sound_trigger_hw_call_back_t st_callback;
205 struct listnode st_ses_list;
206 pthread_mutex_t lock;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530207 unsigned int sthal_prop_api_version;
kunleizef40adb2018-12-28 17:50:23 +0800208 bool st_ec_ref_enabled;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700209};
210
211static struct sound_trigger_audio_device *st_dev;
212
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530213#if LINUX_ENABLED
214static void get_library_path(char *lib_path)
215{
216 snprintf(lib_path, MAX_LIBRARY_PATH,
Manish Dewangan6a36d002017-10-09 14:11:00 +0530217 "sound_trigger.primary.default.so");
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530218}
219#else
220static void get_library_path(char *lib_path)
221{
222 snprintf(lib_path, MAX_LIBRARY_PATH,
David Ng06ccd872017-03-15 11:39:33 -0700223 "/vendor/lib/hw/sound_trigger.primary.%s.so",
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530224 XSTR(SOUND_TRIGGER_PLATFORM_NAME));
225}
226#endif
227
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700228static struct sound_trigger_info *
229get_sound_trigger_info(int capture_handle)
230{
231 struct sound_trigger_info *st_ses_info = NULL;
232 struct listnode *node;
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700233 ALOGV("%s: list empty %d capture_handle %d", __func__,
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700234 list_empty(&st_dev->st_ses_list), capture_handle);
235 list_for_each(node, &st_dev->st_ses_list) {
236 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
237 if (st_ses_info->st_ses.capture_handle == capture_handle)
238 return st_ses_info;
239 }
240 return NULL;
241}
242
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530243static int populate_usecase(struct audio_hal_usecase *usecase,
244 struct audio_usecase *uc_info)
245{
246 int status = 0;
247
248 switch(uc_info->type) {
249 case PCM_PLAYBACK:
250 if (uc_info->id == USECASE_AUDIO_PLAYBACK_VOIP)
251 usecase->type = USECASE_TYPE_VOIP_CALL;
252 else
253 usecase->type = USECASE_TYPE_PCM_PLAYBACK;
254 break;
255
256 case PCM_CAPTURE:
257 if (uc_info->id == USECASE_AUDIO_RECORD_VOIP)
258 usecase->type = USECASE_TYPE_VOIP_CALL;
259 else
260 usecase->type = USECASE_TYPE_PCM_CAPTURE;
261 break;
262
263 case VOICE_CALL:
264 usecase->type = USECASE_TYPE_VOICE_CALL;
265 break;
266
267 default:
268 ALOGE("%s: unsupported usecase type %d", __func__, uc_info->type);
269 status = -EINVAL;
270 }
271 return status;
272}
273
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530274static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
275{
276 if (!parms)
277 return;
278
279 audio_extn_sound_trigger_set_parameters(NULL, parms);
280 return;
281}
282
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700283int audio_hw_call_back(sound_trigger_event_type_t event,
284 sound_trigger_event_info_t* config)
285{
286 int status = 0;
287 struct sound_trigger_info *st_ses_info;
288
289 if (!st_dev)
290 return -EINVAL;
291
292 pthread_mutex_lock(&st_dev->lock);
293 switch (event) {
294 case ST_EVENT_SESSION_REGISTER:
295 if (!config) {
296 ALOGE("%s: NULL config", __func__);
297 status = -EINVAL;
298 break;
299 }
300 st_ses_info= calloc(1, sizeof(struct sound_trigger_info ));
301 if (!st_ses_info) {
302 ALOGE("%s: st_ses_info alloc failed", __func__);
303 status = -ENOMEM;
304 break;
305 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700306 memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
307 ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
308 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700309 list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
310 break;
311
Surendar Karka59c51072017-12-13 11:25:57 +0530312 case ST_EVENT_START_KEEP_ALIVE:
313 pthread_mutex_unlock(&st_dev->lock);
314 pthread_mutex_lock(&st_dev->adev->lock);
315 audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
316 pthread_mutex_unlock(&st_dev->adev->lock);
317 goto done;
318
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700319 case ST_EVENT_SESSION_DEREGISTER:
320 if (!config) {
321 ALOGE("%s: NULL config", __func__);
322 status = -EINVAL;
323 break;
324 }
325 st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
326 if (!st_ses_info) {
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700327 ALOGE("%s: st session opaque ptr %p not in the list!", __func__, config->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700328 status = -EINVAL;
329 break;
330 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700331 ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
332 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700333 list_remove(&st_ses_info->list);
334 free(st_ses_info);
335 break;
Surendar Karka59c51072017-12-13 11:25:57 +0530336
337 case ST_EVENT_STOP_KEEP_ALIVE:
338 pthread_mutex_unlock(&st_dev->lock);
339 pthread_mutex_lock(&st_dev->adev->lock);
340 audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
341 pthread_mutex_unlock(&st_dev->adev->lock);
342 goto done;
343
kunleizef40adb2018-12-28 17:50:23 +0800344 case ST_EVENT_UPDATE_ECHO_REF:
345 if (!config) {
346 ALOGE("%s: NULL config", __func__);
347 status = -EINVAL;
348 break;
349 }
350 st_dev->st_ec_ref_enabled = config->st_ec_ref_enabled;
351 break;
352
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700353 default:
354 ALOGW("%s: Unknown event %d", __func__, event);
355 break;
356 }
357 pthread_mutex_unlock(&st_dev->lock);
Surendar Karka59c51072017-12-13 11:25:57 +0530358done:
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700359 return status;
360}
361
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700362int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
363 size_t bytes)
364{
365 int ret = -1;
366 struct sound_trigger_info *st_info = NULL;
367 audio_event_info_t event;
368
369 if (!st_dev)
370 return ret;
371
372 if (!in->is_st_session_active) {
373 ALOGE(" %s: Sound trigger is not active", __func__);
374 goto exit;
375 }
376 if(in->standby)
377 in->standby = false;
378
379 pthread_mutex_lock(&st_dev->lock);
380 st_info = get_sound_trigger_info(in->capture_handle);
381 pthread_mutex_unlock(&st_dev->lock);
382 if (st_info) {
383 event.u.aud_info.ses_info = &st_info->st_ses;
384 event.u.aud_info.buf = buffer;
385 event.u.aud_info.num_bytes = bytes;
386 ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
387 }
388
389exit:
390 if (ret) {
391 if (-ENETRESET == ret)
392 in->is_st_session_active = false;
393 memset(buffer, 0, bytes);
394 ALOGV("%s: read failed status %d - sleep", __func__, ret);
395 usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
396 in->config.rate));
397 }
398 return ret;
399}
400
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700401void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
402{
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700403 struct sound_trigger_info *st_ses_info = NULL;
404 audio_event_info_t event;
405
Mingming Yinfd7607b2016-01-22 12:48:44 -0800406 if (!st_dev || !in || !in->is_st_session_active)
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700407 return;
408
409 pthread_mutex_lock(&st_dev->lock);
410 st_ses_info = get_sound_trigger_info(in->capture_handle);
Bharath Ramachandramurthy5baa6a52014-10-21 11:18:49 -0700411 pthread_mutex_unlock(&st_dev->lock);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700412 if (st_ses_info) {
413 event.u.ses_info = st_ses_info->st_ses;
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700414 ALOGV("%s: AUDIO_EVENT_STOP_LAB st sess %p", __func__, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700415 st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
Mingming Yinfd7607b2016-01-22 12:48:44 -0800416 in->is_st_session_active = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700417 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700418}
419void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in)
420{
421 struct sound_trigger_info *st_ses_info = NULL;
422 struct listnode *node;
423
424 if (!st_dev || !in)
425 return;
426
427 pthread_mutex_lock(&st_dev->lock);
428 in->is_st_session = false;
429 ALOGV("%s: list %d capture_handle %d", __func__,
430 list_empty(&st_dev->st_ses_list), in->capture_handle);
431 list_for_each(node, &st_dev->st_ses_list) {
432 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
433 if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700434 in->config = st_ses_info->st_ses.config;
435 in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
436 in->is_st_session = true;
Bharath Ramachandramurthy837535b2015-02-05 14:27:59 -0800437 in->is_st_session_active = true;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700438 ALOGD("%s: capture_handle %d is sound trigger", __func__, in->capture_handle);
439 break;
440 }
441 }
442 pthread_mutex_unlock(&st_dev->lock);
443}
444
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530445
kunleizef40adb2018-12-28 17:50:23 +0800446bool audio_extn_sound_trigger_check_ec_ref_enable()
447{
448 bool ret = false;
449
450 if (!st_dev) {
451 ALOGE("%s: st_dev NULL", __func__);
452 return ret;
453 }
454
455 pthread_mutex_lock(&st_dev->lock);
456 if (st_dev->st_ec_ref_enabled) {
457 ret = true;
458 ALOGD("%s: EC Reference is enabled", __func__);
459 } else {
460 ALOGD("%s: EC Reference is disabled", __func__);
461 }
462 pthread_mutex_unlock(&st_dev->lock);
463
464 return ret;
465}
466
467void audio_extn_sound_trigger_update_ec_ref_status(bool on)
468{
469 struct audio_event_info ev_info;
470
471 if (!st_dev) {
472 ALOGE("%s: st_dev NULL", __func__);
473 return;
474 }
475
476 ev_info.u.audio_ec_ref_enabled = on;
477 st_dev->st_callback(AUDIO_EVENT_UPDATE_ECHO_REF, &ev_info);
478 ALOGD("%s: update audio echo ref status %s",__func__,
479 ev_info.u.audio_ec_ref_enabled == true ? "true" : "false");
480}
481
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700482void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
483 st_event_type_t event)
484{
485 bool raise_event = false;
486 int device_type = -1;
487
488 if (!st_dev)
489 return;
490
491 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
492 snd_device < SND_DEVICE_OUT_END)
493 device_type = PCM_PLAYBACK;
494 else if (snd_device >= SND_DEVICE_IN_BEGIN &&
495 snd_device < SND_DEVICE_IN_END)
496 device_type = PCM_CAPTURE;
497 else {
498 ALOGE("%s: invalid device 0x%x, for event %d",
499 __func__, snd_device, event);
500 return;
501 }
502
503 raise_event = platform_sound_trigger_device_needs_event(snd_device);
504 ALOGI("%s: device 0x%x of type %d for Event %d, with Raise=%d",
505 __func__, snd_device, device_type, event, raise_event);
506 if (raise_event && (device_type == PCM_CAPTURE)) {
507 switch(event) {
508 case ST_EVENT_SND_DEVICE_FREE:
509 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE, NULL);
510 break;
511 case ST_EVENT_SND_DEVICE_BUSY:
512 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE, NULL);
513 break;
514 default:
515 ALOGW("%s:invalid event %d for device 0x%x",
516 __func__, event, snd_device);
517 }
518 }/*Events for output device, if required can be placed here in else*/
519}
520
521void audio_extn_sound_trigger_update_stream_status(struct audio_usecase *uc_info,
522 st_event_type_t event)
523{
524 bool raise_event = false;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530525 struct audio_event_info ev_info;
526 audio_event_type_t ev;
527 /*Initialize to invalid device*/
528 ev_info.device_info.device = -1;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700529
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530530 if (!st_dev)
531 return;
532
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700533 if (uc_info == NULL) {
534 ALOGE("%s: usecase is NULL!!!", __func__);
535 return;
536 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700537
Dhanalakshmi Siddani24e9ad52018-06-15 14:47:20 +0530538 if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
539 (uc_info->type != PCM_PLAYBACK))
540 return;
541
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530542 raise_event = platform_sound_trigger_usecase_needs_event(uc_info->id);
543 ALOGD("%s: uc_info->id %d of type %d for Event %d, with Raise=%d",
544 __func__, uc_info->id, uc_info->type, event, raise_event);
545 if (raise_event) {
546 if (uc_info->type == PCM_PLAYBACK) {
Zhou Songc1088ea2018-06-12 00:17:29 +0800547 if (uc_info->stream.out)
548 ev_info.device_info.device = uc_info->stream.out->devices;
549 else
550 ev_info.device_info.device = AUDIO_DEVICE_OUT_SPEAKER;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530551 switch(event) {
552 case ST_EVENT_STREAM_FREE:
Zhou Songc1088ea2018-06-12 00:17:29 +0800553 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530554 break;
555 case ST_EVENT_STREAM_BUSY:
Zhou Songc1088ea2018-06-12 00:17:29 +0800556 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530557 break;
558 default:
559 ALOGW("%s:invalid event %d, for usecase %d",
560 __func__, event, uc_info->id);
561 }
Revathi Uddaraju9f99ddd2018-05-03 12:01:38 +0530562 } else if ((uc_info->type == PCM_CAPTURE) || (uc_info->type == VOICE_CALL)) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530563 if (event == ST_EVENT_STREAM_BUSY)
564 ev = AUDIO_EVENT_CAPTURE_STREAM_ACTIVE;
565 else
566 ev = AUDIO_EVENT_CAPTURE_STREAM_INACTIVE;
567 if (!populate_usecase(&ev_info.u.usecase, uc_info)) {
568 ALOGD("%s: send event %d: usecase id %d, type %d",
569 __func__, ev, uc_info->id, uc_info->type);
570 st_dev->st_callback(ev, &ev_info);
571 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700572 }
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530573 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700574}
575
Zhou Songc1088ea2018-06-12 00:17:29 +0800576void audio_extn_sound_trigger_update_battery_status(bool charging)
577{
578 struct audio_event_info ev_info;
579
580 if (!st_dev || st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
581 return;
582
583 ev_info.u.value = charging;
584 st_dev->st_callback(AUDIO_EVENT_BATTERY_STATUS_CHANGED, &ev_info);
585}
586
587
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700588void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
589 struct str_parms *params)
590{
591 audio_event_info_t event;
592 char value[32];
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700593 int ret, val;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700594
595 if(!st_dev || !params) {
596 ALOGE("%s: str_params NULL", __func__);
597 return;
598 }
599
600 ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
601 sizeof(value));
602 if (ret > 0) {
603 if (strstr(value, "OFFLINE")) {
604 event.u.status = SND_CARD_STATUS_OFFLINE;
605 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
606 }
607 else if (strstr(value, "ONLINE")) {
608 event.u.status = SND_CARD_STATUS_ONLINE;
609 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
610 }
611 else
612 ALOGE("%s: unknown snd_card_status", __func__);
613 }
614
615 ret = str_parms_get_str(params, "CPE_STATUS", value, sizeof(value));
616 if (ret > 0) {
617 if (strstr(value, "OFFLINE")) {
618 event.u.status = CPE_STATUS_OFFLINE;
619 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
620 }
621 else if (strstr(value, "ONLINE")) {
622 event.u.status = CPE_STATUS_ONLINE;
623 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
624 }
625 else
626 ALOGE("%s: unknown CPE status", __func__);
627 }
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700628
629 ret = str_parms_get_int(params, "SVA_NUM_SESSIONS", &val);
630 if (ret >= 0) {
631 event.u.value = val;
632 st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
633 }
Quinn male73dd1fd2016-12-02 10:47:11 -0800634
635 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
Dhanalakshmi Siddani0f1dfd52019-01-09 12:38:13 +0530636 if ((ret >= 0) && (audio_is_input_device(val) ||
637 (val == AUDIO_DEVICE_OUT_LINE))) {
Quinn male73dd1fd2016-12-02 10:47:11 -0800638 event.u.value = val;
639 st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
640 }
641
642 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
Dhanalakshmi Siddani0f1dfd52019-01-09 12:38:13 +0530643 if ((ret >= 0) && (audio_is_input_device(val) ||
644 (val == AUDIO_DEVICE_OUT_LINE))) {
Quinn male73dd1fd2016-12-02 10:47:11 -0800645 event.u.value = val;
646 st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
647 }
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530648
649 ret = str_parms_get_str(params, "SVA_EXEC_MODE", value, sizeof(value));
650 if (ret >= 0) {
651 strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
652 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
653 }
654}
655
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530656static int extract_sm_handle(const char *keys, char *paramstr) {
657 char *tmpstr, *token;
658 char *inputstr = NULL;
659 int value = -EINVAL;
660
661 if (keys == NULL || paramstr == NULL)
662 goto exit;
663
664 inputstr = strdup(keys);
665 token =strtok_r(inputstr,":",&tmpstr);
666
667 if (token == NULL)
668 goto exit;
669
670 ALOGD("%s input string <%s> param string <%s>", __func__, keys,token);
671 strlcpy(paramstr, token, MAX_STR_LENGTH_FFV_PARAMS);
672 token =strtok_r(NULL,":=",&tmpstr);
673
674 if (token == NULL)
675 goto exit;
676
677 value = atoi(token);
678 if (value > 0 && value < MAX_FFV_SESSION_ID)
679 ALOGD(" %s SVA sm handle<=%d>",__func__, value);
680
681exit:
682 if (inputstr != NULL)
683 free(inputstr);
684
685 return value;
686}
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530687void audio_extn_sound_trigger_get_parameters(const struct audio_device *adev __unused,
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530688 struct str_parms *query,
689 struct str_parms *reply)
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530690{
691 audio_event_info_t event;
692 int ret;
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530693 char value[32], paramstr[MAX_STR_LENGTH_FFV_PARAMS];
694
695 ALOGD("%s input string<%s>", __func__, str_parms_to_str(query));
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530696
697 ret = str_parms_get_str(query, "SVA_EXEC_MODE_STATUS", value,
698 sizeof(value));
699 if (ret >= 0) {
700 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE_STATUS, &event);
701 str_parms_add_int(reply, "SVA_EXEC_MODE_STATUS", event.u.value);
702 }
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530703
704 ret = extract_sm_handle(str_parms_to_str(query), paramstr);
705
706 if ((ret >= 0) && !strncmp(paramstr, SVA_PARAM_DIRECTION_OF_ARRIVAL,
707 MAX_STR_LENGTH_FFV_PARAMS)) {
708 event.u.st_get_param_data.sm_handle = ret;
709 event.u.st_get_param_data.param = SVA_PARAM_DIRECTION_OF_ARRIVAL;
710 event.u.st_get_param_data.reply = reply;
711 st_dev->st_callback(AUDIO_EVENT_GET_PARAM, &event);
712 } else if ((ret >=0) && !strncmp(paramstr, SVA_PARAM_CHANNEL_INDEX,
713 MAX_STR_LENGTH_FFV_PARAMS)) {
714 event.u.st_get_param_data.sm_handle = ret;
715 event.u.st_get_param_data.param = SVA_PARAM_CHANNEL_INDEX;
716 event.u.st_get_param_data.reply = reply;
717 st_dev->st_callback(AUDIO_EVENT_GET_PARAM, &event);
718 }
719
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700720}
721
722int audio_extn_sound_trigger_init(struct audio_device *adev)
723{
724 int status = 0;
725 char sound_trigger_lib[100];
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530726 void *sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700727
728 ALOGI("%s: Enter", __func__);
729
730 st_dev = (struct sound_trigger_audio_device*)
731 calloc(1, sizeof(struct sound_trigger_audio_device));
732 if (!st_dev) {
733 ALOGE("%s: ERROR. sound trigger alloc failed", __func__);
734 return -ENOMEM;
735 }
736
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530737 get_library_path(sound_trigger_lib);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700738 st_dev->lib_handle = dlopen(sound_trigger_lib, RTLD_NOW);
739
740 if (st_dev->lib_handle == NULL) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530741 ALOGE("%s: error %s", __func__, dlerror());
742 status = -ENODEV;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700743 goto cleanup;
744 }
745 ALOGI("%s: DLOPEN successful for %s", __func__, sound_trigger_lib);
746
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530747 DLSYM(st_dev->lib_handle, st_dev->st_callback, sound_trigger_hw_call_back,
748 status);
749 if (status)
750 goto cleanup;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700751
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530752 DLSYM(st_dev->lib_handle, sthal_prop_api_version,
753 sthal_prop_api_version, status);
754 if (status) {
755 st_dev->sthal_prop_api_version = 0;
756 status = 0; /* passthru for backward compability */
757 } else {
758 st_dev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
759 if (MAJOR_VERSION(st_dev->sthal_prop_api_version) !=
760 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
761 ALOGE("%s: Incompatible API versions ahal:0x%x != sthal:0x%x",
762 __func__, STHAL_PROP_API_CURRENT_VERSION,
763 st_dev->sthal_prop_api_version);
764 goto cleanup;
765 }
766 ALOGD("%s: sthal is using proprietary API version 0x%04x", __func__,
767 st_dev->sthal_prop_api_version);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700768 }
769
770 st_dev->adev = adev;
kunleizef40adb2018-12-28 17:50:23 +0800771 st_dev->st_ec_ref_enabled = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700772 list_init(&st_dev->st_ses_list);
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530773 audio_extn_snd_mon_register_listener(st_dev, stdev_snd_mon_cb);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700774
775 return 0;
776
777cleanup:
778 if (st_dev->lib_handle)
779 dlclose(st_dev->lib_handle);
780 free(st_dev);
781 st_dev = NULL;
782 return status;
783
784}
785
786void audio_extn_sound_trigger_deinit(struct audio_device *adev)
787{
788 ALOGI("%s: Enter", __func__);
789 if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530790 audio_extn_snd_mon_unregister_listener(st_dev);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700791 dlclose(st_dev->lib_handle);
792 free(st_dev);
793 st_dev = NULL;
794 }
795}