diff options
author | Jie Yang <yang.jie@intel.com> | 2015-02-05 09:56:48 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-02-05 13:05:28 -0500 |
commit | cd311dd123f5ae5c6da71bdfa9a379a694eb9917 (patch) | |
tree | b0b86dcdd990d64371879399d1f282672454eb28 /sound | |
parent | c41cda1dbe50816d839c32271007c7b832d4d14a (diff) |
ASoC: Intel: add a status for runtime suspend/resume
For runtime suspend/resume, it is some different with suspend/resume,
e.g. codec power supply won't be switch off, codec jack detection
still working(to wake up system from Jack event), won't call call
snd_soc_suspend/resume, etc.
So here, we add a platform PM status, HSW_PM_STATE_RTD3, to make
the status more clear, when in idle, it will enter this status, to
transfer from HSW_PM_STATE_RTD3 to HSW_PM_STATE_D3, we will do those
extra jobs, and vice versa for resuming.
Signed-off-by: Jie Yang <yang.jie@intel.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/soc/intel/sst-haswell-pcm.c | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c index ad7f4a51e138..78fa01be57f2 100644 --- a/sound/soc/intel/sst-haswell-pcm.c +++ b/sound/soc/intel/sst-haswell-pcm.c | |||
@@ -119,8 +119,9 @@ struct hsw_pcm_data { | |||
119 | }; | 119 | }; |
120 | 120 | ||
121 | enum hsw_pm_state { | 121 | enum hsw_pm_state { |
122 | HSW_PM_STATE_D3 = 0, | 122 | HSW_PM_STATE_D0 = 0, |
123 | HSW_PM_STATE_D0 = 1, | 123 | HSW_PM_STATE_RTD3 = 1, |
124 | HSW_PM_STATE_D3 = 2, | ||
124 | }; | 125 | }; |
125 | 126 | ||
126 | /* private data for the driver */ | 127 | /* private data for the driver */ |
@@ -1035,12 +1036,12 @@ static int hsw_pcm_runtime_suspend(struct device *dev) | |||
1035 | struct hsw_priv_data *pdata = dev_get_drvdata(dev); | 1036 | struct hsw_priv_data *pdata = dev_get_drvdata(dev); |
1036 | struct sst_hsw *hsw = pdata->hsw; | 1037 | struct sst_hsw *hsw = pdata->hsw; |
1037 | 1038 | ||
1038 | if (pdata->pm_state == HSW_PM_STATE_D3) | 1039 | if (pdata->pm_state >= HSW_PM_STATE_RTD3) |
1039 | return 0; | 1040 | return 0; |
1040 | 1041 | ||
1041 | sst_hsw_dsp_runtime_suspend(hsw); | 1042 | sst_hsw_dsp_runtime_suspend(hsw); |
1042 | sst_hsw_dsp_runtime_sleep(hsw); | 1043 | sst_hsw_dsp_runtime_sleep(hsw); |
1043 | pdata->pm_state = HSW_PM_STATE_D3; | 1044 | pdata->pm_state = HSW_PM_STATE_RTD3; |
1044 | 1045 | ||
1045 | return 0; | 1046 | return 0; |
1046 | } | 1047 | } |
@@ -1051,7 +1052,7 @@ static int hsw_pcm_runtime_resume(struct device *dev) | |||
1051 | struct sst_hsw *hsw = pdata->hsw; | 1052 | struct sst_hsw *hsw = pdata->hsw; |
1052 | int ret; | 1053 | int ret; |
1053 | 1054 | ||
1054 | if (pdata->pm_state == HSW_PM_STATE_D0) | 1055 | if (pdata->pm_state != HSW_PM_STATE_RTD3) |
1055 | return 0; | 1056 | return 0; |
1056 | 1057 | ||
1057 | ret = sst_hsw_dsp_load(hsw); | 1058 | ret = sst_hsw_dsp_load(hsw); |
@@ -1091,7 +1092,7 @@ static void hsw_pcm_complete(struct device *dev) | |||
1091 | struct hsw_pcm_data *pcm_data; | 1092 | struct hsw_pcm_data *pcm_data; |
1092 | int i, err; | 1093 | int i, err; |
1093 | 1094 | ||
1094 | if (pdata->pm_state == HSW_PM_STATE_D0) | 1095 | if (pdata->pm_state != HSW_PM_STATE_D3) |
1095 | return; | 1096 | return; |
1096 | 1097 | ||
1097 | err = sst_hsw_dsp_load(hsw); | 1098 | err = sst_hsw_dsp_load(hsw); |
@@ -1139,41 +1140,42 @@ static int hsw_pcm_prepare(struct device *dev) | |||
1139 | 1140 | ||
1140 | if (pdata->pm_state == HSW_PM_STATE_D3) | 1141 | if (pdata->pm_state == HSW_PM_STATE_D3) |
1141 | return 0; | 1142 | return 0; |
1142 | /* suspend all active streams */ | 1143 | else if (pdata->pm_state == HSW_PM_STATE_D0) { |
1143 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { | 1144 | /* suspend all active streams */ |
1144 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; | 1145 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
1146 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; | ||
1147 | |||
1148 | if (!pcm_data->substream) | ||
1149 | continue; | ||
1150 | dev_dbg(dev, "suspending pcm %d\n", i); | ||
1151 | snd_pcm_suspend_all(pcm_data->hsw_pcm); | ||
1152 | |||
1153 | /* We need to wait until the DSP FW stops the streams */ | ||
1154 | msleep(2); | ||
1155 | } | ||
1145 | 1156 | ||
1146 | if (!pcm_data->substream) | 1157 | /* preserve persistent memory */ |
1147 | continue; | 1158 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { |
1148 | dev_dbg(dev, "suspending pcm %d\n", i); | 1159 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; |
1149 | snd_pcm_suspend_all(pcm_data->hsw_pcm); | 1160 | |
1161 | if (!pcm_data->substream) | ||
1162 | continue; | ||
1150 | 1163 | ||
1151 | /* We need to wait until the DSP FW stops the streams */ | 1164 | dev_dbg(dev, "saving context pcm %d\n", i); |
1152 | msleep(2); | 1165 | err = sst_module_runtime_save(pcm_data->runtime, |
1166 | &pcm_data->context); | ||
1167 | if (err < 0) | ||
1168 | dev_err(dev, "failed to save context for PCM %d\n", i); | ||
1169 | } | ||
1170 | /* enter D3 state and stall */ | ||
1171 | sst_hsw_dsp_runtime_suspend(hsw); | ||
1172 | /* put the DSP to sleep */ | ||
1173 | sst_hsw_dsp_runtime_sleep(hsw); | ||
1153 | } | 1174 | } |
1154 | 1175 | ||
1155 | snd_soc_suspend(pdata->soc_card->dev); | 1176 | snd_soc_suspend(pdata->soc_card->dev); |
1156 | snd_soc_poweroff(pdata->soc_card->dev); | 1177 | snd_soc_poweroff(pdata->soc_card->dev); |
1157 | 1178 | ||
1158 | /* enter D3 state and stall */ | ||
1159 | sst_hsw_dsp_runtime_suspend(hsw); | ||
1160 | |||
1161 | /* preserve persistent memory */ | ||
1162 | for (i = 0; i < ARRAY_SIZE(mod_map); i++) { | ||
1163 | pcm_data = &pdata->pcm[mod_map[i].dai_id][mod_map[i].stream]; | ||
1164 | |||
1165 | if (!pcm_data->substream) | ||
1166 | continue; | ||
1167 | |||
1168 | dev_dbg(dev, "saving context pcm %d\n", i); | ||
1169 | err = sst_module_runtime_save(pcm_data->runtime, | ||
1170 | &pcm_data->context); | ||
1171 | if (err < 0) | ||
1172 | dev_err(dev, "failed to save context for PCM %d\n", i); | ||
1173 | } | ||
1174 | |||
1175 | /* put the DSP to sleep */ | ||
1176 | sst_hsw_dsp_runtime_sleep(hsw); | ||
1177 | pdata->pm_state = HSW_PM_STATE_D3; | 1179 | pdata->pm_state = HSW_PM_STATE_D3; |
1178 | 1180 | ||
1179 | return 0; | 1181 | return 0; |