aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/intel/sst-haswell-pcm.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/intel/sst-haswell-pcm.c')
-rw-r--r--sound/soc/intel/sst-haswell-pcm.c419
1 files changed, 346 insertions, 73 deletions
diff --git a/sound/soc/intel/sst-haswell-pcm.c b/sound/soc/intel/sst-haswell-pcm.c
index 4df867cbb92a..0180b386c421 100644
--- a/sound/soc/intel/sst-haswell-pcm.c
+++ b/sound/soc/intel/sst-haswell-pcm.c
@@ -18,6 +18,7 @@
18#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/pm_runtime.h>
21#include <asm/page.h> 22#include <asm/page.h>
22#include <asm/pgtable.h> 23#include <asm/pgtable.h>
23#include <sound/core.h> 24#include <sound/core.h>
@@ -73,6 +74,13 @@ static const u32 volume_map[] = {
73#define HSW_PCM_PERIODS_MAX 64 74#define HSW_PCM_PERIODS_MAX 64
74#define HSW_PCM_PERIODS_MIN 2 75#define HSW_PCM_PERIODS_MIN 2
75 76
77#define HSW_PCM_DAI_ID_SYSTEM 0
78#define HSW_PCM_DAI_ID_OFFLOAD0 1
79#define HSW_PCM_DAI_ID_OFFLOAD1 2
80#define HSW_PCM_DAI_ID_LOOPBACK 3
81#define HSW_PCM_DAI_ID_CAPTURE 4
82
83
76static const struct snd_pcm_hardware hsw_pcm_hardware = { 84static const struct snd_pcm_hardware hsw_pcm_hardware = {
77 .info = SNDRV_PCM_INFO_MMAP | 85 .info = SNDRV_PCM_INFO_MMAP |
78 SNDRV_PCM_INFO_MMAP_VALID | 86 SNDRV_PCM_INFO_MMAP_VALID |
@@ -89,22 +97,39 @@ static const struct snd_pcm_hardware hsw_pcm_hardware = {
89 .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE, 97 .buffer_bytes_max = HSW_PCM_PERIODS_MAX * PAGE_SIZE,
90}; 98};
91 99
100struct hsw_pcm_module_map {
101 int dai_id;
102 enum sst_hsw_module_id mod_id;
103};
104
92/* private data for each PCM DSP stream */ 105/* private data for each PCM DSP stream */
93struct hsw_pcm_data { 106struct hsw_pcm_data {
94 int dai_id; 107 int dai_id;
95 struct sst_hsw_stream *stream; 108 struct sst_hsw_stream *stream;
109 struct sst_module_runtime *runtime;
110 struct sst_module_runtime_context context;
111 struct snd_pcm *hsw_pcm;
96 u32 volume[2]; 112 u32 volume[2];
97 struct snd_pcm_substream *substream; 113 struct snd_pcm_substream *substream;
98 struct snd_compr_stream *cstream; 114 struct snd_compr_stream *cstream;
99 unsigned int wpos; 115 unsigned int wpos;
100 struct mutex mutex; 116 struct mutex mutex;
101 bool allocated; 117 bool allocated;
118 int persistent_offset;
119};
120
121enum hsw_pm_state {
122 HSW_PM_STATE_D3 = 0,
123 HSW_PM_STATE_D0 = 1,
102}; 124};
103 125
104/* private data for the driver */ 126/* private data for the driver */
105struct hsw_priv_data { 127struct hsw_priv_data {
106 /* runtime DSP */ 128 /* runtime DSP */
107 struct sst_hsw *hsw; 129 struct sst_hsw *hsw;
130 struct device *dev;
131 enum hsw_pm_state pm_state;
132 struct snd_soc_card *soc_card;
108 133
109 /* page tables */ 134 /* page tables */
110 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2]; 135 struct snd_dma_buffer dmab[HSW_PCM_COUNT][2];
@@ -138,21 +163,25 @@ static inline unsigned int hsw_ipc_to_mixer(u32 value)
138static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol, 163static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
139 struct snd_ctl_elem_value *ucontrol) 164 struct snd_ctl_elem_value *ucontrol)
140{ 165{
141 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 166 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
142 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
143 struct soc_mixer_control *mc = 167 struct soc_mixer_control *mc =
144 (struct soc_mixer_control *)kcontrol->private_value; 168 (struct soc_mixer_control *)kcontrol->private_value;
169 struct hsw_priv_data *pdata =
170 snd_soc_platform_get_drvdata(platform);
145 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 171 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
146 struct sst_hsw *hsw = pdata->hsw; 172 struct sst_hsw *hsw = pdata->hsw;
147 u32 volume; 173 u32 volume;
148 174
149 mutex_lock(&pcm_data->mutex); 175 mutex_lock(&pcm_data->mutex);
176 pm_runtime_get_sync(pdata->dev);
150 177
151 if (!pcm_data->stream) { 178 if (!pcm_data->stream) {
152 pcm_data->volume[0] = 179 pcm_data->volume[0] =
153 hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 180 hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
154 pcm_data->volume[1] = 181 pcm_data->volume[1] =
155 hsw_mixer_to_ipc(ucontrol->value.integer.value[1]); 182 hsw_mixer_to_ipc(ucontrol->value.integer.value[1]);
183 pm_runtime_mark_last_busy(pdata->dev);
184 pm_runtime_put_autosuspend(pdata->dev);
156 mutex_unlock(&pcm_data->mutex); 185 mutex_unlock(&pcm_data->mutex);
157 return 0; 186 return 0;
158 } 187 }
@@ -160,7 +189,8 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
160 if (ucontrol->value.integer.value[0] == 189 if (ucontrol->value.integer.value[0] ==
161 ucontrol->value.integer.value[1]) { 190 ucontrol->value.integer.value[1]) {
162 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 191 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
163 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 2, volume); 192 /* apply volume value to all channels */
193 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, SST_HSW_CHANNELS_ALL, volume);
164 } else { 194 } else {
165 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 195 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
166 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume); 196 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 0, volume);
@@ -168,6 +198,8 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
168 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume); 198 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0, 1, volume);
169 } 199 }
170 200
201 pm_runtime_mark_last_busy(pdata->dev);
202 pm_runtime_put_autosuspend(pdata->dev);
171 mutex_unlock(&pcm_data->mutex); 203 mutex_unlock(&pcm_data->mutex);
172 return 0; 204 return 0;
173} 205}
@@ -175,21 +207,25 @@ static int hsw_stream_volume_put(struct snd_kcontrol *kcontrol,
175static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol, 207static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
176 struct snd_ctl_elem_value *ucontrol) 208 struct snd_ctl_elem_value *ucontrol)
177{ 209{
178 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 210 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
179 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt);
180 struct soc_mixer_control *mc = 211 struct soc_mixer_control *mc =
181 (struct soc_mixer_control *)kcontrol->private_value; 212 (struct soc_mixer_control *)kcontrol->private_value;
213 struct hsw_priv_data *pdata =
214 snd_soc_platform_get_drvdata(platform);
182 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg]; 215 struct hsw_pcm_data *pcm_data = &pdata->pcm[mc->reg];
183 struct sst_hsw *hsw = pdata->hsw; 216 struct sst_hsw *hsw = pdata->hsw;
184 u32 volume; 217 u32 volume;
185 218
186 mutex_lock(&pcm_data->mutex); 219 mutex_lock(&pcm_data->mutex);
220 pm_runtime_get_sync(pdata->dev);
187 221
188 if (!pcm_data->stream) { 222 if (!pcm_data->stream) {
189 ucontrol->value.integer.value[0] = 223 ucontrol->value.integer.value[0] =
190 hsw_ipc_to_mixer(pcm_data->volume[0]); 224 hsw_ipc_to_mixer(pcm_data->volume[0]);
191 ucontrol->value.integer.value[1] = 225 ucontrol->value.integer.value[1] =
192 hsw_ipc_to_mixer(pcm_data->volume[1]); 226 hsw_ipc_to_mixer(pcm_data->volume[1]);
227 pm_runtime_mark_last_busy(pdata->dev);
228 pm_runtime_put_autosuspend(pdata->dev);
193 mutex_unlock(&pcm_data->mutex); 229 mutex_unlock(&pcm_data->mutex);
194 return 0; 230 return 0;
195 } 231 }
@@ -198,6 +234,9 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
198 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume); 234 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
199 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume); 235 sst_hsw_stream_get_volume(hsw, pcm_data->stream, 0, 1, &volume);
200 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume); 236 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
237
238 pm_runtime_mark_last_busy(pdata->dev);
239 pm_runtime_put_autosuspend(pdata->dev);
201 mutex_unlock(&pcm_data->mutex); 240 mutex_unlock(&pcm_data->mutex);
202 241
203 return 0; 242 return 0;
@@ -206,16 +245,18 @@ static int hsw_stream_volume_get(struct snd_kcontrol *kcontrol,
206static int hsw_volume_put(struct snd_kcontrol *kcontrol, 245static int hsw_volume_put(struct snd_kcontrol *kcontrol,
207 struct snd_ctl_elem_value *ucontrol) 246 struct snd_ctl_elem_value *ucontrol)
208{ 247{
209 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 248 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
210 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt); 249 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
211 struct sst_hsw *hsw = pdata->hsw; 250 struct sst_hsw *hsw = pdata->hsw;
212 u32 volume; 251 u32 volume;
213 252
253 pm_runtime_get_sync(pdata->dev);
254
214 if (ucontrol->value.integer.value[0] == 255 if (ucontrol->value.integer.value[0] ==
215 ucontrol->value.integer.value[1]) { 256 ucontrol->value.integer.value[1]) {
216 257
217 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 258 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
218 sst_hsw_mixer_set_volume(hsw, 0, 2, volume); 259 sst_hsw_mixer_set_volume(hsw, 0, SST_HSW_CHANNELS_ALL, volume);
219 260
220 } else { 261 } else {
221 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]); 262 volume = hsw_mixer_to_ipc(ucontrol->value.integer.value[0]);
@@ -225,23 +266,28 @@ static int hsw_volume_put(struct snd_kcontrol *kcontrol,
225 sst_hsw_mixer_set_volume(hsw, 0, 1, volume); 266 sst_hsw_mixer_set_volume(hsw, 0, 1, volume);
226 } 267 }
227 268
269 pm_runtime_mark_last_busy(pdata->dev);
270 pm_runtime_put_autosuspend(pdata->dev);
228 return 0; 271 return 0;
229} 272}
230 273
231static int hsw_volume_get(struct snd_kcontrol *kcontrol, 274static int hsw_volume_get(struct snd_kcontrol *kcontrol,
232 struct snd_ctl_elem_value *ucontrol) 275 struct snd_ctl_elem_value *ucontrol)
233{ 276{
234 struct snd_soc_component *cmpnt = snd_soc_kcontrol_component(kcontrol); 277 struct snd_soc_platform *platform = snd_soc_kcontrol_platform(kcontrol);
235 struct hsw_priv_data *pdata = snd_soc_component_get_drvdata(cmpnt); 278 struct hsw_priv_data *pdata = snd_soc_platform_get_drvdata(platform);
236 struct sst_hsw *hsw = pdata->hsw; 279 struct sst_hsw *hsw = pdata->hsw;
237 unsigned int volume = 0; 280 unsigned int volume = 0;
238 281
282 pm_runtime_get_sync(pdata->dev);
239 sst_hsw_mixer_get_volume(hsw, 0, 0, &volume); 283 sst_hsw_mixer_get_volume(hsw, 0, 0, &volume);
240 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume); 284 ucontrol->value.integer.value[0] = hsw_ipc_to_mixer(volume);
241 285
242 sst_hsw_mixer_get_volume(hsw, 0, 1, &volume); 286 sst_hsw_mixer_get_volume(hsw, 0, 1, &volume);
243 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume); 287 ucontrol->value.integer.value[1] = hsw_ipc_to_mixer(volume);
244 288
289 pm_runtime_mark_last_busy(pdata->dev);
290 pm_runtime_put_autosuspend(pdata->dev);
245 return 0; 291 return 0;
246} 292}
247 293
@@ -252,23 +298,19 @@ static const DECLARE_TLV_DB_SCALE(hsw_vol_tlv, -9000, 300, 1);
252static const struct snd_kcontrol_new hsw_volume_controls[] = { 298static const struct snd_kcontrol_new hsw_volume_controls[] = {
253 /* Global DSP volume */ 299 /* Global DSP volume */
254 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8, 300 SOC_DOUBLE_EXT_TLV("Master Playback Volume", 0, 0, 8,
255 ARRAY_SIZE(volume_map) -1, 0, 301 ARRAY_SIZE(volume_map) - 1, 0,
256 hsw_volume_get, hsw_volume_put, hsw_vol_tlv), 302 hsw_volume_get, hsw_volume_put, hsw_vol_tlv),
257 /* Offload 0 volume */ 303 /* Offload 0 volume */
258 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8, 304 SOC_DOUBLE_EXT_TLV("Media0 Playback Volume", 1, 0, 8,
259 ARRAY_SIZE(volume_map), 0, 305 ARRAY_SIZE(volume_map) - 1, 0,
260 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 306 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
261 /* Offload 1 volume */ 307 /* Offload 1 volume */
262 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8, 308 SOC_DOUBLE_EXT_TLV("Media1 Playback Volume", 2, 0, 8,
263 ARRAY_SIZE(volume_map), 0, 309 ARRAY_SIZE(volume_map) - 1, 0,
264 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
265 /* Loopback volume */
266 SOC_DOUBLE_EXT_TLV("Loopback Capture Volume", 3, 0, 8,
267 ARRAY_SIZE(volume_map), 0,
268 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 310 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
269 /* Mic Capture volume */ 311 /* Mic Capture volume */
270 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 4, 0, 8, 312 SOC_DOUBLE_EXT_TLV("Mic Capture Volume", 0, 0, 8,
271 ARRAY_SIZE(volume_map), 0, 313 ARRAY_SIZE(volume_map) - 1, 0,
272 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv), 314 hsw_stream_volume_get, hsw_stream_volume_put, hsw_vol_tlv),
273}; 315};
274 316
@@ -354,8 +396,14 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
354 /* DSP stream type depends on DAI ID */ 396 /* DSP stream type depends on DAI ID */
355 switch (rtd->cpu_dai->id) { 397 switch (rtd->cpu_dai->id) {
356 case 0: 398 case 0:
357 stream_type = SST_HSW_STREAM_TYPE_SYSTEM; 399 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
358 module_id = SST_HSW_MODULE_PCM_SYSTEM; 400 stream_type = SST_HSW_STREAM_TYPE_SYSTEM;
401 module_id = SST_HSW_MODULE_PCM_SYSTEM;
402 }
403 else {
404 stream_type = SST_HSW_STREAM_TYPE_CAPTURE;
405 module_id = SST_HSW_MODULE_PCM_CAPTURE;
406 }
359 break; 407 break;
360 case 1: 408 case 1:
361 case 2: 409 case 2:
@@ -368,10 +416,6 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
368 path_id = SST_HSW_STREAM_PATH_SSP0_OUT; 416 path_id = SST_HSW_STREAM_PATH_SSP0_OUT;
369 module_id = SST_HSW_MODULE_PCM_REFERENCE; 417 module_id = SST_HSW_MODULE_PCM_REFERENCE;
370 break; 418 break;
371 case 4:
372 stream_type = SST_HSW_STREAM_TYPE_CAPTURE;
373 module_id = SST_HSW_MODULE_PCM_CAPTURE;
374 break;
375 default: 419 default:
376 dev_err(rtd->dev, "error: invalid DAI ID %d\n", 420 dev_err(rtd->dev, "error: invalid DAI ID %d\n",
377 rtd->cpu_dai->id); 421 rtd->cpu_dai->id);
@@ -421,13 +465,7 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
421 return ret; 465 return ret;
422 } 466 }
423 467
424 /* we only support stereo atm */
425 channels = params_channels(params); 468 channels = params_channels(params);
426 if (channels != 2) {
427 dev_err(rtd->dev, "error: invalid channels %d\n", channels);
428 return -EINVAL;
429 }
430
431 map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO); 469 map = create_channel_map(SST_HSW_CHANNEL_CONFIG_STEREO);
432 sst_hsw_stream_set_map_config(hsw, pcm_data->stream, 470 sst_hsw_stream_set_map_config(hsw, pcm_data->stream,
433 map, SST_HSW_CHANNEL_CONFIG_STEREO); 471 map, SST_HSW_CHANNEL_CONFIG_STEREO);
@@ -478,35 +516,23 @@ static int hsw_pcm_hw_params(struct snd_pcm_substream *substream,
478 return -EINVAL; 516 return -EINVAL;
479 } 517 }
480 518
481 /* we use hardcoded memory offsets atm, will be updated for new FW */ 519 sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
482 if (stream_type == SST_HSW_STREAM_TYPE_CAPTURE) { 520 pcm_data->runtime);
483 sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
484 SST_HSW_MODULE_PCM_CAPTURE, module_data->entry);
485 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
486 0x449400, 0x4000);
487 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
488 0x400000, 0);
489 } else { /* stream_type == SST_HSW_STREAM_TYPE_SYSTEM */
490 sst_hsw_stream_set_module_info(hsw, pcm_data->stream,
491 SST_HSW_MODULE_PCM_SYSTEM, module_data->entry);
492
493 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
494 module_data->offset, module_data->size);
495 sst_hsw_stream_set_pmemory_info(hsw, pcm_data->stream,
496 0x44d400, 0x3800);
497
498 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
499 module_data->offset, module_data->size);
500 sst_hsw_stream_set_smemory_info(hsw, pcm_data->stream,
501 0x400000, 0);
502 }
503 521
504 ret = sst_hsw_stream_commit(hsw, pcm_data->stream); 522 ret = sst_hsw_stream_commit(hsw, pcm_data->stream);
505 if (ret < 0) { 523 if (ret < 0) {
506 dev_err(rtd->dev, "error: failed to commit stream %d\n", ret); 524 dev_err(rtd->dev, "error: failed to commit stream %d\n", ret);
507 return ret; 525 return ret;
508 } 526 }
509 pcm_data->allocated = true; 527
528 if (!pcm_data->allocated) {
529 /* Set previous saved volume */
530 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
531 0, pcm_data->volume[0]);
532 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
533 1, pcm_data->volume[1]);
534 pcm_data->allocated = true;
535 }
510 536
511 ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1); 537 ret = sst_hsw_stream_pause(hsw, pcm_data->stream, 1);
512 if (ret < 0) 538 if (ret < 0)
@@ -558,7 +584,7 @@ static u32 hsw_notify_pointer(struct sst_hsw_stream *stream, void *data)
558 pos = frames_to_bytes(runtime, 584 pos = frames_to_bytes(runtime,
559 (runtime->control->appl_ptr % runtime->buffer_size)); 585 (runtime->control->appl_ptr % runtime->buffer_size));
560 586
561 dev_dbg(rtd->dev, "PCM: App pointer %d bytes\n", pos); 587 dev_vdbg(rtd->dev, "PCM: App pointer %d bytes\n", pos);
562 588
563 /* let alsa know we have play a period */ 589 /* let alsa know we have play a period */
564 snd_pcm_period_elapsed(substream); 590 snd_pcm_period_elapsed(substream);
@@ -580,7 +606,7 @@ static snd_pcm_uframes_t hsw_pcm_pointer(struct snd_pcm_substream *substream)
580 offset = bytes_to_frames(runtime, position); 606 offset = bytes_to_frames(runtime, position);
581 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream); 607 ppos = sst_hsw_get_dsp_presentation_position(hsw, pcm_data->stream);
582 608
583 dev_dbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n", 609 dev_vdbg(rtd->dev, "PCM: DMA pointer %du bytes, pos %llu\n",
584 position, ppos); 610 position, ppos);
585 return offset; 611 return offset;
586} 612}
@@ -596,6 +622,7 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
596 pcm_data = &pdata->pcm[rtd->cpu_dai->id]; 622 pcm_data = &pdata->pcm[rtd->cpu_dai->id];
597 623
598 mutex_lock(&pcm_data->mutex); 624 mutex_lock(&pcm_data->mutex);
625 pm_runtime_get_sync(pdata->dev);
599 626
600 snd_soc_pcm_set_drvdata(rtd, pcm_data); 627 snd_soc_pcm_set_drvdata(rtd, pcm_data);
601 pcm_data->substream = substream; 628 pcm_data->substream = substream;
@@ -606,16 +633,12 @@ static int hsw_pcm_open(struct snd_pcm_substream *substream)
606 hsw_notify_pointer, pcm_data); 633 hsw_notify_pointer, pcm_data);
607 if (pcm_data->stream == NULL) { 634 if (pcm_data->stream == NULL) {
608 dev_err(rtd->dev, "error: failed to create stream\n"); 635 dev_err(rtd->dev, "error: failed to create stream\n");
636 pm_runtime_mark_last_busy(pdata->dev);
637 pm_runtime_put_autosuspend(pdata->dev);
609 mutex_unlock(&pcm_data->mutex); 638 mutex_unlock(&pcm_data->mutex);
610 return -EINVAL; 639 return -EINVAL;
611 } 640 }
612 641
613 /* Set previous saved volume */
614 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
615 0, pcm_data->volume[0]);
616 sst_hsw_stream_set_volume(hsw, pcm_data->stream, 0,
617 1, pcm_data->volume[1]);
618
619 mutex_unlock(&pcm_data->mutex); 642 mutex_unlock(&pcm_data->mutex);
620 return 0; 643 return 0;
621} 644}
@@ -645,6 +668,8 @@ static int hsw_pcm_close(struct snd_pcm_substream *substream)
645 pcm_data->stream = NULL; 668 pcm_data->stream = NULL;
646 669
647out: 670out:
671 pm_runtime_mark_last_busy(pdata->dev);
672 pm_runtime_put_autosuspend(pdata->dev);
648 mutex_unlock(&pcm_data->mutex); 673 mutex_unlock(&pcm_data->mutex);
649 return ret; 674 return ret;
650} 675}
@@ -660,6 +685,56 @@ static struct snd_pcm_ops hsw_pcm_ops = {
660 .page = snd_pcm_sgbuf_ops_page, 685 .page = snd_pcm_sgbuf_ops_page,
661}; 686};
662 687
688/* static mappings between PCMs and modules - may be dynamic in future */
689static struct hsw_pcm_module_map mod_map[] = {
690 {HSW_PCM_DAI_ID_SYSTEM, SST_HSW_MODULE_PCM_SYSTEM},
691 {HSW_PCM_DAI_ID_OFFLOAD0, SST_HSW_MODULE_PCM},
692 {HSW_PCM_DAI_ID_OFFLOAD1, SST_HSW_MODULE_PCM},
693 {HSW_PCM_DAI_ID_LOOPBACK, SST_HSW_MODULE_PCM_REFERENCE},
694 {HSW_PCM_DAI_ID_CAPTURE, SST_HSW_MODULE_PCM_CAPTURE},
695};
696
697static int hsw_pcm_create_modules(struct hsw_priv_data *pdata)
698{
699 struct sst_hsw *hsw = pdata->hsw;
700 struct hsw_pcm_data *pcm_data;
701 int i;
702
703 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
704 pcm_data = &pdata->pcm[i];
705
706 /* create new runtime module, use same offset if recreated */
707 pcm_data->runtime = sst_hsw_runtime_module_create(hsw,
708 mod_map[i].mod_id, pcm_data->persistent_offset);
709 if (pcm_data->runtime == NULL)
710 goto err;
711 pcm_data->persistent_offset =
712 pcm_data->runtime->persistent_offset;
713 }
714
715 return 0;
716
717err:
718 for (--i; i >= 0; i--) {
719 pcm_data = &pdata->pcm[i];
720 sst_hsw_runtime_module_free(pcm_data->runtime);
721 }
722
723 return -ENODEV;
724}
725
726static void hsw_pcm_free_modules(struct hsw_priv_data *pdata)
727{
728 struct hsw_pcm_data *pcm_data;
729 int i;
730
731 for (i = 0; i < ARRAY_SIZE(mod_map); i++) {
732 pcm_data = &pdata->pcm[i];
733
734 sst_hsw_runtime_module_free(pcm_data->runtime);
735 }
736}
737
663static void hsw_pcm_free(struct snd_pcm *pcm) 738static void hsw_pcm_free(struct snd_pcm *pcm)
664{ 739{
665 snd_pcm_lib_preallocate_free_for_all(pcm); 740 snd_pcm_lib_preallocate_free_for_all(pcm);
@@ -670,6 +745,7 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
670 struct snd_pcm *pcm = rtd->pcm; 745 struct snd_pcm *pcm = rtd->pcm;
671 struct snd_soc_platform *platform = rtd->platform; 746 struct snd_soc_platform *platform = rtd->platform;
672 struct sst_pdata *pdata = dev_get_platdata(platform->dev); 747 struct sst_pdata *pdata = dev_get_platdata(platform->dev);
748 struct hsw_priv_data *priv_data = dev_get_drvdata(platform->dev);
673 struct device *dev = pdata->dma_dev; 749 struct device *dev = pdata->dma_dev;
674 int ret = 0; 750 int ret = 0;
675 751
@@ -686,6 +762,7 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
686 return ret; 762 return ret;
687 } 763 }
688 } 764 }
765 priv_data->pcm[rtd->cpu_dai->id].hsw_pcm = pcm;
689 766
690 return ret; 767 return ret;
691} 768}
@@ -696,6 +773,7 @@ static int hsw_pcm_new(struct snd_soc_pcm_runtime *rtd)
696static struct snd_soc_dai_driver hsw_dais[] = { 773static struct snd_soc_dai_driver hsw_dais[] = {
697 { 774 {
698 .name = "System Pin", 775 .name = "System Pin",
776 .id = HSW_PCM_DAI_ID_SYSTEM,
699 .playback = { 777 .playback = {
700 .stream_name = "System Playback", 778 .stream_name = "System Playback",
701 .channels_min = 2, 779 .channels_min = 2,
@@ -703,10 +781,18 @@ static struct snd_soc_dai_driver hsw_dais[] = {
703 .rates = SNDRV_PCM_RATE_48000, 781 .rates = SNDRV_PCM_RATE_48000,
704 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, 782 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
705 }, 783 },
784 .capture = {
785 .stream_name = "Analog Capture",
786 .channels_min = 2,
787 .channels_max = 4,
788 .rates = SNDRV_PCM_RATE_48000,
789 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
790 },
706 }, 791 },
707 { 792 {
708 /* PCM */ 793 /* PCM */
709 .name = "Offload0 Pin", 794 .name = "Offload0 Pin",
795 .id = HSW_PCM_DAI_ID_OFFLOAD0,
710 .playback = { 796 .playback = {
711 .stream_name = "Offload0 Playback", 797 .stream_name = "Offload0 Playback",
712 .channels_min = 2, 798 .channels_min = 2,
@@ -718,6 +804,7 @@ static struct snd_soc_dai_driver hsw_dais[] = {
718 { 804 {
719 /* PCM */ 805 /* PCM */
720 .name = "Offload1 Pin", 806 .name = "Offload1 Pin",
807 .id = HSW_PCM_DAI_ID_OFFLOAD1,
721 .playback = { 808 .playback = {
722 .stream_name = "Offload1 Playback", 809 .stream_name = "Offload1 Playback",
723 .channels_min = 2, 810 .channels_min = 2,
@@ -728,6 +815,7 @@ static struct snd_soc_dai_driver hsw_dais[] = {
728 }, 815 },
729 { 816 {
730 .name = "Loopback Pin", 817 .name = "Loopback Pin",
818 .id = HSW_PCM_DAI_ID_LOOPBACK,
731 .capture = { 819 .capture = {
732 .stream_name = "Loopback Capture", 820 .stream_name = "Loopback Capture",
733 .channels_min = 2, 821 .channels_min = 2,
@@ -736,16 +824,6 @@ static struct snd_soc_dai_driver hsw_dais[] = {
736 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE, 824 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
737 }, 825 },
738 }, 826 },
739 {
740 .name = "Capture Pin",
741 .capture = {
742 .stream_name = "Analog Capture",
743 .channels_min = 2,
744 .channels_max = 2,
745 .rates = SNDRV_PCM_RATE_48000,
746 .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S16_LE,
747 },
748 },
749}; 827};
750 828
751static const struct snd_soc_dapm_widget widgets[] = { 829static const struct snd_soc_dapm_widget widgets[] = {
@@ -776,9 +854,20 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
776{ 854{
777 struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform); 855 struct hsw_priv_data *priv_data = snd_soc_platform_get_drvdata(platform);
778 struct sst_pdata *pdata = dev_get_platdata(platform->dev); 856 struct sst_pdata *pdata = dev_get_platdata(platform->dev);
779 struct device *dma_dev = pdata->dma_dev; 857 struct device *dma_dev, *dev;
780 int i, ret = 0; 858 int i, ret = 0;
781 859
860 if (!pdata)
861 return -ENODEV;
862
863 dev = platform->dev;
864 dma_dev = pdata->dma_dev;
865
866 priv_data->hsw = pdata->dsp;
867 priv_data->dev = platform->dev;
868 priv_data->pm_state = HSW_PM_STATE_D0;
869 priv_data->soc_card = platform->component.card;
870
782 /* allocate DSP buffer page tables */ 871 /* allocate DSP buffer page tables */
783 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 872 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
784 873
@@ -801,6 +890,16 @@ static int hsw_pcm_probe(struct snd_soc_platform *platform)
801 } 890 }
802 } 891 }
803 892
893 /* allocate runtime modules */
894 hsw_pcm_create_modules(priv_data);
895
896 /* enable runtime PM with auto suspend */
897 pm_runtime_set_autosuspend_delay(platform->dev,
898 SST_RUNTIME_SUSPEND_DELAY);
899 pm_runtime_use_autosuspend(platform->dev);
900 pm_runtime_enable(platform->dev);
901 pm_runtime_idle(platform->dev);
902
804 return 0; 903 return 0;
805 904
806err: 905err:
@@ -819,6 +918,9 @@ static int hsw_pcm_remove(struct snd_soc_platform *platform)
819 snd_soc_platform_get_drvdata(platform); 918 snd_soc_platform_get_drvdata(platform);
820 int i; 919 int i;
821 920
921 pm_runtime_disable(platform->dev);
922 hsw_pcm_free_modules(priv_data);
923
822 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) { 924 for (i = 0; i < ARRAY_SIZE(hsw_dais); i++) {
823 if (hsw_dais[i].playback.channels_min) 925 if (hsw_dais[i].playback.channels_min)
824 snd_dma_free_pages(&priv_data->dmab[i][0]); 926 snd_dma_free_pages(&priv_data->dmab[i][0]);
@@ -896,10 +998,181 @@ static int hsw_pcm_dev_remove(struct platform_device *pdev)
896 return 0; 998 return 0;
897} 999}
898 1000
1001#ifdef CONFIG_PM_RUNTIME
1002
1003static int hsw_pcm_runtime_idle(struct device *dev)
1004{
1005 return 0;
1006}
1007
1008static int hsw_pcm_runtime_suspend(struct device *dev)
1009{
1010 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1011 struct sst_hsw *hsw = pdata->hsw;
1012
1013 if (pdata->pm_state == HSW_PM_STATE_D3)
1014 return 0;
1015
1016 sst_hsw_dsp_runtime_suspend(hsw);
1017 sst_hsw_dsp_runtime_sleep(hsw);
1018 pdata->pm_state = HSW_PM_STATE_D3;
1019
1020 return 0;
1021}
1022
1023static int hsw_pcm_runtime_resume(struct device *dev)
1024{
1025 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1026 struct sst_hsw *hsw = pdata->hsw;
1027 int ret;
1028
1029 if (pdata->pm_state == HSW_PM_STATE_D0)
1030 return 0;
1031
1032 ret = sst_hsw_dsp_load(hsw);
1033 if (ret < 0) {
1034 dev_err(dev, "failed to reload %d\n", ret);
1035 return ret;
1036 }
1037
1038 ret = hsw_pcm_create_modules(pdata);
1039 if (ret < 0) {
1040 dev_err(dev, "failed to create modules %d\n", ret);
1041 return ret;
1042 }
1043
1044 ret = sst_hsw_dsp_runtime_resume(hsw);
1045 if (ret < 0)
1046 return ret;
1047 else if (ret == 1) /* no action required */
1048 return 0;
1049
1050 pdata->pm_state = HSW_PM_STATE_D0;
1051 return ret;
1052}
1053
1054#else
1055#define hsw_pcm_runtime_idle NULL
1056#define hsw_pcm_runtime_suspend NULL
1057#define hsw_pcm_runtime_resume NULL
1058#endif
1059
1060#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_RUNTIME)
1061
1062static void hsw_pcm_complete(struct device *dev)
1063{
1064 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1065 struct sst_hsw *hsw = pdata->hsw;
1066 struct hsw_pcm_data *pcm_data;
1067 int i, err;
1068
1069 if (pdata->pm_state == HSW_PM_STATE_D0)
1070 return;
1071
1072 err = sst_hsw_dsp_load(hsw);
1073 if (err < 0) {
1074 dev_err(dev, "failed to reload %d\n", err);
1075 return;
1076 }
1077
1078 err = hsw_pcm_create_modules(pdata);
1079 if (err < 0) {
1080 dev_err(dev, "failed to create modules %d\n", err);
1081 return;
1082 }
1083
1084 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
1085 pcm_data = &pdata->pcm[i];
1086
1087 if (!pcm_data->substream)
1088 continue;
1089
1090 err = sst_module_runtime_restore(pcm_data->runtime,
1091 &pcm_data->context);
1092 if (err < 0)
1093 dev_err(dev, "failed to restore context for PCM %d\n", i);
1094 }
1095
1096 snd_soc_resume(pdata->soc_card->dev);
1097
1098 err = sst_hsw_dsp_runtime_resume(hsw);
1099 if (err < 0)
1100 return;
1101 else if (err == 1) /* no action required */
1102 return;
1103
1104 pdata->pm_state = HSW_PM_STATE_D0;
1105 return;
1106}
1107
1108static int hsw_pcm_prepare(struct device *dev)
1109{
1110 struct hsw_priv_data *pdata = dev_get_drvdata(dev);
1111 struct sst_hsw *hsw = pdata->hsw;
1112 struct hsw_pcm_data *pcm_data;
1113 int i, err;
1114
1115 if (pdata->pm_state == HSW_PM_STATE_D3)
1116 return 0;
1117 /* suspend all active streams */
1118 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
1119 pcm_data = &pdata->pcm[i];
1120
1121 if (!pcm_data->substream)
1122 continue;
1123 dev_dbg(dev, "suspending pcm %d\n", i);
1124 snd_pcm_suspend_all(pcm_data->hsw_pcm);
1125
1126 /* We need to wait until the DSP FW stops the streams */
1127 msleep(2);
1128 }
1129
1130 snd_soc_suspend(pdata->soc_card->dev);
1131 snd_soc_poweroff(pdata->soc_card->dev);
1132
1133 /* enter D3 state and stall */
1134 sst_hsw_dsp_runtime_suspend(hsw);
1135
1136 /* preserve persistent memory */
1137 for (i = 0; i < HSW_PCM_DAI_ID_CAPTURE + 1; i++) {
1138 pcm_data = &pdata->pcm[i];
1139
1140 if (!pcm_data->substream)
1141 continue;
1142
1143 dev_dbg(dev, "saving context pcm %d\n", i);
1144 err = sst_module_runtime_save(pcm_data->runtime,
1145 &pcm_data->context);
1146 if (err < 0)
1147 dev_err(dev, "failed to save context for PCM %d\n", i);
1148 }
1149
1150 /* put the DSP to sleep */
1151 sst_hsw_dsp_runtime_sleep(hsw);
1152 pdata->pm_state = HSW_PM_STATE_D3;
1153
1154 return 0;
1155}
1156
1157#else
1158#define hsw_pcm_prepare NULL
1159#define hsw_pcm_complete NULL
1160#endif
1161
1162static const struct dev_pm_ops hsw_pcm_pm = {
1163 .runtime_idle = hsw_pcm_runtime_idle,
1164 .runtime_suspend = hsw_pcm_runtime_suspend,
1165 .runtime_resume = hsw_pcm_runtime_resume,
1166 .prepare = hsw_pcm_prepare,
1167 .complete = hsw_pcm_complete,
1168};
1169
899static struct platform_driver hsw_pcm_driver = { 1170static struct platform_driver hsw_pcm_driver = {
900 .driver = { 1171 .driver = {
901 .name = "haswell-pcm-audio", 1172 .name = "haswell-pcm-audio",
902 .owner = THIS_MODULE, 1173 .owner = THIS_MODULE,
1174 .pm = &hsw_pcm_pm,
1175
903 }, 1176 },
904 1177
905 .probe = hsw_pcm_dev_probe, 1178 .probe = hsw_pcm_dev_probe,