int adm_matrix_map(int session_id, int path, int num_copps, unsigned int *port_id, int copp_id) { struct adm_cmd_matrix_map_routings_v5 *route; struct adm_session_map_node_v5 *node; uint32_t *copps_list; int cmd_size = 0; int ret = 0, i = 0; void *payload = NULL; void *matrix_map = NULL; /* Assumes port_ids have already been validated during adm_open */ int index = q6audio_get_port_index(copp_id); if (index < 0 || index >= Q6_AFE_MAX_PORTS) { pr_err("%s: invalid port idx %d token %d\n", __func__, index, copp_id); return 0; } cmd_size = (sizeof(struct adm_cmd_matrix_map_routings_v5) + sizeof(struct adm_session_map_node_v5) + (sizeof(uint32_t) * num_copps)); matrix_map = kzalloc(cmd_size, GFP_KERNEL); if (matrix_map == NULL) { pr_err("%s: Mem alloc failed\n", __func__); ret = -EINVAL; return ret; } route = (struct adm_cmd_matrix_map_routings_v5 *)matrix_map; pr_debug("%s: session 0x%x path:%d num_copps:%d port_id[0] :%d coppid[%d]\n", __func__, session_id, path, num_copps, port_id[0], copp_id); route->hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); route->hdr.pkt_size = cmd_size; route->hdr.src_svc = 0; route->hdr.src_domain = APR_DOMAIN_APPS; route->hdr.src_port = copp_id; route->hdr.dest_svc = APR_SVC_ADM; route->hdr.dest_domain = APR_DOMAIN_ADSP; route->hdr.dest_port = atomic_read(&this_adm.copp_id[index]); route->hdr.token = copp_id; route->hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS_V5; route->num_sessions = 1; switch (path) { case 0x1: route->matrix_id = ADM_MATRIX_ID_AUDIO_RX; break; case 0x2: case 0x3: route->matrix_id = ADM_MATRIX_ID_AUDIO_TX; break; default: pr_err("%s: Wrong path set[%d]\n", __func__, path); break; } payload = ((u8 *)matrix_map + sizeof(struct adm_cmd_matrix_map_routings_v5)); node = (struct adm_session_map_node_v5 *)payload; node->session_id = session_id; node->num_copps = num_copps; payload = (u8 *)node + sizeof(struct adm_session_map_node_v5); copps_list = (uint32_t *)payload; for (i = 0; i < num_copps; i++) { int tmp; port_id[i] = q6audio_convert_virtual_to_portid(port_id[i]); tmp = q6audio_get_port_index(port_id[i]); if (tmp >= 0 && tmp < Q6_AFE_MAX_PORTS) copps_list[i] = atomic_read(&this_adm.copp_id[tmp]); pr_debug("%s: port_id[%d]: %d, index: %d act coppid[0x%x]\n", __func__, i, port_id[i], tmp, atomic_read(&this_adm.copp_id[tmp])); } atomic_set(&this_adm.copp_stat[index], 0); ret = apr_send_pkt(this_adm.apr, (uint32_t *)matrix_map); if (ret < 0) { pr_err("%s: ADM routing for port %d failed\n", __func__, port_id[0]); ret = -EINVAL; goto fail_cmd; } ret = wait_event_timeout(this_adm.wait[index], atomic_read(&this_adm.copp_stat[index]), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: ADM cmd Route failed for port %d\n", __func__, port_id[0]); ret = -EINVAL; goto fail_cmd; } for (i = 0; i < num_copps; i++) send_adm_cal(port_id[i], path); fail_cmd: kfree(matrix_map); return ret; }
int adm_matrix_map(int session_id, int path, int num_copps, unsigned int *port_id, int copp_id) { struct adm_routings_command route; int ret = 0, i = 0; /* Assumes port_ids have already been validated during adm_open */ int index = afe_get_port_index(copp_id); pr_debug("%s: session 0x%x path:%d num_copps:%d port_id[0]:%d\n", __func__, session_id, path, num_copps, port_id[0]); route.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); route.hdr.pkt_size = sizeof(route); route.hdr.src_svc = 0; route.hdr.src_domain = APR_DOMAIN_APPS; route.hdr.src_port = copp_id; route.hdr.dest_svc = APR_SVC_ADM; route.hdr.dest_domain = APR_DOMAIN_ADSP; route.hdr.dest_port = atomic_read(&this_adm.copp_id[index]); route.hdr.token = copp_id; route.hdr.opcode = ADM_CMD_MATRIX_MAP_ROUTINGS; route.num_sessions = 1; route.session[0].id = session_id; route.session[0].num_copps = num_copps; for (i = 0; i < num_copps; i++) { int tmp; port_id[i] = afe_convert_virtual_to_portid(port_id[i]); tmp = afe_get_port_index(port_id[i]); pr_debug("%s: port_id[%d]: %d, index: %d\n", __func__, i, port_id[i], tmp); route.session[0].copp_id[i] = atomic_read(&this_adm.copp_id[tmp]); } if (num_copps % 2) route.session[0].copp_id[i] = 0; switch (path) { case 0x1: route.path = AUDIO_RX; break; case 0x2: case 0x3: route.path = AUDIO_TX; break; default: pr_err("%s: Wrong path set[%d]\n", __func__, path); break; } atomic_set(&this_adm.copp_stat[index], 0); ret = apr_send_pkt(this_adm.apr, (uint32_t *)&route); if (ret < 0) { pr_err("%s: ADM routing for port %d failed\n", __func__, port_id[0]); ret = -EINVAL; goto fail_cmd; } ret = wait_event_timeout(this_adm.wait, atomic_read(&this_adm.copp_stat[index]), msecs_to_jiffies(TIMEOUT_MS)); if (!ret) { pr_err("%s: ADM cmd Route failed for port %d\n", __func__, port_id[0]); ret = -EINVAL; goto fail_cmd; } for (i = 0; i < num_copps; i++) send_adm_cal(port_id[i], path); for (i = 0; i < num_copps; i++) rtac_add_adm_device(port_id[i], atomic_read(&this_adm.copp_id [afe_get_port_index(port_id[i])]), path, session_id); return 0; fail_cmd: return ret; }