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

Commit 11d5ee2d authored by Satya Krishna Pindiproli's avatar Satya Krishna Pindiproli Committed by Gerrit - the friendly Code Review server
Browse files

ASoC: msm: qdsp6v2: set proper channel mapping for ALAC format



Current channel mapping of multichannel ALAC clips is different
from the one the decoder expects due to which playback of
multichannel ALAC clips does not work in non-tunnel mode.

Set the pre-defined channel mapping according to the ALAC specification
for multichannel ALAC clips based on the number of channels for
decoding to succeed.

CRs-Fixed: 843138
Change-Id: I7c8b7cf8cc555b9667a1713d59999460e6251732
Signed-off-by: default avatarSatya Krishna Pindiproli <satyak@codeaurora.org>
parent f7d9868d
Loading
Loading
Loading
Loading
+74 −4
Original line number Diff line number Diff line
@@ -27,6 +27,8 @@ static struct dentry *config_debugfs_create_file(const char *name, void *data)
				NULL, (void *)data, &audio_alac_debug_fops);
}

static int alac_channel_map(u8 *channel_mapping, uint32_t channels);

static long audio_ioctl_shared(struct file *file, unsigned int cmd,
						void *arg)
{
@@ -37,13 +39,25 @@ static long audio_ioctl_shared(struct file *file, unsigned int cmd,
	case AUDIO_START: {
		struct asm_alac_cfg alac_cfg;
		struct msm_audio_alac_config *alac_config;
		u8 channel_mapping[PCM_FORMAT_MAX_NUM_CHANNEL];

		memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);

		if (alac_channel_map(channel_mapping,
			audio->pcm_cfg.channel_count)) {
			pr_err("%s: setting channel map failed %d\n",
					__func__, audio->pcm_cfg.channel_count);
		}

		pr_debug("%s[%p]: AUDIO_START session_id[%d]\n", __func__,
						audio, audio->ac->session);
		if (audio->feedback == NON_TUNNEL_MODE) {
			/* Configure PCM output block */
			rc = q6asm_enc_cfg_blk_pcm(audio->ac,
			rc = q6asm_enc_cfg_blk_pcm_v2(audio->ac,
					audio->pcm_cfg.sample_rate,
					audio->pcm_cfg.channel_count);
					audio->pcm_cfg.channel_count,
					16, /*bits per sample*/
					false, channel_mapping);
			if (rc < 0) {
				pr_err("pcm output block config failed\n");
				break;
@@ -132,7 +146,6 @@ static long audio_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
		break;
	}
	default: {
		pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
		rc = audio->codec_ioctl(file, cmd, arg);
		if (rc)
			pr_err("Failed in utils_ioctl: %d\n", rc);
@@ -233,7 +246,6 @@ static long audio_compat_ioctl(struct file *file, unsigned int cmd,
		break;
	}
	default: {
		pr_debug("%s[%p]: Calling utils ioctl\n", __func__, audio);
		rc = audio->codec_compat_ioctl(file, cmd, arg);
		if (rc)
			pr_err("Failed in utils_ioctl: %d\n", rc);
@@ -330,6 +342,64 @@ fail:
	return rc;
}

static int alac_channel_map(u8 *channel_mapping, uint32_t channels)
{
	u8 *lchannel_mapping;

	lchannel_mapping = channel_mapping;
	pr_debug("%s:  channels passed: %d\n", __func__, channels);
	if (channels == 1)  {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
	} else if (channels == 2) {
		lchannel_mapping[0] = PCM_CHANNEL_FL;
		lchannel_mapping[1] = PCM_CHANNEL_FR;
	} else if (channels == 3) {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
		lchannel_mapping[1] = PCM_CHANNEL_FL;
		lchannel_mapping[2] = PCM_CHANNEL_FR;
	} else if (channels == 4) {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
		lchannel_mapping[1] = PCM_CHANNEL_FL;
		lchannel_mapping[2] = PCM_CHANNEL_FR;
		lchannel_mapping[3] = PCM_CHANNEL_CS;
	} else if (channels == 5) {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
		lchannel_mapping[1] = PCM_CHANNEL_FL;
		lchannel_mapping[2] = PCM_CHANNEL_FR;
		lchannel_mapping[3] = PCM_CHANNEL_LS;
		lchannel_mapping[4] = PCM_CHANNEL_RS;
	} else if (channels == 6) {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
		lchannel_mapping[1] = PCM_CHANNEL_FL;
		lchannel_mapping[2] = PCM_CHANNEL_FR;
		lchannel_mapping[3] = PCM_CHANNEL_LS;
		lchannel_mapping[4] = PCM_CHANNEL_RS;
		lchannel_mapping[5] = PCM_CHANNEL_LFE;
	} else if (channels == 7) {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
		lchannel_mapping[1] = PCM_CHANNEL_FL;
		lchannel_mapping[2] = PCM_CHANNEL_FR;
		lchannel_mapping[3] = PCM_CHANNEL_LS;
		lchannel_mapping[4] = PCM_CHANNEL_RS;
		lchannel_mapping[5] = PCM_CHANNEL_CS;
		lchannel_mapping[6] = PCM_CHANNEL_LFE;
	} else if (channels == 8) {
		lchannel_mapping[0] = PCM_CHANNEL_FC;
		lchannel_mapping[1] = PCM_CHANNEL_FLC;
		lchannel_mapping[2] = PCM_CHANNEL_FRC;
		lchannel_mapping[3] = PCM_CHANNEL_FL;
		lchannel_mapping[4] = PCM_CHANNEL_FR;
		lchannel_mapping[5] = PCM_CHANNEL_LS;
		lchannel_mapping[6] = PCM_CHANNEL_RS;
		lchannel_mapping[7] = PCM_CHANNEL_LFE;
	} else {
		pr_err("%s: ERROR.unsupported num_ch = %u\n",
				__func__, channels);
		return -EINVAL;
	}
	return 0;
}

static const struct file_operations audio_alac_fops = {
	.owner = THIS_MODULE,
	.open = audio_open,
+5 −0
Original line number Diff line number Diff line
@@ -314,6 +314,11 @@ int q6asm_enc_cfg_blk_aac(struct audio_client *ac,
int q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
			uint32_t rate, uint32_t channels);

int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
			uint32_t rate, uint32_t channels,
			uint16_t bits_per_sample,
			bool use_default_chmap, u8 *channel_map);

int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
			uint32_t rate, uint32_t channels,
			uint16_t bits_per_sample);
+29 −5
Original line number Diff line number Diff line
@@ -2873,8 +2873,9 @@ fail_cmd:
		return rc;
}

static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
		uint32_t rate, uint32_t channels, uint16_t bits_per_sample)
int q6asm_enc_cfg_blk_pcm_v2(struct audio_client *ac,
		uint32_t rate, uint32_t channels, uint16_t bits_per_sample,
		bool use_default_chmap, u8 *channel_map)
{
	struct asm_multi_channel_pcm_enc_cfg_v2  enc_cfg;
	u8 *channel_mapping;
@@ -2882,6 +2883,12 @@ static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac,

	int rc = 0;

	if (!use_default_chmap && (channel_map == NULL)) {
		pr_err("%s: No valid chan map and can't use default\n",
				__func__);
		return -EINVAL;
	}

	pr_debug("%s: Session %d, rate = %d, channels = %d\n", __func__,
			 ac->session, rate, channels);

@@ -2903,10 +2910,19 @@ static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac,

	memset(channel_mapping, 0, PCM_FORMAT_MAX_NUM_CHANNEL);

	if (use_default_chmap) {
		pr_debug("%s: setting default channel map for %d channels",
		__func__, channels);
		if (q6asm_map_channels(channel_mapping, channels)) {
		pr_err("%s: map channels failed %d", __func__, channels);
			pr_err("%s: map channels failed %d\n",
			 __func__, channels);
			return -EINVAL;
		}
	} else {
		pr_debug("%s: Using pre-defined channel map", __func__);
		memcpy(channel_mapping, channel_map,
			PCM_FORMAT_MAX_NUM_CHANNEL);
	}

	rc = apr_send_pkt(ac->apr, (uint32_t *) &enc_cfg);
	if (rc < 0) {
@@ -2931,6 +2947,14 @@ fail_cmd:
	return -EINVAL;
}


static int __q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
		uint32_t rate, uint32_t channels, uint16_t bits_per_sample)
{
	return q6asm_enc_cfg_blk_pcm_v2(ac, rate, channels,
					bits_per_sample, true, NULL);
}

int q6asm_enc_cfg_blk_pcm(struct audio_client *ac,
			uint32_t rate, uint32_t channels)
{