ALSA: hda/tas2781: restore power state after system_resume
authorGergo Koteles <soyer@irl.hu>
Fri, 8 Mar 2024 17:41:44 +0000 (18:41 +0100)
committerTakashi Iwai <tiwai@suse.de>
Mon, 11 Mar 2024 08:14:39 +0000 (09:14 +0100)
After system_resume the amplifers will remain off, even if they were on
before system_suspend.

Use playback_started bool to save the playback state, and restore power
state based on it.

Fixes: 5be27f1e3ec9 ("ALSA: hda/tas2781: Add tas2781 HDA driver")
Signed-off-by: Gergo Koteles <soyer@irl.hu>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Message-ID: <1742b61901781826f6e6212ffe1d21af542d134a.1709918447.git.soyer@irl.hu>

sound/pci/hda/tas2781_hda_i2c.c

index a99f490c6a2340b195bcff0e7f970f93667c3dd7..7aef93126ed0c9e88667f57fc6b6896e5c4ea039 100644 (file)
@@ -160,11 +160,13 @@ static void tas2781_hda_playback_hook(struct device *dev, int action)
                pm_runtime_get_sync(dev);
                mutex_lock(&tas_hda->priv->codec_lock);
                tasdevice_tuning_switch(tas_hda->priv, 0);
+               tas_hda->priv->playback_started = true;
                mutex_unlock(&tas_hda->priv->codec_lock);
                break;
        case HDA_GEN_PCM_ACT_CLOSE:
                mutex_lock(&tas_hda->priv->codec_lock);
                tasdevice_tuning_switch(tas_hda->priv, 1);
+               tas_hda->priv->playback_started = false;
                mutex_unlock(&tas_hda->priv->codec_lock);
 
                pm_runtime_mark_last_busy(dev);
@@ -666,6 +668,7 @@ static void tasdev_fw_ready(const struct firmware *fmw, void *context)
        tasdevice_save_calibration(tas_priv);
 
        tasdevice_tuning_switch(tas_hda->priv, 0);
+       tas_hda->priv->playback_started = true;
 
 out:
        mutex_unlock(&tas_hda->priv->codec_lock);
@@ -837,6 +840,9 @@ static int tas2781_runtime_suspend(struct device *dev)
 
        mutex_lock(&tas_hda->priv->codec_lock);
 
+       /* The driver powers up the amplifiers at module load time.
+        * Stop the playback if it's unused.
+        */
        if (tas_hda->priv->playback_started) {
                tasdevice_tuning_switch(tas_hda->priv, 1);
                tas_hda->priv->playback_started = false;
@@ -876,7 +882,8 @@ static int tas2781_system_suspend(struct device *dev)
        mutex_lock(&tas_hda->priv->codec_lock);
 
        /* Shutdown chip before system suspend */
-       tasdevice_tuning_switch(tas_hda->priv, 1);
+       if (tas_hda->priv->playback_started)
+               tasdevice_tuning_switch(tas_hda->priv, 1);
 
        mutex_unlock(&tas_hda->priv->codec_lock);
 
@@ -908,6 +915,10 @@ static int tas2781_system_resume(struct device *dev)
         * calibrated data inside algo.
         */
        tasdevice_apply_calibration(tas_hda->priv);
+
+       if (tas_hda->priv->playback_started)
+               tasdevice_tuning_switch(tas_hda->priv, 0);
+
        mutex_unlock(&tas_hda->priv->codec_lock);
 
        return 0;