Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42160048 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: msm: qdsp6v2: separate multi channel map for playback and record"

parents 869dc6e1 6df22525
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -87,9 +87,9 @@ void adm_ec_ref_rx_id(int port_id);

int adm_get_lowlatency_copp_id(int port_id);

void adm_set_multi_ch_map(char *channel_map);
int adm_set_multi_ch_map(char *channel_map, int path);

void adm_get_multi_ch_map(char *channel_map);
int adm_get_multi_ch_map(char *channel_map, int path);

int adm_validate_and_get_port_index(int port_id);

+3 −3
Original line number Diff line number Diff line
/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -472,7 +472,7 @@ static int msm_qti_pp_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
	char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
	int i;

	adm_get_multi_ch_map(channel_map);
	adm_get_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);
	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		ucontrol->value.integer.value[i] = (unsigned) channel_map[i];
	return 0;
@@ -486,7 +486,7 @@ static int msm_qti_pp_put_channel_map_mixer(struct snd_kcontrol *kcontrol,

	for (i = 0; i < PCM_FORMAT_MAX_NUM_CHANNEL; i++)
		channel_map[i] = (char)(ucontrol->value.integer.value[i]);
	adm_set_multi_ch_map(channel_map);
	adm_set_multi_ch_map(channel_map, ADM_PATH_PLAYBACK);

	return 0;
}
+121 −57
Original line number Diff line number Diff line
@@ -83,8 +83,15 @@ struct adm_multi_ch_map {
	char channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];
};

static struct adm_multi_ch_map multi_ch_map = { false,
#define ADM_MCH_MAP_IDX_PLAYBACK 0
#define ADM_MCH_MAP_IDX_REC 1
static struct adm_multi_ch_map multi_ch_maps[2] = {
							{ false,
							{0, 0, 0, 0, 0, 0, 0, 0}
							},
							{ false,
							{0, 0, 0, 0, 0, 0, 0, 0}
							}
};

static int adm_get_parameters[MAX_COPPS_PER_PORT * ADM_GET_PARAMETER_LENGTH];
@@ -994,19 +1001,45 @@ static void adm_callback_debug_print(struct apr_client_data *data)
			__func__, data->opcode, data->payload_size);
}

void adm_set_multi_ch_map(char *channel_map)
int adm_set_multi_ch_map(char *channel_map, int path)
{
	memcpy(multi_ch_map.channel_mapping, channel_map,
	int idx;

	if (path == ADM_PATH_PLAYBACK) {
		idx = ADM_MCH_MAP_IDX_PLAYBACK;
	} else if (path == ADM_PATH_LIVE_REC) {
		idx = ADM_MCH_MAP_IDX_REC;
	} else {
		pr_err("%s: invalid attempt to set path %d\n", __func__, path);
		return -EINVAL;
	}

	memcpy(multi_ch_maps[idx].channel_mapping, channel_map,
		PCM_FORMAT_MAX_NUM_CHANNEL);
	multi_ch_map.set_channel_map = true;
	multi_ch_maps[idx].set_channel_map = true;

	return 0;
}

void adm_get_multi_ch_map(char *channel_map)
int adm_get_multi_ch_map(char *channel_map, int path)
{
	if (multi_ch_map.set_channel_map) {
		memcpy(channel_map, multi_ch_map.channel_mapping,
	int idx;

	if (path == ADM_PATH_PLAYBACK) {
		idx = ADM_MCH_MAP_IDX_PLAYBACK;
	} else if (path == ADM_PATH_LIVE_REC) {
		idx = ADM_MCH_MAP_IDX_REC;
	} else {
		pr_err("%s: invalid attempt to get path %d\n", __func__, path);
		return -EINVAL;
	}

	if (multi_ch_maps[idx].set_channel_map) {
		memcpy(channel_map, multi_ch_maps[idx].channel_mapping,
		       PCM_FORMAT_MAX_NUM_CHANNEL);
	}

	return 0;
}

static int32_t adm_callback(struct apr_client_data *data, void *priv)
@@ -1814,6 +1847,79 @@ fail_cmd:
	return ret;
}

int adm_arrange_mch_map(struct adm_cmd_device_open_v5 *open, int path,
			 int channel_mode)
{
	int rc = 0, idx;

	memset(open->dev_channel_mapping, 0,
	       PCM_FORMAT_MAX_NUM_CHANNEL);

	if (channel_mode == 1)	{
		open->dev_channel_mapping[0] = PCM_CHANNEL_FC;
	} else if (channel_mode == 2) {
		open->dev_channel_mapping[0] = PCM_CHANNEL_FL;
		open->dev_channel_mapping[1] = PCM_CHANNEL_FR;
	} else if (channel_mode == 3)	{
		open->dev_channel_mapping[0] = PCM_CHANNEL_FL;
		open->dev_channel_mapping[1] = PCM_CHANNEL_FR;
		open->dev_channel_mapping[2] = PCM_CHANNEL_FC;
	} else if (channel_mode == 4) {
		open->dev_channel_mapping[0] = PCM_CHANNEL_FL;
		open->dev_channel_mapping[1] = PCM_CHANNEL_FR;
		open->dev_channel_mapping[2] = PCM_CHANNEL_LS;
		open->dev_channel_mapping[3] = PCM_CHANNEL_RS;
	} else if (channel_mode == 5) {
		open->dev_channel_mapping[0] = PCM_CHANNEL_FL;
		open->dev_channel_mapping[1] = PCM_CHANNEL_FR;
		open->dev_channel_mapping[2] = PCM_CHANNEL_FC;
		open->dev_channel_mapping[3] = PCM_CHANNEL_LS;
		open->dev_channel_mapping[4] = PCM_CHANNEL_RS;
	} else if (channel_mode == 6) {
		open->dev_channel_mapping[0] = PCM_CHANNEL_FL;
		open->dev_channel_mapping[1] = PCM_CHANNEL_FR;
		open->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
		open->dev_channel_mapping[3] = PCM_CHANNEL_FC;
		open->dev_channel_mapping[4] = PCM_CHANNEL_LS;
		open->dev_channel_mapping[5] = PCM_CHANNEL_RS;
	} else if (channel_mode == 8) {
		open->dev_channel_mapping[0] = PCM_CHANNEL_FL;
		open->dev_channel_mapping[1] = PCM_CHANNEL_FR;
		open->dev_channel_mapping[2] = PCM_CHANNEL_LFE;
		open->dev_channel_mapping[3] = PCM_CHANNEL_FC;
		open->dev_channel_mapping[4] = PCM_CHANNEL_LS;
		open->dev_channel_mapping[5] = PCM_CHANNEL_RS;
		open->dev_channel_mapping[6] = PCM_CHANNEL_LB;
		open->dev_channel_mapping[7] = PCM_CHANNEL_RB;
	} else {
		pr_err("%s: invalid num_chan %d\n", __func__,
			channel_mode);
		rc = -EINVAL;
		goto inval_ch_mod;
	}

	switch (path) {
	case ADM_PATH_PLAYBACK:
		idx = ADM_MCH_MAP_IDX_PLAYBACK;
		break;
	case ADM_PATH_LIVE_REC:
		idx = ADM_MCH_MAP_IDX_REC;
		break;
	default:
		goto non_mch_path;
		break;
	};

	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);

non_mch_path:
inval_ch_mod:
	return rc;
}

int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
	     int perf_mode, uint16_t bit_width, int app_type, int acdb_id)
{
@@ -1963,53 +2069,11 @@ int adm_open(int port_id, int path, int rate, int channel_mode, int topology,
		WARN_ON((perf_mode == ULTRA_LOW_LATENCY_PCM_MODE) &&
			(rate != ULL_SUPPORTED_SAMPLE_RATE));
		open.sample_rate  = rate;
		memset(open.dev_channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);

		if (channel_mode == 1)	{
			open.dev_channel_mapping[0] = PCM_CHANNEL_FC;
		} else if (channel_mode == 2) {
			open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
			open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
		} else if (channel_mode == 3)	{
			open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
			open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
			open.dev_channel_mapping[2] = PCM_CHANNEL_FC;
		} else if (channel_mode == 4) {
			open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
			open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
			open.dev_channel_mapping[2] = PCM_CHANNEL_LS;
			open.dev_channel_mapping[3] = PCM_CHANNEL_RS;
		} else if (channel_mode == 5) {
			open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
			open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
			open.dev_channel_mapping[2] = PCM_CHANNEL_FC;
			open.dev_channel_mapping[3] = PCM_CHANNEL_LS;
			open.dev_channel_mapping[4] = PCM_CHANNEL_RS;
		} else if (channel_mode == 6) {
			open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
			open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
			open.dev_channel_mapping[2] = PCM_CHANNEL_LFE;
			open.dev_channel_mapping[3] = PCM_CHANNEL_FC;
			open.dev_channel_mapping[4] = PCM_CHANNEL_LS;
			open.dev_channel_mapping[5] = PCM_CHANNEL_RS;
		} else if (channel_mode == 8) {
			open.dev_channel_mapping[0] = PCM_CHANNEL_FL;
			open.dev_channel_mapping[1] = PCM_CHANNEL_FR;
			open.dev_channel_mapping[2] = PCM_CHANNEL_LFE;
			open.dev_channel_mapping[3] = PCM_CHANNEL_FC;
			open.dev_channel_mapping[4] = PCM_CHANNEL_LS;
			open.dev_channel_mapping[5] = PCM_CHANNEL_RS;
			open.dev_channel_mapping[6] = PCM_CHANNEL_LB;
			open.dev_channel_mapping[7] = PCM_CHANNEL_RB;
		} else {
			pr_err("%s: invalid num_chan %d\n", __func__,
					channel_mode);
			return -EINVAL;
		}
		if ((open.dev_num_channel > 2) && multi_ch_map.set_channel_map)
			memcpy(open.dev_channel_mapping,
			       multi_ch_map.channel_mapping,
			       PCM_FORMAT_MAX_NUM_CHANNEL);
		ret = adm_arrange_mch_map(&open, path, channel_mode);

		if (ret)
			return ret;

		pr_debug("%s: port_id=0x%x rate=%d topology_id=0x%X\n",
			__func__, open.endpoint_id_1, open.sample_rate,