2626#include <rtos/alloc.h>
2727#include <rtos/clk.h>
2828#include <rtos/init.h>
29+ #include <rtos/symbol.h>
2930#include <sof/lib/pm_runtime.h>
3031#include <sof/lib/uuid.h>
3132#include <sof/list.h>
@@ -107,13 +108,19 @@ struct comp_data {
107108 struct kpb_fmt_dev_list fmt_device_list ;
108109 struct fast_mode_task fmt ;
109110
110- #if CONFIG_AMS
111+ #if CONFIG_AMS && ! CONFIG_KPB_CLI_Q
111112 uint32_t kpd_uuid_id ;
112113#endif
113114};
114115
115116/*! KPB private functions */
116- #ifndef CONFIG_AMS
117+ #if CONFIG_KPB_CLI_Q
118+ #include <zephyr/kernel.h>
119+
120+ static struct k_queue * kpb_q ;
121+ static struct k_thread kpb_thread ;
122+ K_KERNEL_STACK_DEFINE (kpb_stack , 4096 );
123+ #elif !CONFIG_AMS
117124static void kpb_event_handler (void * arg , enum notify_id type , void * event_data );
118125static int kpb_register_client (struct comp_data * kpb , struct kpb_client * cli );
119126#endif
@@ -176,7 +183,7 @@ static uint64_t kpb_task_deadline(void *data)
176183#endif
177184}
178185
179- #if CONFIG_AMS
186+ #if CONFIG_AMS && ! CONFIG_KPB_CLI_Q
180187
181188/* Key-phrase detected message*/
182189static const ams_uuid_t ams_kpd_msg_uuid = AMS_KPD_MSG_UUID ;
@@ -456,6 +463,42 @@ static void kpb_set_params(struct comp_dev *dev,
456463
457464static int kpb_params (struct comp_dev * dev , struct sof_ipc_stream_params * params );
458465
466+ #if CONFIG_KPB_CLI_Q
467+ static void kpb_thread_fn (void * p1 , void * p2 , void * p3 )
468+ {
469+ struct k_queue * q = p1 ;
470+
471+ for (;;) {
472+ struct kpb_client * cli = k_queue_get (q , K_FOREVER );
473+
474+ kpb_init_draining (cli -> dev , cli );
475+ }
476+ }
477+
478+ void kpb_notifier_schedule (struct kpb_client * cli )
479+ {
480+ k_queue_alloc_append (cli -> queue , cli );
481+ }
482+ EXPORT_SYMBOL (kpb_notifier_schedule );
483+
484+ void z_impl_kpb_notifier_init (struct comp_dev * dev , struct kpb_client * cli )
485+ {
486+ comp_dbg (dev , "adding new client to %p" , kpb_q );
487+ k_thread_access_grant (k_current_get (), kpb_q );
488+ cli -> queue = kpb_q ;
489+ cli -> dev = dev ;
490+ }
491+
492+ #include <zephyr/internal/syscall_handler.h>
493+ void z_vrfy_kpb_notifier_init (struct comp_dev * dev , struct kpb_client * cli )
494+ {
495+ K_OOPS (K_SYSCALL_MEMORY_WRITE (dev , sizeof (* dev )));
496+ K_OOPS (K_SYSCALL_MEMORY_WRITE (cli , sizeof (* cli )));
497+ z_impl_kpb_notifier_init (dev , cli );
498+ }
499+ #include <zephyr/syscalls/kpb_notifier_init_mrsh.c>
500+ #endif
501+
459502/*
460503 * \brief Create a key phrase buffer component.
461504 * \param[in] config - generic ipc component pointer.
@@ -484,7 +527,7 @@ static struct comp_dev *kpb_new(const struct comp_driver *drv,
484527 struct comp_data * kpb ;
485528 int ret ;
486529
487- comp_cl_info (& comp_kpb , "kpb_new() " );
530+ comp_cl_info (& comp_kpb , "entry " );
488531
489532 /* make sure data size is not bigger than config space */
490533 if (ipc_config_size > kpb_config_size ) {
@@ -548,6 +591,21 @@ static struct comp_dev *kpb_new(const struct comp_driver *drv,
548591 }
549592#endif
550593
594+ #if CONFIG_KPB_CLI_Q
595+ kpb_q = k_object_alloc (K_OBJ_QUEUE );
596+ if (!kpb_q ) {
597+ comp_free_device (dev );
598+ return NULL ;
599+ }
600+
601+ k_queue_init (kpb_q );
602+ k_thread_create (& kpb_thread , kpb_stack , 4096 , kpb_thread_fn , kpb_q , NULL , NULL ,
603+ 1 , 0 , K_FOREVER );
604+
605+ k_thread_cpu_pin (& kpb_thread , cpu_get_id ());
606+ k_thread_start (& kpb_thread );
607+ #endif
608+
551609 return dev ;
552610}
553611
@@ -693,7 +751,10 @@ static void kpb_free(struct comp_dev *dev)
693751
694752 comp_info (dev , "entry" );
695753
696- #if CONFIG_AMS
754+ #if CONFIG_KPB_CLI_Q
755+ k_thread_abort (& kpb_thread );
756+ k_object_free (kpb_q );
757+ #elif CONFIG_AMS
697758 /* Unregister KPB as AMS consumer */
698759 int ret ;
699760
@@ -704,7 +765,7 @@ static void kpb_free(struct comp_dev *dev)
704765#else
705766 /* Unregister KPB from notifications */
706767 notifier_unregister (dev , NULL , NOTIFIER_ID_KPB_CLIENT_EVT );
707- #endif /* CONFIG_AMS */
768+ #endif /* CONFIG_KPB_CLI_Q */
708769
709770 /* Reclaim memory occupied by history buffer */
710771 kpb_free_history_buffer (kpb -> hd .c_hb );
@@ -780,7 +841,7 @@ static int kpb_params(struct comp_dev *dev,
780841 kpb -> host_period_size = params -> host_period_bytes ;
781842 kpb -> config .sampling_width = params -> sample_container_bytes * 8 ;
782843
783- #if CONFIG_AMS
844+ #if ! CONFIG_KPB_CLI_Q && CONFIG_AMS
784845 kpb -> kpd_uuid_id = AMS_INVALID_MSG_TYPE ;
785846#endif
786847
@@ -869,16 +930,18 @@ static int kpb_prepare(struct comp_dev *dev)
869930 kpb -> clients [i ].r_ptr = NULL ;
870931 }
871932
933+ #if !CONFIG_KPB_CLI_Q
872934#if CONFIG_AMS
873935 /* AMS Register KPB for notification */
874936 ret = ams_helper_register_consumer (dev , & kpb -> kpd_uuid_id ,
875937 ams_kpd_msg_uuid ,
876938 kpb_ams_kpd_notification );
877939#else
878- /* Register KPB for notification */
940+ /* Register KPB for notification *on the current core* * /
879941 ret = notifier_register (dev , NULL , NOTIFIER_ID_KPB_CLIENT_EVT ,
880942 kpb_event_handler , 0 );
881943#endif /* CONFIG_AMS */
944+ #endif
882945
883946 if (ret < 0 ) {
884947 kpb_free_history_buffer (kpb -> hd .c_hb );
@@ -1010,7 +1073,7 @@ static int kpb_reset(struct comp_dev *dev)
10101073 kpb_reset_history_buffer (kpb -> hd .c_hb );
10111074 }
10121075
1013- #ifndef CONFIG_AMS
1076+ #if ! CONFIG_KPB_CLI_Q && ! CONFIG_AMS
10141077 /* Unregister KPB from notifications */
10151078 notifier_unregister (dev , NULL , NOTIFIER_ID_KPB_CLIENT_EVT );
10161079#endif
0 commit comments