blob: c49d779bf2236e47ff944ea25b91fe7a358426b1 [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>
38#include "audio_hw.h"
39#include "audio_extn.h"
40#include "platform.h"
41#include "platform_api.h"
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +053042
43/*-------------------- Begin: AHAL-STHAL Interface ---------------------------*/
44/*
45 * Maintain the proprietary interface between AHAL and STHAL locally to avoid
46 * the compilation dependency of interface header file from STHAL.
47 */
48
49#define MAKE_HAL_VERSION(maj, min) ((((maj) & 0xff) << 8) | ((min) & 0xff))
50#define MAJOR_VERSION(ver) (((ver) & 0xff00) >> 8)
51#define MINOR_VERSION(ver) ((ver) & 0x00ff)
52
53/* Proprietary interface version used for compatibility with STHAL */
54#define STHAL_PROP_API_VERSION_1_0 MAKE_HAL_VERSION(1, 0)
55#define STHAL_PROP_API_CURRENT_VERSION STHAL_PROP_API_VERSION_1_0
56
57#define ST_EVENT_CONFIG_MAX_STR_VALUE 32
58#define ST_DEVICE_HANDSET_MIC 1
59
60typedef enum {
61 ST_EVENT_SESSION_REGISTER,
62 ST_EVENT_SESSION_DEREGISTER,
63 ST_EVENT_START_KEEP_ALIVE,
64 ST_EVENT_STOP_KEEP_ALIVE,
65} sound_trigger_event_type_t;
66
67typedef enum {
68 AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE,
69 AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE,
70 AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE,
71 AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE,
72 AUDIO_EVENT_STOP_LAB,
73 AUDIO_EVENT_SSR,
74 AUDIO_EVENT_NUM_ST_SESSIONS,
75 AUDIO_EVENT_READ_SAMPLES,
76 AUDIO_EVENT_DEVICE_CONNECT,
77 AUDIO_EVENT_DEVICE_DISCONNECT,
78 AUDIO_EVENT_SVA_EXEC_MODE,
79 AUDIO_EVENT_SVA_EXEC_MODE_STATUS,
80 AUDIO_EVENT_CAPTURE_STREAM_INACTIVE,
81 AUDIO_EVENT_CAPTURE_STREAM_ACTIVE,
82} audio_event_type_t;
83
84typedef enum {
85 USECASE_TYPE_PCM_PLAYBACK,
86 USECASE_TYPE_PCM_CAPTURE,
87 USECASE_TYPE_VOICE_CALL,
88 USECASE_TYPE_VOIP_CALL,
89} audio_stream_usecase_type_t;
90
91typedef enum {
92 SND_CARD_STATUS_OFFLINE,
93 SND_CARD_STATUS_ONLINE,
94 CPE_STATUS_OFFLINE,
95 CPE_STATUS_ONLINE
96} ssr_event_status_t;
97
98struct sound_trigger_session_info {
99 void* p_ses; /* opaque pointer to st_session obj */
100 int capture_handle;
101 struct pcm *pcm;
102 struct pcm_config config;
103};
104
105struct audio_read_samples_info {
106 struct sound_trigger_session_info *ses_info;
107 void *buf;
108 size_t num_bytes;
109};
110
111struct audio_hal_usecase {
112 audio_stream_usecase_type_t type;
113};
114
115struct sound_trigger_event_info {
116 struct sound_trigger_session_info st_ses;
117};
118typedef struct sound_trigger_event_info sound_trigger_event_info_t;
119
120struct sound_trigger_device_info {
121 int device;
122};
123
124struct audio_event_info {
125 union {
126 ssr_event_status_t status;
127 int value;
128 struct sound_trigger_session_info ses_info;
129 struct audio_read_samples_info aud_info;
130 char str_value[ST_EVENT_CONFIG_MAX_STR_VALUE];
131 struct audio_hal_usecase usecase;
132 } u;
133 struct sound_trigger_device_info device_info;
134};
135typedef struct audio_event_info audio_event_info_t;
136/* STHAL callback which is called by AHAL */
137typedef int (*sound_trigger_hw_call_back_t)(audio_event_type_t,
138 struct audio_event_info*);
139
140/*---------------- End: AHAL-STHAL Interface ----------------------------------*/
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700141
Revathi Uddaraju1eac8b02017-05-18 17:13:33 +0530142#ifdef DYNAMIC_LOG_ENABLED
143#include <log_xml_parser.h>
144#define LOG_MASK HAL_MOD_FILE_SND_TRIGGER
145#include <log_utils.h>
146#endif
147
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700148#define XSTR(x) STR(x)
149#define STR(x) #x
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530150#define MAX_LIBRARY_PATH 100
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700151
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530152#define DLSYM(handle, ptr, symbol, err) \
153do {\
Venkatesh Mangalappalibcc684c2018-04-06 14:58:44 -0700154 ptr = dlsym(handle, #symbol); \
155 if (ptr == NULL) {\
156 ALOGW("%s: %s not found. %s", __func__, #symbol, dlerror());\
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530157 err = -ENODEV;\
158 }\
159} while(0)
160
161#ifdef __LP64__
162#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib64/hw/sound_trigger.primary.%s.so"
163#else
164#define SOUND_TRIGGER_LIBRARY_PATH "/vendor/lib/hw/sound_trigger.primary.%s.so"
165#endif
166
167/*
168 * Current proprietary API version used by AHAL. Queried by STHAL
169 * for compatibility check with AHAL
170 */
171const unsigned int sthal_prop_api_version = STHAL_PROP_API_CURRENT_VERSION;
172
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700173struct sound_trigger_info {
174 struct sound_trigger_session_info st_ses;
175 bool lab_stopped;
176 struct listnode list;
177};
178
179struct sound_trigger_audio_device {
180 void *lib_handle;
181 struct audio_device *adev;
182 sound_trigger_hw_call_back_t st_callback;
183 struct listnode st_ses_list;
184 pthread_mutex_t lock;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530185 unsigned int sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700186};
187
188static struct sound_trigger_audio_device *st_dev;
189
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530190#if LINUX_ENABLED
191static void get_library_path(char *lib_path)
192{
193 snprintf(lib_path, MAX_LIBRARY_PATH,
Manish Dewangan6a36d002017-10-09 14:11:00 +0530194 "sound_trigger.primary.default.so");
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530195}
196#else
197static void get_library_path(char *lib_path)
198{
199 snprintf(lib_path, MAX_LIBRARY_PATH,
David Ng06ccd872017-03-15 11:39:33 -0700200 "/vendor/lib/hw/sound_trigger.primary.%s.so",
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530201 XSTR(SOUND_TRIGGER_PLATFORM_NAME));
202}
203#endif
204
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700205static struct sound_trigger_info *
206get_sound_trigger_info(int capture_handle)
207{
208 struct sound_trigger_info *st_ses_info = NULL;
209 struct listnode *node;
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700210 ALOGV("%s: list empty %d capture_handle %d", __func__,
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700211 list_empty(&st_dev->st_ses_list), capture_handle);
212 list_for_each(node, &st_dev->st_ses_list) {
213 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
214 if (st_ses_info->st_ses.capture_handle == capture_handle)
215 return st_ses_info;
216 }
217 return NULL;
218}
219
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530220static int populate_usecase(struct audio_hal_usecase *usecase,
221 struct audio_usecase *uc_info)
222{
223 int status = 0;
224
225 switch(uc_info->type) {
226 case PCM_PLAYBACK:
227 if (uc_info->id == USECASE_AUDIO_PLAYBACK_VOIP)
228 usecase->type = USECASE_TYPE_VOIP_CALL;
229 else
230 usecase->type = USECASE_TYPE_PCM_PLAYBACK;
231 break;
232
233 case PCM_CAPTURE:
234 if (uc_info->id == USECASE_AUDIO_RECORD_VOIP)
235 usecase->type = USECASE_TYPE_VOIP_CALL;
236 else
237 usecase->type = USECASE_TYPE_PCM_CAPTURE;
238 break;
239
240 case VOICE_CALL:
241 usecase->type = USECASE_TYPE_VOICE_CALL;
242 break;
243
244 default:
245 ALOGE("%s: unsupported usecase type %d", __func__, uc_info->type);
246 status = -EINVAL;
247 }
248 return status;
249}
250
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530251static void stdev_snd_mon_cb(void * stream __unused, struct str_parms * parms)
252{
253 if (!parms)
254 return;
255
256 audio_extn_sound_trigger_set_parameters(NULL, parms);
257 return;
258}
259
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700260int audio_hw_call_back(sound_trigger_event_type_t event,
261 sound_trigger_event_info_t* config)
262{
263 int status = 0;
264 struct sound_trigger_info *st_ses_info;
265
266 if (!st_dev)
267 return -EINVAL;
268
269 pthread_mutex_lock(&st_dev->lock);
270 switch (event) {
271 case ST_EVENT_SESSION_REGISTER:
272 if (!config) {
273 ALOGE("%s: NULL config", __func__);
274 status = -EINVAL;
275 break;
276 }
277 st_ses_info= calloc(1, sizeof(struct sound_trigger_info ));
278 if (!st_ses_info) {
279 ALOGE("%s: st_ses_info alloc failed", __func__);
280 status = -ENOMEM;
281 break;
282 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700283 memcpy(&st_ses_info->st_ses, &config->st_ses, sizeof (struct sound_trigger_session_info));
284 ALOGV("%s: add capture_handle %d st session opaque ptr %p", __func__,
285 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700286 list_add_tail(&st_dev->st_ses_list, &st_ses_info->list);
287 break;
288
Surendar Karka59c51072017-12-13 11:25:57 +0530289 case ST_EVENT_START_KEEP_ALIVE:
290 pthread_mutex_unlock(&st_dev->lock);
291 pthread_mutex_lock(&st_dev->adev->lock);
292 audio_extn_keep_alive_start(KEEP_ALIVE_OUT_PRIMARY);
293 pthread_mutex_unlock(&st_dev->adev->lock);
294 goto done;
295
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700296 case ST_EVENT_SESSION_DEREGISTER:
297 if (!config) {
298 ALOGE("%s: NULL config", __func__);
299 status = -EINVAL;
300 break;
301 }
302 st_ses_info = get_sound_trigger_info(config->st_ses.capture_handle);
303 if (!st_ses_info) {
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700304 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 -0700305 status = -EINVAL;
306 break;
307 }
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700308 ALOGV("%s: remove capture_handle %d st session opaque ptr %p", __func__,
309 st_ses_info->st_ses.capture_handle, st_ses_info->st_ses.p_ses);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700310 list_remove(&st_ses_info->list);
311 free(st_ses_info);
312 break;
Surendar Karka59c51072017-12-13 11:25:57 +0530313
314 case ST_EVENT_STOP_KEEP_ALIVE:
315 pthread_mutex_unlock(&st_dev->lock);
316 pthread_mutex_lock(&st_dev->adev->lock);
317 audio_extn_keep_alive_stop(KEEP_ALIVE_OUT_PRIMARY);
318 pthread_mutex_unlock(&st_dev->adev->lock);
319 goto done;
320
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700321 default:
322 ALOGW("%s: Unknown event %d", __func__, event);
323 break;
324 }
325 pthread_mutex_unlock(&st_dev->lock);
Surendar Karka59c51072017-12-13 11:25:57 +0530326done:
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700327 return status;
328}
329
Bharath Ramachandramurthy76d20892015-04-27 15:47:55 -0700330int audio_extn_sound_trigger_read(struct stream_in *in, void *buffer,
331 size_t bytes)
332{
333 int ret = -1;
334 struct sound_trigger_info *st_info = NULL;
335 audio_event_info_t event;
336
337 if (!st_dev)
338 return ret;
339
340 if (!in->is_st_session_active) {
341 ALOGE(" %s: Sound trigger is not active", __func__);
342 goto exit;
343 }
344 if(in->standby)
345 in->standby = false;
346
347 pthread_mutex_lock(&st_dev->lock);
348 st_info = get_sound_trigger_info(in->capture_handle);
349 pthread_mutex_unlock(&st_dev->lock);
350 if (st_info) {
351 event.u.aud_info.ses_info = &st_info->st_ses;
352 event.u.aud_info.buf = buffer;
353 event.u.aud_info.num_bytes = bytes;
354 ret = st_dev->st_callback(AUDIO_EVENT_READ_SAMPLES, &event);
355 }
356
357exit:
358 if (ret) {
359 if (-ENETRESET == ret)
360 in->is_st_session_active = false;
361 memset(buffer, 0, bytes);
362 ALOGV("%s: read failed status %d - sleep", __func__, ret);
363 usleep((bytes * 1000000) / (audio_stream_in_frame_size((struct audio_stream_in *)in) *
364 in->config.rate));
365 }
366 return ret;
367}
368
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700369void audio_extn_sound_trigger_stop_lab(struct stream_in *in)
370{
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700371 struct sound_trigger_info *st_ses_info = NULL;
372 audio_event_info_t event;
373
Mingming Yinfd7607b2016-01-22 12:48:44 -0800374 if (!st_dev || !in || !in->is_st_session_active)
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700375 return;
376
377 pthread_mutex_lock(&st_dev->lock);
378 st_ses_info = get_sound_trigger_info(in->capture_handle);
Bharath Ramachandramurthy5baa6a52014-10-21 11:18:49 -0700379 pthread_mutex_unlock(&st_dev->lock);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700380 if (st_ses_info) {
381 event.u.ses_info = st_ses_info->st_ses;
Shiv Maliyappanahalli0e283d32016-07-14 23:20:03 -0700382 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 -0700383 st_dev->st_callback(AUDIO_EVENT_STOP_LAB, &event);
Mingming Yinfd7607b2016-01-22 12:48:44 -0800384 in->is_st_session_active = false;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700385 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700386}
387void audio_extn_sound_trigger_check_and_get_session(struct stream_in *in)
388{
389 struct sound_trigger_info *st_ses_info = NULL;
390 struct listnode *node;
391
392 if (!st_dev || !in)
393 return;
394
395 pthread_mutex_lock(&st_dev->lock);
396 in->is_st_session = false;
397 ALOGV("%s: list %d capture_handle %d", __func__,
398 list_empty(&st_dev->st_ses_list), in->capture_handle);
399 list_for_each(node, &st_dev->st_ses_list) {
400 st_ses_info = node_to_item(node, struct sound_trigger_info , list);
401 if (st_ses_info->st_ses.capture_handle == in->capture_handle) {
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700402 in->config = st_ses_info->st_ses.config;
403 in->channel_mask = audio_channel_in_mask_from_count(in->config.channels);
404 in->is_st_session = true;
Bharath Ramachandramurthy837535b2015-02-05 14:27:59 -0800405 in->is_st_session_active = true;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700406 ALOGD("%s: capture_handle %d is sound trigger", __func__, in->capture_handle);
407 break;
408 }
409 }
410 pthread_mutex_unlock(&st_dev->lock);
411}
412
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530413bool is_same_as_st_device(snd_device_t snd_device)
414{
415 if (snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC ||
416 snd_device == SND_DEVICE_IN_HANDSET_MIC ||
417 snd_device == SND_DEVICE_IN_HANDSET_MIC_AEC_NS ||
418 snd_device == SND_DEVICE_IN_SPEAKER_MIC ||
419 snd_device == SND_DEVICE_IN_VOICE_SPEAKER_MIC ||
420 snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC ||
421 snd_device == SND_DEVICE_IN_SPEAKER_MIC_AEC_NS ||
422 snd_device == SND_DEVICE_IN_SPEAKER_MIC_NS) {
423 ALOGD("audio HAL using same device %d as ST", snd_device);
424 return true;
425 }
426 return false;
427}
428
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700429void audio_extn_sound_trigger_update_device_status(snd_device_t snd_device,
430 st_event_type_t event)
431{
432 bool raise_event = false;
433 int device_type = -1;
434
435 if (!st_dev)
436 return;
437
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530438 if (st_dev->sthal_prop_api_version >= STHAL_PROP_API_VERSION_1_0)
439 return;
440
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700441 if (snd_device >= SND_DEVICE_OUT_BEGIN &&
442 snd_device < SND_DEVICE_OUT_END)
443 device_type = PCM_PLAYBACK;
444 else if (snd_device >= SND_DEVICE_IN_BEGIN &&
445 snd_device < SND_DEVICE_IN_END)
446 device_type = PCM_CAPTURE;
447 else {
448 ALOGE("%s: invalid device 0x%x, for event %d",
449 __func__, snd_device, event);
450 return;
451 }
452
453 raise_event = platform_sound_trigger_device_needs_event(snd_device);
454 ALOGI("%s: device 0x%x of type %d for Event %d, with Raise=%d",
455 __func__, snd_device, device_type, event, raise_event);
456 if (raise_event && (device_type == PCM_CAPTURE)) {
457 switch(event) {
458 case ST_EVENT_SND_DEVICE_FREE:
459 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE, NULL);
460 break;
461 case ST_EVENT_SND_DEVICE_BUSY:
462 st_dev->st_callback(AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE, NULL);
463 break;
464 default:
465 ALOGW("%s:invalid event %d for device 0x%x",
466 __func__, event, snd_device);
467 }
468 }/*Events for output device, if required can be placed here in else*/
469}
470
471void audio_extn_sound_trigger_update_stream_status(struct audio_usecase *uc_info,
472 st_event_type_t event)
473{
474 bool raise_event = false;
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530475 struct audio_event_info ev_info;
476 audio_event_type_t ev;
477 /*Initialize to invalid device*/
478 ev_info.device_info.device = -1;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700479
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530480 if (!st_dev)
481 return;
482
483 if (st_dev->sthal_prop_api_version < STHAL_PROP_API_VERSION_1_0)
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700484 return;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700485
486 if (uc_info == NULL) {
487 ALOGE("%s: usecase is NULL!!!", __func__);
488 return;
489 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700490
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) {
504 switch(event) {
505 case ST_EVENT_STREAM_FREE:
506 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE, NULL);
507 break;
508 case ST_EVENT_STREAM_BUSY:
509 st_dev->st_callback(AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE, NULL);
510 break;
511 default:
512 ALOGW("%s:invalid event %d, for usecase %d",
513 __func__, event, uc_info->id);
514 }
515 } else if (uc_info->type == PCM_CAPTURE) {
516 if (event == ST_EVENT_STREAM_BUSY)
517 ev = AUDIO_EVENT_CAPTURE_STREAM_ACTIVE;
518 else
519 ev = AUDIO_EVENT_CAPTURE_STREAM_INACTIVE;
520 if (!populate_usecase(&ev_info.u.usecase, uc_info)) {
521 ALOGD("%s: send event %d: usecase id %d, type %d",
522 __func__, ev, uc_info->id, uc_info->type);
523 st_dev->st_callback(ev, &ev_info);
524 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700525 }
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530526 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700527}
528
529void audio_extn_sound_trigger_set_parameters(struct audio_device *adev __unused,
530 struct str_parms *params)
531{
532 audio_event_info_t event;
533 char value[32];
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700534 int ret, val;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700535
536 if(!st_dev || !params) {
537 ALOGE("%s: str_params NULL", __func__);
538 return;
539 }
540
541 ret = str_parms_get_str(params, "SND_CARD_STATUS", value,
542 sizeof(value));
543 if (ret > 0) {
544 if (strstr(value, "OFFLINE")) {
545 event.u.status = SND_CARD_STATUS_OFFLINE;
546 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
547 }
548 else if (strstr(value, "ONLINE")) {
549 event.u.status = SND_CARD_STATUS_ONLINE;
550 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
551 }
552 else
553 ALOGE("%s: unknown snd_card_status", __func__);
554 }
555
556 ret = str_parms_get_str(params, "CPE_STATUS", value, sizeof(value));
557 if (ret > 0) {
558 if (strstr(value, "OFFLINE")) {
559 event.u.status = CPE_STATUS_OFFLINE;
560 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
561 }
562 else if (strstr(value, "ONLINE")) {
563 event.u.status = CPE_STATUS_ONLINE;
564 st_dev->st_callback(AUDIO_EVENT_SSR, &event);
565 }
566 else
567 ALOGE("%s: unknown CPE status", __func__);
568 }
Bharath Ramachandramurthyc694f8a2014-09-25 16:15:12 -0700569
570 ret = str_parms_get_int(params, "SVA_NUM_SESSIONS", &val);
571 if (ret >= 0) {
572 event.u.value = val;
573 st_dev->st_callback(AUDIO_EVENT_NUM_ST_SESSIONS, &event);
574 }
Quinn male73dd1fd2016-12-02 10:47:11 -0800575
576 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_CONNECT, &val);
577 if ((ret >= 0) && audio_is_input_device(val)) {
578 event.u.value = val;
579 st_dev->st_callback(AUDIO_EVENT_DEVICE_CONNECT, &event);
580 }
581
582 ret = str_parms_get_int(params, AUDIO_PARAMETER_DEVICE_DISCONNECT, &val);
583 if ((ret >= 0) && audio_is_input_device(val)) {
584 event.u.value = val;
585 st_dev->st_callback(AUDIO_EVENT_DEVICE_DISCONNECT, &event);
586 }
Chaithanya Krishna Bacharajue3d711e2016-12-08 16:17:32 +0530587
588 ret = str_parms_get_str(params, "SVA_EXEC_MODE", value, sizeof(value));
589 if (ret >= 0) {
590 strlcpy(event.u.str_value, value, sizeof(event.u.str_value));
591 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE, &event);
592 }
593}
594
595void audio_extn_sound_trigger_get_parameters(const struct audio_device *adev __unused,
596 struct str_parms *query, struct str_parms *reply)
597{
598 audio_event_info_t event;
599 int ret;
600 char value[32];
601
602 ret = str_parms_get_str(query, "SVA_EXEC_MODE_STATUS", value,
603 sizeof(value));
604 if (ret >= 0) {
605 st_dev->st_callback(AUDIO_EVENT_SVA_EXEC_MODE_STATUS, &event);
606 str_parms_add_int(reply, "SVA_EXEC_MODE_STATUS", event.u.value);
607 }
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700608}
609
610int audio_extn_sound_trigger_init(struct audio_device *adev)
611{
612 int status = 0;
613 char sound_trigger_lib[100];
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530614 void *sthal_prop_api_version;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700615
616 ALOGI("%s: Enter", __func__);
617
618 st_dev = (struct sound_trigger_audio_device*)
619 calloc(1, sizeof(struct sound_trigger_audio_device));
620 if (!st_dev) {
621 ALOGE("%s: ERROR. sound trigger alloc failed", __func__);
622 return -ENOMEM;
623 }
624
Yamit Mehtaa0d653a2016-11-25 20:33:25 +0530625 get_library_path(sound_trigger_lib);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700626 st_dev->lib_handle = dlopen(sound_trigger_lib, RTLD_NOW);
627
628 if (st_dev->lib_handle == NULL) {
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530629 ALOGE("%s: error %s", __func__, dlerror());
630 status = -ENODEV;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700631 goto cleanup;
632 }
633 ALOGI("%s: DLOPEN successful for %s", __func__, sound_trigger_lib);
634
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530635 DLSYM(st_dev->lib_handle, st_dev->st_callback, sound_trigger_hw_call_back,
636 status);
637 if (status)
638 goto cleanup;
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700639
Dhanalakshmi Siddanif133cc52018-02-08 14:34:51 +0530640 DLSYM(st_dev->lib_handle, sthal_prop_api_version,
641 sthal_prop_api_version, status);
642 if (status) {
643 st_dev->sthal_prop_api_version = 0;
644 status = 0; /* passthru for backward compability */
645 } else {
646 st_dev->sthal_prop_api_version = *(int*)sthal_prop_api_version;
647 if (MAJOR_VERSION(st_dev->sthal_prop_api_version) !=
648 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
649 ALOGE("%s: Incompatible API versions ahal:0x%x != sthal:0x%x",
650 __func__, STHAL_PROP_API_CURRENT_VERSION,
651 st_dev->sthal_prop_api_version);
652 goto cleanup;
653 }
654 ALOGD("%s: sthal is using proprietary API version 0x%04x", __func__,
655 st_dev->sthal_prop_api_version);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700656 }
657
658 st_dev->adev = adev;
659 list_init(&st_dev->st_ses_list);
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530660 audio_extn_snd_mon_register_listener(st_dev, stdev_snd_mon_cb);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700661
662 return 0;
663
664cleanup:
665 if (st_dev->lib_handle)
666 dlclose(st_dev->lib_handle);
667 free(st_dev);
668 st_dev = NULL;
669 return status;
670
671}
672
673void audio_extn_sound_trigger_deinit(struct audio_device *adev)
674{
675 ALOGI("%s: Enter", __func__);
676 if (st_dev && (st_dev->adev == adev) && st_dev->lib_handle) {
Dhananjay Kumare6293dd2017-05-25 17:25:30 +0530677 audio_extn_snd_mon_unregister_listener(st_dev);
Ravi Kumar Alamanda8fa6b192014-09-09 16:06:42 -0700678 dlclose(st_dev->lib_handle);
679 free(st_dev);
680 st_dev = NULL;
681 }
682}