1 /*
2 * Copyright (C) 2018 Knowles Electronics
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "SoundTriggerHAL"
18 #define LOG_NDEBUG 0
19
20 #include <errno.h>
21 #include <fcntl.h>
22 #include <malloc.h>
23 #include <poll.h>
24 #include <pthread.h>
25 #include <sys/ioctl.h>
26 #include <sys/prctl.h>
27 #include <log/log.h>
28 #include <cutils/uevent.h>
29 #include <cutils/properties.h>
30 #include <math.h>
31 #include <dlfcn.h>
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <unistd.h>
35 #include <sys/timerfd.h>
36
37 #include <hardware/hardware.h>
38 #include <hardware_legacy/power.h>
39
40 #include "cvq_ioctl.h"
41 #include "sound_trigger_hw_iaxxx.h"
42 #include "sound_trigger_intf.h"
43
44 #define MAX_GENERIC_SOUND_MODELS (9)
45 #define MAX_KEY_PHRASES (1)
46 #define MAX_MODELS (MAX_GENERIC_SOUND_MODELS + MAX_KEY_PHRASES)
47
48 #define MAX_USERS (1)
49 #define MAX_BUFFER_MS (3000)
50 #define POWER_CONSUMPTION (0) // TBD
51 #define ST_HAL_VERSION (1)
52
53 #define UEVENT_MSG_LEN (1024)
54
55 #define OK_GOOGLE_KW_ID (0)
56 #define AMBIENT_KW_ID (1)
57 #define ENTITY_KW_ID (2)
58 #define WAKEUP_KW_ID (3)
59 #define USELESS_KW_ID (999)
60
61 #define CVQ_ENDPOINT (IAXXX_SYSID_PLUGIN_1_OUT_EP_0)
62 #define MUSIC_BUF_ENDPOINT (IAXXX_SYSID_PLUGIN_3_OUT_EP_1)
63
64 #define IAXXX_VQ_EVENT_STR "IAXXX_VQ_EVENT"
65 #define IAXXX_RECOVERY_EVENT_STR "IAXXX_RECOVERY_EVENT"
66 #define IAXXX_FW_DWNLD_SUCCESS_STR "IAXXX_FW_DWNLD_SUCCESS"
67 #define IAXXX_FW_CRASH_EVENT_STR "IAXXX_CRASH_EVENT"
68
69 #define WAKE_LOCK_NAME "sthal_wake_lock"
70
71 #define CARD_NAME "iaxxx"
72 #define SOUND_TRIGGER_MIXER_PATH_BASE "/vendor/etc/sound_trigger_mixer_paths"
73 #define SOUND_TRIGGER_MIXER_PATH_XML "/vendor/etc/sound_trigger_mixer_paths_default.xml"
74
75 #define MAX_SND_CARD (8)
76 #define RETRY_NUMBER (10)
77 #define RETRY_US (500000)
78 #define TUNNEL_TIMEOUT 5
79
80 #define SENSOR_CREATE_WAIT_TIME_IN_S (1)
81 #define SENSOR_CREATE_WAIT_MAX_COUNT (5)
82
83 #define CHRE_CREATE_WAIT_TIME_IN_S (1)
84 #define CHRE_CREATE_WAIT_MAX_COUNT (5)
85
86 #define ST_DEVICE_HANDSET_MIC 1
87
88 #ifdef __LP64__
89 #define ADNC_STRM_LIBRARY_PATH "/vendor/lib64/hw/adnc_strm.primary.default.so"
90 #else
91 #define ADNC_STRM_LIBRARY_PATH "/vendor/lib/hw/adnc_strm.primary.default.so"
92 #endif
93
94 static const struct sound_trigger_properties hw_properties = {
95 "Knowles Electronics", // implementor
96 "Continous VoiceQ", // description
97 1, // version
98 // Version UUID
99 { 0x80f7dcd5, 0xbb62, 0x4816, 0xa931, {0x9c, 0xaa, 0x52, 0x5d, 0xf5, 0xc7}},
100 MAX_MODELS, // max_sound_models
101 MAX_KEY_PHRASES, // max_key_phrases
102 MAX_USERS, // max_users
103 RECOGNITION_MODE_VOICE_TRIGGER | // recognition_mode
104 RECOGNITION_MODE_GENERIC_TRIGGER,
105 true, // capture_transition
106 MAX_BUFFER_MS, // max_capture_ms
107 true, // concurrent_capture
108 false, // trigger_in_event
109 POWER_CONSUMPTION // power_consumption_mw
110 };
111
112 struct model_info {
113 void *recognition_cookie;
114 void *sound_model_cookie;
115 sound_model_handle_t model_handle;
116 sound_trigger_uuid_t uuid;
117 recognition_callback_t recognition_callback;
118 sound_model_callback_t sound_model_callback;
119 struct sound_trigger_recognition_config *config;
120 int kw_id;
121 sound_trigger_sound_model_type_t type;
122
123 void *data;
124 int data_sz;
125 bool is_loaded;
126 bool is_active;
127 bool is_state_query;
128 };
129
130 struct knowles_sound_trigger_device {
131 struct sound_trigger_hw_device device;
132 struct model_info models[MAX_MODELS];
133 sound_trigger_uuid_t authkw_model_uuid;
134 pthread_t callback_thread;
135 pthread_t monitor_thread;
136 pthread_t transitions_thread;
137 pthread_mutex_t lock;
138 pthread_cond_t transition_cond;
139 pthread_cond_t tunnel_create;
140 pthread_cond_t sensor_create;
141 pthread_cond_t chre_create;
142 int opened;
143 int send_sock;
144 int recv_sock;
145 struct sound_trigger_recognition_config *last_keyword_detected_config;
146
147 // Information about streaming
148 int is_streaming;
149 void *adnc_cvq_strm_lib;
150 int (*adnc_strm_open)(bool, int, int);
151 size_t (*adnc_strm_read)(long, void *, size_t);
152 int (*adnc_strm_close)(long);
153 long adnc_strm_handle[MAX_MODELS];
154 struct timespec adnc_strm_last_read[MAX_MODELS];
155
156 sound_trigger_uuid_t hotword_model_uuid;
157 sound_trigger_uuid_t sensor_model_uuid;
158 sound_trigger_uuid_t ambient_model_uuid;
159 sound_trigger_uuid_t chre_model_uuid;
160 sound_trigger_uuid_t entity_model_uuid;
161 sound_trigger_uuid_t wakeup_model_uuid;
162
163 int last_detected_model_type;
164 bool is_mic_route_enabled;
165 bool is_bargein_route_enabled;
166 bool is_chre_loaded;
167 bool is_buffer_package_loaded;
168 bool is_sensor_route_enabled;
169 bool is_src_package_loaded;
170 bool is_st_hal_ready;
171 int hotword_buffer_enable;
172 int music_buffer_enable;
173 bool is_sensor_destroy_in_prog;
174 bool is_chre_destroy_in_prog;
175
176 // conditions indicate AHAL and mic concurrency status
177 bool is_concurrent_capture;
178 bool is_con_mic_route_enabled;
179 bool is_ahal_media_recording;
180 bool is_ahal_in_voice_voip_mode;
181 bool is_ahal_voice_voip_stop;
182 bool is_ahal_voice_voip_start;
183
184 unsigned int current_enable;
185 unsigned int recover_model_list;
186 unsigned int rx_active_count;
187 transit_case_t transit_case;
188
189 struct audio_route *route_hdl;
190 struct mixer *mixer;
191 struct iaxxx_odsp_hw *odsp_hdl;
192
193 void *audio_hal_handle;
194 audio_hw_call_back_t audio_hal_cb;
195 unsigned int sthal_prop_api_version;
196
197 int snd_crd_num;
198 char mixer_path_xml[NAME_MAX_SIZE];
199 bool fw_reset_done_by_hal;
200
201 // sensor stop signal event
202 timer_t ss_timer;
203 bool ss_timer_created;
204
205 // Chre stop signal event
206 timer_t chre_timer;
207 bool chre_timer_created;
208 };
209
210 /*
211 * Since there's only ever one sound_trigger_device, keep it as a global so
212 * that other people can dlopen this lib to get at the streaming audio.
213 */
214
215 static struct knowles_sound_trigger_device g_stdev =
216 {
217 .lock = PTHREAD_MUTEX_INITIALIZER,
218 .tunnel_create = PTHREAD_COND_INITIALIZER,
219 .sensor_create = PTHREAD_COND_INITIALIZER,
220 .chre_create = PTHREAD_COND_INITIALIZER
221 };
222
223 static struct timespec reset_time = {0};
224
get_sthal_mode(struct knowles_sound_trigger_device * stdev)225 static enum sthal_mode get_sthal_mode(struct knowles_sound_trigger_device *stdev)
226 {
227 enum sthal_mode stmode = CON_DISABLED_ST;
228
229 if (stdev->is_ahal_in_voice_voip_mode == true) {
230 stmode = IN_CALL;
231 goto exit;
232 }
233
234 if (stdev->is_concurrent_capture == false) {
235 if (stdev->is_ahal_media_recording == true)
236 stmode = CON_DISABLED_CAPTURE;
237 else
238 stmode = CON_DISABLED_ST;
239 goto exit;
240 }
241
242 if (stdev->is_con_mic_route_enabled == true ) {
243 stmode = CON_ENABLED_CAPTURE_ST;
244 goto exit;
245 } else {
246 stmode = CON_ENABLED_ST;
247 goto exit;
248 }
249
250 ALOGW("%s: Invalid ST mode, use defualt mode", __func__);
251
252 exit:
253 //ALOGV("%s: ST mode is %d", __func__, stmode);
254 return stmode;
255 }
256
can_enable_chre(struct knowles_sound_trigger_device * stdev)257 static bool can_enable_chre(struct knowles_sound_trigger_device *stdev)
258 {
259 bool ret = false;
260 enum sthal_mode stm = get_sthal_mode(stdev);
261
262 if (stm == CON_ENABLED_CAPTURE_ST ||
263 stm == CON_ENABLED_ST ||
264 stm == CON_DISABLED_ST)
265 ret = true;
266 return ret;
267 }
268
can_update_recover_list(struct knowles_sound_trigger_device * stdev)269 static bool can_update_recover_list(struct knowles_sound_trigger_device *stdev)
270 {
271 bool ret = false;
272 enum sthal_mode stm = get_sthal_mode(stdev);
273
274 if (stm == IN_CALL || stm == CON_DISABLED_CAPTURE)
275 ret = true;
276 return ret;
277 }
278
is_mic_controlled_by_ahal(struct knowles_sound_trigger_device * stdev)279 static bool is_mic_controlled_by_ahal(struct knowles_sound_trigger_device *stdev)
280 {
281 bool ret = false;
282
283 if (get_sthal_mode(stdev) == CON_ENABLED_CAPTURE_ST)
284 ret = true;
285 return ret;
286 }
287
check_uuid_equality(sound_trigger_uuid_t uuid1,sound_trigger_uuid_t uuid2)288 static bool check_uuid_equality(sound_trigger_uuid_t uuid1,
289 sound_trigger_uuid_t uuid2)
290 {
291 if (uuid1.timeLow != uuid2.timeLow ||
292 uuid1.timeMid != uuid2.timeMid ||
293 uuid1.timeHiAndVersion != uuid2.timeHiAndVersion ||
294 uuid1.clockSeq != uuid2.clockSeq) {
295 return false;
296 }
297
298 for (int i = 0; i < 6; i++) {
299 if(uuid1.node[i] != uuid2.node[i]) {
300 return false;
301 }
302 }
303
304 return true;
305 }
306
str_to_uuid(char * uuid_str,sound_trigger_uuid_t * uuid)307 bool str_to_uuid(char* uuid_str, sound_trigger_uuid_t* uuid)
308 {
309 if (uuid_str == NULL) {
310 ALOGI("Invalid str_to_uuid input.");
311 return false;
312 }
313
314 int tmp[10];
315 if (sscanf(uuid_str, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
316 tmp, tmp+1, tmp+2, tmp+3, tmp+4, tmp+5,
317 tmp+6, tmp+7, tmp+8, tmp+9) < 10) {
318 ALOGI("Invalid UUID, got: %s", uuid_str);
319 return false;
320 }
321 uuid->timeLow = (unsigned int)tmp[0];
322 uuid->timeMid = (unsigned short)tmp[1];
323 uuid->timeHiAndVersion = (unsigned short)tmp[2];
324 uuid->clockSeq = (unsigned short)tmp[3];
325 uuid->node[0] = (unsigned char)tmp[4];
326 uuid->node[1] = (unsigned char)tmp[5];
327 uuid->node[2] = (unsigned char)tmp[6];
328 uuid->node[3] = (unsigned char)tmp[7];
329 uuid->node[4] = (unsigned char)tmp[8];
330 uuid->node[5] = (unsigned char)tmp[9];
331
332 return true;
333 }
334
find_empty_model_slot(struct knowles_sound_trigger_device * st_dev)335 static int find_empty_model_slot(struct knowles_sound_trigger_device *st_dev)
336 {
337 int i = -1;
338 for (i = 0; i < MAX_MODELS; i++) {
339 if (st_dev->models[i].is_loaded == false)
340 break;
341 }
342
343 if (i >= MAX_MODELS) {
344 i = -1;
345 }
346
347 return i;
348 }
349
find_handle_for_kw_id(struct knowles_sound_trigger_device * st_dev,int kw_id)350 static int find_handle_for_kw_id(
351 struct knowles_sound_trigger_device *st_dev, int kw_id)
352 {
353 int i = 0;
354 for (i = 0; i < MAX_MODELS; i++) {
355 if (kw_id == st_dev->models[i].kw_id)
356 break;
357 }
358
359 return i;
360 }
361
find_handle_for_uuid(struct knowles_sound_trigger_device * stdev,sound_trigger_uuid_t uuid)362 static int find_handle_for_uuid(
363 struct knowles_sound_trigger_device *stdev,
364 sound_trigger_uuid_t uuid)
365 {
366 int i = 0;
367 for (i = 0; i < MAX_MODELS; i++) {
368 if (check_uuid_equality(uuid, stdev->models[i].uuid))
369 break;
370 }
371
372 if (i == MAX_MODELS)
373 return -1;
374 else
375 return i;
376 }
377
is_any_model_active(struct knowles_sound_trigger_device * stdev)378 static bool is_any_model_active(struct knowles_sound_trigger_device *stdev) {
379 int i = 0;
380 for (i = 0; i < MAX_MODELS; i++) {
381 if (stdev->models[i].is_active == true) {
382 break;
383 }
384 }
385
386 if (i == MAX_MODELS)
387 return false;
388 else
389 return true;
390 }
391
is_any_model_loaded(struct knowles_sound_trigger_device * stdev)392 static bool is_any_model_loaded(struct knowles_sound_trigger_device *stdev) {
393 int i = 0;
394 for (i = 0; i < MAX_MODELS; i++) {
395 if (stdev->models[i].is_loaded == true) {
396 break;
397 }
398 }
399
400 if (i == MAX_MODELS)
401 return false;
402 else
403 return true;
404 }
405
reg_hal_event_session(struct sound_trigger_recognition_config * config,sound_model_handle_t handle)406 static void reg_hal_event_session(
407 struct sound_trigger_recognition_config *config,
408 sound_model_handle_t handle)
409 {
410 struct knowles_sound_trigger_device *stdev = &g_stdev;
411 struct sound_trigger_event_info event_info;
412 /*
413 * Register config and capture_handle of trigger sound model to audio hal
414 * It only register while request capturing buffer.
415 */
416 if (config->capture_requested && stdev->audio_hal_cb) {
417 ALOGD("%s: ST_EVENT_SESSION_REGISTER capture_handle %d model %p",
418 __func__, config->capture_handle, &stdev->models[handle]);
419 event_info.st_ses.p_ses = (void *)&stdev->models[handle];
420 event_info.st_ses.config = stdev_hotword_pcm_config;
421 event_info.st_ses.capture_handle = config->capture_handle;
422 event_info.st_ses.pcm = NULL;
423 stdev->audio_hal_cb(ST_EVENT_SESSION_REGISTER, &event_info);
424 }
425 }
426
dereg_hal_event_session(struct sound_trigger_recognition_config * config,sound_model_handle_t handle)427 static void dereg_hal_event_session(
428 struct sound_trigger_recognition_config *config,
429 sound_model_handle_t handle)
430 {
431 struct knowles_sound_trigger_device *stdev = &g_stdev;
432 struct sound_trigger_event_info event_info;
433 /*
434 * Indicate to audio hal that streaming is stopped.
435 * Stop capturing data from STHAL.
436 */
437 if (config->capture_requested && stdev->audio_hal_cb) {
438 ALOGD("%s: ST_EVENT_SESSION_DEREGISTER capture_handle %d model %p",
439 __func__, config->capture_handle, &stdev->models[handle]);
440 event_info.st_ses.p_ses = (void *)&stdev->models[handle];
441 event_info.st_ses.capture_handle = config->capture_handle;
442 event_info.st_ses.pcm = NULL;
443 stdev->audio_hal_cb(ST_EVENT_SESSION_DEREGISTER, &event_info);
444 }
445 }
446
447
stdev_keyphrase_event_alloc(sound_model_handle_t handle,struct sound_trigger_recognition_config * config,int recognition_status)448 static char *stdev_keyphrase_event_alloc(sound_model_handle_t handle,
449 struct sound_trigger_recognition_config *config,
450 int recognition_status)
451 {
452 char *data;
453 struct sound_trigger_phrase_recognition_event *event;
454 data = (char *)calloc(1,
455 sizeof(struct sound_trigger_phrase_recognition_event));
456 if (!data)
457 return NULL;
458 event = (struct sound_trigger_phrase_recognition_event *)data;
459 event->common.status = recognition_status;
460 event->common.type = SOUND_MODEL_TYPE_KEYPHRASE;
461 event->common.model = handle;
462 event->common.capture_available = false;
463
464 if (config) {
465 unsigned int i;
466
467 event->num_phrases = config->num_phrases;
468 if (event->num_phrases > SOUND_TRIGGER_MAX_PHRASES)
469 event->num_phrases = SOUND_TRIGGER_MAX_PHRASES;
470 for (i = 0; i < event->num_phrases; i++)
471 memcpy(&event->phrase_extras[i],
472 &config->phrases[i],
473 sizeof(struct sound_trigger_phrase_recognition_extra));
474 }
475
476 event->num_phrases = 1;
477 event->phrase_extras[0].confidence_level = 100;
478 event->phrase_extras[0].num_levels = 1;
479 event->phrase_extras[0].levels[0].level = 100;
480 event->phrase_extras[0].levels[0].user_id = 0;
481 /*
482 * Signify that all the data is comming through streaming
483 * and not through the buffer.
484 */
485 event->common.capture_available = true;
486 event->common.capture_delay_ms = 0;
487 event->common.capture_preamble_ms = 0;
488 event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
489 event->common.audio_config.sample_rate = 16000;
490 event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
491 event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
492
493 return data;
494 }
495
stdev_generic_event_alloc(int model_handle,void * payload,unsigned int payload_size,int recognition_status)496 static char *stdev_generic_event_alloc(int model_handle, void *payload,
497 unsigned int payload_size,
498 int recognition_status)
499 {
500 char *data;
501 struct sound_trigger_generic_recognition_event *event;
502
503 data = (char *)calloc(1,
504 sizeof(struct sound_trigger_generic_recognition_event) +
505 payload_size);
506 if (!data) {
507 ALOGE("%s: Failed to allocate memory for recog event", __func__);
508 return NULL;
509 }
510
511 event = (struct sound_trigger_generic_recognition_event *)data;
512 event->common.status = recognition_status;
513 event->common.type = SOUND_MODEL_TYPE_GENERIC;
514 event->common.model = model_handle;
515
516 /*
517 * Signify that all the data is comming through streaming and
518 * not through the buffer.
519 */
520 event->common.capture_available = true;
521 event->common.audio_config = AUDIO_CONFIG_INITIALIZER;
522 event->common.audio_config.sample_rate = 16000;
523 event->common.audio_config.channel_mask = AUDIO_CHANNEL_IN_MONO;
524 event->common.audio_config.format = AUDIO_FORMAT_PCM_16_BIT;
525
526 if (payload && payload_size > 0) {
527 ALOGD("%s: Attach payload in the event", __func__);
528 event->common.data_size = payload_size;
529 event->common.data_offset =
530 sizeof(struct sound_trigger_generic_recognition_event);
531
532 memcpy((data + event->common.data_offset), payload, payload_size);
533 }
534
535 return data;
536 }
537
stdev_close_term_sock(struct knowles_sound_trigger_device * stdev)538 static void stdev_close_term_sock(struct knowles_sound_trigger_device *stdev)
539 {
540 if (stdev->send_sock >= 0) {
541 close(stdev->send_sock);
542 stdev->send_sock = -1;
543 }
544
545 if (stdev->recv_sock >= 0) {
546 close(stdev->recv_sock);
547 stdev->recv_sock = -1;
548 }
549 }
550
is_uuid_in_recover_list(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle)551 static bool is_uuid_in_recover_list(struct knowles_sound_trigger_device *stdev,
552 sound_model_handle_t handle)
553 {
554 int mask = 0;
555 sound_trigger_uuid_t target_uuid = stdev->models[handle].uuid;
556
557 if (check_uuid_equality(target_uuid, stdev->chre_model_uuid)) {
558 mask = CHRE_MASK;
559 } else if (check_uuid_equality(target_uuid, stdev->hotword_model_uuid) ||
560 check_uuid_equality(target_uuid, stdev->wakeup_model_uuid)) {
561 mask = PLUGIN1_MASK;
562 } else if (check_uuid_equality(target_uuid, stdev->ambient_model_uuid) ||
563 check_uuid_equality(target_uuid, stdev->entity_model_uuid)) {
564 mask = PLUGIN2_MASK;
565 } else {
566 //ALOGV("%s: Invalid uuid.", __func__);
567 }
568
569 return (stdev->recover_model_list & mask) ? true : false;
570 }
571
update_recover_list(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle,bool enable)572 static void update_recover_list(struct knowles_sound_trigger_device *stdev,
573 sound_model_handle_t handle,
574 bool enable)
575 {
576 int mask = 0;
577
578 sound_trigger_uuid_t target_uuid = stdev->models[handle].uuid;
579
580 ALOGD("%s: handle %d enable %d", __func__, handle, enable);
581 if (check_uuid_equality(target_uuid, stdev->chre_model_uuid)) {
582 mask = CHRE_MASK;
583 } else if (check_uuid_equality(target_uuid, stdev->hotword_model_uuid) ||
584 check_uuid_equality(target_uuid, stdev->wakeup_model_uuid)) {
585 mask = PLUGIN1_MASK;
586 } else if (check_uuid_equality(target_uuid, stdev->ambient_model_uuid) ||
587 check_uuid_equality(target_uuid, stdev->entity_model_uuid)) {
588 mask = PLUGIN2_MASK;
589 } else {
590 //ALOGV("%s: Invalid uuid.", __func__);
591 }
592
593 if (enable)
594 stdev->recover_model_list |= mask;
595 else
596 stdev->recover_model_list &= ~mask;
597
598 return;
599 }
600
check_and_setup_src_package(struct knowles_sound_trigger_device * stdev)601 static int check_and_setup_src_package(
602 struct knowles_sound_trigger_device *stdev)
603 {
604 int err = 0;
605
606 if (stdev->is_src_package_loaded == false) {
607 err = setup_src_package(stdev->odsp_hdl);
608 if (err != 0) {
609 ALOGE("%s: Failed to load SRC package", __func__);
610 goto exit;
611 } else {
612 ALOGD("%s: SRC package loaded", __func__);
613 stdev->is_src_package_loaded = true;
614 }
615 } else {
616 ALOGD("%s: SRC package is already loaded", __func__);
617 }
618
619 exit:
620 return err;
621 }
622
check_and_destroy_src_package(struct knowles_sound_trigger_device * stdev)623 static int check_and_destroy_src_package(
624 struct knowles_sound_trigger_device *stdev)
625 {
626 int err = 0;
627
628 if (!is_any_model_active(stdev) && stdev->is_src_package_loaded == true) {
629 err = destroy_src_package(stdev->odsp_hdl);
630 if (err != 0) {
631 ALOGE("%s: Failed to destroy SRC package", __func__);
632 goto exit;
633 } else {
634 ALOGD("%s: SRC package destroy", __func__);
635 stdev->is_src_package_loaded = false;
636 }
637 }
638
639 exit:
640 return err;
641 }
642
check_and_setup_buffer_package(struct knowles_sound_trigger_device * stdev)643 static int check_and_setup_buffer_package(
644 struct knowles_sound_trigger_device *stdev)
645 {
646 int err = 0;
647
648 if (stdev->is_buffer_package_loaded == false) {
649 err = setup_buffer_package(stdev->odsp_hdl);
650 if (err != 0) {
651 ALOGE("%s: Failed to load Buffer package", __func__);
652 goto exit;
653 } else {
654 ALOGD("%s: Buffer package loaded", __func__);
655 stdev->is_buffer_package_loaded = true;
656 }
657 } else {
658 ALOGD("%s: Buffer package is already loaded", __func__);
659 }
660
661 exit:
662 return err;
663 }
664
check_and_destroy_buffer_package(struct knowles_sound_trigger_device * stdev)665 static int check_and_destroy_buffer_package(
666 struct knowles_sound_trigger_device *stdev)
667 {
668 int err = 0;
669
670 if (!is_any_model_active(stdev) &&
671 stdev->is_buffer_package_loaded &&
672 (!stdev->is_sensor_destroy_in_prog &&
673 !stdev->is_sensor_route_enabled) &&
674 (!stdev->is_chre_destroy_in_prog &&
675 !stdev->is_chre_loaded)) {
676
677 err = destroy_buffer_package(stdev->odsp_hdl);
678 if (err != 0) {
679 ALOGE("%s: Failed to destroy Buffer package", __func__);
680 goto exit;
681 } else {
682 ALOGD("%s: Buffer package destroy", __func__);
683 stdev->is_buffer_package_loaded = false;
684 }
685 }
686
687 exit:
688 return err;
689 }
690
setup_package(struct knowles_sound_trigger_device * stdev,struct model_info * model)691 static int setup_package(struct knowles_sound_trigger_device *stdev,
692 struct model_info *model)
693 {
694 int err = 0;
695
696 if (check_uuid_equality(model->uuid, stdev->chre_model_uuid)) {
697 if (!(stdev->current_enable & CHRE_MASK)) {
698 err = setup_chre_package(stdev->odsp_hdl);
699 if (err != 0) {
700 ALOGE("Failed to load CHRE package");
701 goto exit;
702 }
703 }
704 stdev->current_enable = stdev->current_enable | CHRE_MASK;
705 } else if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid)) {
706 if (!(stdev->current_enable & PLUGIN1_MASK)) {
707 err = setup_hotword_package(stdev->odsp_hdl);
708 if (err != 0) {
709 ALOGE("Failed to load Hotword package");
710 goto exit;
711 }
712 }
713 err = write_model(stdev->odsp_hdl, model->data, model->data_sz,
714 model->kw_id);
715 if (err != 0) {
716 ALOGE("Failed to write Hotword model");
717 goto exit;
718 }
719
720 //setup model state.
721 stdev->current_enable = stdev->current_enable | HOTWORD_MASK;
722 err = set_hotword_state(stdev->odsp_hdl, stdev->current_enable);
723 if (err != 0) {
724 ALOGE("Failed to set Hotword state");
725 goto exit;
726 }
727 } else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid)) {
728 if (!(stdev->current_enable & PLUGIN1_MASK)) {
729 err = setup_hotword_package(stdev->odsp_hdl);
730 if (err != 0) {
731 ALOGE("Failed to load Hotword package");
732 goto exit;
733 }
734 }
735 err = write_model(stdev->odsp_hdl, model->data, model->data_sz,
736 model->kw_id);
737 if (err != 0) {
738 ALOGE("Failed to write Wakeup model");
739 goto exit;
740 }
741
742 //setup model state.
743 stdev->current_enable = stdev->current_enable | WAKEUP_MASK;
744 err = set_hotword_state(stdev->odsp_hdl, stdev->current_enable);
745 if (err != 0) {
746 ALOGE("Failed to set Wakeup state");
747 goto exit;
748 }
749 } else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid)) {
750 if (!(stdev->current_enable & PLUGIN2_MASK)) {
751 err = setup_ambient_package(stdev->odsp_hdl);
752 if (err != 0) {
753 ALOGE("Failed to load Ambient package");
754 goto exit;
755 }
756 } else {
757 // tear down plugin2 for writing new model data.
758 err = tear_ambient_state(stdev->odsp_hdl,
759 stdev->current_enable);
760 }
761 err = write_model(stdev->odsp_hdl, model->data,
762 model->data_sz, model->kw_id);
763 if (err != 0) {
764 ALOGE("Failed to write Ambient model");
765 goto exit;
766 }
767
768 //setup model state.
769 stdev->current_enable = stdev->current_enable | AMBIENT_MASK;
770 err = set_ambient_state(stdev->odsp_hdl, stdev->current_enable);
771 if (err != 0) {
772 ALOGE("Failed to set Ambient state");
773 goto exit;
774 }
775
776 } else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
777 if (!(stdev->current_enable & PLUGIN2_MASK)) {
778 err = setup_ambient_package(stdev->odsp_hdl);
779 if (err != 0) {
780 ALOGE("Failed to load Ambient package");
781 goto exit;
782 }
783 } else {
784 // tear down plugin2 for writing new model data.
785 err = tear_ambient_state(stdev->odsp_hdl,
786 stdev->current_enable);
787 }
788 err = write_model(stdev->odsp_hdl, model->data,
789 model->data_sz, model->kw_id);
790 if (err != 0) {
791 ALOGE("Failed to write Entity model");
792 goto exit;
793 }
794
795 //setup model state.
796 stdev->current_enable = stdev->current_enable | ENTITY_MASK;
797 err = set_ambient_state(stdev->odsp_hdl, stdev->current_enable);
798 if (err != 0) {
799 ALOGE("Failed to set Entity state");
800 goto exit;
801 }
802 }
803
804 exit:
805 return err;
806 }
807
setup_buffer(struct knowles_sound_trigger_device * stdev,struct model_info * model,bool enabled)808 static int setup_buffer(struct knowles_sound_trigger_device *stdev,
809 struct model_info *model,
810 bool enabled)
811 {
812 int err = 0;
813 if (enabled) {
814 if ((check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
815 || (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
816
817 stdev->hotword_buffer_enable++;
818 if (stdev->hotword_buffer_enable > 1)
819 goto exit;
820
821 err = setup_howord_buffer(stdev->odsp_hdl);
822 if (err != 0) {
823 stdev->hotword_buffer_enable--;
824 ALOGE("Failed to create the buffer plugin");
825 goto exit;
826 }
827 } else if ((check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
828 || (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
829
830 stdev->music_buffer_enable++;
831 if (stdev->music_buffer_enable > 1)
832 goto exit;
833
834 err = setup_music_buffer(stdev->odsp_hdl);
835 if (err != 0) {
836 stdev->music_buffer_enable--;
837 ALOGE("Failed to load music buffer package");
838 goto exit;
839 }
840 }
841 } else {
842 if ((check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
843 || (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
844 if (stdev->hotword_buffer_enable == 0) {
845 ALOGW("Invalid call for setup buffer");
846 goto exit;
847 }
848 stdev->hotword_buffer_enable--;
849 if (stdev->hotword_buffer_enable != 0)
850 goto exit;
851
852 err = destroy_howord_buffer(stdev->odsp_hdl);
853
854 if (err != 0) {
855 ALOGE("Failed to unload hotword buffer package");
856 goto exit;
857 }
858
859 } else if ((check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
860 || (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
861 if (stdev->music_buffer_enable == 0) {
862 ALOGW("Invalid call for setup buffer");
863 goto exit;
864 }
865 stdev->music_buffer_enable--;
866 if (stdev->music_buffer_enable != 0)
867 goto exit;
868
869 err = destroy_music_buffer(stdev->odsp_hdl);
870 if (err != 0) {
871 ALOGE("Failed to unload music buffer package");
872 goto exit;
873 }
874 }
875 }
876
877 exit:
878 return err;
879 }
880
destroy_package(struct knowles_sound_trigger_device * stdev,struct model_info * model)881 static int destroy_package(struct knowles_sound_trigger_device *stdev,
882 struct model_info *model)
883 {
884 int err = 0;
885
886 if (check_uuid_equality(model->uuid, stdev->chre_model_uuid)) {
887 stdev->current_enable = stdev->current_enable & ~CHRE_MASK;
888 if (!(stdev->current_enable & CHRE_MASK)) {
889 err = destroy_chre_package(stdev->odsp_hdl);
890 if (err != 0) {
891 ALOGE("Failed to destroy CHRE package");
892 goto exit;
893 }
894 }
895 } else if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid)) {
896 err = tear_hotword_state(stdev->odsp_hdl, HOTWORD_MASK);
897 if (err != 0) {
898 ALOGE("Failed to tear Hotword state");
899 goto exit;
900 }
901
902 err = flush_model(stdev->odsp_hdl, model->kw_id);
903 if (err != 0) {
904 ALOGE("Failed to flush Hotword model");
905 goto exit;
906 }
907 stdev->current_enable = stdev->current_enable & ~HOTWORD_MASK;
908
909 if (!(stdev->current_enable & PLUGIN1_MASK)) {
910 err = destroy_hotword_package(stdev->odsp_hdl);
911 if (err != 0) {
912 ALOGE("Failed to destroy Hotword package");
913 goto exit;
914 }
915 }
916
917 } else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid)) {
918 err = tear_hotword_state(stdev->odsp_hdl, WAKEUP_MASK);
919 if (err != 0) {
920 ALOGE("Failed to tear Wakeup state");
921 goto exit;
922 }
923
924 err = flush_model(stdev->odsp_hdl, model->kw_id);
925 if (err != 0) {
926 ALOGE("Failed to flush Wakeup model");
927 goto exit;
928 }
929 stdev->current_enable = stdev->current_enable & ~WAKEUP_MASK;
930
931 if (!(stdev->current_enable & PLUGIN1_MASK)) {
932 err = destroy_hotword_package(stdev->odsp_hdl);
933 if (err != 0) {
934 ALOGE("Failed to destroy Hotword package");
935 goto exit;
936 }
937 }
938
939 } else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid)) {
940 err = tear_ambient_state(stdev->odsp_hdl, AMBIENT_MASK);
941 if (err != 0) {
942 ALOGE("Failed to tear Ambient state");
943 goto exit;
944 }
945
946 err = flush_model(stdev->odsp_hdl, model->kw_id);
947 if (err != 0) {
948 ALOGE("Failed to flush Ambient model");
949 goto exit;
950 }
951 stdev->current_enable = stdev->current_enable & ~AMBIENT_MASK;
952
953 if (!(stdev->current_enable & PLUGIN2_MASK)) {
954 err = destroy_ambient_package(stdev->odsp_hdl);
955 if (err != 0) {
956 ALOGE("Failed to destroy Ambient package");
957 goto exit;
958 }
959 }
960 } else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
961 err = tear_ambient_state(stdev->odsp_hdl, ENTITY_MASK);
962 if (err != 0) {
963 ALOGE("Failed to tear Entity state");
964 goto exit;
965 }
966
967 err = flush_model(stdev->odsp_hdl, model->kw_id);
968 if (err != 0) {
969 ALOGE("Failed to flush Entity model");
970 goto exit;
971 }
972 stdev->current_enable = stdev->current_enable & ~ENTITY_MASK;
973
974 if (!(stdev->current_enable & PLUGIN2_MASK)) {
975 err = destroy_ambient_package(stdev->odsp_hdl);
976 if (err != 0) {
977 ALOGE("Failed to destroy Ambient package");
978 goto exit;
979 }
980 }
981 }
982 exit:
983 return err;
984 }
985
set_package_route(struct knowles_sound_trigger_device * stdev,sound_trigger_uuid_t uuid,bool bargein)986 static int set_package_route(struct knowles_sound_trigger_device *stdev,
987 sound_trigger_uuid_t uuid,
988 bool bargein)
989 {
990 int ret = 0;
991 /*
992 *[TODO] Add correct error return value for package route
993 * b/119390722 for tracing.
994 */
995 if (check_uuid_equality(uuid, stdev->chre_model_uuid)) {
996 if (stdev->is_chre_loaded == true) {
997 set_chre_audio_route(stdev->route_hdl, bargein);
998 }
999 } else if (check_uuid_equality(uuid, stdev->hotword_model_uuid)) {
1000 if (!((stdev->current_enable & PLUGIN1_MASK) & ~HOTWORD_MASK)) {
1001 set_hotword_route(stdev->route_hdl, bargein);
1002 }
1003 } else if (check_uuid_equality(uuid, stdev->wakeup_model_uuid)) {
1004 if (!((stdev->current_enable & PLUGIN1_MASK) & ~WAKEUP_MASK)) {
1005 set_hotword_route(stdev->route_hdl, bargein);
1006 }
1007 } else if (check_uuid_equality(uuid, stdev->ambient_model_uuid)) {
1008 if (!((stdev->current_enable & PLUGIN2_MASK) & ~AMBIENT_MASK)) {
1009 set_ambient_route(stdev->route_hdl, bargein);
1010 }
1011 } else if (check_uuid_equality(uuid, stdev->entity_model_uuid)) {
1012 if (!((stdev->current_enable & PLUGIN2_MASK) & ~ENTITY_MASK)) {
1013 set_ambient_route(stdev->route_hdl, bargein);
1014 }
1015 }
1016
1017 return ret;
1018 }
1019
tear_package_route(struct knowles_sound_trigger_device * stdev,sound_trigger_uuid_t uuid,bool bargein)1020 static int tear_package_route(struct knowles_sound_trigger_device *stdev,
1021 sound_trigger_uuid_t uuid,
1022 bool bargein)
1023 {
1024 int ret = 0;
1025 /*
1026 *[TODO] Add correct error return value for package route
1027 * b/119390722 for tracing.
1028 */
1029 if (check_uuid_equality(uuid, stdev->chre_model_uuid)) {
1030 if (stdev->is_chre_loaded == true) {
1031 tear_chre_audio_route(stdev->route_hdl, bargein);
1032 }
1033 } else if (check_uuid_equality(uuid, stdev->hotword_model_uuid)) {
1034 if (!((stdev->current_enable & PLUGIN1_MASK) & ~HOTWORD_MASK))
1035 tear_hotword_route(stdev->route_hdl, bargein);
1036 } else if (check_uuid_equality(uuid, stdev->wakeup_model_uuid)) {
1037 if (!((stdev->current_enable & PLUGIN1_MASK) & ~WAKEUP_MASK))
1038 tear_hotword_route(stdev->route_hdl, bargein);
1039 } else if (check_uuid_equality(uuid, stdev->ambient_model_uuid)) {
1040 if (!((stdev->current_enable & PLUGIN2_MASK) & ~AMBIENT_MASK))
1041 tear_ambient_route(stdev->route_hdl, bargein);
1042 } else if (check_uuid_equality(uuid, stdev->entity_model_uuid)) {
1043 if (!((stdev->current_enable & PLUGIN2_MASK) & ~ENTITY_MASK))
1044 tear_ambient_route(stdev->route_hdl, bargein);
1045 }
1046
1047 return ret;
1048 }
1049
async_setup_aec(struct knowles_sound_trigger_device * stdev)1050 static int async_setup_aec(struct knowles_sound_trigger_device *stdev)
1051 {
1052 int ret = 0;
1053 if (stdev->rx_active_count > 0 &&
1054 stdev->is_bargein_route_enabled != true &&
1055 stdev->is_mic_route_enabled != false) {
1056 ALOGD("%s: Bargein enabling", __func__);
1057 if (is_mic_controlled_by_ahal(stdev) == false) {
1058 ret = enable_mic_route(stdev->route_hdl, false,
1059 INTERNAL_OSCILLATOR);
1060 if (ret != 0) {
1061 ALOGE("Failed to disable mic route with INT OSC");
1062 goto exit;
1063 }
1064 }
1065 ret = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1066 if (ret != 0) {
1067 ALOGE("Failed to load SRC-amp package");
1068 goto exit;
1069 }
1070 ret = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
1071 if (ret != 0) {
1072 ALOGE("Failed to enable SRC-amp route");
1073 goto exit;
1074 }
1075
1076 ret = setup_aec_package(stdev->odsp_hdl);
1077 if (ret != 0) {
1078 ALOGE("Failed to load AEC package");
1079 goto exit;
1080 }
1081 ret = enable_bargein_route(stdev->route_hdl, true);
1082 if (ret != 0) {
1083 ALOGE("Failed to enable buffer route");
1084 goto exit;
1085 }
1086
1087 if (is_mic_controlled_by_ahal(stdev) == false) {
1088 ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_16K);
1089 if (ret != 0) {
1090 ALOGE("Failed to enable amp-ref route");
1091 goto exit;
1092 }
1093 ret = enable_mic_route(stdev->route_hdl, true,
1094 EXTERNAL_OSCILLATOR);
1095 if (ret != 0) {
1096 ALOGE("Failed to enable mic route with EXT OSC");
1097 goto exit;
1098 }
1099 } else {
1100 // main mic is turned by media recording
1101 ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_48K);
1102 if (ret != 0) {
1103 ALOGE("Failed to enable amp-ref route");
1104 goto exit;
1105 }
1106 }
1107 stdev->is_bargein_route_enabled = true;
1108
1109 if (stdev->hotword_buffer_enable) {
1110 ret = tear_hotword_buffer_route(stdev->route_hdl,
1111 !stdev->is_bargein_route_enabled);
1112 if (ret != 0) {
1113 ALOGE("Failed to tear old buffer route");
1114 goto exit;
1115 }
1116 ret = set_hotword_buffer_route(stdev->route_hdl,
1117 stdev->is_bargein_route_enabled);
1118 if (ret != 0) {
1119 ALOGE("Failed to enable buffer route");
1120 goto exit;
1121 }
1122 }
1123
1124 if (stdev->music_buffer_enable) {
1125 ret = tear_music_buffer_route(stdev->route_hdl,
1126 !stdev->is_bargein_route_enabled);
1127 if (ret != 0) {
1128 ALOGE("Failed to tear old music buffer route");
1129 goto exit;
1130 }
1131 ret = set_music_buffer_route(stdev->route_hdl,
1132 stdev->is_bargein_route_enabled);
1133 if (ret != 0) {
1134 ALOGE("Failed to enable buffer route");
1135 goto exit;
1136 }
1137 }
1138
1139 // Check each model, if it is active then update it's route
1140 for (int i = 0; i < MAX_MODELS; i++) {
1141 if (stdev->models[i].is_active == true) {
1142 // teardown the package route without bargein
1143 ret = tear_package_route(stdev,
1144 stdev->models[i].uuid,
1145 !stdev->is_bargein_route_enabled);
1146 if (ret != 0) {
1147 ALOGE("Failed to tear old package route");
1148 goto exit;
1149 }
1150 // resetup the package route with bargein
1151 ret = set_package_route(stdev,
1152 stdev->models[i].uuid,
1153 stdev->is_bargein_route_enabled);
1154 if (ret != 0) {
1155 ALOGE("Failed to enable package route");
1156 goto exit;
1157 }
1158 }
1159 }
1160 } else {
1161 ALOGD("%s: Bargein is already enabled", __func__);
1162 }
1163
1164 exit:
1165 return ret;
1166 }
1167
handle_input_source(struct knowles_sound_trigger_device * stdev,bool enable)1168 static int handle_input_source(struct knowles_sound_trigger_device *stdev,
1169 bool enable)
1170 {
1171 int err = 0;
1172 enum clock_type ct = INTERNAL_OSCILLATOR;
1173 enum strm_type strmt = STRM_16K;
1174
1175 if (stdev->rx_active_count > 0) {
1176 ct = EXTERNAL_OSCILLATOR;
1177 }
1178
1179 if (is_mic_controlled_by_ahal(stdev) == true) {
1180 strmt = STRM_48K;
1181 }
1182
1183 /*
1184 *[TODO] Add correct error return value for input source route
1185 * b/119390722 for tracing.
1186 */
1187 if (enable) {
1188 if (stdev->is_mic_route_enabled == false) {
1189 err = check_and_setup_src_package(stdev);
1190 if (err != 0) {
1191 ALOGE("Fail to setup src Package");
1192 goto exit;
1193 }
1194 err = setup_src_plugin(stdev->odsp_hdl, SRC_MIC);
1195 if (err != 0) {
1196 ALOGE("Failed to load SRC package");
1197 goto exit;
1198 }
1199 err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
1200 if (err != 0) {
1201 ALOGE("Failed to enable SRC-mic route");
1202 goto exit;
1203 }
1204 }
1205 if (stdev->rx_active_count > 0 &&
1206 stdev->is_bargein_route_enabled == false) {
1207 err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1208 if (err != 0) {
1209 ALOGE("Failed to load SRC-amp package");
1210 goto exit;
1211 }
1212 err = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
1213 if (err != 0) {
1214 ALOGE("Failed to enable SRC-amp route");
1215 goto exit;
1216 }
1217
1218 err = setup_aec_package(stdev->odsp_hdl);
1219 if (err != 0) {
1220 ALOGE("Failed to load AEC package");
1221 // We didn't load AEC package so don't setup the routes
1222 goto exit;
1223 }
1224
1225 // Enable the bargein route if not enabled
1226 err = enable_bargein_route(stdev->route_hdl, true);
1227 if (err != 0) {
1228 ALOGE("Failed to enable buffer route");
1229 goto exit;
1230 }
1231 err = enable_amp_ref_route(stdev->route_hdl, true, strmt);
1232 if (err != 0) {
1233 ALOGE("Failed to amp-ref route");
1234 goto exit;
1235 }
1236 stdev->is_bargein_route_enabled = true;
1237 }
1238 if (stdev->is_mic_route_enabled == false) {
1239 if (is_mic_controlled_by_ahal(stdev) == false) {
1240 err = enable_mic_route(stdev->route_hdl, true, ct);
1241 if (err != 0) {
1242 ALOGE("Failed to enable mic route");
1243 goto exit;
1244 }
1245 }
1246 stdev->is_mic_route_enabled = true;
1247 }
1248 } else {
1249 if (!is_any_model_active(stdev)) {
1250 ALOGD("None of keywords are active");
1251 if (stdev->rx_active_count > 0 &&
1252 stdev->is_bargein_route_enabled == true) {
1253 // Just disable the route and update the route status but retain
1254 // bargein status
1255 err = enable_bargein_route(stdev->route_hdl, false);
1256 if (err != 0) {
1257 ALOGE("Failed to disable bargein route");
1258 goto exit;
1259 }
1260 err = destroy_aec_package(stdev->odsp_hdl);
1261 if (err != 0) {
1262 ALOGE("Failed to unload AEC package");
1263 goto exit;
1264 }
1265 err = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
1266 if (err != 0) {
1267 ALOGE("Failed to disable SRC-amp route");
1268 goto exit;
1269 }
1270 err = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1271 if (err != 0) {
1272 ALOGE("Failed to unload SRC-amp package");
1273 goto exit;
1274 }
1275 err = enable_amp_ref_route(stdev->route_hdl, false, strmt);
1276 if (err != 0) {
1277 ALOGE("Failed to amp-ref route");
1278 goto exit;
1279 }
1280 stdev->is_bargein_route_enabled = false;
1281 }
1282 if (stdev->is_mic_route_enabled == true) {
1283 // Close SRC package
1284 err = enable_src_route(stdev->route_hdl, false, SRC_MIC);
1285 if (err != 0) {
1286 ALOGE("Failed to disable SRC-mic route");
1287 goto exit;
1288 }
1289 err = destroy_src_plugin(stdev->odsp_hdl, SRC_MIC);
1290 if (err != 0) {
1291 ALOGE("Failed to unload SRC-mic package");
1292 goto exit;
1293 }
1294 if (is_mic_controlled_by_ahal(stdev) == false) {
1295 err = enable_mic_route(stdev->route_hdl, false, ct);
1296 if (err != 0) {
1297 ALOGE("Failed to disable mic route");
1298 goto exit;
1299 }
1300 }
1301 stdev->is_mic_route_enabled = false;
1302 err = check_and_destroy_src_package(stdev);
1303 if (err != 0) {
1304 ALOGE("Fail to destroy src Package");
1305 goto exit;
1306 }
1307 }
1308 }
1309 }
1310
1311 exit:
1312 return err;
1313 }
1314
update_rx_conditions(struct knowles_sound_trigger_device * stdev,audio_event_type_t event,struct audio_event_info * config)1315 static void update_rx_conditions(struct knowles_sound_trigger_device *stdev,
1316 audio_event_type_t event,
1317 struct audio_event_info *config)
1318 {
1319 if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE) {
1320 if (stdev->rx_active_count > 0) {
1321 stdev->rx_active_count--;
1322 } else {
1323 ALOGW("%s: unexpected rx inactive event", __func__);
1324 }
1325 } else if (event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
1326 if (!(config->device_info.device & AUDIO_DEVICE_OUT_SPEAKER)) {
1327 ALOGD("%s: Playback device doesn't include SPEAKER.",
1328 __func__);
1329 } else {
1330 stdev->rx_active_count++;
1331 }
1332 } else {
1333 ALOGW("%s: invalid event %d", __func__, event);
1334 }
1335 ALOGD("%s: updated rx_concurrency as %d", __func__,
1336 stdev->rx_active_count);
1337 }
1338
1339
update_sthal_conditions(struct knowles_sound_trigger_device * stdev,audio_event_type_t event,struct audio_event_info * config)1340 static void update_sthal_conditions(struct knowles_sound_trigger_device *stdev,
1341 audio_event_type_t event,
1342 struct audio_event_info *config)
1343 {
1344 if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
1345 // get correct voice/voip mode in sthal
1346 if (stdev->is_ahal_in_voice_voip_mode == false &&
1347 stdev->is_ahal_voice_voip_stop == true &&
1348 stdev->is_ahal_media_recording == true) {
1349 ALOGD("%s: voice/voip didn't start, treat it as media recording inactive",
1350 __func__);
1351 stdev->is_ahal_voice_voip_stop = false;
1352 stdev->is_ahal_media_recording = false;
1353 } else if (stdev->is_ahal_voice_voip_stop == true) {
1354 ALOGD("%s: voice/voip device is inactive", __func__);
1355 stdev->is_ahal_in_voice_voip_mode = false;
1356 stdev->is_ahal_voice_voip_stop = false;
1357 } else if (stdev->is_ahal_in_voice_voip_mode == true &&
1358 stdev->is_ahal_voice_voip_stop == false &&
1359 stdev->is_ahal_voice_voip_start == false) {
1360 ALOGD("%s: voice/voip usecase didn't start in incall mode, treat it as voice/voip is inactive",
1361 __func__);
1362 stdev->is_ahal_in_voice_voip_mode = false;
1363 }
1364
1365 if (stdev->is_concurrent_capture == true &&
1366 stdev->is_ahal_in_voice_voip_mode == false) {
1367 if (stdev->is_ahal_media_recording == true)
1368 stdev->is_con_mic_route_enabled = true;
1369 else
1370 stdev->is_con_mic_route_enabled = false;
1371 ALOGD("%s: update mic con %d", __func__,
1372 stdev->is_con_mic_route_enabled);
1373 }
1374 } else if (event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
1375 if (stdev->is_ahal_in_voice_voip_mode == false &&
1376 (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
1377 config->u.usecase.type == USECASE_TYPE_VOIP_CALL)) {
1378 ALOGD("%s: voice/voip is actvie, close ST mic and don't use mic concurrently",
1379 __func__);
1380 stdev->is_ahal_in_voice_voip_mode = true;
1381 }
1382 if (config->u.usecase.type == USECASE_TYPE_PCM_CAPTURE) {
1383 stdev->is_ahal_media_recording = true;
1384 }
1385 if (stdev->is_concurrent_capture == true &&
1386 stdev->is_ahal_in_voice_voip_mode == false &&
1387 stdev->is_con_mic_route_enabled == false &&
1388 config->device_info.device == ST_DEVICE_HANDSET_MIC) {
1389 ALOGD("%s: enable mic concurrency", __func__);
1390 stdev->is_con_mic_route_enabled = true;
1391 }
1392 } else if (event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE) {
1393 if (stdev->is_ahal_voice_voip_start == true &&
1394 (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
1395 config->u.usecase.type == USECASE_TYPE_VOIP_CALL)) {
1396 stdev->is_ahal_voice_voip_stop = true;
1397 stdev->is_ahal_voice_voip_start = false;
1398 } else if (config->u.usecase.type == USECASE_TYPE_PCM_CAPTURE)
1399 stdev->is_ahal_media_recording = false;
1400 } else if (event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
1401 if (config->u.usecase.type == USECASE_TYPE_VOICE_CALL ||
1402 config->u.usecase.type == USECASE_TYPE_VOIP_CALL) {
1403 stdev->is_ahal_voice_voip_start = true;
1404 }
1405 }
1406 }
1407
do_handle_functions(struct knowles_sound_trigger_device * stdev,enum sthal_mode pre_mode,enum sthal_mode cur_mode,audio_event_type_t event)1408 static bool do_handle_functions(struct knowles_sound_trigger_device *stdev,
1409 enum sthal_mode pre_mode,
1410 enum sthal_mode cur_mode,
1411 audio_event_type_t event)
1412 {
1413 int ret = 0;
1414 int i = 0;
1415
1416 ALOGD("+%s+: pre %d, cur %d, event %d", __func__, pre_mode, cur_mode, event);
1417
1418 // handle event AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE
1419 if (event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE) {
1420 if ((pre_mode == CON_DISABLED_ST && cur_mode == CON_DISABLED_CAPTURE) ||
1421 (pre_mode == CON_DISABLED_ST && cur_mode == IN_CALL) ||
1422 (pre_mode == CON_DISABLED_CAPTURE && cur_mode == IN_CALL) ||
1423 (pre_mode == CON_ENABLED_CAPTURE_ST && cur_mode == IN_CALL) ||
1424 (pre_mode == CON_ENABLED_ST && cur_mode == IN_CALL)) {
1425 // disable all ST
1426 // if tunnel is active, close it first
1427 for (i = 0; i < MAX_MODELS; i++) {
1428 if (stdev->adnc_strm_handle[i] != 0) {
1429 ALOGD("%s: stop tunnling for index:%d", __func__, i);
1430 stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
1431 stdev->adnc_strm_handle[i] = 0;
1432 stdev->adnc_strm_last_read[i] = reset_time;
1433 }
1434 }
1435 stdev->is_streaming = 0;
1436
1437 for (i = 0; i < MAX_MODELS; i++) {
1438 if (stdev->models[i].is_active == true) {
1439 update_recover_list(stdev, i, true);
1440 tear_package_route(stdev, stdev->models[i].uuid,
1441 stdev->is_bargein_route_enabled);
1442 stdev->models[i].is_active = false;
1443 if (!check_uuid_equality(stdev->models[i].uuid,
1444 stdev->chre_model_uuid))
1445 destroy_package(stdev, &stdev->models[i]);
1446
1447 if ((stdev->hotword_buffer_enable) &&
1448 !(stdev->current_enable & PLUGIN1_MASK)) {
1449 tear_hotword_buffer_route(stdev->route_hdl,
1450 stdev->is_bargein_route_enabled);
1451 }
1452
1453 if ((stdev->music_buffer_enable) &&
1454 !(stdev->current_enable & PLUGIN2_MASK)) {
1455 tear_music_buffer_route(stdev->route_hdl,
1456 stdev->is_bargein_route_enabled);
1457 }
1458
1459 setup_buffer(stdev, &stdev->models[i], false);
1460 }
1461 }
1462 handle_input_source(stdev, false);
1463 check_and_destroy_buffer_package(stdev);
1464 } else if (pre_mode == CON_ENABLED_ST && cur_mode == CON_ENABLED_CAPTURE_ST) {
1465 //reconfig mic
1466 if (stdev->is_mic_route_enabled == true) {
1467 if (stdev->is_bargein_route_enabled == true) {
1468 // close amp-ref first and reconfig it again with 48K after
1469 // main mic is turned on by media recording
1470 ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
1471 if (ret != 0) {
1472 ALOGE("Failed to disable amp-ref route");
1473 goto exit;
1474 }
1475 ret = enable_mic_route(stdev->route_hdl, false,
1476 EXTERNAL_OSCILLATOR);
1477 if (ret != 0) {
1478 ALOGE("Failed to disable mic route with EXT OSC");
1479 goto exit;
1480 }
1481
1482 ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_48K);
1483 if (ret != 0) {
1484 ALOGE("Failed to enable amp-ref route");
1485 goto exit;
1486 }
1487 } else {
1488 ret = enable_mic_route(stdev->route_hdl, false,
1489 INTERNAL_OSCILLATOR);
1490 if (ret != 0) {
1491 ALOGE("Failed to disable mic route with INT OSC");
1492 goto exit;
1493 }
1494 }
1495 } else {
1496 ALOGD("%s: ST mic isn't enabled, recording mic is turned on",
1497 __func__);
1498 }
1499 }
1500 }
1501
1502 // handle event AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE
1503 if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE) {
1504 if ((pre_mode == IN_CALL && cur_mode == CON_DISABLED_ST) ||
1505 (pre_mode == IN_CALL && cur_mode == CON_DISABLED_CAPTURE) ||
1506 (pre_mode == IN_CALL && cur_mode == CON_ENABLED_ST) ||
1507 (pre_mode == IN_CALL && cur_mode == CON_ENABLED_CAPTURE_ST) ||
1508 (pre_mode == CON_DISABLED_CAPTURE && cur_mode == CON_DISABLED_ST)) {
1509 //recover all STs
1510 for (i = 0; i < MAX_MODELS; i++) {
1511 // recover all models from list
1512 if (is_uuid_in_recover_list(stdev, i)) {
1513 if (stdev->models[i].is_active == false) {
1514 check_and_setup_buffer_package(stdev);
1515 stdev->models[i].is_active = true;
1516 handle_input_source(stdev, true);
1517
1518 setup_buffer(stdev, &stdev->models[i], true);
1519 if (stdev->hotword_buffer_enable &&
1520 !(stdev->current_enable & PLUGIN1_MASK)) {
1521 set_hotword_buffer_route(stdev->route_hdl,
1522 stdev->is_bargein_route_enabled);
1523 }
1524 if (stdev->music_buffer_enable &&
1525 !(stdev->current_enable & PLUGIN2_MASK)) {
1526 set_music_buffer_route(stdev->route_hdl,
1527 stdev->is_bargein_route_enabled);
1528 }
1529
1530 if (!check_uuid_equality(stdev->models[i].uuid,
1531 stdev->chre_model_uuid))
1532 setup_package(stdev, &stdev->models[i]);
1533 set_package_route(stdev, stdev->models[i].uuid,
1534 stdev->is_bargein_route_enabled);
1535 }
1536 }
1537 }
1538 stdev->recover_model_list = 0;
1539 } else if (pre_mode == CON_ENABLED_CAPTURE_ST && cur_mode == CON_ENABLED_ST) {
1540 // reconfig mic
1541 if (stdev->is_mic_route_enabled == true) {
1542 if (stdev->is_bargein_route_enabled == true) {
1543 ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
1544 if (ret != 0) {
1545 ALOGE("Failed to disable amp-ref route");
1546 goto exit;
1547 }
1548 ret = enable_mic_route(stdev->route_hdl, true,
1549 EXTERNAL_OSCILLATOR);
1550 if (ret != 0) {
1551 ALOGE("Failed to enable mic route with EXT OSC");
1552 goto exit;
1553 }
1554 // turn on amp-ref with 16khz
1555 ret = enable_amp_ref_route(stdev->route_hdl, true, STRM_16K);
1556 if (ret != 0) {
1557 ALOGE("Failed to enable amp-ref route");
1558 goto exit;
1559 }
1560 } else {
1561 ret = enable_mic_route(stdev->route_hdl, true,
1562 INTERNAL_OSCILLATOR);
1563 if (ret != 0) {
1564 ALOGE("Failed to enable mic route with INT OSC");
1565 goto exit;
1566 }
1567 }
1568 } else {
1569 ALOGD("%s: ST mic isn't enabled, recording mic is turned off",
1570 __func__);
1571 }
1572 }
1573 }
1574
1575 exit:
1576 ALOGD("-%s-: pre %d, cur %d, event %d", __func__, pre_mode, cur_mode, event);
1577 return ret;
1578 }
1579
1580 // stdev needs to be locked before calling this function
restart_recognition(struct knowles_sound_trigger_device * stdev)1581 static int restart_recognition(struct knowles_sound_trigger_device *stdev)
1582 {
1583 int err = 0;
1584 int i = 0;
1585 enum strm_type strmt = STRM_16K;
1586 enum clock_type ct = INTERNAL_OSCILLATOR;
1587 /*
1588 * The libaudioroute library doesn't set the mixer controls if previously
1589 * applied values are the same or the active_count > 0, so we need to
1590 * teardown the route so that it can clear up the value and active_count.
1591 * Then we could setup the routes again.
1592 */
1593
1594 stdev->current_enable = 0;
1595 stdev->hotword_buffer_enable = 0;
1596 stdev->music_buffer_enable = 0;
1597
1598 if (stdev->rx_active_count == 0 &&
1599 stdev->is_bargein_route_enabled == true) {
1600 /* rx stream is disabled during codec recovery.
1601 * Need to reset the enabled flag
1602 */
1603 stdev->is_bargein_route_enabled = false;
1604 }
1605
1606 if (stdev->is_buffer_package_loaded == true) {
1607 err = setup_buffer_package(stdev->odsp_hdl);
1608 if (err != 0) {
1609 ALOGE("%s: Failed to restart Buffer package", __func__);
1610 }
1611 }
1612
1613 if (stdev->is_src_package_loaded == true) {
1614 err = setup_src_package(stdev->odsp_hdl);
1615 if (err != 0) {
1616 ALOGE("%s: Failed to restart SRC package", __func__);
1617 }
1618 }
1619
1620 /*
1621 * If ST mode is IN_CALL, make sure mic route as false,
1622 * that would be reloaded after ending the call
1623 */
1624 if (get_sthal_mode(stdev) == IN_CALL) {
1625 ALOGD("%s: ST mode is in_call, reset all routes", __func__);
1626
1627 stdev->is_mic_route_enabled = false;
1628 stdev->is_bargein_route_enabled = false;
1629 for (i = 0; i < MAX_MODELS; i++) {
1630 if (stdev->models[i].is_active == true) {
1631 update_recover_list(stdev, i, true);
1632 stdev->models[i].is_active = false;
1633 }
1634 }
1635
1636 // if chre enabled before crash during call, need to setup package for SLPI.
1637 if (stdev->is_chre_loaded == true) {
1638 err = setup_chre_package(stdev->odsp_hdl);
1639 if (err != 0) {
1640 ALOGE("Failed to load CHRE package");
1641 }
1642 stdev->current_enable = stdev->current_enable | CHRE_MASK;
1643 }
1644 goto reload_oslo;
1645 }
1646
1647
1648 /*
1649 * Reset mic and src package if sound trigger recording is active
1650 * The src-mic, src-amp must be enable before AEC enable, because
1651 * the endpoint sequence control.
1652 */
1653 if (stdev->is_mic_route_enabled == true) {
1654 // recover src package if sound trigger recording is active
1655 err = setup_src_plugin(stdev->odsp_hdl, SRC_MIC);
1656 if (err != 0) {
1657 ALOGE("failed to load SRC package");
1658 }
1659 err = enable_src_route(stdev->route_hdl, true, SRC_MIC);
1660 if (err != 0) {
1661 ALOGE("Failed to restart SRC-mic route");
1662 }
1663 /*
1664 * RX stream was enabled during codec recovery.
1665 * Need to setup the barge-in package and routing.
1666 */
1667 if (stdev->rx_active_count > 0) {
1668 stdev->is_bargein_route_enabled = true;
1669 ct = EXTERNAL_OSCILLATOR;
1670 if (is_mic_controlled_by_ahal(stdev) == true) {
1671 strmt = STRM_48K;
1672 }
1673 err = setup_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
1674 if (err != 0) {
1675 ALOGE("failed to load SRC package");
1676 }
1677 err = enable_src_route(stdev->route_hdl, true, SRC_AMP_REF);
1678 if (err != 0) {
1679 ALOGE("Failed to restart SRC-amp route");
1680 }
1681
1682 err = setup_aec_package(stdev->odsp_hdl);
1683 if (err != 0) {
1684 ALOGE("Failed to restart AEC package");
1685 }
1686 err = enable_bargein_route(stdev->route_hdl, true);
1687 if (err != 0) {
1688 ALOGE("Failed to restart bargein route");
1689 }
1690 err = enable_amp_ref_route(stdev->route_hdl, true, strmt);
1691 if (err != 0) {
1692 ALOGE("Failed to restart amp-ref route");
1693 }
1694 }
1695 // The stream 0 should be enable at last moment for the data alignment.
1696 if (is_mic_controlled_by_ahal(stdev) == false) {
1697 err = enable_mic_route(stdev->route_hdl, true, ct);
1698 if (err != 0) {
1699 ALOGE("failed to restart mic route");
1700 }
1701 }
1702 }
1703
1704 // Download all the keyword models files that were previously loaded
1705 for (i = 0; i < MAX_MODELS; i++) {
1706 if (stdev->models[i].is_active == true) {
1707 if (stdev->is_buffer_package_loaded == true) {
1708 setup_buffer(stdev, &stdev->models[i], true);
1709 }
1710 if (check_uuid_equality(stdev->models[i].uuid, stdev->hotword_model_uuid) ||
1711 (check_uuid_equality(stdev->models[i].uuid, stdev->wakeup_model_uuid))) {
1712 if ((stdev->hotword_buffer_enable) &&
1713 (!(stdev->current_enable & HOTWORD_MASK) ||
1714 (stdev->current_enable & WAKEUP_MASK))) {
1715 set_hotword_buffer_route(stdev->route_hdl,
1716 stdev->is_bargein_route_enabled);
1717 }
1718 }
1719 if (check_uuid_equality(stdev->models[i].uuid, stdev->ambient_model_uuid) ||
1720 (check_uuid_equality(stdev->models[i].uuid, stdev->entity_model_uuid))) {
1721 if ((stdev->music_buffer_enable) &&
1722 (!(stdev->current_enable & AMBIENT_MASK) ||
1723 (stdev->current_enable & ENTITY_MASK))) {
1724 set_music_buffer_route(stdev->route_hdl,
1725 stdev->is_bargein_route_enabled);
1726 }
1727 }
1728 setup_package(stdev, &stdev->models[i]);
1729 set_package_route(stdev, stdev->models[i].uuid,
1730 stdev->is_bargein_route_enabled);
1731 }
1732 }
1733
1734 reload_oslo:
1735 // reload Oslo part after every package loaded to avoid HMD memory overlap
1736 // issue, b/128914464
1737 for (i = 0; i < MAX_MODELS; i++) {
1738 if (stdev->models[i].is_loaded == true) {
1739 if (check_uuid_equality(stdev->models[i].uuid,
1740 stdev->sensor_model_uuid)) {
1741 // setup the sensor route
1742 err = setup_sensor_package(stdev->odsp_hdl);
1743 if (err != 0) {
1744 ALOGE("%s: setup Sensor package failed", __func__);
1745 goto exit;
1746 }
1747
1748 err = set_sensor_route(stdev->route_hdl, true);
1749 if (err != 0) {
1750 ALOGE("%s: Sensor route fail", __func__);
1751 goto exit;
1752 }
1753 stdev->is_sensor_route_enabled = true;
1754 }
1755 }
1756 }
1757 ALOGD("%s: recovery done", __func__);
1758 exit:
1759 return err;
1760 }
1761
1762 // stdev needs to be locked before calling this function
crash_recovery(struct knowles_sound_trigger_device * stdev)1763 static int crash_recovery(struct knowles_sound_trigger_device *stdev)
1764 {
1765 int err = 0;
1766
1767 set_default_apll_clk(stdev->mixer);
1768 setup_slpi_wakeup_event(stdev->odsp_hdl, true);
1769
1770 // Redownload the keyword model files and start recognition
1771 err = restart_recognition(stdev);
1772 if (err != 0) {
1773 ALOGE("%s: ERROR: Failed to download the keyword models and restarting"
1774 " recognition", __func__);
1775 goto exit;
1776 }
1777
1778 // Reset the flag only after successful recovery
1779 stdev->is_st_hal_ready = true;
1780
1781 exit:
1782 return err;
1783 }
1784
sensor_crash_handler(struct knowles_sound_trigger_device * stdev)1785 static void sensor_crash_handler(struct knowles_sound_trigger_device *stdev)
1786 {
1787 int i;
1788
1789 if (stdev->is_sensor_destroy_in_prog == false)
1790 return;
1791
1792 if (stdev->ss_timer_created) {
1793 timer_delete(stdev->ss_timer);
1794 stdev->ss_timer_created = false;
1795 }
1796
1797 if (stdev->is_sensor_route_enabled == true) {
1798 for (i = 0; i < MAX_MODELS; i++) {
1799 if (check_uuid_equality(stdev->models[i].uuid,
1800 stdev->sensor_model_uuid) &&
1801 stdev->models[i].is_loaded == true) {
1802 stdev->models[i].is_loaded = false;
1803 memset(&stdev->models[i].uuid, 0,
1804 sizeof(sound_trigger_uuid_t));
1805 break;
1806 }
1807 }
1808 stdev->is_sensor_route_enabled = false;
1809 stdev->current_enable &= ~OSLO_MASK;
1810 }
1811 stdev->is_sensor_destroy_in_prog = false;
1812
1813 // There could be another thread waiting for us to destroy
1814 // so signal that thread, if no one is waiting then this signal
1815 // will have no effect
1816 pthread_cond_signal(&stdev->sensor_create);
1817 }
1818
destroy_sensor_model(struct knowles_sound_trigger_device * stdev)1819 static void destroy_sensor_model(struct knowles_sound_trigger_device *stdev)
1820 {
1821 int ret, i;
1822 ALOGD("+%s+", __func__);
1823
1824 if (stdev->is_sensor_route_enabled == true) {
1825 ret = set_sensor_route(stdev->route_hdl, false);
1826 if (ret != 0) {
1827 ALOGE("%s: tear Sensor route fail", __func__);
1828 }
1829 stdev->is_sensor_route_enabled = false;
1830
1831 ret = destroy_sensor_package(stdev->odsp_hdl);
1832 if (ret != 0) {
1833 ALOGE("%s: destroy Sensor package failed %d",
1834 __func__, ret);
1835 }
1836 stdev->current_enable = stdev->current_enable & ~OSLO_MASK;
1837 }
1838
1839 // now we can change the flag
1840 for (i = 0 ; i < MAX_MODELS ; i++) {
1841 if (check_uuid_equality(stdev->models[i].uuid,
1842 stdev->sensor_model_uuid) &&
1843 stdev->models[i].is_loaded == true) {
1844 memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
1845 stdev->models[i].is_loaded = false;
1846 break;
1847 }
1848 }
1849
1850 stdev->is_sensor_destroy_in_prog = false;
1851 check_and_destroy_buffer_package(stdev);
1852
1853 // There could be another thread waiting for us to destroy so signal that
1854 // thread, if no one is waiting then this signal will have no effect
1855 pthread_cond_signal(&stdev->sensor_create);
1856
1857 ALOGD("-%s-", __func__);
1858 }
1859
sensor_timeout_recover()1860 static void sensor_timeout_recover()
1861 {
1862 int err = 0;
1863 ALOGD("+%s+", __func__);
1864
1865 struct knowles_sound_trigger_device *stdev = &g_stdev;
1866 pthread_mutex_lock(&stdev->lock);
1867 // We are here because we timed out so check if we still need to destroy
1868 // the sensor package, if yes then reset the firmware
1869 if (stdev->is_sensor_destroy_in_prog == true) {
1870 if (stdev->is_st_hal_ready) {
1871 stdev->is_st_hal_ready = false;
1872 // reset the firmware and wait for firmware download complete
1873 err = reset_fw(stdev->odsp_hdl);
1874 if (err == -1) {
1875 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
1876 __func__, errno, strerror(errno));
1877 }
1878 reset_all_route(stdev->route_hdl);
1879 sensor_crash_handler(stdev);
1880 }
1881 }
1882 pthread_mutex_unlock(&stdev->lock);
1883 ALOGD("-%s-", __func__);
1884 }
1885
start_sensor_model(struct knowles_sound_trigger_device * stdev)1886 static int start_sensor_model(struct knowles_sound_trigger_device * stdev)
1887 {
1888 struct timespec ts;
1889 int wait_counter = 0, err = 0;
1890
1891 while (stdev->is_sensor_destroy_in_prog == true &&
1892 wait_counter < SENSOR_CREATE_WAIT_MAX_COUNT) {
1893 // We wait for 1sec * MAX_COUNT times for the HOST 1 to respond, if
1894 // within that time we don't get any response, we will go ahead with the
1895 // sensor model creation. Note this might result in an error which would
1896 // be better than blocking the thread indefinitely.
1897 clock_gettime(CLOCK_REALTIME, &ts);
1898 ts.tv_sec += SENSOR_CREATE_WAIT_TIME_IN_S;
1899 err = pthread_cond_timedwait(&stdev->sensor_create, &stdev->lock, &ts);
1900 if (err == ETIMEDOUT) {
1901 ALOGE("%s: WARNING: Sensor create timed out after %ds",
1902 __func__, SENSOR_CREATE_WAIT_TIME_IN_S);
1903 wait_counter++;
1904 }
1905 }
1906
1907 // If firmware crashed when we are waiting
1908 if (stdev->is_st_hal_ready == false) {
1909 err = -EAGAIN;
1910 goto exit;
1911 }
1912
1913 if (stdev->is_sensor_destroy_in_prog == true) {
1914 ALOGE("%s: ERROR: Waited for %ds but we didn't get the event from "
1915 "Host 1, and fw reset is not yet complete", __func__,
1916 SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT);
1917 err = -EAGAIN;
1918 goto exit;
1919 }
1920
1921 // setup the sensor route
1922 err = check_and_setup_buffer_package(stdev);
1923 if (err != 0) {
1924 ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
1925 goto exit;
1926 }
1927
1928 if(stdev->is_sensor_route_enabled == false) {
1929 err = setup_sensor_package(stdev->odsp_hdl);
1930 if (err) {
1931 ALOGE("%s: Failed to setup sensor package", __func__);
1932 goto exit;
1933 }
1934 // Don't download the keyword model file, just setup the
1935 // sensor route
1936 err = set_sensor_route(stdev->route_hdl, true);
1937 if (err) {
1938 ALOGE("%s: Sensor route fail", __func__);
1939 goto exit;
1940 }
1941 stdev->is_sensor_route_enabled = true;
1942 stdev->current_enable = stdev->current_enable | OSLO_MASK;
1943 }
1944
1945 exit:
1946 return err;
1947 }
1948
chre_crash_handler(struct knowles_sound_trigger_device * stdev)1949 static void chre_crash_handler(struct knowles_sound_trigger_device *stdev)
1950 {
1951 int i;
1952
1953 if (stdev->is_chre_destroy_in_prog == false)
1954 return;
1955
1956 if (stdev->chre_timer_created) {
1957 timer_delete(stdev->chre_timer);
1958 stdev->chre_timer_created = false;
1959 }
1960
1961 if (stdev->is_chre_loaded == true) {
1962 for (i = 0; i < MAX_MODELS; i++) {
1963 if (check_uuid_equality(stdev->models[i].uuid,
1964 stdev->chre_model_uuid)) {
1965 stdev->models[i].is_active = false;
1966 stdev->models[i].is_loaded = false;
1967 memset(&stdev->models[i].uuid, 0,
1968 sizeof(sound_trigger_uuid_t));
1969 break;
1970 }
1971 }
1972 stdev->is_chre_loaded = false;
1973 stdev->current_enable &= ~CHRE_MASK;
1974 }
1975 stdev->is_chre_destroy_in_prog = false;
1976
1977 // There could be another thread waiting for us to destroy
1978 // so signal that thread, if no one is waiting then this signal
1979 // will have no effect
1980 pthread_cond_signal(&stdev->chre_create);
1981 }
1982
start_chre_model(struct knowles_sound_trigger_device * stdev,int model_id)1983 static int start_chre_model(struct knowles_sound_trigger_device *stdev,
1984 int model_id)
1985 {
1986 struct timespec ts;
1987 int wait_counter = 0, err = 0;
1988
1989 while (stdev->is_chre_destroy_in_prog == true &&
1990 wait_counter < CHRE_CREATE_WAIT_MAX_COUNT) {
1991 // We wait for 1sec * MAX_COUNT times for the HOST 1 to respond, if
1992 // within that time we don't get any response, we will go ahead with the
1993 // sensor model creation. Note this might result in an error which would
1994 // be better than blocking the thread indefinitely.
1995 clock_gettime(CLOCK_REALTIME, &ts);
1996 ts.tv_sec += CHRE_CREATE_WAIT_TIME_IN_S;
1997 err = pthread_cond_timedwait(&stdev->chre_create, &stdev->lock, &ts);
1998 if (err == ETIMEDOUT) {
1999 ALOGE("%s: WARNING: CHRE create timed out after %ds",
2000 __func__, CHRE_CREATE_WAIT_TIME_IN_S);
2001 wait_counter++;
2002 }
2003 }
2004
2005 // If firmware crashed when we are waiting
2006 if (stdev->is_st_hal_ready == false) {
2007 err = -EAGAIN;
2008 goto exit;
2009 }
2010
2011 if (stdev->is_chre_destroy_in_prog == true) {
2012 ALOGE("%s: ERROR: Waited for %ds but we didn't get the event from "
2013 "Host 1, and fw reset is not yet complete", __func__,
2014 CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT);
2015 err = -EAGAIN;
2016 goto exit;
2017 }
2018
2019 err = check_and_setup_buffer_package(stdev);
2020 if (err != 0) {
2021 ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
2022 goto exit;
2023 }
2024
2025 // add chre to recover list
2026 if (can_enable_chre(stdev)) {
2027 if(stdev->is_chre_loaded == false) {
2028 stdev->models[model_id].is_active = true;
2029 handle_input_source(stdev, true);
2030 setup_chre_package(stdev->odsp_hdl);
2031 set_chre_audio_route(stdev->route_hdl,
2032 stdev->is_bargein_route_enabled);
2033 stdev->is_chre_loaded = true;
2034 stdev->current_enable = stdev->current_enable | CHRE_MASK;
2035 }
2036 } else {
2037 ALOGW("%s: device is in call, setup CHRE for SLPI",
2038 __func__);
2039 //Setup CHRE package and allow SLPI connect
2040 //during in-call mode.
2041 if (stdev->is_chre_loaded == false) {
2042 setup_chre_package(stdev->odsp_hdl);
2043 stdev->models[model_id].uuid = stdev->chre_model_uuid;
2044 stdev->is_chre_loaded = true;
2045 stdev->current_enable = stdev->current_enable | CHRE_MASK;
2046 if (can_update_recover_list(stdev) == true)
2047 update_recover_list(stdev, model_id, true);
2048 }
2049 }
2050
2051 exit:
2052 return err;
2053 }
2054
destroy_chre_model(struct knowles_sound_trigger_device * stdev)2055 static void destroy_chre_model(struct knowles_sound_trigger_device *stdev)
2056 {
2057 int err = 0;
2058 ALOGD("+%s+", __func__);
2059
2060 if (stdev->is_chre_loaded == true) {
2061 int i;
2062 tear_chre_audio_route(stdev->route_hdl,
2063 stdev->is_bargein_route_enabled);
2064 err = destroy_chre_package(stdev->odsp_hdl);
2065 if (err != 0) {
2066 ALOGE("%s: ERROR: Failed to destroy chre package", __func__);
2067 }
2068
2069 //Need force reset the flag for chre due to in-call state
2070 //The model is inactive, but need to clean if user disable it
2071 //during call.
2072 for (i = 0; i < MAX_MODELS; i++) {
2073 if (check_uuid_equality(stdev->models[i].uuid,
2074 stdev->chre_model_uuid)) {
2075 stdev->models[i].is_active = false;
2076 stdev->models[i].is_loaded = false;
2077 memset(&stdev->models[i].uuid, 0,
2078 sizeof(sound_trigger_uuid_t));
2079 break;
2080 }
2081 }
2082 handle_input_source(stdev, false);
2083 stdev->is_chre_loaded = false;
2084 stdev->current_enable = stdev->current_enable & ~CHRE_MASK;
2085 }
2086
2087 stdev->is_chre_destroy_in_prog = false;
2088
2089 // setup the sensor route
2090 err = check_and_destroy_buffer_package(stdev);
2091 if (err != 0) {
2092 ALOGE("%s: ERROR: Failed to destroy buffer package", __func__);
2093 }
2094
2095 // There could be another thread waiting for us to destroy so signal that
2096 // thread, if no one is waiting then this signal will have no effect
2097 pthread_cond_signal(&stdev->chre_create);
2098
2099 ALOGD("-%s-", __func__);
2100 }
2101
chre_timeout_recover()2102 static void chre_timeout_recover()
2103 {
2104 int err = 0;
2105 ALOGD("+%s+", __func__);
2106
2107 struct knowles_sound_trigger_device *stdev = &g_stdev;
2108 pthread_mutex_lock(&stdev->lock);
2109 // We are here because we timed out so check if we still need to destroy
2110 // the chre package, if yes then reset the firmware
2111 if (stdev->is_chre_destroy_in_prog == true) {
2112 if (stdev->is_st_hal_ready) {
2113 stdev->is_st_hal_ready = false;
2114 // reset the firmware and wait for firmware download complete
2115 err = reset_fw(stdev->odsp_hdl);
2116 if (err == -1) {
2117 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2118 __func__, errno, strerror(errno));
2119 }
2120 reset_all_route(stdev->route_hdl);
2121 chre_crash_handler(stdev);
2122 }
2123 }
2124 pthread_mutex_unlock(&stdev->lock);
2125 ALOGD("-%s-", __func__);
2126 }
2127
transitions_thread_loop(void * context)2128 static void *transitions_thread_loop(void *context)
2129 {
2130 struct knowles_sound_trigger_device *stdev =
2131 (struct knowles_sound_trigger_device *)context;
2132
2133 int err = 0;
2134 pthread_mutex_lock(&stdev->lock);
2135 while (1) {
2136 if (stdev->transit_case == TRANSIT_NONE)
2137 pthread_cond_wait(&stdev->transition_cond, &stdev->lock);
2138
2139 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
2140 switch (stdev->transit_case) {
2141 case TRANSIT_NONE:
2142 break;
2143 case TRANSIT_SETUP_AEC:
2144 err = async_setup_aec(stdev);
2145 break;
2146 }
2147 stdev->transit_case = TRANSIT_NONE;
2148 release_wake_lock(WAKE_LOCK_NAME);
2149 }
2150 pthread_mutex_unlock(&stdev->lock);
2151 }
2152
2153
monitor_thread_loop(void * context)2154 static void *monitor_thread_loop(void *context)
2155 {
2156 struct knowles_sound_trigger_device *stdev =
2157 (struct knowles_sound_trigger_device *)context;
2158 struct timespec now;
2159 double diff;
2160
2161 pthread_mutex_lock(&stdev->lock);
2162 while (1) {
2163 if (!stdev->is_streaming)
2164 pthread_cond_wait(&stdev->tunnel_create, &stdev->lock);
2165 pthread_mutex_unlock(&stdev->lock);
2166
2167 sleep(TUNNEL_TIMEOUT);
2168
2169 pthread_mutex_lock(&stdev->lock);
2170
2171 acquire_wake_lock(PARTIAL_WAKE_LOCK, WAKE_LOCK_NAME);
2172 clock_gettime(CLOCK_REALTIME, &now);
2173 for (int i = 0; i < MAX_MODELS; i++) {
2174 if (stdev->adnc_strm_handle[i] != 0) {
2175 diff = (now.tv_sec - stdev->adnc_strm_last_read[i].tv_sec)
2176 + (double) ((now.tv_nsec) - (stdev->adnc_strm_last_read[i].tv_nsec))
2177 / 1000000000.0;
2178
2179 if (diff > TUNNEL_TIMEOUT) {
2180 ALOGE("%s: Waiting timeout for %f sec", __func__, diff);
2181 stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
2182 stdev->adnc_strm_handle[i] = 0;
2183 stdev->is_streaming--;
2184 stdev->adnc_strm_last_read[i] = reset_time;
2185 }
2186 }
2187 }
2188 release_wake_lock(WAKE_LOCK_NAME);
2189 }
2190 pthread_mutex_unlock(&stdev->lock);
2191 }
2192
callback_thread_loop(void * context)2193 static void *callback_thread_loop(void *context)
2194 {
2195 struct knowles_sound_trigger_device *stdev =
2196 (struct knowles_sound_trigger_device *)context;
2197 struct pollfd fds[2];
2198 char msg[UEVENT_MSG_LEN];
2199 int exit_sockets[2];
2200 int err = 0;
2201 int i, n;
2202 int kwid = 0;
2203 struct iaxxx_get_event_info ge;
2204 void *payload = NULL;
2205 unsigned int payload_size = 0, fw_status = IAXXX_FW_IDLE;
2206 int fw_status_retries = 0;
2207
2208 ALOGI("%s", __func__);
2209 prctl(PR_SET_NAME, (unsigned long)"sound trigger callback", 0, 0, 0);
2210
2211 pthread_mutex_lock(&stdev->lock);
2212
2213 if (socketpair(AF_UNIX, SOCK_STREAM, 0, exit_sockets) == -1) {
2214 ALOGE("%s: Failed to create termination socket", __func__);
2215 goto exit;
2216 }
2217
2218 stdev_close_term_sock(stdev);
2219 stdev->send_sock = exit_sockets[0];
2220 stdev->recv_sock = exit_sockets[1];
2221
2222 memset(fds, 0, 2 * sizeof(struct pollfd));
2223 int timeout = -1; // Wait for event indefinitely
2224 fds[0].events = POLLIN;
2225 fds[0].fd = uevent_open_socket(64*1024, true);
2226 if (fds[0].fd == -1) {
2227 ALOGE("Error opening socket for hotplug uevent errno %d(%s)",
2228 errno, strerror(errno));
2229 goto exit;
2230 }
2231 fds[1].events = POLLIN;
2232 fds[1].fd = stdev->recv_sock;
2233
2234 ge.event_id = -1;
2235
2236 // Try to get the firmware status, if we fail, try for 10 times with a gap
2237 // of 500ms, if we are unable to get the status after that then exit
2238 do {
2239 err = get_fw_status(stdev->odsp_hdl, &fw_status);
2240 if (err == -1) {
2241 ALOGE("%s: ERROR: Failed to get the firmware status %d(%s)",
2242 __func__, errno, strerror(errno));
2243 usleep(RETRY_US);
2244 fw_status_retries++;
2245 }
2246 } while (err != 0 && fw_status_retries < RETRY_NUMBER);
2247
2248 if (err != 0) {
2249 ALOGE("%s: ERROR: Failed to get firmware status after %d tries",
2250 __func__, RETRY_NUMBER);
2251 goto exit;
2252 }
2253
2254 if (fw_status == IAXXX_FW_ACTIVE) {
2255 stdev->is_st_hal_ready = false;
2256 // reset the firmware and wait for firmware download complete
2257 err = reset_fw(stdev->odsp_hdl);
2258 if (err == -1) {
2259 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2260 __func__, errno, strerror(errno));
2261 }
2262 stdev->fw_reset_done_by_hal = true;
2263 } else if (fw_status == IAXXX_FW_CRASH) {
2264 // Firmware has crashed wait till it recovers
2265 stdev->is_st_hal_ready = false;
2266 } else if (fw_status == IAXXX_FW_IDLE) {
2267 stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2268 stdev->mixer_path_xml);
2269 if (stdev->route_hdl == NULL) {
2270 ALOGE("Failed to init the audio_route library");
2271 goto exit;
2272 }
2273
2274 set_default_apll_clk(stdev->mixer);
2275 setup_slpi_wakeup_event(stdev->odsp_hdl, true);
2276 stdev->is_st_hal_ready = true;
2277 }
2278 pthread_mutex_unlock(&stdev->lock);
2279
2280 while (1) {
2281 err = poll(fds, 2, timeout);
2282
2283 pthread_mutex_lock(&stdev->lock);
2284 if (err < 0) {
2285 ALOGE("%s: Error in poll: %d (%s)",
2286 __func__, errno, strerror(errno));
2287 break;
2288 }
2289
2290 if (fds[0].revents & POLLIN) {
2291 n = uevent_kernel_multicast_recv(fds[0].fd, msg, UEVENT_MSG_LEN);
2292 if (n <= 0) {
2293 pthread_mutex_unlock(&stdev->lock);
2294 continue;
2295 }
2296 for (i = 0; i < n;) {
2297 if (strstr(msg + i, IAXXX_VQ_EVENT_STR)) {
2298 ALOGI("%s", IAXXX_VQ_EVENT_STR);
2299
2300 err = get_event(stdev->odsp_hdl, &ge);
2301 if (err == 0) {
2302 if (ge.event_id == OK_GOOGLE_KW_ID) {
2303 ALOGD("Eventid received is OK_GOOGLE_KW_ID %d",
2304 OK_GOOGLE_KW_ID);
2305 kwid = OK_GOOGLE_KW_ID;
2306 } else if (ge.event_id == AMBIENT_KW_ID) {
2307 ALOGD("Eventid received is AMBIENT_KW_ID %d",
2308 AMBIENT_KW_ID);
2309 kwid = AMBIENT_KW_ID;
2310 reset_ambient_plugin(stdev->odsp_hdl);
2311 } else if (ge.event_id == OSLO_EP_DISCONNECT) {
2312 ALOGD("Eventid received is OSLO_EP_DISCONNECT %d",
2313 OSLO_EP_DISCONNECT);
2314 if (stdev->is_sensor_destroy_in_prog == true) {
2315 // A timer would have been created during stop,
2316 // check and delete it
2317 if (stdev->ss_timer_created) {
2318 timer_delete(stdev->ss_timer);
2319 stdev->ss_timer_created = false;
2320 }
2321
2322 destroy_sensor_model(stdev);
2323 } else {
2324 ALOGE("Unexpected OSLO_EP_DISCONNECT received"
2325 ", ignoring..");
2326 }
2327 break;
2328 } else if (ge.event_id == CHRE_EP_DISCONNECT) {
2329 ALOGD("Eventid received is CHRE_EP_DISCONNECT %d",
2330 CHRE_EP_DISCONNECT);
2331 if (stdev->is_chre_destroy_in_prog == true) {
2332 // A timer would have been created during stop,
2333 // check and delete it
2334 if (stdev->chre_timer_created) {
2335 timer_delete(stdev->chre_timer);
2336 stdev->chre_timer_created = false;
2337 }
2338
2339 destroy_chre_model(stdev);
2340 } else {
2341 ALOGE("Unexpected CHRE_EP_DISCONNECT received"
2342 ", ignoring..");
2343 }
2344 break;
2345 } else if (ge.event_id == ENTITY_KW_ID) {
2346 ALOGD("Eventid received is ENTITY_KW_ID %d",
2347 ENTITY_KW_ID);
2348 kwid = ENTITY_KW_ID;
2349 } else if (ge.event_id == WAKEUP_KW_ID) {
2350 ALOGD("Eventid received is WAKEUP_KW_ID %d",
2351 WAKEUP_KW_ID);
2352 kwid = WAKEUP_KW_ID;
2353 } else {
2354 ALOGE("Unknown event id received, ignoring %d",
2355 ge.event_id);
2356 }
2357 stdev->last_detected_model_type = kwid;
2358 break;
2359 } else {
2360 ALOGE("get_event failed with error %d", err);
2361 }
2362 } else if (strstr(msg + i, IAXXX_RECOVERY_EVENT_STR)) {
2363 /* If the ST HAL did the firmware reset then that means
2364 * that the userspace crashed so we need to reinit the audio
2365 * route library, if we didn't reset the firmware, then it
2366 * was genuine firmware crash and we don't need to reinit
2367 * the audio route library.
2368 */
2369 if (stdev->fw_reset_done_by_hal == true) {
2370 stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2371 stdev->mixer_path_xml);
2372 if (stdev->route_hdl == NULL) {
2373 ALOGE("Failed to init the audio_route library");
2374 goto exit;
2375 }
2376
2377 stdev->fw_reset_done_by_hal = false;
2378 }
2379
2380 ALOGD("Firmware has redownloaded, start the recovery");
2381 int err = crash_recovery(stdev);
2382 if (err != 0) {
2383 ALOGE("Crash recovery failed");
2384 }
2385 } else if (strstr(msg + i, IAXXX_FW_DWNLD_SUCCESS_STR)) {
2386 ALOGD("Firmware downloaded successfully");
2387 stdev->is_st_hal_ready = true;
2388 set_default_apll_clk(stdev->mixer);
2389 } else if (strstr(msg + i, IAXXX_FW_CRASH_EVENT_STR)) {
2390 ALOGD("Firmware has crashed");
2391 // Don't allow any op on ST HAL until recovery is complete
2392 stdev->is_st_hal_ready = false;
2393 reset_all_route(stdev->route_hdl);
2394 stdev->is_streaming = 0;
2395
2396 // Firmware crashed, clear CHRE/Oslo timer and flags here
2397 sensor_crash_handler(stdev);
2398 chre_crash_handler(stdev);
2399 }
2400
2401 i += strlen(msg + i) + 1;
2402 }
2403
2404 if (ge.event_id == OK_GOOGLE_KW_ID ||
2405 ge.event_id == AMBIENT_KW_ID ||
2406 ge.event_id == ENTITY_KW_ID ||
2407 ge.event_id == WAKEUP_KW_ID) {
2408 ALOGD("%s: Keyword ID %d", __func__, kwid);
2409
2410 if (ge.data != 0) {
2411 ALOGD("Size of payload is %d", ge.data);
2412 payload_size = ge.data;
2413 payload = malloc(payload_size);
2414 if (payload != NULL) {
2415 if (ge.event_id == AMBIENT_KW_ID ||
2416 ge.event_id == ENTITY_KW_ID)
2417 err = get_entity_param_blk(stdev->odsp_hdl,
2418 payload,
2419 payload_size);
2420 else if (ge.event_id == OK_GOOGLE_KW_ID ||
2421 ge.event_id == WAKEUP_KW_ID)
2422 err = get_wakeup_param_blk(stdev->odsp_hdl,
2423 payload,
2424 payload_size);
2425 if (err != 0) {
2426 ALOGE("Failed to get payload data");
2427 free(payload);
2428 payload = NULL;
2429 payload_size = 0;
2430 }
2431 } else {
2432 ALOGE("Failed to allocate memory for payload");
2433 }
2434 }
2435 int idx = find_handle_for_kw_id(stdev, kwid);
2436 if (idx < MAX_MODELS && stdev->models[idx].is_active == true) {
2437 int recognition_status = RECOGNITION_STATUS_SUCCESS;
2438 if (stdev->models[idx].is_state_query == true) {
2439 recognition_status =
2440 RECOGNITION_STATUS_GET_STATE_RESPONSE;
2441
2442 // We need to send this only once, so reset now
2443 stdev->models[idx].is_state_query = false;
2444 }
2445 if (stdev->models[idx].type == SOUND_MODEL_TYPE_KEYPHRASE) {
2446 struct sound_trigger_phrase_recognition_event *event;
2447 event = (struct sound_trigger_phrase_recognition_event*)
2448 stdev_keyphrase_event_alloc(
2449 stdev->models[idx].model_handle,
2450 stdev->models[idx].config,
2451 recognition_status);
2452 if (event) {
2453 struct model_info *model;
2454 model = &stdev->models[idx];
2455
2456 ALOGD("Sending recognition callback for id %d",
2457 kwid);
2458 model->recognition_callback(&event->common,
2459 model->recognition_cookie);
2460 // Update the config so that it will be used
2461 // during the streaming
2462 stdev->last_keyword_detected_config = model->config;
2463
2464 free(event);
2465 } else {
2466 ALOGE("Failed to allocate memory for the event");
2467 }
2468 } else if (stdev->models[idx].type == SOUND_MODEL_TYPE_GENERIC) {
2469 struct sound_trigger_generic_recognition_event *event;
2470 event = (struct sound_trigger_generic_recognition_event*)
2471 stdev_generic_event_alloc(
2472 stdev->models[idx].model_handle,
2473 payload,
2474 payload_size,
2475 recognition_status);
2476 if (event) {
2477 struct model_info *model;
2478 model = &stdev->models[idx];
2479
2480 ALOGD("Sending recognition callback for id %d",
2481 kwid);
2482 model->recognition_callback(&event->common,
2483 model->recognition_cookie);
2484 // Update the config so that it will be used
2485 // during the streaming
2486 stdev->last_keyword_detected_config = model->config;
2487
2488 free(event);
2489 } else {
2490 ALOGE("Failed to allocate memory for the event");
2491 }
2492 }
2493 } else {
2494 ALOGE("Invalid id or keyword is not active, Subsume the event");
2495 }
2496 // Reset all event related data
2497 ge.event_id = -1;
2498 ge.data = 0;
2499 kwid = -1;
2500 }
2501 // Free the payload data
2502 if (payload) {
2503 free(payload);
2504 payload = NULL;
2505 payload_size = 0;
2506 }
2507 } else if (fds[1].revents & POLLIN) {
2508 read(fds[1].fd, &n, sizeof(n)); /* clear the socket */
2509 ALOGD("%s: Termination message", __func__);
2510 break;
2511 }
2512 else {
2513 ALOGI("%s: Message ignored", __func__);
2514 }
2515 pthread_mutex_unlock(&stdev->lock);
2516 }
2517
2518 exit:
2519 stdev_close_term_sock(stdev);
2520 pthread_mutex_unlock(&stdev->lock);
2521
2522 return (void *)(long)err;
2523 }
2524
stdev_get_properties(const struct sound_trigger_hw_device * dev __unused,struct sound_trigger_properties * properties)2525 static int stdev_get_properties(
2526 const struct sound_trigger_hw_device *dev __unused,
2527 struct sound_trigger_properties *properties)
2528 {
2529 ALOGV("+%s+", __func__);
2530 if (properties == NULL)
2531 return -EINVAL;
2532 memcpy(properties, &hw_properties, sizeof(struct sound_trigger_properties));
2533 ALOGV("-%s-", __func__);
2534 return 0;
2535 }
2536
stop_recognition(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle)2537 static int stop_recognition(struct knowles_sound_trigger_device *stdev,
2538 sound_model_handle_t handle)
2539 {
2540 int status = 0;
2541 struct model_info *model = &stdev->models[handle];
2542
2543 if (stdev->is_st_hal_ready == false) {
2544 ALOGE("%s: ST HAL is not ready yet", __func__);
2545 status = -EAGAIN;
2546 goto exit;
2547 }
2548
2549 if (model->config != NULL) {
2550 dereg_hal_event_session(model->config, handle);
2551 free(model->config);
2552 model->config = NULL;
2553 }
2554
2555 model->recognition_callback = NULL;
2556 model->recognition_cookie = NULL;
2557 if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
2558 check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
2559 // This avoids any processing of chre/oslo.
2560 goto exit;
2561 }
2562 if (can_update_recover_list(stdev) == true) {
2563 update_recover_list(stdev, handle, false);
2564 model->is_active = false;
2565 goto exit;
2566 }
2567
2568 if (stdev->adnc_strm_handle[handle] != 0) {
2569 ALOGD("%s: stop tunnling for index:%d", __func__, handle);
2570 stdev->adnc_strm_close(stdev->adnc_strm_handle[handle]);
2571 stdev->adnc_strm_handle[handle] = 0;
2572 stdev->is_streaming--;
2573 stdev->adnc_strm_last_read[handle] = reset_time;
2574 }
2575
2576 model->is_active = false;
2577
2578 tear_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
2579
2580 destroy_package(stdev, model);
2581
2582
2583 if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
2584 (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
2585 if ((stdev->hotword_buffer_enable) &&
2586 !(stdev->current_enable & PLUGIN1_MASK)) {
2587 tear_hotword_buffer_route(stdev->route_hdl,
2588 stdev->is_bargein_route_enabled);
2589 }
2590 }
2591
2592 if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
2593 (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
2594 if ((stdev->music_buffer_enable) &&
2595 !(stdev->current_enable & PLUGIN2_MASK)) {
2596 tear_music_buffer_route(stdev->route_hdl,
2597 stdev->is_bargein_route_enabled);
2598 }
2599 }
2600
2601 setup_buffer(stdev, model, false);
2602
2603 handle_input_source(stdev, false);
2604
2605 check_and_destroy_buffer_package(stdev);
2606
2607 exit:
2608 return status;
2609 }
2610
stdev_load_sound_model(const struct sound_trigger_hw_device * dev,struct sound_trigger_sound_model * sound_model,sound_model_callback_t callback,void * cookie,sound_model_handle_t * handle)2611 static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
2612 struct sound_trigger_sound_model *sound_model,
2613 sound_model_callback_t callback,
2614 void *cookie,
2615 sound_model_handle_t *handle)
2616 {
2617 struct knowles_sound_trigger_device *stdev =
2618 (struct knowles_sound_trigger_device *)dev;
2619 int ret = 0;
2620 int kw_model_sz = 0;
2621 int i = 0;
2622
2623 unsigned char *kw_buffer = NULL;
2624
2625 ALOGD("+%s+", __func__);
2626 pthread_mutex_lock(&stdev->lock);
2627
2628 if (stdev->is_st_hal_ready == false) {
2629 ALOGE("%s: ST HAL is not ready yet", __func__);
2630 ret = -EAGAIN;
2631 goto exit;
2632 }
2633
2634 if (handle == NULL || sound_model == NULL) {
2635 ALOGE("%s: handle/sound_model is NULL", __func__);
2636 ret = -EINVAL;
2637 goto exit;
2638 }
2639
2640 if (sound_model->data_size == 0 ||
2641 sound_model->data_offset < sizeof(struct sound_trigger_sound_model)) {
2642 ALOGE("%s: Invalid sound model data", __func__);
2643 ret = -EINVAL;
2644 goto exit;
2645 }
2646
2647 // When a delayed CHRE/Oslo destroy process is in progress,
2648 // we should not skip the new model and return the existing handle
2649 // which will be destroyed soon.
2650 if ((check_uuid_equality(sound_model->vendor_uuid,
2651 stdev->chre_model_uuid) &&
2652 stdev->is_chre_destroy_in_prog) ||
2653 (check_uuid_equality(sound_model->vendor_uuid,
2654 stdev->sensor_model_uuid) &&
2655 stdev->is_sensor_destroy_in_prog)) {
2656 ALOGD("%s: CHRE/Oslo destroy in progress, skipped handle check.",
2657 __func__);
2658 } else {
2659 i = find_handle_for_uuid(stdev, sound_model->vendor_uuid);
2660 if (i != -1) {
2661 ALOGW("%s: model is existed at index %d", __func__, i);
2662 *handle = i;
2663 goto exit;
2664 }
2665 }
2666
2667 // Find an empty slot to load the model
2668 i = find_empty_model_slot(stdev);
2669 if (i == -1) {
2670 ALOGE("%s: Can't load model no free slots available", __func__);
2671 ret = -ENOSYS;
2672 goto exit;
2673 }
2674
2675 kw_buffer = (unsigned char *) sound_model + sound_model->data_offset;
2676 kw_model_sz = sound_model->data_size;
2677 ALOGV("%s: kw_model_sz %d", __func__, kw_model_sz);
2678
2679 stdev->models[i].data = malloc(kw_model_sz);
2680 if (stdev->models[i].data == NULL) {
2681 stdev->models[i].data_sz = 0;
2682 ALOGE("%s: could not allocate memory for keyword model data",
2683 __func__);
2684 ret = -ENOMEM;
2685 goto exit;
2686 } else {
2687 memcpy(stdev->models[i].data, kw_buffer, kw_model_sz);
2688 stdev->models[i].data_sz = kw_model_sz;
2689 }
2690
2691 // Send the keyword model to the chip only for hotword and ambient audio
2692 if (check_uuid_equality(sound_model->vendor_uuid,
2693 stdev->hotword_model_uuid)) {
2694 stdev->models[i].kw_id = OK_GOOGLE_KW_ID;
2695 } else if (check_uuid_equality(sound_model->vendor_uuid,
2696 stdev->wakeup_model_uuid)) {
2697 stdev->models[i].kw_id = WAKEUP_KW_ID;
2698 } else if (check_uuid_equality(sound_model->vendor_uuid,
2699 stdev->ambient_model_uuid)) {
2700 stdev->models[i].kw_id = AMBIENT_KW_ID;
2701 } else if (check_uuid_equality(sound_model->vendor_uuid,
2702 stdev->entity_model_uuid)) {
2703 stdev->models[i].kw_id = ENTITY_KW_ID;
2704 } else if (check_uuid_equality(sound_model->vendor_uuid,
2705 stdev->sensor_model_uuid)) {
2706 ret = start_sensor_model(stdev);
2707 if (ret) {
2708 ALOGE("%s: ERROR: Failed to start sensor model", __func__);
2709 goto error;
2710 }
2711 stdev->models[i].kw_id = USELESS_KW_ID;
2712 } else if (check_uuid_equality(sound_model->vendor_uuid,
2713 stdev->chre_model_uuid)) {
2714 ret = start_chre_model(stdev, i);
2715 if (ret) {
2716 ALOGE("%s: ERROR: Failed to start chre model", __func__);
2717 goto error;
2718 }
2719 stdev->models[i].kw_id = USELESS_KW_ID;
2720 } else {
2721 ALOGE("%s: ERROR: unknown keyword model file", __func__);
2722 ret = -EINVAL;
2723 goto error;
2724 }
2725
2726 *handle = i;
2727 ALOGV("%s: Loading keyword model handle(%d) type(%d)", __func__,
2728 *handle, sound_model->type);
2729 // This will need to be replaced with UUID once they are fixed
2730 stdev->models[i].model_handle = *handle;
2731 stdev->models[i].type = sound_model->type;
2732 stdev->models[i].uuid = sound_model->vendor_uuid;
2733 stdev->models[i].sound_model_callback = callback;
2734 stdev->models[i].sound_model_cookie = cookie;
2735 stdev->models[i].recognition_callback = NULL;
2736 stdev->models[i].recognition_cookie = NULL;
2737
2738 stdev->models[i].is_loaded = true;
2739
2740 error:
2741 if (ret != 0) {
2742 if (stdev->models[i].data) {
2743 free(stdev->models[i].data);
2744 stdev->models[i].data = NULL;
2745 stdev->models[i].data_sz = 0;
2746 }
2747 if (!is_any_model_loaded(stdev) && stdev->is_buffer_package_loaded) {
2748 destroy_buffer_package(stdev->odsp_hdl);
2749 stdev->is_buffer_package_loaded = false;
2750 }
2751 }
2752
2753 exit:
2754 pthread_mutex_unlock(&stdev->lock);
2755 ALOGD("-%s handle %d-", __func__, *handle);
2756 return ret;
2757 }
2758
stdev_unload_sound_model(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)2759 static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
2760 sound_model_handle_t handle)
2761 {
2762 struct knowles_sound_trigger_device *stdev =
2763 (struct knowles_sound_trigger_device *)dev;
2764 int ret = 0;
2765 ALOGD("+%s handle %d+", __func__, handle);
2766 pthread_mutex_lock(&stdev->lock);
2767
2768 if (stdev->is_st_hal_ready == false) {
2769 ALOGE("%s: ST HAL is not ready yet", __func__);
2770 ret = -EAGAIN;
2771 goto exit;
2772 }
2773
2774 // Just confirm the model was previously loaded
2775 if (stdev->models[handle].is_loaded == false) {
2776 ALOGE("%s: Invalid model(%d) being called for unload",
2777 __func__, handle);
2778 ret = -EINVAL;
2779 goto exit;
2780 }
2781
2782 if (stdev->models[handle].is_active == true) {
2783 ret = stop_recognition(stdev, handle);
2784 if (ret)
2785 goto exit;
2786 }
2787
2788 if (check_uuid_equality(stdev->models[handle].uuid,
2789 stdev->sensor_model_uuid)) {
2790 // Inform the Host 1 that sensor route/packages are about to be
2791 // torndown and then wait for confirmation from Host 1 that it can be
2792 // torndown. Also start a timer for 5 seconds, if the Host 1 doesn't
2793 // send us the event within 5 seconds we force remove the sensor pkgs
2794 if (stdev->is_sensor_route_enabled == true) {
2795 struct itimerspec ss_timer_spec;
2796 struct sigevent ss_sigevent;
2797
2798 // Inform the host 1
2799 stdev->is_sensor_destroy_in_prog = true;
2800 trigger_sensor_destroy_event(stdev->odsp_hdl);
2801
2802 // Start timer for 5 seconds
2803 ss_sigevent.sigev_notify = SIGEV_THREAD;
2804 ss_sigevent.sigev_notify_function = sensor_timeout_recover;
2805 ss_sigevent.sigev_notify_attributes = NULL;
2806
2807 ss_timer_spec.it_interval.tv_sec = 0;
2808 ss_timer_spec.it_interval.tv_nsec = 0;
2809 ss_timer_spec.it_value.tv_sec =
2810 SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT;
2811 ss_timer_spec.it_value.tv_nsec = 0;
2812
2813 if (stdev->ss_timer_created) {
2814 timer_delete(stdev->ss_timer);
2815 stdev->ss_timer_created = false;
2816 }
2817
2818 if (timer_create(CLOCK_REALTIME,
2819 &ss_sigevent, &stdev->ss_timer) == -1) {
2820 ALOGE("%s: Timer Create Failed", __func__);
2821 } else {
2822 stdev->ss_timer_created = true;
2823 if (timer_settime(stdev->ss_timer,
2824 0, &ss_timer_spec, NULL) == -1) {
2825 ALOGE("%s: Timer Set Failed", __func__);
2826 }
2827 }
2828 }
2829 } else if (check_uuid_equality(stdev->models[handle].uuid,
2830 stdev->chre_model_uuid)) {
2831 // remove chre from recover list
2832 if (can_update_recover_list(stdev) == true)
2833 update_recover_list(stdev, handle, false);
2834
2835 // Disable the CHRE route
2836 if (stdev->is_chre_loaded == true) {
2837 struct itimerspec chre_timer_spec;
2838 struct sigevent chre_sigevent;
2839
2840 // Inform the host 1
2841 stdev->is_chre_destroy_in_prog = true;
2842 trigger_chre_destroy_event(stdev->odsp_hdl);
2843
2844 // Start timer for 5 seconds
2845 chre_sigevent.sigev_notify = SIGEV_THREAD;
2846 chre_sigevent.sigev_notify_function = chre_timeout_recover;
2847 chre_sigevent.sigev_notify_attributes = NULL;
2848
2849 chre_timer_spec.it_interval.tv_sec = 0;
2850 chre_timer_spec.it_interval.tv_nsec = 0;
2851 chre_timer_spec.it_value.tv_sec =
2852 CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT;
2853 chre_timer_spec.it_value.tv_nsec = 0;
2854
2855 if (stdev->chre_timer_created) {
2856 timer_delete(stdev->chre_timer);
2857 stdev->chre_timer_created = false;
2858 }
2859
2860 if (timer_create(CLOCK_REALTIME,
2861 &chre_sigevent, &stdev->chre_timer) == -1) {
2862 ALOGE("%s: Timer Create Failed", __func__);
2863 } else {
2864 stdev->chre_timer_created = true;
2865 if (timer_settime(stdev->chre_timer,
2866 0, &chre_timer_spec, NULL) == -1) {
2867 ALOGE("%s: Timer Set Failed", __func__);
2868 }
2869 }
2870 }
2871 }
2872
2873 stdev->models[handle].sound_model_callback = NULL;
2874 stdev->models[handle].sound_model_cookie = NULL;
2875
2876 if (!(check_uuid_equality(stdev->models[handle].uuid,
2877 stdev->sensor_model_uuid) &&
2878 stdev->is_sensor_destroy_in_prog) &&
2879 !(check_uuid_equality(stdev->models[handle].uuid,
2880 stdev->chre_model_uuid) &&
2881 stdev->is_chre_destroy_in_prog)) {
2882 memset(&stdev->models[handle].uuid, 0, sizeof(sound_trigger_uuid_t));
2883 stdev->models[handle].is_loaded = false;
2884 }
2885
2886 if (stdev->models[handle].data) {
2887 free(stdev->models[handle].data);
2888 stdev->models[handle].data = NULL;
2889 stdev->models[handle].data_sz = 0;
2890 }
2891
2892 ALOGD("%s: Successfully unloaded the model, handle - %d",
2893 __func__, handle);
2894 exit:
2895 pthread_mutex_unlock(&stdev->lock);
2896 ALOGD("-%s handle %d-", __func__, handle);
2897 return ret;
2898 }
2899
stdev_start_recognition(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle,const struct sound_trigger_recognition_config * config,recognition_callback_t callback,void * cookie)2900 static int stdev_start_recognition(
2901 const struct sound_trigger_hw_device *dev,
2902 sound_model_handle_t handle,
2903 const struct sound_trigger_recognition_config *config,
2904 recognition_callback_t callback,
2905 void *cookie)
2906 {
2907 struct knowles_sound_trigger_device *stdev =
2908 (struct knowles_sound_trigger_device *)dev;
2909 int status = 0;
2910 struct model_info *model = &stdev->models[handle];
2911
2912 ALOGD("%s stdev %p, sound model %d", __func__, stdev, handle);
2913
2914 pthread_mutex_lock(&stdev->lock);
2915
2916 if (stdev->is_st_hal_ready == false) {
2917 ALOGE("%s: ST HAL is not ready yet", __func__);
2918 status = -EAGAIN;
2919 goto exit;
2920 }
2921
2922 if (callback == NULL) {
2923 ALOGE("%s: recognition_callback is null", __func__);
2924 status = -EINVAL;
2925 goto exit;
2926 }
2927
2928 if (model->config != NULL) {
2929 dereg_hal_event_session(model->config, handle);
2930 free(model->config);
2931 model->config = NULL;
2932 }
2933
2934 if (config != NULL) {
2935 model->config = (struct sound_trigger_recognition_config *)
2936 malloc(sizeof(*config));
2937 if (model->config == NULL) {
2938 ALOGE("%s: Failed to allocate memory for model config", __func__);
2939 status = -ENOMEM;
2940 goto exit;
2941 }
2942
2943 memcpy(model->config, config, sizeof(*config));
2944 reg_hal_event_session(model->config, handle);
2945
2946 ALOGD("%s: Is capture requested %d",
2947 __func__, config->capture_requested);
2948 } else {
2949 ALOGD("%s: config is null", __func__);
2950 model->config = NULL;
2951 }
2952
2953 model->recognition_callback = callback;
2954 model->recognition_cookie = cookie;
2955 if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
2956 check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
2957 // This avoids any processing of chre/oslo.
2958 goto exit;
2959 }
2960 if (model->is_active == true) {
2961 // This model is already active, do nothing except updating callbacks,
2962 // configs and cookie
2963 goto exit;
2964 }
2965 if (can_update_recover_list(stdev) == true) {
2966 // Device is in voice/VoIP call, add model to recover list first
2967 // recover model once voice/VoIP is ended.
2968 update_recover_list(stdev, handle, true);
2969 goto exit;
2970 }
2971
2972 status = check_and_setup_buffer_package(stdev);
2973 if (status != 0) {
2974 ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
2975 goto exit;
2976 }
2977
2978 model->is_active = true;
2979
2980 handle_input_source(stdev, true);
2981
2982 if (stdev->is_buffer_package_loaded == true) {
2983 setup_buffer(stdev, model, true);
2984 }
2985
2986 if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
2987 (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
2988 if ((stdev->hotword_buffer_enable) &&
2989 (!(stdev->current_enable & HOTWORD_MASK) ||
2990 (stdev->current_enable & WAKEUP_MASK))) {
2991 set_hotword_buffer_route(stdev->route_hdl,
2992 stdev->is_bargein_route_enabled);
2993 }
2994 }
2995
2996 if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
2997 (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
2998 if ((stdev->music_buffer_enable) &&
2999 (!(stdev->current_enable & AMBIENT_MASK) ||
3000 (stdev->current_enable & ENTITY_MASK))) {
3001 set_music_buffer_route(stdev->route_hdl,
3002 stdev->is_bargein_route_enabled);
3003 }
3004 }
3005
3006 setup_package(stdev, model);
3007
3008 set_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
3009
3010 exit:
3011 pthread_mutex_unlock(&stdev->lock);
3012 ALOGD("-%s sound model %d-", __func__, handle);
3013 return status;
3014 }
3015
stdev_stop_recognition(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)3016 static int stdev_stop_recognition(
3017 const struct sound_trigger_hw_device *dev,
3018 sound_model_handle_t handle)
3019 {
3020 struct knowles_sound_trigger_device *stdev =
3021 (struct knowles_sound_trigger_device *)dev;
3022 int status = 0;
3023 pthread_mutex_lock(&stdev->lock);
3024 ALOGD("+%s sound model %d+", __func__, handle);
3025
3026 status = stop_recognition(stdev, handle);
3027
3028 if (status != 0)
3029 goto exit;
3030
3031 ALOGD("-%s sound model %d-", __func__, handle);
3032 exit:
3033 pthread_mutex_unlock(&stdev->lock);
3034
3035 return status;
3036 }
3037
3038 /**
3039 * Get the state of a given model.
3040 * The model state is returned asynchronously as a RecognitionEvent via
3041 * the callback that was registered in StartRecognition().
3042 * @param modelHandle The handle of the sound model whose state is being
3043 * queried.
3044 * @return retval Operation completion status: 0 in case of success,
3045 * -ENOSYS in case of invalid model handle,
3046 * -ENOMEM in case of memory allocation failure,
3047 * -ENODEV in case of initialization error,
3048 * -EINVAL in case where a recognition event is already
3049 * being processed.
3050 */
stdev_get_model_state(const struct sound_trigger_hw_device * dev,sound_model_handle_t sound_model_handle)3051 static int stdev_get_model_state(const struct sound_trigger_hw_device *dev,
3052 sound_model_handle_t sound_model_handle) {
3053 struct knowles_sound_trigger_device *stdev =
3054 (struct knowles_sound_trigger_device *)dev;
3055 struct model_info *model = &stdev->models[sound_model_handle];
3056 int ret = 0;
3057 ALOGD("+%s+", __func__);
3058 pthread_mutex_lock(&stdev->lock);
3059
3060 if (!stdev->opened) {
3061 ALOGE("%s: stdev isn't initialized", __func__);
3062 ret = -ENODEV;
3063 goto exit;
3064 }
3065
3066 if (stdev->is_st_hal_ready == false) {
3067 ALOGE("%s: ST HAL is not ready yet", __func__);
3068 ret = -ENODEV;
3069 goto exit;
3070 }
3071
3072 if (model->is_active == false) {
3073 ALOGE("%s: ERROR: %d model is not active",
3074 __func__, sound_model_handle);
3075 ret = -ENOSYS;
3076 goto exit;
3077 }
3078
3079 if (model->is_state_query == true) {
3080 ALOGE("%s: ERROR: model %d is already processing",
3081 __func__, sound_model_handle);
3082 ret = -EINVAL;
3083 goto exit;
3084 }
3085
3086 model->is_state_query = true;
3087
3088 if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
3089 ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3090 HOTWORD_SLOT_ID);
3091 else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))
3092 ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3093 WAKEUP_SLOT_ID);
3094 else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
3095 ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3096 AMBIENT_SLOT_ID);
3097 else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
3098 ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3099 ENTITY_SLOT_ID);
3100 } else {
3101 ALOGE("%s: ERROR: %d model is not supported",
3102 __func__, sound_model_handle);
3103 ret = -ENOSYS;
3104 }
3105
3106 if (ret != 0) {
3107 model->is_state_query = false;
3108 ALOGE("%s: ERROR: Failed to get the model state", __func__);
3109 }
3110
3111 exit:
3112 pthread_mutex_unlock(&stdev->lock);
3113 ALOGD("-%s-", __func__);
3114 return ret;
3115 }
3116
stdev_close(hw_device_t * device)3117 static int stdev_close(hw_device_t *device)
3118 {
3119 struct knowles_sound_trigger_device *stdev =
3120 (struct knowles_sound_trigger_device *)device;
3121 int ret = 0;
3122 ALOGD("+%s+", __func__);
3123 pthread_mutex_lock(&stdev->lock);
3124
3125 if (!stdev->opened) {
3126 ALOGE("%s: device already closed", __func__);
3127 ret = -EFAULT;
3128 goto exit;
3129 }
3130
3131 if (stdev->is_st_hal_ready == false) {
3132 ALOGE("%s: ST HAL is not ready yet", __func__);
3133 ret = -EAGAIN;
3134 goto exit;
3135 }
3136
3137 setup_slpi_wakeup_event(stdev->odsp_hdl, false);
3138
3139 stdev->opened = false;
3140
3141 if (stdev->send_sock >= 0)
3142 write(stdev->send_sock, "T", 1);
3143 pthread_join(stdev->callback_thread, (void **)NULL);
3144
3145 if (stdev->route_hdl)
3146 audio_route_free(stdev->route_hdl);
3147 if (stdev->odsp_hdl)
3148 iaxxx_odsp_deinit(stdev->odsp_hdl);
3149
3150 if (stdev->ss_timer_created) {
3151 timer_delete(stdev->ss_timer);
3152 stdev->ss_timer_created = false;
3153 }
3154
3155 exit:
3156 pthread_mutex_unlock(&stdev->lock);
3157 ALOGD("-%s-", __func__);
3158 return ret;
3159 }
3160
3161 __attribute__ ((visibility ("default")))
stdev_get_audio_handle()3162 audio_io_handle_t stdev_get_audio_handle()
3163 {
3164 if (g_stdev.last_keyword_detected_config == NULL) {
3165 ALOGI("%s: Config is NULL so returning audio handle as 0", __func__);
3166 return 0;
3167 }
3168
3169 ALOGI("%s: Audio Handle is %d",
3170 __func__, g_stdev.last_keyword_detected_config->capture_handle);
3171
3172 return g_stdev.last_keyword_detected_config->capture_handle;
3173 }
3174
open_streaming_lib(struct knowles_sound_trigger_device * stdev)3175 static int open_streaming_lib(struct knowles_sound_trigger_device *stdev) {
3176 int ret = 0;
3177
3178 if (access(ADNC_STRM_LIBRARY_PATH, R_OK) == 0) {
3179 stdev->adnc_cvq_strm_lib = dlopen(ADNC_STRM_LIBRARY_PATH, RTLD_NOW);
3180 if (stdev->adnc_cvq_strm_lib == NULL) {
3181 char const *err_str = dlerror();
3182 ALOGE("%s: module = %s error = %s", __func__,
3183 ADNC_STRM_LIBRARY_PATH, err_str ? err_str : "unknown");
3184 ALOGE("%s: DLOPEN failed for %s", __func__, ADNC_STRM_LIBRARY_PATH);
3185 } else {
3186 ALOGV("%s: DLOPEN successful for %s",
3187 __func__, ADNC_STRM_LIBRARY_PATH);
3188 for (int index = 0; index < MAX_MODELS; index++) {
3189 stdev->adnc_strm_handle[index] = 0;
3190 stdev->adnc_strm_last_read[index] = reset_time;
3191 }
3192 stdev->adnc_strm_open =
3193 (int (*)(bool, int, int))dlsym(stdev->adnc_cvq_strm_lib,
3194 "adnc_strm_open");
3195 stdev->adnc_strm_read =
3196 (size_t (*)(long, void *, size_t))dlsym(stdev->adnc_cvq_strm_lib,
3197 "adnc_strm_read");
3198 stdev->adnc_strm_close =
3199 (int (*)(long))dlsym(stdev->adnc_cvq_strm_lib,
3200 "adnc_strm_close");
3201 if (!stdev->adnc_strm_open || !stdev->adnc_strm_read ||
3202 !stdev->adnc_strm_close) {
3203 ALOGE("%s: Error grabbing functions in %s", __func__,
3204 ADNC_STRM_LIBRARY_PATH);
3205 stdev->adnc_strm_open = 0;
3206 stdev->adnc_strm_read = 0;
3207 stdev->adnc_strm_close = 0;
3208 }
3209 }
3210 }
3211
3212 return ret;
3213 }
3214
find_stdev_mixer_path(int card_num,char * mixer_path_xml)3215 static struct mixer* find_stdev_mixer_path(int card_num, char *mixer_path_xml)
3216 {
3217 struct mixer *mixer = NULL;
3218 const char *in_snd_card_name;
3219 char *snd_card_name = NULL;
3220 char *tmp = NULL;
3221 char *platform = NULL;
3222 char *snd_card = NULL;
3223 char *device = NULL;
3224
3225 mixer = mixer_open(card_num);
3226
3227 if (!mixer) {
3228 ALOGE("%s: Unable to open the mixer: %d", __func__,
3229 card_num);
3230 return NULL;
3231 }
3232
3233 in_snd_card_name = mixer_get_name(mixer);
3234 snd_card_name = strdup(in_snd_card_name);
3235
3236 if (snd_card_name == NULL) {
3237 ALOGE("%s: snd_card_name is NULL", __func__);
3238 goto on_error;
3239 }
3240
3241 platform = strtok_r(snd_card_name, "-", &tmp);
3242 if (platform == NULL) {
3243 ALOGE("%s: snd card is invalid", __func__);
3244 goto on_error;
3245 }
3246
3247 snd_card = strtok_r(NULL, "-", &tmp);
3248 if (snd_card == NULL) {
3249 ALOGE("%s: snd card is invalid", __func__);
3250 goto on_error;
3251 }
3252
3253 device = strtok_r(NULL, "-", &tmp);
3254 if (device != NULL) {
3255 snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s_%s.xml",
3256 SOUND_TRIGGER_MIXER_PATH_BASE, device);
3257 } else {
3258 ALOGE("%s: Unknown device, try to use default xml", __func__);
3259 snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s",
3260 SOUND_TRIGGER_MIXER_PATH_XML);
3261 }
3262
3263 ALOGD("%s: using %s", __func__, mixer_path_xml);
3264
3265 on_error:
3266 if (snd_card_name)
3267 free(snd_card_name);
3268 return mixer;
3269 }
3270
find_sound_card()3271 static int find_sound_card() {
3272 int retry_num = 0, snd_card_num = 0, ret = -1;
3273 const char *snd_card_name;
3274 struct mixer *mixer = NULL;
3275 bool card_verifed[MAX_SND_CARD] = {false};
3276 const int retry_limit = property_get_int32("audio.snd_card.open.retries",
3277 RETRY_NUMBER);
3278 ALOGD("+%s+", __func__);
3279
3280 for (;;) {
3281 if (snd_card_num >= MAX_SND_CARD) {
3282 if (retry_num++ >= retry_limit) {
3283 ALOGE("%s: iaxxx sound card not found", __func__);
3284 goto exit;
3285 }
3286 snd_card_num = 0;
3287 usleep(RETRY_US);
3288 continue;
3289 }
3290 if (card_verifed[snd_card_num]) {
3291 snd_card_num++;
3292 continue;
3293 }
3294
3295 mixer = mixer_open(snd_card_num);
3296 if (!mixer) {
3297 snd_card_num++;
3298 continue;
3299 }
3300
3301 snd_card_name = mixer_get_name(mixer);
3302 if (strstr(snd_card_name, CARD_NAME)) {
3303 ALOGD("%s: find card %d has iaxxx - %s",
3304 __func__, snd_card_num, snd_card_name);
3305 ret = snd_card_num;
3306 break;
3307 }
3308
3309 ALOGD("%s: sound card %s does NOT have iaxxx", __func__, snd_card_name);
3310 mixer_close(mixer);
3311 mixer = NULL;
3312 card_verifed[snd_card_num] = true;
3313 snd_card_num++;
3314 }
3315
3316 exit:
3317 if (mixer)
3318 mixer_close(mixer);
3319
3320 ALOGD("-%s-", __func__);
3321 return ret;
3322 }
3323
load_audio_hal()3324 static int load_audio_hal()
3325 {
3326 char audio_hal_lib[100];
3327 void *sthal_prop_api_version = NULL;
3328 struct knowles_sound_trigger_device *stdev = &g_stdev;
3329 int ret = 0;
3330
3331 snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
3332 AUDIO_HAL_LIBRARY_PATH, AUDIO_HAL_NAME_PREFIX,
3333 SOUND_TRIGGER_PLATFORM);
3334 if (access(audio_hal_lib, R_OK)) {
3335 ALOGE("%s: ERROR. %s not found", __func__, audio_hal_lib);
3336 return -ENOENT;
3337 }
3338
3339 stdev->audio_hal_handle = dlopen(audio_hal_lib, RTLD_NOW);
3340 if (stdev->audio_hal_handle == NULL) {
3341 ALOGE("%s: ERROR. %s", __func__, dlerror());
3342 return -ENODEV;
3343 }
3344
3345 stdev->audio_hal_cb = dlsym(stdev->audio_hal_handle, "audio_hw_call_back");
3346 if (stdev->audio_hal_cb == NULL) {
3347 ALOGE("%s: ERROR. %s", __func__, dlerror());
3348 ret = -ENODEV;
3349 goto error;
3350 }
3351
3352 sthal_prop_api_version = dlsym(stdev->audio_hal_handle,
3353 "sthal_prop_api_version");
3354 if (sthal_prop_api_version == NULL) {
3355 stdev->sthal_prop_api_version = 0;
3356 ret = 0; /* passthru for backward compability */
3357 } else {
3358 stdev->sthal_prop_api_version = *(int *)sthal_prop_api_version;
3359 if (MAJOR_VERSION(stdev->sthal_prop_api_version) !=
3360 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
3361 ALOGE("%s: Incompatible API versions sthal:0x%x != ahal:0x%x",
3362 __func__, STHAL_PROP_API_CURRENT_VERSION,
3363 stdev->sthal_prop_api_version);
3364 goto error;
3365 }
3366 ALOGD("%s: ahal is using proprietary API version 0x%04x", __func__,
3367 stdev->sthal_prop_api_version);
3368 }
3369
3370 ALOGD("%s: load AHAL successfully.", __func__);
3371 return ret;
3372
3373 error:
3374 dlclose(stdev->audio_hal_handle);
3375 stdev->audio_hal_handle = NULL;
3376 return ret;
3377 }
3378
stdev_open(const hw_module_t * module,const char * name,hw_device_t ** device)3379 static int stdev_open(const hw_module_t *module, const char *name,
3380 hw_device_t **device)
3381 {
3382 struct knowles_sound_trigger_device *stdev;
3383 int ret = 0, i = 0;
3384 int snd_card_num = 0;
3385
3386 ALOGE("!! Knowles SoundTrigger v1!!");
3387
3388 if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0)
3389 return -EINVAL;
3390
3391 if (device == NULL)
3392 return -EINVAL;
3393
3394 stdev = &g_stdev;
3395 pthread_mutex_lock(&stdev->lock);
3396
3397 snd_card_num = find_sound_card();
3398 if (snd_card_num == -1) {
3399 ALOGE("%s: Unable to find the sound card %s", __func__, CARD_NAME);
3400 ret = -EAGAIN;
3401 goto exit;
3402 }
3403
3404 if (stdev->opened) {
3405 ALOGE("%s: Only one sountrigger can be opened at a time", __func__);
3406 ret = -EBUSY;
3407 goto exit;
3408 }
3409
3410 ret = open_streaming_lib(stdev);
3411 if (ret != 0) {
3412 ALOGE("%s: Couldnot open the streaming library", __func__);
3413 goto error;
3414 }
3415
3416 ret = load_audio_hal();
3417 if (ret != 0) {
3418 ALOGE("%s: Couldn't load AHAL", __func__);
3419 goto error;
3420 }
3421
3422 stdev->device.common.tag = HARDWARE_DEVICE_TAG;
3423 stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_2;
3424 stdev->device.common.module = (struct hw_module_t *)module;
3425 stdev->device.common.close = stdev_close;
3426 stdev->device.get_properties = stdev_get_properties;
3427 stdev->device.load_sound_model = stdev_load_sound_model;
3428 stdev->device.unload_sound_model = stdev_unload_sound_model;
3429 stdev->device.start_recognition = stdev_start_recognition;
3430 stdev->device.stop_recognition = stdev_stop_recognition;
3431 stdev->device.get_model_state = stdev_get_model_state;
3432
3433 stdev->opened = true;
3434 /* Initialize all member variable */
3435 for (i = 0; i < MAX_MODELS; i++) {
3436 stdev->models[i].type = SOUND_MODEL_TYPE_UNKNOWN;
3437 memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
3438 stdev->models[i].config = NULL;
3439 stdev->models[i].data = NULL;
3440 stdev->models[i].data_sz = 0;
3441 stdev->models[i].is_loaded = false;
3442 stdev->models[i].is_active = false;
3443 stdev->last_keyword_detected_config = NULL;
3444 stdev->models[i].is_state_query = false;
3445 }
3446
3447 stdev->is_mic_route_enabled = false;
3448 stdev->is_con_mic_route_enabled = false;
3449 stdev->is_ahal_in_voice_voip_mode = false;
3450 stdev->is_ahal_voice_voip_stop = false;
3451 stdev->is_ahal_voice_voip_start = false;
3452 stdev->is_bargein_route_enabled = false;
3453 stdev->is_chre_loaded = false;
3454 stdev->is_buffer_package_loaded = false;
3455 stdev->hotword_buffer_enable = 0;
3456 stdev->music_buffer_enable = 0;
3457 stdev->current_enable = 0;
3458 stdev->is_sensor_route_enabled = false;
3459 stdev->recover_model_list = 0;
3460 stdev->rx_active_count = 0;
3461 stdev->is_ahal_media_recording = false;
3462 stdev->is_concurrent_capture = hw_properties.concurrent_capture;
3463
3464 stdev->is_sensor_destroy_in_prog = false;
3465 stdev->ss_timer_created = false;
3466
3467 stdev->is_chre_destroy_in_prog = false;
3468 stdev->chre_timer_created = false;
3469
3470 stdev->snd_crd_num = snd_card_num;
3471 stdev->fw_reset_done_by_hal = false;
3472
3473 str_to_uuid(HOTWORD_AUDIO_MODEL, &stdev->hotword_model_uuid);
3474 str_to_uuid(WAKEUP_MODEL, &stdev->wakeup_model_uuid);
3475 str_to_uuid(SENSOR_MANAGER_MODEL, &stdev->sensor_model_uuid);
3476 str_to_uuid(AMBIENT_AUDIO_MODEL, &stdev->ambient_model_uuid);
3477 str_to_uuid(CHRE_AUDIO_MODEL, &stdev->chre_model_uuid);
3478 str_to_uuid(ENTITY_AUDIO_MODEL, &stdev->entity_model_uuid);
3479
3480 stdev->odsp_hdl = iaxxx_odsp_init();
3481 if (stdev->odsp_hdl == NULL) {
3482 ALOGE("%s: Failed to get handle to ODSP HAL", __func__);
3483 ret = -EIO;
3484 goto error;
3485 }
3486 stdev->mixer = find_stdev_mixer_path(stdev->snd_crd_num, stdev->mixer_path_xml);
3487 if (stdev->mixer == NULL) {
3488 ALOGE("Failed to init the mixer");
3489 ret = -EAGAIN;
3490 goto error;
3491 }
3492
3493 ALOGD("stdev before pthread_create %p", stdev);
3494 // Create a thread to handle all events from kernel
3495 pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
3496 callback_thread_loop, stdev);
3497
3498 pthread_create(&stdev->monitor_thread, (const pthread_attr_t *) NULL,
3499 monitor_thread_loop, stdev);
3500
3501 pthread_create(&stdev->transitions_thread, (const pthread_attr_t *) NULL,
3502 transitions_thread_loop, stdev);
3503
3504 *device = &stdev->device.common; /* same address as stdev */
3505 exit:
3506 pthread_mutex_unlock(&stdev->lock);
3507 return ret;
3508
3509 error:
3510 if (stdev->adnc_cvq_strm_lib)
3511 dlclose(stdev->adnc_cvq_strm_lib);
3512 if (stdev->audio_hal_handle)
3513 dlclose(stdev->audio_hal_handle);
3514 if (stdev->route_hdl)
3515 audio_route_free(stdev->route_hdl);
3516 if (stdev->odsp_hdl)
3517 iaxxx_odsp_deinit(stdev->odsp_hdl);
3518 if (stdev->mixer)
3519 mixer_close(stdev->mixer);
3520
3521 pthread_mutex_unlock(&stdev->lock);
3522 return ret;
3523 }
3524
3525 /* AHAL calls this callback to communicate with STHAL */
sound_trigger_hw_call_back(audio_event_type_t event,struct audio_event_info * config)3526 int sound_trigger_hw_call_back(audio_event_type_t event,
3527 struct audio_event_info *config)
3528 {
3529 int ret = 0;
3530 int i = 0;
3531 int index = -1;
3532 struct knowles_sound_trigger_device *stdev = &g_stdev;
3533 enum sthal_mode pre_mode, cur_mode;
3534
3535 if (!stdev)
3536 return -ENODEV;
3537
3538 if (!stdev->opened) {
3539 ALOGE("%s: Error SoundTrigger has not been opened", __func__);
3540 return -EINVAL;
3541 }
3542
3543 pthread_mutex_lock(&stdev->lock);
3544
3545 // update conditions for mic concurrency whatever firmware status may be.
3546 if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE ||
3547 event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
3548 event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE ||
3549 event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
3550 pre_mode = get_sthal_mode(stdev);
3551 update_sthal_conditions(stdev, event, config);
3552 cur_mode = get_sthal_mode(stdev);
3553 }
3554
3555 // update conditions for bargein whatever firmware status may be.
3556 if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE ||
3557 event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
3558 update_rx_conditions(stdev, event, config);
3559 }
3560
3561 if (stdev->is_st_hal_ready == false) {
3562 ALOGE("%s: ST HAL is not ready yet", __func__);
3563 ret = -EINVAL;
3564 goto exit;
3565 }
3566
3567 switch (event) {
3568 case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
3569 case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
3570 ALOGD("%s: handle capture device event %d", __func__, event);
3571
3572 //handle capture device on/off event
3573 do_handle_functions(stdev, pre_mode, cur_mode, event);
3574
3575 break;
3576 case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
3577 case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
3578 ALOGD("%s: handle capture stream event %d, usecase %d",
3579 __func__, event, config->u.usecase.type);
3580
3581 break;
3582 case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
3583 ALOGD("%s: handle playback stream inactive", __func__);
3584
3585 if (stdev->rx_active_count == 0) {
3586 if (stdev->is_mic_route_enabled != false) {
3587 // Atleast one keyword model is active so update the routes
3588 // Check if the bargein route is enabled if not enable bargein route
3589 // Check each model, if it is active then update it's route
3590 if (stdev->is_bargein_route_enabled != false) {
3591 ALOGD("Bargein disabling");
3592 stdev->is_bargein_route_enabled = false;
3593 // Check each model, if it is active then update it's route
3594 // Disable the bargein route
3595 for (i = 0; i < MAX_MODELS; i++) {
3596 if (stdev->models[i].is_active == true) {
3597 // teardown the package route with bargein
3598 ret = tear_package_route(stdev,
3599 stdev->models[i].uuid,
3600 !stdev->is_bargein_route_enabled);
3601 if (ret != 0) {
3602 ALOGE("Failed to tear old package route");
3603 goto exit;
3604 }
3605 // resetup the package route with out bargein
3606 ret = set_package_route(stdev,
3607 stdev->models[i].uuid,
3608 stdev->is_bargein_route_enabled);
3609 if (ret != 0) {
3610 ALOGE("Failed to enable package route");
3611 goto exit;
3612 }
3613 }
3614 }
3615
3616 //Switch buffer input source
3617 if (stdev->hotword_buffer_enable) {
3618 ret = tear_hotword_buffer_route(stdev->route_hdl,
3619 !stdev->is_bargein_route_enabled);
3620 if (ret != 0) {
3621 ALOGE("Failed to tear old buffer route");
3622 goto exit;
3623 }
3624 ret = set_hotword_buffer_route(stdev->route_hdl,
3625 stdev->is_bargein_route_enabled);
3626 if (ret != 0) {
3627 ALOGE("Failed to enable buffer route");
3628 goto exit;
3629 }
3630 }
3631
3632 if (stdev->music_buffer_enable) {
3633 ret = tear_music_buffer_route(stdev->route_hdl,
3634 !stdev->is_bargein_route_enabled);
3635 if (ret != 0) {
3636 ALOGE("Failed to tear old music buffer route");
3637 goto exit;
3638 }
3639 ret = set_music_buffer_route(stdev->route_hdl,
3640 stdev->is_bargein_route_enabled);
3641 if (ret != 0) {
3642 ALOGE("Failed to enable buffer route");
3643 goto exit;
3644 }
3645 }
3646
3647 ret = enable_bargein_route(stdev->route_hdl, false);
3648 if (ret != 0) {
3649 ALOGE("Failed to enable buffer route");
3650 goto exit;
3651 }
3652
3653 ret = destroy_aec_package(stdev->odsp_hdl);
3654 if (ret != 0) {
3655 ALOGE("Failed to unload AEC package");
3656 goto exit;
3657 }
3658
3659 ret = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
3660 if (ret != 0) {
3661 ALOGE("Failed to disable SRC-amp route");
3662 goto exit;
3663 }
3664
3665 ret = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
3666 if (ret != 0) {
3667 ALOGE("Failed to unload SRC-amp package");
3668 goto exit;
3669 }
3670
3671 if (is_mic_controlled_by_ahal(stdev) == false) {
3672 ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
3673 if (ret != 0) {
3674 ALOGE("Failed to disable amp-ref route");
3675 goto exit;
3676 }
3677 ret = enable_mic_route(stdev->route_hdl, false,
3678 EXTERNAL_OSCILLATOR);
3679 if (ret != 0) {
3680 ALOGE("Failed to disable mic route with INT OSC");
3681 goto exit;
3682 }
3683 ret = enable_mic_route(stdev->route_hdl, true,
3684 INTERNAL_OSCILLATOR);
3685 if (ret != 0) {
3686 ALOGE("Failed to enable mic route with EXT OSC");
3687 goto exit;
3688 }
3689 } else {
3690 // main mic is turned by media record, close it by 48khz
3691 ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
3692 if (ret != 0) {
3693 ALOGE("Failed to disable amp-ref route");
3694 goto exit;
3695 }
3696 }
3697 } else {
3698 ALOGW("%s: barge-in isn't enabled", __func__);
3699 }
3700 }
3701 } else {
3702 ALOGD("%s: rx stream is still active", __func__);
3703 }
3704 break;
3705 case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
3706 ALOGD("%s: handle playback stream active", __func__);
3707
3708 if (stdev->rx_active_count > 0) {
3709 if (stdev->is_mic_route_enabled != false) {
3710 // Atleast one keyword model is active so update the routes
3711 // Check if the bargein route is enabled if not enable bargein route
3712 // Check each model, if it is active then update it's route
3713 stdev->transit_case = TRANSIT_SETUP_AEC;
3714 pthread_cond_signal(&stdev->transition_cond);
3715 }
3716 } else {
3717 ALOGW("%s: unexpeted stream active event", __func__);
3718 }
3719 break;
3720 case AUDIO_EVENT_STOP_LAB:
3721 /* Close Stream Driver */
3722 for (i = 0; i < MAX_MODELS; i++) {
3723 if (stdev->models[i].is_active &&
3724 stdev->models[i].config &&
3725 (stdev->models[i].config->capture_handle ==
3726 config->u.ses_info.capture_handle)) {
3727 index = i;
3728 break;
3729 }
3730 }
3731
3732 /*
3733 * Close unused adnc if ...
3734 * 1. No capture handle is found
3735 * 2. Model is inactive
3736 * 3. adnc stream handle is existed
3737 */
3738 if (index == -1 && stdev->is_streaming > 0) {
3739 ALOGD("%s: close unused adnc handle, cap_handle:%d", __func__,
3740 config->u.ses_info.capture_handle);
3741 for (i = 0; i < MAX_MODELS; i++) {
3742 if (stdev->adnc_strm_handle[i] != 0 &&
3743 !stdev->models[i].is_active) {
3744 stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
3745 stdev->adnc_strm_handle[i] = 0;
3746 stdev->is_streaming--;
3747 stdev->adnc_strm_last_read[i] = reset_time;
3748 }
3749 }
3750 goto exit;
3751 }
3752
3753 ALOGD("%s: close streaming %d, cap_handle:%d, index:%d",
3754 __func__, event, config->u.ses_info.capture_handle, index);
3755 if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3756 stdev->adnc_strm_close(stdev->adnc_strm_handle[index]);
3757 stdev->adnc_strm_handle[index] = 0;
3758 stdev->is_streaming--;
3759 stdev->adnc_strm_last_read[index] = reset_time;
3760 }
3761
3762 break;
3763
3764 case AUDIO_EVENT_SSR:
3765 /*[TODO] Do we need to handle adsp SSR event ? */
3766 ALOGD("%s: handle audio subsystem restart %d", __func__, event);
3767 break;
3768
3769 case AUDIO_EVENT_READ_SAMPLES:
3770 /* It is possible to change session info, check config */
3771 if (config->u.aud_info.ses_info == NULL) {
3772 ALOGE("%s: Invalid config, event:%d", __func__, event);
3773 ret = -EINVAL;
3774 goto exit;
3775 }
3776
3777 for (i = 0; i < MAX_MODELS; i++) {
3778 if (stdev->models[i].is_active &&
3779 stdev->models[i].config &&
3780 (stdev->models[i].config->capture_handle ==
3781 config->u.aud_info.ses_info->capture_handle)) {
3782 index = i;
3783 break;
3784 }
3785 }
3786
3787 /* Open Stream Driver */
3788 if (index != -1 && stdev->adnc_strm_handle[index] == 0) {
3789 if (stdev->adnc_strm_open == NULL) {
3790 ALOGE("%s: Error adnc streaming not supported", __func__);
3791 } else {
3792 bool keyword_stripping_enabled = false;
3793 int stream_end_point;
3794 switch (stdev->last_detected_model_type) {
3795 case OK_GOOGLE_KW_ID:
3796 stream_end_point = CVQ_ENDPOINT;
3797 break;
3798 case AMBIENT_KW_ID:
3799 case ENTITY_KW_ID:
3800 stream_end_point = MUSIC_BUF_ENDPOINT;
3801 break;
3802 default:
3803 stream_end_point = CVQ_ENDPOINT;
3804 break;
3805 };
3806 stdev->adnc_strm_handle[index] = stdev->adnc_strm_open(
3807 keyword_stripping_enabled, 0,
3808 stream_end_point);
3809 if (stdev->adnc_strm_handle[index]) {
3810 ALOGD("Successfully opened adnc strm! index %d handle %d",
3811 index, config->u.aud_info.ses_info->capture_handle);
3812 stdev->is_streaming++;
3813
3814 clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3815 if (stdev->is_streaming == 1)
3816 pthread_cond_signal(&stdev->tunnel_create);
3817 } else {
3818 ALOGE("%s: DSP is currently not streaming", __func__);
3819 }
3820 }
3821 }
3822
3823 if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3824 //ALOGD("%s: soundtrigger HAL adnc_strm_read", __func__);
3825 clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3826 pthread_mutex_unlock(&stdev->lock);
3827 stdev->adnc_strm_read(stdev->adnc_strm_handle[index],
3828 config->u.aud_info.buf,
3829 config->u.aud_info.num_bytes);
3830 pthread_mutex_lock(&stdev->lock);
3831 } else {
3832 ALOGE("%s: soundtrigger is not streaming", __func__);
3833 }
3834
3835 break;
3836
3837 case AUDIO_EVENT_NUM_ST_SESSIONS:
3838 case AUDIO_EVENT_DEVICE_CONNECT:
3839 case AUDIO_EVENT_DEVICE_DISCONNECT:
3840 case AUDIO_EVENT_SVA_EXEC_MODE:
3841 case AUDIO_EVENT_SVA_EXEC_MODE_STATUS:
3842 ALOGV("%s: useless event %d", __func__, event);
3843 break;
3844
3845 default:
3846 ALOGW("%s: Unknown event %d", __func__, event);
3847 break;
3848 }
3849
3850 exit:
3851 pthread_mutex_unlock(&stdev->lock);
3852 return ret;
3853 }
3854
3855 static struct hw_module_methods_t hal_module_methods = {
3856 .open = stdev_open,
3857 };
3858
3859 struct sound_trigger_module HAL_MODULE_INFO_SYM = {
3860 .common = {
3861 .tag = HARDWARE_MODULE_TAG,
3862 .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
3863 .hal_api_version = HARDWARE_HAL_API_VERSION,
3864 .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
3865 .name = "Knowles Sound Trigger HAL",
3866 .author = "Knowles Electronics",
3867 .methods = &hal_module_methods,
3868 },
3869 };
3870