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