|
@@ -22,6 +22,7 @@
|
|
|
#include <linux/input.h>
|
|
|
#include <linux/of_device.h>
|
|
|
#include <linux/pm_qos.h>
|
|
|
+#include <linux/regulator/consumer.h>
|
|
|
#include <sound/core.h>
|
|
|
#include <sound/soc.h>
|
|
|
#include <sound/soc-dapm.h>
|
|
@@ -176,32 +177,20 @@ struct msm_csra66x0_dev_info {
|
|
|
u32 index;
|
|
|
};
|
|
|
|
|
|
-enum pinctrl_pin_state {
|
|
|
- STATE_DISABLE = 0, /* All pins are in sleep state */
|
|
|
- STATE_MI2S_ACTIVE, /* I2S = active, TDM = sleep */
|
|
|
- STATE_TDM_ACTIVE, /* I2S = sleep, TDM = active */
|
|
|
-};
|
|
|
-
|
|
|
-struct msm_pinctrl_info {
|
|
|
- struct pinctrl *pinctrl;
|
|
|
- struct pinctrl_state *mi2s_disable;
|
|
|
- struct pinctrl_state *tdm_disable;
|
|
|
- struct pinctrl_state *mi2s_active;
|
|
|
- struct pinctrl_state *tdm_active;
|
|
|
- enum pinctrl_pin_state curr_state;
|
|
|
-};
|
|
|
-
|
|
|
struct msm_asoc_mach_data {
|
|
|
struct snd_info_entry *codec_root;
|
|
|
- struct msm_pinctrl_info pinctrl_info;
|
|
|
struct device_node *dmic_01_gpio_p; /* used by pinctrl API */
|
|
|
struct device_node *dmic_23_gpio_p; /* used by pinctrl API */
|
|
|
struct device_node *dmic_45_gpio_p; /* used by pinctrl API */
|
|
|
struct device_node *dmic_67_gpio_p; /* used by pinctrl API */
|
|
|
+ struct device_node *mi2s_gpio_p[MI2S_MAX]; /* used by pinctrl API */
|
|
|
int dmic_01_gpio_cnt;
|
|
|
int dmic_23_gpio_cnt;
|
|
|
int dmic_45_gpio_cnt;
|
|
|
int dmic_67_gpio_cnt;
|
|
|
+ struct regulator *tdm_micb_supply;
|
|
|
+ u32 tdm_micb_voltage;
|
|
|
+ u32 tdm_micb_current;
|
|
|
};
|
|
|
|
|
|
struct msm_asoc_wcd93xx_codec {
|
|
@@ -5074,164 +5063,6 @@ err:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static int msm_set_pinctrl(struct msm_pinctrl_info *pinctrl_info,
|
|
|
- enum pinctrl_pin_state new_state)
|
|
|
-{
|
|
|
- int ret = 0;
|
|
|
- int curr_state = 0;
|
|
|
-
|
|
|
- if (pinctrl_info == NULL) {
|
|
|
- pr_err("%s: pinctrl_info is NULL\n", __func__);
|
|
|
- ret = -EINVAL;
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- if (pinctrl_info->pinctrl == NULL) {
|
|
|
- pr_err("%s: pinctrl_info->pinctrl is NULL\n", __func__);
|
|
|
- ret = -EINVAL;
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- curr_state = pinctrl_info->curr_state;
|
|
|
- pinctrl_info->curr_state = new_state;
|
|
|
- pr_debug("%s: curr_state = %s new_state = %s\n", __func__,
|
|
|
- pin_states[curr_state], pin_states[pinctrl_info->curr_state]);
|
|
|
-
|
|
|
- if (curr_state == pinctrl_info->curr_state) {
|
|
|
- pr_debug("%s: Already in same state\n", __func__);
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- if (curr_state != STATE_DISABLE &&
|
|
|
- pinctrl_info->curr_state != STATE_DISABLE) {
|
|
|
- pr_debug("%s: state already active cannot switch\n", __func__);
|
|
|
- ret = -EIO;
|
|
|
- goto err;
|
|
|
- }
|
|
|
-
|
|
|
- switch (pinctrl_info->curr_state) {
|
|
|
- case STATE_MI2S_ACTIVE:
|
|
|
- ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
|
|
- pinctrl_info->mi2s_active);
|
|
|
- if (ret) {
|
|
|
- pr_err("%s: MI2S state select failed with %d\n",
|
|
|
- __func__, ret);
|
|
|
- ret = -EIO;
|
|
|
- goto err;
|
|
|
- }
|
|
|
- break;
|
|
|
- case STATE_TDM_ACTIVE:
|
|
|
- ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
|
|
- pinctrl_info->tdm_active);
|
|
|
- if (ret) {
|
|
|
- pr_err("%s: TDM state select failed with %d\n",
|
|
|
- __func__, ret);
|
|
|
- ret = -EIO;
|
|
|
- goto err;
|
|
|
- }
|
|
|
- break;
|
|
|
- case STATE_DISABLE:
|
|
|
- if (curr_state == STATE_MI2S_ACTIVE) {
|
|
|
- ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
|
|
- pinctrl_info->mi2s_disable);
|
|
|
- } else {
|
|
|
- ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
|
|
- pinctrl_info->tdm_disable);
|
|
|
- }
|
|
|
- if (ret) {
|
|
|
- pr_err("%s: state disable failed with %d\n",
|
|
|
- __func__, ret);
|
|
|
- ret = -EIO;
|
|
|
- goto err;
|
|
|
- }
|
|
|
- break;
|
|
|
- default:
|
|
|
- pr_err("%s: TLMM pin state is invalid\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
-err:
|
|
|
- return ret;
|
|
|
-}
|
|
|
-
|
|
|
-static void msm_release_pinctrl(struct platform_device *pdev)
|
|
|
-{
|
|
|
- struct snd_soc_card *card = platform_get_drvdata(pdev);
|
|
|
- struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
|
|
- struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
|
|
-
|
|
|
- if (pinctrl_info->pinctrl) {
|
|
|
- devm_pinctrl_put(pinctrl_info->pinctrl);
|
|
|
- pinctrl_info->pinctrl = NULL;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static int msm_get_pinctrl(struct platform_device *pdev)
|
|
|
-{
|
|
|
- struct snd_soc_card *card = platform_get_drvdata(pdev);
|
|
|
- struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
|
|
- struct msm_pinctrl_info *pinctrl_info = NULL;
|
|
|
- struct pinctrl *pinctrl;
|
|
|
- int ret;
|
|
|
-
|
|
|
- pinctrl_info = &pdata->pinctrl_info;
|
|
|
-
|
|
|
- if (pinctrl_info == NULL) {
|
|
|
- pr_err("%s: pinctrl_info is NULL\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
-
|
|
|
- pinctrl = devm_pinctrl_get(&pdev->dev);
|
|
|
- if (IS_ERR_OR_NULL(pinctrl)) {
|
|
|
- pr_err("%s: Unable to get pinctrl handle\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
- }
|
|
|
- pinctrl_info->pinctrl = pinctrl;
|
|
|
-
|
|
|
- /* get all the states handles from Device Tree */
|
|
|
- pinctrl_info->mi2s_disable = pinctrl_lookup_state(pinctrl,
|
|
|
- "quat-mi2s-sleep");
|
|
|
- if (IS_ERR(pinctrl_info->mi2s_disable)) {
|
|
|
- pr_err("%s: could not get mi2s_disable pinstate\n", __func__);
|
|
|
- goto err;
|
|
|
- }
|
|
|
- pinctrl_info->mi2s_active = pinctrl_lookup_state(pinctrl,
|
|
|
- "quat-mi2s-active");
|
|
|
- if (IS_ERR(pinctrl_info->mi2s_active)) {
|
|
|
- pr_err("%s: could not get mi2s_active pinstate\n", __func__);
|
|
|
- goto err;
|
|
|
- }
|
|
|
- pinctrl_info->tdm_disable = pinctrl_lookup_state(pinctrl,
|
|
|
- "quat-tdm-sleep");
|
|
|
- if (IS_ERR(pinctrl_info->tdm_disable)) {
|
|
|
- pr_err("%s: could not get tdm_disable pinstate\n", __func__);
|
|
|
- goto err;
|
|
|
- }
|
|
|
- pinctrl_info->tdm_active = pinctrl_lookup_state(pinctrl,
|
|
|
- "quat-tdm-active");
|
|
|
- if (IS_ERR(pinctrl_info->tdm_active)) {
|
|
|
- pr_err("%s: could not get tdm_active pinstate\n",
|
|
|
- __func__);
|
|
|
- goto err;
|
|
|
- }
|
|
|
- /* Reset the TLMM pins to a default state */
|
|
|
- ret = pinctrl_select_state(pinctrl_info->pinctrl,
|
|
|
- pinctrl_info->mi2s_disable);
|
|
|
- if (ret != 0) {
|
|
|
- pr_err("%s: Disable TLMM pins failed with %d\n",
|
|
|
- __func__, ret);
|
|
|
- ret = -EIO;
|
|
|
- goto err;
|
|
|
- }
|
|
|
- pinctrl_info->curr_state = STATE_DISABLE;
|
|
|
-
|
|
|
- return 0;
|
|
|
-
|
|
|
-err:
|
|
|
- devm_pinctrl_put(pinctrl);
|
|
|
- pinctrl_info->pinctrl = NULL;
|
|
|
- return -EINVAL;
|
|
|
-}
|
|
|
|
|
|
static int msm_tdm_be_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
|
|
|
struct snd_pcm_hw_params *params)
|
|
@@ -5281,7 +5112,7 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
|
|
int ret = 0;
|
|
|
int slot_width = 32;
|
|
|
- int channels, slots;
|
|
|
+ int channels, slots = 8;
|
|
|
unsigned int slot_mask, rate, clk_freq;
|
|
|
unsigned int slot_offset[8] = {0, 4, 8, 12, 16, 20, 24, 28};
|
|
|
|
|
@@ -5290,34 +5121,34 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|
|
/* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
|
|
switch (cpu_dai->id) {
|
|
|
case AFE_PORT_ID_PRIMARY_TDM_RX:
|
|
|
- slots = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
|
|
|
+ channels = tdm_rx_cfg[TDM_PRI][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_SECONDARY_TDM_RX:
|
|
|
- slots = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
|
|
|
+ channels = tdm_rx_cfg[TDM_SEC][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_TERTIARY_TDM_RX:
|
|
|
- slots = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
|
|
|
+ channels = tdm_rx_cfg[TDM_TERT][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_QUATERNARY_TDM_RX:
|
|
|
- slots = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
|
|
|
+ channels = tdm_rx_cfg[TDM_QUAT][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_QUINARY_TDM_RX:
|
|
|
- slots = tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
|
|
|
+ channels = tdm_rx_cfg[TDM_QUIN][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_PRIMARY_TDM_TX:
|
|
|
- slots = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
|
|
|
+ channels = tdm_tx_cfg[TDM_PRI][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_SECONDARY_TDM_TX:
|
|
|
- slots = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
|
|
|
+ channels = tdm_tx_cfg[TDM_SEC][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_TERTIARY_TDM_TX:
|
|
|
- slots = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
|
|
|
+ channels = tdm_tx_cfg[TDM_TERT][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_QUATERNARY_TDM_TX:
|
|
|
- slots = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
|
|
|
+ channels = tdm_tx_cfg[TDM_QUAT][TDM_0].channels;
|
|
|
break;
|
|
|
case AFE_PORT_ID_QUINARY_TDM_TX:
|
|
|
- slots = tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
|
|
|
+ channels = tdm_tx_cfg[TDM_QUIN][TDM_0].channels;
|
|
|
break;
|
|
|
|
|
|
default:
|
|
@@ -5328,8 +5159,7 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|
|
|
|
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
|
|
|
/*2 slot config - bits 0 and 1 set for the first two slots */
|
|
|
- slot_mask = 0x0000FFFF >> (16-slots);
|
|
|
- channels = slots;
|
|
|
+ slot_mask = 0x0000FFFF >> (16-channels);
|
|
|
|
|
|
pr_debug("%s: tdm rx slot_width %d slots %d\n",
|
|
|
__func__, slot_width, slots);
|
|
@@ -5351,8 +5181,7 @@ static int qcs405_tdm_snd_hw_params(struct snd_pcm_substream *substream,
|
|
|
}
|
|
|
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
|
|
|
/*2 slot config - bits 0 and 1 set for the first two slots */
|
|
|
- slot_mask = 0x0000FFFF >> (16-slots);
|
|
|
- channels = slots;
|
|
|
+ slot_mask = 0x0000FFFF >> (16-channels);
|
|
|
|
|
|
pr_debug("%s: tdm tx slot_width %d slots %d\n",
|
|
|
__func__, slot_width, slots);
|
|
@@ -5390,6 +5219,38 @@ end:
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+static int msm_get_tdm_mode(u32 port_id)
|
|
|
+{
|
|
|
+ u32 tdm_mode;
|
|
|
+
|
|
|
+ switch (port_id) {
|
|
|
+ case AFE_PORT_ID_PRIMARY_TDM_RX:
|
|
|
+ case AFE_PORT_ID_PRIMARY_TDM_TX:
|
|
|
+ tdm_mode = TDM_PRI;
|
|
|
+ break;
|
|
|
+ case AFE_PORT_ID_SECONDARY_TDM_RX:
|
|
|
+ case AFE_PORT_ID_SECONDARY_TDM_TX:
|
|
|
+ tdm_mode = TDM_SEC;
|
|
|
+ break;
|
|
|
+ case AFE_PORT_ID_TERTIARY_TDM_RX:
|
|
|
+ case AFE_PORT_ID_TERTIARY_TDM_TX:
|
|
|
+ tdm_mode = TDM_TERT;
|
|
|
+ break;
|
|
|
+ case AFE_PORT_ID_QUATERNARY_TDM_RX:
|
|
|
+ case AFE_PORT_ID_QUATERNARY_TDM_TX:
|
|
|
+ tdm_mode = TDM_QUAT;
|
|
|
+ break;
|
|
|
+ case AFE_PORT_ID_QUINARY_TDM_RX:
|
|
|
+ case AFE_PORT_ID_QUINARY_TDM_TX:
|
|
|
+ tdm_mode = TDM_QUIN;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ pr_err("%s: Invalid port id: %d\n", __func__, port_id);
|
|
|
+ tdm_mode = -EINVAL;
|
|
|
+ }
|
|
|
+ return tdm_mode;
|
|
|
+}
|
|
|
+
|
|
|
static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream)
|
|
|
{
|
|
|
int ret = 0;
|
|
@@ -5397,17 +5258,50 @@ static int qcs405_tdm_snd_startup(struct snd_pcm_substream *substream)
|
|
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
|
|
struct snd_soc_card *card = rtd->card;
|
|
|
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
|
|
- struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
|
|
+ u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id);
|
|
|
|
|
|
- /* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
|
|
- if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
|
|
|
- (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
|
|
|
- ret = msm_set_pinctrl(pinctrl_info, STATE_TDM_ACTIVE);
|
|
|
+ if (tdm_mode >= TDM_INTERFACE_MAX) {
|
|
|
+ ret = -EINVAL;
|
|
|
+ pr_err("%s: Invalid TDM interface %d\n",
|
|
|
+ __func__, ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pdata->mi2s_gpio_p[tdm_mode]) {
|
|
|
+ ret = msm_cdc_pinctrl_select_active_state(
|
|
|
+ pdata->mi2s_gpio_p[tdm_mode]);
|
|
|
if (ret)
|
|
|
- pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
|
|
|
+ pr_err("%s: TDM GPIO pinctrl set active failed with %d\n",
|
|
|
__func__, ret);
|
|
|
}
|
|
|
|
|
|
+ /* Enable Mic bias for TDM Mics */
|
|
|
+ if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX) {
|
|
|
+ if (pdata->tdm_micb_supply) {
|
|
|
+ ret = regulator_set_voltage(pdata->tdm_micb_supply,
|
|
|
+ pdata->tdm_micb_voltage,
|
|
|
+ pdata->tdm_micb_voltage);
|
|
|
+ if (ret) {
|
|
|
+ pr_err("%s: Setting voltage failed, err = %d\n",
|
|
|
+ __func__, ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ ret = regulator_set_load(pdata->tdm_micb_supply,
|
|
|
+ pdata->tdm_micb_current);
|
|
|
+ if (ret) {
|
|
|
+ pr_err("%s: Setting current failed, err = %d\n",
|
|
|
+ __func__, ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ ret = regulator_enable(pdata->tdm_micb_supply);
|
|
|
+ if (ret) {
|
|
|
+ pr_err("%s: regulator enable failed, err = %d\n",
|
|
|
+ __func__, ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -5418,14 +5312,25 @@ static void qcs405_tdm_snd_shutdown(struct snd_pcm_substream *substream)
|
|
|
struct snd_soc_dai *cpu_dai = rtd->cpu_dai;
|
|
|
struct snd_soc_card *card = rtd->card;
|
|
|
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
|
|
- struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
|
|
+ u32 tdm_mode = msm_get_tdm_mode(cpu_dai->id);
|
|
|
|
|
|
- /* currently only supporting TDM_RX_0 and TDM_TX_0 */
|
|
|
- if ((cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_RX) ||
|
|
|
- (cpu_dai->id == AFE_PORT_ID_QUATERNARY_TDM_TX)) {
|
|
|
- ret = msm_set_pinctrl(pinctrl_info, STATE_DISABLE);
|
|
|
+ if (cpu_dai->id == AFE_PORT_ID_QUINARY_TDM_TX) {
|
|
|
+ if (pdata->tdm_micb_supply) {
|
|
|
+ ret = regulator_disable(pdata->tdm_micb_supply);
|
|
|
+ if (ret)
|
|
|
+ pr_err("%s: regulator disable failed, err = %d\n",
|
|
|
+ __func__, ret);
|
|
|
+ regulator_set_voltage(pdata->tdm_micb_supply, 0,
|
|
|
+ pdata->tdm_micb_voltage);
|
|
|
+ regulator_set_load(pdata->tdm_micb_supply, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (pdata->mi2s_gpio_p[tdm_mode]) {
|
|
|
+ ret = msm_cdc_pinctrl_select_sleep_state(
|
|
|
+ pdata->mi2s_gpio_p[tdm_mode]);
|
|
|
if (ret)
|
|
|
- pr_err("%s: TDM TLMM pinctrl set failed with %d\n",
|
|
|
+ pr_err("%s: TDM GPIO pinctrl set sleep failed with %d\n",
|
|
|
__func__, ret);
|
|
|
}
|
|
|
}
|
|
@@ -5469,8 +5374,6 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
|
|
|
unsigned int fmt = SND_SOC_DAIFMT_CBS_CFS;
|
|
|
struct snd_soc_card *card = rtd->card;
|
|
|
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
|
|
- struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
|
|
- int ret_pinctrl = 0;
|
|
|
|
|
|
dev_dbg(rtd->card->dev,
|
|
|
"%s: substream = %s stream = %d, dai name %s, dai ID %d\n",
|
|
@@ -5510,13 +5413,9 @@ static int msm_mi2s_snd_startup(struct snd_pcm_substream *substream)
|
|
|
__func__, index, ret);
|
|
|
goto clk_off;
|
|
|
}
|
|
|
- if (index == QUAT_MI2S) {
|
|
|
- ret_pinctrl = msm_set_pinctrl(pinctrl_info,
|
|
|
- STATE_MI2S_ACTIVE);
|
|
|
- if (ret_pinctrl)
|
|
|
- pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
|
|
|
- __func__, ret_pinctrl);
|
|
|
- }
|
|
|
+ if (pdata->mi2s_gpio_p[index])
|
|
|
+ msm_cdc_pinctrl_select_active_state(
|
|
|
+ pdata->mi2s_gpio_p[index]);
|
|
|
}
|
|
|
clk_off:
|
|
|
if (ret < 0)
|
|
@@ -5536,8 +5435,6 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
|
|
|
int index = rtd->cpu_dai->id;
|
|
|
struct snd_soc_card *card = rtd->card;
|
|
|
struct msm_asoc_mach_data *pdata = snd_soc_card_get_drvdata(card);
|
|
|
- struct msm_pinctrl_info *pinctrl_info = &pdata->pinctrl_info;
|
|
|
- int ret_pinctrl = 0;
|
|
|
|
|
|
pr_debug("%s(): substream = %s stream = %d\n", __func__,
|
|
|
substream->name, substream->stream);
|
|
@@ -5548,17 +5445,14 @@ static void msm_mi2s_snd_shutdown(struct snd_pcm_substream *substream)
|
|
|
|
|
|
mutex_lock(&mi2s_intf_conf[index].lock);
|
|
|
if (--mi2s_intf_conf[index].ref_cnt == 0) {
|
|
|
+ if (pdata->mi2s_gpio_p[index])
|
|
|
+ msm_cdc_pinctrl_select_sleep_state(
|
|
|
+ pdata->mi2s_gpio_p[index]);
|
|
|
+
|
|
|
ret = msm_mi2s_set_sclk(substream, false);
|
|
|
if (ret < 0)
|
|
|
pr_err("%s:clock disable failed for MI2S (%d); ret=%d\n",
|
|
|
__func__, index, ret);
|
|
|
- if (index == QUAT_MI2S) {
|
|
|
- ret_pinctrl = msm_set_pinctrl(pinctrl_info,
|
|
|
- STATE_DISABLE);
|
|
|
- if (ret_pinctrl)
|
|
|
- pr_err("%s: MI2S TLMM pinctrl set failed with %d\n",
|
|
|
- __func__, ret_pinctrl);
|
|
|
- }
|
|
|
}
|
|
|
mutex_unlock(&mi2s_intf_conf[index].lock);
|
|
|
}
|
|
@@ -8342,6 +8236,10 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|
|
struct msm_asoc_mach_data *pdata;
|
|
|
int ret;
|
|
|
u32 val;
|
|
|
+ const char *micb_supply_str = "tdm-vdd-micb-supply";
|
|
|
+ const char *micb_supply_str1 = "tdm-vdd-micb";
|
|
|
+ const char *micb_voltage_str = "qcom,tdm-vdd-micb-voltage";
|
|
|
+ const char *micb_current_str = "qcom,tdm-vdd-micb-current";
|
|
|
|
|
|
if (!pdev->dev.of_node) {
|
|
|
dev_err(&pdev->dev, "No platform supplied from device tree\n");
|
|
@@ -8404,17 +8302,53 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|
|
}
|
|
|
|
|
|
pdata->dmic_01_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
|
|
- "qcom,cdc-dmic01-gpios",
|
|
|
- 0);
|
|
|
+ "qcom,cdc-dmic01-gpios", 0);
|
|
|
pdata->dmic_23_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
|
|
- "qcom,cdc-dmic23-gpios",
|
|
|
- 0);
|
|
|
+ "qcom,cdc-dmic23-gpios", 0);
|
|
|
pdata->dmic_45_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
|
|
- "qcom,cdc-dmic45-gpios",
|
|
|
- 0);
|
|
|
+ "qcom,cdc-dmic45-gpios", 0);
|
|
|
pdata->dmic_67_gpio_p = of_parse_phandle(pdev->dev.of_node,
|
|
|
- "qcom,cdc-dmic67-gpios",
|
|
|
- 0);
|
|
|
+ "qcom,cdc-dmic67-gpios", 0);
|
|
|
+
|
|
|
+ pdata->mi2s_gpio_p[PRIM_MI2S] = of_parse_phandle(pdev->dev.of_node,
|
|
|
+ "qcom,pri-mi2s-gpios", 0);
|
|
|
+ pdata->mi2s_gpio_p[SEC_MI2S] = of_parse_phandle(pdev->dev.of_node,
|
|
|
+ "qcom,sec-mi2s-gpios", 0);
|
|
|
+ pdata->mi2s_gpio_p[TERT_MI2S] = of_parse_phandle(pdev->dev.of_node,
|
|
|
+ "qcom,tert-mi2s-gpios", 0);
|
|
|
+ pdata->mi2s_gpio_p[QUAT_MI2S] = of_parse_phandle(pdev->dev.of_node,
|
|
|
+ "qcom,quat-mi2s-gpios", 0);
|
|
|
+ pdata->mi2s_gpio_p[QUIN_MI2S] = of_parse_phandle(pdev->dev.of_node,
|
|
|
+ "qcom,quin-mi2s-gpios", 0);
|
|
|
+
|
|
|
+ if (of_parse_phandle(pdev->dev.of_node, micb_supply_str, 0)) {
|
|
|
+ pdata->tdm_micb_supply = devm_regulator_get(&pdev->dev,
|
|
|
+ micb_supply_str1);
|
|
|
+ if (IS_ERR(pdata->tdm_micb_supply)) {
|
|
|
+ ret = PTR_ERR(pdata->tdm_micb_supply);
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "%s:Failed to get micbias supply for TDM Mic %d\n",
|
|
|
+ __func__, ret);
|
|
|
+ }
|
|
|
+ ret = of_property_read_u32(pdev->dev.of_node,
|
|
|
+ micb_voltage_str,
|
|
|
+ &pdata->tdm_micb_voltage);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "%s:Looking up %s property in node %s failed\n",
|
|
|
+ __func__, micb_voltage_str,
|
|
|
+ pdev->dev.of_node->full_name);
|
|
|
+ }
|
|
|
+ ret = of_property_read_u32(pdev->dev.of_node,
|
|
|
+ micb_current_str,
|
|
|
+ &pdata->tdm_micb_current);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(&pdev->dev,
|
|
|
+ "%s:Looking up %s property in node %s failed\n",
|
|
|
+ __func__, micb_current_str,
|
|
|
+ pdev->dev.of_node->full_name);
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
ret = devm_snd_soc_register_card(&pdev->dev, card);
|
|
|
if (ret == -EPROBE_DEFER) {
|
|
@@ -8434,23 +8368,11 @@ static int msm_asoc_machine_probe(struct platform_device *pdev)
|
|
|
dev_err(&pdev->dev, "msm_mdf_mem_init failed (%d)\n",
|
|
|
ret);
|
|
|
|
|
|
- /* Parse pinctrl info from devicetree */
|
|
|
- ret = msm_get_pinctrl(pdev);
|
|
|
- if (!ret) {
|
|
|
- pr_debug("%s: pinctrl parsing successful\n", __func__);
|
|
|
- } else {
|
|
|
- dev_dbg(&pdev->dev,
|
|
|
- "%s: Parsing pinctrl failed with %d. Cannot use Ports\n",
|
|
|
- __func__, ret);
|
|
|
- ret = 0;
|
|
|
- }
|
|
|
-
|
|
|
msm_i2s_auxpcm_init(pdev);
|
|
|
|
|
|
is_initial_boot = true;
|
|
|
return 0;
|
|
|
err:
|
|
|
- msm_release_pinctrl(pdev);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -8460,7 +8382,6 @@ static int msm_asoc_machine_remove(struct platform_device *pdev)
|
|
|
msm_i2s_auxpcm_deinit();
|
|
|
msm_mdf_mem_deinit();
|
|
|
|
|
|
- msm_release_pinctrl(pdev);
|
|
|
return 0;
|
|
|
}
|
|
|
|