]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ASoC: qdsp6: audioreach: add support for more port connections
authorSrinivas Kandagatla <srinivas.kandagatla@linaro.org>
Thu, 27 Oct 2022 10:27:07 +0000 (11:27 +0100)
committerMark Brown <broonie@kernel.org>
Fri, 28 Oct 2022 16:19:22 +0000 (17:19 +0100)
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>
include/uapi/sound/snd_ar_tokens.h
sound/soc/qcom/qdsp6/audioreach.c
sound/soc/qcom/qdsp6/audioreach.h
sound/soc/qcom/qdsp6/topology.c

index 440c0725660b7deca1ae5352f9ab5ce3a13f24df..b9b9093b4396c970ac6a6d1064b258220d5b013d 100644 (file)
@@ -191,6 +191,33 @@ enum ar_event_types {
 #define AR_TKN_U32_MODULE_SRC_INSTANCE_ID      208
 #define AR_TKN_U32_MODULE_DST_INSTANCE_ID      209
 
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID1      210
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID1      211
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID1     212
+
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID2      213
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID2      214
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID2     215
+
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID3      216
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID3      217
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID3     218
+
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID4      219
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID4      220
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID4     221
+
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID5      222
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID5      223
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID5     224
+
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID6      225
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID6      226
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID6     227
+
+#define AR_TKN_U32_MODULE_SRC_OP_PORT_ID7      228
+#define AR_TKN_U32_MODULE_DST_IN_PORT_ID7      229
+#define AR_TKN_U32_MODULE_DST_INSTANCE_ID7     230
 
 #define AR_TKN_U32_MODULE_HW_IF_IDX            250
 #define AR_TKN_U32_MODULE_HW_IF_TYPE           251
index 87a3fd1f81071a32691e36c43aff10868277e78b..99cade6d8a487327ef3532032633ed32125550b7 100644 (file)
@@ -311,15 +311,6 @@ static void apm_populate_sub_graph_config(struct apm_sub_graph_data *cfg,
        cfg->sid.scenario_id = sg->scenario_id;
 }
 
-static void apm_populate_connection_obj(struct apm_module_conn_obj *obj,
-                                       struct audioreach_module *module)
-{
-       obj->src_mod_inst_id = module->src_mod_inst_id;
-       obj->src_mod_op_port_id = module->src_mod_op_port_id;
-       obj->dst_mod_inst_id = module->instance_id;
-       obj->dst_mod_ip_port_id = module->in_port;
-}
-
 static void apm_populate_module_prop_obj(struct apm_mod_prop_obj *obj,
                                         struct audioreach_module *module)
 {
@@ -394,22 +385,30 @@ static void audioreach_populate_graph(struct q6apm *apm, struct audioreach_graph
                        apm_populate_module_list_obj(mlobj, container, sg->sub_graph_id);
 
                        list_for_each_entry(module, &container->modules_list, node) {
-                               uint32_t src_mod_inst_id;
+                               int pn;
 
-                               src_mod_inst_id = module->src_mod_inst_id;
-
-                               module_prop_obj = &mp_data->mod_prop_obj[nmodule];
+                               module_prop_obj = &mp_data->mod_prop_obj[nmodule++];
                                apm_populate_module_prop_obj(module_prop_obj, module);
 
-                               if (src_mod_inst_id) {
-                                       conn_obj = &mc_data->conn_obj[nconn];
-                                       apm_populate_connection_obj(conn_obj, module);
-                                       nconn++;
+                               if (!module->max_op_port)
+                                       continue;
+
+                               for (pn = 0; pn < module->max_op_port; pn++) {
+                                       if (module->dst_mod_inst_id[pn]) {
+                                               conn_obj = &mc_data->conn_obj[nconn];
+                                               conn_obj->src_mod_inst_id = module->instance_id;
+                                               conn_obj->src_mod_op_port_id =
+                                                               module->src_mod_op_port_id[pn];
+                                               conn_obj->dst_mod_inst_id =
+                                                               module->dst_mod_inst_id[pn];
+                                               conn_obj->dst_mod_ip_port_id =
+                                                               module->dst_mod_ip_port_id[pn];
+                                               nconn++;
+                                       }
                                }
-
-                               nmodule++;
                        }
-                       mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules);
+                       mlobj = (void *) mlobj + APM_MOD_LIST_OBJ_PSIZE(mlobj,
+                                                                       container->num_modules);
 
                        ncontainer++;
                }
@@ -454,8 +453,7 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct audioreach_graph_info
                                APM_MOD_LIST_OBJ_PSIZE(mlobj, container->num_modules);
 
                        list_for_each_entry(module, &container->modules_list, node) {
-                               if (module->src_mod_inst_id)
-                                       num_connections++;
+                               num_connections += module->num_connections;
                        }
                }
        }
@@ -500,7 +498,7 @@ void *audioreach_alloc_graph_pkt(struct q6apm *apm, struct audioreach_graph_info
        param_data->module_instance_id = APM_MODULE_INSTANCE_ID;
        param_data->param_id = APM_PARAM_ID_MODULE_LIST;
        param_data->param_size = ml_sz - APM_MODULE_PARAM_DATA_SIZE;
-       params.mod_list_data->num_modules_list = num_sub_graphs;
+       params.mod_list_data->num_modules_list = num_modules_list;
        p += ml_sz;
 
        /* Module Properties */
index 1dc6ffcb3362766e263edc8e41eb7fb21497f5f6..df5026b646c11ddde7c8a7da4c414790ddd488ce 100644 (file)
@@ -627,6 +627,8 @@ struct audioreach_container {
        struct audioreach_sub_graph *sub_graph;
 };
 
+#define AR_MAX_MOD_LINKS       8
+
 struct audioreach_module {
        uint32_t module_id;
        uint32_t instance_id;
@@ -637,11 +639,12 @@ struct audioreach_module {
        uint32_t in_port;
        uint32_t out_port;
 
+       uint32_t num_connections;
        /* Connections */
        uint32_t src_mod_inst_id;
-       uint32_t src_mod_op_port_id;
-       uint32_t dst_mod_inst_id;
-       uint32_t dst_mod_ip_port_id;
+       uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS];
+       uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS];
+       uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS];
 
        /* Format specifics */
        uint32_t ch_fmt;
index f66d7054177c37bdc170fdbd65f73dcbbdacae8c..cccc59b570b9a4cc2e1e3ff9e9fe691b585460b4 100644 (file)
@@ -412,19 +412,25 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
                                                        struct snd_soc_dapm_widget *w)
 {
        uint32_t max_ip_port = 0, max_op_port = 0, in_port = 0, out_port = 0;
-       uint32_t src_mod_inst_id = 0, src_mod_op_port_id = 0;
-       uint32_t dst_mod_inst_id = 0, dst_mod_ip_port_id = 0;
+       uint32_t src_mod_op_port_id[AR_MAX_MOD_LINKS] = { 0, };
+       uint32_t dst_mod_inst_id[AR_MAX_MOD_LINKS] = { 0, };
+       uint32_t dst_mod_ip_port_id[AR_MAX_MOD_LINKS] = { 0, };
+       uint32_t src_mod_inst_id = 0;
+
        int module_id = 0, instance_id = 0, tkn_count = 0;
        struct snd_soc_tplg_vendor_value_elem *mod_elem;
        struct snd_soc_tplg_vendor_array *mod_array;
        struct audioreach_module *mod = NULL;
+       uint32_t token;
        bool found;
+       int max_tokens;
 
        mod_array = audioreach_get_module_array(private);
        mod_elem = mod_array->value;
-
-       while (tkn_count <= (le32_to_cpu(mod_array->num_elems) - 1)) {
-               switch (le32_to_cpu(mod_elem->token)) {
+       max_tokens = le32_to_cpu(mod_array->num_elems);
+       while (tkn_count <= (max_tokens - 1)) {
+               token = le32_to_cpu(mod_elem->token);
+               switch (token) {
                /* common module info */
                case AR_TKN_U32_MODULE_ID:
                        module_id = le32_to_cpu(mod_elem->value);
@@ -454,17 +460,80 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
                case AR_TKN_U32_MODULE_OUT_PORTS:
                        out_port = le32_to_cpu(mod_elem->value);
                        break;
-               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID:
-                       src_mod_op_port_id = le32_to_cpu(mod_elem->value);
-                       break;
                case AR_TKN_U32_MODULE_SRC_INSTANCE_ID:
                        src_mod_inst_id = le32_to_cpu(mod_elem->value);
                        break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID:
+                       src_mod_op_port_id[0] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID1:
+                       src_mod_op_port_id[1] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID2:
+                       src_mod_op_port_id[2] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID3:
+                       src_mod_op_port_id[3] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID4:
+                       src_mod_op_port_id[4] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID5:
+                       src_mod_op_port_id[5] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID6:
+                       src_mod_op_port_id[6] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_SRC_OP_PORT_ID7:
+                       src_mod_op_port_id[7] = le32_to_cpu(mod_elem->value);
+                       break;
                case AR_TKN_U32_MODULE_DST_INSTANCE_ID:
-                       dst_mod_inst_id = le32_to_cpu(mod_elem->value);
+                       dst_mod_inst_id[0] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID1:
+                       dst_mod_inst_id[1] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID2:
+                       dst_mod_inst_id[2] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID3:
+                       dst_mod_inst_id[3] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID4:
+                       dst_mod_inst_id[4] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID5:
+                       dst_mod_inst_id[5] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID6:
+                       dst_mod_inst_id[6] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_INSTANCE_ID7:
+                       dst_mod_inst_id[7] = le32_to_cpu(mod_elem->value);
                        break;
                case AR_TKN_U32_MODULE_DST_IN_PORT_ID:
-                       dst_mod_ip_port_id = le32_to_cpu(mod_elem->value);
+                       dst_mod_ip_port_id[0] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID1:
+                       dst_mod_ip_port_id[1] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID2:
+                       dst_mod_ip_port_id[2] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID3:
+                       dst_mod_ip_port_id[3] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID4:
+                       dst_mod_ip_port_id[4] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID5:
+                       dst_mod_ip_port_id[5] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID6:
+                       dst_mod_ip_port_id[6] = le32_to_cpu(mod_elem->value);
+                       break;
+               case AR_TKN_U32_MODULE_DST_IN_PORT_ID7:
+                       dst_mod_ip_port_id[7] = le32_to_cpu(mod_elem->value);
                        break;
                default:
                        break;
@@ -475,15 +544,23 @@ static struct audioreach_module *audioreach_parse_common_tokens(struct q6apm *ap
        }
 
        if (mod) {
+               int pn, id = 0;
                mod->module_id = module_id;
                mod->max_ip_port = max_ip_port;
                mod->max_op_port = max_op_port;
                mod->in_port = in_port;
                mod->out_port = out_port;
                mod->src_mod_inst_id = src_mod_inst_id;
-               mod->src_mod_op_port_id = src_mod_op_port_id;
-               mod->dst_mod_inst_id = dst_mod_inst_id;
-               mod->dst_mod_ip_port_id = dst_mod_ip_port_id;
+               for (pn = 0; pn < mod->max_op_port; pn++) {
+                       if (src_mod_op_port_id[pn] && dst_mod_inst_id[pn] &&
+                           dst_mod_ip_port_id[pn]) {
+                               mod->src_mod_op_port_id[id] = src_mod_op_port_id[pn];
+                               mod->dst_mod_inst_id[id] = dst_mod_inst_id[pn];
+                               mod->dst_mod_ip_port_id[id] = dst_mod_ip_port_id[pn];
+                               id++;
+                               mod->num_connections = id;
+                       }
+               }
        }
 
        return mod;