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 "9b55e25e-8ea3-4f73-bce9-b37860d57f5a", //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 stdev->hotword_version = get_hotword_version(stdev->odsp_hdl);
2256 // reset the firmware and wait for firmware download complete
2257 err = reset_fw(stdev->odsp_hdl);
2258 if (err == -1) {
2259 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2260 __func__, errno, strerror(errno));
2261 }
2262 stdev->fw_reset_done_by_hal = true;
2263 } else if (fw_status == IAXXX_FW_CRASH) {
2264 // Firmware has crashed wait till it recovers
2265 stdev->is_st_hal_ready = false;
2266 } else if (fw_status == IAXXX_FW_IDLE) {
2267 stdev->hotword_version = get_hotword_version(stdev->odsp_hdl);
2268 if (stdev->hotword_version == HOTWORD_DEFAULT_VER) {
2269 /* This is unlikely use-case, the codec is abnormal at the beginning
2270 * reset_fw the firmware to recovery.
2271 */
2272 stdev->is_st_hal_ready = false;
2273 err = reset_fw(stdev->odsp_hdl);
2274 if (err == -1) {
2275 ALOGE("%s: ERROR: Failed to reset the firmware %d(%s)",
2276 __func__, errno, strerror(errno));
2277 }
2278 stdev->fw_reset_done_by_hal = true;
2279 } else {
2280 stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2281 stdev->mixer_path_xml);
2282 if (stdev->route_hdl == NULL) {
2283 ALOGE("Failed to init the audio_route library");
2284 goto exit;
2285 }
2286 set_default_apll_clk(stdev->mixer);
2287 setup_slpi_wakeup_event(stdev->odsp_hdl, true);
2288 stdev->is_st_hal_ready = true;
2289 }
2290 }
2291 pthread_mutex_unlock(&stdev->lock);
2292
2293 while (1) {
2294 err = poll(fds, 2, timeout);
2295
2296 pthread_mutex_lock(&stdev->lock);
2297 if (err < 0) {
2298 ALOGE("%s: Error in poll: %d (%s)",
2299 __func__, errno, strerror(errno));
2300 break;
2301 }
2302
2303 if (fds[0].revents & POLLIN) {
2304 n = uevent_kernel_multicast_recv(fds[0].fd, msg, UEVENT_MSG_LEN);
2305 if (n <= 0) {
2306 pthread_mutex_unlock(&stdev->lock);
2307 continue;
2308 }
2309 for (i = 0; i < n;) {
2310 if (strstr(msg + i, IAXXX_VQ_EVENT_STR)) {
2311 ALOGI("%s", IAXXX_VQ_EVENT_STR);
2312
2313 err = get_event(stdev->odsp_hdl, &ge);
2314 if (err == 0) {
2315 if (ge.event_id == OK_GOOGLE_KW_ID) {
2316 kwid = OK_GOOGLE_KW_ID;
2317 } else if (ge.event_id == AMBIENT_KW_ID) {
2318 kwid = AMBIENT_KW_ID;
2319 reset_ambient_plugin(stdev->odsp_hdl);
2320 } else if (ge.event_id == OSLO_EP_DISCONNECT) {
2321 ALOGD("Eventid received is OSLO_EP_DISCONNECT %d",
2322 OSLO_EP_DISCONNECT);
2323 if (stdev->is_sensor_destroy_in_prog == true) {
2324 // A timer would have been created during stop,
2325 // check and delete it
2326 if (stdev->ss_timer_created) {
2327 timer_delete(stdev->ss_timer);
2328 stdev->ss_timer_created = false;
2329 }
2330
2331 destroy_sensor_model(stdev);
2332 } else {
2333 ALOGE("Unexpected OSLO_EP_DISCONNECT received"
2334 ", ignoring..");
2335 }
2336 break;
2337 } else if (ge.event_id == CHRE_EP_DISCONNECT) {
2338 ALOGD("Eventid received is CHRE_EP_DISCONNECT %d",
2339 CHRE_EP_DISCONNECT);
2340 if (stdev->is_chre_destroy_in_prog == true) {
2341 // A timer would have been created during stop,
2342 // check and delete it
2343 if (stdev->chre_timer_created) {
2344 timer_delete(stdev->chre_timer);
2345 stdev->chre_timer_created = false;
2346 }
2347
2348 destroy_chre_model(stdev);
2349 } else {
2350 ALOGE("Unexpected CHRE_EP_DISCONNECT received"
2351 ", ignoring..");
2352 }
2353 break;
2354 } else if (ge.event_id == ENTITY_KW_ID) {
2355 kwid = ENTITY_KW_ID;
2356 } else if (ge.event_id == WAKEUP_KW_ID) {
2357 kwid = WAKEUP_KW_ID;
2358 } else {
2359 ALOGE("Unknown event id received, ignoring %d",
2360 ge.event_id);
2361 }
2362 break;
2363 } else {
2364 ALOGE("get_event failed with error %d", err);
2365 }
2366 } else if (strstr(msg + i, IAXXX_RECOVERY_EVENT_STR)) {
2367 /* If the ST HAL did the firmware reset then that means
2368 * that the userspace crashed so we need to reinit the audio
2369 * route library, if we didn't reset the firmware, then it
2370 * was genuine firmware crash and we don't need to reinit
2371 * the audio route library.
2372 */
2373 ALOGD("Firmware has redownloaded, start the recovery");
2374 if (stdev->fw_reset_done_by_hal == true) {
2375 stdev->route_hdl = audio_route_init(stdev->snd_crd_num,
2376 stdev->mixer_path_xml);
2377 if (stdev->route_hdl == NULL) {
2378 ALOGE("Failed to init the audio_route library");
2379 goto exit;
2380 }
2381
2382 stdev->fw_reset_done_by_hal = false;
2383 }
2384
2385 int err = crash_recovery(stdev);
2386 if (err != 0) {
2387 ALOGE("Crash recovery failed");
2388 }
2389 pthread_cond_signal(&stdev->firmware_ready_cond);
2390 } else if (strstr(msg + i, IAXXX_FW_DWNLD_SUCCESS_STR)) {
2391 ALOGD("Firmware downloaded successfully");
2392 stdev->is_st_hal_ready = true;
2393 set_default_apll_clk(stdev->mixer);
2394 } else if (strstr(msg + i, IAXXX_FW_CRASH_EVENT_STR)) {
2395 ALOGD("Firmware has crashed");
2396 // Don't allow any op on ST HAL until recovery is complete
2397 stdev->is_st_hal_ready = false;
2398 reset_all_route(stdev->route_hdl);
2399 stdev->is_streaming = 0;
2400
2401 // Firmware crashed, clear CHRE/Oslo timer and flags here
2402 sensor_crash_handler(stdev);
2403 chre_crash_handler(stdev);
2404 }
2405
2406 i += strlen(msg + i) + 1;
2407 }
2408
2409 if (ge.event_id == OK_GOOGLE_KW_ID ||
2410 ge.event_id == AMBIENT_KW_ID ||
2411 ge.event_id == ENTITY_KW_ID ||
2412 ge.event_id == WAKEUP_KW_ID) {
2413 ALOGD("%s: Keyword ID %d", __func__, kwid);
2414
2415 if (ge.data != 0) {
2416 ALOGD("Size of payload is %d", ge.data);
2417 payload_size = ge.data;
2418 payload = malloc(payload_size);
2419 if (payload != NULL) {
2420 if (ge.event_id == AMBIENT_KW_ID ||
2421 ge.event_id == ENTITY_KW_ID)
2422 err = get_entity_param_blk(stdev->odsp_hdl,
2423 payload,
2424 payload_size);
2425 else if (ge.event_id == OK_GOOGLE_KW_ID ||
2426 ge.event_id == WAKEUP_KW_ID)
2427 err = get_wakeup_param_blk(stdev->odsp_hdl,
2428 payload,
2429 payload_size);
2430 if (err != 0) {
2431 ALOGE("Failed to get payload data");
2432 free(payload);
2433 payload = NULL;
2434 payload_size = 0;
2435 }
2436 } else {
2437 ALOGE("Failed to allocate memory for payload");
2438 }
2439 }
2440 int idx = find_handle_for_kw_id(stdev, kwid);
2441 if (idx < MAX_MODELS && stdev->models[idx].is_active == true) {
2442 int recognition_status = RECOGNITION_STATUS_SUCCESS;
2443 if (stdev->models[idx].is_state_query == true) {
2444 recognition_status =
2445 RECOGNITION_STATUS_GET_STATE_RESPONSE;
2446
2447 // We need to send this only once, so reset now
2448 stdev->models[idx].is_state_query = false;
2449 }
2450 if (stdev->models[idx].type == SOUND_MODEL_TYPE_KEYPHRASE &&
2451 stdev->adnc_strm_handle[idx] == 0) {
2452 struct sound_trigger_phrase_recognition_event *event;
2453 event = (struct sound_trigger_phrase_recognition_event*)
2454 stdev_keyphrase_event_alloc(
2455 stdev->models[idx].model_handle,
2456 stdev->models[idx].config,
2457 recognition_status);
2458 if (event) {
2459 struct model_info *model;
2460 model = &stdev->models[idx];
2461
2462 ALOGD("Sending recognition callback for id %d",
2463 kwid);
2464 /* Exit the critical section of interaction with
2465 * firmware, release the lock to avoid deadlock
2466 * when processing recognition event */
2467 pthread_mutex_unlock(&stdev->lock);
2468 model->recognition_callback(&event->common,
2469 model->recognition_cookie);
2470 pthread_mutex_lock(&stdev->lock);
2471
2472 free(event);
2473 } else {
2474 ALOGE("Failed to allocate memory for the event");
2475 }
2476 } else if (stdev->models[idx].type == SOUND_MODEL_TYPE_GENERIC &&
2477 stdev->adnc_strm_handle[idx] == 0) {
2478 struct sound_trigger_generic_recognition_event *event;
2479 event = (struct sound_trigger_generic_recognition_event*)
2480 stdev_generic_event_alloc(
2481 stdev->models[idx].model_handle,
2482 payload,
2483 payload_size,
2484 recognition_status);
2485 if (event) {
2486 struct model_info *model;
2487 model = &stdev->models[idx];
2488
2489 ALOGD("Sending recognition callback for id %d",
2490 kwid);
2491 /* Exit the critical section of interaction with
2492 * firmware, release the lock to avoid deadlock
2493 * when processing recognition event */
2494 pthread_mutex_unlock(&stdev->lock);
2495 model->recognition_callback(&event->common,
2496 model->recognition_cookie);
2497 pthread_mutex_lock(&stdev->lock);
2498 free(event);
2499 } else {
2500 ALOGE("Failed to allocate memory for the event");
2501 }
2502 } else if (stdev->adnc_strm_handle[idx] != 0) {
2503 ALOGD("model %d is streaming.", idx);
2504 }
2505 } else {
2506 ALOGE("Invalid id or keyword is not active, Subsume the event");
2507 }
2508 // Reset all event related data
2509 ge.event_id = -1;
2510 ge.data = 0;
2511 kwid = -1;
2512 }
2513 // Free the payload data
2514 if (payload) {
2515 free(payload);
2516 payload = NULL;
2517 payload_size = 0;
2518 }
2519 } else if (fds[1].revents & POLLIN) {
2520 read(fds[1].fd, &n, sizeof(n)); /* clear the socket */
2521 ALOGD("%s: Termination message", __func__);
2522 break;
2523 }
2524 else {
2525 ALOGI("%s: Message ignored", __func__);
2526 }
2527 pthread_mutex_unlock(&stdev->lock);
2528 }
2529
2530 exit:
2531 stdev_close_term_sock(stdev);
2532 pthread_mutex_unlock(&stdev->lock);
2533
2534 return (void *)(long)err;
2535 }
2536
stdev_get_properties(const struct sound_trigger_hw_device * dev __unused,struct sound_trigger_properties * properties)2537 static int stdev_get_properties(
2538 const struct sound_trigger_hw_device *dev __unused,
2539 struct sound_trigger_properties *properties)
2540 {
2541 ALOGV("+%s+", __func__);
2542 if (properties == NULL)
2543 return -EINVAL;
2544 memcpy(properties, &hw_properties.base, sizeof(struct sound_trigger_properties));
2545 ALOGV("-%s-", __func__);
2546 return 0;
2547 }
2548
2549 /* Insert a decimal numeral for Prefix into the beginning of String.
2550 Length specifies the total number of bytes available at str.
2551 */
int_prefix_str(char * str,size_t str_len,int prefix,const char * prefix_format)2552 static int int_prefix_str(char *str, size_t str_len, int prefix, const char *prefix_format)
2553 {
2554 int prefix_len = snprintf(NULL, 0, prefix_format, prefix);
2555 size_t str_cur_len = strlen(str);
2556
2557 if (str_len < prefix_len + str_cur_len + 1)
2558 {
2559 ALOGE("%s: Error, not enough space in string to insert prefix: %d, %s\n",
2560 __func__, prefix, str);
2561 return -1;
2562 }
2563
2564 // Move the string to make room for the prefix.
2565 memmove(str + prefix_len, str, str_cur_len + 1);
2566
2567 /* Remember the first character, because snprintf will overwrite it with a
2568 null character.
2569 */
2570 char tmp = str[0];
2571
2572 snprintf(str, prefix_len + 1, prefix_format, prefix);
2573 str[prefix_len] = tmp;
2574 return 0;
2575 }
2576
stdev_get_properties_extended(const struct sound_trigger_hw_device * dev __unused)2577 static const struct sound_trigger_properties_header* stdev_get_properties_extended(
2578 const struct sound_trigger_hw_device *dev __unused)
2579 {
2580 struct knowles_sound_trigger_device *stdev =
2581 (struct knowles_sound_trigger_device *)dev;
2582 ALOGV("+%s+", __func__);
2583 pthread_mutex_lock(&stdev->lock);
2584 if (hw_properties.header.version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
2585 hw_properties.base.version = stdev->hotword_version;
2586
2587 /* Per GMS requirement new to Android R, the supported_model_arch field
2588 must be the Google hotword firmware version comma separated with the
2589 supported_model_arch platform identifier.
2590 */
2591 int_prefix_str(hw_properties.supported_model_arch, SOUND_TRIGGER_MAX_STRING_LEN,
2592 hw_properties.base.version, "%u,");
2593 ALOGW("SoundTrigger supported model arch identifier is %s",
2594 hw_properties.supported_model_arch);
2595 } else {
2596 ALOGE("STHAL Version is %u", hw_properties.header.version);
2597 pthread_mutex_unlock(&stdev->lock);
2598 return NULL;
2599 }
2600
2601 pthread_mutex_unlock(&stdev->lock);
2602 ALOGV("-%s-", __func__);
2603 return &hw_properties.header;
2604 }
2605
2606
stop_recognition(struct knowles_sound_trigger_device * stdev,sound_model_handle_t handle)2607 static int stop_recognition(struct knowles_sound_trigger_device *stdev,
2608 sound_model_handle_t handle)
2609 {
2610 int status = 0;
2611 struct model_info *model = &stdev->models[handle];
2612
2613 if (model->config != NULL) {
2614 dereg_hal_event_session(model->config, handle);
2615 free(model->config);
2616 model->config = NULL;
2617 }
2618
2619 model->recognition_callback = NULL;
2620 model->recognition_cookie = NULL;
2621 if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
2622 check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
2623 // This avoids any processing of chre/oslo.
2624 goto exit;
2625 }
2626 if (can_update_recover_list(stdev) == true) {
2627 update_recover_list(stdev, handle, false);
2628 model->is_active = false;
2629 goto exit;
2630 }
2631
2632 if (stdev->adnc_strm_handle[handle] != 0) {
2633 ALOGD("%s: stop tunnling for index:%d", __func__, handle);
2634 stdev->adnc_strm_close(stdev->adnc_strm_handle[handle]);
2635 stdev->adnc_strm_handle[handle] = 0;
2636 stdev->is_streaming--;
2637 stdev->adnc_strm_last_read[handle] = reset_time;
2638 }
2639
2640 model->is_active = false;
2641
2642 tear_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
2643
2644 destroy_package(stdev, model);
2645
2646
2647 if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
2648 (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
2649 if ((stdev->hotword_buffer_enable) &&
2650 !(stdev->current_enable & PLUGIN1_MASK)) {
2651 tear_hotword_buffer_route(stdev->route_hdl,
2652 stdev->is_bargein_route_enabled);
2653 }
2654 }
2655
2656 if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
2657 (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
2658 if ((stdev->music_buffer_enable) &&
2659 !(stdev->current_enable & PLUGIN2_MASK)) {
2660 tear_music_buffer_route(stdev->route_hdl,
2661 stdev->is_bargein_route_enabled);
2662 }
2663 }
2664
2665 setup_buffer(stdev, model, false);
2666
2667 handle_input_source(stdev, false);
2668
2669 check_and_destroy_buffer_package(stdev);
2670
2671 exit:
2672 return status;
2673 }
2674
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)2675 static int stdev_load_sound_model(const struct sound_trigger_hw_device *dev,
2676 struct sound_trigger_sound_model *sound_model,
2677 sound_model_callback_t callback,
2678 void *cookie,
2679 sound_model_handle_t *handle)
2680 {
2681 struct knowles_sound_trigger_device *stdev =
2682 (struct knowles_sound_trigger_device *)dev;
2683 int ret = 0;
2684 int kw_model_sz = 0;
2685 int i = 0;
2686 sound_trigger_uuid_t empty_uuid = {0};
2687 unsigned char *kw_buffer = NULL;
2688
2689 ALOGD("+%s+", __func__);
2690 pthread_mutex_lock(&stdev->lock);
2691
2692 ret = check_firmware_ready(stdev);
2693 if (ret != 0)
2694 goto exit;
2695
2696 if (handle == NULL || sound_model == NULL) {
2697 ALOGE("%s: handle/sound_model is NULL", __func__);
2698 ret = -EINVAL;
2699 goto exit;
2700 }
2701
2702 if (sound_model->data_size == 0 ||
2703 sound_model->data_offset < sizeof(struct sound_trigger_sound_model)) {
2704 ALOGE("%s: Invalid sound model data", __func__);
2705 ret = -EINVAL;
2706 goto exit;
2707 }
2708
2709 if (check_uuid_equality(sound_model->vendor_uuid, empty_uuid)) {
2710 ALOGE("%s Invalid vendor uuid", __func__);
2711 ret = -EINVAL;
2712 goto exit;
2713 }
2714
2715 // When a delayed CHRE/Oslo destroy process is in progress,
2716 // we should not skip the new model and return the existing handle
2717 // which will be destroyed soon.
2718 if ((check_uuid_equality(sound_model->vendor_uuid,
2719 stdev->chre_model_uuid) &&
2720 stdev->is_chre_destroy_in_prog) ||
2721 (check_uuid_equality(sound_model->vendor_uuid,
2722 stdev->sensor_model_uuid) &&
2723 stdev->is_sensor_destroy_in_prog)) {
2724 ALOGD("%s: CHRE/Oslo destroy in progress, skipped handle check.",
2725 __func__);
2726 } else {
2727 i = find_handle_for_uuid(stdev, sound_model->vendor_uuid);
2728 if (i != -1) {
2729 ALOGW("%s: model is existed at index %d", __func__, i);
2730 *handle = i;
2731 goto exit;
2732 }
2733 }
2734
2735 // Find an empty slot to load the model
2736 i = find_empty_model_slot(stdev);
2737 if (i == -1) {
2738 ALOGE("%s: Can't load model no free slots available", __func__);
2739 ret = -ENOSYS;
2740 goto exit;
2741 }
2742
2743 kw_buffer = (unsigned char *) sound_model + sound_model->data_offset;
2744 kw_model_sz = sound_model->data_size;
2745 ALOGV("%s: kw_model_sz %d", __func__, kw_model_sz);
2746
2747 stdev->models[i].data = malloc(kw_model_sz);
2748 if (stdev->models[i].data == NULL) {
2749 stdev->models[i].data_sz = 0;
2750 ALOGE("%s: could not allocate memory for keyword model data",
2751 __func__);
2752 ret = -ENOMEM;
2753 goto exit;
2754 } else {
2755 memcpy(stdev->models[i].data, kw_buffer, kw_model_sz);
2756 stdev->models[i].data_sz = kw_model_sz;
2757 }
2758
2759 // Send the keyword model to the chip only for hotword and ambient audio
2760 if (check_uuid_equality(sound_model->vendor_uuid,
2761 stdev->hotword_model_uuid)) {
2762 stdev->models[i].kw_id = OK_GOOGLE_KW_ID;
2763 } else if (check_uuid_equality(sound_model->vendor_uuid,
2764 stdev->wakeup_model_uuid)) {
2765 stdev->models[i].kw_id = WAKEUP_KW_ID;
2766 } else if (check_uuid_equality(sound_model->vendor_uuid,
2767 stdev->ambient_model_uuid)) {
2768 stdev->models[i].kw_id = AMBIENT_KW_ID;
2769 } else if (check_uuid_equality(sound_model->vendor_uuid,
2770 stdev->entity_model_uuid)) {
2771 stdev->models[i].kw_id = ENTITY_KW_ID;
2772 } else if (check_uuid_equality(sound_model->vendor_uuid,
2773 stdev->sensor_model_uuid)) {
2774 ret = start_sensor_model(stdev);
2775 if (ret) {
2776 ALOGE("%s: ERROR: Failed to start sensor model", __func__);
2777 goto error;
2778 }
2779 stdev->models[i].kw_id = USELESS_KW_ID;
2780 } else if (check_uuid_equality(sound_model->vendor_uuid,
2781 stdev->chre_model_uuid)) {
2782 ret = start_chre_model(stdev, i);
2783 if (ret) {
2784 ALOGE("%s: ERROR: Failed to start chre model", __func__);
2785 goto error;
2786 }
2787 stdev->models[i].kw_id = USELESS_KW_ID;
2788 } else {
2789 ALOGE("%s: ERROR: unknown model uuid", __func__);
2790 ret = -EINVAL;
2791 goto error;
2792 }
2793
2794 *handle = i;
2795 ALOGV("%s: Loading model handle(%d) type(%d)", __func__,
2796 *handle, sound_model->type);
2797 // This will need to be replaced with UUID once they are fixed
2798 stdev->models[i].model_handle = *handle;
2799 stdev->models[i].type = sound_model->type;
2800 stdev->models[i].uuid = sound_model->vendor_uuid;
2801 stdev->models[i].sound_model_callback = callback;
2802 stdev->models[i].sound_model_cookie = cookie;
2803 stdev->models[i].recognition_callback = NULL;
2804 stdev->models[i].recognition_cookie = NULL;
2805
2806 stdev->models[i].is_loaded = true;
2807
2808 error:
2809 if (ret != 0) {
2810 if (stdev->models[i].data) {
2811 free(stdev->models[i].data);
2812 stdev->models[i].data = NULL;
2813 stdev->models[i].data_sz = 0;
2814 }
2815 if (!is_any_model_loaded(stdev) && stdev->is_buffer_package_loaded) {
2816 destroy_buffer_package(stdev->odsp_hdl);
2817 stdev->is_buffer_package_loaded = false;
2818 }
2819 }
2820
2821 exit:
2822 pthread_mutex_unlock(&stdev->lock);
2823 ALOGD("-%s handle %d-", __func__, *handle);
2824 return ret;
2825 }
2826
stdev_unload_sound_model(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)2827 static int stdev_unload_sound_model(const struct sound_trigger_hw_device *dev,
2828 sound_model_handle_t handle)
2829 {
2830 struct knowles_sound_trigger_device *stdev =
2831 (struct knowles_sound_trigger_device *)dev;
2832 int ret = 0;
2833 ALOGD("+%s handle %d+", __func__, handle);
2834 pthread_mutex_lock(&stdev->lock);
2835
2836 ret = check_firmware_ready(stdev);
2837 if (ret != 0)
2838 goto exit;
2839
2840 // Just confirm the model was previously loaded
2841 if (stdev->models[handle].is_loaded == false) {
2842 ALOGE("%s: Invalid model(%d) being called for unload",
2843 __func__, handle);
2844 ret = -EINVAL;
2845 goto exit;
2846 }
2847
2848 if (stdev->models[handle].is_active == true) {
2849 ret = stop_recognition(stdev, handle);
2850 if (ret)
2851 goto exit;
2852 }
2853
2854 if (check_uuid_equality(stdev->models[handle].uuid,
2855 stdev->sensor_model_uuid)) {
2856 // Inform the Host 1 that sensor route/packages are about to be
2857 // torndown and then wait for confirmation from Host 1 that it can be
2858 // torndown. Also start a timer for 5 seconds, if the Host 1 doesn't
2859 // send us the event within 5 seconds we force remove the sensor pkgs
2860 if (stdev->is_sensor_route_enabled == true) {
2861 struct itimerspec ss_timer_spec;
2862 struct sigevent ss_sigevent;
2863
2864 // Inform the host 1
2865 stdev->is_sensor_destroy_in_prog = true;
2866 trigger_sensor_destroy_event(stdev->odsp_hdl);
2867
2868 // Start timer for 5 seconds
2869 ss_sigevent.sigev_notify = SIGEV_THREAD;
2870 ss_sigevent.sigev_notify_function = sensor_timeout_recover;
2871 ss_sigevent.sigev_notify_attributes = NULL;
2872
2873 ss_timer_spec.it_interval.tv_sec = 0;
2874 ss_timer_spec.it_interval.tv_nsec = 0;
2875 ss_timer_spec.it_value.tv_sec =
2876 SENSOR_CREATE_WAIT_TIME_IN_S * SENSOR_CREATE_WAIT_MAX_COUNT;
2877 ss_timer_spec.it_value.tv_nsec = 0;
2878
2879 if (stdev->ss_timer_created) {
2880 timer_delete(stdev->ss_timer);
2881 stdev->ss_timer_created = false;
2882 }
2883
2884 if (timer_create(CLOCK_REALTIME,
2885 &ss_sigevent, &stdev->ss_timer) == -1) {
2886 ALOGE("%s: Timer Create Failed", __func__);
2887 } else {
2888 stdev->ss_timer_created = true;
2889 if (timer_settime(stdev->ss_timer,
2890 0, &ss_timer_spec, NULL) == -1) {
2891 ALOGE("%s: Timer Set Failed", __func__);
2892 }
2893 }
2894 }
2895 } else if (check_uuid_equality(stdev->models[handle].uuid,
2896 stdev->chre_model_uuid)) {
2897 // remove chre from recover list
2898 if (can_update_recover_list(stdev) == true)
2899 update_recover_list(stdev, handle, false);
2900
2901 // Disable the CHRE route
2902 if (stdev->is_chre_loaded == true) {
2903 struct itimerspec chre_timer_spec;
2904 struct sigevent chre_sigevent;
2905
2906 // Inform the host 1
2907 stdev->is_chre_destroy_in_prog = true;
2908 trigger_chre_destroy_event(stdev->odsp_hdl);
2909
2910 // Start timer for 5 seconds
2911 chre_sigevent.sigev_notify = SIGEV_THREAD;
2912 chre_sigevent.sigev_notify_function = chre_timeout_recover;
2913 chre_sigevent.sigev_notify_attributes = NULL;
2914
2915 chre_timer_spec.it_interval.tv_sec = 0;
2916 chre_timer_spec.it_interval.tv_nsec = 0;
2917 chre_timer_spec.it_value.tv_sec =
2918 CHRE_CREATE_WAIT_TIME_IN_S * CHRE_CREATE_WAIT_MAX_COUNT;
2919 chre_timer_spec.it_value.tv_nsec = 0;
2920
2921 if (stdev->chre_timer_created) {
2922 timer_delete(stdev->chre_timer);
2923 stdev->chre_timer_created = false;
2924 }
2925
2926 if (timer_create(CLOCK_REALTIME,
2927 &chre_sigevent, &stdev->chre_timer) == -1) {
2928 ALOGE("%s: Timer Create Failed", __func__);
2929 } else {
2930 stdev->chre_timer_created = true;
2931 if (timer_settime(stdev->chre_timer,
2932 0, &chre_timer_spec, NULL) == -1) {
2933 ALOGE("%s: Timer Set Failed", __func__);
2934 }
2935 }
2936 }
2937 }
2938
2939 stdev->models[handle].sound_model_callback = NULL;
2940 stdev->models[handle].sound_model_cookie = NULL;
2941
2942 if (!(check_uuid_equality(stdev->models[handle].uuid,
2943 stdev->sensor_model_uuid) &&
2944 stdev->is_sensor_destroy_in_prog) &&
2945 !(check_uuid_equality(stdev->models[handle].uuid,
2946 stdev->chre_model_uuid) &&
2947 stdev->is_chre_destroy_in_prog)) {
2948 memset(&stdev->models[handle].uuid, 0, sizeof(sound_trigger_uuid_t));
2949 stdev->models[handle].is_loaded = false;
2950 }
2951
2952 if (stdev->models[handle].data) {
2953 free(stdev->models[handle].data);
2954 stdev->models[handle].data = NULL;
2955 stdev->models[handle].data_sz = 0;
2956 }
2957
2958 ALOGD("%s: Successfully unloaded the model, handle - %d",
2959 __func__, handle);
2960 exit:
2961 pthread_mutex_unlock(&stdev->lock);
2962 ALOGD("-%s handle %d-", __func__, handle);
2963 return ret;
2964 }
2965
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)2966 static int stdev_start_recognition(
2967 const struct sound_trigger_hw_device *dev,
2968 sound_model_handle_t handle,
2969 const struct sound_trigger_recognition_config *config,
2970 recognition_callback_t callback,
2971 void *cookie)
2972 {
2973 struct knowles_sound_trigger_device *stdev =
2974 (struct knowles_sound_trigger_device *)dev;
2975 int status = 0;
2976 struct model_info *model = &stdev->models[handle];
2977
2978 ALOGD("%s stdev %p, sound model %d", __func__, stdev, handle);
2979 pthread_mutex_lock(&stdev->lock);
2980
2981 status = check_firmware_ready(stdev);
2982 if (status != 0)
2983 goto exit;
2984
2985 if (callback == NULL) {
2986 ALOGE("%s: recognition_callback is null", __func__);
2987 status = -EINVAL;
2988 goto exit;
2989 }
2990
2991 if (model->config != NULL) {
2992 dereg_hal_event_session(model->config, handle);
2993 free(model->config);
2994 model->config = NULL;
2995 }
2996
2997 if (config != NULL) {
2998 model->config = (struct sound_trigger_recognition_config *)
2999 malloc(sizeof(*config));
3000 if (model->config == NULL) {
3001 ALOGE("%s: Failed to allocate memory for model config", __func__);
3002 status = -ENOMEM;
3003 goto exit;
3004 }
3005
3006 memcpy(model->config, config, sizeof(*config));
3007 reg_hal_event_session(model->config, handle);
3008
3009 ALOGD("%s: Is capture requested %d",
3010 __func__, config->capture_requested);
3011 } else {
3012 ALOGD("%s: config is null", __func__);
3013 model->config = NULL;
3014 }
3015
3016 model->recognition_callback = callback;
3017 model->recognition_cookie = cookie;
3018 if (check_uuid_equality(model->uuid, stdev->chre_model_uuid) ||
3019 check_uuid_equality(model->uuid, stdev->sensor_model_uuid)) {
3020 // This avoids any processing of chre/oslo.
3021 goto exit;
3022 }
3023 if (model->is_active == true) {
3024 // This model is already active, do nothing except updating callbacks,
3025 // configs and cookie
3026 goto exit;
3027 }
3028 if (can_update_recover_list(stdev) == true) {
3029 // Device is in voice/VoIP call, add model to recover list first
3030 // recover model once voice/VoIP is ended.
3031 update_recover_list(stdev, handle, true);
3032 goto exit;
3033 }
3034
3035 status = check_and_setup_buffer_package(stdev);
3036 if (status != 0) {
3037 ALOGE("%s: ERROR: Failed to load the buffer package", __func__);
3038 }
3039
3040 model->is_active = true;
3041
3042 handle_input_source(stdev, true);
3043
3044 if (stdev->is_buffer_package_loaded == true) {
3045 setup_buffer(stdev, model, true);
3046 }
3047
3048 if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid) ||
3049 (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))) {
3050 if ((stdev->hotword_buffer_enable) &&
3051 (!(stdev->current_enable & HOTWORD_MASK) ||
3052 (stdev->current_enable & WAKEUP_MASK))) {
3053 set_hotword_buffer_route(stdev->route_hdl,
3054 stdev->is_bargein_route_enabled);
3055 }
3056 }
3057
3058 if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid) ||
3059 (check_uuid_equality(model->uuid, stdev->entity_model_uuid))) {
3060 if ((stdev->music_buffer_enable) &&
3061 (!(stdev->current_enable & AMBIENT_MASK) ||
3062 (stdev->current_enable & ENTITY_MASK))) {
3063 set_music_buffer_route(stdev->route_hdl,
3064 stdev->is_bargein_route_enabled);
3065 }
3066 }
3067
3068 setup_package(stdev, model);
3069
3070 set_package_route(stdev, model->uuid, stdev->is_bargein_route_enabled);
3071
3072 exit:
3073 pthread_mutex_unlock(&stdev->lock);
3074 ALOGD("-%s sound model %d-", __func__, handle);
3075 return status;
3076 }
3077
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)3078 static int stdev_start_recognition_extended(
3079 const struct sound_trigger_hw_device *dev,
3080 sound_model_handle_t sound_model_handle,
3081 const struct sound_trigger_recognition_config_header *header,
3082 recognition_callback_t callback,
3083 void *cookie)
3084 {
3085 struct sound_trigger_recognition_config_extended_1_3 *config_1_3 =
3086 (struct sound_trigger_recognition_config_extended_1_3 *)header;
3087 int status = 0;
3088
3089 if (header->version >= SOUND_TRIGGER_DEVICE_API_VERSION_1_3) {
3090 /* Use old version before we have real usecase */
3091 ALOGD("%s: Running 2_3", __func__);
3092 status = stdev_start_recognition(dev, sound_model_handle,
3093 &config_1_3->base,
3094 callback,
3095 cookie);
3096 } else {
3097 /* Rollback into old start recognition */
3098 ALOGD("%s: Running 2_1", __func__);
3099 status = stdev_start_recognition(dev, sound_model_handle,
3100 &config_1_3->base,
3101 callback,
3102 cookie);
3103 }
3104
3105 return status;
3106 }
3107
3108
stdev_stop_recognition(const struct sound_trigger_hw_device * dev,sound_model_handle_t handle)3109 static int stdev_stop_recognition(
3110 const struct sound_trigger_hw_device *dev,
3111 sound_model_handle_t handle)
3112 {
3113 struct knowles_sound_trigger_device *stdev =
3114 (struct knowles_sound_trigger_device *)dev;
3115 int status = 0;
3116 ALOGD("+%s sound model %d+", __func__, handle);
3117 pthread_mutex_lock(&stdev->lock);
3118
3119 status = check_firmware_ready(stdev);
3120 if (status != 0)
3121 goto exit;
3122
3123 status = stop_recognition(stdev, handle);
3124
3125 if (status != 0)
3126 goto exit;
3127
3128 ALOGD("-%s sound model %d-", __func__, handle);
3129 exit:
3130 pthread_mutex_unlock(&stdev->lock);
3131
3132 return status;
3133 }
3134
3135 /**
3136 * Get the state of a given model.
3137 * The model state is returned asynchronously as a RecognitionEvent via
3138 * the callback that was registered in StartRecognition().
3139 * @param modelHandle The handle of the sound model whose state is being
3140 * queried.
3141 * @return retval Operation completion status: 0 in case of success,
3142 * -ENOSYS in case of invalid model handle,
3143 * -ENOMEM in case of memory allocation failure,
3144 * -ENODEV in case of initialization error,
3145 * -EINVAL in case where a recognition event is already
3146 * being processed.
3147 */
stdev_get_model_state(const struct sound_trigger_hw_device * dev,sound_model_handle_t sound_model_handle)3148 static int stdev_get_model_state(const struct sound_trigger_hw_device *dev,
3149 sound_model_handle_t sound_model_handle) {
3150 struct knowles_sound_trigger_device *stdev =
3151 (struct knowles_sound_trigger_device *)dev;
3152 struct model_info *model = &stdev->models[sound_model_handle];
3153 int ret = 0;
3154 ALOGD("+%s+", __func__);
3155 pthread_mutex_lock(&stdev->lock);
3156
3157 ret = check_firmware_ready(stdev);
3158 if (ret != 0)
3159 goto exit;
3160
3161 if (!stdev->opened) {
3162 ALOGE("%s: stdev isn't initialized", __func__);
3163 ret = -ENODEV;
3164 goto exit;
3165 }
3166
3167 if (model->is_active == false &&
3168 !is_uuid_in_recover_list(stdev, sound_model_handle)) {
3169 ALOGE("%s: ERROR: %d model is not active",
3170 __func__, sound_model_handle);
3171 ret = -ENOSYS;
3172 goto exit;
3173 } else if (is_uuid_in_recover_list(stdev, sound_model_handle)) {
3174 ALOGD("%s: Ignore %d model request due to call active",
3175 __func__, sound_model_handle);
3176 goto exit;
3177 }
3178
3179 if (model->is_state_query == true) {
3180 ALOGE("%s: ERROR: model %d is already processing",
3181 __func__, sound_model_handle);
3182 ret = -EINVAL;
3183 goto exit;
3184 }
3185
3186 model->is_state_query = true;
3187
3188 if (check_uuid_equality(model->uuid, stdev->hotword_model_uuid))
3189 ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3190 HOTWORD_SLOT_ID);
3191 else if (check_uuid_equality(model->uuid, stdev->wakeup_model_uuid))
3192 ret = get_model_state(stdev->odsp_hdl, HOTWORD_INSTANCE_ID,
3193 WAKEUP_SLOT_ID);
3194 else if (check_uuid_equality(model->uuid, stdev->ambient_model_uuid))
3195 ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3196 AMBIENT_SLOT_ID);
3197 else if (check_uuid_equality(model->uuid, stdev->entity_model_uuid)) {
3198 ret = get_model_state(stdev->odsp_hdl, AMBIENT_INSTANCE_ID,
3199 ENTITY_SLOT_ID);
3200 } else {
3201 ALOGE("%s: ERROR: %d model is not supported",
3202 __func__, sound_model_handle);
3203 ret = -ENOSYS;
3204 }
3205
3206 if (ret != 0) {
3207 model->is_state_query = false;
3208 ALOGE("%s: ERROR: Failed to get the model state", __func__);
3209 }
3210
3211 exit:
3212 pthread_mutex_unlock(&stdev->lock);
3213 ALOGD("-%s-", __func__);
3214 return ret;
3215 }
3216
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)3217 static int stdev_query_parameter(
3218 const struct sound_trigger_hw_device *dev __unused,
3219 sound_model_handle_t sound_model_handle __unused,
3220 sound_trigger_model_parameter_t model_param __unused,
3221 sound_trigger_model_parameter_range_t* param_range)
3222 {
3223 ALOGW("%s: NOT SUPPORTED", __func__);
3224 param_range->is_supported = false;
3225 return 0;
3226 }
3227
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)3228 static int stdev_set_parameter(
3229 const struct sound_trigger_hw_device *dev __unused,
3230 sound_model_handle_t sound_model_handle __unused,
3231 sound_trigger_model_parameter_t model_param __unused,
3232 int32_t value __unused)
3233 {
3234 ALOGW("%s: NOT SUPPORTED", __func__);
3235 return -EINVAL;
3236 }
3237
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)3238 static int stdev_get_parameter(
3239 const struct sound_trigger_hw_device *dev __unused,
3240 sound_model_handle_t sound_model_handle __unused,
3241 sound_trigger_model_parameter_t model_param __unused,
3242 int32_t* value __unused)
3243 {
3244 ALOGW("%s: NOT SUPPORTED", __func__);
3245 return -EINVAL;
3246 }
3247
3248
stdev_close(hw_device_t * device)3249 static int stdev_close(hw_device_t *device)
3250 {
3251 struct knowles_sound_trigger_device *stdev =
3252 (struct knowles_sound_trigger_device *)device;
3253 int ret = 0;
3254 ALOGD("+%s+", __func__);
3255 pthread_mutex_lock(&stdev->lock);
3256
3257 ret = check_firmware_ready(stdev);
3258 if (ret != 0)
3259 goto exit;
3260
3261 if (!stdev->opened) {
3262 ALOGE("%s: device already closed", __func__);
3263 ret = -EFAULT;
3264 goto exit;
3265 }
3266
3267 setup_slpi_wakeup_event(stdev->odsp_hdl, false);
3268
3269 stdev->opened = false;
3270
3271 if (stdev->send_sock >= 0)
3272 write(stdev->send_sock, "T", 1);
3273 pthread_join(stdev->callback_thread, (void **)NULL);
3274
3275 if (stdev->route_hdl)
3276 audio_route_free(stdev->route_hdl);
3277 if (stdev->odsp_hdl)
3278 iaxxx_odsp_deinit(stdev->odsp_hdl);
3279
3280 if (stdev->ss_timer_created) {
3281 timer_delete(stdev->ss_timer);
3282 stdev->ss_timer_created = false;
3283 }
3284
3285 exit:
3286 pthread_mutex_unlock(&stdev->lock);
3287 ALOGD("-%s-", __func__);
3288 return ret;
3289 }
3290
open_streaming_lib(struct knowles_sound_trigger_device * stdev)3291 static int open_streaming_lib(struct knowles_sound_trigger_device *stdev) {
3292 int ret = 0;
3293
3294 if (access(ADNC_STRM_LIBRARY_PATH, R_OK) == 0) {
3295 stdev->adnc_cvq_strm_lib = dlopen(ADNC_STRM_LIBRARY_PATH, RTLD_NOW);
3296 if (stdev->adnc_cvq_strm_lib == NULL) {
3297 char const *err_str = dlerror();
3298 ALOGE("%s: module = %s error = %s", __func__,
3299 ADNC_STRM_LIBRARY_PATH, err_str ? err_str : "unknown");
3300 ALOGE("%s: DLOPEN failed for %s", __func__, ADNC_STRM_LIBRARY_PATH);
3301 } else {
3302 ALOGV("%s: DLOPEN successful for %s",
3303 __func__, ADNC_STRM_LIBRARY_PATH);
3304 for (int index = 0; index < MAX_MODELS; index++) {
3305 stdev->adnc_strm_handle[index] = 0;
3306 stdev->adnc_strm_last_read[index] = reset_time;
3307 }
3308 stdev->adnc_strm_open =
3309 (int (*)(bool, int, int))dlsym(stdev->adnc_cvq_strm_lib,
3310 "adnc_strm_open");
3311 stdev->adnc_strm_read =
3312 (size_t (*)(long, void *, size_t))dlsym(stdev->adnc_cvq_strm_lib,
3313 "adnc_strm_read");
3314 stdev->adnc_strm_close =
3315 (int (*)(long))dlsym(stdev->adnc_cvq_strm_lib,
3316 "adnc_strm_close");
3317 if (!stdev->adnc_strm_open || !stdev->adnc_strm_read ||
3318 !stdev->adnc_strm_close) {
3319 ALOGE("%s: Error grabbing functions in %s", __func__,
3320 ADNC_STRM_LIBRARY_PATH);
3321 stdev->adnc_strm_open = 0;
3322 stdev->adnc_strm_read = 0;
3323 stdev->adnc_strm_close = 0;
3324 }
3325 }
3326 }
3327
3328 return ret;
3329 }
3330
find_stdev_mixer_path(int card_num,char * mixer_path_xml)3331 static struct mixer* find_stdev_mixer_path(int card_num, char *mixer_path_xml)
3332 {
3333 struct mixer *mixer = NULL;
3334 const char *in_snd_card_name;
3335 char *snd_card_name = NULL;
3336 char *tmp = NULL;
3337 char *platform = NULL;
3338 char *snd_card = NULL;
3339 char *device = NULL;
3340
3341 mixer = mixer_open(card_num);
3342
3343 if (!mixer) {
3344 ALOGE("%s: Unable to open the mixer: %d", __func__,
3345 card_num);
3346 return NULL;
3347 }
3348
3349 in_snd_card_name = mixer_get_name(mixer);
3350 snd_card_name = strdup(in_snd_card_name);
3351
3352 if (snd_card_name == NULL) {
3353 ALOGE("%s: snd_card_name is NULL", __func__);
3354 goto on_error;
3355 }
3356
3357 platform = strtok_r(snd_card_name, "-", &tmp);
3358 if (platform == NULL) {
3359 ALOGE("%s: snd card is invalid", __func__);
3360 goto on_error;
3361 }
3362
3363 snd_card = strtok_r(NULL, "-", &tmp);
3364 if (snd_card == NULL) {
3365 ALOGE("%s: snd card is invalid", __func__);
3366 goto on_error;
3367 }
3368
3369 device = strtok_r(NULL, "-", &tmp);
3370 if (device != NULL) {
3371 snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s_%s.xml",
3372 SOUND_TRIGGER_MIXER_PATH_BASE, device);
3373 } else {
3374 ALOGE("%s: Unknown device, try to use default xml", __func__);
3375 snprintf(mixer_path_xml, NAME_MAX_SIZE, "%s",
3376 SOUND_TRIGGER_MIXER_PATH_XML);
3377 }
3378
3379 ALOGD("%s: using %s", __func__, mixer_path_xml);
3380
3381 on_error:
3382 if (snd_card_name)
3383 free(snd_card_name);
3384 return mixer;
3385 }
3386
find_sound_card()3387 static int find_sound_card() {
3388 int retry_num = 0, snd_card_num = 0, ret = -1;
3389 const char *snd_card_name;
3390 struct mixer *mixer = NULL;
3391 bool card_verifed[MAX_SND_CARD] = {false};
3392 const int retry_limit = property_get_int32("vendor.audio.snd_card.open.retries",
3393 RETRY_NUMBER);
3394 ALOGD("+%s+", __func__);
3395
3396 for (;;) {
3397 if (snd_card_num >= MAX_SND_CARD) {
3398 if (retry_num++ >= retry_limit) {
3399 ALOGE("%s: iaxxx sound card not found", __func__);
3400 goto exit;
3401 }
3402 snd_card_num = 0;
3403 usleep(RETRY_US);
3404 continue;
3405 }
3406 if (card_verifed[snd_card_num]) {
3407 snd_card_num++;
3408 continue;
3409 }
3410
3411 mixer = mixer_open(snd_card_num);
3412 if (!mixer) {
3413 snd_card_num++;
3414 continue;
3415 }
3416
3417 snd_card_name = mixer_get_name(mixer);
3418 if (strstr(snd_card_name, CARD_NAME)) {
3419 ALOGD("%s: find card %d has iaxxx - %s",
3420 __func__, snd_card_num, snd_card_name);
3421 ret = snd_card_num;
3422 break;
3423 }
3424
3425 ALOGD("%s: sound card %s does NOT have iaxxx", __func__, snd_card_name);
3426 mixer_close(mixer);
3427 mixer = NULL;
3428 card_verifed[snd_card_num] = true;
3429 snd_card_num++;
3430 }
3431
3432 exit:
3433 if (mixer)
3434 mixer_close(mixer);
3435
3436 ALOGD("-%s-", __func__);
3437 return ret;
3438 }
3439
load_audio_hal()3440 static int load_audio_hal()
3441 {
3442 char audio_hal_lib[100];
3443 void *sthal_prop_api_version = NULL;
3444 struct knowles_sound_trigger_device *stdev = &g_stdev;
3445 int ret = 0;
3446
3447 snprintf(audio_hal_lib, sizeof(audio_hal_lib), "%s/%s.%s.so",
3448 AUDIO_HAL_LIBRARY_PATH, AUDIO_HAL_NAME_PREFIX,
3449 SOUND_TRIGGER_PLATFORM);
3450 if (access(audio_hal_lib, R_OK)) {
3451 ALOGE("%s: ERROR. %s not found", __func__, audio_hal_lib);
3452 return -ENOENT;
3453 }
3454
3455 stdev->audio_hal_handle = dlopen(audio_hal_lib, RTLD_NOW);
3456 if (stdev->audio_hal_handle == NULL) {
3457 ALOGE("%s: ERROR. %s", __func__, dlerror());
3458 return -ENODEV;
3459 }
3460
3461 stdev->audio_hal_cb = dlsym(stdev->audio_hal_handle, "audio_hw_call_back");
3462 if (stdev->audio_hal_cb == NULL) {
3463 ALOGE("%s: ERROR. %s", __func__, dlerror());
3464 ret = -ENODEV;
3465 goto error;
3466 }
3467
3468 sthal_prop_api_version = dlsym(stdev->audio_hal_handle,
3469 "sthal_prop_api_version");
3470 if (sthal_prop_api_version == NULL) {
3471 stdev->sthal_prop_api_version = 0;
3472 ret = 0; /* passthru for backward compability */
3473 } else {
3474 stdev->sthal_prop_api_version = *(int *)sthal_prop_api_version;
3475 if (MAJOR_VERSION(stdev->sthal_prop_api_version) !=
3476 MAJOR_VERSION(STHAL_PROP_API_CURRENT_VERSION)) {
3477 ALOGE("%s: Incompatible API versions sthal:0x%x != ahal:0x%x",
3478 __func__, STHAL_PROP_API_CURRENT_VERSION,
3479 stdev->sthal_prop_api_version);
3480 goto error;
3481 }
3482 ALOGD("%s: ahal is using proprietary API version 0x%04x", __func__,
3483 stdev->sthal_prop_api_version);
3484 }
3485
3486 ALOGD("%s: load AHAL successfully.", __func__);
3487 return ret;
3488
3489 error:
3490 dlclose(stdev->audio_hal_handle);
3491 stdev->audio_hal_handle = NULL;
3492 return ret;
3493 }
3494
stdev_open(const hw_module_t * module,const char * name,hw_device_t ** device)3495 static int stdev_open(const hw_module_t *module, const char *name,
3496 hw_device_t **device)
3497 {
3498 struct knowles_sound_trigger_device *stdev;
3499 int ret = 0, i = 0;
3500 int snd_card_num = 0;
3501
3502 ALOGE("!! Knowles SoundTrigger v1!!");
3503
3504 if (strcmp(name, SOUND_TRIGGER_HARDWARE_INTERFACE) != 0)
3505 return -EINVAL;
3506
3507 if (device == NULL)
3508 return -EINVAL;
3509
3510 stdev = &g_stdev;
3511 pthread_mutex_lock(&stdev->lock);
3512
3513 snd_card_num = find_sound_card();
3514 if (snd_card_num == -1) {
3515 ALOGE("%s: Unable to find the sound card %s", __func__, CARD_NAME);
3516 ret = -EAGAIN;
3517 goto exit;
3518 }
3519
3520 if (stdev->opened) {
3521 ALOGE("%s: Only one sountrigger can be opened at a time", __func__);
3522 ret = -EBUSY;
3523 goto exit;
3524 }
3525
3526 ret = open_streaming_lib(stdev);
3527 if (ret != 0) {
3528 ALOGE("%s: Couldnot open the streaming library", __func__);
3529 goto error;
3530 }
3531
3532 ret = load_audio_hal();
3533 if (ret != 0) {
3534 ALOGE("%s: Couldn't load AHAL", __func__);
3535 goto error;
3536 }
3537
3538 stdev->device.common.tag = HARDWARE_DEVICE_TAG;
3539 stdev->device.common.version = SOUND_TRIGGER_DEVICE_API_VERSION_1_3;
3540 stdev->device.common.module = (struct hw_module_t *)module;
3541 stdev->device.common.close = stdev_close;
3542 stdev->device.get_properties = stdev_get_properties;
3543 stdev->device.load_sound_model = stdev_load_sound_model;
3544 stdev->device.unload_sound_model = stdev_unload_sound_model;
3545 stdev->device.start_recognition = stdev_start_recognition;
3546 stdev->device.start_recognition_extended = stdev_start_recognition_extended;
3547 stdev->device.stop_recognition = stdev_stop_recognition;
3548 stdev->device.get_model_state = stdev_get_model_state;
3549 stdev->device.query_parameter = stdev_query_parameter;
3550 stdev->device.set_parameter = stdev_set_parameter;
3551 stdev->device.get_parameter = stdev_get_parameter;
3552 stdev->device.get_properties_extended = stdev_get_properties_extended;
3553
3554 stdev->opened = true;
3555 /* Initialize all member variable */
3556 for (i = 0; i < MAX_MODELS; i++) {
3557 stdev->models[i].type = SOUND_MODEL_TYPE_UNKNOWN;
3558 memset(&stdev->models[i].uuid, 0, sizeof(sound_trigger_uuid_t));
3559 stdev->models[i].config = NULL;
3560 stdev->models[i].data = NULL;
3561 stdev->models[i].data_sz = 0;
3562 stdev->models[i].is_loaded = false;
3563 stdev->models[i].is_active = false;
3564 stdev->models[i].is_state_query = false;
3565 }
3566
3567 stdev->is_mic_route_enabled = false;
3568 stdev->is_con_mic_route_enabled = false;
3569 stdev->is_ahal_in_voice_voip_mode = false;
3570 stdev->is_ahal_voice_voip_stop = false;
3571 stdev->is_ahal_voice_voip_start = false;
3572 stdev->is_bargein_route_enabled = false;
3573 stdev->is_chre_loaded = false;
3574 stdev->is_buffer_package_loaded = false;
3575 stdev->hotword_buffer_enable = 0;
3576 stdev->music_buffer_enable = 0;
3577 stdev->current_enable = 0;
3578 stdev->is_sensor_route_enabled = false;
3579 stdev->recover_model_list = 0;
3580 stdev->rx_active_count = 0;
3581 stdev->is_ahal_media_recording = false;
3582 stdev->is_concurrent_capture = hw_properties.base.concurrent_capture;
3583
3584 stdev->is_sensor_destroy_in_prog = false;
3585 stdev->ss_timer_created = false;
3586
3587 stdev->is_chre_destroy_in_prog = false;
3588 stdev->chre_timer_created = false;
3589
3590 stdev->snd_crd_num = snd_card_num;
3591 stdev->fw_reset_done_by_hal = false;
3592 stdev->hotword_version = 0;
3593
3594 str_to_uuid(HOTWORD_AUDIO_MODEL, &stdev->hotword_model_uuid);
3595 str_to_uuid(WAKEUP_MODEL, &stdev->wakeup_model_uuid);
3596 str_to_uuid(SENSOR_MANAGER_MODEL, &stdev->sensor_model_uuid);
3597 str_to_uuid(AMBIENT_AUDIO_MODEL, &stdev->ambient_model_uuid);
3598 str_to_uuid(CHRE_AUDIO_MODEL, &stdev->chre_model_uuid);
3599 str_to_uuid(ENTITY_AUDIO_MODEL, &stdev->entity_model_uuid);
3600
3601 stdev->odsp_hdl = iaxxx_odsp_init();
3602 if (stdev->odsp_hdl == NULL) {
3603 ALOGE("%s: Failed to get handle to ODSP HAL", __func__);
3604 ret = -EIO;
3605 goto error;
3606 }
3607 stdev->mixer = find_stdev_mixer_path(stdev->snd_crd_num, stdev->mixer_path_xml);
3608 if (stdev->mixer == NULL) {
3609 ALOGE("Failed to init the mixer");
3610 ret = -EAGAIN;
3611 goto error;
3612 }
3613
3614 ALOGD("stdev before pthread_create %p", stdev);
3615 // Create a thread to handle all events from kernel
3616 pthread_create(&stdev->callback_thread, (const pthread_attr_t *) NULL,
3617 callback_thread_loop, stdev);
3618
3619 pthread_create(&stdev->monitor_thread, (const pthread_attr_t *) NULL,
3620 monitor_thread_loop, stdev);
3621
3622 pthread_create(&stdev->transitions_thread, (const pthread_attr_t *) NULL,
3623 transitions_thread_loop, stdev);
3624
3625 *device = &stdev->device.common; /* same address as stdev */
3626 exit:
3627 pthread_mutex_unlock(&stdev->lock);
3628 return ret;
3629
3630 error:
3631 if (stdev->adnc_cvq_strm_lib)
3632 dlclose(stdev->adnc_cvq_strm_lib);
3633 if (stdev->audio_hal_handle)
3634 dlclose(stdev->audio_hal_handle);
3635 if (stdev->route_hdl)
3636 audio_route_free(stdev->route_hdl);
3637 if (stdev->odsp_hdl)
3638 iaxxx_odsp_deinit(stdev->odsp_hdl);
3639 if (stdev->mixer)
3640 mixer_close(stdev->mixer);
3641
3642 pthread_mutex_unlock(&stdev->lock);
3643 return ret;
3644 }
3645
3646 /* AHAL calls this callback to communicate with STHAL */
sound_trigger_hw_call_back(audio_event_type_t event,struct audio_event_info * config)3647 int sound_trigger_hw_call_back(audio_event_type_t event,
3648 struct audio_event_info *config)
3649 {
3650 int ret = 0;
3651 int i = 0;
3652 int index = -1;
3653 struct knowles_sound_trigger_device *stdev = &g_stdev;
3654 enum sthal_mode pre_mode, cur_mode;
3655
3656 if (!stdev)
3657 return -ENODEV;
3658
3659 if (!stdev->opened) {
3660 ALOGE("%s: Error SoundTrigger has not been opened", __func__);
3661 return -EINVAL;
3662 }
3663
3664 pthread_mutex_lock(&stdev->lock);
3665
3666 // update conditions for mic concurrency whatever firmware status may be.
3667 if (event == AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE ||
3668 event == AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE ||
3669 event == AUDIO_EVENT_CAPTURE_STREAM_INACTIVE ||
3670 event == AUDIO_EVENT_CAPTURE_STREAM_ACTIVE) {
3671 pre_mode = get_sthal_mode(stdev);
3672 update_sthal_conditions(stdev, event, config);
3673 cur_mode = get_sthal_mode(stdev);
3674 }
3675
3676 // update conditions for bargein whatever firmware status may be.
3677 if (event == AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE ||
3678 event == AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE) {
3679 update_rx_conditions(stdev, event, config);
3680 }
3681
3682 if (stdev->is_st_hal_ready == false) {
3683 ALOGE("%s: ST HAL is not ready yet", __func__);
3684 ret = -EINVAL;
3685 goto exit;
3686 }
3687
3688 switch (event) {
3689 case AUDIO_EVENT_CAPTURE_DEVICE_INACTIVE:
3690 case AUDIO_EVENT_CAPTURE_DEVICE_ACTIVE:
3691 ALOGD("%s: handle capture device event %d", __func__, event);
3692
3693 //handle capture device on/off event
3694 do_handle_functions(stdev, pre_mode, cur_mode, event);
3695
3696 break;
3697 case AUDIO_EVENT_CAPTURE_STREAM_INACTIVE:
3698 case AUDIO_EVENT_CAPTURE_STREAM_ACTIVE:
3699 ALOGD("%s: handle capture stream event %d, usecase %d",
3700 __func__, event, config->u.usecase.type);
3701
3702 break;
3703 case AUDIO_EVENT_PLAYBACK_STREAM_INACTIVE:
3704 ALOGD("%s: handle playback stream inactive", __func__);
3705
3706 if (stdev->rx_active_count == 0) {
3707 if (stdev->is_mic_route_enabled != false) {
3708 // Atleast one keyword model is active so update the routes
3709 // Check if the bargein route is enabled if not enable bargein route
3710 // Check each model, if it is active then update it's route
3711 if (stdev->is_bargein_route_enabled != false) {
3712 ALOGD("Bargein disabling");
3713 stdev->is_bargein_route_enabled = false;
3714 // Check each model, if it is active then update it's route
3715 // Disable the bargein route
3716 for (i = 0; i < MAX_MODELS; i++) {
3717 if (stdev->models[i].is_active == true) {
3718 // teardown the package route with bargein
3719 ret = tear_package_route(stdev,
3720 stdev->models[i].uuid,
3721 !stdev->is_bargein_route_enabled);
3722 if (ret != 0) {
3723 ALOGE("Failed to tear old package route");
3724 }
3725 // resetup the package route with out bargein
3726 ret = set_package_route(stdev,
3727 stdev->models[i].uuid,
3728 stdev->is_bargein_route_enabled);
3729 if (ret != 0) {
3730 ALOGE("Failed to enable package route");
3731 }
3732 }
3733 }
3734
3735 //Switch buffer input source
3736 if (stdev->hotword_buffer_enable) {
3737 ret = tear_hotword_buffer_route(stdev->route_hdl,
3738 !stdev->is_bargein_route_enabled);
3739 if (ret != 0) {
3740 ALOGE("Failed to tear old buffer route");
3741 }
3742 ret = set_hotword_buffer_route(stdev->route_hdl,
3743 stdev->is_bargein_route_enabled);
3744 if (ret != 0) {
3745 ALOGE("Failed to enable buffer route");
3746 }
3747 }
3748
3749 if (stdev->music_buffer_enable) {
3750 ret = tear_music_buffer_route(stdev->route_hdl,
3751 !stdev->is_bargein_route_enabled);
3752 if (ret != 0) {
3753 ALOGE("Failed to tear old music buffer route");
3754 }
3755 ret = set_music_buffer_route(stdev->route_hdl,
3756 stdev->is_bargein_route_enabled);
3757 if (ret != 0) {
3758 ALOGE("Failed to enable buffer route");
3759 }
3760 }
3761
3762 ret = enable_bargein_route(stdev->route_hdl, false);
3763 if (ret != 0) {
3764 ALOGE("Failed to enable buffer route");
3765 }
3766
3767 ret = destroy_aec_package(stdev->odsp_hdl);
3768 if (ret != 0) {
3769 ALOGE("Failed to destroy AEC package");
3770 }
3771
3772 ret = enable_src_route(stdev->route_hdl, false, SRC_AMP_REF);
3773 if (ret != 0) {
3774 ALOGE("Failed to disable SRC-amp route");
3775 }
3776
3777 ret = destroy_src_plugin(stdev->odsp_hdl, SRC_AMP_REF);
3778 if (ret != 0) {
3779 ALOGE("Failed to destroy SRC-amp package");
3780 }
3781
3782 if (is_mic_controlled_by_ahal(stdev) == false) {
3783 ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_16K);
3784 if (ret != 0) {
3785 ALOGE("Failed to disable amp-ref route");
3786 }
3787 ret = enable_mic_route(stdev->route_hdl, false,
3788 EXTERNAL_OSCILLATOR);
3789 if (ret != 0) {
3790 ALOGE("Failed to disable mic route with INT OSC");
3791 }
3792 ret = enable_mic_route(stdev->route_hdl, true,
3793 INTERNAL_OSCILLATOR);
3794 if (ret != 0) {
3795 ALOGE("Failed to enable mic route with EXT OSC");
3796 }
3797 } else {
3798 // main mic is turned by media record, close it by 48khz
3799 ret = enable_amp_ref_route(stdev->route_hdl, false, STRM_48K);
3800 if (ret != 0) {
3801 ALOGE("Failed to disable amp-ref route");
3802 }
3803 }
3804 } else {
3805 ALOGW("%s: barge-in isn't enabled", __func__);
3806 }
3807 }
3808 } else {
3809 ALOGD("%s: rx stream is still active", __func__);
3810 }
3811 break;
3812 case AUDIO_EVENT_PLAYBACK_STREAM_ACTIVE:
3813 ALOGD("%s: handle playback stream active", __func__);
3814
3815 if (stdev->rx_active_count > 0) {
3816 if (stdev->is_mic_route_enabled != false) {
3817 // Atleast one keyword model is active so update the routes
3818 // Check if the bargein route is enabled if not enable bargein route
3819 // Check each model, if it is active then update it's route
3820 stdev->transit_case = TRANSIT_SETUP_AEC;
3821 pthread_cond_signal(&stdev->transition_cond);
3822 }
3823 } else {
3824 ALOGW("%s: unexpeted stream active event", __func__);
3825 }
3826 break;
3827 case AUDIO_EVENT_STOP_LAB:
3828 /* Close Stream Driver */
3829 for (i = 0; i < MAX_MODELS; i++) {
3830 if (stdev->models[i].is_active &&
3831 stdev->models[i].config &&
3832 (stdev->models[i].config->capture_handle ==
3833 config->u.ses_info.capture_handle)) {
3834 index = i;
3835 break;
3836 }
3837 }
3838
3839 /*
3840 * Close unused adnc if ...
3841 * 1. No capture handle is found
3842 * 2. Model is inactive
3843 * 3. adnc stream handle is existed
3844 */
3845 if (index == -1 && stdev->is_streaming > 0) {
3846 ALOGD("%s: close unused adnc handle, cap_handle:%d", __func__,
3847 config->u.ses_info.capture_handle);
3848 for (i = 0; i < MAX_MODELS; i++) {
3849 if (stdev->adnc_strm_handle[i] != 0 &&
3850 !stdev->models[i].is_active) {
3851 stdev->adnc_strm_close(stdev->adnc_strm_handle[i]);
3852 stdev->adnc_strm_handle[i] = 0;
3853 stdev->is_streaming--;
3854 stdev->adnc_strm_last_read[i] = reset_time;
3855 }
3856 }
3857 goto exit;
3858 }
3859
3860 ALOGD("%s: close streaming %d, cap_handle:%d, index:%d",
3861 __func__, event, config->u.ses_info.capture_handle, index);
3862 if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3863 stdev->adnc_strm_close(stdev->adnc_strm_handle[index]);
3864 stdev->adnc_strm_handle[index] = 0;
3865 stdev->is_streaming--;
3866 stdev->adnc_strm_last_read[index] = reset_time;
3867 }
3868
3869 break;
3870
3871 case AUDIO_EVENT_SSR:
3872 /*[TODO] Do we need to handle adsp SSR event ? */
3873 ALOGD("%s: handle audio subsystem restart %d", __func__, event);
3874 break;
3875
3876 case AUDIO_EVENT_READ_SAMPLES:
3877 /* It is possible to change session info, check config */
3878 if (config->u.aud_info.ses_info == NULL) {
3879 ALOGE("%s: Invalid config, event:%d", __func__, event);
3880 ret = -EINVAL;
3881 goto exit;
3882 }
3883
3884 for (i = 0; i < MAX_MODELS; i++) {
3885 if (stdev->models[i].is_active &&
3886 stdev->models[i].config &&
3887 (stdev->models[i].config->capture_handle ==
3888 config->u.aud_info.ses_info->capture_handle)) {
3889 index = i;
3890 break;
3891 }
3892 }
3893
3894 /* There is not valid model to provide pcm samples. */
3895 if (i == MAX_MODELS) {
3896 ret = -EINVAL;
3897 goto exit;
3898 }
3899
3900 /* Open Stream Driver */
3901 if (index != -1 && stdev->adnc_strm_handle[index] == 0) {
3902 if (stdev->adnc_strm_open == NULL) {
3903 ALOGE("%s: Error adnc streaming not supported", __func__);
3904 } else {
3905 bool keyword_stripping_enabled = false;
3906 int stream_end_point;
3907 if (check_uuid_equality(stdev->models[index].uuid,
3908 stdev->hotword_model_uuid)) {
3909 stream_end_point = CVQ_ENDPOINT;
3910 } else if (check_uuid_equality(stdev->models[index].uuid,
3911 stdev->ambient_model_uuid)) {
3912 stream_end_point = MUSIC_BUF_ENDPOINT;
3913 } else if (check_uuid_equality(stdev->models[index].uuid,
3914 stdev->entity_model_uuid)) {
3915 stream_end_point = MUSIC_BUF_ENDPOINT;
3916 } else {
3917 stream_end_point = CVQ_ENDPOINT;
3918 }
3919 stdev->adnc_strm_handle[index] = stdev->adnc_strm_open(
3920 keyword_stripping_enabled, 0,
3921 stream_end_point);
3922 if (stdev->adnc_strm_handle[index]) {
3923 ALOGD("Opened adnc index %d handle %d endpoint 0x%x",
3924 index, config->u.aud_info.ses_info->capture_handle,
3925 stream_end_point);
3926 stdev->is_streaming++;
3927
3928 clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3929 if (stdev->is_streaming == 1)
3930 pthread_cond_signal(&stdev->tunnel_create);
3931 } else {
3932 ALOGE("%s: DSP is currently not streaming", __func__);
3933 }
3934 }
3935 }
3936
3937 if (index != -1 && stdev->adnc_strm_handle[index] != 0) {
3938 //ALOGD("%s: soundtrigger HAL adnc_strm_read", __func__);
3939 clock_gettime(CLOCK_REALTIME, &stdev->adnc_strm_last_read[index]);
3940 pthread_mutex_unlock(&stdev->lock);
3941 stdev->adnc_strm_read(stdev->adnc_strm_handle[index],
3942 config->u.aud_info.buf,
3943 config->u.aud_info.num_bytes);
3944 pthread_mutex_lock(&stdev->lock);
3945 } else {
3946 ALOGE("%s: soundtrigger is not streaming", __func__);
3947 }
3948
3949 break;
3950
3951 case AUDIO_EVENT_NUM_ST_SESSIONS:
3952 case AUDIO_EVENT_DEVICE_CONNECT:
3953 case AUDIO_EVENT_DEVICE_DISCONNECT:
3954 case AUDIO_EVENT_SVA_EXEC_MODE:
3955 case AUDIO_EVENT_SVA_EXEC_MODE_STATUS:
3956 ALOGV("%s: useless event %d", __func__, event);
3957 break;
3958
3959 default:
3960 ALOGW("%s: Unknown event %d", __func__, event);
3961 break;
3962 }
3963
3964 exit:
3965 pthread_mutex_unlock(&stdev->lock);
3966 return ret;
3967 }
3968
3969 static struct hw_module_methods_t hal_module_methods = {
3970 .open = stdev_open,
3971 };
3972
3973 struct sound_trigger_module HAL_MODULE_INFO_SYM = {
3974 .common = {
3975 .tag = HARDWARE_MODULE_TAG,
3976 .module_api_version = SOUND_TRIGGER_MODULE_API_VERSION_1_0,
3977 .hal_api_version = HARDWARE_HAL_API_VERSION,
3978 .id = SOUND_TRIGGER_HARDWARE_MODULE_ID,
3979 .name = "Knowles Sound Trigger HAL",
3980 .author = "Knowles Electronics",
3981 .methods = &hal_module_methods,
3982 },
3983 };
3984