Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: qdsp6: audioreach: add support for more port connections

AudioReach Modules can connect to other modules using source and
destination port, and each module in theory can support up to 255 port
connections. But in practice this limit is at max 8 ports at a time.
So add support for allowing multiple port connections.

This support is needed for more detailed graphs like ECNS, speaker
protection and so.

Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
Link: https://lore.kernel.org/r/20221027102710.21407-7-srinivas.kandagatla@linaro.org
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

Srinivas Kandagatla and committed by
Mark Brown
03365d6a 4efb98e9

+144 -39
+27
include/uapi/sound/snd_ar_tokens.h
··· 191 191 #define AR_TKN_U32_MODULE_SRC_INSTANCE_ID 208 192 192 #define AR_TKN_U32_MODULE_DST_INSTANCE_ID 209 193 193 194 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID1 210 195 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID1 211 196 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID1 212 197 + 198 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID2 213 199 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID2 214 200 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID2 215 201 + 202 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID3 216 203 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID3 217 204 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID3 218 205 + 206 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID4 219 207 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID4 220 208 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID4 221 209 + 210 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID5 222 211 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID5 223 212 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID5 224 213 + 214 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID6 225 215 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID6 226 216 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID6 227 217 + 218 + #define AR_TKN_U32_MODULE_SRC_OP_PORT_ID7 228 219 + #define AR_TKN_U32_MODULE_DST_IN_PORT_ID7 229 220 + #define AR_TKN_U32_MODULE_DST_INSTANCE_ID7 230 194 221 195 222 #define AR_TKN_U32_MODULE_HW_IF_IDX 250 196 223 #define AR_TKN_U32_MODULE_HW_IF_TYPE 251
+21 -23
sound/soc/qcom/qdsp6/audioreach.c
··· 311 311 cfg->sid.scenario_id = sg->scenario_id; 312 312 } 313 313 314 - static void apm_populate_connection_obj(struct apm_module_conn_obj *obj, 315 - struct audioreach_module *module) 316 - { 317 - obj->src_mod_inst_id = module->src_mod_inst_id; 318 - obj->src_mod_op_port_id = module->src_mod_op_port_id; 319 - obj->dst_mod_inst_id = module->instance_id; 320 - obj->dst_mod_ip_port_id = module->in_port; 321 - } 322 - 323 314 static void apm_populate_module_prop_obj(struct apm_mod_prop_obj *obj, 324 315 struct audioreach_module *module) 325 316 { ··· 385 394 apm_populate_module_list_obj(mlobj, container, sg->sub_graph_id); 386 395 387 396 list_for_each_entry(module, &container->modules_list, node) { 388 - uint32_t src_mod_inst_id; 397 + int pn; 389 398 390 - src_mod_inst_id = module->src_mod_inst_id; 391 - 392 - module_prop_obj = &mp_data->mod_prop_obj[nmodule]; 399 + module_prop_obj = &mp_data->mod_prop_obj[nmodule++]; 393 400 apm_populate_module_prop_obj(module_prop_obj, module); 394 401 395 - if (src_mod_inst_id) { 396 - conn_obj = &mc_data->conn_obj[nconn]; 397 - apm_populate_connection_obj(conn_obj, module); 398 - nconn++; 399 - } 402 + if (!module->max_op_port) 403 + continue; 400 404 401 - nmodule++; 405 + for (pn = 0; pn < module->max_op_port; pn++) { 406 + if (module->dst_mod_inst_id[pn]) { 407 + conn_obj = &mc_data->conn_obj[nconn]; 408 + conn_obj->src_mod_inst_id = module->instance_id; 409 + conn_obj->src_mod_op_port_id = 410 + module->src_mod_op_port_id[pn]; 411 + conn_obj->dst_mod_inst_id = 412 + module->dst_mod_inst_id[pn]; 413 + conn_obj->dst_mod_ip_port_id = 414 + module->dst_mod_ip_port_id[pn]; 415 + nconn++; 416 + } 417 + } 402 418 } 403 - mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules); 419 + mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj, 420 + container->num_modules); 404 421 405 422 ncontainer++; 406 423 } ··· 453 454 APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules); 454 455 455 456 list_for_each_entry(module, &container->modules_list, node) { 456 - if (module->src_mod_inst_id) 457 - num_connections++; 457 + num_connections += module->num_connections; 458 458 } 459 459 } 460 460 } ··· 498 500 param_data->module_instance_id = APM_MODULE_INSTANCE_ID; 499 501 param_data->param_id = APM_PARAM_ID_MODULE_LIST; 500 502 param_data->param_size = ml_sz - APM_MODULE_PARAM_DATA_SIZE; 501 - params.mod_list_data->num_modules_list = num_sub_graphs; 503 + params.mod_list_data->num_modules_list = num_modules_list; 502 504 p += ml_sz; 503 505 504 506 /* Module Properties */
+6 -3
sound/soc/qcom/qdsp6/audioreach.h
··· 627 627 struct audioreach_sub_graph *sub_graph; 628 628 }; 629 629 630 + #define AR_MAX_MOD_LINKS 8 631 + 630 632 struct audioreach_module { 631 633 uint32_t module_id; 632 634 uint32_t instance_id; ··· 639 637 uint32_t in_port; 640 638 uint32_t out_port; 641 639 640 + uint32_t num_connections; 642 641 /* Connections */ 643 642 uint32_t src_mod_inst_id; 644 - uint32_t src_mod_op_port_id; 645 - uint32_t dst_mod_inst_id; 646 - uint32_t dst_mod_ip_port_id; 643 + uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS]; 644 + uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS]; 645 + uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS]; 647 646 648 647 /* Format specifics */ 649 648 uint32_t ch_fmt;
+90 -13
sound/soc/qcom/qdsp6/topology.c
··· 412 412 struct snd_soc_dapm_widget *w) 413 413 { 414 414 uint32_t max_ip_port = 0, max_op_port = 0, in_port = 0, out_port = 0; 415 - uint32_t src_mod_inst_id = 0, src_mod_op_port_id = 0; 416 - uint32_t dst_mod_inst_id = 0, dst_mod_ip_port_id = 0; 415 + uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS] = { 0, }; 416 + uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS] = { 0, }; 417 + uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS] = { 0, }; 418 + uint32_t src_mod_inst_id = 0; 419 + 417 420 int module_id = 0, instance_id = 0, tkn_count = 0; 418 421 struct snd_soc_tplg_vendor_value_elem *mod_elem; 419 422 struct snd_soc_tplg_vendor_array *mod_array; 420 423 struct audioreach_module *mod = NULL; 424 + uint32_t token; 421 425 bool found; 426 + int max_tokens; 422 427 423 428 mod_array = audioreach_get_module_array(private); 424 429 mod_elem = mod_array->value; 425 - 426 - while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) { 427 - switch (le32_to_cpu(mod_elem->token)) { 430 + max_tokens = le32_to_cpu(mod_array->num_elems); 431 + while (tkn_count <= (max_tokens - 1)) { 432 + token = le32_to_cpu(mod_elem->token); 433 + switch (token) { 428 434 /* common module info */ 429 435 case AR_TKN_U32_MODULE_ID: 430 436 module_id = le32_to_cpu(mod_elem->value); ··· 460 454 case AR_TKN_U32_MODULE_OUT_PORTS: 461 455 out_port = le32_to_cpu(mod_elem->value); 462 456 break; 463 - case AR_TKN_U32_MODULE_SRC_OP_PORT_ID: 464 - src_mod_op_port_id = le32_to_cpu(mod_elem->value); 465 - break; 466 457 case AR_TKN_U32_MODULE_SRC_INSTANCE_ID: 467 458 src_mod_inst_id = le32_to_cpu(mod_elem->value); 468 459 break; 460 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID: 461 + src_mod_op_port_id[0] = le32_to_cpu(mod_elem->value); 462 + break; 463 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID1: 464 + src_mod_op_port_id[1] = le32_to_cpu(mod_elem->value); 465 + break; 466 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID2: 467 + src_mod_op_port_id[2] = le32_to_cpu(mod_elem->value); 468 + break; 469 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID3: 470 + src_mod_op_port_id[3] = le32_to_cpu(mod_elem->value); 471 + break; 472 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID4: 473 + src_mod_op_port_id[4] = le32_to_cpu(mod_elem->value); 474 + break; 475 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID5: 476 + src_mod_op_port_id[5] = le32_to_cpu(mod_elem->value); 477 + break; 478 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID6: 479 + src_mod_op_port_id[6] = le32_to_cpu(mod_elem->value); 480 + break; 481 + case AR_TKN_U32_MODULE_SRC_OP_PORT_ID7: 482 + src_mod_op_port_id[7] = le32_to_cpu(mod_elem->value); 483 + break; 469 484 case AR_TKN_U32_MODULE_DST_INSTANCE_ID: 470 - dst_mod_inst_id = le32_to_cpu(mod_elem->value); 485 + dst_mod_inst_id[0] = le32_to_cpu(mod_elem->value); 486 + break; 487 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID1: 488 + dst_mod_inst_id[1] = le32_to_cpu(mod_elem->value); 489 + break; 490 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID2: 491 + dst_mod_inst_id[2] = le32_to_cpu(mod_elem->value); 492 + break; 493 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID3: 494 + dst_mod_inst_id[3] = le32_to_cpu(mod_elem->value); 495 + break; 496 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID4: 497 + dst_mod_inst_id[4] = le32_to_cpu(mod_elem->value); 498 + break; 499 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID5: 500 + dst_mod_inst_id[5] = le32_to_cpu(mod_elem->value); 501 + break; 502 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID6: 503 + dst_mod_inst_id[6] = le32_to_cpu(mod_elem->value); 504 + break; 505 + case AR_TKN_U32_MODULE_DST_INSTANCE_ID7: 506 + dst_mod_inst_id[7] = le32_to_cpu(mod_elem->value); 471 507 break; 472 508 case AR_TKN_U32_MODULE_DST_IN_PORT_ID: 473 - dst_mod_ip_port_id = le32_to_cpu(mod_elem->value); 509 + dst_mod_ip_port_id[0] = le32_to_cpu(mod_elem->value); 510 + break; 511 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID1: 512 + dst_mod_ip_port_id[1] = le32_to_cpu(mod_elem->value); 513 + break; 514 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID2: 515 + dst_mod_ip_port_id[2] = le32_to_cpu(mod_elem->value); 516 + break; 517 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID3: 518 + dst_mod_ip_port_id[3] = le32_to_cpu(mod_elem->value); 519 + break; 520 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID4: 521 + dst_mod_ip_port_id[4] = le32_to_cpu(mod_elem->value); 522 + break; 523 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID5: 524 + dst_mod_ip_port_id[5] = le32_to_cpu(mod_elem->value); 525 + break; 526 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID6: 527 + dst_mod_ip_port_id[6] = le32_to_cpu(mod_elem->value); 528 + break; 529 + case AR_TKN_U32_MODULE_DST_IN_PORT_ID7: 530 + dst_mod_ip_port_id[7] = le32_to_cpu(mod_elem->value); 474 531 break; 475 532 default: 476 533 break; ··· 544 475 } 545 476 546 477 if (mod) { 478 + int pn, id = 0; 547 479 mod->module_id = module_id; 548 480 mod->max_ip_port = max_ip_port; 549 481 mod->max_op_port = max_op_port; 550 482 mod->in_port = in_port; 551 483 mod->out_port = out_port; 552 484 mod->src_mod_inst_id = src_mod_inst_id; 553 - mod->src_mod_op_port_id = src_mod_op_port_id; 554 - mod->dst_mod_inst_id = dst_mod_inst_id; 555 - mod->dst_mod_ip_port_id = dst_mod_ip_port_id; 485 + for (pn = 0; pn < mod->max_op_port; pn++) { 486 + if (src_mod_op_port_id[pn] && dst_mod_inst_id[pn] && 487 + dst_mod_ip_port_id[pn]) { 488 + mod->src_mod_op_port_id[id] = src_mod_op_port_id[pn]; 489 + mod->dst_mod_inst_id[id] = dst_mod_inst_id[pn]; 490 + mod->dst_mod_ip_port_id[id] = dst_mod_ip_port_id[pn]; 491 + id++; 492 + mod->num_connections = id; 493 + } 494 + } 556 495 } 557 496 558 497 return mod;