spdif: fix standby power consumption is too high [1/1]
authorjiejing.wang <jiejing.wang@amlogic.com>
Tue, 23 Jul 2019 08:16:51 +0000 (16:16 +0800)
committerjiejing.wang <jiejing.wang@amlogic.com>
Fri, 23 Aug 2019 04:20:42 +0000 (12:20 +0800)
PD#SWPL-12461

Problem:
standby power consumption is too high

Solution:
1.when standby set spdif pin low
2.when standby set GPIOAO_2 low

Verify:
verify by U212

Change-Id: I29699688288b0e09529b7a35a4559ff1fad9891e
Signed-off-by: jiejing.wang <jiejing.wang@amlogic.com>
sound/soc/amlogic/auge/card.c
sound/soc/amlogic/auge/spdif.c

index f0b32d3..d7404bf 100644 (file)
@@ -84,7 +84,7 @@ struct aml_card_data {
        int micphone_gpio_det;
        int mic_detect_flag;
        bool mic_det_enable;
-
+       bool av_mute_enable;
        struct aml_chipset_info *chipinfo;
 };
 
@@ -747,17 +747,25 @@ static int aml_card_parse_gpios(struct device_node *node,
                                        ARRAY_SIZE(card_controls));
                }
        }
-
-       priv->avout_mute_desc = gpiod_get(dev,
-                               "avout_mute", GPIOF_OUT_INIT_LOW);
+       if (IS_ERR_OR_NULL(priv->avout_mute_desc)) {
+               priv->avout_mute_desc = gpiod_get(dev,
+                                       "avout_mute", GPIOF_OUT_INIT_LOW);
+       }
        if (!IS_ERR(priv->avout_mute_desc)) {
-               msleep(500);
-               gpiod_direction_output(priv->avout_mute_desc,
-                       GPIOF_OUT_INIT_HIGH);
-               pr_info("av out status: %s\n",
-                       gpiod_get_value(priv->avout_mute_desc) ?
-                       "high" : "low");
-
+               if (!priv->av_mute_enable) {
+                       msleep(500);
+                       gpiod_direction_output(priv->avout_mute_desc,
+                               GPIOF_OUT_INIT_HIGH);
+                       pr_info("av out status: %s\n",
+                               gpiod_get_value(priv->avout_mute_desc) ?
+                               "high" : "low");
+               } else {
+                       gpiod_direction_output(priv->avout_mute_desc,
+                               GPIOF_OUT_INIT_LOW);
+                       pr_info("av out status: %s\n",
+                               gpiod_get_value(priv->avout_mute_desc) ?
+                               "high" : "low");
+               }
        }
 
        return 0;
@@ -773,7 +781,6 @@ static void aml_init_work(struct work_struct *init_work)
                        struct aml_card_data, init_work);
        dev = aml_priv_to_dev(priv);
        np = dev->of_node;
-
        aml_card_parse_gpios(np, priv);
 }
 
@@ -871,6 +878,29 @@ static const struct of_device_id auge_of_match[] = {
 };
 MODULE_DEVICE_TABLE(of, auge_of_match);
 
+static int card_suspend_pre(struct snd_soc_card *card)
+{
+       struct aml_card_data *priv = snd_soc_card_get_drvdata(card);
+
+       priv->av_mute_enable = 1;
+       INIT_WORK(&priv->init_work, aml_init_work);
+       schedule_work(&priv->init_work);
+       pr_info("it is card_pre_suspend\n");
+       return 0;
+}
+
+static int card_resume_post(struct snd_soc_card *card)
+{
+       struct aml_card_data *priv = snd_soc_card_get_drvdata(card);
+
+       priv->av_mute_enable = 0;
+       INIT_WORK(&priv->init_work, aml_init_work);
+       schedule_work(&priv->init_work);
+       pr_info("it is card_post_resume\n");
+       return 0;
+
+}
+
 static int aml_card_probe(struct platform_device *pdev)
 {
        struct aml_card_data *priv;
@@ -911,6 +941,8 @@ static int aml_card_probe(struct platform_device *pdev)
        priv->snd_card.dev              = dev;
        priv->snd_card.dai_link         = priv->dai_link;
        priv->snd_card.num_links        = num;
+       priv->snd_card.suspend_pre      = card_suspend_pre;
+       priv->snd_card.resume_post      = card_resume_post;
 
        if (np && of_device_is_available(np)) {
 
@@ -981,7 +1013,7 @@ static int aml_card_probe(struct platform_device *pdev)
                audio_jack_detect(priv);
                audio_extcon_register(priv, dev);
        }
-
+       priv->av_mute_enable = 0;
        INIT_WORK(&priv->init_work, aml_init_work);
        schedule_work(&priv->init_work);
 
@@ -1004,6 +1036,16 @@ static int aml_card_remove(struct platform_device *pdev)
        return aml_card_clean_reference(card);
 }
 
+static void aml_card_platform_shutdown(struct platform_device *pdev)
+{
+       struct snd_soc_card *card = platform_get_drvdata(pdev);
+       struct aml_card_data *priv = snd_soc_card_get_drvdata(card);
+
+       priv->av_mute_enable = 1;
+       INIT_WORK(&priv->init_work, aml_init_work);
+       schedule_work(&priv->init_work);
+}
+
 static struct platform_driver aml_card = {
        .driver = {
                .name = "asoc-aml-card",
@@ -1012,6 +1054,7 @@ static struct platform_driver aml_card = {
        },
        .probe = aml_card_probe,
        .remove = aml_card_remove,
+       .shutdown = aml_card_platform_shutdown,
 };
 
 module_platform_driver(aml_card);
index cbdb250..45f40d8 100644 (file)
@@ -277,6 +277,65 @@ static int aml_audio_set_spdif_mute(struct snd_kcontrol *kcontrol,
        return 0;
 }
 
+static int aml_spdif_platform_suspend(
+       struct platform_device *pdev, pm_message_t state)
+{
+       struct aml_spdif *p_spdif = dev_get_drvdata(&pdev->dev);
+       struct pinctrl_state *pstate = NULL;
+       int stream = SNDRV_PCM_STREAM_PLAYBACK;
+
+       if (!IS_ERR_OR_NULL(p_spdif->pin_ctl)) {
+               pstate = pinctrl_lookup_state
+               (p_spdif->pin_ctl, "spdif_pins_mute");
+               if (!IS_ERR_OR_NULL(pstate))
+                       pinctrl_select_state(p_spdif->pin_ctl, pstate);
+       }
+       clk_disable_unprepare(p_spdif->sysclk);
+       aml_spdif_enable(p_spdif->actrl,
+                           stream, p_spdif->id, false);
+       pr_info("%s is mute\n", __func__);
+       return 0;
+}
+
+static int aml_spdif_platform_resume(struct platform_device *pdev)
+{
+       struct aml_spdif *p_spdif = dev_get_drvdata(&pdev->dev);
+       struct pinctrl_state *state = NULL;
+       int stream = SNDRV_PCM_STREAM_PLAYBACK;
+
+       if (!IS_ERR_OR_NULL(p_spdif->pin_ctl)) {
+               state = pinctrl_lookup_state
+               (p_spdif->pin_ctl, "spdif_pins");
+               if (!IS_ERR_OR_NULL(state))
+                       pinctrl_select_state(p_spdif->pin_ctl, state);
+       }
+       clk_prepare_enable(p_spdif->sysclk);
+       aml_spdif_enable(p_spdif->actrl,
+                       stream, p_spdif->id, true);
+       pr_info("%s is unmute\n", __func__);
+
+       return 0;
+}
+
+static void aml_spdif_platform_shutdown(struct platform_device *pdev)
+{
+       struct aml_spdif *p_spdif = dev_get_drvdata(&pdev->dev);
+       struct pinctrl_state *pstate = NULL;
+       int stream = SNDRV_PCM_STREAM_PLAYBACK;
+
+       if (!IS_ERR_OR_NULL(p_spdif->pin_ctl)) {
+               pstate = pinctrl_lookup_state
+               (p_spdif->pin_ctl, "spdif_pins_mute");
+               if (!IS_ERR_OR_NULL(pstate))
+                       pinctrl_select_state(p_spdif->pin_ctl, pstate);
+       }
+       clk_disable_unprepare(p_spdif->sysclk);
+       aml_spdif_enable(p_spdif->actrl,
+                           stream, p_spdif->id, false);
+       pr_info("%s is mute\n", __func__);
+
+}
+
 static int aml_audio_get_spdif_mute(struct snd_kcontrol *kcontrol,
                                        struct snd_ctl_elem_value *ucontrol)
 {
@@ -1651,6 +1710,9 @@ struct platform_driver aml_spdif_driver = {
                .of_match_table = aml_spdif_device_id,
        },
        .probe = aml_spdif_platform_probe,
+       .suspend = aml_spdif_platform_suspend,
+       .resume  = aml_spdif_platform_resume,
+       .shutdown = aml_spdif_platform_shutdown,
 };
 module_platform_driver(aml_spdif_driver);