blob: 38e7ae7f2707401e228163cca51ca524a00c5c7c [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>
37#include <cutils/log.h>
Vinay Vermaaddfa4a2018-04-29 14:03:38 +053038#include <unistd.h>
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -070039#include "audio_hw.h"
40#include "audio_extn.h"
41#include "platform.h"
42#include "platform_api.h"
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053043
44/*-------------------- Begin: AHAL-STHAL Interface ---------------------------*/
45/*
46 * Maintain the proprietary interface between AHAL and STHAL locally to avoid
47 * the compilation dependency of interface header file from STHAL.
48 */
49
50#define MAKE_HAL_VERSION(maj, min) ((((maj) & 0xff) << 8) | ((min) & 0xff))
51#define MAJOR_VERSION(ver) (((ver) & 0xff00) >> 8)
52#define MINOR_VERSION(ver) ((ver) & 0x00ff)
53
54/* Proprietary interface version used for compatibility with STHAL */
55#define STHAL_PROP_API_VERSION_1_0 MAKE_HAL_VERSION(1, 0)
kunleizef40adb2018-12-28 17:50:23 +080056#define STHAL_PROP_API_VERSION_1_1 MAKE_HAL_VERSION(1, 1)
57#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_1
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053058
59#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
60#define ST_DEVICE_HANDSET_MIC 1
61
62typedef enum {
63 ST_EVENT_SESSION_REGISTER,
64 ST_EVENT_SESSION_DEREGISTER,
65 ST_EVENT_START_KEEP_ALIVE,
66 ST_EVENT_STOP_KEEP_ALIVE,
kunleizef40adb2018-12-28 17:50:23 +080067 ST_EVENT_UPDATE_ECHO_REF
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053068} sound_trigger_event_type_t;
69
70typedef enum {
71 AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
72 AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
73 AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE,
74 AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE,
75 AUDIO_EVENT_STOP_LAB,
76 AUDIO_EVENT_SSR,
77 AUDIO_EVENT_NUM_ST_SESSIONS,
78 AUDIO_EVENT_READ_SAMPLES,
79 AUDIO_EVENT_DEVICE_CONNECT,
80 AUDIO_EVENT_DEVICE_DISCONNECT,
81 AUDIO_EVENT_SVA_EXEC_MODE,
82 AUDIO_EVENT_SVA_EXEC_MODE_STATUS,
83 AUDIO_EVENT_CAPTURE_STREAM_INACTIVE,
84 AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
Zhou Songc1088ea2018-06-12 00:17:29 +080085 AUDIO_EVENT_BATTERY_STATUS_CHANGED,
kunleizef40adb2018-12-28 17:50:23 +080086 AUDIO_EVENT_GET_PARAM,
87 AUDIO_EVENT_UPDATE_ECHO_REF
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053088} audio_event_type_t;
89
90typedef enum {
91 USECASE_TYPE_PCM_PLAYBACK,
92 USECASE_TYPE_PCM_CAPTURE,
93 USECASE_TYPE_VOICE_CALL,
94 USECASE_TYPE_VOIP_CALL,
95} audio_stream_usecase_type_t;
96
97typedef enum {
98 SND_CARD_STATUS_OFFLINE,
99 SND_CARD_STATUS_ONLINE,
100 CPE_STATUS_OFFLINE,
101 CPE_STATUS_ONLINE
102} ssr_event_status_t;
103
104struct sound_trigger_session_info {
105 void* p_ses; /* opaque pointer to st_session obj */
106 int capture_handle;
107 struct pcm *pcm;
108 struct pcm_config config;
109};
110
111struct audio_read_samples_info {
112 struct sound_trigger_session_info *ses_info;
113 void *buf;
114 size_t num_bytes;
115};
116
117struct audio_hal_usecase {
118 audio_stream_usecase_type_t type;
119};
120
121struct sound_trigger_event_info {
122 struct sound_trigger_session_info st_ses;
kunleizef40adb2018-12-28 17:50:23 +0800123 bool st_ec_ref_enabled;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530124};
125typedef struct sound_trigger_event_info sound_trigger_event_info_t;
126
127struct sound_trigger_device_info {
128 int device;
129};
130
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530131struct sound_trigger_get_param_data {
132 char *param;
133 int sm_handle;
134 struct str_parms *reply;
135};
136
137
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530138struct audio_event_info {
139 union {
140 ssr_event_status_t status;
141 int value;
142 struct sound_trigger_session_info ses_info;
143 struct audio_read_samples_info aud_info;
144 char str_value[ST_EVENT_CONFIG_MAX_STR_VALUE];
145 struct audio_hal_usecase usecase;
kunleizef40adb2018-12-28 17:50:23 +0800146 bool audio_ec_ref_enabled;
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530147 struct sound_trigger_get_param_data st_get_param_data;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530148 } u;
149 struct sound_trigger_device_info device_info;
150};
151typedef struct audio_event_info audio_event_info_t;
152/* STHAL callback which is called by AHAL */
153typedef int (*sound_trigger_hw_call_back_t)(audio_event_type_t,
154 struct audio_event_info*);
155
156/*---------------- End: AHAL-STHAL Interface ----------------------------------*/
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700157
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +0530158#ifdef DYNAMIC_LOG_ENABLED
159#include <log_xml_parser.h>
160#define LOG_MASK HAL_MOD_FILE_SND_TRIGGER
161#include <log_utils.h>
162#endif
163
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700164#define XSTR(x) STR(x)
165#define STR(x) #x
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530166#define MAX_LIBRARY_PATH 100
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700167
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530168#define DLSYM(handle, ptr, symbol, err) \
169do {\
Venkatesh Mangalappalibcc684c2018-04-06 14:58:44 -0700170 ptr = dlsym(handle, #symbol); \
171 if (ptr == NULL) {\
172 ALOGW("%s: %s not found. %s", __func__, #symbol, dlerror());\
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530173 err = -ENODEV;\
174 }\
175} while(0)
176
177#ifdef __LP64__
178#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib64/hw/sound_trigger.primary.%s.so"
179#else
180#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib/hw/sound_trigger.primary.%s.so"
181#endif
182
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530183#define SVA_PARAM_DIRECTION_OF_ARRIVAL "st_direction_of_arrival"
184#define SVA_PARAM_CHANNEL_INDEX "st_channel_index"
185
186#define MAX_STR_LENGTH_FFV_PARAMS 30
187#define MAX_FFV_SESSION_ID 100
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530188/*
189 * Current proprietary API version used by AHAL. Queried by STHAL
190 * for compatibility check with AHAL
191 */
192const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;
193
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700194struct sound_trigger_info {
195 struct sound_trigger_session_info st_ses;
196 bool lab_stopped;
197 struct listnode list;
198};
199
200struct sound_trigger_audio_device {
201 void *lib_handle;
202 struct audio_device *adev;
203 sound_trigger_hw_call_back_t st_callback;
204 struct listnode st_ses_list;
205 pthread_mutex_t lock;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530206 unsigned int sthal_prop_api_version;
kunleizef40adb2018-12-28 17:50:23 +0800207 bool st_ec_ref_enabled;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700208};
209
210static struct sound_trigger_audio_device *st_dev;
211
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530212#if LINUX_ENABLED
213static void get_library_path(char *lib_path)
214{
215 snprintf(lib_path, MAX_LIBRARY_PATH,
Manish Dewangan6a36d002017-10-09 14:11:00 +0530216 "sound_trigger.primary.default.so");
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530217}
218#else
219static void get_library_path(char *lib_path)
220{
221 snprintf(lib_path, MAX_LIBRARY_PATH,
David Ng06ccd872017-03-15 11:39:33 -0700222 "/vendor/lib/hw/sound_trigger.primary.%s.so",
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530223 XSTR(SOUND_TRIGGER_PLATFORM_NAME));
224}
225#endif
226
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700227static struct sound_trigger_info *
228get_sound_trigger_info(int capture_handle)
229{
230 struct sound_trigger_info *st_ses_info = NULL;
231 struct listnode *node;
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700232 ALOGV("%s: list empty %d capture_handle %d", __func__,
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700233 list_empty(&st_dev->st_ses_list), capture_handle);
234 list_for_each(node, &st_dev->st_ses_list) {
235 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
236 if (st_ses_info->st_ses.capture_handle == capture_handle)
237 return st_ses_info;
238 }
239 return NULL;
240}
241
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530242static int populate_usecase(struct audio_hal_usecase *usecase,
243 struct audio_usecase *uc_info)
244{
245 int status = 0;
246
247 switch(uc_info->type) {
248 case PCM_PLAYBACK:
249 if (uc_info->id == USECASE_AUDIO_PLAYBACK_VOIP)
250 usecase->type = USECASE_TYPE_VOIP_CALL;
251 else
252 usecase->type = USECASE_TYPE_PCM_PLAYBACK;
253 break;
254
255 case PCM_CAPTURE:
256 if (uc_info->id == USECASE_AUDIO_RECORD_VOIP)
257 usecase->type = USECASE_TYPE_VOIP_CALL;
258 else
259 usecase->type = USECASE_TYPE_PCM_CAPTURE;
260 break;
261
262 case VOICE_CALL:
263 usecase->type = USECASE_TYPE_VOICE_CALL;
264 break;
265
266 default:
267 ALOGE("%s: unsupported usecase type %d", __func__, uc_info->type);
268 status = -EINVAL;
269 }
270 return status;
271}
272
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530273static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
274{
275 if (!parms)
276 return;
277
278 audio_extn_sound_trigger_set_parameters(NULL, parms);
279 return;
280}
281
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700282int audio_hw_call_back(sound_trigger_event_type_t event,
283 sound_trigger_event_info_t* config)
284{
285 int status = 0;
286 struct sound_trigger_info *st_ses_info;
287
288 if (!st_dev)
289 return -EINVAL;
290
291 pthread_mutex_lock(&st_dev->lock);
292 switch (event) {
293 case ST_EVENT_SESSION_REGISTER:
294 if (!config) {
295 ALOGE("%s: NULL config", __func__);
296 status = -EINVAL;
297 break;
298 }
299 st_ses_info= calloc(1, sizeof(struct sound_trigger_info ));
300 if (!st_ses_info) {
301 ALOGE("%s: st_ses_info alloc failed", __func__);
302 status = -ENOMEM;
303 break;
304 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700305 memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
306 ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
307 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700308 list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
309 break;
310
Surendar Karka59c51072017-12-13 11:25:57 +0530311 case ST_EVENT_START_KEEP_ALIVE:
312 pthread_mutex_unlock(&st_dev->lock);
313 pthread_mutex_lock(&st_dev->adev->lock);
314 audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
315 pthread_mutex_unlock(&st_dev->adev->lock);
316 goto done;
317
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700318 case ST_EVENT_SESSION_DEREGISTER:
319 if (!config) {
320 ALOGE("%s: NULL config", __func__);
321 status = -EINVAL;
322 break;
323 }
324 st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
325 if (!st_ses_info) {
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700326 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 -0700327 status = -EINVAL;
328 break;
329 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700330 ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
331 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700332 list_remove(&st_ses_info->list);
333 free(st_ses_info);
334 break;
Surendar Karka59c51072017-12-13 11:25:57 +0530335
336 case ST_EVENT_STOP_KEEP_ALIVE:
337 pthread_mutex_unlock(&st_dev->lock);
338 pthread_mutex_lock(&st_dev->adev->lock);
339 audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
340 pthread_mutex_unlock(&st_dev->adev->lock);
341 goto done;
342
kunleizef40adb2018-12-28 17:50:23 +0800343 case ST_EVENT_UPDATE_ECHO_REF:
344 if (!config) {
345 ALOGE("%s: NULL config", __func__);
346 status = -EINVAL;
347 break;
348 }
349 st_dev->st_ec_ref_enabled = config->st_ec_ref_enabled;
350 break;
351
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700352 default:
353 ALOGW("%s: Unknown event %d", __func__, event);
354 break;
355 }
356 pthread_mutex_unlock(&st_dev->lock);
Surendar Karka59c51072017-12-13 11:25:57 +0530357done:
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700358 return status;
359}
360
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700361int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
362 size_t bytes)
363{
364 int ret = -1;
365 struct sound_trigger_info *st_info = NULL;
366 audio_event_info_t event;
367
368 if (!st_dev)
369 return ret;
370
371 if (!in->is_st_session_active) {
372 ALOGE(" %s: Sound trigger is not active", __func__);
373 goto exit;
374 }
375 if(in->standby)
376 in->standby = false;
377
378 pthread_mutex_lock(&st_dev->lock);
379 st_info = get_sound_trigger_info(in->capture_handle);
380 pthread_mutex_unlock(&st_dev->lock);
381 if (st_info) {
382 event.u.aud_info.ses_info = &st_info->st_ses;
383 event.u.aud_info.buf = buffer;
384 event.u.aud_info.num_bytes = bytes;
385 ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
386 }
387
388exit:
389 if (ret) {
390 if (-ENETRESET == ret)
391 in->is_st_session_active = false;
392 memset(buffer, 0, bytes);
393 ALOGV("%s: read failed status %d - sleep", __func__, ret);
394 usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
395 in->config.rate));
396 }
397 return ret;
398}
399
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700400void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
401{
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700402 struct sound_trigger_info *st_ses_info = NULL;
403 audio_event_info_t event;
404
Mingming Yinfd7607b2016-01-22 12:48:44 -0800405 if (!st_dev || !in || !in->is_st_session_active)
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700406 return;
407
408 pthread_mutex_lock(&st_dev->lock);
409 st_ses_info = get_sound_trigger_info(in->capture_handle);
Bharath Ramachandramurthy5baa6a52014-10-21 11:18:49 -0700410 pthread_mutex_unlock(&st_dev->lock);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700411 if (st_ses_info) {
412 event.u.ses_info = st_ses_info->st_ses;
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700413 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 -0700414 st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
Mingming Yinfd7607b2016-01-22 12:48:44 -0800415 in->is_st_session_active = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700416 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700417}
418void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in)
419{
420 struct sound_trigger_info *st_ses_info = NULL;
421 struct listnode *node;
422
423 if (!st_dev || !in)
424 return;
425
426 pthread_mutex_lock(&st_dev->lock);
427 in->is_st_session = false;
428 ALOGV("%s: list %d capture_handle %d", __func__,
429 list_empty(&st_dev->st_ses_list), in->capture_handle);
430 list_for_each(node, &st_dev->st_ses_list) {
431 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
432 if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700433 in->config = st_ses_info->st_ses.config;
434 in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
435 in->is_st_session = true;
Bharath Ramachandramurthy837535b2015-02-05 14:27:59 -0800436 in->is_st_session_active = true;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700437 ALOGD("%s: capture_handle %d is sound trigger", __func__, in->capture_handle);
438 break;
439 }
440 }
441 pthread_mutex_unlock(&st_dev->lock);
442}
443
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530444
kunleizef40adb2018-12-28 17:50:23 +0800445bool audio_extn_sound_trigger_check_ec_ref_enable()
446{
447 bool ret = false;
448
449 if (!st_dev) {
450 ALOGE("%s: st_dev NULL", __func__);
451 return ret;
452 }
453
454 pthread_mutex_lock(&st_dev->lock);
455 if (st_dev->st_ec_ref_enabled) {
456 ret = true;
457 ALOGD("%s: EC Reference is enabled", __func__);
458 } else {
459 ALOGD("%s: EC Reference is disabled", __func__);
460 }
461 pthread_mutex_unlock(&st_dev->lock);
462
463 return ret;
464}
465
466void audio_extn_sound_trigger_update_ec_ref_status(bool on)
467{
468 struct audio_event_info ev_info;
469
470 if (!st_dev) {
471 ALOGE("%s: st_dev NULL", __func__);
472 return;
473 }
474
475 ev_info.u.audio_ec_ref_enabled = on;
476 st_dev->st_callback(AUDIO_EVENT_UPDATE_ECHO_REF, &ev_info);
477 ALOGD("%s: update audio echo ref status %s",__func__,
478 ev_info.u.audio_ec_ref_enabled == true ? "true" : "false");
479}
480
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700481void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
482 st_event_type_t event)
483{
484 bool raise_event = false;
485 int device_type = -1;
486
487 if (!st_dev)
488 return;
489
490 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
491 snd_device < SND_DEVICE_OUT_END)
492 device_type = PCM_PLAYBACK;
493 else if (snd_device >= SND_DEVICE_IN_BEGIN &&
494 snd_device < SND_DEVICE_IN_END)
495 device_type = PCM_CAPTURE;
496 else {
497 ALOGE("%s: invalid device 0x%x, for event %d",
498 __func__, snd_device, event);
499 return;
500 }
501
502 raise_event = platform_sound_trigger_device_needs_event(snd_device);
503 ALOGI("%s: device 0x%x of type %d for Event %d, with Raise=%d",
504 __func__, snd_device, device_type, event, raise_event);
505 if (raise_event && (device_type == PCM_CAPTURE)) {
506 switch(event) {
507 case ST_EVENT_SND_DEVICE_FREE:
508 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE, NULL);
509 break;
510 case ST_EVENT_SND_DEVICE_BUSY:
511 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE, NULL);
512 break;
513 default:
514 ALOGW("%s:invalid event %d for device 0x%x",
515 __func__, event, snd_device);
516 }
517 }/*Events for output device, if required can be placed here in else*/
518}
519
520void audio_extn_sound_trigger_update_stream_status(struct audio_usecase *uc_info,
521 st_event_type_t event)
522{
523 bool raise_event = false;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530524 struct audio_event_info ev_info;
525 audio_event_type_t ev;
526 /*Initialize to invalid device*/
527 ev_info.device_info.device = -1;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700528
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530529 if (!st_dev)
530 return;
531
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700532 if (uc_info == NULL) {
533 ALOGE("%s: usecase is NULL!!!", __func__);
534 return;
535 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700536
Dhanalakshmi Siddani24e9ad52018-06-15 14:47:20 +0530537 if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
538 (uc_info->type != PCM_PLAYBACK))
539 return;
540
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530541 raise_event = platform_sound_trigger_usecase_needs_event(uc_info->id);
542 ALOGD("%s: uc_info->id %d of type %d for Event %d, with Raise=%d",
543 __func__, uc_info->id, uc_info->type, event, raise_event);
544 if (raise_event) {
545 if (uc_info->type == PCM_PLAYBACK) {
Zhou Songc1088ea2018-06-12 00:17:29 +0800546 if (uc_info->stream.out)
547 ev_info.device_info.device = uc_info->stream.out->devices;
548 else
549 ev_info.device_info.device = AUDIO_DEVICE_OUT_SPEAKER;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530550 switch(event) {
551 case ST_EVENT_STREAM_FREE:
Zhou Songc1088ea2018-06-12 00:17:29 +0800552 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530553 break;
554 case ST_EVENT_STREAM_BUSY:
Zhou Songc1088ea2018-06-12 00:17:29 +0800555 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530556 break;
557 default:
558 ALOGW("%s:invalid event %d, for usecase %d",
559 __func__, event, uc_info->id);
560 }
Revathi Uddaraju9f99ddd2018-05-03 12:01:38 +0530561 } else if ((uc_info->type == PCM_CAPTURE) || (uc_info->type == VOICE_CALL)) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530562 if (event == ST_EVENT_STREAM_BUSY)
563 ev = AUDIO_EVENT_CAPTURE_STREAM_ACTIVE;
564 else
565 ev = AUDIO_EVENT_CAPTURE_STREAM_INACTIVE;
566 if (!populate_usecase(&ev_info.u.usecase, uc_info)) {
567 ALOGD("%s: send event %d: usecase id %d, type %d",
568 __func__, ev, uc_info->id, uc_info->type);
569 st_dev->st_callback(ev, &ev_info);
570 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700571 }
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530572 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700573}
574
Zhou Songc1088ea2018-06-12 00:17:29 +0800575void audio_extn_sound_trigger_update_battery_status(bool charging)
576{
577 struct audio_event_info ev_info;
578
579 if (!st_dev || st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
580 return;
581
582 ev_info.u.value = charging;
583 st_dev->st_callback(AUDIO_EVENT_BATTERY_STATUS_CHANGED, &ev_info);
584}
585
586
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700587void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
588 struct str_parms *params)
589{
590 audio_event_info_t event;
591 char value[32];
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700592 int ret, val;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700593
594 if(!st_dev || !params) {
595 ALOGE("%s: str_params NULL", __func__);
596 return;
597 }
598
599 ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
600 sizeof(value));
601 if (ret > 0) {
602 if (strstr(value, "OFFLINE")) {
603 event.u.status = SND_CARD_STATUS_OFFLINE;
604 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
605 }
606 else if (strstr(value, "ONLINE")) {
607 event.u.status = SND_CARD_STATUS_ONLINE;
608 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
609 }
610 else
611 ALOGE("%s: unknown snd_card_status", __func__);
612 }
613
614 ret = str_parms_get_str(params, "CPE_STATUS", value, sizeof(value));
615 if (ret > 0) {
616 if (strstr(value, "OFFLINE")) {
617 event.u.status = CPE_STATUS_OFFLINE;
618 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
619 }
620 else if (strstr(value, "ONLINE")) {
621 event.u.status = CPE_STATUS_ONLINE;
622 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
623 }
624 else
625 ALOGE("%s: unknown CPE status", __func__);
626 }
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700627
628 ret = str_parms_get_int(params, "SVA_NUM_SESSIONS", &val);
629 if (ret >= 0) {
630 event.u.value = val;
631 st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
632 }
Quinn male73dd1fd2016-12-02 10:47:11 -0800633
634 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
Dhanalakshmi Siddani0f1dfd52019-01-09 12:38:13 +0530635 if ((ret >= 0) && (audio_is_input_device(val) ||
636 (val == AUDIO_DEVICE_OUT_LINE))) {
Quinn male73dd1fd2016-12-02 10:47:11 -0800637 event.u.value = val;
638 st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
639 }
640
641 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
Dhanalakshmi Siddani0f1dfd52019-01-09 12:38:13 +0530642 if ((ret >= 0) && (audio_is_input_device(val) ||
643 (val == AUDIO_DEVICE_OUT_LINE))) {
Quinn male73dd1fd2016-12-02 10:47:11 -0800644 event.u.value = val;
645 st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
646 }
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530647
648 ret = str_parms_get_str(params, "SVA_EXEC_MODE", value, sizeof(value));
649 if (ret >= 0) {
650 strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
651 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
652 }
653}
654
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530655static int extract_sm_handle(const char *keys, char *paramstr) {
656 char *tmpstr, *token;
657 char *inputstr = NULL;
658 int value = -EINVAL;
659
660 if (keys == NULL || paramstr == NULL)
661 goto exit;
662
663 inputstr = strdup(keys);
664 token =strtok_r(inputstr,":",&tmpstr);
665
666 if (token == NULL)
667 goto exit;
668
669 ALOGD("%s input string <%s> param string <%s>", __func__, keys,token);
670 strlcpy(paramstr, token, MAX_STR_LENGTH_FFV_PARAMS);
671 token =strtok_r(NULL,":=",&tmpstr);
672
673 if (token == NULL)
674 goto exit;
675
676 value = atoi(token);
677 if (value > 0 && value < MAX_FFV_SESSION_ID)
678 ALOGD(" %s SVA sm handle<=%d>",__func__, value);
679
680exit:
681 if (inputstr != NULL)
682 free(inputstr);
683
684 return value;
685}
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530686void audio_extn_sound_trigger_get_parameters(const struct audio_device *adev __unused,
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530687 struct str_parms *query,
688 struct str_parms *reply)
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530689{
690 audio_event_info_t event;
691 int ret;
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530692 char value[32], paramstr[MAX_STR_LENGTH_FFV_PARAMS];
693
694 ALOGD("%s input string<%s>", __func__, str_parms_to_str(query));
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530695
696 ret = str_parms_get_str(query, "SVA_EXEC_MODE_STATUS", value,
697 sizeof(value));
698 if (ret >= 0) {
699 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE_STATUS, &event);
700 str_parms_add_int(reply, "SVA_EXEC_MODE_STATUS", event.u.value);
701 }
Sidipotu Ashok090f0bc2018-12-21 09:19:26 +0530702
703 ret = extract_sm_handle(str_parms_to_str(query), paramstr);
704
705 if ((ret >= 0) && !strncmp(paramstr, SVA_PARAM_DIRECTION_OF_ARRIVAL,
706 MAX_STR_LENGTH_FFV_PARAMS)) {
707 event.u.st_get_param_data.sm_handle = ret;
708 event.u.st_get_param_data.param = SVA_PARAM_DIRECTION_OF_ARRIVAL;
709 event.u.st_get_param_data.reply = reply;
710 st_dev->st_callback(AUDIO_EVENT_GET_PARAM, &event);
711 } else if ((ret >=0) && !strncmp(paramstr, SVA_PARAM_CHANNEL_INDEX,
712 MAX_STR_LENGTH_FFV_PARAMS)) {
713 event.u.st_get_param_data.sm_handle = ret;
714 event.u.st_get_param_data.param = SVA_PARAM_CHANNEL_INDEX;
715 event.u.st_get_param_data.reply = reply;
716 st_dev->st_callback(AUDIO_EVENT_GET_PARAM, &event);
717 }
718
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700719}
720
721int audio_extn_sound_trigger_init(struct audio_device *adev)
722{
723 int status = 0;
724 char sound_trigger_lib[100];
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530725 void *sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700726
727 ALOGI("%s: Enter", __func__);
728
729 st_dev = (struct sound_trigger_audio_device*)
730 calloc(1, sizeof(struct sound_trigger_audio_device));
731 if (!st_dev) {
732 ALOGE("%s: ERROR. sound trigger alloc failed", __func__);
733 return -ENOMEM;
734 }
735
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530736 get_library_path(sound_trigger_lib);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700737 st_dev->lib_handle = dlopen(sound_trigger_lib, RTLD_NOW);
738
739 if (st_dev->lib_handle == NULL) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530740 ALOGE("%s: error %s", __func__, dlerror());
741 status = -ENODEV;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700742 goto cleanup;
743 }
744 ALOGI("%s: DLOPEN successful for %s", __func__, sound_trigger_lib);
745
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530746 DLSYM(st_dev->lib_handle, st_dev->st_callback, sound_trigger_hw_call_back,
747 status);
748 if (status)
749 goto cleanup;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700750
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530751 DLSYM(st_dev->lib_handle, sthal_prop_api_version,
752 sthal_prop_api_version, status);
753 if (status) {
754 st_dev->sthal_prop_api_version = 0;
755 status = 0; /* passthru for backward compability */
756 } else {
757 st_dev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
758 if (MAJOR_VERSION(st_dev->sthal_prop_api_version) !=
759 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
760 ALOGE("%s: Incompatible API versions ahal:0x%x != sthal:0x%x",
761 __func__, STHAL_PROP_API_CURRENT_VERSION,
762 st_dev->sthal_prop_api_version);
763 goto cleanup;
764 }
765 ALOGD("%s: sthal is using proprietary API version 0x%04x", __func__,
766 st_dev->sthal_prop_api_version);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700767 }
768
769 st_dev->adev = adev;
kunleizef40adb2018-12-28 17:50:23 +0800770 st_dev->st_ec_ref_enabled = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700771 list_init(&st_dev->st_ses_list);
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530772 audio_extn_snd_mon_register_listener(st_dev, stdev_snd_mon_cb);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700773
774 return 0;
775
776cleanup:
777 if (st_dev->lib_handle)
778 dlclose(st_dev->lib_handle);
779 free(st_dev);
780 st_dev = NULL;
781 return status;
782
783}
784
785void audio_extn_sound_trigger_deinit(struct audio_device *adev)
786{
787 ALOGI("%s: Enter", __func__);
788 if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530789 audio_extn_snd_mon_unregister_listener(st_dev);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700790 dlclose(st_dev->lib_handle);
791 free(st_dev);
792 st_dev = NULL;
793 }
794}