From 395fde109b1c0297dece4d07ee8f6fe79d2ddee4 Mon Sep 17 00:00:00 2001 From: Kuirong Wang Date: Mon, 9 May 2016 14:35:30 -0700 Subject: [PATCH] ASoC: msm: Add USB audio via ADSP support Add new USB rx and tx afe ports and routing to different fe dais to enable USB audio via ADSP. Change-Id: I4f82ba27becee1f3b62c410be0d00876961f9b18 Signed-off-by: Vidyakumar Athota Signed-off-by: Kuirong Wang --- include/sound/apr_audio-v2.h | 79 +++++++++ include/sound/q6afe-v2.h | 3 + sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c | 151 +++++++++++++++- sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c | 191 +++++++++++++++++++++ sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h | 4 + sound/soc/msm/qdsp6v2/q6afe.c | 79 +++++++++ sound/soc/msm/qdsp6v2/q6audio-v2.c | 10 ++ 7 files changed, 515 insertions(+), 2 deletions(-) diff --git a/include/sound/apr_audio-v2.h b/include/sound/apr_audio-v2.h index db66cd71aaae..24b283311817 100644 --- a/include/sound/apr_audio-v2.h +++ b/include/sound/apr_audio-v2.h @@ -953,6 +953,9 @@ struct adm_cmd_connect_afe_port_v5 { #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_RX 0x4010 /* SLIMbus Tx port on channel 8. */ #define AFE_PORT_ID_SLIMBUS_MULTI_CHAN_8_TX 0x4011 +/*USB AFE port */ +#define AFE_PORT_ID_USB_RX 0x7000 +#define AFE_PORT_ID_USB_TX 0x7001 /* Generic pseudoport 1. */ #define AFE_PORT_ID_PSEUDOPORT_01 0x8001 @@ -2228,6 +2231,81 @@ struct afe_param_id_slimbus_cfg { */ } __packed; + +/* ID of the parameter used by AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS to configure + * USB audio device parameter. It should be used with + * AFE_MODULE_AUDIO_DEV_INTERFACE + */ +#define AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS 0x000102A5 + +/* Minor version used for tracking USB audio configuration */ +#define AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG 0x1 + +/* Payload of the AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_usb_audio_dev_params { +/* Minor version used for tracking USB audio device parameter. + * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + */ + u32 cfg_minor_version; +/* Token of actual end USB aduio device */ + u32 dev_token; +} __packed; + +/* ID of the parameter used by AFE_PARAM_ID_USB_AUDIO_CONFIG to configure + * USB audio interface. It should be used with AFE_MODULE_AUDIO_DEV_INTERFACE +*/ +#define AFE_PARAM_ID_USB_AUDIO_CONFIG 0x000102A4 + +/* Payload of the AFE_PARAM_ID_USB_AUDIO_CONFIG parameter used by + * AFE_MODULE_AUDIO_DEV_INTERFACE. + */ +struct afe_param_id_usb_audio_cfg { +/* Minor version used for tracking USB audio device configuration. + * Supported values: AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG + */ + u32 cfg_minor_version; +/* Sampling rate of the port. + * Supported values: + * - AFE_PORT_SAMPLE_RATE_8K + * - AFE_PORT_SAMPLE_RATE_11025 + * - AFE_PORT_SAMPLE_RATE_12K + * - AFE_PORT_SAMPLE_RATE_16K + * - AFE_PORT_SAMPLE_RATE_22050 + * - AFE_PORT_SAMPLE_RATE_24K + * - AFE_PORT_SAMPLE_RATE_32K + * - AFE_PORT_SAMPLE_RATE_44P1K + * - AFE_PORT_SAMPLE_RATE_48K + * - AFE_PORT_SAMPLE_RATE_96K + * - AFE_PORT_SAMPLE_RATE_192K + */ + u32 sample_rate; +/* Bit width of the sample. + * Supported values: 16, 24 + */ + u16 bit_width; +/* Number of channels. + * Supported values: 1 and 2 + */ + u16 num_channels; +/* Data format supported by the USB. The supported value is + * 0 (#AFE_USB_AUDIO_DATA_FORMAT_LINEAR_PCM). + */ + u16 data_format; +/* this field must be 0 */ + u16 reserved; +/* device token of actual end USB aduio device */ + u32 dev_token; +} __packed; + +struct afe_usb_audio_dev_param_command { + struct apr_hdr hdr; + struct afe_port_cmd_set_param_v2 param; + struct afe_port_param_data_v2 pdata; + struct afe_param_id_usb_audio_dev_params usb_dev; +} __packed; + /* * This param id is used to configure Real Time Proxy interface. */ @@ -2672,6 +2750,7 @@ union afe_port_config { struct afe_param_id_spdif_cfg spdif; struct afe_param_id_set_topology_cfg topology; struct afe_param_id_tdm_cfg tdm; + struct afe_param_id_usb_audio_cfg usb_audio; } __packed; struct afe_audioif_config_command_no_payload { diff --git a/include/sound/q6afe-v2.h b/include/sound/q6afe-v2.h index d30be944dc8c..5cd65357dd95 100644 --- a/include/sound/q6afe-v2.h +++ b/include/sound/q6afe-v2.h @@ -178,6 +178,9 @@ enum { IDX_SLIMBUS_7_TX, IDX_SLIMBUS_8_RX, IDX_SLIMBUS_8_TX, + /* IDX 123-> 124 */ + IDX_AFE_PORT_ID_USB_RX, + IDX_AFE_PORT_ID_USB_TX, AFE_MAX_PORTS }; diff --git a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c index 07fd1a44df7f..2ca6f590c532 100644 --- a/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c @@ -1493,6 +1493,43 @@ static int msm_dai_q6_slim_bus_hw_params(struct snd_pcm_hw_params *params, return 0; } +static int msm_dai_q6_usb_audio_hw_params(struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, int stream) +{ + struct msm_dai_q6_dai_data *dai_data = dev_get_drvdata(dai->dev); + + dai_data->channels = params_channels(params); + dai_data->rate = params_rate(params); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + case SNDRV_PCM_FORMAT_SPECIAL: + dai_data->port_config.usb_audio.bit_width = 16; + break; + case SNDRV_PCM_FORMAT_S24_LE: + dai_data->port_config.usb_audio.bit_width = 24; + break; + default: + dev_err(dai->dev, "%s: invalid format %d\n", + __func__, params_format(params)); + return -EINVAL; + } + dai_data->port_config.usb_audio.cfg_minor_version = + AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + dai_data->port_config.usb_audio.num_channels = dai_data->channels; + dai_data->port_config.usb_audio.sample_rate = dai_data->rate; + + dev_dbg(dai->dev, "%s: dev_id[0x%x] bit_wd[%hu] format[%hu]\n" + "num_channel %hu sample_rate %d\n", __func__, + dai_data->port_config.usb_audio.dev_token, + dai_data->port_config.usb_audio.bit_width, + dai_data->port_config.usb_audio.data_format, + dai_data->port_config.usb_audio.num_channels, + dai_data->port_config.usb_audio.sample_rate); + + return 0; +} + static int msm_dai_q6_bt_fm_hw_params(struct snd_pcm_hw_params *params, struct snd_soc_dai *dai, int stream) { @@ -1619,6 +1656,11 @@ static int msm_dai_q6_hw_params(struct snd_pcm_substream *substream, case INT_FM_TX: rc = msm_dai_q6_bt_fm_hw_params(params, dai, substream->stream); break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + rc = msm_dai_q6_usb_audio_hw_params(params, dai, + substream->stream); + break; case RT_PROXY_DAI_001_TX: case RT_PROXY_DAI_001_RX: case RT_PROXY_DAI_002_TX: @@ -1862,6 +1904,40 @@ static int msm_dai_q6_sb_format_get(struct snd_kcontrol *kcontrol, return 0; } +static int msm_dai_q6_usb_audio_cfg_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + u32 val = ucontrol->value.integer.value[0]; + + if (dai_data) { + dai_data->port_config.usb_audio.dev_token = val; + pr_debug("%s: dev_token = 0x%x\n", __func__, + dai_data->port_config.usb_audio.dev_token); + } else { + pr_err("%s: dai_data is NULL\n", __func__); + } + + return 0; +} + +static int msm_dai_q6_usb_audio_cfg_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct msm_dai_q6_dai_data *dai_data = kcontrol->private_data; + + if (dai_data) { + ucontrol->value.integer.value[0] = + dai_data->port_config.usb_audio.dev_token; + pr_debug("%s: dev_token = 0x%x\n", __func__, + dai_data->port_config.usb_audio.dev_token); + } else { + pr_err("%s: dai_data is NULL\n", __func__); + } + + return 0; +} + static const char * const afe_cal_mode_text[] = { "CAL_MODE_DEFAULT", "CAL_MODE_NONE" }; @@ -1896,6 +1972,15 @@ static const struct snd_kcontrol_new rt_proxy_config_controls[] = { msm_dai_q6_cal_info_put), }; +static const struct snd_kcontrol_new usb_audio_cfg_controls[] = { + SOC_SINGLE_EXT("USB_AUDIO_RX dev_token", 0, 0, UINT_MAX, 0, + msm_dai_q6_usb_audio_cfg_get, + msm_dai_q6_usb_audio_cfg_put), + SOC_SINGLE_EXT("USB_AUDIO_TX dev_token", 0, 0, UINT_MAX, 0, + msm_dai_q6_usb_audio_cfg_get, + msm_dai_q6_usb_audio_cfg_put), +}; + static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) { struct msm_dai_q6_dai_data *dai_data; @@ -1942,6 +2027,16 @@ static int msm_dai_q6_dai_probe(struct snd_soc_dai *dai) snd_ctl_new1(&rt_proxy_config_controls[1], dai_data)); break; + case AFE_PORT_ID_USB_RX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[0], + dai_data)); + break; + case AFE_PORT_ID_USB_TX: + rc = snd_ctl_add(dai->component->card->snd_card, + snd_ctl_new1(&usb_audio_cfg_controls[1], + dai_data)); + break; } if (IS_ERR_VALUE(rc)) dev_err(dai->dev, "%s: err add config ctl, DAI = %s\n", @@ -2205,6 +2300,48 @@ static struct snd_soc_dai_driver msm_dai_q6_incall_record_dai[] = { }, }; +static struct snd_soc_dai_driver msm_dai_q6_usb_rx_dai = { + .playback = { + .stream_name = "USB Audio Playback", + .aif_name = "USB_AUDIO_RX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_max = 192000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = AFE_PORT_ID_USB_RX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + +static struct snd_soc_dai_driver msm_dai_q6_usb_tx_dai = { + .capture = { + .stream_name = "USB Audio Capture", + .aif_name = "USB_AUDIO_TX", + .rates = SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | + SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 | + SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE, + .channels_min = 1, + .channels_max = 2, + .rate_max = 192000, + .rate_min = 8000, + }, + .ops = &msm_dai_q6_ops, + .id = AFE_PORT_ID_USB_TX, + .probe = msm_dai_q6_dai_probe, + .remove = msm_dai_q6_dai_remove, +}; + static int msm_auxpcm_dev_probe(struct platform_device *pdev) { struct msm_dai_q6_auxpcm_dai_data *dai_data; @@ -3854,8 +3991,18 @@ register_slim_capture: &msm_dai_q6_fm_rx_dai, 1); break; case INT_FM_TX: - rc = snd_soc_register_component(&pdev->dev, &msm_dai_q6_component, - &msm_dai_q6_fm_tx_dai, 1); + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, &msm_dai_q6_fm_tx_dai, 1); + break; + case AFE_PORT_ID_USB_RX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_usb_rx_dai, 1); + break; + case AFE_PORT_ID_USB_TX: + rc = snd_soc_register_component(&pdev->dev, + &msm_dai_q6_component, + &msm_dai_q6_usb_tx_dai, 1); break; case RT_PROXY_DAI_001_RX: strlcpy(stream_name, "AFE Playback", 80); diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c index a8dae0e39df4..444c3fa49799 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c @@ -425,6 +425,8 @@ struct msm_pcm_routing_bdai_data msm_bedais[MSM_BACKEND_DAI_MAX] = { { SLIMBUS_7_TX, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_7_TX}, { SLIMBUS_8_RX, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_RX}, { SLIMBUS_8_TX, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_SLIMBUS_8_TX}, + { AFE_PORT_ID_USB_RX, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_RX}, + { AFE_PORT_ID_USB_TX, 0, 0, 0, 0, 0, 0, 0, LPASS_BE_USB_AUDIO_TX}, }; /* Track ASM playback & capture sessions of DAI */ @@ -2872,6 +2874,57 @@ static const struct snd_kcontrol_new slimbus_7_rx_mixer_controls[] = { msm_routing_put_audio_mixer), }; +static const struct snd_kcontrol_new usb_audio_rx_mixer_controls[] = { + SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia2", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia3", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA3, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia4", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia5", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia6", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia7", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA7, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia8", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia9", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA9, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia10", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA10, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia11", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA11, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia12", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA12, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia13", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA13, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia14", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA14, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia15", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA15, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("MultiMedia16", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_MULTIMEDIA16, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), +}; + static const struct snd_kcontrol_new int_bt_sco_rx_mixer_controls[] = { SOC_SINGLE_EXT("MultiMedia1", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, @@ -3668,6 +3721,9 @@ static const struct snd_kcontrol_new mmul1_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA1, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul2_mixer_controls[] = { @@ -3722,6 +3778,9 @@ static const struct snd_kcontrol_new mmul2_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA2, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul4_mixer_controls[] = { @@ -3779,6 +3838,9 @@ static const struct snd_kcontrol_new mmul4_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_MI2S_TX", MSM_BACKEND_DAI_QUATERNARY_MI2S_TX, MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA4, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul5_mixer_controls[] = { @@ -3845,6 +3907,9 @@ static const struct snd_kcontrol_new mmul5_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA5, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul6_mixer_controls[] = { @@ -3896,6 +3961,9 @@ static const struct snd_kcontrol_new mmul6_mixer_controls[] = { SOC_SINGLE_EXT("QUAT_TDM_TX_3", MSM_BACKEND_DAI_QUAT_TDM_TX_3, MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA6, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new mmul8_mixer_controls[] = { @@ -3959,6 +4027,9 @@ static const struct snd_kcontrol_new mmul8_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_7_TX", MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, msm_routing_put_audio_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_MULTIMEDIA8, 1, 0, msm_routing_get_audio_mixer, + msm_routing_put_audio_mixer), }; static const struct snd_kcontrol_new pri_rx_voice_mixer_controls[] = { @@ -4117,6 +4188,45 @@ static const struct snd_kcontrol_new slimbus_6_rx_voice_mixer_controls[] = { msm_routing_put_voice_mixer), }; +static const struct snd_kcontrol_new usb_audio_rx_voice_mixer_controls[] = { + SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice2", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voip", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("Voice Stub", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("Voice2 Stub", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICE2_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoLTE", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoLTE Stub", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOLTE_STUB, 1, 0, msm_routing_get_voice_stub_mixer, + msm_routing_put_voice_stub_mixer), + SOC_SINGLE_EXT("VoWLAN", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("DTMF", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_DTMF_RX, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("QCHAT", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode1", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("VoiceMMode2", MSM_BACKEND_DAI_USB_RX, + MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), +}; + static const struct snd_kcontrol_new bt_sco_rx_voice_mixer_controls[] = { SOC_SINGLE_EXT("CSVoice", MSM_BACKEND_DAI_INT_BT_SCO_RX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, @@ -4640,6 +4750,9 @@ static const struct snd_kcontrol_new tx_voice_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_Voice", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_Voice", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_CS_VOICE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = { @@ -4676,6 +4789,9 @@ static const struct snd_kcontrol_new tx_voice2_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_Voice2", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_Voice2", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOICE2, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_volte_mixer_controls[] = { @@ -4712,6 +4828,9 @@ static const struct snd_kcontrol_new tx_volte_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_VoLTE", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_VoLTE", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOLTE, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_vowlan_mixer_controls[] = { @@ -4748,6 +4867,9 @@ static const struct snd_kcontrol_new tx_vowlan_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_VoWLAN", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_VoWLAN", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOWLAN, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { @@ -4784,6 +4906,9 @@ static const struct snd_kcontrol_new tx_voicemmode1_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_MMode1", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_MMode1", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOICEMMODE1, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { @@ -4820,6 +4945,9 @@ static const struct snd_kcontrol_new tx_voicemmode2_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_MMode2", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_MMode2", + MSM_BACKEND_DAI_USB_TX, MSM_FRONTEND_DAI_VOICEMMODE2, 1, + 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { @@ -4856,6 +4984,9 @@ static const struct snd_kcontrol_new tx_voip_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_Voip", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_Voip", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_VOIP, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new tx_voice_stub_mixer_controls[] = { @@ -5012,6 +5143,9 @@ static const struct snd_kcontrol_new tx_qchat_mixer_controls[] = { SOC_SINGLE_EXT("SLIM_8_TX_QCHAT", MSM_BACKEND_DAI_SLIMBUS_8_TX, MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, msm_routing_put_voice_mixer), + SOC_SINGLE_EXT("USB_AUDIO_TX_QCHAT", MSM_BACKEND_DAI_USB_TX, + MSM_FRONTEND_DAI_QCHAT, 1, 0, msm_routing_get_voice_mixer, + msm_routing_put_voice_mixer), }; static const struct snd_kcontrol_new sbus_0_rx_port_mixer_controls[] = { @@ -7249,6 +7383,8 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_AIF_OUT("SLIMBUS_8_RX", "Slimbus8 Playback", 0, 0, 0, 0), SND_SOC_DAPM_AIF_IN("SLIMBUS_8_TX", "Slimbus8 Capture", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_OUT("USB_AUDIO_RX", "USB Audio Playback", 0, 0, 0, 0), + SND_SOC_DAPM_AIF_IN("USB_AUDIO_TX", "USB Audio Capture", 0, 0, 0, 0), /* Switch Definitions */ SND_SOC_DAPM_SWITCH("SLIMBUS_DL_HL", SND_SOC_NOPM, 0, 0, @@ -7381,6 +7517,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("SLIMBUS_6_RX Audio Mixer", SND_SOC_NOPM, 0, 0, slimbus_6_rx_mixer_controls, ARRAY_SIZE(slimbus_6_rx_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX Audio Mixer", SND_SOC_NOPM, 0, 0, + usb_audio_rx_mixer_controls, + ARRAY_SIZE(usb_audio_rx_mixer_controls)), /* Voice Mixer */ SND_SOC_DAPM_MIXER("PRI_RX_Voice Mixer", SND_SOC_NOPM, 0, 0, pri_rx_voice_mixer_controls, @@ -7562,6 +7701,9 @@ static const struct snd_soc_dapm_widget msm_qdsp6_widgets[] = { SND_SOC_DAPM_MIXER("QCHAT_Tx Mixer", SND_SOC_NOPM, 0, 0, tx_qchat_mixer_controls, ARRAY_SIZE(tx_qchat_mixer_controls)), + SND_SOC_DAPM_MIXER("USB_AUDIO_RX_Voice Mixer", + SND_SOC_NOPM, 0, 0, usb_audio_rx_voice_mixer_controls, + ARRAY_SIZE(usb_audio_rx_voice_mixer_controls)), /* Virtual Pins to force backends ON atm */ SND_SOC_DAPM_OUTPUT("BE_OUT"), SND_SOC_DAPM_INPUT("BE_IN"), @@ -7749,6 +7891,24 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_7_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, {"SLIMBUS_7_RX", NULL, "SLIMBUS_7_RX Audio Mixer"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia4", "MM_DL4"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia5", "MM_DL5"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia6", "MM_DL6"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia7", "MM_DL7"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia8", "MM_DL8"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia9", "MM_DL9"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia10", "MM_DL10"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia11", "MM_DL11"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia12", "MM_DL12"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia13", "MM_DL13"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia14", "MM_DL14"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia15", "MM_DL15"}, + {"USB_AUDIO_RX Audio Mixer", "MultiMedia16", "MM_DL16"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX Audio Mixer"}, + {"MultiMedia1 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, {"MultiMedia4 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, {"MultiMedia8 Mixer", "VOC_REC_UL", "INCALL_RECORD_TX"}, @@ -8101,6 +8261,13 @@ static const struct snd_soc_dapm_route intercon[] = { {"MultiMedia8 Mixer", "QUAT_TDM_TX_2", "QUAT_TDM_TX_2"}, {"MultiMedia8 Mixer", "QUAT_TDM_TX_3", "QUAT_TDM_TX_3"}, + {"MultiMedia1 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia2 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia4 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia5 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia6 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"MultiMedia8 Mixer", "USB_AUDIO_TX", "USB_AUDIO_TX"}, + {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia1", "MM_DL1"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia2", "MM_DL2"}, {"INTERNAL_BT_SCO_RX Audio Mixer", "MultiMedia3", "MM_DL3"}, @@ -8304,6 +8471,20 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIM_6_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, {"SLIMBUS_6_RX", NULL, "SLIM_6_RX_Voice Mixer"}, + {"USB_AUDIO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, + {"USB_AUDIO_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoWLAN", "VoWLAN_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "Voip", "VOIP_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "DTMF", "DTMF_DL_HL"}, + {"USB_AUDIO_RX_Voice Mixer", "Voice Stub", "VOICE_STUB_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "Voice2 Stub", "VOICE2_STUB_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoLTE Stub", "VOLTE_STUB_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "QCHAT", "QCHAT_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode1", "VOICEMMODE1_DL"}, + {"USB_AUDIO_RX_Voice Mixer", "VoiceMMode2", "VOICEMMODE2_DL"}, + {"USB_AUDIO_RX", NULL, "USB_AUDIO_RX_Voice Mixer"}, + {"INTERNAL_BT_SCO_RX_Voice Mixer", "CSVoice", "CS-VOICE_DL1"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "Voice2", "VOICE2_DL"}, {"INTERNAL_BT_SCO_RX_Voice Mixer", "VoLTE", "VoLTE_DL"}, @@ -8497,6 +8678,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice_Tx Mixer", "SLIM_0_TX_Voice", "SLIMBUS_0_TX"}, {"Voice_Tx Mixer", "SLIM_7_TX_Voice", "SLIMBUS_7_TX"}, {"Voice_Tx Mixer", "SLIM_8_TX_Voice", "SLIMBUS_8_TX"}, + {"Voice_Tx Mixer", "USB_AUDIO_TX_Voice", "USB_AUDIO_TX"}, {"Voice_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice", "INT_BT_SCO_TX"}, {"Voice_Tx Mixer", "AFE_PCM_TX_Voice", "PCM_TX"}, {"Voice_Tx Mixer", "AUX_PCM_TX_Voice", "AUX_PCM_TX"}, @@ -8511,6 +8693,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voice2_Tx Mixer", "SLIM_0_TX_Voice2", "SLIMBUS_0_TX"}, {"Voice2_Tx Mixer", "SLIM_7_TX_Voice2", "SLIMBUS_7_TX"}, {"Voice2_Tx Mixer", "SLIM_8_TX_Voice2", "SLIMBUS_8_TX"}, + {"Voice2_Tx Mixer", "USB_AUDIO_TX_Voice2", "USB_AUDIO_TX"}, {"Voice2_Tx Mixer", "INTERNAL_BT_SCO_TX_Voice2", "INT_BT_SCO_TX"}, {"Voice2_Tx Mixer", "AFE_PCM_TX_Voice2", "PCM_TX"}, {"Voice2_Tx Mixer", "AUX_PCM_TX_Voice2", "AUX_PCM_TX"}, @@ -8521,6 +8704,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoLTE_Tx Mixer", "SLIM_0_TX_VoLTE", "SLIMBUS_0_TX"}, {"VoLTE_Tx Mixer", "SLIM_7_TX_VoLTE", "SLIMBUS_7_TX"}, {"VoLTE_Tx Mixer", "SLIM_8_TX_VoLTE", "SLIMBUS_8_TX"}, + {"VoLTE_Tx Mixer", "USB_AUDIO_TX_VoLTE", "USB_AUDIO_TX"}, {"VoLTE_Tx Mixer", "INTERNAL_BT_SCO_TX_VoLTE", "INT_BT_SCO_TX"}, {"VoLTE_Tx Mixer", "AFE_PCM_TX_VoLTE", "PCM_TX"}, {"VoLTE_Tx Mixer", "AUX_PCM_TX_VoLTE", "AUX_PCM_TX"}, @@ -8534,6 +8718,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoWLAN_Tx Mixer", "SLIM_0_TX_VoWLAN", "SLIMBUS_0_TX"}, {"VoWLAN_Tx Mixer", "SLIM_7_TX_VoWLAN", "SLIMBUS_7_TX"}, {"VoWLAN_Tx Mixer", "SLIM_8_TX_VoWLAN", "SLIMBUS_8_TX"}, + {"VoWLAN_Tx Mixer", "USB_AUDIO_TX_VoWLAN", "USB_AUDIO_TX"}, {"VoWLAN_Tx Mixer", "INTERNAL_BT_SCO_TX_VoWLAN", "INT_BT_SCO_TX"}, {"VoWLAN_Tx Mixer", "AFE_PCM_TX_VoWLAN", "PCM_TX"}, {"VoWLAN_Tx Mixer", "AUX_PCM_TX_VoWLAN", "AUX_PCM_TX"}, @@ -8550,6 +8735,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode1_Tx Mixer", "SLIM_0_TX_MMode1", "SLIMBUS_0_TX"}, {"VoiceMMode1_Tx Mixer", "SLIM_7_TX_MMode1", "SLIMBUS_7_TX"}, {"VoiceMMode1_Tx Mixer", "SLIM_8_TX_MMode1", "SLIMBUS_8_TX"}, + {"VoiceMMode1_Tx Mixer", "USB_AUDIO_TX_MMode1", "USB_AUDIO_TX"}, {"VoiceMMode1_Tx Mixer", "INT_BT_SCO_TX_MMode1", "INT_BT_SCO_TX"}, {"VoiceMMode1_Tx Mixer", "AFE_PCM_TX_MMode1", "PCM_TX"}, {"VoiceMMode1_Tx Mixer", "AUX_PCM_TX_MMode1", "AUX_PCM_TX"}, @@ -8563,6 +8749,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"VoiceMMode2_Tx Mixer", "SLIM_0_TX_MMode2", "SLIMBUS_0_TX"}, {"VoiceMMode2_Tx Mixer", "SLIM_7_TX_MMode2", "SLIMBUS_7_TX"}, {"VoiceMMode2_Tx Mixer", "SLIM_8_TX_MMode2", "SLIMBUS_8_TX"}, + {"VoiceMMode2_Tx Mixer", "USB_AUDIO_TX_MMode2", "USB_AUDIO_TX"}, {"VoiceMMode2_Tx Mixer", "INT_BT_SCO_TX_MMode2", "INT_BT_SCO_TX"}, {"VoiceMMode2_Tx Mixer", "AFE_PCM_TX_MMode2", "PCM_TX"}, {"VoiceMMode2_Tx Mixer", "AUX_PCM_TX_MMode2", "AUX_PCM_TX"}, @@ -8575,6 +8762,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"Voip_Tx Mixer", "SLIM_0_TX_Voip", "SLIMBUS_0_TX"}, {"Voip_Tx Mixer", "SLIM_7_TX_Voip", "SLIMBUS_7_TX"}, {"Voip_Tx Mixer", "SLIM_8_TX_Voip", "SLIMBUS_8_TX"}, + {"Voip_Tx Mixer", "USB_AUDIO_TX_Voip", "USB_AUDIO_TX"}, {"Voip_Tx Mixer", "INTERNAL_BT_SCO_TX_Voip", "INT_BT_SCO_TX"}, {"Voip_Tx Mixer", "AFE_PCM_TX_Voip", "PCM_TX"}, {"Voip_Tx Mixer", "AUX_PCM_TX_Voip", "AUX_PCM_TX"}, @@ -8676,6 +8864,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"QCHAT_Tx Mixer", "MI2S_TX_QCHAT", "MI2S_TX"}, {"QCHAT_Tx Mixer", "PRI_MI2S_TX_QCHAT", "PRI_MI2S_TX"}, {"QCHAT_Tx Mixer", "TERT_MI2S_TX_QCHAT", "TERT_MI2S_TX"}, + {"QCHAT_Tx Mixer", "USB_AUDIO_TX_QCHAT", "USB_AUDIO_TX"}, {"QCHAT_UL", NULL, "QCHAT_Tx Mixer"}, {"INT_FM_RX", NULL, "INTFM_DL_HL"}, @@ -9069,6 +9258,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"BE_OUT", NULL, "SLIMBUS_6_RX"}, {"BE_OUT", NULL, "SLIMBUS_7_RX"}, {"BE_OUT", NULL, "SLIMBUS_8_RX"}, + {"BE_OUT", NULL, "USB_AUDIO_RX"}, {"BE_OUT", NULL, "HDMI"}, {"BE_OUT", NULL, "SPDIF_RX"}, {"BE_OUT", NULL, "MI2S_RX"}, @@ -9118,6 +9308,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"SLIMBUS_6_TX", NULL, "BE_IN" }, {"SLIMBUS_7_TX", NULL, "BE_IN" }, {"SLIMBUS_8_TX", NULL, "BE_IN" }, + {"USB_AUDIO_TX", NULL, "BE_IN" }, {"INT_BT_SCO_TX", NULL, "BE_IN"}, {"INT_FM_TX", NULL, "BE_IN"}, {"PCM_TX", NULL, "BE_IN"}, diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h index 01e7d8641c69..6d1109f0bc6d 100644 --- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h +++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h @@ -135,6 +135,8 @@ #define LPASS_BE_SLIMBUS_8_RX "SLIMBUS_8_RX" #define LPASS_BE_SLIMBUS_8_TX "SLIMBUS_8_TX" +#define LPASS_BE_USB_AUDIO_RX "USB_AUDIO_RX" +#define LPASS_BE_USB_AUDIO_TX "USB_AUDIO_TX" /* For multimedia front-ends, asm session is allocated dynamically. * Hence, asm session/multimedia front-end mapping has to be maintained. * Due to this reason, additional multimedia front-end must be placed before @@ -305,6 +307,8 @@ enum { MSM_BACKEND_DAI_SLIMBUS_7_TX, MSM_BACKEND_DAI_SLIMBUS_8_RX, MSM_BACKEND_DAI_SLIMBUS_8_TX, + MSM_BACKEND_DAI_USB_RX, + MSM_BACKEND_DAI_USB_TX, MSM_BACKEND_DAI_MAX, }; diff --git a/sound/soc/msm/qdsp6v2/q6afe.c b/sound/soc/msm/qdsp6v2/q6afe.c index 48cd7c8ebff0..89d3fb7d6156 100644 --- a/sound/soc/msm/qdsp6v2/q6afe.c +++ b/sound/soc/msm/qdsp6v2/q6afe.c @@ -477,6 +477,7 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_RX_5: case AFE_PORT_ID_QUATERNARY_TDM_RX_6: case AFE_PORT_ID_QUATERNARY_TDM_RX_7: + case AFE_PORT_ID_USB_RX: ret = MSM_AFE_PORT_TYPE_RX; break; @@ -538,6 +539,7 @@ int afe_get_port_type(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_TX_5: case AFE_PORT_ID_QUATERNARY_TDM_TX_6: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: + case AFE_PORT_ID_USB_TX: ret = MSM_AFE_PORT_TYPE_TX; break; @@ -603,6 +605,10 @@ int afe_sizeof_cfg_cmd(u16 port_id) case RT_PROXY_PORT_001_TX: ret_size = SIZEOF_CFG_CMD(afe_param_id_rt_proxy_port_cfg); break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + ret_size = SIZEOF_CFG_CMD(afe_param_id_usb_audio_cfg); + break; case AFE_PORT_ID_PRIMARY_PCM_RX: case AFE_PORT_ID_PRIMARY_PCM_TX: case AFE_PORT_ID_SECONDARY_PCM_RX: @@ -2577,6 +2583,55 @@ void afe_set_cal_mode(u16 port_id, enum afe_cal_mode afe_cal_mode) this_afe.afe_cal_mode[port_index] = afe_cal_mode; } +int afe_port_send_usb_dev_param(u16 port_id, union afe_port_config *afe_config) +{ + struct afe_usb_audio_dev_param_command config; + int ret = 0, index = 0; + + if (!afe_config) { + pr_err("%s: Error, no configuration data\n", __func__); + ret = -EINVAL; + goto exit; + } + index = q6audio_get_port_index(port_id); + if (index < 0 || index > AFE_MAX_PORTS) { + pr_err("%s: AFE port index[%d] invalid! for port ID 0x%x\n", + __func__, index, port_id); + ret = -EINVAL; + goto exit; + } + memset(&config, 0, sizeof(config)); + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, + APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); + config.hdr.pkt_size = sizeof(config); + config.hdr.src_port = 0; + config.hdr.dest_port = 0; + config.hdr.token = index; + config.hdr.opcode = AFE_PORT_CMD_SET_PARAM_V2; + config.param.port_id = q6audio_get_port_id(port_id); + config.param.payload_size = sizeof(config) - sizeof(struct apr_hdr) - + sizeof(config.param); + config.param.payload_address_lsw = 0x00; + config.param.payload_address_msw = 0x00; + config.param.mem_map_handle = 0x00; + config.pdata.module_id = AFE_MODULE_AUDIO_DEV_INTERFACE; + config.pdata.param_id = AFE_PARAM_ID_USB_AUDIO_DEV_PARAMS; + config.pdata.param_size = sizeof(config.usb_dev); + config.usb_dev.cfg_minor_version = + AFE_API_MINIOR_VERSION_USB_AUDIO_CONFIG; + config.usb_dev.dev_token = afe_config->usb_audio.dev_token; + + ret = afe_apr_send_pkt(&config, &this_afe.wait[index]); + if (ret) { + pr_err("%s: AFE device param cmd failed %d\n", + __func__, ret); + ret = -EINVAL; + goto exit; + } +exit: + return ret; +} + int afe_port_start(u16 port_id, union afe_port_config *afe_config, u32 rate) /* This function is no blocking */ { @@ -2688,6 +2743,18 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, this_afe.aanc_info.aanc_rx_port); pr_debug("%s: afe_aanc_start ret %d\n", __func__, ret); } + + if ((port_id == AFE_PORT_ID_USB_RX) || + (port_id == AFE_PORT_ID_USB_TX)) { + ret = afe_port_send_usb_dev_param(port_id, afe_config); + if (ret) { + pr_err("%s: AFE device param for port 0x%x failed %d\n", + __func__, port_id, ret); + ret = -EINVAL; + goto fail_cmd; + } + } + config.hdr.hdr_field = APR_HDR_FIELD(APR_MSG_TYPE_SEQ_CMD, APR_HDR_LEN(APR_HDR_SIZE), APR_PKT_VER); config.hdr.pkt_size = sizeof(config); @@ -2751,6 +2818,10 @@ int afe_port_start(u16 port_id, union afe_port_config *afe_config, case SLIMBUS_8_TX: cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG; + break; case RT_PROXY_PORT_001_RX: case RT_PROXY_PORT_001_TX: cfg_type = AFE_PARAM_ID_RT_PROXY_CONFIG; @@ -2870,6 +2941,8 @@ int afe_get_port_index(u16 port_id) case SLIMBUS_7_TX: return IDX_SLIMBUS_7_TX; case SLIMBUS_8_RX: return IDX_SLIMBUS_8_RX; case SLIMBUS_8_TX: return IDX_SLIMBUS_8_TX; + case AFE_PORT_ID_USB_RX: return IDX_AFE_PORT_ID_USB_RX; + case AFE_PORT_ID_USB_TX: return IDX_AFE_PORT_ID_USB_TX; case AFE_PORT_ID_PRIMARY_MI2S_RX: return IDX_AFE_PORT_ID_PRIMARY_MI2S_RX; case AFE_PORT_ID_PRIMARY_MI2S_TX: @@ -3135,6 +3208,10 @@ int afe_open(u16 port_id, case SLIMBUS_8_TX: cfg_type = AFE_PARAM_ID_SLIMBUS_CONFIG; break; + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: + cfg_type = AFE_PARAM_ID_USB_AUDIO_CONFIG; + break; default: pr_err("%s: Invalid port id 0x%x\n", __func__, port_id); @@ -4598,6 +4675,8 @@ int afe_validate_port(u16 port_id) case SLIMBUS_7_TX: case SLIMBUS_8_RX: case SLIMBUS_8_TX: + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: case AFE_PORT_ID_PRIMARY_MI2S_RX: case AFE_PORT_ID_PRIMARY_MI2S_TX: case AFE_PORT_ID_SECONDARY_MI2S_RX: diff --git a/sound/soc/msm/qdsp6v2/q6audio-v2.c b/sound/soc/msm/qdsp6v2/q6audio-v2.c index 232132f90e4d..56dc6b58a646 100644 --- a/sound/soc/msm/qdsp6v2/q6audio-v2.c +++ b/sound/soc/msm/qdsp6v2/q6audio-v2.c @@ -220,6 +220,10 @@ int q6audio_get_port_index(u16 port_id) return IDX_AFE_PORT_ID_QUATERNARY_TDM_TX_7; case AFE_PORT_ID_SENARY_MI2S_TX: return IDX_AFE_PORT_ID_SENARY_MI2S_TX; + case AFE_PORT_ID_USB_RX: + return IDX_AFE_PORT_ID_USB_RX; + case AFE_PORT_ID_USB_TX: + return IDX_AFE_PORT_ID_USB_TX; default: return -EINVAL; } } @@ -425,6 +429,10 @@ int q6audio_get_port_id(u16 port_id) return AFE_PORT_ID_QUATERNARY_TDM_TX_7; case AFE_PORT_ID_SENARY_MI2S_TX: return AFE_PORT_ID_SENARY_MI2S_TX; + case AFE_PORT_ID_USB_RX: + return AFE_PORT_ID_USB_RX; + case AFE_PORT_ID_USB_TX: + return AFE_PORT_ID_USB_TX; default: pr_warn("%s: Invalid port_id %d\n", __func__, port_id); return -EINVAL; @@ -672,6 +680,8 @@ int q6audio_validate_port(u16 port_id) case AFE_PORT_ID_QUATERNARY_TDM_RX_7: case AFE_PORT_ID_QUATERNARY_TDM_TX_7: case AFE_PORT_ID_SENARY_MI2S_TX: + case AFE_PORT_ID_USB_RX: + case AFE_PORT_ID_USB_TX: { ret = 0; break;