blob: b2e1befd10d5829774b0668528ca3646760c209a [file] [log] [blame]
Surendar Karka59c51072017-12-13 11:25:57 +05301/* Copyright (c) 2013-2014, 2016-2018 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)
56#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_0
57
58#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
59#define ST_DEVICE_HANDSET_MIC 1
60
61typedef enum {
62 ST_EVENT_SESSION_REGISTER,
63 ST_EVENT_SESSION_DEREGISTER,
64 ST_EVENT_START_KEEP_ALIVE,
65 ST_EVENT_STOP_KEEP_ALIVE,
66} sound_trigger_event_type_t;
67
68typedef enum {
69 AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
70 AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
71 AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE,
72 AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE,
73 AUDIO_EVENT_STOP_LAB,
74 AUDIO_EVENT_SSR,
75 AUDIO_EVENT_NUM_ST_SESSIONS,
76 AUDIO_EVENT_READ_SAMPLES,
77 AUDIO_EVENT_DEVICE_CONNECT,
78 AUDIO_EVENT_DEVICE_DISCONNECT,
79 AUDIO_EVENT_SVA_EXEC_MODE,
80 AUDIO_EVENT_SVA_EXEC_MODE_STATUS,
81 AUDIO_EVENT_CAPTURE_STREAM_INACTIVE,
82 AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
Zhou Songc1088ea2018-06-12 00:17:29 +080083 AUDIO_EVENT_BATTERY_STATUS_CHANGED,
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053084} audio_event_type_t;
85
86typedef enum {
87 USECASE_TYPE_PCM_PLAYBACK,
88 USECASE_TYPE_PCM_CAPTURE,
89 USECASE_TYPE_VOICE_CALL,
90 USECASE_TYPE_VOIP_CALL,
91} audio_stream_usecase_type_t;
92
93typedef enum {
94 SND_CARD_STATUS_OFFLINE,
95 SND_CARD_STATUS_ONLINE,
96 CPE_STATUS_OFFLINE,
97 CPE_STATUS_ONLINE
98} ssr_event_status_t;
99
100struct sound_trigger_session_info {
101 void* p_ses; /* opaque pointer to st_session obj */
102 int capture_handle;
103 struct pcm *pcm;
104 struct pcm_config config;
105};
106
107struct audio_read_samples_info {
108 struct sound_trigger_session_info *ses_info;
109 void *buf;
110 size_t num_bytes;
111};
112
113struct audio_hal_usecase {
114 audio_stream_usecase_type_t type;
115};
116
117struct sound_trigger_event_info {
118 struct sound_trigger_session_info st_ses;
119};
120typedef struct sound_trigger_event_info sound_trigger_event_info_t;
121
122struct sound_trigger_device_info {
123 int device;
124};
125
126struct audio_event_info {
127 union {
128 ssr_event_status_t status;
129 int value;
130 struct sound_trigger_session_info ses_info;
131 struct audio_read_samples_info aud_info;
132 char str_value[ST_EVENT_CONFIG_MAX_STR_VALUE];
133 struct audio_hal_usecase usecase;
134 } u;
135 struct sound_trigger_device_info device_info;
136};
137typedef struct audio_event_info audio_event_info_t;
138/* STHAL callback which is called by AHAL */
139typedef int (*sound_trigger_hw_call_back_t)(audio_event_type_t,
140 struct audio_event_info*);
141
142/*---------------- End: AHAL-STHAL Interface ----------------------------------*/
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700143
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +0530144#ifdef DYNAMIC_LOG_ENABLED
145#include <log_xml_parser.h>
146#define LOG_MASK HAL_MOD_FILE_SND_TRIGGER
147#include <log_utils.h>
148#endif
149
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700150#define XSTR(x) STR(x)
151#define STR(x) #x
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530152#define MAX_LIBRARY_PATH 100
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700153
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530154#define DLSYM(handle, ptr, symbol, err) \
155do {\
Venkatesh Mangalappalibcc684c2018-04-06 14:58:44 -0700156 ptr = dlsym(handle, #symbol); \
157 if (ptr == NULL) {\
158 ALOGW("%s: %s not found. %s", __func__, #symbol, dlerror());\
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530159 err = -ENODEV;\
160 }\
161} while(0)
162
163#ifdef __LP64__
164#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib64/hw/sound_trigger.primary.%s.so"
165#else
166#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib/hw/sound_trigger.primary.%s.so"
167#endif
168
169/*
170 * Current proprietary API version used by AHAL. Queried by STHAL
171 * for compatibility check with AHAL
172 */
173const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;
174
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700175struct sound_trigger_info {
176 struct sound_trigger_session_info st_ses;
177 bool lab_stopped;
178 struct listnode list;
179};
180
181struct sound_trigger_audio_device {
182 void *lib_handle;
183 struct audio_device *adev;
184 sound_trigger_hw_call_back_t st_callback;
185 struct listnode st_ses_list;
186 pthread_mutex_t lock;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530187 unsigned int sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700188};
189
190static struct sound_trigger_audio_device *st_dev;
191
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530192#if LINUX_ENABLED
193static void get_library_path(char *lib_path)
194{
195 snprintf(lib_path, MAX_LIBRARY_PATH,
Manish Dewangan6a36d002017-10-09 14:11:00 +0530196 "sound_trigger.primary.default.so");
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530197}
198#else
199static void get_library_path(char *lib_path)
200{
201 snprintf(lib_path, MAX_LIBRARY_PATH,
David Ng06ccd872017-03-15 11:39:33 -0700202 "/vendor/lib/hw/sound_trigger.primary.%s.so",
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530203 XSTR(SOUND_TRIGGER_PLATFORM_NAME));
204}
205#endif
206
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700207static struct sound_trigger_info *
208get_sound_trigger_info(int capture_handle)
209{
210 struct sound_trigger_info *st_ses_info = NULL;
211 struct listnode *node;
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700212 ALOGV("%s: list empty %d capture_handle %d", __func__,
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700213 list_empty(&st_dev->st_ses_list), capture_handle);
214 list_for_each(node, &st_dev->st_ses_list) {
215 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
216 if (st_ses_info->st_ses.capture_handle == capture_handle)
217 return st_ses_info;
218 }
219 return NULL;
220}
221
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530222static int populate_usecase(struct audio_hal_usecase *usecase,
223 struct audio_usecase *uc_info)
224{
225 int status = 0;
226
227 switch(uc_info->type) {
228 case PCM_PLAYBACK:
229 if (uc_info->id == USECASE_AUDIO_PLAYBACK_VOIP)
230 usecase->type = USECASE_TYPE_VOIP_CALL;
231 else
232 usecase->type = USECASE_TYPE_PCM_PLAYBACK;
233 break;
234
235 case PCM_CAPTURE:
236 if (uc_info->id == USECASE_AUDIO_RECORD_VOIP)
237 usecase->type = USECASE_TYPE_VOIP_CALL;
238 else
239 usecase->type = USECASE_TYPE_PCM_CAPTURE;
240 break;
241
242 case VOICE_CALL:
243 usecase->type = USECASE_TYPE_VOICE_CALL;
244 break;
245
246 default:
247 ALOGE("%s: unsupported usecase type %d", __func__, uc_info->type);
248 status = -EINVAL;
249 }
250 return status;
251}
252
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530253static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
254{
255 if (!parms)
256 return;
257
258 audio_extn_sound_trigger_set_parameters(NULL, parms);
259 return;
260}
261
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700262int audio_hw_call_back(sound_trigger_event_type_t event,
263 sound_trigger_event_info_t* config)
264{
265 int status = 0;
266 struct sound_trigger_info *st_ses_info;
267
268 if (!st_dev)
269 return -EINVAL;
270
271 pthread_mutex_lock(&st_dev->lock);
272 switch (event) {
273 case ST_EVENT_SESSION_REGISTER:
274 if (!config) {
275 ALOGE("%s: NULL config", __func__);
276 status = -EINVAL;
277 break;
278 }
279 st_ses_info= calloc(1, sizeof(struct sound_trigger_info ));
280 if (!st_ses_info) {
281 ALOGE("%s: st_ses_info alloc failed", __func__);
282 status = -ENOMEM;
283 break;
284 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700285 memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
286 ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
287 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700288 list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
289 break;
290
Surendar Karka59c51072017-12-13 11:25:57 +0530291 case ST_EVENT_START_KEEP_ALIVE:
292 pthread_mutex_unlock(&st_dev->lock);
293 pthread_mutex_lock(&st_dev->adev->lock);
294 audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
295 pthread_mutex_unlock(&st_dev->adev->lock);
296 goto done;
297
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700298 case ST_EVENT_SESSION_DEREGISTER:
299 if (!config) {
300 ALOGE("%s: NULL config", __func__);
301 status = -EINVAL;
302 break;
303 }
304 st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
305 if (!st_ses_info) {
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700306 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 -0700307 status = -EINVAL;
308 break;
309 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700310 ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
311 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700312 list_remove(&st_ses_info->list);
313 free(st_ses_info);
314 break;
Surendar Karka59c51072017-12-13 11:25:57 +0530315
316 case ST_EVENT_STOP_KEEP_ALIVE:
317 pthread_mutex_unlock(&st_dev->lock);
318 pthread_mutex_lock(&st_dev->adev->lock);
319 audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
320 pthread_mutex_unlock(&st_dev->adev->lock);
321 goto done;
322
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700323 default:
324 ALOGW("%s: Unknown event %d", __func__, event);
325 break;
326 }
327 pthread_mutex_unlock(&st_dev->lock);
Surendar Karka59c51072017-12-13 11:25:57 +0530328done:
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700329 return status;
330}
331
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700332int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
333 size_t bytes)
334{
335 int ret = -1;
336 struct sound_trigger_info *st_info = NULL;
337 audio_event_info_t event;
338
339 if (!st_dev)
340 return ret;
341
342 if (!in->is_st_session_active) {
343 ALOGE(" %s: Sound trigger is not active", __func__);
344 goto exit;
345 }
346 if(in->standby)
347 in->standby = false;
348
349 pthread_mutex_lock(&st_dev->lock);
350 st_info = get_sound_trigger_info(in->capture_handle);
351 pthread_mutex_unlock(&st_dev->lock);
352 if (st_info) {
353 event.u.aud_info.ses_info = &st_info->st_ses;
354 event.u.aud_info.buf = buffer;
355 event.u.aud_info.num_bytes = bytes;
356 ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
357 }
358
359exit:
360 if (ret) {
361 if (-ENETRESET == ret)
362 in->is_st_session_active = false;
363 memset(buffer, 0, bytes);
364 ALOGV("%s: read failed status %d - sleep", __func__, ret);
365 usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
366 in->config.rate));
367 }
368 return ret;
369}
370
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700371void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
372{
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700373 struct sound_trigger_info *st_ses_info = NULL;
374 audio_event_info_t event;
375
Mingming Yinfd7607b2016-01-22 12:48:44 -0800376 if (!st_dev || !in || !in->is_st_session_active)
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700377 return;
378
379 pthread_mutex_lock(&st_dev->lock);
380 st_ses_info = get_sound_trigger_info(in->capture_handle);
Bharath Ramachandramurthy5baa6a52014-10-21 11:18:49 -0700381 pthread_mutex_unlock(&st_dev->lock);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700382 if (st_ses_info) {
383 event.u.ses_info = st_ses_info->st_ses;
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700384 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 -0700385 st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
Mingming Yinfd7607b2016-01-22 12:48:44 -0800386 in->is_st_session_active = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700387 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700388}
389void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in)
390{
391 struct sound_trigger_info *st_ses_info = NULL;
392 struct listnode *node;
393
394 if (!st_dev || !in)
395 return;
396
397 pthread_mutex_lock(&st_dev->lock);
398 in->is_st_session = false;
399 ALOGV("%s: list %d capture_handle %d", __func__,
400 list_empty(&st_dev->st_ses_list), in->capture_handle);
401 list_for_each(node, &st_dev->st_ses_list) {
402 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
403 if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700404 in->config = st_ses_info->st_ses.config;
405 in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
406 in->is_st_session = true;
Bharath Ramachandramurthy837535b2015-02-05 14:27:59 -0800407 in->is_st_session_active = true;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700408 ALOGD("%s: capture_handle %d is sound trigger", __func__, in->capture_handle);
409 break;
410 }
411 }
412 pthread_mutex_unlock(&st_dev->lock);
413}
414
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530415bool is_same_as_st_device(snd_device_t snd_device)
416{
417 if (snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC ||
418 snd_device == SND_DEVICE_IN_HANDSET_MIC ||
419 snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC_NS ||
420 snd_device == SND_DEVICE_IN_SPEAKER_MIC ||
421 snd_device == SND_DEVICE_IN_VOICE_SPEAKER_MIC ||
422 snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC ||
423 snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC_NS ||
424 snd_device == SND_DEVICE_IN_SPEAKER_MIC_NS) {
425 ALOGD("audio HAL using same device %d as ST", snd_device);
426 return true;
427 }
428 return false;
429}
430
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700431void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
432 st_event_type_t event)
433{
434 bool raise_event = false;
435 int device_type = -1;
436
437 if (!st_dev)
438 return;
439
440 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
441 snd_device < SND_DEVICE_OUT_END)
442 device_type = PCM_PLAYBACK;
443 else if (snd_device >= SND_DEVICE_IN_BEGIN &&
444 snd_device < SND_DEVICE_IN_END)
445 device_type = PCM_CAPTURE;
446 else {
447 ALOGE("%s: invalid device 0x%x, for event %d",
448 __func__, snd_device, event);
449 return;
450 }
451
452 raise_event = platform_sound_trigger_device_needs_event(snd_device);
453 ALOGI("%s: device 0x%x of type %d for Event %d, with Raise=%d",
454 __func__, snd_device, device_type, event, raise_event);
455 if (raise_event && (device_type == PCM_CAPTURE)) {
456 switch(event) {
457 case ST_EVENT_SND_DEVICE_FREE:
458 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE, NULL);
459 break;
460 case ST_EVENT_SND_DEVICE_BUSY:
461 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE, NULL);
462 break;
463 default:
464 ALOGW("%s:invalid event %d for device 0x%x",
465 __func__, event, snd_device);
466 }
467 }/*Events for output device, if required can be placed here in else*/
468}
469
470void audio_extn_sound_trigger_update_stream_status(struct audio_usecase *uc_info,
471 st_event_type_t event)
472{
473 bool raise_event = false;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530474 struct audio_event_info ev_info;
475 audio_event_type_t ev;
476 /*Initialize to invalid device*/
477 ev_info.device_info.device = -1;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700478
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530479 if (!st_dev)
480 return;
481
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700482 if (uc_info == NULL) {
483 ALOGE("%s: usecase is NULL!!!", __func__);
484 return;
485 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700486
Dhanalakshmi Siddani24e9ad52018-06-15 14:47:20 +0530487 if ((st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0) &&
488 (uc_info->type != PCM_PLAYBACK))
489 return;
490
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530491 if ((uc_info->in_snd_device >= SND_DEVICE_IN_BEGIN &&
492 uc_info->in_snd_device < SND_DEVICE_IN_END)) {
493 if (is_same_as_st_device(uc_info->in_snd_device))
494 ev_info.device_info.device = ST_DEVICE_HANDSET_MIC;
495 } else {
496 ALOGE("%s: invalid input device 0x%x, for event %d",
497 __func__, uc_info->in_snd_device, event);
498 }
499 raise_event = platform_sound_trigger_usecase_needs_event(uc_info->id);
500 ALOGD("%s: uc_info->id %d of type %d for Event %d, with Raise=%d",
501 __func__, uc_info->id, uc_info->type, event, raise_event);
502 if (raise_event) {
503 if (uc_info->type == PCM_PLAYBACK) {
Zhou Songc1088ea2018-06-12 00:17:29 +0800504 if (uc_info->stream.out)
505 ev_info.device_info.device = uc_info->stream.out->devices;
506 else
507 ev_info.device_info.device = AUDIO_DEVICE_OUT_SPEAKER;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530508 switch(event) {
509 case ST_EVENT_STREAM_FREE:
Zhou Songc1088ea2018-06-12 00:17:29 +0800510 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530511 break;
512 case ST_EVENT_STREAM_BUSY:
Zhou Songc1088ea2018-06-12 00:17:29 +0800513 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, &ev_info);
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530514 break;
515 default:
516 ALOGW("%s:invalid event %d, for usecase %d",
517 __func__, event, uc_info->id);
518 }
Revathi Uddaraju9f99ddd2018-05-03 12:01:38 +0530519 } else if ((uc_info->type == PCM_CAPTURE) || (uc_info->type == VOICE_CALL)) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530520 if (event == ST_EVENT_STREAM_BUSY)
521 ev = AUDIO_EVENT_CAPTURE_STREAM_ACTIVE;
522 else
523 ev = AUDIO_EVENT_CAPTURE_STREAM_INACTIVE;
524 if (!populate_usecase(&ev_info.u.usecase, uc_info)) {
525 ALOGD("%s: send event %d: usecase id %d, type %d",
526 __func__, ev, uc_info->id, uc_info->type);
527 st_dev->st_callback(ev, &ev_info);
528 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700529 }
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530530 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700531}
532
Zhou Songc1088ea2018-06-12 00:17:29 +0800533void audio_extn_sound_trigger_update_battery_status(bool charging)
534{
535 struct audio_event_info ev_info;
536
537 if (!st_dev || st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
538 return;
539
540 ev_info.u.value = charging;
541 st_dev->st_callback(AUDIO_EVENT_BATTERY_STATUS_CHANGED, &ev_info);
542}
543
544
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700545void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
546 struct str_parms *params)
547{
548 audio_event_info_t event;
549 char value[32];
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700550 int ret, val;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700551
552 if(!st_dev || !params) {
553 ALOGE("%s: str_params NULL", __func__);
554 return;
555 }
556
557 ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
558 sizeof(value));
559 if (ret > 0) {
560 if (strstr(value, "OFFLINE")) {
561 event.u.status = SND_CARD_STATUS_OFFLINE;
562 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
563 }
564 else if (strstr(value, "ONLINE")) {
565 event.u.status = SND_CARD_STATUS_ONLINE;
566 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
567 }
568 else
569 ALOGE("%s: unknown snd_card_status", __func__);
570 }
571
572 ret = str_parms_get_str(params, "CPE_STATUS", value, sizeof(value));
573 if (ret > 0) {
574 if (strstr(value, "OFFLINE")) {
575 event.u.status = CPE_STATUS_OFFLINE;
576 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
577 }
578 else if (strstr(value, "ONLINE")) {
579 event.u.status = CPE_STATUS_ONLINE;
580 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
581 }
582 else
583 ALOGE("%s: unknown CPE status", __func__);
584 }
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700585
586 ret = str_parms_get_int(params, "SVA_NUM_SESSIONS", &val);
587 if (ret >= 0) {
588 event.u.value = val;
589 st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
590 }
Quinn male73dd1fd2016-12-02 10:47:11 -0800591
592 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
593 if ((ret >= 0) && audio_is_input_device(val)) {
594 event.u.value = val;
595 st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
596 }
597
598 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
599 if ((ret >= 0) && audio_is_input_device(val)) {
600 event.u.value = val;
601 st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
602 }
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530603
604 ret = str_parms_get_str(params, "SVA_EXEC_MODE", value, sizeof(value));
605 if (ret >= 0) {
606 strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
607 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
608 }
609}
610
611void audio_extn_sound_trigger_get_parameters(const struct audio_device *adev __unused,
612 struct str_parms *query, struct str_parms *reply)
613{
614 audio_event_info_t event;
615 int ret;
616 char value[32];
617
618 ret = str_parms_get_str(query, "SVA_EXEC_MODE_STATUS", value,
619 sizeof(value));
620 if (ret >= 0) {
621 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE_STATUS, &event);
622 str_parms_add_int(reply, "SVA_EXEC_MODE_STATUS", event.u.value);
623 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700624}
625
626int audio_extn_sound_trigger_init(struct audio_device *adev)
627{
628 int status = 0;
629 char sound_trigger_lib[100];
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530630 void *sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700631
632 ALOGI("%s: Enter", __func__);
633
634 st_dev = (struct sound_trigger_audio_device*)
635 calloc(1, sizeof(struct sound_trigger_audio_device));
636 if (!st_dev) {
637 ALOGE("%s: ERROR. sound trigger alloc failed", __func__);
638 return -ENOMEM;
639 }
640
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530641 get_library_path(sound_trigger_lib);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700642 st_dev->lib_handle = dlopen(sound_trigger_lib, RTLD_NOW);
643
644 if (st_dev->lib_handle == NULL) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530645 ALOGE("%s: error %s", __func__, dlerror());
646 status = -ENODEV;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700647 goto cleanup;
648 }
649 ALOGI("%s: DLOPEN successful for %s", __func__, sound_trigger_lib);
650
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530651 DLSYM(st_dev->lib_handle, st_dev->st_callback, sound_trigger_hw_call_back,
652 status);
653 if (status)
654 goto cleanup;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700655
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530656 DLSYM(st_dev->lib_handle, sthal_prop_api_version,
657 sthal_prop_api_version, status);
658 if (status) {
659 st_dev->sthal_prop_api_version = 0;
660 status = 0; /* passthru for backward compability */
661 } else {
662 st_dev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
663 if (MAJOR_VERSION(st_dev->sthal_prop_api_version) !=
664 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
665 ALOGE("%s: Incompatible API versions ahal:0x%x != sthal:0x%x",
666 __func__, STHAL_PROP_API_CURRENT_VERSION,
667 st_dev->sthal_prop_api_version);
668 goto cleanup;
669 }
670 ALOGD("%s: sthal is using proprietary API version 0x%04x", __func__,
671 st_dev->sthal_prop_api_version);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700672 }
673
674 st_dev->adev = adev;
675 list_init(&st_dev->st_ses_list);
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530676 audio_extn_snd_mon_register_listener(st_dev, stdev_snd_mon_cb);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700677
678 return 0;
679
680cleanup:
681 if (st_dev->lib_handle)
682 dlclose(st_dev->lib_handle);
683 free(st_dev);
684 st_dev = NULL;
685 return status;
686
687}
688
689void audio_extn_sound_trigger_deinit(struct audio_device *adev)
690{
691 ALOGI("%s: Enter", __func__);
692 if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530693 audio_extn_snd_mon_unregister_listener(st_dev);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700694 dlclose(st_dev->lib_handle);
695 free(st_dev);
696 st_dev = NULL;
697 }
698}