示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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;
}
示例#4
0
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;
}
示例#5
0
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;
}
示例#6
0
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;
}