Ver Fonte

Merge "dsp: adm: Add support for port specific channel map"

qctecmdr há 6 anos atrás
pai
commit
06eacac35e
2 ficheiros alterados com 64 adições e 18 exclusões
  1. 62 18
      dsp/q6adm.c
  2. 2 0
      include/dsp/q6adm-v2.h

+ 62 - 18
dsp/q6adm.c

@@ -128,6 +128,8 @@ static struct adm_multi_ch_map multi_ch_maps[2] = {
 			}
 			}
 };
 };
 
 
+static struct adm_multi_ch_map port_channel_map[AFE_MAX_PORTS];
+
 static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
 static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
 static int adm_module_topo_list[MAX_COPPS_PER_PORT *
 static int adm_module_topo_list[MAX_COPPS_PER_PORT *
 				ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH];
 				ADM_GET_TOPO_MODULE_INSTANCE_LIST_LENGTH];
@@ -146,7 +148,8 @@ void msm_dts_srs_release_lock(void)
 static int adm_arrange_mch_map_v8(
 static int adm_arrange_mch_map_v8(
 		struct adm_device_endpoint_payload *ep_payload,
 		struct adm_device_endpoint_payload *ep_payload,
 		int path,
 		int path,
-		int channel_mode);
+		int channel_mode,
+		int port_idx);
 
 
 /**
 /**
  * adm_validate_and_get_port_index -
  * adm_validate_and_get_port_index -
@@ -578,7 +581,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id,
 		index += ch_mixer->output_channel;
 		index += ch_mixer->output_channel;
 	} else {
 	} else {
 		ep_params.dev_num_channel = ch_mixer->output_channel;
 		ep_params.dev_num_channel = ch_mixer->output_channel;
-		adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+		adm_arrange_mch_map_v8(&ep_params, path_type,
+				       ep_params.dev_num_channel, port_idx);
 		for (i = 0; i < ch_mixer->output_channel; i++)
 		for (i = 0; i < ch_mixer->output_channel; i++)
 			adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
 			adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
 	}
 	}
@@ -589,7 +593,8 @@ int adm_programable_channel_mixer(int port_id, int copp_idx, int session_id,
 		index += ch_mixer->input_channel;
 		index += ch_mixer->input_channel;
 	} else {
 	} else {
 		ep_params.dev_num_channel = ch_mixer->input_channels[channel_index];
 		ep_params.dev_num_channel = ch_mixer->input_channels[channel_index];
-		adm_arrange_mch_map_v8(&ep_params, path_type, ep_params.dev_num_channel);
+		adm_arrange_mch_map_v8(&ep_params, path_type,
+				       ep_params.dev_num_channel, port_idx);
 		for (i = 0; i < ch_mixer->input_channels[channel_index]; i++)
 		for (i = 0; i < ch_mixer->input_channels[channel_index]; i++)
 			adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
 			adm_pspd_params[index++] = ep_params.dev_channel_mapping[i];
 	}
 	}
@@ -1302,6 +1307,31 @@ int adm_get_multi_ch_map(char *channel_map, int path)
 }
 }
 EXPORT_SYMBOL(adm_get_multi_ch_map);
 EXPORT_SYMBOL(adm_get_multi_ch_map);
 
 
+/**
+ * adm_set_port_multi_ch_map -
+ *        Update port specific channel map info
+ *
+ * @channel_map: pointer with channel map info
+ * @port_id: port for which chmap is set
+ */
+void adm_set_port_multi_ch_map(char *channel_map, int port_id)
+{
+	int port_idx;
+
+	port_id = q6audio_convert_virtual_to_portid(port_id);
+	port_idx = adm_validate_and_get_port_index(port_id);
+
+	if (port_idx < 0) {
+		pr_err("%s: Invalid port_id 0x%x\n", __func__, port_id);
+		return;
+	}
+
+	memcpy(port_channel_map[port_idx].channel_mapping, channel_map,
+			PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+	port_channel_map[port_idx].set_channel_map = true;
+}
+EXPORT_SYMBOL(adm_set_port_multi_ch_map);
+
 static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
 static int adm_process_get_param_response(u32 opcode, u32 idx, u32 *payload,
 					  u32 payload_size)
 					  u32 payload_size)
 {
 {
@@ -2380,7 +2410,7 @@ fail_cmd:
 EXPORT_SYMBOL(adm_connect_afe_port);
 EXPORT_SYMBOL(adm_connect_afe_port);
 
 
 int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
 int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
-			 int channel_mode)
+			 int channel_mode, int port_idx)
 {
 {
 	int rc = 0, idx;
 	int rc = 0, idx;
 
 
@@ -2398,10 +2428,18 @@ int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
 	default:
 	default:
 		goto non_mch_path;
 		goto non_mch_path;
 	};
 	};
-	if ((open->dev_num_channel > 2) && multi_ch_maps[idx].set_channel_map) {
-		memcpy(open->dev_channel_mapping,
-			multi_ch_maps[idx].channel_mapping,
-			PCM_FORMAT_MAX_NUM_CHANNEL);
+
+	if ((open->dev_num_channel > 2) &&
+		(port_channel_map[port_idx].set_channel_map ||
+		 multi_ch_maps[idx].set_channel_map)) {
+		if (port_channel_map[port_idx].set_channel_map)
+			memcpy(open->dev_channel_mapping,
+				port_channel_map[port_idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL);
+		else
+			memcpy(open->dev_channel_mapping,
+				multi_ch_maps[idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL);
 	} else {
 	} else {
 		if (channel_mode == 1) {
 		if (channel_mode == 1) {
 			open->dev_channel_mapping[0] = PCM_CHANNEL_FC;
 			open->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -2515,8 +2553,7 @@ int adm_arrange_mch_ep2_map(struct adm_cmd_device_open_v6 *open_v6,
 
 
 static int adm_arrange_mch_map_v8(
 static int adm_arrange_mch_map_v8(
 		struct adm_device_endpoint_payload *ep_payload,
 		struct adm_device_endpoint_payload *ep_payload,
-		int path,
-		int channel_mode)
+		int path, int channel_mode, int port_idx)
 {
 {
 	int rc = 0, idx;
 	int rc = 0, idx;
 
 
@@ -2535,10 +2572,16 @@ static int adm_arrange_mch_map_v8(
 	};
 	};
 
 
 	if ((ep_payload->dev_num_channel > 2) &&
 	if ((ep_payload->dev_num_channel > 2) &&
-			multi_ch_maps[idx].set_channel_map) {
-		memcpy(ep_payload->dev_channel_mapping,
-			multi_ch_maps[idx].channel_mapping,
-			PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+		(port_channel_map[port_idx].set_channel_map ||
+		 multi_ch_maps[idx].set_channel_map)) {
+		if (port_channel_map[port_idx].set_channel_map)
+			memcpy(ep_payload->dev_channel_mapping,
+				port_channel_map[port_idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL_V8);
+		else
+			memcpy(ep_payload->dev_channel_mapping,
+				multi_ch_maps[idx].channel_mapping,
+				PCM_FORMAT_MAX_NUM_CHANNEL_V8);
 	} else {
 	} else {
 		if (channel_mode == 1) {
 		if (channel_mode == 1) {
 			ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
 			ep_payload->dev_channel_mapping[0] = PCM_CHANNEL_FC;
@@ -3052,7 +3095,7 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
 			ep1_payload.bit_width = bit_width;
 			ep1_payload.bit_width = bit_width;
 			ep1_payload.sample_rate  = rate;
 			ep1_payload.sample_rate  = rate;
 			ret = adm_arrange_mch_map_v8(&ep1_payload, path,
 			ret = adm_arrange_mch_map_v8(&ep1_payload, path,
-					channel_mode);
+					channel_mode, port_idx);
 			if (ret)
 			if (ret)
 				return ret;
 				return ret;
 
 
@@ -3165,8 +3208,8 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
 				(rate != ULL_SUPPORTED_SAMPLE_RATE));
 				(rate != ULL_SUPPORTED_SAMPLE_RATE));
 			open.sample_rate  = rate;
 			open.sample_rate  = rate;
 
 
-			ret = adm_arrange_mch_map(&open, path, channel_mode);
-
+			ret = adm_arrange_mch_map(&open, path, channel_mode,
+						  port_idx);
 			if (ret)
 			if (ret)
 				return ret;
 				return ret;
 
 
@@ -3314,7 +3357,7 @@ void adm_copp_mfc_cfg(int port_id, int copp_idx, int dst_sample_rate)
 		atomic_read(&this_adm.copp.channels[port_idx][copp_idx]);
 		atomic_read(&this_adm.copp.channels[port_idx][copp_idx]);
 
 
 	rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK,
 	rc = adm_arrange_mch_map(&open, ADM_PATH_PLAYBACK,
-		mfc_cfg.num_channels);
+		mfc_cfg.num_channels, port_idx);
 	if (rc < 0) {
 	if (rc < 0) {
 		pr_err("%s: unable to get channal map\n", __func__);
 		pr_err("%s: unable to get channal map\n", __func__);
 		goto fail_cmd;
 		goto fail_cmd;
@@ -3671,6 +3714,7 @@ int adm_close(int port_id, int perf_mode, int copp_idx)
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
+	port_channel_map[port_idx].set_channel_map = false;
 	if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode
 	if (this_adm.copp.adm_delay[port_idx][copp_idx] && perf_mode
 		== LEGACY_PCM_MODE) {
 		== LEGACY_PCM_MODE) {
 		atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx],
 		atomic_set(&this_adm.copp.adm_delay_stat[port_idx][copp_idx],

+ 2 - 0
include/dsp/q6adm-v2.h

@@ -145,6 +145,8 @@ int adm_set_multi_ch_map(char *channel_map, int path);
 
 
 int adm_get_multi_ch_map(char *channel_map, int path);
 int adm_get_multi_ch_map(char *channel_map, int path);
 
 
+void adm_set_port_multi_ch_map(char *channel_map, int port_id);
+
 int adm_validate_and_get_port_index(int port_id);
 int adm_validate_and_get_port_index(int port_id);
 
 
 int adm_get_default_copp_idx(int port_id);
 int adm_get_default_copp_idx(int port_id);