|
27 | 27 | #include <rtos/clk.h> |
28 | 28 | #include <rtos/init.h> |
29 | 29 | #include <sof/lib/memory.h> |
30 | | -#include <sof/lib/notifier.h> |
31 | 30 | #include <sof/lib/pm_runtime.h> |
32 | 31 | #include <sof/lib/uuid.h> |
33 | 32 | #include <sof/list.h> |
|
47 | 46 | #include <stdbool.h> |
48 | 47 | #include <stddef.h> |
49 | 48 | #include <stdint.h> |
| 49 | +#include <sof/lib/notifier.h> |
50 | 50 |
|
51 | 51 | static const struct comp_driver comp_kpb; |
52 | 52 |
|
@@ -95,10 +95,17 @@ struct comp_data { |
95 | 95 | uint32_t num_of_in_channels; |
96 | 96 | uint32_t offsets[KPB_MAX_MICSEL_CHANNELS]; |
97 | 97 | struct kpb_micselector_config mic_sel; |
| 98 | + |
| 99 | +#if CONFIG_AMS |
| 100 | + uint32_t kpd_uuid_id; |
| 101 | + uint32_t reg_cli_uuid_id; |
| 102 | +#endif |
98 | 103 | }; |
99 | 104 |
|
100 | 105 | /*! KPB private functions */ |
| 106 | +#ifndef CONFIG_AMS |
101 | 107 | static void kpb_event_handler(void *arg, enum notify_id type, void *event_data); |
| 108 | +#endif |
102 | 109 | static int kpb_register_client(struct comp_data *kpb, struct kpb_client *cli); |
103 | 110 | static void kpb_init_draining(struct comp_dev *dev, struct kpb_client *cli); |
104 | 111 | static enum task_state kpb_draining_task(void *arg); |
@@ -130,6 +137,179 @@ static uint64_t kpb_task_deadline(void *data) |
130 | 137 | return SOF_TASK_DEADLINE_ALMOST_IDLE; |
131 | 138 | } |
132 | 139 |
|
| 140 | +#if CONFIG_AMS |
| 141 | +/* AMS messages uuids*/ |
| 142 | +/* Key-phrase detected uuid: 80a11122-b36c-11ed-afa1-0242ac120002 */ |
| 143 | +const uint8_t ams_kpd_msg_uuid[UUID_SIZE] = {0x80, 0xa1, 0x11, 0x22, 0xb3, 0x6c, |
| 144 | + 0x11, 0xed, 0xaf, 0xa1, 0x02, 0x42, |
| 145 | + 0xac, 0x12, 0x00, 0x02}; |
| 146 | + |
| 147 | +/* Register KPB client uuid: c5d9850f-cbdd-4bf4-9c6a-43dfc5faee9f*/ |
| 148 | +const uint8_t ams_reg_cli_msg_uuid[UUID_SIZE] = {0xcd, 0x59, 0x85, 0x0f, 0xdd, |
| 149 | + 0xcb, 0xf4, 0x4b, 0x9c, 0x6a, |
| 150 | + 0x43, 0xdf, 0xc5, 0xfa, 0xee, |
| 151 | + 0x9f}; |
| 152 | + |
| 153 | +static void |
| 154 | +kpb_ams_kpd_notification(const struct ams_message_payload *const ams_message_payload, |
| 155 | + void *ctx) |
| 156 | +{ |
| 157 | + struct kpb_client *cli_data = (struct kpb_client *)ams_message_payload->message; |
| 158 | + struct comp_dev *dev = ctx; |
| 159 | + |
| 160 | + comp_dbg(dev, "kpb_ams_kpd_notification()"); |
| 161 | + |
| 162 | + kpb_init_draining(dev, cli_data); |
| 163 | +} |
| 164 | + |
| 165 | +static void |
| 166 | +kpb_ams_register_cli_notification(const struct ams_message_payload *const ams_message_payload, |
| 167 | + void *ctx) |
| 168 | +{ |
| 169 | + struct kpb_client *cli_data = (struct kpb_client *)ams_message_payload->message; |
| 170 | + struct comp_dev *dev = ctx; |
| 171 | + struct comp_data *kpb = comp_get_drvdata(dev); |
| 172 | + int ret; |
| 173 | + |
| 174 | + comp_dbg(dev, "kpb_ams_register_cli_notification()"); |
| 175 | + |
| 176 | + ret = kpb_register_client(kpb, cli_data); |
| 177 | + if (ret) |
| 178 | + comp_err(dev, "kpb_ams_register_cli_notification(): register client error"); |
| 179 | +} |
| 180 | + |
| 181 | +static int kpb_register_ams_consumer(struct comp_dev *dev, |
| 182 | + const uint8_t *msg_uuid, |
| 183 | + uint32_t ams_uuid_id, |
| 184 | + ams_msg_callback_fn callback) |
| 185 | +{ |
| 186 | + uint16_t mod_id, inst_id; |
| 187 | + int ret; |
| 188 | + |
| 189 | + comp_dbg(dev, "kpb_register_ams_consumer()"); |
| 190 | + |
| 191 | +#ifdef CONFIG_IPC_MAJOR_4 |
| 192 | + mod_id = IPC4_MOD_ID(dev_comp_id(dev)); |
| 193 | + inst_id = IPC4_INST_ID(dev_comp_id(dev)); |
| 194 | +#else |
| 195 | + /* In IPC3 case KPB could be created only once so instance id = 0 */ |
| 196 | + mod_id = dev_comp_type(dev); |
| 197 | + inst_id = 0; |
| 198 | +#endif |
| 199 | + |
| 200 | + ret = ams_get_message_type_id(msg_uuid, &ams_uuid_id); |
| 201 | + if (ret) |
| 202 | + return ret; |
| 203 | + |
| 204 | + return ams_register_consumer(ams_uuid_id, mod_id, inst_id, callback, dev); |
| 205 | +} |
| 206 | + |
| 207 | +static int kpb_unregister_ams_consumer(struct comp_dev *dev, |
| 208 | + uint32_t ams_uuid_id, |
| 209 | + ams_msg_callback_fn callback) |
| 210 | +{ |
| 211 | +#ifdef CONFIG_IPC_MAJOR_4 |
| 212 | + uint16_t mod_id = IPC4_MOD_ID(dev_comp_id(dev)); |
| 213 | + uint16_t inst_id = IPC4_INST_ID(dev_comp_id(dev)); |
| 214 | +#else |
| 215 | + /* In IPC3 case KPB could be created only once so instance id = 0 */ |
| 216 | + uint16_t mod_id = dev_comp_type(dev); |
| 217 | + uint16_t inst_id = 0; |
| 218 | +#endif |
| 219 | + comp_dbg(dev, "kpb_unregister_ams_consumer()"); |
| 220 | + |
| 221 | + return ams_unregister_consumer(ams_uuid_id, mod_id, inst_id, callback); |
| 222 | +} |
| 223 | + |
| 224 | +int kpb_register_ams_producer(const struct comp_dev *dev, |
| 225 | + struct ams_message_payload *payload, |
| 226 | + const uint8_t *msg_uuid, |
| 227 | + uint32_t ams_uuid_id) |
| 228 | +{ |
| 229 | + uint16_t mod_id, inst_id; |
| 230 | + int ret; |
| 231 | + |
| 232 | + comp_dbg(dev, "kpb_register_ams_producer()"); |
| 233 | + |
| 234 | +#ifdef CONFIG_IPC_MAJOR_4 |
| 235 | + mod_id = IPC4_MOD_ID(dev_comp_id(dev)); |
| 236 | + inst_id = IPC4_INST_ID(dev_comp_id(dev)); |
| 237 | +#else |
| 238 | + /* In IPC3 case detector could be created only once so instance id = 0 */ |
| 239 | + mod_id = dev_comp_type(dev); |
| 240 | + inst_id = 0; |
| 241 | +#endif |
| 242 | + |
| 243 | + ret = ams_get_message_type_id(msg_uuid, &ams_uuid_id); |
| 244 | + if (ret) |
| 245 | + return ret; |
| 246 | + |
| 247 | + ret = ams_register_producer(ams_uuid_id, mod_id, inst_id); |
| 248 | + if (ret) |
| 249 | + return ret; |
| 250 | + |
| 251 | + payload->message_type_id = ams_uuid_id; |
| 252 | + payload->producer_module_id = mod_id; |
| 253 | + payload->producer_instance_id = inst_id; |
| 254 | + |
| 255 | + return 0; |
| 256 | +} |
| 257 | + |
| 258 | +int kpb_unregister_ams_producer(const struct comp_dev *dev, |
| 259 | + uint32_t ams_uuid_id) |
| 260 | +{ |
| 261 | +#ifdef CONFIG_IPC_MAJOR_4 |
| 262 | + uint16_t mod_id = IPC4_MOD_ID(dev_comp_id(dev)); |
| 263 | + uint16_t inst_id = IPC4_INST_ID(dev_comp_id(dev)); |
| 264 | +#else |
| 265 | + /* In IPC3 case detector could be created only once so instance id = 0 */ |
| 266 | + uint16_t mod_id = dev_comp_type(dev); |
| 267 | + uint16_t inst_id = 0; |
| 268 | +#endif |
| 269 | + |
| 270 | + comp_dbg(dev, "test_keyword_unregister_ams_producer()"); |
| 271 | + |
| 272 | + return ams_unregister_producer(ams_uuid_id, mod_id, inst_id); |
| 273 | +} |
| 274 | + |
| 275 | +#else |
| 276 | +/** |
| 277 | + * \brief Main event dispatcher. |
| 278 | + * \param[in] arg - KPB component internal data. |
| 279 | + * \param[in] type - notification type |
| 280 | + * \param[in] event_data - event specific data. |
| 281 | + * \return none. |
| 282 | + */ |
| 283 | +static void kpb_event_handler(void *arg, enum notify_id type, void *event_data) |
| 284 | +{ |
| 285 | + struct comp_dev *dev = arg; |
| 286 | + struct comp_data *kpb = comp_get_drvdata(dev); |
| 287 | + struct kpb_event_data *evd = event_data; |
| 288 | + struct kpb_client *cli = evd->client_data; |
| 289 | + |
| 290 | + comp_info(dev, "kpb_event_handler(): received event with ID: %d ", |
| 291 | + evd->event_id); |
| 292 | + |
| 293 | + switch (evd->event_id) { |
| 294 | + case KPB_EVENT_REGISTER_CLIENT: |
| 295 | + kpb_register_client(kpb, cli); |
| 296 | + break; |
| 297 | + case KPB_EVENT_UNREGISTER_CLIENT: |
| 298 | + /*TODO*/ |
| 299 | + break; |
| 300 | + case KPB_EVENT_BEGIN_DRAINING: |
| 301 | + kpb_init_draining(dev, cli); |
| 302 | + break; |
| 303 | + case KPB_EVENT_STOP_DRAINING: |
| 304 | + /*TODO*/ |
| 305 | + break; |
| 306 | + default: |
| 307 | + comp_err(dev, "kpb_cmd(): unsupported command"); |
| 308 | + break; |
| 309 | + } |
| 310 | +} |
| 311 | +#endif /* CONFIG_AMS */ |
| 312 | + |
133 | 313 | #ifdef __ZEPHYR__ |
134 | 314 |
|
135 | 315 | static void kpb_lock(struct comp_data *kpb) |
@@ -615,8 +795,23 @@ static void kpb_free(struct comp_dev *dev) |
615 | 795 |
|
616 | 796 | comp_info(dev, "kpb_free()"); |
617 | 797 |
|
| 798 | +#if CONFIG_AMS |
| 799 | + /* Unregister KPB as AMS consumer */ |
| 800 | + int ret; |
| 801 | + |
| 802 | + ret = kpb_unregister_ams_consumer(dev, kpb->kpd_uuid_id, |
| 803 | + kpb_ams_kpd_notification); |
| 804 | + if (ret) |
| 805 | + comp_err(dev, "kpb_free(): ams kpd error %d", ret); |
| 806 | + |
| 807 | + ret = kpb_unregister_ams_consumer(dev, kpb->reg_cli_uuid_id, |
| 808 | + kpb_ams_register_cli_notification); |
| 809 | + if (ret) |
| 810 | + comp_err(dev, "kpb_free(): ams register client error %d", ret); |
| 811 | +#else |
618 | 812 | /* Unregister KPB from notifications */ |
619 | 813 | notifier_unregister(dev, NULL, NOTIFIER_ID_KPB_CLIENT_EVT); |
| 814 | +#endif/* CONFIG_AMS */ |
620 | 815 |
|
621 | 816 | /* Reclaim memory occupied by history buffer */ |
622 | 817 | kpb_free_history_buffer(kpb->hd.c_hb); |
@@ -692,6 +887,11 @@ static int kpb_params(struct comp_dev *dev, |
692 | 887 | kpb->host_period_size = params->host_period_bytes; |
693 | 888 | kpb->config.sampling_width = params->sample_container_bytes * 8; |
694 | 889 |
|
| 890 | +#if CONFIG_AMS |
| 891 | + kpb->kpd_uuid_id = AMS_INVALID_MSG_TYPE; |
| 892 | + kpb->reg_cli_uuid_id = AMS_INVALID_MSG_TYPE; |
| 893 | +#endif |
| 894 | + |
695 | 895 | return 0; |
696 | 896 | } |
697 | 897 |
|
@@ -767,14 +967,31 @@ static int kpb_prepare(struct comp_dev *dev) |
767 | 967 | kpb->clients[i].r_ptr = NULL; |
768 | 968 | } |
769 | 969 |
|
| 970 | +#if CONFIG_AMS |
| 971 | + /* Register KPB as AMS consumer */ |
| 972 | + ret = kpb_register_ams_consumer(dev, ams_kpd_msg_uuid, kpb->kpd_uuid_id, |
| 973 | + kpb_ams_kpd_notification); |
| 974 | + if (ret) { |
| 975 | + comp_err(dev, "kpb_prepare(): register ams consumer kpd err %d", ret); |
| 976 | + goto err; |
| 977 | + } |
| 978 | + |
| 979 | + ret = kpb_register_ams_consumer(dev, ams_reg_cli_msg_uuid, |
| 980 | + kpb->reg_cli_uuid_id, |
| 981 | + kpb_ams_register_cli_notification); |
| 982 | + if (ret) { |
| 983 | + comp_err(dev, "kpb_prepare(): register ams consumer reg_cli err %d", ret); |
| 984 | + goto err; |
| 985 | + } |
| 986 | +#else |
770 | 987 | /* Register KPB for notification */ |
771 | 988 | ret = notifier_register(dev, NULL, NOTIFIER_ID_KPB_CLIENT_EVT, |
772 | 989 | kpb_event_handler, 0); |
773 | | - if (ret < 0) { |
774 | | - kpb_free_history_buffer(kpb->hd.c_hb); |
775 | | - kpb->hd.c_hb = NULL; |
776 | | - return -ENOMEM; |
| 990 | + if (ret) { |
| 991 | + comp_err(dev, "kpb_prepare(): notifier_register err %d", ret); |
| 992 | + goto err; |
777 | 993 | } |
| 994 | +#endif /* CONFIG_AMS */ |
778 | 995 |
|
779 | 996 | #ifndef CONFIG_IPC_MAJOR_4 |
780 | 997 | /* Search for KPB related sinks. |
@@ -850,6 +1067,11 @@ static int kpb_prepare(struct comp_dev *dev) |
850 | 1067 | kpb_change_state(kpb, KPB_STATE_RUN); |
851 | 1068 |
|
852 | 1069 | return ret; |
| 1070 | + |
| 1071 | +err: |
| 1072 | + kpb_free_history_buffer(kpb->hd.c_hb); |
| 1073 | + kpb->hd.c_hb = NULL; |
| 1074 | + return ret; |
853 | 1075 | } |
854 | 1076 |
|
855 | 1077 | /** |
@@ -912,8 +1134,10 @@ static int kpb_reset(struct comp_dev *dev) |
912 | 1134 | kpb_reset_history_buffer(kpb->hd.c_hb); |
913 | 1135 | } |
914 | 1136 |
|
| 1137 | +#ifndef CONFIG_AMS |
915 | 1138 | /* Unregister KPB from notifications */ |
916 | 1139 | notifier_unregister(dev, NULL, NOTIFIER_ID_KPB_CLIENT_EVT); |
| 1140 | +#endif |
917 | 1141 | /* Finally KPB is ready after reset */ |
918 | 1142 | kpb_change_state(kpb, KPB_STATE_PREPARING); |
919 | 1143 |
|
@@ -1417,42 +1641,6 @@ static int kpb_buffer_data(struct comp_dev *dev, |
1417 | 1641 | return ret; |
1418 | 1642 | } |
1419 | 1643 |
|
1420 | | -/** |
1421 | | - * \brief Main event dispatcher. |
1422 | | - * \param[in] arg - KPB component internal data. |
1423 | | - * \param[in] type - notification type |
1424 | | - * \param[in] event_data - event specific data. |
1425 | | - * \return none. |
1426 | | - */ |
1427 | | -static void kpb_event_handler(void *arg, enum notify_id type, void *event_data) |
1428 | | -{ |
1429 | | - struct comp_dev *dev = arg; |
1430 | | - struct comp_data *kpb = comp_get_drvdata(dev); |
1431 | | - struct kpb_event_data *evd = event_data; |
1432 | | - struct kpb_client *cli = evd->client_data; |
1433 | | - |
1434 | | - comp_info(dev, "kpb_event_handler(): received event with ID: %d ", |
1435 | | - evd->event_id); |
1436 | | - |
1437 | | - switch (evd->event_id) { |
1438 | | - case KPB_EVENT_REGISTER_CLIENT: |
1439 | | - kpb_register_client(kpb, cli); |
1440 | | - break; |
1441 | | - case KPB_EVENT_UNREGISTER_CLIENT: |
1442 | | - /*TODO*/ |
1443 | | - break; |
1444 | | - case KPB_EVENT_BEGIN_DRAINING: |
1445 | | - kpb_init_draining(dev, cli); |
1446 | | - break; |
1447 | | - case KPB_EVENT_STOP_DRAINING: |
1448 | | - /*TODO*/ |
1449 | | - break; |
1450 | | - default: |
1451 | | - comp_err(dev, "kpb_cmd(): unsupported command"); |
1452 | | - break; |
1453 | | - } |
1454 | | -} |
1455 | | - |
1456 | 1644 | /** |
1457 | 1645 | * \brief Register clients in the system. |
1458 | 1646 | * |
|
0 commit comments