OSDN Git Service

ASoC: msm: Add USB audio via ADSP support
authorKuirong Wang <kuirongw@codeaurora.org>
Mon, 9 May 2016 21:35:30 +0000 (14:35 -0700)
committerJeevan Shriram <jshriram@codeaurora.org>
Mon, 16 May 2016 05:42:12 +0000 (22:42 -0700)
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 <vathota@codeaurora.org>
Signed-off-by: Kuirong Wang <kuirongw@codeaurora.org>
include/sound/apr_audio-v2.h
include/sound/q6afe-v2.h
sound/soc/msm/qdsp6v2/msm-dai-q6-v2.c
sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.h
sound/soc/msm/qdsp6v2/q6afe.c
sound/soc/msm/qdsp6v2/q6audio-v2.c

index db66cd7..24b2833 100644 (file)
@@ -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 {
index d30be94..5cd6535 100644 (file)
@@ -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
 };
 
index 07fd1a4..2ca6f59 100644 (file)
@@ -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);
index a8dae0e..444c3fa 100644 (file)
@@ -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"},
index 01e7d86..6d1109f 100644 (file)
 #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,
 };
 
index 48cd7c8..89d3fb7 100644 (file)
@@ -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:
index 232132f..56dc6b5 100644 (file)
@@ -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;