blob: e01b23bd8b15a9615e65a5d88313c3efaa71f8d9 [file] [log] [blame]
Aalique Grahame22e49102018-12-18 14:23:57 -08001/* 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>
Aalique Grahame22e49102018-12-18 14:23:57 -080037#include <pthread.h>
38#include <log/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)
57#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_0
58
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,
67} sound_trigger_event_type_t;
68
69typedef enum {
70 AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
71 AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
72 AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE,
73 AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE,
74 AUDIO_EVENT_STOP_LAB,
75 AUDIO_EVENT_SSR,
76 AUDIO_EVENT_NUM_ST_SESSIONS,
77 AUDIO_EVENT_READ_SAMPLES,
78 AUDIO_EVENT_DEVICE_CONNECT,
79 AUDIO_EVENT_DEVICE_DISCONNECT,
80 AUDIO_EVENT_SVA_EXEC_MODE,
81 AUDIO_EVENT_SVA_EXEC_MODE_STATUS,
82 AUDIO_EVENT_CAPTURE_STREAM_INACTIVE,
83 AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
Zhou Songc1088ea2018-06-12 00:17:29 +080084 AUDIO_EVENT_BATTERY_STATUS_CHANGED,
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +053085 AUDIO_EVENT_GET_PARAM
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053086} audio_event_type_t;
87
88typedef enum {
89 USECASE_TYPE_PCM_PLAYBACK,
90 USECASE_TYPE_PCM_CAPTURE,
91 USECASE_TYPE_VOICE_CALL,
92 USECASE_TYPE_VOIP_CALL,
93} audio_stream_usecase_type_t;
94
95typedef enum {
96 SND_CARD_STATUS_OFFLINE,
97 SND_CARD_STATUS_ONLINE,
98 CPE_STATUS_OFFLINE,
Aalique Grahame22e49102018-12-18 14:23:57 -080099 CPE_STATUS_ONLINE,
100 SLPI_STATUS_OFFLINE,
101 SLPI_STATUS_ONLINE
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530102} 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;
123};
124typedef struct sound_trigger_event_info sound_trigger_event_info_t;
125
126struct sound_trigger_device_info {
127 int device;
128};
129
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +0530130struct sound_trigger_get_param_data {
131 char *param;
132 int sm_handle;
133 struct str_parms *reply;
134};
135
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530136struct audio_event_info {
137 union {
138 ssr_event_status_t status;
139 int value;
140 struct sound_trigger_session_info ses_info;
141 struct audio_read_samples_info aud_info;
142 char str_value[ST_EVENT_CONFIG_MAX_STR_VALUE];
143 struct audio_hal_usecase usecase;
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +0530144 struct sound_trigger_get_param_data st_get_param_data;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530145 } u;
146 struct sound_trigger_device_info device_info;
147};
148typedef struct audio_event_info audio_event_info_t;
149/* STHAL callback which is called by AHAL */
150typedef int (*sound_trigger_hw_call_back_t)(audio_event_type_t,
151 struct audio_event_info*);
152
153/*---------------- End: AHAL-STHAL Interface ----------------------------------*/
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700154
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +0530155#ifdef DYNAMIC_LOG_ENABLED
156#include <log_xml_parser.h>
157#define LOG_MASK HAL_MOD_FILE_SND_TRIGGER
158#include <log_utils.h>
159#endif
160
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700161#define XSTR(x) STR(x)
162#define STR(x) #x
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530163#define MAX_LIBRARY_PATH 100
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700164
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530165#define DLSYM(handle, ptr, symbol, err) \
166do {\
Venkatesh Mangalappalibcc684c2018-04-06 14:58:44 -0700167 ptr = dlsym(handle, #symbol); \
168 if (ptr == NULL) {\
169 ALOGW("%s: %s not found. %s", __func__, #symbol, dlerror());\
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530170 err = -ENODEV;\
171 }\
172} while(0)
173
174#ifdef __LP64__
175#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib64/hw/sound_trigger.primary.%s.so"
176#else
177#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib/hw/sound_trigger.primary.%s.so"
178#endif
179
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +0530180#define SVA_PARAM_DIRECTION_OF_ARRIVAL "st_direction_of_arrival"
181#define SVA_PARAM_CHANNEL_INDEX "st_channel_index"
Sidipotu Ashokaa4fa6a2018-12-21 09:19:26 +0530182#define MAX_STR_LENGTH_FFV_PARAMS 30
183#define MAX_FFV_SESSION_ID 100
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530184/*
185 * Current proprietary API version used by AHAL. Queried by STHAL
186 * for compatibility check with AHAL
187 */
188const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;
189
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700190struct sound_trigger_info {
191 struct sound_trigger_session_info st_ses;
192 bool lab_stopped;
193 struct listnode list;
194};
195
196struct sound_trigger_audio_device {
197 void *lib_handle;
198 struct audio_device *adev;
199 sound_trigger_hw_call_back_t st_callback;
200 struct listnode st_ses_list;
201 pthread_mutex_t lock;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530202 unsigned int sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700203};
204
205static struct sound_trigger_audio_device *st_dev;
206
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530207#if LINUX_ENABLED
208static void get_library_path(char *lib_path)
209{
210 snprintf(lib_path, MAX_LIBRARY_PATH,
Manish Dewangan6a36d002017-10-09 14:11:00 +0530211 "sound_trigger.primary.default.so");
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530212}
213#else
214static void get_library_path(char *lib_path)
215{
216 snprintf(lib_path, MAX_LIBRARY_PATH,
David Ng06ccd872017-03-15 11:39:33 -0700217 "/vendor/lib/hw/sound_trigger.primary.%s.so",
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530218 XSTR(SOUND_TRIGGER_PLATFORM_NAME));
219}
220#endif
221
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700222static struct sound_trigger_info *
223get_sound_trigger_info(int capture_handle)
224{
225 struct sound_trigger_info *st_ses_info = NULL;
226 struct listnode *node;
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700227 ALOGV("%s: list empty %d capture_handle %d", __func__,
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700228 list_empty(&st_dev->st_ses_list), capture_handle);
229 list_for_each(node, &st_dev->st_ses_list) {
230 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
231 if (st_ses_info->st_ses.capture_handle == capture_handle)
232 return st_ses_info;
233 }
234 return NULL;
235}
236
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530237static int populate_usecase(struct audio_hal_usecase *usecase,
238 struct audio_usecase *uc_info)
239{
240 int status = 0;
241
242 switch(uc_info->type) {
243 case PCM_PLAYBACK:
244 if (uc_info->id == USECASE_AUDIO_PLAYBACK_VOIP)
245 usecase->type = USECASE_TYPE_VOIP_CALL;
246 else
247 usecase->type = USECASE_TYPE_PCM_PLAYBACK;
248 break;
249
250 case PCM_CAPTURE:
251 if (uc_info->id == USECASE_AUDIO_RECORD_VOIP)
252 usecase->type = USECASE_TYPE_VOIP_CALL;
253 else
254 usecase->type = USECASE_TYPE_PCM_CAPTURE;
255 break;
256
257 case VOICE_CALL:
258 usecase->type = USECASE_TYPE_VOICE_CALL;
259 break;
260
261 default:
262 ALOGE("%s: unsupported usecase type %d", __func__, uc_info->type);
263 status = -EINVAL;
264 }
265 return status;
266}
267
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530268static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
269{
270 if (!parms)
271 return;
272
273 audio_extn_sound_trigger_set_parameters(NULL, parms);
274 return;
275}
276
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700277int audio_hw_call_back(sound_trigger_event_type_t event,
278 sound_trigger_event_info_t* config)
279{
280 int status = 0;
281 struct sound_trigger_info *st_ses_info;
282
283 if (!st_dev)
284 return -EINVAL;
285
286 pthread_mutex_lock(&st_dev->lock);
287 switch (event) {
288 case ST_EVENT_SESSION_REGISTER:
289 if (!config) {
290 ALOGE("%s: NULL config", __func__);
291 status = -EINVAL;
292 break;
293 }
294 st_ses_info= calloc(1, sizeof(struct sound_trigger_info ));
295 if (!st_ses_info) {
296 ALOGE("%s: st_ses_info alloc failed", __func__);
297 status = -ENOMEM;
298 break;
299 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700300 memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
301 ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
302 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700303 list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
304 break;
305
Surendar Karka59c51072017-12-13 11:25:57 +0530306 case ST_EVENT_START_KEEP_ALIVE:
307 pthread_mutex_unlock(&st_dev->lock);
308 pthread_mutex_lock(&st_dev->adev->lock);
309 audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
310 pthread_mutex_unlock(&st_dev->adev->lock);
311 goto done;
312
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700313 case ST_EVENT_SESSION_DEREGISTER:
314 if (!config) {
315 ALOGE("%s: NULL config", __func__);
316 status = -EINVAL;
317 break;
318 }
319 st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
320 if (!st_ses_info) {
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700321 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 -0700322 status = -EINVAL;
323 break;
324 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700325 ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
326 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700327 list_remove(&st_ses_info->list);
328 free(st_ses_info);
329 break;
Surendar Karka59c51072017-12-13 11:25:57 +0530330
331 case ST_EVENT_STOP_KEEP_ALIVE:
332 pthread_mutex_unlock(&st_dev->lock);
333 pthread_mutex_lock(&st_dev->adev->lock);
334 audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
335 pthread_mutex_unlock(&st_dev->adev->lock);
336 goto done;
337
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700338 default:
339 ALOGW("%s: Unknown event %d", __func__, event);
340 break;
341 }
342 pthread_mutex_unlock(&st_dev->lock);
Surendar Karka59c51072017-12-13 11:25:57 +0530343done:
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700344 return status;
345}
346
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700347int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
348 size_t bytes)
349{
350 int ret = -1;
351 struct sound_trigger_info *st_info = NULL;
352 audio_event_info_t event;
353
354 if (!st_dev)
355 return ret;
356
357 if (!in->is_st_session_active) {
358 ALOGE(" %s: Sound trigger is not active", __func__);
359 goto exit;
360 }
361 if(in->standby)
362 in->standby = false;
363
364 pthread_mutex_lock(&st_dev->lock);
365 st_info = get_sound_trigger_info(in->capture_handle);
366 pthread_mutex_unlock(&st_dev->lock);
367 if (st_info) {
368 event.u.aud_info.ses_info = &st_info->st_ses;
369 event.u.aud_info.buf = buffer;
370 event.u.aud_info.num_bytes = bytes;
371 ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
372 }
373
374exit:
375 if (ret) {
376 if (-ENETRESET == ret)
377 in->is_st_session_active = false;
378 memset(buffer, 0, bytes);
379 ALOGV("%s: read failed status %d - sleep", __func__, ret);
380 usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
381 in->config.rate));
382 }
383 return ret;
384}
385
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700386void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
387{
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700388 struct sound_trigger_info *st_ses_info = NULL;
389 audio_event_info_t event;
390
Mingming Yinfd7607b2016-01-22 12:48:44 -0800391 if (!st_dev || !in || !in->is_st_session_active)
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700392 return;
393
394 pthread_mutex_lock(&st_dev->lock);
395 st_ses_info = get_sound_trigger_info(in->capture_handle);
Bharath Ramachandramurthy5baa6a52014-10-21 11:18:49 -0700396 pthread_mutex_unlock(&st_dev->lock);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700397 if (st_ses_info) {
398 event.u.ses_info = st_ses_info->st_ses;
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700399 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 -0700400 st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
Mingming Yinfd7607b2016-01-22 12:48:44 -0800401 in->is_st_session_active = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700402 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700403}
404void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in)
405{
406 struct sound_trigger_info *st_ses_info = NULL;
407 struct listnode *node;
408
409 if (!st_dev || !in)
410 return;
411
412 pthread_mutex_lock(&st_dev->lock);
413 in->is_st_session = false;
414 ALOGV("%s: list %d capture_handle %d", __func__,
415 list_empty(&st_dev->st_ses_list), in->capture_handle);
416 list_for_each(node, &st_dev->st_ses_list) {
417 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
418 if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700419 in->config = st_ses_info->st_ses.config;
420 in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
421 in->is_st_session = true;
Bharath Ramachandramurthy837535b2015-02-05 14:27:59 -0800422 in->is_st_session_active = true;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700423 ALOGD("%s: capture_handle %d is sound trigger", __func__, in->capture_handle);
424 break;
425 }
426 }
427 pthread_mutex_unlock(&st_dev->lock);
428}
429
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530430bool is_same_as_st_device(snd_device_t snd_device)
431{
432 if (snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC ||
433 snd_device == SND_DEVICE_IN_HANDSET_MIC ||
434 snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC_NS ||
435 snd_device == SND_DEVICE_IN_SPEAKER_MIC ||
436 snd_device == SND_DEVICE_IN_VOICE_SPEAKER_MIC ||
437 snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC ||
438 snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC_NS ||
439 snd_device == SND_DEVICE_IN_SPEAKER_MIC_NS) {
440 ALOGD("audio HAL using same device %d as ST", snd_device);
441 return true;
442 }
443 return false;
444}
445
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700446void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
447 st_event_type_t event)
448{
449 bool raise_event = false;
450 int device_type = -1;
451
452 if (!st_dev)
453 return;
454
455 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
456 snd_device < SND_DEVICE_OUT_END)
457 device_type = PCM_PLAYBACK;
458 else if (snd_device >= SND_DEVICE_IN_BEGIN &&
459 snd_device < SND_DEVICE_IN_END)
460 device_type = PCM_CAPTURE;
461 else {
462 ALOGE("%s: invalid device 0x%x, for event %d",
463 __func__, snd_device, event);
464 return;
465 }
466
467 raise_event = platform_sound_trigger_device_needs_event(snd_device);
468 ALOGI("%s: device 0x%x of type %d for Event %d, with Raise=%d",
469 __func__, snd_device, device_type, event, raise_event);
470 if (raise_event && (device_type == PCM_CAPTURE)) {
471 switch(event) {
472 case ST_EVENT_SND_DEVICE_FREE:
473 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE, NULL);
474 break;
475 case ST_EVENT_SND_DEVICE_BUSY:
476 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE, NULL);
477 break;
478 default:
479 ALOGW("%s:invalid event %d for device 0x%x",
480 __func__, event, snd_device);
481 }
482 }/*Events for output device, if required can be placed here in else*/
483}
484
485void audio_extn_sound_trigger_update_stream_status(struct audio_usecase *uc_info,
486 st_event_type_t event)
487{
488 bool raise_event = false;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530489 struct audio_event_info ev_info;
490 audio_event_type_t ev;
491 /*Initialize to invalid device*/
492 ev_info.device_info.device = -1;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700493
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530494 if (!st_dev)
495 return;
496
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700497 if (uc_info == NULL) {
498 ALOGE("%s: usecase is NULL!!!", __func__);
499 return;
500 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700501
Dhanalakshmi Siddani24e9ad52018-06-15 14:47:20 +0530502 if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
503 (uc_info->type != PCM_PLAYBACK))
504 return;
505
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530506 if ((uc_info->in_snd_device >= SND_DEVICE_IN_BEGIN &&
507 uc_info->in_snd_device < SND_DEVICE_IN_END)) {
508 if (is_same_as_st_device(uc_info->in_snd_device))
509 ev_info.device_info.device = ST_DEVICE_HANDSET_MIC;
510 } else {
511 ALOGE("%s: invalid input device 0x%x, for event %d",
512 __func__, uc_info->in_snd_device, event);
513 }
514 raise_event = platform_sound_trigger_usecase_needs_event(uc_info->id);
515 ALOGD("%s: uc_info->id %d of type %d for Event %d, with Raise=%d",
516 __func__, uc_info->id, uc_info->type, event, raise_event);
517 if (raise_event) {
518 if (uc_info->type == PCM_PLAYBACK) {
Zhou Songc1088ea2018-06-12 00:17:29 +0800519 if (uc_info->stream.out)
520 ev_info.device_info.device = uc_info->stream.out->devices;
521 else
522 ev_info.device_info.device = AUDIO_DEVICE_OUT_SPEAKER;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530523 switch(event) {
524 case ST_EVENT_STREAM_FREE:
Zhou Songc1088ea2018-06-12 00:17:29 +0800525 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530526 break;
527 case ST_EVENT_STREAM_BUSY:
Zhou Songc1088ea2018-06-12 00:17:29 +0800528 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530529 break;
530 default:
531 ALOGW("%s:invalid event %d, for usecase %d",
532 __func__, event, uc_info->id);
533 }
Revathi Uddaraju9f99ddd2018-05-03 12:01:38 +0530534 } else if ((uc_info->type == PCM_CAPTURE) || (uc_info->type == VOICE_CALL)) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530535 if (event == ST_EVENT_STREAM_BUSY)
536 ev = AUDIO_EVENT_CAPTURE_STREAM_ACTIVE;
537 else
538 ev = AUDIO_EVENT_CAPTURE_STREAM_INACTIVE;
539 if (!populate_usecase(&ev_info.u.usecase, uc_info)) {
540 ALOGD("%s: send event %d: usecase id %d, type %d",
541 __func__, ev, uc_info->id, uc_info->type);
542 st_dev->st_callback(ev, &ev_info);
543 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700544 }
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530545 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700546}
547
Zhou Songc1088ea2018-06-12 00:17:29 +0800548void audio_extn_sound_trigger_update_battery_status(bool charging)
549{
550 struct audio_event_info ev_info;
551
552 if (!st_dev || st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
553 return;
554
555 ev_info.u.value = charging;
556 st_dev->st_callback(AUDIO_EVENT_BATTERY_STATUS_CHANGED, &ev_info);
557}
558
559
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700560void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
561 struct str_parms *params)
562{
563 audio_event_info_t event;
564 char value[32];
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700565 int ret, val;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700566
567 if(!st_dev || !params) {
568 ALOGE("%s: str_params NULL", __func__);
569 return;
570 }
571
572 ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
573 sizeof(value));
574 if (ret > 0) {
575 if (strstr(value, "OFFLINE")) {
576 event.u.status = SND_CARD_STATUS_OFFLINE;
577 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
578 }
579 else if (strstr(value, "ONLINE")) {
580 event.u.status = SND_CARD_STATUS_ONLINE;
581 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
582 }
583 else
584 ALOGE("%s: unknown snd_card_status", __func__);
585 }
586
587 ret = str_parms_get_str(params, "CPE_STATUS", value, sizeof(value));
588 if (ret > 0) {
589 if (strstr(value, "OFFLINE")) {
590 event.u.status = CPE_STATUS_OFFLINE;
591 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
592 }
593 else if (strstr(value, "ONLINE")) {
594 event.u.status = CPE_STATUS_ONLINE;
595 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
596 }
597 else
598 ALOGE("%s: unknown CPE status", __func__);
599 }
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700600
601 ret = str_parms_get_int(params, "SVA_NUM_SESSIONS", &val);
602 if (ret >= 0) {
603 event.u.value = val;
604 st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
605 }
Quinn male73dd1fd2016-12-02 10:47:11 -0800606
607 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
Dhanalakshmi Siddani10621622018-04-30 15:07:27 +0530608 if ((ret >= 0) && (audio_is_input_device(val) ||
609 (val == AUDIO_DEVICE_OUT_LINE))) {
Quinn male73dd1fd2016-12-02 10:47:11 -0800610 event.u.value = val;
611 st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
612 }
613
614 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
Dhanalakshmi Siddani10621622018-04-30 15:07:27 +0530615 if ((ret >= 0) && (audio_is_input_device(val) ||
616 (val == AUDIO_DEVICE_OUT_LINE))) {
Quinn male73dd1fd2016-12-02 10:47:11 -0800617 event.u.value = val;
618 st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
619 }
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530620
621 ret = str_parms_get_str(params, "SVA_EXEC_MODE", value, sizeof(value));
622 if (ret >= 0) {
623 strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
624 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
625 }
Aalique Grahame22e49102018-12-18 14:23:57 -0800626
627 ret = str_parms_get_str(params, "SLPI_STATUS", value, sizeof(value));
628 if (ret > 0) {
629 if (strstr(value, "OFFLINE")) {
630 event.u.status = SLPI_STATUS_OFFLINE;
631 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
632 } else if (strstr(value, "ONLINE")) {
633 event.u.status = SLPI_STATUS_ONLINE;
634 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
635 } else
636 ALOGE("%s: unknown SLPI status", __func__);
637 }
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530638}
639
Sidipotu Ashokaa4fa6a2018-12-21 09:19:26 +0530640static int extract_sm_handle(const char *keys, char *paramstr) {
641 char *tmpstr, *token;
642 char *inputstr = NULL;
643 int value = -EINVAL;
644
645 if (keys == NULL || paramstr == NULL)
646 goto exit;
647
648 inputstr = strdup(keys);
649 token =strtok_r(inputstr,":", &tmpstr);
650
651 if (token == NULL)
652 goto exit;
653
654 ALOGD("%s input string <%s> param string <%s>", __func__, keys,token);
655 strlcpy(paramstr, token, MAX_STR_LENGTH_FFV_PARAMS);
656 token =strtok_r(NULL,":=",&tmpstr);
657
658 if (token == NULL)
659 goto exit;
660
661 value = atoi(token);
662 if (value > 0 && value < MAX_FFV_SESSION_ID)
663 ALOGD(" %s SVA sm handle<=%d>",__func__, value);
664
665exit:
666 if (inputstr != NULL)
667 free(inputstr);
668
669 return value;
670}
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530671void audio_extn_sound_trigger_get_parameters(const struct audio_device *adev __unused,
Sidipotu Ashokaa4fa6a2018-12-21 09:19:26 +0530672 struct str_parms *query,
673 struct str_parms *reply)
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530674{
675 audio_event_info_t event;
Sidipotu Ashokaa4fa6a2018-12-21 09:19:26 +0530676 int ret;
677 char value[32], paramstr[MAX_STR_LENGTH_FFV_PARAMS];
678
679 ALOGD("%s input string<%s>", __func__, str_parms_to_str(query));
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530680
681 ret = str_parms_get_str(query, "SVA_EXEC_MODE_STATUS", value,
682 sizeof(value));
683 if (ret >= 0) {
684 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE_STATUS, &event);
685 str_parms_add_int(reply, "SVA_EXEC_MODE_STATUS", event.u.value);
686 }
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +0530687
Sidipotu Ashokaa4fa6a2018-12-21 09:19:26 +0530688 ret = extract_sm_handle(str_parms_to_str(query), paramstr);
689
690 if ((ret >= 0) && !strncmp(paramstr, SVA_PARAM_DIRECTION_OF_ARRIVAL,
691 MAX_STR_LENGTH_FFV_PARAMS)) {
692 event.u.st_get_param_data.sm_handle = ret;
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +0530693 event.u.st_get_param_data.param = SVA_PARAM_DIRECTION_OF_ARRIVAL;
694 event.u.st_get_param_data.reply = reply;
695 st_dev->st_callback(AUDIO_EVENT_GET_PARAM, &event);
Sidipotu Ashokaa4fa6a2018-12-21 09:19:26 +0530696 } else if ((ret >=0) && !strncmp(paramstr, SVA_PARAM_CHANNEL_INDEX,
697 MAX_STR_LENGTH_FFV_PARAMS)) {
698 event.u.st_get_param_data.sm_handle = ret;
Dhanalakshmi Siddani57b014e2018-04-23 12:52:02 +0530699 event.u.st_get_param_data.param = SVA_PARAM_CHANNEL_INDEX;
700 event.u.st_get_param_data.reply = reply;
701 st_dev->st_callback(AUDIO_EVENT_GET_PARAM, &event);
702 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700703}
704
705int audio_extn_sound_trigger_init(struct audio_device *adev)
706{
707 int status = 0;
708 char sound_trigger_lib[100];
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530709 void *sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700710
711 ALOGI("%s: Enter", __func__);
712
713 st_dev = (struct sound_trigger_audio_device*)
714 calloc(1, sizeof(struct sound_trigger_audio_device));
715 if (!st_dev) {
716 ALOGE("%s: ERROR. sound trigger alloc failed", __func__);
717 return -ENOMEM;
718 }
719
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530720 get_library_path(sound_trigger_lib);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700721 st_dev->lib_handle = dlopen(sound_trigger_lib, RTLD_NOW);
722
723 if (st_dev->lib_handle == NULL) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530724 ALOGE("%s: error %s", __func__, dlerror());
725 status = -ENODEV;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700726 goto cleanup;
727 }
728 ALOGI("%s: DLOPEN successful for %s", __func__, sound_trigger_lib);
729
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530730 DLSYM(st_dev->lib_handle, st_dev->st_callback, sound_trigger_hw_call_back,
731 status);
732 if (status)
733 goto cleanup;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700734
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530735 DLSYM(st_dev->lib_handle, sthal_prop_api_version,
736 sthal_prop_api_version, status);
737 if (status) {
738 st_dev->sthal_prop_api_version = 0;
739 status = 0; /* passthru for backward compability */
740 } else {
Jhansi Konathala902fc412018-09-05 13:21:44 +0530741 if (sthal_prop_api_version != NULL) {
742 st_dev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
743 }
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530744 if (MAJOR_VERSION(st_dev->sthal_prop_api_version) !=
745 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
746 ALOGE("%s: Incompatible API versions ahal:0x%x != sthal:0x%x",
747 __func__, STHAL_PROP_API_CURRENT_VERSION,
748 st_dev->sthal_prop_api_version);
749 goto cleanup;
750 }
751 ALOGD("%s: sthal is using proprietary API version 0x%04x", __func__,
752 st_dev->sthal_prop_api_version);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700753 }
754
755 st_dev->adev = adev;
756 list_init(&st_dev->st_ses_list);
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530757 audio_extn_snd_mon_register_listener(st_dev, stdev_snd_mon_cb);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700758
759 return 0;
760
761cleanup:
762 if (st_dev->lib_handle)
763 dlclose(st_dev->lib_handle);
764 free(st_dev);
765 st_dev = NULL;
766 return status;
767
768}
769
770void audio_extn_sound_trigger_deinit(struct audio_device *adev)
771{
772 ALOGI("%s: Enter", __func__);
773 if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530774 audio_extn_snd_mon_unregister_listener(st_dev);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700775 dlclose(st_dev->lib_handle);
776 free(st_dev);
777 st_dev = NULL;
778 }
779}