summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPreetam Singh Ranawat <apranawat@codeaurora.org>2016-08-18 12:02:14 +0530
committerPhani Kumar Uppalapati <phaniu@codeaurora.org>2016-08-20 14:42:05 -0700
commitfc9f30ee3d3977b9d5ef697f46bd2df74c6e1452 (patch)
tree1583817a4e2d8788d58f94643b67c49079ee7185
parent83728d257501fd95ff3ffcbff1e4c976f48b36e6 (diff)
ASoC: msm: Add support for native DSD playabck
Add DSD playback support in compress offload passthrough mode. Add DAPM widget in routing driver for DSD playback over SLIM_2_RX backend. CRs-Fixed: 1056422 Change-Id: I398db5f6deded10a515f05277b6316a93f9e14ab Signed-off-by: Preetam Singh Ranawat <apranawat@codeaurora.org>
-rw-r--r--include/sound/apr_audio-v2.h25
-rw-r--r--include/sound/q6asm-v2.h4
-rw-r--r--[-rwxr-xr-x]sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c37
-rw-r--r--sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c11
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c85
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h2
-rw-r--r--sound/soc/msm/qdsp6v2/q6asm.c72
7 files changed, 224 insertions, 12 deletions
diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h
index 3464726c408a..695e33f4d1cf 100644
--- a/include/sound/apr_audio-v2.h
+++ b/include/sound/apr_audio-v2.h
@@ -3375,6 +3375,7 @@ struct afe_lpass_core_shared_clk_config_command {
#define DEFAULT_COPP_TOPOLOGY 0x00010314
#define DEFAULT_POPP_TOPOLOGY 0x00010BE4
#define COMPRESSED_PASSTHROUGH_DEFAULT_TOPOLOGY 0x0001076B
+#define COMPRESS_PASSTHROUGH_NONE_TOPOLOGY 0x00010774
#define VPM_TX_SM_ECNS_COPP_TOPOLOGY 0x00010F71
#define VPM_TX_DM_FLUENCE_COPP_TOPOLOGY 0x00010F72
#define VPM_TX_QMIC_FLUENCE_COPP_TOPOLOGY 0x00010F75
@@ -3590,6 +3591,15 @@ struct asm_ape_cfg {
u32 seek_table_present;
};
+struct asm_dsd_cfg {
+ u16 num_version;
+ u16 is_bitwise_big_endian;
+ u16 dsd_channel_block_size;
+ u16 num_channels;
+ u8 channel_mapping[8];
+ u32 dsd_data_rate;
+};
+
struct asm_softpause_params {
u32 enable;
u32 period;
@@ -4158,6 +4168,19 @@ struct asm_ape_fmt_blk_v2 {
} __packed;
+struct asm_dsd_fmt_blk_v2 {
+ struct apr_hdr hdr;
+ struct asm_data_cmd_media_fmt_update_v2 fmtblk;
+
+ u16 num_version;
+ u16 is_bitwise_big_endian;
+ u16 dsd_channel_block_size;
+ u16 num_channels;
+ u8 channel_mapping[8];
+ u32 dsd_data_rate;
+
+} __packed;
+
#define ASM_MEDIA_FMT_AMRNB_FS 0x00010BEB
/* Enumeration for 4.75 kbps AMR-NB Encoding mode. */
@@ -4566,6 +4589,7 @@ struct asm_amrwbplus_fmt_blk_v2 {
#define ASM_MEDIA_FMT_ALAC 0x00012F31
#define ASM_MEDIA_FMT_VORBIS 0x00010C15
#define ASM_MEDIA_FMT_APE 0x00012F32
+#define ASM_MEDIA_FMT_DSD 0x00012F3E
/* Media format ID for adaptive transform acoustic coding. This
@@ -9565,6 +9589,7 @@ enum {
LEGACY_PCM = 0,
COMPRESSED_PASSTHROUGH,
COMPRESSED_PASSTHROUGH_CONVERT,
+ COMPRESSED_PASSTHROUGH_DSD,
};
#define AUDPROC_MODULE_ID_COMPRESSED_MUTE 0x00010770
diff --git a/include/sound/q6asm-v2.h b/include/sound/q6asm-v2.h
index 8339d538d578..dadc2f7a4eae 100644
--- a/include/sound/q6asm-v2.h
+++ b/include/sound/q6asm-v2.h
@@ -52,6 +52,7 @@
#define FORMAT_G711_ALAW_FS 0x001a
#define FORMAT_G711_MLAW_FS 0x001b
#define FORMAT_DTS 0x001c
+#define FORMAT_DSD 0x001d
#define ENCDEC_SBCBITRATE 0x0001
#define ENCDEC_IMMEDIATE_DECODE 0x0002
@@ -471,6 +472,9 @@ int q6asm_stream_media_format_block_vorbis(struct audio_client *ac,
int q6asm_media_format_block_ape(struct audio_client *ac,
struct asm_ape_cfg *cfg, int stream_id);
+int q6asm_media_format_block_dsd(struct audio_client *ac,
+ struct asm_dsd_cfg *cfg, int stream_id);
+
int q6asm_ds1_set_endp_params(struct audio_client *ac,
int param_id, int param_value);
diff --git a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
index 08c2b89de646..7e0f790b30e9 100755..100644
--- a/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-compress-q6-v2.c
@@ -96,7 +96,7 @@ struct msm_compr_gapless_state {
static unsigned int supported_sample_rates[] = {
8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, 48000, 64000,
- 88200, 96000, 176400, 192000
+ 88200, 96000, 176400, 192000, 352800, 384000, 2822400, 5644800
};
struct msm_compr_pdata {
@@ -170,7 +170,8 @@ struct msm_compr_audio {
};
const u32 compr_codecs[] = {
- SND_AUDIOCODEC_AC3, SND_AUDIOCODEC_EAC3, SND_AUDIOCODEC_DTS};
+ SND_AUDIOCODEC_AC3, SND_AUDIOCODEC_EAC3, SND_AUDIOCODEC_DTS,
+ SND_AUDIOCODEC_DSD};
struct query_audio_effect {
uint32_t mod_id;
@@ -642,7 +643,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
COMPR_PLAYBACK_MIN_NUM_FRAGMENTS;
prtd->compr_cap.max_fragments =
COMPR_PLAYBACK_MAX_NUM_FRAGMENTS;
- prtd->compr_cap.num_codecs = 13;
+ prtd->compr_cap.num_codecs = 14;
prtd->compr_cap.codecs[0] = SND_AUDIOCODEC_MP3;
prtd->compr_cap.codecs[1] = SND_AUDIOCODEC_AAC;
prtd->compr_cap.codecs[2] = SND_AUDIOCODEC_AC3;
@@ -656,6 +657,7 @@ static void populate_codec_list(struct msm_compr_audio *prtd)
prtd->compr_cap.codecs[10] = SND_AUDIOCODEC_ALAC;
prtd->compr_cap.codecs[11] = SND_AUDIOCODEC_APE;
prtd->compr_cap.codecs[12] = SND_AUDIOCODEC_DTS;
+ prtd->compr_cap.codecs[13] = SND_AUDIOCODEC_DSD;
}
static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
@@ -674,6 +676,7 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
struct asm_vorbis_cfg vorbis_cfg;
struct asm_alac_cfg alac_cfg;
struct asm_ape_cfg ape_cfg;
+ struct asm_dsd_cfg dsd_cfg;
union snd_codec_options *codec_options;
int ret = 0;
@@ -885,7 +888,20 @@ static int msm_compr_send_media_format_block(struct snd_compr_stream *cstream,
pr_debug("SND_AUDIOCODEC_DTS\n");
/* no media format block needed */
break;
-
+ case FORMAT_DSD:
+ pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__);
+ memset(&dsd_cfg, 0x0, sizeof(struct asm_dsd_cfg));
+ dsd_cfg.num_channels = prtd->num_channels;
+ dsd_cfg.dsd_data_rate = prtd->sample_rate;
+ dsd_cfg.num_version = 0;
+ dsd_cfg.is_bitwise_big_endian = 1;
+ dsd_cfg.dsd_channel_block_size = 1;
+ ret = q6asm_media_format_block_dsd(prtd->audio_client,
+ &dsd_cfg, stream_id);
+ if (ret < 0)
+ pr_err("%s: CMD DSD Format block failed ret %d\n",
+ __func__, ret);
+ break;
default:
pr_debug("%s, unsupported format, skip", __func__);
break;
@@ -1298,8 +1314,8 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
prtd->sample_rate = prtd->codec_param.codec.sample_rate;
pr_debug("%s: sample_rate %d\n", __func__, prtd->sample_rate);
- if (prtd->codec_param.codec.compr_passthr >= 0 &&
- prtd->codec_param.codec.compr_passthr <= 2)
+ if (prtd->codec_param.codec.compr_passthr >= LEGACY_PCM &&
+ prtd->codec_param.codec.compr_passthr <= COMPRESSED_PASSTHROUGH_DSD)
prtd->compr_passthr = prtd->codec_param.codec.compr_passthr;
else
prtd->compr_passthr = LEGACY_PCM;
@@ -1410,6 +1426,12 @@ static int msm_compr_set_params(struct snd_compr_stream *cstream,
break;
}
+ case SND_AUDIOCODEC_DSD: {
+ pr_debug("%s: SND_AUDIOCODEC_DSD\n", __func__);
+ prtd->codec = FORMAT_DSD;
+ break;
+ }
+
default:
pr_err("codec not supported, id =%d\n", params->codec.id);
return -EINVAL;
@@ -2199,6 +2221,8 @@ static int msm_compr_get_codec_caps(struct snd_compr_stream *cstream,
break;
case SND_AUDIOCODEC_DTS:
break;
+ case SND_AUDIOCODEC_DSD:
+ break;
default:
pr_err("%s: Unsupported audio codec %d\n",
__func__, codec->codec);
@@ -2675,6 +2699,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
case FORMAT_ALAC:
case FORMAT_APE:
case FORMAT_DTS:
+ case FORMAT_DSD:
pr_debug("%s: no runtime parameters for codec: %d\n", __func__,
prtd->codec);
break;
diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
index c439c5cf2de5..51ebd039d96b 100644
--- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
@@ -230,10 +230,11 @@ static const struct soc_enum mi2s_config_enum[] = {
static const char *const sb_format[] = {
"UNPACKED",
"PACKED_16B",
+ "DSD_DOP",
};
static const struct soc_enum sb_config_enum[] = {
- SOC_ENUM_SINGLE_EXT(2, sb_format),
+ SOC_ENUM_SINGLE_EXT(3, sb_format),
};
static const char *const tdm_data_format[] = {
@@ -2129,7 +2130,10 @@ static const struct snd_kcontrol_new sb_config_controls[] = {
msm_dai_q6_sb_format_put),
SOC_ENUM_EXT("SLIM_2_RX SetCalMode", slim_2_rx_enum,
msm_dai_q6_cal_info_get,
- msm_dai_q6_cal_info_put)
+ msm_dai_q6_cal_info_put),
+ SOC_ENUM_EXT("SLIM_2_RX Format", sb_config_enum[0],
+ msm_dai_q6_sb_format_get,
+ msm_dai_q6_sb_format_put)
};
static const struct snd_kcontrol_new rt_proxy_config_controls[] = {
@@ -2185,6 +2189,9 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai)
rc = snd_ctl_add(dai->component->card->snd_card,
snd_ctl_new1(&sb_config_controls[1],
dai_data));
+ rc = snd_ctl_add(dai->component->card->snd_card,
+ snd_ctl_new1(&sb_config_controls[2],
+ dai_data));
break;
case SLIMBUS_7_RX:
rc = snd_ctl_add(dai->component->card->snd_card,
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 9e3d85b807aa..695f57b30322 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -270,6 +270,7 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = {
{ SECONDARY_I2S_RX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SEC_I2S_RX},
{ SLIMBUS_1_RX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_RX},
{ SLIMBUS_1_TX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_1_TX},
+ { SLIMBUS_2_RX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_2_RX},
{ SLIMBUS_4_RX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_RX},
{ SLIMBUS_4_TX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_4_TX},
{ SLIMBUS_3_RX, 0, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_3_RX},
@@ -851,7 +852,7 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
msm_pcm_routing_get_app_type_idx(
app_type);
sample_rate =
- app_type_cfg[app_type_idx].sample_rate;
+ fe_dai_app_type_cfg[fe_id].sample_rate;
bit_width =
app_type_cfg[app_type_idx].bit_width;
} else {
@@ -860,6 +861,8 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
acdb_dev_id = fe_dai_app_type_cfg[fe_id].acdb_dev_id;
topology = msm_routing_get_adm_topology(path_type,
fe_id);
+ if (compr_passthr_mode == COMPRESSED_PASSTHROUGH_DSD)
+ topology = COMPRESS_PASSTHROUGH_NONE_TOPOLOGY;
pr_err("%s: Before adm open topology %d\n", __func__,
topology);
@@ -897,8 +900,11 @@ int msm_pcm_routing_reg_phy_compr_stream(int fe_id, int perf_mode,
num_copps++;
}
}
- msm_routing_send_device_pp_params(msm_bedais[i].port_id,
- copp_idx);
+ if (compr_passthr_mode != COMPRESSED_PASSTHROUGH_DSD) {
+ msm_routing_send_device_pp_params(
+ msm_bedais[i].port_id,
+ copp_idx);
+ }
}
}
if (num_copps) {
@@ -2414,6 +2420,57 @@ static const struct snd_kcontrol_new spdif_rx_mixer_controls[] = {
msm_routing_put_audio_mixer),
};
+static const struct snd_kcontrol_new slimbus_2_rx_mixer_controls[] = {
+ SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+ SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_SLIMBUS_2_RX,
+ MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer,
+ msm_routing_put_audio_mixer),
+};
+
static const struct snd_kcontrol_new slimbus_5_rx_mixer_controls[] = {
SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_SLIMBUS_5_RX ,
MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer,
@@ -7375,6 +7432,7 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("SPDIF_RX", "SPDIF Playback", 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_0_RX", "Slimbus Playback", 0, 0, 0, 0),
+ SND_SOC_DAPM_AIF_OUT("SLIMBUS_2_RX", "Slimbus2 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("SLIMBUS_5_RX", "Slimbus5 Playback", 0, 0, 0, 0),
SND_SOC_DAPM_AIF_OUT("HDMI", "HDMI Playback", 0, 0, 0 , 0),
SND_SOC_DAPM_AIF_OUT("MI2S_RX", "MI2S Playback", 0, 0, 0, 0),
@@ -7643,6 +7701,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
sec_i2s_rx_mixer_controls, ARRAY_SIZE(sec_i2s_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIMBUS_0_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
slimbus_rx_mixer_controls, ARRAY_SIZE(slimbus_rx_mixer_controls)),
+ SND_SOC_DAPM_MIXER("SLIMBUS_2_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
+ slimbus_2_rx_mixer_controls, ARRAY_SIZE(slimbus_2_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIMBUS_5_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
slimbus_5_rx_mixer_controls, ARRAY_SIZE(slimbus_5_rx_mixer_controls)),
SND_SOC_DAPM_MIXER("SLIMBUS_7_RX Audio Mixer", SND_SOC_NOPM, 0, 0,
@@ -8000,6 +8060,24 @@ static const struct snd_soc_dapm_route intercon[] = {
{"SLIMBUS_0_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
{"SLIMBUS_0_RX", NULL, "SLIMBUS_0_RX Audio Mixer"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia4", "MM_DL4"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia5", "MM_DL5"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia6", "MM_DL6"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia7", "MM_DL7"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia8", "MM_DL8"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia9", "MM_DL9"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia10", "MM_DL10"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia11", "MM_DL11"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia12", "MM_DL12"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia13", "MM_DL13"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia14", "MM_DL14"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia15", "MM_DL15"},
+ {"SLIMBUS_2_RX Audio Mixer", "MultiMedia16", "MM_DL16"},
+ {"SLIMBUS_2_RX", NULL, "SLIMBUS_2_RX Audio Mixer"},
+
{"SLIMBUS_5_RX Audio Mixer", "MultiMedia1", "MM_DL1"},
{"SLIMBUS_5_RX Audio Mixer", "MultiMedia2", "MM_DL2"},
{"SLIMBUS_5_RX Audio Mixer", "MultiMedia3", "MM_DL3"},
@@ -9484,6 +9562,7 @@ static const struct snd_soc_dapm_route intercon[] = {
{"BE_OUT", NULL, "SEC_I2S_RX"},
{"BE_OUT", NULL, "SLIMBUS_0_RX"},
{"BE_OUT", NULL, "SLIMBUS_1_RX"},
+ {"BE_OUT", NULL, "SLIMBUS_2_RX"},
{"BE_OUT", NULL, "SLIMBUS_3_RX"},
{"BE_OUT", NULL, "SLIMBUS_4_RX"},
{"BE_OUT", NULL, "SLIMBUS_5_RX"},
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
index f422fd7d3e85..009eebede28a 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
@@ -53,6 +53,7 @@
#define LPASS_BE_SLIMBUS_1_RX "SLIMBUS_1_RX"
#define LPASS_BE_SLIMBUS_1_TX "SLIMBUS_1_TX"
#define LPASS_BE_STUB_1_TX "STUB_1_TX"
+#define LPASS_BE_SLIMBUS_2_RX "SLIMBUS_2_RX"
#define LPASS_BE_SLIMBUS_3_RX "SLIMBUS_3_RX"
#define LPASS_BE_SLIMBUS_3_TX "SLIMBUS_3_TX"
#define LPASS_BE_SLIMBUS_4_RX "SLIMBUS_4_RX"
@@ -211,6 +212,7 @@ enum {
MSM_BACKEND_DAI_SEC_I2S_RX,
MSM_BACKEND_DAI_SLIMBUS_1_RX,
MSM_BACKEND_DAI_SLIMBUS_1_TX,
+ MSM_BACKEND_DAI_SLIMBUS_2_RX,
MSM_BACKEND_DAI_SLIMBUS_4_RX,
MSM_BACKEND_DAI_SLIMBUS_4_TX,
MSM_BACKEND_DAI_SLIMBUS_3_RX,
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
index 6409b81c0764..20d3f5212323 100644
--- a/sound/soc/msm/qdsp6v2/q6asm.c
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
@@ -2397,6 +2397,9 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
case FORMAT_DTS:
open.fmt_id = ASM_MEDIA_FMT_DTS;
break;
+ case FORMAT_DSD:
+ open.fmt_id = ASM_MEDIA_FMT_DSD;
+ break;
default:
pr_err("%s: Invalid format[%d]\n", __func__, format);
rc = -EINVAL;
@@ -2404,7 +2407,8 @@ int q6asm_open_write_compressed(struct audio_client *ac, uint32_t format,
}
/*Below flag indicates the DSP that Compressed audio input
stream is not IEC 61937 or IEC 60958 packetizied*/
- if (passthrough_flag == COMPRESSED_PASSTHROUGH) {
+ if (passthrough_flag == COMPRESSED_PASSTHROUGH ||
+ passthrough_flag == COMPRESSED_PASSTHROUGH_DSD) {
open.flags = 0x0;
pr_debug("%s: Flag 0 COMPRESSED_PASSTHROUGH\n", __func__);
} else if (passthrough_flag == COMPRESSED_PASSTHROUGH_CONVERT) {
@@ -2568,6 +2572,9 @@ static int __q6asm_open_write(struct audio_client *ac, uint32_t format,
case FORMAT_APE:
open.dec_fmt_id = ASM_MEDIA_FMT_APE;
break;
+ case FORMAT_DSD:
+ open.dec_fmt_id = ASM_MEDIA_FMT_DSD;
+ break;
default:
pr_err("%s: Invalid format 0x%x\n", __func__, format);
rc = -EINVAL;
@@ -2748,6 +2755,9 @@ static int __q6asm_open_read_write(struct audio_client *ac, uint32_t rd_format,
case FORMAT_APE:
open.dec_fmt_id = ASM_MEDIA_FMT_APE;
break;
+ case FORMAT_DSD:
+ open.dec_fmt_id = ASM_MEDIA_FMT_DSD;
+ break;
default:
pr_err("%s: Invalid format 0x%x\n",
__func__, wr_format);
@@ -5041,6 +5051,66 @@ fail_cmd:
return rc;
}
+/*
+ * q6asm_media_format_block_dsd- Sends DSD Decoder
+ * configuration parameters
+ *
+ * @ac: Client session handle
+ * @cfg: DSD Media Format Configuration.
+ * @stream_id: stream id of stream to be associated with this session
+ *
+ * Return 0 on success or negative error code on failure
+ */
+int q6asm_media_format_block_dsd(struct audio_client *ac,
+ struct asm_dsd_cfg *cfg, int stream_id)
+{
+ struct asm_dsd_fmt_blk_v2 fmt;
+ int rc;
+
+ pr_debug("%s: session[%d] data_rate[%d] ch[%d]\n", __func__,
+ ac->session, cfg->dsd_data_rate, cfg->num_channels);
+
+ memset(&fmt, 0, sizeof(fmt));
+ q6asm_stream_add_hdr(ac, &fmt.hdr, sizeof(fmt), TRUE, stream_id);
+
+ fmt.hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
+ fmt.fmtblk.fmt_blk_size = sizeof(fmt) - sizeof(fmt.hdr) -
+ sizeof(fmt.fmtblk);
+
+ fmt.num_version = cfg->num_version;
+ fmt.is_bitwise_big_endian = cfg->is_bitwise_big_endian;
+ fmt.dsd_channel_block_size = cfg->dsd_channel_block_size;
+ fmt.num_channels = cfg->num_channels;
+ fmt.dsd_data_rate = cfg->dsd_data_rate;
+ atomic_set(&ac->cmd_state, -1);
+ rc = apr_send_pkt(ac->apr, (uint32_t *) &fmt);
+ if (rc < 0) {
+ pr_err("%s: Command DSD media format update failed, err: %d\n",
+ __func__, rc);
+ goto done;
+ }
+ rc = wait_event_timeout(ac->cmd_wait,
+ (atomic_read(&ac->cmd_state) >= 0), 5*HZ);
+ if (!rc) {
+ pr_err("%s: timeout. waited for DSD FORMAT_UPDATE\n", __func__);
+ rc = -ETIMEDOUT;
+ goto done;
+ }
+
+ if (atomic_read(&ac->cmd_state) > 0) {
+ pr_err("%s: DSP returned error[%s]\n",
+ __func__, adsp_err_get_err_str(
+ atomic_read(&ac->cmd_state)));
+ rc = adsp_err_get_lnx_err_code(
+ atomic_read(&ac->cmd_state));
+ goto done;
+ }
+ return 0;
+done:
+ return rc;
+}
+EXPORT_SYMBOL(q6asm_media_format_block_dsd);
+
static int __q6asm_ds1_set_endp_params(struct audio_client *ac, int param_id,
int param_value, int stream_id)
{