Merge "ASoC: msm: qdsp6v2: Add ASM low latency loopback support"
This commit is contained in:
commit
15942a33a3
5 changed files with 297 additions and 23 deletions
|
@ -177,6 +177,11 @@ Required properties:
|
||||||
|
|
||||||
- compatible : "qcom,msm-pcm-loopback"
|
- compatible : "qcom,msm-pcm-loopback"
|
||||||
|
|
||||||
|
Optional properties:
|
||||||
|
|
||||||
|
- qcom,msm-pcm-loopback-low-latency : Flag indicating whether
|
||||||
|
the device node is of type low latency.
|
||||||
|
|
||||||
* msm-dai-q6
|
* msm-dai-q6
|
||||||
|
|
||||||
[First Level Nodes]
|
[First Level Nodes]
|
||||||
|
@ -415,6 +420,11 @@ Example:
|
||||||
qcom,msm-pcm-low-latency;
|
qcom,msm-pcm-low-latency;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
qcom,msm-pcm-loopback-low-latency {
|
||||||
|
compatible = "qcom,msm-pcm-loopback";
|
||||||
|
qcom,msm-pcm-loopback-low-latency;
|
||||||
|
};
|
||||||
|
|
||||||
qcom,msm-pcm-routing {
|
qcom,msm-pcm-routing {
|
||||||
compatible = "qcom,msm-pcm-routing";
|
compatible = "qcom,msm-pcm-routing";
|
||||||
};
|
};
|
||||||
|
@ -2121,13 +2131,15 @@ Example:
|
||||||
|
|
||||||
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
|
asoc-platform = <&pcm0>, <&pcm1>, <&pcm2>, <&voip>, <&voice>,
|
||||||
<&loopback>, <&compress>, <&hostless>,
|
<&loopback>, <&compress>, <&hostless>,
|
||||||
<&afe>, <&lsm>, <&routing>, <&compr>;
|
<&afe>, <&lsm>, <&routing>, <&compr>,
|
||||||
|
<&loopback1>;
|
||||||
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
|
asoc-platform-names = "msm-pcm-dsp.0", "msm-pcm-dsp.1",
|
||||||
"msm-pcm-dsp.2", "msm-voip-dsp",
|
"msm-pcm-dsp.2", "msm-voip-dsp",
|
||||||
"msm-pcm-voice", "msm-pcm-loopback",
|
"msm-pcm-voice", "msm-pcm-loopback",
|
||||||
"msm-compress-dsp", "msm-pcm-hostless",
|
"msm-compress-dsp", "msm-pcm-hostless",
|
||||||
"msm-pcm-afe", "msm-lsm-client",
|
"msm-pcm-afe", "msm-lsm-client",
|
||||||
"msm-pcm-routing", "msm-compr-dsp";
|
"msm-pcm-routing", "msm-compr-dsp",
|
||||||
|
"msm-pcm-loopback.1";
|
||||||
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
|
asoc-cpu = <&dai_pri_auxpcm>, <&dai_sec_auxpcm>, <&dai_hdmi>,
|
||||||
<&dai_mi2s>, <&dai_mi2s_quat>,
|
<&dai_mi2s>, <&dai_mi2s_quat>,
|
||||||
<&afe_pcm_rx>, <&afe_pcm_tx>,
|
<&afe_pcm_rx>, <&afe_pcm_tx>,
|
||||||
|
|
|
@ -5955,6 +5955,138 @@ struct asm_stream_cmd_open_loopback_v2 {
|
||||||
/* Reserved for future use. This field must be set to zero. */
|
/* Reserved for future use. This field must be set to zero. */
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
|
#define ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK 0x00010DBA
|
||||||
|
|
||||||
|
/* Bitmask for the stream's Performance mode. */
|
||||||
|
#define ASM_BIT_MASK_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK \
|
||||||
|
(0x70000000UL)
|
||||||
|
|
||||||
|
/* Bit shift for the stream's Performance mode. */
|
||||||
|
#define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK 28
|
||||||
|
|
||||||
|
/* Bitmask for the decoder converter enable flag. */
|
||||||
|
#define ASM_BIT_MASK_DECODER_CONVERTER_FLAG (0x00000078UL)
|
||||||
|
|
||||||
|
/* Shift value for the decoder converter enable flag. */
|
||||||
|
#define ASM_SHIFT_DECODER_CONVERTER_FLAG 3
|
||||||
|
|
||||||
|
/* Converter mode is None (Default). */
|
||||||
|
#define ASM_CONVERTER_MODE_NONE 0
|
||||||
|
|
||||||
|
/* Converter mode is DDP-to-DD. */
|
||||||
|
#define ASM_DDP_DD_CONVERTER_MODE 1
|
||||||
|
|
||||||
|
/* Identifies a special converter mode where source and sink formats
|
||||||
|
* are the same but postprocessing must applied. Therefore, Decode
|
||||||
|
* @rarrow Re-encode is necessary.
|
||||||
|
*/
|
||||||
|
#define ASM_POST_PROCESS_CONVERTER_MODE 2
|
||||||
|
|
||||||
|
|
||||||
|
struct asm_stream_cmd_open_transcode_loopback_t {
|
||||||
|
struct apr_hdr hdr;
|
||||||
|
u32 mode_flags;
|
||||||
|
/* Mode Flags specifies the performance mode in which this stream
|
||||||
|
* is to be opened.
|
||||||
|
* Supported values{for bits 30 to 28}(stream_perf_mode flag)
|
||||||
|
*
|
||||||
|
* #ASM_LEGACY_STREAM_SESSION -- This mode ensures backward
|
||||||
|
* compatibility to the original behavior
|
||||||
|
* of ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK
|
||||||
|
*
|
||||||
|
* #ASM_LOW_LATENCY_STREAM_SESSION -- Opens a loopback session by using
|
||||||
|
* shortened buffers in low latency POPP
|
||||||
|
* - Recommendation: Do not enable high latency algorithms. They might
|
||||||
|
* negate the benefits of opening a low latency stream, and they
|
||||||
|
* might also suffer quality degradation from unexpected jitter.
|
||||||
|
* - This Low Latency mode is supported only for PCM In and PCM Out
|
||||||
|
* loopbacks. An error is returned if Low Latency mode is opened for
|
||||||
|
* other transcode loopback modes.
|
||||||
|
* - To configure this subfield, use
|
||||||
|
* ASM_BIT_MASK_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK and
|
||||||
|
* ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_TRANSCODE_LOOPBACK.
|
||||||
|
*
|
||||||
|
* Supported values{for bits 6 to 3} (decoder-converter compatibility)
|
||||||
|
* #ASM_CONVERTER_MODE_NONE (0x0) -- Default
|
||||||
|
* #ASM_DDP_DD_CONVERTER_MODE (0x1)
|
||||||
|
* #ASM_POST_PROCESS_CONVERTER_MODE (0x2)
|
||||||
|
* 0x3-0xF -- Reserved for future use
|
||||||
|
* - Use #ASM_BIT_MASK_DECODER_CONVERTER_FLAG and
|
||||||
|
* ASM_SHIFT_DECODER_CONVERTER_FLAG to set this bit
|
||||||
|
* All other bits are reserved; clients must set them to 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 src_format_id;
|
||||||
|
/* Specifies the media format of the input audio stream.
|
||||||
|
*
|
||||||
|
* Supported values
|
||||||
|
* - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2
|
||||||
|
* - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3
|
||||||
|
* - #ASM_MEDIA_FMT_DTS
|
||||||
|
* - #ASM_MEDIA_FMT_EAC3_DEC
|
||||||
|
* - #ASM_MEDIA_FMT_EAC3
|
||||||
|
* - #ASM_MEDIA_FMT_AC3_DEC
|
||||||
|
* - #ASM_MEDIA_FMT_AC3
|
||||||
|
*/
|
||||||
|
u32 sink_format_id;
|
||||||
|
/* Specifies the media format of the output stream.
|
||||||
|
*
|
||||||
|
* Supported values
|
||||||
|
* - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2
|
||||||
|
* - #ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V3
|
||||||
|
* - #ASM_MEDIA_FMT_DTS (not supported in Low Latency mode)
|
||||||
|
* - #ASM_MEDIA_FMT_EAC3_DEC (not supported in Low Latency mode)
|
||||||
|
* - #ASM_MEDIA_FMT_EAC3 (not supported in Low Latency mode)
|
||||||
|
* - #ASM_MEDIA_FMT_AC3_DEC (not supported in Low Latency mode)
|
||||||
|
* - #ASM_MEDIA_FMT_AC3 (not supported in Low Latency mode)
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 audproc_topo_id;
|
||||||
|
/* Postprocessing topology ID, which specifies the topology (order of
|
||||||
|
* processing) of postprocessing algorithms.
|
||||||
|
*
|
||||||
|
* Supported values
|
||||||
|
* - #ASM_STREAM_POSTPROC_TOPO_ID_DEFAULT
|
||||||
|
* - #ASM_STREAM_POSTPROC_TOPO_ID_PEAKMETER
|
||||||
|
* - #ASM_STREAM_POSTPROC_TOPO_ID_MCH_PEAK_VOL
|
||||||
|
* - #ASM_STREAM_POSTPROC_TOPO_ID_NONE
|
||||||
|
* Topologies can be added through #ASM_CMD_ADD_TOPOLOGIES.
|
||||||
|
* This field is ignored for the Converter mode, in which no
|
||||||
|
* postprocessing is performed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u16 src_endpoint_type;
|
||||||
|
/* Specifies the source endpoint that provides the input samples.
|
||||||
|
*
|
||||||
|
* Supported values
|
||||||
|
* - 0 -- Tx device matrix or stream router (gateway to the hardware
|
||||||
|
* ports)
|
||||||
|
* - All other values are reserved
|
||||||
|
* Clients must set this field to 0. Otherwise, an error is returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u16 sink_endpoint_type;
|
||||||
|
/* Specifies the sink endpoint type.
|
||||||
|
*
|
||||||
|
* Supported values
|
||||||
|
* - 0 -- Rx device matrix or stream router (gateway to the hardware
|
||||||
|
* ports)
|
||||||
|
* - All other values are reserved
|
||||||
|
* Clients must set this field to 0. Otherwise, an error is returned.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u16 bits_per_sample;
|
||||||
|
/* Number of bits per sample processed by the ASM modules.
|
||||||
|
* Supported values 16, 24
|
||||||
|
*/
|
||||||
|
|
||||||
|
u16 reserved;
|
||||||
|
/* This field must be set to 0.
|
||||||
|
*/
|
||||||
|
} __packed;
|
||||||
|
|
||||||
|
|
||||||
#define ASM_STREAM_CMD_CLOSE 0x00010BCD
|
#define ASM_STREAM_CMD_CLOSE 0x00010BCD
|
||||||
#define ASM_STREAM_CMD_FLUSH 0x00010BCE
|
#define ASM_STREAM_CMD_FLUSH 0x00010BCE
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <sound/control.h>
|
#include <sound/control.h>
|
||||||
#include <sound/tlv.h>
|
#include <sound/tlv.h>
|
||||||
#include <asm/dma.h>
|
#include <asm/dma.h>
|
||||||
|
#include <sound/q6audio-v2.h>
|
||||||
|
|
||||||
#include "msm-pcm-routing-v2.h"
|
#include "msm-pcm-routing-v2.h"
|
||||||
|
|
||||||
|
@ -67,6 +68,10 @@ static struct fe_dai_session_map session_map[LOOPBACK_SESSION_MAX] = {
|
||||||
|
|
||||||
static u32 hfp_tx_mute;
|
static u32 hfp_tx_mute;
|
||||||
|
|
||||||
|
struct msm_pcm_pdata {
|
||||||
|
int perf_mode;
|
||||||
|
};
|
||||||
|
|
||||||
static void stop_pcm(struct msm_pcm_loopback *pcm);
|
static void stop_pcm(struct msm_pcm_loopback *pcm);
|
||||||
static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd,
|
static int msm_pcm_loopback_get_session(struct snd_soc_pcm_runtime *rtd,
|
||||||
struct msm_pcm_loopback **pcm);
|
struct msm_pcm_loopback **pcm);
|
||||||
|
@ -244,6 +249,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
|
||||||
struct msm_pcm_routing_evt event;
|
struct msm_pcm_routing_evt event;
|
||||||
struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window;
|
struct asm_session_mtmx_strtr_param_window_v2_t asm_mtmx_strtr_window;
|
||||||
uint32_t param_id;
|
uint32_t param_id;
|
||||||
|
struct msm_pcm_pdata *pdata;
|
||||||
|
|
||||||
ret = msm_pcm_loopback_get_session(rtd, &pcm);
|
ret = msm_pcm_loopback_get_session(rtd, &pcm);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -269,6 +275,15 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
|
||||||
if (pcm->audio_client != NULL)
|
if (pcm->audio_client != NULL)
|
||||||
stop_pcm(pcm);
|
stop_pcm(pcm);
|
||||||
|
|
||||||
|
pdata = (struct msm_pcm_pdata *)
|
||||||
|
dev_get_drvdata(rtd->platform->dev);
|
||||||
|
if (!pdata) {
|
||||||
|
dev_err(rtd->platform->dev,
|
||||||
|
"%s: platform data not populated\n", __func__);
|
||||||
|
mutex_unlock(&pcm->lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
pcm->audio_client = q6asm_audio_client_alloc(
|
pcm->audio_client = q6asm_audio_client_alloc(
|
||||||
(app_cb)msm_pcm_loopback_event_handler, pcm);
|
(app_cb)msm_pcm_loopback_event_handler, pcm);
|
||||||
if (!pcm->audio_client) {
|
if (!pcm->audio_client) {
|
||||||
|
@ -278,7 +293,7 @@ static int msm_pcm_open(struct snd_pcm_substream *substream)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
pcm->session_id = pcm->audio_client->session;
|
pcm->session_id = pcm->audio_client->session;
|
||||||
pcm->audio_client->perf_mode = false;
|
pcm->audio_client->perf_mode = pdata->perf_mode;
|
||||||
ret = q6asm_open_loopback_v2(pcm->audio_client,
|
ret = q6asm_open_loopback_v2(pcm->audio_client,
|
||||||
bits_per_sample);
|
bits_per_sample);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -745,9 +760,23 @@ static struct snd_soc_platform_driver msm_soc_platform = {
|
||||||
|
|
||||||
static int msm_pcm_probe(struct platform_device *pdev)
|
static int msm_pcm_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
|
struct msm_pcm_pdata *pdata;
|
||||||
|
|
||||||
dev_dbg(&pdev->dev, "%s: dev name %s\n",
|
dev_dbg(&pdev->dev, "%s: dev name %s\n",
|
||||||
__func__, dev_name(&pdev->dev));
|
__func__, dev_name(&pdev->dev));
|
||||||
|
|
||||||
|
pdata = kzalloc(sizeof(struct msm_pcm_pdata), GFP_KERNEL);
|
||||||
|
if (!pdata)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
if (of_property_read_bool(pdev->dev.of_node,
|
||||||
|
"qcom,msm-pcm-loopback-low-latency"))
|
||||||
|
pdata->perf_mode = LOW_LATENCY_PCM_MODE;
|
||||||
|
else
|
||||||
|
pdata->perf_mode = LEGACY_PCM_MODE;
|
||||||
|
|
||||||
|
dev_set_drvdata(&pdev->dev, pdata);
|
||||||
|
|
||||||
return snd_soc_register_platform(&pdev->dev,
|
return snd_soc_register_platform(&pdev->dev,
|
||||||
&msm_soc_platform);
|
&msm_soc_platform);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5257,6 +5257,57 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = {
|
||||||
msm_routing_put_audio_mixer),
|
msm_routing_put_audio_mixer),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct snd_kcontrol_new mmul9_mixer_controls[] = {
|
||||||
|
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("PRI_MI2S_TX", MSM_BACKEND_DAI_PRI_MI2S_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("INTERNAL_FM_TX", MSM_BACKEND_DAI_INT_FM_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("INTERNAL_BT_SCO_TX", MSM_BACKEND_DAI_INT_BT_SCO_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("AFE_PCM_TX", MSM_BACKEND_DAI_AFE_PCM_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("VOC_REC_DL", MSM_BACKEND_DAI_INCALL_RECORD_RX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("VOC_REC_UL", MSM_BACKEND_DAI_INCALL_RECORD_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("SLIM_6_TX", MSM_BACKEND_DAI_SLIMBUS_6_TX,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("TERT_TDM_TX_0", MSM_BACKEND_DAI_TERT_TDM_TX_0,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("TERT_TDM_TX_1", MSM_BACKEND_DAI_TERT_TDM_TX_1,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("TERT_TDM_TX_2", MSM_BACKEND_DAI_TERT_TDM_TX_2,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("TERT_TDM_TX_3", MSM_BACKEND_DAI_TERT_TDM_TX_3,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("QUAT_TDM_TX_0", MSM_BACKEND_DAI_QUAT_TDM_TX_0,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("QUAT_TDM_TX_1", MSM_BACKEND_DAI_QUAT_TDM_TX_1,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("QUAT_TDM_TX_2", MSM_BACKEND_DAI_QUAT_TDM_TX_2,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3,
|
||||||
|
MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
msm_routing_put_audio_mixer),
|
||||||
|
};
|
||||||
|
|
||||||
static const struct snd_kcontrol_new mmul17_mixer_controls[] = {
|
static const struct snd_kcontrol_new mmul17_mixer_controls[] = {
|
||||||
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
|
SOC_SINGLE_EXT("SLIM_0_TX", MSM_BACKEND_DAI_SLIMBUS_0_TX,
|
||||||
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
|
MSM_FRONTEND_DAI_MULTIMEDIA17, 1, 0, msm_routing_get_audio_mixer,
|
||||||
|
@ -9225,6 +9276,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = {
|
||||||
mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)),
|
mmul6_mixer_controls, ARRAY_SIZE(mmul6_mixer_controls)),
|
||||||
SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_MIXER("MultiMedia8 Mixer", SND_SOC_NOPM, 0, 0,
|
||||||
mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
|
mmul8_mixer_controls, ARRAY_SIZE(mmul8_mixer_controls)),
|
||||||
|
SND_SOC_DAPM_MIXER("MultiMedia9 Mixer", SND_SOC_NOPM, 0, 0,
|
||||||
|
mmul9_mixer_controls, ARRAY_SIZE(mmul9_mixer_controls)),
|
||||||
SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_MIXER("MultiMedia17 Mixer", SND_SOC_NOPM, 0, 0,
|
||||||
mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)),
|
mmul17_mixer_controls, ARRAY_SIZE(mmul17_mixer_controls)),
|
||||||
SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0,
|
SND_SOC_DAPM_MIXER("MultiMedia18 Mixer", SND_SOC_NOPM, 0, 0,
|
||||||
|
@ -10260,6 +10313,15 @@ static const struct snd_soc_dapm_route intercon[] = {
|
||||||
{"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
|
{"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
|
||||||
{"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
|
{"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
|
||||||
|
|
||||||
|
{"MultiMedia9 Mixer", "TERT_TDM_TX_0", "TERT_TDM_TX_0"},
|
||||||
|
{"MultiMedia9 Mixer", "TERT_TDM_TX_1", "TERT_TDM_TX_1"},
|
||||||
|
{"MultiMedia9 Mixer", "TERT_TDM_TX_2", "TERT_TDM_TX_2"},
|
||||||
|
{"MultiMedia9 Mixer", "TERT_TDM_TX_3", "TERT_TDM_TX_3"},
|
||||||
|
{"MultiMedia9 Mixer", "QUAT_TDM_TX_0", "QUAT_TDM_TX_0"},
|
||||||
|
{"MultiMedia9 Mixer", "QUAT_TDM_TX_1", "QUAT_TDM_TX_1"},
|
||||||
|
{"MultiMedia9 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"},
|
||||||
|
{"MultiMedia9 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"},
|
||||||
|
|
||||||
{"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
|
{"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
|
||||||
{"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
|
{"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
|
||||||
{"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
|
{"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"},
|
||||||
|
@ -10374,6 +10436,7 @@ static const struct snd_soc_dapm_route intercon[] = {
|
||||||
{"MM_UL5", NULL, "MultiMedia5 Mixer"},
|
{"MM_UL5", NULL, "MultiMedia5 Mixer"},
|
||||||
{"MM_UL6", NULL, "MultiMedia6 Mixer"},
|
{"MM_UL6", NULL, "MultiMedia6 Mixer"},
|
||||||
{"MM_UL8", NULL, "MultiMedia8 Mixer"},
|
{"MM_UL8", NULL, "MultiMedia8 Mixer"},
|
||||||
|
{"MM_UL9", NULL, "MultiMedia9 Mixer"},
|
||||||
{"MM_UL17", NULL, "MultiMedia17 Mixer"},
|
{"MM_UL17", NULL, "MultiMedia17 Mixer"},
|
||||||
{"MM_UL18", NULL, "MultiMedia18 Mixer"},
|
{"MM_UL18", NULL, "MultiMedia18 Mixer"},
|
||||||
{"MM_UL19", NULL, "MultiMedia19 Mixer"},
|
{"MM_UL19", NULL, "MultiMedia19 Mixer"},
|
||||||
|
|
|
@ -1710,6 +1710,7 @@ static int32_t q6asm_callback(struct apr_client_data *data, void *priv)
|
||||||
case ASM_STREAM_CMD_OPEN_PUSH_MODE_READ:
|
case ASM_STREAM_CMD_OPEN_PUSH_MODE_READ:
|
||||||
case ASM_STREAM_CMD_OPEN_READWRITE_V2:
|
case ASM_STREAM_CMD_OPEN_READWRITE_V2:
|
||||||
case ASM_STREAM_CMD_OPEN_LOOPBACK_V2:
|
case ASM_STREAM_CMD_OPEN_LOOPBACK_V2:
|
||||||
|
case ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK:
|
||||||
case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
|
case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
|
||||||
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
|
case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
|
||||||
case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
|
case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
|
||||||
|
@ -2982,7 +2983,6 @@ int q6asm_open_read_write_v2(struct audio_client *ac, uint32_t rd_format,
|
||||||
int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
|
int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
|
||||||
{
|
{
|
||||||
int rc = 0x00;
|
int rc = 0x00;
|
||||||
struct asm_stream_cmd_open_loopback_v2 open;
|
|
||||||
|
|
||||||
if (ac == NULL) {
|
if (ac == NULL) {
|
||||||
pr_err("%s: APR handle NULL\n", __func__);
|
pr_err("%s: APR handle NULL\n", __func__);
|
||||||
|
@ -2994,29 +2994,67 @@ int q6asm_open_loopback_v2(struct audio_client *ac, uint16_t bits_per_sample)
|
||||||
}
|
}
|
||||||
pr_debug("%s: session[%d]\n", __func__, ac->session);
|
pr_debug("%s: session[%d]\n", __func__, ac->session);
|
||||||
|
|
||||||
q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
|
if (ac->perf_mode == LOW_LATENCY_PCM_MODE) {
|
||||||
atomic_set(&ac->cmd_state, -1);
|
struct asm_stream_cmd_open_transcode_loopback_t open;
|
||||||
open.hdr.opcode = ASM_STREAM_CMD_OPEN_LOOPBACK_V2;
|
|
||||||
|
|
||||||
open.mode_flags = 0;
|
q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
|
||||||
open.src_endpointype = 0;
|
atomic_set(&ac->cmd_state, -1);
|
||||||
open.sink_endpointype = 0;
|
open.hdr.opcode = ASM_STREAM_CMD_OPEN_TRANSCODE_LOOPBACK;
|
||||||
/* source endpoint : matrix */
|
|
||||||
open.postprocopo_id = q6asm_get_asm_topology_cal();
|
|
||||||
|
|
||||||
ac->app_type = q6asm_get_asm_app_type_cal();
|
open.mode_flags = 0;
|
||||||
ac->topology = open.postprocopo_id;
|
open.src_endpoint_type = 0;
|
||||||
open.bits_per_sample = bits_per_sample;
|
open.sink_endpoint_type = 0;
|
||||||
open.reserved = 0;
|
open.src_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
|
||||||
|
open.sink_format_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
|
||||||
|
/* source endpoint : matrix */
|
||||||
|
open.audproc_topo_id = q6asm_get_asm_topology_cal();
|
||||||
|
|
||||||
rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
|
ac->app_type = q6asm_get_asm_app_type_cal();
|
||||||
if (rc < 0) {
|
if (ac->perf_mode == LOW_LATENCY_PCM_MODE)
|
||||||
pr_err("%s: open failed op[0x%x]rc[%d]\n", __func__,
|
open.mode_flags |= ASM_LOW_LATENCY_STREAM_SESSION;
|
||||||
open.hdr.opcode, rc);
|
else
|
||||||
rc = -EINVAL;
|
open.mode_flags |= ASM_LEGACY_STREAM_SESSION;
|
||||||
goto fail_cmd;
|
ac->topology = open.audproc_topo_id;
|
||||||
|
open.bits_per_sample = bits_per_sample;
|
||||||
|
open.reserved = 0;
|
||||||
|
pr_debug("%s: opening a transcode_loopback with mode_flags =[%d] session[%d]\n",
|
||||||
|
__func__, open.mode_flags, ac->session);
|
||||||
|
|
||||||
|
rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: open failed op[0x%x]rc[%d]\n",
|
||||||
|
__func__, open.hdr.opcode, rc);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto fail_cmd;
|
||||||
|
}
|
||||||
|
} else {/*if(ac->perf_mode == LEGACY_PCM_MODE)*/
|
||||||
|
struct asm_stream_cmd_open_loopback_v2 open;
|
||||||
|
|
||||||
|
q6asm_add_hdr(ac, &open.hdr, sizeof(open), TRUE);
|
||||||
|
atomic_set(&ac->cmd_state, -1);
|
||||||
|
open.hdr.opcode = ASM_STREAM_CMD_OPEN_LOOPBACK_V2;
|
||||||
|
|
||||||
|
open.mode_flags = 0;
|
||||||
|
open.src_endpointype = 0;
|
||||||
|
open.sink_endpointype = 0;
|
||||||
|
/* source endpoint : matrix */
|
||||||
|
open.postprocopo_id = q6asm_get_asm_topology_cal();
|
||||||
|
|
||||||
|
ac->app_type = q6asm_get_asm_app_type_cal();
|
||||||
|
ac->topology = open.postprocopo_id;
|
||||||
|
open.bits_per_sample = bits_per_sample;
|
||||||
|
open.reserved = 0;
|
||||||
|
pr_debug("%s: opening a loopback_v2 with mode_flags =[%d] session[%d]\n",
|
||||||
|
__func__, open.mode_flags, ac->session);
|
||||||
|
|
||||||
|
rc = apr_send_pkt(ac->apr, (uint32_t *) &open);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("%s: open failed op[0x%x]rc[%d]\n",
|
||||||
|
__func__, open.hdr.opcode, rc);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto fail_cmd;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = wait_event_timeout(ac->cmd_wait,
|
rc = wait_event_timeout(ac->cmd_wait,
|
||||||
(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
|
(atomic_read(&ac->cmd_state) >= 0), 5*HZ);
|
||||||
if (!rc) {
|
if (!rc) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue