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

Commit c21b7142 authored by Aviral Gupta's avatar Aviral Gupta
Browse files

ASoC: mpq8092: Add the passthrough support in the compressed driver



Compressed passthrough gives the user the flexibility to decode the audio
data on end device.
Configure the ADSP so that the data gets passthrough without decoding.

Change-Id: I6bd073d55c14d4ed6f7c67829759aef3655eef82
Signed-off-by: default avatarAviral Gupta <aviralg@codeaurora.org>
parent a36eecd5
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, 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
@@ -22,6 +22,7 @@
#define ADM_CMDRSP_SHARED_MEM_MAP_REGIONS 0x00010323
#define ADM_CMD_SHARED_MEM_UNMAP_REGIONS 0x00010324

#define ADM_CMD_STREAM_DEVICE_MAP_ROUTINGS_V5	0x0001033D
#define ADM_CMD_MATRIX_MAP_ROUTINGS_V5 0x00010325

/* Enumeration for an audio Rx matrix ID.*/
@@ -29,6 +30,7 @@

#define ADM_MATRIX_ID_AUDIO_TX              1

#define ADM_COMPRESSED_AUDIO_OUT        2
/* Enumeration for an audio Tx matrix ID.*/
#define ADM_MATRIX_ID_AUDIOX              1

@@ -2281,6 +2283,7 @@ struct afe_port_cmdrsp_get_param_v2 {

#define NULL_COPP_TOPOLOGY				0x00010312
#define DEFAULT_COPP_TOPOLOGY				0x00010be3
#define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY		0x0001076B
#define DEFAULT_POPP_TOPOLOGY				0x00010be4
#define VPM_TX_SM_ECNS_COPP_TOPOLOGY			0x00010F71
#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY			0x00010F72
@@ -2696,6 +2699,17 @@ struct asm_multi_channel_pcm_enc_cfg_v2 {
#define ASM_MEDIA_FMT_AAC_AOT_PS             29
#define ASM_MEDIA_FMT_AAC_AOT_BSAC           22

#define AC3_DECODER	0x00010BF6
#define EAC3_DECODER	0x00010C3C
#define MP3		0x00010BE9
#define DTS		0x00010D88
#define DTS_LBR		0x00010DBB
#define MPEG4_AAC	0x00010BEA
#define ATRAC		0x00010D89
#define WMA_V10PRO	0x00010BF3
#define MAT		0x00010D8A
#define MP2		0x00010DBE

struct asm_aac_fmt_blk_v2 {
	struct apr_hdr hdr;
	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
@@ -3709,6 +3723,7 @@ struct asm_session_cmd_run_v2 {
#define ASM_SESSION_CMD_SUSPEND 0x00010DEC
#define ASM_SESSION_CMD_GET_SESSIONTIME_V3 0x00010D9D
#define ASM_SESSION_CMD_REGISTER_FOR_RX_UNDERFLOW_EVENTS 0x00010BD5
#define ADM_MULTI_CH_COPP_OPEN_PERF_MODE_BIT	(1<<13)

struct asm_session_cmd_rgstr_rx_underflow {
	struct apr_hdr hdr;
+2 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, 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
@@ -16,6 +16,7 @@
#define ADM_PATH_PLAYBACK 0x1
#define ADM_PATH_LIVE_REC 0x2
#define ADM_PATH_NONLIVE_REC 0x3
#define ADM_PATH_COMPRESSED_RX 0x5
#include <linux/qdsp6v2/rtac.h>
#include <sound/q6afe-v2.h>
#include <sound/q6audio-v2.h>
+8 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2014, 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
@@ -44,6 +44,11 @@
#define FORMAT_MULTI_CHANNEL_LINEAR_PCM 0x0012
#define FORMAT_AC3          0x0013
#define FORMAT_EAC3         0x0014
#define FORMAT_DTS	0x0016
#define FORMAT_ATRAC	0x0017
#define FORMAT_MAT	0x0018
#define FORMAT_AAC	0x0019
#define FORMAT_DTS_LBR	0x001a

#define ENCDEC_SBCBITRATE   0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
@@ -216,6 +221,8 @@ int q6asm_stream_open_write_v2(struct audio_client *ac, uint32_t format,
				uint16_t bits_per_sample, int32_t stream_id,
				bool is_gapless_mode);

int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format);

int q6asm_open_read_write(struct audio_client *ac,
			uint32_t rd_format,
			uint32_t wr_format);
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ struct snd_compressed_buffer {
struct snd_compr_params {
	struct snd_compressed_buffer buffer;
	struct snd_codec codec;
	__u32 compr_passthr;
	__u8 no_wake_mode;
};

+54 −14
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ struct msm_compr_audio {
	struct audio_client *audio_client;

	uint32_t codec;
	uint32_t compr_passthr;
	void    *buffer; /* virtual address */
	uint32_t buffer_paddr; /* physical address */
	uint32_t app_pointer;
@@ -131,6 +132,8 @@ struct msm_compr_audio_effects {
	struct eq_params equalizer;
};

u32 compr_codecs[] = {SND_AUDIOCODEC_AC3};

static int msm_compr_set_volume(struct snd_compr_stream *cstream,
				uint32_t volume_l, uint32_t volume_r)
{
@@ -460,6 +463,28 @@ static int msm_compr_configure_dsp(struct snd_compr_stream *cstream)

	prtd->gapless_state.stream_opened[ac->stream_id] = 1;
	pr_debug("%s be_id %d\n", __func__, soc_prtd->dai_link->be_id);

	if (prtd->compr_passthr == true) {
		ret = q6asm_open_write_compressed(ac, prtd->codec);
		if (ret < 0) {
			pr_err("%s: Session out open failed\n", __func__);
			return -ENOMEM;
		}
		msm_pcm_routing_reg_phy_compr_stream(
				soc_prtd->dai_link->be_id,
				ac->perf_mode,
				prtd->session_id,
				SNDRV_PCM_STREAM_PLAYBACK,
				prtd->compr_passthr);
	} else {
		ret = q6asm_stream_open_write_v2(ac,
				prtd->codec, bits_per_sample,
				ac->stream_id, true/*gapless*/);
		if (ret < 0) {
			pr_err("%s: Session out open failed\n", __func__);
			return -ENOMEM;
		}

		msm_pcm_routing_reg_phy_stream(soc_prtd->dai_link->be_id,
				ac->perf_mode,
				prtd->session_id,
@@ -478,6 +503,7 @@ static int msm_compr_configure_dsp(struct snd_compr_stream *cstream)
		if (ret < 0)
			pr_err("%s: Send SoftVolume Param failed ret=%d\n",
					__func__, ret);
	}

	ret = q6asm_set_io_mode(ac, (COMPRESSED_IO | ASYNC_IO_MODE));
	if (ret < 0) {
@@ -668,6 +694,15 @@ static int msm_compr_free(struct snd_compr_stream *cstream)
	return 0;
}

int validate_codec_compr(__u32 codec_id)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(compr_codecs); i++)
		if (compr_codecs[i] == codec_id)
			return 0;
	return -EINVAL;
}

/* compress stream operations */
static int msm_compr_set_params(struct snd_compr_stream *cstream,
				struct snd_compr_params *params)
@@ -683,6 +718,8 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
	/* ToDo: remove duplicates */
	prtd->num_channels = prtd->codec_param.codec.ch_in;

	prtd->compr_passthr = params->compr_passthr;

	switch (prtd->codec_param.codec.sample_rate) {
	case SNDRV_PCM_RATE_8000:
		prtd->sample_rate = 8000;
@@ -707,8 +744,11 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
		prtd->sample_rate = 48000;
		break;
	}

	pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate);
	if (prtd->compr_passthr && validate_codec_compr(params->codec.id)) {
		pr_err("%s codec not supported in passthrough, id =%d\n",
				__func__, params->codec.id);
		return -EINVAL;
	}

	switch (params->codec.id) {
	case SND_AUDIOCODEC_MP3: {
Loading