Skip to content

Commit

Permalink
ASoC: mediatek: mt8183: switch tdm pins gpio function when playback o…
Browse files Browse the repository at this point in the history
…n or off

Pull TDM pins down when TDM BE shutdown to avoid current leakage.

Signed-off-by: Jiaxin Yu <jiaxin.yu@mediatek.com>
Link: https://lore.kernel.org/r/1566478261-13464-2-git-send-email-jiaxin.yu@mediatek.com
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
yujiaxinff authored and broonie committed Aug 22, 2019
1 parent 97aad5c commit 6191cbd
Showing 1 changed file with 109 additions and 6 deletions.
115 changes: 109 additions & 6 deletions sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,32 @@ static int mt8183_i2s_hw_params_fixup(struct snd_soc_pcm_runtime *rtd,
return 0;
}

static const struct snd_soc_dapm_widget
mt8183_mt6358_ts3a227_max98357_dapm_widgets[] = {
SND_SOC_DAPM_OUTPUT("IT6505_8CH"),
};

static const struct snd_soc_dapm_route
mt8183_mt6358_ts3a227_max98357_dapm_routes[] = {
{"IT6505_8CH", NULL, "TDM"},
};

enum PINCTRL_PIN_STATE {
PIN_STATE_DEFAULT = 0,
PIN_TDM_OUT_ON,
PIN_TDM_OUT_OFF,
PIN_STATE_MAX
};

static const char * const mt8183_pin_str[PIN_STATE_MAX] = {
"default", "aud_tdm_out_on", "aud_tdm_out_off",
};

struct mt8183_mt6358_ts3a227_max98357_priv {
struct pinctrl *pinctrl;
struct pinctrl_state *pin_states[PIN_STATE_MAX];
};

static int
mt8183_mt6358_ts3a227_max98357_bt_sco_startup(
struct snd_pcm_substream *substream)
Expand Down Expand Up @@ -173,6 +199,47 @@ SND_SOC_DAILINK_DEFS(tdm,
DAILINK_COMP_ARRAY(COMP_DUMMY()),
DAILINK_COMP_ARRAY(COMP_EMPTY()));

static int mt8183_mt6358_tdm_startup(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
snd_soc_card_get_drvdata(rtd->card);
int ret;

if (IS_ERR(priv->pin_states[PIN_TDM_OUT_ON]))
return PTR_ERR(priv->pin_states[PIN_TDM_OUT_ON]);

ret = pinctrl_select_state(priv->pinctrl,
priv->pin_states[PIN_TDM_OUT_ON]);
if (ret)
dev_err(rtd->card->dev, "%s failed to select state %d\n",
__func__, ret);

return ret;
}

static void mt8183_mt6358_tdm_shutdown(struct snd_pcm_substream *substream)
{
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct mt8183_mt6358_ts3a227_max98357_priv *priv =
snd_soc_card_get_drvdata(rtd->card);
int ret;

if (IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF]))
return;

ret = pinctrl_select_state(priv->pinctrl,
priv->pin_states[PIN_TDM_OUT_OFF]);
if (ret)
dev_err(rtd->card->dev, "%s failed to select state %d\n",
__func__, ret);
}

static struct snd_soc_ops mt8183_mt6358_tdm_ops = {
.startup = mt8183_mt6358_tdm_startup,
.shutdown = mt8183_mt6358_tdm_shutdown,
};

static struct snd_soc_dai_link
mt8183_mt6358_ts3a227_max98357_dai_links[] = {
/* FE */
Expand Down Expand Up @@ -325,6 +392,8 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = {
.no_pcm = 1,
.dpcm_playback = 1,
.ignore_suspend = 1,
.be_hw_params_fixup = mt8183_i2s_hw_params_fixup,
.ops = &mt8183_mt6358_tdm_ops,
SND_SOC_DAILINK_REG(tdm),
},
};
Expand Down Expand Up @@ -371,7 +440,8 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
struct snd_soc_card *card = &mt8183_mt6358_ts3a227_max98357_card;
struct device_node *platform_node;
struct snd_soc_dai_link *dai_link;
struct pinctrl *default_pins;
struct mt8183_mt6358_ts3a227_max98357_priv *priv;
int ret;
int i;

card->dev = &pdev->dev;
Expand All @@ -397,12 +467,45 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
card->num_aux_devs = 1;
}

default_pins =
devm_pinctrl_get_select(&pdev->dev, PINCTRL_STATE_DEFAULT);
if (IS_ERR(default_pins)) {
dev_err(&pdev->dev, "%s set pins failed\n",
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;

snd_soc_card_set_drvdata(card, priv);

priv->pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(priv->pinctrl)) {
dev_err(&pdev->dev, "%s devm_pinctrl_get failed\n",
__func__);
return PTR_ERR(default_pins);
return PTR_ERR(priv->pinctrl);
}

for (i = 0 ; i < PIN_STATE_MAX ; i++) {
priv->pin_states[i] = pinctrl_lookup_state(priv->pinctrl,
mt8183_pin_str[i]);
if (IS_ERR(priv->pin_states[i])) {
ret = PTR_ERR(priv->pin_states[i]);
dev_info(&pdev->dev, "%s Can't find pin state %s %d\n",
__func__, mt8183_pin_str[i], ret);
}
}

if (!IS_ERR(priv->pin_states[PIN_TDM_OUT_OFF])) {
ret = pinctrl_select_state(priv->pinctrl,
priv->pin_states[PIN_TDM_OUT_OFF]);
if (ret)
dev_info(&pdev->dev,
"%s failed to select state %d\n",
__func__, ret);
}

if (!IS_ERR(priv->pin_states[PIN_STATE_DEFAULT])) {
ret = pinctrl_select_state(priv->pinctrl,
priv->pin_states[PIN_STATE_DEFAULT]);
if (ret)
dev_info(&pdev->dev,
"%s failed to select state %d\n",
__func__, ret);
}

return devm_snd_soc_register_card(&pdev->dev, card);
Expand Down

0 comments on commit 6191cbd

Please sign in to comment.