aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c')
-rw-r--r--sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c150
1 files changed, 115 insertions, 35 deletions
diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
index 887c932229d0..bb9cdc0d6552 100644
--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
+++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c
@@ -15,7 +15,22 @@
#include "mt8183-afe-common.h"
#include "../../codecs/ts3a227e.h"
-static struct snd_soc_jack headset_jack;
+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];
+ struct snd_soc_jack headset_jack;
+};
static int mt8183_mt6358_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
@@ -46,16 +61,6 @@ 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"},
-};
-
static int
mt8183_mt6358_ts3a227_max98357_bt_sco_startup(
struct snd_pcm_substream *substream)
@@ -183,6 +188,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 */
@@ -333,33 +379,30 @@ mt8183_mt6358_ts3a227_max98357_dai_links[] = {
{
.name = "TDM",
.no_pcm = 1,
+ .dai_fmt = SND_SOC_DAIFMT_I2S |
+ SND_SOC_DAIFMT_IB_IF |
+ SND_SOC_DAIFMT_CBM_CFM,
.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),
},
};
-static int
-mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *cpnt);
-
-static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
- .name = "Headset Chip",
- .init = mt8183_mt6358_ts3a227_max98357_headset_init,
-};
-
static struct snd_soc_card mt8183_mt6358_ts3a227_max98357_card = {
.name = "mt8183_mt6358_ts3a227_max98357",
.owner = THIS_MODULE,
.dai_link = mt8183_mt6358_ts3a227_max98357_dai_links,
.num_links = ARRAY_SIZE(mt8183_mt6358_ts3a227_max98357_dai_links),
- .aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev,
- .num_aux_devs = 1,
};
static int
mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
{
int ret;
+ struct mt8183_mt6358_ts3a227_max98357_priv *priv =
+ snd_soc_card_get_drvdata(component->card);
/* Enable Headset and 4 Buttons Jack detection */
ret = snd_soc_card_jack_new(&mt8183_mt6358_ts3a227_max98357_card,
@@ -367,23 +410,29 @@ mt8183_mt6358_ts3a227_max98357_headset_init(struct snd_soc_component *component)
SND_JACK_HEADSET |
SND_JACK_BTN_0 | SND_JACK_BTN_1 |
SND_JACK_BTN_2 | SND_JACK_BTN_3,
- &headset_jack,
+ &priv->headset_jack,
NULL, 0);
if (ret)
return ret;
- ret = ts3a227e_enable_jack_detect(component, &headset_jack);
+ ret = ts3a227e_enable_jack_detect(component, &priv->headset_jack);
return ret;
}
+static struct snd_soc_aux_dev mt8183_mt6358_ts3a227_max98357_headset_dev = {
+ .dlc = COMP_EMPTY(),
+ .init = mt8183_mt6358_ts3a227_max98357_headset_init,
+};
+
static int
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;
@@ -401,21 +450,53 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev)
dai_link->platforms->of_node = platform_node;
}
- mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node =
+ mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node =
of_parse_phandle(pdev->dev.of_node,
"mediatek,headset-codec", 0);
- if (!mt8183_mt6358_ts3a227_max98357_headset_dev.codec_of_node) {
- dev_err(&pdev->dev,
- "Property 'mediatek,headset-codec' missing/invalid\n");
- return -EINVAL;
+ if (mt8183_mt6358_ts3a227_max98357_headset_dev.dlc.of_node) {
+ card->aux_dev = &mt8183_mt6358_ts3a227_max98357_headset_dev;
+ 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);
@@ -445,4 +526,3 @@ MODULE_DESCRIPTION("MT8183-MT6358-TS3A227-MAX98357 ALSA SoC machine driver");
MODULE_AUTHOR("Shunli Wang <shunli.wang@mediatek.com>");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("mt8183_mt6358_ts3a227_max98357 soc card");
-