int msm_snddev_set_enc(int popp_id, int copp_id, int set, int rate, int mode) { int topology; int tbl_idx; int rc = 0, i = 0; mutex_lock(&routing_info.adm_mutex); if (set) { mutex_lock(&adm_tx_topology_tbl.lock); tbl_idx = check_tx_copp_topology(popp_id); if (tbl_idx == -ENOENT) topology = DEFAULT_COPP_TOPOLOGY; else { topology = adm_tx_topology_tbl.topolog_id[tbl_idx]; rate = 16000; } mutex_unlock(&adm_tx_topology_tbl.lock); rc = adm_open(copp_id, ADM_PATH_LIVE_REC, rate, mode, topology); if (rc < 0) { pr_err("%s: adm open fail rc[%d]\n", __func__, rc); rc = -EINVAL; goto fail_cmd; } rc = adm_matrix_map(popp_id, ADM_PATH_LIVE_REC, 1, (unsigned int *)&copp_id, copp_id); if (rc < 0) { pr_err("%s: matrix map failed rc[%d]\n", __func__, rc); adm_close(copp_id); rc = -EINVAL; goto fail_cmd; } msm_set_copp_id(popp_id, copp_id); #ifdef CONFIG_MSM8X60_RTAC rtac_add_adm_device(copp_id, popp_id); #endif } else { for (i = 0; i < AFE_MAX_PORTS; i++) { if (routing_info.copp_list[popp_id][i] == copp_id) { rc = adm_close(copp_id); if (rc < 0) { pr_err("%s: adm close fail copp[%d]" "rc[%d]\n", __func__, copp_id, rc); rc = -EINVAL; goto fail_cmd; } msm_clear_copp_id(popp_id, copp_id); break; } } } fail_cmd: mutex_unlock(&routing_info.adm_mutex); return rc; }
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); int copp_cnt; if (index < 0 || index >= AFE_MAX_PORTS) { pr_err("%s: invalid port idx %d token %d\n", __func__, index, copp_id); return 0; } 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; if (num_copps < ADM_MAX_COPPS) { copp_cnt = num_copps; } else { copp_cnt = ADM_MAX_COPPS; /* print out warning for now as playback/capture to/from * COPPs more than maximum allowed is extremely unlikely */ pr_warn("%s: max out routable COPPs\n", __func__); } route.session[0].num_copps = copp_cnt; for (i = 0; i < copp_cnt; 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); if (tmp >= 0 && tmp < AFE_MAX_PORTS) route.session[0].copp_id[i] = atomic_read(&this_adm.copp_id[tmp]); } if (copp_cnt % 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++) { int tmp; tmp = afe_get_port_index(port_id[i]); if (tmp >= 0 && tmp < AFE_MAX_PORTS) rtac_add_adm_device(port_id[i], atomic_read(&this_adm.copp_id[tmp]), path, session_id); else pr_debug("%s: Invalid port index %d", __func__, tmp); } return 0; fail_cmd: return ret; }
int msm_snddev_set_dec(int popp_id, int copp_id, int set, int rate, int mode) { int rc = 0, i = 0, num_copps; struct route_payload payload; if ((popp_id >= MAX_SESSIONS) || (popp_id <= 0)) { pr_err("%s: Invalid session id %d\n", __func__, popp_id); return 0; } mutex_lock(&routing_info.adm_mutex); if (set) { rc = adm_open(copp_id, ADM_PATH_PLAYBACK, rate, mode, DEFAULT_COPP_TOPOLOGY); if (rc < 0) { pr_err("%s: adm open fail rc[%d]\n", __func__, rc); rc = -EINVAL; mutex_unlock(&routing_info.adm_mutex); return rc; } msm_set_copp_id(popp_id, copp_id); pr_debug("%s:Session id=%d copp_id=%d\n", __func__, popp_id, copp_id); memset(payload.copp_ids, COPP_IGNORE, (sizeof(unsigned int) * AFE_MAX_PORTS)); num_copps = msm_check_multicopp_per_stream(popp_id, &payload); rc = adm_matrix_map(popp_id, ADM_PATH_PLAYBACK, num_copps, payload.copp_ids, copp_id); if (rc < 0) { pr_err("%s: matrix map failed rc[%d]\n", __func__, rc); adm_close(copp_id); rc = -EINVAL; mutex_unlock(&routing_info.adm_mutex); return rc; } #ifdef CONFIG_MSM8X60_RTAC for (i = 0; i < num_copps; i++) rtac_add_adm_device(payload.copp_ids[i], popp_id); #endif } else { for (i = 0; i < AFE_MAX_PORTS; i++) { if (routing_info.copp_list[popp_id][i] == copp_id) { rc = adm_close(copp_id); if (rc < 0) { pr_err("%s: adm close fail copp[%d]" "rc[%d]\n", __func__, copp_id, rc); rc = -EINVAL; mutex_unlock(&routing_info.adm_mutex); return rc; } msm_clear_copp_id(popp_id, copp_id); break; } } } if (copp_id == VOICE_PLAYBACK_TX) { rc = voice_start_playback(set); } mutex_unlock(&routing_info.adm_mutex); return rc; }
int msm_snddev_set_dec(int popp_id, int copp_id, int set, int rate, int mode) { int rc = 0, i = 0, num_copps; struct route_payload payload; if ((popp_id >= MAX_SESSIONS) || (popp_id <= 0)) { pr_err("%s: Invalid session id %d\n", __func__, popp_id); return 0; } mutex_lock(&routing_info.adm_mutex); if (set) { rc = adm_open(copp_id, ADM_PATH_PLAYBACK, rate, mode, DEFAULT_COPP_TOPOLOGY); if (rc < 0) { pr_err("%s: adm open fail rc[%d]\n", __func__, rc); rc = -EINVAL; goto fail_cmd; } rc = adm_matrix_map(popp_id, PLAYBACK, 1, &copp_id); if (rc < 0) { pr_err("%s: matrix map failed rc[%d]\n", __func__, rc); adm_close(copp_id); rc = -EINVAL; goto fail_cmd; msm_set_copp_id(popp_id, copp_id); pr_debug("%s:Session id=%d copp_id=%d\n", __func__, popp_id, copp_id); memset(payload.copp_ids, COPP_IGNORE, (sizeof(unsigned int) * AFE_MAX_PORTS)); num_copps = msm_check_multicopp_per_stream(popp_id, &payload); /* Multiple streams per copp is handled, one stream at a time */ rc = adm_matrix_map(popp_id, ADM_PATH_PLAYBACK, num_copps, payload.copp_ids, copp_id); if (rc < 0) { pr_err("%s: matrix map failed rc[%d]\n", __func__, rc); adm_close(copp_id); rc = -EINVAL; mutex_unlock(&routing_info.adm_mutex); return rc; } #ifdef CONFIG_MSM8X60_RTAC for (i = 0; i < num_copps; i++) rtac_add_adm_device(payload.copp_ids[i], popp_id); #endif } else { for (i = 0; i < AFE_MAX_PORTS; i++) { if (routing_info.copp_list[popp_id][i] == copp_id) { rc = adm_close(copp_id); if (rc < 0) { pr_err("%s: adm close fail copp[%d]" "rc[%d]\n", __func__, copp_id, rc); rc = -EINVAL; mutex_unlock(&routing_info.adm_mutex); return rc; } msm_clear_copp_id(popp_id, copp_id); break; } } } if (copp_id == VOICE_PLAYBACK_TX) { /* Signal uplink playback. */ rc = voice_start_playback(set); } mutex_unlock(&routing_info.adm_mutex); return rc; } EXPORT_SYMBOL(msm_snddev_set_dec); static int check_tx_copp_topology(int session_id) { int cnt; int ret_val = -ENOENT; cnt = adm_tx_topology_tbl.session_cnt; if (cnt) { do { if (adm_tx_topology_tbl.session_id[cnt-1] == session_id) ret_val = cnt-1; } while (--cnt); } return ret_val; }
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; 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); #ifdef CONFIG_MSM8X60_RTAC for (i = 0; i < num_copps; i++) rtac_add_adm_device(port_id[i], session_id); #endif return 0; fail_cmd: return ret; }
int adm_matrix_map(int session_id, int path, int num_copps, unsigned int *port_id, int copp_id, bool perf_mode) { struct adm_cmd_matrix_map_routings_v5 *route; struct adm_session_map_node_v5 *node; uint16_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 >= 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]:%#x 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; if (perf_mode) { route->hdr.dest_port = atomic_read(&this_adm.copp_low_latency_id[index]); } else { 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 = (uint16_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 < AFE_MAX_PORTS) { if (perf_mode) copps_list[i] = atomic_read(&this_adm.copp_low_latency_id[tmp]); else copps_list[i] = atomic_read(&this_adm.copp_id[tmp]); } else continue; pr_debug("%s: port_id[%#x]: %d, index: %d act coppid[0x%x]\n", __func__, i, port_id[i], tmp, copps_list[i] ); } 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 %#x 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 %#x\n", __func__, port_id[0]); ret = -EINVAL; goto fail_cmd; } for (i = 0; i < num_copps; i++) send_adm_cal(port_id[i], path, perf_mode); for (i = 0; i < num_copps; i++) { int tmp, copp_id; tmp = afe_get_port_index(port_id[i]); if (tmp >= 0 && tmp < AFE_MAX_PORTS) { if(!perf_mode) copp_id = atomic_read(&this_adm.copp_id[tmp]); else copp_id = atomic_read(&this_adm.copp_low_latency_id[tmp]); rtac_add_adm_device(port_id[i], copp_id, path, session_id); pr_debug("%s, copp_id: %d\n", __func__, copp_id); } else { pr_debug("%s: Invalid port index %d", __func__, tmp); } } fail_cmd: kfree(matrix_map); return ret; }