]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
tegra-virt-alt: Add support for I2S loopback
authorHariharan Sivaraman <hariharans@nvidia.com>
Mon, 9 Jan 2017 05:31:45 +0000 (11:01 +0530)
committermobile promotions <svcmobile_promotions@nvidia.com>
Wed, 1 Feb 2017 05:56:42 +0000 (21:56 -0800)
Add mixer command support for I2S loopback enable

Jira EMA-372

Change-Id: Iec4aedd6fdadae71c7ecd358ffe187af9e3def13
Signed-off-by: Hariharan Sivaraman <hariharans@nvidia.com>
Reviewed-on: http://git-master/r/1282080
(cherry picked from commit cad26f6a0b4b3c0f3caa92dac30f6fd1d1f2e872)
Reviewed-on: http://git-master/r/1293717
Reviewed-by: svccoveritychecker <svccoveritychecker@nvidia.com>
GVS: Gerrit_Virtual_Submit
Reviewed-by: Nitin Pai <npai@nvidia.com>
sound/soc/tegra-virt-alt/tegra_virt_alt_ivc_common.h
sound/soc/tegra-virt-alt/tegra_virt_t210ref_pcm.c

index 9ba1ff805a6f81a59093236c18301e6222a2a20f..b13dc44b1da3c0c582d01c401e2e7aa493515951 100644 (file)
@@ -83,6 +83,8 @@ enum nvaudio_ivc_cmd_t {
 #endif
        NVAUDIO_ADSP_REQUEST_ASSIGNMENT,
        NVAUDIO_AMX_SET_INPUT_STREAM_ENABLE,
+       NVAUDIO_I2S_SET_LOOPBACK_ENABLE,
+       NVAUDIO_I2S_GET_LOOPBACK_ENABLE,
        NVAUDIO_CMD_MAX,
 };
 
@@ -100,6 +102,11 @@ struct nvaudio_ivc_t210_amx_info {
        uint32_t        amx_stream_enable;
 };
 
+struct nvaudio_ivc_t210_i2s_info {
+       int32_t         i2s_id;
+       uint32_t        i2s_loopback_enable;
+};
+
 struct nvaudio_ivc_t210_amixer_info {
        int32_t         id;
        uint32_t        rx_idx;
@@ -167,6 +174,7 @@ struct nvaudio_ivc_msg {
                struct nvaudio_ivc_t186_arad_info       arad_info;
 #endif
                struct nvaudio_ivc_t210_amx_info        amx_info;
+               struct nvaudio_ivc_t210_i2s_info        i2s_info;
                struct nvaudio_ivc_xbar_link            xbar_info;
        } params;
        bool                    ack_required;
index bcf6aaffdb5f86cad1b79b9b90cc5337e7a2c461..2b6594972a6ccc8b7c0d06b4b547703dd6db61be 100644 (file)
@@ -1917,6 +1917,76 @@ static int tegra_virt_t210_amx_set_input_stream_enable(
        return 0;
 }
 
+static int tegra_virt_i2s_get_loopback_enable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+       struct nvaudio_ivc_ctxt *hivc_client =
+               nvaudio_ivc_alloc_ctxt(card->dev);
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       unsigned int reg = mc->reg;
+       int err;
+       struct nvaudio_ivc_msg msg;
+
+       memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
+       msg.cmd = NVAUDIO_I2S_GET_LOOPBACK_ENABLE;
+       msg.params.i2s_info.i2s_id = reg;
+
+       err = nvaudio_ivc_send_retry(hivc_client,
+                       &msg,
+                       sizeof(struct nvaudio_ivc_msg));
+
+       if (err < 0) {
+               pr_err("%s: Timedout on ivc_send_retry\n", __func__);
+               return err;
+       }
+
+       err = nvaudio_ivc_receive(hivc_client,
+                       &msg,
+                       sizeof(struct nvaudio_ivc_msg));
+       if (err < 0) {
+               pr_err("%s: Timedout on ivc_send_retry\n", __func__);
+               return err;
+       }
+
+       ucontrol->value.integer.value[0] =
+                       msg.params.i2s_info.i2s_loopback_enable;
+
+       return 0;
+}
+
+static int tegra_virt_i2s_set_loopback_enable(
+       struct snd_kcontrol *kcontrol,
+       struct snd_ctl_elem_value *ucontrol)
+{
+       struct soc_mixer_control *mc =
+               (struct soc_mixer_control *)kcontrol->private_value;
+       unsigned int reg = mc->reg;
+       struct snd_soc_card *card = snd_kcontrol_chip(kcontrol);
+       struct nvaudio_ivc_ctxt *hivc_client =
+               nvaudio_ivc_alloc_ctxt(card->dev);
+       int err;
+       struct nvaudio_ivc_msg msg;
+
+       memset(&msg, 0, sizeof(struct nvaudio_ivc_msg));
+       msg.cmd = NVAUDIO_I2S_SET_LOOPBACK_ENABLE;
+       msg.params.i2s_info.i2s_id = reg;
+       msg.params.i2s_info.i2s_loopback_enable =
+               ucontrol->value.integer.value[0];
+
+       err = nvaudio_ivc_send_retry(hivc_client,
+                       &msg,
+                       sizeof(struct nvaudio_ivc_msg));
+       if (err < 0) {
+               pr_err("%s: Timedout on ivc_send_retry\n", __func__);
+               return err;
+       }
+
+       return 0;
+}
+
 static const struct soc_enum tegra_virt_t210ref_source =
        SOC_ENUM_SINGLE_EXT(NUM_MUX_INPUT, tegra_virt_t210ref_source_text);
 
@@ -2096,6 +2166,13 @@ static int32_t tegra210_adsp_hv_req_adsp_assignment(
        tegra_virt_t210_amx_get_input_stream_enable,    \
        tegra_virt_t210_amx_set_input_stream_enable)
 
+
+#define I2S_LOOPBACK_ENABLE_CTRL_DECL(ename, reg) \
+       SOC_SINGLE_EXT(ename, reg,      \
+       0, 1, 0,        \
+       tegra_virt_i2s_get_loopback_enable,     \
+       tegra_virt_i2s_set_loopback_enable)
+
 static const struct snd_kcontrol_new tegra_virt_t210ref_controls[] = {
 MUX_ENUM_CTRL_DECL("ADMAIF1 Mux", 0x00),
 MUX_ENUM_CTRL_DECL("ADMAIF2 Mux", 0x01),
@@ -2369,6 +2446,15 @@ AMX_ENABLE_CTRL_DECL("AMX4-2 Enable", 0x04, 0x02),
 AMX_ENABLE_CTRL_DECL("AMX4-3 Enable", 0x04, 0x03),
 AMX_ENABLE_CTRL_DECL("AMX4-4 Enable", 0x04, 0x04),
 #endif
+
+I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S1 Loopback", 0x01),
+I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S2 Loopback", 0x02),
+I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S3 Loopback", 0x03),
+I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S4 Loopback", 0x04),
+I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S5 Loopback", 0x05),
+#ifdef CONFIG_ARCH_TEGRA_18x_SOC
+I2S_LOOPBACK_ENABLE_CTRL_DECL("I2S6 Loopback", 0x06),
+#endif
 };
 
 static const struct of_device_id tegra_virt_t210ref_pcm_of_match[] = {